Skip to content

Commit 71a762d

Browse files
authored
1 parent d47fdbd commit 71a762d

File tree

1 file changed

+216
-0
lines changed

1 file changed

+216
-0
lines changed

sql-pretty-printer.html

+216
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>SQL Pretty Printer</title>
6+
<style>
7+
* {
8+
box-sizing: border-box;
9+
}
10+
11+
body {
12+
font-family: Helvetica, Arial, sans-serif;
13+
max-width: 800px;
14+
margin: 0 auto;
15+
padding: 20px;
16+
}
17+
18+
h1 {
19+
color: #333;
20+
margin-bottom: 24px;
21+
}
22+
23+
.container {
24+
display: flex;
25+
flex-direction: column;
26+
gap: 20px;
27+
}
28+
29+
.field {
30+
display: flex;
31+
flex-direction: column;
32+
gap: 8px;
33+
}
34+
35+
label {
36+
font-weight: bold;
37+
color: #555;
38+
}
39+
40+
textarea {
41+
width: 100%;
42+
min-height: 200px;
43+
padding: 12px;
44+
border: 1px solid #ccc;
45+
border-radius: 4px;
46+
font-size: 16px;
47+
font-family: monospace;
48+
resize: vertical;
49+
}
50+
51+
textarea:focus {
52+
outline: none;
53+
border-color: #666;
54+
}
55+
56+
.controls {
57+
display: flex;
58+
flex-wrap: wrap;
59+
gap: 16px;
60+
margin-bottom: 20px;
61+
}
62+
63+
.control-group {
64+
display: flex;
65+
align-items: center;
66+
gap: 8px;
67+
}
68+
69+
select {
70+
padding: 8px;
71+
border: 1px solid #ccc;
72+
border-radius: 4px;
73+
font-size: 16px;
74+
}
75+
76+
.copy-button {
77+
display: none;
78+
margin-top: 8px;
79+
padding: 8px 16px;
80+
background: #007bff;
81+
color: white;
82+
border: none;
83+
border-radius: 4px;
84+
cursor: pointer;
85+
font-size: 14px;
86+
}
87+
88+
.copy-button:hover {
89+
background: #0056b3;
90+
}
91+
92+
input[type="number"] {
93+
width: 60px;
94+
padding: 8px;
95+
border: 1px solid #ccc;
96+
border-radius: 4px;
97+
font-size: 16px;
98+
}
99+
100+
input[type="checkbox"] {
101+
width: 16px;
102+
height: 16px;
103+
}
104+
</style>
105+
</head>
106+
<body>
107+
<h1>SQL Pretty Printer</h1>
108+
109+
<div class="container">
110+
<div class="controls">
111+
<div class="control-group">
112+
<label for="dialect">Dialect:</label>
113+
<select id="dialect">
114+
<option value="sqlite">SQLite</option>
115+
<option value="sql">Standard SQL</option>
116+
<option value="postgresql">PostgreSQL</option>
117+
<option value="mysql">MySQL</option>
118+
</select>
119+
</div>
120+
121+
<div class="control-group">
122+
<label for="tabWidth">Tab width:</label>
123+
<input type="number" id="tabWidth" value="2" min="1" max="8">
124+
</div>
125+
126+
<div class="control-group">
127+
<label for="keywordCase">Keyword case:</label>
128+
<select id="keywordCase">
129+
<option value="preserve">preserve</option>
130+
<option value="upper">UPPER</option>
131+
<option value="lower">lower</option>
132+
</select>
133+
</div>
134+
135+
<div class="control-group">
136+
<label for="indentStyle">Indent style:</label>
137+
<select id="indentStyle">
138+
<option value="standard">Standard</option>
139+
<option value="tabularLeft">Tabular (left)</option>
140+
<option value="tabularRight">Tabular (right)</option>
141+
</select>
142+
</div>
143+
</div>
144+
145+
<div class="field">
146+
<label for="input">Input SQL:</label>
147+
<textarea id="input" spellcheck="false"></textarea>
148+
</div>
149+
150+
<div class="field">
151+
<label for="output">Formatted SQL:</label>
152+
<textarea id="output" readonly spellcheck="false"></textarea>
153+
</div>
154+
155+
<button class="copy-button">Copy to clipboard</button>
156+
</div>
157+
158+
<script src="https://cdnjs.cloudflare.com/ajax/libs/sql-formatter/12.2.3/sql-formatter.min.js"></script>
159+
<script type="module">
160+
const inputArea = document.getElementById('input')
161+
const outputArea = document.getElementById('output')
162+
const copyButton = document.querySelector('.copy-button')
163+
const dialectSelect = document.getElementById('dialect')
164+
const tabWidthInput = document.getElementById('tabWidth')
165+
const uppercaseCheckbox = document.getElementById('uppercase')
166+
const keywordCaseSelect = document.getElementById('keywordCase')
167+
const indentStyleSelect = document.getElementById('indentStyle')
168+
169+
function formatSQL(sql) {
170+
if (!sql.trim()) return ''
171+
172+
try {
173+
const options = {
174+
language: dialectSelect.value,
175+
tabWidth: parseInt(tabWidthInput.value, 10),
176+
keywordCase: keywordCaseSelect.value,
177+
indentStyle: indentStyleSelect.value
178+
}
179+
180+
return sqlFormatter.format(sql, options)
181+
} catch (err) {
182+
return `Error formatting SQL: ${err.message}`
183+
}
184+
}
185+
186+
function updateFormatting() {
187+
const formatted = formatSQL(inputArea.value)
188+
outputArea.value = formatted
189+
copyButton.style.display = formatted ? 'block' : 'none'
190+
}
191+
192+
// Add event listeners to all controls
193+
const controls = [
194+
inputArea, dialectSelect, tabWidthInput,
195+
keywordCaseSelect, indentStyleSelect
196+
]
197+
198+
controls.forEach(control => {
199+
control.addEventListener('input', updateFormatting)
200+
control.addEventListener('change', updateFormatting)
201+
})
202+
203+
copyButton.addEventListener('click', async () => {
204+
try {
205+
await navigator.clipboard.writeText(outputArea.value)
206+
copyButton.textContent = 'Copied!'
207+
setTimeout(() => {
208+
copyButton.textContent = 'Copy to clipboard'
209+
}, 1500)
210+
} catch (err) {
211+
console.error('Failed to copy:', err)
212+
}
213+
})
214+
</script>
215+
</body>
216+
</html>

0 commit comments

Comments
 (0)