├── website ├── static │ ├── .nojekyll │ └── img │ │ ├── dino.png │ │ ├── favicon.ico │ │ ├── docusaurus.png │ │ └── docusaurus-social-card.jpg ├── bun.lockb ├── babel.config.js ├── src │ ├── components │ │ └── HomepageFeatures │ │ │ ├── styles.module.css │ │ │ └── index.js │ ├── pages │ │ ├── index.module.css │ │ └── index.js │ └── css │ │ ├── custom.css │ │ └── docusaurus-openapi-docs.css ├── .gitignore ├── README.md ├── package.json └── sidebars.js ├── examples ├── .gitignore ├── antora │ ├── .gitignore │ ├── bun.lockb │ ├── deps.edn │ ├── bb.edn │ ├── package.json │ ├── src │ │ └── example │ │ │ └── main.clj │ ├── doc.clj │ ├── antora.yml │ ├── antora-playbook.yml │ └── README.md ├── javadoc │ ├── .gitignore │ ├── deps.edn │ ├── README.md │ └── doc.clj ├── rust │ ├── .gitignore │ ├── src │ │ ├── greeting.rs │ │ └── main.rs │ ├── Cargo.lock │ ├── deps.edn │ ├── README.md │ ├── Cargo.toml │ └── doc.clj ├── ts │ ├── src │ │ ├── index.ts │ │ ├── app.ts │ │ └── greeter.ts │ ├── test │ │ └── greeter.test.ts │ ├── readme.ts │ └── README.md ├── kotlin │ ├── shell.nix │ ├── deps.edn │ ├── doc.clj │ ├── src │ │ └── main │ │ │ └── kotlin │ │ │ └── demo │ │ │ ├── Greeter.kt │ │ │ └── Main.kt │ └── README.md ├── contextive │ ├── deps.edn │ ├── README.md │ ├── doc.clj │ └── .contextive │ │ └── definitions.yml ├── java │ ├── doc.clj │ ├── src │ │ └── main │ │ │ └── java │ │ │ └── demo │ │ │ ├── Main.java │ │ │ └── Greeter.java │ ├── deps.edn │ └── README.md ├── multi │ ├── deps.edn │ ├── README.md │ └── doc.clj ├── structurizr │ ├── deps.edn │ ├── README.md │ └── doc.clj ├── polylith │ ├── deps.edn │ └── doc.clj ├── promesa │ ├── deps.edn │ └── doc.clj ├── reitit │ ├── deps.edn │ └── doc.clj ├── ring │ ├── deps.edn │ └── doc.clj ├── contextmapper │ ├── deps.edn │ ├── doc.clj │ └── README.md ├── openapi │ ├── doc.clj │ ├── deps.edn │ ├── README.md │ └── reitit.json ├── dbschema │ ├── deps.edn │ ├── README.md │ └── doc.clj └── statecharts │ ├── deps.edn │ ├── doc.clj │ └── src │ └── example │ └── statecharts.clj ├── components ├── statecharts │ ├── deps.edn │ ├── README.md │ ├── test │ │ └── src │ │ │ └── dinodoc │ │ │ └── statecharts │ │ │ ├── statecharts_test.clj │ │ │ └── example_test.clj │ └── src │ │ └── dinodoc │ │ └── statecharts.clj ├── antora │ ├── deps.edn │ ├── src │ │ └── dinodoc │ │ │ ├── antora.clj │ │ │ └── antora │ │ │ └── impl.clj │ ├── README.md │ └── test │ │ └── src │ │ └── dinodoc │ │ └── antora_test.clj ├── contextmapper │ ├── test │ │ ├── resources │ │ │ ├── minimal.cml │ │ │ └── example.cml │ │ ├── output │ │ │ ├── example │ │ │ │ ├── domains │ │ │ │ │ ├── BlankDomain │ │ │ │ │ │ └── index.md │ │ │ │ │ ├── _category_.json │ │ │ │ │ └── DomainA │ │ │ │ │ │ └── index.md │ │ │ │ ├── teams │ │ │ │ │ ├── _category_.json │ │ │ │ │ └── index.md │ │ │ │ ├── contexts │ │ │ │ │ ├── _category_.json │ │ │ │ │ ├── ContextA │ │ │ │ │ │ ├── index.md │ │ │ │ │ │ └── diagram.svg │ │ │ │ │ └── ContextB │ │ │ │ │ │ ├── index.md │ │ │ │ │ │ └── diagram.svg │ │ │ │ ├── index.md │ │ │ │ └── context-mapExampleMap.svg │ │ │ └── minimal │ │ │ │ ├── index.md │ │ │ │ └── context-mapMinimal.svg │ │ └── src │ │ │ └── dinodoc │ │ │ └── contextmapper_test.clj │ ├── deps.edn │ └── src │ │ └── dinodoc │ │ └── contextmapper.clj ├── structurizr │ ├── test │ │ ├── output │ │ │ ├── json-big-bank-plc │ │ │ │ ├── systems │ │ │ │ │ ├── ATM-6 │ │ │ │ │ │ └── index.md │ │ │ │ │ └── index.md │ │ │ │ └── index.md │ │ │ └── dsl-getting-started │ │ │ │ ├── index.md │ │ │ │ └── Software System-2 │ │ │ │ └── index.md │ │ └── src │ │ │ └── dinodoc │ │ │ └── structurizr_test.clj │ ├── deps.edn │ ├── src │ │ └── dinodoc │ │ │ └── structurizr.clj │ └── README.md └── dokka │ ├── deps.edn │ ├── README.md │ └── src │ └── dinodoc │ └── dokka.clj ├── test ├── output │ ├── docs │ │ ├── api │ │ │ ├── _category_.json │ │ │ ├── codox │ │ │ │ ├── import │ │ │ │ │ └── index.md │ │ │ │ ├── example2 │ │ │ │ │ ├── core │ │ │ │ │ │ └── index.md │ │ │ │ │ └── index.md │ │ │ │ ├── markdown │ │ │ │ │ └── index.md │ │ │ │ ├── example3 │ │ │ │ │ └── index.md │ │ │ │ └── example │ │ │ │ │ └── index.md │ │ │ ├── samples │ │ │ │ ├── crossplatform-mixed │ │ │ │ │ └── index.md │ │ │ │ ├── crossplatform │ │ │ │ │ └── index.md │ │ │ │ ├── protocols │ │ │ │ │ └── index.md │ │ │ │ └── source │ │ │ │ │ └── index.md │ │ │ └── promesa │ │ │ │ ├── exec │ │ │ │ ├── semaphore │ │ │ │ │ └── index.md │ │ │ │ └── bulkhead │ │ │ │ │ └── index.md │ │ │ │ └── util │ │ │ │ └── index.md │ │ ├── example │ │ │ ├── intro.md │ │ │ └── index.md │ │ └── promesa │ │ │ ├── contributing.md │ │ │ └── bulkhead-concurrency-limiter.md │ └── machines.md ├── resources │ └── contextive │ │ ├── output │ │ ├── glossary │ │ │ ├── index.md │ │ │ └── ContextA │ │ │ │ └── index.md │ │ └── index.md │ │ ├── README.md │ │ └── definitions.yml ├── projects │ └── samples │ │ └── src │ │ └── samples │ │ ├── crossplatform.clj │ │ ├── crossplatform.cljs │ │ ├── crossplatform_mixed.cljc │ │ ├── protocols.clj │ │ └── source.clj └── src │ └── dinodoc │ ├── approval_helpers.clj │ ├── contextive_test.clj │ ├── rustdoc_test.clj │ ├── fs_helpers_test.clj │ ├── tbls_test.clj │ ├── impl │ ├── git_test.clj │ ├── linking_test.clj │ └── core_test.clj │ ├── fs_helpers.clj │ └── javadoc_test.clj ├── experiments ├── antora │ ├── .gitignore │ ├── experiments │ │ ├── modules │ │ │ ├── ROOT │ │ │ │ ├── pages │ │ │ │ │ ├── apidir │ │ │ │ │ │ └── foo.adoc │ │ │ │ │ ├── nested │ │ │ │ │ │ └── page.adoc │ │ │ │ │ └── index.adoc │ │ │ │ └── attachments │ │ │ │ │ └── foo3.html │ │ │ └── apimod │ │ │ │ └── pages │ │ │ │ └── foo2.adoc │ │ └── antora.yml │ ├── bun.lockb │ ├── deps.edn │ ├── package.json │ ├── examples │ │ └── antora.yml │ ├── README.md │ ├── bb.edn │ ├── doc.clj │ ├── tmp.js │ ├── apilink-extension.js │ └── antora-playbook.yml ├── stack-graphs │ ├── deps.edn │ ├── shell.nix │ ├── dumper │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ ├── README.md │ └── src │ │ └── dinodoc │ │ └── stack_graphs │ │ └── main.clj └── tree-sitter │ ├── README.md │ ├── deps.edn │ └── src │ └── dinodoc │ └── tree_sitter │ └── main.clj ├── doc └── cljdoc.edn ├── .gitignore ├── .clj-kondo └── config.edn ├── src ├── dinodoc │ ├── impl │ │ ├── fs.clj │ │ ├── cljapi.clj │ │ ├── articles.clj │ │ ├── git.clj │ │ └── quickdoc │ │ │ └── api.cljc │ ├── tbls │ │ └── impl.clj │ ├── generator.clj │ ├── rustdoc.clj │ ├── tbls.clj │ ├── javadoc.clj │ └── contextive.clj └── readme.clj ├── shell.nix ├── tests.edn ├── script ├── build_examples.clj └── add_example_submodules.clj ├── LICENSE ├── CHANGELOG.md ├── deps.edn ├── .github └── workflows │ └── ci.yml ├── doc.clj ├── bb.edn └── .gitmodules /website/static/.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/.gitignore: -------------------------------------------------------------------------------- 1 | docs/ 2 | -------------------------------------------------------------------------------- /components/statecharts/deps.edn: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /examples/antora/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /examples/javadoc/.gitignore: -------------------------------------------------------------------------------- 1 | /static 2 | -------------------------------------------------------------------------------- /examples/rust/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /static 3 | -------------------------------------------------------------------------------- /test/output/docs/api/_category_.json: -------------------------------------------------------------------------------- 1 | {"label":"API"} -------------------------------------------------------------------------------- /experiments/antora/.gitignore: -------------------------------------------------------------------------------- 1 | /examples/modules/ROOT 2 | /build 3 | -------------------------------------------------------------------------------- /components/antora/deps.edn: -------------------------------------------------------------------------------- 1 | {:deps {babashka/fs {:mvn/version "0.5.20"}}} 2 | -------------------------------------------------------------------------------- /examples/ts/src/index.ts: -------------------------------------------------------------------------------- 1 | import { main } from "./app"; 2 | 3 | main() 4 | -------------------------------------------------------------------------------- /components/contextmapper/test/resources/minimal.cml: -------------------------------------------------------------------------------- 1 | ContextMap Minimal { 2 | } 3 | -------------------------------------------------------------------------------- /website/bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dundalek/dinodoc/HEAD/website/bun.lockb -------------------------------------------------------------------------------- /components/contextmapper/test/output/example/domains/BlankDomain/index.md: -------------------------------------------------------------------------------- 1 | # BlankDomain 2 | -------------------------------------------------------------------------------- /components/contextmapper/test/output/example/teams/_category_.json: -------------------------------------------------------------------------------- 1 | {"position":3,"label":"Teams"} -------------------------------------------------------------------------------- /components/contextmapper/test/output/example/contexts/_category_.json: -------------------------------------------------------------------------------- 1 | {"position":2,"label":"Contexts"} -------------------------------------------------------------------------------- /components/contextmapper/test/output/example/domains/_category_.json: -------------------------------------------------------------------------------- 1 | {"position":1,"label":"Domains"} -------------------------------------------------------------------------------- /examples/antora/bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dundalek/dinodoc/HEAD/examples/antora/bun.lockb -------------------------------------------------------------------------------- /experiments/antora/experiments/modules/ROOT/pages/apidir/foo.adoc: -------------------------------------------------------------------------------- 1 | 2 | == bar 3 | 4 | this is bar 5 | -------------------------------------------------------------------------------- /examples/rust/src/greeting.rs: -------------------------------------------------------------------------------- 1 | pub fn greet() -> String { 2 | String::from("Hello, World!") 3 | } 4 | -------------------------------------------------------------------------------- /experiments/antora/bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dundalek/dinodoc/HEAD/experiments/antora/bun.lockb -------------------------------------------------------------------------------- /experiments/antora/experiments/modules/ROOT/attachments/foo3.html: -------------------------------------------------------------------------------- 1 | 2 |

Bar

3 | -------------------------------------------------------------------------------- /test/resources/contextive/output/glossary/index.md: -------------------------------------------------------------------------------- 1 | # Bounded Contexts 2 | 3 | - [ContextA](ContextA/) 4 | -------------------------------------------------------------------------------- /website/static/img/dino.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dundalek/dinodoc/HEAD/website/static/img/dino.png -------------------------------------------------------------------------------- /website/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dundalek/dinodoc/HEAD/website/static/img/favicon.ico -------------------------------------------------------------------------------- /examples/kotlin/shell.nix: -------------------------------------------------------------------------------- 1 | with import { }; 2 | mkShell { 3 | buildInputs = [ 4 | kotlin 5 | ]; 6 | } 7 | -------------------------------------------------------------------------------- /website/static/img/docusaurus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dundalek/dinodoc/HEAD/website/static/img/docusaurus.png -------------------------------------------------------------------------------- /doc/cljdoc.edn: -------------------------------------------------------------------------------- 1 | {:cljdoc.doc/tree 2 | [["Introduction" {:file "README.md"}] 3 | ["Guide" {:file "doc/guide.md"}]]} 4 | -------------------------------------------------------------------------------- /components/contextmapper/test/output/example/contexts/ContextA/index.md: -------------------------------------------------------------------------------- 1 | # ContextA 2 | 3 | 4 | ![ContextA](./diagram.svg) 5 | -------------------------------------------------------------------------------- /test/resources/contextive/README.md: -------------------------------------------------------------------------------- 1 | basic link: [[foo]] 2 | 3 | namespaced: [[ContextA:foo]] 4 | 5 | [[Multi Word Term]] 6 | -------------------------------------------------------------------------------- /website/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /components/structurizr/test/output/json-big-bank-plc/systems/ATM-6/index.md: -------------------------------------------------------------------------------- 1 | # ATM 2 | 3 | Allows customers to withdraw cash. 4 | 5 | -------------------------------------------------------------------------------- /examples/rust/src/main.rs: -------------------------------------------------------------------------------- 1 | mod greeting; 2 | 3 | fn main() { 4 | println!("{}", greeting::greet()); 5 | } 6 | 7 | // cargo run 8 | -------------------------------------------------------------------------------- /examples/ts/src/app.ts: -------------------------------------------------------------------------------- 1 | import { greet } from "./greeter"; 2 | 3 | export function main() { 4 | console.log(greet("World")); 5 | } 6 | -------------------------------------------------------------------------------- /experiments/stack-graphs/deps.edn: -------------------------------------------------------------------------------- 1 | {:deps {cheshire/cheshire {:mvn/version "5.12.0"} 2 | aysylu/loom {:mvn/version "1.0.2"}}} 3 | -------------------------------------------------------------------------------- /experiments/stack-graphs/shell.nix: -------------------------------------------------------------------------------- 1 | with import { }; 2 | mkShell { 3 | buildInputs = [ 4 | cargo 5 | graphviz 6 | ]; 7 | } 8 | -------------------------------------------------------------------------------- /website/static/img/docusaurus-social-card.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dundalek/dinodoc/HEAD/website/static/img/docusaurus-social-card.jpg -------------------------------------------------------------------------------- /examples/antora/deps.edn: -------------------------------------------------------------------------------- 1 | {:aliases 2 | {:apidoc 3 | {:extra-deps {dinodoc/dinodoc {:local/root "../../"}} 4 | :main-opts ["doc.clj"]}}} 5 | -------------------------------------------------------------------------------- /examples/contextive/deps.edn: -------------------------------------------------------------------------------- 1 | {:aliases 2 | {:doc {:extra-deps {dinodoc/dinodoc {:local/root "../../"}} 3 | :main-opts ["doc.clj"]}}} 4 | -------------------------------------------------------------------------------- /experiments/antora/deps.edn: -------------------------------------------------------------------------------- 1 | {:aliases 2 | {:doc 3 | {:extra-deps {dinodoc/dinodoc {:local/root "../../"}} 4 | :main-opts ["doc.clj"]}}} 5 | 6 | -------------------------------------------------------------------------------- /examples/kotlin/deps.edn: -------------------------------------------------------------------------------- 1 | {:aliases 2 | {:doc {:extra-deps {dinodoc/dokka {:local/root "../../components/dokka"}} 3 | :main-opts ["doc.clj"]}}} 4 | -------------------------------------------------------------------------------- /examples/java/doc.clj: -------------------------------------------------------------------------------- 1 | (ns doc 2 | (:require [dinodoc.dokka :as dokka])) 3 | 4 | (dokka/generate 5 | {:output-path "docs" 6 | :source-paths ["src/main"]}) 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .cache 2 | .cpcache 3 | test/out 4 | .clj-kondo/* 5 | !.clj-kondo/config.edn 6 | .nrepl-port 7 | target 8 | /tmp 9 | /docs 10 | node_modules 11 | -------------------------------------------------------------------------------- /examples/kotlin/doc.clj: -------------------------------------------------------------------------------- 1 | (ns doc 2 | (:require [dinodoc.dokka :as dokka])) 3 | 4 | (dokka/generate 5 | {:output-path "docs" 6 | :source-paths ["src/main"]}) 7 | -------------------------------------------------------------------------------- /examples/ts/src/greeter.ts: -------------------------------------------------------------------------------- 1 | /** Prepares a greeting for the given name. */ 2 | export function greet(name: string): string { 3 | return "Hello, " + name; 4 | } 5 | -------------------------------------------------------------------------------- /examples/antora/bb.edn: -------------------------------------------------------------------------------- 1 | {:tasks 2 | {generate {:task (shell "bunx antora generate antora-playbook.yml")} 3 | serve {:task (shell {:dir "build/site"} "bunx vite dev")}}} 4 | -------------------------------------------------------------------------------- /components/structurizr/test/output/dsl-getting-started/index.md: -------------------------------------------------------------------------------- 1 | # Name 2 | 3 | Description 4 | 5 | Systems: 6 | 7 | - [Software System](./Software%20System-2/) 8 | 9 | 10 | -------------------------------------------------------------------------------- /experiments/tree-sitter/README.md: -------------------------------------------------------------------------------- 1 | This is an experiment using Treesitter parser from Clojure using Java bindings. Perhaps it could be used for implementing a polyglot documentation generator. 2 | -------------------------------------------------------------------------------- /.clj-kondo/config.edn: -------------------------------------------------------------------------------- 1 | {:cljc {:features [:clj]} 2 | :config-in-ns {quickdoc.api 3 | {:linters 4 | {:unused-binding {:exclude-destructured-keys-in-fn-args true}}}}} 5 | -------------------------------------------------------------------------------- /examples/antora/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@antora/cli": "3.1.7", 4 | "@antora/collector-extension": "1.0.0-alpha.3", 5 | "@antora/site-generator": "3.1.7" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/java/src/main/java/demo/Main.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | System.out.println(Greeter.greet("World")); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/kotlin/src/main/kotlin/demo/Greeter.kt: -------------------------------------------------------------------------------- 1 | package demo 2 | 3 | object Greeter { 4 | /** 5 | * Returns a greeting. 6 | */ 7 | fun greet(name: String) = "Hello, $name!" 8 | } 9 | -------------------------------------------------------------------------------- /examples/rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "example" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /experiments/antora/experiments/modules/apimod/pages/foo2.adoc: -------------------------------------------------------------------------------- 1 | 2 | ## bar 3 | 4 | hi 5 | 6 | [#--GT-] 7 | ## -> 8 | 9 | munged id 10 | 11 | [#->>] 12 | ## ->> 13 | 14 | original id 15 | -------------------------------------------------------------------------------- /components/contextmapper/test/output/example/teams/index.md: -------------------------------------------------------------------------------- 1 | # Teams 2 | 3 | ## TeamX 4 | 5 | - [ContextB](../contexts/ContextB/) 6 | - owns: AggregateBar, AggregateFoo 7 | 8 | ## TeamY 9 | 10 | -------------------------------------------------------------------------------- /examples/javadoc/deps.edn: -------------------------------------------------------------------------------- 1 | {:aliases 2 | {:doc {:extra-deps {dinodoc/dinodoc {:local/root "../../"} 3 | babashka/process {:mvn/version "0.5.22"}} 4 | :main-opts ["doc.clj"]}}} 5 | -------------------------------------------------------------------------------- /examples/multi/deps.edn: -------------------------------------------------------------------------------- 1 | {:aliases 2 | {:doc {:extra-deps {dinodoc/dinodoc {:local/root "../../"} 3 | babashka/process {:mvn/version "0.5.22"}} 4 | :main-opts ["doc.clj"]}}} 5 | -------------------------------------------------------------------------------- /examples/rust/deps.edn: -------------------------------------------------------------------------------- 1 | {:aliases 2 | {:doc {:extra-deps {dinodoc/dinodoc {:local/root "../../"} 3 | babashka/process {:mvn/version "0.5.22"}} 4 | :main-opts ["doc.clj"]}}} 5 | -------------------------------------------------------------------------------- /examples/structurizr/deps.edn: -------------------------------------------------------------------------------- 1 | {:aliases 2 | {:doc {:extra-deps {dinodoc/dinodoc {:local/root "../../"} 3 | babashka/fs {:mvn/version "0.4.19"}} 4 | :main-opts ["doc.clj"]}}} 5 | -------------------------------------------------------------------------------- /examples/kotlin/src/main/kotlin/demo/Main.kt: -------------------------------------------------------------------------------- 1 | package demo 2 | 3 | import demo.Greeter 4 | 5 | /** 6 | * Prints a greeting. 7 | */ 8 | fun main() { 9 | println(Greeter.greet("World")) 10 | } 11 | -------------------------------------------------------------------------------- /test/projects/samples/src/samples/crossplatform.clj: -------------------------------------------------------------------------------- 1 | (ns ^{:doc "This is docstring from CLJ."} 2 | samples.crossplatform) 3 | 4 | (defn some-clj-fn []) 5 | 6 | (defn shared-name 7 | "CLJ docstring" 8 | []) 9 | -------------------------------------------------------------------------------- /examples/polylith/deps.edn: -------------------------------------------------------------------------------- 1 | {:deps {} 2 | 3 | :aliases 4 | {:doc {:extra-deps {dinodoc/dinodoc {:local/root "../../"} 5 | babashka/fs {:mvn/version "0.4.19"}} 6 | :main-opts ["doc.clj"]}}} 7 | -------------------------------------------------------------------------------- /examples/promesa/deps.edn: -------------------------------------------------------------------------------- 1 | {:deps {} 2 | 3 | :aliases 4 | {:doc {:extra-deps {dinodoc/dinodoc {:local/root "../../"} 5 | babashka/fs {:mvn/version "0.4.19"}} 6 | :main-opts ["doc.clj"]}}} 7 | -------------------------------------------------------------------------------- /examples/reitit/deps.edn: -------------------------------------------------------------------------------- 1 | {:deps {} 2 | 3 | :aliases 4 | {:doc {:extra-deps {dinodoc/dinodoc {:local/root "../../"} 5 | babashka/fs {:mvn/version "0.4.19"}} 6 | :main-opts ["doc.clj"]}}} 7 | -------------------------------------------------------------------------------- /examples/ring/deps.edn: -------------------------------------------------------------------------------- 1 | {:deps {} 2 | 3 | :aliases 4 | {:doc {:extra-deps {dinodoc/dinodoc {:local/root "../../"} 5 | babashka/fs {:mvn/version "0.4.19"}} 6 | :main-opts ["doc.clj"]}}} 7 | -------------------------------------------------------------------------------- /examples/rust/README.md: -------------------------------------------------------------------------------- 1 | # Rust with rustdoc 2 | 3 | The main entrypoint of the example is [[example::main]] and greeting is returned by [[example::greeting::greet]]. 4 | 5 | Run example: 6 | ``` 7 | cargo run 8 | ``` 9 | -------------------------------------------------------------------------------- /test/projects/samples/src/samples/crossplatform.cljs: -------------------------------------------------------------------------------- 1 | (ns ^{:doc "And this docstring comes from CLJS."} 2 | samples.crossplatform) 3 | 4 | (defn some-cljs-fn []) 5 | 6 | (defn shared-name 7 | "CLJS docstring" 8 | []) 9 | -------------------------------------------------------------------------------- /examples/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "example" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /experiments/antora/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@antora/cli": "3.1.7", 4 | "@antora/site-generator": "3.1.7", 5 | "@sntke/antora-mermaid-extension": "0.0.4", 6 | "asciidoctor": "3.0.4" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/ts/test/greeter.test.ts: -------------------------------------------------------------------------------- 1 | import { expect, test } from "bun:test"; 2 | import { greet } from "../src/greeter"; 3 | import "../readme" 4 | 5 | test("greeter", () => { 6 | expect(greet("John")).toBe("Hello, John"); 7 | }); 8 | -------------------------------------------------------------------------------- /examples/contextmapper/deps.edn: -------------------------------------------------------------------------------- 1 | {:aliases 2 | {:doc {:extra-deps {dinodoc/dinodoc {:local/root "../.."} 3 | dinodoc/contextmapper {:local/root "../../components/contextmapper"}} 4 | :main-opts ["doc.clj"]}}} 5 | -------------------------------------------------------------------------------- /test/projects/samples/src/samples/crossplatform_mixed.cljc: -------------------------------------------------------------------------------- 1 | (ns samples.crossplatform-mixed) 2 | 3 | #?(:clj (defn some-clj-fn [])) 4 | 5 | #?(:cljs (defn some-cljs-fn [])) 6 | 7 | (defn shared-name 8 | "docstring" 9 | []) 10 | -------------------------------------------------------------------------------- /website/src/components/HomepageFeatures/styles.module.css: -------------------------------------------------------------------------------- 1 | .features { 2 | display: flex; 3 | align-items: center; 4 | padding: 2rem 0; 5 | width: 100%; 6 | } 7 | 8 | .featureSvg { 9 | height: 200px; 10 | width: 200px; 11 | } 12 | -------------------------------------------------------------------------------- /components/contextmapper/test/output/example/contexts/ContextB/index.md: -------------------------------------------------------------------------------- 1 | # ContextB 2 | 3 | Responsible for B. 4 | 5 | - Type: System 6 | - Responsibilities: Foo, Bar 7 | - Implementation Technology: Clojure 8 | 9 | ![ContextB](./diagram.svg) 10 | -------------------------------------------------------------------------------- /components/contextmapper/test/output/minimal/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 0 3 | title: Minimal 4 | --- 5 | 6 | # Minimal 7 | 8 | ![Minimal](./context-mapMinimal.svg) 9 | 10 | ## Domains 11 | 12 | 13 | ## Bounded Contexts 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/openapi/doc.clj: -------------------------------------------------------------------------------- 1 | (ns doc 2 | (:require 3 | [clojure.java.io :as io])) 4 | 5 | (let [app (requiring-resolve 'example.server/app)] 6 | (io/copy 7 | (:body (app {:request-method :get :uri "/openapi.json"})) 8 | (io/file "reitit.json"))) 9 | -------------------------------------------------------------------------------- /examples/java/src/main/java/demo/Greeter.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | public class Greeter { 4 | public static String GREETING = "Hello"; 5 | 6 | public static String greet(String name) { 7 | return GREETING + ", " + name + "!"; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/dbschema/deps.edn: -------------------------------------------------------------------------------- 1 | {:aliases 2 | {:doc {:extra-deps {dinodoc/dinodoc {:local/root "../../"} 3 | babashka/fs {:mvn/version "0.4.19"} 4 | babashka/process {:mvn/version "0.5.21"}} 5 | :main-opts ["doc.clj"]}}} 6 | -------------------------------------------------------------------------------- /examples/structurizr/README.md: -------------------------------------------------------------------------------- 1 | # Structurizr examples 2 | 3 | Examples of linked elements: 4 | 5 | - Big Bank: [[Internet Banking System]] 6 | - Financial Risk System: [[Trade Data System]] 7 | - [[E-mail Component]] (Big Bank) vs. [[E-mail system]] (Risk System) 8 | -------------------------------------------------------------------------------- /components/contextmapper/deps.edn: -------------------------------------------------------------------------------- 1 | {:deps 2 | {org.contextmapper/context-mapper-dsl {:mvn/version "6.10.0"} 3 | org.clojure/java.data {:mvn/version "1.2.107"} 4 | babashka/fs {:mvn/version "0.5.20"} 5 | net.sourceforge.plantuml/plantuml-mit {:mvn/version "1.2024.4"}}} 6 | -------------------------------------------------------------------------------- /experiments/antora/experiments/antora.yml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://raw.githubusercontent.com/asciidoctor/asciidoctor-intellij-plugin/main/src/main/resources/jsonSchemas/antoraComponentSchema.json 2 | name: experiments 3 | title: Experiments 4 | version: ~ 5 | -------------------------------------------------------------------------------- /components/structurizr/deps.edn: -------------------------------------------------------------------------------- 1 | {:deps {com.structurizr/structurizr-dsl {:mvn/version "1.32.0"} 2 | com.structurizr/structurizr-export {:mvn/version "1.16.1"} 3 | org.clojure/java.data {:mvn/version "1.2.107"} 4 | babashka/fs {:mvn/version "0.4.19"}}} 5 | -------------------------------------------------------------------------------- /examples/statecharts/deps.edn: -------------------------------------------------------------------------------- 1 | {:deps {clj-statecharts/clj-statecharts {:mvn/version "0.1.7"}} 2 | 3 | :aliases 4 | {:doc {:extra-deps {dinodoc/dinodoc {:local/root "../../"} 5 | babashka/fs {:mvn/version "0.4.19"}} 6 | :main-opts ["doc.clj"]}}} 7 | -------------------------------------------------------------------------------- /components/contextmapper/test/output/example/domains/DomainA/index.md: -------------------------------------------------------------------------------- 1 | # DomainA 2 | 3 | About domain A. 4 | 5 | ## SubdomainB 6 | 7 | SubdomainB managing B. 8 | 9 | *Core domain* 10 | 11 | - [ContextB](../../contexts/ContextB/) 12 | 13 | ## SubdomainWithoutMetadata 14 | 15 | -------------------------------------------------------------------------------- /examples/antora/src/example/main.clj: -------------------------------------------------------------------------------- 1 | (ns ^{:doc "This a docstring on a namespace."} 2 | example.main) 3 | 4 | (defn greet 5 | "Returns a greeting message for a given name." 6 | [name] 7 | (str "Hello, " name "!")) 8 | 9 | (defn -main [] 10 | (println (greet "World"))) 11 | -------------------------------------------------------------------------------- /examples/java/deps.edn: -------------------------------------------------------------------------------- 1 | {:aliases 2 | {:doc {:extra-deps {dinodoc/dokka {:local/root "../../components/dokka"} 3 | ;; for Java signature format 4 | org.jetbrains.dokka/kotlin-as-java-plugin {:mvn/version "1.9.20"}} 5 | :main-opts ["doc.clj"]}}} 6 | -------------------------------------------------------------------------------- /test/output/docs/api/codox/import/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_label: import 3 | title: codox.import 4 | toc_min_heading_level: 2 5 | toc_max_heading_level: 4 6 | custom_edit_url: 7 | --- 8 | 9 | 10 | 11 | 12 | 13 | ### foop {#foop} 14 | ``` clojure 15 | (foop & args) 16 | ``` 17 | 18 | -------------------------------------------------------------------------------- /experiments/antora/examples/antora.yml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://raw.githubusercontent.com/asciidoctor/asciidoctor-intellij-plugin/main/src/main/resources/jsonSchemas/antoraComponentSchema.json 2 | name: examples 3 | title: Examples 4 | version: ~ 5 | nav: 6 | - modules/ROOT/nav.adoc 7 | -------------------------------------------------------------------------------- /examples/multi/README.md: -------------------------------------------------------------------------------- 1 | For example the entrypoint is [[demo.Main.main]] and uses the [[demo.Greeter.greet]] method. 2 | 3 | Example linking to a field: [[demo.Greeter.GREETING]]. 4 | 5 | The main entrypoint of the example is [[example::main]] and greeting is returned by [[example::greeting::greet]]. 6 | -------------------------------------------------------------------------------- /experiments/tree-sitter/deps.edn: -------------------------------------------------------------------------------- 1 | {:deps {io.github.bonede/tree-sitter {:mvn/version "0.22.2"} 2 | io.github.bonede/tree-sitter-typescript {:mvn/version "0.20.3"} 3 | io.github.bonede/tree-sitter-clojure {:mvn/version "0.0.12"} 4 | io.github.bonede/tree-sitter-json {:mvn/version "0.20.1"}}} 5 | -------------------------------------------------------------------------------- /test/resources/contextive/output/glossary/ContextA/index.md: -------------------------------------------------------------------------------- 1 | # ContextA 2 | 3 | Lorem Ipsum 4 | 5 | ## foo {#foo} 6 | 7 | Some definition of Foo 8 | 9 | ## bar {#bar} 10 | 11 | Some definition of Bar 12 | 13 | Examples: 14 | 15 | - First 16 | - Second 17 | 18 | ## Multi Word Term {#multi-word-term} 19 | -------------------------------------------------------------------------------- /test/resources/contextive/output/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | {sidebar_position: 0, custom_edit_url: repo/tree/main/README.md} 3 | --- 4 | 5 | basic link: [`foo`](./glossary/ContextA#foo) 6 | 7 | namespaced: [`ContextA:foo`](./glossary/ContextA#foo) 8 | 9 | [`Multi Word Term`](./glossary/ContextA#multi-word-term) 10 | -------------------------------------------------------------------------------- /test/output/docs/api/codox/example2/core/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_label: core 3 | title: codox.example2.core 4 | toc_min_heading_level: 2 5 | toc_max_heading_level: 4 6 | custom_edit_url: 7 | --- 8 | 9 | Namespace with three parts 10 | 11 | 12 | 13 | 14 | ### inner {#inner} 15 | ``` clojure 16 | (inner x) 17 | ``` 18 | 19 | -------------------------------------------------------------------------------- /examples/contextive/README.md: -------------------------------------------------------------------------------- 1 | # Contextive example 2 | 3 | Renders glossary of terms from [Contextive](https://github.com/dev-cycles/contextive) definitions. 4 | 5 | See the rendered [example](https://dinodoc.pages.dev/examples/contextive/glossary/University/). 6 | 7 | Examples of links to terms: [[course]] and namespaced [[University:student]]. 8 | -------------------------------------------------------------------------------- /website/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | /docs 7 | 8 | # Generated files 9 | .docusaurus 10 | .cache-loader 11 | 12 | # Misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /examples/kotlin/README.md: -------------------------------------------------------------------------------- 1 | # Minimal Kotlin example 2 | 3 | Uses the [Dokka](https://dinodoc.pages.dev/docs/dokka/) engine. 4 | See the rendered [result](https://dinodoc.pages.dev/examples/kotlin/). 5 | 6 | Run the example code: 7 | ``` 8 | kotlinc src/main/kotlin/demo/*.kt -include-runtime -d target/hello.jar && java -jar target/hello.jar 9 | ``` 10 | -------------------------------------------------------------------------------- /test/projects/samples/src/samples/protocols.clj: -------------------------------------------------------------------------------- 1 | (ns samples.protocols) 2 | 3 | (defprotocol IQueue 4 | (-poll! [_]) 5 | (-offer! [_ _])) 6 | 7 | (defprotocol IBulkhead 8 | "Bulkhead main API" 9 | (-get-stats [_] "Get internal statistics of the bulkhead instance") 10 | (-invoke! [_ f] "Call synchronously a function under bulkhead context")) 11 | -------------------------------------------------------------------------------- /test/output/docs/example/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | {sidebar_position: 1, custom_edit_url: 'https://github.com/weavejester/codox/tree/master/doc/intro.md'} 3 | --- 4 | 5 | # Introduction 6 | 7 | This is a **markdown** introduction page. 8 | 9 | Maybe check out [formatting](index.md) as well? 10 | 11 | Here's another way of going to [formatting][1]. 12 | 13 | [1]: index.md 14 | -------------------------------------------------------------------------------- /experiments/antora/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Antora experiments 3 | 4 | Trying out how existing examples work in when rendered in Antora. 5 | 6 | Install dependencies: 7 | ``` 8 | bun install 9 | ``` 10 | 11 | Generate and copy the example content: 12 | ``` 13 | bb examples 14 | ``` 15 | 16 | Generate the Antora site (saved to `build/site`): 17 | ``` 18 | bb generate 19 | ``` 20 | -------------------------------------------------------------------------------- /experiments/antora/bb.edn: -------------------------------------------------------------------------------- 1 | {:tasks 2 | {generate {:task (shell "bunx antora generate antora-playbook.yml")} 3 | serve {:task (shell {:dir "build/site"} "bunx vite dev --open /examples/docs/")} 4 | 5 | examples {:depends [examples:generate examples:copy]} 6 | examples:generate {:task (shell {:dir "../.."} "bb website:content")} 7 | examples:copy {:task (clojure "-M:doc")}}} 8 | -------------------------------------------------------------------------------- /test/resources/contextive/definitions.yml: -------------------------------------------------------------------------------- 1 | contexts: 2 | - name: ContextA 3 | domainVisionStatement: Lorem Ipsum 4 | terms: 5 | - name: foo 6 | definition: Some definition of Foo 7 | - name: bar 8 | definition: Some definition of Bar 9 | examples: 10 | - First 11 | - Second 12 | - name: Multi Word Term 13 | -------------------------------------------------------------------------------- /examples/contextive/doc.clj: -------------------------------------------------------------------------------- 1 | (ns doc 2 | (:require 3 | [dinodoc.api :as dinodoc] 4 | [dinodoc.contextive :as contextive])) 5 | 6 | (dinodoc/generate 7 | {:inputs [{:path "."} 8 | {:generator (contextive/make-generator {:definitions-file ".contextive/definitions.yml"}) 9 | :output-path "glossary"}] 10 | :output-path "docs"}) 11 | 12 | (shutdown-agents) 13 | -------------------------------------------------------------------------------- /examples/javadoc/README.md: -------------------------------------------------------------------------------- 1 | # Javadoc Example 2 | 3 | When using API documentation generator that does not support markdown output like Javadoc, 4 | we can still link from markdown articles by transforming logical references to HTML links. 5 | 6 | For example the entrypoint is [[demo.Main.main]] and uses the [[demo.Greeter.greet]] method. 7 | 8 | Example linking to a field: [[demo.Greeter.GREETING]]. 9 | -------------------------------------------------------------------------------- /components/contextmapper/test/output/example/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 0 3 | title: ExampleMap 4 | --- 5 | 6 | # ExampleMap 7 | 8 | ![ExampleMap](./context-mapExampleMap.svg) 9 | 10 | ## Domains 11 | 12 | - [BlankDomain](domains/BlankDomain/) 13 | - [DomainA](domains/DomainA/) 14 | 15 | ## Bounded Contexts 16 | 17 | - [ContextA](contexts/ContextA/) 18 | - [ContextB](contexts/ContextB/) 19 | 20 | -------------------------------------------------------------------------------- /examples/antora/doc.clj: -------------------------------------------------------------------------------- 1 | (ns doc 2 | (:require 3 | [dinodoc.api :as dinodoc] 4 | [dinodoc.antora :as antora])) 5 | 6 | (def output-path "docs/pages") 7 | 8 | (dinodoc/generate 9 | {:inputs [{:path "."}] 10 | :output-path output-path}) 11 | 12 | ;; Convert Markdown to Asciidoc 13 | (antora/transform-directory output-path) 14 | 15 | (spit "docs/nav.adoc" (antora/generate-navigation output-path)) 16 | 17 | (shutdown-agents) 18 | -------------------------------------------------------------------------------- /examples/contextmapper/doc.clj: -------------------------------------------------------------------------------- 1 | (ns doc 2 | (:require 3 | [dinodoc.api :as dinodoc] 4 | [dinodoc.contextmapper :as contextmapper])) 5 | 6 | (dinodoc/generate 7 | {:output-path "docs" 8 | :inputs [{:input "."} 9 | {:generator (contextmapper/make-generator 10 | {:model-file "examples/Insurance-Example-Stage-5.cml"}) 11 | :output-path "insurance-map"}]}) 12 | 13 | (shutdown-agents) 14 | -------------------------------------------------------------------------------- /src/dinodoc/impl/fs.clj: -------------------------------------------------------------------------------- 1 | (ns 2 | ^:no-doc 3 | dinodoc.impl.fs 4 | (:require 5 | [babashka.fs :as fs])) 6 | 7 | (def ^:dynamic *tmp-dir* ".cache") 8 | 9 | (defn create-local-temp-dir [] 10 | ;; Moving generated files from /tmp can cause issues since it can be on a different filesystem. 11 | ;; Helper for using the relative local directory instead. 12 | (fs/create-dirs *tmp-dir*) 13 | (fs/create-temp-dir {:dir *tmp-dir*})) 14 | -------------------------------------------------------------------------------- /examples/ts/readme.ts: -------------------------------------------------------------------------------- 1 | import { main } from "./src/app" 2 | import * as greeter from "./src/greeter" 3 | 4 | // # Hello world 5 | // Main entrypoint prints the greeting 6 | main 7 | // Prepares the greeting message 8 | ; greeter.greet 9 | 10 | // 11 | // # Alternative nested padding with blocks in curlies 12 | // 13 | // Main entrypoint prints the greeting 14 | main 15 | { 16 | // Prepares the greeting message 17 | greeter.greet 18 | } 19 | -------------------------------------------------------------------------------- /components/dokka/deps.edn: -------------------------------------------------------------------------------- 1 | {:deps {org.jetbrains.dokka/dokka-cli {:mvn/version "1.9.20"} 2 | org.jetbrains.dokka/dokka-base {:mvn/version "1.9.20"} 3 | org.jetbrains.dokka/analysis-kotlin-descriptors {:mvn/version "1.9.20"} 4 | 5 | ;; for Markdown output 6 | org.jetbrains.dokka/gfm-plugin {:mvn/version "1.9.20"} 7 | 8 | cheshire/cheshire {:mvn/version "5.12.0"} 9 | babashka/fs {:mvn/version "0.5.20"}}} 10 | -------------------------------------------------------------------------------- /experiments/stack-graphs/dumper/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dumper" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | serde = "1.0.197" 10 | serde_json = "1.0.114" 11 | stack-graphs = "0.13.0" 12 | tree-sitter-stack-graphs = "0.8.1" 13 | 14 | 15 | [features] 16 | default = ["stack-graphs/serde", "stack-graphs/storage"] 17 | -------------------------------------------------------------------------------- /test/output/docs/api/samples/crossplatform-mixed/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_label: crossplatform-mixed 3 | title: samples.crossplatform-mixed 4 | toc_min_heading_level: 2 5 | toc_max_heading_level: 4 6 | custom_edit_url: 7 | --- 8 | 9 | 10 | 11 | 12 | 13 | ### shared\-name {#shared-name} 14 | ``` clojure 15 | (shared-name) 16 | ``` 17 | 18 | 19 | docstring 20 | 21 | ### some\-clj\-fn {#some-clj-fn} 22 | ``` clojure 23 | (some-clj-fn) 24 | ``` 25 | 26 | -------------------------------------------------------------------------------- /examples/antora/antora.yml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://raw.githubusercontent.com/asciidoctor/asciidoctor-intellij-plugin/main/src/main/resources/jsonSchemas/antoraComponentSchema.json 2 | name: example 3 | title: My Example 4 | version: ~ 5 | # version: 1.0 6 | nav: 7 | - docs/nav.adoc 8 | ext: 9 | collector: 10 | run: 11 | command: clojure -M:apidoc 12 | dir: . 13 | scan: 14 | dir: ./docs 15 | base: modules/ROOT 16 | -------------------------------------------------------------------------------- /examples/java/README.md: -------------------------------------------------------------------------------- 1 | # Minimal Java example 2 | 3 | Uses the [Dokka](https://dinodoc.pages.dev/docs/dokka/) engine. 4 | See the rendered [result](https://dinodoc.pages.dev/examples/java/). 5 | Note that `org.jetbrains.dokka/kotlin-as-java-plugin` needs to be added as a dependency to render signatures in the Java format. 6 | 7 | Run the example code: 8 | ``` 9 | mkdir target 10 | javac src/main/java/demo/*.java -d target && java -cp target demo.Main 11 | ``` 12 | -------------------------------------------------------------------------------- /experiments/antora/doc.clj: -------------------------------------------------------------------------------- 1 | (ns doc 2 | (:require 3 | [babashka.fs :as fs] 4 | [dinodoc.antora :as antora])) 5 | 6 | (def target-path "examples/modules/ROOT") 7 | (def pages-path (str target-path "/pages")) 8 | 9 | (fs/delete-tree pages-path) 10 | (fs/copy-tree "../../website/docs" pages-path) 11 | (antora/transform-directory pages-path) 12 | 13 | (spit (str target-path "/nav.adoc") (antora/generate-navigation pages-path)) 14 | 15 | (shutdown-agents) 16 | 17 | -------------------------------------------------------------------------------- /components/structurizr/test/output/json-big-bank-plc/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | {sidebar_position: 0, custom_edit_url: /tree//README.md} 3 | --- 4 | 5 | link to system: [`Mainframe Banking System`](./systems/Mainframe%20Banking%20System-4/) 6 | 7 | link to container: [`Mobile App`](./systems/Internet%20Banking%20System-7/Mobile%20App-9/) 8 | 9 | link to component: [`Security Component`](./systems/Internet%20Banking%20System-7/API%20Application-11/Security%20Component-15/) 10 | 11 | -------------------------------------------------------------------------------- /experiments/antora/tmp.js: -------------------------------------------------------------------------------- 1 | const Asciidoctor = require('asciidoctor') 2 | 3 | const asciidoctor = Asciidoctor() 4 | 5 | const registry = asciidoctor.Extensions.create() 6 | require('./apilink-extension')(registry) 7 | 8 | // var html = asciidoctor.convert('Hello, _Asciidoctor_') 9 | 10 | var html = asciidoctor.convertFile('experiments/modules/ROOT/pages/custom.adoc', { 11 | to_file: false, 12 | standalone: false, 13 | extension_registry: registry, 14 | }) 15 | console.log(html) 16 | 17 | -------------------------------------------------------------------------------- /examples/ts/README.md: -------------------------------------------------------------------------------- 1 | # Minimal TypeScript example 2 | 3 | This is a minimal example to show generating docs for a TypeScript project using [docusaurus-plugin-typedoc](ttps://github.com/tgreyuk/typedoc-plugin-markdown/tree/master/packages/docusaurus-plugin-typedoc). 4 | 5 | The setup is in the `plugins` section of [docusaurus.config.js](https://github.com/dundalek/dinodoc/blob/main/website/docusaurus.config.js). 6 | 7 | Run with: 8 | ```sh 9 | bun src/index.ts 10 | ``` 11 | 12 | Test with: 13 | ```sh 14 | bun test 15 | ``` 16 | -------------------------------------------------------------------------------- /experiments/antora/apilink-extension.js: -------------------------------------------------------------------------------- 1 | 2 | // dummy example implementation 3 | function lookup(target) { 4 | return { 5 | target: 'apimod:' + target.replace(/\//, '#').replace(/>/, '-GT-'), 6 | label: target, 7 | } 8 | } 9 | 10 | module.exports = function(registry) { 11 | registry.inlineMacro('api', function() { 12 | this.process((parent, node) => { 13 | const { target, label } = lookup(node) 14 | var text = 'xref:' + target + '[' + label + ']' 15 | return this.createInline(parent, 'quoted', text) 16 | }) 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /examples/openapi/deps.edn: -------------------------------------------------------------------------------- 1 | {:aliases 2 | {:doc {:extra-deps {;; for the reitit example 3 | metosin/jsonista {:mvn/version "0.2.6"} 4 | metosin/reitit {:mvn/version "0.7.0-alpha7"} 5 | metosin/ring-swagger-ui {:mvn/version "5.9.0"} 6 | ring/ring-jetty-adapter {:mvn/version "1.7.1"}} 7 | ;; need to use external path, can't use :loca/root because the example does not have deps.edn 8 | :extra-paths ["../reitit/reitit/examples/openapi/src"] 9 | :main-opts ["doc.clj"]}}} 10 | -------------------------------------------------------------------------------- /test/output/docs/api/samples/crossplatform/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_label: crossplatform 3 | title: samples.crossplatform 4 | toc_min_heading_level: 2 5 | toc_max_heading_level: 4 6 | custom_edit_url: 7 | --- 8 | 9 | And this docstring comes from CLJS. 10 | 11 | 12 | 13 | 14 | ### shared\-name {#shared-name} 15 | ``` clojure 16 | (shared-name) 17 | ``` 18 | 19 | 20 | CLJ docstring 21 | 22 | ### some\-clj\-fn {#some-clj-fn} 23 | ``` clojure 24 | (some-clj-fn) 25 | ``` 26 | 27 | 28 | ### some\-cljs\-fn {#some-cljs-fn} 29 | ``` clojure 30 | (some-cljs-fn) 31 | ``` 32 | 33 | -------------------------------------------------------------------------------- /examples/multi/doc.clj: -------------------------------------------------------------------------------- 1 | (ns doc 2 | (:require 3 | [dinodoc.api :as dinodoc] 4 | [dinodoc.javadoc :as javadoc] 5 | [dinodoc.rustdoc :as rustdoc])) 6 | 7 | (dinodoc/generate 8 | {:inputs [{:path "."} 9 | {:output-path "javadoc" 10 | :generator (javadoc/make-generator 11 | {:sourcepath "../java/src/main/java" 12 | :subpackages "demo"})} 13 | {:output-path "rustdoc" 14 | :generator (rustdoc/make-generator 15 | {:manifest-path "../rust/Cargo.toml"})}] 16 | :output-path "docs"}) 17 | 18 | -------------------------------------------------------------------------------- /shell.nix: -------------------------------------------------------------------------------- 1 | with import { }; 2 | mkShell { 3 | buildInputs = [ 4 | babashka 5 | bun 6 | clojure 7 | git 8 | 9 | # for antora example 10 | pandoc 11 | nodejs_20 # Antora broken with Node 22: https://antora.zulipchat.com/#narrow/stream/282403-announce-.F0.9F.93.A2/topic/Incompatibility.20with.20Node.2Ejs.2022 12 | 13 | # for dbschema example 14 | postgresql 15 | tbls 16 | 17 | # for contextmapper examples (dependency of plantuml) 18 | graphviz 19 | 20 | # for rust example 21 | cargo 22 | 23 | # for javadoc example 24 | jdk 25 | ]; 26 | } 27 | -------------------------------------------------------------------------------- /examples/structurizr/doc.clj: -------------------------------------------------------------------------------- 1 | (ns doc 2 | (:require 3 | [dinodoc.api :as dinodoc] 4 | [dinodoc.structurizr :as structurizr])) 5 | 6 | (dinodoc/generate 7 | {:output-path "docs" 8 | :inputs [{:path "."} 9 | {:generator (structurizr/make-generator 10 | {:workspace-file "examples/dsl/big-bank-plc/workspace.dsl"}) 11 | :output-path "big-bank-plc"} 12 | {:generator (structurizr/make-generator 13 | {:workspace-file "examples/dsl/financial-risk-system/workspace.dsl"}) 14 | :output-path "financial-risk-system"}]}) 15 | 16 | (shutdown-agents) 17 | -------------------------------------------------------------------------------- /examples/antora/antora-playbook.yml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://raw.githubusercontent.com/asciidoctor/asciidoctor-intellij-plugin/main/src/main/resources/jsonSchemas/antoraPlaybookSchema.json 2 | site: 3 | title: Antora Docs 4 | start_page: example::index.adoc 5 | content: 6 | sources: 7 | # if url is a path, it must be to the git repo root 8 | - url: ../.. 9 | start_paths: examples/antora 10 | ui: 11 | bundle: 12 | url: https://gitlab.com/antora/antora-ui-default/-/jobs/artifacts/HEAD/raw/build/ui-bundle.zip?job=bundle-stable 13 | snapshot: true 14 | antora: 15 | extensions: 16 | - '@antora/collector-extension' 17 | -------------------------------------------------------------------------------- /examples/rust/doc.clj: -------------------------------------------------------------------------------- 1 | (ns doc 2 | (:require 3 | [babashka.fs :as fs] 4 | [babashka.process :refer [shell]] 5 | [dinodoc.api :as dinodoc] 6 | [dinodoc.rustdoc :as rustdoc])) 7 | 8 | ;; Generated assets included by using `staticDirectories` option in `docusaurus.config.js` 9 | (def rustdoc-path "target/doc") 10 | (def api-path "static/examples/rust/api") 11 | 12 | (shell "cargo doc --no-deps") 13 | (fs/delete-tree api-path) 14 | (fs/move rustdoc-path api-path) 15 | 16 | (dinodoc/generate 17 | {:inputs [{:path "."}] 18 | :output-path "docs" 19 | :resolve-apilink #(some->> (rustdoc/resolve-link api-path %) (str "api/"))}) 20 | 21 | (shutdown-agents) 22 | -------------------------------------------------------------------------------- /website/src/pages/index.module.css: -------------------------------------------------------------------------------- 1 | /** 2 | * CSS files with the .module.css suffix will be treated as CSS modules 3 | * and scoped locally. 4 | */ 5 | 6 | .heroBanner { 7 | padding: 4rem 0; 8 | text-align: center; 9 | position: relative; 10 | overflow: hidden; 11 | } 12 | 13 | .heroLine { 14 | display: flex; 15 | justify-content: center; 16 | } 17 | 18 | @media screen and (max-width: 996px) { 19 | .heroBanner { 20 | padding: 2rem; 21 | } 22 | 23 | .heroLine { 24 | flex-direction: column; 25 | } 26 | } 27 | 28 | .buttons { 29 | display: flex; 30 | align-items: center; 31 | justify-content: center; 32 | gap: 1rem; 33 | } 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /examples/javadoc/doc.clj: -------------------------------------------------------------------------------- 1 | (ns doc 2 | (:require 3 | [babashka.process :refer [shell]] 4 | [dinodoc.api :as dinodoc] 5 | ;; TODO: Think about public API 6 | [dinodoc.javadoc :as javadoc])) 7 | 8 | ;; Generated assets included by using `staticDirectories` option in `docusaurus.config.js` 9 | (def api-path "static/examples/javadoc/api") 10 | 11 | ; (apply shell "javadoc -d out" (fs/glob "src" "**.java")) 12 | (shell "javadoc -sourcepath ../java/src/main/java -subpackages demo -d" api-path) 13 | 14 | (dinodoc/generate 15 | {:inputs [{:path "."}] 16 | :output-path "docs" 17 | :resolve-apilink #(some->> (javadoc/resolve-link api-path %) (str "api/"))}) 18 | 19 | (shutdown-agents) 20 | -------------------------------------------------------------------------------- /test/output/docs/api/promesa/exec/semaphore/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_label: semaphore 3 | title: promesa.exec.semaphore 4 | toc_min_heading_level: 2 5 | toc_max_heading_level: 4 6 | custom_edit_url: 7 | --- 8 | 9 | Concurrency limiter: Semaphore 10 | 11 | 12 | 13 | 14 | ### acquire\! {#acquire-BANG-} 15 | ``` clojure 16 | (acquire! sem) 17 | (acquire! sem & {:keys [permits timeout blocking], :or {blocking true, permits 1}}) 18 | ``` 19 | 20 | 21 | ### create {#create} 22 | ``` clojure 23 | (create & {:keys [permits], :or {permits 1}}) 24 | ``` 25 | 26 | 27 | Creates a Semaphore instance. 28 | 29 | ### release\! {#release-BANG-} 30 | ``` clojure 31 | (release! sem) 32 | (release! sem & {:keys [permits]}) 33 | ``` 34 | 35 | -------------------------------------------------------------------------------- /test/src/dinodoc/approval_helpers.clj: -------------------------------------------------------------------------------- 1 | (ns dinodoc.approval-helpers 2 | (:require 3 | [clojure.java.shell :refer [sh]] 4 | [clojure.test :refer [is]] 5 | [clojure.string :as str])) 6 | 7 | ;; We compare if output is the same as committed state, git status returns empty output if there are no changes. 8 | ;; If implementation changes and expected state needs to be updated, commit the changes after inspecting the diff. 9 | 10 | #_(defmacro is-same? [path] 11 | `(is (= {:exit 0 :err "" :out ""} 12 | (sh "git" "status" "--porcelain" ~path)))) 13 | 14 | (defn is-same? [path] 15 | (let [result (sh "git" "status" "--porcelain" path)] 16 | (is (= 0 (:exit result))) 17 | (is (= "" (:err result))) 18 | (is (= [""] (str/split-lines (:out result)))))) 19 | -------------------------------------------------------------------------------- /src/dinodoc/tbls/impl.clj: -------------------------------------------------------------------------------- 1 | (ns ^:no-doc dinodoc.tbls.impl 2 | (:require 3 | [babashka.fs :as fs] 4 | [clojure.string :as str])) 5 | 6 | (defn resolve-link [dir target] 7 | (let [segments (str/split target #":") 8 | target-path (->> (concat (butlast segments) 9 | [(str (last segments) ".md")]) 10 | (str/join "/"))] 11 | (if (fs/exists? (fs/file dir target-path)) 12 | target-path 13 | (let [target-pattern (->> (concat (butlast segments) 14 | [(str "*." (last segments) ".md")]) 15 | (str/join "/"))] 16 | (when-some [filename (first (fs/glob dir target-pattern))] 17 | (str/replace-first filename (str dir "/") "")))))) 18 | -------------------------------------------------------------------------------- /test/src/dinodoc/contextive_test.clj: -------------------------------------------------------------------------------- 1 | (ns dinodoc.contextive-test 2 | (:require 3 | [clojure.test :refer [deftest]] 4 | [dinodoc.contextive :as contextive] 5 | [dinodoc.api :as dinodoc] 6 | [dinodoc.approval-helpers :as approval])) 7 | 8 | (deftest generator-test 9 | (let [output-path "test/resources/contextive/output"] 10 | (dinodoc/generate 11 | {:inputs [{:path "test/resources/contextive" 12 | :output-path "."} 13 | {:generator (contextive/make-generator 14 | {:definitions-file "test/resources/contextive/definitions.yml"}) 15 | :output-path "glossary"}] 16 | :output-path output-path 17 | :github/repo "repo" 18 | :git/branch "main"}) 19 | 20 | (approval/is-same? output-path))) 21 | -------------------------------------------------------------------------------- /test/output/docs/api/codox/example2/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_label: example2 3 | title: codox.example2 4 | toc_min_heading_level: 2 5 | toc_max_heading_level: 4 6 | custom_edit_url: 7 | --- 8 | 9 | 10 | *deprecated in 2.0 | added in 1.1* 11 | 12 | 13 | 14 | 15 | 16 | ### bar {#bar} 17 | ``` clojure 18 | (bar x & body) 19 | ``` 20 | 21 | 22 | *macro* 23 | 24 | 25 | ### baz {#baz} 26 | 27 | 28 | ### foo {#foo} 29 | ``` clojure 30 | (foo x y & z) 31 | ``` 32 | 33 | 34 | ### marklinks {#marklinks} 35 | ``` clojure 36 | (marklinks x) 37 | ``` 38 | 39 | 40 | Let's try some [links][1]. 41 | 42 | [1]: http://example.com 43 | 44 | ### quz {#quz} 45 | 46 | 47 | Var with removed source link. 48 | 49 | ### really\-long\-function\-name\-with\-hyphens {#really-long-function-name-with-hyphens} 50 | 51 | -------------------------------------------------------------------------------- /experiments/antora/antora-playbook.yml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://raw.githubusercontent.com/asciidoctor/asciidoctor-intellij-plugin/main/src/main/resources/jsonSchemas/antoraPlaybookSchema.json 2 | site: 3 | title: Antora Docs 4 | # start_page: example::index.adoc 5 | content: 6 | sources: 7 | # if url is a path, it must be to the git repo root 8 | - url: ../.. 9 | start_paths: experiments/antora/examples, experiments/antora/experiments 10 | # start_paths: experiments/antora/experiments 11 | ui: 12 | bundle: 13 | url: https://gitlab.com/antora/antora-ui-default/-/jobs/artifacts/HEAD/raw/build/ui-bundle.zip?job=bundle-stable 14 | snapshot: true 15 | antora: 16 | extensions: 17 | - require: '@sntke/antora-mermaid-extension' 18 | asciidoc: 19 | extensions: 20 | - ./apilink-extension 21 | -------------------------------------------------------------------------------- /components/antora/src/dinodoc/antora.clj: -------------------------------------------------------------------------------- 1 | (ns dinodoc.antora 2 | (:require 3 | [babashka.fs :as fs] 4 | [clojure.string :as str] 5 | [dinodoc.antora.impl :as impl])) 6 | 7 | (defn generate-navigation 8 | "Given a directory with .adoc files returns a string of auto-generated AsciiDoc content to be used for a navigation sidebar tree." 9 | [path] 10 | (let [base-path (str/replace (str path) #"/?$" "/")] 11 | (->> (impl/generate-navigation-items path base-path "*") 12 | (str/join "\n")))) 13 | 14 | (defn transform-directory 15 | "Transforms .md files in a given directory to .adoc files that can be rendered as pages with Antora." 16 | [path] 17 | (doseq [file (fs/glob path "**.md")] 18 | (->> (slurp (fs/file file)) 19 | (impl/md->adoc) 20 | (spit (str (fs/strip-ext file) ".adoc"))))) 21 | -------------------------------------------------------------------------------- /components/contextmapper/src/dinodoc/contextmapper.clj: -------------------------------------------------------------------------------- 1 | (ns dinodoc.contextmapper 2 | (:require 3 | [dinodoc.contextmapper.impl :as impl] 4 | [dinodoc.generator :as generator])) 5 | 6 | (deftype ^:private ContextMapperGenerator [opts ^:volatile-mutable jmodel ^:volatile-mutable index] 7 | generator/Generator 8 | (prepare-index [_] 9 | (let [{:keys [model-file]} opts] 10 | (set! jmodel (impl/load-model model-file)) 11 | (set! index (impl/build-index jmodel)))) 12 | (resolve-link [_ target] 13 | (get index target)) 14 | (generate [_ {:keys [output-path]}] 15 | (impl/render-model {:jmodel jmodel 16 | :output-path output-path}))) 17 | 18 | (defn make-generator 19 | "Options: 20 | 21 | - `:model-file` - path to .cml file" 22 | [opts] 23 | (->ContextMapperGenerator opts nil nil)) 24 | -------------------------------------------------------------------------------- /components/statecharts/README.md: -------------------------------------------------------------------------------- 1 | # Statechart diagrams 2 | 3 | Render logic modeled as state machines or [statecharts](https://statecharts.dev/ 4 | ) represented in code using [clj-statecharts](https://github.com/lucywang000/clj-statecharts) library. 5 | 6 | Statecharts are currently specified manually and rendered using [[dinodoc.statecharts/render-machine-var]]. 7 | 8 | See the example [doc.clj](https://github.com/dundalek/dinodoc/blob/main/examples/statecharts/doc.clj) recipe and the rendered [result](https://dinodoc.pages.dev/examples/statecharts/). 9 | 10 | In the future a better API should be designed, perhaps collecting statecharts from a codebase automatically. 11 | 12 | **⚠️ Warning**: Using `requiring-resolve` to access statechart machine data will result in code being evaluated, therefore it only needs to be run on trusted sources! 13 | 14 | -------------------------------------------------------------------------------- /components/contextmapper/test/resources/example.cml: -------------------------------------------------------------------------------- 1 | ContextMap ExampleMap { 2 | contains ContextA 3 | contains ContextB 4 | } 5 | 6 | BoundedContext ContextA { 7 | } 8 | 9 | BoundedContext ContextB implements SubdomainB { 10 | type = SYSTEM 11 | domainVisionStatement = "Responsible for B." 12 | responsibilities = "Foo", "Bar" 13 | implementationTechnology = "Clojure" 14 | 15 | Aggregate AggregateFoo { 16 | owner = TeamX 17 | } 18 | 19 | Aggregate AggregateBar { 20 | owner = TeamX 21 | } 22 | } 23 | 24 | BoundedContext TeamX { type TEAM } 25 | BoundedContext TeamY { type TEAM } 26 | 27 | Domain DomainA { 28 | domainVisionStatement = "About domain A." 29 | Subdomain SubdomainB { 30 | type = CORE_DOMAIN 31 | domainVisionStatement = "SubdomainB managing B." 32 | } 33 | Subdomain SubdomainWithoutMetadata { 34 | } 35 | } 36 | 37 | Domain BlankDomain {} 38 | -------------------------------------------------------------------------------- /examples/promesa/doc.clj: -------------------------------------------------------------------------------- 1 | (ns doc 2 | (:require 3 | [babashka.fs :as fs] 4 | [clojure.string :as str] 5 | [dinodoc.api :as dinodoc])) 6 | 7 | (dinodoc/generate 8 | {:inputs [{:path "promesa" 9 | :output-path "."}] 10 | :output-path "docs"}) 11 | 12 | (fs/update-file "docs/changelog.md" 13 | #(str/replace % "[`promesa.impl`](./api/promesa/impl/" "`promesa.impl`")) 14 | 15 | ;; Fixups for MDX compatibility, for own documentation would fix source markdown articles directly 16 | (fs/update-file "docs/changelog.md" 17 | #(str/replace % "JDK <= 8" "JDK \\<= 8")) 18 | 19 | (fs/update-file "docs/api/promesa/core/index.md" 20 | #(str/replace % "(js/fetch #js {...})" "(js/fetch #js \\{...\\})")) 21 | 22 | (fs/update-file "docs/api/promesa/exec/csp/index.md" 23 | #(str/replace % "(sp/ yarn deploy 39 | ``` 40 | 41 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. 42 | -------------------------------------------------------------------------------- /examples/antora/README.md: -------------------------------------------------------------------------------- 1 | # Antora integration 2 | 3 | Uses [Antora utilities](https://dinodoc.pages.dev/docs/antora/) to render markdown files and API docs using Antora. 4 | 5 | See the [rendered example](https://dinodoc.pages.dev/examples/antora/example/api/example/main/). Generate example docs with: 6 | 7 | ```sh 8 | bb generate 9 | ``` 10 | 11 | Sample link to [[example.main/greet]] function in API docs. 12 | 13 | ## How the example works 14 | 15 | 1) The Antora generator uses `antora-playbook.yml` where sources are defined. 16 | 2) That resolves to a component described in `antora.yml` which uses the [collector-extension](https://gitlab.com/antora/antora-collector-extension) that executes the API docs generator and converts markdown files to asciidoc using `pandoc`. 17 | 18 | We do this two-step process to be able to leverage functionality of Antora to fetch and collect content from multiple repos, where each can optionaly specify how its API docs are generated. 19 | -------------------------------------------------------------------------------- /src/dinodoc/generator.clj: -------------------------------------------------------------------------------- 1 | (ns dinodoc.generator) 2 | 3 | (defprotocol Generator 4 | "The `Generator` protocol defines an abstraction for a source that generates documentation and resolves links to entities. 5 | 6 | Lifecycle: 7 | 1. `prepare-index` is called once at the beginning. 8 | 9 | The generator can parse or analyze the source at this stage to be able to serve subsequent `resolve-link` calls. 10 | 2. `resolve-link` can be called zero or many times. 11 | 3. `generate` is called once at the end. 12 | 13 | The generator writes its output to a given location. The generator can rely on the index to generate the output." 14 | 15 | (prepare-index 16 | [_] "Prepare the index for subsequent `resolve-link` calls.") 17 | (resolve-link 18 | [_ target] "Return a relative link given a logical target or `nil` if there is no match.") 19 | (generate 20 | [_ opts] "Passed options: 21 | 22 | - `:output-path` - location where output should be written")) 23 | -------------------------------------------------------------------------------- /components/statecharts/test/src/dinodoc/statecharts/statecharts_test.clj: -------------------------------------------------------------------------------- 1 | (ns dinodoc.statecharts.statecharts-test 2 | (:require 3 | [clojure.java.io :as io] 4 | [clojure.test :refer [deftest]] 5 | [dinodoc.approval-helpers :as approval] 6 | [dinodoc.impl.git :as git] 7 | [dinodoc.impl.git-test :as git-test] 8 | [dinodoc.statecharts :as statecharts])) 9 | 10 | (deftest render-machine-test 11 | (let [approval-file "test/output/machines.md"] 12 | (with-open [writer (io/writer approval-file)] 13 | (binding [*out* writer] 14 | (git-test/with-main-branch 15 | (statecharts/render-machine-var (requiring-resolve 'example.statecharts/machine)) 16 | (statecharts/render-machine-var (requiring-resolve 'example.statecharts/regions))) 17 | (with-redefs [git/detect-repo-info (fn [_])] 18 | (statecharts/render-machine-var (requiring-resolve 'example.statecharts/dog-walk))))) 19 | (approval/is-same? approval-file))) 20 | -------------------------------------------------------------------------------- /test/output/docs/api/samples/protocols/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_label: protocols 3 | title: samples.protocols 4 | toc_min_heading_level: 2 5 | toc_max_heading_level: 4 6 | custom_edit_url: 7 | --- 8 | 9 | 10 | 11 | 12 | 13 | ### IBulkhead {#IBulkhead} 14 | 15 | 16 | Bulkhead main API 17 | 18 | *protocol* 19 | 20 | 21 | #### \-get\-stats {#-get-stats} 22 | ``` clojure 23 | (-get-stats _) 24 | ``` 25 | 26 | 27 | Get internal statistics of the bulkhead instance 28 | 29 | *protocol* 30 | 31 | 32 | #### \-invoke\! {#-invoke-BANG-} 33 | ``` clojure 34 | (-invoke! _ f) 35 | ``` 36 | 37 | 38 | Call synchronously a function under bulkhead context 39 | 40 | *protocol* 41 | 42 | 43 | ### IQueue {#IQueue} 44 | 45 | 46 | *protocol* 47 | 48 | 49 | #### \-offer\! {#-offer-BANG-} 50 | ``` clojure 51 | (-offer! _ _) 52 | ``` 53 | 54 | 55 | *protocol* 56 | 57 | 58 | #### \-poll\! {#-poll-BANG-} 59 | ``` clojure 60 | (-poll! _) 61 | ``` 62 | 63 | 64 | *protocol* 65 | 66 | -------------------------------------------------------------------------------- /tests.edn: -------------------------------------------------------------------------------- 1 | #kaocha/v1 2 | {:tests 3 | [{:id :unit 4 | :source-paths ["src" 5 | "components/antora/src" 6 | "components/contextmapper/src" 7 | "components/structurizr/src" 8 | "components/statecharts/src" 9 | "examples/statecharts/src"] 10 | :test-paths ["test/src" 11 | "components/antora/test/src" 12 | "components/contextmapper/test/src" 13 | "components/structurizr/test/src" 14 | "components/statecharts/test/src"] 15 | :skip-meta [:skip] 16 | :focus-meta [:focus]}]} 17 | 18 | ; :cloverage/opts 19 | ; ;; Doseq reports false partial coverage (always yellow) due to how it macroexpands. 20 | ; ;; There is an option to disable instrumenting it, but that unfortunately also stops covering the whole body. 21 | ; ;; https://github.com/cloverage/cloverage/issues/23 22 | ; {:exclude-call [clojure.core/doseq]}} 23 | -------------------------------------------------------------------------------- /examples/reitit/doc.clj: -------------------------------------------------------------------------------- 1 | (ns doc 2 | (:require 3 | [babashka.fs :as fs] 4 | [clojure.string :as str] 5 | [dinodoc.api :as dinodoc])) 6 | 7 | (dinodoc/generate 8 | {:inputs (concat 9 | [{:path "reitit" 10 | :output-path "."}] 11 | (fs/list-dir "reitit/modules")) 12 | :path "reitit" 13 | :output-path "docs" 14 | :api-mode :global}) 15 | 16 | (fs/copy-tree "reitit/doc/images" "docs/images") 17 | 18 | ;; causes issues with images, dinodoc should replace image links as well 19 | (fs/update-file "docs/misc/performance.md" 20 | (fn [content] 21 | (str/replace content #"\]\(images/" "](../images/"))) 22 | 23 | (fs/update-file "docs/basics/name-based-routing.md" 24 | (fn [content] 25 | (str/replace content 26 | "[`reitit.impl/IntoString`](../api/reitit/impl/#IntoString)" 27 | "`reitit.impl/IntoString`"))) 28 | 29 | (shutdown-agents) 30 | -------------------------------------------------------------------------------- /components/contextmapper/test/output/minimal/context-mapMinimal.svg: -------------------------------------------------------------------------------- 1 | Sorry, we cannot generate a component diagram. Your Context Map seems to be empty. -------------------------------------------------------------------------------- /examples/contextmapper/README.md: -------------------------------------------------------------------------------- 1 | # ContextMapper 2 | 3 | Example of rendering documentation for Domain Driven Design (DDD) model using [ContextMapper](https://contextmapper.org) 4 | defined [CML](https://contextmapper.org/docs/language-reference/) model. 5 | 6 | See the rendered [example](https://dinodoc.pages.dev/examples/contextmapper/insurance-map/). 7 | Example of linking to a specific domain [[InsuranceDomain]] or a bounded context [[RiskManagementContext]]. 8 | 9 | ### Considerations 10 | 11 | - Teams in CML are modeled as type of Bounded Contexts, but I find clearer to treat and render them separately from contexts. 12 | - Teams are rendered on a single page since there is not much details available. 13 | If there is more content in the future then they can be rendered as separate pages. 14 | - Currently not rendering: 15 | - user requirements, use cases, user stories. 16 | - partnership details 17 | - tactical elements like aggregates, entities, etc. (just shown in the context diagrams for now) 18 | -------------------------------------------------------------------------------- /test/src/dinodoc/fs_helpers_test.clj: -------------------------------------------------------------------------------- 1 | (ns dinodoc.fs-helpers-test 2 | (:require 3 | [babashka.fs :as fs] 4 | [clojure.test :refer [deftest is testing]] 5 | [dinodoc.fs-helpers :as fsh])) 6 | 7 | (deftest with-temp-dir-test 8 | (fsh/with-temp-dir 9 | (fn [{:keys [fspit fslurp]}] 10 | (testing "basic file helper" 11 | (fspit "file.txt" "foo") 12 | (is (= "foo" (fslurp "file.txt")))) 13 | 14 | (testing "automatically creates nested directories" 15 | (fspit "nested/file.txt" "bar") 16 | (is (= "bar" (fslurp "nested/file.txt"))))))) 17 | 18 | (deftest fsdata-test 19 | (fsh/with-temp-dir 20 | (fn [{:keys [dir fspit]}] 21 | (fspit "file.txt" "foo") 22 | (fspit "nested/file.txt" "bar") 23 | (fs/create-dir (str dir "/emptydir")) 24 | 25 | (is (= {"file.txt" "foo" 26 | "nested" {"file.txt" "bar"} 27 | "emptydir" {}} 28 | (fsh/fsdata dir))) 29 | (is (= {} (fsh/fsdata (str dir "/emptydir"))))))) 30 | -------------------------------------------------------------------------------- /components/structurizr/test/output/dsl-getting-started/Software System-2/index.md: -------------------------------------------------------------------------------- 1 | # Software System 2 | 3 | My software system. 4 | 5 | ### SystemContext 6 | 7 | ```mermaid 8 | graph TB 9 | linkStyle default fill:transparent 10 | 11 | subgraph diagram [Software System - System Context] 12 | style diagram fill:transparent,stroke:#ffffff 13 | 14 | 1["
User
[Person]
A user of my software system.
"] 15 | style 1 fill:#08427b,stroke:#052e56,color:#ffffff 16 | 2["
Software System
[Software System]
My software system.
"] 17 | click 2 "../Software%20System-2/" "Software%20System-2/" 18 | style 2 fill:#1168bd,stroke:#0b4884,color:#ffffff 19 | 20 | 1-. "
Uses
" .->2 21 | end 22 | ``` 23 | 24 | -------------------------------------------------------------------------------- /test/src/dinodoc/tbls_test.clj: -------------------------------------------------------------------------------- 1 | (ns dinodoc.tbls-test 2 | (:require 3 | [clojure.test :refer [deftest is testing]] 4 | [dinodoc.fs-helpers :refer [with-temp-dir]] 5 | [dinodoc.tbls.impl :refer [resolve-link]])) 6 | 7 | (deftest resolve-test 8 | (with-temp-dir 9 | (fn [{:keys [dir fspit]}] 10 | (fspit "chinook/Album.md" "") 11 | (fspit "sakila/public.customer.md" "") 12 | 13 | (testing "basic" 14 | (is (= "Album.md" (resolve-link (str dir "/chinook") "Album"))) 15 | (is (= "public.customer.md" (resolve-link (str dir "/sakila") "public.customer")))) 16 | 17 | (testing "multiple databases" 18 | (is (= "chinook/Album.md" (resolve-link dir "chinook:Album"))) 19 | (is (= "sakila/public.customer.md" (resolve-link dir "sakila:customer")))) 20 | 21 | (testing "shorthand omitting postgres public schema" 22 | (is (= "public.customer.md" (resolve-link (str dir "/sakila") "customer"))) 23 | (is (= "sakila/public.customer.md" (resolve-link dir "sakila:public.customer"))))))) 24 | -------------------------------------------------------------------------------- /experiments/stack-graphs/dumper/src/main.rs: -------------------------------------------------------------------------------- 1 | use serde_json; 2 | use stack_graphs::storage::SQLiteReader; 3 | use std::fs; 4 | 5 | fn main() -> Result<(), std::io::Error> { 6 | let file_to_dump = "../../../examples/ts/src/index.ts"; 7 | 8 | // Tried to use `tree_sitter_stack_graphs::cli::database::default_user_database_path_for_crate("tree-sitter-stack-graphs-typescript")` 9 | // but it seems it is a private module. 10 | let db_path = concat!( 11 | env!("HOME"), 12 | "/.local/share/tree-sitter-stack-graphs-typescript.sqlite" 13 | ); 14 | let file_path = std::env::current_dir()?.join(file_to_dump).canonicalize()?; 15 | 16 | let mut db = SQLiteReader::open(&db_path).expect("DB opened"); 17 | db.load_graph_for_file(&file_path.to_string_lossy()) 18 | .expect("Graph loaded"); 19 | let (graph, _, _) = db.get(); 20 | 21 | let json = serde_json::to_string_pretty(&graph.to_serializable())?; 22 | fs::create_dir_all("../target")?; 23 | fs::write("../target/graph.json", json)?; 24 | 25 | Ok(()) 26 | } 27 | -------------------------------------------------------------------------------- /test/src/dinodoc/impl/git_test.clj: -------------------------------------------------------------------------------- 1 | (ns dinodoc.impl.git-test 2 | (:require 3 | [clojure.test :refer [deftest is]] 4 | [dinodoc.impl.git :as git])) 5 | 6 | ;; mocking current branch so that test does not fail when being switched to other branch during development 7 | (defmacro with-main-branch [& body] 8 | `(with-redefs [git/current-branch (fn [_#] "main") 9 | git/branch-remote (fn [_# _#] "origin")] 10 | ~@body)) 11 | 12 | (deftest detect-repo-info 13 | (is (= {:branch "main" 14 | :url "https://github.com/dundalek/dinodoc"} 15 | (with-main-branch 16 | (git/detect-repo-info "."))))) 17 | 18 | (deftest remote-url-to-web 19 | (is (= "https://github.com/borkdude/quickdoc" 20 | (git/remote-url-to-web "https://github.com/borkdude/quickdoc"))) 21 | (is (= "https://github.com/borkdude/quickdoc" 22 | (git/remote-url-to-web "https://github.com/borkdude/quickdoc.git"))) 23 | (is (= "https://github.com/borkdude/quickdoc" 24 | (git/remote-url-to-web "git@github.com:borkdude/quickdoc.git")))) 25 | -------------------------------------------------------------------------------- /components/structurizr/src/dinodoc/structurizr.clj: -------------------------------------------------------------------------------- 1 | (ns dinodoc.structurizr 2 | (:require 3 | [dinodoc.generator :as generator] 4 | [dinodoc.structurizr.impl.core :as impl])) 5 | 6 | (deftype ^:private StructurizrGenerator [opts ^:volatile-mutable workspace ^:volatile-mutable index] 7 | generator/Generator 8 | (prepare-index [_] 9 | (let [{:keys [workspace-file]} opts] 10 | (set! workspace (impl/load-workspace workspace-file)) 11 | (impl/set-element-urls workspace) 12 | (set! index (impl/build-index workspace)))) 13 | (resolve-link [_ target] 14 | (get index target)) 15 | (generate [_ {:keys [output-path]}] 16 | (impl/render-workspace {:workspace workspace 17 | :output-path output-path}))) 18 | 19 | (defn make-generator 20 | "Generate architecture documentation with diagrams from a Structurizr workspace. 21 | 22 | Options: 23 | * `:workspace-file` - Structurizr workspace file, accepts DSL or JSON format, for example `\"some/path/workspace.dsl\"`" 24 | [opts] 25 | (->StructurizrGenerator opts nil nil)) 26 | -------------------------------------------------------------------------------- /script/build_examples.clj: -------------------------------------------------------------------------------- 1 | (ns build-examples 2 | (:require 3 | [babashka.fs :as fs] 4 | [babashka.process :refer [shell]])) 5 | 6 | (defn build-and-copy-docs [source-dir target-path] 7 | (shell {:dir source-dir} "clojure -M:doc") 8 | (fs/delete-tree target-path) 9 | (fs/copy-tree (str source-dir "/docs") target-path)) 10 | 11 | (defn build-dinodoc-docs [] 12 | (let [target-path "website/docs/docs" 13 | source-dir "."] 14 | (build-and-copy-docs source-dir target-path))) 15 | 16 | (defn build-example-docs [example] 17 | (let [target-path (str "website/docs/examples/" example) 18 | source-dir (str "examples/" example)] 19 | (build-and-copy-docs source-dir target-path))) 20 | 21 | (defn copy-test-samples [] 22 | (let [target-path "website/docs/docs/samples"] 23 | (fs/delete-tree target-path) 24 | (fs/copy-tree "test/output/docs" target-path))) 25 | 26 | (defn copy-antora-example [] 27 | (let [target-path "website/build/examples/antora"] 28 | (fs/delete-tree target-path) 29 | (fs/copy-tree "examples/antora/build/site" target-path))) 30 | -------------------------------------------------------------------------------- /components/contextmapper/test/src/dinodoc/contextmapper_test.clj: -------------------------------------------------------------------------------- 1 | (ns dinodoc.contextmapper-test 2 | (:require 3 | [clojure.test :refer [deftest]] 4 | [dinodoc.api :as dinodoc] 5 | [dinodoc.approval-helpers :as approval-helpers] 6 | [dinodoc.contextmapper :as contextmapper])) 7 | 8 | (deftest minimal-model 9 | (let [output-path "components/contextmapper/test/output/minimal"] 10 | (dinodoc/generate 11 | {:inputs [{:generator (contextmapper/make-generator 12 | {:model-file "components/contextmapper/test/resources/minimal.cml"})}] 13 | :output-path output-path}) 14 | (approval-helpers/is-same? output-path))) 15 | 16 | (deftest ^{:skip-ci "Likely a different version of Graphviz."} 17 | example-model 18 | (let [output-path "components/contextmapper/test/output/example"] 19 | (dinodoc/generate 20 | {:inputs [{:generator (contextmapper/make-generator 21 | {:model-file "components/contextmapper/test/resources/example.cml"})}] 22 | :output-path output-path}) 23 | (approval-helpers/is-same? output-path))) 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023-2024 Jakub Dundalek 4 | Copyright (c) 2022 Michiel Borkent 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /components/contextmapper/test/output/example/contexts/ContextA/diagram.svg: -------------------------------------------------------------------------------- 1 | Sorry, we cannot generate a class diagram for this Bounded Context. There are no Aggregates or none of the Aggregates contain any domain objects (entities, value objects or domain events). -------------------------------------------------------------------------------- /components/contextmapper/test/output/example/contexts/ContextB/diagram.svg: -------------------------------------------------------------------------------- 1 | Sorry, we cannot generate a class diagram for this Bounded Context. There are no Aggregates or none of the Aggregates contain any domain objects (entities, value objects or domain events). -------------------------------------------------------------------------------- /test/output/docs/api/promesa/util/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_label: util 3 | title: promesa.util 4 | toc_min_heading_level: 2 5 | toc_max_heading_level: 4 6 | custom_edit_url: 7 | --- 8 | 9 | 10 | 11 | 12 | 13 | ### \->Consumer2 {#--GT-Consumer2} 14 | ``` clojure 15 | (->Consumer2 f) 16 | ``` 17 | 18 | 19 | ### \->Function {#--GT-Function} 20 | ``` clojure 21 | (->Function f) 22 | ``` 23 | 24 | 25 | ### \->Function2 {#--GT-Function2} 26 | ``` clojure 27 | (->Function2 f) 28 | ``` 29 | 30 | 31 | ### \->Supplier {#--GT-Supplier} 32 | ``` clojure 33 | (->Supplier f) 34 | ``` 35 | 36 | 37 | ### Consumer2 {#Consumer2} 38 | 39 | 40 | ### Function {#Function} 41 | 42 | 43 | ### Function2 {#Function2} 44 | 45 | 46 | ### Supplier {#Supplier} 47 | 48 | 49 | ### f\-identity {#f-identity} 50 | 51 | 52 | ### handler {#handler} 53 | ``` clojure 54 | (handler fv fc) 55 | ``` 56 | 57 | 58 | Create a handler, mainly for combine two separate functions 59 | into a single callbale. 60 | 61 | ### ignoring {#ignoring} 62 | ``` clojure 63 | (ignoring & exprs) 64 | ``` 65 | 66 | 67 | *macro* 68 | 69 | 70 | ### try\! {#try-BANG-} 71 | ``` clojure 72 | (try! & exprs) 73 | ``` 74 | 75 | 76 | *macro* 77 | 78 | -------------------------------------------------------------------------------- /website/src/css/custom.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Any CSS included here will be global. The classic template 3 | * bundles Infima by default. Infima is a CSS framework designed to 4 | * work well for content-centric websites. 5 | */ 6 | 7 | /* You can override the default Infima variables here. */ 8 | :root { 9 | --ifm-color-primary: #2e8555; 10 | --ifm-color-primary-dark: #29784c; 11 | --ifm-color-primary-darker: #277148; 12 | --ifm-color-primary-darkest: #205d3b; 13 | --ifm-color-primary-light: #33925d; 14 | --ifm-color-primary-lighter: #359962; 15 | --ifm-color-primary-lightest: #3cad6e; 16 | --ifm-code-font-size: 95%; 17 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); 18 | } 19 | 20 | /* For readability concerns, you should choose a lighter palette in dark mode. */ 21 | [data-theme='dark'] { 22 | --ifm-color-primary: #25c2a0; 23 | --ifm-color-primary-dark: #21af90; 24 | --ifm-color-primary-darker: #1fa588; 25 | --ifm-color-primary-darkest: #1a8870; 26 | --ifm-color-primary-light: #29d5b0; 27 | --ifm-color-primary-lighter: #32d8b4; 28 | --ifm-color-primary-lightest: #4fddbf; 29 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); 30 | } 31 | 32 | main { 33 | display: flex; 34 | flex-grow: 1; 35 | } 36 | -------------------------------------------------------------------------------- /test/output/docs/promesa/contributing.md: -------------------------------------------------------------------------------- 1 | --- 2 | {sidebar_position: 5, custom_edit_url: 'https://github.com/funcool/promesa/tree/master/doc/contributing.md'} 3 | --- 4 | 5 | # Contributing 6 | 7 | Unlike Clojure and other Clojure contrib libs, this project does not 8 | have many restrictions for contributions. Just open an issue or pull 9 | request. 10 | 11 | 12 | ### Get the Code 13 | 14 | _promesa_ is open source and can be found on 15 | [github](https://github.com/funcool/promesa). 16 | 17 | You can clone the public repository with this command: 18 | 19 | ``` 20 | git clone https://github.com/funcool/promesa 21 | ``` 22 | 23 | ### Run tests 24 | 25 | To run the tests execute the following: 26 | 27 | For the JVM platform: 28 | 29 | ``` 30 | clojure -X:dev:test 31 | ``` 32 | 33 | And for JS platform: 34 | 35 | ``` 36 | npm install 37 | npm test 38 | ``` 39 | 40 | You will need to have Node.js installed on your system. 41 | 42 | 43 | ### License 44 | 45 | _promesa_ is licensed under MPL-2.0 license: 46 | 47 | ``` 48 | This Source Code Form is subject to the terms of the Mozilla Public 49 | License, v. 2.0. If a copy of the MPL was not distributed with this 50 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 51 | 52 | Copyright (c) Andrey Antukh 53 | ``` 54 | 55 | -------------------------------------------------------------------------------- /examples/polylith/doc.clj: -------------------------------------------------------------------------------- 1 | (ns doc 2 | (:require 3 | [babashka.fs :as fs] 4 | [clojure.string :as str] 5 | [dinodoc.api :as dinodoc])) 6 | 7 | (def doc-tree [["Polylith" {:file "readme.md"}]]) 8 | 9 | (dinodoc/generate 10 | {:output-path "docs" 11 | :inputs (concat 12 | [{:path "polylith" 13 | :output-path "." 14 | :doc-tree doc-tree}] 15 | (->> (fs/list-dir "polylith/components") 16 | (map (fn [path] 17 | {:path path 18 | ;; Example of specifying :source-paths to only include interface.clj files for API docs 19 | :source-paths (->> (fs/glob path "**/interface.clj") 20 | (map #(fs/relativize path %))) 21 | :output-path (str "Components/" (fs/file-name path))})))) 22 | :github/repo "https://github.com/polyfy/polylith" 23 | :git/branch "master"}) 24 | 25 | (fs/copy-tree "polylith/images" "docs/images") 26 | 27 | (fs/update-file "docs/index.md" 28 | (fn [input] 29 | (-> input 30 | (str/replace #"(]+\")>" "$1/>") 31 | (str/replace #"src=\"(images/[^\"]+)\"" "src={require(\"./$1\").default}")))) 32 | 33 | (shutdown-agents) 34 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [main](https://github.com/dundalek/dinodoc/compare/v0.3.0...main) (unreleased) 4 | 5 | ## [v0.3.0](https://github.com/dundalek/dinodoc/compare/v0.2.0...v0.3.0) (2024-05-16) 6 | 7 | New features: 8 | - DB Schema and Structurizr generators now support wiki links to elements 9 | - Integration with language-specific API docs generators (rendering and linking): 10 | - Dokka for Kotlin and Java (markdown-based) 11 | - Javadoc for Java (HTML-based) 12 | - Rustdoc for Rust (HTML-based) 13 | - Rendering and linking to documentation based on non-code models 14 | - Generate documentation for ContextMapper model (Domain Driven Design) 15 | - Render and link to glossary of terms from Contextive definitions 16 | - Experimental helpers to render documentation with Antora 17 | - Transform Markdown to AsciiDoc 18 | - Auto-generate navigation sidebar 19 | 20 | Fixes: 21 | - Fixed rendering without a git repo 22 | 23 | ## [0.2.0](https://github.com/dundalek/dinodoc/compare/v0.1.0...v0.2.0) (2024-03-05) 24 | 25 | New features and examples: 26 | - Structurizr Architecture docs rendering 27 | - HTTP API documentation using OpenAPI 28 | - DB schema documentation 29 | - Statecharts diagram rendering 30 | 31 | Fixes: 32 | - Fixed links to API docs in global hierarchy mode 33 | 34 | ## 0.1.0 (2024-01-16) 35 | 36 | Initial release 37 | -------------------------------------------------------------------------------- /test/output/machines.md: -------------------------------------------------------------------------------- 1 | 2 | ## machine 3 | 4 | An example of a simple lights machine. 5 | Based on https://lucywang000.github.io/clj-statecharts/docs/actions/#a-full-example 6 | 7 | ```mermaid 8 | stateDiagram-v2 9 | state lights { 10 | [*] --> red 11 | green --> yellow : timer 12 | yellow --> red : timer 13 | red --> green : timer 14 | } 15 | ``` 16 | 17 | [source](https://github.com/dundalek/dinodoc/blob/main/example/statecharts.clj#L8-L8) 18 | 19 | ## regions 20 | 21 | Example of parallel regions. 22 | Based on https://statecharts.dev/what-is-a-statechart.html#a-state-can-have-many-regions 23 | 24 | ```mermaid 25 | stateDiagram-v2 26 | state A { 27 | state bc { 28 | [*] --> B 29 | B --> C : flick 30 | C --> B : after-1s 31 | } 32 | state de { 33 | [*] --> D 34 | D --> E : flick 35 | E --> D : flick 36 | } 37 | } 38 | ``` 39 | 40 | [source](https://github.com/dundalek/dinodoc/blob/main/example/statecharts.clj#L41-L41) 41 | 42 | ## dog-walk 43 | 44 | Demonstrating nested states. 45 | Based on https://stately.ai/docs/state-machines-and-statecharts#parent-states 46 | 47 | ```mermaid 48 | stateDiagram-v2 49 | state dog_walk { 50 | [*] --> waiting 51 | waiting --> on_a_walk : leave-home 52 | on_a_walk --> walk_complete : arrive-home 53 | state on_a_walk { 54 | [*] --> walking 55 | walking --> running : speed-up 56 | running --> walking : slow-down 57 | } 58 | } 59 | ``` 60 | -------------------------------------------------------------------------------- /examples/dbschema/README.md: -------------------------------------------------------------------------------- 1 | # Database Schemas 2 | 3 | This example demonstrates using [tbls](https://github.com/k1LoW/tbls) utility to generate documentation for relational database schema. 4 | 5 | Examples (defined in [doc.clj](https://github.com/dundalek/dinodoc/blob/main/examples/dbschema/doc.clj) script): 6 | 7 | - [Chinook](https://dinodoc.pages.dev/examples/dbschema/chinook/) - documentation for the [Chinook](https://github.com/lerocha/chinook-database) sample database using SQLite. 8 | - [Sakila](https://dinodoc.pages.dev/examples/dbschema/sakila/) - uses the [Pagila](https://github.com/devrimgunduz/pagila) sample database and PostgreSQL. 9 | It may not be desirable to connect to real database just to extract schema. 10 | This example shows how to generate docs from a static DDL SQL script by loading it into a temporary Postgres instance. 11 | 12 | Examples of wikilinks: 13 | - [[Album]] or [[chinook:Album]] 14 | - [[actor]] or [[sakila:public.actor]] or [[sakila:actor]] (without the `public.` schema) 15 | 16 | ### Diagram format considerations 17 | 18 | `tbls` supports rendering diagrams as SVG (default, uses graphviz) and Mermaid. 19 | 20 | - I find that Mermaid diagrams look a bit better, but a disadvantage is that for larger schemas the diagrams are scaled down and the text can end up illegible. 21 | - Therefore I slightly prefer the SVG format because as a workaround one can open it in another browser tab to pan and zoom to see all details. 22 | -------------------------------------------------------------------------------- /src/dinodoc/impl/cljapi.clj: -------------------------------------------------------------------------------- 1 | (ns 2 | ^:no-doc 3 | dinodoc.impl.cljapi 4 | (:require 5 | [babashka.fs :as fs] 6 | [dinodoc.generator :as generator] 7 | [dinodoc.impl.core :as impl] 8 | [dinodoc.impl.quickdoc.api :as qd] 9 | [dinodoc.impl.quickdoc.impl :as qimpl])) 10 | 11 | (deftype CljapiGenerator [opts ^:volatile-mutable resolve-link-fn ^:volatile-mutable analysis] 12 | generator/Generator 13 | (prepare-index [_] 14 | (let [{:keys [source-paths]} opts 15 | analysis' (impl/run-analysis source-paths)] 16 | (set! analysis analysis') 17 | (set! resolve-link-fn 18 | (let [format-href (fn [target-ns target-var] 19 | (let [formatted-ns (qimpl/absolute-namespace-link target-ns)] 20 | (qimpl/format-href formatted-ns target-var)))] 21 | (qimpl/make-link-resolver (impl/make-ns->vars analysis) nil format-href))))) 22 | (resolve-link [_ target] 23 | (resolve-link-fn target)) 24 | (generate [_ {:keys [output-path]}] 25 | (let [{:keys [path var-source-fn]} opts] 26 | (println "Generating" path) 27 | (qd/quickdoc 28 | {:analysis analysis 29 | :outdir output-path 30 | :var-source-fn var-source-fn}) 31 | 32 | (when (fs/exists? output-path) 33 | (spit (str output-path "/_category_.json") 34 | "{\"label\":\"API\"}"))))) 35 | 36 | (defn make-generator [opts] 37 | (->CljapiGenerator opts nil nil)) 38 | -------------------------------------------------------------------------------- /test/src/dinodoc/fs_helpers.clj: -------------------------------------------------------------------------------- 1 | (ns dinodoc.fs-helpers 2 | (:require 3 | [babashka.fs :as fs] 4 | [clojure.string :as str])) 5 | 6 | (defn relfs [dir] 7 | {:dir dir 8 | :fspit (fn [filename content & opts] 9 | (let [path (str dir "/" filename)] 10 | (fs/create-dirs (fs/parent path)) 11 | (apply spit path content opts))) 12 | :fslurp (fn [filename & opts] 13 | (apply slurp (str dir "/" filename) opts))}) 14 | 15 | (defn with-temp-dir [f] 16 | (fs/with-temp-dir [dir {}] 17 | (f (relfs dir)))) 18 | 19 | (defn fsdata [dir] 20 | (let [file (fs/file dir) 21 | path (str file "/")] 22 | (->> (file-seq file) 23 | (next) ;; first item is the directory itself, drop it 24 | (reduce (fn [m filename] 25 | (let [filepath (-> (str filename) 26 | (str/replace-first path "")) 27 | segments (str/split filepath #"/")] 28 | (cond 29 | (fs/regular-file? filename) (assoc-in m segments (slurp filename)) 30 | (fs/directory? filename) (update-in m segments #(or % {})) 31 | :else (throw (ex-info "Unsupported file type" {:filename filename}))))) 32 | {})))) 33 | 34 | (comment 35 | (let [{:keys [dir fspit fslurp]} (relfs "tmp")] 36 | (fspit "file.txt" "foo") 37 | (fspit "nested/file.txt" "bar") 38 | (fsdata dir))) 39 | -------------------------------------------------------------------------------- /website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "website", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "docusaurus": "docusaurus", 7 | "start": "docusaurus start --no-open", 8 | "build": "docusaurus build", 9 | "swizzle": "docusaurus swizzle", 10 | "deploy": "docusaurus deploy", 11 | "clear": "docusaurus clear", 12 | "serve": "docusaurus serve", 13 | "write-translations": "docusaurus write-translations", 14 | "write-heading-ids": "docusaurus write-heading-ids" 15 | }, 16 | "dependencies": { 17 | "@docusaurus/core": "2.4.1", 18 | "@docusaurus/preset-classic": "2.4.1", 19 | "@docusaurus/theme-mermaid": "2.4.1", 20 | "@mdx-js/react": "^1.6.22", 21 | "clsx": "^1.2.1", 22 | "docusaurus-plugin-openapi-docs": "^2.0.4", 23 | "docusaurus-plugin-typedoc": "^0.22.0", 24 | "docusaurus-theme-openapi-docs": "^2.0.4", 25 | "prism-react-renderer": "^1.3.5", 26 | "react": "^18.2.0", 27 | "react-dom": "^18.2.0", 28 | "typedoc": "^0.25.7", 29 | "typedoc-plugin-markdown": "^3.17.1" 30 | }, 31 | "devDependencies": { 32 | "@docusaurus/module-type-aliases": "2.4.1" 33 | }, 34 | "browserslist": { 35 | "production": [ 36 | ">0.5%", 37 | "not dead", 38 | "not op_mini all" 39 | ], 40 | "development": [ 41 | "last 1 chrome version", 42 | "last 1 firefox version", 43 | "last 1 safari version" 44 | ] 45 | }, 46 | "engines": { 47 | "node": ">=16.14" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /examples/dbschema/doc.clj: -------------------------------------------------------------------------------- 1 | (ns doc 2 | (:require 3 | [babashka.fs :as fs] 4 | [babashka.process :refer [shell]] 5 | [dinodoc.api :as dinodoc] 6 | [dinodoc.tbls :as tbls])) 7 | 8 | (defn with-temporary-postgres-db [f] 9 | (fs/with-temp-dir [dir {}] 10 | (let [data-dir (str dir "/data") 11 | db-name "mydb" 12 | uri (str "postgresql://" dir "/" db-name)] 13 | (shell "initdb -D" data-dir) 14 | (shell "pg_ctl start -D" data-dir "-o" "-h ''" "-o" "-k" "-o" dir) 15 | (shell "createdb -h" dir db-name) 16 | (try 17 | (f {:host dir :db db-name :uri uri}) 18 | (finally 19 | (shell "pg_ctl stop -D" data-dir)))))) 20 | 21 | (with-temporary-postgres-db 22 | (fn [{:keys [host db uri]}] 23 | (shell "psql --quiet -f" "pagila/pagila-schema.sql" 24 | "-h" host "-d" db) 25 | 26 | (dinodoc/generate 27 | {:inputs [{:path "."} 28 | {:generator (tbls/make-generator 29 | {:dsn (str "sqlite:" (fs/absolutize "./chinook/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite")) 30 | :UNSTABLE_prefix "chinook"}) 31 | :output-path "chinook"} 32 | {:generator (tbls/make-generator 33 | {:dsn uri 34 | :title "Sakila" 35 | :UNSTABLE_prefix "sakila"}) 36 | :output-path "sakila"}] 37 | :output-path "docs"}))) 38 | 39 | (shutdown-agents) 40 | -------------------------------------------------------------------------------- /experiments/stack-graphs/README.md: -------------------------------------------------------------------------------- 1 | This is experiment of using [Stack Graphs](https://github.com/github/stack-graphs/) to index source code in language-agnostic way (based on tree-sitter) in order to get definitions. 2 | 3 | Index example TypeScript source (installing all features to explore, but `--features cli` might be enough): 4 | ``` 5 | cargo install --all-features tree-sitter-stack-graphs-typescript 6 | ``` 7 | 8 | ``` 9 | tree-sitter-stack-graphs-typescript index ../../examples/ts/src 10 | ``` 11 | 12 | Dump to JSON for further exploration, will crate `target/graph.json`. 13 | 14 | ``` 15 | cd dumper 16 | cargo run 17 | ``` 18 | 19 | Explore in REPL using [main.clj](https://github.com/dundalek/dinodoc/blob/main/experiments/stack-graphs/src/dinodoc/stack_graphs/main.clj). 20 | 21 | ## Other utilities 22 | 23 | Show the parse tree: 24 | ``` 25 | tree-sitter-stack-graphs-typescript parse ../../examples/ts/src/index.ts 26 | ``` 27 | 28 | Query for symbol definitions: 29 | ``` 30 | tree-sitter-stack-graphs-typescript query definition ../../examples/ts/src/index.ts:6:13 31 | ``` 32 | 33 | Clear the databse: 34 | ``` 35 | tree-sitter-stack-graphs-typescript clean --delete 36 | ``` 37 | 38 | ## Structure of the database 39 | 40 | - Index stored in sqlite database, on Linux in `~/.local/share/tree-sitter-stack-graphs-typescript.sqlite` (see `default_user_database_path_for_crate`). 41 | - Table `graphs` contains the per-file graphs which are stored as blobs encoded using Rust-specific `bincode` serialization. 42 | -------------------------------------------------------------------------------- /components/dokka/README.md: -------------------------------------------------------------------------------- 1 | # Java, Kotlin (Dokka) 2 | 3 | [Dokka](https://github.com/Kotlin/dokka) engine is used to generate documentation for [Java](https://github.com/dundalek/dinodoc/tree/main/examples/java) and [Kotlin](https://github.com/dundalek/dinodoc/tree/main/examples/kotlin) using the `gfm-plugin`. 4 | 5 | Use [[dinodoc.dokka/generate]] function. 6 | 7 | ## Experimental status 8 | 9 | This is an experimental approach that currently has known issues and limitations: 10 | 11 | - Class members are rendered on separate pages 12 | - Default Dokka markdown renderer (GFM) renders each class member as a separate page which is not very usable. 13 | - A modification is needed to render all members on a single like the HTML renderer. 14 | - Sidebar items and headings do not have proper titles 15 | - We should render title in frontmatter metadata. The `dokkaJekyll` renderer (that builds on top of `dokkaGfm`) outputs frontmatter and can serve as an inspiration. 16 | - We can't use the `jekyll` renderer instead of `gfm` because it transforms link targets from `.md` to `.html` which breaks them in Docusaurus. 17 | - Bad look of rendered signatures 18 | - They are rendered as regular text and contain extra `[jvm]` plaftorm tag (issues [#2073](https://github.com/Kotlin/dokka/issues/2073), [#2782](https://github.com/Kotlin/dokka/issues/2782)). 19 | - As a workaround we could hide the tag for non-multiplatform projects and wrap the signature in `
` either via regex replacement (easier, but brittle) or plugin transformation (more effort, but robust). 20 | -------------------------------------------------------------------------------- /src/dinodoc/rustdoc.clj: -------------------------------------------------------------------------------- 1 | (ns dinodoc.rustdoc 2 | (:require 3 | [babashka.fs :as fs] 4 | [babashka.process :refer [shell]] 5 | [clojure.string :as str] 6 | [dinodoc.generator :as generator] 7 | [dinodoc.impl.fs :refer [create-local-temp-dir]])) 8 | 9 | (defn resolve-link [doc-path definition] 10 | (let [segments (str/split definition #"::") 11 | module-index-path (str/join "/" (concat segments ["index.html"]))] 12 | (if (fs/exists? (str doc-path "/" module-index-path)) 13 | module-index-path 14 | (let [module-path (str/join "/" (butlast segments)) 15 | module-dir (fs/file doc-path module-path) 16 | pattern (str "*." (last segments) ".html")] 17 | (when (fs/directory? module-dir) 18 | (when-some [match (first (fs/list-dir module-dir pattern))] 19 | (str module-path "/" (fs/file-name match)))))))) 20 | 21 | (deftype ^:private RustdocGenerator [opts tmp-dir doc-dir] 22 | generator/Generator 23 | (prepare-index [_] 24 | (let [{:keys [manifest-path]} opts] 25 | (shell "cargo doc --no-deps --manifest-path" manifest-path "--target-dir" tmp-dir))) 26 | (resolve-link [_ target] 27 | (resolve-link doc-dir target)) 28 | (generate [_ {:keys [output-path]}] 29 | (fs/move doc-dir output-path) 30 | (fs/delete-tree tmp-dir))) 31 | 32 | (defn make-generator 33 | "Options: 34 | 35 | - `:manifest-path` - path to Cargo.toml" 36 | [opts] 37 | (let [tmp-dir (str (create-local-temp-dir)) 38 | doc-dir (str tmp-dir "/doc")] 39 | (->RustdocGenerator opts tmp-dir doc-dir))) 40 | -------------------------------------------------------------------------------- /examples/ring/doc.clj: -------------------------------------------------------------------------------- 1 | (ns doc 2 | (:require 3 | [babashka.fs :as fs] 4 | [clojure.string :as str] 5 | [dinodoc.api :as dinodoc])) 6 | 7 | (def doc-tree [["Ring" {:file "wiki/Home.md"}]]) 8 | 9 | (dinodoc/generate 10 | {:output-path "docs" 11 | :inputs (concat 12 | [{:path "." 13 | :output-path "." 14 | :doc-path "wiki" 15 | :doc-tree doc-tree 16 | :edit-url-fn (fn [filename] 17 | (str "https://github.com/ring-clojure/ring/" 18 | (fs/strip-ext filename)))}] 19 | (->> (fs/glob "." "projects/ring/ring*") 20 | (map (fn [path] 21 | {:path path 22 | :output-path (str "ring/" (fs/file-name path))}))) 23 | (fs/glob "." "projects/*"))}) 24 | 25 | (defn strip-build-status [content] 26 | (str/replace content #"\[!\[Build Status\]\([^\n]*" "")) 27 | 28 | ;; Strip out badge from the title which shows in the sidebar 29 | (fs/update-file "docs/ring-defaults/index.md" strip-build-status) 30 | (fs/update-file "docs/ring/index.md" strip-build-status) 31 | (fs/update-file "docs/ring-websocket-async/index.md" strip-build-status) 32 | ;; Fix unquouted HTML tags that interfere with docusaurus MDX renderer 33 | (fs/update-file "docs/ring-headers/api/ring/middleware/x-headers/index.md" 34 | str/replace #",