aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Waters <awaters@nextfaze.com>2017-05-01 14:00:31 +0930
committerSimon Ogorodnik <sem-oro@yandex.ru>2017-05-04 14:26:37 +0300
commitc2afb348bb0d3dd60d336aa312b5fcedfb31b966 (patch)
tree7071aebbdb30b82532bcdce545edc27d2d3eb4a5
parent54c3c87acfb31afc22afc5f20229384f755b677f (diff)
downloaddokka-c2afb348bb0d3dd60d336aa312b5fcedfb31b966.tar.gz
dokka-c2afb348bb0d3dd60d336aa312b5fcedfb31b966.tar.bz2
dokka-c2afb348bb0d3dd60d336aa312b5fcedfb31b966.zip
Fix Markdown list spacing, ordering, and erroneous new lines
-rw-r--r--core/src/main/kotlin/Formats/MarkdownFormatService.kt27
-rw-r--r--core/src/main/kotlin/Kotlin/ContentBuilder.kt5
-rw-r--r--core/src/main/kotlin/Markdown/MarkdownProcessor.kt2
-rw-r--r--core/src/test/kotlin/format/MarkdownFormatTest.kt8
-rw-r--r--core/testdata/format/javadocOrderedList.md4
-rw-r--r--core/testdata/format/nestedLists.kt31
-rw-r--r--core/testdata/format/nestedLists.md43
-rw-r--r--core/testdata/format/unorderedLists.kt36
-rw-r--r--core/testdata/format/unorderedLists.md47
9 files changed, 191 insertions, 12 deletions
diff --git a/core/src/main/kotlin/Formats/MarkdownFormatService.kt b/core/src/main/kotlin/Formats/MarkdownFormatService.kt
index b9c9c04f..f7c17401 100644
--- a/core/src/main/kotlin/Formats/MarkdownFormatService.kt
+++ b/core/src/main/kotlin/Formats/MarkdownFormatService.kt
@@ -10,6 +10,13 @@ enum class ListKind {
Unordered
}
+private class ListState(val kind: ListKind, var size: Int = 1) {
+ fun getTagAndIncrement() = when (kind) {
+ ListKind.Ordered -> "${size++}. "
+ else -> "* "
+ }
+}
+
private val TWO_LINE_BREAKS = System.lineSeparator() + System.lineSeparator()
open class MarkdownOutputBuilder(to: StringBuilder,
@@ -20,7 +27,7 @@ open class MarkdownOutputBuilder(to: StringBuilder,
impliedPlatforms: List<String>)
: StructuredOutputBuilder(to, location, locationService, languageService, extension, impliedPlatforms)
{
- private val listKindStack = Stack<ListKind>()
+ private val listStack = ArrayDeque<ListState>()
protected var inTableCell = false
protected var inCodeBlock = false
private var lastTableCellStart = -1
@@ -34,7 +41,7 @@ open class MarkdownOutputBuilder(to: StringBuilder,
}
private fun ensureNewline() {
- if (inTableCell && listKindStack.isEmpty()) {
+ if (inTableCell && listStack.isEmpty()) {
if (to.length != lastTableCellStart && !to.endsWith("<br>")) {
to.append("<br>")
}
@@ -101,22 +108,22 @@ open class MarkdownOutputBuilder(to: StringBuilder,
}
override fun appendUnorderedList(body: () -> Unit) {
- listKindStack.push(ListKind.Unordered)
+ listStack.push(ListState(ListKind.Unordered))
body()
- listKindStack.pop()
+ listStack.pop()
ensureNewline()
}
override fun appendOrderedList(body: () -> Unit) {
- listKindStack.push(ListKind.Ordered)
+ listStack.push(ListState(ListKind.Ordered))
body()
- listKindStack.pop()
+ listStack.pop()
ensureNewline()
}
override fun appendListItem(body: () -> Unit) {
ensureNewline()
- to.append(if (listKindStack.peek() == ListKind.Unordered) "* " else "1. ")
+ to.append(listStack.peek()?.getTagAndIncrement())
body()
ensureNewline()
}
@@ -151,8 +158,10 @@ open class MarkdownOutputBuilder(to: StringBuilder,
if (inTableCell) {
ensureNewline()
body()
- }
- else {
+ } else if (listStack.isNotEmpty()) {
+ body()
+ ensureNewline()
+ } else {
ensureParagraph()
body()
ensureParagraph()
diff --git a/core/src/main/kotlin/Kotlin/ContentBuilder.kt b/core/src/main/kotlin/Kotlin/ContentBuilder.kt
index c124821e..a244a48e 100644
--- a/core/src/main/kotlin/Kotlin/ContentBuilder.kt
+++ b/core/src/main/kotlin/Kotlin/ContentBuilder.kt
@@ -96,7 +96,9 @@ fun buildContentTo(tree: MarkdownNode, target: ContentBlock, linkResolver: (Stri
}
}
MarkdownTokenTypes.EOL -> {
- if (keepEol(nodeStack.peek()) && node.parent?.children?.last() != node) {
+ if ((keepEol(nodeStack.peek()) && node.parent?.children?.last() != node) ||
+ // Keep extra blank lines when processing lists (affects Markdown formatting)
+ (processingList(nodeStack.peek()) && node.previous?.type == MarkdownTokenTypes.EOL)) {
parent.append(ContentText(node.text))
}
}
@@ -156,6 +158,7 @@ fun buildContentTo(tree: MarkdownNode, target: ContentBlock, linkResolver: (Stri
private fun MarkdownNode.getLabelText() = children.filter { it.type == MarkdownTokenTypes.TEXT || it.type == MarkdownTokenTypes.EMPH }.joinToString("") { it.text }
private fun keepEol(node: ContentNode) = node is ContentParagraph || node is ContentSection || node is ContentBlockCode
+private fun processingList(node: ContentNode) = node is ContentOrderedList || node is ContentUnorderedList
fun buildInlineContentTo(tree: MarkdownNode, target: ContentBlock, linkResolver: (String) -> ContentBlock) {
val inlineContent = tree.children.singleOrNull { it.type == MarkdownElementTypes.PARAGRAPH }?.children ?: listOf(tree)
diff --git a/core/src/main/kotlin/Markdown/MarkdownProcessor.kt b/core/src/main/kotlin/Markdown/MarkdownProcessor.kt
index d1d40dd4..2c8f7a73 100644
--- a/core/src/main/kotlin/Markdown/MarkdownProcessor.kt
+++ b/core/src/main/kotlin/Markdown/MarkdownProcessor.kt
@@ -14,6 +14,8 @@ class MarkdownNode(val node: ASTNode, val parent: MarkdownNode?, val markdown: S
val text: String get() = node.getTextInNode(markdown).toString()
fun child(type: IElementType): MarkdownNode? = children.firstOrNull { it.type == type }
+ val previous get() = parent?.children?.getOrNull(parent.children.indexOf(this) - 1)
+
override fun toString(): String = StringBuilder().apply { presentTo(this) }.toString()
}
diff --git a/core/src/test/kotlin/format/MarkdownFormatTest.kt b/core/src/test/kotlin/format/MarkdownFormatTest.kt
index 999d739b..217bfd09 100644
--- a/core/src/test/kotlin/format/MarkdownFormatTest.kt
+++ b/core/src/test/kotlin/format/MarkdownFormatTest.kt
@@ -356,6 +356,14 @@ class MarkdownFormatTest {
verifyMarkdownNode("tokensInHeaders")
}
+ @Test fun unorderedLists() {
+ verifyMarkdownNode("unorderedLists")
+ }
+
+ @Test fun nestedLists() {
+ verifyMarkdownNode("nestedLists")
+ }
+
private fun buildMultiplePlatforms(path: String): DocumentationModule {
val module = DocumentationModule("test")
val options = DocumentationOptions("", "html", generateIndexPages = false)
diff --git a/core/testdata/format/javadocOrderedList.md b/core/testdata/format/javadocOrderedList.md
index 00aa1bc4..f18ee96a 100644
--- a/core/testdata/format/javadocOrderedList.md
+++ b/core/testdata/format/javadocOrderedList.md
@@ -5,13 +5,13 @@
`open class Bar`
1. Rinse
- 1. Repeat
+ 2. Repeat
### Constructors
| [&lt;init&gt;](test/-bar/-init-) | `Bar()`<br>
1. Rinse
- 1. Repeat
+ 2. Repeat
<br> |
diff --git a/core/testdata/format/nestedLists.kt b/core/testdata/format/nestedLists.kt
new file mode 100644
index 00000000..83217f8a
--- /dev/null
+++ b/core/testdata/format/nestedLists.kt
@@ -0,0 +1,31 @@
+/**
+ * Usage instructions:
+ *
+ * - __Rinse__
+ * 1. Alter any rinse options _(optional)_
+ * - Recommended to [Bar.useSoap]
+ * - Optionally apply [Bar.elbowGrease] for best results
+ * 2. [Bar.rinse] to begin rinse
+ * 1. Thus you should call [Bar.rinse]
+ * 2. *Then* call [Bar.repeat]
+ * - Don't forget to use:
+ * - Soap
+ * - Elbow Grease
+ * 3. Finally, adjust soap usage [Bar.useSoap] as needed
+ * 3. Repeat with [Bar.repeat]
+ *
+ * - __Repeat__
+ * - Will use previously used rinse options
+ * - [Bar.rinse] must have been called once before
+ * - Can be repeated any number of times
+ * - Options include:
+ * - [Bar.useSoap]
+ * - [Bar.useElbowGrease]
+ */
+class Bar {
+ fun rinse() = Unit
+ fun repeat() = Unit
+
+ var useSoap = false
+ var useElbowGrease = false
+}
diff --git a/core/testdata/format/nestedLists.md b/core/testdata/format/nestedLists.md
new file mode 100644
index 00000000..dd151944
--- /dev/null
+++ b/core/testdata/format/nestedLists.md
@@ -0,0 +1,43 @@
+[test](test/index) / [Bar](test/-bar/index)
+
+# Bar
+
+`class Bar`
+
+Usage instructions:
+
+* **Rinse**
+ 1. Alter any rinse options *(optional)*
+ * Recommended to [Bar.useSoap](test/-bar/use-soap)
+ * Optionally apply [Bar.elbowGrease](#) for best results
+ 2. [Bar.rinse](test/-bar/rinse) to begin rinse
+ 1. Thus you should call [Bar.rinse](test/-bar/rinse)
+ 2. *Then* call [Bar.repeat](test/-bar/repeat)
+ * Don't forget to use:
+ * Soap
+ * Elbow Grease
+ 3. Finally, adjust soap usage [Bar.useSoap](test/-bar/use-soap) as needed
+ 3. Repeat with [Bar.repeat](test/-bar/repeat)
+
+* **Repeat**
+ * Will use previously used rinse options
+ * [Bar.rinse](test/-bar/rinse) must have been called once before
+ * Can be repeated any number of times
+ * Options include:
+ * [Bar.useSoap](test/-bar/use-soap)
+ * [Bar.useElbowGrease](test/-bar/use-elbow-grease)
+
+### Constructors
+
+| [&lt;init&gt;](test/-bar/-init-) | `Bar()`<br>Usage instructions: |
+
+### Properties
+
+| [useElbowGrease](test/-bar/use-elbow-grease) | `var useElbowGrease: Boolean` |
+| [useSoap](test/-bar/use-soap) | `var useSoap: Boolean` |
+
+### Functions
+
+| [repeat](test/-bar/repeat) | `fun repeat(): Unit` |
+| [rinse](test/-bar/rinse) | `fun rinse(): Unit` |
+
diff --git a/core/testdata/format/unorderedLists.kt b/core/testdata/format/unorderedLists.kt
new file mode 100644
index 00000000..a594b89b
--- /dev/null
+++ b/core/testdata/format/unorderedLists.kt
@@ -0,0 +1,36 @@
+/**
+ * Usage summary:
+ *
+ * - Rinse
+ * - Repeat
+ *
+ * Usage instructions:
+ *
+ * - [Bar.rinse] to rinse
+ * - Alter any rinse options _(optional)_
+ * - To repeat; [Bar.repeat]
+ * - Can reconfigure options:
+ * - Soap
+ * - Elbow Grease
+ * - Bleach
+ *
+ * Rinse options:
+ *
+ * - [Bar.useSoap]
+ * - _recommended_
+ *
+ * - [Bar.useElbowGrease]
+ * - _warning: requires effort_
+ *
+ * - [Bar.useBleach]
+ * - __use with caution__
+ *
+ */
+class Bar {
+ fun rinse() = Unit
+ fun repeat() = Unit
+
+ var useSoap = false
+ var useElbowGrease = false
+ var useBleach = false
+}
diff --git a/core/testdata/format/unorderedLists.md b/core/testdata/format/unorderedLists.md
new file mode 100644
index 00000000..a6b00b34
--- /dev/null
+++ b/core/testdata/format/unorderedLists.md
@@ -0,0 +1,47 @@
+[test](test/index) / [Bar](test/-bar/index)
+
+# Bar
+
+`class Bar`
+
+Usage summary:
+
+* Rinse
+* Repeat
+
+Usage instructions:
+
+* [Bar.rinse](test/-bar/rinse) to rinse
+* Alter any rinse options *(optional)*
+* To repeat; [Bar.repeat](test/-bar/repeat)
+ * Can reconfigure options:
+ * Soap
+ * Elbow Grease
+ * Bleach
+
+Rinse options:
+
+* [Bar.useSoap](test/-bar/use-soap)
+ * *recommended*
+
+* [Bar.useElbowGrease](test/-bar/use-elbow-grease)
+ * *warning: requires effort*
+
+* [Bar.useBleach](test/-bar/use-bleach)
+ * **use with caution**
+
+### Constructors
+
+| [&lt;init&gt;](test/-bar/-init-) | `Bar()`<br>Usage summary: |
+
+### Properties
+
+| [useBleach](test/-bar/use-bleach) | `var useBleach: Boolean` |
+| [useElbowGrease](test/-bar/use-elbow-grease) | `var useElbowGrease: Boolean` |
+| [useSoap](test/-bar/use-soap) | `var useSoap: Boolean` |
+
+### Functions
+
+| [repeat](test/-bar/repeat) | `fun repeat(): Unit` |
+| [rinse](test/-bar/rinse) | `fun rinse(): Unit` |
+