Skip to content

Commit

Permalink
Implementa novas funções especiais de modificadores (#115)
Browse files Browse the repository at this point in the history
* Implementa novo método calc()
* Testes unitários para o método calcular()
* Implementa novo método gradiente-linear()
* Testes unitaŕios - método gradiente-linear()
* Implementa novo método contraste()
* Implementa testes unitários de valores para o método contraste()
  • Loading branch information
VitBrandao authored Mar 29, 2024
1 parent b81f5e4 commit 9e97f88
Show file tree
Hide file tree
Showing 14 changed files with 433 additions and 27 deletions.
7 changes: 7 additions & 0 deletions exemplos/exemplo3.foles
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,11 @@ lmht {
lmht {
colunas: 20px;
opacidade: 80%;
}

lmht {
espacamento: calcular(100px - 80px);
imagem-máscara: gradiente-linear(inferior, azul, vermelho);
origem-imagem-borda: gradiente-linear(90deg, verde, amarelo);
filtro: contraste(1.75rem);
}
101 changes: 92 additions & 9 deletions fontes/avaliador-sintatico/avaliador-sintatico.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,34 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
[codigoHEX.lexema],
);

case "calcular":
this.consumir(tiposDeSimbolos.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'calcular'.");
const valorCalc1 = this.avancarEDevolverAnterior();
const quantificadorCalc1 = this.avancarEDevolverAnterior();
const operadorCalc = this.avancarEDevolverAnterior();
const valorCalc2 = this.avancarEDevolverAnterior();
const quantificadorCalc2 = this.avancarEDevolverAnterior();
this.consumir(tiposDeSimbolos.PARENTESE_DIREITO, "Esperado parêntese direito após método 'calcular'.");
return new SeletorValor(
lexema,
[valorCalc1, quantificadorCalc1, operadorCalc, valorCalc2, quantificadorCalc2]
);

case "contraste":
this.consumir(tiposDeSimbolos.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'contraste'.");
const valorContraste = this.avancarEDevolverAnterior();
let quantificadorContraste;
if (this.simbolos[this.atual].tipo === 'QUANTIFICADOR') {
quantificadorContraste = this.avancarEDevolverAnterior();
} else {
quantificadorContraste = null;
}
this.consumir(tiposDeSimbolos.PARENTESE_DIREITO, "Esperado parêntese direito após método 'contraste'.");
return new SeletorValor(
lexema,
[valorContraste, quantificadorContraste]
);

case "curva-cúbica" || "curva-cubica":
this.consumir(tiposDeSimbolos.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'cubic-bezier'.");
const parametro1 = this.avancarEDevolverAnterior();
Expand All @@ -93,6 +121,61 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
[valorFit['lexema'], quantificadorFit['lexema']]
);

case "gradiente-linear":
this.consumir(tiposDeSimbolos.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'gradiente-linear'.");
const valorAngulo = this.avancarEDevolverAnterior();
let quantificadorAngulo;
if (valorAngulo.tipo === 'QUALITATIVO') {
switch (valorAngulo.lexema) {
case 'superior':
valorAngulo.lexema = '0'
valorAngulo.tipo = 'NUMERO'
quantificadorAngulo = {
tipo: 'QUANTIFICADOR',
lexema: 'deg',
}
break;
case 'direita':
valorAngulo.lexema = '90'
valorAngulo.tipo = 'NUMERO'
quantificadorAngulo = {
tipo: 'QUANTIFICADOR',
lexema: 'deg',
}
break;
case 'inferior':
valorAngulo.lexema = '180'
valorAngulo.tipo = 'NUMERO'
quantificadorAngulo = {
tipo: 'QUANTIFICADOR',
lexema: 'deg',
}
break;
case 'esquerda':
valorAngulo.lexema = '270'
valorAngulo.tipo = 'NUMERO'
quantificadorAngulo = {
tipo: 'QUANTIFICADOR',
lexema: 'deg',
}
break;
default:
break;
}
} else {
quantificadorAngulo = this.avancarEDevolverAnterior();
}

this.consumir(tiposDeSimbolos.VIRGULA, "Esperado vírgula após segundo argumento do método gradiente-linear.");
const cor1 = this.avancarEDevolverAnterior();
this.consumir(tiposDeSimbolos.VIRGULA, "Esperado vírgula após segundo argumento do método gradiente-linear.");
const cor2 = this.avancarEDevolverAnterior();
this.consumir(tiposDeSimbolos.PARENTESE_DIREITO, "Esperado parêntese direito após método 'gradiente-linear'.");
return new SeletorValor(
lexema,
[valorAngulo, quantificadorAngulo, cor1, cor2]
);

case "hsl":
this.consumir(tiposDeSimbolos.PARENTESE_ESQUERDO, "Esperado parêntese esquerdo após método 'hsl'.");
const HdeHSL = this.avancarEDevolverAnterior();
Expand Down Expand Up @@ -227,7 +310,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
[url]
);
}

throw new Error(`Método ${lexema} não reconhecido em FolEs.`);
}

Expand Down Expand Up @@ -281,9 +364,9 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
}

private tratarValorNumerico(modificador: Simbolo): Boolean {
if(!(ValorNumerico.includes(modificador.lexema))) {
if (!(ValorNumerico.includes(modificador.lexema))) {
if (ValorNumericoComQuantificador.includes(modificador.lexema)) {
if(this.simbolos[this.atual].tipo === 'QUANTIFICADOR') {
if (this.simbolos[this.atual].tipo === 'QUANTIFICADOR') {
return true;
} else {
return false;
Expand Down Expand Up @@ -421,7 +504,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
tiposDeSimbolos.IDENTIFICADOR,
"Esperado nome do modificador."
);

this.consumir(
tiposDeSimbolos.DOIS_PONTOS,
"Esperado ':' após nome do modificador."
Expand All @@ -434,10 +517,10 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
quantificador = this.avancarEDevolverAnterior();
}*/

if (valorModificador.hasOwnProperty('tipo') && valorModificador.tipo === tiposDeSimbolos.NUMERO) {
if (valorModificador.hasOwnProperty('tipo') && valorModificador.tipo === tiposDeSimbolos.NUMERO) {
const tratarValorNumerico = this.tratarValorNumerico(modificador);

if(tratarValorNumerico) {
if (tratarValorNumerico) {
quantificador = this.avancarEDevolverAnterior();
}
}
Expand Down Expand Up @@ -485,7 +568,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
}

this.avancarEDevolverAnterior(); // chave direita
return {
return {
modificadores,
declaracoesAninhadas
};
Expand All @@ -504,7 +587,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
default:
const seletores = this.resolverSeletores();
const modificadoresEDeclaracoesAninhadas = this.resolverModificadoresEDeclaracoesAninhadas();

return new Declaracao(
seletores,
modificadoresEDeclaracoesAninhadas.modificadores,
Expand All @@ -517,7 +600,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
this.simbolos = simbolos;
this.erros = [];
this.atual = 0;

const declaracoes: Declaracao[] = [];
while (!this.estaNoFinal()) {
declaracoes.push(this.declaracao());
Expand Down
3 changes: 3 additions & 0 deletions fontes/lexador/palavras-reservadas/foles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,13 @@ export default {
"ms": tiposDeSimbolos.QUANTIFICADOR,

// Métodos
"calcular": tiposDeSimbolos.METODO,
"contraste": tiposDeSimbolos.METODO,
"curva-cubica": tiposDeSimbolos.METODO,
"curva-cúbica": tiposDeSimbolos.METODO,
"encaixar-conteudo": tiposDeSimbolos.METODO,
"encaixar-conteúdo": tiposDeSimbolos.METODO,
"gradiente-linear": tiposDeSimbolos.METODO,
"hsl": tiposDeSimbolos.METODO,
"hsla": tiposDeSimbolos.METODO,
"hex": tiposDeSimbolos.METODO,
Expand Down
5 changes: 2 additions & 3 deletions fontes/modificadores/conteudo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ export class Conteudo extends Modificador {
constructor(valor: string, quantificador?: string, pragmas?: PragmasModificador) {
super(["conteudo", "conteúdo"], "content", pragmas);

// Também aceita como valor as funções linear-gradient(), image-set() e counter()

const valoresExtra = ['url'];
// Também aceita como valor as funções image-set() e counter()
const valoresExtra = ['url', 'linear-gradient'];
validarValores('conteúdo', valor, this.valoresAceitos, valoresExtra);

this.valor = valor;
Expand Down
3 changes: 2 additions & 1 deletion fontes/modificadores/espacamento.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ export class Espacamento extends Modificador {
// Pode receber também dois valores. Ex.: espacamento: 10px 2mm;
// Também pode receber a função calc. Ex.: espacamento: calc(20% + 20px);

validarValorNumerico('espaçamento', valor);
const valoresExtra = ['calc'];
validarValorNumerico('espaçamento', valor, undefined, valoresExtra);

this.valor = valor;

Expand Down
2 changes: 1 addition & 1 deletion fontes/modificadores/filtro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class Filtro extends Modificador {
// filter: brightness(0.4);
// filter: contrast(200%);

const valoresExtra = ['url'];
const valoresExtra = ['url', 'contrast'];
validarValores('filtro', valor, this.valoresAceitos, valoresExtra);

this.valor = valor;
Expand Down
6 changes: 2 additions & 4 deletions fontes/modificadores/imagem-mascara.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@ export class ImagemMascara extends Modificador {
constructor(valor: string, quantificador: string, pragmas?: PragmasModificador) {
super(["imagem-mascara", "imagem-máscara"], "mask-image", pragmas);

// OBS.: Também pode receber funções específicas do grupo <image>
// Ex.: mask-image: linear-gradient(rgba(0, 0, 0, 1), transparent);
// OBS.: Também pode receber a função image
// Ex.: mask-image: image(url(mask.png), skyblue);

// A validação abaixo cobre os valores aceitos e extras

const valoresExtra = ['url'];
const valoresExtra = ['url', 'linear-gradient'];
validarValores('imagem-máscara', valor, this.valoresAceitos, valoresExtra);

this.valor = valor;
Expand Down
2 changes: 1 addition & 1 deletion fontes/modificadores/origem-imagem-borda.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export class OrigemImagemBorda extends Modificador {
constructor(valor: string, quantificador?: string, pragmas?: PragmasModificador) {
super("origem-imagem-borda", "border-image-source", pragmas);

const valoresExtra = ['url'];
const valoresExtra = ['url', 'linear-gradient'];
validarValores('origem-imagem-borda', valor, this.valoresAceitos, valoresExtra);
this.valor = valor;

Expand Down
6 changes: 6 additions & 0 deletions fontes/valores/dicionario-valores.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { Calcular } from "./metodos/calcular";
import { Contraste } from "./metodos/contraste";
import { CurvaCubica } from "./metodos/curva-cubica";
import { EncaixarConteudo } from "./metodos/encaixar-conteudo";
import { GradienteLinear } from "./metodos/gradiente-linear";
import { HexadecimalCor } from "./metodos/hexadecimal-cor";
import { Hsl } from "./metodos/hsl";
import { Hsla } from "./metodos/hsla";
Expand All @@ -12,10 +15,13 @@ import { Passos } from "./metodos/passos";
import { Url } from "./metodos/url";

export const DicionarioValores: { [nomeFolEs: string]: any } = {
"calcular": Calcular,
"contraste": Contraste,
"curva-cubica": CurvaCubica,
"curva-cúbica": CurvaCubica,
"encaixar-conteudo": EncaixarConteudo,
"encaixar-conteúdo": EncaixarConteudo,
"gradiente-linear": GradienteLinear,
"hsl": Hsl,
"hsla": Hsla,
"hex": HexadecimalCor,
Expand Down
25 changes: 25 additions & 0 deletions fontes/valores/metodos/calcular.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Simbolo } from "../../lexador";
import { Metodo } from "./metodo";

export class Calcular extends Metodo {
valor1: number;
quantificador1: string;
operador: string;
valor2: number;
quantificador2: string;
traducao: string;

constructor(valor1: Simbolo, quantificador1: Simbolo, operador: Simbolo, valor2: Simbolo, quantificador2: Simbolo) {
super();
this.valor1 = Number(valor1.lexema);
this.quantificador1 = quantificador1.lexema;
this.operador = operador.lexema;
this.valor2 = Number(valor2.lexema);
this.quantificador2 = quantificador2.lexema;
this.traducao = 'calc';
}

paraTexto() {
return `calc(${this.valor1}${this.quantificador1} ${this.operador} ${this.valor2}${this.quantificador2})`
}
}
24 changes: 24 additions & 0 deletions fontes/valores/metodos/contraste.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Simbolo } from "../../lexador";
import { Metodo } from "./metodo";

export class Contraste extends Metodo {
valor: number;
quantificador: string;
traducao: string;

constructor(valor: Simbolo, quantificador: Simbolo) {
super();
this.valor = Number(valor.lexema);

this.quantificador = quantificador ? quantificador.lexema : null;
this.traducao = 'contrast';
}

paraTexto() {
if (this.quantificador) {
return `contrast(${this.valor}${this.quantificador})`
}

return `contrast(${this.valor})`
}
}
26 changes: 26 additions & 0 deletions fontes/valores/metodos/gradiente-linear.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Simbolo } from "../../lexador";
import { Metodo } from "./metodo";
import { cores } from "../../modificadores/atributos/cores";

export class GradienteLinear extends Metodo {
valorAngulo: number;
quantificadorAngulo: string;
cor1: string;
cor2: string;
traducao: string;

constructor(valorAngulo: Simbolo, quantificadorAngulo: Simbolo, cor1: Simbolo, cor2: Simbolo) {
super();
this.valorAngulo = Number(valorAngulo.lexema);
this.quantificadorAngulo = quantificadorAngulo.lexema;
this.cor1 = cor1.lexema;
this.cor2 = cor2.lexema;
this.traducao = 'linear-gradient';
}

paraTexto() {
this.cor1 = cores[this.cor1];
this.cor2 = cores[this.cor2];
return `linear-gradient(${this.valorAngulo}${this.quantificadorAngulo}, ${this.cor1}, ${this.cor2})`
}
}
27 changes: 26 additions & 1 deletion testes/listas/metodos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,23 @@ export const MetodoLinear: Array<string> = [
'transição',
];

export const MetodoCalcular: Array<string> = [
'espacamento',
'espaçamento',
];

export const MetodoGradienteLinear: Array<string> = [
'imagem-mascara',
'imagem-máscara',
'origem-imagem-borda',
'conteudo',
'conteúdo',
];

export const MetodoContraste: Array<string> = [
'filtro',
];


export const TraducaoValoresMetodos: Object = {
'altura-maxima': 'max-height',
Expand Down Expand Up @@ -87,4 +104,12 @@ export const TraducaoValoresMetodos: Object = {
'modelo-colunas-em-grade': 'grid-template-columns',
'modelo-em-grade': 'grid-template',
'modelo-linhas-em-grade': 'grid-template-rows',
}
'espaçamento': 'gap',
'espacamento': 'gap',
'imagem-mascara': 'mask-image',
'imagem-máscara': 'mask-image',
'origem-imagem-borda': 'border-image-source',
'conteudo': 'content',
'conteúdo': 'content',
'filtro': 'filter',
}
Loading

0 comments on commit 9e97f88

Please sign in to comment.