Skip to content

Commit

Permalink
implement more robust reindentatino for code blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
jillesvangurp committed Feb 17, 2024
1 parent 1341560 commit 6a75825
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 11 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ The code that writes the `README.md file` is as follows:
class DocGenTest {
@Test
fun `generate readme for this project`() {
val readmePage = Page("Kotlin4Example",fileName = "README.md")
val readmePage = Page("Kotlin4Example", fileName = "README.md")
// readmeMarkdown is a lazy of the markdown content
readmePage.write(markdown = readmeMarkdown)
}
Expand All @@ -208,7 +208,7 @@ Simply add a simple extension function like this:.
context(Kotlin4Example)!
fun ExampleOutput<*>.printStdOut() {
+"""
This prints:
This prints:
""".trimIndent()

mdCodeBlock(stdOut, type = "text", wrap = true)
Expand Down
55 changes: 47 additions & 8 deletions src/main/kotlin/com/jillesvangurp/kotlin4example/Kotlin4Example.kt
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,22 @@ class Kotlin4Example(
*
* Use [allowLongLines] turn off the check for lines longer than [lineLength]
*
* Use [wrap] to wrap your code. Note, all it does is add a new line at the 80th character
* Use [wrap] to wrap your code. Note, all it does is add a new line at the 80th character.
*
* Use [reIndent] to change the indentation of the code to [reIndentSize]. Shorter indentation helps
* keeping the lines short. Defaults to true
*/
fun mdCodeBlock(
code: String,
type: String,
allowLongLines: Boolean = false,
wrap: Boolean = false,
lineLength: Int = 80
lineLength: Int = 80,
reIndent: Boolean = true,
reIndentSize: Int = 2
) {
var c = code.replace(" ", " ")
// reindenting is useful when including source snippets that are indented with 4 or 8 spaces
var c = if(reIndent) code.reIndent(reIndentSize) else code
if (wrap) {
var l = 1
c = c.lines().flatMap { line ->
Expand Down Expand Up @@ -215,7 +221,9 @@ class Kotlin4Example(
allowLongLines: Boolean = false,
wrap: Boolean = false,
lineLength: Int = 80,
type: String = "kotlin"
type: String = "kotlin",
reIndent: Boolean = true,
reIndentSize: Int = 2
) {
val snippetLines = mutableListOf<String>()

Expand Down Expand Up @@ -243,7 +251,9 @@ class Kotlin4Example(
type = type,
allowLongLines = allowLongLines,
wrap = wrap,
lineLength = lineLength
lineLength = lineLength,
reIndent=reIndent,
reIndentSize=reIndentSize,
)
}

Expand Down Expand Up @@ -289,6 +299,8 @@ class Kotlin4Example(
allowLongLines: Boolean = false,
wrap: Boolean = false,
lineLength: Int = 80,
reIndent: Boolean = true,
reIndentSize: Int = 2,
block: suspend BlockOutputCapture.() -> T
): ExampleOutput<T> {
val state = BlockOutputCapture()
Expand All @@ -310,7 +322,9 @@ class Kotlin4Example(
allowLongLines = allowLongLines,
wrap = wrap,
lineLength = lineLength,
type = type
type = type,
reIndent = reIndent,
reIndentSize = reIndentSize,
)

return ExampleOutput(returnVal, state.output().trimIndent())
Expand Down Expand Up @@ -339,6 +353,8 @@ class Kotlin4Example(
allowLongLines: Boolean = false,
wrap: Boolean = false,
lineLength: Int = 80,
reIndent: Boolean = true,
reIndentSize: Int = 2
) {
if(!stdOutOnly) {
exampleOutput.result.let { r ->
Expand All @@ -349,7 +365,9 @@ class Kotlin4Example(
allowLongLines = allowLongLines,
wrap = wrap,
lineLength = lineLength,
type = "text"
type = "text",
reIndent = reIndent,
reIndentSize = reIndentSize,
)
}
}
Expand All @@ -361,7 +379,9 @@ class Kotlin4Example(
allowLongLines = allowLongLines,
wrap = wrap,
lineLength = lineLength,
type = "text"
type = "text",
reIndent = reIndent,
reIndentSize = reIndentSize,
)
}
}
Expand Down Expand Up @@ -623,3 +643,22 @@ class Kotlin4Example(
}
}
}

fun String.reIndent(indent: Int=2): String {
val spaceFinder = "^(\\s+)".toRegex()
return this.lines().firstOrNull {
val whiteSpace = spaceFinder.find(it)?.value
whiteSpace?.let {
whiteSpace.length > indent
} == true
}?.let {
val whiteSpace = spaceFinder.find(it)!!.groups[1]!!.value
if(whiteSpace.length != indent ) {
val originalIndent = " ".repeat(whiteSpace.length)
val newIndent = " ".repeat(indent)
this.replace(originalIndent, newIndent)
} else {
this
}
}?:this
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import org.junit.jupiter.api.Test
class DocGenTest {
@Test
fun `generate readme for this project`() {
val readmePage = Page("Kotlin4Example",fileName = "README.md")
val readmePage = Page("Kotlin4Example", fileName = "README.md")
// readmeMarkdown is a lazy of the markdown content
readmePage.write(markdown = readmeMarkdown)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.jillesvangurp.kotlin4example

import io.kotest.matchers.ints.shouldBeLessThanOrEqual
import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import io.kotest.matchers.string.shouldContain
import io.kotest.matchers.string.shouldNotContain
import org.junit.jupiter.api.Test
Expand Down Expand Up @@ -126,4 +128,31 @@ class KotlinForExampleTest {
out2 shouldContain "hello"
out2 shouldContain "world"
}

@Test
fun `reindent correctly`() {
val json = """
{
"foo": {
"bar": "foo"
}
}
""".trimIndent()
val reindented = json.reIndent(2)
reindented.lines().firstOrNull {
// should have cleaned up the double indent
it.startsWith(" ")
} shouldBe null
reindented.lines().firstOrNull {
// should have replaced the double indent with four spaces
it.startsWith(" ")
} shouldNotBe null
reindented shouldBe """
{
"foo": {
"bar": "foo"
}
}
""".trimIndent()
}
}

0 comments on commit 6a75825

Please sign in to comment.