sphinx-gherkin-feature is a Sphinx extension for documenting complete Gherkin feature scripts and optionally writing those scripts as .feature files during the Sphinx build.
It provides the domain directive:
.. gherkin:feature::
:filename: login
Feature: Login
Scenario: Successful login
Given a user account exists
When the user logs in
Then the dashboard is shownThe directive body is rendered as a highlighted literal block. When file writing is enabled, the same body is also written as login.feature.
This project is configured for uv.
For local development:
uv sync --group dev --group docsThe project pins gherkin-lint to the upstream GitHub release tag v26.1.1 via tool.uv.sources:
[tool.uv.sources]
gherkin-lint = { git = "https://github.com/procitec/gherkin-lint.git", tag = "v26.1.1" }For use in another uv-managed Sphinx project, add this package and the same source override for gherkin-lint in that project's pyproject.toml.
Add the extension to conf.py:
extensions = ["sphinx_gherkin_feature"]Available configuration values:
# Validate :filename: values. The .feature suffix is not part of the option.
gherkin_feature_filename_regex = r"^[a-z0-9_]+$"
# Write feature files after successful builds.
gherkin_feature_write_file = False
# Where generated files are written.
# Relative paths are resolved below the Sphinx builder output directory.
# Absolute paths are used as configured.
gherkin_feature_output_dir = "gherkin"
# Lint integration with procitec/gherkin-lint v26.1.0.
gherkin_feature_lint = False
gherkin_feature_lint_indent_size = 4
# Optional Pygments highlighting integration.
gherkin_feature_highlight = True
gherkin_feature_pygments_language = "gherkin-feature"
gherkin_feature_register_lexer = True
gherkin_feature_lexer_aliases = ["gherkin-feature"]extensions = ["sphinx_gherkin_feature"]
gherkin_feature_write_file = True
gherkin_feature_output_dir = "features"With an HTML build, this writes files below:
_build/html/features/
Absolute paths are also supported when the project explicitly wants generated files outside the builder output directory:
gherkin_feature_output_dir = "/tmp/generated-features"By default, the extension registers a bundled Pygments lexer under gherkin-feature and renders directive bodies with that language alias.
To use a different alias:
gherkin_feature_pygments_language = "gherkin"
gherkin_feature_lexer_aliases = ["gherkin"]To use a lexer supplied by another package, disable bundled registration and point the rendered literal block to that alias:
gherkin_feature_register_lexer = False
gherkin_feature_pygments_language = "gherkin"To disable highlighting entirely:
gherkin_feature_highlight = FalseWhen gherkin_feature_lint = True, the extension imports the real upstream package:
from gherkin_lint.gherkin_lint import GherkinLintThe Sphinx directive receives feature scripts as strings. The bridge therefore accepts strings and maps them to whatever API the installed upstream release exposes:
lint_text(code, source_name=...), if presentlint_string(code, source_name=...), if presentlint_lines(lines, source_name=...), if presentlint_file(path)via a temporary.featurefile
For procitec/gherkin-lint release v26.1.1, the file-based path is expected. No patched or vendored copy of gherkin-lint is used by this package.
Create or update the local environment:
uv sync --group dev --group docsRun tests:
uv run pytestRun lint checks:
uv run ruff check src testsBuild the example documentation:
uv run sphinx-build -b html docs docs/_build/htmlBuild source distribution and wheel:
uv buildCreate or refresh the lockfile when you want to commit a local dependency snapshot:
uv lockPublish, after configuring credentials:
uv publishsrc/sphinx_gherkin_feature/
__init__.py Sphinx setup and config registration
directives.py gherkin:feature directive
domain.py gherkin domain
lexer.py bundled Pygments lexer
lint.py optional gherkin-lint bridge
writer.py build-finished file writer
gherkin_feature_lint = True integrates with procitec/gherkin-lint.
The preferred interface is now an in-memory API on gherkin-lint:
errors = linter.lint_text(code, source_name="login.feature")The Sphinx bridge calls lint_text(...) when available, then falls back to
lint_string(...), and finally to the older lint_file(...) API via a temporary
.feature file. A proposed upstream patch for gherkin-lint is included in
external/gherkin-lint-string-api/.