sommark 5.0.2 → 5.0.3

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.
@@ -18,7 +18,7 @@ export function registerHostSettings(settings) {
18
18
  hostSettings = settings || {};
19
19
  }
20
20
 
21
- const version = "5.0.2";
21
+ const version = "5.0.3";
22
22
 
23
23
  const SomMark = {
24
24
  version,
package/core/lexer.js CHANGED
@@ -346,13 +346,6 @@ function lexer(src, filename = "anonymous") {
346
346
  // LOGIC BLOCKS (${ ... }$) — explicit: static/runtime ${ }$ shorthand: ${ }$ = static ${ }$
347
347
  if (char === "$" && next === "{") {
348
348
  {
349
- const hasExplicitKeyword = last_non_junk_type === TOKEN_TYPES.STATIC_KEYWORD || last_non_junk_type === TOKEN_TYPES.RUNTIME_KEYWORD;
350
- if (!hasExplicitKeyword) {
351
- // Zero-width: synthetic token has no source presence, must not shift position
352
- tokens.push({ type: TOKEN_TYPES.STATIC_KEYWORD, value: "static", source: filename, range: { start: { line, character }, end: { line, character } } });
353
- prev_type = TOKEN_TYPES.STATIC_KEYWORD;
354
- last_non_junk_type = TOKEN_TYPES.STATIC_KEYWORD;
355
- }
356
349
  addToken(TOKEN_TYPES.LOGIC_OPEN, "${");
357
350
  i += 2;
358
351
 
package/core/parser.js CHANGED
@@ -389,6 +389,22 @@ function parseValue(tokens, i, placeholders = {}, variables = {}, allowLogic = t
389
389
  nextI++;
390
390
  }
391
391
 
392
+ return [node, nextI, false];
393
+ } else if (current_token(tokens, i).type === TOKEN_TYPES.LOGIC_OPEN) {
394
+ if (!allowLogic) {
395
+ parserError(errorMessage(tokens, i, "literal value", "", "Logic blocks are not allowed in this context."));
396
+ }
397
+ let nextI = i + 1;
398
+ const logicToken = current_token(tokens, nextI);
399
+ const node = makeLogicNode(STATIC_LOGIC);
400
+ node.code = logicToken ? logicToken.value : "";
401
+ node.range = logicToken ? logicToken.range : current_token(tokens, i).range;
402
+ nextI++;
403
+
404
+ if (current_token(tokens, nextI) && current_token(tokens, nextI).type === TOKEN_TYPES.LOGIC_CLOSE) {
405
+ nextI++;
406
+ }
407
+
392
408
  return [node, nextI, false];
393
409
  } else if (current_token(tokens, i).type === TOKEN_TYPES.PREFIX_V) {
394
410
  i++; // consume PREFIX_V keyword
@@ -938,6 +954,28 @@ function parseNode(tokens, i, filename = null, placeholders = {}, variables = {}
938
954
  return [node, nextI];
939
955
  }
940
956
  // ========================================================================== //
957
+ // Bare Logic Block (${ }$ without explicit static/runtime — defaults to static)
958
+ // ========================================================================== //
959
+ else if (current_token(tokens, i) && current_token(tokens, i).type === TOKEN_TYPES.LOGIC_OPEN) {
960
+ global_static_logic_count++;
961
+ let nextI = i + 1;
962
+ const logicToken = current_token(tokens, nextI);
963
+ const node = makeLogicNode(STATIC_LOGIC);
964
+ node.code = logicToken ? logicToken.value : "";
965
+ node.depth = depth;
966
+ node.range = {
967
+ start: current_token(tokens, i).range.start,
968
+ end: logicToken ? logicToken.range.end : current_token(tokens, i).range.end
969
+ };
970
+ nextI++;
971
+
972
+ if (current_token(tokens, nextI) && current_token(tokens, nextI).type === TOKEN_TYPES.LOGIC_CLOSE) {
973
+ nextI++;
974
+ }
975
+
976
+ return [node, nextI];
977
+ }
978
+ // ========================================================================== //
941
979
  // Text or Placeholder //
942
980
  // ========================================================================== //
943
981
  else if (
@@ -801,13 +801,6 @@ function lexer(src, filename = "anonymous") {
801
801
  // LOGIC BLOCKS (${ ... }$) — explicit: static/runtime ${ }$ shorthand: ${ }$ = static ${ }$
802
802
  if (char === "$" && next === "{") {
803
803
  {
804
- const hasExplicitKeyword = last_non_junk_type === TOKEN_TYPES.STATIC_KEYWORD || last_non_junk_type === TOKEN_TYPES.RUNTIME_KEYWORD;
805
- if (!hasExplicitKeyword) {
806
- // Zero-width: synthetic token has no source presence, must not shift position
807
- tokens.push({ type: TOKEN_TYPES.STATIC_KEYWORD, value: "static", source: filename, range: { start: { line, character }, end: { line, character } } });
808
- TOKEN_TYPES.STATIC_KEYWORD;
809
- last_non_junk_type = TOKEN_TYPES.STATIC_KEYWORD;
810
- }
811
804
  addToken(TOKEN_TYPES.LOGIC_OPEN, "${");
812
805
  i += 2;
813
806
 
@@ -1761,6 +1754,22 @@ function parseValue(tokens, i, placeholders = {}, variables = {}, allowLogic = t
1761
1754
  nextI++;
1762
1755
  }
1763
1756
 
1757
+ return [node, nextI, false];
1758
+ } else if (current_token(tokens, i).type === TOKEN_TYPES.LOGIC_OPEN) {
1759
+ if (!allowLogic) {
1760
+ parserError(errorMessage(tokens, i, "literal value", "", "Logic blocks are not allowed in this context."));
1761
+ }
1762
+ let nextI = i + 1;
1763
+ const logicToken = current_token(tokens, nextI);
1764
+ const node = makeLogicNode(STATIC_LOGIC);
1765
+ node.code = logicToken ? logicToken.value : "";
1766
+ node.range = logicToken ? logicToken.range : current_token(tokens, i).range;
1767
+ nextI++;
1768
+
1769
+ if (current_token(tokens, nextI) && current_token(tokens, nextI).type === TOKEN_TYPES.LOGIC_CLOSE) {
1770
+ nextI++;
1771
+ }
1772
+
1764
1773
  return [node, nextI, false];
1765
1774
  } else if (current_token(tokens, i).type === TOKEN_TYPES.PREFIX_V) {
1766
1775
  i++; // consume PREFIX_V keyword
@@ -2269,6 +2278,27 @@ function parseNode(tokens, i, filename = null, placeholders = {}, variables = {}
2269
2278
  return [node, nextI];
2270
2279
  }
2271
2280
  // ========================================================================== //
2281
+ // Bare Logic Block (${ }$ without explicit static/runtime — defaults to static)
2282
+ // ========================================================================== //
2283
+ else if (current_token(tokens, i) && current_token(tokens, i).type === TOKEN_TYPES.LOGIC_OPEN) {
2284
+ let nextI = i + 1;
2285
+ const logicToken = current_token(tokens, nextI);
2286
+ const node = makeLogicNode(STATIC_LOGIC);
2287
+ node.code = logicToken ? logicToken.value : "";
2288
+ node.depth = depth;
2289
+ node.range = {
2290
+ start: current_token(tokens, i).range.start,
2291
+ end: logicToken ? logicToken.range.end : current_token(tokens, i).range.end
2292
+ };
2293
+ nextI++;
2294
+
2295
+ if (current_token(tokens, nextI) && current_token(tokens, nextI).type === TOKEN_TYPES.LOGIC_CLOSE) {
2296
+ nextI++;
2297
+ }
2298
+
2299
+ return [node, nextI];
2300
+ }
2301
+ // ========================================================================== //
2272
2302
  // Text or Placeholder //
2273
2303
  // ========================================================================== //
2274
2304
  else if (
@@ -8592,7 +8622,7 @@ function registerHostSettings(settings) {
8592
8622
  hostSettings = settings || {};
8593
8623
  }
8594
8624
 
8595
- const version = "5.0.2";
8625
+ const version = "5.0.3";
8596
8626
 
8597
8627
  const SomMark$1 = {
8598
8628
  version,
@@ -801,13 +801,6 @@ function lexer(src, filename = "anonymous") {
801
801
  // LOGIC BLOCKS (${ ... }$) — explicit: static/runtime ${ }$ shorthand: ${ }$ = static ${ }$
802
802
  if (char === "$" && next === "{") {
803
803
  {
804
- const hasExplicitKeyword = last_non_junk_type === TOKEN_TYPES.STATIC_KEYWORD || last_non_junk_type === TOKEN_TYPES.RUNTIME_KEYWORD;
805
- if (!hasExplicitKeyword) {
806
- // Zero-width: synthetic token has no source presence, must not shift position
807
- tokens.push({ type: TOKEN_TYPES.STATIC_KEYWORD, value: "static", source: filename, range: { start: { line, character }, end: { line, character } } });
808
- TOKEN_TYPES.STATIC_KEYWORD;
809
- last_non_junk_type = TOKEN_TYPES.STATIC_KEYWORD;
810
- }
811
804
  addToken(TOKEN_TYPES.LOGIC_OPEN, "${");
812
805
  i += 2;
813
806
 
@@ -1761,6 +1754,22 @@ function parseValue(tokens, i, placeholders = {}, variables = {}, allowLogic = t
1761
1754
  nextI++;
1762
1755
  }
1763
1756
 
1757
+ return [node, nextI, false];
1758
+ } else if (current_token(tokens, i).type === TOKEN_TYPES.LOGIC_OPEN) {
1759
+ if (!allowLogic) {
1760
+ parserError(errorMessage(tokens, i, "literal value", "", "Logic blocks are not allowed in this context."));
1761
+ }
1762
+ let nextI = i + 1;
1763
+ const logicToken = current_token(tokens, nextI);
1764
+ const node = makeLogicNode(STATIC_LOGIC);
1765
+ node.code = logicToken ? logicToken.value : "";
1766
+ node.range = logicToken ? logicToken.range : current_token(tokens, i).range;
1767
+ nextI++;
1768
+
1769
+ if (current_token(tokens, nextI) && current_token(tokens, nextI).type === TOKEN_TYPES.LOGIC_CLOSE) {
1770
+ nextI++;
1771
+ }
1772
+
1764
1773
  return [node, nextI, false];
1765
1774
  } else if (current_token(tokens, i).type === TOKEN_TYPES.PREFIX_V) {
1766
1775
  i++; // consume PREFIX_V keyword
@@ -2269,6 +2278,27 @@ function parseNode(tokens, i, filename = null, placeholders = {}, variables = {}
2269
2278
  return [node, nextI];
2270
2279
  }
2271
2280
  // ========================================================================== //
2281
+ // Bare Logic Block (${ }$ without explicit static/runtime — defaults to static)
2282
+ // ========================================================================== //
2283
+ else if (current_token(tokens, i) && current_token(tokens, i).type === TOKEN_TYPES.LOGIC_OPEN) {
2284
+ let nextI = i + 1;
2285
+ const logicToken = current_token(tokens, nextI);
2286
+ const node = makeLogicNode(STATIC_LOGIC);
2287
+ node.code = logicToken ? logicToken.value : "";
2288
+ node.depth = depth;
2289
+ node.range = {
2290
+ start: current_token(tokens, i).range.start,
2291
+ end: logicToken ? logicToken.range.end : current_token(tokens, i).range.end
2292
+ };
2293
+ nextI++;
2294
+
2295
+ if (current_token(tokens, nextI) && current_token(tokens, nextI).type === TOKEN_TYPES.LOGIC_CLOSE) {
2296
+ nextI++;
2297
+ }
2298
+
2299
+ return [node, nextI];
2300
+ }
2301
+ // ========================================================================== //
2272
2302
  // Text or Placeholder //
2273
2303
  // ========================================================================== //
2274
2304
  else if (
@@ -451,13 +451,6 @@ function lexer(src, filename = "anonymous") {
451
451
  // LOGIC BLOCKS (${ ... }$) — explicit: static/runtime ${ }$ shorthand: ${ }$ = static ${ }$
452
452
  if (char === "$" && next === "{") {
453
453
  {
454
- const hasExplicitKeyword = last_non_junk_type === TOKEN_TYPES.STATIC_KEYWORD || last_non_junk_type === TOKEN_TYPES.RUNTIME_KEYWORD;
455
- if (!hasExplicitKeyword) {
456
- // Zero-width: synthetic token has no source presence, must not shift position
457
- tokens.push({ type: TOKEN_TYPES.STATIC_KEYWORD, value: "static", source: filename, range: { start: { line, character }, end: { line, character } } });
458
- TOKEN_TYPES.STATIC_KEYWORD;
459
- last_non_junk_type = TOKEN_TYPES.STATIC_KEYWORD;
460
- }
461
454
  addToken(TOKEN_TYPES.LOGIC_OPEN, "${");
462
455
  i += 2;
463
456
 
@@ -472,13 +472,6 @@ function lexer(src, filename = "anonymous") {
472
472
  // LOGIC BLOCKS (${ ... }$) — explicit: static/runtime ${ }$ shorthand: ${ }$ = static ${ }$
473
473
  if (char === "$" && next === "{") {
474
474
  {
475
- const hasExplicitKeyword = last_non_junk_type === TOKEN_TYPES.STATIC_KEYWORD || last_non_junk_type === TOKEN_TYPES.RUNTIME_KEYWORD;
476
- if (!hasExplicitKeyword) {
477
- // Zero-width: synthetic token has no source presence, must not shift position
478
- tokens.push({ type: TOKEN_TYPES.STATIC_KEYWORD, value: "static", source: filename, range: { start: { line, character }, end: { line, character } } });
479
- TOKEN_TYPES.STATIC_KEYWORD;
480
- last_non_junk_type = TOKEN_TYPES.STATIC_KEYWORD;
481
- }
482
475
  addToken(TOKEN_TYPES.LOGIC_OPEN, "${");
483
476
  i += 2;
484
477
 
@@ -1316,6 +1309,22 @@ function parseValue(tokens, i, placeholders = {}, variables = {}, allowLogic = t
1316
1309
  nextI++;
1317
1310
  }
1318
1311
 
1312
+ return [node, nextI, false];
1313
+ } else if (current_token(tokens, i).type === TOKEN_TYPES.LOGIC_OPEN) {
1314
+ if (!allowLogic) {
1315
+ parserError(errorMessage(tokens, i, "literal value", "", "Logic blocks are not allowed in this context."));
1316
+ }
1317
+ let nextI = i + 1;
1318
+ const logicToken = current_token(tokens, nextI);
1319
+ const node = makeLogicNode(STATIC_LOGIC);
1320
+ node.code = logicToken ? logicToken.value : "";
1321
+ node.range = logicToken ? logicToken.range : current_token(tokens, i).range;
1322
+ nextI++;
1323
+
1324
+ if (current_token(tokens, nextI) && current_token(tokens, nextI).type === TOKEN_TYPES.LOGIC_CLOSE) {
1325
+ nextI++;
1326
+ }
1327
+
1319
1328
  return [node, nextI, false];
1320
1329
  } else if (current_token(tokens, i).type === TOKEN_TYPES.PREFIX_V) {
1321
1330
  i++; // consume PREFIX_V keyword
@@ -1824,6 +1833,27 @@ function parseNode(tokens, i, filename = null, placeholders = {}, variables = {}
1824
1833
  return [node, nextI];
1825
1834
  }
1826
1835
  // ========================================================================== //
1836
+ // Bare Logic Block (${ }$ without explicit static/runtime — defaults to static)
1837
+ // ========================================================================== //
1838
+ else if (current_token(tokens, i) && current_token(tokens, i).type === TOKEN_TYPES.LOGIC_OPEN) {
1839
+ let nextI = i + 1;
1840
+ const logicToken = current_token(tokens, nextI);
1841
+ const node = makeLogicNode(STATIC_LOGIC);
1842
+ node.code = logicToken ? logicToken.value : "";
1843
+ node.depth = depth;
1844
+ node.range = {
1845
+ start: current_token(tokens, i).range.start,
1846
+ end: logicToken ? logicToken.range.end : current_token(tokens, i).range.end
1847
+ };
1848
+ nextI++;
1849
+
1850
+ if (current_token(tokens, nextI) && current_token(tokens, nextI).type === TOKEN_TYPES.LOGIC_CLOSE) {
1851
+ nextI++;
1852
+ }
1853
+
1854
+ return [node, nextI];
1855
+ }
1856
+ // ========================================================================== //
1827
1857
  // Text or Placeholder //
1828
1858
  // ========================================================================== //
1829
1859
  else if (
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sommark",
3
- "version": "5.0.2",
3
+ "version": "5.0.3",
4
4
  "description": "SomMark is a template language that compiles to multiple output formats — HTML, JSON, YAML, TOML, CSV, Markdown, XML, and more.",
5
5
  "main": "index.js",
6
6
  "files": [