JSON to Markdown
Convert JSON array to markdown table or list
Source Code
import fs from "fs";
import path from "path";
const [inputPath, format = "table", fieldsArg, outputPath] = process.argv.slice(2);
if (!inputPath || !fieldsArg || !outputPath) {
console.error("Usage: inputPath format fields outputPath");
process.exit(1);
}
/**
* Get nested field value using dot notation
*/
function getField(obj, fieldPath) {
const parts = fieldPath.split(".");
let value = obj;
for (const part of parts) {
if (value == null) return undefined;
value = value[part];
}
return value;
}
/**
* Escape markdown special characters in cell content
*/
function escapeMarkdown(str) {
if (str == null) return "";
return String(str)
.replace(/\|/g, "\\|")
.replace(/\n/g, " ")
.replace(/\r/g, "");
}
/**
* Format value for display
*/
function formatValue(value, maxLength = 100) {
if (value == null) return "";
if (typeof value === "object") {
const str = JSON.stringify(value);
return str.length > maxLength ? str.slice(0, maxLength) + "..." : str;
}
const str = String(value);
return str.length > maxLength ? str.slice(0, maxLength) + "..." : str;
}
/**
* Generate markdown table
*/
function toTable(items, fields) {
const lines = [];
// Header
lines.push("| " + fields.join(" | ") + " |");
lines.push("| " + fields.map(() => "---").join(" | ") + " |");
// Rows
for (const item of items) {
const cells = fields.map((f) => escapeMarkdown(formatValue(getField(item, f))));
lines.push("| " + cells.join(" | ") + " |");
}
return lines.join("\n");
}
/**
* Generate markdown list (numbered)
*/
function toList(items, fields) {
const lines = [];
for (let i = 0; i < items.length; i++) {
const item = items[i];
const values = fields.map((f) => `**${f}:** ${formatValue(getField(item, f))}`);
lines.push(`${i + 1}. ${values.join(", ")}`);
}
return lines.join("\n");
}
/**
* Generate markdown bullets
*/
function toBullets(items, fields) {
const lines = [];
for (const item of items) {
const values = fields.map((f) => `**${f}:** ${formatValue(getField(item, f))}`);
lines.push(`- ${values.join(", ")}`);
}
return lines.join("\n");
}
try {
console.log(`Reading ${inputPath}...`);
const raw = fs.readFileSync(inputPath, "utf-8");
const data = JSON.parse(raw);
const items = Array.isArray(data)
? data
: data.items || data.results || data.messages || [];
if (!Array.isArray(items)) {
console.error("Input must be a JSON array or object with array property");
process.exit(1);
}
// Determine fields
let fields;
if (fieldsArg === "all" && items.length > 0) {
fields = Object.keys(items[0]);
} else {
fields = fieldsArg.split(",").map((f) => f.trim());
}
console.log(`Converting ${items.length} items to ${format} with fields: ${fields.join(", ")}`);
let markdown;
switch (format) {
case "table":
markdown = toTable(items, fields);
break;
case "list":
markdown = toList(items, fields);
break;
case "bullets":
markdown = toBullets(items, fields);
break;
default:
console.error(`Unknown format: ${format}. Use 'table', 'list', or 'bullets'`);
process.exit(1);
}
// Ensure output directory exists
const dir = path.dirname(outputPath);
if (dir && dir !== ".") {
fs.mkdirSync(dir, { recursive: true });
}
fs.writeFileSync(outputPath, markdown);
console.log(`\nā Converted ${items.length} items to ${format}`);
console.log(` Fields: ${fields.join(", ")}`);
console.log(` Written to: ${outputPath}`);
// Show preview
const previewLines = markdown.split("\n").slice(0, 5);
console.log(`\n Preview:`);
for (const line of previewLines) {
console.log(` ${line.slice(0, 80)}${line.length > 80 ? "..." : ""}`);
}
if (markdown.split("\n").length > 5) {
console.log(` ... (${markdown.split("\n").length - 5} more lines)`);
}
console.log(
JSON.stringify({
success: true,
outputPath,
count: items.length,
format,
fields,
})
);
} catch (error) {
console.error("Error:", error.message);
process.exit(1);
}