Skip to content

Conversation

@Rossi-Luciano
Copy link
Collaborator

O que esse PR faz?

Este PR implementa melhorias críticas nas validações de acessibilidade para o elemento <alt-text> conforme especificação SPS 1.10, aumentando a conformidade de 56% para 89%. As principais mudanças incluem:

Novas Validações:

  1. Restrição de mídia: Alt-text em <media> só é permitido para vídeo (mp4) e áudio (mp3)
  2. Prevenção de duplicação: Alt-text não pode copiar conteúdo de <label> ou <caption>
  3. Figuras decorativas: Figuras sem label/caption devem ter <alt-text>null</alt-text>

Correções:

  • Validação de @content-type agora é opcional (só valida quando presente)
  • XPath simplificado elimina captura duplicada de elementos

Internacionalização:

  • Adiciona suporte completo a gettext em todas as validações
  • 4 novos campos em respostas: msg_text, msg_params, adv_text, adv_params

Onde a revisão poderia começar?

  1. packtools/sps/validation/utils.py (linhas 1-10, 65-145)

    • Verifique adição de gettext e novos campos msg_text/adv_text
  2. packtools/sps/models/accessibility_data.py (linhas 18-28, 95-125)

    • Revise simplificação do XPath e novas propriedades parent_info e mimetype_info
  3. packtools/sps/validation/accessibility_data.py (linhas 30-380)

    • Foque nas 3 novas validações: validate_alt_text_media_restriction, validate_alt_text_not_duplicate_label_caption, validate_decorative_figure_alt_text
    • Verifique correção em validate_alt_text (linha 67: validação de @content-type)

Como este poderia ser testado manualmente?

Pré-requisitos:

cd packtools
git checkout feature/alt-text-validations-i18n
pip install -e .

Teste 1 - Restrição de mídia (deve gerar ERROR):

<media mimetype="application" mime-subtype="pdf">
    <alt-text>Documento PDF</alt-text>
</media>
# Validar XML e verificar ERROR em "alt-text restriction for media"

Teste 2 - Duplicação de label (deve gerar WARNING):

<fig>
    <label>Figura 1</label>
    <graphic>
        <alt-text>Figura 1</alt-text>
    </graphic>
</fig>

Teste 3 - Figura decorativa (deve gerar WARNING):

<fig>
    <graphic>
        <alt-text>linha decorativa</alt-text>
    </graphic>
</fig>

Teste 4 - @Content-Type opcional (deve passar):

<graphic>
    <alt-text>Descrição da imagem</alt-text>
</graphic>

Teste 5 - Executar suite de testes:

python -m unittest tests.sps.validation.test_accessibility_data
# Esperado: Ran 17 tests - OK

Algum cenário de contexto que queira dar?

Contexto:
A especificação SPS 1.10 introduziu novas regras de acessibilidade para elementos visuais que não estavam sendo validadas. Documentos científicos publicados podem conter:

  • PDFs/ZIPs com alt-text (incorreto)
  • Alt-text duplicando label/caption (redundante)
  • Figuras decorativas sem identificação adequada

Impacto:

  • XMLs existentes podem gerar novos avisos/erros
  • Editores precisarão ajustar documentos não conformes
  • Melhora significativa na acessibilidade de documentos SciELO

Motivação:
Este PR faz parte do esforço de conformidade total com SPS 1.10, melhorando a qualidade e acessibilidade dos documentos publicados na plataforma SciELO.


Screenshots

N.A.


Quais são tickets relevantes?

N.A.


Referências

SPS 1.10

…ponse

Adiciona suporte a gettext e 4 novos campos de i18n nas respostas de
validação:
- msg_text e msg_params para templates de mensagens
- adv_text e adv_params para templates de conselhos

Habilita suporte multi-idioma para mensagens de validação mantendo
retrocompatibilidade com código existente.
…ent/mimetype

- Simplifica XPath para eliminar captura duplicada de elementos
- Adiciona propriedade parent_info para extrair dados de label e caption
- Adiciona propriedade mimetype_info para validação de elementos media
- Adiciona helper _get_xml_string para melhores mensagens de erro

Essas mudanças suportam novas validações de acessibilidade e melhoram
a extração de dados para conformidade com SPS 1.10.
Adiciona 3 novas validações de acessibilidade SPS 1.10:
1. validate_alt_text_media_restriction: restringe alt-text em media
apenas para vídeo/áudio
2. validate_alt_text_not_duplicate_label_caption: previne duplicação de
conteúdo
3. validate_decorative_figure_alt_text: força valor null para figuras
decorativas

Melhorias adicionais:
- Corrige validação de @Content-Type para ser opcional (valida apenas
quando presente)
- Adiciona suporte completo a internacionalização com gettext
- Adiciona adv_text e adv_params em todas as respostas de validação
Adiciona 3 novos parâmetros de nível de erro:
- alt_text_media_restriction_error_level: ERROR
- alt_text_duplication_error_level: WARNING
- decorative_alt_text_error_level: WARNING

Esses parâmetros configuram a severidade de validação para as novas
verificações de acessibilidade introduzidas no esforço de conformidade
SPS 1.10.
…existentes

Adiciona 10 novos casos de teste:
- 3 testes para validação de restrição de media (vídeo, áudio, pdf)
- 3 testes para detecção de duplicação de label/caption
- 2 testes para validação de figura decorativa
- 2 testes para campos de internacionalização

Corrige testes existentes:
- Substitui asserções frágeis baseadas em índice por filtros robustos
- Atualiza teste de estrutura para refletir comportamento correto do
XPath
- Adiciona teste para atributo @Content-Type opcional
@robertatakenaka robertatakenaka merged commit 526c771 into scieloorg:master Jan 15, 2026
6 checks passed
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request implements critical accessibility validation enhancements for the <alt-text> element according to SPS 1.10 specifications, improving compliance from 56% to 89%. The PR adds three new validation rules, fixes an optional attribute validation issue, and introduces comprehensive internationalization support using gettext.

Changes:

  • Adds three new accessibility validations: media restriction (alt-text only for video/audio), duplication prevention (alt-text cannot copy label/caption), and decorative figure handling (requires <alt-text>null</alt-text>)
  • Fixes @content-type validation to be optional (only validates when the attribute is present)
  • Implements full i18n support with four new response fields: msg_text, msg_params, adv_text, adv_params

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
packtools/sps/validation/utils.py Adds gettext support and new i18n fields (msg_text, msg_params, adv_text, adv_params) to validation response structures
packtools/sps/validation/accessibility_data.py Implements three new validation methods, fixes optional @content-type validation, and adds i18n support to all validation messages
packtools/sps/models/accessibility_data.py Simplifies XPath queries to prevent duplicates, adds parent_info property for label/caption extraction, adds mimetype_info property for media validation
packtools/sps/validation_rules/accessibility_data_rules.json Adds error level configuration for three new validation rules
tests/sps/validation/test_accessibility_data.py Adds comprehensive test coverage for new validations with 17 test cases including i18n field verification

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

error_level = self.params["long_desc_content_error_level"]
valid = False
validation_type = "format"
advice = f"long-desc has {len(long_desc)} characters in {long_desc_xml}. Provide text with more than to 120 characters."
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grammar error: "more than to" should be "more than". The phrase should read "Provide text with more than 120 characters" instead of "Provide text with more than to 120 characters".

Suggested change
advice = f"long-desc has {len(long_desc)} characters in {long_desc_xml}. Provide text with more than to 120 characters."
advice = f"long-desc has {len(long_desc)} characters in {long_desc_xml}. Provide text with more than 120 characters."

Copilot uses AI. Check for mistakes.
response = long_desc_results[0]

self.assertEqual(response["response"], "CRITICAL")
expected_advice = f"long-desc has {len(response['got_value'])} characters in <long-desc>Short description.</long-desc>. Provide text with more than to 120 characters."
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grammar error: The test expectation contains "more than to" which should be "more than". This test is validating against the current incorrect error message, so it should be updated to match the corrected version: "Provide text with more than 120 characters".

Suggested change
expected_advice = f"long-desc has {len(response['got_value'])} characters in <long-desc>Short description.</long-desc>. Provide text with more than to 120 characters."
expected_advice = f"long-desc has {len(response['got_value'])} characters in <long-desc>Short description.</long-desc>. Provide text with more than 120 characters."

Copilot uses AI. Check for mistakes.
Comment on lines +101 to +102
label = parent.findtext(".//label")
caption_title = parent.findtext(".//caption/title")
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential bug: Using .//label with findtext() performs a descendant search which could match nested labels in complex structures. Consider using ./label (direct child search) instead to avoid matching labels from nested figures. Same applies to the caption_title search on line 102. This ensures you only match the direct child label/caption of the parent element, not labels from deeply nested structures.

Suggested change
label = parent.findtext(".//label")
caption_title = parent.findtext(".//caption/title")
label = parent.findtext("./label")
caption_title = parent.findtext("./caption/title")

Copilot uses AI. Check for mistakes.
Comment on lines +245 to +251
else:
advice = None
advice_text = None
advice_params = None

# Só reporta se houver problema
if not valid:
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable advice is not used.

Suggested change
else:
advice = None
advice_text = None
advice_params = None
# Só reporta se houver problema
if not valid:
# Só reporta se houver problema

Copilot uses AI. Check for mistakes.
Comment on lines +245 to +251
else:
advice = None
advice_text = None
advice_params = None

# Só reporta se houver problema
if not valid:
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable advice_text is not used.

Suggested change
else:
advice = None
advice_text = None
advice_params = None
# Só reporta se houver problema
if not valid:
# Só reporta se houver problema

Copilot uses AI. Check for mistakes.
else:
advice = None
advice_text = None
advice_params = None
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable advice_params is not used.

Copilot uses AI. Check for mistakes.
xml_str = etree.tostring(self.node, encoding='unicode')
# Limita a 200 caracteres para não sobrecarregar logs
return xml_str[:200] + "..." if len(xml_str) > 200 else xml_str
except:
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Except block directly handles BaseException.

Suggested change
except:
except Exception:

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants