Skip to content

Commit

Permalink
feat: add indent-spaces option
Browse files Browse the repository at this point in the history
Add "--indent-spaces" integer option to specify the number of spaces
to add in the TOC per indentation level. Defaults to the current width
of 3 spaces.

Add test cases for the new "indentSpaces" parameter as well as the
existing "indentCharacters" parameter.
  • Loading branch information
joshuaprince committed May 9, 2024
1 parent a71350a commit 354f3b1
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ Usage: bitdowntoc [<options>] [<path>]
Options:
--version Show version and exit
--indent-chars=<text> Characters used for indenting the toc (default: '-*+')
--indent-spaces=<int> Number of spaces per indentation level for indenting the toc (default: 3)
--concat-spaces / --no-concat-spaces Whether to trim heading spaces in generated links (foo-bar) or not
(foo----bar) (default: true)
--anchors-prefix=<text> Prefix added to all anchors and TOC links (e.g. 'heading-') (default: '')
Expand Down
3 changes: 2 additions & 1 deletion src/commonMain/kotlin/ch/derlin/bitdowntoc/BitGenerator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ object BitGenerator {

data class Params(
val indentChars: String = BitOptions.indentChars.default,
val indentSpaces: Int = BitOptions.indentSpaces.default,
val maxLevel: Int = BitOptions.maxLevel.default,
val generateAnchors: Boolean = BitOptions.generateAnchors.default,
val anchorAlgorithm: AnchorAlgorithm = BitOptions.anchorAlgorithm.default,
Expand Down Expand Up @@ -74,7 +75,7 @@ object BitGenerator {
}
}

val tocString = toc.generateToc(params.indentChars, params.trimTocIndent).let {
val tocString = toc.generateToc(params.indentChars, params.indentSpaces, params.trimTocIndent).let {
if (params.oneShot) it else commenter.wrapToc(it).asText()
}

Expand Down
5 changes: 5 additions & 0 deletions src/commonMain/kotlin/ch/derlin/bitdowntoc/BitOptions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ object BitOptions {
"indent-chars", "indent characters", "-*+",
"Characters used for indenting the toc"
)
val indentSpaces = BitOption(
"indent-spaces", "indent spaces", 3,
"Number of spaces per indentation level for indenting the toc"
)
val generateAnchors = BitOption(
"anchors", "generate anchors", true,
"Whether to generate anchors below headings (e.g. BitBucket Server)"
Expand Down Expand Up @@ -107,6 +111,7 @@ object BitOptions {

val list: Array<BitOption<*>> = arrayOf(
indentChars,
indentSpaces,
generateAnchors,
anchorAlgorithm,
anchorsPrefix,
Expand Down
4 changes: 2 additions & 2 deletions src/commonMain/kotlin/ch/derlin/bitdowntoc/Toc.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ class Toc(
}
}

fun generateToc(indentCharacters: String, trimTocIndent: Boolean): String {
fun generateToc(indentCharacters: String, indentSpaces: Int, trimTocIndent: Boolean): String {
if (this.entries.isEmpty()) return ""
val minIndent = if (trimTocIndent) entries.minOf { it.indent } else 0
return entries.joinToString("\n") { (indent, text, link) ->
(indent - minIndent).let {
" ".repeat(it * 3) + "${indentCharacters[it % indentCharacters.length]} [$text](#$link)"
" ".repeat(it * indentSpaces) + "${indentCharacters[it % indentCharacters.length]} [$text](#$link)"
}
}
}
Expand Down
115 changes: 115 additions & 0 deletions src/commonTest/kotlin/ch.derlin.bitdowntoc/GenerateTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,121 @@ class GenerateTest {
)
}

@Test
fun testIndentCharacters() {
val input = """
# Some readme
[TOC]
## heading
this is a test
```code
## comment, not header
```
### subheading
test
## heading
duplicate name
""".trimIndent()

assertEquals(
"""
# Some readme
<!-- TOC start (generated with $BITDOWNTOC_URL) -->
+ [heading](#heading)
+ [subheading](#subheading)
+ [heading](#heading-1)
<!-- TOC end -->
<!-- TOC --><a name="heading"></a>
## heading
this is a test
```code
## comment, not header
```
<!-- TOC --><a name="subheading"></a>
### subheading
test
<!-- TOC --><a name="heading-1"></a>
## heading
duplicate name
""".trimIndent(),
BitGenerator.generate(input, Params(indentChars = "+"))
)
}

@Test
fun testIndentSpaces() {
val input = """
# Some readme
[TOC]
## heading
this is a test
```code
## comment, not header
```
### subheading
#### nested subheading
test
## heading
duplicate name
""".trimIndent()

assertEquals(
"""
# Some readme
<!-- TOC start (generated with $BITDOWNTOC_URL) -->
- [heading](#heading)
* [subheading](#subheading)
+ [nested subheading](#nested-subheading)
- [heading](#heading-1)
<!-- TOC end -->
<!-- TOC --><a name="heading"></a>
## heading
this is a test
```code
## comment, not header
```
<!-- TOC --><a name="subheading"></a>
### subheading
<!-- TOC --><a name="nested-subheading"></a>
#### nested subheading
test
<!-- TOC --><a name="heading-1"></a>
## heading
duplicate name
""".trimIndent(),
BitGenerator.generate(input, Params(indentSpaces = 5))
)
}

@Test
fun testNoText() {
Expand Down
1 change: 1 addition & 0 deletions src/jsMain/kotlin/toc.kt
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ fun generate(text: String) =

fun getParams() = BitGenerator.Params(
indentChars = BitOptions.indentChars.getValue(),
indentSpaces = BitOptions.indentSpaces.getValue(),
generateAnchors = BitOptions.generateAnchors.getValue(),
anchorsPrefix = BitOptions.anchorsPrefix.getValue(),
commentStyle = BitOptions.commentStyle.getValue(),
Expand Down
2 changes: 2 additions & 0 deletions src/jvmMain/kotlin/ch/derlin/bitdowntoc/main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class Cli(
private val path: String by argument(help = "Markdown file, or '-' to read from stdin").default("")

private val indentChars: String by BitOptions.indentChars.cliOption()
private val indentSpaces: Int by BitOptions.indentSpaces.cliOptionInt()
private val concatSpaces: Boolean by BitOptions.concatSpaces.cliOptionBool()
private val anchorsPrefix: String by BitOptions.anchorsPrefix.cliOption()
private val generateAnchors: Boolean by BitOptions.generateAnchors.cliOptionBool()
Expand Down Expand Up @@ -93,6 +94,7 @@ class Cli(
val output = if (inplace) inputFile else outputFile?.toFile()
val params = BitGenerator.Params(
indentChars = indentChars,
indentSpaces = indentSpaces,
generateAnchors = generateAnchors,
anchorAlgorithm = anchorAlgorithm,
anchorsPrefix = anchorsPrefix,
Expand Down

0 comments on commit 354f3b1

Please sign in to comment.