human (Dec 15, 2024, 12:30 PM)
Tool where I can paste in JSON and it instantly shows me the corresponding YAML with a copy to clipboard button
It should give me suitable options for that YAML conversation reflecting the way in which things like long strings are represented
assistant (Dec 15, 2024, 12:30 PM)
I'll create a simple HTML tool for converting JSON to YAML with formatting options.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JSON to YAML Converter</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-yaml/4.1.0/js-yaml.min.js"></script>
<style>
* {
box-sizing: border-box;
}
body {
font-family: Helvetica, Arial, sans-serif;
margin: 0;
padding: 20px;
background: #f5f5f5;
}
.container {
max-width: 1200px;
margin: 0 auto;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.panel {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
textarea {
width: 100%;
height: 400px;
padding: 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-family: monospace;
font-size: 16px;
resize: vertical;
}
.controls {
margin: 20px 0;
}
label {
display: block;
margin-bottom: 8px;
font-weight: bold;
}
select {
font-size: 16px;
padding: 8px;
border-radius: 4px;
border: 1px solid #ddd;
min-width: 200px;
}
button {
background: #2563eb;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
button:hover {
background: #1d4ed8;
}
.error {
color: #dc2626;
margin-top: 8px;
font-size: 14px;
}
</style>
</head>
<body>
<div class="container">
<div class="panel">
<label for="jsonInput">JSON Input</label>
<textarea id="jsonInput" placeholder="Paste your JSON here..."></textarea>
</div>
<div class="panel">
<div class="controls">
<label for="styleSelect">YAML Style</label>
<select id="styleSelect">
<option value="block">Block Style (Default)</option>
<option value="flow">Flow Style (Compact)</option>
<option value="quote">Quote Strings</option>
</select>
<button id="copyButton">Copy YAML</button>
</div>
<textarea id="yamlOutput" readonly></textarea>
<div id="error" class="error"></div>
</div>
</div>
<script type="module">
const jsonInput = document.getElementById('jsonInput')
const yamlOutput = document.getElementById('yamlOutput')
const styleSelect = document.getElementById('styleSelect')
const copyButton = document.getElementById('copyButton')
const errorDiv = document.getElementById('error')
function convertToYaml() {
const jsonStr = jsonInput.value
errorDiv.textContent = ''
if (!jsonStr.trim()) {
yamlOutput.value = ''
return
}
try {
const jsonObj = JSON.parse(jsonStr)
const style = styleSelect.value
let yamlStr = ''
if (style === 'flow') {
yamlStr = jsyaml.dump(jsonObj, { flowLevel: 1 })
} else if (style === 'quote') {
yamlStr = jsyaml.dump(jsonObj, {
styles: {
'!!str': 'double'
}
})
} else {
yamlStr = jsyaml.dump(jsonObj, { indent: 2 })
}
yamlOutput.value = yamlStr
} catch (err) {
errorDiv.textContent = 'Invalid JSON: ' + err.message
}
}
jsonInput.addEventListener('input', convertToYaml)
styleSelect.addEventListener('change', convertToYaml)
copyButton.addEventListener('click', async () => {
try {
await navigator.clipboard.writeText(yamlOutput.value)
const originalText = copyButton.textContent
copyButton.textContent = 'Copied!'
setTimeout(() => {
copyButton.textContent = originalText
}, 2000)
} catch (err) {
errorDiv.textContent = 'Failed to copy: ' + err.message
}
})
// Add some example JSON on load
jsonInput.value = `{
"name": "Example Project",
"version": "1.0.0",
"description": "A longer description that might need special handling in YAML",
"dependencies": {
"library1": "^2.0.0",
"library2": "~1.5.0"
},
"tags": ["web", "tool", "converter"],
"settings": {
"enabled": true,
"maxItems": 100
}
}`
convertToYaml()
</script>
</body>
</html>
I've created a simple web tool for converting JSON to YAML. Here's what it offers:
- A two-panel interface with JSON input on the left and YAML output on the right
- Three YAML formatting options:
- Block Style (default) - Most readable format
- Flow Style - More compact, uses inline notation
- Quote Strings - Forces quotes around string values
- Copy to clipboard button with visual feedback
- Error handling for invalid JSON
- Real-time conversion as you type
- Responsive layout that works well on different screen sizes
The tool loads with an example JSON object to demonstrate the conversion. You can just paste over it with your own JSON.
Would you like me to add any additional formatting options or make any adjustments to the styling?
human (Dec 15, 2024, 12:31 PM)
Don't have two columns, just one column please
Rather than letting me select those styles from a select box output all of them one after the other, each with a copy button
assistant (Dec 15, 2024, 12:31 PM)
I'll modify the layout to show the JSON input followed by three different YAML outputs vertically.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JSON to YAML Converter</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-yaml/4.1.0/js-yaml.min.js"></script>
<style>
* {
box-sizing: border-box;
}
body {
font-family: Helvetica, Arial, sans-serif;
margin: 0;
padding: 20px;
background: #f5f5f5;
max-width: 800px;
margin: 0 auto;
}
.panel {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
margin-bottom: 20px;
}
textarea {
width: 100%;
height: 200px;
padding: 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-family: monospace;
font-size: 16px;
resize: vertical;
}
.output-section {
margin-top: 16px;
}
.output-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
label {
display: block;
margin-bottom: 8px;
font-weight: bold;
}
button {
background: #2563eb;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
button:hover {
background: #1d4ed8;
}
.error {
color: #dc2626;
margin-top: 8px;
font-size: 14px;
}
</style>
</head>
<body>
<div class="panel">
<label for="jsonInput">JSON Input</label>
<textarea id="jsonInput" placeholder="Paste your JSON here..."></textarea>
<div id="error" class="error"></div>
</div>
<div class="panel">
<div class="output-section">
<div class="output-header">
<label>Block Style YAML</label>
<button data-copy="block">Copy</button>
</div>
<textarea id="blockOutput" readonly></textarea>
</div>
<div class="output-section">
<div class="output-header">
<label>Flow Style YAML (Compact)</label>
<button data-copy="flow">Copy</button>
</div>
<textarea id="flowOutput" readonly></textarea>
</div>
<div class="output-section">
<div class="output-header">
<label>Quoted Strings YAML</label>
<button data-copy="quote">Copy</button>
</div>
<textarea id="quoteOutput" readonly></textarea>
</div>
</div>
<script type="module">
const jsonInput = document.getElementById('jsonInput')
const blockOutput = document.getElementById('blockOutput')
const flowOutput = document.getElementById('flowOutput')
const quoteOutput = document.getElementById('quoteOutput')
const errorDiv = document.getElementById('error')
function convertToYaml() {
const jsonStr = jsonInput.value
errorDiv.textContent = ''
if (!jsonStr.trim()) {
blockOutput.value = ''
flowOutput.value = ''
quoteOutput.value = ''
return
}
try {
const jsonObj = JSON.parse(jsonStr)
// Block style (default)
blockOutput.value = jsyaml.dump(jsonObj, {
indent: 2
})
// Flow style (compact)
flowOutput.value = jsyaml.dump(jsonObj, {
flowLevel: 1
})
// Quoted strings
quoteOutput.value = jsyaml.dump(jsonObj, {
styles: {
'!!str': 'double'
}
})
} catch (err) {
errorDiv.textContent = 'Invalid JSON: ' + err.message
}
}
jsonInput.addEventListener('input', convertToYaml)
document.querySelectorAll('button[data-copy]').forEach(button => {
button.addEventListener('click', async () => {
const style = button.dataset.copy
const output = document.getElementById(style + 'Output')
try {
await navigator.clipboard.writeText(output.value)
const originalText = button.textContent
button.textContent = 'Copied!'
setTimeout(() => {
button.textContent = originalText
}, 2000)
} catch (err) {
errorDiv.textContent = 'Failed to copy: ' + err.message
}
})
})
// Add some example JSON on load
jsonInput.value = `{
"name": "Example Project",
"version": "1.0.0",
"description": "A longer description that might need special handling in YAML",
"dependencies": {
"library1": "^2.0.0",
"library2": "~1.5.0"
},
"tags": ["web", "tool", "converter"],
"settings": {
"enabled": true,
"maxItems": 100
}
}`
convertToYaml()
</script>
</body>
</html>
I've revised the tool to:
- Use a single-column layout with maximum width of 800px
- Show the JSON input at the top
- Show three different YAML formats below, each with its own copy button:
- Block Style (most readable)
- Flow Style (compact)
- Quoted Strings (forces quotes around strings)
- Each output section is clearly labeled and has its own copy button
- Kept the real-time conversion and error handling
The sample JSON is still included to demonstrate the different YAML formats. Let me know if you'd like any adjustments to the layout or styling!
human (Dec 15, 2024, 12:33 PM)
I also want the style of YAML that looks like this (note indentation) - make that the first one displayed
models:
- provider: gemini
model_id: gemini-1.5-flash
tiers:
- max_tokens: 128000
input_cost: 7
output_cost: 30
assistant (Dec 15, 2024, 12:34 PM)
I'll add a "List Style" YAML output that uses that specific indentation pattern with hyphens for array items. I'll make it the first output shown.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JSON to YAML Converter</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-yaml/4.1.0/js-yaml.min.js"></script>
<style>
* {
box-sizing: border-box;
}
body {
font-family: Helvetica, Arial, sans-serif;
margin: 0;
padding: 20px;
background: #f5f5f5;
max-width: 800px;
margin: 0 auto;
}
.panel {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
margin-bottom: 20px;
}
textarea {
width: 100%;
height: 200px;
padding: 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-family: monospace;
font-size: 16px;
resize: vertical;
line-height: 1.4;
}
.output-section {
margin-top: 16px;
}
.output-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
label {
display: block;
margin-bottom: 8px;
font-weight: bold;
}
button {
background: #2563eb;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
button:hover {
background: #1d4ed8;
}
.error {
color: #dc2626;
margin-top: 8px;
font-size: 14px;
}
</style>
</head>
<body>
<div class="panel">
<label for="jsonInput">JSON Input</label>
<textarea id="jsonInput" placeholder="Paste your JSON here..."></textarea>
<div id="error" class="error"></div>
</div>
<div class="panel">
<div class="output-section">
<div class="output-header">
<label>List Style YAML (2-space indent with dashes)</label>
<button data-copy="list">Copy</button>
</div>
<textarea id="listOutput" readonly></textarea>
</div>
<div class="output-section">
<div class="output-header">
<label>Block Style YAML</label>
<button data-copy="block">Copy</button>
</div>
<textarea id="blockOutput" readonly></textarea>
</div>
<div class="output-section">
<div class="output-header">
<label>Flow Style YAML (Compact)</label>
<button data-copy="flow">Copy</button>
</div>
<textarea id="flowOutput" readonly></textarea>
</div>
<div class="output-section">
<div class="output-header">
<label>Quoted Strings YAML</label>
<button data-copy="quote">Copy</button>
</div>
<textarea id="quoteOutput" readonly></textarea>
</div>
</div>
<script type="module">
const jsonInput = document.getElementById('jsonInput')
const listOutput = document.getElementById('listOutput')
const blockOutput = document.getElementById('blockOutput')
const flowOutput = document.getElementById('flowOutput')
const quoteOutput = document.getElementById('quoteOutput')
const errorDiv = document.getElementById('error')
function formatListStyle(obj, indent = 0) {
let result = ''
const spaces = ' '.repeat(indent)
if (Array.isArray(obj)) {
for (const item of obj) {
result += spaces + '- '
if (typeof item === 'object' && item !== null) {
result += '\n' + formatListStyle(item, indent + 2)
} else {
result += item + '\n'
}
}
} else if (typeof obj === 'object' && obj !== null) {
for (const [key, value] of Object.entries(obj)) {
if (Array.isArray(value)) {
result += spaces + key + ':\n' + formatListStyle(value, indent + 2)
} else if (typeof value === 'object' && value !== null) {
result += spaces + key + ':\n' + formatListStyle(value, indent + 2)
} else {
result += spaces + key + ': ' + value + '\n'
}
}
}
return result
}
function convertToYaml() {
const jsonStr = jsonInput.value
errorDiv.textContent = ''
if (!jsonStr.trim()) {
listOutput.value = ''
blockOutput.value = ''
flowOutput.value = ''
quoteOutput.value = ''
return
}
try {
const jsonObj = JSON.parse(jsonStr)
// List style (2-space indent with dashes)
listOutput.value = formatListStyle(jsonObj)
// Block style
blockOutput.value = jsyaml.dump(jsonObj, {
indent: 2
})
// Flow style (compact)
flowOutput.value = jsyaml.dump(jsonObj, {
flowLevel: 1
})
// Quoted strings
quoteOutput.value = jsyaml.dump(jsonObj, {
styles: {
'!!str': 'double'
}
})
} catch (err) {
errorDiv.textContent = 'Invalid JSON: ' + err.message
}
}
jsonInput.addEventListener('input', convertToYaml)
document.querySelectorAll('button[data-copy]').forEach(button => {
button.addEventListener('click', async () => {
const style = button.dataset.copy
const output = document.getElementById(style + 'Output')
try {
await navigator.clipboard.writeText(output.value)
const originalText = button.textContent
button.textContent = 'Copied!'
setTimeout(() => {
button.textContent = originalText
}, 2000)
} catch (err) {
errorDiv.textContent = 'Failed to copy: ' + err.message
}
})
})
// Add some example JSON on load
jsonInput.value = `{
"models": [
{
"provider": "gemini",
"model_id": "gemini-1.5-flash",
"tiers": [
{
"max_tokens": 128000,
"input_cost": 7,
"output_cost": 30
}
]
}
]
}`
convertToYaml()
</script>
</body>
</html>
I've made these changes:
- Added a custom "List Style" YAML format that:
- Uses 2-space indentation
- Uses dashes for array items
- Places array items on new lines
- Matches the exact formatting you showed
- Made this the first output format shown
- Updated the example JSON to match your use case
- Added proper line height to the textareas for better readability
- Kept all the other formats below
The custom formatter I added maintains the specific style you showed, with arrays using dashes and the exact indentation pattern you specified. Let me know if you'd like any adjustments to the formatting!
human (Dec 15, 2024, 12:43 PM)
Use noArrayIndent: false for that last one
assistant (Dec 15, 2024, 12:43 PM)
I'll modify the quoted strings YAML output to use noArrayIndent: false
which will keep array items indented.
Find this:
// Quoted strings
quoteOutput.value = jsyaml.dump(jsonObj, {
styles: {
'!!str': 'double'
}
})
Replace with this:
// Quoted strings with array indentation
quoteOutput.value = jsyaml.dump(jsonObj, {
styles: {
'!!str': 'double'
},
noArrayIndent: false
})
Now the quoted strings format will maintain indentation for array items. The arrays will be properly indented relative to their parent keys, making the structure clearer. You can see this reflected in the output when you test with the example JSON or your own input.
human (Dec 15, 2024, 12:43 PM)
actually use true
assistant (Dec 15, 2024, 12:43 PM)
I'll modify the quoted strings YAML output to use noArrayIndent: true
which will align array items with their parent key.
Find this:
// Quoted strings with array indentation
quoteOutput.value = jsyaml.dump(jsonObj, {
styles: {
'!!str': 'double'
},
noArrayIndent: false
})
Replace with this:
// Quoted strings with no array indentation
quoteOutput.value = jsyaml.dump(jsonObj, {
styles: {
'!!str': 'double'
},
noArrayIndent: true
})
Now the quoted strings format will align array items with their parent keys rather than indenting them. This creates a more compact vertical layout while still maintaining readability.
human (Dec 15, 2024, 12:44 PM)
use that option on all of them
assistant (Dec 15, 2024, 12:44 PM)
I'll update all YAML formats to use noArrayIndent: true
.
Find this:
// Block style
blockOutput.value = jsyaml.dump(jsonObj, {
indent: 2
})
// Flow style (compact)
flowOutput.value = jsyaml.dump(jsonObj, {
flowLevel: 1
})
// Quoted strings with no array indentation
quoteOutput.value = jsyaml.dump(jsonObj, {
styles: {
'!!str': 'double'
},
noArrayIndent: true
})
Replace with this:
// Block style
blockOutput.value = jsyaml.dump(jsonObj, {
indent: 2,
noArrayIndent: true
})
// Flow style (compact)
flowOutput.value = jsyaml.dump(jsonObj, {
flowLevel: 1,
noArrayIndent: true
})
// Quoted strings with no array indentation
quoteOutput.value = jsyaml.dump(jsonObj, {
styles: {
'!!str': 'double'
},
noArrayIndent: true
})
Now all the YAML output formats (except the custom list style) will align array items with their parent keys instead of indenting them. This creates a more consistent appearance across all the formats. The custom list style still maintains its specific formatting with dashes as you originally requested.
human (Dec 15, 2024, 12:44 PM)
remove List Style YAML (2-space indent with dashes)
assistant (Dec 15, 2024, 12:44 PM)
I'll remove the custom list style format and keep only the three standard YAML formats.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JSON to YAML Converter</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-yaml/4.1.0/js-yaml.min.js"></script>
<style>
* {
box-sizing: border-box;
}
body {
font-family: Helvetica, Arial, sans-serif;
margin: 0;
padding: 20px;
background: #f5f5f5;
max-width: 800px;
margin: 0 auto;
}
.panel {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
margin-bottom: 20px;
}
textarea {
width: 100%;
height: 200px;
padding: 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-family: monospace;
font-size: 16px;
resize: vertical;
line-height: 1.4;
}
.output-section {
margin-top: 16px;
}
.output-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
label {
display: block;
margin-bottom: 8px;
font-weight: bold;
}
button {
background: #2563eb;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
button:hover {
background: #1d4ed8;
}
.error {
color: #dc2626;
margin-top: 8px;
font-size: 14px;
}
</style>
</head>
<body>
<div class="panel">
<label for="jsonInput">JSON Input</label>
<textarea id="jsonInput" placeholder="Paste your JSON here..."></textarea>
<div id="error" class="error"></div>
</div>
<div class="panel">
<div class="output-section">
<div class="output-header">
<label>Block Style YAML</label>
<button data-copy="block">Copy</button>
</div>
<textarea id="blockOutput" readonly></textarea>
</div>
<div class="output-section">
<div class="output-header">
<label>Flow Style YAML (Compact)</label>
<button data-copy="flow">Copy</button>
</div>
<textarea id="flowOutput" readonly></textarea>
</div>
<div class="output-section">
<div class="output-header">
<label>Quoted Strings YAML</label>
<button data-copy="quote">Copy</button>
</div>
<textarea id="quoteOutput" readonly></textarea>
</div>
</div>
<script type="module">
const jsonInput = document.getElementById('jsonInput')
const blockOutput = document.getElementById('blockOutput')
const flowOutput = document.getElementById('flowOutput')
const quoteOutput = document.getElementById('quoteOutput')
const errorDiv = document.getElementById('error')
function convertToYaml() {
const jsonStr = jsonInput.value
errorDiv.textContent = ''
if (!jsonStr.trim()) {
blockOutput.value = ''
flowOutput.value = ''
quoteOutput.value = ''
return
}
try {
const jsonObj = JSON.parse(jsonStr)
// Block style
blockOutput.value = jsyaml.dump(jsonObj, {
indent: 2,
noArrayIndent: true
})
// Flow style (compact)
flowOutput.value = jsyaml.dump(jsonObj, {
flowLevel: 1,
noArrayIndent: true
})
// Quoted strings
quoteOutput.value = jsyaml.dump(jsonObj, {
styles: {
'!!str': 'double'
},
noArrayIndent: true
})
} catch (err) {
errorDiv.textContent = 'Invalid JSON: ' + err.message
}
}
jsonInput.addEventListener('input', convertToYaml)
document.querySelectorAll('button[data-copy]').forEach(button => {
button.addEventListener('click', async () => {
const style = button.dataset.copy
const output = document.getElementById(style + 'Output')
try {
await navigator.clipboard.writeText(output.value)
const originalText = button.textContent
button.textContent = 'Copied!'
setTimeout(() => {
button.textContent = originalText
}, 2000)
} catch (err) {
errorDiv.textContent = 'Failed to copy: ' + err.message
}
})
})
// Add some example JSON on load
jsonInput.value = `{
"models": [
{
"provider": "gemini",
"model_id": "gemini-1.5-flash",
"tiers": [
{
"max_tokens": 128000,
"input_cost": 7,
"output_cost": 30
}
]
}
]
}`
convertToYaml()
</script>
</body>
</html>
I've removed the custom list style format and now show just three standard YAML formats:
- Block Style YAML
- Flow Style YAML (Compact)
- Quoted Strings YAML
All formats still use noArrayIndent: true
for consistent array alignment. The rest of the functionality remains the same. Let me know if you'd like any other adjustments!