ether-code 0.9.7 → 0.9.9

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.9.7'
9
+ const VERSION = '0.9.9'
10
10
 
11
11
  const COLORS = {
12
12
  reset: '\x1b[0m',
@@ -589,6 +589,12 @@ class HTMLGenerator {
589
589
  case 'include':
590
590
  this.generateInclude(node)
591
591
  break
592
+ case 'EtherCSS':
593
+ this.generateEtherCSS(node)
594
+ break
595
+ case 'EtherJS':
596
+ this.generateEtherJS(node)
597
+ break
592
598
  default:
593
599
  if (node.tag || node.tagName || node.name) {
594
600
  this.generateElement(node)
@@ -1069,6 +1075,58 @@ class HTMLGenerator {
1069
1075
  })
1070
1076
  return result.join('\n')
1071
1077
  }
1078
+
1079
+ generateEtherCSS(node) {
1080
+ if (!node.source) return
1081
+
1082
+ try {
1083
+ const { EtherParserCSS } = require('./ether-parser-css')
1084
+ const { CSSGenerator } = require('./css-generator')
1085
+
1086
+ const cssParser = new EtherParserCSS()
1087
+ const cssAst = cssParser.parse(node.source)
1088
+
1089
+ const cssGenerator = new CSSGenerator()
1090
+ cssGenerator.loadI18n('./i18n-css.json')
1091
+ const cssOutput = cssGenerator.generate(cssAst)
1092
+
1093
+ if (cssOutput) {
1094
+ const lines = cssOutput.split('\n')
1095
+ for (const line of lines) {
1096
+ this.writeLine(line)
1097
+ }
1098
+ }
1099
+ } catch (e) {
1100
+ this.writeLine('/* Erreur de compilation CSS: ' + e.message + ' */')
1101
+ this.writeLine(node.source)
1102
+ }
1103
+ }
1104
+
1105
+ generateEtherJS(node) {
1106
+ if (!node.source) return
1107
+
1108
+ try {
1109
+ const { EtherParserJS } = require('./ether-parser-js')
1110
+ const { JSGenerator } = require('./js-generator')
1111
+
1112
+ const jsParser = new EtherParserJS()
1113
+ const jsAst = jsParser.parse(node.source)
1114
+
1115
+ const jsGenerator = new JSGenerator()
1116
+ jsGenerator.loadI18n('./i18n-js.json')
1117
+ const jsOutput = jsGenerator.generate(jsAst)
1118
+
1119
+ if (jsOutput) {
1120
+ const lines = jsOutput.split('\n')
1121
+ for (const line of lines) {
1122
+ this.writeLine(line)
1123
+ }
1124
+ }
1125
+ } catch (e) {
1126
+ this.writeLine('// Erreur de compilation JS: ' + e.message)
1127
+ this.writeLine(node.source)
1128
+ }
1129
+ }
1072
1130
  }
1073
1131
 
1074
1132
  module.exports = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ether-code",
3
- "version": "0.9.7",
3
+ "version": "0.9.9",
4
4
  "description": "Ether - Le langage intentionnel",
5
5
  "main": "cli/compiler.js",
6
6
  "bin": {
@@ -118,14 +118,14 @@ class EtherParserHTML extends EtherParserBase {
118
118
  'lecture': ['seule', 'auto'],
119
119
  'nouvelle': ['fenetre'],
120
120
  'a': ['popup'],
121
- 'jeu': ['caracteres', 'caractères'],
121
+ 'jeu': ['caracteres', 'caractères'],
122
122
  'equivalent': ['http'],
123
- 'équivalent': ['http'],
123
+ 'équivalent': ['http'],
124
124
  'fusion': ['colonnes', 'lignes'],
125
- 'plein': ['ecran', 'écran'],
125
+ 'plein': ['ecran', 'écran'],
126
126
  'bac': ['sable'],
127
- 'origine': ['croisee', 'croisée'],
128
- 'sources': ['reactives', 'réactives']
127
+ 'origine': ['croisee', 'croisée'],
128
+ 'sources': ['reactives', 'réactives']
129
129
  }
130
130
 
131
131
  while (!this.isAtEnd()) {
@@ -172,6 +172,13 @@ class EtherParserHTML extends EtherParserBase {
172
172
  this.advance()
173
173
  }
174
174
 
175
+ if (this.current() && this.current().type === TokenType.COMMA) {
176
+ this.advance()
177
+ }
178
+ } else if (nextToken && nextToken.type === TokenType.STRING) {
179
+ attributes[attrName] = nextToken.value.replace(/^["']|["']$/g, '')
180
+ this.advance()
181
+
175
182
  if (this.current() && this.current().type === TokenType.COMMA) {
176
183
  this.advance()
177
184
  }
@@ -203,9 +210,22 @@ class EtherParserHTML extends EtherParserBase {
203
210
  const rawContentTags = ['script', 'style']
204
211
  const isRawContent = rawContentTags.includes(tag)
205
212
  const isScript = tag === 'script'
213
+ const isStyle = tag === 'style'
206
214
 
207
215
  if (this.match(TokenType.INDENT)) {
208
- if (isRawContent) {
216
+ if (isStyle) {
217
+ const etherSource = this.collectEtherBlock()
218
+ children.push({
219
+ type: 'EtherCSS',
220
+ source: etherSource
221
+ })
222
+ } else if (isScript) {
223
+ const etherSource = this.collectEtherBlock()
224
+ children.push({
225
+ type: 'EtherJS',
226
+ source: etherSource
227
+ })
228
+ } else if (isRawContent) {
209
229
  let rawText = []
210
230
  while (!this.isAtEnd()) {
211
231
  const current = this.current()
@@ -227,11 +247,7 @@ class EtherParserHTML extends EtherParserBase {
227
247
  }
228
248
 
229
249
  if (current && current.type === TokenType.STRING) {
230
- if (isScript) {
231
- rawText.push("'" + current.value.replace(/'/g, "\\'") + "'")
232
- } else {
233
- rawText.push(current.value)
234
- }
250
+ rawText.push(current.value)
235
251
  this.advance()
236
252
  continue
237
253
  }
@@ -321,6 +337,84 @@ class EtherParserHTML extends EtherParserBase {
321
337
  return String(token.value)
322
338
  }
323
339
 
340
+ collectEtherBlock() {
341
+ const lines = []
342
+ let currentLine = []
343
+ let indentDepth = 1
344
+
345
+ while (!this.isAtEnd()) {
346
+ const current = this.current()
347
+
348
+ if (current && current.type === TokenType.DEDENT) {
349
+ if (currentLine.length > 0) {
350
+ lines.push(' '.repeat(Math.max(0, indentDepth - 1)) + this.joinTokens(currentLine))
351
+ currentLine = []
352
+ }
353
+ indentDepth--
354
+ this.advance()
355
+ if (indentDepth <= 0) {
356
+ break
357
+ }
358
+ continue
359
+ }
360
+
361
+ if (current && current.type === TokenType.INDENT) {
362
+ if (currentLine.length > 0) {
363
+ lines.push(' '.repeat(Math.max(0, indentDepth - 1)) + this.joinTokens(currentLine))
364
+ currentLine = []
365
+ }
366
+ indentDepth++
367
+ this.advance()
368
+ continue
369
+ }
370
+
371
+ if (current && current.type === TokenType.NEWLINE) {
372
+ if (currentLine.length > 0) {
373
+ lines.push(' '.repeat(Math.max(0, indentDepth - 1)) + this.joinTokens(currentLine))
374
+ currentLine = []
375
+ }
376
+ this.advance()
377
+ continue
378
+ }
379
+
380
+ if (!current || current.type === TokenType.EOF) break
381
+
382
+ if (current.type === TokenType.STRING) {
383
+ currentLine.push('"' + current.value + '"')
384
+ } else {
385
+ currentLine.push(this.tokenToString(current))
386
+ }
387
+ this.advance()
388
+ }
389
+
390
+ if (currentLine.length > 0) {
391
+ lines.push(' '.repeat(Math.max(0, indentDepth - 1)) + this.joinTokens(currentLine))
392
+ }
393
+
394
+ return lines.join('\n')
395
+ }
396
+
397
+ joinTokens(tokens) {
398
+ let result = ''
399
+ for (let i = 0; i < tokens.length; i++) {
400
+ const token = tokens[i]
401
+ const prevToken = i > 0 ? tokens[i - 1] : null
402
+
403
+ const noSpaceBefore = [':', ',', ')', ']']
404
+ const noSpaceAfter = ['.', '#', '(', '[', '::', '-']
405
+
406
+ if (i > 0) {
407
+ const needSpace = !noSpaceBefore.includes(token) && !noSpaceAfter.includes(prevToken)
408
+ if (needSpace) {
409
+ result += ' '
410
+ }
411
+ }
412
+
413
+ result += token
414
+ }
415
+ return result
416
+ }
417
+
324
418
  processCompoundTags(tagName) {
325
419
  const nextToken = this.current()
326
420
  if (!nextToken || nextToken.type !== TokenType.IDENTIFIER) {
@@ -529,6 +623,7 @@ class EtherParserHTML extends EtherParserBase {
529
623
  'retour ligne possible': 'wbr',
530
624
  'carte image': 'map',
531
625
  'script': 'script',
626
+ 'style': 'style',
532
627
  'details': 'details',
533
628
  'resume': 'summary',
534
629
  'dialogue': 'dialog',
@@ -585,4 +680,4 @@ class EtherParserHTML extends EtherParserBase {
585
680
  }
586
681
  }
587
682
 
588
- module.exports = { EtherParserHTML }
683
+ module.exports = { EtherParserHTML }