Reformat single files

This commit is contained in:
Joscha 2024-09-04 19:02:18 +02:00
parent f411db572d
commit 8f55c90980
4 changed files with 83 additions and 5 deletions

View file

@ -1,6 +1,8 @@
package de.plugh.asciiprooftree
import java.nio.file.Path
import de.plugh.asciiprooftree.file.Formatter
import java.nio.file.{Files, Path}
@main
def main(args: String*): Unit = args match
@ -11,4 +13,12 @@ def main(args: String*): Unit = args match
println("Usage: asciiprooftree [path] [marker]")
System.exit(1)
def run(path: Path = Path.of(""), marker: String = "§"): Unit = println(s"$path $marker")
@main
def testMain(path: String): Unit = run(Path.of(path))
def run(path: Path = Path.of(""), marker: String = "§"): Unit =
println(s"Path: $path")
println(s"Marker: $marker")
val text = Files.readString(path)
val newText = Formatter.reformat(text, marker = marker)
Files.writeString(path, newText)

View file

@ -0,0 +1,23 @@
package de.plugh.asciiprooftree.file
case class Block(lines: Seq[(String, String)]):
require(lines.nonEmpty)
def last: (String, String) = lines.last
def content: Seq[String] = lines.map((_, content) => content)
def toLines: Seq[String] = lines.map((prefix, content) => s"$prefix $content")
def extend(prefix: String, content: String): Block = Block(lines :+ (prefix, content))
def resize(height: Int): Block =
require(height > 0)
if height < lines.length then return Block(lines.take(height))
if height == lines.length then return this
Block(lines ++ Seq.fill(height - lines.length)(lines.last))
def replace(newContent: IndexedSeq[String]): Block =
require(newContent.nonEmpty)
Block(resize(newContent.length).lines.zip(newContent).map { case ((prefix, _), content) => (prefix, content) })
object Block:
def apply(prefix: String, content: String): Block = Block(Seq((prefix, content)))

View file

@ -0,0 +1,45 @@
package de.plugh.asciiprooftree.file
import de.plugh.asciiprooftree.tree.{Line, Parser}
import scala.collection.mutable
private class Formatter(marker: String):
private val lines: mutable.Buffer[String] = mutable.Buffer()
private var block: Option[Block] = None
private def flushBlock(): Unit = for block <- this.block do
val newBlock = Parser(block.content).parse match
case Some(tree) => block.replace(tree.formatted.toString.linesIterator.toIndexedSeq)
case None => block
lines.appendAll(newBlock.toLines)
this.block = None
private def pushBlockLine(prefix: String, content: String): Unit = this.block match
case Some(block) if Line(block.last._1).width == Line(prefix).width =>
this.block = Some(block.extend(prefix, content))
case _ =>
flushBlock()
this.block = Some(Block(prefix, content))
private def pushPlainLine(line: String): Unit =
flushBlock()
lines.append(line)
private def pushLine(line: String): Unit =
val i = line.indexOf(marker)
if i < 0 then pushPlainLine(line)
else
val prefix = line.slice(0, i + marker.length)
val content = line.slice(i + marker.length, line.length)
pushBlockLine(prefix, content)
private def pushText(text: String): Unit = text.linesIterator.foreach(pushLine)
override def toString: String = lines.map(l => s"$l\n").mkString
object Formatter:
def reformat(text: String, marker: String = "§"): String =
val fmt = new Formatter(marker)
fmt.pushText(text)
fmt.toString

View file

@ -65,7 +65,7 @@ case class Parser(lines: Lines):
object Parser:
def apply(lines: Seq[String]): Parser =
val trimmedLines = lines.map(Line(_).trim)
Parser(Lines(trimmedLines.toIndexedSeq))
val trimmedLines = lines.reverseIterator.map(Line(_).trim).toIndexedSeq
Parser(Lines(trimmedLines))
def apply(text: String): Parser = apply(text.linesIterator.toSeq.reverse)
def apply(text: String): Parser = apply(text.linesIterator.toSeq)