Skip to content

Commit

Permalink
Various docs
Browse files Browse the repository at this point in the history
  • Loading branch information
deusaquilus committed Dec 29, 2023
1 parent 4746d45 commit dc617ea
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 3 deletions.
90 changes: 89 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# PPrint for Kotlin

This is a port of Li Haoyi's excellent Scala pretty-printing library into Kotlin.
This is a port of Li Haoyi's excellent Scala pretty-printing library into Kotlin (pprint)[https://github.com/com-lihaoyi/PPrint].
(As well as Li Haoyi's excellent Ansi-Formatting library Fansi!)

## Usage
Expand All @@ -21,4 +21,92 @@ val p = Person(Name("Joe", "Bloggs"), 42)
println(pprint(p))
```

It will print the following beautiful output:



PPrint-Kotlin supports most of the same features and options as the Scala version.
I will document them here over time however for now please refer to the Scala documentation
* For PPrint here - https://github.com/com-lihaoyi/PPrint
* For Fansi here - https://github.com/com-lihaoyi/fansi

## Nested Data and Complex Collections

PPrint excells at printing nested data structures and complex collections.

For example lists embedded in objects:
```kotlin
data class Address(val street: String, val zip: Int)
data class Customer(val name: Name, val addresses: List<Address>)

val p = Customer(Name("Joe", "Bloggs"), listOf(Address("foo", 123), Address("bar", 456), Address("baz", 789)))
println(pprint(p))
```

Maps embedded in objects:
```kotlin
data class Alias(val value: String)
data class ComplexCustomer(val name: Name, val addressAliases: Map<Alias, Address>)

val p =
ComplexCustomer(
Name("Joe", "Bloggs"),
mapOf(Alias("Primary") to Address("foo", 123), Alias("Secondary") to Address("bar", 456), Alias("Tertiary") to Address("baz", 789))
)
println(pprint(p))
```

Lists embedded in maps imbedded in objects:
```kotlin
val p =
VeryComplexCustomer(
Name("Joe", "Bloggs"),
mapOf(
Alias("Primary") to
listOf(Address("foo", 123), Address("foo1", 123), Address("foo2", 123)),
Alias("Secondary") to
listOf(Address("bar", 456), Address("bar1", 456), Address("bar2", 456)),
Alias("Tertiary") to
listOf(Address("baz", 789), Address("baz1", 789), Address("baz2", 789))
)
)
println(pprint(p))
```

## Infinite Sequences

Another very impressive ability of PPrint is that it can print infinite sequences, even if they are embedded
other objects for example:
```kotlin
data class SequenceHolder(val seq: Sequence<String>)

var i = 0
val p = SequenceHolder(generateSequence { "foo-${i++}" })
println(pprint(p, defaultHeight = 10))
```

PPrint is able to print this infinite sequence without stack-overflowing or running out of memory
because it is highly lazy. It only evaluates the sequence as it is printing it,
and the printing is always constrained by the height and width of the output. You can
control these with the `defaultHeight` and `defaultWidth` parameters to the `pprint` function.

## Black & White Printing

The output of the pprint function is not actually a java.lang.String, but a fansi.Str. This
means you can control how it is printed. For example, to print it in black and white simple do:
```kotlin
import io.exoquery.pprint.PPrinter

val p = Person(Name("Joe", "Bloggs"), 42)

// Use Black & White Printing
println(pprint(p).plainText)
```

## Extending PPrint

TODO

## Fansi

TODO
49 changes: 47 additions & 2 deletions src/test/kotlin/io/exoquery/pprint/Examples.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,56 @@ import io.exoquery.pprint
data class Name(val first: String, val last: String)
data class Person(val name: Name, val age: Int)

data class Address(val street: String, val zip: Int)
data class Customer(val name: Name, val addresses: List<Address>)

data class Alias(val value: String)
data class ComplexCustomer(val name: Name, val addressAliases: Map<Alias, Address>)

data class VeryComplexCustomer(val name: Name, val addressAliases: Map<Alias, List<Address>>)

data class SequenceHolder(val seq: Sequence<String>)

fun main() {
// run {
// val p = Person(Name("Joe", "Bloggs"), 42)
// println(pprint(p))
// }

// run {
// val p = Customer(Name("Joe", "Bloggs"), listOf(Address("foo", 123), Address("bar", 456), Address("baz", 789)))
// println(pprint(p))
// }

// run {
// val p =
// ComplexCustomer(
// Name("Joe", "Bloggs"),
// mapOf(Alias("Primary") to Address("foo", 123), Alias("Secondary") to Address("bar", 456), Alias("Tertiary") to Address("baz", 789))
// )
// println(pprint(p))
// }

// run {
// val p =
// VeryComplexCustomer(
// Name("Joe", "Bloggs"),
// mapOf(
// Alias("Primary") to
// listOf(Address("foo", 123), Address("foo1", 123), Address("foo2", 123)),
// Alias("Secondary") to
// listOf(Address("bar", 456), Address("bar1", 456), Address("bar2", 456)),
// Alias("Tertiary") to
// listOf(Address("baz", 789), Address("baz1", 789), Address("baz2", 789))
// )
// )
// println(pprint(p))
// }

run {
val p = Person(Name("Joe", "Bloggs"), 42)
println(pprint(p))
var i = 0
val p = SequenceHolder(generateSequence { "foo-${i++}" })
println(pprint(p, defaultHeight = 10).plainText)
}

//val seq = generateSequence { "foo" }
Expand Down

0 comments on commit dc617ea

Please sign in to comment.