Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package ch.epfl.data.sc.pardis.utils
- import Document._
- /**
- * Doc formatter using string interpolation.
- * Markers " #{ ", " #} " (including the space character) are used to express nesting
- * Marker " # " expresses document break, just like "\n".
- *
- * For example:
- * {{{
- * doc"class A { #{ # $decl #} # }"
- * }}}
- * instead of:
- * {{{
- * "class A {" :: Document.nest(2, DocBreak :: decl) :/: "}"
- * }}}
- */
- class DocumentContext(ctx: StringContext) {
- val NEST_COUNT = 2
- object doc {
- def apply(docs: Document*): Document = {
- case object Nest extends Document
- case object UnNest extends Document
- case object Insert extends Document
- assert(ctx.parts.size == docs.size + 1 && ctx.parts.size > 0)
- def interleave(arr: Seq[Document], interleaved: Document) =
- arr(0) +: arr.tail.map { List(interleaved, _) }.flatten
- def splitOn(mark: String, interleaved: Document) = (ds: Seq[Document]) => ds flatMap {
- case DocText(str) => interleave(str.split(mark, -1) map DocText, interleaved)
- case d => Seq(d)
- }
- // Makes a sequence of the parts separated with Nest, UnNest and Insert (for positions where docs are to be inserted)
- val parts = (
- splitOn(" #\\{ ", Nest) andThen
- splitOn(" #\\} ", UnNest) andThen
- splitOn(" # ", DocBreak) andThen
- splitOn("\n", DocBreak)
- )(interleave(ctx.parts map DocText, Insert))
- // println(parts)
- val diter = docs.iterator
- val allDocs = parts map { case Insert => diter.next() case d => d }
- // Processes the sequence, replacing ..Nest..UnNest.. by a nest(..) operation
- def proc(xs: Seq[Document]): Document = xs match {
- case Seq(Nest) => throw new IllegalArgumentException("Unmatched opening nesting marker")
- case Seq(UnNest) => throw new IllegalArgumentException("Closing nesting marker closes nothing")
- case Nest +: rest :+ UnNest => nest(NEST_COUNT, proc(rest))
- case (n @ Nest +: rest) :+ d => proc(n) :: d
- case d +: rest => d :: proc(rest)
- case Seq() => empty
- }
- proc(allDocs)
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement