Formateador de Código

Formatea y limpia código HTML, CSS y JavaScript

<> Formateador de Código Web

Formatea, valida y limpia código HTML, CSS y JavaScript de manera profesional

Seleccionar Lenguaje

Acciones

Código de Entrada

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

Resultado Formateado


                                
📊

Análisis de Código

Lenguaje: --
Tamaño: --
Etiquetas HTML: --
Clases CSS: --
Funciones JS: --

Herramientas

📚

Consejos

Mejores prácticas para código limpio:

  • Usa indentación consistente
  • Comenta tu código cuando sea necesario
  • Sigue las convenciones del lenguaje
  • Valida tu código regularmente
Operación completada
`, minified: `Sitio Minificado

Hola Mundo

Este es un ejemplo de código minificado.

` }; // Initialize updateLineNumbers(codeInput, inputLineNumbers); updateInputStats(); detectLanguage(); setupEventListeners(); // Set default example formatCode(); function setupEventListeners() { // Input events codeInput.addEventListener('input', () => { updateLineNumbers(codeInput, inputLineNumbers); updateInputStats(); detectLanguage(); }); codeInput.addEventListener('keydown', (e) => { if (e.key === 'Tab') { e.preventDefault(); const start = codeInput.selectionStart; const end = codeInput.selectionEnd; const indent = indentSize.value === 'tab' ? '\t' : ' '.repeat(parseInt(indentSize.value)); codeInput.value = codeInput.value.substring(0, start) + indent + codeInput.value.substring(end); codeInput.selectionStart = codeInput.selectionEnd = start + indent.length; updateLineNumbers(codeInput, inputLineNumbers); updateInputStats(); } }); // Language tabs languageTabs.forEach(tab => { tab.addEventListener('click', () => { languageTabs.forEach(t => t.classList.remove('active')); tab.classList.add('active'); currentLanguage = tab.dataset.lang; languageIndicator.textContent = currentLanguage.toUpperCase(); // Update examples based on language updateExamplesForLanguage(); showToast(`Modo ${tab.textContent} activado`, 'success'); }); }); // Button events formatBtn.addEventListener('click', formatCode); minifyBtn.addEventListener('click', minifyCode); validateBtn.addEventListener('click', validateCode); cleanBtn.addEventListener('click', cleanCode); clearBtn.addEventListener('click', () => { codeInput.value = ''; codeOutput.textContent = ''; outputLineNumbers.innerHTML = ''; updateLineNumbers(codeInput, inputLineNumbers); updateInputStats(); updateOutputStats(); resetCodeInfo(); showToast('Entrada limpiada', 'success'); }); copyBtn.addEventListener('click', copyOutput); downloadBtn.addEventListener('click', downloadCode); pasteExampleBtn.addEventListener('click', pasteExample); clearInputBtn.addEventListener('click', () => { codeInput.value = ''; updateLineNumbers(codeInput, inputLineNumbers); updateInputStats(); }); // Quick action buttons quickActionBtns.forEach(btn => { btn.addEventListener('click', () => { const example = btn.dataset.example; codeInput.value = examples[example]; updateLineNumbers(codeInput, inputLineNumbers); updateInputStats(); detectLanguage(); if (example === 'minified') { showToast('Código minificado cargado', 'warning'); } else { formatCode(); showToast(`Ejemplo "${btn.textContent}" cargado`, 'success'); } }); }); // Tool buttons extractCssBtn.addEventListener('click', extractCSS); extractJsBtn.addEventListener('click', extractJavaScript); compressBtn.addEventListener('click', compressCode); convertHtmlBtn.addEventListener('click', convertToJSX); // Modal closeErrorModal.addEventListener('click', () => { errorModal.style.display = 'none'; }); tryFixBtn.addEventListener('click', tryFixCode); // Settings change events [indentSize, lineWrap, quoteStyle].forEach(select => { select.addEventListener('change', formatCode); }); [preserveNewlines, wrapAttributes, endWithNewline].forEach(checkbox => { checkbox.addEventListener('change', formatCode); }); } function updateLineNumbers(textarea, lineNumbersElement) { const lines = textarea.value.split('\n').length; let numbers = ''; for (let i = 1; i <= lines; i++) { numbers += i + '
'; } lineNumbersElement.innerHTML = numbers; } function updateOutputLineNumbers(text) { const lines = text.split('\n').length; let numbers = ''; for (let i = 1; i <= lines; i++) { numbers += i + '
'; } outputLineNumbers.innerHTML = numbers; } function updateInputStats() { const text = codeInput.value; const chars = text.length; const lines = text.split('\n').length; const words = text.trim() === '' ? 0 : text.trim().split(/\s+/).length; inputStats.textContent = `Caracteres: ${chars} | Líneas: ${lines} | Palabras: ${words}`; } function updateOutputStats() { const text = codeOutput.textContent; const chars = text.length; const lines = text.split('\n').length; outputStats.textContent = `Caracteres: ${chars} | Líneas: ${lines}`; } function detectLanguage() { const code = codeInput.value.trim(); if (!code) { infoLanguage.textContent = '--'; return; } // Simple language detection if (code.includes(']+>)/g; formatted = formatted.replace(htmlRegex, (match) => { try { return html_beautify(match, { indent_size: 4, indent_char: ' ', preserve_newlines: false }); } catch { return match; } }); // Format CSS parts const cssRegex = /({[^}]+})/g; formatted = formatted.replace(cssRegex, (match) => { try { return css_beautify(match, { indent_size: 4, indent_char: ' ' }); } catch { return match; } }); // Format JS parts const jsRegex = /(function\s*\([^)]*\)\s*{[^}]+})/g; formatted = formatted.replace(jsRegex, (match) => { try { return js_beautify(match, { indent_size: 4, indent_char: ' ' }); } catch { return match; } }); return formatted; } function minifyCode() { try { const code = codeInput.value.trim(); if (!code) { codeOutput.textContent = ''; updateOutputLineNumbers(''); updateOutputStats(); return; } let minified = code; // Minify based on language if (currentLanguage === 'html' || infoLanguage.textContent === 'HTML') { minified = minifyHTML(code); } else if (currentLanguage === 'css' || infoLanguage.textContent === 'CSS') { minified = minifyCSS(code); } else if (currentLanguage === 'js' || infoLanguage.textContent === 'JavaScript') { minified = minifyJS(code); } else { minified = minifyMixedCode(code); } codeOutput.innerHTML = syntaxHighlight(minified, currentLanguage); updateOutputLineNumbers(minified); updateOutputStats(); // Update validation status validationStatus.textContent = '✓ Código minificado'; validationStatus.className = 'stat-item valid'; // Update code info updateCodeInfo(minified); showToast('Código minificado correctamente', 'success'); } catch (error) { showError(error); } } function minifyHTML(html) { return html .replace(/\s+/g, ' ') .replace(/>\s+<') .replace(//g, '') .trim(); } function minifyCSS(css) { return css .replace(/\/\*[\s\S]*?\*\//g, '') .replace(/\s+/g, ' ') .replace(/;\s+/g, ';') .replace(/:\s+/g, ':') .replace(/\s*{\s*/g, '{') .replace(/\s*}\s*/g, '}') .trim(); } function minifyJS(js) { return js .replace(/\/\/.*$/gm, '') .replace(/\/\*[\s\S]*?\*\//g, '') .replace(/\s+/g, ' ') .replace(/\s*([=+\-*\/<>!&|^%?:,;{}()[\]])\s*/g, '$1') .trim(); } function minifyMixedCode(code) { return code .replace(/\/\/.*$/gm, '') .replace(/\/\*[\s\S]*?\*\//g, '') .replace(/\s+/g, ' ') .replace(/>\s+<') .trim(); } function validateCode() { try { const code = codeInput.value.trim(); if (!code) { validationStatus.textContent = 'Ingresa código para validar'; validationStatus.className = 'stat-item warning'; return; } // Simple validation based on language let isValid = true; let message = ''; if (currentLanguage === 'html' || infoLanguage.textContent === 'HTML') { isValid = validateHTML(code); message = isValid ? '✓ HTML válido' : '✗ HTML inválido'; } else if (currentLanguage === 'css' || infoLanguage.textContent === 'CSS') { isValid = validateCSS(code); message = isValid ? '✓ CSS válido' : '✗ CSS inválido'; } else if (currentLanguage === 'js' || infoLanguage.textContent === 'JavaScript') { isValid = validateJS(code); message = isValid ? '✓ JavaScript válido' : '✗ JavaScript inválido'; } else { isValid = true; message = '✓ Código mixto válido'; } validationStatus.textContent = message; validationStatus.className = isValid ? 'stat-item valid' : 'stat-item error'; if (isValid) { showToast('Código válido', 'success'); } else { showError(new Error('Código inválido detectado')); } } catch (error) { showError(error); } } function validateHTML(html) { try { // Create a temporary div to parse HTML const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); // Check for parsing errors const errors = doc.querySelectorAll('parsererror'); return errors.length === 0; } catch { return false; } } function validateCSS(css) { try { // Create a style element to test CSS const style = document.createElement('style'); style.textContent = css; document.head.appendChild(style); // Check if CSS is valid by trying to parse it const sheet = style.sheet; const isValid = sheet !== null; document.head.removeChild(style); return isValid; } catch { return false; } } function validateJS(js) { try { // Try to parse JavaScript new Function(js); return true; } catch { return false; } } function cleanCode() { try { let code = codeInput.value; // Remove trailing whitespace code = code.replace(/\s+$/gm, ''); // Remove multiple blank lines code = code.replace(/\n\s*\n\s*\n/g, '\n\n'); // Normalize line endings code = code.replace(/\r\n/g, '\n'); codeInput.value = code; updateLineNumbers(codeInput, inputLineNumbers); updateInputStats(); formatCode(); showToast('Código limpiado correctamente', 'success'); } catch (error) { showError(error); } } function copyOutput() { const text = codeOutput.textContent; if (!text) { showToast('No hay contenido para copiar', 'warning'); return; } navigator.clipboard.writeText(text) .then(() => { showToast('Código copiado al portapapeles', 'success'); }) .catch(() => { // Fallback for older browsers const textArea = document.createElement('textarea'); textArea.value = text; document.body.appendChild(textArea); textArea.select(); document.execCommand('copy'); document.body.removeChild(textArea); showToast('Código copiado al portapapeles', 'success'); }); } function downloadCode() { const text = codeOutput.textContent; if (!text) { showToast('No hay contenido para descargar', 'warning'); return; } let extension = '.txt'; if (currentLanguage === 'html') extension = '.html'; else if (currentLanguage === 'css') extension = '.css'; else if (currentLanguage === 'js') extension = '.js'; const blob = new Blob([text], { type: 'text/plain' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `codigo_${Date.now()}${extension}`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); showToast('Código descargado correctamente', 'success'); } function pasteExample() { codeInput.value = examples[currentLanguage] || examples.html; updateLineNumbers(codeInput, inputLineNumbers); updateInputStats(); detectLanguage(); formatCode(); showToast('Ejemplo cargado', 'success'); } function extractCSS() { try { const code = codeInput.value; const styleRegex = /([\s\S]*?)<\/style>/gi; const inlineStyleRegex = /style="([^"]*)"/gi; let css = ''; let match; // Extract internal CSS while ((match = styleRegex.exec(code)) !== null) { css += match[1] + '\n'; } // Extract inline CSS (optional) if (css === '') { while ((match = inlineStyleRegex.exec(code)) !== null) { css += match[1] + '\n'; } } if (css.trim() === '') { showToast('No se encontró CSS para extraer', 'warning'); return; } codeOutput.textContent = css.trim(); updateOutputLineNumbers(css.trim()); updateOutputStats(); validationStatus.textContent = 'CSS extraído'; validationStatus.className = 'stat-item info'; showToast('CSS extraído correctamente', 'success'); } catch (error) { showError(error); } } function extractJavaScript() { try { const code = codeInput.value; const scriptRegex = /([\s\S]*?)<\/script>/gi; let js = ''; let match; while ((match = scriptRegex.exec(code)) !== null) { js += match[1] + '\n'; } if (js.trim() === '') { showToast('No se encontró JavaScript para extraer', 'warning'); return; } codeOutput.textContent = js.trim(); updateOutputLineNumbers(js.trim()); updateOutputStats(); validationStatus.textContent = 'JavaScript extraído'; validationStatus.className = 'stat-item info'; showToast('JavaScript extraído correctamente', 'success'); } catch (error) { showError(error); } } function compressCode() { try { let code = codeOutput.textContent || codeInput.value; if (!code.trim()) { showToast('Ingresa código primero', 'warning'); return; } // Simple compression (remove comments and extra spaces) let compressed = code .replace(/\/\/.*$/gm, '') .replace(/\/\*[\s\S]*?\*\//g, '') .replace(/\s+/g, ' ') .replace(/;\s+/g, ';') .replace(/:\s+/g, ':') .trim(); codeOutput.textContent = compressed; updateOutputLineNumbers(compressed); updateOutputStats(); validationStatus.textContent = 'Código comprimido'; validationStatus.className = 'stat-item info'; showToast('Código comprimido correctamente', 'success'); } catch (error) { showError(error); } } function convertToJSX() { try { let html = codeInput.value.trim(); if (!html) { showToast('Ingresa HTML primero', 'warning'); return; } // Simple HTML to JSX conversion let jsx = html .replace(/class=/g, 'className=') .replace(/for=/g, 'htmlFor=') .replace(/\s+/g, ' ') .replace(//g, ''); // Wrap in a React component jsx = `import React from 'react'; function Component() { return ( ${jsx} ); } export default Component;`; codeOutput.textContent = jsx; updateOutputLineNumbers(jsx); updateOutputStats(); validationStatus.textContent = 'Convertido a JSX'; validationStatus.className = 'stat-item info'; showToast('Convertido a JSX', 'success'); } catch (error) { showError(error); } } function updateExamplesForLanguage() { // Update quick actions based on current language quickActionBtns.forEach(btn => { const example = btn.dataset.example; if (example === currentLanguage || (currentLanguage === 'html' && example === 'responsive') || (currentLanguage === 'html' && example === 'bootstrap')) { btn.style.display = 'flex'; } else if (example === 'minified') { btn.style.display = 'flex'; } else { btn.style.display = 'none'; } }); } function showError(error) { const message = error.message; const position = findErrorPosition(codeInput.value, error); errorMessage.textContent = message; errorPosition.textContent = position ? `Posición: ${position}` : ''; errorModal.style.display = 'flex'; validationStatus.textContent = '✗ Error en el código'; validationStatus.className = 'stat-item error'; codeOutput.textContent = `Error: ${message}`; updateOutputLineNumbers(codeOutput.textContent); updateOutputStats(); resetCodeInfo(); } function tryFixCode() { const code = codeInput.value; // Try to fix common issues let fixed = code .replace(/“/g, '"') .replace(/”/g, '"') .replace(/‘/g, "'") .replace(/’/g, "'") .replace(/ /g, ' ') .replace(/
/g, '
'); codeInput.value = fixed; updateLineNumbers(codeInput, inputLineNumbers); updateInputStats(); formatCode(); errorModal.style.display = 'none'; showToast('Código corregido automáticamente', 'warning'); } function showToast(message, type = 'info') { toastMessage.textContent = message; successToast.className = `toast toast-${type}`; successToast.style.display = 'flex'; setTimeout(() => { successToast.style.display = 'none'; }, 3000); } function updateCodeInfo(code) { infoSize.textContent = formatBytes(code.length); // Count HTML tags const tagCount = (code.match(/<(\w+)[^>]*>/g) || []).length; infoTags.textContent = tagCount; // Count CSS classes const classCount = (code.match(/class=["'][^"']*["']/g) || []).length; infoClasses.textContent = classCount; // Count JS functions const functionCount = (code.match(/(function|const|let|var)\s+\w+\s*=/g) || []).length; infoFunctions.textContent = functionCount; } function resetCodeInfo() { infoSize.textContent = '--'; infoTags.textContent = '--'; infoClasses.textContent = '--'; infoFunctions.textContent = '--'; } // Utility functions function formatBytes(bytes) { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; } function syntaxHighlight(code, language) { if (typeof code != 'string') { code = String(code); } code = code.replace(/&/g, '&').replace(//g, '>'); // HTML highlighting if (language === 'html' || language === 'mixed') { code = code.replace(/(<\/?)(\w+)([^&]*>)/g, function(match, open, tag, rest) { return `${open}${tag}${rest}`; }); code = code.replace(/(\w+)=/g, '$1='); code = code.replace(/("([^"]*)")/g, '$1'); } // CSS highlighting if (language === 'css' || language === 'mixed') { code = code.replace(/([.#]?\w+)\s*{/g, '$1 {'); code = code.replace(/(\w+):/g, '$1:'); code = code.replace(/(#[0-9a-fA-F]{3,6}|\b\d+\b)/g, '$1'); } // JS highlighting if (language === 'js' || language === 'mixed') { const keywords = ['function', 'const', 'let', 'var', 'if', 'else', 'for', 'while', 'return', 'class', 'new', 'try', 'catch', 'async', 'await']; keywords.forEach(keyword => { const regex = new RegExp(`\\b${keyword}\\b`, 'g'); code = code.replace(regex, `${keyword}`); }); code = code.replace(/(\w+)\(/g, '$1('); code = code.replace(/(\/\/.*$)/gm, '$1'); } return code; } function findErrorPosition(text, error) { const match = error.message.match(/position (\d+)/); if (match) { const position = parseInt(match[1]); const lines = text.substring(0, position).split('\n'); const line = lines.length; const column = lines[lines.length - 1].length + 1; return `Línea ${line}, Columna ${column}`; } return null; } });