Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementa novas funções especiais de modificadores #115

Merged
merged 6 commits into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
Copy link
Contributor

Choose a reason for hiding this comment

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

Eu vou aceitar a PR com deg, mas vou querer a unidade graus também. Vou abrir outra issue com isso.

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
Loading