diff --git a/README.md b/README.md index 3a1660a..a77555e 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ This project implements [literate programming](https://en.wikipedia.org/wiki/Lit for documenting projects. Having working code in your documentation, ensures that the examples you include are correct and always up to date. And making it easy to include examples with your code lowers the barrier for writing good documentation. +This library is intended for anyone that publishes some kind of Kotlin library or code and wants to document their code using Markdown files that contain working examples. + ## Get started Add the dependency to your project and start writing some documentation. See below for some examples. @@ -32,42 +34,112 @@ examples in the documentation working was a challenge. I'd refactor or rename so all my examples. Staying on top of that is a lot of work. Instead of just using one of the many documentation tools out there that can grab chunks of source code based on -some string marker, I instead came up with a better solution. +some string marker, I instead came up with a **better solution**: Kotlin4example implements a **Markdown Kotlin DSL** that includes a few nifty features, including an `example` function that takes an arbitrary block of Kotlin code and turns it into a markdown code block. -I wanted something that can leverage Kotlin's fantastic support for so-called internal DSLs. Like Ruby, you -can create domain specific languages using Kotlin's language features. In Kotlin, this works with regular functions -that take a block of code as a parameter. If such a parameter is the last one in a function, you can move the block outside -the parentheses. And if there are no other parameters those are optional. And then I realized that I could use -reflection to figure exactly from where the function call is made. This became the core -of what kotlin4example does. Any time you call example, it figures out from where in the code it is called and grabs the source -code in the block. +So, to write documentation, you simply use the DSL to write your documentation in Kotlin. You don't have to write all of it in Kotlin of course; it can include regular markdown files as well. But when writing examples, you just write them in Kotlin and the library turns them into markdown code blocks. -The library has a few other features, which are detailed in the examples below. But the simple idea is what -differentiates kotlin4example from other solutions. I'm not aware of any better or more convenient way to write -documentation for Kotlin libraries. +There is of course more to this library. For more on that, check out the examples below. Which are of course generated with this library. +## Getting Started -## Usage +After adding this library to your (test) dependencies, you can start adding code +to generate markdown. -### Example blocks +### Creating a SourceRepository -With Kotlin4Example you can mix examples and markdown easily. -An example is a code block -and it is executed by default. Because it is a code block, - you are forced to ensure -it is syntactically correct and compiles. +The first thing you need is a `SourceRepository` definition. This is needed to tell +kotlin4example about your repository. -By executing it, you can further guarantee it does what it -is supposed to and you can -intercept output and integrate that into your documentation. +Some of the functions in kotlin4example construct links to files in your github repository, +or lookup code from files in your source code. -For example: +```kotlin +val k4ERepo = SourceRepository( + // used to construct markdown links to files in your repository + repoUrl = "https://github.com/jillesvangurp/kotlin4example", + // default is main + branch = "master", + // this is the default + sourcePaths = setOf( + "src/main/kotlin", + "src/test/kotlin" + ) +) +``` + +### Creating markdown ```kotlin -print("Hello World") +val myMarkdown = k4ERepo.md { + section("Introduction") + +""" + Hello world! + """.trimIndent() +} +println(myMarkdown) ``` -This example prints **Hello World** when it executes. +This will generate some markdown that looks as follows. + +```markdown +## Introduction + +Hello world! + + +``` + +### Using your Markdown to create a page + +Kotlin4example has a simple page abstraction that you +can use to organize your markdown content into pages and files + +```kotlin +val page = Page(title = "Hello!", fileName = "hello.md") +// creates hello.md +page.write(myMarkdown) +``` + +### This README is generated + +This README.md is of course created from kotlin code that +runs as part of the test suite. You can look at the kotlin +source code that generates this markdown [here](https://github.com/jillesvangurp/kotlin4example/blob/master/src/test/kotlin/com/jillesvangurp/kotlin4example/docs/readme.kt). + +The code that writes the `README.md file` is as follows: + +```kotlin +/** + * The readme is generated when the tests run. + */ +class DocGenTest { + @Test + fun `generate readme for this project`() { + val readmePage = Page( + title = "Kotlin4Example", + fileName = "README.md" + ) + // readmeMarkdown is a lazy of the markdown content + readmePage.write(markdown = readmeMarkdown) + } +} +``` + +Here's a link to the source code on Github: [`DocGenTest`](https://github.com/jillesvangurp/kotlin4example/blob/master/src/test/kotlin/com/jillesvangurp/kotlin4example/DocGenTest.kt) + +## Usage + +### Example blocks + +With Kotlin4Example you can mix examples and markdown easily. +An example is a Kotlin code block. Because it is a code block, + you are forced to ensure it is syntactically correct and that it compiles. + +By executing the block (you can disable this), you can further guarantee it does what it +is supposed to and you can intercept output and integrate that into your +documentation as well + +For example: ```kotlin // out is an ExampleOutput instance @@ -83,8 +155,16 @@ val out = example { """.trimIndent() ``` -The block you pass to example can be a suspending block. It uses `runBlocking` to run it. Earlier -versions of this library had a separate function for this; this is no longer needed. +The block you pass to example can be a suspending block; so you can create examples for +your co-routine libraries too. Kotlin4example uses `runBlocking` to run your examples. + +When you include the above in your Markdown it will render as follows: + +```kotlin +print("Hello World") +``` + +This example prints **Hello World** when it executes. ### Configuring examples @@ -97,11 +177,13 @@ example( runExample = false, ) { // your code goes here + // but it won't run } ``` -The library imposes a line length of 80 characters on your examples. The -reason is that code blocks with horizontal scroll bars look ugly. +The library imposes a default line length of 80 characters on your examples. The +reason is that code blocks with long lines look ugly on web pages. E.g. Github will give +you a horizontal scrollbar. You can of course turn this off or turn on the built in wrapping (wraps at the 80th character) @@ -110,10 +192,13 @@ You can of course turn this off or turn on the built in wrapping (wraps at the 8 // making sure the example fits in a web page // long lines tend to look ugly in documentation example( + // use longer line length // default is 80 lineLength = 120, + // wrap lines that are too long // default is false wrap = true, + // don't fail on lines that are too long // default is false allowLongLines = true, @@ -124,37 +209,67 @@ example( ### Code snippets -While it is nice to have executable blocks, +While it is nice to have executable blocks as examples, sometimes you just want to grab -code directly from a file. You can do that with snippets. +code directly from some Kotlin file. You can do that with snippets. ```kotlin -// the BEGIN_ and END_ are optional but I find it -// helps for readability. // BEGIN_MY_CODE_SNIPPET println("Example code that shows in a snippet") // END_MY_CODE_SNIPPET -exampleFromSnippet("readme.kt", "MY_CODE_SNIPPET") ``` -### Markdown +```kotlin +println("Example code that shows in a snippet") +``` + +The `BEGIN_` and `END_` prefix are optional but I find it helps readability. + +You include the code in your markdown as follows: + +```kotlin +exampleFromSnippet( + sourceFileName = "com/jillesvangurp/kotlin4example/docs/readme.kt", + snippetId = "MY_CODE_SNIPPET" +) +``` + +### Misc Markdown ```kotlin section("Section") { - +""" - You can use string literals, templates ${1 + 1}, - and [links](https://github.com/jillesvangurp/kotlin4example) - or other markdown formatting. - """.trimIndent() + subSection("Sub Section") { + +""" + You can use string literals, templates ${1 + 1}, + and [links](https://github.com/jillesvangurp/kotlin4example) + or other markdown formatting. + """.trimIndent() + } +} +section("Links") { + + // you can also just include markdown files + // useful if you have a lot of markdown + // content without code examples + includeMdFile("intro.md") + + // link to things in your git repository + mdLink(DocGenTest::class) + + // link to things in one of your source directories + // you can customize where it looks in SourceRepository + mdLinkToRepoResource( + title = "A file", + relativeUrl = "com/jillesvangurp/kotlin4example/Kotlin4Example.kt" + ) + + val anotherPage = Page("Page 2", "page2.md") + // link to another page in your manual + mdPageLink(anotherPage) + + // and of course you can link to your self + mdLinkToSelf("This class") } -// you can also just include markdown files -// useful if you have a lot of markdown -// content without code examples -includeMdFile("intro.md") -// link to things in your git repository -mdLink(DocGenTest::class) -mdLinkToRepoResource("build file", "build.gradle.kts") -mdLinkToSelf("This class") ``` ### Source code blocks @@ -170,27 +285,11 @@ mdCodeBlock( ) ``` -### This README is generated +## Advanced topics -This README.md is of course created from kotlin code that -runs as part of the test suite. You can look at the kotlin -source code that generates this markdown [here](https://github.com/jillesvangurp/kotlin4example/blob/master/src/test/kotlin/com/jillesvangurp/kotlin4example/docs/readme.kt). +### Organizing pages -The code that writes the `README.md file` is as follows: - -```kotlin -/** - * The readme is generated when the tests run. - */ -class DocGenTest { - @Test - fun `generate readme for this project`() { - val readmePage = Page("Kotlin4Example", fileName = "README.md") - // readmeMarkdown is a lazy of the markdown content - readmePage.write(markdown = readmeMarkdown) - } -} -``` +A manual typically contains multiple pages. So, it helps to get organized a little. ### Context receivers @@ -229,7 +328,13 @@ kotlin { For more elaborate examples of using this library, checkout my [kt-search](https://github.com/jillesvangurp/kt-search) project. That -project is where this project emerged from and all markdown in that project is generated by kotlin4example. Give it a -try on one of your own projects and let me know what you think. +project is where this project emerged from and all markdown in that project is generated by kotlin4example. Give it a try on one of your own projects and let me know what you think. + +## Projects that use kotlin4example + +- [kt-search](https://github.com/jillesvangurp/kt-search) +- [kotlin-opencage-client](https://github.com/jillesvangurp/kotlin-opencage-client) +- [json-dsl](https://github.com/jillesvangurp/json-dsl) +Create a pull request against [outro.md](https://github.com/jillesvangurp/kotlin4example/blob/master/src/test/kotlin/com/jillesvangurp/kotlin4example/docs/outro.md) if you want to add your project here. diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d64cd49..e644113 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a80b22c..9355b41 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew.bat b/gradlew.bat index 93e3f59..25da30d 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -43,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail diff --git a/src/main/kotlin/com/jillesvangurp/kotlin4example/Kotlin4Example.kt b/src/main/kotlin/com/jillesvangurp/kotlin4example/Kotlin4Example.kt index 1bf0d02..88e0d41 100644 --- a/src/main/kotlin/com/jillesvangurp/kotlin4example/Kotlin4Example.kt +++ b/src/main/kotlin/com/jillesvangurp/kotlin4example/Kotlin4Example.kt @@ -11,8 +11,11 @@ import kotlin.reflect.KClass private val logger: KLogger = KotlinLogging.logger { } fun mdLink(title: String, target: String) = "[$title]($target)" +@Deprecated("use mdPageLink", ReplaceWith("mdPageLink")) fun mdLink(page: Page) = mdLink(page.title, page.fileName) +fun mdPageLink(page: Page) = mdLink(page.title, page.fileName) + fun md(sourceRepository: SourceRepository, block: Kotlin4Example.() -> Unit) = lazyOf(Kotlin4Example.markdown(sourceRepository, block)) diff --git a/src/test/kotlin/com/jillesvangurp/kotlin4example/DocGenTest.kt b/src/test/kotlin/com/jillesvangurp/kotlin4example/DocGenTest.kt index fdeddf7..3f0dacf 100644 --- a/src/test/kotlin/com/jillesvangurp/kotlin4example/DocGenTest.kt +++ b/src/test/kotlin/com/jillesvangurp/kotlin4example/DocGenTest.kt @@ -10,7 +10,10 @@ import org.junit.jupiter.api.Test class DocGenTest { @Test fun `generate readme for this project`() { - val readmePage = Page("Kotlin4Example", fileName = "README.md") + val readmePage = Page( + title = "Kotlin4Example", + fileName = "README.md" + ) // readmeMarkdown is a lazy of the markdown content readmePage.write(markdown = readmeMarkdown) } diff --git a/src/test/kotlin/com/jillesvangurp/kotlin4example/docs/intro.md b/src/test/kotlin/com/jillesvangurp/kotlin4example/docs/intro.md index 6218002..cc4663c 100644 --- a/src/test/kotlin/com/jillesvangurp/kotlin4example/docs/intro.md +++ b/src/test/kotlin/com/jillesvangurp/kotlin4example/docs/intro.md @@ -5,6 +5,8 @@ This project implements [literate programming](https://en.wikipedia.org/wiki/Lit for documenting projects. Having working code in your documentation, ensures that the examples you include are correct and always up to date. And making it easy to include examples with your code lowers the barrier for writing good documentation. +This library is intended for anyone that publishes some kind of Kotlin library or code and wants to document their code using Markdown files that contain working examples. + ## Get started Add the dependency to your project and start writing some documentation. See below for some examples. @@ -30,17 +32,8 @@ examples in the documentation working was a challenge. I'd refactor or rename so all my examples. Staying on top of that is a lot of work. Instead of just using one of the many documentation tools out there that can grab chunks of source code based on -some string marker, I instead came up with a better solution. - -I wanted something that can leverage Kotlin's fantastic support for so-called internal DSLs. Like Ruby, you -can create domain specific languages using Kotlin's language features. In Kotlin, this works with regular functions -that take a block of code as a parameter. If such a parameter is the last one in a function, you can move the block outside -the parentheses. And if there are no other parameters those are optional. And then I realized that I could use -reflection to figure exactly from where the function call is made. This became the core -of what kotlin4example does. Any time you call example, it figures out from where in the code it is called and grabs the source -code in the block. +some string marker, I instead came up with a **better solution**: Kotlin4example implements a **Markdown Kotlin DSL** that includes a few nifty features, including an `example` function that takes an arbitrary block of Kotlin code and turns it into a markdown code block. -The library has a few other features, which are detailed in the examples below. But the simple idea is what -differentiates kotlin4example from other solutions. I'm not aware of any better or more convenient way to write -documentation for Kotlin libraries. +So, to write documentation, you simply use the DSL to write your documentation in Kotlin. You don't have to write all of it in Kotlin of course; it can include regular markdown files as well. But when writing examples, you just write them in Kotlin and the library turns them into markdown code blocks. +There is of course more to this library. For more on that, check out the examples below. Which are of course generated with this library. diff --git a/src/test/kotlin/com/jillesvangurp/kotlin4example/docs/outro.md b/src/test/kotlin/com/jillesvangurp/kotlin4example/docs/outro.md index 541aa5f..2a91ab4 100644 --- a/src/test/kotlin/com/jillesvangurp/kotlin4example/docs/outro.md +++ b/src/test/kotlin/com/jillesvangurp/kotlin4example/docs/outro.md @@ -1,5 +1,11 @@ For more elaborate examples of using this library, checkout my [kt-search](https://github.com/jillesvangurp/kt-search) project. That -project is where this project emerged from and all markdown in that project is generated by kotlin4example. Give it a -try on one of your own projects and let me know what you think. +project is where this project emerged from and all markdown in that project is generated by kotlin4example. Give it a try on one of your own projects and let me know what you think. +## Projects that use kotlin4example + +- [kt-search](https://github.com/jillesvangurp/kt-search) +- [kotlin-opencage-client](https://github.com/jillesvangurp/kotlin-opencage-client) +- [json-dsl](https://github.com/jillesvangurp/json-dsl) + +Create a pull request against [outro.md](https://github.com/jillesvangurp/kotlin4example/blob/master/src/test/kotlin/com/jillesvangurp/kotlin4example/docs/outro.md) if you want to add your project here. diff --git a/src/test/kotlin/com/jillesvangurp/kotlin4example/docs/readme.kt b/src/test/kotlin/com/jillesvangurp/kotlin4example/docs/readme.kt index 0d9728e..61d97d3 100644 --- a/src/test/kotlin/com/jillesvangurp/kotlin4example/docs/readme.kt +++ b/src/test/kotlin/com/jillesvangurp/kotlin4example/docs/readme.kt @@ -1,32 +1,111 @@ package com.jillesvangurp.kotlin4example.docs import com.jillesvangurp.kotlin4example.DocGenTest +import com.jillesvangurp.kotlin4example.Page import com.jillesvangurp.kotlin4example.SourceRepository +import com.jillesvangurp.kotlin4example.mdPageLink -val k4ERepo = SourceRepository("https://github.com/jillesvangurp/kotlin4example", branch = "master") +// BEGIN_REPO_DEFINITION +val k4ERepo = SourceRepository( + // used to construct markdown links to files in your repository + repoUrl = "https://github.com/jillesvangurp/kotlin4example", + // default is main + branch = "master", + // this is the default + sourcePaths = setOf( + "src/main/kotlin", + "src/test/kotlin" + ) +) +// END_REPO_DEFINITION val readmeMarkdown by k4ERepo.md { // for larger bits of text, it's nice to load them from a markdown file includeMdFile("intro.md") + section("Getting Started") { + +""" + After adding this library to your (test) dependencies, you can start adding code + to generate markdown. + """.trimIndent() + + subSection("Creating a SourceRepository") { + + +""" + The first thing you need is a `SourceRepository` definition. This is needed to tell + kotlin4example about your repository. + + Some of the functions in kotlin4example construct links to files in your github repository, + or lookup code from files in your source code. + """.trimIndent() + + exampleFromSnippet("com/jillesvangurp/kotlin4example/docs/readme.kt", "REPO_DEFINITION") + } + subSection("Creating markdown") { + + """ + Once you have a repository, you can use it to create some Markdown via an extension function: + """.trimIndent() + + example { + val myMarkdown = k4ERepo.md { + section("Introduction") + +""" + Hello world! + """.trimIndent() + } + println(myMarkdown) + }.let { + +""" + This will generate some markdown that looks as follows. + """.trimIndent() + mdCodeBlock(code = it.stdOut, type = "markdown") + } + } + subSection("Using your Markdown to create a page") { + +""" + Kotlin4example has a simple page abstraction that you + can use to organize your markdown content into pages and files + """.trimIndent() + + val myMarkdown= "ignore" + example(runExample = false) { + val page = Page(title = "Hello!", fileName = "hello.md") + // creates hello.md + page.write(myMarkdown) + } + } + + subSection("This README is generated") { + +""" + This README.md is of course created from kotlin code that + runs as part of the test suite. You can look at the kotlin + source code that generates this markdown ${mdLinkToSelf("here")}. + + The code that writes the `README.md file` is as follows: + """.trimIndent() + exampleFromSnippet(DocGenTest::class, "READMEWRITE") + +""" + Here's a link to the source code on Github: ${mdLink(DocGenTest::class)} + """.trimIndent() + } + } section("Usage") { subSection("Example blocks") { +""" With Kotlin4Example you can mix examples and markdown easily. - An example is a code block - and it is executed by default. Because it is a code block, - you are forced to ensure - it is syntactically correct and compiles. + An example is a Kotlin code block. Because it is a code block, + you are forced to ensure it is syntactically correct and that it compiles. - By executing it, you can further guarantee it does what it - is supposed to and you can - intercept output and integrate that into your documentation. + By executing the block (you can disable this), you can further guarantee it does what it + is supposed to and you can intercept output and integrate that into your + documentation as well For example: """.trimIndent() // a bit of kotlin4example inception here, but it works - example { + example(runExample = false) { // out is an ExampleOutput instance // with both stdout and the return // value as a Result. Any exceptions @@ -40,9 +119,20 @@ val readmeMarkdown by k4ERepo.md { """.trimIndent() } +""" - The block you pass to example can be a suspending block. It uses `runBlocking` to run it. Earlier - versions of this library had a separate function for this; this is no longer needed. + The block you pass to example can be a suspending block; so you can create examples for + your co-routine libraries too. Kotlin4example uses `runBlocking` to run your examples. + + When you include the above in your Markdown it will render as follows: """.trimIndent() + + example { + print("Hello World") + }.let { out -> + // this is how you can append arbitrary markdown + +""" + This example prints **${out.stdOut}** when it executes. + """.trimIndent() + } } subSection("Configuring examples") { @@ -57,11 +147,13 @@ val readmeMarkdown by k4ERepo.md { runExample = false, ) { // your code goes here + // but it won't run } } +""" - The library imposes a line length of 80 characters on your examples. The - reason is that code blocks with horizontal scroll bars look ugly. + The library imposes a default line length of 80 characters on your examples. The + reason is that code blocks with long lines look ugly on web pages. E.g. Github will give + you a horizontal scrollbar. You can of course turn this off or turn on the built in wrapping (wraps at the 80th character) @@ -71,10 +163,13 @@ val readmeMarkdown by k4ERepo.md { // making sure the example fits in a web page // long lines tend to look ugly in documentation example( + // use longer line length // default is 80 lineLength = 120, + // wrap lines that are too long // default is false wrap = true, + // don't fail on lines that are too long // default is false allowLongLines = true, @@ -83,41 +178,71 @@ val readmeMarkdown by k4ERepo.md { } } } + subSection("Code snippets") { +""" - While it is nice to have executable blocks, + While it is nice to have executable blocks as examples, sometimes you just want to grab - code directly from a file. You can do that with snippets. + code directly from some Kotlin file. You can do that with snippets. """.trimIndent() example { - // the BEGIN_ and END_ are optional but I find it - // helps for readability. // BEGIN_MY_CODE_SNIPPET println("Example code that shows in a snippet") // END_MY_CODE_SNIPPET - exampleFromSnippet("readme.kt", "MY_CODE_SNIPPET") + } + // little hack to avoid picking up this line ;-) + exampleFromSnippet("com/jillesvangurp/kotlin4example/docs/readme.kt","MY_" + "CODE_SNIPPET") + +""" + The `BEGIN_` and `END_` prefix are optional but I find it helps readability. + + You include the code in your markdown as follows: + """.trimIndent() + + example(runExample = false) { + exampleFromSnippet( + sourceFileName = "com/jillesvangurp/kotlin4example/docs/readme.kt", + snippetId = "MY_CODE_SNIPPET" + ) } } - subSection("Markdown") { + subSection("Misc Markdown") { // you can use our Kotlin DSL to structure your documentation. example(runExample = false) { section("Section") { - +""" - You can use string literals, templates ${1 + 1}, - and [links](https://github.com/jillesvangurp/kotlin4example) - or other markdown formatting. - """.trimIndent() + subSection("Sub Section") { + +""" + You can use string literals, templates ${1 + 1}, + and [links](https://github.com/jillesvangurp/kotlin4example) + or other markdown formatting. + """.trimIndent() + } + } + section("Links") { + + // you can also just include markdown files + // useful if you have a lot of markdown + // content without code examples + includeMdFile("intro.md") + + // link to things in your git repository + mdLink(DocGenTest::class) + + // link to things in one of your source directories + // you can customize where it looks in SourceRepository + mdLinkToRepoResource( + title = "A file", + relativeUrl = "com/jillesvangurp/kotlin4example/Kotlin4Example.kt" + ) + + val anotherPage = Page("Page 2", "page2.md") + // link to another page in your manual + mdPageLink(anotherPage) + + // and of course you can link to your self + mdLinkToSelf("This class") } - // you can also just include markdown files - // useful if you have a lot of markdown - // content without code examples - includeMdFile("intro.md") - // link to things in your git repository - mdLink(DocGenTest::class) - mdLinkToRepoResource("build file", "build.gradle.kts") - mdLinkToSelf("This class") } } subSection("Source code blocks") { @@ -133,15 +258,14 @@ val readmeMarkdown by k4ERepo.md { ) } } - subSection("This README is generated") { + } + + section("Advanced topics") { + subSection("Organizing pages") { +""" - This README.md is of course created from kotlin code that - runs as part of the test suite. You can look at the kotlin - source code that generates this markdown ${mdLinkToSelf("here")}. - - The code that writes the `README.md file` is as follows: + A manual typically contains multiple pages. So, it helps to get organized a little. """.trimIndent() - exampleFromSnippet(DocGenTest::class, "READMEWRITE") + } subSection("Context receivers") { diff --git a/versions.properties b/versions.properties index adcc24c..16cd106 100644 --- a/versions.properties +++ b/versions.properties @@ -7,42 +7,41 @@ #### suppress inspection "SpellCheckingInspection" for whole file #### suppress inspection "UnusedProperty" for whole file -plugin.org.jetbrains.dokka=1.9.10 +plugin.org.jetbrains.dokka=1.9.20 -version.kotlinx.coroutines=1.8.0 +version.kotlinx.coroutines=1.8.1 +## # available=1.9.0-RC +## # available=1.9.0-RC.2 -version.org.slf4j..slf4j-api=2.0.12 +version.org.slf4j..slf4j-api=2.0.16 ## # available=2.1.0-alpha0 ## # available=2.1.0-alpha1 -version.org.slf4j..log4j-over-slf4j=2.0.12 +version.org.slf4j..log4j-over-slf4j=2.0.16 ## # available=2.1.0-alpha0 ## # available=2.1.0-alpha1 -version.org.slf4j..jul-to-slf4j=2.0.12 +version.org.slf4j..jul-to-slf4j=2.0.16 ## # available=2.1.0-alpha0 ## # available=2.1.0-alpha1 -version.org.slf4j..jcl-over-slf4j=2.0.12 +version.org.slf4j..jcl-over-slf4j=2.0.16 ## # available=2.1.0-alpha0 ## # available=2.1.0-alpha1 -version.org.apache.logging.log4j..log4j-to-slf4j=2.22.1 +version.org.apache.logging.log4j..log4j-to-slf4j=2.23.1 ## # available=3.0.0-alpha1 ## # available=3.0.0-beta1 +## # available=3.0.0-beta2 -version.kotlin=1.9.22 -## # available=2.0.0-Beta1 -## # available=2.0.0-Beta2 -## # available=2.0.0-Beta3 -## # available=2.0.0-Beta4 +version.kotlin=2.0.20 -version.kotest=5.8.0 +version.kotest=5.9.1 -version.junit.jupiter=5.10.2 +version.junit.jupiter=5.11.0 version.io.github.microutils..kotlin-logging=3.0.5 ## # available=4.0.0-beta-1 ## # available=4.0.0-beta-2 -version.ch.qos.logback..logback-classic=1.5.0 +version.ch.qos.logback..logback-classic=1.5.7