A Quarto extension that automatically converts Git hosting platform references (issues, pull requests, commits, users) into clickable links. Supports GitHub, GitLab, Codeberg, Gitea, and Bitbucket.
- Automatic URL shortening: Converts long URLs into short, readable references.
- Platform badges: Displays subtle, always-visible platform badges in HTML output for improved accessibility.
- Platform tooltips: Shows the platform name on hover in HTML output (accessible via
titleattribute). - Platform labels: Adds platform name in parentheses for non-HTML formats (PDF, DOCX, etc.).
- Multi-platform support: Works with GitHub, GitLab, Codeberg, Gitea, and Bitbucket.
- Cross-repository references: Link to issues, PRs, and commits in other repositories.
- User mentions: Convert user profile URLs to
@usernameformat.
quarto add mcanouil/quarto-gitlink@1.8.0This will install the extension under the _extensions subdirectory.
If you're using version control, you will want to check in this directory.
Add the extension to your document's YAML front matter:
---
title: "My Document"
filters:
- path: gitlink
at: post-quarto
extensions:
gitlink:
platform: github # Platform: github, gitlab, codeberg, gitea, bitbucket
base-url: https://github.com # Base URL (optional, auto-detected from platform)
repository-name: owner/repo # Repository name for relative references
---Each platform has different reference formats. Choose your platform below:
Official documentation: Autolinked references
extensions:
gitlink:
platform: github
base-url: https://github.com
repository-name: owner/repoReferences:
- Issues/PRs:
#123,owner/repo#123,GH-123 - Commits:
a5c3785,owner/repo@a5c3785 - Users:
@username
Official documentation: GitLab Flavored Markdown
extensions:
gitlink:
platform: gitlab
base-url: https://gitlab.com
repository-name: group/projectReferences:
- Issues:
#123,group/project#123 - Merge Requests:
!456,group/project!456 - Commits:
9ba12248,group/project@9ba12248 - Users:
@username
Official documentation: Codeberg Documentation (uses Forgejo)
extensions:
gitlink:
platform: codeberg
base-url: https://codeberg.org
repository-name: user/repoReferences:
- Issues/PRs:
#123,user/repo#123(same format for both) - Commits:
e59ff077,user/repo@e59ff077 - Users:
@username
Official documentation: Gitea Documentation
extensions:
gitlink:
platform: gitea
base-url: https://gitea.com
repository-name: user/repoReferences:
- Issues/PRs:
#123,user/repo#123(same format for both) - Commits:
e59ff077,user/repo@e59ff077 - Users:
@username
Official documentation: Bitbucket markup syntax
extensions:
gitlink:
platform: bitbucket
base-url: https://bitbucket.org
repository-name: workspace/repoReferences:
Bitbucket requires keyword prefixes:
- Issues:
issue #123,issue workspace/repo#123 - Pull Requests:
pull request #456,pull request workspace/repo#456 - Commits:
9cc27f2,workspace/repo@9cc27f2 - Users:
@accountname
Note
The issue and pull request keywords are required to distinguish reference types.
The extension automatically processes full URLs and converts them to short references:
Input: https://github.com/owner/repo/issues/123
Output: owner/repo#123 (or #123 if current repository)
Tip
Wrap URLs in angle brackets (<URL>) for best results instead of bare URLs.
You can opt out of URL shortening with normalize-links: false:
extensions:
gitlink:
normalize-links: false # leave autolinked URLs as-is (default: true)You can also have the extension fetch the page title of an autolinked platform URL and use it as the link text (best-effort via curl):
extensions:
gitlink:
fetch-titles: true # default: false; requires network accessReferences are recognised even when wrapped in brackets or punctuation, for example (#1), [#1], "#1", #1., something(#1), and .(#1)..
Comma-separated groups of references inside a single bracket pair are also recognised, both with and without spaces, for example (#2, #3), (#1, #2, #3), (#2,#3), and a bare #2,#3.
A group is linked only when every item is a valid reference, so text such as 1,000 is left untouched.
To opt out of all link rewriting for a single document (for example, in a draft or template), set:
extensions:
gitlink:
enabled: falseWhen a Quarto bibliography contains an entry whose id matches a Git hosting username (for example, both @mcanouil the user and a @mcanouil citation), Pandoc treats the token as a citation and Gitlink leaves it alone.
You can force-treat selected citation IDs as Git hosting mentions with:
extensions:
gitlink:
mentions:
- mcanouil
- other-usernameThe extension resolves the repository URL using the following priority order:
-
Explicit configuration (highest priority): Set
repository-name,platform, andbase-urldirectly in the document or project metadata.extensions: gitlink: platform: github base-url: https://github.com repository-name: owner/repo
-
Quarto project
repo-url: For website or book projects, the extension readsrepo-urlfrom the project configuration (_quarto.yml). The platform, base URL, and repository name are all auto-detected from the full URL.# _quarto.yml website: repo-url: https://github.com/owner/repo
This also works with
bookprojects:# _quarto.yml book: repo-url: https://gitlab.com/group/project
[!NOTE] When using
repo-url, the platform is auto-detected from the URL. You can still override individual values (e.g., setplatformexplicitly) while letting the rest be auto-detected. -
Git remote (lowest priority): If neither of the above is available, the extension falls back to detecting the repository from the git remote origin URL.
git remote get-url origin
Supports:
https://github.com/owner/repo.git,git@gitlab.com:group/project.git,ssh://git@codeberg.org/user/repo.git.
Gitlink adds subtle platform badges to links in HTML and Typst output. You can control them with:
extensions:
gitlink:
show-platform-badge: true # Show/hide badges (default: true)
badge-position: "after" # "after" or "before" link (default: "after")
badge-background-colour: "#c3c3c3" # Badge background colour (default: "#c3c3c3")
badge-text-colour: "#000000" # Badge text colour (optional)Features:
- HTML output: Badges are styled with Bootstrap classes and include tooltips. You can customise colours with hex codes or colour names.
- Typst output: Badges appear as styled boxes with configurable colours.
- Other formats: Platform names appear in parentheses (e.g.,
#123 (GitHub)).
Colour Customisation:
badge-background-colour: Set the background colour (hex code or colour name). Defaults to#c3c3c3(grey).badge-text-colour: Set the text colour (hex code or colour name). If not specified, uses the default text colour.
For Quarto websites (HTML output), gitlink can replace a navbar item with a repository widget: a button showing live star and fork counts (fetched from the platform API, cached in localStorage for four hours) that opens a dropdown of repository links.
Add a placeholder navbar item with href #gitlink-widget to _quarto.yml:
website:
navbar:
right:
- text: "GitHub"
href: "#gitlink-widget"
aria-label: "GitHub"
filters:
- path: gitlink
at: post-quarto
extensions:
gitlink:
platform: github
repository-name: owner/repo
widget:
enabled: trueThe default dropdown contains Repository, Issues, Pull Requests (Merge Requests on GitLab), Releases, Add a Star, and Create a Fork, based on what the platform supports. Customise it with:
extensions:
gitlink:
widget:
enabled: true # Inject the widget (default: false)
links: # Toggle default entries
discussions: true # Discussions link (default: false)
releases: false # Any default entry can be turned off
extra-links: # Appended after the default set
- text: "Q&A"
href: "/discussions/categories/q-a" # '/...' resolves against the repository URL
icon: question # Icon name (see below)
sponsor: username # Sponsor entry (platforms with a sponsor URL, i.e. GitHub)
icon: mark-github # Trigger icon override (defaults to the platform mark)
style-navbar-tools: true # Bordered pill style for Quarto's search button and colour-scheme toggle (default: false)icon works like Quarto's own icon fields (navbar tools, callouts): it takes a name from the Bootstrap Icons set that Quarto bundles with every HTML page, so the widget has no icon-extension dependency. The widget additionally embeds an octicon set (16px bodies from primer/octicons), usable by name too; embedded names win over Bootstrap ones:
mark-github, git-branch, repo, issue, pull-request, release, discussion, question, star, fork, heart, heart-fill, marketplace, globe, book, bookmark, bug, calendar, checklist, clock, code, comment, database, download, eye, file-code, gear, gift, git-commit, git-merge, graph, history, home, info, key, law, light-bulb, link, link-external, lock, mail, megaphone, milestone, organization, package, people, person, play, plus, project, rocket, rss, search, shield-check, terminal, tools, verified, versions, workflow, zap, pencil, pin.
For any other icon, put a shortcode in the entry's text instead, for example with the iconify extension; this requires running the filter at: post-quarto so the shortcode is resolved before the widget reads it:
extra-links:
- text: "{{< iconify simple-icons:typst >}} Typst Universe"
href: "https://typst.app/universe/package/gribouille"The widget's appearance follows Bootstrap tokens by default and can be themed via CSS custom properties: --gitlink-widget-border, --gitlink-widget-accent, --gitlink-widget-accent-soft, --gitlink-widget-pill-bg, --gitlink-widget-menu-bg, and --gitlink-widget-menu-fg.
The widget sizes Quarto's navbar search button and colour-scheme toggle to match its trigger, with consistent spacing across the navbar-right control group; style-navbar-tools additionally paints both with the widget's bordered pill style.
The widget works independently of link rewriting: set enabled: false alongside widget.enabled: true to use only the widget. On Bitbucket the widget renders without counters, as its API exposes no star count.
You can add support for additional Git hosting platforms by creating a custom YAML configuration file.
Create a YAML file (e.g., my-platforms.yml):
platforms:
gitplatform:
base-url: https://git.example.com
patterns:
issue:
- '#(%d+)'
- '([^/]+/[^/#]+)#(%d+)'
merge-request:
- '#(%d+)'
- '([^/]+/[^/#]+)#(%d+)'
commit:
- '^(%x+)$'
- '([^/]+/[^/@]+)@(%x+)'
- '(%w+)@(%x+)'
user: '@([%w%-%.]+)'
url-formats:
issue: '/{repo}/issues/{number}'
merge-request: '/{repo}/pull/{number}'
pull: '/{repo}/pulls/{number}'
commit: '/{repo}/commit/{sha}'
user: '/{username}'Reference it in your document:
extensions:
gitlink:
platform: gitplatform
custom-platforms-file: my-platforms.yml
repository-name: owner/repoEvery platform configuration must follow this schema for validation and proper functionality.
platforms:
platform-name:
base-url: string # Required: Base URL for the platform
patterns:
issue: [string, ...] # Required: Lua regex patterns for issues
merge-request: [string, ...] # Required: Lua regex patterns for merge requests/PRs
commit: [string, ...] # Required: Lua regex patterns for commits
user: string # Required: Lua regex pattern for user mentions
url-formats:
issue: string # Required: URL template for issues
pull: string # Required: URL template for pull requests
commit: string # Required: URL template for commits
user: string # Required: URL template for user profiles
merge-request: string # Required: URL template for merge requestsbase-url (required, string):
- The base URL of the Git hosting platform.
- Must start with
http://orhttps://. - Example:
https://git.example.com
patterns (required, object):
- Regular expressions for matching references.
- Uses Lua regex syntax.
- Must contain four pattern types.
patterns.issue (required, array of strings):
- Lua regex patterns for matching issue references.
- Should have 1-2 patterns (single issue, cross-repository issue).
- Example:
['#(%d+)', '([^/]+/[^/#]+)#(%d+)']
patterns.merge-request (required, array of strings):
- Lua regex patterns for matching merge request/pull request references.
- Should have 1-2 patterns (similar to issue patterns).
- Example:
['!(%d+)', '([^/]+/[^/#]+)!(%d+)']
patterns.commit (required, array of strings):
- Lua regex patterns for matching commit references.
- Should have 2-3 patterns (SHA, cross-repository, user@SHA).
- Example:
['^(%x+)$', '([^/]+/[^/@]+)@(%x+)', '(%w+)@(%x+)']
patterns.user (required, string):
- Single Lua regex pattern for matching user mentions.
- Typically starts with
@. - Example:
'@([%w%-%.]+)'
url-formats (required, object):
- URL templates for generating links.
- Must contain five format types.
url-formats.issue (required, string):
- Template for issue URLs.
- Placeholders:
{repo}(repository),{number}(issue number). - Example:
'/{repo}/issues/{number}'
url-formats.pull (required, string):
- Template for pull request URLs.
- Placeholders:
{repo},{number}. - Example:
'/{repo}/pull/{number}'
url-formats.merge-request (required, string):
- Template for merge request URLs.
- Placeholders:
{repo},{number}. - Example:
'/{repo}/-/merge_requests/{number}'
url-formats.commit (required, string):
- Template for commit URLs.
- Placeholders:
{repo},{sha}(commit hash). - Example:
'/{repo}/commit/{sha}'
url-formats.user (required, string):
- Template for user profile URLs.
- Placeholder:
{username}. - Example:
'/{username}'
Common patterns used in Gitlink configurations:
| Pattern | Matches | Example |
|---|---|---|
#(%d+) |
Issue with number | #123 |
!(%d+) |
Merge request with number | !456 |
(%x+) |
Hexadecimal string (SHA) | a5c3785d9 |
@([%w%-%.]+) |
User mention | @username |
([^/]+/[^/#]+)#(%d+) |
Cross-repo issue | owner/repo#123 |
^(%x+)$ |
Full commit SHA | abc123def |
(%w+)@(%x+) |
User with commit | username@abc123 |
Platform configurations are automatically validated for:
- Required fields:
base-url,patterns,url-formatsmust all exist. - Pattern syntax: All regex patterns are checked for valid Lua regex syntax.
- URL format syntax: URL templates must start with
/and contain at least one placeholder. - Field completeness: All required pattern and format types must be defined.
- Type correctness: Patterns must be arrays, URL formats must be strings.
If your platform configuration is invalid, you will see detailed error messages such as:
Missing required field: "patterns"- The patterns object is missing.Invalid Lua regex in issue[1]: ... bad escape ...- Pattern has invalid regex syntax.Missing required pattern type: "commit"- A required pattern type is missing.Missing required URL format: "pull"- A required URL format is missing.Invalid url-formats.issue: URL format must contain at least one placeholder- Template missing placeholders.
platforms:
gitea:
base-url: https://gitea.io
patterns:
issue:
- '#(%d+)'
- '([^/]+/[^/#]+)#(%d+)'
merge-request:
- '#(%d+)'
- '([^/]+/[^/#]+)#(%d+)'
commit:
- '^(%x+)$'
- '([^/]+/[^/@]+)@(%x+)'
- '(%w+)@(%x+)'
user: '@([%w%-%.]+)'
url-formats:
issue: '/{repo}/issues/{number}'
pull: '/{repo}/pulls/{number}'
merge-request: '/{repo}/pulls/{number}'
commit: '/{repo}/commit/{sha}'
user: '/{username}'After creating a custom platform YAML file, you can validate it by:
- Using the Gitlink extension with
custom-platforms-fileoption. - Checking the Quarto output for validation errors.
- Creating a test document and running
quarto render.
To add a new platform to the built-in configuration:
- Fork the repository.
- Edit
_extensions/gitlink/platforms.yml. - Test your configuration using a custom platforms file first.
- Submit a pull request.
This approach makes it easy to add support for new platforms without modifying Lua code.
Here is the source code for a comprehensive example: example.qmd.
Output of example.qmd:
The repository navbar widget is inspired by and derived from the GitHub button in posit-dev/great-docs by Rich Iannone. Embedded icons are 16px bodies from primer/octicons (MIT License, GitHub Inc.).