packages feed

pandocz-0.0.1: src/Text/Pandoc/Z/Definition.hs

{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

module Text.Pandoc.Z.Definition where

import Control.Lens
    ( view,
      from,
      iso,
      prism',
      review,
      _Wrapped,
      At(..),
      Index,
      IxValue,
      Ixed(..),
      Each(..),
      AsEmpty(..),
      Plated(..),
      Iso',
      Lens',
      Prism',
      Rewrapped,
      Wrapped(..) )
import Data.Data(Data)
import Data.Typeable(Typeable)
import Data.Map(Map)
import qualified Data.Map as Map(map, union)
import Data.Text(Text)
import GHC.Generics(Generic)
import qualified Text.Pandoc.Definition as D
import Text.Pandoc.Walk(Walkable(walkM, query))
import Text.Pandoc.Z.Text ( HasText(..) )
import Prelude hiding (div, span)

data Pandoc =
  Pandoc
    Meta
    [Block]
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

class HasPandoc a where
  pandoc ::
    Lens' a Pandoc

instance HasPandoc Pandoc where
  pandoc =
    id

instance HasBlocks Pandoc where
  blocks f (Pandoc m b) =
    fmap (Pandoc m) (f b)

instance HasPandoc D.Pandoc where
  pandoc =
    from isPandoc

instance HasMeta Pandoc where
  meta f (Pandoc m b) =
    fmap (`Pandoc` b) (f m)

instance HasMeta D.Pandoc where
  meta =
    from isPandoc . meta

class AsPandoc a where
  _Pandoc ::
    Prism' a Pandoc

instance AsPandoc Pandoc where
  _Pandoc =
    id

instance AsPandoc D.Pandoc where
  _Pandoc =
    from isPandoc

isPandoc ::
  Iso'
    Pandoc
    D.Pandoc
isPandoc =
  iso
    (\(Pandoc m b) -> D.Pandoc (view isMeta m) (fmap (view isBlock) b))
    (\(D.Pandoc m b) -> Pandoc (review isMeta m) (fmap (review isBlock) b))

instance Walkable D.Pandoc Pandoc where
  walkM =
    isPandoc
  query f =
    f . view isPandoc

instance Semigroup Pandoc where
  Pandoc m1 b1 <> Pandoc m2 b2 =
    Pandoc (m1 <> m2) (b1 <> b2)

instance Monoid Pandoc where
  mempty =
    Pandoc mempty mempty

data Alignment =
  AlignLeft
  | AlignRight
  | AlignCenter
  | AlignDefault
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup Alignment where
  AlignLeft <> _ =
    AlignLeft
  AlignDefault <> y =
    y
  AlignRight <> _ =
    AlignRight
  AlignCenter <> _ =
    AlignCenter

instance Monoid Alignment where
  mempty =
    AlignDefault

class HasAlignment a where
  alignment ::
    Lens' a Alignment

instance HasAlignment Alignment where
  alignment =
    id

instance HasAlignment D.Alignment where
  alignment =
    from isAlignment

class AsAlignment a where
  _Alignment ::
    Prism' a Alignment
  _AlignLeft ::
    Prism' a ()
  _AlignLeft =
    _Alignment . _AlignLeft
  _AlignRight ::
    Prism' a ()
  _AlignRight =
    _Alignment . _AlignRight
  _AlignCenter ::
    Prism' a ()
  _AlignCenter =
    _Alignment . _AlignCenter
  _AlignDefault ::
    Prism' a ()
  _AlignDefault =
    _Alignment . _AlignDefault

instance AsAlignment Alignment where
  _Alignment =
    id
  _AlignLeft =
    prism'
      (\() -> AlignLeft)
      (\case
        AlignLeft -> Just ()
        _ -> Nothing
      )
  _AlignRight =
    prism'
      (\() -> AlignRight)
      (\case
        AlignRight -> Just ()
        _ -> Nothing
      )
  _AlignCenter =
    prism'
      (\() -> AlignCenter)
      (\case
        AlignCenter -> Just ()
        _ -> Nothing
      )
  _AlignDefault =
    prism'
      (\() -> AlignDefault)
      (\case
        AlignDefault -> Just ()
        _ -> Nothing
      )

instance AsAlignment D.Alignment where
  _Alignment =
    from isAlignment

isAlignment ::
  Iso'
    Alignment
    D.Alignment
isAlignment =
  iso
    (\case
      AlignLeft -> D.AlignLeft
      AlignRight -> D.AlignRight
      AlignCenter -> D.AlignCenter
      AlignDefault -> D.AlignDefault
    )
    (\case
      D.AlignLeft -> AlignLeft
      D.AlignRight -> AlignRight
      D.AlignCenter -> AlignCenter
      D.AlignDefault -> AlignDefault
    )

instance Walkable D.Alignment Alignment where
  walkM =
    isAlignment
  query f =
    f . view isAlignment

data Attr =
  Attr
    Text
    [Text]
    [(Text, Text)]
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup Attr where
  Attr s1 s2 s3 <> Attr t1 t2 t3 =
    Attr (s1 <> t1) (s2 <> t2) (s3 <> t3)

instance Monoid Attr where
  mempty =
    Attr mempty mempty mempty

class HasAttr a where
  attr ::
    Lens' a Attr
  identifier ::
    Lens' a Text
  identifier =
    attr . identifier
  classes ::
    Lens' a [Text]
  classes =
    attr . classes
  keyValuePairs ::
    Lens' a [(Text, Text)]
  keyValuePairs =
    attr . keyValuePairs

instance HasAttr Attr where
  attr =
    id
  identifier f (Attr i c kv) =
    fmap (\i' -> Attr i' c kv) (f i)
  classes f (Attr i c kv) =
    fmap (\c' -> Attr i c' kv) (f c)
  keyValuePairs f (Attr i c kv) =
    fmap (Attr i c) (f kv)

instance HasAttr D.Attr where
  attr =
    from isAttr

class AsAttr a where
  _Attr ::
    Prism' a Attr

instance AsAttr Attr where
  _Attr =
    id

instance AsAttr D.Attr where
  _Attr =
    from isAttr

isAttr ::
  Iso'
    Attr
    D.Attr
isAttr =
  iso
    (\(Attr i c kv) -> (i, c, kv))
    (\(i, c, kv) -> Attr i c kv)

instance Walkable D.Attr Attr where
  walkM =
    isAttr
  query f =
    f . view isAttr

data Caption =
  Caption
    (Maybe ShortCaption)
    [Block]
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup Caption where
  Caption sc1 b1 <> Caption sc2 b2 =
    Caption (sc1 <> sc2) (b1 <> b2)

instance Monoid Caption where
  mempty =
    Caption mempty mempty

class HasCaption a where
  caption ::
    Lens' a Caption
  maybeShortCaption ::
    Lens' a (Maybe ShortCaption)
  maybeShortCaption =
    caption . maybeShortCaption

instance HasCaption Caption where
  caption =
    id
  maybeShortCaption f (Caption s b) =
    fmap (`Caption` b) (f s)

instance HasBlocks Caption where
  blocks f (Caption s b) =
    fmap (Caption s) (f b)

instance HasCaption D.Caption where
  caption =
    from isCaption

class AsCaption a where
  _Caption ::
    Prism' a Caption

instance AsCaption Caption where
  _Caption =
    id

instance AsCaption D.Caption where
  _Caption =
    from isCaption

isCaption ::
  Iso'
    Caption
    D.Caption
isCaption =
  iso
    (\(Caption c b) -> D.Caption (fmap (view isShortCaption) c) (fmap (view isBlock) b))
    (\(D.Caption c b) -> Caption (fmap (review isShortCaption) c) (fmap (review isBlock) b))

instance Walkable D.Caption Caption where
  walkM =
    isCaption
  query f =
    f . view isCaption

data CitationMode =
  AuthorInText
  | SuppressAuthor
  | NormalCitation
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

class HasCitationMode a where
  citationMode ::
    Lens' a CitationMode

instance HasCitationMode CitationMode where
  citationMode =
    id

instance HasCitationMode D.CitationMode where
  citationMode =
    from isCitationMode

class AsCitationMode a where
  _CitationMode ::
    Prism' a CitationMode
  _AuthorInText ::
    Prism' a ()
  _AuthorInText =
    _CitationMode . _AuthorInText
  _SuppressAuthor ::
    Prism' a ()
  _SuppressAuthor =
    _CitationMode . _SuppressAuthor
  _NormalCitation ::
    Prism' a ()
  _NormalCitation =
    _CitationMode . _NormalCitation

instance AsCitationMode CitationMode where
  _CitationMode =
    id
  _AuthorInText =
    prism'
      (\() -> AuthorInText)
      (\case
        AuthorInText -> Just ()
        _ -> Nothing)
  _SuppressAuthor =
    prism'
      (\() -> SuppressAuthor)
      (\case
        SuppressAuthor -> Just ()
        _ -> Nothing)
  _NormalCitation =
    prism'
      (\() -> NormalCitation)
      (\case
        NormalCitation -> Just ()
        _ -> Nothing)

instance AsCitationMode D.CitationMode where
  _CitationMode =
    from isCitationMode

isCitationMode ::
  Iso'
    CitationMode
    D.CitationMode
isCitationMode =
  iso
    (\case
      AuthorInText -> D.AuthorInText
      SuppressAuthor -> D.SuppressAuthor
      NormalCitation -> D.NormalCitation
    )
    (\case
      D.AuthorInText -> AuthorInText
      D.SuppressAuthor -> SuppressAuthor
      D.NormalCitation -> NormalCitation
    )

instance Walkable D.CitationMode CitationMode where
  walkM =
    isCitationMode
  query f =
    f . view isCitationMode

data ColSpec =
  ColSpec
    Alignment
    ColWidth
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup ColSpec where
  ColSpec a1 w1 <> ColSpec a2 w2 =
    ColSpec (a1 <> a2) (w1 <> w2)

instance Monoid ColSpec where
  mempty =
    ColSpec mempty mempty

class HasColSpec a where
  colSpec ::
    Lens' a ColSpec

instance HasColSpec ColSpec where
  colSpec =
    id

instance HasAlignment ColSpec where
  alignment f (ColSpec a w) =
    fmap (`ColSpec` w) (f a)

instance HasColWidth ColSpec where
  colWidth f (ColSpec a w) =
    fmap (ColSpec a) (f w)

instance HasColSpec D.ColSpec where
  colSpec =
    from isColSpec

class AsColSpec a where
  _ColSpec ::
    Prism' a ColSpec

instance AsColSpec ColSpec where
  _ColSpec =
    id

instance AsColSpec D.ColSpec where
  _ColSpec =
    from isColSpec

isColSpec ::
  Iso'
    ColSpec
    D.ColSpec
isColSpec =
  iso
    (\(ColSpec a w) -> (view isAlignment a, view isColWidth w))
    (\(a, w) -> ColSpec (review isAlignment a) (review isColWidth w))

instance Walkable D.ColSpec ColSpec where
  walkM =
    isColSpec
  query f =
    f . view isColSpec

data ColWidth =
  ColWidth Double
  | ColWidthDefault
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup ColWidth where
  ColWidthDefault <> y =
    y
  ColWidth x <> _ =
    ColWidth x

instance Monoid ColWidth where
  mempty =
    ColWidthDefault

class HasColWidth a where
  colWidth ::
    Lens' a ColWidth

instance HasColWidth ColWidth where
  colWidth =
    id

instance HasColWidth D.ColWidth where
  colWidth =
    from isColWidth

class AsColWidth a where
  _ColWidth ::
    Prism' a ColWidth
  _ColWidth' ::
    Prism' a Double
  _ColWidth' =
    _ColWidth . _ColWidth'
  _ColWidthDefault ::
    Prism' a ()
  _ColWidthDefault =
    _ColWidth . _ColWidthDefault

instance AsColWidth ColWidth where
  _ColWidth =
    id

instance AsColWidth D.ColWidth where
  _ColWidth =
    from isColWidth

isColWidth ::
  Iso'
    ColWidth
    D.ColWidth
isColWidth =
  iso
    (\case
      ColWidth d -> D.ColWidth d
      ColWidthDefault -> D.ColWidthDefault
    )
    (\case
      D.ColWidth d -> ColWidth d
      D.ColWidthDefault -> ColWidthDefault
    )

instance Walkable D.ColWidth ColWidth where
  walkM =
    isColWidth
  query f =
    f . view isColWidth

newtype Format =
  Format D.Format
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance (Format ~ t) => Rewrapped Format t
instance Wrapped Format where
  type Unwrapped Format =
    D.Format
  _Wrapped' =
    iso (\(Format x) -> x) Format

class HasFormat a where
  format ::
    Lens' a Format

instance HasFormat Format where
  format =
    id

instance HasFormat D.Format where
  format =
    from isFormat

class AsFormat a where
  _Format ::
    Prism' a Format

instance AsFormat Format where
  _Format =
    id

instance AsFormat D.Format where
  _Format =
    from isFormat

isFormat ::
  Iso'
    Format
    D.Format
isFormat =
  iso
    (\(Format x) -> x)
    Format

instance Walkable D.Format Format where
  walkM =
    isFormat
  query f =
    f . view isFormat

data ListAttributes =
  ListAttributes
    Int
    ListNumberStyle
    ListNumberDelim
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup ListAttributes where
  ListAttributes n1 s1 d1 <> ListAttributes n2 s2 d2 =
    ListAttributes (n1 + n2) (s1 <> s2) (d1 <> d2)

instance Monoid ListAttributes where
  mempty =
    ListAttributes 0 mempty mempty

class HasListAttributes a where
  listAttributes ::
    Lens' a ListAttributes
  listAttributesStart ::
    Lens' a Int
  listAttributesStart =
    listAttributes . listAttributesStart

instance HasListAttributes ListAttributes where
  listAttributes =
    id
  listAttributesStart f (ListAttributes n s d) =
    fmap (\n' -> ListAttributes n' s d) (f n)

instance HasListNumberStyle ListAttributes where
  listNumberStyle f (ListAttributes n s d) =
    fmap (\s' -> ListAttributes n s' d) (f s)

instance HasListNumberDelim ListAttributes where
  listNumberDelim f (ListAttributes n s d) =
    fmap (ListAttributes n s) (f d)

instance HasListAttributes D.ListAttributes where
  listAttributes =
    from isListAttributes

class AsListAttributes a where
  _ListAttributes ::
    Prism' a ListAttributes

instance AsListAttributes ListAttributes where
  _ListAttributes =
    id

instance AsListAttributes D.ListAttributes where
  _ListAttributes =
    from isListAttributes

isListAttributes ::
  Iso'
    ListAttributes
    D.ListAttributes
isListAttributes =
  iso
    (\(ListAttributes n s d) -> (n, view isListNumberStyle s, view isListNumberDelim d))
    (\(n, s, d) -> ListAttributes n (review isListNumberStyle s) (review isListNumberDelim d))

instance Walkable D.ListAttributes ListAttributes where
  walkM =
    isListAttributes
  query f =
    f . view isListAttributes

data ListNumberDelim =
  DefaultDelim
  | Period
  | OneParen
  | TwoParens
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup ListNumberDelim where
  DefaultDelim <> y =
    y
  Period <> _ =
    Period
  OneParen <> _ =
    OneParen
  TwoParens <> _ =
    TwoParens

instance Monoid ListNumberDelim where
  mempty =
    DefaultDelim

class HasListNumberDelim a where
  listNumberDelim ::
    Lens' a ListNumberDelim

instance HasListNumberDelim ListNumberDelim where
  listNumberDelim =
    id

instance HasListNumberDelim D.ListNumberDelim where
  listNumberDelim =
    from isListNumberDelim

class AsListNumberDelim a where
  _ListNumberDelim ::
    Prism' a ListNumberDelim
  _DefaultDelim ::
    Prism' a ()
  _DefaultDelim =
    _ListNumberDelim . _DefaultDelim
  _Period ::
    Prism' a ()
  _Period =
    _ListNumberDelim . _Period
  _OneParen ::
    Prism' a ()
  _OneParen =
    _ListNumberDelim . _OneParen
  _TwoParens ::
    Prism' a ()
  _TwoParens =
    _ListNumberDelim . _TwoParens

instance AsListNumberDelim ListNumberDelim where
  _ListNumberDelim =
    id
  _DefaultDelim =
    prism'
      (\() -> DefaultDelim)
      (\case
        DefaultDelim -> Just ()
        _ -> Nothing)
  _Period =
    prism'
      (\() -> Period)
      (\case
        Period -> Just ()
        _ -> Nothing)
  _OneParen =
    prism'
      (\() -> OneParen)
      (\case
        OneParen -> Just ()
        _ -> Nothing)
  _TwoParens =
    prism'
      (\() -> TwoParens)
      (\case
        TwoParens -> Just ()
        _ -> Nothing)

instance AsListNumberDelim D.ListNumberDelim where
  _ListNumberDelim =
    from isListNumberDelim

isListNumberDelim ::
  Iso'
    ListNumberDelim
    D.ListNumberDelim
isListNumberDelim =
  iso
    (\case
      DefaultDelim -> D.DefaultDelim
      Period -> D.Period
      OneParen -> D.OneParen
      TwoParens -> D.TwoParens
    )
    (\case
      D.DefaultDelim -> DefaultDelim
      D.Period -> Period
      D.OneParen -> OneParen
      D.TwoParens -> TwoParens
    )

instance Walkable D.ListNumberDelim ListNumberDelim where
  walkM =
    isListNumberDelim
  query f =
    f . view isListNumberDelim

data ListNumberStyle =
  DefaultStyle
  | Example
  | Decimal
  | LowerRoman
  | UpperRoman
  | LowerAlpha
  | UpperAlpha
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup ListNumberStyle where
  DefaultStyle <> y =
    y
  Example <> _ =
    Example
  Decimal <> _ =
    Decimal
  LowerRoman <> _ =
    LowerRoman
  UpperRoman <> _ =
    UpperRoman
  LowerAlpha <> _ =
    LowerAlpha
  UpperAlpha <> _ =
    UpperAlpha

instance Monoid ListNumberStyle where
  mempty =
    DefaultStyle

class HasListNumberStyle a where
  listNumberStyle ::
    Lens' a ListNumberStyle

instance HasListNumberStyle ListNumberStyle where
  listNumberStyle =
    id

instance HasListNumberStyle D.ListNumberStyle where
  listNumberStyle =
    from isListNumberStyle

class AsListNumberStyle a where
  _ListNumberStyle ::
    Prism' a ListNumberStyle
  _DefaultStyle ::
    Prism' a ()
  _DefaultStyle =
    _ListNumberStyle . _DefaultStyle
  _Example ::
    Prism' a ()
  _Example =
    _ListNumberStyle . _Example
  _Decimal ::
    Prism' a ()
  _Decimal =
    _ListNumberStyle . _Decimal
  _LowerRoman ::
    Prism' a ()
  _LowerRoman =
    _ListNumberStyle . _LowerRoman
  _UpperRoman ::
    Prism' a ()
  _UpperRoman =
    _ListNumberStyle . _UpperRoman
  _LowerAlpha ::
    Prism' a ()
  _LowerAlpha =
    _ListNumberStyle . _LowerAlpha
  _UpperAlpha ::
    Prism' a ()
  _UpperAlpha =
    _ListNumberStyle . _UpperAlpha

instance AsListNumberStyle ListNumberStyle where
  _ListNumberStyle =
    id

instance AsListNumberStyle D.ListNumberStyle where
  _ListNumberStyle =
    from isListNumberStyle

isListNumberStyle ::
  Iso'
    ListNumberStyle
    D.ListNumberStyle
isListNumberStyle =
  iso
    (\case
      DefaultStyle -> D.DefaultStyle
      Example -> D.Example
      Decimal -> D.Decimal
      LowerRoman -> D.LowerRoman
      UpperRoman -> D.UpperRoman
      LowerAlpha -> D.LowerAlpha
      UpperAlpha -> D.UpperAlpha
    )
    (\case
      D.DefaultStyle -> DefaultStyle
      D.Example -> Example
      D.Decimal -> Decimal
      D.LowerRoman -> LowerRoman
      D.UpperRoman -> UpperRoman
      D.LowerAlpha -> LowerAlpha
      D.UpperAlpha -> UpperAlpha
    )

instance Walkable D.ListNumberStyle ListNumberStyle where
  walkM =
    isListNumberStyle
  query f =
    f . view isListNumberStyle

newtype RowSpan =
  RowSpan D.RowSpan
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic, Num)

instance Semigroup RowSpan where
  x <> y =
    x + y

instance Monoid RowSpan where
  mempty =
    0

instance (RowSpan ~ t) => Rewrapped RowSpan t
instance Wrapped RowSpan where
  type Unwrapped RowSpan =
    D.RowSpan
  _Wrapped' =
    iso (\(RowSpan x) -> x) RowSpan

class HasRowSpan a where
  rowSpan ::
    Lens' a RowSpan

instance HasRowSpan RowSpan where
  rowSpan =
    id

instance HasRowSpan D.RowSpan where
  rowSpan =
    from isRowSpan

class AsRowSpan a where
  _RowSpan ::
    Prism' a RowSpan

instance AsRowSpan RowSpan where
  _RowSpan =
    id

instance AsRowSpan D.RowSpan where
  _RowSpan =
    from isRowSpan

isRowSpan ::
  Iso'
    RowSpan
    D.RowSpan
isRowSpan =
  iso
    (\(RowSpan x) -> x)
    RowSpan

instance Walkable D.RowSpan RowSpan where
  walkM =
    isRowSpan
  query f =
    f . view isRowSpan

newtype ColSpan =
  ColSpan D.ColSpan
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic, Num)

instance Semigroup ColSpan where
  x <> y =
    x + y

instance Monoid ColSpan where
  mempty =
    0

instance (ColSpan ~ t) => Rewrapped ColSpan t
instance Wrapped ColSpan where
  type Unwrapped ColSpan =
    D.ColSpan
  _Wrapped' =
    iso (\(ColSpan x) -> x) ColSpan

class HasColSpan a where
  colSpan ::
    Lens' a ColSpan

instance HasColSpan ColSpan where
  colSpan =
    id

instance HasColSpan D.ColSpan where
  colSpan =
    from isColSpan

class AsColSpan a where
  _ColSpan ::
    Prism' a ColSpan

instance AsColSpan ColSpan where
  _ColSpan =
    id

instance AsColSpan D.ColSpan where
  _ColSpan =
    from isColSpan

isColSpan ::
  Iso'
    ColSpan
    D.ColSpan
isColSpan =
  iso
    (\(ColSpan x) -> x)
    ColSpan

instance Walkable D.ColSpan ColSpan where
  walkM =
    isColSpan
  query f =
    f . view isColSpan

data Cell =
  Cell
    Attr
    Alignment
    RowSpan
    ColSpan
    [Block]
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup Cell where
  Cell a1 l1 r1 c1 b1 <> Cell a2 l2 r2 c2 b2 =
    Cell (a1 <> a2) (l1 <> l2) (r1 <> r2) (c1 <> c2) (b1 <> b2)

instance Monoid Cell where
  mempty =
    Cell mempty mempty mempty mempty mempty

class HasCell a where
  cell ::
    Lens' a Cell

instance HasCell Cell where
  cell =
    id

instance HasBlocks Cell where
  blocks f (Cell a l r c b) =
    fmap (Cell a l r c) (f b)

instance HasAttr Cell where
  attr f (Cell a l r c b) =
    fmap (\a' -> Cell a' l r c b) (f a)

instance HasAlignment Cell where
  alignment f (Cell a l r c b) =
    fmap (\l' -> Cell a l' r c b) (f l)

instance HasRowSpan Cell where
  rowSpan f (Cell a l r c b) =
    fmap (\r' -> Cell a l r' c b) (f r)

instance HasColSpan Cell where
  colSpan f (Cell a l r c b) =
    fmap (\c' -> Cell a l r c' b) (f c)

instance HasCell D.Cell where
  cell =
    from isCell

class AsCell a where
  _Cell ::
    Prism' a Cell

instance AsCell Cell where
  _Cell =
    id

instance AsCell D.Cell where
  _Cell =
    from isCell

isCell ::
  Iso'
    Cell
    D.Cell
isCell =
  iso
    (\(Cell a l r c b) -> D.Cell (view isAttr a) (view isAlignment l) (view isRowSpan r) (view isColSpan c) (fmap (view isBlock) b))
    (\(D.Cell a l r c b) -> Cell (review isAttr a) (review isAlignment l) (review isRowSpan r) (review isColSpan c) (fmap (review isBlock) b))

instance Walkable D.Cell Cell where
  walkM =
    isCell
  query f =
    f . view isCell

data Row =
  Row
    Attr
    [Cell]
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup Row where
  Row a1 c1 <> Row a2 c2 =
    Row (a1 <> a2) (c1 <> c2)

instance Monoid Row where
  mempty =
    Row mempty mempty

class HasRow a where
  row ::
    Lens' a Row
  rowCells ::
    Lens' a [Cell]
  rowCells =
    row . rowCells

instance HasRow Row where
  row =
    id
  rowCells f (Row a c) =
    fmap (Row a) (f c)

instance HasAttr Row where
  attr f (Row a c) =
    fmap (`Row` c) (f a)

instance HasRow D.Row where
  row =
    from isRow

class AsRow a where
  _Row ::
    Prism' a Row

instance AsRow Row where
  _Row =
    id

instance AsRow D.Row where
  _Row =
    from isRow

isRow ::
  Iso'
    Row
    D.Row
isRow =
  iso
    (\(Row a c) -> D.Row (view isAttr a) (fmap (view isCell) c))
    (\(D.Row a c) -> Row (review isAttr a) (fmap (review isCell) c))

instance Walkable D.Row Row where
  walkM =
    isRow
  query f =
    f . view isRow

data TableHead =
  TableHead Attr [Row]
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup TableHead where
  TableHead a1 r1 <> TableHead a2 r2 =
    TableHead (a1 <> a2) (r1 <> r2)

instance Monoid TableHead where
  mempty =
    TableHead mempty mempty

class HasTableHead a where
  tableHead ::
    Lens' a TableHead
  tableHeadRows ::
    Lens' a [Row]
  tableHeadRows =
    tableHead . tableHeadRows

instance HasTableHead TableHead where
  tableHead =
    id
  tableHeadRows f (TableHead a r) =
    fmap (TableHead a) (f r)

instance HasAttr TableHead where
  attr f (TableHead a r) =
    fmap (`TableHead` r) (f a)

instance HasTableHead D.TableHead where
  tableHead =
    from isTableHead

class AsTableHead a where
  _TableHead ::
    Prism' a TableHead

instance AsTableHead TableHead where
  _TableHead =
    id

instance AsTableHead D.TableHead where
  _TableHead =
    from isTableHead

isTableHead ::
  Iso'
    TableHead
    D.TableHead
isTableHead =
  iso
    (\(TableHead a r) -> D.TableHead (view isAttr a) (fmap (view isRow) r))
    (\(D.TableHead a r) -> TableHead (review isAttr a) (fmap (review isRow) r))

instance Walkable D.TableHead TableHead where
  walkM =
    isTableHead
  query f =
    f . view isTableHead

newtype RowHeadColumns =
  RowHeadColumns D.RowHeadColumns
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic, Num)

instance Semigroup RowHeadColumns where
  x <> y =
    x + y

instance Monoid RowHeadColumns where
  mempty =
    0

instance (RowHeadColumns ~ t) => Rewrapped RowHeadColumns t
instance Wrapped RowHeadColumns where
  type Unwrapped RowHeadColumns =
    D.RowHeadColumns
  _Wrapped' =
    iso (\(RowHeadColumns x) -> x) RowHeadColumns

class HasRowHeadColumns a where
  rowHeadColumns ::
    Lens' a RowHeadColumns

instance HasRowHeadColumns RowHeadColumns where
  rowHeadColumns =
    id

instance HasRowHeadColumns D.RowHeadColumns where
  rowHeadColumns =
    from isRowHeadColumns

class AsRowHeadColumns a where
  _RowHeadColumns ::
    Prism' a RowHeadColumns

instance AsRowHeadColumns RowHeadColumns where
  _RowHeadColumns =
    id

instance AsRowHeadColumns D.RowHeadColumns where
  _RowHeadColumns =
    from isRowHeadColumns

isRowHeadColumns ::
  Iso'
    RowHeadColumns
    D.RowHeadColumns
isRowHeadColumns =
  iso
    (\(RowHeadColumns x) -> x)
    RowHeadColumns

instance Walkable D.RowHeadColumns RowHeadColumns where
  walkM =
    isRowHeadColumns
  query f =
    f . view isRowHeadColumns

data TableBody =
  TableBody
    Attr
    RowHeadColumns
    [Row]
    [Row]
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup TableBody where
  TableBody a1 c1 r1 s1 <> TableBody a2 c2 r2 s2 =
    TableBody (a1 <> a2) (c1 <> c2) (r1 <> r2) (s1 <> s2)

instance Monoid TableBody where
  mempty =
    TableBody mempty mempty mempty mempty

class HasTableBody a where
  tableBody ::
    Lens' a TableBody
  tableBodyRows1 ::
    Lens' a [Row]
  tableBodyRows1 =
    tableBody . tableBodyRows1
  tableBodyRows2 ::
    Lens' a [Row]
  tableBodyRows2 =
    tableBody . tableBodyRows2

instance HasTableBody TableBody where
  tableBody =
    id
  tableBodyRows1 f (TableBody a c r1 r2) =
    fmap (\r1' -> TableBody a c r1' r2) (f r1)
  tableBodyRows2 f (TableBody a c r1 r2) =
    fmap (TableBody a c r1) (f r2)

instance HasAttr TableBody where
  attr f (TableBody a c r1 r2) =
    fmap (\a' -> TableBody a' c r1 r2) (f a)

instance HasRowHeadColumns TableBody where
  rowHeadColumns f (TableBody a c r1 r2) =
    fmap (\c' -> TableBody a c' r1 r2) (f c)

instance HasTableBody D.TableBody where
  tableBody =
    from isTableBody

class AsTableBody a where
  _TableBody ::
    Prism' a TableBody

instance AsTableBody TableBody where
  _TableBody =
    id

instance AsTableBody D.TableBody where
  _TableBody =
    from isTableBody

isTableBody ::
  Iso'
    TableBody
    D.TableBody
isTableBody =
  iso
    (\(TableBody a c r1 r2) -> D.TableBody (view isAttr a) (view isRowHeadColumns c) (fmap (view isRow) r1) (fmap (view isRow) r2))
    (\(D.TableBody a c r1 r2) -> TableBody (review isAttr a) (review isRowHeadColumns c) (fmap (review isRow) r1) (fmap (review isRow) r2))

instance Walkable D.TableBody TableBody where
  walkM =
    isTableBody
  query f =
    f . view isTableBody

data TableFoot =
  TableFoot Attr [Row]
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup TableFoot where
  TableFoot a1 r1 <> TableFoot a2 r2 =
    TableFoot (a1 <> a2) (r1 <> r2)

instance Monoid TableFoot where
  mempty =
    TableFoot mempty mempty

class HasTableFoot a where
  tableFoot ::
    Lens' a TableFoot
  tableFootRows ::
    Lens' a [Row]
  tableFootRows =
    tableFoot . tableFootRows

instance HasTableFoot TableFoot where
  tableFoot =
    id
  tableFootRows f (TableFoot a r) =
    fmap (TableFoot a) (f r)

instance HasAttr TableFoot where
  attr f (TableFoot a r) =
    fmap (`TableFoot` r) (f a)

instance HasTableFoot D.TableFoot where
  tableFoot =
    from isTableFoot

class AsTableFoot a where
  _TableFoot ::
    Prism' a TableFoot

instance AsTableFoot TableFoot where
  _TableFoot =
    id

instance AsTableFoot D.TableFoot where
  _TableFoot =
    from isTableFoot

isTableFoot ::
  Iso'
    TableFoot
    D.TableFoot
isTableFoot =
  iso
    (\(TableFoot a r) -> D.TableFoot (view isAttr a) (fmap (view isRow) r))
    (\(D.TableFoot a r) -> TableFoot (review isAttr a) (fmap (review isRow) r))

instance Walkable D.TableFoot TableFoot where
  walkM =
    isTableFoot
  query f =
    f . view isTableFoot

data Definition =
  Definition
    [Inline]
    [[Block]]
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup Definition where
  Definition i1 b1 <> Definition i2 b2 =
    Definition (i1 <> i2) (b1 <> b2)

instance Monoid Definition where
  mempty =
    Definition mempty mempty

class HasDefinition a where
  definition ::
    Lens' a Definition
  definitionBlocks ::
    Lens' a [[Block]]
  definitionBlocks =
    definition . definitionBlocks

instance HasDefinition Definition where
  definition =
    id
  definitionBlocks f (Definition i b) =
    fmap (Definition i) (f b)

instance HasInlines Definition where
  inlines f (Definition i b) =
    fmap (`Definition` b) (f i)

class AsDefinition a where
  _Definition ::
    Prism' a Definition

instance AsDefinition Definition where
  _Definition =
    id

data Header =
  Header
    Int
    Attr
    [Inline]
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

class HasHeader a where
  header ::
    Lens' a Header
  headerLevel ::
    Lens' a Int
  headerLevel =
    header . headerLevel
  headerText ::
    Lens' a [Inline]
  headerText =
    header . headerText

instance HasHeader Header where
  header =
    id
  headerLevel f (Header l a i) =
    fmap (\l' -> Header l' a i) (f l)
  headerText f (Header l a i) =
    fmap (Header l a) (f i)

instance HasAttr Header where
  attr f (Header l a i) =
    fmap (\a' -> Header l a' i) (f a)

class AsHeader a where
  _Header ::
    Prism' a Header

instance AsHeader Header where
  _Header =
    id

instance AsHeader Block where
  _Header =
    prism'
      HeaderBlock
      (\case
        HeaderBlock x -> Just x
        _ -> Nothing)

instance AsHeader D.Block where
  _Header =
    from isBlock . _Header

data OrderedList =
  OrderedList
    ListAttributes
    [[Block]]
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup OrderedList where
  OrderedList a1 b1 <> OrderedList a2 b2 =
    OrderedList (a1 <> a2) (b1 <> b2)

instance Monoid OrderedList where
  mempty =
    OrderedList mempty mempty

class HasOrderedList a where
  orderedList ::
    Lens' a OrderedList
  orderedListBlocks ::
    Lens' a [[Block]]
  orderedListBlocks =
    orderedList . orderedListBlocks

instance HasOrderedList OrderedList where
  orderedList =
    id
  orderedListBlocks f (OrderedList a b) =
    fmap (OrderedList a) (f b)

instance HasListAttributes OrderedList where
  listAttributes f (OrderedList a b) =
    fmap (`OrderedList` b) (f a)

class AsOrderedList a where
  _OrderedList ::
    Prism' a OrderedList

instance AsOrderedList OrderedList where
  _OrderedList =
    id

instance AsOrderedList Block where
  _OrderedList =
    prism'
      OrderedListBlock
      (\case
        OrderedListBlock x -> Just x
        _ -> Nothing)

instance AsOrderedList D.Block where
  _OrderedList =
    from isBlock . _OrderedList

data Code =
  Code
    Attr
    Text
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup Code where
  Code a1 t1 <> Code a2 t2 =
    Code (a1 <> a2) (t1 <> t2)

instance Monoid Code where
  mempty =
    Code mempty mempty

class HasCode a where
  code ::
    Lens' a Code

instance HasCode Code where
  code =
    id

instance HasAttr Code where
  attr f (Code a t) =
    fmap (`Code` t) (f a)

instance HasText Code where
  text f (Code a t) =
    fmap (Code a) (f t)

class AsCode a where
  _Code ::
    Prism' a Code

instance AsCode Code where
  _Code =
    id

instance AsCode Block where
  _Code =
    prism'
      CodeBlock
      (\case
        CodeBlock x -> Just x
        _ -> Nothing)

instance AsCode D.Block where
  _Code =
    from isBlock . _Code

data Raw =
  Raw
    Format
    Text
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

class HasRaw a where
  raw ::
    Lens' a Raw

instance HasRaw Raw where
  raw =
    id

instance HasText Raw where
  text f (Raw r t) =
    fmap (Raw r) (f t)

class AsRaw a where
  _Raw ::
    Prism' a Raw

instance AsRaw Raw where
  _Raw =
    id

instance AsRaw Block where
  _Raw =
    prism'
      RawBlock
      (\case
        RawBlock i -> Just i
        _ -> Nothing)

instance AsRaw D.Block where
  _Raw =
    from isBlock . _Raw

data Table =
  Table
    Attr
    Caption
    [ColSpec]
    TableHead
    [TableBody]
    TableFoot
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup Table where
  Table a1 c1 s1 h1 b1 t1 <> Table a2 c2 s2 h2 b2 t2 =
    Table (a1 <> a2) (c1 <> c2) (s1 <> s2) (h1 <> h2) (b1 <> b2) (t1 <> t2)

instance Monoid Table where
  mempty =
    Table mempty mempty mempty mempty mempty mempty

class HasTable a where
  table ::
    Lens' a Table
  tableColSpecs ::
    Lens' a [ColSpec]
  tableColSpecs =
    table . tableColSpecs
  tableBodies ::
    Lens' a [TableBody]
  tableBodies =
    table . tableBodies

instance HasTable Table where
  table =
    id
  tableColSpecs f (Table a c s h b t) =
    fmap (\s' -> Table a c s' h b t) (f s)
  tableBodies f (Table a c s h b t) =
    fmap (\b' -> Table a c s h b' t) (f b)

instance HasAttr Table where
  attr f (Table a c s h b t) =
    fmap (\a' -> Table a' c s h b t) (f a)

instance HasCaption Table where
  caption f (Table a c s h b t) =
    fmap (\c' -> Table a c' s h b t) (f c)

instance HasTableHead Table where
  tableHead f (Table a c s h b t) =
    fmap (\h' -> Table a c s h' b t) (f h)

instance HasTableFoot Table where
  tableFoot f (Table a c s h b t) =
    fmap (Table a c s h b) (f t)

class AsTable a where
  _Table ::
    Prism' a Table

instance AsTable Table where
  _Table =
    id

instance AsTable Block where
  _Table =
    prism'
      TableBlock
      (\case
        TableBlock i -> Just i
        _ -> Nothing)

instance AsTable D.Block where
  _Table =
    from isBlock . _Table

data Figure =
  Figure
    Attr
    Caption
    [Block]
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup Figure where
  Figure a1 c1 b1 <> Figure a2 c2 b2 =
    Figure (a1 <> a2) (c1 <> c2) (b1 <> b2)

instance Monoid Figure where
  mempty =
    Figure mempty mempty mempty

class HasFigure a where
  figure ::
    Lens' a Figure

instance HasFigure Figure where
  figure =
    id

instance HasBlocks Figure where
  blocks f (Figure a c b) =
    fmap (Figure a c) (f b)

instance HasAttr Figure where
  attr f (Figure a c b) =
    fmap (\a' -> Figure a' c b) (f a)

instance HasCaption Figure where
  caption f (Figure a c b) =
    fmap (\c' -> Figure a c' b) (f c)

class AsFigure a where
  _Figure ::
    Prism' a Figure

instance AsFigure Figure where
  _Figure =
    id

instance AsFigure Block where
  _Figure =
    prism'
      FigureBlock
      (\case
        FigureBlock i -> Just i
        _ -> Nothing)

instance AsFigure D.Block where
  _Figure =
    from isBlock . _Figure

data Div =
  Div
    Attr
    [Block]
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup Div where
  Div a1 b1 <> Div a2 b2 =
    Div (a1 <> a2) (b1 <> b2)

instance Monoid Div where
  mempty =
    Div mempty mempty

class HasDiv a where
  div ::
    Lens' a Div

instance HasDiv Div where
  div =
    id


instance HasBlocks Div where
  blocks f (Div a b) =
    fmap (Div a) (f b)

class AsDiv a where
  _Div ::
    Prism' a Div

instance AsDiv Div where
  _Div =
    id

instance AsDiv Block where
  _Div =
    prism'
      DivBlock
      (\case
        DivBlock x -> Just x
        _ -> Nothing)

instance AsDiv D.Block where
  _Div =
    from isBlock . _Div

data Block =
  Plain [Inline]
  | Para [Inline]
  | LineBlock [[Inline]]
  | CodeBlock Code
  | RawBlock Raw
  | BlockQuote [Block]
  | OrderedListBlock OrderedList
  | BulletList [[Block]]
  | DefinitionList [Definition]
  | HeaderBlock Header
  | HorizontalRule
  | TableBlock Table
  | FigureBlock Figure
  | DivBlock Div
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

class HasBlock a where
  block ::
    Lens' a Block

instance HasBlock Block where
  block =
    id

instance HasBlock D.Block where
  block =
    from isBlock

class AsBlock a where
  _Block ::
    Prism' a Block
  _Plain ::
    Prism' a [Inline]
  _Plain =
    _Block . _Plain
  _Para ::
    Prism' a [Inline]
  _Para =
    _Block . _Para
  _LineBlock ::
    Prism' a [[Inline]]
  _LineBlock =
    _Block . _LineBlock
  _BlockQuote ::
    Prism' a [Block]
  _BlockQuote =
    _Block . _BlockQuote
  _BulletList ::
    Prism' a [[Block]]
  _BulletList =
    _Block . _BulletList
  _DefinitionList ::
    Prism' a [Definition]
  _DefinitionList =
    _Block . _DefinitionList
  _HorizontalRule ::
    Prism' a ()
  _HorizontalRule =
    _Block . _HorizontalRule

instance AsBlock Block where
  _Block =
    id
  _Plain =
    prism'
      Plain
      (\case
        Plain i -> Just i
        _ -> Nothing)
  _Para =
    prism'
      Para
      (\case
        Para i -> Just i
        _ -> Nothing)
  _LineBlock =
    prism'
      LineBlock
      (\case
        LineBlock i -> Just i
        _ -> Nothing)
  _BlockQuote =
    prism'
      BlockQuote
      (\case
        BlockQuote i -> Just i
        _ -> Nothing)
  _BulletList =
    prism'
      BulletList
      (\case
        BulletList i -> Just i
        _ -> Nothing)
  _DefinitionList =
    prism'
      DefinitionList
      (\case
        DefinitionList i -> Just i
        _ -> Nothing)
  _HorizontalRule =
    prism'
      (\() -> HorizontalRule)
      (\case
        HorizontalRule -> Just ()
        _ -> Nothing)

instance AsBlock D.Block where
  _Block =
    from isBlock

instance Plated Block where
  plate _ (Plain i) =
    pure (Plain i)
  plate _ (Para i) =
    pure (Para i)
  plate _ (LineBlock i) =
    pure (LineBlock i)
  plate _ (CodeBlock x) =
    pure (CodeBlock x)
  plate _ (RawBlock x) =
    pure (RawBlock x)
  plate f (BlockQuote b) =
    BlockQuote <$> traverse f b
  plate f (OrderedListBlock x) =
    OrderedListBlock . OrderedList (view listAttributes x) <$> traverse (traverse f) (view orderedListBlocks x)
  plate f (BulletList b) =
    BulletList <$> traverse (traverse f) b
  plate f (DefinitionList x) =
    DefinitionList <$> traverse (\(Definition i b) -> Definition i <$> traverse (traverse f) b) x
  plate _ (HeaderBlock x) =
    pure (HeaderBlock x)
  plate _ HorizontalRule =
    pure HorizontalRule
  plate _ (TableBlock x) =
    pure (TableBlock x)
  plate f (FigureBlock (Figure a c b)) =
    FigureBlock . Figure a c <$> traverse f b
  plate f (DivBlock (Div a b)) =
    DivBlock . Div a <$> traverse f b

isBlock ::
  Iso'
    Block
    D.Block
isBlock =
  iso
    (\case
      Plain i -> D.Plain (fmap (view isInline) i)
      Para i -> D.Para (fmap (view isInline) i)
      LineBlock i -> D.LineBlock (fmap (fmap (view isInline)) i)
      CodeBlock (Code a t) -> D.CodeBlock (view isAttr a) t
      RawBlock (Raw f t) -> D.RawBlock (view isFormat f) t
      BlockQuote b -> D.BlockQuote (fmap (view isBlock) b)
      OrderedListBlock (OrderedList a b) -> D.OrderedList (view isListAttributes a) (fmap (fmap (view isBlock)) b)
      BulletList b -> D.BulletList (fmap (fmap (view isBlock)) b)
      DefinitionList x -> D.DefinitionList (fmap (\(Definition i b) -> (fmap (view isInline) i, fmap (fmap (view isBlock)) b)) x)
      HeaderBlock h -> D.Header (view headerLevel h) (view (attr . isAttr) h) (fmap (view isInline) (view headerText h))
      HorizontalRule -> D.HorizontalRule
      TableBlock (Table a c s h b f) -> D.Table (view isAttr a) (view isCaption c) (fmap (view isColSpec) s) (view isTableHead h) (fmap (view isTableBody) b) (view isTableFoot f)
      FigureBlock (Figure a c b) -> D.Figure (view isAttr a) (view isCaption c) (fmap (view isBlock) b)
      DivBlock (Div a b) -> D.Div (view isAttr a) (fmap (view isBlock) b)
    )
    (\case
      D.Plain i -> Plain (fmap (review isInline) i)
      D.Para i -> Para (fmap (review isInline) i)
      D.LineBlock i -> LineBlock (fmap (fmap (review isInline)) i)
      D.CodeBlock a t -> CodeBlock (Code (review isAttr a) t)
      D.RawBlock f t -> RawBlock (Raw (review isFormat f) t)
      D.BlockQuote b -> BlockQuote (fmap (review isBlock) b)
      D.OrderedList a b -> OrderedListBlock (OrderedList (review isListAttributes a) (fmap (fmap (review isBlock)) b))
      D.BulletList b -> BulletList (fmap (fmap (review isBlock)) b)
      D.DefinitionList x -> DefinitionList (fmap (\(i, b) -> Definition (fmap (review isInline) i) (fmap (fmap (review isBlock)) b)) x)
      D.Header n a i -> HeaderBlock (Header n (review isAttr a) (fmap (review isInline) i))
      D.HorizontalRule -> HorizontalRule
      D.Table a c s h b f -> TableBlock (Table (review isAttr a) (review isCaption c) (fmap (review isColSpec) s) (review isTableHead h) (fmap (review isTableBody) b) (review isTableFoot f))
      D.Figure a c b -> FigureBlock (Figure (review isAttr a) (review isCaption c) (fmap (review isBlock) b))
      D.Div a b -> DivBlock (Div (review isAttr a) (fmap (review isBlock) b))
    )

instance Walkable D.Block Block where
  walkM =
    isBlock
  query f =
    f . view isBlock

data MathType =
  DisplayMath
  | InlineMath
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

class HasMathType a where
  mathType ::
    Lens' a MathType

instance HasMathType MathType where
  mathType =
    id

instance HasMathType D.MathType where
  mathType =
    from isMathType

class AsMathType a where
  _MathType ::
    Prism' a MathType
  _DisplayMath ::
    Prism' a ()
  _DisplayMath =
    _MathType . _DisplayMath
  _InlineMath ::
    Prism' a ()
  _InlineMath =
    _MathType . _InlineMath

instance AsMathType MathType where
  _MathType =
    id
  _DisplayMath =
    prism'
      (\() -> DisplayMath)
      (\case
        DisplayMath -> Just ()
        _ -> Nothing)
  _InlineMath =
    prism'
      (\() -> InlineMath)
      (\case
        InlineMath -> Just ()
        _ -> Nothing)

instance AsMathType D.MathType where
  _MathType =
    from isMathType

isMathType ::
  Iso'
    MathType
    D.MathType
isMathType =
  iso
    (\case
      DisplayMath -> D.DisplayMath
      InlineMath -> D.InlineMath
    )
    (\case
      D.DisplayMath -> DisplayMath
      D.InlineMath -> InlineMath
    )

instance Walkable D.MathType MathType where
  walkM =
    isMathType
  query f =
    f . view isMathType

newtype Meta =
  Meta (Map Text MetaValue)
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance (Meta ~ t) => Rewrapped Meta t
instance Wrapped Meta where
  type Unwrapped Meta =
    (Map Text MetaValue)
  _Wrapped' =
    iso (\(Meta x) -> x) Meta

type instance Index Meta = Text
type instance IxValue Meta = MetaValue
instance Ixed Meta where
  ix i =
    _Wrapped . ix i

instance At Meta where
  at k =
    _Wrapped . at k

instance Each Meta Meta MetaValue MetaValue where
  each =
    _Wrapped . each

instance AsEmpty Meta where
  _Empty =
    _Wrapped . _Empty

class HasMeta a where
  meta ::
    Lens' a Meta

instance HasMeta Meta where
  meta =
    id

instance HasMeta D.Meta where
  meta =
    from isMeta

class AsMeta a where
  _Meta ::
    Prism' a Meta

instance AsMeta Meta where
  _Meta =
    id

instance AsMeta D.Meta where
  _Meta =
    from isMeta

isMeta ::
  Iso'
    Meta
    D.Meta
isMeta =
  iso
    (\(Meta x) -> D.Meta (Map.map (view isMetaValue) x))
    (\(D.Meta x) -> Meta (Map.map (review isMetaValue) x))

instance Walkable D.Meta Meta where
  walkM =
    isMeta
  query f =
    f . view isMeta

instance Semigroup Meta where
  Meta x <> Meta y =
    Meta (Map.union y x)

instance Monoid Meta where
  mempty =
    Meta mempty

data MetaValue =
  MetaMap (Map Text MetaValue)
  | MetaList [MetaValue]
  | MetaBool Bool
  | MetaString Text
  | MetaInlines [Inline]
  | MetaBlocks [Block]
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Plated MetaValue where
  plate f (MetaMap m) =
    MetaMap <$> traverse f m
  plate f (MetaList x) =
    MetaList <$> traverse f x
  plate _ (MetaBool x) =
    pure (MetaBool x)
  plate _ (MetaString x) =
    pure (MetaString x)
  plate _ (MetaInlines x) =
    pure (MetaInlines x)
  plate _ (MetaBlocks x) =
    pure (MetaBlocks x)

class HasMetaValue a where
  metaValue ::
    Lens' a MetaValue

instance HasMetaValue MetaValue where
  metaValue =
    id

instance HasMetaValue D.MetaValue where
  metaValue =
    from isMetaValue

class AsMetaValue a where
  _MetaValue ::
    Prism' a MetaValue
  _MetaMap ::
    Prism' a (Map Text MetaValue)
  _MetaMap =
    _MetaValue . _MetaMap
  _MetaList ::
    Prism' a [MetaValue]
  _MetaList =
    _MetaValue . _MetaList
  _MetaBool ::
    Prism' a Bool
  _MetaBool =
    _MetaValue . _MetaBool
  _MetaString ::
    Prism' a Text
  _MetaString =
    _MetaValue . _MetaString

instance AsMetaValue MetaValue where
  _MetaValue =
    id
  _MetaMap =
    prism'
      MetaMap
      (\case
        MetaMap m -> Just m
        _ -> Nothing)
  _MetaList =
    prism'
      MetaList
      (\case
        MetaList m -> Just m
        _ -> Nothing)
  _MetaBool =
    prism'
      MetaBool
      (\case
        MetaBool m -> Just m
        _ -> Nothing)
  _MetaString =
    prism'
      MetaString
      (\case
        MetaString m -> Just m
        _ -> Nothing)

instance AsInlines MetaValue where
  _Inlines =
    prism'
      MetaInlines
      (\case
        MetaInlines m -> Just m
        _ -> Nothing)

instance AsBlocks MetaValue where
  _Blocks =
    prism'
      MetaBlocks
      (\case
        MetaBlocks m -> Just m
        _ -> Nothing)

instance AsMetaValue D.MetaValue where
  _MetaValue =
    from isMetaValue

isMetaValue ::
  Iso'
    MetaValue
    D.MetaValue
isMetaValue =
  iso
    (\case
      MetaMap m -> D.MetaMap (Map.map (view isMetaValue) m)
      MetaList m -> D.MetaList (fmap (view isMetaValue) m)
      MetaBool b -> D.MetaBool b
      MetaString s -> D.MetaString s
      MetaInlines i -> D.MetaInlines (fmap (view isInline) i)
      MetaBlocks b -> D.MetaBlocks (fmap (view isBlock) b)
    )
    (\case
      D.MetaMap m -> MetaMap (Map.map (review isMetaValue) m)
      D.MetaList m -> MetaList (fmap (review isMetaValue) m)
      D.MetaBool b -> MetaBool b
      D.MetaString s -> MetaString s
      D.MetaInlines i -> MetaInlines (fmap (review isInline) i)
      D.MetaBlocks b -> MetaBlocks (fmap (review isBlock) b)
    )

instance Walkable D.MetaValue MetaValue where
  walkM =
    isMetaValue
  query f =
    f . view isMetaValue

data QuoteType =
  SingleQuote
  | DoubleQuote
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

class HasQuoteType a where
  quoteType ::
    Lens' a QuoteType

instance HasQuoteType QuoteType where
  quoteType =
    id

instance HasQuoteType D.QuoteType where
  quoteType =
    from isQuoteType

class AsQuoteType a where
  _QuoteType ::
    Prism' a QuoteType
  _SingleQuote ::
    Prism' a ()
  _SingleQuote =
    _QuoteType . _SingleQuote
  _DoubleQuote ::
    Prism' a ()
  _DoubleQuote =
    _QuoteType . _DoubleQuote

instance AsQuoteType QuoteType where
  _QuoteType =
    id
  _SingleQuote =
    prism'
      (\() -> SingleQuote)
      (\case
        SingleQuote -> Just ()
        _ -> Nothing)
  _DoubleQuote =
    prism'
      (\() -> DoubleQuote)
      (\case
        DoubleQuote -> Just ()
        _ -> Nothing)

instance AsQuoteType D.QuoteType where
  _QuoteType =
    from isQuoteType

isQuoteType ::
  Iso'
    QuoteType
    D.QuoteType
isQuoteType =
  iso
    (\case
      SingleQuote -> D.SingleQuote
      DoubleQuote -> D.DoubleQuote
    )
    (\case
      D.SingleQuote -> SingleQuote
      D.DoubleQuote -> DoubleQuote
    )

instance Walkable D.QuoteType QuoteType where
  walkM =
    isQuoteType
  query f =
    f . view isQuoteType

newtype ShortCaption =
  ShortCaption [Inline]
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup ShortCaption where
  ShortCaption x <> ShortCaption y =
    ShortCaption (x <> y)

instance Monoid ShortCaption where
  mempty =
    ShortCaption mempty

instance (ShortCaption ~ t) => Rewrapped ShortCaption t
instance Wrapped ShortCaption where
  type Unwrapped ShortCaption =
    [Inline]
  _Wrapped' =
    iso (\(ShortCaption x) -> x) ShortCaption

class HasShortCaption a where
  shortCaption ::
    Lens' a ShortCaption

instance HasShortCaption ShortCaption where
  shortCaption =
    id

instance HasShortCaption D.ShortCaption where
  shortCaption =
    from isShortCaption

class AsShortCaption a where
  _ShortCaption ::
    Prism' a ShortCaption

instance AsShortCaption ShortCaption where
  _ShortCaption =
    id

instance AsShortCaption D.ShortCaption where
  _ShortCaption =
    from isShortCaption

isShortCaption ::
  Iso'
    ShortCaption
    D.ShortCaption
isShortCaption =
  iso
    (\(ShortCaption x) -> fmap (view isInline) x)
    (\i -> ShortCaption (fmap (review isInline) i))

instance Walkable D.ShortCaption ShortCaption where
  walkM =
    isShortCaption
  query f =
    f . view isShortCaption

data Target =
  Target
    Text
    Text
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup Target where
  Target t1 t2 <> Target u1 u2 =
    Target (t1 <> u1) (t2 <> u2)

instance Monoid Target where
  mempty =
    Target mempty mempty

class HasTarget a where
  target ::
    Lens' a Target
  targetURL ::
    Lens' a Text
  targetURL =
    target . targetURL
  targetTitle ::
    Lens' a Text
  targetTitle =
    target . targetTitle

instance HasTarget Target where
  target =
    id
  targetURL f (Target u t) =
    fmap (`Target` t) (f u)
  targetTitle f (Target u t) =
    fmap (Target u) (f t)

instance HasTarget D.Target where
  target =
    from isTarget

class AsTarget a where
  _Target ::
    Prism' a Target

instance AsTarget Target where
  _Target =
    id

instance AsTarget D.Target where
  _Target =
    from isTarget

isTarget ::
  Iso'
    Target
    D.Target
isTarget =
  iso
    (\(Target t1 t2) -> (t1, t2))
    (\(t1, t2) -> Target t1 t2)

instance Walkable D.Target Target where
  walkM =
    isTarget
  query f =
    f . view isTarget

data Link =
  Link
    Attr
    [Inline]
    Target
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup Link where
  Link a1 c1 i1 <> Link a2 c2 i2 =
    Link (a1 <> a2) (c1 <> c2) (i1 <> i2)

instance Monoid Link where
  mempty =
    Link mempty mempty mempty

class HasLink a where
  link ::
    Lens' a Link

instance HasLink Link where
  link =
    id

instance HasInlines Link where
  inlines f (Link a i t) =
    fmap (\i' -> Link a i' t) (f i)

instance HasAttr Link where
  attr f (Link a i t) =
    fmap (\a' -> Link a' i t) (f a)

instance HasTarget Link where
  target f (Link a i t) =
    fmap (Link a i) (f t)

class AsLink a where
  _Link ::
    Prism' a Link

instance AsLink Link where
  _Link =
    id

instance AsLink Inline where
  _Link =
    prism'
      LinkInline
      (\case
        LinkInline x -> Just x
        _ -> Nothing)

instance AsLink D.Inline where
  _Link =
    from isInline . _Link

data Image =
  Image
    Attr
    [Inline]
    Target
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup Image where
  Image a1 c1 i1 <> Image a2 c2 i2 =
    Image (a1 <> a2) (c1 <> c2) (i1 <> i2)

instance Monoid Image where
  mempty =
    Image mempty mempty mempty

class HasImage a where
  image ::
    Lens' a Image

instance HasImage Image where
  image =
    id

instance HasInlines Image where
  inlines f (Image a i t) =
    fmap (\i' -> Image a i' t) (f i)

instance HasAttr Image where
  attr f (Image a i t) =
    fmap (\a' -> Image a' i t) (f a)

instance HasTarget Image where
  target f (Image a i t) =
    fmap (Image a i) (f t)

class AsImage a where
  _Image ::
    Prism' a Image

instance AsImage Image where
  _Image =
    id

instance AsImage Inline where
  _Image =
    prism'
      ImageInline
      (\case
        ImageInline x -> Just x
        _ -> Nothing)

instance AsImage D.Inline where
  _Image =
    from isInline . _Image

data Span =
  Span
    Attr
    [Inline]
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup Span where
  Span c1 i1 <> Span c2 i2 =
    Span (c1 <> c2) (i1 <> i2)

instance Monoid Span where
  mempty =
    Span mempty mempty

class HasSpan a where
  span ::
    Lens' a Span

instance HasSpan Span where
  span =
    id

instance HasSpan Link where
  span f (Link a i t) =
    fmap (\(Span a' i') -> Link a' i' t) (f (Span a i))

instance HasSpan Image where
  span f (Image a i t) =
    fmap (\(Span a' i') -> Image a' i' t) (f (Span a i))

instance HasInlines Span where
  inlines f (Span a i) =
    fmap (Span a) (f i)

instance HasAttr Span where
  attr f (Span a i) =
    fmap (`Span` i) (f a)

class AsSpan a where
  _Span ::
    Prism' a Span

instance AsSpan Span where
  _Span =
    id

instance AsSpan Inline where
  _Span =
    prism'
      SpanInline
      (\case
        SpanInline x -> Just x
        _ -> Nothing)

instance AsSpan D.Inline where
  _Span =
    from isInline . _Span

data Quoted =
  Quoted
    QuoteType
    [Inline]
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

class HasQuoted a where
  quoted ::
    Lens' a Quoted

instance HasQuoted Quoted where
  quoted =
    id

instance HasInlines Quoted where
  inlines f (Quoted a i) =
    fmap (Quoted a) (f i)

instance HasQuoteType Quoted where
  quoteType f (Quoted a i) =
    fmap (`Quoted` i) (f a)

class AsQuoted a where
  _Quoted ::
    Prism' a Quoted

instance AsQuoted Quoted where
  _Quoted =
    id

instance AsQuoted Inline where
  _Quoted =
    prism'
      QuotedInline
      (\case
        QuotedInline x -> Just x
        _ -> Nothing)

instance AsQuoted D.Inline where
  _Quoted =
    from isInline . _Quoted

data Cite =
  Cite
    [Citation]
    [Inline]
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

instance Semigroup Cite where
  Cite c1 i1 <> Cite c2 i2 =
    Cite (c1 <> c2) (i1 <> i2)

instance Monoid Cite where
  mempty =
    Cite mempty mempty

class HasCite a where
  cite ::
    Lens' a Cite
  citeCitations ::
    Lens' a [Citation]
  citeCitations =
    cite . citeCitations

instance HasCite Cite where
  cite =
    id
  citeCitations f (Cite a i) =
    fmap (`Cite` i) (f a)

instance HasInlines Cite where
  inlines f (Cite a i) =
    fmap (Cite a) (f i)

class AsCite a where
  _Cite ::
    Prism' a Cite

instance AsCite Cite where
  _Cite =
    id

instance AsCite Inline where
  _Cite =
    prism'
      CiteInline
      (\case
        CiteInline x -> Just x
        _ -> Nothing)

instance AsCite D.Inline where
  _Cite =
    from isInline . _Cite

data Math =
  Math
    MathType
    Text
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

class HasMath a where
  math ::
    Lens' a Math

instance HasMath Math where
  math =
    id

instance HasMathType Math where
  mathType f (Math a i) =
    fmap (`Math` i) (f a)

instance HasText Math where
  text f (Math a i) =
    fmap (Math a) (f i)

class AsMath a where
  _Math ::
    Prism' a Math

instance AsMath Math where
  _Math =
    id

instance AsMath Inline where
  _Math =
    prism'
      MathInline
      (\case
        MathInline x -> Just x
        _ -> Nothing)

instance AsMath D.Inline where
  _Math =
    from isInline . _Math

data Inline =
  Str Text
  | Emph [Inline]
  | Underline [Inline]
  | Strong [Inline]
  | Strikeout [Inline]
  | Superscript [Inline]
  | Subscript [Inline]
  | SmallCaps [Inline]
  | QuotedInline Quoted
  | CiteInline Cite
  | CodeInline Code
  | Space
  | SoftBreak
  | LineBreak
  | MathInline Math
  | RawInline Raw
  | LinkInline Link
  | ImageInline Image
  | Note [Block]
  | SpanInline Span
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

class HasInline a where
  inline ::
    Lens' a Inline

instance HasInline Inline where
  inline =
    id

instance HasInline D.Inline where
  inline =
    from isInline

class AsInline a where
  _Inline ::
    Prism' a Inline
  _Str ::
    Prism' a Text
  _Str =
    _Inline . _Str
  _Emph ::
    Prism' a [Inline]
  _Emph =
    _Inline . _Emph
  _Underline ::
    Prism' a [Inline]
  _Underline =
    _Inline . _Underline
  _Strong ::
    Prism' a [Inline]
  _Strong =
    _Inline . _Strong
  _Strikeout ::
    Prism' a [Inline]
  _Strikeout =
    _Inline . _Strikeout
  _Superscript ::
    Prism' a [Inline]
  _Superscript =
    _Inline . _Superscript
  _Subscript ::
    Prism' a [Inline]
  _Subscript =
    _Inline . _Subscript
  _SmallCaps ::
    Prism' a [Inline]
  _SmallCaps =
    _Inline . _SmallCaps
  _Space ::
    Prism' a ()
  _Space =
    _Inline . _Space
  _SoftBreak ::
    Prism' a ()
  _SoftBreak =
    _Inline . _SoftBreak
  _LineBreak ::
    Prism' a ()
  _LineBreak =
    _Inline . _LineBreak
  _Note ::
    Prism' a [Block]
  _Note =
    _Inline . _Note

instance AsInline Inline where
  _Inline =
    id
  _Str =
    prism'
      Str
      (\case
        Str x -> Just x
        _ -> Nothing)
  _Emph =
    prism'
      Emph
      (\case
        Emph x -> Just x
        _ -> Nothing)
  _Underline =
    prism'
      Underline
      (\case
        Underline x -> Just x
        _ -> Nothing)
  _Strong =
    prism'
      Strong
      (\case
        Strong x -> Just x
        _ -> Nothing)
  _Strikeout =
    prism'
      Strikeout
      (\case
        Strikeout x -> Just x
        _ -> Nothing)
  _Superscript =
    prism'
      Superscript
      (\case
        Superscript x -> Just x
        _ -> Nothing)
  _Subscript =
    prism'
      Subscript
      (\case
        Subscript x -> Just x
        _ -> Nothing)
  _SmallCaps =
    prism'
      SmallCaps
      (\case
        SmallCaps x -> Just x
        _ -> Nothing)
  _Space =
    prism'
      (\() -> Space)
      (\case
        Space -> Just ()
        _ -> Nothing)
  _SoftBreak =
    prism'
      (\() -> SoftBreak)
      (\case
        SoftBreak -> Just ()
        _ -> Nothing)
  _LineBreak =
    prism'
      (\() -> LineBreak)
      (\case
        LineBreak -> Just ()
        _ -> Nothing)
  _Note =
    prism'
      Note
      (\case
        Note x -> Just x
        _ -> Nothing)

instance AsInline D.Inline where
  _Inline =
    from isInline

instance AsCode Inline where
  _Code =
    prism'
      CodeInline
      (\case
        CodeInline x -> Just x
        _ -> Nothing)

instance AsCode D.Inline where
  _Code =
    from isInline . _Code

instance AsRaw Inline where
  _Raw =
    prism'
      RawInline
      (\case
        RawInline x -> Just x
        _ -> Nothing)

instance AsRaw D.Inline where
  _Raw =
    from isInline . _Raw

instance Plated Inline where
  plate _ (Str t) =
    pure (Str t)
  plate f (Emph i) =
    Emph <$> traverse f i
  plate f (Underline i) =
    Underline <$> traverse f i
  plate f (Strong i) =
    Strong <$> traverse f i
  plate f (Strikeout i) =
    Strikeout <$> traverse f i
  plate f (Superscript i) =
    Superscript <$> traverse f i
  plate f (Subscript i) =
    Subscript <$> traverse f i
  plate f (SmallCaps i) =
    SmallCaps <$> traverse f i
  plate f (QuotedInline (Quoted q i)) =
    QuotedInline . Quoted q <$> traverse f i
  plate f (CiteInline (Cite c i)) =
    CiteInline . Cite c <$> traverse f i
  plate _ (CodeInline x) =
    pure (CodeInline x)
  plate _ Space =
    pure Space
  plate _ SoftBreak =
    pure SoftBreak
  plate _ LineBreak =
    pure LineBreak
  plate _ (MathInline x) =
    pure (MathInline x)
  plate _ (RawInline x) =
    pure (RawInline x)
  plate f (LinkInline (Link a i t)) =
    (\i' -> LinkInline (Link a i' t)) <$> traverse f i
  plate f (ImageInline (Image a i t)) =
    (\i' -> ImageInline (Image a i' t)) <$> traverse f i
  plate _ (Note b) =
    pure (Note b)
  plate f (SpanInline (Span a i)) =
    SpanInline . Span a <$> traverse f i

isInline ::
  Iso'
    Inline
    D.Inline
isInline =
  iso
    (\case
      Str t -> D.Str t
      Emph i -> D.Emph (fmap (view isInline) i)
      Underline i -> D.Underline (fmap (view isInline) i)
      Strong i -> D.Strong (fmap (view isInline) i)
      Strikeout i -> D.Strikeout (fmap (view isInline) i)
      Superscript i -> D.Superscript (fmap (view isInline) i)
      Subscript i -> D.Subscript (fmap (view isInline) i)
      SmallCaps i -> D.SmallCaps (fmap (view isInline) i)
      QuotedInline (Quoted t i) -> D.Quoted (view isQuoteType t) (fmap (view isInline) i)
      CiteInline (Cite c i) -> D.Cite (fmap (view isCitation) c) (fmap (view isInline) i)
      CodeInline (Code a t) -> D.Code (view isAttr a) t
      Space -> D.Space
      SoftBreak -> D.SoftBreak
      LineBreak -> D.LineBreak
      MathInline (Math m t) -> D.Math (view isMathType m) t
      RawInline (Raw f t) -> D.RawInline (view isFormat f) t
      LinkInline (Link a i t) -> D.Link (view isAttr a) (fmap (view isInline) i) (view isTarget t)
      ImageInline (Image a i t) -> D.Image (view isAttr a) (fmap (view isInline) i) (view isTarget t)
      Note b -> D.Note (fmap (view isBlock) b)
      SpanInline (Span a i) -> D.Span (view isAttr a) (fmap (view isInline) i)
    )
    (\case
      D.Str t -> Str t
      D.Emph i -> Emph (fmap (review isInline) i)
      D.Underline i -> Underline (fmap (review isInline) i)
      D.Strong i -> Strong (fmap (review isInline) i)
      D.Strikeout i -> Strikeout (fmap (review isInline) i)
      D.Superscript i -> Superscript (fmap (review isInline) i)
      D.Subscript i -> Subscript (fmap (review isInline) i)
      D.SmallCaps i -> SmallCaps (fmap (review isInline) i)
      D.Quoted t i -> QuotedInline (Quoted (review isQuoteType t) (fmap (review isInline) i))
      D.Cite c i -> CiteInline (Cite (fmap (review isCitation) c) (fmap (review isInline) i))
      D.Code a t -> CodeInline (Code (review isAttr a) t)
      D.Space -> Space
      D.SoftBreak -> SoftBreak
      D.LineBreak -> LineBreak
      D.Math m t -> MathInline (Math (review isMathType m) t)
      D.RawInline f t -> RawInline (Raw (review isFormat f) t)
      D.Link a i t -> LinkInline (Link (review isAttr a) (fmap (review isInline) i) (review isTarget t))
      D.Image a i t -> ImageInline (Image (review isAttr a) (fmap (review isInline) i) (review isTarget t))
      D.Note b -> Note (fmap (review isBlock) b)
      D.Span a i -> SpanInline (Span (review isAttr a) (fmap (review isInline) i))
    )

instance Walkable D.Inline Inline where
  walkM =
    isInline
  query f =
    f . view isInline

data Citation =
  Citation
    Text
    [Inline]
    [Inline]
    CitationMode
    Int
    Int
  deriving (Eq, Ord, Show, Data, Typeable, Read, Generic)

class HasCitation a where
  citation ::
    Lens' a Citation
  citationId ::
    Lens' a Text
  citationId =
    citation . citationId
  citationPrefix ::
    Lens' a [Inline]
  citationPrefix =
    citation . citationPrefix
  citationSuffix ::
    Lens' a [Inline]
  citationSuffix =
    citation . citationSuffix
  citationNoteNum ::
    Lens' a Int
  citationNoteNum =
    citation . citationNoteNum
  citationHash ::
    Lens' a Int
  citationHash =
    citation . citationHash

instance HasCitation Citation where
  citation =
    id
  citationId f (Citation i p s m n h) =
    fmap (\i' -> Citation i' p s m n h) (f i)
  citationPrefix f (Citation i p s m n h) =
    fmap (\p' -> Citation i p' s m n h) (f p)
  citationSuffix f (Citation i p s m n h) =
    fmap (\s' -> Citation i p s' m n h) (f s)
  citationNoteNum f (Citation i p s m n h) =
    fmap (\n' -> Citation i p s m n' h) (f n)
  citationHash f (Citation i p s m n h) =
    fmap (Citation i p s m n) (f h)

instance HasCitationMode Citation where
  citationMode f (Citation i p s m n h) =
    fmap (\m' -> Citation i p s m' n h) (f m)

instance HasCitation D.Citation where
  citation =
    from isCitation

class AsCitation a where
  _Citation ::
    Prism' a Citation

instance AsCitation Citation where
  _Citation =
    id

instance AsCitation D.Citation where
  _Citation =
    from isCitation

isCitation ::
  Iso'
    Citation
    D.Citation
isCitation =
  iso
    (\(Citation i p s m n h) -> D.Citation i (fmap (view isInline) p) (fmap (view isInline) s) (view isCitationMode m) n h)
    (\(D.Citation i p s m n h) -> Citation i (fmap (review isInline) p) (fmap (review isInline) s) (review isCitationMode m) n h)

instance Walkable D.Citation Citation where
  walkM =
    isCitation
  query f =
    f . view isCitation

class HasBlocks a where
  blocks ::
    Lens' a [Block]

instance HasBlocks [Block] where
  blocks =
    id

class AsBlocks a where
  _Blocks ::
    Prism' a [Block]

instance AsBlocks [Block] where
  _Blocks =
    id

class HasInlines a where
  inlines ::
    Lens' a [Inline]

instance HasInlines [Inline] where
  inlines =
    id

class AsInlines a where
  _Inlines ::
    Prism' a [Inline]

instance AsInlines [Inline] where
  _Inlines =
    id