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

scribe.output.format.ANSIOutputFormat.scala Maven / Gradle / Ivy

There is a newer version: 3.15.3
Show newest version
package scribe.output.format

import scribe.ANSI
import scribe.output._

import scala.language.implicitConversions

object ANSIOutputFormat extends OutputFormat {
  private var fg: Option[ANSI] = None
  private var bg: Option[ANSI] = None
  private var bold: Boolean = false
  private var italic: Boolean = false
  private var underline: Boolean = false
  private var strikethrough: Boolean = false

  override def begin(stream: String => Unit): Unit = {}

  override def end(stream: String => Unit): Unit = {
    stream(ANSI.ctrl.Reset)
  }

  def apply(output: LogOutput, stream: String => Unit): Unit = synchronized {
    def reset(stream: String => Unit): Unit = {
      stream(ANSI.ctrl.Reset)
      fg.map(_.ansi).foreach(stream)
      bg.map(_.ansi).foreach(stream)
      if (bold) stream(ANSI.fx.Bold.ansi)
      if (italic) stream(ANSI.fx.Italic.ansi)
      if (underline) stream(ANSI.fx.Underline.ansi)
      if (strikethrough) stream(ANSI.fx.Strikethrough.ansi)
    }

    output match {
      case o: TextOutput => stream(o.plainText)
      case o: CompositeOutput => o.entries.foreach(apply(_, stream))
      case o: ColoredOutput =>
        val color = color2fg(o.color)
        stream(color.ansi)
        val previous = fg
        fg = Some(color)
        try {
          apply(o.output, stream)
        } finally {
          fg = previous
          reset(stream)
        }
      case o: BackgroundColoredOutput =>
        val color = color2bg(o.color)
        stream(color.ansi)
        val previous = bg
        bg = Some(color)
        try {
          apply(o.output, stream)
        } finally {
          bg = previous
          reset(stream)
        }
      case o: URLOutput =>
        stream("""]8;;""")
        stream(o.url)
        stream("""\""")
        if (o.output == EmptyOutput) {
          stream(o.url)
        } else {
          apply(o.output, stream)
        }
        stream("""]8;;\""")
      case o: BoldOutput =>
        val previous = bold
        bold = true
        try {
          stream(ANSI.fx.Bold.ansi)
          apply(o.output, stream)
        } finally {
          bold = previous
          reset(stream)
        }
      case o: ItalicOutput =>
        val previous = italic
        italic = true
        try {
          stream(ANSI.fx.Italic.ansi)
          apply(o.output, stream)
        } finally {
          italic = previous
          reset(stream)
        }
      case o: UnderlineOutput =>
        val previous = underline
        underline = true
        try {
          stream(ANSI.fx.Underline.ansi)
          apply(o.output, stream)
        } finally {
          underline = previous
          reset(stream)
        }
      case o: StrikethroughOutput =>
        val previous = strikethrough
        strikethrough = true
        try {
          stream(ANSI.fx.Strikethrough.ansi)
          apply(o.output, stream)
        } finally {
          strikethrough = previous
          reset(stream)
        }
      case EmptyOutput => // Nothing to do
    }
  }

  private def color2fg(color: Color): ANSI = color match {
    case Color.Black => ANSI.fg.Black
    case Color.Blue => ANSI.fg.Blue
    case Color.Cyan => ANSI.fg.Cyan
    case Color.Green => ANSI.fg.Green
    case Color.Magenta => ANSI.fg.Magenta
    case Color.Red => ANSI.fg.Red
    case Color.White => ANSI.fg.White
    case Color.Yellow => ANSI.fg.Yellow
    case Color.Gray => ANSI.fg.Gray
    case Color.BrightBlue => ANSI.fg.BrightBlue
    case Color.BrightCyan => ANSI.fg.BrightCyan
    case Color.BrightGreen => ANSI.fg.BrightGreen
    case Color.BrightMagenta => ANSI.fg.BrightMagenta
    case Color.BrightRed => ANSI.fg.BrightRed
    case Color.BrightWhite => ANSI.fg.BrightWhite
    case Color.BrightYellow => ANSI.fg.BrightYellow
  }

  private def color2bg(color: Color): ANSI = color match {
    case Color.Black => ANSI.bg.Black
    case Color.Blue => ANSI.bg.Blue
    case Color.Cyan => ANSI.bg.Cyan
    case Color.Green => ANSI.bg.Green
    case Color.Magenta => ANSI.bg.Magenta
    case Color.Red => ANSI.bg.Red
    case Color.White => ANSI.bg.White
    case Color.Yellow => ANSI.bg.Yellow
    case Color.Gray => ANSI.bg.Gray
    case Color.BrightBlue => ANSI.bg.BrightBlue
    case Color.BrightCyan => ANSI.bg.BrightCyan
    case Color.BrightGreen => ANSI.bg.BrightGreen
    case Color.BrightMagenta => ANSI.bg.BrightMagenta
    case Color.BrightRed => ANSI.bg.BrightRed
    case Color.BrightWhite => ANSI.bg.BrightWhite
    case Color.BrightYellow => ANSI.bg.BrightYellow
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy