(block: JSDocBlock)
| 1291 | } |
| 1292 | if (lines[headingIndex + 1]?.trim() !== "") { |
| 1293 | diagnostics.push(diagnostic("invalid-spacing", "Example headings must be followed by exactly one blank line")) |
| 1294 | } |
| 1295 | |
| 1296 | let index = headingIndex + 2 |
| 1297 | const bodyStart = index |
| 1298 | let fenceIndex = -1 |
| 1299 | while (index < lines.length) { |
| 1300 | const trimmed = lines[index].trim() |
| 1301 | if (isTypeScriptFence(trimmed)) { |
| 1302 | fenceIndex = index |
| 1303 | break |
| 1304 | } |
| 1305 | if (trimmed.startsWith("```")) { |
| 1306 | diagnostics.push(diagnostic("malformed-example", "Examples may only contain one TypeScript code fence")) |
| 1307 | } |
| 1308 | if (trimmed === "" && isHeadingLine(lines[index + 1])) { |
| 1309 | break |
| 1310 | } |
| 1311 | if (trimmed.startsWith("@")) { |
| 1312 | break |
| 1313 | } |
| 1314 | index++ |
| 1315 | } |
| 1316 | |
| 1317 | if (fenceIndex === -1) { |
| 1318 | diagnostics.push(diagnostic("malformed-example", "Examples must include a non-empty ```ts fence")) |
| 1319 | return { nextIndex: index, diagnostics } |
| 1320 | } |
| 1321 | |
| 1322 | const bodyLines = lines.slice(bodyStart, fenceIndex) |
| 1323 | const nonEmptyBody = joinBody(bodyLines).trim() !== "" |
| 1324 | if (nonEmptyBody && bodyLines.at(-1)?.trim() !== "") { |
| 1325 | diagnostics.push( |
| 1326 | diagnostic("invalid-spacing", "Example prose must be separated from code by exactly one blank line") |
| 1327 | ) |
| 1328 | } |
| 1329 | const prose = nonEmptyBody ? joinBody(bodyLines.slice(0, bodyLines.at(-1)?.trim() === "" ? -1 : undefined)) : null |
| 1330 | |
| 1331 | index = fenceIndex + 1 |
| 1332 | const codeStart = index |
| 1333 | while (index < lines.length && lines[index].trim() !== "```") { |
| 1334 | if (isTypeScriptFence(lines[index].trim())) { |
no test coverage detected
searching dependent graphs…