ether-code 0.4.9 → 0.5.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 CHANGED
@@ -6,7 +6,7 @@ const http = require('http')
6
6
  const { EtherCompiler } = require('./compiler')
7
7
  const { Watcher } = require('./watcher')
8
8
 
9
- const VERSION = '0.4.9'
9
+ const VERSION = '0.5.1'
10
10
 
11
11
  const COLORS = {
12
12
  reset: '\x1b[0m',
package/ether-parser.js CHANGED
@@ -651,6 +651,8 @@ class EtherParser {
651
651
  'titre6': 'h6',
652
652
  'paragraphe': 'p',
653
653
  'lien': 'a',
654
+ 'ressource': 'link',
655
+ 'lien externe': 'link',
654
656
  'image': 'img',
655
657
  'bouton': 'button',
656
658
  'formulaire': 'form',
@@ -680,9 +682,61 @@ class EtherParser {
680
682
  const token = this.current()
681
683
  if (!token || token.type !== TokenType.IDENTIFIER) return null
682
684
 
683
- const property = token.value
685
+ const compoundProperties = {
686
+ 'marge': ['dedans', 'autour', 'haut', 'bas', 'gauche', 'droite'],
687
+ 'marge dedans': ['haut', 'bas', 'gauche', 'droite'],
688
+ 'marge autour': ['haut', 'bas', 'gauche', 'droite'],
689
+ 'remplissage': ['haut', 'bas', 'gauche', 'droite'],
690
+ 'taille': ['police'],
691
+ 'poids': ['police'],
692
+ 'style': ['police', 'liste'],
693
+ 'hauteur': ['ligne', 'min', 'max', 'minimum', 'maximum'],
694
+ 'largeur': ['min', 'max', 'minimum', 'maximum'],
695
+ 'alignement': ['texte'],
696
+ 'decoration': ['texte'],
697
+ 'transformation': ['texte'],
698
+ 'ombre': ['texte', 'boite', 'boîte'],
699
+ 'espacement': ['lettres'],
700
+ 'bordure': ['haut', 'bas', 'gauche', 'droite', 'couleur', 'style', 'largeur', 'arrondi'],
701
+ 'couleur': ['bordure', 'fond', 'texte', 'remplissage'],
702
+ 'arrondi': ['haut', 'bas'],
703
+ 'arrondi haut': ['gauche', 'droite'],
704
+ 'arrondi bas': ['gauche', 'droite'],
705
+ 'fond': ['couleur', 'image', 'position', 'taille', 'repetition', 'attachement'],
706
+ 'direction': ['flex'],
707
+ 'enveloppe': ['flex'],
708
+ 'justifier': ['contenu'],
709
+ 'aligner': ['elements', 'éléments', 'contenu'],
710
+ 'colonnes': ['grille'],
711
+ 'lignes': ['grille'],
712
+ 'espace': ['ligne', 'colonne', 'blanc'],
713
+ 'débordement': ['x', 'y'],
714
+ 'debordement': ['x', 'y'],
715
+ 'événements': ['pointeur'],
716
+ 'evenements': ['pointeur'],
717
+ 'modèle': ['boite', 'boîte'],
718
+ 'modele': ['boite', 'boîte'],
719
+ 'filtre': ['fond'],
720
+ 'decoupe': ['fond'],
721
+ 'découpe': ['fond'],
722
+ 'origine': ['transformation', 'perspective']
723
+ }
724
+
725
+ let property = token.value
684
726
  this.advance()
685
727
 
728
+ let nextToken = this.current()
729
+ while (nextToken && nextToken.type === TokenType.IDENTIFIER) {
730
+ const propLower = property.toLowerCase()
731
+ if (compoundProperties[propLower] && compoundProperties[propLower].includes(nextToken.value.toLowerCase())) {
732
+ property = property + ' ' + nextToken.value
733
+ this.advance()
734
+ nextToken = this.current()
735
+ } else {
736
+ break
737
+ }
738
+ }
739
+
686
740
  let hasColon = this.match(TokenType.COLON)
687
741
  let hasEquals = !hasColon && this.match(TokenType.EQUALS)
688
742
 
@@ -710,6 +764,15 @@ class EtherParser {
710
764
  needsSpace = false
711
765
  }
712
766
 
767
+ if (lastType === TokenType.NUMBER || lastType === TokenType.INTEGER || lastType === TokenType.FLOAT) {
768
+ if (current.type === TokenType.IDENTIFIER) {
769
+ const units = ['px', 'em', 'rem', '%', 'vw', 'vh', 'vmin', 'vmax', 'ch', 'ex', 'cm', 'mm', 'in', 'pt', 'pc', 'deg', 'rad', 'turn', 'ms', 's', 'fr', 'cqw', 'cqh']
770
+ if (units.includes(current.value.toLowerCase())) {
771
+ needsSpace = false
772
+ }
773
+ }
774
+ }
775
+
713
776
  if (current.type === TokenType.IDENTIFIER) {
714
777
  if (needsSpace) valueParts.push(' ')
715
778
  valueParts.push(current.value)
@@ -738,12 +801,14 @@ class EtherParser {
738
801
  if (needsSpace) valueParts.push(' ')
739
802
  valueParts.push('/')
740
803
  } else if (current.type === TokenType.MINUS) {
741
- if (lastType === TokenType.LPAREN || lastType === TokenType.MINUS) {
742
- valueParts.push('-')
804
+ if (current.value === '--') {
805
+ valueParts.push('--')
806
+ } else if (lastType === TokenType.LPAREN || lastType === TokenType.MINUS) {
807
+ valueParts.push(current.value)
743
808
  } else if (needsSpace) {
744
- valueParts.push(' -')
809
+ valueParts.push(' ' + current.value)
745
810
  } else {
746
- valueParts.push('-')
811
+ valueParts.push(current.value)
747
812
  }
748
813
  } else if (current.type === TokenType.COLON) {
749
814
  valueParts.push(':')
@@ -854,7 +919,7 @@ class EtherParser {
854
919
  const name = nameToken.value.toLowerCase()
855
920
  this.advance()
856
921
 
857
- if (name === 'media' || name === 'requete media' || name === 'ecran') {
922
+ if (name === 'media' || name === 'requete media' || name === 'ecran' || name === 'si') {
858
923
  return this.parseCSSMediaQuery()
859
924
  }
860
925
 
@@ -916,20 +981,30 @@ class EtherParser {
916
981
  }
917
982
 
918
983
  translateMediaQuery(query) {
919
- return query
984
+ let result = query
985
+
986
+ result = result.replace(/ecran\s+tres\s+petit/gi, 'screen and (max-width: 480px)')
987
+ result = result.replace(/ecran\s+petit/gi, 'screen and (max-width: 768px)')
988
+ result = result.replace(/ecran\s+moyen/gi, 'screen and (max-width: 1024px)')
989
+ result = result.replace(/ecran\s+large/gi, 'screen and (min-width: 1025px) and (max-width: 1280px)')
990
+ result = result.replace(/ecran\s+tres\s+large/gi, 'screen and (min-width: 1281px)')
991
+
992
+ result = result
920
993
  .replace(/ecran/gi, 'screen')
921
994
  .replace(/imprimante/gi, 'print')
922
995
  .replace(/tous/gi, 'all')
923
- .replace(/largeur min/gi, 'min-width')
924
- .replace(/largeur max/gi, 'max-width')
925
- .replace(/hauteur min/gi, 'min-height')
926
- .replace(/hauteur max/gi, 'max-height')
996
+ .replace(/largeur\s+min/gi, 'min-width')
997
+ .replace(/largeur\s+max/gi, 'max-width')
998
+ .replace(/hauteur\s+min/gi, 'min-height')
999
+ .replace(/hauteur\s+max/gi, 'max-height')
927
1000
  .replace(/orientation/gi, 'orientation')
928
1001
  .replace(/paysage/gi, 'landscape')
929
1002
  .replace(/portrait/gi, 'portrait')
930
- .replace(/et/gi, 'and')
931
- .replace(/ou/gi, 'or')
932
- .replace(/pas/gi, 'not')
1003
+ .replace(/\bet\b/gi, 'and')
1004
+ .replace(/\bou\b/gi, 'or')
1005
+ .replace(/\bpas\b/gi, 'not')
1006
+
1007
+ return result
933
1008
  }
934
1009
 
935
1010
  parseCSSKeyframes() {
@@ -1101,12 +1176,237 @@ class EtherParser {
1101
1176
 
1102
1177
  parseHTMLElement() {
1103
1178
  const tagToken = this.current()
1104
- const tag = this.translateHTMLTag(tagToken.value)
1179
+ let tagName = tagToken.value.toLowerCase()
1105
1180
  this.advance()
1106
1181
 
1182
+ const nextToken = this.current()
1183
+ if ((tagName === 'titre' || tagName === 'heading') && nextToken && (nextToken.type === TokenType.NUMBER || nextToken.type === TokenType.INTEGER)) {
1184
+ const num = parseInt(nextToken.value)
1185
+ if (num >= 1 && num <= 6) {
1186
+ tagName = `titre${num}`
1187
+ this.advance()
1188
+ }
1189
+ }
1190
+
1191
+ if ((tagName === 'liste' || tagName === 'list') && nextToken) {
1192
+ if (nextToken.type === TokenType.IDENTIFIER) {
1193
+ const nextVal = nextToken.value.toLowerCase()
1194
+ if (nextVal === 'ordonnee' || nextVal === 'ordered') {
1195
+ tagName = 'liste ordonnee'
1196
+ this.advance()
1197
+ } else if (nextVal === 'non') {
1198
+ this.advance()
1199
+ const thirdToken = this.current()
1200
+ if (thirdToken && thirdToken.type === TokenType.IDENTIFIER && thirdToken.value.toLowerCase() === 'ordonnee') {
1201
+ tagName = 'liste non ordonnee'
1202
+ this.advance()
1203
+ }
1204
+ }
1205
+ }
1206
+ }
1207
+
1208
+ if ((tagName === 'element' || tagName === 'item') && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1209
+ if (nextToken.value.toLowerCase() === 'liste' || nextToken.value.toLowerCase() === 'list') {
1210
+ tagName = 'element liste'
1211
+ this.advance()
1212
+ }
1213
+ }
1214
+
1215
+ if ((tagName === 'zone' || tagName === 'area') && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1216
+ if (nextToken.value.toLowerCase() === 'texte' || nextToken.value.toLowerCase() === 'text') {
1217
+ tagName = 'zone texte'
1218
+ this.advance()
1219
+ }
1220
+ }
1221
+
1222
+ if ((tagName === 'retour' || tagName === 'saut') && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1223
+ if (nextToken.value.toLowerCase() === 'ligne' || nextToken.value.toLowerCase() === 'line') {
1224
+ tagName = 'retour ligne'
1225
+ this.advance()
1226
+ }
1227
+ }
1228
+
1229
+ if (tagName === 'ligne' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1230
+ if (nextToken.value.toLowerCase() === 'horizontale') {
1231
+ tagName = 'ligne horizontale'
1232
+ this.advance()
1233
+ }
1234
+ }
1235
+
1236
+ if ((tagName === 'cellule' || tagName === 'cell') && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1237
+ if (nextToken.value.toLowerCase() === 'entete' || nextToken.value.toLowerCase() === 'header') {
1238
+ tagName = 'entete cellule'
1239
+ this.advance()
1240
+ }
1241
+ }
1242
+
1243
+ if (tagName === 'groupe' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1244
+ const next = nextToken.value.toLowerCase()
1245
+ if (next === 'titres') {
1246
+ tagName = 'groupe titres'
1247
+ this.advance()
1248
+ } else if (next === 'options') {
1249
+ tagName = 'groupe options'
1250
+ this.advance()
1251
+ } else if (next === 'colonnes') {
1252
+ tagName = 'groupe colonnes'
1253
+ this.advance()
1254
+ }
1255
+ }
1256
+
1257
+ if (tagName === 'entete' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1258
+ const next = nextToken.value.toLowerCase()
1259
+ if (next === 'tableau' || next === 'table') {
1260
+ tagName = 'entete tableau'
1261
+ this.advance()
1262
+ }
1263
+ }
1264
+
1265
+ if (tagName === 'corps' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1266
+ const next = nextToken.value.toLowerCase()
1267
+ if (next === 'tableau' || next === 'table') {
1268
+ tagName = 'corps tableau'
1269
+ this.advance()
1270
+ }
1271
+ }
1272
+
1273
+ if (tagName === 'pied' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1274
+ const next = nextToken.value.toLowerCase()
1275
+ if (next === 'tableau' || next === 'table') {
1276
+ tagName = 'pied tableau'
1277
+ this.advance()
1278
+ }
1279
+ }
1280
+
1281
+ if (tagName === 'legende' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1282
+ const next = nextToken.value.toLowerCase()
1283
+ if (next === 'tableau' || next === 'table') {
1284
+ tagName = 'legende tableau'
1285
+ this.advance()
1286
+ } else if (next === 'figure') {
1287
+ tagName = 'legende figure'
1288
+ this.advance()
1289
+ }
1290
+ }
1291
+
1292
+ if (tagName === 'ensemble' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1293
+ const next = nextToken.value.toLowerCase()
1294
+ if (next === 'champs' || next === 'fields') {
1295
+ tagName = 'ensemble champs'
1296
+ this.advance()
1297
+ }
1298
+ }
1299
+
1300
+ if (tagName === 'liste' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1301
+ const next = nextToken.value.toLowerCase()
1302
+ if (next === 'donnees' || next === 'data') {
1303
+ tagName = 'liste donnees'
1304
+ this.advance()
1305
+ } else if (next === 'description') {
1306
+ tagName = 'liste description'
1307
+ this.advance()
1308
+ }
1309
+ }
1310
+
1311
+ if (tagName === 'image' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1312
+ const next = nextToken.value.toLowerCase()
1313
+ if (next === 'reactive' || next === 'responsive') {
1314
+ tagName = 'image reactive'
1315
+ this.advance()
1316
+ }
1317
+ }
1318
+
1319
+ if (tagName === 'cadre' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1320
+ const next = nextToken.value.toLowerCase()
1321
+ if (next === 'en') {
1322
+ this.advance()
1323
+ const thirdToken = this.current()
1324
+ if (thirdToken && thirdToken.type === TokenType.IDENTIFIER && thirdToken.value.toLowerCase() === 'ligne') {
1325
+ tagName = 'cadre en ligne'
1326
+ this.advance()
1327
+ }
1328
+ }
1329
+ }
1330
+
1331
+ if (tagName === 'citation' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1332
+ const next = nextToken.value.toLowerCase()
1333
+ if (next === 'bloc' || next === 'block') {
1334
+ tagName = 'citation bloc'
1335
+ this.advance()
1336
+ }
1337
+ }
1338
+
1339
+ if (tagName === 'reference' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1340
+ const next = nextToken.value.toLowerCase()
1341
+ if (next === 'citation') {
1342
+ tagName = 'reference citation'
1343
+ this.advance()
1344
+ }
1345
+ }
1346
+
1347
+ if (tagName === 'sans' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1348
+ const next = nextToken.value.toLowerCase()
1349
+ if (next === 'script') {
1350
+ tagName = 'sans script'
1351
+ this.advance()
1352
+ }
1353
+ }
1354
+
1355
+ if ((tagName === 'texte' || tagName === 'text') && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1356
+ const next = nextToken.value.toLowerCase()
1357
+ if (next === 'alternatif' || next === 'alt') {
1358
+ tagName = 'texte alternatif'
1359
+ this.advance()
1360
+ }
1361
+ }
1362
+
1363
+ if (tagName === 'entree' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1364
+ const next = nextToken.value.toLowerCase()
1365
+ if (next === 'clavier') {
1366
+ tagName = 'entree clavier'
1367
+ this.advance()
1368
+ }
1369
+ }
1370
+
1371
+ if (tagName === 'sortie' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1372
+ const next = nextToken.value.toLowerCase()
1373
+ if (next === 'exemple') {
1374
+ tagName = 'sortie exemple'
1375
+ this.advance()
1376
+ }
1377
+ }
1378
+
1379
+ if (tagName === 'definition' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1380
+ const next = nextToken.value.toLowerCase()
1381
+ if (next === 'description') {
1382
+ tagName = 'definition description'
1383
+ this.advance()
1384
+ }
1385
+ }
1386
+
1387
+ const tag = this.translateHTMLTag(tagName)
1388
+
1107
1389
  const attributes = {}
1108
1390
  let inlineText = null
1109
1391
 
1392
+ const compoundAttrs = {
1393
+ 'texte': ['alternatif'],
1394
+ 'longueur': ['max', 'min'],
1395
+ 'valeur': ['max', 'min'],
1396
+ 'zone': ['depot'],
1397
+ 'mode': ['saisie'],
1398
+ 'verification': ['orthographe'],
1399
+ 'ordre': ['tabulation'],
1400
+ 'action': ['formulaire'],
1401
+ 'methode': ['formulaire'],
1402
+ 'encodage': ['formulaire'],
1403
+ 'validation': ['formulaire', 'auto'],
1404
+ 'cible': ['formulaire', 'popover'],
1405
+ 'lecture': ['seule'],
1406
+ 'nouvelle': ['fenetre'],
1407
+ 'a': ['popup']
1408
+ }
1409
+
1110
1410
  while (!this.isAtEnd()) {
1111
1411
  const current = this.current()
1112
1412
 
@@ -1122,18 +1422,30 @@ class EtherParser {
1122
1422
  }
1123
1423
 
1124
1424
  if (current.type === TokenType.IDENTIFIER) {
1125
- const attrName = current.value
1126
- const nextToken = this.peek(1)
1425
+ let attrName = current.value.toLowerCase()
1426
+ this.advance()
1427
+
1428
+ if (compoundAttrs[attrName]) {
1429
+ const nextTok = this.current()
1430
+ if (nextTok && nextTok.type === TokenType.IDENTIFIER) {
1431
+ const nextVal = nextTok.value.toLowerCase()
1432
+ if (compoundAttrs[attrName].includes(nextVal)) {
1433
+ attrName = attrName + ' ' + nextVal
1434
+ this.advance()
1435
+ }
1436
+ }
1437
+ }
1438
+
1439
+ const nextToken = this.current()
1127
1440
 
1128
1441
  if (nextToken && (nextToken.type === TokenType.EQUALS || nextToken.type === TokenType.COLON)) {
1129
- this.advance()
1130
1442
  this.advance()
1131
1443
  const valueToken = this.current()
1132
1444
  if (valueToken) {
1133
1445
  if (valueToken.type === TokenType.STRING) {
1134
1446
  attributes[attrName] = valueToken.value.replace(/^["']|["']$/g, '')
1135
1447
  } else if (valueToken.type === TokenType.IDENTIFIER ||
1136
- valueToken.type === TokenType.NUMBER) {
1448
+ valueToken.type === TokenType.NUMBER || valueToken.type === TokenType.INTEGER) {
1137
1449
  attributes[attrName] = valueToken.value
1138
1450
  }
1139
1451
  this.advance()
@@ -1144,7 +1456,6 @@ class EtherParser {
1144
1456
  }
1145
1457
  } else {
1146
1458
  attributes[attrName] = true
1147
- this.advance()
1148
1459
 
1149
1460
  if (this.current() && this.current().type === TokenType.COMMA) {
1150
1461
  this.advance()
@@ -1221,6 +1532,20 @@ class EtherParser {
1221
1532
  'titre4': 'h4',
1222
1533
  'titre5': 'h5',
1223
1534
  'titre6': 'h6',
1535
+ 'titre 1': 'h1',
1536
+ 'titre 2': 'h2',
1537
+ 'titre 3': 'h3',
1538
+ 'titre 4': 'h4',
1539
+ 'titre 5': 'h5',
1540
+ 'titre 6': 'h6',
1541
+ 'heading 1': 'h1',
1542
+ 'heading 2': 'h2',
1543
+ 'heading 3': 'h3',
1544
+ 'heading 4': 'h4',
1545
+ 'heading 5': 'h5',
1546
+ 'heading 6': 'h6',
1547
+ 'groupe titres': 'hgroup',
1548
+ 'heading group': 'hgroup',
1224
1549
  'sous titre': 'h2',
1225
1550
  'paragraphe': 'p',
1226
1551
  'texte': 'span',
@@ -1229,6 +1554,8 @@ class EtherParser {
1229
1554
  'bloc': 'div',
1230
1555
  'span': 'span',
1231
1556
  'lien': 'a',
1557
+ 'ressource': 'link',
1558
+ 'lien externe': 'link',
1232
1559
  'image': 'img',
1233
1560
  'liste': 'ul',
1234
1561
  'liste ordonnee': 'ol',
@@ -1241,6 +1568,8 @@ class EtherParser {
1241
1568
  'entete cellule': 'th',
1242
1569
  'formulaire': 'form',
1243
1570
  'champ': 'input',
1571
+ 'entree': 'input',
1572
+ 'input': 'input',
1244
1573
  'zone texte': 'textarea',
1245
1574
  'bouton': 'button',
1246
1575
  'selection': 'select',
@@ -1268,7 +1597,58 @@ class EtherParser {
1268
1597
  'canvas': 'canvas',
1269
1598
  'toile': 'canvas',
1270
1599
  'figure': 'figure',
1271
- 'legende': 'figcaption',
1600
+ 'legende': 'legend',
1601
+ 'legende figure': 'figcaption',
1602
+ 'legende tableau': 'caption',
1603
+ 'legende ensemble': 'legend',
1604
+ 'figure caption': 'figcaption',
1605
+ 'table caption': 'caption',
1606
+ 'entete tableau': 'thead',
1607
+ 'table header': 'thead',
1608
+ 'corps tableau': 'tbody',
1609
+ 'table body': 'tbody',
1610
+ 'pied tableau': 'tfoot',
1611
+ 'table footer': 'tfoot',
1612
+ 'ensemble champs': 'fieldset',
1613
+ 'fieldset': 'fieldset',
1614
+ 'liste donnees': 'datalist',
1615
+ 'datalist': 'datalist',
1616
+ 'liste description': 'dl',
1617
+ 'description list': 'dl',
1618
+ 'definition description': 'dd',
1619
+ 'image reactive': 'picture',
1620
+ 'picture': 'picture',
1621
+ 'cadre en ligne': 'iframe',
1622
+ 'inline frame': 'iframe',
1623
+ 'iframe': 'iframe',
1624
+ 'citation bloc': 'blockquote',
1625
+ 'blockquote': 'blockquote',
1626
+ 'reference citation': 'cite',
1627
+ 'groupe options': 'optgroup',
1628
+ 'option group': 'optgroup',
1629
+ 'groupe colonnes': 'colgroup',
1630
+ 'column group': 'colgroup',
1631
+ 'colonne': 'col',
1632
+ 'column': 'col',
1633
+ 'entree clavier': 'kbd',
1634
+ 'keyboard input': 'kbd',
1635
+ 'sortie exemple': 'samp',
1636
+ 'sample output': 'samp',
1637
+ 'texte alternatif': 'alt',
1638
+ 'resultat': 'output',
1639
+ 'result': 'output',
1640
+ 'piste': 'track',
1641
+ 'track': 'track',
1642
+ 'insere': 'ins',
1643
+ 'inserted': 'ins',
1644
+ 'supprime': 'del',
1645
+ 'deleted': 'del',
1646
+ 'donnee': 'data',
1647
+ 'retour ligne possible': 'wbr',
1648
+ 'word break': 'wbr',
1649
+ 'carte image': 'map',
1650
+ 'image map': 'map',
1651
+ 'script': 'script',
1272
1652
  'details': 'details',
1273
1653
  'resume': 'summary',
1274
1654
  'dialogue': 'dialog',
@@ -215,10 +215,78 @@ class CSSGenerator {
215
215
  'lavande': 'lavender',
216
216
  'prune': 'plum',
217
217
  'chocolat': 'chocolate',
218
- 'transparent': 'transparent'
218
+ 'transparent': 'transparent',
219
+ 'marron': 'brown'
220
+ }
221
+
222
+ const shadeMap = {
223
+ 'bleu clair': 'lightblue',
224
+ 'bleu fonce': 'darkblue',
225
+ 'bleu foncé': 'darkblue',
226
+ 'bleu tres clair': 'lightcyan',
227
+ 'bleu très clair': 'lightcyan',
228
+ 'bleu tres fonce': '#00008B',
229
+ 'bleu très foncé': '#00008B',
230
+ 'bleu pale': 'lightsteelblue',
231
+ 'bleu pâle': 'lightsteelblue',
232
+ 'bleu vif': 'royalblue',
233
+ 'vert clair': 'lightgreen',
234
+ 'vert fonce': 'darkgreen',
235
+ 'vert foncé': 'darkgreen',
236
+ 'vert tres clair': 'palegreen',
237
+ 'vert très clair': 'palegreen',
238
+ 'vert tres fonce': '#006400',
239
+ 'vert très foncé': '#006400',
240
+ 'vert pale': 'palegreen',
241
+ 'vert pâle': 'palegreen',
242
+ 'vert vif': 'limegreen',
243
+ 'rouge clair': 'lightcoral',
244
+ 'rouge fonce': 'darkred',
245
+ 'rouge foncé': 'darkred',
246
+ 'rouge tres clair': 'mistyrose',
247
+ 'rouge très clair': 'mistyrose',
248
+ 'rouge tres fonce': '#8B0000',
249
+ 'rouge très foncé': '#8B0000',
250
+ 'rouge pale': 'lightpink',
251
+ 'rouge pâle': 'lightpink',
252
+ 'rouge vif': 'crimson',
253
+ 'jaune clair': 'lightyellow',
254
+ 'jaune fonce': 'darkgoldenrod',
255
+ 'jaune foncé': 'darkgoldenrod',
256
+ 'jaune pale': 'lemonchiffon',
257
+ 'jaune pâle': 'lemonchiffon',
258
+ 'jaune vif': 'gold',
259
+ 'gris clair': 'lightgray',
260
+ 'gris fonce': 'darkgray',
261
+ 'gris foncé': 'darkgray',
262
+ 'gris tres clair': 'whitesmoke',
263
+ 'gris très clair': 'whitesmoke',
264
+ 'gris tres fonce': 'dimgray',
265
+ 'gris très foncé': 'dimgray',
266
+ 'violet clair': 'plum',
267
+ 'violet fonce': 'darkviolet',
268
+ 'violet foncé': 'darkviolet',
269
+ 'violet vif': 'blueviolet',
270
+ 'orange clair': 'lightsalmon',
271
+ 'orange fonce': 'darkorange',
272
+ 'orange foncé': 'darkorange',
273
+ 'orange vif': 'orangered',
274
+ 'rose clair': 'lightpink',
275
+ 'rose fonce': 'hotpink',
276
+ 'rose foncé': 'hotpink',
277
+ 'rose vif': 'deeppink',
278
+ 'cyan clair': 'lightcyan',
279
+ 'cyan fonce': 'darkcyan',
280
+ 'cyan foncé': 'darkcyan'
219
281
  }
220
282
 
221
283
  let result = val
284
+
285
+ for (const [fr, en] of Object.entries(shadeMap)) {
286
+ const regex = new RegExp(`\\b${fr}\\b`, 'gi')
287
+ result = result.replace(regex, en)
288
+ }
289
+
222
290
  for (const [fr, en] of Object.entries(colorMap)) {
223
291
  const regex = new RegExp(`\\b${fr}\\b`, 'gi')
224
292
  result = result.replace(regex, en)
@@ -314,7 +382,47 @@ class CSSGenerator {
314
382
  'ease-out': 'ease-out',
315
383
  'ease-in-out': 'ease-in-out',
316
384
  'linéaire': 'linear',
317
- 'lineaire': 'linear'
385
+ 'lineaire': 'linear',
386
+ 'infini': 'infinite',
387
+ 'alternatif': 'alternate',
388
+ 'inverse': 'reverse',
389
+ 'alternatif inverse': 'alternate-reverse',
390
+ 'en avant': 'forwards',
391
+ 'en arriere': 'backwards',
392
+ 'les deux': 'both',
393
+ 'en pause': 'paused',
394
+ 'en cours': 'running',
395
+ 'ombre': 'box-shadow',
396
+ 'transformation': 'transform',
397
+ 'fond': 'background',
398
+ 'couleur': 'color',
399
+ 'opacite': 'opacity',
400
+ 'opacité': 'opacity',
401
+ 'bordure': 'border',
402
+ 'largeur': 'width',
403
+ 'hauteur': 'height',
404
+ 'marge': 'margin',
405
+ 'remplissage': 'padding'
406
+ }
407
+
408
+ const filterFunctions = {
409
+ 'flou': 'blur',
410
+ 'luminosite': 'brightness',
411
+ 'luminosité': 'brightness',
412
+ 'contraste': 'contrast',
413
+ 'saturation': 'saturate',
414
+ 'niveaux de gris': 'grayscale',
415
+ 'niveaux-de-gris': 'grayscale',
416
+ 'sepia': 'sepia',
417
+ 'sépia': 'sepia',
418
+ 'inverser': 'invert',
419
+ 'teinte rotation': 'hue-rotate',
420
+ 'teinte-rotation': 'hue-rotate',
421
+ 'opacite': 'opacity',
422
+ 'opacité': 'opacity',
423
+ 'ombre portee': 'drop-shadow',
424
+ 'ombre-portee': 'drop-shadow',
425
+ 'ombre portée': 'drop-shadow'
318
426
  }
319
427
 
320
428
  let result = val
@@ -325,6 +433,11 @@ class CSSGenerator {
325
433
  return `__VAR_PLACEHOLDER_${varPlaceholders.length - 1}__`
326
434
  })
327
435
 
436
+ for (const [fr, en] of Object.entries(filterFunctions)) {
437
+ const regex = new RegExp(`${fr}\\s*\\(`, 'gi')
438
+ result = result.replace(regex, `${en}(`)
439
+ }
440
+
328
441
  for (const [fr, en] of Object.entries(keywords)) {
329
442
  const regex = new RegExp(`\\b${fr}\\b`, 'gi')
330
443
  result = result.replace(regex, en)
@@ -368,6 +481,16 @@ class CSSGenerator {
368
481
  'ombre-texte': 'text-shadow',
369
482
  'ombre texte': 'text-shadow',
370
483
  'marge': 'margin',
484
+ 'marge autour': 'margin',
485
+ 'marge-autour': 'margin',
486
+ 'marge autour haut': 'margin-top',
487
+ 'marge-autour-haut': 'margin-top',
488
+ 'marge autour bas': 'margin-bottom',
489
+ 'marge-autour-bas': 'margin-bottom',
490
+ 'marge autour gauche': 'margin-left',
491
+ 'marge-autour-gauche': 'margin-left',
492
+ 'marge autour droite': 'margin-right',
493
+ 'marge-autour-droite': 'margin-right',
371
494
  'marge haut': 'margin-top',
372
495
  'marge-haut': 'margin-top',
373
496
  'marge bas': 'margin-bottom',
@@ -378,6 +501,15 @@ class CSSGenerator {
378
501
  'marge-droite': 'margin-right',
379
502
  'marge dedans': 'padding',
380
503
  'marge-dedans': 'padding',
504
+ 'remplissage': 'padding',
505
+ 'remplissage haut': 'padding-top',
506
+ 'remplissage-haut': 'padding-top',
507
+ 'remplissage bas': 'padding-bottom',
508
+ 'remplissage-bas': 'padding-bottom',
509
+ 'remplissage gauche': 'padding-left',
510
+ 'remplissage-gauche': 'padding-left',
511
+ 'remplissage droite': 'padding-right',
512
+ 'remplissage-droite': 'padding-right',
381
513
  'marge dedans haut': 'padding-top',
382
514
  'marge-dedans-haut': 'padding-top',
383
515
  'marge dedans bas': 'padding-bottom',
@@ -397,6 +529,8 @@ class CSSGenerator {
397
529
  'bordure-droite': 'border-right',
398
530
  'couleur-bordure': 'border-color',
399
531
  'couleur bordure': 'border-color',
532
+ 'bordure couleur': 'border-color',
533
+ 'bordure-couleur': 'border-color',
400
534
  'arrondi': 'border-radius',
401
535
  'largeur': 'width',
402
536
  'hauteur': 'height',
@@ -428,6 +562,13 @@ class CSSGenerator {
428
562
  'transition': 'transition',
429
563
  'animation': 'animation',
430
564
  'transformation': 'transform',
565
+ 'origine transformation': 'transform-origin',
566
+ 'origine-transformation': 'transform-origin',
567
+ 'style transformation': 'transform-style',
568
+ 'style-transformation': 'transform-style',
569
+ 'perspective': 'perspective',
570
+ 'origine perspective': 'perspective-origin',
571
+ 'origine-perspective': 'perspective-origin',
431
572
  'filtre': 'filter',
432
573
  'filtre-fond': 'backdrop-filter',
433
574
  'filtre fond': 'backdrop-filter',
@@ -5,6 +5,9 @@ class HTMLGenerator {
5
5
  this.i18n = null
6
6
  this.indent = 0
7
7
  this.output = ''
8
+ this.tagMap = {}
9
+ this.attrMap = {}
10
+ this.eventMap = {}
8
11
  this.voidElements = [
9
12
  'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',
10
13
  'link', 'meta', 'param', 'source', 'track', 'wbr'
@@ -239,6 +242,7 @@ class HTMLGenerator {
239
242
  'source': 'src',
240
243
  'alt': 'alt',
241
244
  'alternatif': 'alt',
245
+ 'texte alternatif': 'alt',
242
246
  'largeur': 'width',
243
247
  'hauteur': 'height',
244
248
  'chargement': 'loading',
@@ -247,7 +251,10 @@ class HTMLGenerator {
247
251
  'methode': 'method',
248
252
  'type': 'type',
249
253
  'nom': 'name',
254
+ 'contenu': 'content',
250
255
  'valeur': 'value',
256
+ 'valeur min': 'min',
257
+ 'valeur max': 'max',
251
258
  'placeholder': 'placeholder',
252
259
  'indicateur': 'placeholder',
253
260
  'requis': 'required',
@@ -278,6 +285,7 @@ class HTMLGenerator {
278
285
  'fusion colonnes': 'colspan',
279
286
  'portee': 'scope',
280
287
  'pour': 'for',
288
+ 'etiquette': 'label',
281
289
  'accept': 'accept',
282
290
  'accepter': 'accept',
283
291
  'enctype': 'enctype',
@@ -672,4 +680,4 @@ class HTMLGenerator {
672
680
 
673
681
  module.exports = {
674
682
  HTMLGenerator
675
- }
683
+ }
@@ -274,10 +274,18 @@ class EtherLexer {
274
274
  this.advance()
275
275
  }
276
276
 
277
- if (this.isAtEnd() || this.peek() === '\n' || this.peek() === '#') {
277
+ if (this.isAtEnd() || this.peek() === '\n') {
278
278
  this.atLineStart = false
279
279
  return
280
280
  }
281
+
282
+ if (this.peek() === '#') {
283
+ const next = this.peek(1)
284
+ if (!next || (!this.isAlpha(next) && !this.isHexDigit(next))) {
285
+ this.atLineStart = false
286
+ return
287
+ }
288
+ }
281
289
 
282
290
  if (this.peek() === '/' && this.peek(1) === '/') {
283
291
  this.atLineStart = false
@@ -551,13 +559,16 @@ class EtherLexer {
551
559
  }
552
560
 
553
561
  if (this.peek() === 'e' || this.peek() === 'E') {
554
- type = TokenType.FLOAT
555
- value += this.advance()
556
- if (this.peek() === '+' || this.peek() === '-') {
557
- value += this.advance()
558
- }
559
- while (this.isDigit(this.peek())) {
562
+ const nextChar = this.peek(1)
563
+ if (this.isDigit(nextChar) || nextChar === '+' || nextChar === '-') {
564
+ type = TokenType.FLOAT
560
565
  value += this.advance()
566
+ if (this.peek() === '+' || this.peek() === '-') {
567
+ value += this.advance()
568
+ }
569
+ while (this.isDigit(this.peek())) {
570
+ value += this.advance()
571
+ }
561
572
  }
562
573
  }
563
574
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ether-code",
3
- "version": "0.4.9",
3
+ "version": "0.5.1",
4
4
  "description": "Ether - Le langage intentionnel",
5
5
  "main": "cli/compiler.js",
6
6
  "bin": {