# `PtcRunner.Lisp.SpecValidator.Parser`
[🔗](https://github.com/andreasronge/ptc_runner/blob/main/lib/ptc_runner/lisp/spec_validator/parser.ex#L1)

Markdown-extraction half of `PtcRunner.Lisp.SpecValidator`.

Parses the PTC-Lisp specification markdown into structured data —
testable examples (`{code, expected, section}` tuples), `TODO` and
`BUG` markers, illustrative skipped examples (`; => ...`), and
per-section content hashes.

Pure functions over an in-memory string. No file I/O, no execution
of any code. The companion `SpecValidator` module loads the spec
file and runs the extracted examples through `PtcRunner.Lisp.run/2`.

## Markdown shapes recognised

Single-line:

    (+ 1 2)  ; => 3

Multi-line, with the marker on the closing line:

    (let [x 1
          y 2]
      (+ x y))  ; => 3

Multi-line, with the marker on its own comment line below the code:

    (filter odd? [1 2 3 4 5])
    ;;  => [1 3 5]

Section context is the most recent `## N. Title` header seen.

## Return shape

    %{
      examples: [{"(+ 1 2)", 3, "## 1. ..."}, ...],
      todos:    [{"(some-fn x)", "not implemented", "## ..."}, ...],
      bugs:     [{"(buggy-fn)", "known issue",      "## ..."}, ...],
      skipped:  2
    }

# `extract_examples`

```elixir
@spec extract_examples(String.t()) :: map()
```

Extract examples / todos / bugs / skipped counter from the spec
markdown `content`.

See the module docs for the return shape.

# `extract_section_hashes`

```elixir
@spec extract_section_hashes(String.t()) :: map()
```

Compute a SHA-256 hex hash for each `## ...` section of the spec
markdown `content`. Used to detect drift in specific sections.

Returns a map of `"## Section header"` to its hex hash.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
