Extension Schema Specification

Quarto extensions can provide a _schema.yml file alongside their _extension.yml manifest. This file declares every configurable option, shortcode parameter, format key, element attribute, and CSS class the extension accepts.

A single schema serves two consumers:

Warning

Schema specification support in Quarto Wizard may evolve over time. Quarto CLI may use, modify, or discard this schema behaviour in future releases. No guarantees are provided regarding Quarto CLI native support.

File Location

Place _schema.yml (or _schema.yaml) in the same directory as _extension.yml. A _schema.json file is also supported alongside or instead of the YAML variants.

Tree
_extensions/
└── my-extension/
    ├── _extension.yml
    ├── _schema.yml
    └── my-extension.lua

When both a JSON and a YAML schema exist in the same directory, the JSON file takes precedence. JSON files use camelCase keys natively (e.g., enumCaseInsensitive, patternExact, minLength), whereas YAML files use kebab-case (e.g., enum-case-insensitive, pattern-exact, min-length).

Quarto Wizard discovers schema files automatically when scanning installed extensions.

Schema Version ($schema)

Schema files may include a $schema key at the top level to declare the schema format version. This is optional but recommended for forward-compatibility.

yaml
$schema: https://m.canouil.dev/quarto-wizard/assets/schema/v1/extension-schema.json
options:
  threshold:
    type: number

The currently supported URI is:

  • https://m.canouil.dev/quarto-wizard/assets/schema/v1/extension-schema.json

When an unrecognised version URI is encountered, Quarto Wizard emits a warning but does not reject the schema. This allows older tooling to gracefully handle schemas written for newer versions.

Top-level Structure

The schema has six optional top-level sections. An extension may define any combination of these.

yaml
# Extension-level metadata options (all extension types).
# Configured under the extension name in YAML metadata.
options:
  <option-name>: <field-descriptor>

# Per-shortcode schemas (one entry per contributed shortcode).
shortcodes:
  <shortcode-name>:
    description: <string>
    arguments:
      - name: <string>
        <field-descriptor properties>
    attributes:
      <attribute-name>: <field-descriptor>

# Per-format schemas (one entry per contributed format).
# Configured under format: <format-name>: in YAML metadata.
formats:
  <format-name>:
    <option-name>: <field-descriptor>

# Project types contributed by the extension.
# Suggested for project.type in _quarto.yml.
projects:
  - <project-type>

# Element attributes accepted by filters on Div/Span/CodeBlock elements.
# Used in: [text]{.class attr=value} or ::: {.class attr=value}
# These are Pandoc AST element attributes, not metadata options.
attributes:
  <class-or-context>:
    <attribute-name>: <field-descriptor>

# CSS classes contributed by filters, with descriptions.
# Used in: [text]{.class} or ::: {.class}
classes:
  <class-name>:
    description: <string>

options

Extension-level configuration options. Users set these values in _quarto.yml, _metadata.yml, or document front matter, scoped under the extension name inside an extensions key.

Given a _schema.yml for an extension called spotlight:

_extensions/spotlight/_schema.yml
options:
  size:
    type: number
    default: 60
    description: "Radius of the spotlight circle in pixels."
  lockPointerInsideCanvas:
    type: boolean
    default: false
    description: "Whether to lock the mouse pointer inside the canvas."

The corresponding user configuration in _quarto.yml would be:

_quarto.yml
extensions:
  spotlight:
    size: 80
    lockPointerInsideCanvas: true

The same structure works in _metadata.yml or document front matter:

presentation.qmd
---
title: "My Presentation"
extensions:
  spotlight:
    size: 80
---

shortcodes

Per-shortcode schemas, keyed by shortcode name. Each shortcode entry can specify a description, positional arguments (as an ordered array), and named attributes (as a map).

yaml
shortcodes:
  modal:
    description: "Generate a Bootstrap modal toggle or dismiss button."
    arguments:
      - name: type
        type: string
        default: "toggle"
        enum: [toggle, dismiss]
        description: "Button type: toggle to open, dismiss to close."
    attributes:
      target:
        type: string
        description: "ID of the modal to target (without the # prefix)."
      label:
        type: string
        description: "Button label text."

Shortcode arguments use the same field descriptor properties as options, plus a required name field that identifies the positional argument.

formats

Per-format options, keyed by the format name as it appears in YAML metadata (e.g., letter-pdf, invoice-pdf).

yaml
formats:
  letter-pdf:
    address:
      type: array
      required: true
      description: "Recipient address lines."
      items:
        type: string
    subject:
      type: string
      description: "Letter subject line."

projects

An array of project type strings contributed by the extension. These values are suggested for project.type in _quarto.yml.

yaml
projects:
  - my-website

attributes

Attributes accepted by filter extensions on Pandoc Div, Span, CodeBlock, and Header elements. Groups are matched against the current element using five strategies:

  • _any: matches any element regardless of class, ID, or type.
  • CSS class name (e.g. panel, highlight): matches elements that carry that class.
  • ID prefix (e.g. modal matches #modal-example): matches elements whose ID starts with that prefix followed by a hyphen.
  • Pandoc element type (Div, Span, Code, CodeBlock, Header): matches based on the structural context (fenced div :::, bracketed span ], backtick code `, or ATX heading #).

Group key matching is case-insensitive: div matches Div, codeblock matches CodeBlock, header matches Header, and so on.

Use _any for attributes accepted on any element regardless of class.

yaml
attributes:
  _any:
    colour:
      type: string
      aliases: [color, ink, fg]
      description: "Text (foreground) colour."
      completion:
        type: color
    bg-colour:
      type: string
      aliases: [bg-color, bg, paper]
      description: "Background colour."
      completion:
        type: color
  Header:
    toc-depth:
      type: number
      min: 1
      max: 6
      description: "Override table-of-contents depth for this heading."
  CodeBlock:
    filename:
      type: string
      description: "Display filename label for the code block."

classes

CSS classes contributed by the extension’s filters. Each entry maps a class name to a descriptor containing a description. Quarto Wizard uses this information to provide class name completion and hover documentation in fenced divs (:::), bracketed spans ([]), and code block attributes.

yaml
classes:
  panel:
    description: "Wraps content in a styled panel box."
  highlight:
    description: "Applies highlight styling to the element."
  callout-note:
    description: "Renders a note-style callout block."

Field Descriptor Properties

Every option, argument, or attribute is described by the same set of properties. All properties are optional.

Type and Value Constraints

Property Type Description
type string Expected value type: string, number, integer, boolean, array, object, or content.
required boolean Whether the field must be present. Default: false.
default any Default value applied when not provided.
const any Fixed value the field must equal.
enum array List of allowed values.
enum-case-insensitive boolean Case-insensitive enum matching. Default: false.
pattern string Regular expression the value must match (JS regex syntax).
pattern-exact boolean Anchor the pattern to match the entire value (wraps in ^...$). Default: false.
min number Minimum value (inclusive, for type: number or type: integer).
max number Maximum value (inclusive, for type: number or type: integer).
minimum number Alias for min.
maximum number Alias for max.
exclusive-minimum number Exclusive minimum (value must be strictly greater).
exclusive-maximum number Exclusive maximum (value must be strictly less).
min-length integer Minimum string length (for type: string).
max-length integer Maximum string length (for type: string).
min-items integer Minimum number of items (for type: array).
max-items integer Maximum number of items (for type: array).

The integer type validates that the value is a whole number. It supports the same numeric constraints as number (min, max, exclusive-minimum, exclusive-maximum).

The content type is specific to shortcode arguments and accepts any Pandoc Inlines, Blocks, or string value. Validation only checks presence (for required); no further type or pattern checking applies.

In JSON schema files, the properties above use camelCase equivalents: enumCaseInsensitive, patternExact, minLength, maxLength, minItems, maxItems, exclusiveMinimum, and exclusiveMaximum.

Metadata Properties

Property Type Description
description string Human-readable description shown in hover tooltips and completion detail.
aliases array<string> Alternative accepted names (e.g., [color] alongside colour).
deprecated boolean, string, or object Mark the field as deprecated (see Deprecation).

Nested Type Properties

Property Type Description
items field descriptor Schema for array elements (when type: array).
properties map<string, field descriptor> Schema for object keys (when type: object).

Completion

The completion object controls IDE autocomplete behaviour. When omitted, Quarto Wizard infers completion from other properties (e.g., enum values become suggestions, type: boolean suggests true/false).

Property Type Description
type string Completion strategy (see Completion types).
extensions array<string> File extension filter for type: file (e.g., [.csv, .xlsx]).
placeholder string Hint text for type: freeform.
values array Override values for type: enum (when different from validation enum).
dynamic boolean Values come from external sources (brand colours, filesystem). Default: false.
source string Hint for dynamic value source (e.g., "brand-colors", "git-remote").

Completion Types

Type IDE Behaviour
enum Suggests values from the enum or values property.
file Opens a file picker filtered by extensions.
color Shows a colour picker.
boolean Suggests true and false.
freeform Shows a text input with placeholder as hint.
size Suggests common CSS size values.
none Disables autocompletion for this field.

Features

Alias Resolution

Alternative field names allow extensions to accept multiple spellings. The IDE suggests all names; the Lua validator resolves aliases to the primary key.

yaml
colour:
  type: string
  aliases: [color, ink, fg]
  description: "Text colour."

If a user provides color: red, validation and merging resolve it to colour = "red".

Deprecation

The deprecated property supports three forms:

  • deprecated: true marks the field as deprecated with a generic warning.
  • deprecated: "Use X instead" uses the string as the warning message.
  • Object form with replace-with enables automatic value forwarding.
yaml
old_colour:
  type: string
  deprecated:
    since: "1.2"
    message: "Use colour instead."
    replace-with: colour

colour:
  type: string

When replace-with is specified, the deprecated key’s value is forwarded to the replacement key automatically. The IDE shows a diagnostic on deprecated fields.

Boolean Coercion

YAML parsers accept true, True, yes, on (and their negatives) as boolean values. Pandoc metadata may deliver these as native booleans or as the strings "true"/"false".

For type: boolean fields, string representations are normalised to native booleans before validation.

Nested Validation

When type: array with an items descriptor, each array element is validated against the items schema. When type: object with a properties descriptor, the object value is validated recursively.

yaml
badge:
  type: array
  description: "Array of badge configuration objects."
  items:
    type: object
    properties:
      key:
        type: string
        required: true
        description: "Unique identifier for the badge."
      colour:
        type: string
        aliases: [color]
        description: "Background colour for the badge."
        completion:
          type: color

Common Patterns

Filter with options

A filter extension that reads configuration from YAML metadata.

_schema.yml
options:
  enabled:
    type: boolean
    default: true
    description: "Enable or disable the extension."
  threshold:
    type: number
    min: 0
    max: 1
    default: 0.5
    description: "Detection threshold value."

Shortcode with arguments and attributes

A shortcode extension with positional arguments and named attributes.

_schema.yml
shortcodes:
  iconify:
    description: "Renders an Iconify icon."
    arguments:
      - name: set-or-icon
        type: string
        required: true
        description: "Icon set name, or 'set:icon' combined format."
      - name: icon
        type: string
        description: "Icon name when the first argument is the set name."
    attributes:
      size:
        type: string
        description: "Icon size as a keyword or CSS value."
      flip:
        type: string
        enum: [horizontal, vertical, "horizontal,vertical"]
        description: "Flip transformation for the icon."

Format extension

A format extension with format-specific options.

_schema.yml
formats:
  letter-pdf:
    address:
      type: array
      required: true
      description: "Recipient address lines."
      items:
        type: string
    opening:
      type: string
      description: "Opening salutation."
    closing:
      type: string
      description: "Closing salutation."

Element attributes with colour picker

A filter extension that processes element attributes with IDE colour picker support.

_schema.yml
attributes:
  _any:
    colour:
      type: string
      aliases: [color, ink, fg]
      description: "Text (foreground) colour."
      completion:
        type: color
    bg-colour:
      type: string
      aliases: [bg-color, bg, paper]
      description: "Background colour."
      completion:
        type: color
    border-colour:
      type: string
      aliases: [border-color, bc]
      description: "Border colour."
      completion:
        type: color

Combined extension

An extension that defines options, shortcodes, and attributes together.

_schema.yml
options:
  size:
    type: string
    default: ""
    enum: ["", sm, lg, xl]
    enum-case-insensitive: true
    description: "Default modal dialog size."
  fade:
    type: boolean
    default: false
    description: "Apply a fade transition."

shortcodes:
  modal:
    description: "Generate a Bootstrap modal button."
    arguments:
      - name: type
        type: string
        default: "toggle"
        enum: [toggle, dismiss]
        description: "Button type."
    attributes:
      target:
        type: string
        description: "ID of the modal to target."
      label:
        type: string
        description: "Button label text."

attributes:
  modal:
    size:
      type: string
      enum: ["", sm, lg, xl]
      enum-case-insensitive: true
      description: "Modal dialog size override."
    fade:
      type: boolean
      description: "Apply a fade transition for this modal."

Reference Schema Files

The JSON Schema meta-schema that formally describes the structure of _schema.yml and _schema.json files is published at:

This is the same schema referenced by the $schema key at the top of schema definition files. It can be used by any JSON Schema-aware tool for validation and autocompletion.

Example instances showing every supported property are also available:

Generating a Schema with AI

The prompt below can be used with an AI assistant to generate a _schema.yml for an existing extension. Copy the prompt, attach your extension’s _extension.yml and Lua source files, and the assistant will produce a schema that matches your extension’s actual behaviour.

TipPrompt for generating _schema.yml
markdown
Generate a `_schema.yml` file for the attached Quarto extension.

Read the attached `_extension.yml` to identify the extension name and
contribution types (filters, shortcodes, formats, projects).

Then read every Lua source file to discover:

1. **Options** read from `meta` or `meta['extensions']` tables.
   Record each key, its expected type, any default value, and whether
   it is required.
2. **Shortcode arguments and attributes** parsed in shortcode handler
   functions. Record positional arguments (in order) and named
   attributes with their types, defaults, and allowed values.
3. **Format-specific options** read under a format name in metadata.
4. **Attributes** read from `el.attributes` in Div, Span, or
   CodeBlock filter functions. Group them by CSS class (use `_any` when
   the attribute applies regardless of class).
5. **Classes** contributed by the extension's filters. List each CSS
   class name the extension handles, with a short description.
   Look for patterns such as `el.classes:includes("name")`,
   `el.classes:find("name")`, or class-based conditionals.
6. **Project types** declared or contributed by the extension. If the
   extension provides a project type, list it under the `projects`
   top-level key.

For every field use the following properties where applicable:

- `type`: `string`, `number`, `integer`, `boolean`, `array`, `object`,
  or `content` (for shortcode arguments that receive Pandoc content).
  Use `integer` when only whole numbers are valid.
  When a field accepts multiple types, use an array
  (e.g., `type: [string, number]`).
- `required`: set to `true` only when the code raises an error or
  returns early for missing values.
- `default`: the fallback value used in the code.
- `const`: a fixed value the field must equal, when the code expects
  exactly one value.
- `enum`: list of allowed values when the code checks against a
  fixed set.
- `enum-case-insensitive`: `true` when the code lowercases or
  case-folds before comparing.
- `pattern`: regular expression the value must match (JS syntax).
- `pattern-exact`: `true` to anchor the pattern with `^...$`.
- `min` / `max`: inclusive numeric bounds
  (`minimum` and `maximum` are accepted as aliases).
- `exclusive-minimum` / `exclusive-maximum`: exclusive numeric bounds
  (value must be strictly greater / strictly less).
- `min-length` / `max-length`: string length constraints.
- `min-items` / `max-items`: array item count constraints.
- `aliases`: alternative key names accepted by the code.
- `deprecated`: `true`, a message string, or an object with `since`,
  `message`, and `replace-with` keys.
- `description`: one sentence in British English explaining the option.
- `completion`: controls IDE autocompletion behaviour. Sub-properties:
  `type` (`color` for CSS colour values, `file` for file paths,
  `freeform` for text input, `none` to disable), `extensions`
  (file extensions to filter when `type: file`), `placeholder`
  (hint text for `freeform`), `values` (static suggestion list),
  `dynamic` and `source` (for runtime-resolved values).
  Omit `completion` to let the IDE infer from `enum` and `type`.
- `items`: schema for elements of an `array` type. Use `items` to
  describe what each array element looks like (its type, enum, etc.).
- `properties`: schema for keys of an `object` type. Use `properties`
  to describe each expected key and its constraints.

Output only the YAML content of `_schema.yml`, nothing else.
Use kebab-case for multi-word property names (`enum-case-insensitive`,
not `enumCaseInsensitive`).
Add a one-line comment header: `# Schema for the <name> extension`.
Optionally include `$schema: https://m.canouil.dev/quarto-wizard/assets/schema/v1/extension-schema.json`
at the top level.
Back to top

Reuse

MIT