# `DocShell.Generate.Guides`
[🔗](https://github.com/futhr/doc_shell/blob/v2.0.0/lib/doc_shell/generate/guides.ex#L1)

Extracts hand-written Markdown guides, with optional YAML frontmatter.

Module documentation covers the code; guides cover everything else — getting
started pages, architecture notes, runbooks, policy documents. This extractor
walks one or more base directories recursively for `.md` files and turns each
into a content entry:

    %{
      "id" => "getting-started",
      "title" => "Getting Started",
      "kind" => "guide",
      "ast" => [...],
      "meta" => %{"audience" => "operators", "source_path" => "guides/getting-started.md"}
    }

## Frontmatter

A file may open with a YAML block delimited by `---` lines:

    ---
    id: getting-started
    title: Getting Started
    audience: operators
    ---

    # Getting started with the platform

The normalized frontmatter becomes the entry's `meta`, plus a
`source_path` key, so hosts can carry arbitrary facets — audience, locale,
product area, ordering — without DocShell needing to know what they mean.
`DocShell.Presentation.StaticGenerator` reads `audience` and `locale` from
there; everything else passes straight through to the renderer.

`id` and `title` are read from frontmatter when present. Otherwise the id
falls back to the filename without its extension and the title to the first
Markdown H1, which means a guide with no frontmatter at all still produces a
sensible entry.

Frontmatter that is not a YAML mapping, or whose opening `---` is never
closed, is an error rather than something to shrug off — a typo there
otherwise silently reclassifies a document.

Files are sorted by path so the artifact is stable across builds.

# `extract`

```elixir
@spec extract([Path.t()]) :: {:ok, [map()]} | {:error, term()}
```

Extracts every `.md` file found recursively beneath each base directory.

Missing directories contribute nothing. The first unreadable or malformed
file short-circuits the run and returns `{:error, {path, reason}}`.

# `extract_file`

```elixir
@spec extract_file(Path.t()) :: {:ok, map()} | {:error, term()}
```

Extracts one Markdown file, splitting frontmatter from body first.

---

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