summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjeberle <jeberle@epfl.ch>2008-05-27 09:15:38 +0000
committerjeberle <jeberle@epfl.ch>2008-05-27 09:15:38 +0000
commit859f7497e1be11fb81e4678990fccdbc093ac403 (patch)
tree7e3d6b486924917bfb0837220500287ec64e1ed3 /src
parenta480d4381e2f49479552a8b3f14b82618b54e8e1 (diff)
downloadscala-859f7497e1be11fb81e4678990fccdbc093ac403.tar.gz
scala-859f7497e1be11fb81e4678990fccdbc093ac403.tar.bz2
scala-859f7497e1be11fb81e4678990fccdbc093ac403.zip
text.Document for .NET target (using System.IO....
text.Document for .NET target (using System.IO.TextWriter)
Diffstat (limited to 'src')
-rw-r--r--src/dotnet-library/scala/text/Document.scala123
1 files changed, 122 insertions, 1 deletions
diff --git a/src/dotnet-library/scala/text/Document.scala b/src/dotnet-library/scala/text/Document.scala
index ee6cedacd3..0a46b06fe6 100644
--- a/src/dotnet-library/scala/text/Document.scala
+++ b/src/dotnet-library/scala/text/Document.scala
@@ -1 +1,122 @@
-/* Document does not exist for the dotnet target */
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id: Document.scala 11950 2007-06-08 12:08:26Z michelou $
+
+
+package scala.text
+
+
+import System.IO.TextWriter
+
+case object DocNil extends Document
+case object DocBreak extends Document
+case class DocText(txt: String) extends Document
+case class DocGroup(doc: Document) extends Document
+case class DocNest(indent: Int, doc: Document) extends Document
+case class DocCons(hd: Document, tl: Document) extends Document
+
+/**
+ * A basic pretty-printing library, based on Lindig's strict version
+ * of Wadler's adaptation of Hughes' pretty-printer.
+ *
+ * @author Michel Schinz
+ * @version 1.0
+ */
+abstract class Document {
+ def ::(hd: Document): Document = DocCons(hd, this)
+ def ::(hd: String): Document = DocCons(DocText(hd), this)
+ def :/:(hd: Document): Document = hd :: DocBreak :: this
+ def :/:(hd: String): Document = hd :: DocBreak :: this
+
+ /**
+ * Format this document on <code>writer</code> and try to set line
+ * breaks so that the result fits in <code>width</code> columns.
+ *
+ * @param width ...
+ * @param writer ...
+ */
+ def format(width: Int, writer: TextWriter) {
+ type FmtState = (Int, Boolean, Document)
+
+ def fits(w: Int, state: List[FmtState]): Boolean = state match {
+ case _ if w < 0 =>
+ false
+ case List() =>
+ true
+ case (_, _, DocNil) :: z =>
+ fits(w, z)
+ case (i, b, DocCons(h, t)) :: z =>
+ fits(w, (i,b,h) :: (i,b,t) :: z)
+ case (_, _, DocText(t)) :: z =>
+ fits(w - t.length(), z)
+ case (i, b, DocNest(ii, d)) :: z =>
+ fits(w, (i + ii, b, d) :: z)
+ case (_, false, DocBreak) :: z =>
+ fits(w - 1, z)
+ case (_, true, DocBreak) :: z =>
+ true
+ case (i, _, DocGroup(d)) :: z =>
+ fits(w, (i, false, d) :: z)
+ }
+
+ def spaces(n: Int) {
+ var rem = n
+ while (rem >= 16) { writer Write " "; rem -= 16 }
+ if (rem >= 8) { writer Write " "; rem -= 8 }
+ if (rem >= 4) { writer Write " "; rem -= 4 }
+ if (rem >= 2) { writer Write " "; rem -= 2}
+ if (rem == 1) { writer Write " " }
+ }
+
+ def fmt(k: Int, state: List[FmtState]): Unit = state match {
+ case List() => ()
+ case (_, _, DocNil) :: z =>
+ fmt(k, z)
+ case (i, b, DocCons(h, t)) :: z =>
+ fmt(k, (i, b, h) :: (i, b, t) :: z)
+ case (i, _, DocText(t)) :: z =>
+ writer Write t
+ fmt(k + t.length(), z)
+ case (i, b, DocNest(ii, d)) :: z =>
+ fmt(k, (i + ii, b, d) :: z)
+ case (i, true, DocBreak) :: z =>
+ writer Write "\n"
+ spaces(i);
+ fmt(i, z)
+ case (i, false, DocBreak) :: z =>
+ writer Write " "
+ fmt(k + 1, z)
+ case (i, b, DocGroup(d)) :: z =>
+ val fitsFlat = fits(width - k, (i, false, d) :: z)
+ fmt(k, (i, !fitsFlat, d) :: z)
+ }
+
+ fmt(0, (0, false, DocGroup(this)) :: Nil)
+ }
+}
+
+object Document {
+ /** The empty document */
+ def empty = DocNil
+
+ /** A break, which will either be turned into a space or a line break */
+ def break = DocBreak
+
+ /** A document consisting of some text literal */
+ def text(s: String): Document = DocText(s)
+
+ /**
+ * A group, whose components will either be printed with all breaks
+ * rendered as spaces, or with all breaks rendered as line breaks.
+ */
+ def group(d: Document): Document = DocGroup(d)
+
+ /** A nested document, which will be indented as specified. */
+ def nest(i: Int, d: Document): Document = DocNest(i, d)
+}