formatarc 0.1.0 → 0.2.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 +23 -1
- package/dist/cli.js +10 -4
- package/dist/converter.d.ts +1 -1
- package/dist/converter.js +83 -3
- package/package.json +10 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# formatarc
|
|
2
2
|
|
|
3
|
-
Convert JSON, YAML, and
|
|
3
|
+
Convert JSON, YAML, CSV, Markdown, and HTML from the terminal. No config, no dependencies to manage — just pipe or pass your data.
|
|
4
4
|
|
|
5
5
|
**Web version → [formatarc.com](https://formatarc.com)**
|
|
6
6
|
|
|
@@ -31,6 +31,9 @@ cat file | formatarc <tool>
|
|
|
31
31
|
| `yaml-to-json` | Convert YAML to JSON |
|
|
32
32
|
| `json-to-yaml` | Convert JSON to YAML |
|
|
33
33
|
| `csv-to-json` | Convert CSV (with header row) to JSON |
|
|
34
|
+
| `csv-to-markdown` | Convert CSV to a Markdown (GFM) table |
|
|
35
|
+
| `markdown-to-html` | Convert Markdown to HTML |
|
|
36
|
+
| `html-to-markdown` | Convert HTML to Markdown |
|
|
34
37
|
|
|
35
38
|
### Examples
|
|
36
39
|
|
|
@@ -69,6 +72,24 @@ Convert CSV from stdin:
|
|
|
69
72
|
cat users.csv | formatarc csv-to-json
|
|
70
73
|
```
|
|
71
74
|
|
|
75
|
+
Convert CSV to a Markdown table:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
cat users.csv | formatarc csv-to-markdown
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Render Markdown as HTML:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
cat README.md | formatarc markdown-to-html > README.html
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Strip HTML to Markdown (handy for piping web pages into LLMs):
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
curl -s https://example.com | formatarc html-to-markdown
|
|
91
|
+
```
|
|
92
|
+
|
|
72
93
|
## Programmatic API
|
|
73
94
|
|
|
74
95
|
```typescript
|
|
@@ -95,6 +116,7 @@ For a browser-based experience with no signup and no data upload:
|
|
|
95
116
|
**[formatarc.com](https://formatarc.com)**
|
|
96
117
|
|
|
97
118
|
- JSON Formatter, YAML ↔ JSON, CSV → JSON
|
|
119
|
+
- CSV → Markdown, Markdown ↔ HTML
|
|
98
120
|
- Runs entirely in the browser
|
|
99
121
|
- Multilingual (English / Japanese)
|
|
100
122
|
|
package/dist/cli.js
CHANGED
|
@@ -10,15 +10,21 @@ Usage:
|
|
|
10
10
|
cat file | formatarc <tool>
|
|
11
11
|
|
|
12
12
|
Tools:
|
|
13
|
-
json-format
|
|
14
|
-
yaml-to-json
|
|
15
|
-
json-to-yaml
|
|
16
|
-
csv-to-json
|
|
13
|
+
json-format Pretty-print JSON
|
|
14
|
+
yaml-to-json Convert YAML to JSON
|
|
15
|
+
json-to-yaml Convert JSON to YAML
|
|
16
|
+
csv-to-json Convert CSV to JSON
|
|
17
|
+
csv-to-markdown Convert CSV to a Markdown table
|
|
18
|
+
markdown-to-html Convert Markdown to HTML
|
|
19
|
+
html-to-markdown Convert HTML to Markdown
|
|
17
20
|
|
|
18
21
|
Examples:
|
|
19
22
|
formatarc json-format '{"a":1}'
|
|
20
23
|
formatarc yaml-to-json config.yaml
|
|
21
24
|
cat data.csv | formatarc csv-to-json
|
|
25
|
+
cat table.csv | formatarc csv-to-markdown
|
|
26
|
+
cat README.md | formatarc markdown-to-html
|
|
27
|
+
cat page.html | formatarc html-to-markdown
|
|
22
28
|
|
|
23
29
|
Web version: https://formatarc.com
|
|
24
30
|
`.trim();
|
package/dist/converter.d.ts
CHANGED
|
@@ -2,6 +2,6 @@ export type ConvertResult = {
|
|
|
2
2
|
output: string;
|
|
3
3
|
error: string;
|
|
4
4
|
};
|
|
5
|
-
export type Tool = "json-format" | "yaml-to-json" | "json-to-yaml" | "csv-to-json";
|
|
5
|
+
export type Tool = "json-format" | "yaml-to-json" | "json-to-yaml" | "csv-to-json" | "csv-to-markdown" | "markdown-to-html" | "html-to-markdown";
|
|
6
6
|
export declare function isValidTool(value: string): value is Tool;
|
|
7
7
|
export declare function convert(tool: Tool, input: string): ConvertResult;
|
package/dist/converter.js
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import Papa from "papaparse";
|
|
2
2
|
import YAML from "yaml";
|
|
3
|
-
|
|
3
|
+
import { marked } from "marked";
|
|
4
|
+
import TurndownService from "turndown";
|
|
5
|
+
const TOOLS = [
|
|
6
|
+
"json-format",
|
|
7
|
+
"yaml-to-json",
|
|
8
|
+
"json-to-yaml",
|
|
9
|
+
"csv-to-json",
|
|
10
|
+
"csv-to-markdown",
|
|
11
|
+
"markdown-to-html",
|
|
12
|
+
"html-to-markdown",
|
|
13
|
+
];
|
|
4
14
|
export function isValidTool(value) {
|
|
5
15
|
return TOOLS.includes(value);
|
|
6
16
|
}
|
|
@@ -26,7 +36,19 @@ export function convert(tool, input) {
|
|
|
26
36
|
error: "",
|
|
27
37
|
};
|
|
28
38
|
case "csv-to-json":
|
|
29
|
-
return
|
|
39
|
+
return convertCsvToJson(input);
|
|
40
|
+
case "csv-to-markdown":
|
|
41
|
+
return convertCsvToMarkdown(input);
|
|
42
|
+
case "markdown-to-html":
|
|
43
|
+
return {
|
|
44
|
+
output: marked.parse(input, { async: false, gfm: true, breaks: false }),
|
|
45
|
+
error: "",
|
|
46
|
+
};
|
|
47
|
+
case "html-to-markdown":
|
|
48
|
+
return {
|
|
49
|
+
output: turndownService.turndown(input),
|
|
50
|
+
error: "",
|
|
51
|
+
};
|
|
30
52
|
default:
|
|
31
53
|
return { output: "", error: `Unknown tool: ${tool}` };
|
|
32
54
|
}
|
|
@@ -35,7 +57,7 @@ export function convert(tool, input) {
|
|
|
35
57
|
return { output: "", error: formatError(err, input, tool) };
|
|
36
58
|
}
|
|
37
59
|
}
|
|
38
|
-
function
|
|
60
|
+
function convertCsvToJson(input) {
|
|
39
61
|
const parsed = Papa.parse(input, {
|
|
40
62
|
header: true,
|
|
41
63
|
skipEmptyLines: "greedy",
|
|
@@ -54,6 +76,58 @@ function convertCsv(input) {
|
|
|
54
76
|
error: "",
|
|
55
77
|
};
|
|
56
78
|
}
|
|
79
|
+
function renderMarkdownTable(rows) {
|
|
80
|
+
const columnCount = rows[0].length;
|
|
81
|
+
const escapeCell = (value) => value.replace(/\r?\n/g, " ").replace(/\|/g, "\\|").trim();
|
|
82
|
+
const normalizeRow = (row) => {
|
|
83
|
+
const trimmed = row.length > columnCount ? row.slice(0, columnCount) : row;
|
|
84
|
+
const padded = trimmed.length === columnCount
|
|
85
|
+
? trimmed
|
|
86
|
+
: [...trimmed, ...Array(columnCount - trimmed.length).fill("")];
|
|
87
|
+
return padded.map(escapeCell);
|
|
88
|
+
};
|
|
89
|
+
const renderRow = (cells) => `| ${cells.join(" | ")} |`;
|
|
90
|
+
const header = normalizeRow(rows[0]);
|
|
91
|
+
const separator = Array(columnCount).fill("---");
|
|
92
|
+
const body = rows.slice(1).map(normalizeRow);
|
|
93
|
+
return [renderRow(header), renderRow(separator), ...body.map(renderRow)].join("\n");
|
|
94
|
+
}
|
|
95
|
+
function convertCsvToMarkdown(input) {
|
|
96
|
+
const parsed = Papa.parse(input, {
|
|
97
|
+
header: false,
|
|
98
|
+
skipEmptyLines: "greedy",
|
|
99
|
+
});
|
|
100
|
+
if (parsed.errors.length > 0) {
|
|
101
|
+
const first = parsed.errors[0];
|
|
102
|
+
return { output: "", error: `CSV parse error: ${first.message}` };
|
|
103
|
+
}
|
|
104
|
+
const rows = parsed.data.filter((row) => row.length > 0);
|
|
105
|
+
if (rows.length === 0) {
|
|
106
|
+
return { output: "", error: "CSV is empty." };
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
output: renderMarkdownTable(rows) + "\n",
|
|
110
|
+
error: "",
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
const turndownService = (() => {
|
|
114
|
+
const service = new TurndownService({
|
|
115
|
+
headingStyle: "atx",
|
|
116
|
+
codeBlockStyle: "fenced",
|
|
117
|
+
bulletListMarker: "-",
|
|
118
|
+
emDelimiter: "_",
|
|
119
|
+
});
|
|
120
|
+
service.addRule("table", {
|
|
121
|
+
filter: "table",
|
|
122
|
+
replacement: (_content, node) => {
|
|
123
|
+
const rows = Array.from(node.querySelectorAll("tr")).map((row) => Array.from(row.querySelectorAll("th, td")).map((cell) => cell.textContent ?? ""));
|
|
124
|
+
if (rows.length === 0)
|
|
125
|
+
return "";
|
|
126
|
+
return `\n\n${renderMarkdownTable(rows)}\n\n`;
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
return service;
|
|
130
|
+
})();
|
|
57
131
|
function formatError(err, input, tool) {
|
|
58
132
|
if (err instanceof YAML.YAMLParseError) {
|
|
59
133
|
const line = err.linePos?.[0]?.line;
|
|
@@ -67,5 +141,11 @@ function formatError(err, input, tool) {
|
|
|
67
141
|
}
|
|
68
142
|
return "Invalid JSON.";
|
|
69
143
|
}
|
|
144
|
+
if (tool === "markdown-to-html") {
|
|
145
|
+
return "Failed to parse Markdown. Check the syntax.";
|
|
146
|
+
}
|
|
147
|
+
if (tool === "html-to-markdown") {
|
|
148
|
+
return "Failed to parse HTML. Check for unclosed tags.";
|
|
149
|
+
}
|
|
70
150
|
return "Failed to parse input. Check the format.";
|
|
71
151
|
}
|
package/package.json
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "formatarc",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Convert JSON, YAML, and
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Convert JSON, YAML, CSV, Markdown, and HTML from the terminal. Browser-based version at formatarc.com.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"json",
|
|
7
7
|
"yaml",
|
|
8
8
|
"csv",
|
|
9
|
+
"markdown",
|
|
10
|
+
"html",
|
|
9
11
|
"formatter",
|
|
10
12
|
"converter",
|
|
11
13
|
"json-formatter",
|
|
12
14
|
"yaml-to-json",
|
|
13
15
|
"csv-to-json",
|
|
16
|
+
"csv-to-markdown",
|
|
17
|
+
"markdown-to-html",
|
|
18
|
+
"html-to-markdown",
|
|
14
19
|
"cli"
|
|
15
20
|
],
|
|
16
21
|
"author": "FormatArc",
|
|
@@ -36,11 +41,14 @@
|
|
|
36
41
|
"prepublishOnly": "npm run build"
|
|
37
42
|
},
|
|
38
43
|
"dependencies": {
|
|
44
|
+
"marked": "^18.0.1",
|
|
39
45
|
"papaparse": "^5.5.2",
|
|
46
|
+
"turndown": "^7.2.4",
|
|
40
47
|
"yaml": "^2.8.1"
|
|
41
48
|
},
|
|
42
49
|
"devDependencies": {
|
|
43
50
|
"@types/papaparse": "^5.3.15",
|
|
51
|
+
"@types/turndown": "^5.0.6",
|
|
44
52
|
"typescript": "^5.8.3"
|
|
45
53
|
}
|
|
46
54
|
}
|