ether-code 0.6.2 → 0.6.4

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/compiler.js CHANGED
@@ -70,20 +70,52 @@ class EtherCompiler {
70
70
  this.parser = null
71
71
  this.resolvedIncludes = new Set()
72
72
 
73
- this.initGenerators()
74
73
  this.initParser()
74
+ this.initGenerators()
75
75
  }
76
76
 
77
77
  initGenerators() {
78
78
  const i18nDir = path.join(__dirname, '..', 'i18n')
79
79
 
80
+ const jsI18n = path.join(i18nDir, 'i18n-js.json')
81
+ if (fs.existsSync(jsI18n)) {
82
+ this.generators['js'] = new JSGenerator(jsI18n)
83
+ } else {
84
+ this.generators['js'] = new JSGenerator()
85
+ }
86
+ this.generators['javascript'] = this.generators['js']
87
+
88
+ const cssI18n = path.join(i18nDir, 'i18n-css.json')
89
+ if (fs.existsSync(cssI18n)) {
90
+ this.generators['css'] = new CSSGenerator(cssI18n)
91
+ } else {
92
+ this.generators['css'] = new CSSGenerator()
93
+ }
94
+
80
95
  for (const [target, GeneratorClass] of Object.entries(GENERATORS)) {
96
+ if (target === 'js' || target === 'javascript' || target === 'css') {
97
+ continue
98
+ }
99
+
81
100
  const i18nFile = path.join(i18nDir, `i18n-${this.normalizeTarget(target)}.json`)
82
101
 
83
- if (fs.existsSync(i18nFile)) {
84
- this.generators[target] = new GeneratorClass(i18nFile)
102
+ if (target === 'html') {
103
+ const options = {
104
+ parser: this.parser,
105
+ jsGenerator: this.generators['js'],
106
+ cssGenerator: this.generators['css']
107
+ }
108
+ if (fs.existsSync(i18nFile)) {
109
+ this.generators[target] = new GeneratorClass(i18nFile, options)
110
+ } else {
111
+ this.generators[target] = new GeneratorClass(null, options)
112
+ }
85
113
  } else {
86
- this.generators[target] = new GeneratorClass()
114
+ if (fs.existsSync(i18nFile)) {
115
+ this.generators[target] = new GeneratorClass(i18nFile)
116
+ } else {
117
+ this.generators[target] = new GeneratorClass()
118
+ }
87
119
  }
88
120
  }
89
121
  }
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.6.2'
9
+ const VERSION = '0.6.4'
10
10
 
11
11
  const COLORS = {
12
12
  reset: '\x1b[0m',
package/ether-parser.js CHANGED
@@ -281,7 +281,7 @@ class EtherParser {
281
281
  expect(type) {
282
282
  const token = this.current()
283
283
  if (!token || token.type !== type) {
284
- throw new Error(`Attendu ${type}, reçu ${token ? token.type : 'EOF'}`)
284
+ throw new Error(`Attendu ${type}, reçu ${token ? token.type : 'EOF'}`)
285
285
  }
286
286
  return this.advance()
287
287
  }
@@ -1177,7 +1177,7 @@ class EtherParser {
1177
1177
 
1178
1178
  parseHTMLElement() {
1179
1179
  const tagToken = this.current()
1180
- let tagName = tagToken.value.toLowerCase()
1180
+ let tagName = this.normalizeAccents(tagToken.value)
1181
1181
  this.advance()
1182
1182
 
1183
1183
  const includeKeywords = ['inclure', 'requiert', 'include', 'require', 'importer']
@@ -1228,14 +1228,14 @@ class EtherParser {
1228
1228
 
1229
1229
  if ((tagName === 'liste' || tagName === 'list') && nextToken) {
1230
1230
  if (nextToken.type === TokenType.IDENTIFIER) {
1231
- const nextVal = nextToken.value.toLowerCase()
1231
+ const nextVal = this.normalizeAccents(nextToken.value)
1232
1232
  if (nextVal === 'ordonnee' || nextVal === 'ordered') {
1233
1233
  tagName = 'liste ordonnee'
1234
1234
  this.advance()
1235
1235
  } else if (nextVal === 'non') {
1236
1236
  this.advance()
1237
1237
  const thirdToken = this.current()
1238
- if (thirdToken && thirdToken.type === TokenType.IDENTIFIER && thirdToken.value.toLowerCase() === 'ordonnee') {
1238
+ if (thirdToken && thirdToken.type === TokenType.IDENTIFIER && this.normalizeAccents(thirdToken.value) === 'ordonnee') {
1239
1239
  tagName = 'liste non ordonnee'
1240
1240
  this.advance()
1241
1241
  }
@@ -1244,42 +1244,42 @@ class EtherParser {
1244
1244
  }
1245
1245
 
1246
1246
  if ((tagName === 'element' || tagName === 'item') && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1247
- if (nextToken.value.toLowerCase() === 'liste' || nextToken.value.toLowerCase() === 'list') {
1247
+ if (this.normalizeAccents(nextToken.value) === 'liste' || this.normalizeAccents(nextToken.value) === 'list') {
1248
1248
  tagName = 'element liste'
1249
1249
  this.advance()
1250
1250
  }
1251
1251
  }
1252
1252
 
1253
1253
  if ((tagName === 'zone' || tagName === 'area') && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1254
- if (nextToken.value.toLowerCase() === 'texte' || nextToken.value.toLowerCase() === 'text') {
1254
+ if (this.normalizeAccents(nextToken.value) === 'texte' || this.normalizeAccents(nextToken.value) === 'text') {
1255
1255
  tagName = 'zone texte'
1256
1256
  this.advance()
1257
1257
  }
1258
1258
  }
1259
1259
 
1260
1260
  if ((tagName === 'retour' || tagName === 'saut') && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1261
- if (nextToken.value.toLowerCase() === 'ligne' || nextToken.value.toLowerCase() === 'line') {
1261
+ if (this.normalizeAccents(nextToken.value) === 'ligne' || this.normalizeAccents(nextToken.value) === 'line') {
1262
1262
  tagName = 'retour ligne'
1263
1263
  this.advance()
1264
1264
  }
1265
1265
  }
1266
1266
 
1267
1267
  if (tagName === 'ligne' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1268
- if (nextToken.value.toLowerCase() === 'horizontale') {
1268
+ if (this.normalizeAccents(nextToken.value) === 'horizontale') {
1269
1269
  tagName = 'ligne horizontale'
1270
1270
  this.advance()
1271
1271
  }
1272
1272
  }
1273
1273
 
1274
1274
  if ((tagName === 'cellule' || tagName === 'cell') && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1275
- if (nextToken.value.toLowerCase() === 'entete' || nextToken.value.toLowerCase() === 'header') {
1275
+ if (this.normalizeAccents(nextToken.value) === 'entete' || this.normalizeAccents(nextToken.value) === 'header') {
1276
1276
  tagName = 'entete cellule'
1277
1277
  this.advance()
1278
1278
  }
1279
1279
  }
1280
1280
 
1281
1281
  if (tagName === 'groupe' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1282
- const next = nextToken.value.toLowerCase()
1282
+ const next = this.normalizeAccents(nextToken.value)
1283
1283
  if (next === 'titres') {
1284
1284
  tagName = 'groupe titres'
1285
1285
  this.advance()
@@ -1293,7 +1293,7 @@ class EtherParser {
1293
1293
  }
1294
1294
 
1295
1295
  if (tagName === 'entete' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1296
- const next = nextToken.value.toLowerCase()
1296
+ const next = this.normalizeAccents(nextToken.value)
1297
1297
  if (next === 'tableau' || next === 'table') {
1298
1298
  tagName = 'entete tableau'
1299
1299
  this.advance()
@@ -1301,7 +1301,7 @@ class EtherParser {
1301
1301
  }
1302
1302
 
1303
1303
  if (tagName === 'corps' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1304
- const next = nextToken.value.toLowerCase()
1304
+ const next = this.normalizeAccents(nextToken.value)
1305
1305
  if (next === 'tableau' || next === 'table') {
1306
1306
  tagName = 'corps tableau'
1307
1307
  this.advance()
@@ -1309,7 +1309,7 @@ class EtherParser {
1309
1309
  }
1310
1310
 
1311
1311
  if (tagName === 'pied' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1312
- const next = nextToken.value.toLowerCase()
1312
+ const next = this.normalizeAccents(nextToken.value)
1313
1313
  if (next === 'tableau' || next === 'table') {
1314
1314
  tagName = 'pied tableau'
1315
1315
  this.advance()
@@ -1317,7 +1317,7 @@ class EtherParser {
1317
1317
  }
1318
1318
 
1319
1319
  if (tagName === 'legende' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1320
- const next = nextToken.value.toLowerCase()
1320
+ const next = this.normalizeAccents(nextToken.value)
1321
1321
  if (next === 'tableau' || next === 'table') {
1322
1322
  tagName = 'legende tableau'
1323
1323
  this.advance()
@@ -1328,7 +1328,7 @@ class EtherParser {
1328
1328
  }
1329
1329
 
1330
1330
  if (tagName === 'ensemble' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1331
- const next = nextToken.value.toLowerCase()
1331
+ const next = this.normalizeAccents(nextToken.value)
1332
1332
  if (next === 'champs' || next === 'fields') {
1333
1333
  tagName = 'ensemble champs'
1334
1334
  this.advance()
@@ -1336,7 +1336,7 @@ class EtherParser {
1336
1336
  }
1337
1337
 
1338
1338
  if (tagName === 'liste' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1339
- const next = nextToken.value.toLowerCase()
1339
+ const next = this.normalizeAccents(nextToken.value)
1340
1340
  if (next === 'donnees' || next === 'data') {
1341
1341
  tagName = 'liste donnees'
1342
1342
  this.advance()
@@ -1347,7 +1347,7 @@ class EtherParser {
1347
1347
  }
1348
1348
 
1349
1349
  if (tagName === 'image' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1350
- const next = nextToken.value.toLowerCase()
1350
+ const next = this.normalizeAccents(nextToken.value)
1351
1351
  if (next === 'reactive' || next === 'responsive') {
1352
1352
  tagName = 'image reactive'
1353
1353
  this.advance()
@@ -1355,7 +1355,7 @@ class EtherParser {
1355
1355
  }
1356
1356
 
1357
1357
  if (tagName === 'cadre' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1358
- const next = nextToken.value.toLowerCase()
1358
+ const next = this.normalizeAccents(nextToken.value)
1359
1359
  if (next === 'en') {
1360
1360
  this.advance()
1361
1361
  const thirdToken = this.current()
@@ -1367,7 +1367,7 @@ class EtherParser {
1367
1367
  }
1368
1368
 
1369
1369
  if (tagName === 'citation' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1370
- const next = nextToken.value.toLowerCase()
1370
+ const next = this.normalizeAccents(nextToken.value)
1371
1371
  if (next === 'bloc' || next === 'block') {
1372
1372
  tagName = 'citation bloc'
1373
1373
  this.advance()
@@ -1375,7 +1375,7 @@ class EtherParser {
1375
1375
  }
1376
1376
 
1377
1377
  if (tagName === 'reference' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1378
- const next = nextToken.value.toLowerCase()
1378
+ const next = this.normalizeAccents(nextToken.value)
1379
1379
  if (next === 'citation') {
1380
1380
  tagName = 'reference citation'
1381
1381
  this.advance()
@@ -1383,15 +1383,55 @@ class EtherParser {
1383
1383
  }
1384
1384
 
1385
1385
  if (tagName === 'sans' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1386
- const next = nextToken.value.toLowerCase()
1386
+ const next = this.normalizeAccents(nextToken.value)
1387
1387
  if (next === 'script') {
1388
1388
  tagName = 'sans script'
1389
1389
  this.advance()
1390
1390
  }
1391
1391
  }
1392
1392
 
1393
+ if (tagName === 'isolation' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1394
+ const next = this.normalizeAccents(nextToken.value)
1395
+ if (next === 'bidi') {
1396
+ tagName = 'isolation bidi'
1397
+ this.advance()
1398
+ }
1399
+ }
1400
+
1401
+ if (tagName === 'remplacement' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1402
+ const next = this.normalizeAccents(nextToken.value)
1403
+ if (next === 'bidi') {
1404
+ tagName = 'remplacement bidi'
1405
+ this.advance()
1406
+ }
1407
+ }
1408
+
1409
+ if (tagName === 'annotation' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1410
+ const next = this.normalizeAccents(nextToken.value)
1411
+ if (next === 'ruby' || next === 'rubis') {
1412
+ tagName = 'annotation ruby'
1413
+ this.advance()
1414
+ }
1415
+ }
1416
+
1417
+ if ((tagName === 'parentheses' || tagName === 'parenthèses') && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1418
+ const next = this.normalizeAccents(nextToken.value)
1419
+ if (next === 'ruby' || next === 'rubis') {
1420
+ tagName = 'parentheses ruby'
1421
+ this.advance()
1422
+ }
1423
+ }
1424
+
1425
+ if (tagName === 'carte' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1426
+ const next = this.normalizeAccents(nextToken.value)
1427
+ if (next === 'image') {
1428
+ tagName = 'carte image'
1429
+ this.advance()
1430
+ }
1431
+ }
1432
+
1393
1433
  if ((tagName === 'texte' || tagName === 'text') && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1394
- const next = nextToken.value.toLowerCase()
1434
+ const next = this.normalizeAccents(nextToken.value)
1395
1435
  if (next === 'alternatif' || next === 'alt') {
1396
1436
  tagName = 'texte alternatif'
1397
1437
  this.advance()
@@ -1399,7 +1439,7 @@ class EtherParser {
1399
1439
  }
1400
1440
 
1401
1441
  if (tagName === 'entree' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1402
- const next = nextToken.value.toLowerCase()
1442
+ const next = this.normalizeAccents(nextToken.value)
1403
1443
  if (next === 'clavier') {
1404
1444
  tagName = 'entree clavier'
1405
1445
  this.advance()
@@ -1407,7 +1447,7 @@ class EtherParser {
1407
1447
  }
1408
1448
 
1409
1449
  if (tagName === 'sortie' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1410
- const next = nextToken.value.toLowerCase()
1450
+ const next = this.normalizeAccents(nextToken.value)
1411
1451
  if (next === 'exemple') {
1412
1452
  tagName = 'sortie exemple'
1413
1453
  this.advance()
@@ -1415,7 +1455,7 @@ class EtherParser {
1415
1455
  }
1416
1456
 
1417
1457
  if (tagName === 'definition' && nextToken && nextToken.type === TokenType.IDENTIFIER) {
1418
- const next = nextToken.value.toLowerCase()
1458
+ const next = this.normalizeAccents(nextToken.value)
1419
1459
  if (next === 'description') {
1420
1460
  tagName = 'definition description'
1421
1461
  this.advance()
@@ -1440,9 +1480,17 @@ class EtherParser {
1440
1480
  'encodage': ['formulaire'],
1441
1481
  'validation': ['formulaire', 'auto'],
1442
1482
  'cible': ['formulaire', 'popover'],
1443
- 'lecture': ['seule'],
1483
+ 'lecture': ['seule', 'auto'],
1444
1484
  'nouvelle': ['fenetre'],
1445
- 'a': ['popup']
1485
+ 'a': ['popup'],
1486
+ 'jeu': ['caracteres', 'caractères'],
1487
+ 'equivalent': ['http'],
1488
+ 'équivalent': ['http'],
1489
+ 'fusion': ['colonnes', 'lignes'],
1490
+ 'plein': ['ecran', 'écran'],
1491
+ 'bac': ['sable'],
1492
+ 'origine': ['croisee', 'croisée'],
1493
+ 'sources': ['reactives', 'réactives']
1446
1494
  }
1447
1495
 
1448
1496
  while (!this.isAtEnd()) {
@@ -1517,21 +1565,251 @@ class EtherParser {
1517
1565
  })
1518
1566
  }
1519
1567
 
1568
+ const rawContentTags = ['script', 'style']
1569
+ const isRawContent = rawContentTags.includes(tag)
1570
+ const isScript = tag === 'script'
1571
+
1520
1572
  if (this.match(TokenType.INDENT)) {
1521
- while (!this.isAtEnd()) {
1522
- const current = this.current()
1523
-
1524
- if (current && current.type === TokenType.DEDENT) {
1525
- this.advance()
1526
- break
1573
+ if (isRawContent) {
1574
+ let rawText = []
1575
+ while (!this.isAtEnd()) {
1576
+ const current = this.current()
1577
+
1578
+ if (current && current.type === TokenType.DEDENT) {
1579
+ this.advance()
1580
+ break
1581
+ }
1582
+
1583
+ if (current && current.type === TokenType.NEWLINE) {
1584
+ rawText.push('\n')
1585
+ this.advance()
1586
+ continue
1587
+ }
1588
+
1589
+ if (current && current.type === TokenType.INDENT) {
1590
+ this.advance()
1591
+ continue
1592
+ }
1593
+
1594
+ if (current && current.type === TokenType.STRING) {
1595
+ if (isScript) {
1596
+ rawText.push("'" + current.value.replace(/'/g, "\\'") + "'")
1597
+ } else {
1598
+ rawText.push(current.value)
1599
+ }
1600
+ this.advance()
1601
+ continue
1602
+ }
1603
+
1604
+ if (current && current.type === TokenType.LPAREN) {
1605
+ rawText.push('(')
1606
+ this.advance()
1607
+ continue
1608
+ }
1609
+
1610
+ if (current && current.type === TokenType.RPAREN) {
1611
+ rawText.push(')')
1612
+ this.advance()
1613
+ continue
1614
+ }
1615
+
1616
+ if (current && current.type === TokenType.LBRACKET) {
1617
+ rawText.push('[')
1618
+ this.advance()
1619
+ continue
1620
+ }
1621
+
1622
+ if (current && current.type === TokenType.RBRACKET) {
1623
+ rawText.push(']')
1624
+ this.advance()
1625
+ continue
1626
+ }
1627
+
1628
+ if (current && current.type === TokenType.LBRACE) {
1629
+ rawText.push('{')
1630
+ this.advance()
1631
+ continue
1632
+ }
1633
+
1634
+ if (current && current.type === TokenType.RBRACE) {
1635
+ rawText.push('}')
1636
+ this.advance()
1637
+ continue
1638
+ }
1639
+
1640
+ if (current && current.type === TokenType.DOT) {
1641
+ rawText.push('.')
1642
+ this.advance()
1643
+ continue
1644
+ }
1645
+
1646
+ if (current && current.type === TokenType.COMMA) {
1647
+ rawText.push(',')
1648
+ this.advance()
1649
+ continue
1650
+ }
1651
+
1652
+ if (current && current.type === TokenType.COLON) {
1653
+ rawText.push(':')
1654
+ this.advance()
1655
+ continue
1656
+ }
1657
+
1658
+ if (current && current.type === TokenType.EQUALS) {
1659
+ rawText.push('=')
1660
+ this.advance()
1661
+ continue
1662
+ }
1663
+
1664
+ if (current && current.type === TokenType.DOUBLE_EQUALS) {
1665
+ rawText.push('==')
1666
+ this.advance()
1667
+ continue
1668
+ }
1669
+
1670
+ if (current && current.type === TokenType.NOT_EQUALS) {
1671
+ rawText.push('!=')
1672
+ this.advance()
1673
+ continue
1674
+ }
1675
+
1676
+ if (current && current.type === TokenType.BANG) {
1677
+ rawText.push('!')
1678
+ this.advance()
1679
+ continue
1680
+ }
1681
+
1682
+ if (current && current.type === TokenType.PLUS) {
1683
+ rawText.push(current.value)
1684
+ this.advance()
1685
+ continue
1686
+ }
1687
+
1688
+ if (current && current.type === TokenType.MINUS) {
1689
+ rawText.push(current.value)
1690
+ this.advance()
1691
+ continue
1692
+ }
1693
+
1694
+ if (current && current.type === TokenType.STAR) {
1695
+ rawText.push(current.value)
1696
+ this.advance()
1697
+ continue
1698
+ }
1699
+
1700
+ if (current && current.type === TokenType.SLASH) {
1701
+ rawText.push('/')
1702
+ this.advance()
1703
+ continue
1704
+ }
1705
+
1706
+ if (current && current.type === TokenType.PERCENT) {
1707
+ rawText.push('%')
1708
+ this.advance()
1709
+ continue
1710
+ }
1711
+
1712
+ if (current && current.type === TokenType.AMPERSAND) {
1713
+ rawText.push('&')
1714
+ this.advance()
1715
+ continue
1716
+ }
1717
+
1718
+ if (current && current.type === TokenType.DOUBLE_AMPERSAND) {
1719
+ rawText.push('&&')
1720
+ this.advance()
1721
+ continue
1722
+ }
1723
+
1724
+ if (current && current.type === TokenType.PIPE) {
1725
+ rawText.push('|')
1726
+ this.advance()
1727
+ continue
1728
+ }
1729
+
1730
+ if (current && current.type === TokenType.DOUBLE_PIPE) {
1731
+ rawText.push('||')
1732
+ this.advance()
1733
+ continue
1734
+ }
1735
+
1736
+ if (current && current.type === TokenType.LT) {
1737
+ rawText.push('<')
1738
+ this.advance()
1739
+ continue
1740
+ }
1741
+
1742
+ if (current && current.type === TokenType.GT) {
1743
+ rawText.push('>')
1744
+ this.advance()
1745
+ continue
1746
+ }
1747
+
1748
+ if (current && current.type === TokenType.LTE) {
1749
+ rawText.push('<=')
1750
+ this.advance()
1751
+ continue
1752
+ }
1753
+
1754
+ if (current && current.type === TokenType.GTE) {
1755
+ rawText.push('>=')
1756
+ this.advance()
1757
+ continue
1758
+ }
1759
+
1760
+ if (current && current.type === TokenType.QUESTION) {
1761
+ rawText.push('?')
1762
+ this.advance()
1763
+ continue
1764
+ }
1765
+
1766
+ if (current && current.type === TokenType.FAT_ARROW) {
1767
+ rawText.push('=>')
1768
+ this.advance()
1769
+ continue
1770
+ }
1771
+
1772
+ if (current && current.type === TokenType.ARROW) {
1773
+ rawText.push('->')
1774
+ this.advance()
1775
+ continue
1776
+ }
1777
+
1778
+ if (current && current.type === TokenType.SEMICOLON) {
1779
+ rawText.push(';')
1780
+ this.advance()
1781
+ continue
1782
+ }
1783
+
1784
+ if (current) {
1785
+ rawText.push(String(current.value))
1786
+ this.advance()
1787
+ }
1527
1788
  }
1528
1789
 
1529
- const child = this.parseHTMLNode()
1530
- if (child) {
1531
- children.push(child)
1790
+ const textContent = rawText.join('').trim()
1791
+ if (textContent) {
1792
+ children.push({
1793
+ type: 'Text',
1794
+ content: textContent
1795
+ })
1796
+ }
1797
+ } else {
1798
+ while (!this.isAtEnd()) {
1799
+ const current = this.current()
1800
+
1801
+ if (current && current.type === TokenType.DEDENT) {
1802
+ this.advance()
1803
+ break
1804
+ }
1805
+
1806
+ const child = this.parseHTMLNode()
1807
+ if (child) {
1808
+ children.push(child)
1809
+ }
1810
+
1811
+ this.skipNewlines()
1532
1812
  }
1533
-
1534
- this.skipNewlines()
1535
1813
  }
1536
1814
  }
1537
1815
 
@@ -1545,7 +1823,7 @@ class EtherParser {
1545
1823
 
1546
1824
  translateHTMLTag(tag) {
1547
1825
  const map = this.reverseMaps.html || {}
1548
- const lower = tag.toLowerCase()
1826
+ const lower = this.normalizeAccents(tag)
1549
1827
  const withSpaces = lower.replace(/-/g, ' ')
1550
1828
 
1551
1829
  const translations = {
@@ -1716,11 +1994,26 @@ class EtherParser {
1716
1994
  'cesure': 'wbr',
1717
1995
  'noscript': 'noscript',
1718
1996
  'sans script': 'noscript',
1997
+ 'isolation bidi': 'bdi',
1998
+ 'remplacement bidi': 'bdo',
1999
+ 'annotation ruby': 'rt',
2000
+ 'annotation rubis': 'rt',
2001
+ 'parentheses ruby': 'rp',
2002
+ 'parenthèses ruby': 'rp',
2003
+ 'parentheses rubis': 'rp',
2004
+ 'terme': 'dt',
2005
+ 'menu': 'menu',
2006
+ 'recherche': 'search',
2007
+ 'objet': 'object',
2008
+ 'integrer': 'embed',
2009
+ 'svg': 'svg',
2010
+ 'math': 'math',
1719
2011
 
1720
2012
  'zone': 'area'
1721
2013
  }
1722
2014
 
1723
- return translations[lower] || translations[withSpaces] || map[lower] || map[withSpaces] || tag
2015
+ const result = translations[lower] || translations[withSpaces] || map[lower] || map[withSpaces] || tag
2016
+ return result.replace(/^<!DOCTYPE\s+/i, '').replace(/^<|>$/g, '').trim() || 'div'
1724
2017
  }
1725
2018
 
1726
2019
  parseJS() {