{-# LANGUAGE OverloadedStrings, QuasiQuotes #-}

-- | Defines main Markdown printer functions.
module Language.Drasil.Markdown.Print (genMDBook, pSpec) where

import Prelude hiding (print, (<>))
import qualified Prelude as P ((<>))
import Data.List (transpose)
import Data.List.Utils (replace)
import qualified Data.Set as S
import qualified Data.Text as T (Text, pack)
import qualified Prettyprinter as PNew (Doc)
import System.FilePath (takeFileName)
import Text.PrettyPrint hiding (Str)

import Drasil.Data.Formats.CSV (DoubleQuotationPolicy(..), csvRenderOpts,
  mkCSV, renderCSV)
import Drasil.FileHandling (FileLayout, file, directory, ps)

import Language.Drasil.Printing.AST (ItemType(Flat, Nested),
  ListType(Ordered, Unordered, Definitions, Desc, Simple), Expr,
  Expr(..), Spec(Quote, EmptyS, Ref, HARDNL, E, (:+:), Tooltip), Label,
  LinkType(Internal, Cite2, External), OverSymb(Hat), Fonts(Emph, Bold),
  Spacing(Thin), Fence(Abs), Ops(Perc, Mul))
import Language.Drasil.Printing.Citation (BibRef)
import Language.Drasil.Printing.Helpers (sqbrac, pipe, bslash, unders,
  hat, hyph, dot, ($^$), vsep)
import Language.Drasil.Printing.LayoutObj (Project(Project),
  LayoutObj(..), Filename, RefMap, File(File))
import Language.Drasil.HTML.Helpers(BibFormatter(..))
import qualified Language.Drasil.HTML.Print as HTML (renderCite, pSpec)
import Language.Drasil.Markdown.Helpers (heading, image, li, reflink,
  reflinkURI, reflinkInfo, caption, bold, ul, docLength, divTag, centeredDiv,
  em, h, h', centeredDivId)
import Language.Drasil.TeX.Helpers (commandD, command2D, mkEnv)
import qualified Language.Drasil.TeX.Print as TeX (pExpr, fence, OpenClose(..),
  pMatrix, cases)
import Language.Drasil.TeX.Monad (runPrint, MathContext(Math), D, toMath, toText,
  hpunctuate)

-----------------------------------------------------------------
------------------------- mdBook SRS ----------------------------
-----------------------------------------------------------------

-- | Generate a mdBook SRS
genMDBook :: Project -> [FileLayout]
genMDBook :: Project -> [FileLayout]
genMDBook p :: Project
p@(Project Title
t Title
a RefMap
rm [File]
fs) =
  [ PathSegment -> Doc -> FileLayout
forall doc. Writeable doc => PathSegment -> doc -> FileLayout
file [ps|book.toml|] (RefMap -> Title -> Doc
makeBook RefMap
rm Title
t)
  , PathSegment -> Doc (ZonkAny 0) -> FileLayout
forall doc. Writeable doc => PathSegment -> doc -> FileLayout
file [ps|.drasil-requirements.csv|] (Project -> Doc (ZonkAny 0)
forall ann. Project -> Doc ann
makeRequirements Project
p)
  , PathSegment -> [FileLayout] -> FileLayout
forall (f :: * -> *).
Foldable f =>
PathSegment -> f FileLayout -> FileLayout
directory [ps|src|] ((([Char], Doc) -> FileLayout) -> [([Char], Doc)] -> [FileLayout]
forall a b. (a -> b) -> [a] -> [b]
map (\([Char]
fn, Doc
d) -> PathSegment -> Doc -> FileLayout
forall doc. Writeable doc => PathSegment -> doc -> FileLayout
file [ps|{fn}.md|] Doc
d) [([Char], Doc)]
fs'')
  ]
  where
    -- Create "title page" file
    titlePageFile :: File
titlePageFile = Title -> [Char] -> Int -> [LayoutObj] -> File
File Title
t [Char]
"title" Int
0 [Int -> Title -> Title -> LayoutObj
Header Int
0 Title
t Title
EmptyS, Title -> LayoutObj
Paragraph Title
a]
    fs' :: [File]
fs' = File
titlePageFile File -> [File] -> [File]
forall a. a -> [a] -> [a]
: [File]
fs
    -- Create "summary page" file
    summary :: ([Char], Doc)
summary = ([Char]
"SUMMARY", [Doc] -> Doc
vcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ (File -> Doc) -> [File] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (RefMap -> File -> Doc
summaryItem RefMap
rm) [File]
fs')
    -- Render all pages into Markdown
    fs'' :: [([Char], Doc)]
fs'' = ([Char], Doc)
summary ([Char], Doc) -> [([Char], Doc)] -> [([Char], Doc)]
forall a. a -> [a] -> [a]
: (File -> ([Char], Doc)) -> [File] -> [([Char], Doc)]
forall a b. (a -> b) -> [a] -> [b]
map (RefMap -> File -> ([Char], Doc)
print' RefMap
rm) [File]
fs'

-- | Helper for rendering a 'SUMMARY.md' item
summaryItem :: RefMap -> File -> Doc
summaryItem :: RefMap -> File -> Doc
summaryItem RefMap
rm (File Title
t [Char]
n Int
d [LayoutObj]
_) = Doc
bullet Doc -> Doc -> Doc
<+> Doc
lbl Doc -> Doc -> Doc
<> Doc
ref
  where
    bullet :: Doc
bullet = [Char] -> Doc
text (Int -> Char -> [Char]
forall a. Int -> a -> [a]
replicate (Int
dInt -> Int -> Int
forall a. Num a => a -> a -> a
*Int
2) Char
' ') Doc -> Doc -> Doc
<> [Char] -> Doc
text [Char]
"-"
    lbl :: Doc
lbl    = Doc -> Doc
brackets (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ RefMap -> Title -> Doc
pSpec RefMap
rm Title
t
    ref :: Doc
ref    = Doc -> Doc
parens (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ [Char] -> Doc
text ([Char] -> Doc) -> [Char] -> Doc
forall a b. (a -> b) -> a -> b
$ [Char]
"./" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
n [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
".md"

-- | Prints the .toml config file for mdBook.
makeBook :: RefMap -> Spec -> Doc
makeBook :: RefMap -> Title -> Doc
makeBook RefMap
rm Title
t = [Doc] -> Doc
vcat [
  [Char] -> Doc
text [Char]
"[book]",
  [Char] -> Doc
text [Char]
"language = \"en\"",
  [Char] -> Doc
text [Char]
"src = \"src\"",
  [Char] -> Doc
text [Char]
"title =" Doc -> Doc -> Doc
<+> RefMap -> Title -> Doc
mkTitle RefMap
rm Title
t,
  [Char] -> Doc
text [Char]
"[output.html]",
  [Char] -> Doc
text [Char]
"smart-punctuation = true",
  [Char] -> Doc
text [Char]
"mathjax-support = true"
  ]

-- | Render a title 'Spec'.
mkTitle :: RefMap -> Spec -> Doc
mkTitle :: RefMap -> Title -> Doc
mkTitle RefMap
rm Title
t = [Char] -> Doc
text [Char]
"\"" Doc -> Doc -> Doc
<> RefMap -> Title -> Doc
pSpec RefMap
rm Title
t Doc -> Doc -> Doc
<> [Char] -> Doc
text [Char]
"\""

-- | Prints the .csv file mapping the original filepaths of assets to the
-- location mdBook uses.
makeRequirements :: Project -> PNew.Doc ann
makeRequirements :: forall ann. Project -> Doc ann
makeRequirements Project
p =
  let
    mCSV :: Either [Char] CSV
mCSV = Maybe ColumnCount -> Maybe [Text] -> [[Text]] -> Either [Char] CSV
mkCSV (ColumnCount -> Maybe ColumnCount
forall a. a -> Maybe a
Just ColumnCount
2) ([Text] -> Maybe [Text]
forall a. a -> Maybe a
Just [Text
"Original", Text
"Copy"]) (Project -> [[Text]]
assetMat Project
p)
    csv :: CSV
csv = ([Char] -> CSV) -> (CSV -> CSV) -> Either [Char] CSV -> CSV
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either [Char] -> CSV
forall a. HasCallStack => [Char] -> a
error CSV -> CSV
forall a. a -> a
id Either [Char] CSV
mCSV
  in CSVRenderOptions -> CSV -> Doc ann
forall ann. CSVRenderOptions -> CSV -> Doc ann
renderCSV (DoubleQuotationPolicy -> CSVRenderOptions
csvRenderOpts DoubleQuotationPolicy
Minimal) CSV
csv

-- | FIXME: HACK: Find all figure assets from a 'Project'. This is a hack
-- because (a) there can be assets other than figures, (b) we are searching
-- _after_ layout onto a list of 'LayoutObj's. This should be a matter of
-- knowing which artifacts were rendered and when some (new) chunk 'SystemAsset'
-- is referenced.
assetMat :: Project -> [[T.Text]]
assetMat :: Project -> [[Text]]
assetMat (Project Title
_ Title
_ RefMap
_ [File]
files) =
  [[[Char] -> Text
T.pack [Char]
fp, Text
"src/assets/" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
P.<> [Char] -> Text
T.pack ([Char] -> [Char]
takeFileName [Char]
fp)] | [Char]
fp <- Set [Char] -> [[Char]]
forall a. Set a -> [a]
S.toAscList Set [Char]
extractedLOs]
  where
    extractedLOs :: Set [Char]
extractedLOs = [Set [Char]] -> Set [Char]
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
S.unions ([Set [Char]] -> Set [Char]) -> [Set [Char]] -> Set [Char]
forall a b. (a -> b) -> a -> b
$ (File -> Set [Char]) -> [File] -> [Set [Char]]
forall a b. (a -> b) -> [a] -> [b]
map (\(File Title
_ [Char]
_ Int
_ [LayoutObj]
los) -> [Set [Char]] -> Set [Char]
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
S.unions ([Set [Char]] -> Set [Char]) -> [Set [Char]] -> Set [Char]
forall a b. (a -> b) -> a -> b
$ (LayoutObj -> Set [Char]) -> [LayoutObj] -> [Set [Char]]
forall a b. (a -> b) -> [a] -> [b]
map LayoutObj -> Set [Char]
figs [LayoutObj]
los) [File]
files
    unionsFigs :: [LayoutObj] -> Set [Char]
unionsFigs = [Set [Char]] -> Set [Char]
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
S.unions ([Set [Char]] -> Set [Char])
-> ([LayoutObj] -> [Set [Char]]) -> [LayoutObj] -> Set [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LayoutObj -> Set [Char]) -> [LayoutObj] -> [Set [Char]]
forall a b. (a -> b) -> [a] -> [b]
map LayoutObj -> Set [Char]
figs
    figs :: LayoutObj -> S.Set String
    figs :: LayoutObj -> Set [Char]
figs (Figure Title
_ Maybe Title
_ [Char]
fp MaxWidthPercent
_)     = [Char] -> Set [Char]
forall a. a -> Set a
S.singleton [Char]
fp
    figs (HDiv [[Char]]
_ [LayoutObj]
los Title
_)        = [LayoutObj] -> Set [Char]
unionsFigs [LayoutObj]
los
    figs (Cell [LayoutObj]
los)            = [LayoutObj] -> Set [Char]
unionsFigs [LayoutObj]
los
    figs (Definition [([Char], [LayoutObj])]
slos Title
_)   = [Set [Char]] -> Set [Char]
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
S.unions ((([Char], [LayoutObj]) -> Set [Char])
-> [([Char], [LayoutObj])] -> [Set [Char]]
forall a b. (a -> b) -> [a] -> [b]
map ([LayoutObj] -> Set [Char]
unionsFigs ([LayoutObj] -> Set [Char])
-> (([Char], [LayoutObj]) -> [LayoutObj])
-> ([Char], [LayoutObj])
-> Set [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char], [LayoutObj]) -> [LayoutObj]
forall a b. (a, b) -> b
snd) [([Char], [LayoutObj])]
slos)
    figs Table{}               = Set [Char]
forall a. Set a
S.empty
    figs Header{}              = Set [Char]
forall a. Set a
S.empty
    figs Paragraph{}           = Set [Char]
forall a. Set a
S.empty
    figs EqnBlock{}            = Set [Char]
forall a. Set a
S.empty
    figs List{}                = Set [Char]
forall a. Set a
S.empty
    figs Graph{}               = Set [Char]
forall a. Set a
S.empty
    figs CodeBlock{}           = Set [Char]
forall a. Set a
S.empty
    figs Bib{}                 = Set [Char]
forall a. Set a
S.empty

-- | Called by build', uses 'printLO' to render a File
-- into a single Doc
print' :: RefMap -> File -> (Filename, Doc)
print' :: RefMap -> File -> ([Char], Doc)
print' RefMap
rm (File Title
_ [Char]
n Int
_ [LayoutObj]
c) = ([Char]
n, RefMap -> [LayoutObj] -> Doc
print RefMap
rm [LayoutObj]
c)

-- | Uses 'printLO' to render the layout objects
-- into a single Doc
print :: RefMap -> [LayoutObj] -> Doc
print :: RefMap -> [LayoutObj] -> Doc
print RefMap
rm = [Doc] -> Doc
vsep ([Doc] -> Doc) -> ([LayoutObj] -> [Doc]) -> [LayoutObj] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LayoutObj -> Doc) -> [LayoutObj] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (RefMap -> LayoutObj -> Doc
printLO RefMap
rm)

-----------------------------------------------------------------
------------------- LAYOUT OBJECT PRINTING ----------------------
-----------------------------------------------------------------

-- | Helper for rendering LayoutObjects into Markdown
printLO :: RefMap -> LayoutObj -> Doc
printLO :: RefMap -> LayoutObj -> Doc
printLO RefMap
rm (Header Int
n Title
contents Title
l) = Int -> Doc
h (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) Doc -> Doc -> Doc
<+> Doc -> Doc -> Doc
heading (RefMap -> Title -> Doc
pSpec RefMap
rm Title
contents) (RefMap -> Title -> Doc
pSpec RefMap
rm Title
l)
printLO RefMap
rm (Cell [LayoutObj]
layoutObs)      = RefMap -> [LayoutObj] -> Doc
print RefMap
rm [LayoutObj]
layoutObs
printLO RefMap
rm (HDiv [[Char]]
_ [LayoutObj]
layoutObs Title
_)  = RefMap -> [LayoutObj] -> Doc
print RefMap
rm [LayoutObj]
layoutObs
printLO RefMap
rm (Paragraph Title
contents)  = RefMap -> Title -> Doc
pSpec RefMap
rm Title
contents
printLO RefMap
rm (EqnBlock Title
contents)   = [Char] -> Doc
text [Char]
"\\\\[" Doc -> Doc -> Doc
<> Title -> Doc
rndr Title
contents Doc -> Doc -> Doc
<> [Char] -> Doc
text [Char]
"\\\\]"
  where
    rndr :: Title -> Doc
rndr (E Expr
e) = Expr -> Doc
pExpr Expr
e
    rndr Title
c = RefMap -> Title -> Doc
pSpec RefMap
rm Title
c
printLO RefMap
rm (Table [[Char]]
_ [[Title]]
rows Title
r Bool
b Title
t)  = RefMap -> [[Title]] -> Doc -> Bool -> Doc -> Doc
makeTable RefMap
rm [[Title]]
rows (RefMap -> Title -> Doc
pSpec RefMap
rm Title
r) Bool
b (RefMap -> Title -> Doc
pSpec RefMap
rm Title
t)
printLO RefMap
rm (Definition [([Char], [LayoutObj])]
ssPs Title
l)   = RefMap -> [([Char], [LayoutObj])] -> Doc -> Doc
makeDefn RefMap
rm [([Char], [LayoutObj])]
ssPs (RefMap -> Title -> Doc
pSpec RefMap
rm Title
l)
printLO RefMap
rm (List ListType
t)              = RefMap -> ListType -> Int -> Doc
makeList RefMap
rm ListType
t Int
0
printLO RefMap
rm (Figure Title
r Maybe Title
c [Char]
f MaxWidthPercent
_)      = Doc -> Maybe Doc -> Doc -> Doc
makeFigure (RefMap -> Title -> Doc
pSpec RefMap
rm Title
r) ((Title -> Doc) -> Maybe Title -> Maybe Doc
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (RefMap -> Title -> Doc
pSpec RefMap
rm) Maybe Title
c) ([Char] -> Doc
text [Char]
f)
printLO RefMap
rm (Bib BibRef
bib)             = RefMap -> BibRef -> Doc
makeBib RefMap
rm BibRef
bib
printLO RefMap
_ Graph {}               = Doc
empty
printLO RefMap
_ CodeBlock {}           = Doc
empty

-----------------------------------------------------------------
----------------------- SPEC PRINTING ---------------------------
-----------------------------------------------------------------

-- | Helper for rendering Specs into Markdown
pSpec :: RefMap -> Spec -> Doc
pSpec :: RefMap -> Title -> Doc
pSpec RefMap
_ (E Expr
e)      = [Char] -> Doc
text [Char]
"\\\\(" Doc -> Doc -> Doc
<> Expr -> Doc
pExpr Expr
e Doc -> Doc -> Doc
<> [Char] -> Doc
text [Char]
"\\\\)"
pSpec RefMap
rm (Tooltip Title
_ Title
s) = RefMap -> Title -> Doc
pSpec RefMap
rm Title
s
pSpec RefMap
rm (Title
a :+: Title
b) = RefMap -> Title -> Doc
pSpec RefMap
rm Title
a Doc -> Doc -> Doc
<> RefMap -> Title -> Doc
pSpec RefMap
rm Title
b
pSpec RefMap
_ Title
HARDNL     = [Char] -> Doc
text [Char]
"\n"
pSpec RefMap
rm (Ref LinkType
Internal       [Char]
r Title
a) = RefMap -> [Char] -> Doc -> Doc
reflink     RefMap
rm [Char]
r (RefMap -> Title -> Doc
pSpec RefMap
rm Title
a)
pSpec RefMap
rm (Ref (Cite2 Title
EmptyS) [Char]
r Title
a) = RefMap -> [Char] -> Doc -> Doc
reflink     RefMap
rm [Char]
r (RefMap -> Title -> Doc
pSpec RefMap
rm Title
a)
pSpec RefMap
rm (Ref (Cite2 Title
n)      [Char]
r Title
a) = RefMap -> [Char] -> Doc -> Doc -> Doc
reflinkInfo RefMap
rm [Char]
r (RefMap -> Title -> Doc
pSpec RefMap
rm Title
a) (RefMap -> Title -> Doc
pSpec RefMap
rm Title
n)
pSpec RefMap
rm (Ref LinkType
External       [Char]
r Title
a) = Doc -> Doc -> Doc
reflinkURI  ([Char] -> Doc
text [Char]
r) (RefMap -> Title -> Doc
pSpec RefMap
rm Title
a)
pSpec RefMap
rm (Quote Title
q) = Doc -> Doc
doubleQuotes (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ RefMap -> Title -> Doc
pSpec RefMap
rm Title
q
pSpec RefMap
_ Title
s          = Title -> Doc
HTML.pSpec Title
s

-----------------------------------------------------------------
-------------------- EXPRESSION PRINTING ------------------------
-----------------------------------------------------------------

-- | Helper for rendering Exprs into mdBook compatiable Mathjax
pExpr :: Expr -> Doc
pExpr :: Expr -> Doc
pExpr (Str [Char]
s)        = D -> Doc
printMath (D -> Doc) -> D -> Doc
forall a b. (a -> b) -> a -> b
$ D -> D
toText (D -> D) -> D -> D
forall a b. (a -> b) -> a -> b
$ Doc -> D
forall a. a -> PrintLaTeX a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Doc -> D) -> Doc -> D
forall a b. (a -> b) -> a -> b
$ Doc
lq Doc -> Doc -> Doc
<> [Char] -> Doc
text [Char]
s Doc -> Doc -> Doc
<> Doc
rq
  where
    lq :: Doc
lq = [Char] -> Doc
text [Char]
"\\\\(\\``\\\\)"
    rq :: Doc
rq = [Char] -> Doc
text [Char]
"''"
pExpr (Div Expr
n Expr
d)      = D -> Doc
printMath (D -> Doc) -> D -> Doc
forall a b. (a -> b) -> a -> b
$ [Char] -> D -> D -> D
command2D [Char]
"frac" (Expr -> D
pExpr' Expr
n) (Expr -> D
pExpr' Expr
d)
pExpr (Case [(Expr, Expr)]
ees)     = D -> Doc
printMath (D -> Doc) -> D -> Doc
forall a b. (a -> b) -> a -> b
$ [Char] -> (D -> D -> D) -> D -> D
mkEnv [Char]
"cases" D -> D -> D
forall a. Semigroup a => a -> a -> a
(P.<>) D
cases
  where
    cases :: D
cases = [(Expr, Expr)] -> (Doc -> [D] -> D) -> Doc -> (Expr -> D) -> D
TeX.cases [(Expr, Expr)]
ees Doc -> [D] -> D
hpunctuate Doc
lnl Expr -> D
pExpr'
pExpr (Mtx [[Expr]]
a)        = D -> Doc
printMath (D -> Doc) -> D -> Doc
forall a b. (a -> b) -> a -> b
$ [Char] -> (D -> D -> D) -> D -> D
mkEnv [Char]
"bmatrix" D -> D -> D
forall a. Semigroup a => a -> a -> a
(P.<>) D
matrix
  where
    matrix :: D
matrix = [[Expr]] -> (Doc -> [D] -> D) -> Doc -> (Expr -> D) -> D
TeX.pMatrix [[Expr]]
a Doc -> [D] -> D
hpunctuate Doc
lnl Expr -> D
pExpr'
pExpr (Row [Expr
x])      = Doc -> Doc
braces (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ Expr -> Doc
pExpr Expr
x
pExpr (Row [Expr]
l)        = (Doc -> Doc -> Doc) -> [Doc] -> Doc
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1 Doc -> Doc -> Doc
(<>) ((Expr -> Doc) -> [Expr] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map Expr -> Doc
pExpr [Expr]
l)
pExpr (Label [Char]
s)      = D -> Doc
printMath (D -> Doc) -> D -> Doc
forall a b. (a -> b) -> a -> b
$ Expr -> D
TeX.pExpr ([Char] -> Expr
Label [Char]
s')
  where s' :: [Char]
s' = [Char] -> [Char] -> [Char] -> [Char]
forall a. Eq a => [a] -> [a] -> [a] -> [a]
replace [Char]
"*" [Char]
"\\*" ([Char] -> [Char] -> [Char] -> [Char]
forall a. Eq a => [a] -> [a] -> [a] -> [a]
replace [Char]
"_" [Char]
"\\_" [Char]
s)
pExpr (Sub Expr
e)        = Doc
bslash Doc -> Doc -> Doc
<> Doc
unders Doc -> Doc -> Doc
<> Doc -> Doc
braces (Expr -> Doc
pExpr Expr
e)
pExpr (Sup Expr
e)        = Doc
hat    Doc -> Doc -> Doc
<> Doc -> Doc
braces (Expr -> Doc
pExpr Expr
e)
pExpr (Over OverSymb
Hat Expr
s)   = D -> Doc
printMath (D -> Doc) -> D -> Doc
forall a b. (a -> b) -> a -> b
$ [Char] -> D -> D
commandD [Char]
"hat" (Expr -> D
pExpr' Expr
s)
pExpr (MO Ops
o)
  | Ops
o Ops -> Ops -> Bool
forall a. Eq a => a -> a -> Bool
== Ops
Perc Bool -> Bool -> Bool
|| Ops
o Ops -> Ops -> Bool
forall a. Eq a => a -> a -> Bool
== Ops
Mul = Doc
bslash Doc -> Doc -> Doc
<> D -> Doc
printMath (Expr -> D
TeX.pExpr (Ops -> Expr
MO Ops
o))
pExpr (Fenced Fence
l Fence
r Expr
m) = OpenClose -> Fence -> Doc
fence OpenClose
TeX.Open Fence
l Doc -> Doc -> Doc
<> Expr -> Doc
pExpr Expr
m Doc -> Doc -> Doc
<> OpenClose -> Fence -> Doc
fence OpenClose
TeX.Close Fence
r
  where
    fence :: OpenClose -> Fence -> Doc
fence OpenClose
_ Fence
Abs = [Char] -> Doc
text [Char]
"\\|"
    fence OpenClose
a Fence
b   = D -> Doc
printMath (D -> Doc) -> D -> Doc
forall a b. (a -> b) -> a -> b
$ OpenClose -> Fence -> D
TeX.fence OpenClose
a Fence
b
pExpr (Font Fonts
Bold Expr
e)  = D -> Doc
printMath (D -> Doc) -> D -> Doc
forall a b. (a -> b) -> a -> b
$ [Char] -> D -> D
commandD [Char]
"boldsymbol" (Expr -> D
pExpr' Expr
e)
pExpr (Font Fonts
Emph Expr
e)  = Expr -> Doc
pExpr Expr
e
pExpr (Spc Spacing
Thin)     = [Char] -> Doc
text [Char]
"\\\\,"
pExpr (Sqrt Expr
e)       = D -> Doc
printMath (D -> Doc) -> D -> Doc
forall a b. (a -> b) -> a -> b
$ [Char] -> D -> D
commandD [Char]
"sqrt" (Expr -> D
pExpr' Expr
e)
pExpr Expr
e              = D -> Doc
printMath (D -> Doc) -> D -> Doc
forall a b. (a -> b) -> a -> b
$ Expr -> D
TeX.pExpr Expr
e

-- | Print an expression to a LaTeX D
pExpr' :: Expr -> D
pExpr' :: Expr -> D
pExpr' = Doc -> D
forall a. a -> PrintLaTeX a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Doc -> D) -> (Expr -> Doc) -> Expr -> D
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> Doc
pExpr

-- | Helper for rendering a D from LaTeX print
printMath :: D -> Doc
printMath :: D -> Doc
printMath = (D -> MathContext -> Doc
forall a. PrintLaTeX a -> MathContext -> a
`runPrint` MathContext
Math) (D -> Doc) -> (D -> D) -> D -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. D -> D
toMath

-- | LaTeX newline command
lnl :: Doc
lnl :: Doc
lnl = [Char] -> Doc
text [Char]
"\\\\\\\\"

-----------------------------------------------------------------
-------------------- TABLE PRINTING -----------------------------
-----------------------------------------------------------------

-- | Renders Markdown table, called by 'printLO'
makeTable :: RefMap -> [[Spec]] -> Doc -> Bool -> Doc -> Doc
makeTable :: RefMap -> [[Title]] -> Doc -> Bool -> Doc -> Doc
makeTable RefMap
_  [] Doc
_ Bool
_ Doc
_  = [Char] -> Doc
forall a. HasCallStack => [Char] -> a
error [Char]
"No table to print"
makeTable RefMap
rm [[Title]]
ls Doc
r Bool
b Doc
t  =
  Doc -> Doc
divTag Doc
r Doc -> Doc -> Doc
$^$
  [Doc] -> [Int] -> Doc
makeHeaderCols ([[Doc]] -> [Doc]
forall a. HasCallStack => [a] -> a
head [[Doc]]
matrix) [Int]
sizes Doc -> Doc -> Doc
$$
  [[Doc]] -> [Int] -> Doc
makeRows ([[Doc]] -> [[Doc]]
forall a. HasCallStack => [a] -> [a]
tail [[Doc]]
matrix) [Int]
sizes Doc -> Doc -> Doc
$^$
  Doc
capt
    where
      matrix :: [[Doc]]
matrix = RefMap -> [[Title]] -> [[Doc]]
mkDocMatrix RefMap
rm [[Title]]
ls
      sizes :: [Int]
sizes = [[Doc]] -> [Int]
columnSize [[Doc]]
matrix
      capt :: Doc
capt = if Bool
b then Doc -> Doc
bold (Doc -> Doc
caption Doc
t) else Doc
empty

-- | Helper for creating a Doc matrix
mkDocMatrix :: RefMap -> [[Spec]] -> [[Doc]]
mkDocMatrix :: RefMap -> [[Title]] -> [[Doc]]
mkDocMatrix RefMap
rm = ([Title] -> [Doc]) -> [[Title]] -> [[Doc]]
forall a b. (a -> b) -> [a] -> [b]
map (([Title] -> [Doc]) -> [[Title]] -> [[Doc]])
-> ([Title] -> [Doc]) -> [[Title]] -> [[Doc]]
forall a b. (a -> b) -> a -> b
$ (Title -> Doc) -> [Title] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (RefMap -> Title -> Doc
pSpec RefMap
rm)

-- | Helper for getting table column size
columnSize :: [[Doc]] -> [Int]
columnSize :: [[Doc]] -> [Int]
columnSize = ([Doc] -> Int) -> [[Doc]] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map ([Int] -> Int
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([Int] -> Int) -> ([Doc] -> [Int]) -> [Doc] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Doc -> Int) -> [Doc] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Doc -> Int
docLength) ([[Doc]] -> [Int]) -> ([[Doc]] -> [[Doc]]) -> [[Doc]] -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Doc]] -> [[Doc]]
forall a. [[a]] -> [[a]]
transpose

-- | Helper for creating table rows
makeRows :: [[Doc]] -> [Int] -> Doc
makeRows :: [[Doc]] -> [Int] -> Doc
makeRows [[Doc]]
lls [Int]
sizes = ([Doc] -> Doc -> Doc) -> Doc -> [[Doc]] -> Doc
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (Doc -> Doc -> Doc
($$) (Doc -> Doc -> Doc) -> ([Doc] -> Doc) -> [Doc] -> Doc -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Doc] -> [Int] -> Doc
`makeColumns` [Int]
sizes)) Doc
empty [[Doc]]
lls

-- | makeHeaderCols: Helper for creating table header row
-- | makeColumns: Helper for creating table columns
makeHeaderCols, makeColumns :: [Doc] -> [Int] -> Doc
makeHeaderCols :: [Doc] -> [Int] -> Doc
makeHeaderCols [Doc]
l [Int]
sizes = Doc
header Doc -> Doc -> Doc
$$ Doc
seperators
  where header :: Doc
header     = Doc
pipe Doc -> Doc -> Doc
<> [Doc] -> Doc
hcat (Doc -> [Doc] -> [Doc]
punctuate Doc
pipe ((Doc -> Int -> Doc) -> [Doc] -> [Int] -> [Doc]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Doc -> Int -> Doc
makeCell [Doc]
l [Int]
sizes)) Doc -> Doc -> Doc
<> Doc
pipe
        seperators :: Doc
seperators = Doc
pipe Doc -> Doc -> Doc
<> [Doc] -> Doc
hcat (Doc -> [Doc] -> [Doc]
punctuate Doc
pipe ((Int -> Doc) -> [Int] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Doc
makeDashCell [Int]
sizes))   Doc -> Doc -> Doc
<> Doc
pipe

makeColumns :: [Doc] -> [Int] -> Doc
makeColumns [Doc]
ls [Int]
sizes = Doc
pipe Doc -> Doc -> Doc
<> [Doc] -> Doc
hcat (Doc -> [Doc] -> [Doc]
punctuate Doc
pipe ((Doc -> Int -> Doc) -> [Doc] -> [Int] -> [Doc]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Doc -> Int -> Doc
makeCell [Doc]
ls [Int]
sizes)) Doc -> Doc -> Doc
<> Doc
pipe

-- | Helper for making table seperation row
makeDashCell :: Int -> Doc
makeDashCell :: Int -> Doc
makeDashCell Int
size = [Char] -> Doc
text [Char]
":" Doc -> Doc -> Doc
<> [Char] -> Doc
text (Int -> Char -> [Char]
forall a. Int -> a -> [a]
replicate (Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Char
'-')

-- | Helper for rendering a table cell
makeCell :: Doc -> Int -> Doc
makeCell :: Doc -> Int -> Doc
makeCell Doc
content Int
size = Doc
content Doc -> Doc -> Doc
<> Doc
spaces
  where
    numOfSpaces :: Int
numOfSpaces = Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
- Doc -> Int
docLength Doc
content
    spaces :: Doc
spaces      = [Char] -> Doc
text ([Char] -> Doc) -> [Char] -> Doc
forall a b. (a -> b) -> a -> b
$ Int -> Char -> [Char]
forall a. Int -> a -> [a]
replicate Int
numOfSpaces Char
' '

-----------------------------------------------------------------
-------------------- DEFINITION PRINTING ------------------------
-----------------------------------------------------------------

-- | Renders definition tables (Data, General, Theory, etc.)
makeDefn :: RefMap -> [(String,[LayoutObj])] -> Doc -> Doc
makeDefn :: RefMap -> [([Char], [LayoutObj])] -> Doc -> Doc
makeDefn RefMap
_  [] Doc
_ = [Char] -> Doc
forall a. HasCallStack => [Char] -> a
error [Char]
"L.Empty definition"
makeDefn RefMap
rm [([Char], [LayoutObj])]
slos Doc
l =
  RefMap -> [([Char], [LayoutObj])] -> Doc -> Doc
makeDHeaderText RefMap
rm [([Char], [LayoutObj])]
slos Doc
l Doc -> Doc -> Doc
$^$
  [Doc] -> [Int] -> Doc
makeHeaderCols [[Char] -> Doc
text [Char]
"Refname", Doc
l] [Int]
size Doc -> Doc -> Doc
$$
  [[Doc]] -> [Int] -> Doc
makeRows [[Doc]]
docDefn [Int]
size
  where
    docDefn :: [[Doc]]
docDefn = RefMap -> [([Char], [LayoutObj])] -> [[Doc]]
mkDocDefn RefMap
rm [([Char], [LayoutObj])]
slos
    size :: [Int]
size = [[Doc]] -> [Int]
columnSize [[Doc]]
docDefn

-- | Helper for convering definition to Doc matrix
mkDocDefn :: RefMap -> [(String,[LayoutObj])] -> [[Doc]]
mkDocDefn :: RefMap -> [([Char], [LayoutObj])] -> [[Doc]]
mkDocDefn RefMap
rm = (([Char], [LayoutObj]) -> [Doc])
-> [([Char], [LayoutObj])] -> [[Doc]]
forall a b. (a -> b) -> [a] -> [b]
map (\([Char]
f, [LayoutObj]
d) -> [[Char] -> Doc
text [Char]
f, RefMap -> ([Char], [LayoutObj]) -> Doc
makeLO RefMap
rm ([Char]
f,[LayoutObj]
d)])

-- | Renders the title/header of the definition table
makeDHeaderText :: RefMap -> [(String, [LayoutObj])] -> Doc -> Doc
makeDHeaderText :: RefMap -> [([Char], [LayoutObj])] -> Doc -> Doc
makeDHeaderText RefMap
rm [([Char], [LayoutObj])]
slos Doc
l = Doc -> Doc
centeredDiv Doc
header
  where
    lo :: Maybe [LayoutObj]
lo = [Char] -> [([Char], [LayoutObj])] -> Maybe [LayoutObj]
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup [Char]
"Label" [([Char], [LayoutObj])]
slos
    c :: Doc
c = Doc -> ([LayoutObj] -> Doc) -> Maybe [LayoutObj] -> Doc
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc
l (\[LayoutObj]
lo' -> RefMap -> ([Char], [LayoutObj]) -> Doc
makeLO RefMap
rm ([Char]
"Label", [LayoutObj]
lo')) Maybe [LayoutObj]
lo
    header :: Doc
header = Int -> Doc
h' Int
2 Doc -> Doc -> Doc
<+> Doc -> Doc -> Doc
heading Doc
c Doc
l

-- | Converts the [LayoutObj] to a Doc
makeLO :: RefMap -> (String, [LayoutObj]) -> Doc
makeLO :: RefMap -> ([Char], [LayoutObj]) -> Doc
makeLO RefMap
rm ([Char]
f,[LayoutObj]
d) =
      if [Char]
f[Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
==[Char]
"Notes" then Doc -> Doc
ul ([Doc] -> Doc
hcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ (LayoutObj -> Doc) -> [LayoutObj] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (RefMap -> [Char] -> LayoutObj -> Doc
processDefnLO RefMap
rm [Char]
f) [LayoutObj]
d)
      else [Doc] -> Doc
hcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ (LayoutObj -> Doc) -> [LayoutObj] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (RefMap -> [Char] -> LayoutObj -> Doc
processDefnLO RefMap
rm [Char]
f) [LayoutObj]
d

-- | Processes the LayoutObjs in the defn
processDefnLO :: RefMap -> String -> LayoutObj -> Doc
processDefnLO :: RefMap -> [Char] -> LayoutObj -> Doc
processDefnLO RefMap
rm [Char]
"Notes" (Paragraph Title
con) = Doc -> Doc
li (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ RefMap -> Title -> Doc
pSpec RefMap
rm Title
con
processDefnLO RefMap
rm [Char]
_       LayoutObj
lo              = RefMap -> LayoutObj -> Doc
printLO RefMap
rm LayoutObj
lo

-----------------------------------------------------------------
----------------------- LIST PRINTING ---------------------------
-----------------------------------------------------------------

-- | Renders lists into Markdown
makeList :: RefMap -> ListType -> Int -> Doc
makeList :: RefMap -> ListType -> Int -> Doc
makeList RefMap
rm (Simple      [(Title, ItemType, Maybe Title)]
items) Int
_  = [Doc] -> Doc
vsep ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ ((Title, ItemType, Maybe Title) -> Doc)
-> [(Title, ItemType, Maybe Title)] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (RefMap -> (Title, ItemType, Maybe Title) -> Doc
sItem RefMap
rm) [(Title, ItemType, Maybe Title)]
items
makeList RefMap
rm (Desc        [(Title, ItemType, Maybe Title)]
items) Int
_  = [Doc] -> Doc
vsep ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ ((Title, ItemType, Maybe Title) -> Doc)
-> [(Title, ItemType, Maybe Title)] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (RefMap -> (Title, ItemType, Maybe Title) -> Doc
descItem RefMap
rm) [(Title, ItemType, Maybe Title)]
items
makeList RefMap
rm (Ordered     [(ItemType, Maybe Title)]
items) Int
bl = [Doc] -> Doc
vcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$
  ((ItemType, Maybe Title) -> Int -> Doc)
-> [(ItemType, Maybe Title)] -> [Int] -> [Doc]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\(ItemType
i,Maybe Title
_) Int
n -> RefMap -> ItemType -> Int -> Int -> Doc
oItem RefMap
rm ItemType
i Int
bl Int
n) [(ItemType, Maybe Title)]
items [Int
1..]
makeList RefMap
rm (Unordered   [(ItemType, Maybe Title)]
items) Int
bl = [Doc] -> Doc
vcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$
  ((ItemType, Maybe Title) -> Doc)
-> [(ItemType, Maybe Title)] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (\(ItemType
i,Maybe Title
_) -> RefMap -> ItemType -> Int -> Doc
uItem RefMap
rm ItemType
i Int
bl) [(ItemType, Maybe Title)]
items
makeList RefMap
rm (Definitions [(Title, ItemType, Maybe Title)]
items) Int
_  = Doc -> Doc
ul (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ [Doc] -> Doc
hcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$
  ((Title, ItemType, Maybe Title) -> Doc)
-> [(Title, ItemType, Maybe Title)] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (\(Title
b,ItemType
e,Maybe Title
_) -> Doc -> Doc
li (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ RefMap -> Title -> Doc
pSpec RefMap
rm Title
b Doc -> Doc -> Doc
<> [Char] -> Doc
text [Char]
" is the" Doc -> Doc -> Doc
<+> RefMap -> ItemType -> Doc
item RefMap
rm ItemType
e) [(Title, ItemType, Maybe Title)]
items

-- | Helper for setting up reference anchors
mlref :: RefMap -> Maybe Label -> Doc -> Doc
mlref :: RefMap -> Maybe Title -> Doc -> Doc
mlref RefMap
_ Maybe Title
Nothing = (Doc
empty Doc -> Doc -> Doc
$$)
mlref RefMap
rm (Just Title
l) = (Doc -> Doc
divTag (RefMap -> Title -> Doc
pSpec RefMap
rm Title
l) Doc -> Doc -> Doc
$^$)

-- | Helper for rendering unordered list items
uItem :: RefMap -> ItemType -> Int -> Doc
uItem :: RefMap -> ItemType -> Int -> Doc
uItem RefMap
rm (Flat   Title
s)   Int
i = [Char] -> Doc
text (Int -> Char -> [Char]
forall a. Int -> a -> [a]
replicate Int
i Char
' ')
  Doc -> Doc -> Doc
<> Doc
hyph Doc -> Doc -> Doc
<+> RefMap -> Title -> Doc
pSpec RefMap
rm Title
s
uItem RefMap
rm (Nested Title
s ListType
l) Int
i = [Doc] -> Doc
vcat [
  [Char] -> Doc
text (Int -> Char -> [Char]
forall a. Int -> a -> [a]
replicate Int
i Char
' ') Doc -> Doc -> Doc
<> Doc
hyph Doc -> Doc -> Doc
<+> RefMap -> Title -> Doc
pSpec RefMap
rm Title
s,
  RefMap -> ListType -> Int -> Doc
makeList RefMap
rm ListType
l (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
2)
  ]

-- | Helper for rendering ordered list items
oItem :: RefMap -> ItemType -> Int -> Int -> Doc
oItem :: RefMap -> ItemType -> Int -> Int -> Doc
oItem RefMap
rm (Flat   Title
s)   Int
i Int
n = [Char] -> Doc
text (Int -> Char -> [Char]
forall a. Int -> a -> [a]
replicate Int
i Char
' ')
  Doc -> Doc -> Doc
<> Doc -> Doc
dot ([Char] -> Doc
text ([Char] -> Doc) -> [Char] -> Doc
forall a b. (a -> b) -> a -> b
$ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
n) Doc -> Doc -> Doc
<+> RefMap -> Title -> Doc
pSpec RefMap
rm Title
s
oItem RefMap
rm (Nested Title
s ListType
l) Int
i Int
n = [Doc] -> Doc
vcat [
  [Char] -> Doc
text (Int -> Char -> [Char]
forall a. Int -> a -> [a]
replicate Int
i Char
' ') Doc -> Doc -> Doc
<> Doc -> Doc
dot ([Char] -> Doc
text ([Char] -> Doc) -> [Char] -> Doc
forall a b. (a -> b) -> a -> b
$ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
n) Doc -> Doc -> Doc
<+> RefMap -> Title -> Doc
pSpec RefMap
rm Title
s,
  RefMap -> ListType -> Int -> Doc
makeList RefMap
rm ListType
l (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
3)
  ]

-- | Helper for Desc list items
descItem :: RefMap -> (Spec, ItemType, Maybe Label) -> Doc
descItem :: RefMap -> (Title, ItemType, Maybe Title) -> Doc
descItem RefMap
rm (Title
b,ItemType
e,Maybe Title
l) = RefMap -> Maybe Title -> Doc -> Doc
mlref RefMap
rm Maybe Title
l (Doc -> Doc
bold (RefMap -> Title -> Doc
pSpec RefMap
rm Title
b) Doc -> Doc -> Doc
<> [Char] -> Doc
text [Char]
":" Doc -> Doc -> Doc
<+> RefMap -> ItemType -> Doc
item RefMap
rm ItemType
e)

-- | Helper for Simple list items
sItem :: RefMap -> (Spec, ItemType, Maybe Label) -> Doc
sItem :: RefMap -> (Title, ItemType, Maybe Title) -> Doc
sItem RefMap
rm (Title
b,ItemType
e,Maybe Title
l) = RefMap -> Maybe Title -> Doc -> Doc
mlref RefMap
rm Maybe Title
l (RefMap -> Title -> Doc
pSpec RefMap
rm Title
b Doc -> Doc -> Doc
<> [Char] -> Doc
text [Char]
":" Doc -> Doc -> Doc
<+> RefMap -> ItemType -> Doc
item RefMap
rm ItemType
e)

-- | Helper for Markdown list items
item :: RefMap -> ItemType -> Doc
item :: RefMap -> ItemType -> Doc
item RefMap
rm (Flat   Title
s)   = RefMap -> Title -> Doc
pSpec RefMap
rm Title
s
item RefMap
rm (Nested Title
s ListType
l) = [Doc] -> Doc
vcat [RefMap -> Title -> Doc
pSpec RefMap
rm Title
s, RefMap -> ListType -> Int -> Doc
makeList RefMap
rm ListType
l Int
0]

-----------------------------------------------------------------
---------------------- FIGURE PRINTING --------------------------
-----------------------------------------------------------------

-- | Renders figures in Markdown
makeFigure :: Doc -> Maybe Doc -> Doc -> Doc
makeFigure :: Doc -> Maybe Doc -> Doc -> Doc
makeFigure Doc
r Maybe Doc
c Doc
f = Doc -> Doc -> Doc
centeredDivId Doc
r (Doc -> Maybe Doc -> Doc
image Doc
f Maybe Doc
c)

-----------------------------------------------------------------
------------------ Bibliography Printing ------------------------
-----------------------------------------------------------------

-- | Markdown specific bib rendering functions
mdBibFormatter :: RefMap -> BibFormatter
mdBibFormatter :: RefMap -> BibFormatter
mdBibFormatter RefMap
rm = BibFormatter {
  emph :: Doc -> Doc
emph = Doc -> Doc
em,
  spec :: Title -> Doc
spec = RefMap -> Title -> Doc
pSpec RefMap
rm
}

-- | Renders the reference list
makeRefList :: Doc -> Doc -> Doc -> Doc
makeRefList :: Doc -> Doc -> Doc -> Doc
makeRefList Doc
a Doc
l Doc
i = Doc -> Doc
divTag Doc
l Doc -> Doc -> Doc
$^$ (Doc
i Doc -> Doc -> Doc
<> [Char] -> Doc
text [Char]
": " Doc -> Doc -> Doc
<> Doc
a)

-- | Renders the bibliography
makeBib :: RefMap -> BibRef -> Doc
makeBib :: RefMap -> BibRef -> Doc
makeBib RefMap
rm = [Doc] -> Doc
vsep ([Doc] -> Doc) -> (BibRef -> [Doc]) -> BibRef -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  (Doc -> (Doc, Doc) -> Doc) -> [Doc] -> [(Doc, Doc)] -> [Doc]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (((Doc, (Doc, Doc)) -> Doc) -> Doc -> (Doc, Doc) -> Doc
forall a b c. ((a, b) -> c) -> a -> b -> c
curry (\(Doc
x,(Doc
y,Doc
z)) -> Doc -> Doc -> Doc -> Doc
makeRefList Doc
z Doc
y Doc
x))
  [[Char] -> Doc
text ([Char] -> Doc) -> [Char] -> Doc
forall a b. (a -> b) -> a -> b
$ [Char] -> [Char]
sqbrac ([Char] -> [Char]) -> [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
x | Int
x <- [Int
1..] :: [Int]] ([(Doc, Doc)] -> [Doc])
-> (BibRef -> [(Doc, Doc)]) -> BibRef -> [Doc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Citation -> (Doc, Doc)) -> BibRef -> [(Doc, Doc)]
forall a b. (a -> b) -> [a] -> [b]
map (BibFormatter -> Citation -> (Doc, Doc)
HTML.renderCite (RefMap -> BibFormatter
mdBibFormatter RefMap
rm))