{"id":21481979,"url":"https://github.com/jillesvangurp/kotlin4example","last_synced_at":"2026-04-07T15:32:46.264Z","repository":{"id":49744475,"uuid":"276942042","full_name":"jillesvangurp/kotlin4example","owner":"jillesvangurp","description":"Literate programming for Kotlin. Write markdown based documentation for your kotlin project with working examples.","archived":false,"fork":false,"pushed_at":"2025-08-11T08:21:15.000Z","size":385,"stargazers_count":22,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-08-11T10:19:50.600Z","etag":null,"topics":["kotlin","literate-programming","markdown"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jillesvangurp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-07-03T16:21:17.000Z","updated_at":"2025-08-11T08:20:38.000Z","dependencies_parsed_at":"2024-01-12T22:25:11.888Z","dependency_job_id":"2c0aec5e-39d3-4f82-b93b-2ae1a98fea41","html_url":"https://github.com/jillesvangurp/kotlin4example","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/jillesvangurp/kotlin4example","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jillesvangurp%2Fkotlin4example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jillesvangurp%2Fkotlin4example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jillesvangurp%2Fkotlin4example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jillesvangurp%2Fkotlin4example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jillesvangurp","download_url":"https://codeload.github.com/jillesvangurp/kotlin4example/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jillesvangurp%2Fkotlin4example/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31518554,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T03:10:19.677Z","status":"ssl_error","status_checked_at":"2026-04-07T03:10:13.982Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kotlin","literate-programming","markdown"],"created_at":"2024-11-23T12:29:26.093Z","updated_at":"2026-04-07T15:32:46.245Z","avatar_url":"https://github.com/jillesvangurp.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kotlin4Example\n\n[![](https://jitpack.io/v/jillesvangurp/kotlin4example.svg)](https://jitpack.io/#jillesvangurp/kotlin4example)\n[![Actions Status](https://github.com/jillesvangurp/kotlin4example/workflows/CI-gradle-build/badge.svg)](https://github.com/jillesvangurp/kotlin4example/actions)\n\nThis project implements [literate programming](https://en.wikipedia.org/wiki/Literate_programming) in Kotlin. Literate programming is useful\nfor documenting projects. Having working code in your documentation, ensures that the examples you include are correct \nand always up to date. And making it easy to include examples with your code lowers the barrier for writing good documentation.\n\nThis 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.\n\nWrite your documentation using a kotlin markdown DSL. Use simple `example { // code goes here }` blocks to provide examples. Kotlin4example will generate nice markdown with the code inside that block added as code blocks. See below for a detailed introduction.\n\nThis README is of course generated with kotlin4example.\n\n## Gradle\n\nAdd the dependency to your project and start writing some documentation. See below for some examples.\nI tend to put my documentation code in my tests so running the tests produces the documentation as a side effect. \n\n```kotlin\nimplementation(\"com.github.jillesvangurp:kotlin4example:\u003cversion\u003e\")\n```\n\nYou will also need to add the Jitpack repository:\n\n```kotlin\nrepositories {\n    mavenCentral()\n    maven { url = uri(\"https://jitpack.io\") }\n}\n```\n\n## Getting Started\n\nAfter adding this library to your (test) dependencies, you can start adding code \nto generate markdown. \n\n### Creating a SourceRepository\n\nThe first thing you need is a `SourceRepository` definition. This is needed to tell\nkotlin4example about your repository, where to link, and where your code is.\n\nSome of the functions in kotlin4example construct links to files in your github repository,\nor lookup code from files in your source code. \n\n```kotlin\nval k4ERepo = SourceRepository(\n  // used to construct markdown links to files in your repository\n  repoUrl = \"https://github.com/jillesvangurp/kotlin4example\",\n  // default is main\n  branch = \"master\",\n  // this is the default\n  sourcePaths = setOf(\n    \"src/main/kotlin\",\n    \"src/test/kotlin\"\n  )\n)\n```\n\n### Creating markdown\n\n```kotlin\nval myMarkdown = k4ERepo.md {\n  section(\"Introduction\")\n  +\"\"\"\n    Hello world!\n  \"\"\".trimIndent()\n}\nprintln(myMarkdown)\n```\n\nThis will generate some markdown that looks as follows.\n\n```markdown\n## Introduction\n\nHello world!\n\n\n```\n\n### Using your Markdown to create a page\n\nKotlin4example has a simple page abstraction that you\ncan use to organize your markdown content into pages and files\n\n```kotlin\nval page = Page(title = \"Hello!\", fileName = \"hello.md\")\n// creates hello.md\npage.write(myMarkdown)\n```\n\n### This README is generated\n\nThis README.md is of course created from kotlin code that \nruns as part of the test suite. You can look at the kotlin \nsource code that generates this markdown [here](https://github.com/jillesvangurp/kotlin4example/blob/master/src/test/kotlin/com/jillesvangurp/kotlin4example/docs/readme.kt).\n\nThe code that writes the `README.md file` is as follows:\n\n```kotlin\n/**\n * The readme is generated when the tests run.\n */\nclass DocGenTest {\n  @Test\n  fun `generate readme for this project`() {\n    val readmePage = Page(\n      title = \"Kotlin4Example\",\n      fileName = \"README.md\"\n    )\n    // readmeMarkdown is a lazy of the markdown content\n    readmePage.write(markdown = readmeMarkdown)\n  }\n}\n```\n\nHere'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). \n\nThe code that constructs the markdown is a bit longer, you can find it \n[here](https://github.com/jillesvangurp/kotlin4examplecom/jillesvangurp/kotlin4example/docs/readme.kt).\n\n## Example blocks\n\nWith Kotlin4Example you can mix examples and markdown easily. \nAn example is a Kotlin code block. Because it is a code block,\n you are forced to ensure it is syntactically correct and that it compiles. \n\nBy executing the block (you can disable this), you can further guarantee it does what it \nis supposed to and you can intercept output and integrate that into your \ndocumentation as well\n\nFor example:\n\n```kotlin\n// out is an ExampleOutput instance\n// with both stdout and the return\n// value as a Result\u003cT\u003e. Any exceptions\n// are captured as well.\nval out = example {\n  print(\"Hello World\")\n}\n// this is how you can append arbitrary markdown\n+\"\"\"\n  This example prints **${out.stdOut}** when it executes. \n\"\"\".trimIndent()\n```\n\nThe block you pass to example can be a suspending block; so you can create examples for \nyour co-routine libraries too. Kotlin4example uses `runBlocking` to run your examples.\n\nWhen you include the above in your Markdown it will render as follows:\n\n```kotlin\nprint(\"Hello World\")\n```\n\nThis example prints **Hello World** when it executes. \n\n### Configuring examples\n\nSometimes you just want to show but not run the code. You can control this with the \n`runExample` parameter.\n\n```kotlin\n//\nexample(\n  runExample = false,\n) {\n  // your code goes here\n  // but it won't run\n}\n```\n\nThe library imposes a default line length of 80 characters on your examples. The \nreason is that code blocks with long lines look ugly on web pages. E.g. Github will give \nyou a horizontal scrollbar.\n\nYou can of course turn this off or turn on the built in wrapping (wraps at the 80th character) \n\n```kotlin\n\n// making sure the example fits in a web page\n// long lines tend to look ugly in documentation\nexample(\n  // use longer line length\n  // default is 80\n  lineLength = 120,\n  // wrap lines that are too long\n  // default is false\n  wrap = true,\n  // don't fail on lines that are too long\n  // default is false\n  allowLongLines = true,\n\n  ) {\n  // your code goes here\n}\n```\n\n### Code snippets\n\nWhile it is nice to have executable blocks as examples, \nsometimes you just want to grab\ncode directly from some Kotlin file. You can do that with snippets.\n\n```kotlin\n// BEGIN_MY_CODE_SNIPPET\nprintln(\"Example code that shows in a snippet\")\n// END_MY_CODE_SNIPPET\n```\n\n```kotlin\nprintln(\"Example code that shows in a snippet\")\n```\n\nThe `BEGIN_` and `END_` prefix are optional but it helps readability.\n\nYou include the code in your markdown as follows:\n\n```kotlin\nexampleFromSnippet(\n  // relative path to your source file\n  // setup your source modules in the repository\n  sourceFileName = \"com/jillesvangurp/kotlin4example/docs/readme.kt\",\n  snippetId = \"MY_CODE_SNIPPET\"\n)\n```\n\n### Misc Markdown\n\n#### Simple markdown\n\nThis is how you can use the markdown dsl to generate markdown.\n\n## Section\n\n### Sub Section\n\nYou can use string literals, templates 2, \nand [links](https://github.com/jillesvangurp/kotlin4example)\nor other **markdown** formatting.\n\n#### Sub sub section\n\nThere's more\n\n- bullets\n- **bold**\n- *italic\n\n1. one\n2. two\n3. three\n\n\u003e The difference between code and poetry ...\n\u003e  \n\u003e ... poetry doesn’t need to compile.\n\n```kotlin\nsection(\"Section\") {\n  subSection(\"Sub Section\") {\n    +\"\"\"\n      You can use string literals, templates ${1 + 1}, \n      and [links](https://github.com/jillesvangurp/kotlin4example)\n      or other **markdown** formatting.\n    \"\"\".trimIndent()\n\n\n    subSubSection(\"Sub sub section\") {\n      +\"\"\"\n        There's more\n      \"\"\".trimIndent()\n\n      unorderedList(\"bullets\",\"**bold**\",\"*italic\")\n\n      orderedList(\"one\",\"two\",\"three\")\n\n      blockquote(\"\"\"\n        The difference between code and poetry ...\n         \n        ... poetry doesn’t need to compile.\n        \"\"\".trimIndent()\n      )\n\n    }\n  }\n}\n```\n\n#### Links\n\nLinking to different things in your repository.\n\n```kotlin\n\n// you can also just include markdown files\n// useful if you have a lot of markdown\n// content without code examples\nincludeMdFile(\"intro.md\")\n\n// link to things in your git repository\nmdLink(DocGenTest::class)\n\n// link to things in one of your source directories\n// you can customize where it looks in SourceRepository\nmdLinkToRepoResource(\n  title = \"A file\",\n  relativeUrl = \"com/jillesvangurp/kotlin4example/Kotlin4Example.kt\"\n)\n\nval anotherPage = Page(\"Page 2\", \"page2.md\")\n// link to another page in your manual\nmdPageLink(anotherPage)\n\n// and of course you can link to your self\nmdLinkToSelf(\"This class\")\n```\n\n#### Tables\n\nIncluding tables is easy if you don't want to manually format them.\n\n| Function             | Explanation                                      |\n| -------------------- | ------------------------------------------------ |\n| mdLink               | Add a link to a class or file in your repository |\n| mdLinkToRepoResource | Add a file in your repository                    |\n| includeMdFile        | include a markdown file                          |\n| example              | Example code block                               |\n\n```kotlin\ntable(listOf(\"Function\",\"Explanation\"),listOf(\n  listOf(\"mdLink\",\"Add a link to a class or file in your repository\"),\n  listOf(\"mdLinkToRepoResource\",\"Add a file in your repository\"),\n  listOf(\"includeMdFile\",\"include a markdown file\"),\n  listOf(\"example\",\"Example code block\"),\n))\n```\n\n### Source code blocks\n\nYou can add your own source code blocks as well.\n\n```kotlin\nmdCodeBlock(\n  code = \"\"\"\n    Useful if you have some **non kotlin code** that you want to show\n  \"\"\".trimIndent(),\n  type = \"markdown\"\n)\n```\n\nFor more elaborate examples of using this library, checkout my \n[kt-search](https://github.com/jillesvangurp/kt-search) project. That \nproject 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.\n\n## Why another documentation tool?\n\nWhen I started writing documentation for my [Kotlin Client for Elasticsearch](https://githubcom/jillesvangurp/es-kotlin-wrapper-client), I quickly discovered that keeping the\nexamples in the documentation working was a challenge. I'd refactor or rename something which then would invalidate\nall my examples. Staying on top of that is a lot of work.\n\nInstead of just using one of the many documentation tools out there that can grab chunks of source code based on\nsome 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.\n\nSo, 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.\n\nThere is of course more to this library. For more on that, check out the examples below. Which are of course generated with this library.\n\n## Projects that use kotlin4example\n\n- [kt-search](https://github.com/jillesvangurp/kt-search)\n- [kotlin-opencage-client](https://github.com/jillesvangurp/kotlin-opencage-client)\n- [json-dsl](https://github.com/jillesvangurp/json-dsl)\n\nCreate 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.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjillesvangurp%2Fkotlin4example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjillesvangurp%2Fkotlin4example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjillesvangurp%2Fkotlin4example/lists"}