diff --git a/copret/src/Theme.scala b/copret/src/Theme.scala index e214be3..15cd932 100644 --- a/copret/src/Theme.scala +++ b/copret/src/Theme.scala @@ -12,37 +12,38 @@ case class Theme(styles: Map[String, fansi.Attrs], figletFonts: Map[String, Stri figletFonts.getOrElse(key, default) def extend(newStyles: Map[String, fansi.Attrs]) = copy(styles = styles ++ newStyles) - def ++(newStyles: Map[String, fansi.Attrs]) = copy(styles = styles ++ newStyles) + def ++(newStyles: Map[String, fansi.Attrs]) = copy(styles = styles ++ newStyles) def extend(newFonts: Map[String, String])(implicit d: DummyImplicit) = copy(figletFonts = figletFonts ++ newFonts) - def ++(newFonts: Map[String, String])(implicit d: DummyImplicit) = copy(figletFonts = figletFonts ++ newFonts) + def ++(newFonts: Map[String, String])(implicit d: DummyImplicit) = copy(figletFonts = figletFonts ++ newFonts) object Theme: - given default: Theme = Theme(Map( - "titleLine" -> (fansi.Bold.On ++ fansi.Color.DarkGray), - "code" -> fansi.Color.Yellow + given default: Theme = Theme( + Map( + "titleLine" -> (fansi.Bold.On ++ fansi.Color.DarkGray), + "code" -> fansi.Color.Yellow, ), - Map("titleLine" -> "smbraille") - ) + Map("titleLine" -> "smbraille"), + ) object Format: - def alignRight(str: String, padding: Int = 2) =" " * (columns - str.length - padding) + str + " " * padding + def alignRight(str: String, padding: Int = 2) = " " * (columns - str.length - padding) + str + " " * padding def center(str: String) = " " * ((columns - str.length) / 2) + str - def figlet(str: String, font: String):String = new String(%%("figlet", "-t", "-f", font, str)().out.bytes) + def figlet(str: String, font: String): String = new String(%%("figlet", "-t", "-f", font, str)().out.bytes) def centerLines(str: String) = str.split("\n").map(center).mkString("\n") def centerBlock(str: String) = - val lines = str.split("\n") - val maxLen = lines.map(_.length).max - val pad = " " * ((columns - maxLen) / 2) + val lines = str.split("\n") + val maxLen = lines.map(s => Terminal.stripEscapes(s).length).max + val pad = " " * ((columns - maxLen) / 2) lines.map(pad + _).mkString("\n") def distribute(texts: String*) = - val totalPad = columns - texts.map(_.length).sum - val numPads = texts.size - 1 - val pad = " " * (totalPad / numPads) + val totalPad = columns - texts.map(s => Terminal.stripEscapes(s).length).sum + val numPads = texts.size - 1 + val pad = " " * (totalPad / numPads) texts.init.mkString(pad) + pad + " " * (totalPad % numPads) + texts.last private[copret] val ticks = raw"`([^`]*)`".r diff --git a/copret/src/slides.scala b/copret/src/slides.scala index d7eaef6..f47ff00 100644 --- a/copret/src/slides.scala +++ b/copret/src/slides.scala @@ -210,7 +210,7 @@ object TypedCommand: c => runProcess(Vector(shell, "-c", c.mkString(" "))) def runInteractive(using Path): Vector[String] => String = - c => { os.proc(c).call(); "" } + c => { os.proc(c).call(stdin = os.Inherit, stdout = os.Inherit, stderr = os.Inherit); "" } def apply(cmd: String*)(using Path): TypedCommand[Vector[String]] = TypedCommand(run, cmd.mkString(" "), cmd.toVector) diff --git a/copret/src/templates.scala b/copret/src/templates.scala index 56297be..781e5ff 100644 --- a/copret/src/templates.scala +++ b/copret/src/templates.scala @@ -4,24 +4,21 @@ import os.Path trait Templates: def titleLine(title: String)(using theme: Theme) = Paragraph( - "\n" + Format - .figlet(title, theme.font("titleLine", "pagga")) - .block - .blue + "\n" + "\n" + Format.figlet(title, theme.font("titleLine", "pagga")).block.blue + "\n", ) def header(using theme: Theme) = Meta((p, pos) => { - val left = p.meta.getOrElse("author", "") + val left = p.meta.getOrElse("author", "") val center = p.meta.getOrElse("title", "") - val right = s"${pos} / ${p.slides.size - 1}" + val right = s"${pos + 1} / ${p.slides.size}" theme.style("titleLine")(Format.distribute(left, center, right)).text }) def slide(title: String)(slides: Slide*)(using Theme) = Group( - Clear :: header :: titleLine(title) :: slides.toList + Clear :: header :: titleLine(title) :: slides.toList, ) - def slide(slides: Slide*)(using Theme) = Group( - Clear :: header :: slides.toList + def slide(slides: Slide*)(using Theme) = Group( + Clear :: header :: slides.toList, ) def markdown(title: String, content: Path)(using Theme) = slide(title)( @@ -30,11 +27,12 @@ trait Templates: "/usr/bin/mdcat", "--columns", (columns * 0.8).toInt.toString, - content.toString - )(using os.pwd).block - ) + content.toString, + )(using os.pwd).block, + ), ) lazy val --- = Paragraph(("═" * columns).yellow.toString) +end Templates /* vim:set tw=120: */ diff --git a/copret/src/terminal.scala b/copret/src/terminal.scala index 6b45062..991ee6e 100644 --- a/copret/src/terminal.scala +++ b/copret/src/terminal.scala @@ -64,7 +64,11 @@ object Terminal: def csi = if (isTmux) "\u001bPtmux\u001b\u001b[" else "\u001b[" def osc = if (isTmux) "\u001bPtmux\u001b\u001b]" else "\u001b]" def apc = if (isTmux) "\u001bPtmux;\u001b\u001b_" else "\u001b_" - def st = if (isTmux) "\u0007\u001b\\" else "\u0007" + def st = if (isTmux) "\u0007\u001b\\" else "\u001b\\" + + def stripEscapes(str: String) = + // match CSI until letter or OSC/APC until ST + str.replaceAll("\u001b(\\[[^a-zA-Z]*[a-zA-Z]|(\\]|_).*?(\u0007|\u001b\\\\))", "") def hideCursor() = print(s"${csi}?25l") def showCursor() = print(s"${csi}?25h")