aboutsummaryrefslogtreecommitdiff
path: root/src/Formats/MarkdownFormatService.kt
blob: ae1500f208d78be5fcaaf06cffd82dee6b68ed71 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package org.jetbrains.dokka

import org.jetbrains.dokka.DocumentationNode.Kind
import java.util.LinkedHashMap

public class MarkdownFormatService(val locationService: LocationService,
                                   val signatureGenerator: SignatureGenerator) : FormatService {
    override val extension: String = "md"
    override fun format(nodes: Iterable<DocumentationNode>, to: StringBuilder) {
        with (to) {
            val breakdown = nodes.groupByTo(LinkedHashMap()) { node ->
                node.path.map { "[${it.name}](${locationService.relativeLocation(node, it, extension)})" }.joinToString(" / ")
            }
            for ((path, items) in breakdown) {
                appendln(path)
                appendln()
                formatLocation(items)
            }

            for (node in nodes) {
                if (node.members.any()) {
                    appendln("## Members")
                    appendln("| Name | Summary |")
                    appendln("|------|---------|")
                    val children = node.members.sortBy { it.name }
                    val membersMap = children.groupByTo(LinkedHashMap()) { locationService.relativeLocation(node, it, extension) }
                    for ((location, members) in membersMap) {
                        val mainMember = members.first()
                        val displayName = when (mainMember.kind) {
                            Kind.Constructor -> "*.init*"
                            else -> signatureGenerator.renderName(mainMember).htmlEscape()
                        }
                        append("|[${displayName}](${location})|")
                        append(members.groupByTo(LinkedHashMap()) { it.doc.summary }.map { group ->
                            val (summary, items) = group
                            StringBuilder {
                                if (!summary.isEmpty()) {
                                    append("${summary}<br>")
                                }
                                for (item in items) {
                                    append("&nbsp;&nbsp;`${signatureGenerator.render(item)}`<br>")
                                }
                            }.toString()
                        }.joinToString("<br>"))
                        appendln("|")
                    }
                }

            }
        }
    }


    private fun StringBuilder.formatLocation(nodes: Iterable<DocumentationNode>) {
        val breakdown = nodes.groupByTo(LinkedHashMap()) { node ->
            node.name
        }
        for ((name, items) in breakdown) {
            appendln("# ${name}")
            formatSummary(items)
        }
    }

    private fun StringBuilder.formatSummary(nodes: Iterable<DocumentationNode>) {
        val breakdown = nodes.groupByTo(LinkedHashMap()) { node ->
            node.doc.summary
        }
        for ((summary, items) in breakdown) {
            appendln(summary)
            appendln("```")
            for (item in items)
                appendln(signatureGenerator.render(item))
            appendln("```")
        }

        val described = nodes.filter { it.doc.hasDescription }
        if (described.any()) {
            appendln("## Description")
            for (node in described) {
                appendln("```")
                appendln(signatureGenerator.render(node))
                appendln("```")
                appendln(node.doc.description)
                appendln()
                for (section in node.doc.sections) {
                    append("**")
                    append(section.label)
                    append("**")
                    appendln()
                    append(section.text)
                    appendln()
                    appendln()
                }
            }
        }
    }

}