br.gov.lexml.parser.pl.output.html.HtmlRenderer.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lexml-parser-projeto-lei Show documentation
Show all versions of lexml-parser-projeto-lei Show documentation
Brazillian legal document parsing library.
The newest version!
package br.gov.lexml.parser.pl.output.html
import scala.xml._
import br.gov.lexml.parser.pl._
import br.gov.lexml.parser.pl.rotulo._
import br.gov.lexml.parser.pl.block._
import br.gov.lexml.parser.pl.output.LexmlRenderer
import br.gov.lexml.parser.pl.rotulo.rotuloParser.Fem
object HtmlRenderer {
def rename(label : String,n : NodeSeq) : NodeSeq = n match {
case Elem(prefix,_, attributes, scope, child@_*) =>
Elem(prefix, label, attributes, scope, true, child:_*)
case _ => n
}
def elemLabel(r : Rotulo) : String = r match {
case _ : RotuloArtigo => "Artigo"
case RotuloParagrafo(None,_,_) => "Caput"
case _ : RotuloParagrafo => "Paragrafo"
case _ : RotuloInciso => "Inciso"
case _ : RotuloAlinea => "Alinea"
case _ : RotuloItem => "Item"
case RotuloPena => "Pena"
case _ : RotuloParte => "Parte"
case _ : RotuloLivro => "Livro"
case _ : RotuloTitulo => "Titulo"
case _ : RotuloSubTitulo => throw new RenderException("Sub-título não suportado pelo parser")
case _ : RotuloCapitulo => "Capitulo"
case _ : RotuloSubCapitulo => throw new RenderException("Sub-capítulo não suportado pelo parser")
case _ : RotuloSecao => "Secao"
case _ : RotuloSubSecao => "SubSecao"
case _ : RotuloAlteracao => "Alteracao"
case x => throw new RuntimeException("Lexml Xml renderer. Elemento não esperado:" + x)
}
def renderNumeral(num : Int) : String = {
if (num > 1000) { "%s.%03d".format(renderNumeral (num / 1000),num % 100) }
else { num.toString }
}
def renderOrdinal(num : Int) : String = renderNumeral(num) + (if (num < 10) "º" else "")
def renderComp(onum : Option[Int]) : String = onum.map("-" + renderAlphaSeq(_).toUpperCase).getOrElse("")
def renderRomano(num : Int) : String = {
def rom(cX : String, cV : String,cI : String, d : Int) : String = d match {
case 0 => ""
case 9 => cI + cX
case 4 => cI + cV
case _ if d >= 5 => cV + (cI * (d - 5))
case _ => cI * d
}
("M" * (num / 1000)) + rom("M","D","C",(num / 100) % 10) + rom("C","L","X",(num /10) % 10) + rom("X","V","I",num % 10)
}
def renderAlphaSeq(num : Int) : String = {
def rend(n : Int) : String = n match {
case 0 => ""
case _ => {
val nn = n - 1
rend(nn/26) + ('a' + (nn % 26)).asInstanceOf[Char]
}
}
rend(num+1)
}
private implicit class Unico(un : Boolean) {
def unicoChar = if (un) { "u" } else { "" }
def unicoMajStr(alt : => String) : String =
if(un) { "ÚNICO" } else { alt }
def unicaMajStr(alt : => String) : String =
if(un) { "ÚNICA" } else { alt }
def unicoMinStr(alt : => String) : String =
if(un) { "Único" } else { alt }
def unicaMinStr(alt : => String) : String =
if(un) { "Única" } else { alt }
}
class RenderException(msg : String) extends RuntimeException(msg)
def renderRotulo(r : Rotulo) : NodeSeq = r match {
case RotuloArtigo(1,None,true) => Artigo único.
case RotuloArtigo(num,comp,_) => Artigo {renderOrdinal(num) + renderComp(comp) + (if (num>=10 || comp.isDefined) "." else "")}
case RotuloParagrafo(None,_,_) => Caput.
case RotuloParagrafo(Some(1),None,true) => Parágrafo único.
case RotuloParagrafo(Some(num),comp,_) => Parágrafo {renderOrdinal(num) + renderComp(comp) + (if (num>=10 || comp.isDefined) "." else "")}
case RotuloInciso(num, comp) => Inciso {renderRomano(num).toUpperCase + renderComp(comp)} –
case RotuloAlinea(num, comp) => Alínea {renderAlphaSeq(num-1).toLowerCase + renderComp(comp)})
case RotuloItem(num,comp) => Item {num.toString} –
case RotuloPena => Pena –
case RotuloParte(Left(rot),_,_,_,_) => PARTE ${rot}
case RotuloParte(_,_,_,_,Some(rot)) => PARTE ${rot}
case RotuloParte(_,_,true,_,_) => PARTE ÚNICA
case RotuloParte(Right(num),comp,_,true,_) =>
val rot = LexmlRenderer.renderOrdinalExtenso(num = num,g = Fem,allCaps = true) + renderComp(comp)
PARTE ${rot}
case RotuloParte(Right(num),comp,_,_,_) =>
val rot = renderRomano(num).toUpperCase + renderComp(comp)
PARTE ${rot}
case RotuloLivro(Left(_),_, _) => throw new RenderException("Livro sem número não suportado na renderização")
case RotuloLivro(Right(num),comp,unico) => LIVRO {unico.unicoMajStr(renderRomano(num).toUpperCase + renderComp(comp))}
case RotuloTitulo(num, comp,unico) => TÍTULO {unico.unicoMajStr(renderRomano(num) + renderComp(comp))}
case RotuloSubTitulo(num, comp,unico) => SUB-TÍTULO {unico.unicoMajStr(renderRomano(num) + renderComp(comp))}
case RotuloCapitulo(num, comp,unico) => CAPÍTULO {unico.unicoMajStr(renderRomano(num) + renderComp(comp))}
case RotuloSubCapitulo(num, comp,unico) => SUB-CAPÍTULO {unico.unicoMajStr(renderRomano(num) + renderComp(comp))}
case RotuloSecao(num, comp,unica) => SEÇÃO {unica.unicaMajStr(renderRomano(num) + renderComp(comp))}
case RotuloSubSecao(num, comp,unica) => SUBSEÇÃO {unica.unicaMajStr(renderRomano(num) + renderComp(comp))}
case RotuloAlteracao(num) => Alteracao {num.toString}
case x => throw new RuntimeException("Lexml Xml renderer. Elemento não esperado:" + x)
}
def renderCompId(n : Option[Int]) = n.map("-" + _.toString).getOrElse("")
def renderId(r : Rotulo) : String = r match {
case RotuloArtigo(num,comp,_) => "art%d%s" format(num,renderCompId(comp))
case RotuloParagrafo(None,_,_) => "cpt"
case RotuloParagrafo(Some(num),comp,_) => "par%d%s" format(num,renderCompId(comp))
case RotuloInciso(num, comp) => "inc%d%s" format(num,renderCompId(comp))
case RotuloAlinea(num, comp) => "ali%d%s" format(num,renderCompId(comp))
case RotuloItem(num,comp) => "ite%d%s" format(num,renderCompId(comp))
case RotuloPena => "pena"
case RotuloParte(Left(_),_, _,_,_) => throw new RenderException("Parte sem número não suportado na renderização")
case RotuloParte(Right(num),comp,unica,_,_) => "prt%d%s%s" format(num,unica.unicoChar,renderCompId(comp))
case RotuloLivro(Left(_),_, _) => throw new RenderException("Livro sem número não suportado na renderização")
case RotuloLivro(Right(num),comp,unico) => "liv%d%s%s" format(num,unico.unicoChar,renderCompId(comp))
case RotuloTitulo(num, comp,unico) => "tit%d%s%s" format(num,unico.unicoChar,renderCompId(comp))
case RotuloSubTitulo(num, comp, _) => throw new RenderException("Sub-título não suportado pelo parser")
case RotuloCapitulo(num, comp,unico) => "cap%d%s%s" format(num,unico.unicoChar,renderCompId(comp))
case RotuloSubCapitulo(num, comp, _) => throw new RenderException("Sub-capítulo não suportado pelo parser")
case RotuloSecao(num, comp,unica) => "sec%d%s%s" format(num,unica.unicoChar,renderCompId(comp))
case RotuloSubSecao(num, comp,unica) => "sub%d%s%s" format(num,unica.unicoChar,renderCompId(comp))
case RotuloAlteracao(num) => "alt%d" format(num)
case x => throw new RuntimeException("Lexml Xml renderer. Elemento não esperado:" + x)
}
def renderId(path : List[Rotulo]) : String = path.reverse.map(renderId).mkString("","_","")
def render(idPai : String) : ((Block,Int)) => NodeSeq = { case (b : Block,idx : Int) => b match {
case d : Dispositivo => {
val id = d.id
def mid(prefix : String) = prefix + "_" + id
(
{
d.titulo.map(ti => {ti.nodes}).getOrElse(NodeSeq.Empty)
}
{renderRotulo(d.rotulo)}
{
d.conteudo match {
case None => NodeSeq.Empty
case Some(x) => { x match {
case Omissis(_,_,_) => ...
case Paragraph(ns,_) => {ns}
case _ => não esperado: { x.toString }
} }
}
}
{
d.subDispositivos match {
case Nil => NodeSeq.Empty
case _ => {
NodeSeq fromSeq d.subDispositivos.zipWithIndex.flatMap(render(id))
}
}
}
{d.links.map(x => - {x}
)}
)
}
case a : Alteracao => { val id = renderId(a.path) ; (
{
a.matches.map(m => - {m.toString}
)
}
{
NodeSeq fromSeq a.blocks.zipWithIndex.flatMap(render(id))
}
) }
case Omissis(abreAspas,fechaAspas,notaAlteracao) => ...
case Paragraph(ns,_) => {NodeSeq fromSeq ns}
case Table(elem) => elem
case x => Elemento não esperado: {x.toString}
}
}
def renderArticulacao(blocks : List[Block]) : NodeSeq = {NodeSeq fromSeq blocks.zipWithIndex.flatMap(render(""))}
def renderParteInicial(pl : ProjetoLei) : NodeSeq = (
Epígrafe:
{pl.epigrafe.toNodeSeq}
Ementa:
{pl.ementa.map(x => {x.toNodeSeq}
).getOrElse(NodeSeq.Empty)}
Preâmbulo:
{NodeSeq fromSeq pl.preambulo.flatMap(_.toNodeSeq)}
)
/* */
def render(pl : ProjetoLei, headers : NodeSeq, bodyHead : NodeSeq, bodyTail : NodeSeq) : NodeSeq = (
{headers}
{bodyHead}
{renderParteInicial(pl)}
{renderArticulacao(pl.articulacao)}
{bodyTail}
)
}