ether-code 0.6.3 → 0.6.5
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 +36 -4
- package/cli/ether.js +1 -1
- package/ether-parser.js +273 -34
- package/generators/html-generator.js +105 -9
- package/package.json +1 -1
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 (
|
|
84
|
-
|
|
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
|
-
|
|
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
package/ether-parser.js
CHANGED
|
@@ -17,16 +17,16 @@ class EtherParser {
|
|
|
17
17
|
initCompoundTerms() {
|
|
18
18
|
this.compoundOperators = {
|
|
19
19
|
'strictement egal': '===',
|
|
20
|
-
'strictement
|
|
20
|
+
'strictement égal': '===',
|
|
21
21
|
'strictement different': '!==',
|
|
22
|
-
'strictement
|
|
22
|
+
'strictement différent': '!==',
|
|
23
23
|
'superieur ou egal': '>=',
|
|
24
|
-
'
|
|
24
|
+
'supérieur ou égal': '>=',
|
|
25
25
|
'inferieur ou egal': '<=',
|
|
26
|
-
'
|
|
26
|
+
'inférieur ou égal': '<=',
|
|
27
27
|
'coalescence nulle': '??',
|
|
28
28
|
'chainage optionnel': '?.',
|
|
29
|
-
'
|
|
29
|
+
'chaînage optionnel': '?.'
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
this.compoundKeywords = {
|
|
@@ -36,7 +36,7 @@ class EtherParser {
|
|
|
36
36
|
'fonction asynchrone': 'async function',
|
|
37
37
|
'fonction async': 'async function',
|
|
38
38
|
'fonction generatrice': 'function*',
|
|
39
|
-
'fonction
|
|
39
|
+
'fonction génératrice': 'function*',
|
|
40
40
|
'variable globale': 'var'
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -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},
|
|
284
|
+
throw new Error(`Attendu ${type}, reçu ${token ? token.type : 'EOF'}`)
|
|
285
285
|
}
|
|
286
286
|
return this.advance()
|
|
287
287
|
}
|
|
@@ -695,7 +695,7 @@ class EtherParser {
|
|
|
695
695
|
'alignement': ['texte'],
|
|
696
696
|
'decoration': ['texte'],
|
|
697
697
|
'transformation': ['texte'],
|
|
698
|
-
'ombre': ['texte', 'boite', '
|
|
698
|
+
'ombre': ['texte', 'boite', 'boîte'],
|
|
699
699
|
'espacement': ['lettres'],
|
|
700
700
|
'bordure': ['haut', 'bas', 'gauche', 'droite', 'couleur', 'style', 'largeur', 'arrondi'],
|
|
701
701
|
'couleur': ['bordure', 'fond', 'texte', 'remplissage'],
|
|
@@ -706,19 +706,19 @@ class EtherParser {
|
|
|
706
706
|
'direction': ['flex'],
|
|
707
707
|
'enveloppe': ['flex'],
|
|
708
708
|
'justifier': ['contenu'],
|
|
709
|
-
'aligner': ['elements', '
|
|
709
|
+
'aligner': ['elements', 'éléments', 'contenu'],
|
|
710
710
|
'colonnes': ['grille'],
|
|
711
711
|
'lignes': ['grille'],
|
|
712
712
|
'espace': ['ligne', 'colonne', 'blanc'],
|
|
713
|
-
'
|
|
713
|
+
'débordement': ['x', 'y'],
|
|
714
714
|
'debordement': ['x', 'y'],
|
|
715
|
-
'
|
|
715
|
+
'événements': ['pointeur'],
|
|
716
716
|
'evenements': ['pointeur'],
|
|
717
|
-
'
|
|
718
|
-
'modele': ['boite', '
|
|
717
|
+
'modèle': ['boite', 'boîte'],
|
|
718
|
+
'modele': ['boite', 'boîte'],
|
|
719
719
|
'filtre': ['fond'],
|
|
720
720
|
'decoupe': ['fond'],
|
|
721
|
-
'
|
|
721
|
+
'découpe': ['fond'],
|
|
722
722
|
'origine': ['transformation', 'perspective'],
|
|
723
723
|
'liste': ['style', 'type', 'position', 'image'],
|
|
724
724
|
}
|
|
@@ -1178,6 +1178,7 @@ class EtherParser {
|
|
|
1178
1178
|
parseHTMLElement() {
|
|
1179
1179
|
const tagToken = this.current()
|
|
1180
1180
|
let tagName = this.normalizeAccents(tagToken.value)
|
|
1181
|
+
const originalTagName = tagName
|
|
1181
1182
|
this.advance()
|
|
1182
1183
|
|
|
1183
1184
|
const includeKeywords = ['inclure', 'requiert', 'include', 'require', 'importer']
|
|
@@ -1565,21 +1566,258 @@ class EtherParser {
|
|
|
1565
1566
|
})
|
|
1566
1567
|
}
|
|
1567
1568
|
|
|
1569
|
+
const rawContentTags = ['script', 'style']
|
|
1570
|
+
const isRawContent = rawContentTags.includes(tag)
|
|
1571
|
+
const isScript = tag === 'script'
|
|
1572
|
+
|
|
1568
1573
|
if (this.match(TokenType.INDENT)) {
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1574
|
+
if (isRawContent) {
|
|
1575
|
+
let rawText = []
|
|
1576
|
+
while (!this.isAtEnd()) {
|
|
1577
|
+
const current = this.current()
|
|
1578
|
+
|
|
1579
|
+
if (current && current.type === TokenType.DEDENT) {
|
|
1580
|
+
this.advance()
|
|
1581
|
+
break
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
if (current && current.type === TokenType.NEWLINE) {
|
|
1585
|
+
rawText.push('\n')
|
|
1586
|
+
this.advance()
|
|
1587
|
+
continue
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
if (current && current.type === TokenType.INDENT) {
|
|
1591
|
+
this.advance()
|
|
1592
|
+
continue
|
|
1593
|
+
}
|
|
1594
|
+
|
|
1595
|
+
if (current && current.type === TokenType.STRING) {
|
|
1596
|
+
if (isScript) {
|
|
1597
|
+
rawText.push("'" + current.value.replace(/'/g, "\\'") + "'")
|
|
1598
|
+
} else {
|
|
1599
|
+
rawText.push(current.value)
|
|
1600
|
+
}
|
|
1601
|
+
this.advance()
|
|
1602
|
+
continue
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
if (current && current.type === TokenType.LPAREN) {
|
|
1606
|
+
rawText.push('(')
|
|
1607
|
+
this.advance()
|
|
1608
|
+
continue
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
if (current && current.type === TokenType.RPAREN) {
|
|
1612
|
+
rawText.push(')')
|
|
1613
|
+
this.advance()
|
|
1614
|
+
continue
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
if (current && current.type === TokenType.LBRACKET) {
|
|
1618
|
+
rawText.push('[')
|
|
1619
|
+
this.advance()
|
|
1620
|
+
continue
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1623
|
+
if (current && current.type === TokenType.RBRACKET) {
|
|
1624
|
+
rawText.push(']')
|
|
1625
|
+
this.advance()
|
|
1626
|
+
continue
|
|
1627
|
+
}
|
|
1628
|
+
|
|
1629
|
+
if (current && current.type === TokenType.LBRACE) {
|
|
1630
|
+
rawText.push('{')
|
|
1631
|
+
this.advance()
|
|
1632
|
+
continue
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1635
|
+
if (current && current.type === TokenType.RBRACE) {
|
|
1636
|
+
rawText.push('}')
|
|
1637
|
+
this.advance()
|
|
1638
|
+
continue
|
|
1639
|
+
}
|
|
1640
|
+
|
|
1641
|
+
if (current && current.type === TokenType.DOT) {
|
|
1642
|
+
rawText.push('.')
|
|
1643
|
+
this.advance()
|
|
1644
|
+
continue
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
if (current && current.type === TokenType.COMMA) {
|
|
1648
|
+
rawText.push(',')
|
|
1649
|
+
this.advance()
|
|
1650
|
+
continue
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
if (current && current.type === TokenType.COLON) {
|
|
1654
|
+
rawText.push(':')
|
|
1655
|
+
this.advance()
|
|
1656
|
+
continue
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
if (current && current.type === TokenType.EQUALS) {
|
|
1660
|
+
rawText.push('=')
|
|
1661
|
+
this.advance()
|
|
1662
|
+
continue
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
if (current && current.type === TokenType.DOUBLE_EQUALS) {
|
|
1666
|
+
rawText.push('==')
|
|
1667
|
+
this.advance()
|
|
1668
|
+
continue
|
|
1669
|
+
}
|
|
1670
|
+
|
|
1671
|
+
if (current && current.type === TokenType.NOT_EQUALS) {
|
|
1672
|
+
rawText.push('!=')
|
|
1673
|
+
this.advance()
|
|
1674
|
+
continue
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
if (current && current.type === TokenType.BANG) {
|
|
1678
|
+
rawText.push('!')
|
|
1679
|
+
this.advance()
|
|
1680
|
+
continue
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1683
|
+
if (current && current.type === TokenType.PLUS) {
|
|
1684
|
+
rawText.push(current.value)
|
|
1685
|
+
this.advance()
|
|
1686
|
+
continue
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1689
|
+
if (current && current.type === TokenType.MINUS) {
|
|
1690
|
+
rawText.push(current.value)
|
|
1691
|
+
this.advance()
|
|
1692
|
+
continue
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
if (current && current.type === TokenType.STAR) {
|
|
1696
|
+
rawText.push(current.value)
|
|
1697
|
+
this.advance()
|
|
1698
|
+
continue
|
|
1699
|
+
}
|
|
1700
|
+
|
|
1701
|
+
if (current && current.type === TokenType.SLASH) {
|
|
1702
|
+
rawText.push('/')
|
|
1703
|
+
this.advance()
|
|
1704
|
+
continue
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1707
|
+
if (current && current.type === TokenType.PERCENT) {
|
|
1708
|
+
rawText.push('%')
|
|
1709
|
+
this.advance()
|
|
1710
|
+
continue
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1713
|
+
if (current && current.type === TokenType.AMPERSAND) {
|
|
1714
|
+
rawText.push('&')
|
|
1715
|
+
this.advance()
|
|
1716
|
+
continue
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
if (current && current.type === TokenType.DOUBLE_AMPERSAND) {
|
|
1720
|
+
rawText.push('&&')
|
|
1721
|
+
this.advance()
|
|
1722
|
+
continue
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
if (current && current.type === TokenType.PIPE) {
|
|
1726
|
+
rawText.push('|')
|
|
1727
|
+
this.advance()
|
|
1728
|
+
continue
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1731
|
+
if (current && current.type === TokenType.DOUBLE_PIPE) {
|
|
1732
|
+
rawText.push('||')
|
|
1733
|
+
this.advance()
|
|
1734
|
+
continue
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
if (current && current.type === TokenType.LT) {
|
|
1738
|
+
rawText.push('<')
|
|
1739
|
+
this.advance()
|
|
1740
|
+
continue
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
if (current && current.type === TokenType.GT) {
|
|
1744
|
+
rawText.push('>')
|
|
1745
|
+
this.advance()
|
|
1746
|
+
continue
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
if (current && current.type === TokenType.LTE) {
|
|
1750
|
+
rawText.push('<=')
|
|
1751
|
+
this.advance()
|
|
1752
|
+
continue
|
|
1753
|
+
}
|
|
1754
|
+
|
|
1755
|
+
if (current && current.type === TokenType.GTE) {
|
|
1756
|
+
rawText.push('>=')
|
|
1757
|
+
this.advance()
|
|
1758
|
+
continue
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
if (current && current.type === TokenType.QUESTION) {
|
|
1762
|
+
rawText.push('?')
|
|
1763
|
+
this.advance()
|
|
1764
|
+
continue
|
|
1765
|
+
}
|
|
1766
|
+
|
|
1767
|
+
if (current && current.type === TokenType.FAT_ARROW) {
|
|
1768
|
+
rawText.push('=>')
|
|
1769
|
+
this.advance()
|
|
1770
|
+
continue
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1773
|
+
if (current && current.type === TokenType.ARROW) {
|
|
1774
|
+
rawText.push('->')
|
|
1775
|
+
this.advance()
|
|
1776
|
+
continue
|
|
1777
|
+
}
|
|
1778
|
+
|
|
1779
|
+
if (current && current.type === TokenType.SEMICOLON) {
|
|
1780
|
+
rawText.push(';')
|
|
1781
|
+
this.advance()
|
|
1782
|
+
continue
|
|
1783
|
+
}
|
|
1784
|
+
|
|
1785
|
+
if (current) {
|
|
1786
|
+
rawText.push(String(current.value))
|
|
1787
|
+
this.advance()
|
|
1788
|
+
}
|
|
1575
1789
|
}
|
|
1576
1790
|
|
|
1577
|
-
const
|
|
1578
|
-
if (
|
|
1579
|
-
children.push(
|
|
1791
|
+
const textContent = rawText.join('').trim()
|
|
1792
|
+
if (textContent) {
|
|
1793
|
+
children.push({
|
|
1794
|
+
type: 'Text',
|
|
1795
|
+
content: textContent
|
|
1796
|
+
})
|
|
1580
1797
|
}
|
|
1581
|
-
|
|
1582
|
-
this.
|
|
1798
|
+
} else {
|
|
1799
|
+
while (!this.isAtEnd()) {
|
|
1800
|
+
const current = this.current()
|
|
1801
|
+
|
|
1802
|
+
if (current && current.type === TokenType.DEDENT) {
|
|
1803
|
+
this.advance()
|
|
1804
|
+
break
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1807
|
+
const child = this.parseHTMLNode()
|
|
1808
|
+
if (child) {
|
|
1809
|
+
children.push(child)
|
|
1810
|
+
}
|
|
1811
|
+
|
|
1812
|
+
this.skipNewlines()
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1817
|
+
if (originalTagName === 'document') {
|
|
1818
|
+
return {
|
|
1819
|
+
type: 'Doctype',
|
|
1820
|
+
children: children
|
|
1583
1821
|
}
|
|
1584
1822
|
}
|
|
1585
1823
|
|
|
@@ -1782,7 +2020,8 @@ class EtherParser {
|
|
|
1782
2020
|
'zone': 'area'
|
|
1783
2021
|
}
|
|
1784
2022
|
|
|
1785
|
-
|
|
2023
|
+
const result = translations[lower] || translations[withSpaces] || map[lower] || map[withSpaces] || tag
|
|
2024
|
+
return result.replace(/^<!DOCTYPE\s+/i, '').replace(/^<|>$/g, '').trim() || 'div'
|
|
1786
2025
|
}
|
|
1787
2026
|
|
|
1788
2027
|
parseJS() {
|
|
@@ -2557,16 +2796,16 @@ class EtherParser {
|
|
|
2557
2796
|
let left = this.parseComparison(lang)
|
|
2558
2797
|
|
|
2559
2798
|
while (true) {
|
|
2560
|
-
if (this.matchValue('strictement egal') || this.matchValue('strictement
|
|
2799
|
+
if (this.matchValue('strictement egal') || this.matchValue('strictement égal')) {
|
|
2561
2800
|
const right = this.parseComparison(lang)
|
|
2562
2801
|
left = { type: 'BinaryExpression', operator: '===', left, right }
|
|
2563
|
-
} else if (this.matchValue('strictement different') || this.matchValue('strictement
|
|
2802
|
+
} else if (this.matchValue('strictement different') || this.matchValue('strictement différent')) {
|
|
2564
2803
|
const right = this.parseComparison(lang)
|
|
2565
2804
|
left = { type: 'BinaryExpression', operator: '!==', left, right }
|
|
2566
|
-
} else if (this.match(TokenType.DOUBLE_EQUALS) || this.matchValue('egal') || this.matchValue('egale') || this.matchValue('
|
|
2805
|
+
} else if (this.match(TokenType.DOUBLE_EQUALS) || this.matchValue('egal') || this.matchValue('egale') || this.matchValue('égal')) {
|
|
2567
2806
|
const right = this.parseComparison(lang)
|
|
2568
2807
|
left = { type: 'BinaryExpression', operator: '===', left, right }
|
|
2569
|
-
} else if (this.match(TokenType.NOT_EQUALS) || this.matchValue('different') || this.matchValue('
|
|
2808
|
+
} else if (this.match(TokenType.NOT_EQUALS) || this.matchValue('different') || this.matchValue('différent')) {
|
|
2570
2809
|
const right = this.parseComparison(lang)
|
|
2571
2810
|
left = { type: 'BinaryExpression', operator: '!==', left, right }
|
|
2572
2811
|
} else {
|
|
@@ -2581,16 +2820,16 @@ class EtherParser {
|
|
|
2581
2820
|
let left = this.parseAdditive(lang)
|
|
2582
2821
|
|
|
2583
2822
|
while (true) {
|
|
2584
|
-
if (this.matchValue('superieur ou egal') || this.matchValue('
|
|
2823
|
+
if (this.matchValue('superieur ou egal') || this.matchValue('supérieur ou égal') || this.match(TokenType.GTE)) {
|
|
2585
2824
|
const right = this.parseAdditive(lang)
|
|
2586
2825
|
left = { type: 'BinaryExpression', operator: '>=', left, right }
|
|
2587
|
-
} else if (this.matchValue('inferieur ou egal') || this.matchValue('
|
|
2826
|
+
} else if (this.matchValue('inferieur ou egal') || this.matchValue('inférieur ou égal') || this.match(TokenType.LTE)) {
|
|
2588
2827
|
const right = this.parseAdditive(lang)
|
|
2589
2828
|
left = { type: 'BinaryExpression', operator: '<=', left, right }
|
|
2590
|
-
} else if (this.match(TokenType.LT) || this.matchValue('inferieur') || this.matchValue('
|
|
2829
|
+
} else if (this.match(TokenType.LT) || this.matchValue('inferieur') || this.matchValue('inférieur')) {
|
|
2591
2830
|
const right = this.parseAdditive(lang)
|
|
2592
2831
|
left = { type: 'BinaryExpression', operator: '<', left, right }
|
|
2593
|
-
} else if (this.match(TokenType.GT) || this.matchValue('superieur') || this.matchValue('
|
|
2832
|
+
} else if (this.match(TokenType.GT) || this.matchValue('superieur') || this.matchValue('supérieur')) {
|
|
2594
2833
|
const right = this.parseAdditive(lang)
|
|
2595
2834
|
left = { type: 'BinaryExpression', operator: '>', left, right }
|
|
2596
2835
|
} else {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
2
|
|
|
3
3
|
class HTMLGenerator {
|
|
4
|
-
constructor(i18nPath = null) {
|
|
4
|
+
constructor(i18nPath = null, options = {}) {
|
|
5
5
|
this.i18n = null
|
|
6
6
|
this.indent = 0
|
|
7
7
|
this.output = ''
|
|
@@ -15,6 +15,10 @@ class HTMLGenerator {
|
|
|
15
15
|
this.multiWordTags = []
|
|
16
16
|
this.multiWordAttrs = []
|
|
17
17
|
|
|
18
|
+
this.parser = options.parser || null
|
|
19
|
+
this.jsGenerator = options.jsGenerator || null
|
|
20
|
+
this.cssGenerator = options.cssGenerator || null
|
|
21
|
+
|
|
18
22
|
if (i18nPath) {
|
|
19
23
|
this.loadI18n(i18nPath)
|
|
20
24
|
}
|
|
@@ -537,8 +541,20 @@ class HTMLGenerator {
|
|
|
537
541
|
this.output = ''
|
|
538
542
|
this.indent = 0
|
|
539
543
|
|
|
540
|
-
if (ast.type === 'document' || ast.type === 'root') {
|
|
541
|
-
|
|
544
|
+
if (ast.type === 'Document' || ast.type === 'document' || ast.type === 'root') {
|
|
545
|
+
const children = ast.children || []
|
|
546
|
+
|
|
547
|
+
if (children.length > 0) {
|
|
548
|
+
const firstChild = children[0]
|
|
549
|
+
const firstType = (firstChild.type || '').toLowerCase()
|
|
550
|
+
const firstTag = (firstChild.tag || firstChild.tagName || '').toLowerCase()
|
|
551
|
+
|
|
552
|
+
if (firstType !== 'doctype' && (firstTag === 'html' || firstTag === 'document')) {
|
|
553
|
+
this.output += '<!DOCTYPE html>\n'
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
for (const child of children) {
|
|
542
558
|
this.generateNode(child)
|
|
543
559
|
}
|
|
544
560
|
} else {
|
|
@@ -552,19 +568,24 @@ class HTMLGenerator {
|
|
|
552
568
|
if (!node) return
|
|
553
569
|
|
|
554
570
|
switch (node.type) {
|
|
571
|
+
case 'Doctype':
|
|
555
572
|
case 'doctype':
|
|
556
573
|
this.generateDoctype(node)
|
|
557
574
|
break
|
|
575
|
+
case 'Element':
|
|
558
576
|
case 'element':
|
|
559
577
|
case 'tag':
|
|
560
578
|
this.generateElement(node)
|
|
561
579
|
break
|
|
580
|
+
case 'Text':
|
|
562
581
|
case 'text':
|
|
563
582
|
this.generateText(node)
|
|
564
583
|
break
|
|
584
|
+
case 'Comment':
|
|
565
585
|
case 'comment':
|
|
566
586
|
this.generateComment(node)
|
|
567
587
|
break
|
|
588
|
+
case 'Include':
|
|
568
589
|
case 'include':
|
|
569
590
|
this.generateInclude(node)
|
|
570
591
|
break
|
|
@@ -609,8 +630,18 @@ class HTMLGenerator {
|
|
|
609
630
|
const textContent = typeof children === 'string' ? children :
|
|
610
631
|
(node.text || node.textContent || null)
|
|
611
632
|
|
|
633
|
+
const isRawContent = (tag.toLowerCase() === 'script' || tag.toLowerCase() === 'style')
|
|
634
|
+
|
|
612
635
|
if (textContent && !hasChildren) {
|
|
613
|
-
|
|
636
|
+
if (isRawContent) {
|
|
637
|
+
this.writeLine(`<${tag}${attributes}>`)
|
|
638
|
+
this.indent++
|
|
639
|
+
this.writeLine(textContent)
|
|
640
|
+
this.indent--
|
|
641
|
+
this.writeLine(`</${tag}>`)
|
|
642
|
+
} else {
|
|
643
|
+
this.writeLine(`<${tag}${attributes}>${this.escapeHtml(textContent)}</${tag}>`)
|
|
644
|
+
}
|
|
614
645
|
return
|
|
615
646
|
}
|
|
616
647
|
|
|
@@ -622,11 +653,33 @@ class HTMLGenerator {
|
|
|
622
653
|
this.writeLine(`<${tag}${attributes}>`)
|
|
623
654
|
this.indent++
|
|
624
655
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
656
|
+
if (isRawContent) {
|
|
657
|
+
let rawContent = ''
|
|
658
|
+
for (const child of children) {
|
|
659
|
+
if (typeof child === 'string') {
|
|
660
|
+
rawContent += child
|
|
661
|
+
} else if (child.type === 'Text' || child.type === 'text') {
|
|
662
|
+
const content = child.content || child.text || child.value || ''
|
|
663
|
+
if (content.trim()) {
|
|
664
|
+
rawContent += content
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
if (rawContent.trim()) {
|
|
670
|
+
const generatedCode = this.compileEmbeddedCode(rawContent.trim(), tag.toLowerCase())
|
|
671
|
+
const lines = generatedCode.split('\n')
|
|
672
|
+
for (const line of lines) {
|
|
673
|
+
this.writeLine(line)
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
} else {
|
|
677
|
+
for (const child of children) {
|
|
678
|
+
if (typeof child === 'string') {
|
|
679
|
+
this.writeLine(this.escapeHtml(child))
|
|
680
|
+
} else {
|
|
681
|
+
this.generateNode(child)
|
|
682
|
+
}
|
|
630
683
|
}
|
|
631
684
|
}
|
|
632
685
|
|
|
@@ -856,6 +909,11 @@ class HTMLGenerator {
|
|
|
856
909
|
|
|
857
910
|
generateDoctype(node) {
|
|
858
911
|
this.output += '<!DOCTYPE html>\n'
|
|
912
|
+
if (node.children && node.children.length > 0) {
|
|
913
|
+
for (const child of node.children) {
|
|
914
|
+
this.generateNode(child)
|
|
915
|
+
}
|
|
916
|
+
}
|
|
859
917
|
}
|
|
860
918
|
|
|
861
919
|
generateInclude(node) {
|
|
@@ -953,6 +1011,44 @@ class HTMLGenerator {
|
|
|
953
1011
|
}
|
|
954
1012
|
}
|
|
955
1013
|
}
|
|
1014
|
+
|
|
1015
|
+
compileEmbeddedCode(code, tagType) {
|
|
1016
|
+
const etherKeywords = [
|
|
1017
|
+
'journal', 'afficher', 'variable', 'constante', 'fonction', 'si', 'sinon',
|
|
1018
|
+
'pour', 'tant que', 'retourner', 'classe', 'methode', 'importer',
|
|
1019
|
+
'fond', 'couleur', 'marge', 'bordure', 'police', 'largeur', 'hauteur',
|
|
1020
|
+
'remplissage', 'alignement', 'affichage', 'position', 'flexbox', 'grille'
|
|
1021
|
+
]
|
|
1022
|
+
|
|
1023
|
+
const lowerCode = code.toLowerCase()
|
|
1024
|
+
const hasEtherKeywords = etherKeywords.some(kw => lowerCode.includes(kw))
|
|
1025
|
+
|
|
1026
|
+
if (!hasEtherKeywords) {
|
|
1027
|
+
return code
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
if (tagType === 'script' && this.parser && this.jsGenerator) {
|
|
1031
|
+
try {
|
|
1032
|
+
const ast = this.parser.parse(code, 'js')
|
|
1033
|
+
const generated = this.jsGenerator.generate(ast)
|
|
1034
|
+
return generated || code
|
|
1035
|
+
} catch (e) {
|
|
1036
|
+
return code
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
if (tagType === 'style' && this.parser && this.cssGenerator) {
|
|
1041
|
+
try {
|
|
1042
|
+
const ast = this.parser.parse(code, 'css')
|
|
1043
|
+
const generated = this.cssGenerator.generate(ast)
|
|
1044
|
+
return generated || code
|
|
1045
|
+
} catch (e) {
|
|
1046
|
+
return code
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
return code
|
|
1051
|
+
}
|
|
956
1052
|
}
|
|
957
1053
|
|
|
958
1054
|
module.exports = {
|