Ilya Ryzhenkov | a0bfdbd | 2014-07-14 15:00:33 +0400 | [diff] [blame] | 1 | package org.jetbrains.dokka |
| 2 | |
Ilya Ryzhenkov | 68d3bc8 | 2014-07-14 19:34:52 +0400 | [diff] [blame] | 3 | import org.jetbrains.dokka.DocumentationNode.Kind |
Ilya Ryzhenkov | cd7084d | 2014-07-14 21:15:04 +0400 | [diff] [blame] | 4 | import java.util.LinkedHashMap |
Ilya Ryzhenkov | 68d3bc8 | 2014-07-14 19:34:52 +0400 | [diff] [blame] | 5 | |
Ilya Ryzhenkov | eeb42e9 | 2014-07-14 22:29:34 +0400 | [diff] [blame^] | 6 | public open class MarkdownFormatService(val locationService: LocationService, |
| 7 | val signatureGenerator: SignatureGenerator) : FormatService { |
Ilya Ryzhenkov | a0bfdbd | 2014-07-14 15:00:33 +0400 | [diff] [blame] | 8 | override val extension: String = "md" |
Ilya Ryzhenkov | cd7084d | 2014-07-14 21:15:04 +0400 | [diff] [blame] | 9 | override fun format(nodes: Iterable<DocumentationNode>, to: StringBuilder) { |
Ilya Ryzhenkov | a0bfdbd | 2014-07-14 15:00:33 +0400 | [diff] [blame] | 10 | with (to) { |
Ilya Ryzhenkov | cd7084d | 2014-07-14 21:15:04 +0400 | [diff] [blame] | 11 | val breakdown = nodes.groupByTo(LinkedHashMap()) { node -> |
| 12 | node.path.map { "[${it.name}](${locationService.relativeLocation(node, it, extension)})" }.joinToString(" / ") |
| 13 | } |
| 14 | for ((path, items) in breakdown) { |
| 15 | appendln(path) |
Ilya Ryzhenkov | 68d3bc8 | 2014-07-14 19:34:52 +0400 | [diff] [blame] | 16 | appendln() |
Ilya Ryzhenkov | cd7084d | 2014-07-14 21:15:04 +0400 | [diff] [blame] | 17 | formatLocation(items) |
Ilya Ryzhenkov | a0bfdbd | 2014-07-14 15:00:33 +0400 | [diff] [blame] | 18 | } |
| 19 | |
Ilya Ryzhenkov | cd7084d | 2014-07-14 21:15:04 +0400 | [diff] [blame] | 20 | for (node in nodes) { |
| 21 | if (node.members.any()) { |
| 22 | appendln("## Members") |
| 23 | appendln("| Name | Summary |") |
| 24 | appendln("|------|---------|") |
| 25 | val children = node.members.sortBy { it.name } |
| 26 | val membersMap = children.groupByTo(LinkedHashMap()) { locationService.relativeLocation(node, it, extension) } |
| 27 | for ((location, members) in membersMap) { |
| 28 | val mainMember = members.first() |
| 29 | val displayName = when (mainMember.kind) { |
| 30 | Kind.Constructor -> "*.init*" |
| 31 | else -> signatureGenerator.renderName(mainMember).htmlEscape() |
| 32 | } |
| 33 | append("|[${displayName}](${location})|") |
| 34 | append(members.groupByTo(LinkedHashMap()) { it.doc.summary }.map { group -> |
| 35 | val (summary, items) = group |
| 36 | StringBuilder { |
| 37 | if (!summary.isEmpty()) { |
| 38 | append("${summary}<br>") |
| 39 | } |
| 40 | for (item in items) { |
| 41 | append(" `${signatureGenerator.render(item)}`<br>") |
| 42 | } |
| 43 | }.toString() |
| 44 | }.joinToString("<br>")) |
| 45 | appendln("|") |
Ilya Ryzhenkov | 68d3bc8 | 2014-07-14 19:34:52 +0400 | [diff] [blame] | 46 | } |
Ilya Ryzhenkov | cd7084d | 2014-07-14 21:15:04 +0400 | [diff] [blame] | 47 | } |
| 48 | |
| 49 | } |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | |
| 54 | private fun StringBuilder.formatLocation(nodes: Iterable<DocumentationNode>) { |
| 55 | val breakdown = nodes.groupByTo(LinkedHashMap()) { node -> |
| 56 | node.name |
| 57 | } |
| 58 | for ((name, items) in breakdown) { |
| 59 | appendln("# ${name}") |
| 60 | formatSummary(items) |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | private fun StringBuilder.formatSummary(nodes: Iterable<DocumentationNode>) { |
| 65 | val breakdown = nodes.groupByTo(LinkedHashMap()) { node -> |
| 66 | node.doc.summary |
| 67 | } |
| 68 | for ((summary, items) in breakdown) { |
| 69 | appendln(summary) |
| 70 | appendln("```") |
| 71 | for (item in items) |
| 72 | appendln(signatureGenerator.render(item)) |
| 73 | appendln("```") |
| 74 | } |
| 75 | |
| 76 | val described = nodes.filter { it.doc.hasDescription } |
| 77 | if (described.any()) { |
| 78 | appendln("## Description") |
| 79 | for (node in described) { |
| 80 | appendln("```") |
| 81 | appendln(signatureGenerator.render(node)) |
| 82 | appendln("```") |
| 83 | appendln(node.doc.description) |
| 84 | appendln() |
| 85 | for (section in node.doc.sections) { |
| 86 | append("**") |
| 87 | append(section.label) |
| 88 | append("**") |
| 89 | appendln() |
| 90 | append(section.text) |
| 91 | appendln() |
| 92 | appendln() |
Ilya Ryzhenkov | 69abe98 | 2014-07-14 18:38:22 +0400 | [diff] [blame] | 93 | } |
Ilya Ryzhenkov | a0bfdbd | 2014-07-14 15:00:33 +0400 | [diff] [blame] | 94 | } |
| 95 | } |
| 96 | } |
Ilya Ryzhenkov | cd7084d | 2014-07-14 21:15:04 +0400 | [diff] [blame] | 97 | |
Ilya Ryzhenkov | 68d3bc8 | 2014-07-14 19:34:52 +0400 | [diff] [blame] | 98 | } |