@refrakt-md/cli 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/edit.d.ts.map +1 -1
- package/dist/commands/edit.js +32 -5
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/extract.d.ts.map +1 -1
- package/dist/commands/extract.js +7 -4
- package/dist/commands/extract.js.map +1 -1
- package/dist/extractors/index.d.ts.map +1 -1
- package/dist/extractors/index.js +3 -1
- package/dist/extractors/index.js.map +1 -1
- package/dist/extractors/python-docstring.d.ts +26 -0
- package/dist/extractors/python-docstring.d.ts.map +1 -0
- package/dist/extractors/python-docstring.js +396 -0
- package/dist/extractors/python-docstring.js.map +1 -0
- package/dist/extractors/python.d.ts +17 -2
- package/dist/extractors/python.d.ts.map +1 -1
- package/dist/extractors/python.js +556 -4
- package/dist/extractors/python.js.map +1 -1
- package/dist/lib/symbol-generator.d.ts +2 -0
- package/dist/lib/symbol-generator.d.ts.map +1 -1
- package/dist/lib/symbol-generator.js +7 -6
- package/dist/lib/symbol-generator.js.map +1 -1
- package/package.json +9 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/commands/edit.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/commands/edit.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgErE"}
|
package/dist/commands/edit.js
CHANGED
|
@@ -7,12 +7,16 @@ export async function editCommand(options) {
|
|
|
7
7
|
let contentDir = options.contentDir;
|
|
8
8
|
let themeName;
|
|
9
9
|
let configDir = cwd;
|
|
10
|
+
let projectConfig;
|
|
11
|
+
let projectConfigPath;
|
|
10
12
|
if (!contentDir) {
|
|
11
13
|
try {
|
|
12
|
-
const { path:
|
|
13
|
-
|
|
14
|
+
const { path: cfgPath, config } = loadRefraktConfigFile(cwd);
|
|
15
|
+
projectConfigPath = cfgPath;
|
|
16
|
+
configDir = dirname(cfgPath);
|
|
14
17
|
contentDir = resolve(configDir, config.contentDir);
|
|
15
18
|
themeName = config.theme;
|
|
19
|
+
projectConfig = config;
|
|
16
20
|
}
|
|
17
21
|
catch {
|
|
18
22
|
console.error('Error: No refrakt.config.json found. Specify --content-dir or run from a refrakt.md project.');
|
|
@@ -26,8 +30,21 @@ export async function editCommand(options) {
|
|
|
26
30
|
console.error(`Error: Content directory not found: ${contentDir}`);
|
|
27
31
|
process.exit(1);
|
|
28
32
|
}
|
|
29
|
-
// Resolve theme config and
|
|
30
|
-
|
|
33
|
+
// Resolve theme config, CSS, and Svelte entry
|
|
34
|
+
let { themeConfig, themeCssPath, themeSveltePath } = await resolveTheme(themeName, configDir);
|
|
35
|
+
// Merge project-level custom icons into the theme's global icon group
|
|
36
|
+
if (projectConfig?.icons && Object.keys(projectConfig.icons).length > 0) {
|
|
37
|
+
themeConfig = {
|
|
38
|
+
...themeConfig,
|
|
39
|
+
icons: {
|
|
40
|
+
...themeConfig.icons,
|
|
41
|
+
global: { ...themeConfig.icons.global, ...projectConfig.icons },
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
// Resolve static assets directory (SvelteKit convention: {projectRoot}/static/)
|
|
46
|
+
const staticPath = resolve(configDir, 'static');
|
|
47
|
+
const staticDir = existsSync(staticPath) ? staticPath : undefined;
|
|
31
48
|
// Start editor
|
|
32
49
|
const { startEditor } = await import('@refrakt-md/editor');
|
|
33
50
|
await startEditor({
|
|
@@ -35,8 +52,12 @@ export async function editCommand(options) {
|
|
|
35
52
|
port: options.port ?? 4800,
|
|
36
53
|
themeConfig,
|
|
37
54
|
themeCssPath,
|
|
55
|
+
themeSveltePath,
|
|
56
|
+
staticDir,
|
|
38
57
|
devServer: options.devServer,
|
|
39
58
|
open: !options.noOpen,
|
|
59
|
+
configPath: projectConfigPath,
|
|
60
|
+
routeRules: projectConfig?.routeRules,
|
|
40
61
|
});
|
|
41
62
|
}
|
|
42
63
|
async function resolveTheme(themeName, configDir) {
|
|
@@ -69,7 +90,13 @@ async function resolveTheme(themeName, configDir) {
|
|
|
69
90
|
// Look for CSS entry point
|
|
70
91
|
const cssPath = resolve(themePkgDir, 'index.css');
|
|
71
92
|
const themeCssPath = existsSync(cssPath) ? cssPath : undefined;
|
|
72
|
-
|
|
93
|
+
// Look for Svelte entry point (for preview runtime)
|
|
94
|
+
let themeSveltePath;
|
|
95
|
+
const svelteEntry = resolve(themePkgDir, 'svelte', 'index.ts');
|
|
96
|
+
if (existsSync(svelteEntry)) {
|
|
97
|
+
themeSveltePath = svelteEntry;
|
|
98
|
+
}
|
|
99
|
+
return { themeConfig, themeCssPath, themeSveltePath };
|
|
73
100
|
}
|
|
74
101
|
catch {
|
|
75
102
|
console.warn(`Warning: Could not resolve theme "${themeName}", using base config`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edit.js","sourceRoot":"","sources":["../../src/commands/edit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"edit.js","sourceRoot":"","sources":["../../src/commands/edit.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/commands/extract.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,YAAY,GAAG,QAAQ,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;
|
|
1
|
+
{"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/commands/extract.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,YAAY,GAAG,QAAQ,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AA8DD,wBAAsB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA2GxE"}
|
package/dist/commands/extract.js
CHANGED
|
@@ -46,14 +46,17 @@ function walkFiles(dir, ext) {
|
|
|
46
46
|
const files = [];
|
|
47
47
|
const entries = readdirSync(dir);
|
|
48
48
|
for (const entry of entries) {
|
|
49
|
-
if (entry === 'node_modules' || entry.startsWith('.'))
|
|
49
|
+
if (entry === 'node_modules' || entry === '__pycache__' || entry.startsWith('.'))
|
|
50
50
|
continue;
|
|
51
51
|
const fullPath = resolve(dir, entry);
|
|
52
52
|
const stat = statSync(fullPath);
|
|
53
53
|
if (stat.isDirectory()) {
|
|
54
54
|
files.push(...walkFiles(fullPath, ext));
|
|
55
55
|
}
|
|
56
|
-
else if (ext.test(entry)
|
|
56
|
+
else if (ext.test(entry)
|
|
57
|
+
&& !entry.endsWith('.d.ts') && !entry.endsWith('.test.ts') && !entry.endsWith('.spec.ts')
|
|
58
|
+
&& !entry.startsWith('test_') && !entry.endsWith('_test.py')
|
|
59
|
+
&& entry !== 'conftest.py' && entry !== 'setup.py') {
|
|
57
60
|
files.push(fullPath);
|
|
58
61
|
}
|
|
59
62
|
}
|
|
@@ -101,14 +104,14 @@ export async function extractCommand(opts) {
|
|
|
101
104
|
for (const [slug, docs] of slugMap) {
|
|
102
105
|
if (docs.length === 1) {
|
|
103
106
|
const filePath = join(outputPath, `${slug}.md`);
|
|
104
|
-
generated.set(filePath, generateSymbolMarkdown(docs[0]));
|
|
107
|
+
generated.set(filePath, generateSymbolMarkdown(docs[0], { lang }));
|
|
105
108
|
}
|
|
106
109
|
else {
|
|
107
110
|
// Resolve collisions by appending kind
|
|
108
111
|
for (const doc of docs) {
|
|
109
112
|
const uniqueSlug = `${slug}-${doc.kind}`;
|
|
110
113
|
const filePath = join(outputPath, `${uniqueSlug}.md`);
|
|
111
|
-
generated.set(filePath, generateSymbolMarkdown(doc));
|
|
114
|
+
generated.set(filePath, generateSymbolMarkdown(doc, { lang }));
|
|
112
115
|
}
|
|
113
116
|
}
|
|
114
117
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/commands/extract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEpG,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAWpE,SAAS,cAAc,CAAC,SAAiB;IACxC,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAE/B,kCAAkC;IAClC,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;QAC/C,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,OAAO,YAAY,CAAC;QACrE,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,OAAO,QAAQ,CAAC;IAC1C,CAAC;IAED,0BAA0B;IAC1B,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QACzC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC;QAClD,OAAO,YAAY,CAAC;IACrB,CAAC;IAED,2BAA2B;IAC3B,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QACpD,IAAI,CAAC;YACJ,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;YAC/B,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBAAE,OAAO,YAAY,CAAC;YAClF,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;gBAAE,OAAO,QAAQ,CAAC;QACzD,CAAC;QAAC,MAAM,CAAC;YACR,eAAe;QAChB,CAAC;IACF,CAAC;IAED,OAAO,YAAY,CAAC;AACrB,CAAC;AAED,SAAS,eAAe,CAAC,SAAiB,EAAE,IAA6B;IACxE,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAE/B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAEhC,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,IAAI,CAAC,MAAM,EAAE;QAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IAEhC,MAAM,GAAG,GAAG,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;IACxD,OAAO,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED,SAAS,SAAS,CAAC,GAAW,EAAE,GAAW;IAC1C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IACjC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,KAAK,KAAK,cAAc,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;
|
|
1
|
+
{"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/commands/extract.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/extractors/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,SAAS,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,EACvD,eAAe,EAAE,YAAY,EAAE,YAAY,EAC3C,eAAe,EAAE,cAAc,GAC/B,MAAM,YAAY,CAAC;AAEpB,wBAAsB,aAAa,CAClC,IAAI,EAAE,YAAY,GAAG,QAAQ,EAC7B,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,YAAY,EAAE,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/extractors/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,SAAS,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,EACvD,eAAe,EAAE,YAAY,EAAE,YAAY,EAC3C,eAAe,EAAE,cAAc,GAC/B,MAAM,YAAY,CAAC;AAEpB,wBAAsB,aAAa,CAClC,IAAI,EAAE,YAAY,GAAG,QAAQ,EAC7B,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,YAAY,EAAE,eAAe,CAAC,CAe/C"}
|
package/dist/extractors/index.js
CHANGED
|
@@ -6,7 +6,9 @@ export async function loadExtractor(lang, rootDir, sourceUrl) {
|
|
|
6
6
|
}
|
|
7
7
|
case 'python': {
|
|
8
8
|
const { PythonExtractor } = await import('./python.js');
|
|
9
|
-
|
|
9
|
+
const extractor = new PythonExtractor(rootDir, sourceUrl);
|
|
10
|
+
await extractor.init();
|
|
11
|
+
return extractor;
|
|
10
12
|
}
|
|
11
13
|
default:
|
|
12
14
|
throw new Error(`Unsupported language: ${lang}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/extractors/index.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,KAAK,UAAU,aAAa,CAClC,IAA6B,EAC7B,OAAe,EACf,SAAkB;IAElB,QAAQ,IAAI,EAAE,CAAC;QACd,KAAK,YAAY,CAAC,CAAC,CAAC;YACnB,MAAM,EAAE,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;YAChE,OAAO,IAAI,mBAAmB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACpD,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACf,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;YACxD,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/extractors/index.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,KAAK,UAAU,aAAa,CAClC,IAA6B,EAC7B,OAAe,EACf,SAAkB;IAElB,QAAQ,IAAI,EAAE,CAAC;QACd,KAAK,YAAY,CAAC,CAAC,CAAC;YACnB,MAAM,EAAE,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;YAChE,OAAO,IAAI,mBAAmB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACpD,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACf,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;YACxD,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YAC1D,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;YACvB,OAAO,SAAS,CAAC;QAClB,CAAC;QACD;YACC,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Python docstring parser — supports Google, NumPy, and Sphinx (reST) conventions.
|
|
3
|
+
* Auto-detects the format and extracts parameters, returns, raises, since, and deprecated.
|
|
4
|
+
*/
|
|
5
|
+
export interface DocstringParam {
|
|
6
|
+
type: string;
|
|
7
|
+
description: string;
|
|
8
|
+
}
|
|
9
|
+
export interface DocstringInfo {
|
|
10
|
+
description: string;
|
|
11
|
+
params: Map<string, DocstringParam>;
|
|
12
|
+
returns?: {
|
|
13
|
+
type: string;
|
|
14
|
+
description: string;
|
|
15
|
+
};
|
|
16
|
+
raises: Array<{
|
|
17
|
+
type: string;
|
|
18
|
+
description: string;
|
|
19
|
+
}>;
|
|
20
|
+
since?: string;
|
|
21
|
+
deprecated?: string;
|
|
22
|
+
}
|
|
23
|
+
export type DocstringStyle = 'google' | 'numpy' | 'sphinx' | 'plain';
|
|
24
|
+
export declare function detectStyle(raw: string): DocstringStyle;
|
|
25
|
+
export declare function parseDocstring(raw: string): DocstringInfo;
|
|
26
|
+
//# sourceMappingURL=python-docstring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"python-docstring.d.ts","sourceRoot":"","sources":["../../src/extractors/python-docstring.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACpC,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAQrE,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAMvD;AAID,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAazD"}
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Python docstring parser — supports Google, NumPy, and Sphinx (reST) conventions.
|
|
3
|
+
* Auto-detects the format and extracts parameters, returns, raises, since, and deprecated.
|
|
4
|
+
*/
|
|
5
|
+
// ── Detection ────────────────────────────────────────────────────────
|
|
6
|
+
const GOOGLE_SECTIONS = /^(Args|Arguments|Parameters|Returns?|Raises?|Yields?|Examples?|Notes?|Attributes|Todo|References):\s*$/m;
|
|
7
|
+
const NUMPY_SECTIONS = /^(Parameters|Returns?|Raises?|Yields?|See Also|Notes|References|Examples|Attributes)\s*\n-{3,}/m;
|
|
8
|
+
const SPHINX_DIRECTIVES = /:(param|type|returns?|rtype|raises?|var|ivar|cvar)[\s:]/;
|
|
9
|
+
export function detectStyle(raw) {
|
|
10
|
+
const text = dedent(raw);
|
|
11
|
+
if (NUMPY_SECTIONS.test(text))
|
|
12
|
+
return 'numpy';
|
|
13
|
+
if (SPHINX_DIRECTIVES.test(text))
|
|
14
|
+
return 'sphinx';
|
|
15
|
+
if (GOOGLE_SECTIONS.test(text))
|
|
16
|
+
return 'google';
|
|
17
|
+
return 'plain';
|
|
18
|
+
}
|
|
19
|
+
// ── Main entry ───────────────────────────────────────────────────────
|
|
20
|
+
export function parseDocstring(raw) {
|
|
21
|
+
const cleaned = dedent(raw);
|
|
22
|
+
const style = detectStyle(cleaned);
|
|
23
|
+
let info;
|
|
24
|
+
switch (style) {
|
|
25
|
+
case 'google':
|
|
26
|
+
info = parseGoogleDocstring(cleaned);
|
|
27
|
+
break;
|
|
28
|
+
case 'numpy':
|
|
29
|
+
info = parseNumpyDocstring(cleaned);
|
|
30
|
+
break;
|
|
31
|
+
case 'sphinx':
|
|
32
|
+
info = parseSphinxDocstring(cleaned);
|
|
33
|
+
break;
|
|
34
|
+
default:
|
|
35
|
+
info = parsePlainDocstring(cleaned);
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
// Extract reStructuredText directives from any style
|
|
39
|
+
extractRstDirectives(cleaned, info);
|
|
40
|
+
return info;
|
|
41
|
+
}
|
|
42
|
+
// ── RST directives (shared across all styles) ────────────────────────
|
|
43
|
+
function extractRstDirectives(raw, info) {
|
|
44
|
+
// .. versionadded:: X.Y
|
|
45
|
+
const sinceMatch = raw.match(/\.\.\s+versionadded::\s*(.+)/);
|
|
46
|
+
if (sinceMatch)
|
|
47
|
+
info.since = sinceMatch[1].trim();
|
|
48
|
+
// .. deprecated:: X.Y
|
|
49
|
+
const deprecatedMatch = raw.match(/\.\.\s+deprecated::\s*(.+)/);
|
|
50
|
+
if (deprecatedMatch)
|
|
51
|
+
info.deprecated = deprecatedMatch[1].trim();
|
|
52
|
+
}
|
|
53
|
+
// ── Plain ────────────────────────────────────────────────────────────
|
|
54
|
+
function parsePlainDocstring(raw) {
|
|
55
|
+
return {
|
|
56
|
+
description: raw.trim(),
|
|
57
|
+
params: new Map(),
|
|
58
|
+
raises: [],
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
// ── Google style ─────────────────────────────────────────────────────
|
|
62
|
+
function parseGoogleDocstring(raw) {
|
|
63
|
+
const info = { description: '', params: new Map(), raises: [] };
|
|
64
|
+
// Split into sections. Each section starts with a header like "Args:"
|
|
65
|
+
const sectionRe = /^(Args|Arguments|Parameters|Returns?|Raises?|Yields?|Examples?|Notes?|Attributes|Todo|References):\s*$/gm;
|
|
66
|
+
const sections = [];
|
|
67
|
+
let match;
|
|
68
|
+
while ((match = sectionRe.exec(raw)) !== null) {
|
|
69
|
+
sections.push({ name: match[1], headerStart: match.index, start: match.index + match[0].length, end: raw.length });
|
|
70
|
+
}
|
|
71
|
+
// Set end boundaries
|
|
72
|
+
for (let i = 0; i < sections.length - 1; i++) {
|
|
73
|
+
sections[i].end = sections[i + 1].headerStart;
|
|
74
|
+
}
|
|
75
|
+
// Description is everything before the first section (minus RST directives)
|
|
76
|
+
const descEnd = sections.length > 0 ? sections[0].headerStart : raw.length;
|
|
77
|
+
info.description = stripRstDirectives(raw.slice(0, descEnd)).trim();
|
|
78
|
+
for (const section of sections) {
|
|
79
|
+
const body = raw.slice(section.start, section.end);
|
|
80
|
+
const normalized = section.name.replace(/s$/, '').toLowerCase();
|
|
81
|
+
if (normalized === 'arg' || normalized === 'argument' || normalized === 'parameter') {
|
|
82
|
+
parseGoogleParams(body, info.params);
|
|
83
|
+
}
|
|
84
|
+
else if (normalized === 'return' || normalized === 'yield') {
|
|
85
|
+
info.returns = parseGoogleReturns(body);
|
|
86
|
+
}
|
|
87
|
+
else if (normalized === 'raise') {
|
|
88
|
+
parseGoogleRaises(body, info.raises);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return info;
|
|
92
|
+
}
|
|
93
|
+
function parseGoogleParams(body, params) {
|
|
94
|
+
// Pattern: " name (type): Description" or " name: Description"
|
|
95
|
+
const lines = body.split('\n');
|
|
96
|
+
let currentName = '';
|
|
97
|
+
let currentType = '';
|
|
98
|
+
let currentDesc = '';
|
|
99
|
+
for (const line of lines) {
|
|
100
|
+
// New param line: starts with indent + identifier
|
|
101
|
+
const paramMatch = line.match(/^\s{2,}(\*{0,2}\w+)\s*(?:\(([^)]+)\))?\s*:\s*(.*)/);
|
|
102
|
+
if (paramMatch) {
|
|
103
|
+
if (currentName) {
|
|
104
|
+
params.set(currentName, { type: currentType || 'Any', description: currentDesc.trim() });
|
|
105
|
+
}
|
|
106
|
+
currentName = paramMatch[1];
|
|
107
|
+
currentType = paramMatch[2] ?? '';
|
|
108
|
+
currentDesc = paramMatch[3] ?? '';
|
|
109
|
+
}
|
|
110
|
+
else if (currentName && line.match(/^\s{4,}/)) {
|
|
111
|
+
// Continuation line
|
|
112
|
+
currentDesc += ' ' + line.trim();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (currentName) {
|
|
116
|
+
params.set(currentName, { type: currentType || 'Any', description: currentDesc.trim() });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function parseGoogleReturns(body) {
|
|
120
|
+
const lines = body.split('\n').filter(l => l.trim());
|
|
121
|
+
if (lines.length === 0)
|
|
122
|
+
return undefined;
|
|
123
|
+
// Pattern: " type: Description" or just " Description"
|
|
124
|
+
const first = lines[0].trim();
|
|
125
|
+
const typeMatch = first.match(/^(\S+)\s*:\s*(.*)/);
|
|
126
|
+
if (typeMatch) {
|
|
127
|
+
const desc = [typeMatch[2], ...lines.slice(1).map(l => l.trim())].join(' ').trim();
|
|
128
|
+
return { type: typeMatch[1], description: desc };
|
|
129
|
+
}
|
|
130
|
+
return { type: 'Any', description: lines.map(l => l.trim()).join(' ').trim() };
|
|
131
|
+
}
|
|
132
|
+
function parseGoogleRaises(body, raises) {
|
|
133
|
+
const lines = body.split('\n');
|
|
134
|
+
let currentType = '';
|
|
135
|
+
let currentDesc = '';
|
|
136
|
+
for (const line of lines) {
|
|
137
|
+
const raiseMatch = line.match(/^\s{2,}(\w+)\s*:\s*(.*)/);
|
|
138
|
+
if (raiseMatch) {
|
|
139
|
+
if (currentType) {
|
|
140
|
+
raises.push({ type: currentType, description: currentDesc.trim() });
|
|
141
|
+
}
|
|
142
|
+
currentType = raiseMatch[1];
|
|
143
|
+
currentDesc = raiseMatch[2] ?? '';
|
|
144
|
+
}
|
|
145
|
+
else if (currentType && line.match(/^\s{4,}/)) {
|
|
146
|
+
currentDesc += ' ' + line.trim();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (currentType) {
|
|
150
|
+
raises.push({ type: currentType, description: currentDesc.trim() });
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// ── NumPy style ──────────────────────────────────────────────────────
|
|
154
|
+
function parseNumpyDocstring(raw) {
|
|
155
|
+
const info = { description: '', params: new Map(), raises: [] };
|
|
156
|
+
// Split on sections delimited by underlined headers
|
|
157
|
+
const sectionRe = /^(\w[\w\s]*?)\s*\n(-{3,})\s*$/gm;
|
|
158
|
+
const sections = [];
|
|
159
|
+
let match;
|
|
160
|
+
while ((match = sectionRe.exec(raw)) !== null) {
|
|
161
|
+
const headerStart = match.index;
|
|
162
|
+
const bodyStart = match.index + match[0].length;
|
|
163
|
+
sections.push({ name: match[1].trim(), start: bodyStart, end: raw.length });
|
|
164
|
+
// Store headerStart for description extraction
|
|
165
|
+
if (sections.length === 1) {
|
|
166
|
+
info.description = stripRstDirectives(raw.slice(0, headerStart)).trim();
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (sections.length === 0) {
|
|
170
|
+
info.description = stripRstDirectives(raw).trim();
|
|
171
|
+
return info;
|
|
172
|
+
}
|
|
173
|
+
// Set end boundaries
|
|
174
|
+
for (let i = 0; i < sections.length - 1; i++) {
|
|
175
|
+
// Find start of next section's header
|
|
176
|
+
const nextHeaderRe = new RegExp(`^${escapeRegex(sections[i + 1].name)}\\s*\\n-{3,}`, 'm');
|
|
177
|
+
const nextMatch = raw.slice(sections[i].start).match(nextHeaderRe);
|
|
178
|
+
if (nextMatch) {
|
|
179
|
+
sections[i].end = sections[i].start + nextMatch.index;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
for (const section of sections) {
|
|
183
|
+
const body = raw.slice(section.start, section.end);
|
|
184
|
+
const normalized = section.name.replace(/s$/, '').toLowerCase();
|
|
185
|
+
if (normalized === 'parameter') {
|
|
186
|
+
parseNumpyParams(body, info.params);
|
|
187
|
+
}
|
|
188
|
+
else if (normalized === 'return' || normalized === 'yield') {
|
|
189
|
+
info.returns = parseNumpyReturns(body);
|
|
190
|
+
}
|
|
191
|
+
else if (normalized === 'raise') {
|
|
192
|
+
parseNumpyRaises(body, info.raises);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return info;
|
|
196
|
+
}
|
|
197
|
+
function parseNumpyParams(body, params) {
|
|
198
|
+
// Pattern: "name : type\n Description" or "name : type, optional\n Description"
|
|
199
|
+
const lines = body.split('\n');
|
|
200
|
+
let currentName = '';
|
|
201
|
+
let currentType = '';
|
|
202
|
+
let currentDesc = '';
|
|
203
|
+
for (const line of lines) {
|
|
204
|
+
const paramMatch = line.match(/^(\*{0,2}\w+)\s*:\s*(.*)/);
|
|
205
|
+
if (paramMatch && !line.match(/^\s/)) {
|
|
206
|
+
if (currentName) {
|
|
207
|
+
params.set(currentName, { type: currentType || 'Any', description: currentDesc.trim() });
|
|
208
|
+
}
|
|
209
|
+
currentName = paramMatch[1];
|
|
210
|
+
currentType = paramMatch[2].replace(/,?\s*optional\s*$/, '').trim() || 'Any';
|
|
211
|
+
currentDesc = '';
|
|
212
|
+
}
|
|
213
|
+
else if (currentName && line.match(/^\s{2,}/)) {
|
|
214
|
+
currentDesc += (currentDesc ? ' ' : '') + line.trim();
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (currentName) {
|
|
218
|
+
params.set(currentName, { type: currentType || 'Any', description: currentDesc.trim() });
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
function parseNumpyReturns(body) {
|
|
222
|
+
const lines = body.split('\n');
|
|
223
|
+
let type = 'Any';
|
|
224
|
+
let desc = '';
|
|
225
|
+
for (const line of lines) {
|
|
226
|
+
const typeMatch = line.match(/^(\S+)\s*$/);
|
|
227
|
+
if (typeMatch && !line.match(/^\s/) && !desc) {
|
|
228
|
+
type = typeMatch[1];
|
|
229
|
+
}
|
|
230
|
+
else if (line.match(/^\s{2,}/)) {
|
|
231
|
+
desc += (desc ? ' ' : '') + line.trim();
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (!type && !desc)
|
|
235
|
+
return undefined;
|
|
236
|
+
return { type, description: desc.trim() };
|
|
237
|
+
}
|
|
238
|
+
function parseNumpyRaises(body, raises) {
|
|
239
|
+
const lines = body.split('\n');
|
|
240
|
+
let currentType = '';
|
|
241
|
+
let currentDesc = '';
|
|
242
|
+
for (const line of lines) {
|
|
243
|
+
const typeMatch = line.match(/^(\w+)\s*$/);
|
|
244
|
+
if (typeMatch && !line.match(/^\s/)) {
|
|
245
|
+
if (currentType) {
|
|
246
|
+
raises.push({ type: currentType, description: currentDesc.trim() });
|
|
247
|
+
}
|
|
248
|
+
currentType = typeMatch[1];
|
|
249
|
+
currentDesc = '';
|
|
250
|
+
}
|
|
251
|
+
else if (currentType && line.match(/^\s{2,}/)) {
|
|
252
|
+
currentDesc += (currentDesc ? ' ' : '') + line.trim();
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (currentType) {
|
|
256
|
+
raises.push({ type: currentType, description: currentDesc.trim() });
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
// ── Sphinx/reST style ────────────────────────────────────────────────
|
|
260
|
+
function parseSphinxDocstring(raw) {
|
|
261
|
+
const info = { description: '', params: new Map(), raises: [] };
|
|
262
|
+
const lines = raw.split('\n');
|
|
263
|
+
const descLines = [];
|
|
264
|
+
let foundDirective = false;
|
|
265
|
+
// Temporary storage for :type: merging
|
|
266
|
+
const paramTypes = new Map();
|
|
267
|
+
let returnDesc = '';
|
|
268
|
+
let returnType = '';
|
|
269
|
+
for (let i = 0; i < lines.length; i++) {
|
|
270
|
+
const line = lines[i];
|
|
271
|
+
// :param name: description
|
|
272
|
+
const paramMatch = line.match(/^\s*:param\s+(\w+)\s*:\s*(.*)/);
|
|
273
|
+
if (paramMatch) {
|
|
274
|
+
foundDirective = true;
|
|
275
|
+
const name = paramMatch[1];
|
|
276
|
+
let desc = paramMatch[2];
|
|
277
|
+
// Collect continuation lines
|
|
278
|
+
while (i + 1 < lines.length && lines[i + 1].match(/^\s+\S/) && !lines[i + 1].match(/^\s*:/)) {
|
|
279
|
+
i++;
|
|
280
|
+
desc += ' ' + lines[i].trim();
|
|
281
|
+
}
|
|
282
|
+
const existing = info.params.get(name);
|
|
283
|
+
info.params.set(name, {
|
|
284
|
+
type: existing?.type ?? 'Any',
|
|
285
|
+
description: desc.trim(),
|
|
286
|
+
});
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
// :type name: type
|
|
290
|
+
const typeMatch = line.match(/^\s*:type\s+(\w+)\s*:\s*(.*)/);
|
|
291
|
+
if (typeMatch) {
|
|
292
|
+
foundDirective = true;
|
|
293
|
+
paramTypes.set(typeMatch[1], typeMatch[2].trim());
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
// :returns: / :return: description
|
|
297
|
+
const returnMatch = line.match(/^\s*:returns?\s*:\s*(.*)/);
|
|
298
|
+
if (returnMatch) {
|
|
299
|
+
foundDirective = true;
|
|
300
|
+
returnDesc = returnMatch[1];
|
|
301
|
+
while (i + 1 < lines.length && lines[i + 1].match(/^\s+\S/) && !lines[i + 1].match(/^\s*:/)) {
|
|
302
|
+
i++;
|
|
303
|
+
returnDesc += ' ' + lines[i].trim();
|
|
304
|
+
}
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
// :rtype: type
|
|
308
|
+
const rtypeMatch = line.match(/^\s*:rtype\s*:\s*(.*)/);
|
|
309
|
+
if (rtypeMatch) {
|
|
310
|
+
foundDirective = true;
|
|
311
|
+
returnType = rtypeMatch[1].trim();
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
// :raises Type: description
|
|
315
|
+
const raiseMatch = line.match(/^\s*:raises?\s+(\w+)\s*:\s*(.*)/);
|
|
316
|
+
if (raiseMatch) {
|
|
317
|
+
foundDirective = true;
|
|
318
|
+
let desc = raiseMatch[2];
|
|
319
|
+
while (i + 1 < lines.length && lines[i + 1].match(/^\s+\S/) && !lines[i + 1].match(/^\s*:/)) {
|
|
320
|
+
i++;
|
|
321
|
+
desc += ' ' + lines[i].trim();
|
|
322
|
+
}
|
|
323
|
+
info.raises.push({ type: raiseMatch[1], description: desc.trim() });
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
326
|
+
// RST directives (.. versionadded, .. deprecated) are handled by extractRstDirectives
|
|
327
|
+
if (line.match(/^\s*\.\.\s+(versionadded|deprecated)::/)) {
|
|
328
|
+
foundDirective = true;
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
if (!foundDirective) {
|
|
332
|
+
descLines.push(line);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
info.description = stripRstDirectives(descLines.join('\n')).trim();
|
|
336
|
+
// Merge :type: into :param:
|
|
337
|
+
for (const [name, type] of paramTypes) {
|
|
338
|
+
const existing = info.params.get(name);
|
|
339
|
+
if (existing) {
|
|
340
|
+
existing.type = type;
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
info.params.set(name, { type, description: '' });
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
// Set returns
|
|
347
|
+
if (returnDesc || returnType) {
|
|
348
|
+
info.returns = { type: returnType || 'Any', description: returnDesc.trim() };
|
|
349
|
+
}
|
|
350
|
+
return info;
|
|
351
|
+
}
|
|
352
|
+
// ── Helpers ──────────────────────────────────────────────────────────
|
|
353
|
+
function stripRstDirectives(text) {
|
|
354
|
+
return text
|
|
355
|
+
.replace(/\.\.\s+versionadded::\s*.+(\n\s+.*)*/g, '')
|
|
356
|
+
.replace(/\.\.\s+deprecated::\s*.+(\n\s+.*)*/g, '')
|
|
357
|
+
.trim();
|
|
358
|
+
}
|
|
359
|
+
function escapeRegex(s) {
|
|
360
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Remove common leading whitespace from all lines (Python's `inspect.cleandoc` equivalent).
|
|
364
|
+
* The first line is treated specially: its leading whitespace is stripped independently.
|
|
365
|
+
*/
|
|
366
|
+
function dedent(text) {
|
|
367
|
+
const lines = text.split('\n');
|
|
368
|
+
// First line: strip leading whitespace
|
|
369
|
+
const firstLine = lines[0].trimStart();
|
|
370
|
+
if (lines.length === 1)
|
|
371
|
+
return firstLine;
|
|
372
|
+
// Find minimum indentation of non-empty lines after the first
|
|
373
|
+
let minIndent = Infinity;
|
|
374
|
+
for (let i = 1; i < lines.length; i++) {
|
|
375
|
+
const line = lines[i];
|
|
376
|
+
if (line.trim().length === 0)
|
|
377
|
+
continue;
|
|
378
|
+
const indent = line.match(/^\s*/)[0].length;
|
|
379
|
+
if (indent < minIndent)
|
|
380
|
+
minIndent = indent;
|
|
381
|
+
}
|
|
382
|
+
if (!isFinite(minIndent))
|
|
383
|
+
minIndent = 0;
|
|
384
|
+
// Strip common indentation
|
|
385
|
+
const dedented = [firstLine];
|
|
386
|
+
for (let i = 1; i < lines.length; i++) {
|
|
387
|
+
dedented.push(lines[i].slice(minIndent));
|
|
388
|
+
}
|
|
389
|
+
// Remove leading/trailing blank lines
|
|
390
|
+
while (dedented.length > 0 && dedented[0].trim() === '')
|
|
391
|
+
dedented.shift();
|
|
392
|
+
while (dedented.length > 0 && dedented[dedented.length - 1].trim() === '')
|
|
393
|
+
dedented.pop();
|
|
394
|
+
return dedented.join('\n');
|
|
395
|
+
}
|
|
396
|
+
//# sourceMappingURL=python-docstring.js.map
|