fix: alinha DOI à direita e confina título do artigo à coluna própria - #1330
fix: alinha DOI à direita e confina título do artigo à coluna própria#1330Rossi-Luciano wants to merge 1 commit into
Conversation
Itens 1 e 5 de revisao visual do corpus: o DOI (pagina 1) e o titulo do artigo no cabecalho corrido (paginas >1) dividiam o mesmo paragrafo do titulo do periodico, separados so por um caractere de tabulacao. Uma tab stop define so onde um run COMECA, nao onde ele quebra linha - uma linha quebrada volta para a margem esquerda do paragrafo, nao para a posicao da tab. Isso tinha dois efeitos: - DOI (docx_doi_pipe): quando a segunda linha do titulo do periodico (_format_journal_title_two_lines) ja era longa, nao sobrava espaco na linha pra tab+DOI chegar na margem direita, e ele quebrava pra uma 3a linha em vez de ficar alinhado a direita (visto em a30.xml: "URBE. / REVISTA BRASILEIRA DE GESTAO URBANA" + DOI colidindo). - Titulo do artigo (docx_second_header_pipe, ja tinha virado tabela no fix anterior de scieloorg#1301): esse problema nao se aplicava mais ali, mas o DOI da pagina 1 ainda usava o padrao antigo de tab. Os dois casos agora usam uma tabela sem borda de 2 colunas (helper compartilhado _add_two_column_header_table): titulo do periodico/DOI na pagina 1, titulo do periodico/titulo do artigo nas paginas seguintes. Cada coluna tem largura propria, entao o conteudo de uma nunca disputa espaco horizontal com o da outra na mesma linha. Par titulo do periodico/DOI usa split 65/35 em vez de 50/50 (usado no par titulo do periodico/titulo do artigo, sem mudanca): testado contra varios titulos longos do corpus real (a30, a13 - titulos de 5-6 palavras nao sao raros, 8 dos 26 artigos do corpus) e o maior DOI do corpus (54 chars) - 50/50 empurrava titulos assim pra 3 linhas sem necessidade, ja que o DOI cabe com folga em menos da metade do espaco. Nao existe split unico que garanta 1 linha nos dois lados sempre (texto quebra em pontos discretos, nao continuos); 65/35 foi o que manteve o titulo do periodico em 2 linhas nos casos testados, aceitando que o DOI as vezes quebra em 2 linhas (ainda alinhado a direita, nunca colidindo). Validado contra as 26 amostras do corpus (todas geram sem erro) e visualmente em a30.xml (DOI) e a6.xml (titulo de artigo mais longo do corpus, 172 chars). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X8r2LRJ3PGTT9vLaPtb373
| r1 = para.add_run(_format_journal_title_two_lines(journal_title)) | ||
| journal_para = journal_cell.paragraphs[0] | ||
| journal_para.style = docx.styles[paragraph_header_style_name] | ||
| r1 = journal_para.add_run(_format_journal_title_two_lines(journal_title)) |
There was a problem hiding this comment.
O cabeçalho corrido não deve reutilizar a formatação do masthead da primeira página. Essa quebra forçada faz urbe. Revista Brasileira de Gestão Urbana ocupar três linhas na página 2 quando combinada com a coluna de 50%. Use journal_title sem _format_journal_title_two_lines() e aplique SCL Header Paragraph Char ao run do periódico.
| left_width = int(content_width * left_ratio) | ||
| right_width = content_width - left_width | ||
|
|
||
| table = container.add_table(rows=1, cols=2, width=content_width) |
There was a problem hiding this comment.
Header/Footer já começa com um parágrafo vazio. A tabela é inserida depois dele, deslocando o cabeçalho verticalmente. Sugiro remover os parágrafos de placeholder criados automaticamente pelo python-docx, após confirmar que eles não contém texto, runs ou conteúdo gráfico.
| table = container.add_table(rows=1, cols=2, width=content_width) | ||
| table.autofit = False | ||
| table.allow_autofit = False | ||
|
|
There was a problem hiding this comment.
A tabela padrão mantém w:tblCellMar (≈5,4 pt), criando recuo nas duas extremidades e desalinhando o cabeçalho do corpo. Configure w:tblCellMar com top/left/bottom/right = 0.
pitangainnovare
left a comment
There was a problem hiding this comment.
Em teste manual com vários XMLs, percebi alguns problemas:
-
No cabeçalho corrido, o título do periódico continua usando
_format_journal_title_two_lines()e o estiloSCL Journal Title Char, que pertence ao masthead da primeira página. Com a nova coluna de 50%,
isso fazurbe. Revista Brasileira de Gestão Urbanaocupar três linhas. A sugestão é usar diretamentejournal_titlee aplicarSCL Header Paragraph Char, mantendo o periódico em uma única linha sempre que
houver espaço. -
O Header/Footer criado pelo
python-docxcontém um parágrafo placeholder vazio. Comoadd_table()insere a tabela depois desse parágrafo, o cabeçalho da primeira página passa de aproximadamentey=28,3 ptparay=41,0 pt. A sugestão é remover somente esse placeholder automático, verificando que ele realmente não possui texto, runs ou conteúdo gráfico, sem apagar parágrafos vazios intencionais. -
As células da tabela mantêm margens internas laterais de aproximadamente
5,4 pt. Na renderização, o cabeçalho começa emx=62,2 pt, enquanto o corpo começa emx=56,8 pt. A sugestão é sobrescrever
w:tblCellMar, ao menos paralefteright, com valor zero. Zerar os quatro lados também é aceitável para esse cabeçalho. -
Como ajuste adicional,
para.alignment = WD_ALIGN_PARAGRAPH.RIGHTdeveria ficar depois doif/elseexterno dedocx_doi_pipe. Atualmente, quando o chamador forneceparagraph, o DOI perde tanto a
tabulação removida pelo PR quanto o alinhamento à direita. Esse caminho deveria receber um teste específico.
O que esse PR faz?
Resolve dois problemas do cabeçalho do PDF: o DOI (página 1) não ficava alinhado à margem direita, e o título do artigo nas páginas internas (>1) aparecia colado ao título do periódico em vez de confinado à própria área.
Os dois compartilhavam a mesma causa: DOI e título do periódico dividiam o mesmo parágrafo, separados só por um caractere de tabulação (
\t). Uma tab stop define onde um texto começa, não onde ele quebra linha — uma linha que estoura volta para a margem esquerda do parágrafo, não para a posição da tab. Quando a segunda linha do título do periódico (_format_journal_title_two_lines) já era longa, não sobrava espaço na linha para o DOI alcançar a margem direita, e ele quebrava para uma 3ª linha em vez de ficar alinhado (visto ema30.xml: "URBE. / REVISTA BRASILEIRA DE GESTÃO URBANA" colidindo com o DOI).A correção usa uma tabela sem borda de 2 colunas no cabeçalho (helper novo
_add_two_column_header_table, reaproveitado pelos dois pares): título do periódico + DOI na página 1, título do periódico + título do artigo nas páginas seguintes (esse segundo par já usava uma tabela desde o fix de #1301; o helper foi extraído para os dois casos compartilharem). Cada coluna tem largura própria, então o conteúdo de uma nunca disputa espaço horizontal com o da outra.O par periódico/DOI usa split 65/35 em vez de 50/50 (usado no par periódico/artigo, sem mudança): testei contra vários títulos longos do corpus real — títulos de 5-6 palavras não são raros (8 dos 26 artigos) — e contra o maior DOI do corpus (54 caracteres). 50/50 empurrava títulos longos para 3 linhas sem necessidade, já que o DOI cabe com folga em bem menos da metade do espaço. Não existe um split único que garanta 1 linha dos dois lados sempre (quebra de texto acontece em pontos discretos, não contínuos); 65/35 foi o que manteve o título do periódico em 2 linhas nos casos testados, aceitando que o DOI às vezes quebre em 2 linhas — mas sempre alinhado à direita, nunca colidindo com o título.
Onde a revisão poderia começar?
packtools/sps/formats/pdf/pipeline/docx.py:_add_two_column_header_table(helper novo, no bloco de helpers privados)docx_journal_title_pipeedocx_doi_pipe(página 1)docx_second_header_pipe(páginas >1, já era tabela, só passou a reusar o helper)Como este poderia ser testado manualmente?
Conferir a página 1 (DOI alinhado à direita, mesmo com título de periódico longo) e uma página interna (título do artigo confinado à direita, sem colidir com o título do periódico).
Algum cenário de contexto que queira dar?
Achado revisando visualmente o corpus de teste de 26 artigos reais (
layout_examples_rafael/corpus/). Validado contra o corpus inteiro (as 26 amostras geram sem erro) e visualmente ema30.xml(o caso original do DOI colidindo) ea6.xml(título de artigo mais longo do corpus, 172 caracteres, para estressar a quebra de linha na coluna própria).Screenshots
Quais são os tickets relevantes?
Nenhuma issue aberta associada; achado durante revisão visual do corpus de teste do gerador de PDF.
Referências
N/A
Segurança da informação (NSI.04)
Este PR manipula dados sensíveis ou pessoais (LGPD)?
Este PR altera autenticação, autorização, controle de acesso ou gerenciamento de sessão?
Este PR introduz, atualiza ou remove dependências de terceiros?
Este PR foi validado pelo pipeline de segurança (SonarQube / Trivy)?
Este PR concatena, monta ou executa comandos SQL, HTML ou JavaScript a partir de entrada externa?
Este PR expõe novos endpoints, telas ou serviços?
Algum segredo, senha, chave ou token está sendo adicionado ao código-fonte?
🤖 Generated with Claude Code
https://claude.ai/code/session_01X8r2LRJ3PGTT9vLaPtb373