Skip to content

Commit b4d40b8

Browse files
committed
apply table to more than just methods, fix titles
1 parent 0372cf1 commit b4d40b8

File tree

6 files changed

+82
-62
lines changed

6 files changed

+82
-62
lines changed

eslint.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export default defineConfig([
104104
CLIENT: 'readonly',
105105
SERVER: 'readonly',
106106
},
107-
ecmaVersion: 'latest'
107+
ecmaVersion: 'latest',
108108
},
109109
},
110110
]);

src/generators/jsx-ast/utils/buildContent.mjs

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
TYPES_WITH_METHOD_SIGNATURES,
2525
} from '../constants.mjs';
2626
import createSignatureElements, {
27+
createPropertyTable,
2728
getFullName,
2829
} from './createSignatureElements.mjs';
2930

@@ -87,14 +88,14 @@ const createSourceLink = sourceLink =>
8788
const createHeadingElement = (content, changeElement) => {
8889
const { type, depth, slug } = content.data;
8990

90-
const headingContent = TYPES_WITH_METHOD_SIGNATURES.includes(type)
91-
? createElement('code', getFullName(content.data))
92-
: sliceMarkdown(
93-
content,
94-
(findTextPositions(content, ':')[0] ?? -1) + 1,
95-
getTreeLength(content),
96-
{ trimWhitespace: true }
97-
).children;
91+
const headingContent =
92+
getFullName(content.data, false) ||
93+
sliceMarkdown(
94+
content,
95+
(findTextPositions(content, ':')[0] ?? -1) + 1,
96+
getTreeLength(content),
97+
{ trimWhitespace: true }
98+
).children;
9899

99100
const headingWrapper = createElement('div', [
100101
createElement(`h${depth}`, [
@@ -161,13 +162,12 @@ const transformHeadingNode = (entry, node, index, parent) => {
161162
}
162163

163164
// Add method signatures for appropriate types
164-
if (TYPES_WITH_METHOD_SIGNATURES.includes(node.data.type)) {
165-
createSignatureElements(
166-
parent,
167-
node.data.entries || [entry],
168-
index + (sourceLink ? 2 : 1)
169-
);
170-
}
165+
createSignatureElements(
166+
parent,
167+
node.data.entries || [entry],
168+
index + (sourceLink ? 2 : 1),
169+
TYPES_WITH_METHOD_SIGNATURES.includes(node.data.type)
170+
);
171171

172172
return [SKIP];
173173
};
@@ -186,6 +186,11 @@ const processEntry = entry => {
186186
visit(content, createQueries.UNIST.isHeading, (node, idx, parent) =>
187187
transformHeadingNode(entry, node, idx, parent)
188188
);
189+
visit(
190+
content,
191+
createQueries.UNIST.isTypedList,
192+
(node, idx, parent) => (parent.children[idx] = createPropertyTable(node))
193+
);
189194

190195
return content;
191196
};

src/generators/jsx-ast/utils/createSignatureElements.mjs

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { h as createElement } from 'hastscript';
22

3-
import { isTypedList } from '../../../utils/generators.mjs';
3+
import createQueries from '../../../utils/queries/index.mjs';
44
import { parseListItem } from '../../legacy-json/utils/parseList.mjs';
55
import parseSignature from '../../legacy-json/utils/parseSignature.mjs';
66

@@ -70,10 +70,13 @@ export const processListItemsIntoProperties = (items, prefix = '') => {
7070
let description = [];
7171

7272
// Special handling for "Returns: " nodes with a description, and no type
73-
if (propName.startsWith('Returns: ') && propName.length > 9) {
73+
if (
74+
(propName.startsWith('Returns: ') || propName.startsWith('Returns ')) &&
75+
propName.length > 9
76+
) {
7477
description = propName.substring(9).trim();
75-
propName = 'Returns';
76-
displayName = { ...propNode, value: 'Returns' };
78+
propName = 'Returns:';
79+
displayName = { ...propNode, value: propName };
7780
} else {
7881
const extracted = extractTypesAndDescription(paragraph.children.slice(1));
7982
types = extracted.types;
@@ -106,7 +109,7 @@ export const processListItemsIntoProperties = (items, prefix = '') => {
106109
});
107110

108111
// Process nested properties
109-
const nestedList = nestedContent.find(isTypedList);
112+
const nestedList = nestedContent.find(createQueries.UNIST.isTypedList);
110113
if (nestedList) {
111114
const nestedProperties = processListItemsIntoProperties(
112115
nestedList.children,
@@ -228,37 +231,48 @@ export const createSignatureCodeBlock = (functionName, signature) => {
228231
/**
229232
* Gets the full name of a function.
230233
* @param {HeadingMetadataEntry} heading
234+
* @param {any} fallback
231235
*/
232-
export const getFullName = ({ name, text }) => {
233-
const code = text.match(/`([^`]+)`/)?.[1];
236+
export const getFullName = ({ name, text }, fallback = name) => {
237+
// Exit early if the name wasn't processed
238+
if (name === text) {
239+
return fallback;
240+
}
241+
242+
const code = text.trim().match(/`([^`]+)`/)?.[1];
234243
return code?.includes(name)
235-
? code.slice(0, code.indexOf(name) + name.length)
236-
: name;
244+
? code
245+
.slice(0, code.indexOf(name) + name.length)
246+
.replace(/^["']|new\s*/, '')
247+
: fallback;
237248
};
238249

239250
/**
240251
* Creates documentation from API metadata entries
241252
* @param {import('@types/mdast').Parent} parent - The parent node
242253
* @param {ApiDocMetadataEntry[]} entries - Array of API documentation metadata entries
243254
* @param {number} backupIndex - If there isn't a list, use this index
255+
* @param {boolean} addSignatureCodebox - Is this a method?
244256
*/
245-
export default (parent, entries, backupIndex) => {
257+
export default (parent, entries, backupIndex, addSignatureCodebox) => {
246258
// Find the list index in the parent for later replacement
247-
const listIdx = parent.children.findIndex(isTypedList);
259+
const listIdx = parent.children.findIndex(createQueries.UNIST.isTypedList);
248260
const elements = [];
249261

250262
// Process all entries
251263
for (const entry of entries) {
252264
// Find the list in the container
253-
const list = entry.content.children.find(isTypedList);
265+
const list = entry.content.children.find(createQueries.UNIST.isTypedList);
254266

255-
// Process the entry
256-
const params = list ? list.children.map(parseListItem) : [];
257-
const signature = parseSignature(entry.heading.data.text, params);
258-
const displayName = getFullName(entry.heading.data);
267+
// Create a signature code box, if this is a method/ctor.
268+
if (addSignatureCodebox) {
269+
const params = list ? list.children.map(parseListItem) : [];
259270

260-
// Create signature code block
261-
elements.push(createSignatureCodeBlock(displayName, signature));
271+
const signature = parseSignature(entry.heading.data.text, params);
272+
const displayName = getFullName(entry.heading.data);
273+
274+
elements.push(createSignatureCodeBlock(displayName, signature));
275+
}
262276

263277
// Create property table if a list exists
264278
if (list) {

src/generators/legacy-json/utils/parseList.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
TYPE_EXPRESSION,
77
} from '../constants.mjs';
88
import parseSignature from './parseSignature.mjs';
9-
import { isTypedList } from '../../../utils/generators.mjs';
9+
import createQueries from '../../../utils/queries/index.mjs';
1010
import { transformNodesToString } from '../../../utils/unist.mjs';
1111

1212
/**
@@ -47,7 +47,7 @@ export const extractPattern = (text, pattern, key, current) => {
4747
export function parseListItem(child) {
4848
const current = {};
4949

50-
const subList = child.children.find(isTypedList);
50+
const subList = child.children.find(createQueries.UNIST.isTypedList);
5151

5252
// Extract and clean raw text from the node, excluding nested lists
5353
current.textRaw = transformTypeReferences(

src/utils/generators.mjs

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -96,29 +96,3 @@ export const sortChanges = (changes, key = 'version') => {
9696
return compare(coerceSemVer(aVersion), coerceSemVer(bVersion));
9797
});
9898
};
99-
100-
/**
101-
* Determines if the input List node is a typed list
102-
* @param {import('@types/mdast').List} list
103-
*/
104-
export const isTypedList = list => {
105-
if (list.type !== 'list') {
106-
// Exit early if not a list
107-
return false;
108-
}
109-
110-
const children = list?.children?.[0]?.children?.[0]?.children;
111-
112-
return (
113-
// The first element must be a code block
114-
children?.[0]?.type === 'inlineCode'
115-
? // Followed by a space
116-
children?.[1]?.value.trim() === '' &&
117-
// Followed by a link (type)
118-
children?.[2]?.type === 'link' &&
119-
// Types start with `<`
120-
children?.[2]?.children?.[0]?.value?.[0] === '<'
121-
: // Or a "Returns:"
122-
children?.[0]?.value?.trim() === 'Returns:'
123-
);
124-
};

src/utils/queries/index.mjs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,33 @@ createQueries.UNIST = {
241241
*/
242242
isLinkReference: ({ type, identifier }) =>
243243
type === 'linkReference' && !!identifier,
244+
245+
/**
246+
* @param {import('@types/mdast').List} list
247+
* @returns {boolean}
248+
*/
249+
isTypedList: list => {
250+
if (list.type !== 'list') {
251+
// Exit early if not a list
252+
return false;
253+
}
254+
255+
const children = list?.children?.[0]?.children?.[0]?.children;
256+
257+
return (
258+
// The first element must be a code block
259+
children?.[0]?.type === 'inlineCode'
260+
? // Followed by a space
261+
children?.[1]?.value.trim() === '' &&
262+
// Followed by a link (type)
263+
children?.[2]?.type === 'link' &&
264+
// Types start with `<`
265+
children?.[2]?.children?.[0]?.value?.[0] === '<'
266+
: // Or a "Returns:" / "Returns" (Malformed)
267+
children?.[0]?.value?.trim() === 'Returns:' ||
268+
children?.[0]?.value?.trim() === 'Returns'
269+
);
270+
},
244271
};
245272

246273
export default createQueries;

0 commit comments

Comments
 (0)