-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
104 lines (91 loc) · 2.71 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
var logger = require('jsdoc/util/logger');
var rdgModule = require('react-docgen');
var buildParser = require('react-docgen/dist/babelParser.js').default;
const parser = buildParser();
function parseDocblock(str) {
// Does not use \s in the regex as this would match also \n and conflicts
// with windows line endings.
return str.replace(/^[ \t]*\*[ \t]?/gm, '').trim();
}
const tableheader = `
<thead>
<tr>
<td>prop</th>
<td>type</td>
<td>required</td>
<td>description</td>
</tr>
</thead>`
function propTableHtml(component) {
if (!component.props) {
return `
<p>No prop-types. Possibly no props</p>
`;
}
const rows = Object.entries(component.props).map(([name, data])=> {
return `
<tr>
<th scope="row">${name}</th>
<td>${data.type.name}</td>
<td>${data.required ? 'yes' : 'no'}</td>
<td>${data.description}</td>
</tr>
`
}).join("");
return `<table>${tableheader}${rows}</table>`;
}
let firstFile = true;
exports.handlers = {
beforeParse: function(file) {
// Add a namespace called Components
// that all of the components can attach to
// using memberof tag. This way class and function
// components can be grouped together
if (firstFile) {
file.source += `
/**
* @namespace Components
*/
`;
firstFile = false;
}
// Parse all of the components in a file
// Chose to document all components not just default exported
// Maybe this isn't what the people want?
let components;
try {
components = rdgModule.parse(file.source, rdgModule.resolver.findAllComponentDefinitions);
} catch (err) {
if (!err.message.includes("No suitable component definition found.")) {
logger.warn(err);
}
return;
}
if (!components?.length) {
return;
}
const ast = parser.parse(file.source);
const reactComments = components.flatMap(c => [c.description, ...Object.values(c.props ?? {})?.map(p => p.description)])
ast.comments?.reverse().forEach(docblock => {
const content = parseDocblock(docblock.value);
if (reactComments.includes(content)) {
file.source = file.source.substring(0, docblock.start) + file.source.substring(docblock.end + 1);
}
});
components.forEach((comp) => {
// Now I need to get rid of content parsed by react-docgen
// becuse it's now redundant or worse misleading
// Could slap @ignore each component docgen consumed.
// or manually edit the source to delete those docblocks.
// Add parsed/generated content
propshtml = propTableHtml(comp)
file.source += `
/**
* ${comp.description}
* ${propshtml}
* @memberof Components
* @name ${comp.displayName}
*/`;
});
}
}