Deck HTML -> PPTX nativo e editável
A regra que esta skill impõe: nunca cole imagens de slide no PowerPoint. Cada quadrado, barra, ponto, pílula, linha e bloco de texto deve ser um objeto PowerPoint real que o usuário possa mover, recolorir e redigitar. O conversor lê a página renderizada (Playwright + layout calculado pelo navegador) em vez de reinterpretar o CSS, depois escreve formas python-pptx nas coordenadas exatas.
Execute
python scripts/html_to_pptx.py <deck.html> <out.pptx> [all | 1,3,5]
Requer: pip install -r requirements.txt e playwright install chromium.
Os slides são os elementos que correspondem a .slide (1280x720 px). Coloque o .html em algum lugar com suas imagens inline
(data: URIs) ou em disco ao lado. examples/sample-deck.html é um deck pequeno para testar primeiro.
Como a página precisa estar quando capturada (o script faz isso por você): classe anim removida de
<html>, animações/transições CSS desativadas, evento beforeprint de window disparado (decks frequentemente revelam gráficos na impressão),
mídia de impressão, zoom 1, elementos com classe .mode ou .jump ocultos (alternador de tema, navegador de slides). Decks
com alternância claro/escuro convertem no tema que estiver sendo exibido — certifique-se de que é o que o usuário deseja.
O que vira o quê
| No HTML | No PPTX |
|---|---|
| div / card com fundo, borda, raio | retângulo / retângulo arredondado (raio -> ajuste de canto) |
| fundo gradiente (linear) | preenchimento gradiente nativo |
| borda unilateral (faixa de destaque) | retângulo fino; bordas finas/tracejadas -> linhas reais |
pílulas com border-radius:999px, círculos | pílula / oval |
texto (qualquer bloco, com execuções em negrito/cor, <br>, links) | uma caixa de texto por bloco, execuções preservadas, hiperlinks mantidos |
<li> | marcadores reais do PowerPoint (cor do marcador mantida) |
| SVG inline rect/circle/line/polyline/path/text | retângulo, oval, conector (pontas de seta mantidas), forma livre com curvas Bezier reais, caixa de texto |
SVG <textPath> (texto em curva) | texto curvo do PowerPoint (distorção Arch Up/Down) |
CSS clip-path: polygon(...) (chevrons, cortes diagonais) | forma livre; uma foto dentro é recortada para o polígono |
<img>, fotos, PNGs de ícone | imagens (são bitmaps — esperado) |
text-transform, espaçamento entre letras, tachado, opacidade/alfa | aplicado às execuções / preenchimentos |
Alternância de duas visualizações (.vtog com botões data-view=codigo e data-view=tempo) | segundo slide para a outra visualização |
| Animações JS | apenas estado final fixo |
Regras difíceis (cada uma custou tempo real — mantenha-as)
- A posição do texto é calibrada, não a "corrija" visualmente. Espaçamento de linha 100% do PowerPoint = 1,2 x tamanho da fonte
(Arial e Arial Black igualmente). Uma caixa de texto deve ser colocada em
top = rangeTop + (ascent-cap)*fs - lineHeight + K*fscom(ascent-cap, K) = (0,189, 0,95)para Arial e(0,385, 1,0)para Arial Black, eline_spacing = cssLineHeight / (1,2*fs). Texto de uma linha usa espaçamento 100% ewrap=nonecom folga para nunca re-quebrar. - Chrome no Windows renderiza
font-family: Arialcom peso 800/900 como ARIAL BLACK. O conversor mapeia para Arial Black (não negrito). Sem isso, cada título pesado parece muito fino e com largura errada. - Nunca engula filhos inline-block em um bloco de texto. Apenas filhos com
display:inlinesão mesclados em uma caixa de texto; filhos inline-block/flex são tratados separadamente. - Meça nós de texto no local (Range no nó). Envolver um nó em um
<span>temporário altera o layout grid/flex. - Abra o resultado no PowerPoint para provar que é válido. O python-pptx pode escrever alegremente um arquivo que o PowerPoint
recusa ("PowerPoint não pôde abrir o arquivo"). Causas conhecidas: tamanhos de forma negativos/NaN (prender, descartar
pontos NaN), e
calc()dentro declip-path(avalie). Divida excluindo formas pela metade e reabrindo. - Uma imagem com geometria personalizada preenche a caixa delimitadora de seu caminho, não seu quadro. Para recortar uma foto em um polígono,
dimensione a imagem para a caixa delimitadora do polígono e defina um corte de origem (
srcRect) para o resto. - Não capture formas por screenshot ("rasterizar as estranhas"). Converta caminhos SVG de logotipos e polígonos de clip-path
para formas livres. O branch
rasteré último recurso. - Pule texto fantasma recortado (grandes numerais desbotados cortados pelo card) — o PowerPoint não pode recortar caixas de texto.
- PowerPoint
a:lnvem depois do preenchimento emspPr; exclua o temap:styleou as formas pegam sombras. - Nunca sobrescreva um .pptx que o usuário tem aberto — escreva um novo nome de arquivo.
Verifique (sempre — nunca envie sem ver)
Windows com PowerPoint instalado:
powershell -NoProfile -File scripts/render_pptx.ps1 -pptx <out.pptx> -outdir <png_dir> # Exportação PowerPoint para PNG
python scripts/compare.py <deck.html> <png_dir> 1,2,3 <out.png> # HTML | PPTX lado a lado
python scripts/compare.py <deck.html> <png_dir> 6:6,7:8 <out.png> # html:pptx quando números de slide diferem
render_pptx.ps1 deixa o PowerPoint em execução se o usuário já o tiver aberto. Sem PowerPoint, renderize o
.pptx para PNGs de outra forma (por exemplo LibreOffice headless) em s1.png, s2.png… e execute compare.py.
Leia o PNG de comparação, corrija, reconstrua. Limpeza típica após uma execução: texto ligeiramente mais largo no PowerPoint (kerning), nada estrutural.
Limitações conhecidas (informe o usuário)
- O posicionamento do texto é calibrado para Arial e Arial Black. Outras fontes convertem, mas o texto pode ficar alguns pixels acima ou abaixo até que essa fonte seja calibrada (meça altura da maiúscula e espaçamento de linha no PowerPoint).
- Fotos, ícones e logotipos fornecidos como bitmaps permanecem imagens. O texto fica em sua própria caixa sobre o card (não agrupado).
- Animações/alternâncias são achatadas em um quadro (a segunda visualização de uma alternância se torna um slide extra).
- Gradientes radiais e raios de canto individuais são aproximados; sombras de caixa são descartadas.
- O tamanho do slide é fixo em 1280x720 px -> 13,333 x 7,5 pol.
Créditos
Construído pela Impera Business Services. Licença MIT — veja LICENSE.