@eeue56/geiriadur
Advanced tools
Comparing version 0.0.2 to 0.0.3
@@ -47,5 +47,5 @@ #!/usr/bin/env ts-node | ||
function exportTitle(exported) { | ||
const firstLine = exported.type[0] || ''; | ||
const firstLine = exported.type[0] || ""; | ||
switch (exported.kind) { | ||
case 'type': { | ||
case "type": { | ||
const matches = firstLine.match(/export type (.+)/); | ||
@@ -55,5 +55,5 @@ if (matches) { | ||
} | ||
return ''; | ||
return ""; | ||
} | ||
case 'function': { | ||
case "function": { | ||
const matches = firstLine.match(/export function (.+)/); | ||
@@ -66,3 +66,3 @@ if (matches) { | ||
} | ||
return ''; | ||
return ""; | ||
} | ||
@@ -76,8 +76,3 @@ } | ||
const linkToSource = `[View source](${repo}/blob/main/${filePath}#L${exported.pos.start}-L${exported.pos.end})`; | ||
return [ | ||
headline, | ||
typeBody, | ||
comments, | ||
linkToSource | ||
].join("\n"); | ||
return [headline, typeBody, comments, linkToSource].join("\n"); | ||
} | ||
@@ -93,9 +88,15 @@ function getExports(fileContents) { | ||
let types = []; | ||
const lines = fileContents.split('\n'); | ||
const lines = fileContents.split("\n"); | ||
lines.forEach((line, lineNumber) => { | ||
if (isInJSDoc) { | ||
currentJSDoc.push(line); | ||
if (line.endsWith("*/")) { | ||
isInJSDoc = false; | ||
return; | ||
} | ||
if (line.startsWith(" *")) { | ||
currentJSDoc.push(line.slice(3)); | ||
} | ||
else { | ||
currentJSDoc.push(line); | ||
} | ||
} | ||
@@ -107,3 +108,3 @@ else if (isInType) { | ||
types.push({ | ||
kind: 'type', | ||
kind: "type", | ||
jsDoc: currentJSDoc, | ||
@@ -113,4 +114,4 @@ type: currentType, | ||
start: startLineNumber, | ||
end: lineNumber | ||
} | ||
end: lineNumber, | ||
}, | ||
}); | ||
@@ -127,3 +128,3 @@ currentJSDoc = []; | ||
isInJSDoc = true; | ||
currentJSDoc.push(line); | ||
currentJSDoc.push(line.slice(3)); | ||
} | ||
@@ -145,3 +146,3 @@ else if (line.startsWith("export type")) { | ||
types.push({ | ||
kind: 'function', | ||
kind: "function", | ||
jsDoc: currentJSDoc, | ||
@@ -151,4 +152,4 @@ type: currentFunction, | ||
start: startLineNumber, | ||
end: lineNumber | ||
} | ||
end: lineNumber, | ||
}, | ||
}); | ||
@@ -168,3 +169,3 @@ currentJSDoc = []; | ||
const packageJson = json5_1.default.parse(strPackage); | ||
const repo = packageJson.homepage.split('#')[0]; | ||
const repo = packageJson.homepage.split("#")[0]; | ||
console.log(`Generating docs for ${packageJson.name} hosted at ${repo}`); | ||
@@ -179,16 +180,19 @@ console.log(`Looking for docs in ${config.include}...`); | ||
const exportedItems = getExports(fileContents); | ||
const docs = exportedItems.map((exported) => { | ||
const docs = exportedItems | ||
.map((exported) => { | ||
return exportToEnglish(repo, fileName, exported); | ||
}).join('\n'); | ||
const fileNameWithoutPath = fileName.split('.')[0] + '.md'; | ||
let additionalPath = ''; | ||
if (fileName.indexOf('/') > -1) { | ||
const split = fileName.split('/'); | ||
additionalPath = split.slice(0, split.length - 1).join('/'); | ||
}) | ||
.join("\n"); | ||
const fileNameWithoutPath = fileName.split(".")[0] + ".md"; | ||
let additionalPath = ""; | ||
if (fileName.indexOf("/") > -1) { | ||
const split = fileName.split("/"); | ||
additionalPath = split.slice(0, split.length - 1).join("/"); | ||
} | ||
try { | ||
await fs_1.promises.mkdir('docs/' + additionalPath, { recursive: true }); | ||
await fs_1.promises.mkdir("docs/" + additionalPath, { | ||
recursive: true, | ||
}); | ||
} | ||
catch (e) { | ||
} | ||
catch (e) { } | ||
await fs_1.promises.writeFile(`docs/${fileNameWithoutPath}`, docs); | ||
@@ -195,0 +199,0 @@ resolve(null); |
{ | ||
"name": "@eeue56/geiriadur", | ||
"version": "0.0.2", | ||
"description": "An Elm-like documentation generator for TypeScript", | ||
"main": "src/geiriadur.ts", | ||
"scripts": { | ||
"build": "tsc -p tsconfig.json" | ||
}, | ||
"bin": { | ||
"geiriadur": "build/geiriadur.js" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/eeue56/geiriadur.git" | ||
}, | ||
"keywords": [ | ||
"elm", | ||
"typescript", | ||
"documentation" | ||
], | ||
"author": "eeue56", | ||
"license": "BSD-3-Clause", | ||
"bugs": { | ||
"url": "https://github.com/eeue56/geiriadur/issues" | ||
}, | ||
"homepage": "https://github.com/eeue56/geiriadur#readme", | ||
"dependencies": { | ||
"@types/node": "^14.14.35", | ||
"fast-glob": "^3.2.5", | ||
"json5": "^2.2.0", | ||
"typescript": "^4.2.3" | ||
} | ||
"name": "@eeue56/geiriadur", | ||
"version": "0.0.3", | ||
"description": "An Elm-like documentation generator for TypeScript", | ||
"main": "src/geiriadur.ts", | ||
"scripts": { | ||
"build": "tsc -p tsconfig.json", | ||
"format": "npx prettier --write ." | ||
}, | ||
"bin": { | ||
"geiriadur": "build/geiriadur.js" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/eeue56/geiriadur.git" | ||
}, | ||
"keywords": [ | ||
"elm", | ||
"typescript", | ||
"documentation" | ||
], | ||
"author": "eeue56", | ||
"license": "BSD-3-Clause", | ||
"bugs": { | ||
"url": "https://github.com/eeue56/geiriadur/issues" | ||
}, | ||
"homepage": "https://github.com/eeue56/geiriadur#readme", | ||
"dependencies": { | ||
"@types/node": "^14.14.35", | ||
"fast-glob": "^3.2.5", | ||
"json5": "^2.2.0", | ||
"typescript": "^4.2.3" | ||
}, | ||
"devDependencies": { | ||
"prettier": "github:eeue56/prettier#feat/spacing-around-square-brackets" | ||
} | ||
} |
# geiriadur | ||
An Elm-style documentation generator for TypeScript. It uses a markdown file to document exposed types and functions, along with their type signature and any jsdoc they may have. There is also a link to the source included. | ||
@@ -9,4 +10,3 @@ | ||
```javascript | ||
export function program<Model, Msg>(program: Program<Model, Msg>) { | ||
} | ||
export function program<Model, Msg>(program: Program<Model, Msg>) {} | ||
``` | ||
@@ -30,5 +30,4 @@ | ||
## Name | ||
Geiriadur means dictionary. An English speaker may pronounce it as "gay-rh-ya-dirh". | ||
Geiriadur means dictionary. An English speaker may pronounce it as "gay-rh-ya-dirh". |
@@ -29,3 +29,3 @@ #!/usr/bin/env ts-node | ||
type ExportedType = { | ||
kind: 'type'; | ||
kind: "type"; | ||
type: string[]; | ||
@@ -36,7 +36,7 @@ jsDoc: string[]; | ||
end: number; | ||
} | ||
} | ||
}; | ||
}; | ||
type ExportedFunction = { | ||
kind: 'function'; | ||
kind: "function"; | ||
type: string[]; | ||
@@ -47,12 +47,12 @@ jsDoc: string[]; | ||
end: number; | ||
} | ||
} | ||
}; | ||
}; | ||
type Export = ExportedType | ExportedFunction | ||
type Export = ExportedType | ExportedFunction; | ||
function exportTitle(exported: Export): string { | ||
const firstLine = exported.type[0] || ''; | ||
const firstLine = exported.type[0] || ""; | ||
switch (exported.kind) { | ||
case 'type': { | ||
case "type": { | ||
const matches = firstLine.match(/export type (.+)/); | ||
@@ -63,5 +63,5 @@ if (matches) { | ||
return '' | ||
return ""; | ||
} | ||
case 'function':{ | ||
case "function": { | ||
const matches = firstLine.match(/export function (.+)/); | ||
@@ -76,3 +76,3 @@ if (matches) { | ||
return '' | ||
return ""; | ||
} | ||
@@ -82,3 +82,7 @@ } | ||
function exportToEnglish(repo: string, filePath: string, exported: Export): string { | ||
function exportToEnglish( | ||
repo: string, | ||
filePath: string, | ||
exported: Export | ||
): string { | ||
const headline = "## " + exportTitle(exported); | ||
@@ -90,8 +94,3 @@ const typeBody = "```javascript\n" + exported.type.join("\n") + "\n```"; | ||
return [ | ||
headline, | ||
typeBody, | ||
comments, | ||
linkToSource | ||
].join("\n"); | ||
return [ headline, typeBody, comments, linkToSource ].join("\n"); | ||
} | ||
@@ -101,29 +100,34 @@ | ||
let isInJSDoc = false; | ||
let currentJSDoc: string[] = []; | ||
let currentJSDoc: string[] = [ ]; | ||
let isInType = false; | ||
let currentType: string[] = []; | ||
let currentType: string[] = [ ]; | ||
let isInFunction = false; | ||
let currentFunction: string[] = []; | ||
let currentFunction: string[] = [ ]; | ||
let startLineNumber = 0; | ||
let types: Export[] = []; | ||
let types: Export[] = [ ]; | ||
const lines = fileContents.split('\n'); | ||
const lines = fileContents.split("\n"); | ||
lines.forEach((line, lineNumber) => { | ||
if (isInJSDoc) { | ||
currentJSDoc.push(line); | ||
if (line.endsWith("*/")) { | ||
isInJSDoc = false; | ||
return; | ||
} | ||
} else if (isInType){ | ||
if (line.startsWith(" *")) { | ||
currentJSDoc.push(line.slice(3)); | ||
} else { | ||
currentJSDoc.push(line); | ||
} | ||
} else if (isInType) { | ||
currentType.push(line); | ||
if (line.length === 0){ | ||
if (line.length === 0) { | ||
isInType = false; | ||
types.push({ | ||
kind: 'type', | ||
kind: "type", | ||
jsDoc: currentJSDoc, | ||
@@ -133,15 +137,15 @@ type: currentType, | ||
start: startLineNumber, | ||
end: lineNumber | ||
} | ||
}) | ||
end: lineNumber, | ||
}, | ||
}); | ||
currentJSDoc = []; | ||
currentType = []; | ||
currentJSDoc = [ ]; | ||
currentType = [ ]; | ||
} | ||
} else if (isInFunction){ | ||
} else if (isInFunction) { | ||
currentFunction.push(line); | ||
} else { | ||
if (line.startsWith("/**")){ | ||
if (line.startsWith("/**")) { | ||
isInJSDoc = true; | ||
currentJSDoc.push(line); | ||
currentJSDoc.push(line.slice(3)); | ||
} else if (line.startsWith("export type")) { | ||
@@ -159,6 +163,6 @@ isInType = true; | ||
if (isInFunction) { | ||
if (line.endsWith("{")){ | ||
if (line.endsWith("{")) { | ||
isInFunction = false; | ||
types.push({ | ||
kind: 'function', | ||
kind: "function", | ||
jsDoc: currentJSDoc, | ||
@@ -168,13 +172,12 @@ type: currentFunction, | ||
start: startLineNumber, | ||
end: lineNumber | ||
} | ||
}) | ||
end: lineNumber, | ||
}, | ||
}); | ||
currentJSDoc = []; | ||
currentFunction = []; | ||
currentJSDoc = [ ]; | ||
currentFunction = [ ]; | ||
} | ||
} | ||
}) | ||
}); | ||
return types; | ||
@@ -190,3 +193,3 @@ } | ||
const packageJson = JSON5.parse(strPackage); | ||
const repo = packageJson.homepage.split('#')[0]; | ||
const repo = packageJson.homepage.split("#")[0]; | ||
@@ -200,3 +203,2 @@ console.log(`Generating docs for ${packageJson.name} hosted at ${repo}`); | ||
await Promise.all( | ||
@@ -207,23 +209,27 @@ files.map(async (fileName) => { | ||
const fileContents = (await fsPromises.readFile(fileName)).toString(); | ||
const fileContents = ( | ||
await fsPromises.readFile(fileName) | ||
).toString(); | ||
const exportedItems = getExports(fileContents); | ||
const docs = exportedItems.map((exported) => { | ||
return exportToEnglish(repo, fileName, exported); | ||
}).join('\n'); | ||
const docs = exportedItems | ||
.map((exported) => { | ||
return exportToEnglish(repo, fileName, exported); | ||
}) | ||
.join("\n"); | ||
const fileNameWithoutPath = fileName.split('.')[0] + '.md'; | ||
const fileNameWithoutPath = fileName.split(".")[0] + ".md"; | ||
let additionalPath = ''; | ||
let additionalPath = ""; | ||
if (fileName.indexOf('/') > -1){ | ||
const split = fileName.split('/'); | ||
additionalPath = split.slice(0, split.length - 1).join('/'); | ||
if (fileName.indexOf("/") > -1) { | ||
const split = fileName.split("/"); | ||
additionalPath = split.slice(0, split.length - 1).join("/"); | ||
} | ||
try { | ||
await fsPromises.mkdir('docs/' + additionalPath, { recursive: true }); | ||
} catch (e) { | ||
} | ||
await fsPromises.mkdir("docs/" + additionalPath, { | ||
recursive: true, | ||
}); | ||
} catch (e) {} | ||
await fsPromises.writeFile(`docs/${fileNameWithoutPath}`, docs); | ||
@@ -230,0 +236,0 @@ |
23696
9
459
1