Gherkin.Markdown (Cucumber v1.0.0)

View Source

Parser for Markdown feature files — "Markdown with Gherkin" (MDG).

MDG embeds Gherkin in ordinary Markdown (.feature.md files):

  • Section headers are ATX headings whose text is a Gherkin keyword — # Feature: Name, ## Rule: Name, ### Scenario: Name, #### Examples: Name. The heading level is decorative; nesting comes from the keywords alone.
  • Steps are bullet-list items: * Given a step (- and + bullets also work). The * step keyword is not available — a bare * text bullet is ordinary prose.
  • Docstrings are fenced code blocks (three or more backticks) under a step. The info string becomes the media type, the fence's indentation is stripped from the content, and the closing fence must repeat the opening backticks exactly, so a longer fence can wrap a shorter one.
  • Data tables and Examples tables are Markdown tables indented two to five spaces. GFM separator rows (| --- |) are skipped. Tables without the indent are ordinary prose and ignored.
  • Tags are inline code spans on their own line before the section they tag: `@wip` `@slow`. Bare @wip text is prose, not a tag.
  • Everything else — prose, unindented tables, headings without a Gherkin keyword — is ignored. Section descriptions are therefore always empty, and there are no comment lines (# starts a heading, so feature.comments is always empty).

Mirroring the reference tokenizer (@cucumber/gherkin's GherkinInMarkdownTokenMatcher), the first line of the file becomes the feature line even when it is not a # Feature: heading — the whole trimmed line is taken as the feature name — and any later # Feature: heading is ignored.

Three deliberate divergences from the reference tokenizer, all lenient:

  • A fenced code block with no step to attach to (in prose) is skipped entirely, so code samples containing * Given ... lines don't parse as steps.
  • The reference captures prose that follows a GFM separator row as a section description — an emergent quirk of its error-tolerant token matching, not MDG behavior. This parser captures no descriptions.
  • The reference treats any line containing a backticked tag span as a tag line; here a tag line must consist solely of tag spans, so prose that merely mentions `@wip` stays prose.

Produces the same Gherkin.Feature structs as Gherkin.NimbleParser, with 0-based line numbers referring to the original Markdown source, so everything downstream — compiler, runtime, Cucumber Messages — behaves exactly as it does for .feature files.

Summary

Functions

Whether a path names a Markdown feature file.

Parses a Markdown feature file string into a Gherkin.Feature struct.

Functions

markdown_path?(path)

@spec markdown_path?(String.t()) :: boolean()

Whether a path names a Markdown feature file.

The single authority for the .feature.md extension — parser dispatch (Gherkin.Parser.parse/2) and the Cucumber Messages media type both use it, so they cannot disagree.

Examples

Gherkin.Markdown.markdown_path?("test/features/cheese.feature.md")
# => true

Gherkin.Markdown.markdown_path?("test/features/cheese.feature")
# => false

parse(source)

@spec parse(String.t()) :: Gherkin.Feature.t()

Parses a Markdown feature file string into a Gherkin.Feature struct.

Raises Gherkin.ParseError when the Gherkin structure is invalid (a step outside a scenario, an Examples table outside a Scenario Outline, an unclosed code fence, and similar).