{"id":19238272,"url":"https://github.com/olical/fenneldoc","last_synced_at":"2026-03-01T17:34:07.865Z","repository":{"id":179499516,"uuid":"663592328","full_name":"Olical/fenneldoc","owner":"Olical","description":"Turn Fennel docstrings into rich markdown documentation (mirror)","archived":false,"fork":false,"pushed_at":"2023-07-07T16:51:17.000Z","size":162,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-23T13:52:23.445Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://gitlab.com/andreyorst/fenneldoc","language":"Fennel","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"andreyorst/fenneldoc","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Olical.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-07-07T16:50:31.000Z","updated_at":"2024-04-17T03:08:02.000Z","dependencies_parsed_at":null,"dependency_job_id":"229f9c39-c388-452a-b3d0-6524275b94bd","html_url":"https://github.com/Olical/fenneldoc","commit_stats":null,"previous_names":["olical/fenneldoc"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/Olical/fenneldoc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Olical%2Ffenneldoc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Olical%2Ffenneldoc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Olical%2Ffenneldoc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Olical%2Ffenneldoc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Olical","download_url":"https://codeload.github.com/Olical/fenneldoc/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Olical%2Ffenneldoc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29976279,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T16:35:47.903Z","status":"ssl_error","status_checked_at":"2026-03-01T16:35:44.899Z","response_time":124,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T16:30:27.890Z","updated_at":"2026-03-01T17:34:07.845Z","avatar_url":"https://github.com/Olical.png","language":"Fennel","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Fenneldoc\n\nTool for automatic documentation generation and validation for the [Fennel](https://fennel-lang.org/) language.\n\n\n## Usage\n\nFenneldoc looks for `.fenneldoc` configuration file in current directory, and accepts files for which documentation will be generated.\n\n    fenneldoc [flags] [files]\n\n\n## Design\n\nFenneldoc loads files at runtime, and goes through exported definitions looking for specific Fennel metadata.\nIt then forms a `doc` directory, in which documentation files are placed following hierarchy of the project.\nIf module specifies `version` or `_VERSION` keyword, documentation is placed under the directory which corresponds to the version.\n\n**Note!**\nFenneldoc doesn't parse files, instead it **runs your code** by using `fennel.dofile`, and collects runtime information, such as metadata and exported functions.\nIt does so in a restricted environment, so if your program has any side effects reachable during file loading, you will get an error.\nUse `--no-sandbox` or `:sandbox` option in config to override this behavior.\n\n\n## Features\n\n- [x] Load runtime information of the module.\n- [x] Configurable item order and sorting.\n- [x] Validate documentation:\n  - [x] Analyze documentation to contain descriptions arguments of the described function;\n  - [x] Run documentation tests, by looking for code inside backticks.\n- [x] Parse macro modules.\n- [x] Automatically generate file local links from inline references.\n\n\n# Documentation format\n\nDocumentation is generated by analyzing function metadata at run time, and inserting it mostly as is into markdown formatted file.\nThis means that all markdown features are supported in the docstring, such as text attributes, cross-linking, commenting, e.t.c.\n\nFor example, here's how you might define information about your `my-module.fnl` file:\n\n``` clojure\n(local my-module {})\n\n(fn my-module.foo [args]\n  \"foo's docstring\"\n  (print args))\n(fn my-module.bar [args]\n  \"bar's docstring, also see `foo'\"\n  (my-module.foo args))\n\nmy-module\n```\n\nAdditionally, you can add a description for the entire module, as well as the author name, copyright, and license via the project-wide `.fenneldoc` configuration file:\n\n```clojure\n{:modules-info\n {\"my-module.fnl\"\n  {:version \"0.1.0\"\n   :description \"Tag line or short description\"\n   :copyright \"Copyright info that appears at the end of the document\"\n   :license \"[license](Link to your license)\"}}}\n```\n\nRunning `fenneldoc my-module.fnl` with this config will procure `doc/my-module.md` with the following contents:\n\n`````` markdown\n# My-module.fnl (0.1.0)\nTag line or short description\n\n**Table of contents**\n\n- [`bar`](#bar)\n- [`foo`](#foo)\n\n## `bar`\nFunction signature:\n\n```\n(bar args)\n```\n\nbar's docstring, also see [`foo`](#foo)\n\n## `foo`\nFunction signature:\n\n```\n(foo args)\n```\n\nfoo's docstring\n\n\n---\n\nCopyright info that appears at the end of the document\n\nLicense: [license](Link to your license)\n\n\n\u003c!-- Generated with Fenneldoc fenneldoc-version\n     https://gitlab.com/andreyorst/fenneldoc --\u003e\n``````\n\nNote that `bar`'s documentation features a link to `foo`'s documentation.\nFor more info see [inline references](#inline-references).\n\nYou will also see warnings in the log, indicating that both `foo` and `bar` have undocumented `args` argument.\n\n\n### Specifying order of documentation items\n\nSince items in Lua tables have arbitrary order, it is impossible to reason about documentation order by inspecting tables returned from modules at runtime.\nAs an escape hatch, Fenneldoc supports specifying order of items in a sequential table in special key `:_DOC_ORDER` stored in the module table.\nFor example we have a module with two functions:\n\n``` clojure\n(fn first-function [...]\n  \"Do something with args.\"\n  ...)\n\n(fn another-function [...]\n  \"Do something else with args.\"\n  ...)\n\n{:first-function first-function\n :another-function another-function}\n```\n\nBecause order of the items in the exported table is arbitrary, Fenneldoc sorts the table alphabetically by default to achieve reproducible results.\nThus the order of the documentation will be `another-function` followed by `first-function`.\nYou can override this behavior by specifying the `:doc-order` key into the respecting file entry under the `:modules-info` key in the configuration file:\n\n``` clojure\n{;; rest of config\n :modules-info {\"path/to/the/file.fnl\" {:doc-order [:first-function :another-function]}}}\n```\n\nIf you wish to sort items differently from alphabetic order, you can specify either `reverse-alphabetic`, or sorting function.\nYou can set this as a value for the `:order` key in configuration file, or by passing it via `--order VALUE` flag.\nNote, that you can't pass sorting function via command-line argument.\n\n\n### Documentation validation\n\nDocumentation is tested by default.\nWhen `fenneldoc` sees three backticks, followed by `fennel`, it treats everything as test code until it sees three backticks again.\nFor example, suppose we made a change in function but forgot to update the docstring:\n\n``` clojure\n(fn sum [a b]\n  \"Sums three arguments.\n\n# Examples\n\n``` fennel\n(assert (= (sum 1 2 3) 6))\n```\"\n  (+ a b))\n```\n\nThis function claims that it sums three arguments, however the actual body only sums two.\n\nIf we run `fenneldoc --mode check sum.fnl`, we'll get the following:\n\n    $ fenneldoc --mode check sum.fnl\n    In file: sum.fnl\n    Error in docstring for: sum\n    In test:\n    ``` fennel\n    (assert (= (sum 1 2 3) 6))\n    ```\n    Error:\n    assertion failed!\n\n    Errors in module sum.fnl\n\nThis prevents confusion when updated function behavior doesn't match documentation.\n\nIn most cases `fenneldoc` is smart enough, and can require your module's exported functions without namespace prefix.\nTherefore you can use functions literally in documentation, e.g. if you return a table, no need to destructure it manually, or store it in some `local` within the docstring.\n\nHowever, if this doesn't work you can specify how dependencies should be required in `.fenneldoc` config.\nThis also doesn't work for macros, so you'll have to add in config a proper require for your macro modules.\nYou do so by writing piece of code as a string under the key, which represents file being processed, and string contains instructing how to require additional dependencies and/or macros:\n\n``` clojure\n{;; rest of config\n :test-requirements {:macro-module.fnl \"(import-macros {: some-macro} :macro-module)\"}}\n```\n\n\n#### Skipping tests\n\nSometimes, you'll want to write a general piece of example code in your documentation that you just don't want to (or it is just impossible) test, but still have the syntax highlighting for the code block in the generated documentation.\nFor this purpose you can use `:skip-test` right after the first code fence:\n\n```clojure\n(fn random-number []\n  \"Generates a random number between 0 and 100.\n# Examples\nHere's a typical representation of a REPL session in the documentation:\n\n``` fennel :skip-test\n\u003e\u003e (random-number)\n42\n```\"\n  (math.random 100))\n```\n\nThis test will not be evaluated.\n\n\n## Inline references\n\nFenneldoc supports automatic resolution of inline references in documentation strings.\nFor example, when docstring contains the following string ``Calls `foo' on its arguments.`` here ```foo'`` is an inline reference.\nInline references start with backtick (backquote) and end with single quote.\nFenneldoc looks up matching heading in currently processed file and replaces inline reference to link, if such heading exists.\nIf heading wasn't found such reference will be replaced to inline code, unless `inline-references` is set to `:keep`.\n\n\n## Configuration\n\nFenneldoc can be configured by placing `.fenneldoc` file at the root of your project, where `fenneldoc` will be called.\nAnother way is to pass command lines to `fenneldoc` directly. Full set of command line arguments can be found by calling `fenneldoc --help`.\n\nConfiguration file is simply a fennel file without extension, which exports a table with keys.\nExample of configuration file:\n\n``` clojure\n{:toc false\n :out-dir \"./documentation\"}\n```\n\nHere, we configure Fenneldoc to omit table of contents, by specifying `:toc false`, and change output directory to `./documentation`.\n\nThere are other options that can be set up on per project basis, see [config.md](./doc/src/config.md) file for more info.\nFull set of available options can also be seen by calling `fenneldoc --help`.\n\n\n### Config generation\n\nFenneldoc can generate configuration file for you with all default options, or update existing config by passing flags to `fenneldoc`.\nIf you want to generate fresh config, remove your old `.fenneldoc` file, and run `fenneldoc --config`.\nThis will create default `.fenneldoc` configuration file.\nIf you want to alter this file contents, you can pass flags to `fenneldoc` like this:\n\n    fenneldoc --no-toc --no-function-signatures --config --mode doc\n\nThis will permanently disable table of contents, function signatures and documentation validation for current project.\n\n## Contributing\n\nPlease do.\nYou can report issues or feature request at [project's Gitlab repository](https://gitlab.com/andreyorst/fenneldoc).\nConsider reading [contribution guidelines](https://gitlab.com/andreyorst/fenneldoc/-/blob/master/CONTRIBUTING.md) beforehand.\n\n\u003c!--  LocalWords:  backticks docstring Fenneldoc TODO config runtime\n      LocalWords:  metadata AST fnl foo's md Lua namespace Gitlab\n      LocalWords:  destructure backtick backquote metamethod\n      LocalWords:  LocalWords\n  --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Folical%2Ffenneldoc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Folical%2Ffenneldoc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Folical%2Ffenneldoc/lists"}