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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # formatarc
2
2
 
3
- Convert JSON, YAML, and CSV from the terminal. No config, no dependencies to manage — just pipe or pass your data.
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 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
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();
@@ -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
- const TOOLS = ["json-format", "yaml-to-json", "json-to-yaml", "csv-to-json"];
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 convertCsv(input);
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 convertCsv(input) {
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.1.0",
4
- "description": "Convert JSON, YAML, and CSV from the terminal. Browser-based version at formatarc.com.",
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
  }