mirror of
https://github.com/jimeh/commonflow.org.git
synced 2026-02-19 05:46:40 +00:00
fix: spec TOC
This commit is contained in:
@@ -96,6 +96,20 @@ function escapeRegex(str: string): string {
|
||||
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
}
|
||||
|
||||
// Spec section titles in order (used for both ToC and anchor injection)
|
||||
const SPEC_SECTION_TITLES = [
|
||||
"TL;DR",
|
||||
"The Master Branch",
|
||||
"Change Branches",
|
||||
"Pull Requests",
|
||||
"Versioning",
|
||||
"Releases",
|
||||
"Short-Term Release Branches",
|
||||
"Long-term Release Branches",
|
||||
"Bug Fixes & Rollback",
|
||||
"Git Best Practices",
|
||||
];
|
||||
|
||||
/**
|
||||
* Extract the numbered spec sections (1. TL;DR, 2. The Master Branch, etc.)
|
||||
*/
|
||||
@@ -107,24 +121,8 @@ function extractSpecSections(specContent: string): SpecSection[] {
|
||||
const olMatch = specContent.match(/<ol[^>]*>([\s\S]*?)<\/ol>/i);
|
||||
if (!olMatch) return sections;
|
||||
|
||||
// Split by top-level list items
|
||||
// We need to handle nested lists carefully
|
||||
const sectionTitles = [
|
||||
"TL;DR",
|
||||
"The Master Branch",
|
||||
"Change Branches",
|
||||
"Pull Requests",
|
||||
"Versioning",
|
||||
"Releases",
|
||||
"Short-Term Release Branches",
|
||||
"Long-term Release Branches",
|
||||
"Bug Fixes & Rollback",
|
||||
"Git Best Practices",
|
||||
];
|
||||
|
||||
// Find each section by looking for the title pattern
|
||||
for (let i = 0; i < sectionTitles.length; i++) {
|
||||
const title = sectionTitles[i];
|
||||
for (const title of SPEC_SECTION_TITLES) {
|
||||
const id = slugify(title);
|
||||
|
||||
// For the content, we'll just use the title for navigation
|
||||
@@ -139,6 +137,27 @@ function extractSpecSections(specContent: string): SpecSection[] {
|
||||
return sections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add anchor IDs to spec section list items.
|
||||
* Finds top-level <li> elements that start with section titles and adds IDs.
|
||||
*/
|
||||
function addSpecSectionAnchors(specContent: string): string {
|
||||
let result = specContent;
|
||||
|
||||
for (const title of SPEC_SECTION_TITLES) {
|
||||
const id = `spec-${slugify(title)}`;
|
||||
// Match <li> followed by the section title (possibly with whitespace)
|
||||
// The title appears right after <li> in the rendered HTML
|
||||
const pattern = new RegExp(
|
||||
`(<li>)(\\s*${escapeRegex(title)})`,
|
||||
"i"
|
||||
);
|
||||
result = result.replace(pattern, `<li id="${id}">$2`);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract FAQ items from the FAQ section HTML
|
||||
*/
|
||||
@@ -187,18 +206,13 @@ function extractFAQItems(faqContent: string): FAQItem[] {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build table of contents from parsed sections
|
||||
* Build table of contents from parsed sections.
|
||||
* Only includes sections rendered in SpecSection (Terminology + Specification).
|
||||
* Introduction/Summary are in AboutSection and excluded from this ToC.
|
||||
*/
|
||||
function buildTocItems(parsed: Partial<ParsedSpec>): TocItem[] {
|
||||
const items: TocItem[] = [];
|
||||
|
||||
// Main sections
|
||||
if (parsed.introduction) {
|
||||
items.push({ id: "introduction", title: "Introduction", level: 2 });
|
||||
}
|
||||
if (parsed.summary) {
|
||||
items.push({ id: "summary", title: "Summary", level: 2 });
|
||||
}
|
||||
if (parsed.terminology) {
|
||||
items.push({ id: "terminology", title: "Terminology", level: 2 });
|
||||
}
|
||||
@@ -256,12 +270,15 @@ export function parseSpecContent(html: string, version: string): ParsedSpec {
|
||||
"License",
|
||||
]);
|
||||
|
||||
const specification = extractSection(
|
||||
const specificationRaw = extractSection(
|
||||
content,
|
||||
"Git Common-Flow Specification",
|
||||
["FAQ", "About", "License"]
|
||||
);
|
||||
|
||||
// Add anchor IDs to spec section list items for ToC navigation
|
||||
const specification = addSpecSectionAnchors(specificationRaw);
|
||||
|
||||
const faqContent = extractSection(content, "FAQ", ["About", "License"]);
|
||||
|
||||
const about = extractSection(content, "About", ["License"]);
|
||||
@@ -269,7 +286,7 @@ export function parseSpecContent(html: string, version: string): ParsedSpec {
|
||||
const license = extractSection(content, "License", []);
|
||||
|
||||
// Parse subsections
|
||||
const specSections = extractSpecSections(specification);
|
||||
const specSections = extractSpecSections(specificationRaw);
|
||||
const faq = extractFAQItems(faqContent);
|
||||
|
||||
const parsed: ParsedSpec = {
|
||||
|
||||
Reference in New Issue
Block a user