| |
|
| | document.addEventListener('DOMContentLoaded', function() { |
| | |
| | const inputText = document.getElementById('inputText'); |
| | const outputContainer = document.getElementById('outputContainer'); |
| | const formatBtn = document.getElementById('formatBtn'); |
| | const copyBtn = document.getElementById('copyBtn'); |
| | const downloadBtn = document.getElementById('downloadBtn'); |
| | const clearBtn = document.getElementById('clearBtn'); |
| | const languageSelect = document.getElementById('languageSelect'); |
| | const uppercaseCheck = document.getElementById('uppercaseCheck'); |
| | |
| | |
| | const tabuWords = { |
| | PT: ['o', 'a', 'os', 'as', 'um', 'uma', 'me', 'te', 'se', 'lhe', 'nos', 'de', 'do', 'da', 'em', 'no', 'na', 'por', 'para', 'com', 'ao', 'e', 'ou', 'mas', 'que', 'como', 'porque', 'quando', 'ent茫o', 's贸', 'j谩', 'tamb茅m', 'tipo', 'nosso', 'nossa', 'at茅', 'sem', 'sob', 'sobre', 'tr谩s', 'ante', 'ap贸s', 'entre', 'durante', 'desde', 'perante', 'mal', 'bem', 'muito', 'pouco', 't茫o', 'mais', 'menos', 'tal', 'qual', 'seu', 'sua', 'seus', 'suas', 'meu', 'minha', 'meus', 'minhas', 'teu', 'tua', 'teus', 'tuas', 'nosso', 'nossa', 'nossos', 'nossas', 'vosso', 'vossa', 'vossos', 'vossas', 'este', 'esta', 'estes', 'estas', 'isto', 'esse', 'essa', 'esses', 'essas', 'isso', 'aquele', 'aquela', 'aqueles', 'aquelas', 'aquilo', 'cada', 'todo', 'toda', 'todos', 'todas', 'outro', 'outra', 'outros', 'outras', 'mesmo', 'mesma', 'mesmos', 'mesmas', 'pr贸prio', 'pr贸pria', 'pr贸prios', 'pr贸prias', 'demais', 'demais', 'certo', 'certa', 'certos', 'certas', 'diverso', 'diversa', 'diversos', 'diversas', 'algum', 'alguma', 'alguns', 'algumas', 'nenhum', 'nenhuma', 'nenhuns', 'nenhumas', 'muito', 'muita', 'muitos', 'muitas', 'pouco', 'pouca', 'poucos', 'poucas', 'tanto', 'tanta', 'tantos', 'tantas', 'quanto', 'quanta', 'quantos', 'quantas', 'varios', 'varias', 'bastante', 'suficiente', 'demais', 'demasiado', 'menos', 'mais', 'melhor', 'pior', 'maior', 'menor', 'talvez', 'acaso', 'caso', 'vez', 'vezes', 'hora', 'horas', 'dia', 'dias', 'noite', 'noites', 'manh茫', 'tarde', 'tarde', 'ano', 'anos', 'm锚s', 'meses', 'semana', 'semanas', 'hoje', 'ontem', 'amanh茫', 'antes', 'depois', 'agora', 'sempre', 'nunca', 'ainda', 'j谩', 'logo', 'depois', 'cedo', 'tarde', 'cedo', 'tarde', 'longe', 'perto', 'acima', 'abaixo', 'dentro', 'fora', 'atr谩s', 'diante', 'frente', 'meio', 'lado', 'outro', 'mesmo', 'pr贸ximo', 'distante', 'junto', 'separado', 'certo', 'duro', 'f谩cil', 'dif铆cil', 'poss铆vel', 'imposs铆vel', 'necess谩rio', 'importante', 'grande', 'pequeno', 'alto', 'baixo', 'comprido', 'curto', 'largo', 'estreito', 'grosso', 'fino', 'cheio', 'vazio', 'claro', 'escuro', 'quente', 'frio', 'seco', 'molhado', 'limpo', 'sujo', 'novo', 'velho', 'antigo', 'moderno', 'bonito', 'feio', 'bom', 'mau', 'melhor', 'pior', 'caro', 'barato', 'r谩pido', 'lento', 'certo', 'errado', 'verdadeiro', 'falso', 'real', 'fict铆cio', 'verdade', 'mentira', 'verdadeiro', 'falso', 'certo', 'incerto', 'seguro', 'perigoso', 'tranquilo', 'agitado', 'calmo', 'nervoso', 'alegre', 'triste', 'feliz', 'infeliz', 'contente', 'descontente', 'satisfeito', 'insatisfeito', 'orgulhoso', 'envergonhado', 'surpreso', 'indiferente', 'interessado', 'entediado', 'cansado', 'descansado', 'faminto', 'satisfeito', 'sede', 'satisfeito', 'com fome', 'com sede', 'com sono', 'acordado', 'dormindo', 'vivo', 'morto', 'nascendo', 'morrendo', 'crescendo', 'diminuindo', 'aumentando', 'diminuindo', 'subindo', 'descendo', 'entrando', 'saindo', 'chegando', 'partindo', 'indo', 'vindo', 'ficando', 'saindo', 'voltando', 'retornando', 'continuando', 'parando', 'come莽ando', 'terminando', 'iniciando', 'finalizando', 'abrindo', 'fechando', 'ligando', 'desligando', 'acendendo', 'apagando', 'acendendo', 'apagando', 'aquecendo', 'esfriando', 'secando', 'molhando', 'limpando', 'sujando', 'enchendo', 'esvaziando', 'cheio', 'vazio', 'claro', 'escuro', 'quente', 'frio', 'seco', 'molhado', 'limpo', 'sujo', 'novo', 'velho', 'antigo', 'moderno', 'bonito', 'feio', 'bom', 'mau', 'melhor', 'pior', 'caro', 'barato', 'r谩pido', 'lento', 'certo', 'errado', 'verdadeiro', 'falso', 'real', 'fict铆cio', 'verdade', 'mentira', 'verdadeiro', 'falso', 'certo', 'incerto', 'seguro', 'perigoso', 'tranquilo', 'agitado', 'calmo', 'nervoso', 'alegre', 'triste', 'feliz', 'infeliz', 'contente', 'descontente', 'satisfeito', 'insatisfeito', 'orgulhoso', 'envergonhado', 'surpreso', 'indiferente', 'interessado', 'entediado', 'cansado', 'descansado', 'faminto', 'satisfeito', 'sede', 'satisfeito', 'com fome', 'com sede', 'com sono', 'acordado', 'dormindo', 'vivo', 'morto', 'nascendo', 'morrendo', 'crescendo', 'diminuindo', 'aumentando', 'diminuindo', 'subindo', 'descendo', 'entrando', 'saindo', 'chegando', 'partindo', 'indo', 'vindo', 'ficando', 'saindo', 'voltando', 'retornando', 'continuando', 'parando', 'come莽ando', 'terminando', 'iniciando', 'finalizando', 'abrindo', 'fechando', 'ligando', 'desligando', 'acendendo', 'apagando', 'acendendo', 'apagando', 'aquecendo', 'esfriando', 'secando', 'molhando', 'limpando', 'sujando', 'enchendo', 'esvaziando'], |
| | EN: ['a', 'an', 'the', 'of', 'in', 'on', 'at', 'to', 'for', 'with', 'from', 'by', 'and', 'or', 'but', 'that', 'me', 'you', 'it', 'he', 'she', 'we', 'they', 'us', 'them', 'his', 'her', 'its', 'our', 'their', 'myself', 'yourself', 'himself', 'herself', 'itself', 'ourselves', 'yourselves', 'themselves', 'this', 'that', 'these', 'those', 'some', 'any', 'many', 'much', 'few', 'little', 'more', 'most', 'other', 'another', 'such', 'same', 'different', 'own', 'main', 'only', 'very', 'quite', 'rather', 'fairly', 'pretty', 'really', 'extremely', 'incredibly', 'absolutely', 'totally', 'completely', 'entirely', 'fully', 'wholly', 'altogether', 'exceedingly', 'intensely', 'highly', 'greatly', 'seriously', 'badly', 'terribly', 'awfully', 'horribly', 'dreadfully', 'frightfully', 'terribly', 'awfully', 'horribly', 'dreadfully', 'frightfully', 'badly', 'seriously', 'greatly', 'highly', 'intensely', 'exceedingly', 'altogether', 'wholly', 'fully', 'entirely', 'completely', 'totally', 'absolutely', 'incredibly', 'extremely', 'really', 'pretty', 'fairly', 'rather', 'quite', 'very', 'only', 'main', 'own', 'different', 'same', 'such', 'another', 'other', 'most', 'more', 'little', 'few', 'much', 'many', 'any', 'some', 'those', 'these', 'that', 'this', 'themselves', 'yourselves', 'ourselves', 'itself', 'herself', 'himself', 'yourself', 'myself', 'their', 'our', 'its', 'her', 'his', 'them', 'us', 'they', 'we', 'she', 'he', 'it', 'you', 'me', 'but', 'or', 'and', 'by', 'from', 'with', 'for', 'to', 'at', 'on', 'in', 'of', 'the', 'an', 'a'], |
| | ES: ['de', 'en', 'a', 'por', 'para', 'con', 'y', 'que', 'el', 'la', 'los', 'las', 'un', 'una', 'unos', 'unas', 'me', 'te', 'se', 'nos', 'os', 'le', 'les', 'lo', 'la', 'los', 'las', 'mi', 'tu', 'su', 'nuestro', 'vuestra', 'este', 'ese', 'aquel', 'esta', 'esa', 'aquella', 'estos', 'esos', 'aquellos', 'estas', 'esas', 'aquellas', 'esto', 'eso', 'aquello', 'cada', 'todo', 'toda', 'todos', 'todas', 'otro', 'otra', 'otros', 'otras', 'mismo', 'misma', 'mismos', 'mismas', 'pr贸ximo', 'pr贸xima', 'pr贸ximos', 'pr贸ximas', 'distante', 'distantes', 'junto', 'juntos', 'junta', 'juntas', 'separado', 'separados', 'separada', 'separadas', 'cierto', 'cierta', 'ciertos', 'ciertas', 'duro', 'duros', 'dura', 'duras', 'f谩cil', 'f谩ciles', 'dif铆cil', 'dif铆ciles', 'posible', 'posibles', 'imposible', 'imposibles', 'necesario', 'necesarios', 'necesaria', 'necesarias', 'importante', 'importantes', 'grande', 'grandes', 'peque帽o', 'peque帽a', 'peque帽os', 'peque帽as', 'alto', 'altos', 'alta', 'altas', 'bajo', 'bajos', 'baja', 'bajas', 'comprido', 'compridos', 'comprida', 'compridas', 'largo', 'largos', 'larga', 'largas', 'corto', 'cortos', 'corta', 'cortas', 'estrecho', 'estrechos', 'estrecha', 'estrechas', 'grosso', 'grueso', 'grosa', 'gruesa', 'grosos', 'gruesos', 'finos', 'fino', 'fina', 'finas', 'cheio', 'lleno', 'cheios', 'llenos', 'cheia', 'llena', 'cheias', 'llenas', 'vazio', 'vac铆o', 'vazios', 'vac铆os', 'vazia', 'vac铆a', 'vazias', 'vac铆as', 'claro', 'clara', 'claros', 'claras', 'escuro', 'oscuro', 'escura', 'oscura', 'escuros', 'oscuros', 'escuras', 'oscuras', 'quente', 'caliente', 'quentes', 'calientes', 'frio', 'fr铆o', 'fria', 'fr铆a', 'frios', 'fr铆os', 'frias', 'fr铆as', 'seco', 'secos', 'seca', 'secas', 'molhado', 'mojado', 'molhados', 'mojados', 'molhada', 'mojada', 'molhadas', 'mojadas', 'limpo', 'limpios', 'limpia', 'limpias', 'sujo', 'sucio', 'sujos', 'sucios', 'suja', 'sucia', 'sujas', 'sucias', 'novo', 'nuevo', 'nuevos', 'nueva', 'nuevas', 'velho', 'viejo', 'viejos', 'vieja', 'viejas', 'antigo', 'antiguo', 'antiguos', 'antigua', 'antiguas', 'moderno', 'modernos', 'moderna', 'modernas', 'bonito', 'bonitos', 'bonita', 'bonitas', 'feio', 'feo', 'feos', 'fea', 'feas', 'bom', 'bueno', 'buenos', 'buena', 'buenas', 'mau', 'malo', 'malos', 'mala', 'malas', 'melhor', 'mejor', 'melhores', 'mejores', 'pior', 'peor', 'piores', 'peores', 'caro', 'caros', 'cara', 'caras', 'barato', 'baratos', 'barata', 'baratas', 'r谩pido', 'r谩pidos', 'r谩pida', 'r谩pidas', 'lento', 'lentos', 'lenta', 'lentas', 'certo', 'cierto', 'ciertos', 'cierta', 'ciertas', 'errado', 'equivocado', 'equivocados', 'equivocada', 'equivocadas', 'verdadeiro', 'verdadero', 'verdaderos', 'verdadera', 'verdaderas', 'falso', 'falsos', 'falsa', 'falsas', 'real', 'reales', 'fict铆cio', 'ficticio', 'ficticios', 'ficticia', 'ficticias', 'verdade', 'verdad', 'mentira', 'mentiras', 'seguro', 'seguros', 'segura', 'seguras', 'perigoso', 'peligroso', 'peligrosos', 'peligrosa', 'peligrosas', 'tranquilo', 'tranquilos', 'tranquila', 'tranquilas', 'agitado', 'agitados', 'agitada', 'agitadas', 'calmo', 'calmos', 'calma', 'calmas', 'nervoso', 'nerviosos', 'nerviosa', 'nerviosas', 'alegre', 'alegres', 'triste', 'tristes', 'feliz', 'felices', 'infeliz', 'infelices', 'contente', 'contentos', 'contenta', 'contentas', 'descontente', 'descontentos', 'descontenta', 'descontentas', 'satisfeito', 'satisfecho', 'satisfechos', 'satisfecha', 'satisfechas', 'insatisfeito', 'insatisfecho', 'insatisfechos', 'insatisfecha', 'insatisfechas', 'orgulhoso', 'orgulloso', 'orgullosos', 'orgullosa', 'orgullosas', 'envergonhado', 'avergonzado', 'avergonzados', 'avergonzada', 'avergonzadas', 'surpreso', 'sorprendido', 'sorprendidos', 'sorprendida', 'sorprendidas', 'indiferente', 'indiferentes', 'interessado', 'interesado', 'interesados', 'interesada', 'interesadas', 'entediado', 'aburrido', 'aburridos', 'aburrida', 'aburridas', 'cansado', 'cansados', 'cansada', 'cansadas', 'descansado', 'descansados', 'descansada', 'descansadas', 'faminto', 'hambriento', 'hambrientos', 'hambrienta', 'hambrientas', 'satisfeito', 'satisfecho', 'satisfechos', 'satisfecha', 'satisfechas', 'sede', 'sed', 'satisfeito', 'satisfecho', 'satisfechos', 'satisfecha', 'satisfechas', 'com fome', 'con hambre', 'com sede', 'con sed', 'com sono', 'con sue帽o', 'acordado', 'despierto', 'despiertos', 'despierta', 'despiertas', 'dormindo', 'durmiendo', 'vivo', 'vivos', 'viva', 'vivas', 'morto', 'muerto', 'muertos', 'muerta', 'muertas', 'nascendo', 'naciendo', 'morrendo', 'muriendo', 'crescendo', 'creciendo', 'diminuindo', 'disminuyendo', 'aumentando', 'aumentando', 'subindo', 'subiendo', 'descendo', 'bajando', 'entrando', 'entrando', 'saindo', 'saliendo', 'chegando', 'llegando', 'partindo', 'partiendo', 'indo', 'yendo', 'vindo', 'viniendo', 'ficando', 'quedando', 'saindo', 'saliendo', 'voltando', 'volviendo', 'retornando', 'retornando', 'continuando', 'continuando', 'parando', 'parando', 'come莽ando', 'comenzando', 'terminando', 'terminando', 'iniciando', 'iniciando', 'finalizando', 'finalizando', 'abrindo', 'abriendo', 'fechando', 'cerrando', 'ligando', 'encendiendo', 'desligando', 'apagando', 'acendendo', 'encendiendo', 'apagando', 'apagando', 'aquecendo', 'calentando', 'esfriando', 'enfriando', 'secando', 'secando', 'molhando', 'mojando', 'limpando', 'limpiando', 'sujando', 'ensuciando', 'enchendo', 'llenando', 'esvaziando', 'vaciando'] |
| | }; |
| | |
| | const connectives = { |
| | PT: ['E', '脡', 'QUE'], |
| | EN: ['AND', 'IS', 'THAT'], |
| | ES: ['Y', 'ES', 'QUE'] |
| | }; |
| |
|
| | |
| | const negationWords = { |
| | PT: ['N脙O', 'NUNCA'], |
| | EN: ['NOT', 'NEVER'], |
| | ES: ['NO', 'NUNCA'] |
| | }; |
| | |
| | function formatText() { |
| | const text = inputText.value.trim(); |
| | if (!text) { |
| | outputContainer.innerHTML = '<p class="text-gray-500 text-center py-20">Please enter some text to format</p>'; |
| | return; |
| | } |
| | |
| | const language = languageSelect.value; |
| | const uppercaseMode = uppercaseCheck.checked; |
| | |
| | try { |
| | const formatted = processText(text, language, uppercaseMode); |
| | outputContainer.innerHTML = `<pre class="whitespace-pre-wrap font-sans text-gray-800">${formatted}</pre>`; |
| | } catch (error) { |
| | outputContainer.innerHTML = `<p class="text-red-500 text-center py-20">Error formatting text: ${error.message}</p>`; |
| | } |
| | } |
| |
|
| | |
| | function processText(text, language, uppercaseMode) { |
| | |
| | |
| | let normalized = text.replace(/\s+/g, ' ').trim(); |
| | |
| | |
| | normalized = normalized.replace(/,/g, '!'); |
| | |
| | |
| | normalized = normalized.replace(/!+/g, '!'); |
| | |
| | |
| | |
| | |
| | |
| | |
| | const sentences = normalized.split(/([.!?]+)/).filter(s => s.trim() !== ''); |
| | let blocks = []; |
| | |
| | for (let i = 0; i < sentences.length; i += 2) { |
| | const sentence = sentences[i]; |
| | const punctuation = sentences[i + 1] || ''; |
| | |
| | |
| | const sentenceBlocks = processSentence(sentence + punctuation, language); |
| | blocks = blocks.concat(sentenceBlocks); |
| | } |
| | |
| | |
| | blocks = applyHeuristics(blocks, language); |
| | |
| | |
| | if (uppercaseMode) { |
| | blocks = blocks.map(block => block.toUpperCase()); |
| | } |
| | |
| | return blocks.join('\n'); |
| | } |
| | |
| | function processSentence(sentence, language) { |
| | const words = sentence.trim().split(/\s+/); |
| | const blocks = []; |
| | let currentBlock = ''; |
| | let i = 0; |
| | |
| | while (i < words.length) { |
| | const word = words[i]; |
| | const cleanWord = word.replace(/[.!?!,]/g, ''); |
| | |
| | |
| | if (isConnective(cleanWord, language)) { |
| | if (currentBlock) { |
| | blocks.push(resolveBlockEnding(currentBlock.trim(), language)); |
| | } |
| | currentBlock = word; |
| | i++; |
| | continue; |
| | } |
| | |
| | |
| | if (isNegation(cleanWord, language)) { |
| | if (currentBlock) { |
| | blocks.push(resolveBlockEnding(currentBlock.trim(), language)); |
| | } |
| | blocks.push(word); |
| | currentBlock = ''; |
| | i++; |
| | continue; |
| | } |
| | |
| | |
| | const testBlock = currentBlock ? `${currentBlock} ${word}` : word; |
| | const charCount = testBlock.replace(/\s/g, '').replace(/[.!?!,]/g, '').length; |
| | |
| | |
| | if (!currentBlock && charCount > 11) { |
| | blocks.push(word); |
| | currentBlock = ''; |
| | i++; |
| | continue; |
| | } |
| | |
| | |
| | if (currentBlock && charCount > 11) { |
| | |
| | const resolvedBlock = resolveBlockEnding(currentBlock.trim(), language); |
| | if (resolvedBlock) { |
| | blocks.push(resolvedBlock); |
| | } |
| | currentBlock = word; |
| | } else { |
| | currentBlock = testBlock; |
| | } |
| | |
| | i++; |
| | } |
| | |
| | |
| | if (currentBlock) { |
| | const resolvedBlock = resolveBlockEnding(currentBlock.trim(), language); |
| | if (resolvedBlock) { |
| | blocks.push(resolvedBlock); |
| | } |
| | } |
| | |
| | return blocks; |
| | } |
| |
|
| | |
| | function resolveBlockEnding(block, language) { |
| | if (!block) return ''; |
| | |
| | const words = block.split(/\s+/); |
| | if (words.length === 0) return ''; |
| | |
| | const lastWord = words[words.length - 1].replace(/[.!?!,]/g, ''); |
| | const lastWordClean = lastWord; |
| | |
| | |
| | if (isTabu(lastWordClean, language)) { |
| | if (words.length === 1) { |
| | |
| | return block; |
| | } |
| | |
| | const newBlock = words.slice(0, -1).join(' '); |
| | return newBlock; |
| | } |
| | |
| | |
| | if (lastWordClean.length >= 2 && lastWordClean.length <= 3) { |
| | if (words.length === 1) { |
| | return block; |
| | } |
| | |
| | const newBlock = words.slice(0, -1).join(' '); |
| | return newBlock; |
| | } |
| | |
| | return block; |
| | } |
| | |
| | function isConnective(word, language) { |
| | if (!word) return false; |
| | const upperWord = word.toUpperCase(); |
| | return connectives[language].includes(upperWord); |
| | } |
| |
|
| | |
| | function isTabu(word, language) { |
| | if (!word) return false; |
| | return tabuWords[language].includes(word.toLowerCase()); |
| | } |
| |
|
| | |
| | function isNegation(word, language) { |
| | if (!word) return false; |
| | const upperWord = word.toUpperCase(); |
| | return negationWords[language].includes(upperWord); |
| | } |
| |
|
| | |
| | function applyHeuristics(blocks, language) { |
| | const optimizedBlocks = []; |
| | |
| | for (let i = 0; i < blocks.length; i++) { |
| | let block = blocks[i]; |
| | const cleanBlock = block.replace(/[.!?!,]/g, '').toUpperCase(); |
| | |
| | |
| | const priceMatch = block.match(/^(POR|E|AND|Y)\s+(\d+)/i); |
| | if (priceMatch) { |
| | optimizedBlocks.push(priceMatch[1]); |
| | optimizedBlocks.push(priceMatch[2]); |
| | continue; |
| | } |
| | |
| | |
| | if (language === 'PT' && /^FEITO\s+EM/i.test(block)) { |
| | const parts = block.split(/\s+/); |
| | if (parts.length > 2) { |
| | optimizedBlocks.push('FEITO EM'); |
| | const materials = parts.slice(2).join(' '); |
| | |
| | const materialParts = materials.split(/\s+E\s+/i); |
| | materialParts.forEach((mat, idx) => { |
| | if (idx > 0) optimizedBlocks.push('E'); |
| | if (mat.trim()) optimizedBlocks.push(mat.trim()); |
| | }); |
| | continue; |
| | } |
| | } |
| | |
| | if (language === 'EN' && /^MADE\s+IN/i.test(block)) { |
| | const parts = block.split(/\s+/); |
| | if (parts.length > 2) { |
| | optimizedBlocks.push('MADE IN'); |
| | const materials = parts.slice(2).join(' '); |
| | |
| | const materialParts = materials.split(/\s+AND\s+/i); |
| | materialParts.forEach((mat, idx) => { |
| | if (idx > 0) optimizedBlocks.push('AND'); |
| | if (mat.trim()) optimizedBlocks.push(mat.trim()); |
| | }); |
| | continue; |
| | } |
| | } |
| | |
| | if (language === 'ES' && /^HECHO\s+EN/i.test(block)) { |
| | const parts = block.split(/\s+/); |
| | if (parts.length > 2) { |
| | optimizedBlocks.push('HECHO EN'); |
| | const materials = parts.slice(2).join(' '); |
| | |
| | const materialParts = materials.split(/\s+Y\s+/i); |
| | materialParts.forEach((mat, idx) => { |
| | if (idx > 0) optimizedBlocks.push('Y'); |
| | if (mat.trim()) optimizedBlocks.push(mat.trim()); |
| | }); |
| | continue; |
| | } |
| | } |
| | |
| | |
| | if (language === 'PT' && /CLIQUE\s+EM\s+SAIBA\s+MAIS/i.test(block)) { |
| | optimizedBlocks.push('CLIQUE'); |
| | optimizedBlocks.push('EM SAIBA'); |
| | optimizedBlocks.push('MAIS'); |
| | continue; |
| | } |
| | |
| | if (language === 'EN' && /CLICK\s+HERE\s+TO\s+LEARN\s+MORE/i.test(block)) { |
| | optimizedBlocks.push('CLICK'); |
| | optimizedBlocks.push('HERE TO'); |
| | optimizedBlocks.push('LEARN MORE'); |
| | continue; |
| | } |
| | |
| | if (language === 'ES' && /HAZ\s+CLIC\s+AQU脥\s+PARA\s+SABER\s+M脕S/i.test(block)) { |
| | optimizedBlocks.push('HAZ CLIC'); |
| | optimizedBlocks.push('AQU脥 PARA'); |
| | optimizedBlocks.push('SABER M脕S'); |
| | continue; |
| | } |
| | |
| | |
| | const subjectMatch = block.match(/^(A|O|AS|OS|THE)\s+(\w{4,})/i); |
| | if (subjectMatch && block.replace(/\s/g, '').length <= 11) { |
| | optimizedBlocks.push(block); |
| | continue; |
| | } |
| | |
| | optimizedBlocks.push(block); |
| | } |
| | |
| | |
| | return validateAndFixBlocks(optimizedBlocks, language); |
| | } |
| |
|
| | |
| | function validateAndFixBlocks(blocks, language) { |
| | const validatedBlocks = []; |
| | |
| | for (let i = 0; i < blocks.length; i++) { |
| | const block = blocks[i]; |
| | const words = block.split(/\s+/); |
| | |
| | if (words.length === 0) continue; |
| | |
| | const lastWord = words[words.length - 1].replace(/[.!?!,]/g, ''); |
| | |
| | |
| | if (isTabu(lastWord, language)) { |
| | if (words.length > 1) { |
| | |
| | const newBlock = words.slice(0, -1).join(' '); |
| | if (newBlock) validatedBlocks.push(newBlock); |
| | |
| | |
| | if (i + 1 < blocks.length) { |
| | const nextBlock = blocks[i + 1]; |
| | const combined = `${lastWord} ${nextBlock}`; |
| | const charCount = combined.replace(/\s/g, '').length; |
| | |
| | if (charCount <= 11) { |
| | blocks[i + 1] = combined; |
| | continue; |
| | } |
| | } |
| | |
| | validatedBlocks.push(lastWord); |
| | } else { |
| | validatedBlocks.push(block); |
| | } |
| | continue; |
| | } |
| | |
| | |
| | if (lastWord.length >= 2 && lastWord.length <= 3) { |
| | if (words.length > 1) { |
| | |
| | const newBlock = words.slice(0, -1).join(' '); |
| | if (newBlock) validatedBlocks.push(newBlock); |
| | |
| | |
| | if (i + 1 < blocks.length) { |
| | const nextBlock = blocks[i + 1]; |
| | const combined = `${lastWord} ${nextBlock}`; |
| | const charCount = combined.replace(/\s/g, '').length; |
| | |
| | if (charCount <= 11) { |
| | blocks[i + 1] = combined; |
| | continue; |
| | } |
| | } |
| | |
| | validatedBlocks.push(lastWord); |
| | } else { |
| | validatedBlocks.push(block); |
| | } |
| | continue; |
| | } |
| | |
| | |
| | const charCount = block.replace(/\s/g, '').replace(/[.!?!,]/g, '').length; |
| | if (charCount > 11 && words.length > 1) { |
| | |
| | const splitResult = splitLongBlock(block, language); |
| | validatedBlocks.push(...splitResult); |
| | } else { |
| | validatedBlocks.push(block); |
| | } |
| | } |
| | |
| | return validatedBlocks; |
| | } |
| |
|
| | |
| | function splitLongBlock(block, language) { |
| | const words = block.split(/\s+/); |
| | const result = []; |
| | let currentBlock = ''; |
| | |
| | for (const word of words) { |
| | const cleanWord = word.replace(/[.!?!,]/g, ''); |
| | |
| | |
| | if (isConnective(cleanWord, language)) { |
| | if (currentBlock) result.push(currentBlock.trim()); |
| | currentBlock = word; |
| | continue; |
| | } |
| | |
| | const testBlock = currentBlock ? `${currentBlock} ${word}` : word; |
| | const charCount = testBlock.replace(/\s/g, '').replace(/[.!?!,]/g, '').length; |
| | |
| | if (currentBlock && charCount > 11) { |
| | const resolved = resolveBlockEnding(currentBlock.trim(), language); |
| | if (resolved) result.push(resolved); |
| | currentBlock = word; |
| | } else { |
| | currentBlock = testBlock; |
| | } |
| | } |
| | |
| | if (currentBlock) { |
| | const resolved = resolveBlockEnding(currentBlock.trim(), language); |
| | if (resolved) result.push(resolved); |
| | } |
| | |
| | return result; |
| | } |
| | |
| | function copyToClipboard() { |
| | const text = outputContainer.innerText; |
| | if (!text || text.includes('Formatted text will appear here') || text.includes('Please enter some text to format')) { |
| | return; |
| | } |
| | |
| | navigator.clipboard.writeText(text).then(() => { |
| | |
| | const originalText = copyBtn.innerHTML; |
| | copyBtn.innerHTML = '<i data-feather="check" class="w-5 h-5 mr-1"></i> Copied!'; |
| | feather.replace(); |
| | |
| | setTimeout(() => { |
| | copyBtn.innerHTML = originalText; |
| | feather.replace(); |
| | }, 2000); |
| | }).catch(err => { |
| | console.error('Failed to copy:', err); |
| | }); |
| | } |
| | |
| | function downloadText() { |
| | const text = outputContainer.innerText; |
| | if (!text || text.includes('Formatted text will appear here') || text.includes('Please enter some text to format')) { |
| | return; |
| | } |
| | |
| | const blob = new Blob([text], { type: 'text/plain' }); |
| | const url = URL.createObjectURL(blob); |
| | const a = document.createElement('a'); |
| | a.href = url; |
| | a.download = 'formatted-text.txt'; |
| | document.body.appendChild(a); |
| | a.click(); |
| | document.body.removeChild(a); |
| | URL.revokeObjectURL(url); |
| | } |
| | |
| | function clearInput() { |
| | inputText.value = ''; |
| | outputContainer.innerHTML = '<p class="text-gray-500 text-center py-20">Formatted text will appear here</p>'; |
| | inputText.focus(); |
| | } |
| | |
| | |
| | formatBtn.addEventListener('click', formatText); |
| | copyBtn.addEventListener('click', copyToClipboard); |
| | downloadBtn.addEventListener('click', downloadText); |
| | clearBtn.addEventListener('click', clearInput); |
| | |
| | |
| | inputText.addEventListener('keydown', (e) => { |
| | if (e.ctrlKey && e.key === 'Enter') { |
| | formatText(); |
| | } |
| | }); |
| | |
| | |
| | feather.replace(); |
| | }); |
| |
|