markdown-table-formatter 1.7.0 → 2.0.1-202611010112.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -7
- package/lib/cli.js +25 -15
- package/lib/engine.js +44 -0
- package/lib/index.js +6 -1
- package/lib/markdown-table-formatter.js +18 -11
- package/lib/options.js +175 -50
- package/lib/wasm/markdown_table_formatter.wasm +0 -0
- package/package.json +15 -43
package/README.md
CHANGED
|
@@ -13,7 +13,11 @@
|
|
|
13
13
|
[](https://github.com/nvuillam/markdown-table-formatter/blob/master/LICENSE)
|
|
14
14
|
[](http://makeapullrequest.com)
|
|
15
15
|
|
|
16
|
-
Format markdown tables in files,
|
|
16
|
+
Format markdown tables in files, with a fast formatting engine written in Rust and embedded as WebAssembly.
|
|
17
|
+
|
|
18
|
+
No dependencies, the same npm package works on every platform (Windows, macOS, Linux, x64 and arm64) with Node.js 22.17+.
|
|
19
|
+
|
|
20
|
+
The formatting rules come from [markdown-table-prettify](https://github.com/darkriszty/MarkdownTablePrettify-VSCodeExt) 4.x, plus some fixes: tables in code blocks are left untouched and column widths follow the Unicode display width (CJK, kana, hangul, emoji...).
|
|
17
21
|
|
|
18
22
|
[](https://github.com/nvuillam/markdown-table-formatter#readme)
|
|
19
23
|
|
|
@@ -26,7 +30,9 @@ Format markdown tables in files, using embedded [markdown-table-prettify](https:
|
|
|
26
30
|
- [Options](#options)
|
|
27
31
|
- [Examples](#examples)
|
|
28
32
|
- [Continuous Integration](#continuous-integration)
|
|
33
|
+
- [pre-commit hook](#pre-commit-hook)
|
|
29
34
|
- [Ignoring Code Blocks](#ignoring-code-blocks)
|
|
35
|
+
- [Debug](#debug)
|
|
30
36
|
- [Contribute](#contribute)
|
|
31
37
|
- [Release notes](#release-notes)
|
|
32
38
|
|
|
@@ -52,12 +58,13 @@ markdown-table-formatter [OPTIONS] (file(s) or glob expression)
|
|
|
52
58
|
|
|
53
59
|
### Options
|
|
54
60
|
|
|
55
|
-
| Parameter
|
|
56
|
-
|
|
57
|
-
| -c<br/>--check
|
|
58
|
-
| -p<br/>--columnpadding
|
|
59
|
-
| -
|
|
60
|
-
| -
|
|
61
|
+
| Parameter | Description | Default value |
|
|
62
|
+
|------------------------|------------------------------------------|---------------|
|
|
63
|
+
| -c<br/>--check | Check only, does not update files | `false` |
|
|
64
|
+
| -p<br/>--columnpadding | Override column padding number of spaces | `0` |
|
|
65
|
+
| -z<br/>--verbose | Verbose mode | `false` |
|
|
66
|
+
| -h<br/>--help | Displays help | <!-- --> |
|
|
67
|
+
| -v<br/>--version | Displays version | <!-- --> |
|
|
61
68
|
|
|
62
69
|
## Examples
|
|
63
70
|
|
|
@@ -103,12 +110,32 @@ You can see **more examples in** [**test methods**](https://github.com/nvuillam/
|
|
|
103
110
|
|
|
104
111
|
You can automatically check markdown tables formatting and fix it using [MegaLinter](https://github.com/oxsecurity/megalinter/), that embeds markdown-table-formatter out of the box
|
|
105
112
|
|
|
113
|
+
## pre-commit hook
|
|
114
|
+
|
|
115
|
+
Format markdown tables of committed files with [pre-commit](https://pre-commit.com), by adding to `.pre-commit-config.yaml`:
|
|
116
|
+
|
|
117
|
+
```yaml
|
|
118
|
+
repos:
|
|
119
|
+
- repo: https://github.com/nvuillam/markdown-table-formatter
|
|
120
|
+
rev: v2.0.0
|
|
121
|
+
hooks:
|
|
122
|
+
- id: markdown-table-formatter
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The hook formats tables of staged markdown files in place: the commit stops when a file was updated, so you can review and stage the changes.
|
|
126
|
+
|
|
106
127
|
## Ignoring Code Blocks
|
|
107
128
|
|
|
108
129
|
You may wish to ignore specific markdown content, especially when using with [Megalinter](https://github.com/oxsecurity/megalinter) or [terraform-docs](https://github.com/terraform-docs/terraform-docs)
|
|
109
130
|
|
|
110
131
|
To achieve this, place tags `<!-- markdown-table-prettify-ignore-start -->` and `<!-- markdown-table-prettify-ignore-end -->` around the content you want markdown-table-formatter to ignore.
|
|
111
132
|
|
|
133
|
+
Tables inside fenced code blocks (` ``` ` or `~~~`) and indented code blocks are never formatted.
|
|
134
|
+
|
|
135
|
+
## Debug
|
|
136
|
+
|
|
137
|
+
Set environment variable `NODE_DEBUG=markdown-table-formatter` to display debug logs.
|
|
138
|
+
|
|
112
139
|
## Contribute
|
|
113
140
|
|
|
114
141
|
Contributions are very welcome !
|
package/lib/cli.js
CHANGED
|
@@ -1,7 +1,26 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
2
|
const { MarkdownTableFormatter } = require("./markdown-table-formatter");
|
|
3
3
|
const optionsDefinition = require("./options");
|
|
4
|
-
const
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
|
|
7
|
+
const EXCLUDED_DIRS = new Set(["node_modules", ".git"]);
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Lists files matching a glob pattern, skipping node_modules and .git folders
|
|
11
|
+
* @param {string} pattern - Glob pattern
|
|
12
|
+
* @return {string[]} - Sorted file paths
|
|
13
|
+
*/
|
|
14
|
+
function findFiles(pattern) {
|
|
15
|
+
const exclude = (entry) =>
|
|
16
|
+
EXCLUDED_DIRS.has(
|
|
17
|
+
path.basename(typeof entry === "string" ? entry : entry.name),
|
|
18
|
+
);
|
|
19
|
+
return fs
|
|
20
|
+
.globSync(pattern, { exclude })
|
|
21
|
+
.filter((file) => fs.statSync(file).isFile())
|
|
22
|
+
.sort();
|
|
23
|
+
}
|
|
5
24
|
|
|
6
25
|
class MarkdownTableFormatterCli {
|
|
7
26
|
"use strict";
|
|
@@ -13,16 +32,7 @@ class MarkdownTableFormatterCli {
|
|
|
13
32
|
|
|
14
33
|
// Show version
|
|
15
34
|
if (this.options.version) {
|
|
16
|
-
|
|
17
|
-
if (!version) {
|
|
18
|
-
try {
|
|
19
|
-
const FindPackageJson = require("find-package-json");
|
|
20
|
-
const finder = FindPackageJson(__dirname);
|
|
21
|
-
version = finder.next().value.version;
|
|
22
|
-
} catch {
|
|
23
|
-
version = "error";
|
|
24
|
-
}
|
|
25
|
-
}
|
|
35
|
+
const version = require("../package.json").version;
|
|
26
36
|
const message = `markdown-table-formatter version ${version}`;
|
|
27
37
|
console.log(message);
|
|
28
38
|
return { stdout: message };
|
|
@@ -47,16 +57,16 @@ class MarkdownTableFormatterCli {
|
|
|
47
57
|
let files = this.options._;
|
|
48
58
|
if (files.length === 0) {
|
|
49
59
|
// use default glob expression **/*.md
|
|
50
|
-
files =
|
|
60
|
+
files = findFiles("**/*.md");
|
|
51
61
|
} else if (files.length === 1 && files[0].includes("*")) {
|
|
52
62
|
// use sent glob expression
|
|
53
|
-
files =
|
|
63
|
+
files = findFiles(files[0]);
|
|
54
64
|
}
|
|
55
65
|
const { status, updates } = await formatter.run(files, this.options);
|
|
56
66
|
// Manage result
|
|
57
67
|
if (status === 0 && updates.length === 0) {
|
|
58
68
|
console.log("No markdown table formatting has been applied.");
|
|
59
|
-
} else if (status === 0 && updates > 0) {
|
|
69
|
+
} else if (status === 0 && updates.length > 0) {
|
|
60
70
|
console.log(
|
|
61
71
|
`Formatted markdown tables in ${
|
|
62
72
|
updates.length
|
|
@@ -74,4 +84,4 @@ class MarkdownTableFormatterCli {
|
|
|
74
84
|
}
|
|
75
85
|
}
|
|
76
86
|
|
|
77
|
-
module.exports = { MarkdownTableFormatterCli };
|
|
87
|
+
module.exports = { MarkdownTableFormatterCli, findFiles };
|
package/lib/engine.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Loads the Rust formatting engine compiled to WebAssembly (lib/wasm, built by `npm run build:wasm`)
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
|
|
6
|
+
const WASM_FILE = path.join(__dirname, "wasm", "markdown_table_formatter.wasm");
|
|
7
|
+
|
|
8
|
+
let wasm = null;
|
|
9
|
+
|
|
10
|
+
function getWasm() {
|
|
11
|
+
if (wasm === null) {
|
|
12
|
+
if (!fs.existsSync(WASM_FILE)) {
|
|
13
|
+
throw new Error(`${WASM_FILE} not found: run "npm run build:wasm"`);
|
|
14
|
+
}
|
|
15
|
+
const module = new WebAssembly.Module(fs.readFileSync(WASM_FILE));
|
|
16
|
+
wasm = new WebAssembly.Instance(module, {}).exports;
|
|
17
|
+
}
|
|
18
|
+
return wasm;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Formats all markdown tables found in a markdown string
|
|
23
|
+
* @param {string} text - Markdown content
|
|
24
|
+
* @param {number} [columnPadding] - Number of spaces around cell values
|
|
25
|
+
* @return {string} - Formatted markdown content
|
|
26
|
+
*/
|
|
27
|
+
function formatTables(text, columnPadding = 0) {
|
|
28
|
+
const engine = getWasm();
|
|
29
|
+
const input = Buffer.from(text, "utf8");
|
|
30
|
+
const inputPtr = engine.mtf_alloc(input.length);
|
|
31
|
+
new Uint8Array(engine.memory.buffer, inputPtr, input.length).set(input);
|
|
32
|
+
// mtf_format frees the input buffer
|
|
33
|
+
const outputPtr = engine.mtf_format(inputPtr, input.length, columnPadding);
|
|
34
|
+
const outputLength = engine.mtf_result_len();
|
|
35
|
+
const output = Buffer.from(
|
|
36
|
+
engine.memory.buffer,
|
|
37
|
+
outputPtr,
|
|
38
|
+
outputLength,
|
|
39
|
+
).toString("utf8");
|
|
40
|
+
engine.mtf_free_result();
|
|
41
|
+
return output;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
module.exports = { formatTables };
|
package/lib/index.js
CHANGED
|
@@ -10,7 +10,12 @@ const runningAsScript = !module.parent;
|
|
|
10
10
|
// Run asynchronously to use the returned status for process.exit
|
|
11
11
|
if (runningAsScript) {
|
|
12
12
|
(async () => {
|
|
13
|
-
|
|
13
|
+
try {
|
|
14
|
+
await new MarkdownTableFormatterCli().run(process.argv);
|
|
15
|
+
} catch (error) {
|
|
16
|
+
console.error(`markdown-table-formatter: ${error.message}`);
|
|
17
|
+
process.exitCode = 1;
|
|
18
|
+
}
|
|
14
19
|
})();
|
|
15
20
|
}
|
|
16
21
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const {
|
|
2
|
+
const fs = require("fs/promises");
|
|
3
|
+
const debug = require("util").debuglog("markdown-table-formatter");
|
|
4
|
+
const { formatTables } = require("./engine");
|
|
5
5
|
|
|
6
6
|
class MarkdownTableFormatter {
|
|
7
7
|
"use strict";
|
|
@@ -15,6 +15,17 @@ class MarkdownTableFormatter {
|
|
|
15
15
|
this.checkOnly = opts.check;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Formats all markdown tables found in a markdown string
|
|
20
|
+
* @param {string} markdownString - Markdown content
|
|
21
|
+
* @param {object} [options] - Format options
|
|
22
|
+
* @param {number} [options.columnpadding] - Number of spaces around cell values
|
|
23
|
+
* @return {string} - Formatted markdown content
|
|
24
|
+
*/
|
|
25
|
+
static formatText(markdownString, options = {}) {
|
|
26
|
+
return formatTables(markdownString, options.columnpadding || 0);
|
|
27
|
+
}
|
|
28
|
+
|
|
18
29
|
/**
|
|
19
30
|
* Runs markdown table formatter
|
|
20
31
|
* @param {string[]} [files] - List of files to format
|
|
@@ -33,23 +44,19 @@ class MarkdownTableFormatter {
|
|
|
33
44
|
if (debug.enabled) {
|
|
34
45
|
debug(`[file] ${file}`);
|
|
35
46
|
}
|
|
36
|
-
const markdown = await
|
|
47
|
+
const markdown = await fs.readFile(file);
|
|
37
48
|
const markdownString = markdown.toString();
|
|
38
49
|
if (debug.enabled) {
|
|
39
50
|
debug(`[file before]\n${markdownString}`);
|
|
40
51
|
}
|
|
41
|
-
const
|
|
42
|
-
if (options.columnpadding) {
|
|
43
|
-
prettifyOptions.columnPadding = options.columnpadding;
|
|
44
|
-
}
|
|
45
|
-
const markdownStringPrettified = CliPrettify.prettify(
|
|
52
|
+
const markdownStringPrettified = MarkdownTableFormatter.formatText(
|
|
46
53
|
markdownString,
|
|
47
|
-
|
|
54
|
+
options,
|
|
48
55
|
);
|
|
49
56
|
const updated = markdownStringPrettified !== markdownString;
|
|
50
57
|
// Update file if necessary
|
|
51
58
|
if (updated && !this.checkOnly) {
|
|
52
|
-
await
|
|
59
|
+
await fs.writeFile(file, markdownStringPrettified);
|
|
53
60
|
debug(`[updated] ${file} with:\n${markdownStringPrettified}`);
|
|
54
61
|
if (options.verbose) {
|
|
55
62
|
console.info(`- Updated file ${file}`);
|
package/lib/options.js
CHANGED
|
@@ -1,59 +1,184 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview
|
|
2
|
+
* @fileoverview Command line options parsing (same behavior and messages as optionator, without dependency)
|
|
3
3
|
* @author Nicolas Vuillamy
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
"use strict";
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
// Requirements
|
|
10
|
-
//------------------------------------------------------------------------------
|
|
8
|
+
const PREPEND = "markdown-table-formatter [options]";
|
|
11
9
|
|
|
12
|
-
const
|
|
10
|
+
const OPTIONS = [
|
|
11
|
+
{
|
|
12
|
+
option: "check",
|
|
13
|
+
alias: "c",
|
|
14
|
+
type: "Boolean",
|
|
15
|
+
description:
|
|
16
|
+
"Check only (exits 1 if wrongly formatted markdown tables are found)",
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
option: "columnpadding",
|
|
20
|
+
alias: "p",
|
|
21
|
+
type: "Int",
|
|
22
|
+
description: "Override table columns padding number of spaces",
|
|
23
|
+
},
|
|
24
|
+
{ option: "help", alias: "h", type: "Boolean", description: "Show help" },
|
|
25
|
+
{
|
|
26
|
+
option: "version",
|
|
27
|
+
alias: "v",
|
|
28
|
+
type: "Boolean",
|
|
29
|
+
description: "Show version",
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
option: "verbose",
|
|
33
|
+
alias: "z",
|
|
34
|
+
type: "Boolean",
|
|
35
|
+
description: "Verbose mode",
|
|
36
|
+
},
|
|
37
|
+
];
|
|
13
38
|
|
|
14
|
-
|
|
15
|
-
// Initialization and Public Interface
|
|
16
|
-
//------------------------------------------------------------------------------
|
|
39
|
+
const MUTUALLY_EXCLUSIVE = [["check", "help", "version"]];
|
|
17
40
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
41
|
+
const byName = (name) =>
|
|
42
|
+
OPTIONS.find((opt) => opt.option === name || opt.alias === name);
|
|
43
|
+
const flag = (name) => (name.length === 1 ? `-${name}` : `--${name}`);
|
|
44
|
+
const label = (opt) =>
|
|
45
|
+
`-${opt.alias}, --${opt.option}${opt.type === "Boolean" ? "" : ` ${opt.type}`}`;
|
|
46
|
+
|
|
47
|
+
function levenshtein(a, b) {
|
|
48
|
+
let previous = Array.from({ length: b.length + 1 }, (_, i) => i);
|
|
49
|
+
for (let i = 1; i <= a.length; i++) {
|
|
50
|
+
const current = [i];
|
|
51
|
+
for (let j = 1; j <= b.length; j++) {
|
|
52
|
+
current[j] = Math.min(
|
|
53
|
+
previous[j] + 1,
|
|
54
|
+
current[j - 1] + 1,
|
|
55
|
+
previous[j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1),
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
previous = current;
|
|
59
|
+
}
|
|
60
|
+
return previous[b.length];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function invalidOption(name) {
|
|
64
|
+
const candidates = OPTIONS.flatMap((opt) => [opt.option, opt.alias]);
|
|
65
|
+
const closest = candidates.reduce((best, candidate) =>
|
|
66
|
+
levenshtein(name, candidate) < levenshtein(name, best) ? candidate : best,
|
|
67
|
+
);
|
|
68
|
+
return new Error(
|
|
69
|
+
`Invalid option '${flag(name)}' - perhaps you meant '${flag(closest)}'?`,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function convert(opt, value) {
|
|
74
|
+
if (opt.type === "Int") {
|
|
75
|
+
if (value === undefined) {
|
|
76
|
+
throw new Error(`Value for '${opt.option}' of type 'Int' required.`);
|
|
77
|
+
}
|
|
78
|
+
if (!/^\d+$/.test(value)) {
|
|
79
|
+
throw new Error(
|
|
80
|
+
`Invalid value for option '${opt.option}' - expected type Int, received value: ${value}.`,
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
return parseInt(value, 10);
|
|
84
|
+
}
|
|
85
|
+
if (value === undefined || value === "true") {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
if (value === "false") {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
throw new Error(
|
|
92
|
+
`Invalid value for option '${opt.option}' - expected type Boolean, received value: ${value}.`,
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Parses command line arguments
|
|
98
|
+
* @param {string[]} input - process.argv-like array (the first 2 items are ignored)
|
|
99
|
+
* @return {object} - Option values, and positional arguments in `_`
|
|
100
|
+
*/
|
|
101
|
+
function parse(input) {
|
|
102
|
+
const args = input.slice(2);
|
|
103
|
+
const result = {};
|
|
104
|
+
const positional = [];
|
|
105
|
+
for (let i = 0; i < args.length; i++) {
|
|
106
|
+
const arg = String(args[i]);
|
|
107
|
+
if (arg === "--") {
|
|
108
|
+
positional.push(...args.slice(i + 1));
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
if (arg.startsWith("--")) {
|
|
112
|
+
const [rawName, ...valueParts] = arg.slice(2).split("=");
|
|
113
|
+
let value = valueParts.length > 0 ? valueParts.join("=") : undefined;
|
|
114
|
+
let opt = byName(rawName);
|
|
115
|
+
if (
|
|
116
|
+
!opt &&
|
|
117
|
+
rawName.startsWith("no-") &&
|
|
118
|
+
byName(rawName.slice(3))?.type === "Boolean" &&
|
|
119
|
+
value === undefined
|
|
120
|
+
) {
|
|
121
|
+
opt = byName(rawName.slice(3));
|
|
122
|
+
value = "false";
|
|
123
|
+
}
|
|
124
|
+
if (!opt || opt.option !== rawName.replace(/^no-/, "")) {
|
|
125
|
+
throw invalidOption(rawName);
|
|
126
|
+
}
|
|
127
|
+
if (opt.type !== "Boolean" && value === undefined) {
|
|
128
|
+
value = args[++i];
|
|
129
|
+
}
|
|
130
|
+
result[opt.option] = convert(opt, value);
|
|
131
|
+
} else if (arg.startsWith("-") && arg.length > 1) {
|
|
132
|
+
const names = arg.slice(1).split("");
|
|
133
|
+
names.forEach((name, index) => {
|
|
134
|
+
const opt = byName(name);
|
|
135
|
+
if (!opt || opt.alias !== name) {
|
|
136
|
+
throw /\d/.test(name)
|
|
137
|
+
? new Error(`No -NUM option defined.`)
|
|
138
|
+
: invalidOption(name);
|
|
139
|
+
}
|
|
140
|
+
if (opt.type !== "Boolean") {
|
|
141
|
+
if (index !== names.length - 1) {
|
|
142
|
+
throw new Error(
|
|
143
|
+
`Can't set argument '${name}' when not last flag in a group of short flags.`,
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
result[opt.option] = convert(opt, args[++i]);
|
|
147
|
+
} else {
|
|
148
|
+
result[opt.option] = true;
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
} else {
|
|
152
|
+
positional.push(arg);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
for (const group of MUTUALLY_EXCLUSIVE) {
|
|
156
|
+
const used = group.filter((name) => name in result);
|
|
157
|
+
if (used.length > 1) {
|
|
158
|
+
throw new Error(
|
|
159
|
+
`The options ${used.map((name) => `--${name}`).join(" and ")} are mutually exclusive - you cannot use them at the same time.`,
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
result._ = positional;
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function generateHelp() {
|
|
168
|
+
const width = Math.max(...OPTIONS.map((opt) => label(opt).length));
|
|
169
|
+
const lines = OPTIONS.map(
|
|
170
|
+
(opt) => ` ${label(opt).padEnd(width)} ${opt.description}`,
|
|
171
|
+
);
|
|
172
|
+
return `${PREPEND}\n\n${lines.join("\n")}`;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function generateHelpForOption(name) {
|
|
176
|
+
const opt = byName(name);
|
|
177
|
+
if (!opt) {
|
|
178
|
+
return invalidOption(name).message;
|
|
179
|
+
}
|
|
180
|
+
const title = label(opt);
|
|
181
|
+
return `${title}\n${"=".repeat(title.length)}\ndescription: ${opt.description}.`;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
module.exports = { parse, generateHelp, generateHelpForOption };
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "markdown-table-formatter",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Format markdown tables in files",
|
|
3
|
+
"version": "2.0.1-202611010112.0",
|
|
4
|
+
"description": "Format markdown tables in files (Rust engine compiled to WebAssembly, no dependencies)",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"files": [
|
|
7
7
|
"lib/"
|
|
@@ -10,10 +10,15 @@
|
|
|
10
10
|
"markdown-table-formatter": "lib/index.js"
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
13
|
+
"build:wasm": "node scripts/build-wasm.js",
|
|
14
|
+
"lint:fix": "eslint --fix && prettier --write \"./lib/**/*.{js,jsx,json}\" --tab-width 4 --print-width 150",
|
|
15
|
+
"prepack": "node scripts/build-wasm.js --if-needed",
|
|
16
|
+
"pretest": "npm run build:wasm",
|
|
17
|
+
"test": "node --test --test-timeout=300000 \"test/**/*.test.js\"",
|
|
18
|
+
"pretest:coverage": "npm run build:wasm",
|
|
19
|
+
"test:coverage": "node --test --test-timeout=300000 --experimental-test-coverage --test-coverage-include=\"lib/**\" \"test/**/*.test.js\"",
|
|
20
|
+
"test:rust": "cargo test --manifest-path rust/Cargo.toml",
|
|
21
|
+
"test:debug": "env NODE_DEBUG=markdown-table-formatter node --test --test-timeout=300000 --test-reporter=spec \"test/**/*.test.js\""
|
|
17
22
|
},
|
|
18
23
|
"repository": {
|
|
19
24
|
"type": "git",
|
|
@@ -32,46 +37,13 @@
|
|
|
32
37
|
"url": "https://github.com/nvuillam/markdown-table-formatter/issues"
|
|
33
38
|
},
|
|
34
39
|
"homepage": "https://github.com/nvuillam/markdown-table-formatter#readme",
|
|
35
|
-
"dependencies": {
|
|
36
|
-
"debug": "^4.3.4",
|
|
37
|
-
"find-package-json": "^1.2.0",
|
|
38
|
-
"fs-extra": "^11.1.1",
|
|
39
|
-
"glob": "^13.0.0",
|
|
40
|
-
"markdown-table-prettify": "^3.6.0",
|
|
41
|
-
"optionator": "^0.9.4"
|
|
42
|
-
},
|
|
43
40
|
"devDependencies": {
|
|
44
|
-
"
|
|
45
|
-
"eslint": "^9.0.0",
|
|
46
|
-
"mega-linter-runner": "^9.0.0",
|
|
47
|
-
"mocha": "^11.0.0",
|
|
48
|
-
"nyc": "^17.0.0",
|
|
49
|
-
"which": "^6.0.0"
|
|
41
|
+
"eslint": "^10.14.0"
|
|
50
42
|
},
|
|
51
43
|
"engines": {
|
|
52
|
-
"node": ">=
|
|
53
|
-
},
|
|
54
|
-
"mocha": {
|
|
55
|
-
"require": [
|
|
56
|
-
"test/helpers/init.js"
|
|
57
|
-
],
|
|
58
|
-
"watch-extensions": [
|
|
59
|
-
"js"
|
|
60
|
-
],
|
|
61
|
-
"recursive": true,
|
|
62
|
-
"reporter": "spec",
|
|
63
|
-
"timeout": "300000"
|
|
44
|
+
"node": ">=22.17.0"
|
|
64
45
|
},
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"lib/**"
|
|
68
|
-
],
|
|
69
|
-
"extension": [
|
|
70
|
-
".js"
|
|
71
|
-
],
|
|
72
|
-
"reporter": [
|
|
73
|
-
"html"
|
|
74
|
-
],
|
|
75
|
-
"all": true
|
|
46
|
+
"overrides": {
|
|
47
|
+
"minimatch": "^11.0.1"
|
|
76
48
|
}
|
|
77
49
|
}
|