ether-code 0.3.9 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/ether.js +1 -1
- package/ether-parser.js +74 -19
- package/generators/css-generator.js +493 -253
- package/lexer/ether-lexer.js +85 -4
- package/package.json +1 -1
package/cli/ether.js
CHANGED
package/ether-parser.js
CHANGED
|
@@ -219,11 +219,15 @@ class EtherParser {
|
|
|
219
219
|
this.skipNewlines()
|
|
220
220
|
|
|
221
221
|
while (!this.isAtEnd()) {
|
|
222
|
+
const startPos = this.pos
|
|
222
223
|
const rule = this.parseCSSRule()
|
|
223
224
|
if (rule) {
|
|
224
225
|
stylesheet.rules.push(rule)
|
|
225
226
|
}
|
|
226
227
|
this.skipNewlines()
|
|
228
|
+
if (this.pos === startPos && !this.isAtEnd()) {
|
|
229
|
+
this.advance()
|
|
230
|
+
}
|
|
227
231
|
}
|
|
228
232
|
|
|
229
233
|
return stylesheet
|
|
@@ -298,11 +302,27 @@ class EtherParser {
|
|
|
298
302
|
const token = this.current()
|
|
299
303
|
|
|
300
304
|
if (!token || token.type === TokenType.NEWLINE || token.type === TokenType.INDENT ||
|
|
301
|
-
token.type === TokenType.
|
|
305
|
+
token.type === TokenType.EOF) {
|
|
302
306
|
break
|
|
303
307
|
}
|
|
304
308
|
|
|
305
|
-
if (token.type === TokenType.
|
|
309
|
+
if (token.type === TokenType.COLON) {
|
|
310
|
+
this.advance()
|
|
311
|
+
const next = this.current()
|
|
312
|
+
if (next && next.type === TokenType.COLON) {
|
|
313
|
+
this.advance()
|
|
314
|
+
const pseudoName = this.current()
|
|
315
|
+
if (pseudoName && pseudoName.type === TokenType.IDENTIFIER) {
|
|
316
|
+
parts.push('::' + pseudoName.value)
|
|
317
|
+
this.advance()
|
|
318
|
+
}
|
|
319
|
+
} else if (next && next.type === TokenType.IDENTIFIER) {
|
|
320
|
+
parts.push(':' + next.value)
|
|
321
|
+
this.advance()
|
|
322
|
+
} else {
|
|
323
|
+
break
|
|
324
|
+
}
|
|
325
|
+
} else if (token.type === TokenType.DOT) {
|
|
306
326
|
this.advance()
|
|
307
327
|
const name = this.current()
|
|
308
328
|
if (name && name.type === TokenType.IDENTIFIER) {
|
|
@@ -334,12 +354,28 @@ class EtherParser {
|
|
|
334
354
|
} else if (token.type === TokenType.TILDE) {
|
|
335
355
|
parts.push('~')
|
|
336
356
|
this.advance()
|
|
357
|
+
} else if (token.type === TokenType.LBRACKET) {
|
|
358
|
+
let attrSelector = '['
|
|
359
|
+
this.advance()
|
|
360
|
+
while (!this.isAtEnd()) {
|
|
361
|
+
const attrToken = this.current()
|
|
362
|
+
if (!attrToken || attrToken.type === TokenType.RBRACKET) {
|
|
363
|
+
attrSelector += ']'
|
|
364
|
+
this.advance()
|
|
365
|
+
break
|
|
366
|
+
}
|
|
367
|
+
attrSelector += attrToken.value
|
|
368
|
+
this.advance()
|
|
369
|
+
}
|
|
370
|
+
parts.push(attrSelector)
|
|
371
|
+
} else if (token.type === TokenType.EQUALS) {
|
|
372
|
+
break
|
|
337
373
|
} else {
|
|
338
374
|
break
|
|
339
375
|
}
|
|
340
376
|
}
|
|
341
377
|
|
|
342
|
-
return parts.join(' ').replace(/\s+([,>+~])\s+/g, ' $1 ').trim()
|
|
378
|
+
return parts.join(' ').replace(/\s+([,>+~])\s+/g, ' $1 ').replace(/\s+(::?)/g, '$1').trim()
|
|
343
379
|
}
|
|
344
380
|
|
|
345
381
|
translateCSSSelector(selector) {
|
|
@@ -400,6 +436,7 @@ class EtherParser {
|
|
|
400
436
|
}
|
|
401
437
|
|
|
402
438
|
const valueParts = []
|
|
439
|
+
let lastType = null
|
|
403
440
|
|
|
404
441
|
while (!this.isAtEnd()) {
|
|
405
442
|
const current = this.current()
|
|
@@ -409,21 +446,31 @@ class EtherParser {
|
|
|
409
446
|
break
|
|
410
447
|
}
|
|
411
448
|
|
|
449
|
+
let needsSpace = valueParts.length > 0
|
|
450
|
+
|
|
451
|
+
if (current.type === TokenType.LPAREN || current.type === TokenType.COMMA ||
|
|
452
|
+
current.type === TokenType.RPAREN || current.type === TokenType.PERCENT ||
|
|
453
|
+
lastType === TokenType.LPAREN || lastType === TokenType.MINUS ||
|
|
454
|
+
lastType === TokenType.HASH || lastType === TokenType.COLON) {
|
|
455
|
+
needsSpace = false
|
|
456
|
+
}
|
|
457
|
+
|
|
412
458
|
if (current.type === TokenType.IDENTIFIER) {
|
|
459
|
+
if (needsSpace) valueParts.push(' ')
|
|
413
460
|
valueParts.push(current.value)
|
|
414
461
|
} else if (current.type === TokenType.NUMBER || current.type === TokenType.INTEGER ||
|
|
415
462
|
current.type === TokenType.FLOAT) {
|
|
463
|
+
if (needsSpace && lastType !== TokenType.HASH) valueParts.push(' ')
|
|
416
464
|
valueParts.push(current.value)
|
|
417
465
|
} else if (current.type === TokenType.STRING) {
|
|
466
|
+
if (needsSpace) valueParts.push(' ')
|
|
467
|
+
valueParts.push('"' + current.value + '"')
|
|
468
|
+
} else if (current.type === TokenType.HEX) {
|
|
469
|
+
if (needsSpace) valueParts.push(' ')
|
|
418
470
|
valueParts.push(current.value)
|
|
419
|
-
} else if (current.type === TokenType.
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
this.advance()
|
|
423
|
-
valueParts.push('#' + next.value)
|
|
424
|
-
} else {
|
|
425
|
-
valueParts.push('#')
|
|
426
|
-
}
|
|
471
|
+
} else if (current.type === TokenType.HASH) {
|
|
472
|
+
if (needsSpace) valueParts.push(' ')
|
|
473
|
+
valueParts.push('#')
|
|
427
474
|
} else if (current.type === TokenType.COMMA) {
|
|
428
475
|
valueParts.push(',')
|
|
429
476
|
} else if (current.type === TokenType.LPAREN) {
|
|
@@ -433,25 +480,33 @@ class EtherParser {
|
|
|
433
480
|
} else if (current.type === TokenType.PERCENT) {
|
|
434
481
|
valueParts.push('%')
|
|
435
482
|
} else if (current.type === TokenType.SLASH) {
|
|
483
|
+
if (needsSpace) valueParts.push(' ')
|
|
436
484
|
valueParts.push('/')
|
|
437
485
|
} else if (current.type === TokenType.MINUS) {
|
|
438
|
-
|
|
486
|
+
if (lastType === TokenType.LPAREN || lastType === TokenType.MINUS) {
|
|
487
|
+
valueParts.push('-')
|
|
488
|
+
} else if (needsSpace) {
|
|
489
|
+
valueParts.push(' -')
|
|
490
|
+
} else {
|
|
491
|
+
valueParts.push('-')
|
|
492
|
+
}
|
|
493
|
+
} else if (current.type === TokenType.COLON) {
|
|
494
|
+
valueParts.push(':')
|
|
495
|
+
} else if (current.type === TokenType.DOT) {
|
|
496
|
+
valueParts.push('.')
|
|
439
497
|
} else {
|
|
440
498
|
break
|
|
441
499
|
}
|
|
442
500
|
|
|
501
|
+
lastType = current.type
|
|
443
502
|
this.advance()
|
|
444
503
|
}
|
|
445
504
|
|
|
446
505
|
return {
|
|
447
506
|
type: 'Declaration',
|
|
448
507
|
property: property,
|
|
449
|
-
value: valueParts.join('
|
|
450
|
-
.replace(
|
|
451
|
-
.replace(/\s+\)/g, ')')
|
|
452
|
-
.replace(/\s+,/g, ',')
|
|
453
|
-
.replace(/-\s+/g, '-')
|
|
454
|
-
.replace(/(\d+)\s+(%|px|em|rem|vh|vw|vmin|vmax|fr|s|ms|deg)/gi, '$1$2')
|
|
508
|
+
value: valueParts.join('')
|
|
509
|
+
.replace(/,\s*/g, ', ')
|
|
455
510
|
.replace(/\s+/g, ' ')
|
|
456
511
|
.trim()
|
|
457
512
|
}
|
|
@@ -3098,4 +3153,4 @@ class EtherParser {
|
|
|
3098
3153
|
|
|
3099
3154
|
module.exports = {
|
|
3100
3155
|
EtherParser
|
|
3101
|
-
}
|
|
3156
|
+
}
|
|
@@ -103,210 +103,86 @@ class CSSGenerator {
|
|
|
103
103
|
|
|
104
104
|
translateProperty(prop) {
|
|
105
105
|
const lower = prop.toLowerCase()
|
|
106
|
-
|
|
106
|
+
if (this.propertyMap && this.propertyMap[lower]) {
|
|
107
|
+
return this.propertyMap[lower]
|
|
108
|
+
}
|
|
109
|
+
return this.translateGeneric(prop)
|
|
107
110
|
}
|
|
108
111
|
|
|
109
112
|
translateValue(val) {
|
|
110
113
|
if (typeof val !== 'string') return val
|
|
111
|
-
const lower = val.toLowerCase()
|
|
112
114
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
115
|
+
let result = val
|
|
116
|
+
result = this.translateFunctions(result)
|
|
117
|
+
result = this.translateColors(result)
|
|
118
|
+
result = this.translateKeywords(result)
|
|
119
|
+
|
|
120
|
+
return result
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
translateFunctions(val) {
|
|
124
|
+
let result = val
|
|
125
|
+
|
|
126
|
+
result = result.replace(/utiliser:\s*([\w\u00C0-\u024F\-]+)/gi, (match, varName) => {
|
|
127
|
+
return `var(--${varName})`
|
|
128
|
+
})
|
|
116
129
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
130
|
+
result = result.replace(/dégradé linéaire:\s*/gi, 'linear-gradient(')
|
|
131
|
+
result = result.replace(/degrade lineaire:\s*/gi, 'linear-gradient(')
|
|
132
|
+
result = result.replace(/dégradé radial:\s*/gi, 'radial-gradient(')
|
|
133
|
+
result = result.replace(/degrade radial:\s*/gi, 'radial-gradient(')
|
|
134
|
+
result = result.replace(/dégradé conique:\s*/gi, 'conic-gradient(')
|
|
135
|
+
result = result.replace(/degrade conique:\s*/gi, 'conic-gradient(')
|
|
136
|
+
|
|
137
|
+
result = result.replace(/rgba:\s*(\d+),\s*(\d+),\s*(\d+),\s*([\d.]+)/gi, 'rgba($1, $2, $3, $4)')
|
|
138
|
+
result = result.replace(/rgb:\s*(\d+),\s*(\d+),\s*(\d+)/gi, 'rgb($1, $2, $3)')
|
|
139
|
+
result = result.replace(/hsl:\s*(\d+),\s*([\d.]+%?),\s*([\d.]+%?)/gi, 'hsl($1, $2, $3)')
|
|
140
|
+
result = result.replace(/hsla:\s*(\d+),\s*([\d.]+%?),\s*([\d.]+%?),\s*([\d.]+)/gi, 'hsla($1, $2, $3, $4)')
|
|
141
|
+
|
|
142
|
+
result = result.replace(/flou:\s*([\d.]+\w*)/gi, 'blur($1)')
|
|
143
|
+
result = result.replace(/luminosité:\s*([\d.]+%?)/gi, 'brightness($1)')
|
|
144
|
+
result = result.replace(/luminosite:\s*([\d.]+%?)/gi, 'brightness($1)')
|
|
145
|
+
result = result.replace(/contraste:\s*([\d.]+%?)/gi, 'contrast($1)')
|
|
146
|
+
result = result.replace(/niveaux-gris:\s*([\d.]+%?)/gi, 'grayscale($1)')
|
|
147
|
+
result = result.replace(/niveaux gris:\s*([\d.]+%?)/gi, 'grayscale($1)')
|
|
148
|
+
result = result.replace(/inverser:\s*([\d.]+%?)/gi, 'invert($1)')
|
|
149
|
+
result = result.replace(/saturation:\s*([\d.]+%?)/gi, 'saturate($1)')
|
|
150
|
+
result = result.replace(/sépia:\s*([\d.]+%?)/gi, 'sepia($1)')
|
|
151
|
+
result = result.replace(/sepia:\s*([\d.]+%?)/gi, 'sepia($1)')
|
|
152
|
+
result = result.replace(/teinte:\s*([\d.]+\w*)/gi, 'hue-rotate($1)')
|
|
153
|
+
|
|
154
|
+
result = result.replace(/déplacer-y:\s*([\d.\-]+\w*)/gi, 'translateY($1)')
|
|
155
|
+
result = result.replace(/deplacer-y:\s*([\d.\-]+\w*)/gi, 'translateY($1)')
|
|
156
|
+
result = result.replace(/déplacer-x:\s*([\d.\-]+\w*)/gi, 'translateX($1)')
|
|
157
|
+
result = result.replace(/deplacer-x:\s*([\d.\-]+\w*)/gi, 'translateX($1)')
|
|
158
|
+
result = result.replace(/déplacer:\s*([\d.\-]+\w*),?\s*([\d.\-]+\w*)?/gi, (match, x, y) => {
|
|
159
|
+
if (y) return `translate(${x}, ${y})`
|
|
160
|
+
return `translate(${x})`
|
|
161
|
+
})
|
|
162
|
+
result = result.replace(/rotation:\s*([\d.\-]+\w*)/gi, 'rotate($1)')
|
|
163
|
+
result = result.replace(/échelle:\s*([\d.]+)/gi, 'scale($1)')
|
|
164
|
+
result = result.replace(/echelle:\s*([\d.]+)/gi, 'scale($1)')
|
|
165
|
+
|
|
166
|
+
result = result.replace(/répéter:\s*([^,]+),\s*minmax:\s*([^,]+),\s*([^\s\)]+)/gi, 'repeat($1, minmax($2, $3))')
|
|
167
|
+
result = result.replace(/repeter:\s*([^,]+),\s*minmax:\s*([^,]+),\s*([^\s\)]+)/gi, 'repeat($1, minmax($2, $3))')
|
|
168
|
+
result = result.replace(/minmax:\s*([^,]+),\s*([^\s\)]+)/gi, 'minmax($1, $2)')
|
|
169
|
+
|
|
170
|
+
result = result.replace(/calcul:\s*(.+)/gi, 'calc($1)')
|
|
171
|
+
result = result.replace(/minimum:\s*([^,]+),\s*([^\s\)]+)/gi, 'min($1, $2)')
|
|
172
|
+
result = result.replace(/maximum:\s*([^,]+),\s*([^\s\)]+)/gi, 'max($1, $2)')
|
|
173
|
+
result = result.replace(/borner:\s*([^,]+),\s*([^,]+),\s*([^\s\)]+)/gi, 'clamp($1, $2, $3)')
|
|
174
|
+
|
|
175
|
+
if (result.includes('linear-gradient(') || result.includes('radial-gradient(') || result.includes('conic-gradient(')) {
|
|
176
|
+
if (!result.endsWith(')')) {
|
|
177
|
+
result = result + ')'
|
|
121
178
|
}
|
|
122
|
-
return mapped
|
|
123
179
|
}
|
|
124
180
|
|
|
125
|
-
return
|
|
181
|
+
return result
|
|
126
182
|
}
|
|
127
183
|
|
|
128
|
-
|
|
129
|
-
const
|
|
130
|
-
'couleur-fond': 'background-color',
|
|
131
|
-
'couleur-texte': 'color',
|
|
132
|
-
'couleur-bordure': 'border-color',
|
|
133
|
-
'couleur-primaire': '--color-primary',
|
|
134
|
-
'couleur-secondaire': '--color-secondary',
|
|
135
|
-
'couleur-accent': '--color-accent',
|
|
136
|
-
'couleur-surface': '--color-surface',
|
|
137
|
-
'couleur-texte-pale': '--color-text-muted',
|
|
138
|
-
'famille-police': 'font-family',
|
|
139
|
-
'taille-police': 'font-size',
|
|
140
|
-
'poids-police': 'font-weight',
|
|
141
|
-
'style-police': 'font-style',
|
|
142
|
-
'hauteur-ligne': 'line-height',
|
|
143
|
-
'espacement-lettres': 'letter-spacing',
|
|
144
|
-
'espacement-mots': 'word-spacing',
|
|
145
|
-
'texte-aligne': 'text-align',
|
|
146
|
-
'alignement-texte': 'text-align',
|
|
147
|
-
'decoration-texte': 'text-decoration',
|
|
148
|
-
'transformation-texte': 'text-transform',
|
|
149
|
-
'retrait-texte': 'text-indent',
|
|
150
|
-
'ombre-texte': 'text-shadow',
|
|
151
|
-
'debordement-texte': 'text-overflow',
|
|
152
|
-
'coupure-mot': 'word-break',
|
|
153
|
-
'retour-ligne': 'word-wrap',
|
|
154
|
-
'espace-blanc': 'white-space',
|
|
155
|
-
'marge-haut': 'margin-top',
|
|
156
|
-
'marge-bas': 'margin-bottom',
|
|
157
|
-
'marge-gauche': 'margin-left',
|
|
158
|
-
'marge-droite': 'margin-right',
|
|
159
|
-
'marge-bloc': 'margin-block',
|
|
160
|
-
'marge-en-ligne': 'margin-inline',
|
|
161
|
-
'remplissage-haut': 'padding-top',
|
|
162
|
-
'remplissage-bas': 'padding-bottom',
|
|
163
|
-
'remplissage-gauche': 'padding-left',
|
|
164
|
-
'remplissage-droite': 'padding-right',
|
|
165
|
-
'remplissage-bloc': 'padding-block',
|
|
166
|
-
'remplissage-en-ligne': 'padding-inline',
|
|
167
|
-
'bordure-haut': 'border-top',
|
|
168
|
-
'bordure-bas': 'border-bottom',
|
|
169
|
-
'bordure-gauche': 'border-left',
|
|
170
|
-
'bordure-droite': 'border-right',
|
|
171
|
-
'largeur-bordure': 'border-width',
|
|
172
|
-
'style-bordure': 'border-style',
|
|
173
|
-
'rayon-bordure': 'border-radius',
|
|
174
|
-
'rayon-haut-gauche': 'border-top-left-radius',
|
|
175
|
-
'rayon-haut-droite': 'border-top-right-radius',
|
|
176
|
-
'rayon-bas-gauche': 'border-bottom-left-radius',
|
|
177
|
-
'rayon-bas-droite': 'border-bottom-right-radius',
|
|
178
|
-
'ombre-boite': 'box-shadow',
|
|
179
|
-
'modele-boite': 'box-sizing',
|
|
180
|
-
'max-largeur': 'max-width',
|
|
181
|
-
'min-largeur': 'min-width',
|
|
182
|
-
'max-hauteur': 'max-height',
|
|
183
|
-
'min-hauteur': 'min-height',
|
|
184
|
-
'ajustement-objet': 'object-fit',
|
|
185
|
-
'position-objet': 'object-position',
|
|
186
|
-
'debordement-x': 'overflow-x',
|
|
187
|
-
'debordement-y': 'overflow-y',
|
|
188
|
-
'comportement-defilement': 'scroll-behavior',
|
|
189
|
-
'justifier-contenu': 'justify-content',
|
|
190
|
-
'aligner-elements': 'align-items',
|
|
191
|
-
'aligner-contenu': 'align-content',
|
|
192
|
-
'aligner-soi': 'align-self',
|
|
193
|
-
'justifier-soi': 'justify-self',
|
|
194
|
-
'justifier-elements': 'justify-items',
|
|
195
|
-
'direction-flex': 'flex-direction',
|
|
196
|
-
'enveloppe-flex': 'flex-wrap',
|
|
197
|
-
'flux-flex': 'flex-flow',
|
|
198
|
-
'croissance-flex': 'flex-grow',
|
|
199
|
-
'retrecissement-flex': 'flex-shrink',
|
|
200
|
-
'base-flex': 'flex-basis',
|
|
201
|
-
'ordre': 'order',
|
|
202
|
-
'colonnes-grille': 'grid-template-columns',
|
|
203
|
-
'lignes-grille': 'grid-template-rows',
|
|
204
|
-
'zones-grille': 'grid-template-areas',
|
|
205
|
-
'colonne-grille': 'grid-column',
|
|
206
|
-
'ligne-grille': 'grid-row',
|
|
207
|
-
'zone-grille': 'grid-area',
|
|
208
|
-
'ecart-grille': 'grid-gap',
|
|
209
|
-
'ecart-colonnes': 'column-gap',
|
|
210
|
-
'ecart-lignes': 'row-gap',
|
|
211
|
-
'flux-auto-grille': 'grid-auto-flow',
|
|
212
|
-
'colonnes-auto-grille': 'grid-auto-columns',
|
|
213
|
-
'lignes-auto-grille': 'grid-auto-rows',
|
|
214
|
-
'z-index': 'z-index',
|
|
215
|
-
'index-z': 'z-index',
|
|
216
|
-
'liste-style': 'list-style',
|
|
217
|
-
'type-liste': 'list-style-type',
|
|
218
|
-
'position-liste': 'list-style-position',
|
|
219
|
-
'image-liste': 'list-style-image',
|
|
220
|
-
'duree-transition': 'transition-duration',
|
|
221
|
-
'delai-transition': 'transition-delay',
|
|
222
|
-
'propriete-transition': 'transition-property',
|
|
223
|
-
'fonction-transition': 'transition-timing-function',
|
|
224
|
-
'nom-animation': 'animation-name',
|
|
225
|
-
'duree-animation': 'animation-duration',
|
|
226
|
-
'delai-animation': 'animation-delay',
|
|
227
|
-
'fonction-animation': 'animation-timing-function',
|
|
228
|
-
'iteration-animation': 'animation-iteration-count',
|
|
229
|
-
'direction-animation': 'animation-direction',
|
|
230
|
-
'remplissage-animation': 'animation-fill-mode',
|
|
231
|
-
'etat-animation': 'animation-play-state',
|
|
232
|
-
'origine-transformation': 'transform-origin',
|
|
233
|
-
'style-transformation': 'transform-style',
|
|
234
|
-
'perspective': 'perspective',
|
|
235
|
-
'origine-perspective': 'perspective-origin',
|
|
236
|
-
'face-arriere': 'backface-visibility',
|
|
237
|
-
'flou-fond': 'backdrop-filter',
|
|
238
|
-
'mode-melange': 'mix-blend-mode',
|
|
239
|
-
'mode-melange-fond': 'background-blend-mode',
|
|
240
|
-
'image-fond': 'background-image',
|
|
241
|
-
'position-fond': 'background-position',
|
|
242
|
-
'taille-fond': 'background-size',
|
|
243
|
-
'repetition-fond': 'background-repeat',
|
|
244
|
-
'attachement-fond': 'background-attachment',
|
|
245
|
-
'origine-fond': 'background-origin',
|
|
246
|
-
'decoupe-fond': 'background-clip',
|
|
247
|
-
'couleur-remplissage-texte': '-webkit-text-fill-color',
|
|
248
|
-
'selection-utilisateur': 'user-select',
|
|
249
|
-
'evenements-pointeur': 'pointer-events',
|
|
250
|
-
'accrochage-defilement': 'scroll-snap-type',
|
|
251
|
-
'alignement-accrochage': 'scroll-snap-align',
|
|
252
|
-
'redimensionnement': 'resize',
|
|
253
|
-
'apparence': 'appearance',
|
|
254
|
-
'contour': 'outline',
|
|
255
|
-
'largeur-contour': 'outline-width',
|
|
256
|
-
'style-contour': 'outline-style',
|
|
257
|
-
'couleur-contour': 'outline-color',
|
|
258
|
-
'decalage-contour': 'outline-offset',
|
|
259
|
-
'compteur-reset': 'counter-reset',
|
|
260
|
-
'compteur-increment': 'counter-increment',
|
|
261
|
-
'guillemets': 'quotes',
|
|
262
|
-
'coupure-colonne': 'break-inside',
|
|
263
|
-
'orphelins': 'orphans',
|
|
264
|
-
'veuves': 'widows',
|
|
265
|
-
'fond': 'background',
|
|
266
|
-
'couleur': 'color',
|
|
267
|
-
'police': 'font-family',
|
|
268
|
-
'taille': 'font-size',
|
|
269
|
-
'poids': 'font-weight',
|
|
270
|
-
'style': 'font-style',
|
|
271
|
-
'alignement': 'text-align',
|
|
272
|
-
'decoration': 'text-decoration',
|
|
273
|
-
'transformation': 'transform',
|
|
274
|
-
'debordement': 'overflow',
|
|
275
|
-
'largeur': 'width',
|
|
276
|
-
'hauteur': 'height',
|
|
277
|
-
'marge': 'margin',
|
|
278
|
-
'remplissage': 'padding',
|
|
279
|
-
'bordure': 'border',
|
|
280
|
-
'arrondi': 'border-radius',
|
|
281
|
-
'ombre': 'box-shadow',
|
|
282
|
-
'affichage': 'display',
|
|
283
|
-
'position': 'position',
|
|
284
|
-
'haut': 'top',
|
|
285
|
-
'bas': 'bottom',
|
|
286
|
-
'gauche': 'left',
|
|
287
|
-
'droite': 'right',
|
|
288
|
-
'z': 'z-index',
|
|
289
|
-
'opacite': 'opacity',
|
|
290
|
-
'curseur': 'cursor',
|
|
291
|
-
'transition': 'transition',
|
|
292
|
-
'animation': 'animation',
|
|
293
|
-
'filtre': 'filter',
|
|
294
|
-
'ajustement': 'object-fit',
|
|
295
|
-
'selection': 'user-select',
|
|
296
|
-
'redimensionner': 'resize',
|
|
297
|
-
'visibilite': 'visibility',
|
|
298
|
-
'flex': 'flex',
|
|
299
|
-
'grille': 'grid',
|
|
300
|
-
'colonnes': 'grid-template-columns',
|
|
301
|
-
'lignes': 'grid-template-rows',
|
|
302
|
-
'zone': 'grid-area',
|
|
303
|
-
'ecart': 'gap',
|
|
304
|
-
'espace': 'gap',
|
|
305
|
-
'direction': 'flex-direction',
|
|
306
|
-
'envelopper': 'flex-wrap',
|
|
307
|
-
'justifier': 'justify-content',
|
|
308
|
-
'aligner': 'align-items',
|
|
309
|
-
'contenu': 'content',
|
|
184
|
+
translateColors(val) {
|
|
185
|
+
const colorMap = {
|
|
310
186
|
'blanc': 'white',
|
|
311
187
|
'noir': 'black',
|
|
312
188
|
'rouge': 'red',
|
|
@@ -317,55 +193,301 @@ class CSSGenerator {
|
|
|
317
193
|
'violet': 'purple',
|
|
318
194
|
'rose': 'pink',
|
|
319
195
|
'gris': 'gray',
|
|
320
|
-
'
|
|
321
|
-
'
|
|
322
|
-
'
|
|
196
|
+
'cyan': 'cyan',
|
|
197
|
+
'magenta': 'magenta',
|
|
198
|
+
'turquoise': 'turquoise',
|
|
199
|
+
'beige': 'beige',
|
|
200
|
+
'or': 'gold',
|
|
201
|
+
'argent': 'silver',
|
|
202
|
+
'corail': 'coral',
|
|
203
|
+
'saumon': 'salmon',
|
|
204
|
+
'olive': 'olive',
|
|
205
|
+
'marine': 'navy',
|
|
206
|
+
'bordeaux': 'maroon',
|
|
207
|
+
'kaki': 'khaki',
|
|
208
|
+
'ivoire': 'ivory',
|
|
209
|
+
'indigo': 'indigo',
|
|
210
|
+
'lavande': 'lavender',
|
|
211
|
+
'prune': 'plum',
|
|
212
|
+
'chocolat': 'chocolate',
|
|
213
|
+
'transparent': 'transparent'
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
let result = val
|
|
217
|
+
for (const [fr, en] of Object.entries(colorMap)) {
|
|
218
|
+
const regex = new RegExp(`\\b${fr}\\b`, 'gi')
|
|
219
|
+
result = result.replace(regex, en)
|
|
220
|
+
}
|
|
221
|
+
return result
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
translateKeywords(val) {
|
|
225
|
+
const keywords = {
|
|
323
226
|
'aucun': 'none',
|
|
227
|
+
'aucune': 'none',
|
|
324
228
|
'auto': 'auto',
|
|
229
|
+
'hériter': 'inherit',
|
|
230
|
+
'heriter': 'inherit',
|
|
231
|
+
'initial': 'initial',
|
|
232
|
+
'caché': 'hidden',
|
|
325
233
|
'cache': 'hidden',
|
|
326
234
|
'visible': 'visible',
|
|
235
|
+
'défiler': 'scroll',
|
|
327
236
|
'defiler': 'scroll',
|
|
328
237
|
'fixe': 'fixed',
|
|
238
|
+
'fixée': 'fixed',
|
|
239
|
+
'fixee': 'fixed',
|
|
240
|
+
'absolue': 'absolute',
|
|
329
241
|
'absolu': 'absolute',
|
|
242
|
+
'relative': 'relative',
|
|
330
243
|
'relatif': 'relative',
|
|
331
244
|
'statique': 'static',
|
|
332
245
|
'collant': 'sticky',
|
|
246
|
+
'collante': 'sticky',
|
|
333
247
|
'centre': 'center',
|
|
248
|
+
'centré': 'center',
|
|
249
|
+
'début': 'flex-start',
|
|
334
250
|
'debut': 'flex-start',
|
|
335
251
|
'fin': 'flex-end',
|
|
336
|
-
'entre': 'space-between',
|
|
337
|
-
'
|
|
338
|
-
'
|
|
252
|
+
'espace-entre': 'space-between',
|
|
253
|
+
'espace entre': 'space-between',
|
|
254
|
+
'espace-autour': 'space-around',
|
|
255
|
+
'espace autour': 'space-around',
|
|
256
|
+
'espace-égal': 'space-evenly',
|
|
257
|
+
'espace egal': 'space-evenly',
|
|
258
|
+
'étirer': 'stretch',
|
|
339
259
|
'etirer': 'stretch',
|
|
340
260
|
'ligne': 'row',
|
|
341
261
|
'colonne': 'column',
|
|
342
|
-
'
|
|
262
|
+
'ligne-inverse': 'row-reverse',
|
|
263
|
+
'ligne inverse': 'row-reverse',
|
|
264
|
+
'colonne-inverse': 'column-reverse',
|
|
265
|
+
'colonne inverse': 'column-reverse',
|
|
266
|
+
'envelopper': 'wrap',
|
|
267
|
+
'sans-retour': 'nowrap',
|
|
268
|
+
'sans retour': 'nowrap',
|
|
343
269
|
'gras': 'bold',
|
|
344
270
|
'normal': 'normal',
|
|
345
271
|
'italique': 'italic',
|
|
272
|
+
'souligné': 'underline',
|
|
346
273
|
'souligne': 'underline',
|
|
274
|
+
'barré': 'line-through',
|
|
347
275
|
'barre': 'line-through',
|
|
348
276
|
'majuscules': 'uppercase',
|
|
349
277
|
'minuscules': 'lowercase',
|
|
350
278
|
'capitaliser': 'capitalize',
|
|
351
279
|
'pointeur': 'pointer',
|
|
352
280
|
'attente': 'wait',
|
|
353
|
-
'texte': 'text',
|
|
354
281
|
'interdit': 'not-allowed',
|
|
355
282
|
'couvrir': 'cover',
|
|
356
283
|
'contenir': 'contain',
|
|
357
284
|
'remplir': 'fill',
|
|
358
285
|
'bloc': 'block',
|
|
359
286
|
'en-ligne': 'inline',
|
|
287
|
+
'en ligne': 'inline',
|
|
360
288
|
'bloc-en-ligne': 'inline-block',
|
|
289
|
+
'bloc en ligne': 'inline-block',
|
|
361
290
|
'flex-en-ligne': 'inline-flex',
|
|
291
|
+
'flex en ligne': 'inline-flex',
|
|
292
|
+
'grille': 'grid',
|
|
362
293
|
'grille-en-ligne': 'inline-grid',
|
|
363
|
-
'
|
|
364
|
-
'
|
|
365
|
-
'
|
|
294
|
+
'grille en ligne': 'inline-grid',
|
|
295
|
+
'préservé': 'pre',
|
|
296
|
+
'preserve': 'pre',
|
|
297
|
+
'pré-ligne': 'pre-line',
|
|
366
298
|
'pre-ligne': 'pre-line',
|
|
299
|
+
'pré-enveloppe': 'pre-wrap',
|
|
367
300
|
'pre-enveloppe': 'pre-wrap',
|
|
368
|
-
'
|
|
301
|
+
'solide': 'solid',
|
|
302
|
+
'pointillée': 'dotted',
|
|
303
|
+
'pointillee': 'dotted',
|
|
304
|
+
'tirets': 'dashed',
|
|
305
|
+
'double': 'double',
|
|
306
|
+
'tout': 'all',
|
|
307
|
+
'ease': 'ease',
|
|
308
|
+
'ease-in': 'ease-in',
|
|
309
|
+
'ease-out': 'ease-out',
|
|
310
|
+
'ease-in-out': 'ease-in-out',
|
|
311
|
+
'linéaire': 'linear',
|
|
312
|
+
'lineaire': 'linear'
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
let result = val
|
|
316
|
+
|
|
317
|
+
const varPlaceholders = []
|
|
318
|
+
result = result.replace(/var\(--[\w\u00C0-\u024F\-]+\)/gi, (match) => {
|
|
319
|
+
varPlaceholders.push(match)
|
|
320
|
+
return `__VAR_PLACEHOLDER_${varPlaceholders.length - 1}__`
|
|
321
|
+
})
|
|
322
|
+
|
|
323
|
+
for (const [fr, en] of Object.entries(keywords)) {
|
|
324
|
+
const regex = new RegExp(`\\b${fr}\\b`, 'gi')
|
|
325
|
+
result = result.replace(regex, en)
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (result === val) {
|
|
329
|
+
const lower = val.toLowerCase()
|
|
330
|
+
if (lower === 'texte') return 'text'
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
for (let i = 0; i < varPlaceholders.length; i++) {
|
|
334
|
+
result = result.replace(`__VAR_PLACEHOLDER_${i}__`, varPlaceholders[i])
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return result
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
translateGeneric(text) {
|
|
341
|
+
const translations = {
|
|
342
|
+
'couleur': 'color',
|
|
343
|
+
'fond': 'background',
|
|
344
|
+
'police': 'font-family',
|
|
345
|
+
'taille police': 'font-size',
|
|
346
|
+
'taille-police': 'font-size',
|
|
347
|
+
'poids police': 'font-weight',
|
|
348
|
+
'poids-police': 'font-weight',
|
|
349
|
+
'style police': 'font-style',
|
|
350
|
+
'style-police': 'font-style',
|
|
351
|
+
'hauteur ligne': 'line-height',
|
|
352
|
+
'hauteur-ligne': 'line-height',
|
|
353
|
+
'espacement-lettres': 'letter-spacing',
|
|
354
|
+
'espacement lettres': 'letter-spacing',
|
|
355
|
+
'alignement-texte': 'text-align',
|
|
356
|
+
'alignement texte': 'text-align',
|
|
357
|
+
'décoration-texte': 'text-decoration',
|
|
358
|
+
'décoration texte': 'text-decoration',
|
|
359
|
+
'decoration-texte': 'text-decoration',
|
|
360
|
+
'decoration texte': 'text-decoration',
|
|
361
|
+
'transformation-texte': 'text-transform',
|
|
362
|
+
'transformation texte': 'text-transform',
|
|
363
|
+
'ombre-texte': 'text-shadow',
|
|
364
|
+
'ombre texte': 'text-shadow',
|
|
365
|
+
'marge': 'margin',
|
|
366
|
+
'marge haut': 'margin-top',
|
|
367
|
+
'marge-haut': 'margin-top',
|
|
368
|
+
'marge bas': 'margin-bottom',
|
|
369
|
+
'marge-bas': 'margin-bottom',
|
|
370
|
+
'marge gauche': 'margin-left',
|
|
371
|
+
'marge-gauche': 'margin-left',
|
|
372
|
+
'marge droite': 'margin-right',
|
|
373
|
+
'marge-droite': 'margin-right',
|
|
374
|
+
'marge dedans': 'padding',
|
|
375
|
+
'marge-dedans': 'padding',
|
|
376
|
+
'marge dedans haut': 'padding-top',
|
|
377
|
+
'marge-dedans-haut': 'padding-top',
|
|
378
|
+
'marge dedans bas': 'padding-bottom',
|
|
379
|
+
'marge-dedans-bas': 'padding-bottom',
|
|
380
|
+
'marge dedans gauche': 'padding-left',
|
|
381
|
+
'marge-dedans-gauche': 'padding-left',
|
|
382
|
+
'marge dedans droite': 'padding-right',
|
|
383
|
+
'marge-dedans-droite': 'padding-right',
|
|
384
|
+
'bordure': 'border',
|
|
385
|
+
'bordure haut': 'border-top',
|
|
386
|
+
'bordure-haut': 'border-top',
|
|
387
|
+
'bordure bas': 'border-bottom',
|
|
388
|
+
'bordure-bas': 'border-bottom',
|
|
389
|
+
'bordure gauche': 'border-left',
|
|
390
|
+
'bordure-gauche': 'border-left',
|
|
391
|
+
'bordure droite': 'border-right',
|
|
392
|
+
'bordure-droite': 'border-right',
|
|
393
|
+
'couleur-bordure': 'border-color',
|
|
394
|
+
'couleur bordure': 'border-color',
|
|
395
|
+
'arrondi': 'border-radius',
|
|
396
|
+
'largeur': 'width',
|
|
397
|
+
'hauteur': 'height',
|
|
398
|
+
'largeur minimum': 'min-width',
|
|
399
|
+
'largeur-minimum': 'min-width',
|
|
400
|
+
'largeur maximum': 'max-width',
|
|
401
|
+
'largeur-maximum': 'max-width',
|
|
402
|
+
'hauteur minimum': 'min-height',
|
|
403
|
+
'hauteur-minimum': 'min-height',
|
|
404
|
+
'hauteur maximum': 'max-height',
|
|
405
|
+
'hauteur-maximum': 'max-height',
|
|
406
|
+
'affichage': 'display',
|
|
407
|
+
'position': 'position',
|
|
408
|
+
'haut': 'top',
|
|
409
|
+
'bas': 'bottom',
|
|
410
|
+
'gauche': 'left',
|
|
411
|
+
'droite': 'right',
|
|
412
|
+
'index-z': 'z-index',
|
|
413
|
+
'z-index': 'z-index',
|
|
414
|
+
'débordement': 'overflow',
|
|
415
|
+
'debordement': 'overflow',
|
|
416
|
+
'débordement-x': 'overflow-x',
|
|
417
|
+
'debordement-x': 'overflow-x',
|
|
418
|
+
'débordement-y': 'overflow-y',
|
|
419
|
+
'debordement-y': 'overflow-y',
|
|
420
|
+
'opacité': 'opacity',
|
|
421
|
+
'opacite': 'opacity',
|
|
422
|
+
'curseur': 'cursor',
|
|
423
|
+
'transition': 'transition',
|
|
424
|
+
'animation': 'animation',
|
|
425
|
+
'transformation': 'transform',
|
|
426
|
+
'filtre': 'filter',
|
|
427
|
+
'filtre-fond': 'backdrop-filter',
|
|
428
|
+
'filtre fond': 'backdrop-filter',
|
|
429
|
+
'ombre-boîte': 'box-shadow',
|
|
430
|
+
'ombre-boite': 'box-shadow',
|
|
431
|
+
'ombre boîte': 'box-shadow',
|
|
432
|
+
'ombre boite': 'box-shadow',
|
|
433
|
+
'modèle-boîte': 'box-sizing',
|
|
434
|
+
'modele-boite': 'box-sizing',
|
|
435
|
+
'modèle boîte': 'box-sizing',
|
|
436
|
+
'modele boite': 'box-sizing',
|
|
437
|
+
'espace': 'gap',
|
|
438
|
+
'espace ligne': 'row-gap',
|
|
439
|
+
'espace-ligne': 'row-gap',
|
|
440
|
+
'espace colonne': 'column-gap',
|
|
441
|
+
'espace-colonne': 'column-gap',
|
|
442
|
+
'justifier-contenu': 'justify-content',
|
|
443
|
+
'justifier contenu': 'justify-content',
|
|
444
|
+
'aligner-éléments': 'align-items',
|
|
445
|
+
'aligner-elements': 'align-items',
|
|
446
|
+
'aligner éléments': 'align-items',
|
|
447
|
+
'aligner elements': 'align-items',
|
|
448
|
+
'aligner-contenu': 'align-content',
|
|
449
|
+
'aligner contenu': 'align-content',
|
|
450
|
+
'direction-flex': 'flex-direction',
|
|
451
|
+
'direction flex': 'flex-direction',
|
|
452
|
+
'enveloppe-flex': 'flex-wrap',
|
|
453
|
+
'enveloppe flex': 'flex-wrap',
|
|
454
|
+
'flex': 'flex',
|
|
455
|
+
'grille': 'display',
|
|
456
|
+
'colonnes-grille': 'grid-template-columns',
|
|
457
|
+
'colonnes grille': 'grid-template-columns',
|
|
458
|
+
'lignes-grille': 'grid-template-rows',
|
|
459
|
+
'lignes grille': 'grid-template-rows',
|
|
460
|
+
'style-liste': 'list-style',
|
|
461
|
+
'style liste': 'list-style',
|
|
462
|
+
'contenu': 'content',
|
|
463
|
+
'évènements-pointeur': 'pointer-events',
|
|
464
|
+
'evenements-pointeur': 'pointer-events',
|
|
465
|
+
'évènements pointeur': 'pointer-events',
|
|
466
|
+
'evenements pointeur': 'pointer-events',
|
|
467
|
+
'découpe-fond': 'background-clip',
|
|
468
|
+
'decoupe-fond': 'background-clip',
|
|
469
|
+
'découpe fond': 'background-clip',
|
|
470
|
+
'decoupe fond': 'background-clip',
|
|
471
|
+
'couleur-remplissage-texte': '-webkit-text-fill-color',
|
|
472
|
+
'couleur remplissage texte': '-webkit-text-fill-color',
|
|
473
|
+
'espace-blanc': 'white-space',
|
|
474
|
+
'espace blanc': 'white-space',
|
|
475
|
+
'taille': 'font-size',
|
|
476
|
+
'poids': 'font-weight',
|
|
477
|
+
'style': 'font-style',
|
|
478
|
+
'alignement': 'text-align',
|
|
479
|
+
'decoration': 'text-decoration',
|
|
480
|
+
'ombre': 'box-shadow',
|
|
481
|
+
'ecart': 'gap',
|
|
482
|
+
'direction': 'flex-direction',
|
|
483
|
+
'envelopper': 'flex-wrap',
|
|
484
|
+
'justifier': 'justify-content',
|
|
485
|
+
'aligner': 'align-items',
|
|
486
|
+
'visibilite': 'visibility',
|
|
487
|
+
'visibilité': 'visibility',
|
|
488
|
+
'redimensionnement': 'resize',
|
|
489
|
+
'apparence': 'appearance',
|
|
490
|
+
'contour': 'outline'
|
|
369
491
|
}
|
|
370
492
|
|
|
371
493
|
const lower = text.toLowerCase()
|
|
@@ -375,30 +497,91 @@ class CSSGenerator {
|
|
|
375
497
|
translateSelector(selector) {
|
|
376
498
|
let result = selector
|
|
377
499
|
|
|
378
|
-
result = result.replace(/
|
|
379
|
-
result = result.replace(/
|
|
380
|
-
result = result.replace(/
|
|
381
|
-
result = result.replace(/
|
|
382
|
-
result = result.replace(/
|
|
383
|
-
result = result.replace(/
|
|
384
|
-
result = result.replace(/
|
|
385
|
-
result = result.replace(/
|
|
386
|
-
result = result.replace(/
|
|
387
|
-
result = result.replace(/
|
|
388
|
-
result = result.replace(/
|
|
389
|
-
|
|
390
|
-
result = result.replace(/
|
|
391
|
-
result = result.replace(
|
|
392
|
-
result = result.replace(
|
|
393
|
-
result = result.replace(/
|
|
394
|
-
result = result.replace(/
|
|
395
|
-
result = result.replace(/
|
|
396
|
-
result = result.replace(/
|
|
397
|
-
result = result.replace(/
|
|
398
|
-
result = result.replace(/
|
|
399
|
-
result = result.replace(/
|
|
400
|
-
result = result.replace(/
|
|
401
|
-
result = result.replace(/
|
|
500
|
+
result = result.replace(/:racine\b/gi, ':root')
|
|
501
|
+
result = result.replace(/::avant\b/gi, '::before')
|
|
502
|
+
result = result.replace(/::après\b/gi, '::after')
|
|
503
|
+
result = result.replace(/::apres\b/gi, '::after')
|
|
504
|
+
result = result.replace(/::première-lettre\b/gi, '::first-letter')
|
|
505
|
+
result = result.replace(/::premiere-lettre\b/gi, '::first-letter')
|
|
506
|
+
result = result.replace(/::première-ligne\b/gi, '::first-line')
|
|
507
|
+
result = result.replace(/::premiere-ligne\b/gi, '::first-line')
|
|
508
|
+
result = result.replace(/::sélection\b/gi, '::selection')
|
|
509
|
+
result = result.replace(/::selection\b/gi, '::selection')
|
|
510
|
+
result = result.replace(/::marqueur\b/gi, '::marker')
|
|
511
|
+
|
|
512
|
+
result = result.replace(/\bau survol\b/gi, ':hover')
|
|
513
|
+
result = result.replace(/\bquand survolé\b/gi, ':hover')
|
|
514
|
+
result = result.replace(/\bquand survole\b/gi, ':hover')
|
|
515
|
+
result = result.replace(/\ben survol\b/gi, ':hover')
|
|
516
|
+
result = result.replace(/\bau clic\b/gi, ':active')
|
|
517
|
+
result = result.replace(/\bquand cliqué\b/gi, ':active')
|
|
518
|
+
result = result.replace(/\bquand clique\b/gi, ':active')
|
|
519
|
+
result = result.replace(/\ben clic\b/gi, ':active')
|
|
520
|
+
result = result.replace(/\bactif\b/gi, ':active')
|
|
521
|
+
result = result.replace(/\bau focus\b/gi, ':focus')
|
|
522
|
+
result = result.replace(/\bquand focalisé\b/gi, ':focus')
|
|
523
|
+
result = result.replace(/\bquand focalise\b/gi, ':focus')
|
|
524
|
+
result = result.replace(/\ben focus\b/gi, ':focus')
|
|
525
|
+
result = result.replace(/\bau focus dans\b/gi, ':focus-within')
|
|
526
|
+
result = result.replace(/\bvisité\b/gi, ':visited')
|
|
527
|
+
result = result.replace(/\bvisite\b/gi, ':visited')
|
|
528
|
+
|
|
529
|
+
result = result.replace(/\s+(:hover|:active|:focus|:focus-within|:visited|:checked|:disabled|:enabled|:required|:optional|:valid|:invalid|:empty|:target)/gi, '$1')
|
|
530
|
+
result = result.replace(/\bpremier enfant\b/gi, ':first-child')
|
|
531
|
+
result = result.replace(/\bdernier enfant\b/gi, ':last-child')
|
|
532
|
+
result = result.replace(/\benfant impair\b/gi, ':nth-child(odd)')
|
|
533
|
+
result = result.replace(/\benfant pair\b/gi, ':nth-child(even)')
|
|
534
|
+
result = result.replace(/\bpremier de type\b/gi, ':first-of-type')
|
|
535
|
+
result = result.replace(/\bdernier de type\b/gi, ':last-of-type')
|
|
536
|
+
result = result.replace(/\benfant unique\b/gi, ':only-child')
|
|
537
|
+
result = result.replace(/\bunique de type\b/gi, ':only-of-type')
|
|
538
|
+
result = result.replace(/\bvide\b/gi, ':empty')
|
|
539
|
+
result = result.replace(/\bcible\b/gi, ':target')
|
|
540
|
+
result = result.replace(/\bcoché\b/gi, ':checked')
|
|
541
|
+
result = result.replace(/\bcoche\b/gi, ':checked')
|
|
542
|
+
result = result.replace(/\bdésactivé\b/gi, ':disabled')
|
|
543
|
+
result = result.replace(/\bdesactive\b/gi, ':disabled')
|
|
544
|
+
result = result.replace(/\bactivé\b/gi, ':enabled')
|
|
545
|
+
result = result.replace(/\brequis\b/gi, ':required')
|
|
546
|
+
result = result.replace(/\boptionnel\b/gi, ':optional')
|
|
547
|
+
result = result.replace(/\bvalide\b/gi, ':valid')
|
|
548
|
+
result = result.replace(/\binvalide\b/gi, ':invalid')
|
|
549
|
+
|
|
550
|
+
result = result.replace(/\bcorps\b/gi, 'body')
|
|
551
|
+
result = result.replace(/\btête\b/gi, 'head')
|
|
552
|
+
result = result.replace(/\btete\b/gi, 'head')
|
|
553
|
+
result = result.replace(/\btitre1\b/gi, 'h1')
|
|
554
|
+
result = result.replace(/\btitre2\b/gi, 'h2')
|
|
555
|
+
result = result.replace(/\btitre3\b/gi, 'h3')
|
|
556
|
+
result = result.replace(/\btitre4\b/gi, 'h4')
|
|
557
|
+
result = result.replace(/\btitre5\b/gi, 'h5')
|
|
558
|
+
result = result.replace(/\btitre6\b/gi, 'h6')
|
|
559
|
+
result = result.replace(/\bparagraphe\b/gi, 'p')
|
|
560
|
+
result = result.replace(/\blien\b/gi, 'a')
|
|
561
|
+
result = result.replace(/\bimage\b/gi, 'img')
|
|
562
|
+
result = result.replace(/\bbouton\b/gi, 'button')
|
|
563
|
+
result = result.replace(/\bformulaire\b/gi, 'form')
|
|
564
|
+
result = result.replace(/\bchamp\b/gi, 'input')
|
|
565
|
+
result = result.replace(/\bliste\b/gi, 'ul')
|
|
566
|
+
result = result.replace(/\bliste-ordonnée\b/gi, 'ol')
|
|
567
|
+
result = result.replace(/\bliste-ordonnee\b/gi, 'ol')
|
|
568
|
+
result = result.replace(/\bélément-liste\b/gi, 'li')
|
|
569
|
+
result = result.replace(/\belement-liste\b/gi, 'li')
|
|
570
|
+
result = result.replace(/\btableau\b/gi, 'table')
|
|
571
|
+
result = result.replace(/\bligne-tableau\b/gi, 'tr')
|
|
572
|
+
result = result.replace(/\bcellule\b/gi, 'td')
|
|
573
|
+
result = result.replace(/\bentête\b/gi, 'header')
|
|
574
|
+
result = result.replace(/\bentete\b/gi, 'header')
|
|
575
|
+
result = result.replace(/\bpied\b/gi, 'footer')
|
|
576
|
+
result = result.replace(/\bnavigation\b/gi, 'nav')
|
|
577
|
+
result = result.replace(/\bsection\b/gi, 'section')
|
|
578
|
+
result = result.replace(/\barticle\b/gi, 'article')
|
|
579
|
+
result = result.replace(/\bcôté\b/gi, 'aside')
|
|
580
|
+
result = result.replace(/\bcote\b/gi, 'aside')
|
|
581
|
+
result = result.replace(/\bprincipal\b/gi, 'main')
|
|
582
|
+
result = result.replace(/\bdivision\b/gi, 'div')
|
|
583
|
+
result = result.replace(/\bportée\b/gi, 'span')
|
|
584
|
+
result = result.replace(/\bportee\b/gi, 'span')
|
|
402
585
|
|
|
403
586
|
return result
|
|
404
587
|
}
|
|
@@ -428,12 +611,13 @@ class CSSGenerator {
|
|
|
428
611
|
'fr': 'fr'
|
|
429
612
|
}
|
|
430
613
|
|
|
614
|
+
let result = value
|
|
431
615
|
for (const [fr, css] of Object.entries(unitMap)) {
|
|
432
616
|
const regex = new RegExp(`(\\d+(?:\\.\\d+)?)\\s*${fr}\\b`, 'gi')
|
|
433
|
-
|
|
617
|
+
result = result.replace(regex, `$1${css}`)
|
|
434
618
|
}
|
|
435
619
|
|
|
436
|
-
return
|
|
620
|
+
return result
|
|
437
621
|
}
|
|
438
622
|
|
|
439
623
|
generate(ast) {
|
|
@@ -483,6 +667,10 @@ class CSSGenerator {
|
|
|
483
667
|
case 'mediaQuery':
|
|
484
668
|
this.generateMediaQuery(node)
|
|
485
669
|
break
|
|
670
|
+
case 'Condition':
|
|
671
|
+
case 'condition':
|
|
672
|
+
this.generateCondition(node)
|
|
673
|
+
break
|
|
486
674
|
case 'FontFace':
|
|
487
675
|
case 'fontFace':
|
|
488
676
|
this.generateFontFace(node)
|
|
@@ -538,7 +726,7 @@ class CSSGenerator {
|
|
|
538
726
|
let value = decl.value
|
|
539
727
|
|
|
540
728
|
if (isRoot) {
|
|
541
|
-
property = '--' + property.toLowerCase()
|
|
729
|
+
property = '--' + property.toLowerCase().replace(/\s+/g, '-')
|
|
542
730
|
} else {
|
|
543
731
|
property = this.translateProperty(property)
|
|
544
732
|
}
|
|
@@ -633,27 +821,79 @@ class CSSGenerator {
|
|
|
633
821
|
generateMediaQuery(node) {
|
|
634
822
|
let query = node.query || node.condition || ''
|
|
635
823
|
|
|
636
|
-
query =
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
824
|
+
query = this.translateMediaQuery(query)
|
|
825
|
+
|
|
826
|
+
this.writeLine(`@media ${query} {`)
|
|
827
|
+
this.indent++
|
|
828
|
+
|
|
829
|
+
const rules = node.rules || node.children || []
|
|
830
|
+
for (const rule of rules) {
|
|
831
|
+
this.generateNode(rule)
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
this.indent--
|
|
835
|
+
this.writeLine('}')
|
|
836
|
+
this.writeLine('')
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
translateMediaQuery(query) {
|
|
840
|
+
let result = query
|
|
841
|
+
|
|
842
|
+
result = result.replace(/écran/gi, 'screen')
|
|
843
|
+
result = result.replace(/ecran/gi, 'screen')
|
|
844
|
+
result = result.replace(/imprimante/gi, 'print')
|
|
845
|
+
result = result.replace(/tous/gi, 'all')
|
|
846
|
+
result = result.replace(/largeur-min/gi, 'min-width')
|
|
847
|
+
result = result.replace(/largeur min/gi, 'min-width')
|
|
848
|
+
result = result.replace(/largeur-max/gi, 'max-width')
|
|
849
|
+
result = result.replace(/largeur max/gi, 'max-width')
|
|
850
|
+
result = result.replace(/max-largeur/gi, 'max-width')
|
|
851
|
+
result = result.replace(/min-largeur/gi, 'min-width')
|
|
852
|
+
result = result.replace(/hauteur-min/gi, 'min-height')
|
|
853
|
+
result = result.replace(/hauteur min/gi, 'min-height')
|
|
854
|
+
result = result.replace(/hauteur-max/gi, 'max-height')
|
|
855
|
+
result = result.replace(/hauteur max/gi, 'max-height')
|
|
856
|
+
result = result.replace(/max-hauteur/gi, 'max-height')
|
|
857
|
+
result = result.replace(/min-hauteur/gi, 'min-height')
|
|
858
|
+
result = result.replace(/orientation/gi, 'orientation')
|
|
859
|
+
result = result.replace(/paysage/gi, 'landscape')
|
|
860
|
+
result = result.replace(/portrait/gi, 'portrait')
|
|
861
|
+
result = result.replace(/\bet\b/gi, 'and')
|
|
862
|
+
result = result.replace(/\bou\b/gi, 'or')
|
|
863
|
+
result = result.replace(/\bpas\b/gi, 'not')
|
|
864
|
+
|
|
865
|
+
return result
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
generateCondition(node) {
|
|
869
|
+
let condition = node.condition || ''
|
|
870
|
+
let query = ''
|
|
871
|
+
|
|
872
|
+
const plusPetitMatch = condition.match(/plus petit que\s+([\d.]+\w*)/i)
|
|
873
|
+
const plusGrandMatch = condition.match(/plus grand que\s+([\d.]+\w*)/i)
|
|
874
|
+
const inferieurMatch = condition.match(/inférieur[e]?\s+à\s+([\d.]+\w*)/i) || condition.match(/inferieur[e]?\s+a\s+([\d.]+\w*)/i)
|
|
875
|
+
const superieurMatch = condition.match(/supérieur[e]?\s+à\s+([\d.]+\w*)/i) || condition.match(/superieur[e]?\s+a\s+([\d.]+\w*)/i)
|
|
876
|
+
const egalMatch = condition.match(/égal[e]?\s+à\s+([\d.]+\w*)/i) || condition.match(/egal[e]?\s+a\s+([\d.]+\w*)/i)
|
|
877
|
+
const simpleInfMatch = condition.match(/<\s*([\d.]+\w*)/i)
|
|
878
|
+
const simpleSupMatch = condition.match(/>\s*([\d.]+\w*)/i)
|
|
879
|
+
|
|
880
|
+
if (plusPetitMatch) {
|
|
881
|
+
query = `(max-width: ${plusPetitMatch[1]})`
|
|
882
|
+
} else if (plusGrandMatch) {
|
|
883
|
+
query = `(min-width: ${plusGrandMatch[1]})`
|
|
884
|
+
} else if (inferieurMatch) {
|
|
885
|
+
query = `(max-width: ${inferieurMatch[1]})`
|
|
886
|
+
} else if (superieurMatch) {
|
|
887
|
+
query = `(min-width: ${superieurMatch[1]})`
|
|
888
|
+
} else if (egalMatch) {
|
|
889
|
+
query = `(width: ${egalMatch[1]})`
|
|
890
|
+
} else if (simpleInfMatch) {
|
|
891
|
+
query = `(max-width: ${simpleInfMatch[1]})`
|
|
892
|
+
} else if (simpleSupMatch) {
|
|
893
|
+
query = `(min-width: ${simpleSupMatch[1]})`
|
|
894
|
+
} else {
|
|
895
|
+
query = this.translateMediaQuery(condition)
|
|
896
|
+
}
|
|
657
897
|
|
|
658
898
|
this.writeLine(`@media ${query} {`)
|
|
659
899
|
this.indent++
|
package/lexer/ether-lexer.js
CHANGED
|
@@ -221,6 +221,11 @@ class EtherLexer {
|
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
if (char === '#') {
|
|
224
|
+
const next = this.peek(1)
|
|
225
|
+
if (next && (this.isHexDigit(next) || this.isAlpha(next))) {
|
|
226
|
+
this.scanHashToken()
|
|
227
|
+
return
|
|
228
|
+
}
|
|
224
229
|
this.scanComment()
|
|
225
230
|
return
|
|
226
231
|
}
|
|
@@ -319,6 +324,42 @@ class EtherLexer {
|
|
|
319
324
|
}
|
|
320
325
|
}
|
|
321
326
|
|
|
327
|
+
scanHashToken() {
|
|
328
|
+
const startLine = this.line
|
|
329
|
+
const startCol = this.column
|
|
330
|
+
|
|
331
|
+
this.advance()
|
|
332
|
+
|
|
333
|
+
let value = ''
|
|
334
|
+
let isHexColor = true
|
|
335
|
+
let charCount = 0
|
|
336
|
+
|
|
337
|
+
while (!this.isAtEnd()) {
|
|
338
|
+
const char = this.peek()
|
|
339
|
+
if (this.isHexDigit(char)) {
|
|
340
|
+
value += this.advance()
|
|
341
|
+
charCount++
|
|
342
|
+
} else if (this.isAlpha(char) && !this.isHexDigit(char)) {
|
|
343
|
+
isHexColor = false
|
|
344
|
+
value += this.advance()
|
|
345
|
+
} else if (char === '-' || char === '_') {
|
|
346
|
+
isHexColor = false
|
|
347
|
+
value += this.advance()
|
|
348
|
+
} else {
|
|
349
|
+
break
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if (isHexColor && (charCount === 3 || charCount === 4 || charCount === 6 || charCount === 8)) {
|
|
354
|
+
this.tokens.push(new Token(TokenType.HEX, '#' + value, startLine, startCol, this.currentIndent))
|
|
355
|
+
} else {
|
|
356
|
+
this.tokens.push(new Token(TokenType.HASH, '#', startLine, startCol, this.currentIndent))
|
|
357
|
+
if (value) {
|
|
358
|
+
this.tokens.push(new Token(TokenType.IDENTIFIER, value, startLine, startCol + 1, this.currentIndent))
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
322
363
|
scanBlockComment() {
|
|
323
364
|
const startLine = this.line
|
|
324
365
|
const startCol = this.column
|
|
@@ -521,10 +562,42 @@ class EtherLexer {
|
|
|
521
562
|
}
|
|
522
563
|
|
|
523
564
|
if (type === TokenType.FLOAT) {
|
|
524
|
-
|
|
565
|
+
let numValue = String(parseFloat(value))
|
|
566
|
+
const unit = this.scanCSSUnit()
|
|
567
|
+
if (unit) numValue += unit
|
|
568
|
+
this.tokens.push(new Token(type, numValue, startLine, startCol, this.currentIndent))
|
|
525
569
|
} else {
|
|
526
|
-
|
|
570
|
+
let numValue = String(parseInt(value, 10))
|
|
571
|
+
const unit = this.scanCSSUnit()
|
|
572
|
+
if (unit) numValue += unit
|
|
573
|
+
this.tokens.push(new Token(type, numValue, startLine, startCol, this.currentIndent))
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
scanCSSUnit() {
|
|
578
|
+
const units = ['px', 'em', 'rem', 'vh', 'vw', 'vmin', 'vmax', '%', 'fr', 's', 'ms', 'deg', 'rad', 'turn', 'ch', 'ex', 'cm', 'mm', 'in', 'pt', 'pc', 'cqw', 'cqh']
|
|
579
|
+
|
|
580
|
+
for (const unit of units) {
|
|
581
|
+
let matches = true
|
|
582
|
+
for (let i = 0; i < unit.length; i++) {
|
|
583
|
+
const char = this.peek(i)
|
|
584
|
+
if (!char || char.toLowerCase() !== unit[i].toLowerCase()) {
|
|
585
|
+
matches = false
|
|
586
|
+
break
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
if (matches) {
|
|
590
|
+
const afterUnit = this.peek(unit.length)
|
|
591
|
+
if (!afterUnit || !this.isAlpha(afterUnit)) {
|
|
592
|
+
let result = ''
|
|
593
|
+
for (let i = 0; i < unit.length; i++) {
|
|
594
|
+
result += this.advance()
|
|
595
|
+
}
|
|
596
|
+
return result
|
|
597
|
+
}
|
|
598
|
+
}
|
|
527
599
|
}
|
|
600
|
+
return ''
|
|
528
601
|
}
|
|
529
602
|
|
|
530
603
|
scanIdentifier() {
|
|
@@ -693,7 +766,15 @@ class EtherLexer {
|
|
|
693
766
|
|
|
694
767
|
case '-':
|
|
695
768
|
if (this.match('-')) {
|
|
696
|
-
this.
|
|
769
|
+
if (this.isAlpha(this.peek()) || this.peek() === '-') {
|
|
770
|
+
let varName = '--'
|
|
771
|
+
while (this.isAlphaNumeric(this.peek()) || this.peek() === '-' || this.peek() === '_') {
|
|
772
|
+
varName += this.advance()
|
|
773
|
+
}
|
|
774
|
+
this.tokens.push(new Token(TokenType.IDENTIFIER, varName, startLine, startCol, this.currentIndent))
|
|
775
|
+
} else {
|
|
776
|
+
this.tokens.push(new Token(TokenType.MINUS, '--', startLine, startCol, this.currentIndent))
|
|
777
|
+
}
|
|
697
778
|
} else if (this.match('>')) {
|
|
698
779
|
this.tokens.push(new Token(TokenType.ARROW, '->', startLine, startCol, this.currentIndent))
|
|
699
780
|
} else if (this.match('=')) {
|
|
@@ -866,4 +947,4 @@ module.exports = {
|
|
|
866
947
|
Token,
|
|
867
948
|
TokenType,
|
|
868
949
|
LANG_BLOCKS
|
|
869
|
-
}
|
|
950
|
+
}
|