Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Performance Benchmarks

on:
# Run on pushes to main branches and feature branches with 'perf' in name
push:
branches: [ master, 'feature/*perf*' ]

# Allow manual triggering
workflow_dispatch:
inputs:
reason:
description: 'Reason for running benchmark'
required: false
default: 'Manual benchmark run'

# Run on release
release:
types: [published]

jobs:
benchmark:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Use Node.js LTS
uses: actions/setup-node@v4
with:
node-version: 'lts/*'

- name: Install dependencies
run: npm ci

- name: Run benchmark
run: |
echo "Starting benchmark run..."
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "Reason: ${{ github.event.inputs.reason }}"
fi
xvfb-run -a npm run benchmark
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
out
node_modules
.vscode-test
*.vsix
*.vsix
benchmark-results-*.json
13 changes: 13 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,19 @@
],
"outFiles": [ "${workspaceRoot}/out/test/**/*.js" ],
"preLaunchTask": "compileAndCopyTestResources"
},
{
"name": "Launch Benchmarks",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--disable-extensions",
"--extensionDevelopmentPath=${workspaceRoot}",
"--extensionTestsPath=${workspaceRoot}/out/test/systemTests/benchmarkRunner.js"
],
"outFiles": [ "${workspaceRoot}/out/test/**/*.js" ],
"preLaunchTask": "compileAndCopyTestResources"
}
]
}
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
[![OVSX](https://img.shields.io/open-vsx/v/darkriszty/markdown-table-prettify?color=success&label=Open%20VSX)](https://open-vsx.org/extension/darkriszty/markdown-table-prettify)
[![Docker image](https://img.shields.io/docker/v/darkriszty/prettify-md?color=success&label=Docker)](https://hub.docker.com/r/darkriszty/prettify-md/tags?page=1&ordering=last_updated)
[![NPM package](https://img.shields.io/npm/v/markdown-table-prettify?color=success)](https://www.npmjs.com/package/markdown-table-prettify)
[![Benchmarks](https://github.com/darkriszty/MarkdownTablePrettify-VSCodeExt/actions/workflows/benchmark.yml/badge.svg)](https://github.com/darkriszty/MarkdownTablePrettify-VSCodeExt/actions/workflows/benchmark.yml)

Makes tables more readable for humans. Compatible with the Markdown writer plugin's table formatter feature in Atom.

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
"compile": "tsc -p ./",
"pretest": "npm run compile",
"test": "npx gulp copy-systemTest-resources && node ./out/test/index.js",
"benchmark": "npm run compile && npx gulp copy-systemTest-resources && node ./out/test/systemTests/benchmarkTestRunner.js",
"prettify-md": "node ./out/cli/index.js",
"check-md": "node ./out/cli/index.js --check"
},
Expand Down
11 changes: 10 additions & 1 deletion src/extension/extension.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
'use strict';
import * as vscode from 'vscode';
import { getSupportLanguageIds, getDocumentRangePrettyfier, getDocumentPrettyfier, getDocumentPrettyfierCommand } from './prettyfierFactory';
import { getSupportLanguageIds, getDocumentRangePrettyfier, getDocumentPrettyfier, getDocumentPrettyfierCommand, invalidateCache } from './prettyfierFactory';

// This method is called when the extension is activated.
// The extension is activated the very first time the command is executed.
export function activate(context: vscode.ExtensionContext): void {

// Invalidate cache when configuration changes
context.subscriptions.push(
vscode.workspace.onDidChangeConfiguration(event => {
if (event.affectsConfiguration("markdownTablePrettify")) {
invalidateCache();
}
})
);

const supportedLanguageIds = getSupportLanguageIds();
for (let language of supportedLanguageIds) {
context.subscriptions.push(
Expand Down
14 changes: 13 additions & 1 deletion src/extension/prettyfierFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ import { SingleTablePrettyfier } from '../prettyfiers/singleTablePrettyfier';
import { TableStringWriter } from "../writers/tableStringWriter";
import { ValuePaddingProvider } from '../writers/valuePaddingProvider';

let cachedMultiTablePrettyfier: MultiTablePrettyfier | null = null;

export function invalidateCache() {
cachedMultiTablePrettyfier = null;
}

export function getSupportLanguageIds() {
return [ "markdown", ...getConfigurationValue<Array<string>>("extendedLanguages", []) ];
}
Expand All @@ -41,15 +47,21 @@ export function getDocumentPrettyfierCommand(): TableDocumentPrettyfierCommand {
}

function getMultiTablePrettyfier(): MultiTablePrettyfier {
if (cachedMultiTablePrettyfier) {
return cachedMultiTablePrettyfier;
}

const loggers = getLoggers();
const sizeLimitCheker = getSizeLimitChecker(loggers);
const columnPadding: number = getConfigurationValue<number>("columnPadding", 0);

return new MultiTablePrettyfier(
cachedMultiTablePrettyfier = new MultiTablePrettyfier(
new TableFinder(new TableValidator(new SelectionInterpreter(true))),
getSingleTablePrettyfier(loggers, sizeLimitCheker, columnPadding),
sizeLimitCheker
);

return cachedMultiTablePrettyfier;
}

function getSingleTablePrettyfier(loggers: ILogger[], sizeLimitCheker: ConfigSizeLimitChecker, columnPadding: number): SingleTablePrettyfier {
Expand Down
38 changes: 25 additions & 13 deletions src/padCalculation/padCalculatorSelector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,41 @@ import * as CenterAlignment from "./center";
import { Alignment } from "../models/alignment";

export class PadCalculatorSelector {
public select(table: Table, column: number) : BasePadCalculator {
private static readonly leftFirstColumn = new LeftAlignment.FirstColumnPadCalculator();
private static readonly leftMiddleColumn = new LeftAlignment.MiddleColumnPadCalculator();
private static readonly leftLastColumn = new LeftAlignment.LastColumnPadCalculator();

private static readonly centerFirstColumn = new CenterAlignment.FirstColumnPadCalculator();
private static readonly centerMiddleColumn = new CenterAlignment.MiddleColumnPadCalculator();
private static readonly centerLastColumn = new CenterAlignment.LastColumnPadCalculator();

private static readonly rightFirstColumn = new RightAlignment.FirstColumnPadCalculator();
private static readonly rightMiddleColumn = new RightAlignment.MiddleColumnPadCalculator();
private static readonly rightLastColumn = new RightAlignment.LastColumnPadCalculator();

public select(table: Table, column: number) : BasePadCalculator {
switch (table.alignments[column]) {
case Alignment.Center: return this.centerAlignmentPadCalculator(table, column);
case Alignment.Right: return this.rightAlignmentPadCalculator(table, column);
default: return this.leftAlignmentPadCalculator(table, column);
}
}

private leftAlignmentPadCalculator(table: Table, column: number) : BasePadCalculator {
if (column == 0) return new LeftAlignment.FirstColumnPadCalculator();
if (column == table.columnCount - 1) return new LeftAlignment.LastColumnPadCalculator();
return new LeftAlignment.MiddleColumnPadCalculator();
private leftAlignmentPadCalculator(table: Table, column: number) : BasePadCalculator {
if (column == 0) return PadCalculatorSelector.leftFirstColumn;
if (column == table.columnCount - 1) return PadCalculatorSelector.leftLastColumn;
return PadCalculatorSelector.leftMiddleColumn;
}

private centerAlignmentPadCalculator(table: Table, column: number) : BasePadCalculator {
if (column == 0) return new CenterAlignment.FirstColumnPadCalculator();
if (column == table.columnCount - 1) return new CenterAlignment.LastColumnPadCalculator();
return new CenterAlignment.MiddleColumnPadCalculator();
private centerAlignmentPadCalculator(table: Table, column: number) : BasePadCalculator {
if (column == 0) return PadCalculatorSelector.centerFirstColumn;
if (column == table.columnCount - 1) return PadCalculatorSelector.centerLastColumn;
return PadCalculatorSelector.centerMiddleColumn;
}

private rightAlignmentPadCalculator(table: Table, column: number) : BasePadCalculator {
if (column == 0) return new RightAlignment.FirstColumnPadCalculator();
if (column == table.columnCount - 1) return new RightAlignment.LastColumnPadCalculator();
return new RightAlignment.MiddleColumnPadCalculator();
private rightAlignmentPadCalculator(table: Table, column: number) : BasePadCalculator {
if (column == 0) return PadCalculatorSelector.rightFirstColumn;
if (column == table.columnCount - 1) return PadCalculatorSelector.rightLastColumn;
return PadCalculatorSelector.rightMiddleColumn;
}
}
21 changes: 15 additions & 6 deletions src/viewModelFactories/alignmentMarking/alignmentMarkerStrategy.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
import { Alignment } from "../../models/alignment";
import { IAlignmentMarker, LeftAlignmentMarker, RightAlignmentMarker, CenterAlignmentMarker, NotSetAlignmentMarker } from ".";


export class AlignmentMarkerStrategy {
constructor(private _markerChar: string) { }
private readonly _leftMarker: IAlignmentMarker;
private readonly _rightMarker: IAlignmentMarker;
private readonly _centerMarker: IAlignmentMarker;
private readonly _notSetMarker: IAlignmentMarker;

constructor(private _markerChar: string) {
this._leftMarker = new LeftAlignmentMarker(this._markerChar);
this._rightMarker = new RightAlignmentMarker(this._markerChar);
this._centerMarker = new CenterAlignmentMarker(this._markerChar);
this._notSetMarker = new NotSetAlignmentMarker();
}

public markerFor(alignment: Alignment): IAlignmentMarker {
switch (alignment) {
case Alignment.Left: return new LeftAlignmentMarker(this._markerChar);
case Alignment.Right: return new RightAlignmentMarker(this._markerChar);
case Alignment.Center: return new CenterAlignmentMarker(this._markerChar);
default: return new NotSetAlignmentMarker();
case Alignment.Left: return this._leftMarker;
case Alignment.Right: return this._rightMarker;
case Alignment.Center: return this._centerMarker;
default: return this._notSetMarker;
}
}
}
36 changes: 18 additions & 18 deletions src/writers/tableStringWriter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,36 +14,36 @@ export class TableStringWriter {
if (table.rows == null) throw new Error("Table rows can't be null.");
if (table.columnCount == 0) throw new Error("Table must have at least one column.");

let buffer = "";
buffer += this.writeRowViewModel(table.header, table, true);
buffer += this.writeRowViewModel(table.separator, table, table.rowCount > 0);
buffer += this.writeRows(table);
const buffer: string[] = [];
buffer.push(this.writeRowViewModel(table.header, table, true));
buffer.push(this.writeRowViewModel(table.separator, table, table.rowCount > 0));
buffer.push(this.writeRows(table));

return buffer;
return buffer.join('');
}

private writeRows(table: TableViewModel): string {
let buffer = "";
const buffer: string[] = [];
for (let row = 0; row < table.rowCount; row++) {
buffer += this.writeRowViewModel(table.rows[row], table, row != table.rowCount - 1);
buffer.push(this.writeRowViewModel(table.rows[row], table, row != table.rowCount - 1));
}
return buffer;
return buffer.join('');
}

private writeRowViewModel(row: RowViewModel, table: TableViewModel, addEndOfLine: boolean): string {
let buffer = "";
buffer += table.leftPad;
buffer += this.getLeftBorderIfNeeded(table);
const buffer: string[] = [];
buffer.push(table.leftPad);
buffer.push(this.getLeftBorderIfNeeded(table));
for (let col = 0; col < table.columnCount; col++) {
buffer += this._valuePaddingProvider.getLeftPadding();
buffer += row.getValueAt(col);
buffer += this._valuePaddingProvider.getRightPadding(table, col);
buffer += this.getSeparatorIfNeeded(table, col);
buffer.push(this._valuePaddingProvider.getLeftPadding());
buffer.push(row.getValueAt(col));
buffer.push(this._valuePaddingProvider.getRightPadding(table, col));
buffer.push(this.getSeparatorIfNeeded(table, col));
}
buffer += this.getRightBorderIfNeeded(table);
buffer.push(this.getRightBorderIfNeeded(table));
if (addEndOfLine)
buffer += row.EOL;
return buffer;
buffer.push(row.EOL);
return buffer.join('');
}

private getSeparatorIfNeeded(table: TableViewModel, currentColumn: number): string {
Expand Down
Loading
Loading