Skip to content

Commit a6bc94f

Browse files
committed
Add column padding support
1 parent 4c53784 commit a6bc94f

19 files changed

Lines changed: 1410 additions & 67 deletions

cli/argumentsParser.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { CliOptions } from "./cliOptions";
2+
3+
export function parseArguments(processArgs: string[]): CliOptions {
4+
return <CliOptions> {
5+
check: Boolean(hasArgument(ArgumentNames.CHECK_ARG) || false),
6+
columnPadding: Number(getArgumentValue(ArgumentNames.PADDING_ARG) || 0)
7+
};
8+
9+
function hasArgument(key: string): boolean {
10+
return processArgs.length > 2 && processArgs.find(arg => arg.startsWith("--" + key)) !== undefined;
11+
}
12+
13+
function getArgumentValue(key: string): string {
14+
const hasArguments = processArgs.length > 2;
15+
const split = (hasArguments
16+
? processArgs.find(arg => arg.startsWith("--" + key)) || ""
17+
: "")
18+
.split("=");
19+
20+
return split.length == 2
21+
? split[1]
22+
: null;
23+
}
24+
}
25+
26+
class ArgumentNames {
27+
public static readonly CHECK_ARG : string = "check";
28+
public static readonly PADDING_ARG : string = "columnPadding";
29+
}

cli/cliOptions.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export interface CliOptions {
2+
check: Boolean;
3+
columnPadding: number;
4+
}

cli/cliPrettify.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
import { CliOptions} from "./cliOptions";
12
import { MultiTablePrettyfier } from "../src/prettyfiers/multiTablePrettyfier";
23
import { TableFinder } from "../src/tableFinding/tableFinder";
34
import { TableValidator } from "../src/modelFactory/tableValidator";
45
import { SelectionInterpreter } from "../src/modelFactory/selectionInterpreter";
56
import { TableFactory } from "../src/modelFactory/tableFactory";
67
import { AlignmentFactory } from "../src/modelFactory/alignmentFactory";
7-
import { TrimmerTransformer } from "../src/modelFactory/transformers/trimmerTransformer";
88
import { BorderTransformer } from "../src/modelFactory/transformers/borderTransformer";
9+
import { TrimmerTransformer } from "../src/modelFactory/transformers/trimmerTransformer";
10+
import { FairTableIndentationDetector } from "../src/modelFactory/tableIndentationDetector";
911
import { ConsoleLogger } from "../src/diagnostics/consoleLogger";
1012
import { SingleTablePrettyfier } from "../src/prettyfiers/singleTablePrettyfier";
1113
import { NoSizeLimitChecker } from "../src/prettyfiers/sizeLimit/noSizeLimitChecker";
@@ -15,22 +17,22 @@ import { ContentPadCalculator } from "../src/padCalculation/contentPadCalculator
1517
import { PadCalculatorSelector } from "../src/padCalculation/padCalculatorSelector";
1618
import { AlignmentMarkerStrategy } from "../src/viewModelFactories/alignmentMarking";
1719
import { TableStringWriter } from "../src/writers/tableStringWriter";
18-
import { FairTableIndentationDetector } from "../src/modelFactory/tableIndentationDetector";
20+
import { ValuePaddingProvider } from "../src/writers/valuePaddingProvider";
1921

2022
export class CliPrettify {
2123

22-
public static prettify(text: string): string {
23-
const prettyfier = this.createPrettyfier();
24+
public static prettify(text: string, options?: CliOptions): string {
25+
const prettyfier = this.createPrettyfier(options);
2426
return prettyfier.formatTables(text);
2527
}
2628

27-
public static check(text: string): void {
28-
if (this.prettify(text) !== text) {
29+
public static check(text: string, options?: CliOptions): void {
30+
if (this.prettify(text, options) !== text) {
2931
throw new Error("The input file is not prettyfied!");
3032
}
3133
}
3234

33-
private static createPrettyfier(): MultiTablePrettyfier {
35+
private static createPrettyfier(options?: CliOptions): MultiTablePrettyfier {
3436
const logger = new ConsoleLogger();
3537
return new MultiTablePrettyfier(
3638
new TableFinder(new TableValidator(new SelectionInterpreter(true))),
@@ -43,10 +45,10 @@ export class CliPrettify {
4345
),
4446
new TableValidator(new SelectionInterpreter(false)),
4547
new TableViewModelFactory(new RowViewModelFactory(
46-
new ContentPadCalculator(new PadCalculatorSelector(), " "),
48+
new ContentPadCalculator(new PadCalculatorSelector(), " "),
4749
new AlignmentMarkerStrategy(":")
4850
)),
49-
new TableStringWriter(),
51+
new TableStringWriter(new ValuePaddingProvider(options.columnPadding)),
5052
[ logger ],
5153
new NoSizeLimitChecker()
5254
),

cli/index.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
#!/usr/bin/env node
22

3+
import { parseArguments } from "./argumentsParser";
4+
import { CliOptions } from "./cliOptions";
35
import { CliPrettify } from "./cliPrettify";
46
import { InputReader } from "./inputReader";
57

6-
const checkOnly = process.argv.length > 2 || process.argv.find(arg => arg === "--check");
8+
const cliOptions: CliOptions = parseArguments(process.argv);
79

810
InputReader.subscribe(input =>
9-
checkOnly
10-
? CliPrettify.check(input)
11-
: process.stdout.write(CliPrettify.prettify(input))
11+
cliOptions.check
12+
? CliPrettify.check(input, cliOptions)
13+
: process.stdout.write(CliPrettify.prettify(input, cliOptions))
1214
);

src/extension/prettyfierFactory.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,19 @@ import { VsWindowLogger } from '../diagnostics/vsWindowLogger';
1010
import { TableFactory } from "../modelFactory/tableFactory";
1111
import { AlignmentFactory } from "../modelFactory/alignmentFactory";
1212
import { TableValidator } from "../modelFactory/tableValidator";
13-
import { TableStringWriter } from "../writers/tableStringWriter";
1413
import { ContentPadCalculator } from '../padCalculation/contentPadCalculator';
1514
import { TableViewModelFactory } from '../viewModelFactories/tableViewModelFactory';
1615
import { RowViewModelFactory } from '../viewModelFactories/rowViewModelFactory';
17-
import { TrimmerTransformer } from '../modelFactory/transformers/trimmerTransformer';
1816
import { BorderTransformer } from '../modelFactory/transformers/borderTransformer';
17+
import { TrimmerTransformer } from '../modelFactory/transformers/trimmerTransformer';
18+
import { FairTableIndentationDetector } from '../modelFactory/tableIndentationDetector';
1919
import { SelectionInterpreter } from '../modelFactory/selectionInterpreter';
2020
import { PadCalculatorSelector } from '../padCalculation/padCalculatorSelector';
2121
import { AlignmentMarkerStrategy } from '../viewModelFactories/alignmentMarking';
2222
import { MultiTablePrettyfier } from '../prettyfiers/multiTablePrettyfier';
2323
import { SingleTablePrettyfier } from '../prettyfiers/singleTablePrettyfier';
24-
import { FairTableIndentationDetector } from '../modelFactory/tableIndentationDetector';
24+
import { TableStringWriter } from "../writers/tableStringWriter";
25+
import { ValuePaddingProvider } from '../writers/valuePaddingProvider';
2526

2627
export function getSupportLanguageIds() {
2728
return [ "markdown", ...getConfigurationValue<Array<string>>("extendedLanguages", []) ];
@@ -42,15 +43,16 @@ export function getDocumentPrettyfierCommand(): TableDocumentPrettyfierCommand {
4243
function getMultiTablePrettyfier(): MultiTablePrettyfier {
4344
const loggers = getLoggers();
4445
const sizeLimitCheker = getSizeLimitChecker(loggers);
46+
const columnPadding: number = getConfigurationValue<number>("columnPadding", 0);
4547

4648
return new MultiTablePrettyfier(
4749
new TableFinder(new TableValidator(new SelectionInterpreter(true))),
48-
getSingleTablePrettyfier(loggers, sizeLimitCheker),
50+
getSingleTablePrettyfier(loggers, sizeLimitCheker, columnPadding),
4951
sizeLimitCheker
5052
);
5153
}
5254

53-
function getSingleTablePrettyfier(loggers: ILogger[], sizeLimitCheker: ConfigSizeLimitChecker): SingleTablePrettyfier {
55+
function getSingleTablePrettyfier(loggers: ILogger[], sizeLimitCheker: ConfigSizeLimitChecker, columnPadding: number): SingleTablePrettyfier {
5456
return new SingleTablePrettyfier(
5557
new TableFactory(
5658
new AlignmentFactory(),
@@ -63,7 +65,7 @@ function getSingleTablePrettyfier(loggers: ILogger[], sizeLimitCheker: ConfigSiz
6365
new ContentPadCalculator(new PadCalculatorSelector(), " "),
6466
new AlignmentMarkerStrategy(":")
6567
)),
66-
new TableStringWriter(),
68+
new TableStringWriter(new ValuePaddingProvider(columnPadding)),
6769
loggers,
6870
sizeLimitCheker
6971
);

src/writers/tableStringWriter.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
import { ValuePaddingProvider } from "./valuePaddingProvider";
12
import { TableViewModel } from "../viewModels/tableViewModel";
23
import { RowViewModel } from "../viewModels/rowViewModel";
34

45
export class TableStringWriter {
6+
public constructor(
7+
private readonly _valuePaddingProvider: ValuePaddingProvider
8+
) { }
9+
510
public writeTable(table: TableViewModel): string {
611
if (table == null) throw new Error("Table can't be null.");
712
if (table.header == null) throw new Error("Table must have a header.");
@@ -29,7 +34,9 @@ export class TableStringWriter {
2934
buffer += table.leftPad;
3035
buffer += this.getLeftBorderIfNeeded(table);
3136
for (let col = 0; col < table.columnCount; col++) {
37+
buffer += this._valuePaddingProvider.getLeftPadding();
3238
buffer += row.getValueAt(col);
39+
buffer += this._valuePaddingProvider.getRightPadding(table, col);
3340
buffer += this.getSeparatorIfNeeded(table, col);
3441
}
3542
buffer += this.getRightBorderIfNeeded(table);
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { TableViewModel } from "../viewModels/tableViewModel";
2+
3+
export class ValuePaddingProvider {
4+
private readonly _columnPad: string;
5+
6+
public constructor(columnPadding: number) {
7+
if (columnPadding < 0) throw new Error("Column padding must be greater than or equal to 0!");
8+
9+
this._columnPad = " ".repeat(columnPadding);
10+
}
11+
12+
public getLeftPadding(): string {
13+
return this._columnPad;
14+
}
15+
16+
public getRightPadding(table: TableViewModel, currentColumn: number): string {
17+
return currentColumn != table.columnCount - 1
18+
? this._columnPad
19+
: table.hasRightBorder
20+
? this._columnPad
21+
: "";
22+
}
23+
}
Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
import * as fs from 'fs';
22
import * as path from 'path';
33
import * as assert from 'assert';
4+
import { getDistinctTestFileNames, readFileContents } from './systemTestFileReader';
5+
import SystemTestsConfig from './systemTestsConfig';
46
import { CliPrettify } from '../../cli/cliPrettify';
57

68
fs.readdir(path.resolve(__dirname, "resources/"), function(err, files) {
79
suite("CLI Prettyfier system tests - prettyfied input files match prepared expected files", () => {
8-
const distinctTests: string[] = getTestFileNames(files);
10+
const distinctTests: string[] = getAllowedAndDistinctTestFileNames(files);
911
for (let fileNameRoot of distinctTests) {
1012
test(`[${fileNameRoot}]`, () => {
11-
const input = fs.readFileSync(pathFor(`${fileNameRoot}-input.md`), "utf8");
12-
const expected = fs.readFileSync(pathFor(`${fileNameRoot}-expected.md`), "utf8");
13+
const input = readFileContents(`${fileNameRoot}-input.md`);
14+
const expected = readFileContents(`${fileNameRoot}-expected.md`);
15+
const cliOptions = SystemTestsConfig.getCliOptionsFor(fileNameRoot);
1316

14-
const actual = CliPrettify.prettify(input);
17+
const actual = CliPrettify.prettify(input, cliOptions);
1518

1619
assert.strictEqual(actual, expected);
1720
});
@@ -21,42 +24,30 @@ fs.readdir(path.resolve(__dirname, "resources/"), function(err, files) {
2124

2225
fs.readdir(path.resolve(__dirname, "resources/"), function(err, files) {
2326
suite("CLI Prettyfier system tests - check() for non pretty files throws error", () => {
24-
const distinctTests: string[] = getTestFileNames(files);
27+
const distinctTests: string[] = getAllowedAndDistinctTestFileNames(files);
2528
for (let fileNameRoot of distinctTests) {
2629
test(`[${fileNameRoot}]`, () => {
27-
const input = fs.readFileSync(pathFor(`${fileNameRoot}-input.md`), "utf8");
30+
const input = readFileContents(`${fileNameRoot}-input.md`);
2831
assert.throws(() => CliPrettify.check(input));
2932
});
3033
}
3134
});
3235
});
3336

34-
3537
fs.readdir(path.resolve(__dirname, "resources/"), function(err, files) {
3638
suite("CLI Prettyfier system tests - check() for pretty files does not throw", () => {
37-
const distinctTests: string[] = getTestFileNames(files);
39+
const distinctTests: string[] = getAllowedAndDistinctTestFileNames(files);
3840
for (let fileNameRoot of distinctTests) {
3941
test(`[${fileNameRoot}]`, () => {
40-
const expected = fs.readFileSync(pathFor(`${fileNameRoot}-expected.md`), "utf8");
41-
assert.doesNotThrow(() => CliPrettify.check(expected));
42+
const expected = readFileContents(`${fileNameRoot}-expected.md`);
43+
const cliOptions = SystemTestsConfig.getCliOptionsFor(fileNameRoot);
44+
45+
assert.doesNotThrow(() => CliPrettify.check(expected, cliOptions));
4246
});
4347
}
4448
});
4549
});
4650

47-
function getTestFileNames(files: string[]): string[] {
48-
const blockListFileName = "_cli-blocklist.config";
49-
const blockedFiles: string[] = files.find(f => f === blockListFileName)
50-
? fs.readFileSync(pathFor(blockListFileName), "utf8").split(/\r\n|\r|\n/)
51-
: [];
52-
53-
const distinctTests: string[] = files
54-
.filter(f => path.extname(f).toLowerCase() === ".md")
55-
.filter(f => blockedFiles.indexOf(f) < 0)
56-
.map(f => f.split("-")[0]).filter((item, i, s) => s.lastIndexOf(item) == i);
57-
return distinctTests;
51+
function getAllowedAndDistinctTestFileNames(files: string[]): string[] {
52+
return getDistinctTestFileNames(files, SystemTestsConfig.isAllowedForCliTests);
5853
}
59-
60-
function pathFor(fileName: string): string {
61-
return path.resolve(__dirname, `resources/${fileName}`);
62-
}

test/systemTests/resources/_cli-blocklist.config

Lines changed: 0 additions & 2 deletions
This file was deleted.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"cliIgnoreFiles": [
3+
"largeFileIsNotFormatted-input.md",
4+
"largeFileIsNotFormatted-expected.md"
5+
],
6+
"columnPadding": {
7+
"paddingOf1": 1,
8+
"paddingOf2": 2
9+
}
10+
}

0 commit comments

Comments
 (0)