allow cycles in graphs even when printing with AsciiTreeLayout, fixes #77

This commit is contained in:
Johannes Rudolph 2015-11-17 17:29:58 +01:00
parent 5f3c2c2659
commit 0c3cf98a89
2 changed files with 27 additions and 17 deletions

View File

@ -28,20 +28,27 @@ object AsciiTreeLayout {
}) + }) +
s.slice(at + 1, s.length) s.slice(at + 1, s.length)
else s else s
def toAsciiLines(node: A, level: Int): Vector[String] = { def toAsciiLines(node: A, level: Int, parents: Set[A]): Vector[String] =
val line = limitLine((twoSpaces * level) + (if (level == 0) "" else "+-") + display(node)) if (parents contains node) // cycle
val cs = Vector(children(node): _*) Vector(limitLine((twoSpaces * level) + "#-" + display(node)))
val childLines = cs map {toAsciiLines(_, level + 1)} else {
val withBar = childLines.zipWithIndex flatMap { val line = limitLine((twoSpaces * level) + (if (level == 0) "" else "+-") + display(node))
case (lines, pos) if pos < (cs.size - 1) => lines map {insertBar(_, 2 * (level + 1))} val cs = Vector(children(node): _*)
case (lines, pos) => val childLines = cs map {
if (lines.last.trim != "") lines ++ Vector(twoSpaces * (level + 1)) toAsciiLines(_, level + 1, parents + node)
else lines }
val withBar = childLines.zipWithIndex flatMap {
case (lines, pos) if pos < (cs.size - 1) => lines map {
insertBar(_, 2 * (level + 1))
}
case (lines, pos) =>
if (lines.last.trim != "") lines ++ Vector(twoSpaces * (level + 1))
else lines
}
line +: withBar
} }
line +: withBar
}
toAsciiLines(top, 0).mkString("\n") toAsciiLines(top, 0, Set.empty).mkString("\n")
} }
def defaultColumnSize: Int = { def defaultColumnSize: Int = {

View File

@ -77,15 +77,18 @@ class AsciiTreeLayoutSpecs extends Specification {
| +-2 | +-2
| | +-4 | | +-4
| | | +-3 | | | +-3
| | | | | |\u0020
| | +-5 | | +-5
| | #-1 | | #-1
| | #-4 | | +-4
| | | +-3
| | |\u0020
| | +-6 | | +-6
| | +-7 | | +-7
| | | |\u0020\u0020\u0020
| #-3 | +-3
| #-4""".stripMargin.trim | +-4
| +-3""".stripMargin.trim
} }
} }
} }