Parse the small subset of YAML front matter the blog uses. The site's posts use simple ``key: value`` pairs (no nesting, no lists), so a hand-rolled parser keeps this script dependency-free.
(text: str)
| 138 | |
| 139 | |
| 140 | def parse_front_matter(text: str) -> tuple[dict[str, Any], str]: |
| 141 | """Parse the small subset of YAML front matter the blog uses. |
| 142 | |
| 143 | The site's posts use simple ``key: value`` pairs (no nesting, no lists), |
| 144 | so a hand-rolled parser keeps this script dependency-free. |
| 145 | """ |
| 146 | if not text.startswith("---\n"): |
| 147 | raise ValueError("missing front matter") |
| 148 | end = text.find("\n---\n", 4) |
| 149 | if end == -1: |
| 150 | raise ValueError("unterminated front matter") |
| 151 | block = text[4:end] |
| 152 | body = text[end + len("\n---\n") :] |
| 153 | |
| 154 | fm: dict[str, Any] = {} |
| 155 | current_key: str | None = None |
| 156 | current_lines: list[str] | None = None |
| 157 | |
| 158 | for raw_line in block.splitlines(): |
| 159 | if current_key is not None and (raw_line.startswith(" ") or raw_line.startswith("\t") or raw_line == ""): |
| 160 | current_lines.append(raw_line) |
| 161 | continue |
| 162 | if current_lines is not None and current_key is not None: |
| 163 | fm[current_key] = _coerce_scalar("\n".join(current_lines).strip()) |
| 164 | current_key = None |
| 165 | current_lines = None |
| 166 | |
| 167 | match = re.match(r"^([A-Za-z0-9_]+):\s*(.*)$", raw_line) |
| 168 | if not match: |
| 169 | continue |
| 170 | key, value = match.group(1), match.group(2) |
| 171 | if value == "": |
| 172 | current_key = key |
| 173 | current_lines = [] |
| 174 | else: |
| 175 | fm[key] = _coerce_scalar(value) |
| 176 | |
| 177 | if current_lines is not None and current_key is not None: |
| 178 | fm[current_key] = _coerce_scalar("\n".join(current_lines).strip()) |
| 179 | |
| 180 | return fm, body |
| 181 | |
| 182 | |
| 183 | def _coerce_scalar(value: str) -> Any: |
no test coverage detected