{"id":42212954,"url":"https://github.com/foliant-docs/foliantcontrib.apireferences","last_synced_at":"2026-01-27T01:07:05.595Z","repository":{"id":37861849,"uuid":"345936672","full_name":"foliant-docs/foliantcontrib.apireferences","owner":"foliant-docs","description":"Preprocessor for replacing references to API methods with links to their description","archived":false,"fork":false,"pushed_at":"2025-07-14T14:13:45.000Z","size":91,"stargazers_count":0,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-28T00:22:52.119Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/foliant-docs.png","metadata":{"files":{"readme":"README.md","changelog":"changelog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-03-09T08:34:25.000Z","updated_at":"2025-07-04T10:39:49.000Z","dependencies_parsed_at":"2025-05-16T16:21:10.449Z","dependency_job_id":"d2d21610-89e4-401f-b8fd-82858422a895","html_url":"https://github.com/foliant-docs/foliantcontrib.apireferences","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/foliant-docs/foliantcontrib.apireferences","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foliant-docs%2Ffoliantcontrib.apireferences","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foliant-docs%2Ffoliantcontrib.apireferences/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foliant-docs%2Ffoliantcontrib.apireferences/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foliant-docs%2Ffoliantcontrib.apireferences/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/foliant-docs","download_url":"https://codeload.github.com/foliant-docs/foliantcontrib.apireferences/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foliant-docs%2Ffoliantcontrib.apireferences/sbom","scorecard":{"id":406057,"data":{"date":"2025-08-11","repo":{"name":"github.com/foliant-docs/foliantcontrib.apireferences","commit":"ccae5c108d06f5629aecb0d4e111cd61fdbadd8b"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.1,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":1,"reason":"2 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":2,"reason":"Found 5/19 approved changesets -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: topLevel 'contents' permission set to 'read': .github/workflows/python-publish.yml:17","Warn: no topLevel permission defined: .github/workflows/python-test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/python-publish.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/foliant-docs/foliantcontrib.apireferences/python-publish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/python-publish.yml:29: update your workflow using https://app.stepsecurity.io/secureworkflow/foliant-docs/foliantcontrib.apireferences/python-publish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/python-publish.yml:45: update your workflow using https://app.stepsecurity.io/secureworkflow/foliant-docs/foliantcontrib.apireferences/python-publish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/python-publish.yml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/foliant-docs/foliantcontrib.apireferences/python-publish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/python-test.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/foliant-docs/foliantcontrib.apireferences/python-test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/python-test.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/foliant-docs/foliantcontrib.apireferences/python-test.yml/master?enable=pin","Warn: pipCommand not pinned by hash: test.sh:4","Warn: pipCommand not pinned by hash: test.sh:6","Warn: pipCommand not pinned by hash: .github/workflows/python-publish.yml:34","Warn: pipCommand not pinned by hash: .github/workflows/python-publish.yml:35","Warn: pipCommand not pinned by hash: .github/workflows/python-publish.yml:36","Warn: pipCommand not pinned by hash: .github/workflows/python-publish.yml:52","Warn: pipCommand not pinned by hash: .github/workflows/python-publish.yml:53","Warn: pipCommand not pinned by hash: .github/workflows/python-test.yml:21","Warn: pipCommand not pinned by hash: .github/workflows/python-test.yml:22","Warn: pipCommand not pinned by hash: .github/workflows/python-test.yml:23","Info:   0 out of   6 GitHub-owned GitHubAction dependencies pinned","Info:   1 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of  10 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/python-publish.yml:40"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 12 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T21:17:30.029Z","repository_id":37861849,"created_at":"2025-08-18T21:17:30.029Z","updated_at":"2025-08-18T21:17:30.029Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28794647,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-26T21:49:50.245Z","status":"ssl_error","status_checked_at":"2026-01-26T21:48:29.455Z","response_time":59,"last_error":"SSL_read: 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":"2026-01-27T01:07:01.885Z","updated_at":"2026-01-27T01:07:05.572Z","avatar_url":"https://github.com/foliant-docs.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![](https://img.shields.io/pypi/v/foliantcontrib.apireferences.svg)](https://pypi.org/project/foliantcontrib.apireferences/)  [![](https://img.shields.io/github/v/tag/foliant-docs/foliantcontrib.apireferences.svg?label=GitHub)](https://github.com/foliant-docs/foliantcontrib.apireferences)\n\n# APIReferences Preprocessor for Foliant\n\n\u003e APIReferences is a successor of APILinks preprocessor with slightly changed configuration syntax and completely rewritten insides. APILinks is now deprecated, please use APIReferences instead.\n\nPreprocessor replaces API *reference*s in markdown files with links to the corresponding method description on the API documentation web-page.\n\n## What is it for?\n\nSay, you have API or DB documentation hosted at the url http://example.com/api-docs\n\nIt may be a [Swagger UI](https://swagger.io/tools/swagger-ui/) website or just some static one-page site (like [Slate](https://github.com/slatedocs/slate)).\n\nIf you have a site with API docs, you probably reference them from time in your other documents:\n\n```\nTo authenticate user use API method `POST /user/authenticate`.\n```\n\nWe thought, how cool it'd be if this fragment: **\\`POST /user/authenticate\\`** automatically transformed into a URL of this method's description on your API docs website:\n\n```\nTo authenticate user use API method [POST user/authenticate](http://example.com/api-docs/#post-user-authenticate).\n```\n\nThat's exactly what APIReferences does.\n\n## How does it work?\n\nThe purpose of APIReferences is to convert references into links. In the example above \\``POST /user/authenticate`\\` is a reference, and `[POST user/authenticate](http://example.com/api-docs/#post-user-authenticate)` is a Markdown link, the result of APIReferences' work.\n\nThe resulting link URL (http://example.com/api-docs/#get-user-authenticate) always consists of two parts: `{url}{anchor}`. `url` is static and is set in config, but `anchor` differs for each method. Open your API documentation website and look for HTML elements with `id` attribute near method description sections. When you add this `id` to the website's URL with number sign # (we call this combination an *anchor*), your browser scrolls the page to this exact element.\n\nThe tricky part is to determine which anchor should be added to the website's URL for each method. APIReferences offers several ways to do that, we call these ways *modes* (which are supplied in the `mode` parameter). It's up to you to choose the most suitable mode for your API website.\n\nHere are available modes with their short descriptions. Detailed descriptions and examples are in the **User Guide** below.\n\n**1. Generating anchors**\n\nMode option: `generate_anchor`\n\nConvert reference into an anchor without checking the website.\n\n**2. Find anchor**\n\nMode option: `find_by_anchor`\n\nParse API website and collect all ids from specific tags. Then convert reference into an anchor and check whether the converted anchor is present among these ids.\n\n**3. Find tag content**\n\nMode option: `find_by_tag_content`\n\nThis mode searches not by tag ids but by tag content (`\u003ctag id=\"id\"\u003econtent\u003c/tag\u003e`) Parse API website and collect all tags from the specified list, which have ids and text content. The content to search is constructed from the reference. If the tag is found, return a link to its id.\n\n**4. Find method in swagger spec for SwaggerUI**\n\nMode option: `find_for_swagger`\n\nParse the swagger spec file and find the referenced method. The anchor is then constructed by a template. This mode will work for SwaggerUI websites.\n\n**5. Find method in swagger spec for Redoc**\n\nMode option: `find_for_redoc`\n\nParse the swagger spec file and find the referenced method. The anchor is then constructed by a template. This mode will work for Redoc websites.\n\n***\n\nAPIReferences is a highly customizable preprocessor. You can tune almost anything about reference conversion.\n\nFor details look through the following sections.\n\nGlossary:\n\n- **reference** — reference to an API method in the source file. The one to be replaced with the link, e.g. `GET user/config`\n- **verb** — HTTP method, e.g. `GET`, `POST`, etc.\n- **command** — resource used to represent method on the API documentation webpage, e.g. `/service/healthcheck`.\n- **endpoint prefix** — A prefix from server root to the command. If the command is `/user/status` and full resource is `/api/v0/user/status` then the endpoint prefix should be stated `/api/v0`. In references, you can use either full resource (`{endpoint_prefix}/{command}`) or just the command. APIReferences will sort it out for you.\n- **output** — string, which will replace the *reference*.\n- **tag content** — plain text between the tags, for example `\u003ctag\u003eTag content\u003c/tag\u003e`.\n- **anchor** — web-element id with leading number sign, for example `#get-user-config`. Adding the anchor to the end of the web URL will make a browser scroll to the specified web element.\n- **mode** — the way APIReferences will determine correct anchors to add to website URLs.\n\n## Quick Recipes\n\n### Recipe 1: find by tag content\n\nWe want reference \\``GET /user/status`\\` to be pointed at this element on our API website:\n\n```html\n\u003ch2 id=\"get-user-status\"\u003eOperation GET /user/status\u003c/h2\u003e\n```\n\nMinimal sufficient foliant.yml:\n\n```yaml\npreprocessors:\n    apireferences:\n        API:\n            My-API:\n                mode: find_by_tag_content\n                url: http://example.com/api  # path to your API website\n                content_template: 'Operation {verb} {command}'\n```\n\n\\``GET /user/status`\\` -\u003e [GET /user/status](http://example.com/api#get-user-status)\n\n### Recipe 2: find by tag id\n\nThe task is the same as in Recipe 1. We want reference \\``GET /user/status`\\` to be pointed at this element on our API website:\n\n```html\n\u003ch2 id=\"get-user-status\"\u003eOperation GET /user/status\u003c/h2\u003e\n```\n\nMinimal sufficient foliant.yml:\n\n```yaml\npreprocessors:\n    apireferences:\n        API:\n            My-API:\n                mode: find_by_anchor\n                url: http://example.com/api  # path to your API website\n                anchor_template: '{verb} {command}'\n                anchor_converter: slate\n```\n\n\\``GET /user/status`\\` -\u003e [GET /user/status](http://example.com/api#get-user-status)\n\n### Recipe 3: generate tag id\n\nThe task is the same as in Recipes 1 and 2, but this time you don't have access to API website at the time of building foliant project. We want reference \\``GET /user/status`\\` to be pointed at this element on our API website:\n\n```html\n\u003ch2 id=\"get-user-status\"\u003eOperation GET /user/status\u003c/h2\u003e\n```\n\nMinimal sufficient foliant.yml:\n\n```yaml\npreprocessors:\n    apireferences:\n        API:\n            My-API:\n                mode: generate_anchor\n                url: http://example.com/api  # path to your API website\n                anchor_template: '{verb} {command}'\n                anchor_converter: slate\n```\n\n\\``GET /user/status`\\` -\u003e [GET /user/status](http://example.com/api#get-user-status)\n\n### Recipe 4: find link for SwaggerUI\n\nWe have a SwaggerUI website, and we need to find the link to the method by reference \\``GET /user/status`\\``.\n\nMethod anchors on SwaggerUI consist of tag and operationId, both of which are not present in our reference. APIReferences can find them for you in the spec file. Let's assume that correct tag and operationId are `usertag` and `getStatus`.\n\nMinimal sufficient foliant.yml:\n\n```yaml\npreprocessors:\n    apireferences:\n        API:\n            My-API:\n                mode: generate_for_swagger\n                url: http://example.com/swagger_ui  # path to your API website\n                spec: !path swagger.json  # path or direct url to OpenAPI spec\n```\n\n\\``GET /user/status`\\` -\u003e [GET /user/status](http://example.com/swagger_ui#/usertag/getStatus)\n\n\n## Installation\n\n```shell\n$ pip install foliantcontrib.apireferences\n```\n\n## Config\n\nTo enable the preprocessor, add `apireferences` to `preprocessors` section in the project config:\n\n```yaml\npreprocessors:\n  - apireferences\n```\n\nThe preprocessor has a lot of options. For your convenience, the required options are marked *(required)*; and those options which are used in customization are marked *(optional)*. Most likely you will need just one or two of the latter.\n\n```yaml\npreprocessors:\n- apireferences:\n    targets:  # optional. default: []\n        - site\n    trim_if_targets: # optional. default: []\n        - pdf\n    prefix_to_ignore: Ignore  # optional\n    warning_level: 2  # optional\n    reference:  # optional\n        - regex: *ref_pattern\n          only_with_prefixes: false\n          only_defined_prefixes: false\n          output_template: '[{verb} {command}]({url})'\n          trim_template: '`{verb} {command}`'\n        - regex: *another_ref_pattern  # second reference config. Unlisted options are default\n          output_template: '**{verb} {command}**'\n    API:  # below are examples for each mode\n        Client-API:  # reference prefix\n            mode: generate_anchor\n            url: http://example.com/api/client\n            anchor_template: '{verb} {command}'\n            anchor_converter: pandoc  # optional\n            endpoint_prefix: /api/v1  # optional\n            endpoint_prefix_list: [/api/v1/,/api/v2/,/api/v3/]\n        Admin-API:\n            mode: find_by_anchor\n            url: http://example.com/api/admin\n            anchor_template: '{verb} {command}'\n            anchor_converter: pandoc  # optional\n            endpoint_prefix: /api/v1  # optional\n            tags: ['h1', 'h2', 'h3', 'h4']  # optional\n            login: login  # optional\n            password: password  # optional\n        Another-API: # with max_endpoint_prefix option\n            mode: find_by_anchor\n            url: http://example.com/api/admin\n            anchor_template: '{verb} {command}'\n            anchor_converter: pandoc  # optional\n            endpoint_prefix_list: [/v2/,/v3/,/v4/] #required if max_endpoint_prefix: true\n            max_endpoint_prefix: true # optional\n            login: login  # optional\n            password: password  # optional\n        External-API:\n            mode: find_by_tag_content\n            url: http://example.com/api/external\n            content_template: '{verb} {command}'\n            endpoint_prefix: /api/v1  # optional\n            tags: ['h1', 'h2', 'h3', 'h4']  # optional\n            login: login  # optional\n            password: password  # optional\n        Inernal-API:\n            mode: find_for_swagger\n            url: http://example.com/api/swagger-ui\n            anchor_template: '/{tag}/{operation_id}'\n            anchor_converter: no-transform\n            endpoint_prefix: /api/v1  # optional\n            login: login  # optional\n            password: password  # optional\n```\n\n`targets`\n:   *(optional)* List of supported targets for `foliant make` command. If target is not listed here — preprocessor won't be applied. If the list is an empty — preprocessor will be applied for any target. Default: `[]`\n\n`trim_if_targets`\n:   *(optional)* List of targets for `foliant make` command for which the prefixes from all *references* in the text will be cut out. Default: `[]`\n\n\u003e Only those references whose prefixes are defined in the `API` section (described below) are affected by this option. All references with unlisted prefixes will not be trimmed.\n\n`prefix_to_ignore`\n:   *(optional)* A default prefix for ignoring references. If APIReferences meets a reference with this prefix, it leaves it unchanged. Default: `Ignore`\n\n`warning_level`\n:   *(optional)* `2` — show all warnings for not found references; `1` — show only warnings for not found prefixed references; `0` — don't show warnings about not found references. Default: `2`\n\n`use_multiproject_mode`\n: *(optional)* - Use cached API registries in case of multiproject. Default: `True`\n\n`reference`\n:   *(optional)* List of dictionaries. A subsection for listing all the types of references you are going to catch in the text, and their properties. Options for this section are listed below.\n\n\u003e All reference properties have defaults. If any of them are missing in the config, the defaults will be used. If `reference` section is omitted, APIReferences will use default values.\n\n`apiref_registry_url`\n:   *(optional)* the URL of the remote registry. This option allows to use a pre-prepared registry instead of building a registry with each documentation build.\n\n***\n\n**Reference options**\n\n`regex`\n:   *(optional)* regular expression used to catch *references* in the source. Look for details in the **Capturing References** section.\nDefault:\n\n```\n`\\s*((?P\u003cprefix\u003e[\\w-]+):\\s*)?(?P\u003cverb\u003eOPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT|PATCH|LINK|UNLINK)\\s+(?P\u003ccommand\u003e[^`]+)\\s*`\n```\n\n`only_with_prefixes`\n:   *(optional)* if this is `true`, only *references* with prefix will be transformed. Ordinary links like `GET user/info` will be ignored. Default: `false`\n\n`only_defined_prefixes`\n:   *(optional)* if this is `true` all references whose prefix is not listed in the `API` section (described below) will be ignored. References without prefixes are not affected by this option. Default: `false`.\n\n`output_template`\n:   *(optional)* A template string describing the *output* which will replace the *reference*. More info in the **Customizing Output** section. Default: `'[{verb} {command}]({url})'`\n\n`trim_template`\n:   *(optional)* Only for targets listed in `trim_if_targets` option. Tune this template if you want to customize how APIReferences cuts out prefixes. The reference will be replaced with a text based on this template. Default: ```'`{verb} {command}`'```\n\n***\n\n`API`\n:   *(required)* A subsection for listing APIs and their properties. Define a separate subsection for each API here. The section name represents the API name and, at the same time, the *prefix* used in the references. You need to add at least one API subsection for the preprocessor to work.\n\n**API properties**\n\nThe list of options and some default values differ for each mode.\n\n`mode`\n:   *(required)* API mode, which determines how references are collected. Available modes: `generate_anchor`, `find_by_anchor`, `find_by_tag_content`, `find_for_swagger`, `find_for_redoc`.\n\n\n**`generate_anchor` mode**\n\n`url`\n:   *(required)* An API documentation web-page URL. It will be used to construct the full link to the method.\n\n`anchor_template`\n:   *(required)* A template string describing the format of the anchors in the API documentation web-page. You can use placeholders in {curly braces}, with names of the groups from the reference regex. Example: `'user-content {verb} {command}'`.\n\n`anchor_converter`\n:   *(optional)* anchor converter from [this list](https://github.com/foliant-docs/foliantcontrib.utils.header_anchors#to_id). Determines how string `GET /user/status` is converted into `get-userstatus` or `get-user-status` etc. [List of available converters](https://github.com/foliant-docs/foliantcontrib.utils.header_anchors#to_id). Default: `pandoc`\n\n`endpoint_prefix`\n:   *(optional)* The endpoint prefix from the server root to API methods. If is stated — APIReferences can divide the command into the reference and search for it more accurately. Also, you could use it in templates. More info in the **Commands and Endpoint Prefixes** section. Default: `''`\n\n`endpoint_prefix_list`\n: *(optional)* The list of available endpoint prefixes which could be added to output. Default: `[]`\n\n`trim_query`\n: *(optional)* Cut a query part after `?` character from command while searching for an API link. Default: `True`\n\n**`find_by_anchor` mode**\n\n`url`\n:   *(required)* An API documentation web-page URL. It will be used to construct the full link to the method. In this mode, it is also being parsed to check whether the generated anchor is present on the page.\n\n`anchor_template`\n:   *(required)* A template string describing the format of the anchors in the API documentation web-page. You can use placeholders in {curly braces}, with names of the groups in the reference regex. Example: `'user-content {verb} {command}'`.\n\n`anchor_converter`\n:   *(optional)* anchor converter from [this list](https://github.com/foliant-docs/foliantcontrib.utils.header_anchors#to_id). Determines how string `GET /user/status` is converted into `get-userstatus` or `get-user-status` etc. Default: `pandoc`\n\n`endpoint_prefix`\n:   *(optional)* The endpoint prefix from the server root to API methods. If is stated — APIReferences can divide the command into the reference and search for it more accurately. Also, you could use it in templates. More info in the **Commands and Endpoint Prefixes** section. Default: `''`\n\n`endpoint_prefix_list`\n: *(optional)* The list of available endpoint prefixes which could be added to output. Default: `[]`\n\n`max_endpoint_prefix`\n: *(optional)* If set to True and endpoint_prefix_list is not empty, the preprocessor will automatically search for the highest available version of the API method. It iterates through the endpoint_prefix_list in descending order until it finds the method. This is useful when API methods have different maximum versions in the documentation. Default: `False`\n\n`tags`\n:   *(optional)* list of HTML tags which will be parsed out from the page and searched for ids. Default: `['h1', 'h2', 'h3', 'h4']`\n\n`login`\n:    *(optional)* Login for basic authentication if present on your API site.\n\n`password`\n:    *(optional)* Password for basic authentication if present on your API site.\n\n`trim_query`\n: *(optional)* Cut a query part after `?` character from command while searching for an API link. Default: `True`\n\n**`find_by_tag_content` mode**\n\n`url`\n:   *(required)* An API documentation web-page URL. It will be used to construct the full link to the method. In this mode, it is also being parsed to check whether the generated anchor is present on the page.\n\n`content_template`\n:   *(required)* A template string describing the format of the tag content in the API documentation web-page. You can use placeholders in {curly braces}, with names of the groups in the reference regex. Example: `'{verb} {command}'`.\n\n`endpoint_prefix`\n:   *(optional)* The endpoint prefix from the server root to API methods. If is stated — APIReferences can divide the command into the reference and search for it more accurately. Also, you could use it in templates. More info in the **Commands and Endpoint Prefixes** section. Default: `''`\n\n`endpoint_prefix_list`\n: *(optional)* The list of available endpoint prefixes which could be added to output. Default: `[]`\n\n`max_endpoint_prefix`\n: *(optional)* If set to True and endpoint_prefix_list is not empty, the preprocessor will automatically search for the highest available version of the API method. It iterates through the endpoint_prefix_list in descending order until it finds the method. This is useful when API methods have different maximum versions in the documentation. Default: `False`\n\n`tags`\n:   *(optional)* list of HTML tags which will be parsed out from the page and searched for ids. Default: `['h1', 'h2', 'h3', 'h4']`\n\n`login`\n:    *(optional)* Login for basic authentication if present on your API site.\n\n`password`\n:    *(optional)* Password for basic authentication if present on your API site.\n\n`trim_query`\n: *(optional)* Cut a query part after `?` character from command while searching for an API link. Default: `True`\n\n**`find_for_swagger` mode**\n\n`url`\n:   *(required)* An API documentation web-page URL. It will be used to construct the full link to the method.\n\n`spec`\n:   *(required)* URL or local path to OpenAPI specification file.\n\n`anchor_template`\n:   *(optional)* A template string describing the format of the anchors in the API documentation web-page. You can use placeholders in {curly braces}, with names of the groups in the reference regex. In this mode, you can also use two additional placeholders: `{tag}` and `{operation_id}`. Default: `'/{tag}/{operation_id}'`.\n\n`endpoint_prefix`\n:   *(optional)* The endpoint prefix from the server root to API methods. You may use it in output template. Default: `''`\n\n`endpoint_prefix_list`\n: *(optional)* The list of available endpoint prefixes which could be added to output. Default: `[]`\n\n`login`\n:    *(optional)* Login for basic authentication if present on your API site.\n\n`password`\n:    *(optional)* Password for basic authentication if present on your API site.\n\n`trim_query`\n: *(optional)* Cut a query part after `?` character from command while searching for an API link. Default: `True`\n\n**`find_for_redoc` mode**\n\n`url`\n:   *(required)* An API documentation web-page URL. It will be used to construct the full link to the method.\n\n`spec`\n:   *(required)* URL or local path to OpenAPI specification file.\n\n`anchor_template`\n:   *(optional)* A template string describing the format of the anchors in the API documentation web-page. You can use placeholders in {curly braces}, with names of the groups in the reference regex. In this mode, you can also use two additional placeholders: `{tag}` and `{operation_id}`. Default: `'operation/{operation_id}'`.\n\n`endpoint_prefix`\n:   *(optional)* The endpoint prefix from the server root to API methods. You may use it in output template. Default: `''`\n\n`endpoint_prefix_list`\n: *(optional)* The list of available endpoint prefixes which could be added to output. Default: `[]`\n\n`login`\n:    *(optional)* Login for basic authentication if present on your API site.\n\n`password`\n:    *(optional)* Password for basic authentication if present on your API site.\n\n`trim_query`\n: *(optional)* Cut a query part after `?` character from command while searching for an API link. Default: `True`\n\n# User guide\n\nThe purpose of APIReferences is to convert *references* into Markdown links. \n\nReference is a chunk of text in your Markdown source which will be parsed by APIReferences, separated into groups, and converted into a link. An example of a reference is \\``GET /user/authenticate`\\`. APIReferences uses Regular Expressions to find the reference and split into groups. You can supply your own regular expression in `reference -\u003e regex` param (details in **Capturing References** section below). If you are using the default one, the reference from the example above will be split into two groups:\n\n- **verb**: `GET`,\n- **command**: `/user/authenticate`.\n\nThese groups then will be used to find the referenced method on the API website and also to construct an *output string*.\n\nFor example, with `find_by_tag_content` mode (see the detailed description of all modes below) APIReferences will use `content_template` from API configuration to construct a tag content and search for it on the API website. If the content template is `'{verb} {command}'`, then the constructed content, for the example above, will be `GET /user/authenticate`. APIReferences will search for a tag with such content on the page and get its id.\n\nThe found tag may be `\u003ch2 id=\"get-userauthenticate\"\u003eGET /user/authenticate\u003c/h2\u003e`. APIReferences will take the id from this tag and use it as an anchor to the link: `#get-userauthenticate`. Then it will add the API website path and here's your url: `http://example.com/api/#get-userauthenticate`.\n\nNow, when APILink has the url of the method description, it can construct an output string. The output string is formed by a template, stated in reference `output_template` param. This template contains placeholders, which correspond to the reference groups with an addition of `{url}` placeholder, which contains the url formed above.\n\nIf the output template is `'[{verb} {command}]({url})'`, then the output string, for our example, will be:\n\n`[GET /user/authenticate](http://example.com/api/#get-userauthenticate)`.\n\nThat's it, we've turned our reference into a Markdown link:\n\n\\``GET /user/authenticate`\\` -\u003e `[GET /user/authenticate](http://example.com/api/#get-userauthenticate)`.\n\nThat's the big picture. Now let's start with exploring different *modes* by means of which APIReferences captures references on API websites and transforms them into links.\n\n## API Modes\n\nAs mentioned above, APIReferences takes a reference from your markdown source and splits it into groups. It then uses these groups to find the correct id on the API website. How this search is performed is determined by *API Mode*. It can search for a specific tag on the page by tag content or by its id; it can also search for the operation in an OpenAPI specification file or just construct an id without any checks, depending on the mode you've chosen. The mode is specified in `API -\u003e \u003capi name\u003e -\u003e mode` config option.\n\n### `generate_anchor` mode\n\n`generate_anchor` is the simplest mode. It just generates the anchor basing on the `anchor_template` parameter. It doesn't perform any checks on the API website and doesn't even require the website to be reachable at the time of building your Foliant project.\n\nLet's assume that your API website code looks like this:\n\n```html\n...\n\u003ch2 id=\"user-content-get-userlogin\"\u003eGET /user/status\u003c/h2\u003e\n\u003cp\u003eLorem ipsum dolor sit amet, consectetur adipisicing elit.\u003c/p\u003e\n\n\u003ch2 id=\"user-content-get-apiv2adminstatus\"\u003eGET /api/v2/admin/status\u003c/h2\u003e\n\u003cp\u003eLorem ipsum dolor sit amet, consectetur adipisicing elit.\u003c/p\u003e\n...\n```\n\nAPIReferences config in your `foliant.yml` in this case may look like this:\n\n```yaml\npreprocessors:\n    apireferences:\n        API:\n            My-API:\n                mode: generate_anchor\n                url: http://example.com/api\n                anchor_template: 'user content {verb} {command}'\n                anchor_converter: pandoc\n```\n\nAs you may have noticed, there's no `reference` section in the example above. That's because we will be using default values for the reference.\n\nNow let's reference a **GET /user/status** method in our Markdown source:\n\n```\nTo find out user's status use `My-API: GET /user/status` method.\n```\n\n\u003e Note that for `generate_anchor` mode, the API prefix (`My-API` in our case) is required in the reference. More info about prefixes in **Handling Multiple APIs** section.\n\nAPIReferences will notice a reference mentioned in our markdown: \\``My-API: GET /user/status`\\`. It will capture it and split into three groups:\n\n- **prefix**: `My-API`,\n- **verb**: `GET`,\n- **command**: `/user/status`.\n\nThen it will pass it to the anchor template `'user content {verb} {command}'` which we've stated in our config, and this will result in a string:\n\n`'user content GET /user/status'`\n\nAfter that, APIReferences will convert this string into an id with an anchor converter. We've chosen `pandoc` converter in our config, which will turn the string into this: `user-content-getuserstatus`. That's exactly the id we needed, look at the webpage source:\n\n```html\n\u003ch2 id=\"user-content-get-userstatus\"\u003eGET /user/status\u003c/h2\u003e\n```\n\nAPIReferences will add this id to our API url (which we've stated in config) to form a link: `http://example.com/api#user-content-get-userstatus`.\n\nFinally, it's time to construct a Markdown link. APIReferences takes an `output_template` from the reference config (which is omitted in our example foliant.yml because we are using defaults): `'[{verb} {command}]({url})'`.\n\nPlaceholders in the output template are replaced by groups from our reference, except `{url}` placeholder which is replaced with the url constructed above:\n\n`[GET /user/status](http://example.com/api#user-content-get-userstatus)`\n\nThe conversion is done. Our Markdown content will now look like this:\n\n```\nTo find out user's status use [GET /user/status](http://example.com/api#user-content-get-userstatus) method.\n```\n\n### `find_by_anchor` mode\n\n`find_by_anchor` generates the id by `anchor_template` parameter and searches for this id on the API web page. If an element with such id is found, the reference is converted into a Markdown link. If not — the reference is skipped.\n\nLet's assume that your API website code looks like this:\n\n```html\n...\n\u003ch2 id=\"api-method-get-userstatus\"\u003eGET /user/status\u003c/h2\u003e\n\u003cp\u003eLorem ipsum dolor sit amet, consectetur adipisicing elit.\u003c/p\u003e\n\n\u003ch2 id=\"api-method-get-apiv2adminstatus\"\u003eGET /api/v2/admin/status\u003c/h2\u003e\n\u003cp\u003eLorem ipsum dolor sit amet, consectetur adipisicing elit.\u003c/p\u003e\n...\n```\n\nAPIReferences config in your `foliant.yml` in this case may look like this:\n\n```yaml\npreprocessors:\n    apireferences:\n        reference:\n            output_template: '**[{verb} {command}]({url})**'\n            # other reference properties are default\n        API:\n            My-API:\n                mode: find_by_anchor\n                url: http://example.com/api\n                tags: ['h1', 'h2']\n                anchor_template: 'api-method {verb} {command}'\n                anchor_converter: pandoc\n```\n\nNow let's reference a **GET /user/status** method in our Markdown source:\n\n```\nTo find out user's status use `GET /user/status` method.\n```\n\nAPIReferences will notice a reference mentioned in our markdown: \\``GET /user/status`\\`. It will capture it and split into two groups:\n\n- **verb**: `GET`,\n- **command**: `/user/status`.\n\nThen it will pass it to the anchor template `'api-method {verb} {command}'` which we've stated in our config, and this will result in a string:\n\n`'user content GET /user/status'`\n\nAfter that, APIReferences will convert this string into an id with an anchor converter. We've used `pandoc` converter in our config, which will turn the string into this: `api-method-getuserstatus`.\n\nNow APIReferences will parse the web page and look for all `h1` and `h2` tags (as specified in `tags` parameter) that have ids and compare these ids to our generated id.\n\nOne of the elements satisfies the requirement:\n\n```html\n\u003ch2 id=\"api-method-get-userstatus\"\u003eGET /user/status\u003c/h2\u003e\n```\n\nIt means that referenced method is present on API web page, so APIReferences will add this id to our API url (which we've stated in config) to form a link: `http://example.com/api#api-method-get-userstatus`.\n\nFinally, it's time to construct a Markdown link. APIReferences takes an `output_template` from the reference config: `'**[{verb} {command}]({url})**'`.\n\nPlaceholders in the output template are replaced by groups from our reference, except `{url}` placeholder which is replaced with the url constructed above:\n\n`**[GET /user/status](http://example.com/api#api-method-get-userstatus)**`\n\nThe conversion is done. Our Markdown content will now look like this:\n\n```\nTo find out user's status use **[GET /user/status](http://example.com/api#api-method-get-userstatus)** method.\n```\n\n### `find_by_tag_content` mode\n\n`find_by_tag_content` generates tag content by the `content_template` and searches for an HTML element with such content on the API web page. If an element is found, the reference is converted into a Markdown link. If not — the reference is skipped.\n\nThis mode is convenient when there's no way to determine tag ID based on the reference, for example, when ids are random strings.\n\nLet's assume that your API website code looks like this:\n\n```html\n...\n\u003ch2 id=\"o1egwb7agw\"\u003eGET /user/status\u003c/h2\u003e\n\u003cp\u003eLorem ipsum dolor sit amet, consectetur adipisicing elit.\u003c/p\u003e\n\n\u003ch2 id=\"y3yn8ewg32\"\u003eGET /api/v2/admin/status\u003c/h2\u003e\n\u003cp\u003eLorem ipsum dolor sit amet, consectetur adipisicing elit.\u003c/p\u003e\n...\n```\n\nAPIReferences config in your `foliant.yml` in this case may look like this:\n\n```yaml\npreprocessors:\n    apireferences:\n        reference:\n            output_template: '[{prefix}: {verb} {command}]({url})'\n            # other reference properties are default\n        API:\n            My-API:\n                mode: find_by_tag_content\n                url: http://example.com/api\n                tags: ['h1', 'h2']\n                content_template: '{verb} {command}'\n```\n\nNow let's reference a **GET /user/status** method in our Markdown source:\n\n```\nTo find out user's status use `My-API: GET /user/status` method.\n```\n\nAPIReferences will notice a reference mentioned in our markdown: \\``My-API: GET /user/status`\\`. The reference has the prefix `My-API`, which means that `My-API` from the `API` section should be used. It will capture it and split into three groups:\n\n- **prefix**: `My-API`,\n- **verb**: `GET`,\n- **command**: `/user/status`.\n\nThen it will pass it to the header template `'{verb} {command}'` which we've stated in our config, and this will result in a string:\n\n`'GET /user/status'`\n\nNow APIReferences will parse the web page and look for all `h1` and `h2` tags (as specified in the `tags` parameter) whose content equals to our generated content.\n\nOne of the elements satisfies the requirement:\n\n```html\n\u003ch2 id=\"o1egwb7agw\"\u003eGET /user/status\u003c/h2\u003e\n```\n\nIt means that referenced method is present on the API web page, so APIReferences will take an id `o1egwb7agw` from it and add it to our API url (which we've stated in config) to form a link: `http://example.com/api#o1egwb7agw`.\n\nFinally, it's time to construct a Markdown link. APIReferences takes an `output_template` from the reference config: `'[{prefix}: {verb} {command}]({url})'`.\n\nPlaceholders in the output template are replaced by groups from our reference, except `{url}` placeholder which is replaced with the url constructed above:\n\n`[My-API: GET /user/status](http://example.com/api#api-method-get-userstatus)`\n\nThe conversion is done. Our Markdown content will now look like this:\n\n```\nTo find out user's status use [My-API: GET /user/status](http://example.com/api#api-method-get-userstatus) method.\n```\n\n### `find_for_swagger` mode\n\n`find_for_swagger` mode parses the OpenAPI spec file and looks for the referenced method in it. It then generates an anchor for SwaggerUI website based on data from the reference and the operation properties in the spec.\n\nLet's assume that your OpenAPI specification looks like this:\n\n```json\n{\n    \"swagger\": \"2.0\",\n    ...\n    \"paths\": {\n        \"/user/status\": {\n            \"GET\": {\n                \"tags\": [\"userauth\"],\n                \"summary\": \"Returns user auth status\",\n                \"operationId\": \"checkStatus\",\n                ...\n            },\n        }\n    ...\n\n```\n\nOn the default SwaggerUI website the anchor to this method will be `#/userauth/checkStatus`. It consists of the first tag from the operation properties and the operationId. So to generate the proper anchor APIReferences, will need to get those parts from the spec. \n\nAPIReferences config in your `foliant.yml` in this case may look like this:\n\n```yaml\npreprocessors:\n    apireferences:\n        # reference options are default in this example\n        API:\n            My-API:\n                mode: find_for_swagger\n                url: http://example.com/api\n                spec: !path swagger.json\n                anchor_template: '/{tag}/{operation_id}'  # you can omit this line because it's the default value\n```\n\nNow let's reference a **GET /user/status** method in our Markdown source:\n\n```\nTo find out user's status use `GET /user/login` method.\n```\n\nAPIReferences will notice a reference mentioned in our markdown: \\``GET /user/login`\\`. It will capture it and split into two groups:\n\n- **verb**: `GET`,\n- **command**: `/user/login`.\n\n\u003e Note that `verb` and `command` groups are required for this mode if you are to redefine default reference regex.\n\nNow, when we have a verb and a command, we can search for it in the OpenAPI spec. APIReferences parses the spec and searches the `paths` section for our operation. From the operation properties APIReferences takes two values: \n\n- **tag**: first element from the `tags` list,\n- **operationId**.\n\nThese values are then passed to the anchor template `'/{tag}/{operation_id}'`, along with groups from our reference, this will result in a string:\n\n`'/userauth/checkStatus'`\n\nThat's the ID we were looking for. APIReferences will add it to our API url (which we've stated in config) to form a link: `http://example.com/api#/userauth/checkStatus`.\n\nFinally, it's time to construct a Markdown link. APIReferences takes an `output_template` from the reference config, which is default: `'[{verb} {command}]({url})'`.\n\nPlaceholders in the output template are replaced by groups from our reference, except `{url}` placeholder which is replaced with the url constructed above:\n\n`[GET /user/login](http://example.com/api#/userauth/checkStatus)`\n\nThe conversion is done. Our Markdown content will now look like this:\n\n```\nTo find out user's status use [GET /user/login](http://example.com/api#/userauth/checkStatus) method.\n```\n\n### `find_for_redoc` mode\n\n`find_for_redoc` is similar to `find_for_swagger` mode, except that default anchor template is `'operation/{operation_id}'`.\n\n## Handling Multiple APIs\n\nAPIReferences can work with several APIs at once, and honestly, it's very good at this.\n\nLet's consider an example foliant.yml:\n\n```yaml\npreprocessors:\n    apireferences:\n        API:\n            Client-API:\n                mode: find_by_tag_content\n                url: http://example.com/api/client\n                content_template: '{verb} {command}'\n            Admin-API:\n                mode: find_by_anchor\n                url: http://example.com/api/admin\n                content_template: '{verb} {command}'\n```\n\nIn this example we've defined two APIs: `Client-API` and `Admin-API`, these are just names, they may be anything you want. Now we can reference both APIs:\n\n```\nWhen user clicks \"LOGIN\" button, the app sends a request `POST /user/login`.\n\nTo restrict user from logging in run `PUT /admin/ban_user/{id}`.\n```\n\nAfter applying the preprocessor, this source will turn into:\n\n```\nWhen user clicks \"LOGIN\" button, the app sends a request [POST /user/login](http://example.com/api/client#post-userlogin).\n\nTo restrict user from logging in run [PUT /admin/ban_user/{id}](](http://example.com/api/admin#put-adminbanuser-id).\n```\n\nAs you see, APIReferences determined, which reference corresponds to which API. That is possible because when APIReferences meets a non-prefixed reference, it goes through each defined API and searches for the mentioned method.\n\nBut what happens if we reference a method which is present in both APIs?\n\n```\nRun `GET /system/healthcheck` for debug information.\n```\n\nYou have to understand that, even though APIReferences is very powerful, it doesn't understand the concept of free will. It can't make the choice for you, so instead, it will show a warning and skip this reference:\n\n```\nWARNING: [index.md] Failed to process reference. Skipping. `GET /system/healthcheck` is present in several APIs (Client-API, Admin-API). Please, use prefix.\n```\n\nIn the warning text, there's a suggestion to use a *prefix*. A prefix is a way to make your reference more specific and point APIReferences to the correct API. The value of the prefix is the API name as defined in the config. So for Client API, the prefix would be `Client-API`, for Admin — `Admin-API`. Let's fix our example:\n\n```\nRun `Admin-API: GET /system/healthcheck` to get debug information about the Admin API service.\n\nRun `Client-API: GET /system/healthcheck` to get debug information about the Client API service.\n```\n\n\u003e If you don't like the format in which we supply prefix (`\u003cprefix\u003e: \u003cverb\u003e \u003ccommand\u003e`), you can change it by tweaking reference regex. More info in **Capturing References** section.\n\nIt's recommended to always use prefixes for unambiguity. The `generate_anchor` mode won't work at all for references without prefixes, because it doesn't perform any checks and almost always returns a link.\n\n## Handling Multiple Reference Configuration\n\nYou can not only make APIReferences work with different APIs but also with different reference configurations. `reference` parameter is a list for a reason. And because `output_template` is part of reference configuration, you can make different references transform into different values.\n\nHere's an example config:\n\n```yaml\npreprocessors:\n    apireferences:\n        reference:\n            - only_with_prefixes: true\n              output_template: '**[{verb} {command}]({url})**'\n            - only_with_prefixes: false\n              output_template: '[{verb} {command}]({url})'\n        API:\n            ...\n```\n\nWith such config references with prefixes will be transformed into **bold links**, while non-prefixed references will remain regular links.\n\n## Commands and Endpoint Prefixes\n\nAPIReferences treats the `command` part of your reference in a special way. While searching for it on the API website, it will try to substitute the command placeholder:\n\n- with and without leading slash (`/user/login` and `user/login`),\n- with and without endpoint prefix, if one is defined (`/api/v1/user/login` and `/user/login`).\n\nHere's an example config to illustrate this feature:\n\n```yaml\npreprocessors:\n    apireferences:\n        reference:\n            - only_with_prefixes: true\n              output_template: '**[{verb} {command}]({url})**'\n            - only_with_prefixes: false\n              output_template: '[{verb} {command}]({url})'\n        API:\n            My-API:\n                mode: find_by_tag_content\n                url: http://example.com/api\n                content_template: '{verb} {command}'\n                endpoint_prefix: /api/v1\n```\n\nConsidering that the API website source looks like this:\n\n```html\n\u003ch2 id=\"asoi17uo\"\u003eGET /api/v1/user/status\u003c/h2\u003e\n```\n\nWhich of these references, do you think, will give us the desired result?\n\n```\n`GET /user/status`\n`GET user/status`\n`GET /api/v2/user/status`\n```\n\nIf you were reading carefully, you already know the answer — all of these references will result in the same link:\n\n```\n[GET /user/status](http://example.com/api#asoi17uo)\n[GET /user/status](http://example.com/api#asoi17uo)\n[GET /user/status](http://example.com/api#asoi17uo)\n```\n\n## Maximum Version Detection\n\nIn APIReferences, the `endpoint_prefix` option is typically used to specify the API version (like `/api/v1/` or `/v2/`) for all method references. This is the standard way to handle versioned API endpoints. However, there are cases when API methods have different maximum versions available in the API documentation web-page.\n\nTo handle such cases, APIReferences can automatically detect and use the highest available version of an API method when the version is not explicitly specified in the reference. This feature is particularly useful when API methods have different maximum versions in the documentation.\n\nTo enable this functionality, you need to:\n\n- Set `max_endpoint_prefix` to True\n- Provide a list of available API versions in `endpoint_prefix_list`\n\nHere's an example configuration:\n\n```yml\npreprocessors:\n    apireferences:\n        API:\n            Admin-API:\n                mode: find_by_anchor\n                url: http://example.com/api/admin\n                anchor_template: '{verb} {command}'\n                anchor_converter: slate\n                endpoint_prefix_list: [/v2/,/v3/,/v4/] \n                max_endpoint_prefix: true\n```\n\nGiven that the API documentation contains methods in different versions:\n\n- `GET /v2/user/status`\n- `GET /v3/user/status`\n- `GET /v4/user/status`\n\nWhen you use a reference without specifying the version:\n\n- `GET /user/status`\n\nThe preprocessor will automatically find and use the highest available version for method:\n\n```md\n[GET /v4/user/status](http://example.com/#get-v4-user-status)\n```\n\nImportant notes:\n\n- `max_endpoint_prefix` cannot be used together with `endpoint_prefix` as they serve different purposes:\n    - endpoint_prefix sets a fixed version for all methods\n    - max_endpoint_prefix automatically determines the highest available version\n- `max_endpoint_prefix` only works when `endpoint_prefix_list` is provided and contains version prefixes\n- This feature only works with `find_by_anchor` and `find_by_tag_content` modes\n\n## Remote Registry\n\nThe `apiref_registry_url` option enables the use of a remote registry, streamlining the documentation assembly process by eliminating the need to re-parse the registry.\n\nA registry is essentially a JSON file with a structured format:\n\n```json\n{\n    \"admin\": [\n        \"post-logo\",\n        \"post-users\"\n    ],\n    \"client\": [\n        \"get-logo\"\n        \"get-users\",\n    ]\n}\n```\n\n\u003e When working with a multiproject setup, the registry is automatically saved in the `.multiprojectcache` directory.\n\nTo create a registry, use an empty foliant-project with a multiproject configuration and the apireferences preprocessor. The `.multiprojectcache` directory will contain `.apirefregistry` files that can be combined and hosted on a server.\n\n\n# Capturing References\n\nAPIReferences uses regular expressions to capture *references* to API methods in Markdown files.\n\nThe default reg-ex is:\n\n```re\n`\\s*((?P\u003cprefix\u003e[\\w-]+):\\s*)?(?P\u003cverb\u003eOPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT|PATCH|LINK|UNLINK)\\s+(?P\u003ccommand\u003e[^`]+)\\s*`\n```\n\nThis expression accepts references like these:\n\n- `Client-API: GET user/info`\n- `UPDATE user/details`\n\nNotice that the default expression uses [Named Capturing Groups](https://docs.python.org/3/howto/regex.html#non-capturing-and-named-groups). You have to use them too, if you are to redefine the expression. You can name these groups as you like and have as many or as few as you wish, but it's recommended to include the `prefix` group for API prefix logic to work. It is also required for all groups which are in the `output_template` also to be present in the regex.\n\nTo redefine the regular expression, add an option `regex` to the reference config.\n\nFor example, if you want to capture ONLY references with prefixes, you may use the following:\n\n```yaml\npreprocessors:\n  - apireferences:\n      reference:\n      - regex: '\\s*((?P\u003cprefix\u003e[\\w-]+):\\s*)(?P\u003cverb\u003ePOST|GET|PUT|UPDATE|DELETE)\\s+(?P\u003ccommand\u003e[^`]+)`\\s*'\n```\n\n\u003e This example is for illustrative purposes only. You can achieve the same goal by just switching on the `only_with_prefixes` option.\n\nNow the references without prefix (`UPDATE user/details`) will be ignored.\n\n# Customizing Output\n\nYou can customize the *output*-string which will replace the *reference* string. To do that add a template into your reference configuration.\n\nA *template* is a string that may contain placeholders, surrounded by curly braces. These placeholders will be replaced with the values, and all the rest will remain unchanged.\n\nFor example, look at the default template:\n\n```yaml\npreprocessors:\n  - apireferences:\n    reference:\n      - output_template: '[{verb} {command}]({url})',\n```\n\n\u003e Don't forget the single quotes around the template. These braces and parenthesis easily make YAML think that it is an embedded dictionary or list.\n\nWith the default template, the reference string will be replaced by something like that:\n\n```md\n[GET user/info](http://example.com/api/#get-user-info)\n```\n\nIf you want references to be transformed into something else, create your own template. You can use placeholders from the reference regular expression along with some additional:\n\n| placeholder     | description                                | example                                 |\n|-----------------|--------------------------------------------|-----------------------------------------|\n| source          | Full original reference string             | \\``Client-API: GET user/info`\\`         |\n| url             | Full url to the method description         | `http://example.com/api/#get-user-info` |\n| endpoint_prefix | API endpoint prefix from API configuration | `/api/v2`                               |\n\nPlaceholders from the default regex are:\n\n| placeholder | description                                               | example      |\n|-------------|-----------------------------------------------------------|--------------|\n| prefix      | API Prefix used in the reference                          | `Client-API` |\n| verb        | HTTP verb used in the reference                           | `GET`        |\n| command     | API command being referenced with endpoint prefix removed | `/user/info` |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffoliant-docs%2Ffoliantcontrib.apireferences","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffoliant-docs%2Ffoliantcontrib.apireferences","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffoliant-docs%2Ffoliantcontrib.apireferences/lists"}