Skip to content

Criar validações para o elemento <list> #1090

@Rossi-Luciano

Description

@Rossi-Luciano

Objetivo

Implementar validações para o elemento <list> conforme a especificação SPS 1.10, aumentando a conformidade de X% para 70% (7 de 10 regras).

Nota: Algumas validações para <list> podem já estar parcialmente implementadas no repositório. Este Issue visa reavaliar, complementar e garantir cobertura completa das regras SPS 1.10.


Contexto

O elemento <list> identifica listas com dois ou mais itens no documento. Validações corretas garantem acessibilidade através do uso adequado do atributo @list-type ao invés de <label>, presença de elementos mínimos necessários, e uso correto de valores permitidos para tipos de lista.

Conformidade atual: X de 10 regras implementadas (X%)
Meta após implementação: 7 de 10 regras (70%)


Documentação SPS

Referência oficial: https://docs.google.com/document/d/1GTv4Inc2LS_AXY-ToHT3HmO66UT0VAHWJNOIqzBNSgA/edit?tab=t.0#heading=h.list

Regras principais conforme SPS 1.10:

  1. Atributo obrigatório:

    • @list-type é obrigatório em todos os <list>
  2. Valores permitidos para @list-type:

    • order - Lista ordenada com números (1, 2, 3...)
    • bullet - Lista desordenada com símbolos (•, -, etc.)
    • alpha-lower - Lista ordenada alfabética minúscula (a, b, c...)
    • alpha-upper - Lista ordenada alfabética maiúscula (A, B, C...)
    • roman-lower - Lista ordenada romana minúscula (i, ii, iii...)
    • roman-upper - Lista ordenada romana maiúscula (I, II, III...)
    • simple - Lista simples sem prefixo
  3. Estrutura mínima:

    • <list> deve conter pelo menos dois <list-item>
  4. Elementos permitidos:

    • <title> (opcional, mas recomendado quando disponível)
    • <list-item> (obrigatório, mínimo 2)
  5. Acessibilidade:

    • Não usar <label> dentro de <list-item> para rótulos
    • O atributo @list-type gera automaticamente os prefixos/rótulos
    • Uso de <label> é menos acessível e menos legível por máquina
  6. Listas aninhadas:

    • Permitido ter <list> dentro de <list-item>

Regras a Implementar

P0 – Críticas (implementar obrigatoriamente)

# Regra Nível Descrição
1 Validar presença de @list-type CRITICAL O atributo @list-type é obrigatório em <list>
2 Validar valores permitidos de @list-type ERROR O valor de @list-type deve estar na lista de valores permitidos
3 Validar presença mínima de <list-item> ERROR O elemento <list> deve conter pelo menos dois <list-item>
4 Validar ausência de <label> em <list-item> WARNING Para acessibilidade, não use <label> em <list-item> (o atributo @list-type gera rótulos automaticamente)

P1 – Importantes (implementar se possível)

# Regra Nível Descrição
5 Validar que cada <list-item> tem conteúdo WARNING Cada <list-item> deve conter pelo menos um elemento filho (tipicamente <p>)
6 Recomendar uso de <title> quando apropriado INFO Quando a lista tiver um título descritivo, recomenda-se usar <title>

P2 – Futuras (fora do escopo deste Issue)

# Regra Motivo de exclusão
7 Validar profundidade de aninhamento de listas Baixa prioridade - formato livre permite múltiplos níveis
8 Validar consistência de tipo em listas aninhadas Baixa prioridade - não há restrição SPS
9 Validar que <list-item> contém <p> ao invés de texto direto Média complexidade - schema permite várias estruturas
10 Validar que lista com um único item deveria ser parágrafo Baixa prioridade - decisão editorial

Arquivos a Criar/Modificar

Avaliar existentes (podem ter validações parciais):

  • packtools/sps/models/list.py ou similar – Verificar se modelo existe
  • packtools/sps/validation/list.py – Verificar validações existentes
  • packtools/sps/validation/rules/list_rules.json ou similar – Verificar configuração

Criar (se não existirem):

  • packtools/sps/models/list.py – Modelo de extração de dados
  • packtools/sps/validation/list.py – Validações
  • packtools/sps/validation/rules/list_rules.json – Configuração de níveis de erro
  • tests/sps/validation/test_list.py – Testes unitários

Referenciar (implementações similares):

  • packtools/sps/validation/fig.py – Validação de atributos obrigatórios
  • packtools/sps/validation/utils.py – Funções auxiliares (build_response)

Exemplos de XML

XML Válido (deve passar sem erros):

<!-- Exemplo 1: Lista com bullet -->
<list list-type="bullet">
    <title>Nam commodo</title>
    <list-item>
        <p>Morbi luctus elit enim.</p>
    </list-item>
    <list-item>
        <p>Nullam nunc leo.</p>
    </list-item>
    <list-item>
        <p>Proin id dui lorem.</p>
    </list-item>
</list>

<!-- Exemplo 2: Lista numérica (order) -->
<list list-type="order">
    <title>Vivamus cursus</title>
    <list-item>
        <p>Primeiro item.</p>
    </list-item>
    <list-item>
        <p>Segundo item.</p>
    </list-item>
</list>

<!-- Exemplo 3: Lista alfabética minúscula -->
<list list-type="alpha-lower">
    <list-item>
        <p>Item a.</p>
    </list-item>
    <list-item>
        <p>Item b.</p>
    </list-item>
</list>

<!-- Exemplo 4: Lista alfabética maiúscula -->
<list list-type="alpha-upper">
    <list-item>
        <p>Item A.</p>
    </list-item>
    <list-item>
        <p>Item B.</p>
    </list-item>
</list>

<!-- Exemplo 5: Lista romana minúscula -->
<list list-type="roman-lower">
    <list-item>
        <p>Item i.</p>
    </list-item>
    <list-item>
        <p>Item ii.</p>
    </list-item>
</list>

<!-- Exemplo 6: Lista romana maiúscula -->
<list list-type="roman-upper">
    <list-item>
        <p>Item I.</p>
    </list-item>
    <list-item>
        <p>Item II.</p>
    </list-item>
</list>

<!-- Exemplo 7: Lista simples -->
<list list-type="simple">
    <list-item>
        <p>Item sem prefixo.</p>
    </list-item>
    <list-item>
        <p>Outro item sem prefixo.</p>
    </list-item>
</list>

<!-- Exemplo 8: Lista com sub-item (aninhada) -->
<list list-type="order">
    <title>Vivamus cursus</title>
    <list-item>
        <p>Nullam gravida tellus eget condimentum egestas.</p>
        <list list-type="order">
            <list-item>
                <p>Curabitur luctus lorem ac feugiat pretium.</p>
            </list-item>
            <list-item>
                <p>Sub-item dois.</p>
            </list-item>
        </list>
    </list-item>
    <list-item>
        <p>Donec pulvinar odio ut enim lobortis.</p>
    </list-item>
</list>

<!-- Exemplo 9: Lista com mais de dois itens -->
<list list-type="bullet">
    <list-item>
        <p>Item 1.</p>
    </list-item>
    <list-item>
        <p>Item 2.</p>
    </list-item>
    <list-item>
        <p>Item 3.</p>
    </list-item>
    <list-item>
        <p>Item 4.</p>
    </list-item>
</list>

<!-- Exemplo 10: Lista sem título (opcional) -->
<list list-type="bullet">
    <list-item>
        <p>Item sem título.</p>
    </list-item>
    <list-item>
        <p>Outro item.</p>
    </list-item>
</list>

XML Inválido – Caso 1: Sem @list-type (CRITICAL)

<list>
    <list-item>
        <p>Item 1.</p>
    </list-item>
    <list-item>
        <p>Item 2.</p>
    </list-item>
</list>

Erro esperado: Atributo @list-type é obrigatório em <list>

XML Inválido – Caso 2: @list-type vazio (CRITICAL)

<list list-type="">
    <list-item>
        <p>Item 1.</p>
    </list-item>
    <list-item>
        <p>Item 2.</p>
    </list-item>
</list>

Erro esperado: Atributo @list-type não pode estar vazio

XML Inválido – Caso 3: @list-type com valor inválido (ERROR)

<list list-type="numbered">
    <list-item>
        <p>Item 1.</p>
    </list-item>
    <list-item>
        <p>Item 2.</p>
    </list-item>
</list>

Erro esperado: Valor "numbered" não está na lista de valores permitidos para @list-type. Valores permitidos: order, bullet, alpha-lower, alpha-upper, roman-lower, roman-upper, simple

XML Inválido – Caso 4: @list-type com valor inválido "unordered" (ERROR)

<list list-type="unordered">
    <list-item>
        <p>Item 1.</p>
    </list-item>
    <list-item>
        <p>Item 2.</p>
    </list-item>
</list>

Erro esperado: Valor "unordered" não está na lista de valores permitidos. Use bullet para listas desordenadas.

XML Inválido – Caso 5: Apenas um (ERROR)

<list list-type="bullet">
    <list-item>
        <p>Único item.</p>
    </list-item>
</list>

Erro esperado: Lista deve conter pelo menos dois <list-item>. Encontrado: 1

XML Inválido – Caso 6: Sem (ERROR)

<list list-type="bullet">
    <title>Título da lista</title>
</list>

Erro esperado: Lista deve conter pelo menos dois <list-item>. Encontrado: 0

XML Inválido – Caso 7: Com em (WARNING)

<list list-type="order">
    <list-item>
        <label>1.</label>
        <p>Primeiro item.</p>
    </list-item>
    <list-item>
        <label>2.</label>
        <p>Segundo item.</p>
    </list-item>
</list>

Erro esperado: Para acessibilidade, não use <label> em <list-item>. O atributo @list-type gera rótulos automaticamente.

XML Inválido – Caso 8: vazio (WARNING)

<list list-type="bullet">
    <list-item>
        <p>Item com conteúdo.</p>
    </list-item>
    <list-item>
    </list-item>
</list>

Erro esperado: <list-item> não deve estar vazio. Adicione conteúdo (tipicamente <p>).

XML Inválido – Caso 9: @list-type com uppercase (ERROR)

<list list-type="Order">
    <list-item>
        <p>Item 1.</p>
    </list-item>
    <list-item>
        <p>Item 2.</p>
    </list-item>
</list>

Erro esperado: Valor de @list-type deve ser em minúsculas. Use order ao invés de Order.

XML Inválido – Caso 10: @list-type com espaços (ERROR)

<list list-type=" bullet ">
    <list-item>
        <p>Item 1.</p>
    </list-item>
    <list-item>
        <p>Item 2.</p>
    </list-item>
</list>

Erro esperado: Valor de @list-type não deve conter espaços extras


Padrão de Implementação

Diretrizes Gerais:

  1. Seguir padrões existentes no repositório:

    • Consultar implementações similares como fig.py (validação de atributos obrigatórios)
    • Usar estrutura de classes já estabelecida no packtools
    • IMPORTANTE: Verificar se já existem validações parciais para <list> e integrá-las ou complementá-las
  2. Internacionalização (i18n):

    • OBRIGATÓRIO: Todas as mensagens devem suportar internacionalização
    • Usar advice_text e advice_params em build_response()
    • Consultar conversas anteriores sobre implementação de i18n no packtools
    • Referência: validações em article_contribs.py que já implementam i18n completo
  3. Validações condicionais:

    • Validações que dependem de contexto devem retornar None quando não aplicável
    • Exemplo: validação de <label> só se aplica se <label> existir
    • Exemplo: validação de conteúdo de <list-item> só se aplica se houver <list-item>
    • Usar filter_results() nos testes para remover None
  4. Uso de build_response():

    • Sempre usar parent=self.data (dict completo, nunca string)
    • Campo response deve conter: "OK", "WARNING", "ERROR", "CRITICAL"
    • Sempre fornecer advice_text e advice_params para i18n
  5. Modelo de dados:

    • Criar propriedade que retorna lista de dicionários (uma para cada <list>)
    • Cada dict deve conter: list_type, title, list_items (lista), has_label_in_items, parent, parent_id, parent_lang
    • Cada list_item deve conter: has_content, has_label, nested_lists (se houver)
  6. Contagem de <list-item>:

    • Usar XPath ou método .findall() para contar elementos filhos diretos
    • Não contar <list-item> de listas aninhadas
  7. Detecção de <label>:

    • Verificar presença de <label> em cada <list-item>
    • Alertar sobre questões de acessibilidade
  8. Validação de valores:

    • Criar constante com lista de valores permitidos
    • Comparação deve ser case-sensitive (valores devem ser minúsculos)
    • Trimmar espaços antes de validar

Testes Esperados

Casos de teste obrigatórios:

Atributo @list-type:

  • <list> com @list-type válido (OK)
  • <list> sem @list-type (CRITICAL)
  • @list-type vazio (CRITICAL)
  • @list-type apenas espaços (CRITICAL)

Valores permitidos de @list-type:

  • @list-type="order" (OK)
  • @list-type="bullet" (OK)
  • @list-type="alpha-lower" (OK)
  • @list-type="alpha-upper" (OK)
  • @list-type="roman-lower" (OK)
  • @list-type="roman-upper" (OK)
  • @list-type="simple" (OK)
  • @list-type="numbered" (ERROR - inválido)
  • @list-type="unordered" (ERROR - inválido)
  • @list-type="list" (ERROR - inválido)
  • @list-type="Order" (ERROR - uppercase)
  • @list-type="BULLET" (ERROR - uppercase)
  • @list-type=" bullet " (ERROR - espaços extras)

Quantidade de :

  • Lista com 2 <list-item> (OK - mínimo)
  • Lista com 3 <list-item> (OK)
  • Lista com 10 <list-item> (OK)
  • Lista com 1 <list-item> (ERROR)
  • Lista com 0 <list-item> (ERROR)

Uso de :

  • <list-item> sem <label> (OK)
  • <list-item> com <label> (WARNING)
  • Múltiplos <list-item> com <label> (WARNING para cada um)
  • Alguns itens com <label>, outros sem (WARNING apenas nos que têm)

Conteúdo de :

  • <list-item> com <p> (OK)
  • <list-item> vazio (WARNING)
  • <list-item> apenas com espaços (WARNING)
  • <list-item> com múltiplos <p> (OK)
  • <list-item> com lista aninhada (OK)

Uso de <title>:

  • Lista com <title> (OK)
  • Lista sem <title> (OK - opcional)
  • <title> vazio (permitir - não validar)
  • Múltiplos <title> (permitir - schema valida)

Listas aninhadas:

  • Lista com sub-lista em <list-item> (OK)
  • Múltiplos níveis de aninhamento (OK)
  • Sub-lista com mesmo tipo (OK)
  • Sub-lista com tipo diferente (OK)
  • Contagem de <list-item> não conta sub-listas (correto)

Casos de borda:

  • Lista muito longa (100+ itens) (OK - sem limite)
  • <list-item> com conteúdo complexo (OK)
  • Lista em diferentes contextos (<p>, <sec>, <app>) (OK)
  • Combinação de várias validações (múltiplos erros)

Total esperado: ~45 testes unitários

Estrutura de testes:

  • Usar filter_results() para remover None dos resultados
  • Asserções devem usar campo response (não is_valid)
  • Testes devem ser autocontidos e descritivos
  • Agrupar testes por categoria (atributos, valores, quantidade, acessibilidade)

Critérios de Aceite

O PR será aceito quando:

  • Verificação de validações existentes: Código existente para <list> foi analisado e integrado ou substituído adequadamente
  • Todas as regras P0 implementadas (4 validações CRITICAL/ERROR/WARNING)
  • Todas as regras P1 implementadas (2 validações WARNING/INFO)
  • Testes unitários passando com cobertura mínima de ~45 casos
  • Nenhum teste existente quebrado
  • Arquivo list_rules.json criado com todos os níveis de erro
  • Internacionalização completa em todas as mensagens (i18n obrigatório)
  • Código seguindo padrões do packtools (build_response, filter_results, validações condicionais)
  • Modelo de dados criado com extração adequada de estrutura de lista
  • Validação de quantidade de itens funcionando (mínimo 2)
  • Validação de valores permitidos case-sensitive
  • Validação de presença de <label> detectando problema de acessibilidade
  • Documentação inline clara (docstrings)

Referências

Documentação SPS:

Padrões JATS:

Acessibilidade:

Referências internas packtools:

  • Internacionalização: Consultar conversas anteriores sobre implementação de i18n
  • Implementações similares: fig.py (atributos obrigatórios)
  • Funções auxiliares: utils.py (build_response)

Labels Sugeridas

enhancement validation SPS-1.10 accessibility good-first-issue


Impacto Esperado

Antes:

  • Conformidade SPS 1.10 para <list>: X% (verificar validações existentes)
  • Listas sem @list-type podem passar
  • Valores inválidos de @list-type não detectados
  • Listas com único item não detectadas
  • Uso inadequado de <label> (problema de acessibilidade) não alertado

Depois:

  • Conformidade SPS 1.10 para <list>: 70% (7 de 10 regras)
  • Validação CRITICAL de @list-type obrigatório
  • Validação ERROR de valores permitidos
  • Validação ERROR de quantidade mínima de itens
  • Validação WARNING sobre uso de <label> (acessibilidade)
  • ~45 testes unitários garantindo qualidade
  • Internacionalização completa (PT/EN/ES)

Benefícios:

  • Melhora a qualidade dos XMLs SciELO
  • Promove acessibilidade através de marcação semântica correta
  • Garante que listas tenham estrutura mínima válida
  • Detecta uso de valores incorretos em @list-type
  • Alerta sobre práticas que prejudicam leitura por máquina
  • Facilita renderização consistente em diferentes plataformas
  • Melhora compatibilidade com tecnologias assistivas
  • Facilita manutenção e depuração de XMLs

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions