Class: Bddgenx::Parser
- Inherits:
-
Object
- Object
- Bddgenx::Parser
- Defined in:
- lib/parser.rb
Overview
Parser de arquivos de história, converte .txt em estrutura de hash com elementos :como, :quero, :para, :idioma e lista de :grupos.
Class Method Summary collapse
-
.ler_historia(caminho_arquivo) ⇒ Hash
Lê e analisa um arquivo de história, retornando um Hash com a estrutura: { como: String ou nil, quero: String ou nil, para: String ou nil, idioma: ‘pt’ ou ‘en’, grupos: [ { tipo: String (tipo de bloco), tag: String ou nil (tag opcional após o bloco), passos: Array<String> (linhas de passo), exemplos: Array<String> (linhas de exemplo) }, … ] }.
Class Method Details
.ler_historia(caminho_arquivo) ⇒ Hash
Lê e analisa um arquivo de história, retornando um Hash com a estrutura: {
como: String ou nil,
quero: String ou nil,
para: String ou nil,
idioma: 'pt' ou 'en',
grupos: [
{
tipo: String (tipo de bloco),
tag: String ou nil (tag opcional após o bloco),
passos: Array<String> (linhas de passo),
exemplos: Array<String> (linhas de exemplo)
},
...
]
}
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/parser.rb', line 41 def self.ler_historia(caminho_arquivo) # Carrega linhas do arquivo, preservando linhas vazias e encoding UTF-8 linhas = File.readlines(caminho_arquivo, encoding: 'utf-8').map(&:rstrip) # parser.rb (durante leitura do .txt) primeira_linha = File.readlines(caminho_arquivo).first idioma_forcado = primeira_linha&.match(/^#\s*lang(?:uage)?\s*:\s*(\w+)/i)&.captures&.first # Detecta idioma no topo do arquivo: suporta '# lang: <codigo>' ou '# language: <codigo>' idioma = 'pt' if linhas.first == idioma_forcado idioma = Regexp.last_match(1).downcase linhas.shift end # Extrai cabeçalho: linhas que começam com Como/Quero/Para (variações PT/EN) como, quero, para = nil, nil, nil linhas.reject! do |l| if l =~ /^\s*(?:como|eu como|as a)/i && como.nil? como = l true elsif l =~ /^\s*(?:quero|eu quero|quero que)/i && quero.nil? quero = l true elsif l =~ /^\s*(?:para|para eu|para que)/i && para.nil? para = l true else false end end # Inicializa estrutura da história historia = { como: como, quero: quero, para: para, idioma: idioma, grupos: [] } exemplos_mode = false # Processa cada linha restante para blocos e exemplos linhas.each do |linha| # Início de bloco de exemplos: [EXEMPLO], [EXEMPLOS] ou [EXAMPLES] com tag opcional if linha =~ /^\[(?:EXEMPLO|EXEMPLOS|EXAMPLES)\](?:@([\w\-]+))?$/i exemplos_mode = true # Cria array de exemplos no último grupo, se ainda não existir historia[:grupos].last[:exemplos] = [] next end # Início de bloco com tipo definido em TIPOS_BLOCOS e tag opcional if linha =~ /^\[(#{TIPOS_BLOCOS.join('|')})\](?:@([\w\-]+))?$/i exemplos_mode = false tipo = Regexp.last_match(1).upcase tag = Regexp.last_match(2) historia[:grupos] << { tipo: tipo, tag: tag, passos: [], exemplos: [] } next end # Atribui linha ao último bloco, como passo ou exemplo conforme modo next if historia[:grupos].empty? bloco = historia[:grupos].last if exemplos_mode bloco[:exemplos] << linha else bloco[:passos] << linha end end historia end |