Skip to content

Instantly share code, notes, and snippets.

@jayliew
Last active February 21, 2025 14:22
Show Gist options
  • Save jayliew/03ef0338b0da9fac737c2cf7db2dc1ce to your computer and use it in GitHub Desktop.
Save jayliew/03ef0338b0da9fac737c2cf7db2dc1ce to your computer and use it in GitHub Desktop.
Self-contained offline JSON pretty print
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JSON Pretty Printer</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 20px auto;
padding: 20px;
}
textarea {
width: 100%;
height: 150px;
margin-bottom: 10px;
padding: 10px;
font-family: monospace;
}
button {
padding: 10px 20px;
background-color: #4CAF50;
color: white;
border: none;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}
#output {
margin-top: 20px;
font-family: monospace;
white-space: pre-wrap;
}
.json-key {
color: #2c3e50;
cursor: pointer;
font-weight: bold;
}
.json-value {
color: #e74c3c;
margin-left: 20px;
}
.hidden {
display: none;
}
.checkbox-container {
margin: 10px 0;
}
</style>
</head>
<body>
<h1>JSON Pretty Printer</h1>
<textarea id="jsonInput" placeholder="Paste your JSON string here..." oninput="updateOutput()"></textarea>
<div class="checkbox-container">
<input type="checkbox" id="interpretNewlines" onchange="updateOutput()">
<label for="interpretNewlines">Interpret newlines</label>
</div>
<button onclick="updateOutput()">Submit</button>
<div id="output"></div>
<script>
let uniqueId = 0;
let lastJsonObj = null;
function updateOutput() {
const input = document.getElementById('jsonInput').value;
const output = document.getElementById('output');
const interpretNewlines = document.getElementById('interpretNewlines').checked;
uniqueId = 0;
if (!input.trim()) {
output.innerHTML = '';
return;
}
try {
const jsonObj = JSON.parse(input);
lastJsonObj = jsonObj; // Store the parsed object
output.innerHTML = formatJSON(jsonObj, 0, interpretNewlines);
addClickListeners();
} catch (e) {
output.innerHTML = 'Invalid JSON: ' + e.message;
output.style.color = 'red';
}
}
function formatJSON(obj, indentLevel, interpretNewlines) {
const indent = ' '.repeat(indentLevel);
let html = '';
if (typeof obj !== 'object' || obj === null) {
let valueStr = JSON.stringify(obj);
if (interpretNewlines && typeof obj === 'string') {
valueStr = `"${obj.replace(/\n/g, '<br>')}"`;
}
return `<span class="json-value">${valueStr}</span>`;
}
for (const [key, value] of Object.entries(obj)) {
const currentId = uniqueId++;
html += `${indent}<span class="json-key" data-id="${currentId}">${key}</span>: `;
if (typeof value === 'object' && value !== null) {
html += `\n${formatJSON(value, indentLevel + 1, interpretNewlines)}`;
} else {
let valueStr = JSON.stringify(value);
if (interpretNewlines && typeof value === 'string') {
valueStr = `"${value.replace(/\n/g, '<br>')}"`;
}
html += `<span class="json-value" data-id="${currentId}">${valueStr}</span>\n`;
}
}
return html;
}
function addClickListeners() {
const keys = document.getElementsByClassName('json-key');
Array.from(keys).forEach(key => {
key.addEventListener('click', function() {
const value = this.parentElement.querySelector(`.json-value[data-id="${this.dataset.id}"]`);
if (value) {
value.classList.toggle('hidden');
}
});
});
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment