Update app.py
Browse files
app.py
CHANGED
|
@@ -1,34 +1,122 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
import html2text
|
|
|
|
| 3 |
|
| 4 |
-
|
|
|
|
| 5 |
"""
|
| 6 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
|
| 8 |
:param html_input: String contendo o código HTML vindo da interface Gradio.
|
| 9 |
:return: String convertida para Markdown.
|
| 10 |
"""
|
| 11 |
-
if not html_input:
|
| 12 |
return "Por favor, insira algum código HTML."
|
| 13 |
-
|
| 14 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
converter = html2text.HTML2Text()
|
| 16 |
-
converter.ignore_links = False
|
| 17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
return markdown_output
|
| 19 |
except Exception as e:
|
| 20 |
-
return f"Ocorreu um erro durante
|
| 21 |
|
| 22 |
-
# Cria a interface Gradio
|
| 23 |
iface = gr.Interface(
|
| 24 |
-
fn=
|
| 25 |
-
inputs=gr.Textbox(lines=15, label="Insira o HTML aqui", placeholder="<html>...</html>"),
|
| 26 |
-
outputs=gr.Textbox(lines=15, label="Markdown Resultante"),
|
| 27 |
-
title="Conversor HTML para Markdown",
|
| 28 |
-
description="Cole seu código HTML na caixa
|
| 29 |
-
allow_flagging='never'
|
| 30 |
)
|
| 31 |
|
| 32 |
-
# Lança a interface
|
| 33 |
if __name__ == "__main__":
|
| 34 |
iface.launch()
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
import html2text
|
| 3 |
+
from bs4 import BeautifulSoup
|
| 4 |
|
| 5 |
+
# --- Função de Limpeza de HTML ---
|
| 6 |
+
def limpar_html(html_bruto):
|
| 7 |
"""
|
| 8 |
+
Limpa o HTML, mantendo tags específicas e removendo outras,
|
| 9 |
+
incluindo scripts, estilos e atributos desnecessários.
|
| 10 |
+
|
| 11 |
+
:param html_bruto: String contendo o código HTML original.
|
| 12 |
+
:return: String contendo o HTML limpo.
|
| 13 |
+
"""
|
| 14 |
+
if not html_bruto:
|
| 15 |
+
return ""
|
| 16 |
+
|
| 17 |
+
soup = BeautifulSoup(html_bruto, 'html.parser')
|
| 18 |
+
|
| 19 |
+
# 1. Tags para remover completamente (incluindo conteúdo)
|
| 20 |
+
tags_para_remover = ['script', 'style', 'header', 'footer', 'nav', 'aside', 'form', 'meta', 'link', 'noscript']
|
| 21 |
+
for tag_nome in tags_para_remover:
|
| 22 |
+
for tag in soup.find_all(tag_nome):
|
| 23 |
+
tag.decompose() # Remove a tag e seu conteúdo
|
| 24 |
+
|
| 25 |
+
# 2. Tags permitidas (vamos manter estas e seus conteúdos)
|
| 26 |
+
# Todas as outras tags serão removidas, mas seu conteúdo será mantido (unwrap)
|
| 27 |
+
tags_permitidas = {
|
| 28 |
+
'html', 'body', 'head', 'title', # Estrutura básica (head/title podem ser removidos pelo html2text depois)
|
| 29 |
+
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', # Cabeçalhos
|
| 30 |
+
'p', 'br', # Parágrafos e quebras de linha
|
| 31 |
+
'a', # Links
|
| 32 |
+
'strong', 'b', 'em', 'i', 'u', 's', 'strike', 'del', # Ênfase/Formatação
|
| 33 |
+
'ul', 'ol', 'li', # Listas
|
| 34 |
+
'img', # Imagens
|
| 35 |
+
'table', 'thead', 'tbody', 'tr', 'th', 'td', # Tabelas
|
| 36 |
+
'blockquote', # Citações
|
| 37 |
+
'pre', 'code' # Código
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
# 3. Atributos permitidos por tag (outros serão removidos)
|
| 41 |
+
atributos_permitidos = {
|
| 42 |
+
'a': ['href', 'title'],
|
| 43 |
+
'img': ['src', 'alt', 'title', 'width', 'height'], # Manter width/height pode ser útil
|
| 44 |
+
'*': ['class', 'id'] # Permitir class e id em qualquer tag pode ser útil para CSS/JS, mas para conversão para Markdown talvez não. Remova se não precisar.
|
| 45 |
+
# Adicione mais tags e seus atributos permitidos aqui se necessário
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
# Itera por todas as tags no documento
|
| 49 |
+
for tag in soup.find_all(True): # True encontra todas as tags
|
| 50 |
+
if tag.name not in tags_permitidas:
|
| 51 |
+
# Se a tag não é permitida, remove a tag mas mantém o conteúdo
|
| 52 |
+
tag.unwrap()
|
| 53 |
+
else:
|
| 54 |
+
# Se a tag é permitida, limpa os atributos não permitidos
|
| 55 |
+
atributos_para_manter = atributos_permitidos.get(tag.name, []) + atributos_permitidos.get('*', [])
|
| 56 |
+
# Cria um dicionário apenas com os atributos permitidos
|
| 57 |
+
attrs_mantidos = {}
|
| 58 |
+
for attr, value in tag.attrs.items():
|
| 59 |
+
if attr in atributos_para_manter:
|
| 60 |
+
attrs_mantidos[attr] = value
|
| 61 |
+
# Define os atributos da tag para serem apenas os mantidos
|
| 62 |
+
tag.attrs = attrs_mantidos
|
| 63 |
+
|
| 64 |
+
# Retorna o HTML limpo como string
|
| 65 |
+
# O pretty print pode ajudar na depuração, mas str(soup) é mais direto
|
| 66 |
+
return str(soup)
|
| 67 |
+
|
| 68 |
+
# --- Função Principal (adaptada) ---
|
| 69 |
+
def html_para_markdown_com_limpeza(html_input):
|
| 70 |
+
"""
|
| 71 |
+
Limpa o HTML e depois converte para Markdown.
|
| 72 |
|
| 73 |
:param html_input: String contendo o código HTML vindo da interface Gradio.
|
| 74 |
:return: String convertida para Markdown.
|
| 75 |
"""
|
| 76 |
+
if not html_input:
|
| 77 |
return "Por favor, insira algum código HTML."
|
| 78 |
+
|
| 79 |
try:
|
| 80 |
+
# 1. Limpa o HTML primeiro
|
| 81 |
+
html_limpo = limpar_html(html_input)
|
| 82 |
+
|
| 83 |
+
if not html_limpo:
|
| 84 |
+
return "O HTML resultante após a limpeza está vazio."
|
| 85 |
+
|
| 86 |
+
# 2. Converte o HTML limpo para Markdown
|
| 87 |
converter = html2text.HTML2Text()
|
| 88 |
+
converter.ignore_links = False
|
| 89 |
+
# Configurações adicionais do html2text (opcional):
|
| 90 |
+
converter.ignore_images = False # Garante que imagens sejam processadas
|
| 91 |
+
converter.body_width = 0 # Evita quebra de linha automática baseada na largura
|
| 92 |
+
# converter.skip_internal_links = True
|
| 93 |
+
# converter.inline_links = True # Usa links inline em vez de referências no final
|
| 94 |
+
|
| 95 |
+
markdown_output = converter.handle(html_limpo)
|
| 96 |
+
|
| 97 |
+
# html2text pode incluir o conteúdo de <title> por padrão.
|
| 98 |
+
# Se quiser remover especificamente o conteúdo do <title> do Markdown final:
|
| 99 |
+
# (Isso é um pós-processamento, pode ser necessário ajustar)
|
| 100 |
+
soup_limpo = BeautifulSoup(html_limpo, 'html.parser')
|
| 101 |
+
titulo = soup_limpo.title
|
| 102 |
+
if titulo and titulo.string:
|
| 103 |
+
markdown_output = markdown_output.replace(titulo.string, '', 1).strip()
|
| 104 |
+
|
| 105 |
+
|
| 106 |
return markdown_output
|
| 107 |
except Exception as e:
|
| 108 |
+
return f"Ocorreu um erro durante o processo: {str(e)}"
|
| 109 |
|
| 110 |
+
# --- Cria a interface Gradio ---
|
| 111 |
iface = gr.Interface(
|
| 112 |
+
fn=html_para_markdown_com_limpeza, # Função principal atualizada
|
| 113 |
+
inputs=gr.Textbox(lines=15, label="Insira o HTML bruto aqui", placeholder="<html><head><title>Título</title><script>...</script></head><body><h1>Cabeçalho</h1>...</body></html>"),
|
| 114 |
+
outputs=gr.Textbox(lines=15, label="Markdown Resultante (após limpeza)"),
|
| 115 |
+
title="Conversor HTML para Markdown com Limpeza",
|
| 116 |
+
description="Cole seu código HTML na caixa da esquerda. O código será limpo (removendo scripts, estilos, tags e atributos desnecessários) e depois convertido para Markdown na caixa da direita. Tags como <h1>, <p>, <a> e <img> (com src/alt) são preservadas.",
|
| 117 |
+
allow_flagging='never'
|
| 118 |
)
|
| 119 |
|
| 120 |
+
# --- Lança a interface ---
|
| 121 |
if __name__ == "__main__":
|
| 122 |
iface.launch()
|