ether-code 0.2.9 → 0.3.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.2.9'
9
+ const VERSION = '0.3.1'
10
10
 
11
11
  const COLORS = {
12
12
  reset: '\x1b[0m',
@@ -37,6 +37,45 @@ const MIME_TYPES = {
37
37
  '.eot': 'application/vnd.ms-fontobject'
38
38
  }
39
39
 
40
+ const LOGO_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 499 500">
41
+ <defs>
42
+ <linearGradient id="g1" x1="1.106" y1="250.053" x2="498.862" y2="250.053" gradientUnits="userSpaceOnUse">
43
+ <stop offset="0" stop-color="#03AFC6"/><stop offset=".513" stop-color="#31BAD3"/><stop offset="1" stop-color="#3EC4DD"/>
44
+ </linearGradient>
45
+ <linearGradient id="g2" x1="56.332" y1="250.053" x2="470.304" y2="250.053" gradientUnits="userSpaceOnUse">
46
+ <stop offset="0" stop-color="#4758A7"/><stop offset=".26" stop-color="#6F53A2"/><stop offset=".594" stop-color="#924A9D"/><stop offset=".852" stop-color="#A64399"/><stop offset="1" stop-color="#AE4097"/>
47
+ </linearGradient>
48
+ <linearGradient id="g3" x1="144.131" y1="289.106" x2="448.279" y2="147.279" gradientUnits="userSpaceOnUse">
49
+ <stop offset="0" stop-color="#5E6AB2"/><stop offset=".114" stop-color="#5A77B7"/><stop offset=".416" stop-color="#4D96C8"/><stop offset=".675" stop-color="#3DADD5"/><stop offset=".878" stop-color="#30BBDD"/><stop offset="1" stop-color="#24C1E1"/>
50
+ </linearGradient>
51
+ <linearGradient id="g4" x1="223.275" y1="258.888" x2="387.137" y2="182.478" gradientUnits="userSpaceOnUse">
52
+ <stop offset="0" stop-color="#5E6AB2"/><stop offset=".114" stop-color="#5A77B7"/><stop offset=".416" stop-color="#4D96C8"/><stop offset=".675" stop-color="#3DADD5"/><stop offset=".878" stop-color="#30BBDD"/><stop offset="1" stop-color="#24C1E1"/>
53
+ </linearGradient>
54
+ </defs>
55
+ <path fill="url(#g1)" d="M5.381,238.563c-5.468-13.48-5.838-18.365-0.256-29.006c5.582-10.641,129.113-178.821,157.852-196.679C191.716-4.979,414.415,0.938,431.034,1.795c16.621,0.856,39.463,3.869,45.858,10.234c6.395,6.365,10.242,8.502,12.175,17.908c1.932,9.406,7.304,45.665,8.664,91.185c1.362,45.521,1.822,152.92-0.505,186.578c-2.325,33.658-1.465,47.184-14.553,67.173c-13.089,19.987-218.044,111.611-232.689,117.413c-14.646,5.801-35.404,16.623-62.205-6.569C160.979,462.526,5.381,238.563,5.381,238.563z"/>
56
+ <path fill="url(#g2)" d="M291.136,436.653c-7.71,3.354-52.39,24.228-61.917,23.915c-10.871-0.359-16.045-4.679-36.578-31.196C157.484,383.969,67.434,258.436,60.702,243.983c-5.766-12.377-6.472-19.474,1.826-32.931c8.299-13.456,105.229-151.605,117.666-160.906c12.648-9.458,23.041-10.032,35.5-10.188c55.329-0.694,152.766-0.725,225.992,1.368c16.294,0.466,24.063,11.799,24.653,21.583c5.707,94.576,6.6,150.435-6.481,266.374c-3.107,27.537-16.15,39.634-36.553,49.895C402.604,389.586,301.741,432.036,291.136,436.653z"/>
57
+ <path fill="url(#g3)" d="M397.598,278.148c2.596,0.083,3.073,1.179,3.474,1.965c0.642,1.265,0.51,3.642-0.264,5.969c-0.545,1.638-10.225,33.388-13.646,43.11c-1.364,3.871-2.896,4.9-5.702,6.357c-2.692,1.396-132.598,52.559-143.222,56.099c-6.013,2.006-6.541,0.742-9.292-1.695c-2.749-2.437-107.08-151.266-109.972-155.301c-2.893-4.034-1.419-6.227-0.711-7.854c1.636-3.759,78.848-110.176,84.417-116.574c5.57-6.398,8.097-8.37,12.46-11.03c2.771-1.689,5.406-3.374,11.53-3.739c12.276-0.731,183.793-0.426,192.787,0.333c4.049,0.342,7.233,1.441,6.384,6.319c-0.853,4.879-9.874,46.584-8.671,43.199c1.204-3.385-1.01,5.33-8.432,5.348c-7.422,0.02-153.731,0-157.729,0.039c-6.107,0.06-6.991,0.443-7.952,1.426c-2.176,2.226-54.269,71.788-57.427,75.836c-3.157,4.048-2.247,5.316,1.448,9.065c3.695,3.748,69.606,62.824,69.606,62.824s-10.604-21.547-8.459-21.547"/>
58
+ <path fill="url(#g4)" d="M213.282,235.909c14.12-20.019,28.129-36.342,31.945-40.798c5.362-6.26,5.762-5.197,8.629-5.197c2.869,0,132.714,0.003,132.714,0.003s2.916-0.469,4.863,1.864c1.029,1.235-0.298,5.654-0.298,5.654l-9.552,40.332c0,0-1.318,5.72-6.366,5.649C334.696,242.847,208.748,250.903,213.282,235.909"/>
59
+ </svg>`
60
+
61
+ const FAVICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 499 500">
62
+ <defs>
63
+ <linearGradient id="f1" x1="0%" y1="0%" x2="100%" y2="100%">
64
+ <stop offset="0" stop-color="#03AFC6"/><stop offset="1" stop-color="#3EC4DD"/>
65
+ </linearGradient>
66
+ <linearGradient id="f2" x1="0%" y1="0%" x2="100%" y2="100%">
67
+ <stop offset="0" stop-color="#4758A7"/><stop offset="1" stop-color="#AE4097"/>
68
+ </linearGradient>
69
+ <linearGradient id="f3" x1="0%" y1="100%" x2="100%" y2="0%">
70
+ <stop offset="0" stop-color="#5E6AB2"/><stop offset="1" stop-color="#24C1E1"/>
71
+ </linearGradient>
72
+ </defs>
73
+ <path fill="url(#f1)" d="M5.381,238.563c-5.468-13.48-5.838-18.365-0.256-29.006c5.582-10.641,129.113-178.821,157.852-196.679C191.716-4.979,414.415,0.938,431.034,1.795c16.621,0.856,39.463,3.869,45.858,10.234c6.395,6.365,10.242,8.502,12.175,17.908c1.932,9.406,7.304,45.665,8.664,91.185c1.362,45.521,1.822,152.92-0.505,186.578c-2.325,33.658-1.465,47.184-14.553,67.173c-13.089,19.987-218.044,111.611-232.689,117.413c-14.646,5.801-35.404,16.623-62.205-6.569C160.979,462.526,5.381,238.563,5.381,238.563z"/>
74
+ <path fill="url(#f2)" d="M291.136,436.653c-7.71,3.354-52.39,24.228-61.917,23.915c-10.871-0.359-16.045-4.679-36.578-31.196C157.484,383.969,67.434,258.436,60.702,243.983c-5.766-12.377-6.472-19.474,1.826-32.931c8.299-13.456,105.229-151.605,117.666-160.906c12.648-9.458,23.041-10.032,35.5-10.188c55.329-0.694,152.766-0.725,225.992,1.368c16.294,0.466,24.063,11.799,24.653,21.583c5.707,94.576,6.6,150.435-6.481,266.374c-3.107,27.537-16.15,39.634-36.553,49.895C402.604,389.586,301.741,432.036,291.136,436.653z"/>
75
+ <path fill="url(#f3)" d="M397.598,278.148c2.596,0.083,3.073,1.179,3.474,1.965c0.642,1.265,0.51,3.642-0.264,5.969c-0.545,1.638-10.225,33.388-13.646,43.11c-1.364,3.871-2.896,4.9-5.702,6.357c-2.692,1.396-132.598,52.559-143.222,56.099c-6.013,2.006-6.541,0.742-9.292-1.695c-2.749-2.437-107.08-151.266-109.972-155.301c-2.893-4.034-1.419-6.227-0.711-7.854c1.636-3.759,78.848-110.176,84.417-116.574c5.57-6.398,8.097-8.37,12.46-11.03c2.771-1.689,5.406-3.374,11.53-3.739c12.276-0.731,183.793-0.426,192.787,0.333c4.049,0.342,7.233,1.441,6.384,6.319c-0.853,4.879-9.874,46.584-8.671,43.199c1.204-3.385-1.01,5.33-8.432,5.348c-7.422,0.02-153.731,0-157.729,0.039c-6.107,0.06-6.991,0.443-7.952,1.426c-2.176,2.226-54.269,71.788-57.427,75.836c-3.157,4.048-2.247,5.316,1.448,9.065c3.695,3.748,69.606,62.824,69.606,62.824s-10.604-21.547-8.459-21.547"/>
76
+ <path fill="url(#f3)" d="M213.282,235.909c14.12-20.019,28.129-36.342,31.945-40.798c5.362-6.26,5.762-5.197,8.629-5.197c2.869,0,132.714,0.003,132.714,0.003s2.916-0.469,4.863,1.864c1.029,1.235-0.298,5.654-0.298,5.654l-9.552,40.332c0,0-1.318,5.72-6.366,5.649C334.696,242.847,208.748,250.903,213.282,235.909"/>
77
+ </svg>`
78
+
40
79
  function log(msg, color) {
41
80
  console.log((color || '') + msg + COLORS.reset)
42
81
  }
@@ -138,7 +177,7 @@ function findEthFiles(dir) {
138
177
  return files
139
178
  }
140
179
 
141
- function startServer(outDir, port) {
180
+ function startServer(outDir, publicDir, port) {
142
181
  const clients = []
143
182
 
144
183
  const liveReloadScript = '<script>(function(){var es=new EventSource("/__ether_reload");es.onmessage=function(e){if(e.data==="reload")location.reload()};})();</script>'
@@ -163,6 +202,10 @@ function startServer(outDir, port) {
163
202
  const urlPath = req.url.split('?')[0]
164
203
  let filePath = path.join(outDir, urlPath === '/' ? 'index.html' : urlPath)
165
204
 
205
+ if (!fs.existsSync(filePath) && publicDir) {
206
+ filePath = path.join(publicDir, urlPath)
207
+ }
208
+
166
209
  if (fs.existsSync(filePath) && fs.statSync(filePath).isDirectory()) {
167
210
  filePath = path.join(filePath, 'index.html')
168
211
  }
@@ -237,13 +280,339 @@ function cmdInit() {
237
280
  if (!fs.existsSync(imagesDir)) fs.mkdirSync(imagesDir, { recursive: true })
238
281
  if (!fs.existsSync(videosDir)) fs.mkdirSync(videosDir, { recursive: true })
239
282
 
240
- const configContent = 'module.exports = {\n src: "src",\n out: "dist",\n port: 3000,\n lang: "fr"\n}\n'
283
+ fs.writeFileSync(path.join(imagesDir, 'logo.svg'), LOGO_SVG)
284
+ fs.writeFileSync(path.join(publicDir, 'favicon.svg'), FAVICON_SVG)
241
285
 
242
- const indexContent = '// cible: html\n\ndocument\n tete\n meta charset: "UTF-8"\n meta name: "viewport", content: "width=device-width, initial-scale=1.0"\n titre "Mon projet Ether"\n lien rel: "stylesheet", href: "styles.css"\n corps\n entete classe: "header"\n titre1 "Bienvenue"\n principal classe: "main"\n paragraphe "Mon premier projet Ether!"\n pied classe: "footer"\n paragraphe "Cree avec Ether"\n'
286
+ const configContent = 'module.exports = {\n src: "src",\n out: "dist",\n public: "public",\n port: 3000,\n lang: "fr"\n}\n'
287
+
288
+ const indexContent = `// cible: html
289
+
290
+ document
291
+ tete
292
+ meta charset: "UTF-8"
293
+ meta name: "viewport", content: "width=device-width, initial-scale=1.0"
294
+ titre "Ether - Le langage intentionnel"
295
+ liaison rel: "icon", type: "image/svg+xml", href: "/favicon.svg"
296
+ liaison rel: "stylesheet", href: "styles.css"
297
+
298
+ corps
299
+ entete classe: "hero"
300
+ nav classe: "navbar"
301
+ div classe: "logo"
302
+ image src: "/images/logo.svg", alt: "Ether", classe: "logo-icon"
303
+ span "Ether"
304
+ liste-non-ordonnee classe: "nav-links"
305
+ element-liste
306
+ lien href: "#features"
307
+ "Fonctionnalités"
308
+ element-liste
309
+ lien href: "#examples"
310
+ "Exemples"
311
+ element-liste
312
+ lien href: "#docs"
313
+ "Documentation"
314
+
315
+ div classe: "hero-content"
316
+ titre1 classe: "hero-title"
317
+ "Écrivez du code"
318
+ saut-ligne
319
+ span classe: "gradient-text"
320
+ "comme vous pensez"
321
+ paragraphe classe: "hero-subtitle"
322
+ "Ether est un langage intentionnel qui compile vers HTML, CSS, JavaScript et plus encore. Naturel, intuitif, puissant."
323
+ div classe: "hero-buttons"
324
+ lien href: "#start", classe: "btn btn-primary"
325
+ "Commencer"
326
+ lien href: "#learn", classe: "btn btn-secondary"
327
+ "En savoir plus"
328
+
329
+ principal
330
+ section id: "features", classe: "features"
331
+ titre2 classe: "section-title"
332
+ "Pourquoi Ether ?"
333
+ div classe: "features-grid"
334
+ article classe: "feature-card"
335
+ div classe: "feature-icon"
336
+ "🎯"
337
+ titre3 "Intuitif"
338
+ paragraphe "Écrivez du code en langage naturel. Plus besoin de mémoriser des syntaxes complexes."
339
+ article classe: "feature-card"
340
+ div classe: "feature-icon"
341
+ "⚡"
342
+ titre3 "Rapide"
343
+ paragraphe "Compilation instantanée avec rechargement automatique en mode développement."
344
+ article classe: "feature-card"
345
+ div classe: "feature-icon"
346
+ "🌍"
347
+ titre3 "Multilingue"
348
+ paragraphe "Codez en français, anglais, espagnol et plus. Votre langue, votre code."
349
+ article classe: "feature-card"
350
+ div classe: "feature-icon"
351
+ "🔧"
352
+ titre3 "Flexible"
353
+ paragraphe "Compile vers HTML, CSS, JS, PHP, Python, SQL et bien d'autres langages."
354
+
355
+ section id: "examples", classe: "examples"
356
+ titre2 classe: "section-title"
357
+ "Simple et élégant"
358
+ div classe: "code-comparison"
359
+ div classe: "code-block"
360
+ div classe: "code-header"
361
+ "Ether"
362
+ pre
363
+ code
364
+ "document\\n corps\\n titre1 \\"Bonjour\\"\\n paragraphe \\"Le monde\\""
365
+ div classe: "code-arrow"
366
+ "→"
367
+ div classe: "code-block"
368
+ div classe: "code-header"
369
+ "HTML"
370
+ pre
371
+ code
372
+ "&lt;!DOCTYPE html&gt;\\n&lt;html&gt;\\n &lt;body&gt;\\n &lt;h1&gt;Bonjour&lt;/h1&gt;\\n &lt;p&gt;Le monde&lt;/p&gt;\\n &lt;/body&gt;\\n&lt;/html&gt;"
373
+
374
+ pied classe: "footer"
375
+ paragraphe
376
+ "Créé avec"
377
+ span classe: "heart"
378
+ " ♥ "
379
+ "par la communauté Ether"
380
+ paragraphe classe: "copyright"
381
+ "© 2025 Ether. MIT License."
382
+
383
+ script src: "app.js"
384
+ `
385
+
386
+ const stylesContent = `// cible: css
387
+
388
+ racine
389
+ couleur-primaire: "#6366f1"
390
+ couleur-secondaire: "#8b5cf6"
391
+ couleur-accent: "#06b6d4"
392
+ couleur-fond: "#0f0f23"
393
+ couleur-surface: "#1a1a2e"
394
+ couleur-texte: "#e2e8f0"
395
+ couleur-texte-pale: "#94a3b8"
396
+
397
+ *
398
+ marge: 0
399
+ remplissage: 0
400
+ modele-boite: border-box
401
+
402
+ corps
403
+ famille-police: "system-ui", "-apple-system", "sans-serif"
404
+ couleur-fond: var(--couleur-fond)
405
+ couleur: var(--couleur-texte)
406
+ hauteur-ligne: 1.6
407
+
408
+ .hero
409
+ min-hauteur: 100vh
410
+ fond: "linear-gradient(135deg, var(--couleur-fond) 0%, var(--couleur-surface) 100%)"
411
+ position: relative
412
+ debordement: cache
413
+
414
+ .navbar
415
+ affichage: flex
416
+ justifier-contenu: space-between
417
+ aligner-elements: center
418
+ remplissage: "1.5rem 5%"
419
+ position: fixed
420
+ largeur: 100%
421
+ haut: 0
422
+ z-index: 100
423
+ fond: "rgba(15, 15, 35, 0.9)"
424
+ flou-fond: "10px"
425
+
426
+ .logo
427
+ affichage: flex
428
+ aligner-elements: center
429
+ espace: "0.75rem"
430
+ taille-police: "1.5rem"
431
+ poids-police: 700
432
+
433
+ .logo-icon
434
+ largeur: "2.5rem"
435
+ hauteur: "2.5rem"
436
+
437
+ .nav-links
438
+ affichage: flex
439
+ liste-style: none
440
+ espace: "2rem"
441
+
442
+ .nav-links lien
443
+ couleur: var(--couleur-texte-pale)
444
+ decoration-texte: none
445
+ transition: "couleur 0.3s"
446
+ au survol
447
+ couleur: var(--couleur-primaire)
448
+
449
+ .hero-content
450
+ texte-aligne: center
451
+ remplissage: "12rem 5% 5rem"
452
+ max-largeur: "800px"
453
+ marge: "0 auto"
454
+
455
+ .hero-title
456
+ taille-police: "3.5rem"
457
+ poids-police: 800
458
+ marge-bas: "1.5rem"
459
+ hauteur-ligne: 1.2
460
+
461
+ .gradient-text
462
+ fond: "linear-gradient(90deg, var(--couleur-primaire), var(--couleur-accent))"
463
+ decoupe-fond: text
464
+ couleur: transparent
465
+
466
+ .hero-subtitle
467
+ taille-police: "1.25rem"
468
+ couleur: var(--couleur-texte-pale)
469
+ marge-bas: "2.5rem"
470
+ max-largeur: "600px"
471
+ marge-gauche: auto
472
+ marge-droite: auto
243
473
 
244
- const stylesContent = '// cible: css\n\n.header\n fond: bleu\n couleur: blanc\n padding: 2rem\n texte aligne: centre\n\n.main\n padding: 2rem\n\n.footer\n fond: gris fonce\n couleur: blanc\n padding: 1rem\n texte aligne: centre\n'
474
+ .hero-buttons
475
+ affichage: flex
476
+ espace: "1rem"
477
+ justifier-contenu: center
245
478
 
246
- const appContent = '// cible: js\n\nconsole.log("Ether ready!")\n'
479
+ .btn
480
+ remplissage: "0.875rem 2rem"
481
+ rayon-bordure: "0.5rem"
482
+ taille-police: "1rem"
483
+ poids-police: 600
484
+ decoration-texte: none
485
+ transition: "transform 0.2s, box-shadow 0.2s"
486
+ au survol
487
+ transformation: "translateY(-2px)"
488
+
489
+ .btn-primary
490
+ fond: "linear-gradient(90deg, var(--couleur-primaire), var(--couleur-secondaire))"
491
+ couleur: white
492
+ au survol
493
+ ombre-boite: "0 10px 30px rgba(99, 102, 241, 0.4)"
494
+
495
+ .btn-secondary
496
+ fond: transparent
497
+ couleur: var(--couleur-texte)
498
+ bordure: "2px solid var(--couleur-primaire)"
499
+ au survol
500
+ fond: "rgba(99, 102, 241, 0.1)"
501
+
502
+ .features
503
+ remplissage: "6rem 5%"
504
+
505
+ .section-title
506
+ texte-aligne: center
507
+ taille-police: "2.5rem"
508
+ marge-bas: "3rem"
509
+
510
+ .features-grid
511
+ affichage: grid
512
+ colonnes-grille: "repeat(auto-fit, minmax(250px, 1fr))"
513
+ espace: "2rem"
514
+ max-largeur: "1200px"
515
+ marge: "0 auto"
516
+
517
+ .feature-card
518
+ fond: var(--couleur-surface)
519
+ remplissage: "2rem"
520
+ rayon-bordure: "1rem"
521
+ texte-aligne: center
522
+ transition: "transform 0.3s"
523
+ au survol
524
+ transformation: "translateY(-5px)"
525
+
526
+ .feature-icon
527
+ taille-police: "3rem"
528
+ marge-bas: "1rem"
529
+
530
+ .feature-card titre3
531
+ marge-bas: "0.75rem"
532
+ taille-police: "1.25rem"
533
+
534
+ .feature-card paragraphe
535
+ couleur: var(--couleur-texte-pale)
536
+
537
+ .examples
538
+ remplissage: "6rem 5%"
539
+ fond: var(--couleur-surface)
540
+
541
+ .code-comparison
542
+ affichage: flex
543
+ aligner-elements: center
544
+ justifier-contenu: center
545
+ espace: "2rem"
546
+ flex-wrap: wrap
547
+ max-largeur: "1000px"
548
+ marge: "0 auto"
549
+
550
+ .code-block
551
+ fond: var(--couleur-fond)
552
+ rayon-bordure: "0.75rem"
553
+ debordement: cache
554
+ min-largeur: "300px"
555
+
556
+ .code-header
557
+ fond: "rgba(99, 102, 241, 0.2)"
558
+ remplissage: "0.75rem 1rem"
559
+ poids-police: 600
560
+ couleur: var(--couleur-primaire)
561
+
562
+ .code-block pre
563
+ remplissage: "1.5rem"
564
+ marge: 0
565
+
566
+ .code-block code
567
+ famille-police: "Fira Code", "Monaco", monospace
568
+ taille-police: "0.9rem"
569
+ blanc: pre
570
+
571
+ .code-arrow
572
+ taille-police: "2rem"
573
+ couleur: var(--couleur-primaire)
574
+
575
+ .footer
576
+ texte-aligne: center
577
+ remplissage: "3rem 5%"
578
+ fond: var(--couleur-fond)
579
+
580
+ .heart
581
+ couleur: "#ef4444"
582
+
583
+ .copyright
584
+ marge-haut: "0.5rem"
585
+ couleur: var(--couleur-texte-pale)
586
+ taille-police: "0.875rem"
587
+
588
+ @media (max-largeur: 768px)
589
+ .hero-title
590
+ taille-police: "2.5rem"
591
+ .nav-links
592
+ affichage: none
593
+ .code-arrow
594
+ transformation: "rotate(90deg)"
595
+ `
596
+
597
+ const appContent = `// cible: js
598
+
599
+ constante annee = nouveau Date().getFullYear()
600
+
601
+ fonction initialiser()
602
+ constante copyright = document.querySelector(".copyright")
603
+ si copyright
604
+ copyright.textContent = "© " + annee + " Ether. MIT License."
605
+
606
+ constante liens = document.querySelectorAll("a[href^='#']")
607
+ pour chaque lien dans liens
608
+ lien.addEventListener "click", fonction(e)
609
+ e.preventDefault()
610
+ constante cible = document.querySelector(this.getAttribute("href"))
611
+ si cible
612
+ cible.scrollIntoView({ behavior: "smooth" })
613
+
614
+ document.addEventListener "DOMContentLoaded", initialiser
615
+ `
247
616
 
248
617
  const packageContent = '{\n "name": "mon-projet-ether",\n "version": "1.0.0",\n "scripts": {\n "dev": "ether dev",\n "build": "ether build"\n }\n}\n'
249
618
 
@@ -259,7 +628,8 @@ function cmdInit() {
259
628
  console.log(' src/index.eth')
260
629
  console.log(' src/styles.eth')
261
630
  console.log(' src/app.eth')
262
- console.log(' public/images/')
631
+ console.log(' public/images/logo.svg')
632
+ console.log(' public/favicon.svg')
263
633
  console.log(' public/videos/')
264
634
  console.log(' ether.config.js')
265
635
  console.log(' package.json')
@@ -347,6 +717,7 @@ function cmdDev(options) {
347
717
  const config = loadConfig(options.config)
348
718
  const srcDir = path.resolve(process.cwd(), config.src)
349
719
  const outDir = path.resolve(process.cwd(), options.output || config.out)
720
+ const publicDir = config.public ? path.resolve(process.cwd(), config.public) : null
350
721
  const port = options.port || config.port || 3000
351
722
 
352
723
  if (!fs.existsSync(srcDir)) {
@@ -360,9 +731,12 @@ function cmdDev(options) {
360
731
 
361
732
  logInfo('Surveillance de ' + srcDir)
362
733
  logInfo('Sortie vers ' + outDir)
734
+ if (publicDir) {
735
+ logInfo('Fichiers statiques depuis ' + publicDir)
736
+ }
363
737
  console.log('')
364
738
 
365
- const devServer = startServer(outDir, port)
739
+ const devServer = startServer(outDir, publicDir, port)
366
740
 
367
741
  logInfo('Compilation initiale...')
368
742
  cmdBuild(Object.assign({}, options, { quiet: true }))
@@ -99,7 +99,8 @@ class HTMLGenerator {
99
99
  'corps': 'body',
100
100
  'titre': 'title',
101
101
  'meta': 'meta',
102
- 'lien': 'link',
102
+ 'lien': 'a',
103
+ 'liaison': 'link',
103
104
  'style': 'style',
104
105
  'script': 'script',
105
106
  'entete': 'header',
@@ -125,7 +126,6 @@ class HTMLGenerator {
125
126
  'div': 'div',
126
127
  'span': 'span',
127
128
  'portee': 'span',
128
- 'lien': 'a',
129
129
  'image': 'img',
130
130
  'figure': 'figure',
131
131
  'legende': 'figcaption',
@@ -416,8 +416,17 @@ class HTMLGenerator {
416
416
  }
417
417
 
418
418
  generateElement(node) {
419
- const tag = this.translateTag(node.tag || node.tagName || node.name)
420
- const attributes = this.generateAttributes(node.attributes || node.attrs || {})
419
+ let tag = this.translateTag(node.tag || node.tagName || node.name)
420
+ const attrs = node.attributes || node.attrs || {}
421
+
422
+ if (tag === 'a' && attrs.rel) {
423
+ const linkRels = ['stylesheet', 'icon', 'preconnect', 'prefetch', 'preload', 'dns-prefetch', 'canonical', 'alternate', 'manifest', 'apple-touch-icon']
424
+ if (linkRels.some(r => attrs.rel.includes(r))) {
425
+ tag = 'link'
426
+ }
427
+ }
428
+
429
+ const attributes = this.generateAttributes(attrs)
421
430
  const isVoid = this.voidElements.includes(tag.toLowerCase())
422
431
 
423
432
  if (isVoid) {
@@ -427,7 +436,7 @@ class HTMLGenerator {
427
436
 
428
437
  const children = node.children || node.content || []
429
438
  const hasChildren = Array.isArray(children) && children.length > 0
430
- const textContent = typeof children === 'string' ? children :
439
+ const textContent = typeof children === 'string' ? children :
431
440
  (node.text || node.textContent || null)
432
441
 
433
442
  if (textContent && !hasChildren) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ether-code",
3
- "version": "0.2.9",
3
+ "version": "0.3.1",
4
4
  "description": "Ether - Le langage intentionnel",
5
5
  "main": "cli/compiler.js",
6
6
  "bin": {