Skip to content

Commit 80809eb

Browse files
committed
fix: Improve documentation generation
- Use product labels from repos-config.json for correct capitalization (e.g., "GravityBoard" instead of "Gravityboard") - Add htmlEscapeDescription() to convert PHPDoc <code> blocks to markdown fenced code blocks in descriptions - Keep htmlEscape() simple for summaries/inline text - Add /claudedocs to .gitignore
1 parent 21cac1f commit 80809eb

3 files changed

Lines changed: 37 additions & 10 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,4 @@ yarn-error.log*
6565
# Misc
6666
*.log
6767
*.tmp
68+
/claudedocs

scripts/generate-category-indexes.mjs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ import { fileURLToPath } from 'node:url';
1212
const __dirname = path.dirname(fileURLToPath(import.meta.url));
1313
const docsDir = path.join(__dirname, '..', 'docs');
1414

15+
// Load product config for proper labels
16+
const configPath = path.join(__dirname, '..', 'repos-config.json');
17+
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
18+
const productLabels = new Map(
19+
(config.products || [])
20+
.filter(p => p.id && p.label)
21+
.map(p => [p.id, p.label])
22+
);
23+
1524
/**
1625
* Find all actions and filters directories (lowercase).
1726
* @param {string} dir
@@ -46,16 +55,21 @@ function countHooks(dir) {
4655
}
4756

4857
/**
49-
* Get product name from path.
58+
* Get product name from path using repos-config.json labels.
5059
* @param {string} dirPath
5160
* @returns {string}
5261
*/
5362
function getProductName(dirPath) {
5463
const parts = dirPath.split(path.sep);
5564
const docsIndex = parts.indexOf('docs');
5665
if (docsIndex !== -1 && parts[docsIndex + 1]) {
57-
// Convert slug to title case
58-
return parts[docsIndex + 1]
66+
const productId = parts[docsIndex + 1];
67+
// Use label from config, fallback to title case
68+
if (productLabels.has(productId)) {
69+
return productLabels.get(productId);
70+
}
71+
// Fallback: convert slug to title case
72+
return productId
5973
.split('-')
6074
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
6175
.join(' ');

scripts/generate-php-api.mjs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,14 +1200,26 @@ function mdEscape(text) {
12001200

12011201
/**
12021202
* Escape HTML entities in text to prevent markdown/HTML parsing issues.
1203-
* Use this for descriptions and summaries that appear in markdown content.
1203+
* Use this for summaries and short text that appear inline.
12041204
*/
12051205
function htmlEscape(text) {
12061206
return String(text ?? '')
12071207
.replace(/</g, '&lt;')
12081208
.replace(/>/g, '&gt;');
12091209
}
12101210

1211+
/**
1212+
* Escape HTML entities in description text, preserving PHPDoc <code> blocks.
1213+
* Converts <code>...</code> to markdown fenced code blocks.
1214+
* Use this for multi-line descriptions where code examples may appear.
1215+
*/
1216+
function htmlEscapeDescription(text) {
1217+
return htmlEscape(text)
1218+
// Convert <code> blocks to markdown fenced code blocks
1219+
.replace(/&lt;code&gt;/gi, '\n```php\n')
1220+
.replace(/&lt;\/code&gt;/gi, '\n```\n');
1221+
}
1222+
12111223
/**
12121224
* Clean description text: strip leading em-dashes and similar prefixes.
12131225
*/
@@ -1518,7 +1530,7 @@ function generateClassPage({ productLabel, classSymbol, product, repoRef, typeLi
15181530
\`${wordpressFormatSignature(phpShortArraySyntax(m.signature || `function ${m.name}()`))}\`
15191531
15201532
${htmlEscape(m.summary || '')}
1521-
${m.description ? `\n${processInlineSeeRefs(htmlEscape(m.description))}\n` : ''}
1533+
${m.description ? `\n${processInlineSeeRefs(htmlEscapeDescription(m.description))}\n` : ''}
15221534
${paramsTable ? `\n#### Parameters\n\n${paramsTable}\n` : ''}
15231535
${resolvedReturnType || resolvedReturnDesc ? `\n#### Returns\n\n- ${codeInlineType(resolvedReturnType, typeLinkCtx)}${resolvedReturnDesc ? ` — ${mdEscape(resolvedReturnDesc)}` : ''}\n` : ''}
15241536
${throwsList.length ? `\n#### Throws\n\n${throwsList.map((t) => `- ${codeInlineType(t.type, typeLinkCtx)}${t.description ? ` — ${mdEscape(cleanDescription(t.description))}` : ''}`).join('\n')}\n` : ''}
@@ -1527,7 +1539,7 @@ ${renderSeeAlsoSection(m.tags, typeLinkCtx, { heading: '####' })}
15271539
${renderSinceTags(since)}
15281540
${deprecated.length ? `\n**Deprecated:** ${deprecated.map((d) => {
15291541
const ver = d.version ? `\`${mdEscape(d.version)}\`` : '';
1530-
const desc = d.description ? processInlineSeeRefs(htmlEscape(d.description)) : '';
1542+
const desc = d.description ? processInlineSeeRefs(htmlEscapeDescription(d.description)) : '';
15311543
if (ver && desc) return `${ver} (${desc})`;
15321544
if (ver) return ver;
15331545
if (desc) return desc;
@@ -1551,13 +1563,13 @@ ${formatTagsYaml(versionTags)}---
15511563
# \`${fqcn}\`
15521564
15531565
${htmlEscape(classSymbol.summary || '')}
1554-
${classSymbol.description ? `\n${processInlineSeeRefs(htmlEscape(classSymbol.description))}\n` : ''}
1566+
${classSymbol.description ? `\n${processInlineSeeRefs(htmlEscapeDescription(classSymbol.description))}\n` : ''}
15551567
${renderExamplesSection(classSymbol.tags, { heading: '##' })}
15561568
${renderSeeAlsoSection(classSymbol.tags, typeLinkCtx, { heading: '##' })}
15571569
${renderSinceTags(since)}
15581570
${deprecated.length ? `\n**Deprecated:** ${deprecated.map((d) => {
15591571
const ver = d.version ? `\`${mdEscape(d.version)}\`` : '';
1560-
const desc = d.description ? processInlineSeeRefs(htmlEscape(d.description)) : '';
1572+
const desc = d.description ? processInlineSeeRefs(htmlEscapeDescription(d.description)) : '';
15611573
if (ver && desc) return `${ver} (${desc})`;
15621574
if (ver) return ver;
15631575
if (desc) return desc;
@@ -1626,13 +1638,13 @@ ${formatTagsYaml(versionTags)}---
16261638
\`${wordpressFormatSignature(phpShortArraySyntax(functionSymbol.signature || `function ${shortName}()`))}\`
16271639
16281640
${htmlEscape(functionSymbol.summary || '')}
1629-
${functionSymbol.description ? `\n${processInlineSeeRefs(htmlEscape(functionSymbol.description))}\n` : ''}
1641+
${functionSymbol.description ? `\n${processInlineSeeRefs(htmlEscapeDescription(functionSymbol.description))}\n` : ''}
16301642
${renderExamplesSection(functionSymbol.tags, { heading: '##' })}
16311643
${renderSeeAlsoSection(functionSymbol.tags, typeLinkCtx, { heading: '##' })}
16321644
${renderSinceTags(since)}
16331645
${deprecated.length ? `\n**Deprecated:** ${deprecated.map((d) => {
16341646
const ver = d.version ? `\`${mdEscape(d.version)}\`` : '';
1635-
const desc = d.description ? processInlineSeeRefs(htmlEscape(d.description)) : '';
1647+
const desc = d.description ? processInlineSeeRefs(htmlEscapeDescription(d.description)) : '';
16361648
if (ver && desc) return `${ver} (${desc})`;
16371649
if (ver) return ver;
16381650
if (desc) return desc;

0 commit comments

Comments
 (0)