All Downloads are FREE. Search and download functionalities are using the official Maven repository.

spandoc.Encoders.scala Maven / Gradle / Ivy

The newest version!
package spandoc

import cats.data._
import cats.syntax.all._
import io.circe._
import io.circe.syntax._

trait Encoders extends EncoderHelpers {
  implicit def PandocEncoder: Encoder[Pandoc] =
    Encoder.instance[Pandoc](pandoc => (pandoc.meta, pandoc.blocks).asJson)

  implicit def MetaEncoder: Encoder[Meta] =
    Encoder.instance[Meta](meta => Json.obj("unMeta" -> meta.data.asJson))

  implicit def MetaValueEncoder: Encoder[MetaValue] =
    Encoder.instance[MetaValue] {
      case MetaMap(values)      => typedNode("MetaMap")(values)
      case MetaList(values)     => typedNode("MetaList")(values)
      case MetaBool(value)      => typedNode("MetaBool")(value)
      case MetaString(value)    => typedNode("MetaString")(value)
      case MetaInlines(inlines) => typedNode("MetaInlines")(inlines)
      case MetaBlocks(blocks)   => typedNode("MetaBlocks")(blocks)
    }

  implicit def BlockEncoder: Encoder[Block] =
    Encoder.instance[Block] {
      case Plain(inlines)               => typedNode("Plain")(inlines)
      case Para(inlines)                => typedNode("Para")(inlines)
      case CodeBlock(attr, text)        => typedNode("CodeBlock")((attr, text))
      case RawBlock(format, text)       => typedNode("RawBlock")((format, text))
      case BlockQuote(blocks)           => typedNode("BlockQuote")(blocks)
      case OrderedList(attr, items)     => typedNode("OrderedList")((attr, items))
      case BulletList(items)            => typedNode("BulletList")(items)
      case DefinitionList(items)        => typedNode("DefinitionList")(items)
      case Header(level, attr, inlines) => typedNode("Header")((level, attr, inlines))
      case HorizontalRule               => typedNode("HorizontalRule")(Json.arr())
      case Table(c, a, w, h, r)         => typedNode("Table")((c, a, w, h, r))
      case Div(attr, blocks)            => typedNode("Div")((attr, blocks))
      case Null                         => typedNode("Null")(Json.arr())
    }

  implicit def InlineEncoder: Encoder[Inline] =
    Encoder.instance[Inline] {
      case Str(text)                => typedNode("Str")(text)
      case Emph(inlines)            => typedNode("Emph")(inlines)
      case Strong(inlines)          => typedNode("Strong")(inlines)
      case Strikeout(inlines)       => typedNode("Strikeout")(inlines)
      case Superscript(inlines)     => typedNode("Superscript")(inlines)
      case Subscript(inlines)       => typedNode("Subscript")(inlines)
      case SmallCaps(inlines)       => typedNode("SmallCaps")(inlines)
      case Quoted(tpe, inlines)     => typedNode("Quoted")((tpe, inlines))
      case Cite(citations, inlines) => typedNode("Cite")((citations, inlines))
      case Code(attr, text)         => typedNode("Code")((attr, text))
      case Space                    => typedNode("Space")(Json.arr())
      case SoftBreak                => typedNode("SoftBreak")(Json.arr())
      case LineBreak                => typedNode("LineBreak")(Json.arr())
      case Math(tpe, text)          => typedNode("Math")((tpe, text))
      case RawInline(format, text)  => typedNode("RawInline")((format, text))
      case Link(inlines, target)    => typedNode("Link")((inlines, target))
      case Image(inlines, target)   => typedNode("Image")((inlines, target))
      case Note(blocks)             => typedNode("Note")(blocks)
      case Span(attr, inlines)      => typedNode("Span")((attr, inlines))
    }

  implicit def AlignmentEncoder: Encoder[Alignment] =
    stringNodeEncoder[Alignment]

  implicit def ListAttributesEncoder: Encoder[ListAttributes] =
    Encoder[(Int, ListNumberStyle, ListNumberDelim)].contramap(unlift(ListAttributes.unapply))

  implicit def ListItemEncoder: Encoder[ListItem] =
    Encoder[List[Block]].contramap(unlift(ListItem.unapply))

  implicit def ListNumberStyleEncoder: Encoder[ListNumberStyle] =
    stringNodeEncoder[ListNumberStyle]

  implicit def ListNumberDelimEncoder: Encoder[ListNumberDelim] =
    stringNodeEncoder[ListNumberDelim]

  implicit def DefinitionItemEncoder: Encoder[DefinitionItem] =
    Encoder[(List[Inline], List[Definition])].contramap(unlift(DefinitionItem.unapply))

  implicit def DefinitionEncoder: Encoder[Definition] =
    Encoder[List[Block]].contramap(unlift(Definition.unapply))

  implicit def AttrEncoder: Encoder[Attr] =
    Encoder[(String, List[String], List[(String, String)])].contramap(unlift(Attr.unapply))

  implicit def TableRowEncoder: Encoder[TableRow] =
    Encoder[List[TableCell]].contramap(unlift(TableRow.unapply))

  implicit def TableCellEncoder: Encoder[TableCell] =
    Encoder[List[Block]].contramap(unlift(TableCell.unapply))

  implicit def QuoteTypeEncoder: Encoder[QuoteType] =
    stringNodeEncoder[QuoteType]

  implicit def TargetEncoder: Encoder[Target] =
    Encoder[(String, String)].contramap(unlift(Target.unapply))

  implicit def MathTypeEncoder: Encoder[MathType] =
    stringNodeEncoder[MathType]

  implicit def CitationEncoder: Encoder[Citation] =
    Encoder[(String, List[Inline], List[Inline], CitationMode, Int, Int)].contramap(unlift(Citation.unapply))

  implicit def CitationModeEncoder: Encoder[CitationMode] =
    stringNodeEncoder[CitationMode]
}

trait EncoderHelpers {
  def typedNode[C: Encoder](t: String)(c: C): Json =
    Json.obj("t" -> Json.string(t), "c" -> c.asJson)

  def stringNodeEncoder[A]: Encoder[A] =
    Encoder.instance[A](value => Json.obj("t" -> Json.string(value.toString), "c" -> Json.arr()))

  def unlift[A, B](func: A => Option[B]): A => B =
    (a: A) => func(a).get
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy