{-# LANGUAGE OverloadedStrings #-}

-- | The geometry package provides an easy interface to page dimensions.
--
-- CTAN page for geometry: <http://www.ctan.org/pkg/geometry>.
module Text.LaTeX.Packages.Geometry (
    -- * Geometry package
    geometry
  , importGeometry
    -- * Geometry options
  , GeometryOption (..)
  , applyGeometry
  ) where

import Text.LaTeX
import Text.LaTeX.Base.Syntax
import Text.LaTeX.Base.Class

-- | Geometry package. Use it to import it like this:
--
-- > usepackage [] geometry
--
-- In most cases, it is recommended to use 'importGeometry' instead.
geometry :: PackageName
geometry :: PackageName
geometry = PackageName
"geometry"

-- | Options of the geometry package.
data GeometryOption = 
    GHeight Measure
  | GWidth  Measure
  | GPaper PaperType
  | GCentered
  | GPaperHeight Measure
  | GPaperWidth Measure
  | GLandscape Bool
    deriving Int -> GeometryOption -> ShowS
[GeometryOption] -> ShowS
GeometryOption -> PackageName
(Int -> GeometryOption -> ShowS)
-> (GeometryOption -> PackageName)
-> ([GeometryOption] -> ShowS)
-> Show GeometryOption
forall a.
(Int -> a -> ShowS)
-> (a -> PackageName) -> ([a] -> ShowS) -> Show a
showList :: [GeometryOption] -> ShowS
$cshowList :: [GeometryOption] -> ShowS
show :: GeometryOption -> PackageName
$cshow :: GeometryOption -> PackageName
showsPrec :: Int -> GeometryOption -> ShowS
$cshowsPrec :: Int -> GeometryOption -> ShowS
Show

renderOption :: Render a => Text -> a -> Text
renderOption :: Text -> a -> Text
renderOption Text
t a
x = Text
t Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"=" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> a -> Text
forall a. Render a => a -> Text
render a
x

instance Render GeometryOption where
  render :: GeometryOption -> Text
render (GHeight Measure
m) = Text -> Measure -> Text
forall a. Render a => Text -> a -> Text
renderOption Text
"height" Measure
m
  render (GWidth  Measure
m) = Text -> Measure -> Text
forall a. Render a => Text -> a -> Text
renderOption Text
"width"  Measure
m
  render (GPaper  PaperType
p) = ClassOption -> Text
forall a. Render a => a -> Text
render (PaperType -> ClassOption
Paper PaperType
p)
  render GeometryOption
GCentered   = Text
"centered"
  render (GPaperHeight Measure
m) = Text -> Measure -> Text
forall a. Render a => Text -> a -> Text
renderOption Text
"paperheight" Measure
m
  render (GPaperWidth Measure
m) = Text -> Measure -> Text
forall a. Render a => Text -> a -> Text
renderOption Text
"paperwidth" Measure
m
  render (GLandscape Bool
b) = Text -> Bool -> Text
forall a. Render a => Text -> a -> Text
renderOption Text
"landscape" Bool
b

-- | Apply the given geometry options to the document.
applyGeometry :: LaTeXC l => [GeometryOption] -> l
applyGeometry :: [GeometryOption] -> l
applyGeometry [GeometryOption]
opts = LaTeX -> l
forall l. LaTeXC l => LaTeX -> l
fromLaTeX (LaTeX -> l) -> LaTeX -> l
forall a b. (a -> b) -> a -> b
$ PackageName -> [TeXArg] -> LaTeX
TeXComm PackageName
"geometry" [LaTeX -> TeXArg
FixArg (LaTeX -> TeXArg) -> LaTeX -> TeXArg
forall a b. (a -> b) -> a -> b
$ Text -> LaTeX
forall l. LaTeXC l => Text -> l
raw (Text -> LaTeX) -> Text -> LaTeX
forall a b. (a -> b) -> a -> b
$ [GeometryOption] -> Text
forall a. Render a => [a] -> Text
renderCommas [GeometryOption]
opts]

-- | Import the geometry package with additional options.
importGeometry :: LaTeXC l => [GeometryOption] -> l
importGeometry :: [GeometryOption] -> l
importGeometry [GeometryOption]
opts = [l] -> PackageName -> l
forall l. LaTeXC l => [l] -> PackageName -> l
usepackage ((GeometryOption -> l) -> [GeometryOption] -> [l]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap GeometryOption -> l
forall a l. (Render a, LaTeXC l) => a -> l
rendertex [GeometryOption]
opts) PackageName
geometry