forked from serenity-js/serenity-js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path.esdoc-patches.js
189 lines (159 loc) · 5.91 KB
/
.esdoc-patches.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
const
assert = require('assert'),
path = require('path'),
fs = require('fs'),
AbstractDoc = require('esdoc/out/src/Doc/AbstractDoc').default;
// --- Monkey patches
/**
* esdoc/out/src/Parser/ParamParser
*
* The original ParamParser does not support @link tags leading to a scoped package,
* for example {@link @serenity-js/core/lib/screenplay~Actor}.
* This patch adds support for this behaviour.
*/
function patched_parseParamValue(value, type = true, name = true, desc = true) {
value = value.trim();
let match;
let typeText = null;
let typeLongname = null;
let paramName = null;
let paramDesc = null;
// e.g {number}
if (type) {
const reg = /^\{(.*?)\}(\s+|$)/; // patch(jan-molak) previous: const reg = /^\{([^@]*?)\}(\s+|$)/; // ``@`` is special char in ``{@link foo}``
match = value.match(reg);
if (match) {
typeLongname = match[1];
typeText = typeLongname.slice(match[1].indexOf('~') + 1); // patch(jan-molak) previous: match[1];
value = value.replace(reg, '');
} else {
typeText = '*';
}
}
// e.g. [p1=123]
if (name) {
if (value.charAt(0) === '[') {
paramName = '';
let counter = 0;
for (const c of value) {
paramName += c;
if (c === '[') counter++;
if (c === ']') counter--;
if (counter === 0) break;
}
if (paramName) {
value = value.substr(paramName.length).trim();
}
} else {
match = value.match(/^(\S+)/);
if (match) {
paramName = match[1];
value = value.replace(/^\S+\s*/, '');
}
}
}
// e.g. this is p1 desc.
if (desc) {
match = value.match(/^-?\s*((:?.|\n)*)$/m);
if (match) {
paramDesc = match[1];
}
}
assert(typeText || paramName || paramDesc, `param is invalid. param = "${value}"`);
return {typeText, typeLongname, paramName, paramDesc};
}
require('esdoc/out/src/Parser/ParamParser').default.parseParamValue = patched_parseParamValue;
/**
* esdoc/out/src/Doc/ExternalDoc
*
* The original ExternalDoc recognised the longname incorrectly; instead of the one defined in the externals.js
* file it would use the externals file itself.
*
* So instead of using the `my-custom-module~Type` from `@external {my-custom-module~Type} description`
* it would use `externals.js~my-custom-module~Type` and then fail to link it correctly when generating the docs.
*/
require('esdoc/out/src/Doc/ExternalDoc').default.prototype._$name = function patched_$name() {
const value = this._findTagValue(['@external']);
if (!value) {
console.warn('can not resolve name.');
}
this._value.name = value;
const tags = this._findAll(['@external']);
if (!tags) {
console.warn('can not resolve name.');
return;
}
let name,
longname;
for (const tag of tags) {
const { typeText, typeLongname, paramDesc } = patched_parseParamValue(tag.tagValue, true, false, true);
name = typeText;
longname = typeLongname; // patch(jan-molak): previously longname was not returned by the ParamParser
this._value.externalLink = paramDesc;
}
this._value.name = name;
this._value.longname = longname;
};
require('esdoc/out/src/Doc/ExternalDoc').default.prototype._$longname = function() {};
/**
* esdoc-publish-html-plugin/out/src/Builder/DocResolver
*
* The original DocResolver did not support links leading to scoped packages.
*/
require('esdoc-publish-html-plugin/out/src/Builder/DocResolver').default.prototype._resolveLink = function patched_resolveLink () {
if (this._data.__RESOLVED_LINK__) return;
const link = str => {
if (!str) return str;
// patch(jan-molak): monkey-patched the regex to support `@`
return str.replace(/\{@link (@?[\w#_\-.:~\/$]+)}/g, (str, longname) => {
return this._builder._buildDocLinkHTML(longname, longname);
});
};
this._data().each(v => {
v.description = link(v.description);
if (v.params) {
for (const param of v.params) {
param.description = link(param.description);
}
}
if (v.properties) {
for (const property of v.properties) {
property.description = link(property.description);
}
}
if (v.return) {
v.return.description = link(v.return.description);
}
if (v.throws) {
for (const _throw of v.throws) {
_throw.description = link(_throw.description);
}
}
if (v.see) {
for (let i = 0; i < v.see.length; i++) {
if (v.see[i].indexOf('{@link') === 0) {
v.see[i] = link(v.see[i]);
} else if (v.see[i].indexOf('<a href') === 0) {
// ignore
} else {
v.see[i] = `<a href="${v.see[i]}">${v.see[i]}</a>`;
}
}
}
});
this._data.__RESOLVED_LINK__ = true;
};
const _exec = require('esdoc-publish-html-plugin/out/src/Plugin')._exec.bind(require('esdoc-publish-html-plugin/out/src/Plugin'));
require('esdoc-publish-html-plugin/out/src/Plugin')._exec = function patched_exec(tags, writeFile, copyDir, readFile) {
/**
* write .hbs instead of html so that they can be processed with MetalSmith
*/
function patched_writeFile(filePath, content, option) {
const
[ext, ...parts] = filePath.split('.').reverse(),
fileName = parts.reverse().join('.');
const newFilePath = (ext === 'html') ? `${fileName}.html.hbs` : filePath;
return writeFile(newFilePath, content, option);
}
return _exec(tags, patched_writeFile, copyDir, readFile);
};