{-# LANGUAGE DerivingStrategies         #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE TypeFamilies               #-}

module Blagda.Latex where

import qualified Data.ByteString.Lazy as LazyBS
import           Data.Generics
import           Data.Text (Text)
import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text
import           Development.Shake
import           Development.Shake.Classes
import           Development.Shake.Forward (cacheAction)


newtype LatexEquation = LatexEquation (Bool, Text) -- TODO: Less lazy instance
  deriving newtype (Int -> LatexEquation -> ShowS
[LatexEquation] -> ShowS
LatexEquation -> String
(Int -> LatexEquation -> ShowS)
-> (LatexEquation -> String)
-> ([LatexEquation] -> ShowS)
-> Show LatexEquation
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LatexEquation] -> ShowS
$cshowList :: [LatexEquation] -> ShowS
show :: LatexEquation -> String
$cshow :: LatexEquation -> String
showsPrec :: Int -> LatexEquation -> ShowS
$cshowsPrec :: Int -> LatexEquation -> ShowS
Show, Typeable, LatexEquation -> LatexEquation -> Bool
(LatexEquation -> LatexEquation -> Bool)
-> (LatexEquation -> LatexEquation -> Bool) -> Eq LatexEquation
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LatexEquation -> LatexEquation -> Bool
$c/= :: LatexEquation -> LatexEquation -> Bool
== :: LatexEquation -> LatexEquation -> Bool
$c== :: LatexEquation -> LatexEquation -> Bool
Eq, Eq LatexEquation
Eq LatexEquation
-> (Int -> LatexEquation -> Int)
-> (LatexEquation -> Int)
-> Hashable LatexEquation
Int -> LatexEquation -> Int
LatexEquation -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: LatexEquation -> Int
$chash :: LatexEquation -> Int
hashWithSalt :: Int -> LatexEquation -> Int
$chashWithSalt :: Int -> LatexEquation -> Int
$cp1Hashable :: Eq LatexEquation
Hashable, Get LatexEquation
[LatexEquation] -> Put
LatexEquation -> Put
(LatexEquation -> Put)
-> Get LatexEquation
-> ([LatexEquation] -> Put)
-> Binary LatexEquation
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
putList :: [LatexEquation] -> Put
$cputList :: [LatexEquation] -> Put
get :: Get LatexEquation
$cget :: Get LatexEquation
put :: LatexEquation -> Put
$cput :: LatexEquation -> Put
Binary, LatexEquation -> ()
(LatexEquation -> ()) -> NFData LatexEquation
forall a. (a -> ()) -> NFData a
rnf :: LatexEquation -> ()
$crnf :: LatexEquation -> ()
NFData)

type instance RuleResult LatexEquation = Text


buildLatexEqn :: Bool -> Text -> Action Text
buildLatexEqn :: Bool -> Text -> Action Text
buildLatexEqn Bool
display Text
tex = LatexEquation -> Action Text -> Action Text
forall a b.
(Typeable a, Binary a, Show a, Typeable b, Binary b, Show b) =>
a -> Action b -> Action b
cacheAction ((Bool, Text) -> LatexEquation
LatexEquation (Bool
display, Text
tex)) (Action Text -> Action Text) -> Action Text -> Action Text
forall a b. (a -> b) -> a -> b
$ do
  Partial => [String] -> Action ()
[String] -> Action ()
need [String
".macros"]

  let args :: [String]
args = [String
"-f", String
".macros", String
"-t"] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String
"-d" | Bool
display]
      stdin :: ByteString
stdin = ByteString -> ByteString
LazyBS.fromStrict (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ Text -> ByteString
Text.encodeUtf8 Text
tex
  Stdout ByteString
out <- [CmdOption] -> String -> [String] -> Action (Stdout ByteString)
forall r.
(Partial, CmdResult r) =>
[CmdOption] -> String -> [String] -> Action r
command [ByteString -> CmdOption
StdinBS ByteString
stdin] String
"katex" [String]
args
  Text -> Action Text
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Action Text)
-> (ByteString -> Text) -> ByteString -> Action Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
Text.stripEnd (Text -> Text) -> (ByteString -> Text) -> ByteString -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
Text.decodeUtf8 (ByteString -> Action Text) -> ByteString -> Action Text
forall a b. (a -> b) -> a -> b
$ ByteString
out