src/markdown/structure-renderer.ts (93 lines of code) (raw):
import * as cm from 'commonmark';
import { CommonMarkRenderer, prefixLines, RendererContext } from './markdown';
/**
* A renderer that will render a CommonMark tree to show its structure
*/
export class StructureRenderer implements CommonMarkRenderer {
public block_quote(node: cm.Node, context: RendererContext) {
return this.handle('block_quote', node, context);
}
public code(node: cm.Node, context: RendererContext) {
return this.handle('code', node, context);
}
public code_block(node: cm.Node, context: RendererContext) {
return this.handle('code_block', node, context);
}
public text(node: cm.Node, context: RendererContext) {
return this.handle('text', node, context);
}
public softbreak(node: cm.Node, context: RendererContext) {
return this.handle('softbreak', node, context);
}
public linebreak(node: cm.Node, context: RendererContext) {
return this.handle('linebreak', node, context);
}
public emph(node: cm.Node, context: RendererContext) {
return this.handle('emph', node, context);
}
public strong(node: cm.Node, context: RendererContext) {
return this.handle('strong', node, context);
}
public html_inline(node: cm.Node, context: RendererContext) {
return this.handle('html_inline', node, context);
}
public html_block(node: cm.Node, context: RendererContext) {
return this.handle('html_block', node, context);
}
public link(node: cm.Node, context: RendererContext) {
return this.handle('link', node, context);
}
public image(node: cm.Node, context: RendererContext) {
return this.handle('image', node, context);
}
public document(node: cm.Node, context: RendererContext) {
return this.handle('document', node, context);
}
public paragraph(node: cm.Node, context: RendererContext) {
return this.handle('paragraph', node, context);
}
public list(node: cm.Node, context: RendererContext) {
return this.handle('list', node, context);
}
public item(node: cm.Node, context: RendererContext) {
return this.handle('item', node, context);
}
public heading(node: cm.Node, context: RendererContext) {
return this.handle('heading', node, context);
}
public thematic_break(node: cm.Node, context: RendererContext) {
return this.handle('thematic_break', node, context);
}
public custom_block(node: cm.Node, context: RendererContext) {
return this.handle('custom_block', node, context);
}
public custom_inline(node: cm.Node, context: RendererContext) {
return this.handle('custom_inline', node, context);
}
private handle(name: string, node: cm.Node, context: RendererContext) {
const contents = context.content();
const enterText = [name, inspectNode(node)].filter((x) => x).join(' ');
if (contents) {
return `(${enterText}\n${prefixLines(' ', contents)})\n`;
}
return `(${enterText})\n`;
}
}
function inspectNode(n: cm.Node): string {
const INTERESTING_KEYS = [
'literal',
'destination',
'title',
'info',
'level',
'listType',
'listTight',
'listStart',
'listDelimiter',
];
const ret: any = {};
// tslint:disable-next-line:forin
for (const key of INTERESTING_KEYS) {
const value = (n as any)[key];
if (typeof value === 'string' || typeof value === 'number') {
ret[key] = value;
}
}
return JSON.stringify(ret);
}