Skip to content

Commit

Permalink
feat: custom link formatter (#366)
Browse files Browse the repository at this point in the history
Option to provide a custom link formatter to control how markdown links are rendered.
  • Loading branch information
iliapolo authored Jul 13, 2021
1 parent 05c2d7e commit 1a013a4
Show file tree
Hide file tree
Showing 32 changed files with 2,695 additions and 79 deletions.
11 changes: 9 additions & 2 deletions src/docgen/transpile/transpile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,11 @@ export interface TranspiledTypeReferenceToStringOptions {
/**
* Type formatter.
*/
typeFormatter?: (t: TranspiledType) => string;
typeFormatter?: (type: TranspiledType) => string;
/**
* String formatter.
*/
stringFormatter?: (formatter: string) => string;
stringFormatter?: (typeName: string) => string;
}

/**
Expand Down Expand Up @@ -421,6 +421,13 @@ export interface Transpile {
*/
readonly language: Language;

/**
* How links to types should be formatted.
*
* @default '#{fqn}'
*/
readonly linkFormatter?: (type: TranspiledType) => string;

/**
* Transpile a module like object (Assembly | Submodule)
*/
Expand Down
11 changes: 6 additions & 5 deletions src/docgen/view/api-reference.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as reflect from 'jsii-reflect';
import { Markdown } from '../render/markdown';
import { Transpile } from '../transpile/transpile';
import { Transpile, TranspiledType } from '../transpile/transpile';
import { Classes } from './classes';
import { Constructs } from './constructs';
import { Enums } from './enums';
Expand All @@ -19,6 +19,7 @@ export class ApiReference {
constructor(
transpile: Transpile,
assembly: reflect.Assembly,
linkFormatter: (type: TranspiledType) => string,
submodule?: reflect.Submodule,
) {
const classes = this.sortByName(
Expand All @@ -29,10 +30,10 @@ export class ApiReference {
);
const enums = this.sortByName(submodule ? submodule.enums : assembly.enums);

this.constructs = new Constructs(transpile, classes);
this.classes = new Classes(transpile, classes);
this.structs = new Structs(transpile, interfaces);
this.interfaces = new Interfaces(transpile, interfaces);
this.constructs = new Constructs(transpile, classes, linkFormatter);
this.classes = new Classes(transpile, classes, linkFormatter);
this.structs = new Structs(transpile, interfaces, linkFormatter);
this.interfaces = new Interfaces(transpile, interfaces, linkFormatter);
this.enums = new Enums(transpile, enums);
}

Expand Down
15 changes: 8 additions & 7 deletions src/docgen/view/class.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as reflect from 'jsii-reflect';
import { Markdown } from '../render/markdown';
import { Transpile, TranspiledClass } from '../transpile/transpile';
import { Transpile, TranspiledClass, TranspiledType } from '../transpile/transpile';
import { Constants } from './constants';
import { Initializer } from './initializer';
import { InstanceMethods } from './instance-methods';
Expand Down Expand Up @@ -31,14 +31,15 @@ export class Class {
constructor(
private readonly transpile: Transpile,
private readonly klass: reflect.ClassType,
private readonly linkFormatter: (type: TranspiledType) => string,
) {
if (klass.initializer) {
this.initializer = new Initializer(transpile, klass.initializer);
this.initializer = new Initializer(transpile, klass.initializer, linkFormatter);
}
this.instanceMethods = new InstanceMethods(transpile, klass.ownMethods);
this.staticFunctions = new StaticFunctions(transpile, klass.ownMethods);
this.constants = new Constants(transpile, klass.ownProperties);
this.properties = new Properties(transpile, klass.ownProperties);
this.instanceMethods = new InstanceMethods(transpile, klass.ownMethods, linkFormatter);
this.staticFunctions = new StaticFunctions(transpile, klass.ownMethods, linkFormatter);
this.constants = new Constants(transpile, klass.ownProperties, linkFormatter);
this.properties = new Properties(transpile, klass.ownProperties, linkFormatter);
this.transpiled = transpile.class(klass);
}

Expand All @@ -52,7 +53,7 @@ export class Class {
const ifaces = [];
for (const iface of this.klass.interfaces) {
const transpiled = this.transpile.type(iface);
ifaces.push(`[${Markdown.pre(transpiled.fqn)}](#${transpiled.fqn})`);
ifaces.push(`[${Markdown.pre(transpiled.fqn)}](${this.linkFormatter(transpiled)})`);
}
md.bullet(`${Markdown.italic('Implements:')} ${ifaces.join(', ')}`);
md.lines('');
Expand Down
6 changes: 3 additions & 3 deletions src/docgen/view/classes.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import * as reflect from 'jsii-reflect';
import { Markdown } from '../render/markdown';
import { Transpile } from '../transpile/transpile';
import { Transpile, TranspiledType } from '../transpile/transpile';
import { Class } from './class';

export class Classes {
private readonly classes: Class[];
constructor(transpile: Transpile, classes: reflect.ClassType[]) {
constructor(transpile: Transpile, classes: reflect.ClassType[], linkFormatter: (type: TranspiledType) => string) {
this.classes = classes
.filter((c) => !Class.isConstruct(c))
.map((c) => new Class(transpile, c));
.map((c) => new Class(transpile, c, linkFormatter));
}

public render(): Markdown {
Expand Down
6 changes: 3 additions & 3 deletions src/docgen/view/constant.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import * as reflect from 'jsii-reflect';
import { Markdown } from '../render/markdown';
import { Transpile } from '../transpile/transpile';
import { Transpile, TranspiledType } from '../transpile/transpile';
import { Property } from './property';

export class Constant {
private readonly constant: Property;
constructor(transpile: Transpile, property: reflect.Property) {
this.constant = new Property(transpile, property);
constructor(transpile: Transpile, property: reflect.Property, linkFormatter: (type: TranspiledType) => string) {
this.constant = new Property(transpile, property, linkFormatter);
}
public render(): Markdown {
return this.constant.render();
Expand Down
6 changes: 3 additions & 3 deletions src/docgen/view/constants.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import * as reflect from 'jsii-reflect';
import { Markdown } from '../render/markdown';
import { Transpile } from '../transpile/transpile';
import { Transpile, TranspiledType } from '../transpile/transpile';
import { Constant } from './constant';

export class Constants {
private readonly constants: Constant[];
constructor(transpile: Transpile, properties: reflect.Property[]) {
constructor(transpile: Transpile, properties: reflect.Property[], linkFormatter: (type: TranspiledType) => string) {
this.constants = properties
.filter((p) => !p.protected && p.const)
.map((p) => new Constant(transpile, p));
.map((p) => new Constant(transpile, p, linkFormatter));
}

public render(): Markdown {
Expand Down
6 changes: 3 additions & 3 deletions src/docgen/view/construct.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import * as reflect from 'jsii-reflect';
import { Markdown } from '../render/markdown';
import { Transpile } from '../transpile/transpile';
import { Transpile, TranspiledType } from '../transpile/transpile';
import { Class } from './class';

export class Construct {
private readonly construct: Class;
constructor(transpile: Transpile, klass: reflect.ClassType) {
this.construct = new Class(transpile, klass);
constructor(transpile: Transpile, klass: reflect.ClassType, linkFormatter: (type: TranspiledType) => string) {
this.construct = new Class(transpile, klass, linkFormatter);
}
public render(): Markdown {
return this.construct.render();
Expand Down
6 changes: 3 additions & 3 deletions src/docgen/view/constructs.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import * as reflect from 'jsii-reflect';
import { Markdown } from '../render/markdown';
import { Transpile } from '../transpile/transpile';
import { Transpile, TranspiledType } from '../transpile/transpile';
import { Class } from './class';
import { Construct } from './construct';

export class Constructs {
private readonly constructs: Construct[];
constructor(transpile: Transpile, classes: reflect.ClassType[]) {
constructor(transpile: Transpile, classes: reflect.ClassType[], linkFormatter: (type: TranspiledType) => string) {
this.constructs = classes
.filter((c) => Class.isConstruct(c))
.map((c) => new Construct(transpile, c));
.map((c) => new Construct(transpile, c, linkFormatter));
}

public render(): Markdown {
Expand Down
13 changes: 10 additions & 3 deletions src/docgen/view/documentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { TargetLanguage } from 'jsii-rosetta';
import { transliterateAssembly } from 'jsii-rosetta/lib/commands/transliterate';
import { Markdown } from '../render/markdown';
import { PythonTranspile } from '../transpile/python';
import { Transpile, Language } from '../transpile/transpile';
import { Transpile, Language, TranspiledType } from '../transpile/transpile';
import { TypeScriptTranspile } from '../transpile/typescript';
import { ApiReference } from './api-reference';
import { Readme } from './readme';
Expand Down Expand Up @@ -39,6 +39,13 @@ export interface RenderOptions {
*/
readonly submodule?: string;

/**
* How should links to types be rendered.
*
* @default '#{fqn}'
*/
readonly linkFormatter?: (type: TranspiledType) => string;

}

/**
Expand Down Expand Up @@ -199,7 +206,7 @@ export class Documentation {
}

private constructor(
private readonly assembly: reflect.Assembly,
public readonly assembly: reflect.Assembly,
private readonly transpile: Transpile,
) {
}
Expand All @@ -217,7 +224,7 @@ export class Documentation {
}

if (options?.apiReference ?? true) {
const apiReference = new ApiReference(this.transpile, this.assembly, submodule);
const apiReference = new ApiReference(this.transpile, this.assembly, options?.linkFormatter ?? ((t: TranspiledType) => `#${t.fqn}`), submodule);
documentation.section(apiReference.render());
}

Expand Down
5 changes: 3 additions & 2 deletions src/docgen/view/initializer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as reflect from 'jsii-reflect';
import { Markdown } from '../render/markdown';
import { Transpile, TranspiledCallable } from '../transpile/transpile';
import { Transpile, TranspiledCallable, TranspiledType } from '../transpile/transpile';
import { Parameter } from './parameter';

export class Initializer {
Expand All @@ -9,10 +9,11 @@ export class Initializer {
constructor(
private readonly transpile: Transpile,
initializer: reflect.Initializer,
linkFormatter: (type: TranspiledType) => string,
) {
this.transpiled = transpile.callable(initializer);
this.parameters = this.transpiled.parameters.map(
(p) => new Parameter(this.transpile, p),
(p) => new Parameter(this.transpile, p, linkFormatter),
);
}

Expand Down
5 changes: 3 additions & 2 deletions src/docgen/view/instance-method.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as reflect from 'jsii-reflect';
import { Markdown } from '../render/markdown';
import { Transpile, TranspiledCallable } from '../transpile/transpile';
import { Transpile, TranspiledCallable, TranspiledType } from '../transpile/transpile';
import { Parameter } from './parameter';

export class InstanceMethod {
Expand All @@ -9,10 +9,11 @@ export class InstanceMethod {
constructor(
private readonly transpile: Transpile,
private readonly method: reflect.Method,
linkFormatter: (type: TranspiledType) => string,
) {
this.transpiled = transpile.callable(method);
this.parameters = this.transpiled.parameters.map(
(p) => new Parameter(this.transpile, p),
(p) => new Parameter(this.transpile, p, linkFormatter),
);
}

Expand Down
6 changes: 3 additions & 3 deletions src/docgen/view/instance-methods.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import * as reflect from 'jsii-reflect';
import { Markdown } from '../render/markdown';
import { Transpile } from '../transpile/transpile';
import { Transpile, TranspiledType } from '../transpile/transpile';
import { InstanceMethod } from './instance-method';

export class InstanceMethods {
private readonly instanceMethods: InstanceMethod[];
constructor(transpile: Transpile, methods: reflect.Method[]) {
constructor(transpile: Transpile, methods: reflect.Method[], linkFormatter: (type: TranspiledType) => string) {
this.instanceMethods = methods
.filter((m) => !m.protected && !m.static)
.map((m) => new InstanceMethod(transpile, m));
.map((m) => new InstanceMethod(transpile, m, linkFormatter));
}

public render(): Markdown {
Expand Down
11 changes: 6 additions & 5 deletions src/docgen/view/interface.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as reflect from 'jsii-reflect';
import { Markdown } from '../render/markdown';
import { Transpile, TranspiledInterface } from '../transpile/transpile';
import { Transpile, TranspiledInterface, TranspiledType } from '../transpile/transpile';
import { InstanceMethods } from './instance-methods';
import { Properties } from './properties';

Expand All @@ -17,10 +17,11 @@ export class Interface {
constructor(
private readonly transpile: Transpile,
private readonly iface: reflect.InterfaceType,
private readonly linkFormatter: (type: TranspiledType) => string,
) {
this.transpiled = transpile.interface(iface);
this.instanceMethods = new InstanceMethods(transpile, iface.ownMethods);
this.properties = new Properties(transpile, iface.allProperties);
this.instanceMethods = new InstanceMethods(transpile, iface.ownMethods, linkFormatter);
this.properties = new Properties(transpile, iface.allProperties, linkFormatter);
}

public render(): Markdown {
Expand All @@ -33,7 +34,7 @@ export class Interface {
const ifaces = [];
for (const iface of this.iface.interfaces) {
const transpiled = this.transpile.type(iface);
ifaces.push(`[${Markdown.pre(transpiled.fqn)}](#${transpiled.fqn})`);
ifaces.push(`[${Markdown.pre(transpiled.fqn)}](${this.linkFormatter(transpiled)})`);
}
md.bullet(`${Markdown.italic('Extends:')} ${ifaces.join(', ')}`);
md.lines('');
Expand All @@ -43,7 +44,7 @@ export class Interface {
const impls = [];
for (const impl of this.iface.allImplementations) {
const transpiled = this.transpile.type(impl);
impls.push(`[${Markdown.pre(transpiled.fqn)}](#${transpiled.fqn})`);
impls.push(`[${Markdown.pre(transpiled.fqn)}](${this.linkFormatter(transpiled)})`);
}
md.bullet(`${Markdown.italic('Implemented By:')} ${impls.join(', ')}`);
md.lines('');
Expand Down
6 changes: 3 additions & 3 deletions src/docgen/view/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import * as reflect from 'jsii-reflect';
import { Markdown } from '../render/markdown';
import { Transpile } from '../transpile/transpile';
import { Transpile, TranspiledType } from '../transpile/transpile';
import { Interface } from './interface';

export class Interfaces {
private readonly interfaces: Interface[];

constructor(transpile: Transpile, interfaces: reflect.InterfaceType[]) {
constructor(transpile: Transpile, interfaces: reflect.InterfaceType[], linkFormatter: (type: TranspiledType) => string) {
this.interfaces = interfaces
.filter((i) => !Interface.isStruct(i))
.map((i) => new Interface(transpile, i));
.map((i) => new Interface(transpile, i, linkFormatter));
}
public render(): Markdown {
if (this.interfaces.length === 0) {
Expand Down
5 changes: 3 additions & 2 deletions src/docgen/view/parameter.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import * as reflect from 'jsii-reflect';
import { Markdown } from '../render/markdown';
import { Transpile, TranspiledParameter } from '../transpile/transpile';
import { Transpile, TranspiledParameter, TranspiledType } from '../transpile/transpile';

export class Parameter {
private readonly transpiled: TranspiledParameter;
constructor(
transpile: Transpile,
private readonly parameter: reflect.Parameter,
private readonly linkFormatter: (type: TranspiledType) => string,
) {
this.transpiled = transpile.parameter(parameter);
}
Expand Down Expand Up @@ -35,7 +36,7 @@ export class Parameter {

const metadata: any = {
Type: this.transpiled.typeReference.toString({
typeFormatter: (t) => `[${Markdown.pre(t.fqn)}](#${t.fqn})`,
typeFormatter: (t) => `[${Markdown.pre(t.fqn)}](${this.linkFormatter(t)})`,
stringFormatter: Markdown.pre,
}),
};
Expand Down
6 changes: 3 additions & 3 deletions src/docgen/view/properties.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import * as reflect from 'jsii-reflect';
import { Markdown } from '../render/markdown';
import { Transpile } from '../transpile/transpile';
import { Transpile, TranspiledType } from '../transpile/transpile';
import { Property } from './property';

export class Properties {
private readonly properties: Property[];
constructor(transpile: Transpile, properties: reflect.Property[]) {
constructor(transpile: Transpile, properties: reflect.Property[], linkFormatter: (type: TranspiledType) => string) {
this.properties = properties
.filter((p) => !p.protected && !p.const)
.map((p) => new Property(transpile, p));
.map((p) => new Property(transpile, p, linkFormatter));
}

public render(): Markdown {
Expand Down
Loading

0 comments on commit 1a013a4

Please sign in to comment.