ts2md
v0.2.5
Published
Simple Typescript Documentation Generator to GitHub Compatible MarkDown
Downloads
475
Maintainers
Readme
ts2md
Simple Typescript Documentation in README.md
Generator
The focus of this generator is single output file, low effort, low maintenance, high accuracy API documentation generation.
Many JSDoc tags are ignored as not relevant to this objective. Some custom tags have been added.
For a full featured, fine grain typescript documentation generator see TypeDoc
A good starting point in the API doc is the ts2md function and then the TypescriptToMarkDown class.
Supported JSDoc Tags
The following JSDoc tags are supported:
| Tag | Description | |---|---| | @example | Adds example as code block or comments and embedded code block(s). | | @param | Adds comment for function or method parameter. | | @private | Hides an otherwise accessible documentation item. | | @privateinitializer | Hides property initializer from documentation typescript. | | @property | Adds comment for class or interface property parameter in parent's JSDoc comment. | | @publicbody | Overrides the normal hidding of method and function bodies. | | @returns | Adds comment for function or method return value. | | @throws | Adds thrown error comment to function or method. |
Installation
npm i -D ts2md
Setup
After installation, use the following command to run markdown generation:
npx ts2md
Which will also remind you to add merge anchors in your README.md
file:
<!--#region ts2md-api-merged-here-->
<!--#endregion ts2md-api-merged-here-->
The anchors must not be indented where you wish to merge the generated documentation.
You may also want to add a script to package.json
as a reminder and to support
automatically updating documentation before publishing your package:
"scripts": {
"build:readme": "npx ts2md",
"prepublish": "npm run build && npx ts2md",
}
A good starting point in the API doc is the ts2md function and then the Ts2Md class.
API
Links: API, Interfaces, Classes, Functions
Interfaces
| | | --- | | DocGenSupportApi | | JSDocInfo | | Ts2MdOptions |
Links: API, Interfaces, Classes, Functions
Interface: DocGenSupportApi
export interface DocGenSupportApi {
printer: ts.Printer;
nothingPrivate: boolean;
headingLevelMd(relativeLevel: number): string;
}
Links: API, Interfaces, Classes, Functions
Interface: JSDocInfo
Parsed JSDoc info associated with a documentation item
export interface JSDocInfo {
isPrivate: boolean;
publicBody: boolean;
privateInitializer: boolean;
comments: string[];
params: ts.JSDocParameterTag[];
returns: ts.JSDocReturnTag[];
throws: ts.JSDocThrowsTag[];
examples: string[];
properties: Record<string, string>;
tags: ts.Node[];
other: ts.Node[];
}
Property comments
JSDoc nodes with ['comment'] strings not otherwise tagged with a recognized tag.
comments: string[]
Property examples
The
examples: string[]
Example
tag comments. Comments without code blocks are assumed to be typescript codeblocks
Property isPrivate
true if has '@private' tag
isPrivate: boolean
Property other
JSDoc nodes not parsed into other properties
other: ts.Node[]
Property params
The
params: ts.JSDocParameterTag[]
Property privateInitializer
true if has '@privateinitializer' tag
privateInitializer: boolean
Property properties
The
properties: Record<string, string>
Property publicBody
true if has '@publicbody' tag
publicBody: boolean
Property returns
JSDoc nodes tagged with '@returns'
returns: ts.JSDocReturnTag[]
Property tags
JSDoc tags not parsed into other properties
tags: ts.Node[]
Property throws
JSDoc nodes tagged with '@throws'
throws: ts.JSDocThrowsTag[]
Links: API, Interfaces, Classes, Functions
Interface: Ts2MdOptions
Options for the Ts2Md
class which generates Typescript documentation.
export interface Ts2MdOptions {
inputFilename: string;
firstHeadingLevel: 1 | 2 | 3;
noTitle: boolean;
outputFilename?: string;
outputReplace: boolean;
readmeMerge: boolean;
nothingPrivate?: boolean;
filenameSubString?: string;
}
Property filenameSubString
If specified, only symbols defined in files with this value as a substring are included in generated markdown.
'/' must be used as the folder separator.
filenameSubString?: string
Property firstHeadingLevel
The heading level for the first generated heading.
firstHeadingLevel: 1 | 2 | 3
Property inputFilename
Primary typescript source file, default is ./src/index.ts
inputFilename: string
Property noTitle
Set to true if generated markdown will be merged into a file that already includes a containing header.
noTitle: boolean
Property nothingPrivate
If true, overrides private typescript keywords and jsdoc tags.
CAUTION: This setting is inappropriate for published documentation ;-)
nothingPrivate?: boolean
Property outputFilename
If valid, a copy of the generated markdown documentation will be saved to this file.
outputFilename?: string
Property outputReplace
Set to true to attempt to delete an existing output file before writing new output.
outputReplace: boolean
Property readmeMerge
Set to true if the generated output should be merged into README.md
Currently README.md must exist at ./README.md
and must contain the following merge start and merge end anchors:
<!--#region ts2md-api-merged-here-->
<!--#endregion ts2md-api-merged-here-->
The anchors must not be indented.
readmeMerge: boolean
Links: API, Interfaces, Classes, Functions
Classes
| | | | --- | --- | | DocBase | DocMethod | | DocClass | DocMethodSignature | | DocConstructor | DocProperty | | DocEnum | DocPropertySignature | | DocEnumMember | DocType | | DocFunction | DocVariable | | DocInterface | TypescriptToMarkdown | | DocItem | |
Links: API, Interfaces, Classes, Functions
Class: DocBase
export abstract class DocBase<T extends ts.Node> {
docItems: DocItem<T>[] = [];
constructor(public sup: DocGenSupportApi, public label: string, public labelPlural: string, public detailsLabel = "Details")
abstract getName(item: T, sf: ts.SourceFile): string;
abstract filterItem(s: ts.Node): T[];
tryAddItem(s: ts.Node, sf: ts.SourceFile, parent?: DocItem<ts.Node>)
extractMemberDocs(docItem: DocItem<ts.Node>): DocBase<ts.Node>[]
isNotPrivate(item: ts.Node): boolean
findTs(findInTs: string, targetTs: string): {
pos: number;
len: number;
}
removeTs(fromTs: string, removeTs: string, withSemi?: boolean): string
toSeeAlso(docItem: DocItem<T>, mdts: string, mdLinks: Record<string, string>, tight?: boolean): string
toTsMarkDown(docItem: DocItem<T>, mdLinks: Record<string, string>, tight?: boolean): string
toMarkDown(docItem: DocItem<T>, mdLinks: Record<string, string>): string
toMarkDownTs(docItem: DocItem<T>): string
toMarkDownDetails(docItem: DocItem<T>, mdLinks: Record<string, string>): string
toMarkDownRefLink(docItem: DocItem<T>): string
isExportedDeclaration(item: ts.Declaration): boolean
argumentsDetails(docItem: DocItem<T>): string
returnsDetails(docItem: DocItem<T>): string
throwsDetails(docItem: DocItem<T>): string
examplesDetails(docItem: DocItem<T>): string
commentsDetails(docItem: DocItem<T>): string
}
See also: DocGenSupportApi, DocItem
Method toMarkDown
Base class implementation of markdown generation for a top level typescript AST node (DocItem
).
Adds relative level 3 heading with label
and docItem.name
Adds the nodes simple (no @
tag) JSDoc nodes under relative level 4 'Description` heading
Calls the toMarkDownTs
override to add the typescript syntax code block for this node.
Calls the toMarkDownDtails
override to add any details markdown for this node.
toMarkDown(docItem: DocItem<T>, mdLinks: Record<string, string>): string
See also: DocItem
Returns
the generated markdown for this DocItem
Method toMarkDownDetails
Generate the 'Details' markdown (including ) for this node.
Base class implementation returns an empty string.
toMarkDownDetails(docItem: DocItem<T>, mdLinks: Record<string, string>): string
See also: DocItem
Method toMarkDownTs
Generate the typescript syntax for this node to be inserted in a typescript syntax code block in generated markdown.
Base class implementation uses the typescript compiler printer on DocItem
AST node item
.
CAUTION: This adds ALL the source code for this item to the generated markdown. Override SHOULD implement appropriate ommission control policies.
toMarkDownTs(docItem: DocItem<T>): string
See also: DocItem
Returns
typescript syntax to be added within a typescript syntax code block for this DocItem
Links: API, Interfaces, Classes, Functions
Class: DocClass
export class DocClass extends DocBase<ts.ClassDeclaration> {
constructor(sup: DocGenSupportApi)
override getName(item: ts.ClassDeclaration): string
override filterItem(item: ts.Node): ts.ClassDeclaration[]
override extractMemberDocs(docItem: DocItem<ts.ClassDeclaration>): DocBase<ts.Node>[]
override toMarkDownTs(docItem: DocItem<ts.ClassDeclaration>): string
override toMarkDownDetails(docItem: DocItem<ts.ClassDeclaration>, mdLinks: Record<string, string>): string
}
See also: DocBase, DocGenSupportApi, DocItem
Links: API, Interfaces, Classes, Functions
Class: DocConstructor
export class DocConstructor extends DocBase<ts.ConstructorDeclaration> {
constructor(sup: DocGenSupportApi)
override getName(item: ts.ConstructorDeclaration): string
override filterItem(item: ts.Node): ts.ConstructorDeclaration[]
override toMarkDownTs(docItem: DocItem<ts.ConstructorDeclaration>): string
override toMarkDownDetails(docItem: DocItem<ts.ConstructorDeclaration>, mdLinks: Record<string, string>): string
}
See also: DocBase, DocGenSupportApi, DocItem
Links: API, Interfaces, Classes, Functions
Class: DocEnum
export class DocEnum extends DocBase<ts.EnumDeclaration> {
constructor(sup: DocGenSupportApi)
override getName(item: ts.EnumDeclaration): string
override filterItem(item: ts.Node): ts.EnumDeclaration[]
override extractMemberDocs(docItem: DocItem<ts.EnumDeclaration>): DocBase<ts.Node>[]
override toMarkDownDetails(docItem: DocItem<ts.EnumDeclaration>, mdLinks: Record<string, string>): string
}
See also: DocBase, DocGenSupportApi, DocItem
Links: API, Interfaces, Classes, Functions
Class: DocEnumMember
export class DocEnumMember extends DocBase<ts.EnumMember> {
constructor(sup: DocGenSupportApi)
override getName(item: ts.EnumMember): string
override filterItem(item: ts.Node): ts.EnumMember[]
override toMarkDownDetails(docItem: DocItem<ts.EnumMember>, mdLinks: Record<string, string>): string
}
See also: DocBase, DocGenSupportApi, DocItem
Links: API, Interfaces, Classes, Functions
Class: DocFunction
export class DocFunction extends DocBase<ts.FunctionDeclaration> {
constructor(sup: DocGenSupportApi)
override getName(item: ts.FunctionDeclaration): string
override filterItem(item: ts.Node): ts.FunctionDeclaration[]
override toMarkDownTs(docItem: DocItem<ts.FunctionDeclaration>): string
override toMarkDownDetails(docItem: DocItem<ts.FunctionDeclaration>, mdLinks: Record<string, string>): string
}
See also: DocBase, DocGenSupportApi, DocItem
Links: API, Interfaces, Classes, Functions
Class: DocInterface
export class DocInterface extends DocBase<ts.InterfaceDeclaration> {
constructor(sup: DocGenSupportApi)
override getName(item: ts.InterfaceDeclaration): string
override filterItem(item: ts.Node): ts.InterfaceDeclaration[]
override extractMemberDocs(docItem: DocItem<ts.InterfaceDeclaration>): DocBase<ts.Node>[]
override toMarkDownDetails(docItem: DocItem<ts.InterfaceDeclaration>, mdLinks: Record<string, string>): string
}
See also: DocBase, DocGenSupportApi, DocItem
Links: API, Interfaces, Classes, Functions
Class: DocItem
Wrapper for a Typescript Node
of a specific derived type,
which is of interest for documentation generation.
export class DocItem<T extends ts.Node> {
jsDoc: JSDocInfo;
memberDocs: DocBase<ts.Node>[] = [];
constructor(public item: T, public name: string, public sf: ts.SourceFile, public parent?: DocItem<ts.Node>)
}
Constructor
This is really here just for demonstration / testing purposes...
constructor(public item: T, public name: string, public sf: ts.SourceFile, public parent?: DocItem<ts.Node>)
See also: DocItem
Argument Details
- item
- The typescript Node for this doc item.
- name
- The name for this doc item.
- sf
- The source file which defined this item.
Property jsDoc
Parsed JSDoc information for this item
jsDoc: JSDocInfo
See also: JSDocInfo
Property memberDocs
Subsidiary documentation nodes when the node has members which are themselves represented as documentation nodes.
memberDocs: DocBase<ts.Node>[] = []
See also: DocBase
Links: API, Interfaces, Classes, Functions
Class: DocMethod
export class DocMethod extends DocBase<ts.MethodDeclaration> {
constructor(sup: DocGenSupportApi)
override getName(item: ts.MethodDeclaration): string
override filterItem(item: ts.Node): ts.MethodDeclaration[]
override toMarkDownTs(docItem: DocItem<ts.MethodDeclaration>): string
override toMarkDownDetails(docItem: DocItem<ts.MethodDeclaration>, mdLinks: Record<string, string>): string
}
See also: DocBase, DocGenSupportApi, DocItem
Links: API, Interfaces, Classes, Functions
Class: DocMethodSignature
export class DocMethodSignature extends DocBase<ts.MethodSignature> {
constructor(sup: DocGenSupportApi)
override getName(item: ts.MethodSignature): string
override filterItem(item: ts.Node): ts.MethodSignature[]
override toMarkDownTs(docItem: DocItem<ts.MethodSignature>): string
override toMarkDownDetails(docItem: DocItem<ts.MethodSignature>, mdLinks: Record<string, string>): string
}
See also: DocBase, DocGenSupportApi, DocItem
Links: API, Interfaces, Classes, Functions
Class: DocProperty
export class DocProperty extends DocBase<ts.PropertyDeclaration> {
constructor(sup: DocGenSupportApi)
override getName(item: ts.PropertyDeclaration): string
override filterItem(item: ts.Node): ts.PropertyDeclaration[]
override toMarkDownDetails(docItem: DocItem<ts.PropertyDeclaration>, mdLinks: Record<string, string>): string
}
See also: DocBase, DocGenSupportApi, DocItem
Links: API, Interfaces, Classes, Functions
Class: DocPropertySignature
export class DocPropertySignature extends DocBase<ts.PropertySignature> {
constructor(sup: DocGenSupportApi)
override getName(item: ts.PropertySignature): string
override filterItem(item: ts.Node): ts.PropertySignature[]
override toMarkDownDetails(docItem: DocItem<ts.PropertySignature>, mdLinks: Record<string, string>): string
}
See also: DocBase, DocGenSupportApi, DocItem
Links: API, Interfaces, Classes, Functions
Class: DocType
export class DocType extends DocBase<ts.TypeAliasDeclaration> {
constructor(sup: DocGenSupportApi)
override getName(item: ts.TypeAliasDeclaration): string
override filterItem(item: ts.Node): ts.TypeAliasDeclaration[]
}
See also: DocBase, DocGenSupportApi
Links: API, Interfaces, Classes, Functions
Class: DocVariable
export class DocVariable extends DocBase<ts.VariableDeclaration> {
constructor(sup: DocGenSupportApi)
override getName(item: ts.VariableDeclaration, sf: ts.SourceFile): string
override filterItem(item: ts.Node): ts.VariableDeclaration[]
}
See also: DocBase, DocGenSupportApi
Links: API, Interfaces, Classes, Functions
Class: TypescriptToMarkdown
Uses the Typescript compiler to parse source tree given a top level source file such as index.ts
.
Extract the exported API interfaces, classes, types, functions and variables.
Generate GitHub friendly MarkDown documentation for the extracted API leveraging TypeScript type information and merging JSDoc style documentation comments.
The following JSDoc tags are supported:
@example
Adds example as code block or comments and embedded code block(s).
@param
Adds comment for function or method parameter.
@private
Hides an otherwise accessible documentation item.
@privateinitializer
Hides property initializer from documentation typescript.
@property
Adds comment for class or interface property parameter in parent's JSDoc comment.
@publicbody
Overrides the normal hidding of method and function bodies.
@returns
Adds comment for function or method return value.
@throws
Adds thrown error comment to function or method.
export class TypescriptToMarkdown implements DocGenSupportApi {
filePath: string;
fileName: string;
markDown?: string;
outputPath?: string;
constructor(public options: Ts2MdOptions)
run(): void
}
See also: DocGenSupportApi, Ts2MdOptions
Constructor
Construct a new instance configured for run
method to be called next.
constructor(public options: Ts2MdOptions)
See also: Ts2MdOptions
Argument Details
- options
- Must be provided. inputFilename defaults to
./src/index.ts
- Must be provided. inputFilename defaults to
Property fileName
The top level input Typescript file's filename without path
fileName: string
Property filePath
The top level input Typescript file's filename with full path.
filePath: string
Property markDown
The generated documentation as markdown string
markDown?: string
Property outputPath
The file path to which markDown
was written.
outputPath?: string
Method run
Generates the documentation markdown and write's it to output file and/or merges it to README.md
run(): void
Links: API, Interfaces, Classes, Functions
Functions
| | | --- | | mdMerge | | ts2md |
Links: API, Interfaces, Classes, Functions
Function: mdMerge
Quick and dirty README.md merge function.
The anchors must not be indented and must exactly match:
<!--#region ts2md-api-merged-here-->
<!--#endregion ts2md-api-merged-here-->
export function mdMerge(md: string)
Argument Details
- md
- The markdown to insert between the start and end anchors.
Links: API, Interfaces, Classes, Functions
Function: ts2md
Generate Typescript documentation and merge into README.md
Attempts to validate options, constructs an instance of Ts2Md with those options, and runs the generation method.
Function argument is used if provided.
Looks for
./ts2md.json
Default options.
Default options are:
{
"inputFilename": "./src/index.ts",
"outputFilename": "./apiDoc.md",
"firstHeadingLevel": 2,
"noTitle": true,
"outputReplace": true,
"readmeMerge": true
}
- Finally examines command line arguments which are treated as overrides of the options determined by steps 1, 2, 3. Command line arguments can be provided as either:
--inputFilename ../index.ts
or
--inputFilename=../index.ts
export function ts2md(options?: Ts2MdOptions): void {
if (!options) {
try {
const configPath = path.resolve("./ts2md.json");
const json = fs.readFileSync(configPath, { encoding: "utf8" });
options = <Ts2MdOptions>JSON.parse(json);
}
catch { }
}
options ||= {
inputFilename: "./src/index.ts",
outputFilename: "",
firstHeadingLevel: 2,
noTitle: true,
outputReplace: true,
readmeMerge: true,
};
const args = process.argv;
for (let i = 0; i < args.length; i++) {
const arg = args[i];
if (!arg.startsWith("--"))
continue;
const e = arg.indexOf("=");
let a = "", v = "";
if (e > -1) {
a = arg.slice(2, e);
v = arg.slice(e + 1);
}
else {
a = arg.slice(2);
v = args[++i];
}
switch (a) {
case "inputFilename":
options.inputFilename = v;
break;
case "outputFilename":
options.outputFilename = v;
break;
case "firstHeadingLevel":
options.firstHeadingLevel = <1 | 2 | 3>Number(v);
break;
case "noTitle":
options.noTitle = (v === "true");
break;
case "outputReplace":
options.outputReplace = (v === "true");
break;
case "readmeMerge":
options.readmeMerge = (v === "true");
break;
case "nothingPrivate":
options.nothingPrivate = (v === "true");
break;
case "filenameSubString":
options.filenameSubString = v;
break;
default: break;
}
}
console.log("ts2md(", options, ")");
new TypescriptToMarkdown(options).run();
}
See also: Ts2MdOptions, TypescriptToMarkdown
Argument Details
- options
- Optional options to control markdown generation.
Links: API, Interfaces, Classes, Functions
License
The license for the code in this repository is the Open BSV License.