ether-code 0.1.2 → 0.1.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 +6 -6
- package/cli/ether.js +126 -19
- package/generators/html-generator.js +61 -19
- package/package.json +4 -4
- package/parsers/html-parser.js +14 -13
package/cli/compiler.js
CHANGED
|
@@ -212,8 +212,8 @@ class EtherCompiler {
|
|
|
212
212
|
inferTargetFromContent(content) {
|
|
213
213
|
const patterns = {
|
|
214
214
|
html: [
|
|
215
|
-
/\b(page|document|entête|
|
|
216
|
-
/\b(balise|élément|
|
|
215
|
+
/\b(page|document|entête|corps|section|div|paragraphe|titre|lien|image|formulaire|bouton)\b/i,
|
|
216
|
+
/\b(balise|élément|attribut)\b/i
|
|
217
217
|
],
|
|
218
218
|
css: [
|
|
219
219
|
/\b(style|couleur|taille|marge|bordure|fond|police|largeur|hauteur)\s*[:=]/i,
|
|
@@ -222,7 +222,7 @@ class EtherCompiler {
|
|
|
222
222
|
],
|
|
223
223
|
js: [
|
|
224
224
|
/\b(fonction|variable|constante|si|sinon|pour|tant que|retourner)\b/i,
|
|
225
|
-
/\b(classe|méthode|
|
|
225
|
+
/\b(classe|méthode|constructeur)\b/i,
|
|
226
226
|
/=>\s*\{/
|
|
227
227
|
],
|
|
228
228
|
php: [
|
|
@@ -230,7 +230,7 @@ class EtherCompiler {
|
|
|
230
230
|
/\$\w+/
|
|
231
231
|
],
|
|
232
232
|
sql: [
|
|
233
|
-
/\b(sélectionner|
|
|
233
|
+
/\b(sélectionner|insérer|mettre à jour|supprimer|créer table|depuis|où)\b/i,
|
|
234
234
|
/\b(SELECT|INSERT|UPDATE|DELETE|CREATE|FROM|WHERE)\b/i
|
|
235
235
|
],
|
|
236
236
|
python: [
|
|
@@ -238,7 +238,7 @@ class EtherCompiler {
|
|
|
238
238
|
/:\s*$/m
|
|
239
239
|
],
|
|
240
240
|
react: [
|
|
241
|
-
/\b(composant|état|
|
|
241
|
+
/\b(composant|état|effet|props|rendu)\b/i,
|
|
242
242
|
/<[\w]+[^>]*\/>/
|
|
243
243
|
],
|
|
244
244
|
graphql: [
|
|
@@ -295,4 +295,4 @@ class EtherCompiler {
|
|
|
295
295
|
}
|
|
296
296
|
}
|
|
297
297
|
|
|
298
|
-
module.exports = { EtherCompiler, GENERATORS, TARGET_EXTENSIONS }
|
|
298
|
+
module.exports = { EtherCompiler, GENERATORS, TARGET_EXTENSIONS }
|
package/cli/ether.js
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('fs')
|
|
4
4
|
const path = require('path')
|
|
5
|
+
const http = require('http')
|
|
5
6
|
const { EtherCompiler } = require('./compiler')
|
|
6
7
|
const { Watcher } = require('./watcher')
|
|
7
8
|
|
|
8
|
-
const VERSION = '0.1.
|
|
9
|
+
const VERSION = '0.1.4'
|
|
9
10
|
|
|
10
11
|
const COLORS = {
|
|
11
12
|
reset: '\x1b[0m',
|
|
@@ -62,7 +63,7 @@ ${COLORS.bright}UTILISATION${COLORS.reset}
|
|
|
62
63
|
${COLORS.bright}COMMANDES${COLORS.reset}
|
|
63
64
|
${COLORS.cyan}init${COLORS.reset} Initialiser un nouveau projet Ether
|
|
64
65
|
${COLORS.cyan}build${COLORS.reset} Compiler les fichiers .eth
|
|
65
|
-
${COLORS.cyan}dev${COLORS.reset} Mode développement (watch +
|
|
66
|
+
${COLORS.cyan}dev${COLORS.reset} Mode développement (serveur + watch + live reload)
|
|
66
67
|
${COLORS.cyan}check${COLORS.reset} Vérifier la syntaxe sans compiler
|
|
67
68
|
${COLORS.cyan}help${COLORS.reset} Afficher cette aide
|
|
68
69
|
${COLORS.cyan}version${COLORS.reset} Afficher la version
|
|
@@ -70,6 +71,7 @@ ${COLORS.bright}COMMANDES${COLORS.reset}
|
|
|
70
71
|
${COLORS.bright}OPTIONS${COLORS.reset}
|
|
71
72
|
-c, --config Chemin vers le fichier de configuration
|
|
72
73
|
-o, --output Dossier de sortie
|
|
74
|
+
-p, --port Port du serveur de développement (défaut: 3000)
|
|
73
75
|
-w, --watch Surveiller les changements (alias de dev)
|
|
74
76
|
-v, --verbose Mode verbeux
|
|
75
77
|
-q, --quiet Mode silencieux
|
|
@@ -82,11 +84,11 @@ ${COLORS.bright}EXEMPLES${COLORS.reset}
|
|
|
82
84
|
${COLORS.dim}# Compiler le projet${COLORS.reset}
|
|
83
85
|
ether build
|
|
84
86
|
|
|
85
|
-
${COLORS.dim}# Mode développement${COLORS.reset}
|
|
87
|
+
${COLORS.dim}# Mode développement sur localhost:3000${COLORS.reset}
|
|
86
88
|
ether dev
|
|
87
89
|
|
|
88
|
-
${COLORS.dim}#
|
|
89
|
-
ether
|
|
90
|
+
${COLORS.dim}# Mode développement sur un autre port${COLORS.reset}
|
|
91
|
+
ether dev -p 8080
|
|
90
92
|
|
|
91
93
|
${COLORS.bright}DOCUMENTATION${COLORS.reset}
|
|
92
94
|
https://ether-code.com/docs
|
|
@@ -222,18 +224,20 @@ async function cmdInit() {
|
|
|
222
224
|
logWarning('package.json existe déjà')
|
|
223
225
|
}
|
|
224
226
|
|
|
225
|
-
const exampleEth =
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
page "Ma première page Ether"
|
|
229
|
-
entête
|
|
230
|
-
titre "Bienvenue"
|
|
231
|
-
|
|
227
|
+
const exampleEth = `html
|
|
228
|
+
tête
|
|
229
|
+
titre "Ma première page Ether"
|
|
232
230
|
corps
|
|
233
|
-
|
|
234
|
-
|
|
231
|
+
entete
|
|
232
|
+
titre1 "Bienvenue sur Ether"
|
|
235
233
|
paragraphe "Le langage intentionnel"
|
|
236
|
-
|
|
234
|
+
principal
|
|
235
|
+
section #hero
|
|
236
|
+
titre2 "Commencez maintenant"
|
|
237
|
+
paragraphe "Programmez dans votre langue naturelle."
|
|
238
|
+
bouton .primary "Démarrer"
|
|
239
|
+
pied
|
|
240
|
+
paragraphe "© 2025 Créé avec Ether"
|
|
237
241
|
`
|
|
238
242
|
|
|
239
243
|
const examplePath = path.join(srcDir, 'index.eth')
|
|
@@ -341,6 +345,7 @@ async function cmdDev(options) {
|
|
|
341
345
|
const config = loadConfig(options.config)
|
|
342
346
|
const srcDir = path.resolve(process.cwd(), config.src)
|
|
343
347
|
const outDir = path.resolve(process.cwd(), options.output || config.out)
|
|
348
|
+
const port = options.port || config.port || 3000
|
|
344
349
|
|
|
345
350
|
if (!fs.existsSync(srcDir)) {
|
|
346
351
|
logError(`Dossier source introuvable: ${srcDir}`)
|
|
@@ -350,11 +355,105 @@ async function cmdDev(options) {
|
|
|
350
355
|
logInfo(`Surveillance de ${srcDir}`)
|
|
351
356
|
logInfo(`Sortie vers ${outDir}`)
|
|
352
357
|
console.log('')
|
|
353
|
-
logInfo('En attente de modifications... (Ctrl+C pour arrêter)')
|
|
354
|
-
console.log('')
|
|
355
358
|
|
|
356
359
|
await cmdBuild({ ...options, quiet: true })
|
|
357
360
|
|
|
361
|
+
const clients = []
|
|
362
|
+
|
|
363
|
+
const MIME_TYPES = {
|
|
364
|
+
'.html': 'text/html',
|
|
365
|
+
'.css': 'text/css',
|
|
366
|
+
'.js': 'application/javascript',
|
|
367
|
+
'.json': 'application/json',
|
|
368
|
+
'.png': 'image/png',
|
|
369
|
+
'.jpg': 'image/jpeg',
|
|
370
|
+
'.jpeg': 'image/jpeg',
|
|
371
|
+
'.gif': 'image/gif',
|
|
372
|
+
'.svg': 'image/svg+xml',
|
|
373
|
+
'.ico': 'image/x-icon',
|
|
374
|
+
'.webp': 'image/webp',
|
|
375
|
+
'.mp4': 'video/mp4',
|
|
376
|
+
'.webm': 'video/webm',
|
|
377
|
+
'.woff': 'font/woff',
|
|
378
|
+
'.woff2': 'font/woff2',
|
|
379
|
+
'.ttf': 'font/ttf'
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
const LIVE_RELOAD_SCRIPT = `
|
|
383
|
+
<script>
|
|
384
|
+
(function() {
|
|
385
|
+
const es = new EventSource('/__ether_reload');
|
|
386
|
+
es.onmessage = function(e) {
|
|
387
|
+
if (e.data === 'reload') {
|
|
388
|
+
window.location.reload();
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
es.onerror = function() {
|
|
392
|
+
es.close();
|
|
393
|
+
setTimeout(function() { window.location.reload(); }, 1000);
|
|
394
|
+
};
|
|
395
|
+
})();
|
|
396
|
+
</script>
|
|
397
|
+
</body>`
|
|
398
|
+
|
|
399
|
+
const server = http.createServer((req, res) => {
|
|
400
|
+
if (req.url === '/__ether_reload') {
|
|
401
|
+
res.writeHead(200, {
|
|
402
|
+
'Content-Type': 'text/event-stream',
|
|
403
|
+
'Cache-Control': 'no-cache',
|
|
404
|
+
'Connection': 'keep-alive',
|
|
405
|
+
'Access-Control-Allow-Origin': '*'
|
|
406
|
+
})
|
|
407
|
+
res.write('data: connected\n\n')
|
|
408
|
+
clients.push(res)
|
|
409
|
+
req.on('close', () => {
|
|
410
|
+
const index = clients.indexOf(res)
|
|
411
|
+
if (index > -1) clients.splice(index, 1)
|
|
412
|
+
})
|
|
413
|
+
return
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
let filePath = req.url === '/' ? '/index.html' : req.url
|
|
417
|
+
filePath = filePath.split('?')[0]
|
|
418
|
+
filePath = path.join(outDir, filePath)
|
|
419
|
+
|
|
420
|
+
const ext = path.extname(filePath).toLowerCase()
|
|
421
|
+
const contentType = MIME_TYPES[ext] || 'application/octet-stream'
|
|
422
|
+
|
|
423
|
+
fs.readFile(filePath, (err, content) => {
|
|
424
|
+
if (err) {
|
|
425
|
+
if (err.code === 'ENOENT') {
|
|
426
|
+
res.writeHead(404)
|
|
427
|
+
res.end('404 - Fichier non trouvé')
|
|
428
|
+
} else {
|
|
429
|
+
res.writeHead(500)
|
|
430
|
+
res.end('Erreur serveur')
|
|
431
|
+
}
|
|
432
|
+
return
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
if (ext === '.html') {
|
|
436
|
+
content = content.toString().replace('</body>', LIVE_RELOAD_SCRIPT)
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
res.writeHead(200, { 'Content-Type': contentType })
|
|
440
|
+
res.end(content)
|
|
441
|
+
})
|
|
442
|
+
})
|
|
443
|
+
|
|
444
|
+
server.listen(port, () => {
|
|
445
|
+
logSuccess(`Serveur démarré sur http://localhost:${port}`)
|
|
446
|
+
console.log('')
|
|
447
|
+
logInfo('En attente de modifications... (Ctrl+C pour arrêter)')
|
|
448
|
+
console.log('')
|
|
449
|
+
})
|
|
450
|
+
|
|
451
|
+
function notifyClients() {
|
|
452
|
+
clients.forEach(client => {
|
|
453
|
+
client.write('data: reload\n\n')
|
|
454
|
+
})
|
|
455
|
+
}
|
|
456
|
+
|
|
358
457
|
const watcher = new Watcher(srcDir, config.watch)
|
|
359
458
|
const compiler = new EtherCompiler(config)
|
|
360
459
|
|
|
@@ -378,6 +477,8 @@ async function cmdDev(options) {
|
|
|
378
477
|
fs.writeFileSync(outPath, output.content)
|
|
379
478
|
logSuccess(`→ ${output.path}`)
|
|
380
479
|
}
|
|
480
|
+
|
|
481
|
+
notifyClients()
|
|
381
482
|
} catch (err) {
|
|
382
483
|
logError(err.message)
|
|
383
484
|
}
|
|
@@ -403,6 +504,8 @@ async function cmdDev(options) {
|
|
|
403
504
|
fs.writeFileSync(outPath, output.content)
|
|
404
505
|
logSuccess(`→ ${output.path}`)
|
|
405
506
|
}
|
|
507
|
+
|
|
508
|
+
notifyClients()
|
|
406
509
|
} catch (err) {
|
|
407
510
|
logError(err.message)
|
|
408
511
|
}
|
|
@@ -417,7 +520,8 @@ async function cmdDev(options) {
|
|
|
417
520
|
|
|
418
521
|
process.on('SIGINT', () => {
|
|
419
522
|
console.log('')
|
|
420
|
-
logInfo('Arrêt du
|
|
523
|
+
logInfo('Arrêt du serveur de développement')
|
|
524
|
+
server.close()
|
|
421
525
|
watcher.stop()
|
|
422
526
|
process.exit(0)
|
|
423
527
|
})
|
|
@@ -516,6 +620,7 @@ function parseArgs(args) {
|
|
|
516
620
|
command: null,
|
|
517
621
|
config: null,
|
|
518
622
|
output: null,
|
|
623
|
+
port: null,
|
|
519
624
|
verbose: false,
|
|
520
625
|
quiet: false,
|
|
521
626
|
watch: false
|
|
@@ -529,6 +634,8 @@ function parseArgs(args) {
|
|
|
529
634
|
options.config = args[++i]
|
|
530
635
|
} else if (arg === '-o' || arg === '--output') {
|
|
531
636
|
options.output = args[++i]
|
|
637
|
+
} else if (arg === '-p' || arg === '--port') {
|
|
638
|
+
options.port = parseInt(args[++i], 10)
|
|
532
639
|
} else if (arg === '-v' || arg === '--verbose') {
|
|
533
640
|
options.verbose = true
|
|
534
641
|
} else if (arg === '-q' || arg === '--quiet') {
|
|
@@ -590,4 +697,4 @@ async function main() {
|
|
|
590
697
|
main().catch(err => {
|
|
591
698
|
logError(err.message)
|
|
592
699
|
process.exit(1)
|
|
593
|
-
})
|
|
700
|
+
})
|
|
@@ -455,10 +455,16 @@ class HTMLGenerator {
|
|
|
455
455
|
if (!node) return
|
|
456
456
|
|
|
457
457
|
switch (node.type) {
|
|
458
|
+
case 'Document':
|
|
459
|
+
this.generateDocument(node)
|
|
460
|
+
break
|
|
458
461
|
case 'Element':
|
|
459
462
|
case 'élément':
|
|
460
463
|
this.generateElement(node)
|
|
461
464
|
break
|
|
465
|
+
case 'TextNode':
|
|
466
|
+
this.generateTextNode(node)
|
|
467
|
+
break
|
|
462
468
|
case 'Text':
|
|
463
469
|
case 'text':
|
|
464
470
|
this.generateText(node)
|
|
@@ -474,14 +480,34 @@ class HTMLGenerator {
|
|
|
474
480
|
default:
|
|
475
481
|
if (node.tag || node.tagName) {
|
|
476
482
|
this.generateElement(node)
|
|
477
|
-
} else if (node.text || node.content) {
|
|
483
|
+
} else if (node.text || node.content || node.value) {
|
|
478
484
|
this.generateText(node)
|
|
479
485
|
}
|
|
480
486
|
}
|
|
481
487
|
}
|
|
482
488
|
|
|
489
|
+
generateDocument(node) {
|
|
490
|
+
this.writeLine('<!DOCTYPE html>')
|
|
491
|
+
if (node.html) {
|
|
492
|
+
this.generateNode(node.html)
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
generateTextNode(node) {
|
|
497
|
+
if (node.value || node.content) {
|
|
498
|
+
this.writeLine(this.escapeHtml(node.value || node.content))
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
483
502
|
generateElement(node) {
|
|
484
|
-
|
|
503
|
+
let tag
|
|
504
|
+
if (node.htmlTag && !node.htmlTag.startsWith('<')) {
|
|
505
|
+
tag = node.htmlTag
|
|
506
|
+
} else {
|
|
507
|
+
const rawTag = node.tag || node.tagName || node.name
|
|
508
|
+
tag = this.translateTag(rawTag)
|
|
509
|
+
}
|
|
510
|
+
|
|
485
511
|
const attributes = this.generateAttributes(node.attributes || node.attrs || {})
|
|
486
512
|
const isVoid = this.voidElements.includes(tag.toLowerCase())
|
|
487
513
|
|
|
@@ -521,30 +547,46 @@ class HTMLGenerator {
|
|
|
521
547
|
}
|
|
522
548
|
|
|
523
549
|
generateAttributes(attrs) {
|
|
524
|
-
if (!attrs || Object.keys(attrs).length === 0) {
|
|
550
|
+
if (!attrs || (Array.isArray(attrs) && attrs.length === 0) || Object.keys(attrs).length === 0) {
|
|
525
551
|
return ''
|
|
526
552
|
}
|
|
527
553
|
|
|
528
554
|
const parts = []
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
if (value === true || value === '') {
|
|
537
|
-
parts.push(attrName)
|
|
538
|
-
} else if (value === false || value === null || value === undefined) {
|
|
539
|
-
continue
|
|
540
|
-
} else {
|
|
541
|
-
let attrValue = this.translateAttrValue(value)
|
|
555
|
+
|
|
556
|
+
if (Array.isArray(attrs)) {
|
|
557
|
+
for (const attr of attrs) {
|
|
558
|
+
const attrName = attr.htmlName || this.translateAttribute(attr.name)
|
|
559
|
+
const value = attr.value
|
|
542
560
|
|
|
543
|
-
if (
|
|
544
|
-
|
|
561
|
+
if (value === true || value === '') {
|
|
562
|
+
parts.push(attrName)
|
|
563
|
+
} else if (value === false || value === null || value === undefined) {
|
|
564
|
+
continue
|
|
565
|
+
} else {
|
|
566
|
+
parts.push(`${attrName}="${this.escapeAttr(value)}"`)
|
|
545
567
|
}
|
|
568
|
+
}
|
|
569
|
+
} else {
|
|
570
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
571
|
+
let attrName = this.translateAttribute(key)
|
|
546
572
|
|
|
547
|
-
|
|
573
|
+
if (attrName.startsWith('au ') || attrName.startsWith('a la ')) {
|
|
574
|
+
attrName = this.translateEvent(key)
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
if (value === true || value === '') {
|
|
578
|
+
parts.push(attrName)
|
|
579
|
+
} else if (value === false || value === null || value === undefined) {
|
|
580
|
+
continue
|
|
581
|
+
} else {
|
|
582
|
+
let attrValue = this.translateAttrValue(value)
|
|
583
|
+
|
|
584
|
+
if (attrName === 'type' && this.isInputType(value)) {
|
|
585
|
+
attrValue = this.translateInputType(value)
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
parts.push(`${attrName}="${this.escapeAttr(attrValue)}"`)
|
|
589
|
+
}
|
|
548
590
|
}
|
|
549
591
|
}
|
|
550
592
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ether-code",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Ether - Le langage intentionnel",
|
|
5
5
|
"main": "cli/compiler.js",
|
|
6
6
|
"bin": {
|
|
@@ -20,15 +20,15 @@
|
|
|
20
20
|
"french",
|
|
21
21
|
"multilingual"
|
|
22
22
|
],
|
|
23
|
-
"author": "
|
|
23
|
+
"author": "Steve",
|
|
24
24
|
"license": "MIT",
|
|
25
25
|
"repository": {
|
|
26
26
|
"type": "git",
|
|
27
|
-
"url": "https://github.com/ether-
|
|
27
|
+
"url": "https://github.com/ether-lang/ether"
|
|
28
28
|
},
|
|
29
29
|
"homepage": "https://ether-code.com",
|
|
30
30
|
"bugs": {
|
|
31
|
-
"url": "https://github.com/ether-
|
|
31
|
+
"url": "https://github.com/ether-lang/ether/issues"
|
|
32
32
|
},
|
|
33
33
|
"engines": {
|
|
34
34
|
"node": ">=14.0.0"
|
package/parsers/html-parser.js
CHANGED
|
@@ -551,6 +551,7 @@ class HTMLParser {
|
|
|
551
551
|
const tagName = elemToken.value
|
|
552
552
|
const htmlTag = this.translateElement(tagName)
|
|
553
553
|
const loc = elemToken.loc
|
|
554
|
+
const elemIndent = loc.column - 1
|
|
554
555
|
|
|
555
556
|
const attributes = this.parseAttributes()
|
|
556
557
|
|
|
@@ -567,7 +568,7 @@ class HTMLParser {
|
|
|
567
568
|
children.push(new AST.TextNode(textContent))
|
|
568
569
|
}
|
|
569
570
|
|
|
570
|
-
const childElements = this.parseChildren()
|
|
571
|
+
const childElements = this.parseChildren(elemIndent)
|
|
571
572
|
children = children.concat(childElements)
|
|
572
573
|
}
|
|
573
574
|
|
|
@@ -575,6 +576,9 @@ class HTMLParser {
|
|
|
575
576
|
}
|
|
576
577
|
|
|
577
578
|
parseShorthandElement() {
|
|
579
|
+
const firstToken = this.peek()
|
|
580
|
+
const elemIndent = firstToken.loc ? firstToken.loc.column - 1 : 0
|
|
581
|
+
|
|
578
582
|
const attributes = []
|
|
579
583
|
let tagName = 'div'
|
|
580
584
|
let htmlTag = 'div'
|
|
@@ -607,7 +611,7 @@ class HTMLParser {
|
|
|
607
611
|
children.push(new AST.TextNode(textContent))
|
|
608
612
|
}
|
|
609
613
|
|
|
610
|
-
const childElements = this.parseChildren()
|
|
614
|
+
const childElements = this.parseChildren(elemIndent)
|
|
611
615
|
children.push(...childElements)
|
|
612
616
|
|
|
613
617
|
return new AST.Element(tagName, htmlTag, attributes, children, false)
|
|
@@ -664,16 +668,13 @@ class HTMLParser {
|
|
|
664
668
|
return attributes
|
|
665
669
|
}
|
|
666
670
|
|
|
667
|
-
parseChildren() {
|
|
671
|
+
parseChildren(parentIndent = -1) {
|
|
668
672
|
const children = []
|
|
669
673
|
|
|
670
|
-
this.skipNewlines()
|
|
671
|
-
const baseIndent = this.currentIndent
|
|
672
|
-
|
|
673
674
|
while (!this.match('EOF')) {
|
|
674
675
|
this.skipNewlines()
|
|
675
676
|
|
|
676
|
-
if (this.currentIndent <=
|
|
677
|
+
if (this.currentIndent <= parentIndent) {
|
|
677
678
|
break
|
|
678
679
|
}
|
|
679
680
|
|
|
@@ -807,12 +808,12 @@ class HTMLParser {
|
|
|
807
808
|
'tete': 'head', 'tête': 'head', 'head': 'head', 'cabeza': 'head', 'голова': 'head', '头部': 'head', 'ヘッド': 'head',
|
|
808
809
|
'corps': 'body', 'body': 'body', 'cuerpo': 'body', 'тело': 'body', '主体': 'body', 'ボディ': 'body',
|
|
809
810
|
'titre': 'title', 'title': 'title', 'título': 'title', 'titulo': 'title', 'заголовок': 'title', '标题': 'title', 'タイトル': 'title',
|
|
810
|
-
'titre 1': 'h1', 'heading 1': 'h1', 'título 1': 'h1', 'titulo 1': 'h1', 'заголовок 1': 'h1', '标题 1': 'h1', '見出し 1': 'h1',
|
|
811
|
-
'titre 2': 'h2', 'heading 2': 'h2', 'título 2': 'h2', 'titulo 2': 'h2', 'заголовок 2': 'h2', '标题 2': 'h2', '見出し 2': 'h2',
|
|
812
|
-
'titre 3': 'h3', 'heading 3': 'h3', 'título 3': 'h3', 'titulo 3': 'h3', 'заголовок 3': 'h3', '标题 3': 'h3', '見出し 3': 'h3',
|
|
813
|
-
'titre 4': 'h4', 'heading 4': 'h4', 'título 4': 'h4', 'titulo 4': 'h4', 'заголовок 4': 'h4', '标题 4': 'h4', '見出し 4': 'h4',
|
|
814
|
-
'titre 5': 'h5', 'heading 5': 'h5', 'título 5': 'h5', 'titulo 5': 'h5', 'заголовок 5': 'h5', '标题 5': 'h5', '見出し 5': 'h5',
|
|
815
|
-
'titre 6': 'h6', 'heading 6': 'h6', 'título 6': 'h6', 'titulo 6': 'h6', 'заголовок 6': 'h6', '标题 6': 'h6', '見出し 6': 'h6',
|
|
811
|
+
'titre 1': 'h1', 'titre1': 'h1', 'heading 1': 'h1', 'título 1': 'h1', 'titulo 1': 'h1', 'заголовок 1': 'h1', '标题 1': 'h1', '見出し 1': 'h1',
|
|
812
|
+
'titre 2': 'h2', 'titre2': 'h2', 'heading 2': 'h2', 'título 2': 'h2', 'titulo 2': 'h2', 'заголовок 2': 'h2', '标题 2': 'h2', '見出し 2': 'h2',
|
|
813
|
+
'titre 3': 'h3', 'titre3': 'h3', 'heading 3': 'h3', 'título 3': 'h3', 'titulo 3': 'h3', 'заголовок 3': 'h3', '标题 3': 'h3', '見出し 3': 'h3',
|
|
814
|
+
'titre 4': 'h4', 'titre4': 'h4', 'heading 4': 'h4', 'título 4': 'h4', 'titulo 4': 'h4', 'заголовок 4': 'h4', '标题 4': 'h4', '見出し 4': 'h4',
|
|
815
|
+
'titre 5': 'h5', 'titre5': 'h5', 'heading 5': 'h5', 'título 5': 'h5', 'titulo 5': 'h5', 'заголовок 5': 'h5', '标题 5': 'h5', '見出し 5': 'h5',
|
|
816
|
+
'titre 6': 'h6', 'titre6': 'h6', 'heading 6': 'h6', 'título 6': 'h6', 'titulo 6': 'h6', 'заголовок 6': 'h6', '标题 6': 'h6', '見出し 6': 'h6',
|
|
816
817
|
'paragraphe': 'p', 'paragraph': 'p', 'párrafo': 'p', 'parrafo': 'p', 'параграф': 'p', '段落': 'p',
|
|
817
818
|
'division': 'div', 'div': 'div', 'bloque': 'div', 'блок': 'div', '块': 'div', 'ディブ': 'div',
|
|
818
819
|
'etendue': 'span', 'étendue': 'span', 'span': 'span', 'extensión': 'span', 'extension': 'span', 'спан': 'span', '跨度': 'span', 'スパン': 'span',
|