ether-code 0.6.3 → 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 +36 -4
- package/cli/ether.js +1 -1
- package/ether-parser.js +265 -34
- package/generators/html-generator.js +98 -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
|
}
|
|
@@ -1565,21 +1565,251 @@ class EtherParser {
|
|
|
1565
1565
|
})
|
|
1566
1566
|
}
|
|
1567
1567
|
|
|
1568
|
+
const rawContentTags = ['script', 'style']
|
|
1569
|
+
const isRawContent = rawContentTags.includes(tag)
|
|
1570
|
+
const isScript = tag === 'script'
|
|
1571
|
+
|
|
1568
1572
|
if (this.match(TokenType.INDENT)) {
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
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
|
+
}
|
|
1575
1788
|
}
|
|
1576
1789
|
|
|
1577
|
-
const
|
|
1578
|
-
if (
|
|
1579
|
-
children.push(
|
|
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()
|
|
1580
1812
|
}
|
|
1581
|
-
|
|
1582
|
-
this.skipNewlines()
|
|
1583
1813
|
}
|
|
1584
1814
|
}
|
|
1585
1815
|
|
|
@@ -1782,7 +2012,8 @@ class EtherParser {
|
|
|
1782
2012
|
'zone': 'area'
|
|
1783
2013
|
}
|
|
1784
2014
|
|
|
1785
|
-
|
|
2015
|
+
const result = translations[lower] || translations[withSpaces] || map[lower] || map[withSpaces] || tag
|
|
2016
|
+
return result.replace(/^<!DOCTYPE\s+/i, '').replace(/^<|>$/g, '').trim() || 'div'
|
|
1786
2017
|
}
|
|
1787
2018
|
|
|
1788
2019
|
parseJS() {
|
|
@@ -2557,16 +2788,16 @@ class EtherParser {
|
|
|
2557
2788
|
let left = this.parseComparison(lang)
|
|
2558
2789
|
|
|
2559
2790
|
while (true) {
|
|
2560
|
-
if (this.matchValue('strictement egal') || this.matchValue('strictement
|
|
2791
|
+
if (this.matchValue('strictement egal') || this.matchValue('strictement égal')) {
|
|
2561
2792
|
const right = this.parseComparison(lang)
|
|
2562
2793
|
left = { type: 'BinaryExpression', operator: '===', left, right }
|
|
2563
|
-
} else if (this.matchValue('strictement different') || this.matchValue('strictement
|
|
2794
|
+
} else if (this.matchValue('strictement different') || this.matchValue('strictement différent')) {
|
|
2564
2795
|
const right = this.parseComparison(lang)
|
|
2565
2796
|
left = { type: 'BinaryExpression', operator: '!==', left, right }
|
|
2566
|
-
} else if (this.match(TokenType.DOUBLE_EQUALS) || this.matchValue('egal') || this.matchValue('egale') || this.matchValue('
|
|
2797
|
+
} else if (this.match(TokenType.DOUBLE_EQUALS) || this.matchValue('egal') || this.matchValue('egale') || this.matchValue('égal')) {
|
|
2567
2798
|
const right = this.parseComparison(lang)
|
|
2568
2799
|
left = { type: 'BinaryExpression', operator: '===', left, right }
|
|
2569
|
-
} else if (this.match(TokenType.NOT_EQUALS) || this.matchValue('different') || this.matchValue('
|
|
2800
|
+
} else if (this.match(TokenType.NOT_EQUALS) || this.matchValue('different') || this.matchValue('différent')) {
|
|
2570
2801
|
const right = this.parseComparison(lang)
|
|
2571
2802
|
left = { type: 'BinaryExpression', operator: '!==', left, right }
|
|
2572
2803
|
} else {
|
|
@@ -2581,16 +2812,16 @@ class EtherParser {
|
|
|
2581
2812
|
let left = this.parseAdditive(lang)
|
|
2582
2813
|
|
|
2583
2814
|
while (true) {
|
|
2584
|
-
if (this.matchValue('superieur ou egal') || this.matchValue('
|
|
2815
|
+
if (this.matchValue('superieur ou egal') || this.matchValue('supérieur ou égal') || this.match(TokenType.GTE)) {
|
|
2585
2816
|
const right = this.parseAdditive(lang)
|
|
2586
2817
|
left = { type: 'BinaryExpression', operator: '>=', left, right }
|
|
2587
|
-
} else if (this.matchValue('inferieur ou egal') || this.matchValue('
|
|
2818
|
+
} else if (this.matchValue('inferieur ou egal') || this.matchValue('inférieur ou égal') || this.match(TokenType.LTE)) {
|
|
2588
2819
|
const right = this.parseAdditive(lang)
|
|
2589
2820
|
left = { type: 'BinaryExpression', operator: '<=', left, right }
|
|
2590
|
-
} else if (this.match(TokenType.LT) || this.matchValue('inferieur') || this.matchValue('
|
|
2821
|
+
} else if (this.match(TokenType.LT) || this.matchValue('inferieur') || this.matchValue('inférieur')) {
|
|
2591
2822
|
const right = this.parseAdditive(lang)
|
|
2592
2823
|
left = { type: 'BinaryExpression', operator: '<', left, right }
|
|
2593
|
-
} else if (this.match(TokenType.GT) || this.matchValue('superieur') || this.matchValue('
|
|
2824
|
+
} else if (this.match(TokenType.GT) || this.matchValue('superieur') || this.matchValue('supérieur')) {
|
|
2594
2825
|
const right = this.parseAdditive(lang)
|
|
2595
2826
|
left = { type: 'BinaryExpression', operator: '>', left, right }
|
|
2596
2827
|
} 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,18 @@ 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 firstTag = (firstChild.tag || firstChild.tagName || '').toLowerCase()
|
|
550
|
+
if (firstTag === 'html' || firstTag === 'document') {
|
|
551
|
+
this.output += '<!DOCTYPE html>\n'
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
for (const child of children) {
|
|
542
556
|
this.generateNode(child)
|
|
543
557
|
}
|
|
544
558
|
} else {
|
|
@@ -552,19 +566,24 @@ class HTMLGenerator {
|
|
|
552
566
|
if (!node) return
|
|
553
567
|
|
|
554
568
|
switch (node.type) {
|
|
569
|
+
case 'Doctype':
|
|
555
570
|
case 'doctype':
|
|
556
571
|
this.generateDoctype(node)
|
|
557
572
|
break
|
|
573
|
+
case 'Element':
|
|
558
574
|
case 'element':
|
|
559
575
|
case 'tag':
|
|
560
576
|
this.generateElement(node)
|
|
561
577
|
break
|
|
578
|
+
case 'Text':
|
|
562
579
|
case 'text':
|
|
563
580
|
this.generateText(node)
|
|
564
581
|
break
|
|
582
|
+
case 'Comment':
|
|
565
583
|
case 'comment':
|
|
566
584
|
this.generateComment(node)
|
|
567
585
|
break
|
|
586
|
+
case 'Include':
|
|
568
587
|
case 'include':
|
|
569
588
|
this.generateInclude(node)
|
|
570
589
|
break
|
|
@@ -609,8 +628,18 @@ class HTMLGenerator {
|
|
|
609
628
|
const textContent = typeof children === 'string' ? children :
|
|
610
629
|
(node.text || node.textContent || null)
|
|
611
630
|
|
|
631
|
+
const isRawContent = (tag.toLowerCase() === 'script' || tag.toLowerCase() === 'style')
|
|
632
|
+
|
|
612
633
|
if (textContent && !hasChildren) {
|
|
613
|
-
|
|
634
|
+
if (isRawContent) {
|
|
635
|
+
this.writeLine(`<${tag}${attributes}>`)
|
|
636
|
+
this.indent++
|
|
637
|
+
this.writeLine(textContent)
|
|
638
|
+
this.indent--
|
|
639
|
+
this.writeLine(`</${tag}>`)
|
|
640
|
+
} else {
|
|
641
|
+
this.writeLine(`<${tag}${attributes}>${this.escapeHtml(textContent)}</${tag}>`)
|
|
642
|
+
}
|
|
614
643
|
return
|
|
615
644
|
}
|
|
616
645
|
|
|
@@ -622,11 +651,33 @@ class HTMLGenerator {
|
|
|
622
651
|
this.writeLine(`<${tag}${attributes}>`)
|
|
623
652
|
this.indent++
|
|
624
653
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
654
|
+
if (isRawContent) {
|
|
655
|
+
let rawContent = ''
|
|
656
|
+
for (const child of children) {
|
|
657
|
+
if (typeof child === 'string') {
|
|
658
|
+
rawContent += child
|
|
659
|
+
} else if (child.type === 'Text' || child.type === 'text') {
|
|
660
|
+
const content = child.content || child.text || child.value || ''
|
|
661
|
+
if (content.trim()) {
|
|
662
|
+
rawContent += content
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
if (rawContent.trim()) {
|
|
668
|
+
const generatedCode = this.compileEmbeddedCode(rawContent.trim(), tag.toLowerCase())
|
|
669
|
+
const lines = generatedCode.split('\n')
|
|
670
|
+
for (const line of lines) {
|
|
671
|
+
this.writeLine(line)
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
} else {
|
|
675
|
+
for (const child of children) {
|
|
676
|
+
if (typeof child === 'string') {
|
|
677
|
+
this.writeLine(this.escapeHtml(child))
|
|
678
|
+
} else {
|
|
679
|
+
this.generateNode(child)
|
|
680
|
+
}
|
|
630
681
|
}
|
|
631
682
|
}
|
|
632
683
|
|
|
@@ -953,6 +1004,44 @@ class HTMLGenerator {
|
|
|
953
1004
|
}
|
|
954
1005
|
}
|
|
955
1006
|
}
|
|
1007
|
+
|
|
1008
|
+
compileEmbeddedCode(code, tagType) {
|
|
1009
|
+
const etherKeywords = [
|
|
1010
|
+
'journal', 'afficher', 'variable', 'constante', 'fonction', 'si', 'sinon',
|
|
1011
|
+
'pour', 'tant que', 'retourner', 'classe', 'methode', 'importer',
|
|
1012
|
+
'fond', 'couleur', 'marge', 'bordure', 'police', 'largeur', 'hauteur',
|
|
1013
|
+
'remplissage', 'alignement', 'affichage', 'position', 'flexbox', 'grille'
|
|
1014
|
+
]
|
|
1015
|
+
|
|
1016
|
+
const lowerCode = code.toLowerCase()
|
|
1017
|
+
const hasEtherKeywords = etherKeywords.some(kw => lowerCode.includes(kw))
|
|
1018
|
+
|
|
1019
|
+
if (!hasEtherKeywords) {
|
|
1020
|
+
return code
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
if (tagType === 'script' && this.parser && this.jsGenerator) {
|
|
1024
|
+
try {
|
|
1025
|
+
const ast = this.parser.parse(code, 'js')
|
|
1026
|
+
const generated = this.jsGenerator.generate(ast)
|
|
1027
|
+
return generated || code
|
|
1028
|
+
} catch (e) {
|
|
1029
|
+
return code
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
if (tagType === 'style' && this.parser && this.cssGenerator) {
|
|
1034
|
+
try {
|
|
1035
|
+
const ast = this.parser.parse(code, 'css')
|
|
1036
|
+
const generated = this.cssGenerator.generate(ast)
|
|
1037
|
+
return generated || code
|
|
1038
|
+
} catch (e) {
|
|
1039
|
+
return code
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
return code
|
|
1044
|
+
}
|
|
956
1045
|
}
|
|
957
1046
|
|
|
958
1047
|
module.exports = {
|