Skip to content

Repository files navigation

Gitlink Extension For Quarto

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.

Features

  • 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 title attribute).
  • 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 @username format.

Installation

quarto add mcanouil/quarto-gitlink@1.8.0

This will install the extension under the _extensions subdirectory.

If you're using version control, you will want to check in this directory.

Usage

Basic Configuration

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
---

Supported Platforms

Each platform has different reference formats. Choose your platform below:

GitHub

Official documentation: Autolinked references

extensions:
  gitlink:
    platform: github
    base-url: https://github.com
    repository-name: owner/repo

References:

  • Issues/PRs: #123, owner/repo#123, GH-123
  • Commits: a5c3785, owner/repo@a5c3785
  • Users: @username

GitLab

Official documentation: GitLab Flavored Markdown

extensions:
  gitlink:
    platform: gitlab
    base-url: https://gitlab.com
    repository-name: group/project

References:

  • Issues: #123, group/project#123
  • Merge Requests: !456, group/project!456
  • Commits: 9ba12248, group/project@9ba12248
  • Users: @username

Codeberg

Official documentation: Codeberg Documentation (uses Forgejo)

extensions:
  gitlink:
    platform: codeberg
    base-url: https://codeberg.org
    repository-name: user/repo

References:

  • Issues/PRs: #123, user/repo#123 (same format for both)
  • Commits: e59ff077, user/repo@e59ff077
  • Users: @username

Gitea

Official documentation: Gitea Documentation

extensions:
  gitlink:
    platform: gitea
    base-url: https://gitea.com
    repository-name: user/repo

References:

  • Issues/PRs: #123, user/repo#123 (same format for both)
  • Commits: e59ff077, user/repo@e59ff077
  • Users: @username

Bitbucket

Official documentation: Bitbucket markup syntax

extensions:
  gitlink:
    platform: bitbucket
    base-url: https://bitbucket.org
    repository-name: workspace/repo

References:

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.

Features and Configuration

URL Processing

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 access

Surrounding Characters and Groups

References 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.

Drafts and Templates

To opt out of all link rewriting for a single document (for example, in a draft or template), set:

extensions:
  gitlink:
    enabled: false

Citations vs. Mentions

When 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-username

Repository Detection

The extension resolves the repository URL using the following priority order:

  1. Explicit configuration (highest priority): Set repository-name, platform, and base-url directly in the document or project metadata.

    extensions:
      gitlink:
        platform: github
        base-url: https://github.com
        repository-name: owner/repo
  2. Quarto project repo-url: For website or book projects, the extension reads repo-url from 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 book projects:

    # _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., set platform explicitly) while letting the rest be auto-detected.

  3. 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.

Platform Badges

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.

Repository Navbar Widget

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: true

The 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.

Custom Platforms

You can add support for additional Git hosting platforms by creating a custom YAML configuration file.

Creating a Custom Platform

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/repo

Platform Configuration Schema Reference

Every platform configuration must follow this schema for validation and proper functionality.

Platform Configuration Structure

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 requests

Field Descriptions

base-url (required, string):

  • The base URL of the Git hosting platform.
  • Must start with http:// or https://.
  • 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}'

Lua Regex Pattern Guide

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

Validation Rules

Platform configurations are automatically validated for:

  1. Required fields: base-url, patterns, url-formats must all exist.
  2. Pattern syntax: All regex patterns are checked for valid Lua regex syntax.
  3. URL format syntax: URL templates must start with / and contain at least one placeholder.
  4. Field completeness: All required pattern and format types must be defined.
  5. Type correctness: Patterns must be arrays, URL formats must be strings.

Validation Errors

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.

Example: Complete Gitea Platform

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}'

Testing Custom Platforms

After creating a custom platform YAML file, you can validate it by:

  1. Using the Gitlink extension with custom-platforms-file option.
  2. Checking the Quarto output for validation errors.
  3. Creating a test document and running quarto render.

Contributing New Platforms

To add a new platform to the built-in configuration:

  1. Fork the repository.
  2. Edit _extensions/gitlink/platforms.yml.
  3. Test your configuration using a custom platforms file first.
  4. Submit a pull request.

This approach makes it easy to add support for new platforms without modifying Lua code.

Example Document

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.).

About

Use Git hosting platforms references (commits, issues, discussions, and pull requests) directly into your Quarto documents.

Topics

Resources

Stars

Watchers

Forks

Releases

Sponsor this project

Contributors

Languages