Skip to content
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
2 changes: 1 addition & 1 deletion exemplos/exemplo.foles
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@

lmht {
cor-fundo: hsl(50, 80%, 80%);
}
}
15 changes: 15 additions & 0 deletions exemplos/exemplo6.foles
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
lmht {
recursos-fonte: "c2sc", "hist";
}

lmht {
eventos-ponteiro: delimitarCaixa;
}

lmht {
espacamento-letras: .2rem;
}

lmht {
fonte-texto: "Times New Roman", sans-serifa;
}
21 changes: 19 additions & 2 deletions fontes/avaliador-sintatico/avaliador-sintatico.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1793,9 +1793,26 @@
return classeModificadora as Modificador;
}

const atribuicaoAbreviada =
this.tratarAtribuicaoAbreviada(valoresModificador);
if (valoresModificador[0].tipo === tiposDeSimbolos.PONTO) {
const valorComPonto = `${valoresModificador[0].lexema}${valoresModificador[1].lexema}`;
const classeModificadora = new SeletorModificador(
modificador.lexema,
valorComPonto,
quantificador && quantificador.hasOwnProperty("lexema")
? quantificador.lexema
: quantificador,

Check warning on line 1803 in fontes/avaliador-sintatico/avaliador-sintatico.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
{
linha: modificador.linha,
colunaInicial: modificador.colunaInicial,
colunaFinal: modificador.colunaFinal,
},
);

return classeModificadora as Modificador;
}

const atribuicaoAbreviada = this.tratarAtribuicaoAbreviada(valoresModificador);

const classeModificadora = new SeletorModificador(
modificador.lexema,
atribuicaoAbreviada,
Expand Down
2 changes: 1 addition & 1 deletion fontes/foles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,6 @@ export class FolEs {
}

// const testeFoles = new FolEs(false);
// console.log(testeFoles.converterParaCss('../exemplos/exemplo5.foles'));
// console.log(testeFoles.converterParaCss('../exemplos/exemplo6.foles'));
// console.log(a.converterParaFolEs('../exemplos/reverso/exemplo-metodos.css'));
// console.log(a.converterParaFolEs('../exemplos/reverso/exemplo-codigo.css'));
3 changes: 3 additions & 0 deletions fontes/lexador/palavras-reservadas/foles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -396,12 +396,15 @@ export default {
"forcar-fim": tiposDeSimbolos.QUALITATIVO,
"forçar-fim": tiposDeSimbolos.QUALITATIVO,
frente: tiposDeSimbolos.QUALITATIVO,
"grossa": tiposDeSimbolos.QUALITATIVO,
"inicio-em-linha": tiposDeSimbolos.QUALITATIVO,
"início-em-linha": tiposDeSimbolos.QUALITATIVO,
isolar: tiposDeSimbolos.QUALITATIVO,
manipulacao: tiposDeSimbolos.QUALITATIVO,
manipulação: tiposDeSimbolos.QUALITATIVO,
manual: tiposDeSimbolos.QUALITATIVO,
"media": tiposDeSimbolos.QUALITATIVO,
"média": tiposDeSimbolos.QUALITATIVO,
"modo-conteudo": tiposDeSimbolos.QUALITATIVO,
"modo-conteúdo": tiposDeSimbolos.QUALITATIVO,
"mudar-conteudo": tiposDeSimbolos.QUALITATIVO,
Expand Down
15 changes: 15 additions & 0 deletions fontes/modificadores/atributos/fontes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export const fontes: { [nomeFoles: string]: string } = {
// Fontes (family font name)
Arial: "Arial",
"Brush Script MT": "Brush Script MT",
"Courier New": "Courier New",
Garamond: "Garamond",
"Gill Sans Extrabold": "Gill Sans Extrabold",
Georgia: "Georgia",
Helvetica: "Helvetica",
"Lucida Console": "Lucida Console",
Tahoma: "Tahoma",
"Trebuchet MS": "Trebuchet MS",
"Times New Roman": "Times New Roman",
Verdana: "Verdana",
};
7 changes: 7 additions & 0 deletions fontes/modificadores/espacamento-letras.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,14 @@ export class EspacamentoLetras extends Modificador {

// Também pode receber valores numéricos com ponto (.) na frente
// Ex.: espaçamento-letras: .2rem;
let valorComPonto = false;

if (!valorVariavel) {
if (valor.includes('.')) {
valorComPonto = true;
valor = valor.replace('.', '');
}

validarValorNumerico(
"espaçamento-letras",
valor,
Expand All @@ -41,6 +47,7 @@ export class EspacamentoLetras extends Modificador {
}
}

if (valorComPonto) valor = `.${valor}`;
this.valor = valor;
}
}
13 changes: 12 additions & 1 deletion fontes/modificadores/eventos-ponteiro.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
import { valoresGlobais } from "./atributos/globais";
import { Modificador, PragmasModificador } from "./superclasse";
import { validarValores } from "./validacoes/comum";

export class EventosPonteiro extends Modificador {
valoresAceitos: { [valorFoles: string]: string } = {
auto: "auto",
nenhum: "none",
pinturaVisivel: "visiblePainted",
Copy link
Contributor

Choose a reason for hiding this comment

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

Estou pensando em não mimetizar esse padrão camelCase mais futuramente. Me parece que foi algo definido apressadamente no próprio padrão do CSS, mas não é algo que pretendo manter em FolEs. Por ora, deixamos assim.

pinturaVisível: "visiblePainted",
preenchimentoVisivel: "visibleFill",
preenchimentoVisível: "visibleFill",
tracoVisivel: "visibleStroke",
traçoVisível: "visibleStroke",
pintado: "painted",
preencher: "fill",
tracado: "stroke",
traçado: "stroke",
delimitarCaixa: "bounding-box",
tudo: "all",
};

constructor(
Expand Down
44 changes: 32 additions & 12 deletions fontes/modificadores/fonte-texto.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Modificador, PragmasModificador } from "./superclasse";
import { validarValores } from "./validacoes/comum";
import { validarValorFonte } from "./validacoes/fonte";
import { validarValorString } from "./validacoes/string";

export class FonteTexto extends Modificador {
valoresAceitos: { [valorFoles: string]: string } = {
Expand All @@ -16,6 +17,21 @@ export class FonteTexto extends Modificador {
math: "math",
emoji: "emoji",
fangsong: "fangsong",
"serifa": "serif",
"sem-serifa": "sans-serif",
"monoespaço": "monospace",
"monoespaco": "monospace",
"cursiva": "cursive",
"fantasia": "fantasy",
"sistema-iu": "system-ui",
"iu-serifa": "ui-serif",
"iu-sem-serifa": "ui-sans-serif",
"iu-monoespaço": "ui-monospace",
"iu-monoespaco": "ui-monospace",
"iu-arredondada": "ui-rounded",
"matematica": "math",
"matemática": "math",
"serifa-chinesa": "fangsong",
};

constructor(
Expand All @@ -26,18 +42,22 @@ export class FonteTexto extends Modificador {
) {
super("fonte-texto", "font-family", pragmas);

// OBS.: A lista de valores aceitos inclui todas as FONTES GENÉRICAS (<generic-name>).
// Porém, o modificador também pode receber DOIS PARÂMETROS,
// sendo o PRIMEIRO o nome de qualquer fonte existente (<family-name>).
if (!valorVariavel) {
if (valor.includes(",")) {
const separarValores = valor.split(", ");

// Ex.: fonte-texto: "Gill Sans Extrabold", sans-serif;

// OBS.2: Fontes com mais de uma palavra devem ser passadas como string (entre "");
// OBS.3: O segundo parâmetro é obrigatório para o caso da primeira fonte não estar disponível.

// A lógica abaixo cobre somente o recebimento dos valores genéricos.
if (!valorVariavel)
validarValores("fonte-texto", valor, this.valoresAceitos);
separarValores.forEach((valorIndividual) => {
const valorString = validarValorString(valorIndividual);
if (valorString) valorIndividual = valorIndividual.replace(/^["']|["']$/g, '');
validarValorFonte("fonte-texto", valorIndividual, this.valoresAceitos);
});
} else {
const valorString = validarValorString(valor);
if (valorString) valor = valor.replace(/^["']|["']$/g, '');
validarValorFonte("fonte-texto", valor, this.valoresAceitos);
if (valorString) valor = `"${valor}"`;
}
}

this.valor = valor;
}
Expand Down
35 changes: 33 additions & 2 deletions fontes/modificadores/recursos-fonte.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Modificador, PragmasModificador } from "./superclasse";
import { validarValores } from "./validacoes/comum";
import { validarValorNumerico } from "./validacoes/numerica";
import { validarValorString } from "./validacoes/string";

export class RecursosFonte extends Modificador {
valoresAceitos: { [valorFoles: string]: string } = {
Expand All @@ -14,8 +16,37 @@ export class RecursosFonte extends Modificador {
) {
super("recursos-fonte", "font-feature-settings", pragmas);

if (!valorVariavel)
validarValores("recursos-fonte", valor, this.valoresAceitos);
const valoresExtra = ["feature-tag-value"];

if (!valorVariavel) {
if (valor.includes(",")) {
const separarValores = valor.split(", ");

separarValores.forEach((valorIndividual) => {
const validacaoString = validarValorString(valorIndividual);

// Valor feature-tag-value: string de 4 caracteres (comprimento 6 com as aspas)
const validacaoTagValue = valorIndividual.length === 6;

if (validacaoString && validacaoTagValue) {
this.valoresAceitos[valorIndividual] = valorIndividual;
}

validarValorNumerico("recursos-fonte", valorIndividual, this.valoresAceitos, valoresExtra);
});
} else {
const validacaoString = validarValorString(valor);

// Valor feature-tag-value: string de 4 caracteres (comprimento 6 com as aspas)
const validacaoTagValue = valor.length === 6;

if (validacaoString && validacaoTagValue) {
this.valoresAceitos[valor] = valor;
}

validarValores("recursos-fonte", valor, this.valoresAceitos, valoresExtra);
}
}

this.valor = valor;
}
Expand Down
21 changes: 21 additions & 0 deletions fontes/modificadores/validacoes/fonte.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { fontes } from "../atributos/fontes";
import { valoresGlobais } from "../atributos/globais";

export function validarValorFonte(
nomePropriedade: string,
valor: any,
valoresAceitos: { [valorFoles: string]: string },
valoresExtra?: any,
) {
if (
!(valor in fontes) &&
!(valor in valoresAceitos) &&
!(valor in valoresGlobais)
) {
throw new Error(`Propriedade '${nomePropriedade}' com valor ${valor} inválido. Valores aceitos:
${Object.keys(fontes).reduce((final, atual) => (final += `, ${atual}`))},

Check warning on line 16 in fontes/modificadores/validacoes/fonte.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

Check warning on line 16 in fontes/modificadores/validacoes/fonte.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🕹️ Function is not covered

Warning! Not covered function
${Object.keys(valoresAceitos).reduce((final, atual) => (final += `, ${atual}`))},

Check warning on line 17 in fontes/modificadores/validacoes/fonte.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

Check warning on line 17 in fontes/modificadores/validacoes/fonte.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🕹️ Function is not covered

Warning! Not covered function
${Object.keys(valoresGlobais).reduce((final, atual) => (final += `, ${atual}`))}.

Check warning on line 18 in fontes/modificadores/validacoes/fonte.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

Check warning on line 18 in fontes/modificadores/validacoes/fonte.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🕹️ Function is not covered

Warning! Not covered function
`);

Check warning on line 19 in fontes/modificadores/validacoes/fonte.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
}

Check warning on line 20 in fontes/modificadores/validacoes/fonte.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
}
70 changes: 46 additions & 24 deletions fontes/serializadores/serializador.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import estruturasHtml from "../tradutores/estruturas-html";
import { DeclaracaoVariavel } from "../declaracoes/declaracao-variavel";
import { Declaracao } from "../declaracoes/declaracao";
import { SeletorModificador } from "../modificadores/superclasse";
import { fontes } from "../modificadores/atributos/fontes";

/**
* A classe que efetivamente traduz FolEs para CSS.
Expand All @@ -31,9 +32,8 @@ export class Serializador {
): string {
// Caso 1: Número-Quantificador ou somente Número.
if (Number(modificador.valor) || modificador.valor === "0") {
return `${" ".repeat(indentacao)}${modificador.propriedadeCss}: ${
modificador.valor
}${modificador.quantificador || ""};\n`;
return `${" ".repeat(indentacao)}${modificador.propriedadeCss}: ${modificador.valor
}${modificador.quantificador || ""};\n`;
}

// Caso 2: Tradução do valor contida no objeto 'valoresAceitos'.
Expand All @@ -43,19 +43,46 @@ export class Serializador {
) {
const objetoValores = modificador["valoresAceitos"];
const valorTraduzido = objetoValores[modificador.valor];
return `${" ".repeat(indentacao)}${
modificador.propriedadeCss
}: ${valorTraduzido};\n`;
return `${" ".repeat(indentacao)}${modificador.propriedadeCss
}: ${valorTraduzido};\n`;
}

// Caso 3: Valor é RGB, RGBA, HSL, HSLA ou HEX, ou seja, um método.
if (modificador.valor instanceof Metodo) {
return `${" ".repeat(indentacao)}${modificador.propriedadeCss}: ${
modificador.valor.paraTexto() || ""
};\n`;
return `${" ".repeat(indentacao)}${modificador.propriedadeCss}: ${modificador.valor.paraTexto() || ""
};\n`;
}

// Caso 4: Atribuição Abreviada | Múltiplos valores separados por espaço, vírgula ou barra
// Caso 4: Valor com aspas - como as fontes de texto.
if (modificador.valor.includes('"')) {
if (modificador.valor.includes(",")) {
const separarValores = modificador.valor.split(", ");
const valorSemAspas = separarValores[0].replace(/["']/g, '');

// Trecho específico para tratamento de fontes com grafia
if (Object.keys(fontes).includes(valorSemAspas)) {
let unirValores = '';
separarValores.forEach((valorIndividual) => {
if (
modificador["valoresAceitos"] !== undefined &&
modificador["valoresAceitos"].hasOwnProperty(valorIndividual)
) {
const objetoValores = modificador["valoresAceitos"];
const valorTraduzido = objetoValores[valorIndividual];
separarValores[1] = valorTraduzido;
unirValores = separarValores.join(", ");
}
});
return `${" ".repeat(indentacao)}${modificador.propriedadeCss}: ${unirValores};\n`;
} else {
Copy link
Contributor

Choose a reason for hiding this comment

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

Via de regra: quando há else { return ... }, você não precisa do else: apenas do return. Usamos else { return ... } quando não há uma forma de quebrar o fluxo de execução do código.

return `${" ".repeat(indentacao)}${modificador.propriedadeCss}: ${modificador.valor};\n`;
}
} else {
return `${" ".repeat(indentacao)}${modificador.propriedadeCss}: ${modificador.valor};\n`;
}
}

// Caso 5: Atribuição Abreviada | Múltiplos valores separados por espaço, vírgula ou barra
if (modificador.valor.includes(" ")) {
if (modificador.valor.includes(",")) {
const separarValores: Array<string> =
Expand All @@ -80,26 +107,21 @@ export class Serializador {
);

if (valoresTraduzidos.length !== 0) {
return `${" ".repeat(indentacao)}${modificador.propriedadeCss}: ${
valoresTraduzidos
};\n`;
return `${" ".repeat(indentacao)}${modificador.propriedadeCss}: ${valoresTraduzidos
};\n`;
} else {
return `${" ".repeat(indentacao)}${modificador.propriedadeCss}: ${
modificador.valor
};\n`;
return `${" ".repeat(indentacao)}${modificador.propriedadeCss}: ${modificador.valor
};\n`;
}
}

return `${" ".repeat(indentacao)}${modificador.propriedadeCss}: ${
modificador.valor
};\n`;
return `${" ".repeat(indentacao)}${modificador.propriedadeCss}: ${modificador.valor
};\n`;
}

// Caso 5: É um valor genérico, cuja tradução está na lista 'valoresGerais'.
// Caso 6: É um valor genérico, cuja tradução está na lista 'valoresGerais'.
const valorTraduzido = valoresGerais[modificador.valor];
return `${" ".repeat(indentacao)}${
modificador.propriedadeCss
}: ${valorTraduzido};\n`;
return `${" ".repeat(indentacao)}${modificador.propriedadeCss}: ${valorTraduzido};\n`;
}

serializarBlocoDeclaracao(
Expand Down Expand Up @@ -193,7 +215,7 @@ export class Serializador {
validarValoresVariaveis(declaracao: BlocoDeclaracao): void {
const nomeFolEs =
declaracao.modificadores[0].nomeFoles.length > 1 &&
typeof declaracao.modificadores[0].nomeFoles === "object"
typeof declaracao.modificadores[0].nomeFoles === "object"
? declaracao.modificadores[0].nomeFoles[0].toString()
: declaracao.modificadores[0].nomeFoles.toString();

Expand Down
2 changes: 0 additions & 2 deletions testes/modificadores/status.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,5 @@ describe('Testando Seletores com STATUS como atributo', () => {
expect(resultadoTradutor).toContain('normal');
}
});


});
});
Loading