aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Jemerov <yole@jetbrains.com>2015-03-23 18:52:05 +0100
committerDmitry Jemerov <yole@jetbrains.com>2015-03-23 18:52:05 +0100
commit76e4d3cbc7cbbe1d35fb2e0c1ba59d3c86e0daf2 (patch)
treeefc5fc2e5dce290fbca9d55c12f0056b96735c3b
parent73bd875b621fedce84015c50b6954509f4978a6d (diff)
downloaddokka-76e4d3cbc7cbbe1d35fb2e0c1ba59d3c86e0daf2.tar.gz
dokka-76e4d3cbc7cbbe1d35fb2e0c1ba59d3c86e0daf2.tar.bz2
dokka-76e4d3cbc7cbbe1d35fb2e0c1ba59d3c86e0daf2.zip
parse included Markdown files to retrieve documentation for modules and packages
-rw-r--r--src/Formats/StructuredFormatService.kt28
-rw-r--r--src/Java/JavaDocumentationBuilder.kt2
-rw-r--r--src/Kotlin/ContentBuilder.kt6
-rw-r--r--src/Kotlin/DocumentationBuilder.kt5
-rw-r--r--src/Model/Content.kt2
-rw-r--r--src/Model/DocumentationNode.kt6
-rw-r--r--src/Model/PackageDocs.kt56
-rw-r--r--src/main.kt38
8 files changed, 107 insertions, 36 deletions
diff --git a/src/Formats/StructuredFormatService.kt b/src/Formats/StructuredFormatService.kt
index 233dd9e3..0ee3c888 100644
--- a/src/Formats/StructuredFormatService.kt
+++ b/src/Formats/StructuredFormatService.kt
@@ -84,12 +84,9 @@ public abstract class StructuredFormatService(locationService: LocationService,
append(formatLink(linkText, content.href))
}
}
- is ContentParagraph -> {
- appendParagraph(this, formatText(location, content.children))
- }
- is ContentBlockCode -> {
- appendBlockCode(this, formatText(location, content.children), content.language)
- }
+ is ContentParagraph -> appendParagraph(this, formatText(location, content.children))
+ is ContentBlockCode -> appendBlockCode(this, formatText(location, content.children), content.language)
+ is ContentHeading -> appendHeader(this, formatText(location, content.children), content.level)
is ContentBlock -> append(formatText(location, content.children))
}
}.toString()
@@ -133,6 +130,9 @@ public abstract class StructuredFormatService(locationService: LocationService,
}
}
+ private fun DocumentationNode.isModuleOrPackage(): Boolean =
+ kind == DocumentationNode.Kind.Module || kind == DocumentationNode.Kind.Package
+
protected open fun appendAsSignature(to: StringBuilder, block: () -> Unit) {
block()
}
@@ -206,10 +206,18 @@ public abstract class StructuredFormatService(locationService: LocationService,
}
fun appendLocation(location: Location, to: StringBuilder, nodes: Iterable<DocumentationNode>) {
- val breakdownByName = nodes.groupBy { node -> node.name }
- for ((name, items) in breakdownByName) {
- appendHeader(to, formatText(name))
- appendDocumentation(location, to, items)
+ val singleNode = nodes.singleOrNull()
+ if (singleNode != null && singleNode.isModuleOrPackage()) {
+ if (singleNode.kind == DocumentationNode.Kind.Package) {
+ appendHeader(to, "Package " + formatText(singleNode.name), 2)
+ }
+ to.append(formatText(location, singleNode.content))
+ } else {
+ val breakdownByName = nodes.groupBy { node -> node.name }
+ for ((name, items) in breakdownByName) {
+ appendHeader(to, formatText(name))
+ appendDocumentation(location, to, items)
+ }
}
}
diff --git a/src/Java/JavaDocumentationBuilder.kt b/src/Java/JavaDocumentationBuilder.kt
index 6624037c..d57210ae 100644
--- a/src/Java/JavaDocumentationBuilder.kt
+++ b/src/Java/JavaDocumentationBuilder.kt
@@ -14,7 +14,7 @@ public class JavaDocumentationBuilder(private val options: DocumentationOptions,
if (file.getClasses().all { skipElement(it) }) {
return
}
- val packageNode = module.findOrCreatePackageNode(file.getPackageName())
+ val packageNode = module.findOrCreatePackageNode(file.getPackageName(), emptyMap())
packageNode.appendChildren(file.getClasses()) { build() }
}
diff --git a/src/Kotlin/ContentBuilder.kt b/src/Kotlin/ContentBuilder.kt
index 742ac58b..f454c8fe 100644
--- a/src/Kotlin/ContentBuilder.kt
+++ b/src/Kotlin/ContentBuilder.kt
@@ -31,6 +31,12 @@ public fun buildContentTo(tree: MarkdownNode, target: ContentBlock, linkResolver
}
when (node.type) {
+ MarkdownElementTypes.ATX_1 -> appendNodeWithChildren(ContentHeading(1))
+ MarkdownElementTypes.ATX_2 -> appendNodeWithChildren(ContentHeading(2))
+ MarkdownElementTypes.ATX_3 -> appendNodeWithChildren(ContentHeading(3))
+ MarkdownElementTypes.ATX_4 -> appendNodeWithChildren(ContentHeading(4))
+ MarkdownElementTypes.ATX_5 -> appendNodeWithChildren(ContentHeading(5))
+ MarkdownElementTypes.ATX_6 -> appendNodeWithChildren(ContentHeading(6))
MarkdownElementTypes.UNORDERED_LIST -> appendNodeWithChildren(ContentUnorderedList())
MarkdownElementTypes.ORDERED_LIST -> appendNodeWithChildren(ContentOrderedList())
MarkdownElementTypes.LIST_ITEM -> appendNodeWithChildren(ContentListItem())
diff --git a/src/Kotlin/DocumentationBuilder.kt b/src/Kotlin/DocumentationBuilder.kt
index e193817a..8910c3e3 100644
--- a/src/Kotlin/DocumentationBuilder.kt
+++ b/src/Kotlin/DocumentationBuilder.kt
@@ -389,7 +389,8 @@ class DocumentationBuilder(val session: ResolveSession,
return this
}
- fun DocumentationNode.appendFragments(fragments: Collection<PackageFragmentDescriptor>) {
+ fun DocumentationModule.appendFragments(fragments: Collection<PackageFragmentDescriptor>,
+ packageContent: Map<String, Content>) {
val descriptors = hashMapOf<String, List<DeclarationDescriptor>>()
for ((name, parts) in fragments.groupBy { it.fqName }) {
descriptors.put(name.asString(), parts.flatMap { it.getMemberScope().getAllDescriptors() })
@@ -397,7 +398,7 @@ class DocumentationBuilder(val session: ResolveSession,
for ((packageName, declarations) in descriptors) {
if (options.skipEmptyPackages && declarations.none { it.isDocumented()}) continue
logger.info(" package $packageName: ${declarations.count()} declarations")
- val packageNode = findOrCreatePackageNode(packageName)
+ val packageNode = findOrCreatePackageNode(packageName, packageContent)
val externalClassNodes = hashMapOf<FqName, DocumentationNode>()
declarations.forEach { descriptor ->
if (descriptor.isDocumented()) {
diff --git a/src/Model/Content.kt b/src/Model/Content.kt
index 0244359e..30ec1fda 100644
--- a/src/Model/Content.kt
+++ b/src/Model/Content.kt
@@ -81,6 +81,8 @@ public class ContentUnorderedList() : ContentBlock()
public class ContentOrderedList() : ContentBlock()
public class ContentListItem() : ContentBlock()
+public class ContentHeading(val level: Int) : ContentBlock()
+
public class ContentSection(public val tag: String, public val subjectName: String?) : ContentBlock() {
override fun equals(other: Any?): Boolean =
super.equals(other) && other is ContentSection && tag == other.tag && subjectName == other.subjectName
diff --git a/src/Model/DocumentationNode.kt b/src/Model/DocumentationNode.kt
index 9e8a981f..6800abef 100644
--- a/src/Model/DocumentationNode.kt
+++ b/src/Model/DocumentationNode.kt
@@ -119,12 +119,14 @@ val DocumentationNode.path: List<DocumentationNode>
return parent.path + this
}
-fun DocumentationNode.findOrCreatePackageNode(packageName: String): DocumentationNode {
+fun DocumentationNode.findOrCreatePackageNode(packageName: String, packageContent: Map<String, Content>): DocumentationNode {
val existingNode = members(DocumentationNode.Kind.Package).firstOrNull { it.name == packageName }
if (existingNode != null) {
return existingNode
}
- val newNode = DocumentationNode(packageName, Content.Empty, DocumentationNode.Kind.Package)
+ val newNode = DocumentationNode(packageName,
+ packageContent.getOrElse(packageName) { Content.Empty },
+ DocumentationNode.Kind.Package)
append(newNode, DocumentationReference.Kind.Member)
return newNode
}
diff --git a/src/Model/PackageDocs.kt b/src/Model/PackageDocs.kt
new file mode 100644
index 00000000..3b0be547
--- /dev/null
+++ b/src/Model/PackageDocs.kt
@@ -0,0 +1,56 @@
+package org.jetbrains.dokka
+
+import org.intellij.markdown.MarkdownElementTypes
+import org.intellij.markdown.MarkdownTokenTypes
+import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
+import java.io.File
+
+public class PackageDocs(val documentationBuilder: DocumentationBuilder,
+ val linkResolveContext: DeclarationDescriptor?,
+ val logger: DokkaLogger) {
+ public val moduleContent: MutableContent = MutableContent()
+ private val _packageContent: MutableMap<String, MutableContent> = hashMapOf()
+ public val packageContent: Map<String, Content>
+ get() = _packageContent
+
+ fun parse(file: String) {
+ val file = File(file)
+ if (file.exists()) {
+ val text = file.readText()
+ val tree = parseMarkdown(text)
+ var targetContent: MutableContent = moduleContent
+ tree.children.forEach {
+ if (it.type == MarkdownElementTypes.ATX_1) {
+ val headingText = it.child(MarkdownTokenTypes.TEXT)?.text
+ if (headingText != null) {
+ targetContent = findTargetContent(headingText)
+ }
+ } else {
+ buildContentTo(it, targetContent, { resolveContentLink(it) })
+ }
+ }
+ } else {
+ logger.warn("Include file $file was not found.")
+ }
+ }
+
+ private fun findTargetContent(heading: String): MutableContent {
+ if (heading.startsWith("Module") || heading.startsWith("module")) {
+ return moduleContent
+ }
+ if (heading.startsWith("Package") || heading.startsWith("package")) {
+ return findOrCreatePackageContent(heading.substring("package".length()).trim())
+ }
+ return findOrCreatePackageContent(heading)
+ }
+
+ private fun findOrCreatePackageContent(packageName: String) =
+ _packageContent.getOrPut(packageName) { -> MutableContent() }
+
+ private fun resolveContentLink(href: String): ContentBlock {
+ if (linkResolveContext != null) {
+ return documentationBuilder.resolveContentLink(linkResolveContext, href)
+ }
+ return ContentExternalLink("#")
+ }
+} \ No newline at end of file
diff --git a/src/main.kt b/src/main.kt
index 8c7e936d..aa3da881 100644
--- a/src/main.kt
+++ b/src/main.kt
@@ -1,17 +1,21 @@
package org.jetbrains.dokka
-import com.sampullara.cli.*
-import com.intellij.openapi.util.*
-import org.jetbrains.kotlin.cli.common.messages.*
-import org.jetbrains.kotlin.cli.common.arguments.*
-import org.jetbrains.kotlin.utils.PathUtil
-import java.io.File
+import com.intellij.openapi.util.Disposer
+import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.psi.PsiFile
-import org.jetbrains.kotlin.cli.jvm.compiler.JetCoreEnvironment
import com.intellij.psi.PsiJavaFile
-import org.jetbrains.kotlin.config.CommonConfigurationKeys
import com.intellij.psi.PsiManager
-import com.intellij.openapi.vfs.VirtualFileManager
+import com.sampullara.cli.Args
+import com.sampullara.cli.Argument
+import org.jetbrains.kotlin.cli.common.arguments.ValueDescription
+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
+import org.jetbrains.kotlin.cli.common.messages.MessageCollector
+import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
+import org.jetbrains.kotlin.cli.jvm.compiler.JetCoreEnvironment
+import org.jetbrains.kotlin.config.CommonConfigurationKeys
+import org.jetbrains.kotlin.utils.PathUtil
+import java.io.File
class DokkaArguments {
Argument(value = "src", description = "Source file or directory (allows many paths separated by the system path separator)")
@@ -215,24 +219,16 @@ fun buildDocumentationModule(environment: AnalysisEnvironment,
val fragmentFiles = environment.getSourceFiles().filter(filesToDocumentFilter)
val fragments = fragmentFiles.map { session.getPackageFragment(it.getPackageFqName()) }.filterNotNull().distinct()
- val moduleContent = Content()
val refGraph = NodeReferenceGraph()
val documentationBuilder = DocumentationBuilder(session, options, refGraph, logger)
+ val packageDocs = PackageDocs(documentationBuilder, fragments.firstOrNull(), logger)
for (include in includes) {
- val file = File(include)
- if (file.exists()) {
- val text = file.readText()
- val tree = parseMarkdown(text)
- val content = buildContent(tree, {href -> documentationBuilder.resolveContentLink(fragments.first(), href)})
- moduleContent.children.addAll(content.children)
- } else {
- logger.warn("Include file $file was not found.")
- }
+ packageDocs.parse(include)
}
- val documentationModule = DocumentationModule(moduleName, moduleContent)
+ val documentationModule = DocumentationModule(moduleName, packageDocs.moduleContent)
with(documentationBuilder) {
- documentationModule.appendFragments(fragments)
+ documentationModule.appendFragments(fragments, packageDocs.packageContent)
}
val javaFiles = environment.getJavaSourceFiles().filter(filesToDocumentFilter)