fscss 1.1.22 → 1.1.23

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # FSCSS
2
2
 
3
- **FSCSS (Figured Shorthand Cascading Style Sheets)** is a powerful CSS preprocessor that extends CSS with shorthand utilities, variables, functions, and advanced transformations.
3
+ **FSCSS (Figured Shorthand Cascading Style Sheets)** is a CSS preprocessor that extends CSS with shorthand utilities, variables, functions, and advanced transformations.
4
4
 
5
5
  It is designed to make styling faster, reusable, and expressive — without losing standard CSS compatibility.
6
6
 
@@ -37,7 +37,7 @@ It is designed to make styling faster, reusable, and expressive — without losi
37
37
 
38
38
  - `$var` → standard variables
39
39
  - `str()` → inline expandable text variables
40
- - fallback operator → `$ / var || fallback`
40
+ - fallback operator → `$/var || fallback`
41
41
  ```css
42
42
  $color: red;
43
43
 
@@ -90,7 +90,7 @@ $color: red;
90
90
  - Vendor prefixing
91
91
  -
92
92
  ```css
93
- $(@keyframes trans, .box &[3s ease-in infinite]){
93
+ $(@keyframes trans, .box, #hero .card, #dashboard .card &[3s ease-in infinite]){
94
94
  from{ width:0; }
95
95
  to{ width:200px; }
96
96
  }
@@ -131,7 +131,7 @@ https://github.com/fscss-ttr/fscss-modules/
131
131
  ## Example
132
132
 
133
133
  ```css
134
- @import((flex-x) from flex-control/fscss)
134
+ @import((flex-x) from flex-control)
135
135
 
136
136
  @arr colors[#1E2783, #8C29B2, #C41348]
137
137
 
@@ -154,7 +154,7 @@ npm install fscss
154
154
  ```
155
155
  ---
156
156
 
157
- ** Browser Usage**
157
+ **Browser Usage**
158
158
  ```html
159
159
  <script src="https://cdn.jsdelivr.net/npm/fscss@latest/exec.min.js" defer></script>
160
160
  ```
@@ -165,7 +165,7 @@ npm install fscss
165
165
  **Or:**
166
166
  ```html
167
167
  <style>
168
- @import(exec(style.fscss))
168
+ @import(exec("style.fscss"))
169
169
  </style>
170
170
  ```
171
171
  > Use "defer" or "async" when loading the script.
package/e/exec.js CHANGED
@@ -1,4 +1,3 @@
1
- /* Figsh-fscss light, source v3., fscss.devtem.org */
2
1
  function exec({ type = 'text', content, onError, onSuccess }) {
3
2
 
4
3
  // 1. Validation
@@ -49,8 +48,6 @@ function exec({ type = 'text', content, onError, onSuccess }) {
49
48
  function xfscssProcessorWrap(){(async ()=>{
50
49
  /**
51
50
  * FSCSS Processing Script
52
- * Note: Use official npm package/CDN instead of copying this directly.
53
- * visit: (fscss.devtem.org) for support.
54
51
  */
55
52
 
56
53
  function procCntInit(ntc,stc){
@@ -368,24 +365,23 @@ function procExC(css) {
368
365
 
369
366
  return modifiedCSS.trim();
370
367
  }
371
- async function initlibraries(css){
372
- css = css.replace(/exec\(\s*_init\sisjs\s*\)/g, "exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/isjs.fscss)");
373
- css = css.replace(/exec\(\s*_init\sthemes\s*\)/g, "exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/trshapes.fthemes.fscss)")
374
- css = css.replace(/exec\(_init\sarray1to500\s*\)/g, "exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/1to500.fscss)");
375
- css = css.replace(/exec\(_init\s+([\w\d\._—\-\%\*\+\&\$\=]+)(?:\/([\w\-]+))?\s*\)/g, (match, impName, impType)=>{
376
- if(!impType){
377
- //`
378
- return `exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${impName}.fscss)`;
368
+
369
+ async function initlibraries(css) {
370
+ const xfr = 'https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/';
371
+ css = css.replace(/exec\(_init\s+([\w\d\._—\-\%\*\+\@\&\$\=]+)(?:\/([\w\-]+))?\s*\)/g, (match, impName, impType) => {
372
+ if (!impType) {
373
+ //`
374
+ return `exec(${xfr+impName}.fscss)`;
379
375
  }
380
- return `exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${impName}.${impType})`;
376
+ return `exec(${xfr+impName}.${impType})`;
381
377
  });
382
- css = css.replace(/(\@import\((?:\s+)?(?:exec)?\((?:[\w\d\.\@\—\-_*\#\$\s\,]+)\)(?:\s+)?from(?:\s+)?)([\w\d\._—\-\%\*\+\&\$\=]+)(?:\/([\w\-]+))?(?:\s+)?\)/g, (match, state, impName, impType) => {
383
- if (!impType) {
384
- return `${state}'https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${impName}.fscss')`;
385
- }
386
- return `${state}'https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${impName}.${impType}')`;
387
- });
388
- return css;
378
+ css = css.replace(/(\@import\((?:\s+)?(?:exec)?\((?:[\w\d\.\@\—\-_*\#\$\s\,]+)\)(?:\s+)?from(?:\s+)?)([\w\d\._—\-\%\*\+\@\&\$\=]+)(?:\/([\w\-]+))?(?:\s+)?\)/g, (match, state, impName, impType) => {
379
+ if (!impType) {
380
+ return `${state}'${xfr+impName}.fscss')`;
381
+ }
382
+ return `${state}'${xfr+impName}.${impType}')`;
383
+ });
384
+ return css;
389
385
  }
390
386
 
391
387
  function procVar(vcss) {
@@ -460,11 +456,14 @@ function procVar(vcss) {
460
456
  return result.css;
461
457
  }
462
458
 
459
+ let defExdepth = 0;
463
460
 
464
461
  function procDef(fscss) {
462
+
465
463
  const pRegex = /@define\s+([\w\_\-\—]+)\s*\(([^)]*)\)\s*\$?\{\s*(?:"([^"]*)"|'([^']*)'|`([^`]*)`|([^\}^\{]*?))\s*\}/g;
466
464
 
467
465
  // First, extract all @define blocks and store them in defExfscss. FIGSH-FSCSS
466
+
468
467
  let processed = fscss.replace(pRegex,
469
468
  (match, name, paramsStr, body1, body2, body3, body4) => {
470
469
  const params = paramsStr.split(',').map(p =>p.trim()).filter(p =>p);
@@ -475,6 +474,7 @@ function procDef(fscss) {
475
474
  );
476
475
 
477
476
  // Now replace all @name(...) usages with their expanded bodies. FIGSH-FSCSS
477
+
478
478
  processed = processed.replace(
479
479
  /@([\w\_\-\—]+)\s*\(([\s\S]*?)\)/g,
480
480
  (match, name, argsStr) => {
@@ -505,10 +505,48 @@ const dfv = xfVal[1]?xfVal[1]:'';
505
505
  return result;
506
506
  }
507
507
  );
508
- if(!pRegex.test(processed)) return processed;
509
508
 
510
- return procDef(processed);
509
+
510
+ if (!pRegex.test(processed)||defExdepth >= 10) {
511
+ for(let g=0;g<10;g++){
512
+ processed = processed.replace(
513
+ /@([\w\_\-\—]+)\s*\(([\s\S]*?)\)/g,
514
+ (match, name, argsStr) => {
515
+ const def = defExfscss[name];
516
+ if (!def){
517
+ return match;
518
+ }// Leave unknown Def macros unchanged. FIGSH-FSCSS
519
+
520
+ const args = argsStr?.split(',').map(a => a.trim());
521
+ if(args[0]==='') args[0] = undefined;
522
+ let result = def.body;
523
+
524
+ /* Replace each @use(param) with the corresponding argument. FIGSH-FSCSS */
525
+ let xfVal = [];
526
+ def.params.forEach((param, index) => {
527
+ const df = def.params[index];
528
+ if(df&&df.includes(':')){
529
+ xfVal = df?.split(':')?.map(i=>i.trim()).filter(i=>i);
530
+ }
531
+
532
+ const dfv = xfVal[1]?xfVal[1]:'';
533
+
534
+ const arg = args[index] !== (undefined) ? args[index] : dfv;
535
+ const regex = new RegExp(`@use\\(\\s*${param.replace(/(\s+)?(\:(\s+)?.*)/g, '')}\\s*\\)`, 'g');
536
+ result = result.replace(regex, arg);
537
+ });
538
+
539
+ return result;
540
+ }
541
+ );
542
+ }
543
+ return processed;
511
544
  }
545
+ defExdepth++;
546
+
547
+ return procDef(processed);
548
+ }
549
+
512
550
  function procExt(css) {
513
551
  let extractedVariables = {};
514
552
  let tempCSS = css;
@@ -517,7 +555,7 @@ function procExt(css) {
517
555
  tempCSS = tempCSS.replace(/("(?:[^"\\]|\\.)*")|('(?:[^'\\]|\\.)*')/g, function(fullMatch) {
518
556
  let quote = fullMatch[0];
519
557
  let content = fullMatch.slice(1, -1);
520
- const directiveRegex = /@ext\((-?\d+),(\d+):\s*([^)]+)\)/g;
558
+ const directiveRegex = /@ext\((?:\s+)?(-?\d+)(?:\s+)?,(?:\s+)?(\d+)(?:\s+)?:\s*([^)]+)(?:\s+)?\)/g;
521
559
  let match;
522
560
  let directivesToProcess = [];
523
561
 
@@ -554,7 +592,7 @@ function procExt(css) {
554
592
  });
555
593
 
556
594
  // Step 2: Outside strings
557
- tempCSS = tempCSS.replace(/([#.\w-]+)\s*@ext\((-?\d+),(\d+):\s*([^)]+)\)/g, function(match, token, start, len, varName) {
595
+ tempCSS = tempCSS.replace(/([#.\w-]+)\s*@ext\((?:\s+)?(-?\d+)(?:\s+)?,(?:\s+)?(\d+)(?:\s+)?:\s*([^)]+)(?:\s+)?\)/g, function(match, token, start, len, varName) {
558
596
  start = parseInt(start);
559
597
  len = parseInt(len);
560
598
  varName = varName.trim();
@@ -584,8 +622,7 @@ function procExt(css) {
584
622
 
585
623
  return tempCSS;
586
624
  }
587
-
588
-
625
+
589
626
  function procRan(input) {
590
627
  return input.replace(/@random\(\[([^\]]+)\](?:, *ordered)?\)/g, (match, valuesStr) => {
591
628
  const isOrdered = /, *ordered\)/.test(match);
package/e/xfscss.js CHANGED
@@ -1,4 +1,3 @@
1
- /* FIGSH-FSCSS light, source v3., fscss.devtem.org */
2
1
  export function exec({ type = 'text', content, onError, onSuccess }) {
3
2
 
4
3
  // 1. Validation
@@ -49,27 +48,6 @@ export function exec({ type = 'text', content, onError, onSuccess }) {
49
48
  function xfscssProcessorWrap(){(async ()=>{
50
49
  /**
51
50
  * FSCSS Processing Script
52
- * Note: Use official npm package/CDN instead of copying this directly.
53
- * visit: (fscss.devtem.org) for support.
54
- */
55
- /**
56
- * FSCSS Processing Script
57
- *
58
- * Credit:
59
- * - EKUYIK SAM as Figsh (Publisher)
60
- * - David-Hux (Writer)
61
- * - Current User (Implementer)
62
- *
63
- * Resources:
64
- * - fscss-ttr on dev.to
65
- * - Figsh on figsh.devtem.org, codepen.io, stackoverflow.com
66
- * - npm package: fscss (npm install -g fscss)
67
- *
68
- * Version: source v14, package v1+
69
- * Last Edited: Mar 5th, 2026
70
- *
71
- * Note: Use official npm package/CDN instead of copying this directly.
72
- * visit: (fscss.devtem.org) for support.
73
51
  */
74
52
 
75
53
  function procCntInit(ntc,stc){
@@ -203,40 +181,36 @@ function parseConditionBlocks(block) {
203
181
 
204
182
  function procExC(css) {
205
183
  const regex = /exec\((_log|_error|_warn|_info),\s*(?:"([^"]*)"|'([^']*)'|([^)]*))\)/g;
206
- let jsCode = '';
207
- let match;
208
184
 
209
- // Replace exec(...) with nothing (remove from CSS) while collecting code
185
+ const methodMap = {
186
+ _log: console.log,
187
+ _error: console.error,
188
+ _warn: console.warn,
189
+ _info: console.info,
190
+ };
191
+
210
192
  const cleanedCSS = css.replace(regex, (full, method, dQ, sQ, raw) => {
211
- const arg = dQ || sQ || raw;
193
+ const arg = dQ ?? sQ ?? raw;
212
194
 
213
- if (!['_log', '_error', '_warn', '_info'].includes(method)) {
195
+ if (!methodMap[method]) {
214
196
  console.warn(`fscss[exec(console)]: Unsupported method: ${method}`);
215
- return ''; // strip it from CSS
197
+ return '';
216
198
  }
217
199
 
218
200
  if (!arg) {
219
201
  console.warn(`fscss[exec(console)]: Empty argument for method: ${method}`);
220
- return ''; // strip it from CSS
202
+ return '';
221
203
  }
222
204
 
223
- jsCode += `console.${method.slice(1)}("${arg.replace(/"/g, '\\"')}");\n`;
224
- return ''; // ensure CSS isn’t broken
205
+ methodMap[method](arg);
206
+ return '';
225
207
  });
226
208
 
227
- // Run console code safely
228
- if (jsCode) {
229
- try {
230
- new Function(jsCode)();
231
- } catch (e) {
232
- console.error("fscss[exec(console)]: Error executing transformed code:", e);
233
- }
234
- }
235
-
236
209
  return cleanedCSS;
237
210
  }
238
211
 
239
212
 
213
+
240
214
  function procEv(css) {
241
215
  const functionMap = {};
242
216
  const funcDefRegex = /@event\s+([\w-]+)\(([^)]*)\)\s*:?{/g;
@@ -393,25 +367,24 @@ function procExC(css) {
393
367
 
394
368
  return modifiedCSS.trim();
395
369
  }
396
- async function initlibraries(css){
397
- css = css.replace(/exec\(\s*_init\sisjs\s*\)/g, "exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/isjs.fscss)");
398
- css = css.replace(/exec\(\s*_init\sthemes\s*\)/g, "exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/trshapes.fthemes.fscss)")
399
- css = css.replace(/exec\(_init\sarray1to500\s*\)/g, "exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/1to500.fscss)");
400
- css = css.replace(/exec\(_init\s+([\w\d\._—\-\%\*\+\&\$\=]+)(?:\/([\w\-]+))?\s*\)/g, (match, impName, impType)=>{
370
+
371
+ async function initlibraries(css){
372
+ const xfr = 'https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/';
373
+ css = css.replace(/exec\(_init\s+([\w\d\._—\-\%\*\+\@\&\$\=]+)(?:\/([\w\-]+))?\s*\)/g, (match, impName, impType)=>{
401
374
  if(!impType){
402
375
  //`
403
- return `exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${impName}.fscss)`;
376
+ return `exec(${xfr+impName}.fscss)`;
404
377
  }
405
- return `exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${impName}.${impType})`;
378
+ return `exec(${xfr+impName}.${impType})`;
406
379
  });
407
- css = css.replace(/(\@import\((?:\s+)?(?:exec)?\((?:[\w\d\.\@\—\-_*\#\$\s\,]+)\)(?:\s+)?from(?:\s+)?)([\w\d\._—\-\%\*\+\&\$\=]+)(?:\/([\w\-]+))?(?:\s+)?\)/g, (match, state, impName, impType) => {
380
+ css = css.replace(/(\@import\((?:\s+)?(?:exec)?\((?:[\w\d\.\@\—\-_*\#\$\s\,]+)\)(?:\s+)?from(?:\s+)?)([\w\d\._—\-\%\*\+\@\&\$\=]+)(?:\/([\w\-]+))?(?:\s+)?\)/g, (match, state, impName, impType) => {
408
381
  if (!impType) {
409
- return `${state}'https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${impName}.fscss')`;
382
+ return `${state}'${xfr+impName}.fscss')`;
410
383
  }
411
- return `${state}'https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${impName}.${impType}')`;
384
+ return `${state}'${xfr+impName}.${impType}')`;
412
385
  });
413
386
  return css;
414
- }
387
+ }
415
388
 
416
389
  function procVar(vcss) {
417
390
  function processSCSS(scssCode) {
@@ -485,11 +458,14 @@ function procVar(vcss) {
485
458
  return result.css;
486
459
  }
487
460
 
461
+ let defExdepth = 0;
488
462
 
489
463
  function procDef(fscss) {
464
+
490
465
  const pRegex = /@define\s+([\w\_\-\—]+)\s*\(([^)]*)\)\s*\$?\{\s*(?:"([^"]*)"|'([^']*)'|`([^`]*)`|([^\}^\{]*?))\s*\}/g;
491
466
 
492
467
  // First, extract all @define blocks and store them in defExfscss. FIGSH-FSCSS
468
+
493
469
  let processed = fscss.replace(pRegex,
494
470
  (match, name, paramsStr, body1, body2, body3, body4) => {
495
471
  const params = paramsStr.split(',').map(p =>p.trim()).filter(p =>p);
@@ -500,6 +476,7 @@ function procDef(fscss) {
500
476
  );
501
477
 
502
478
  // Now replace all @name(...) usages with their expanded bodies. FIGSH-FSCSS
479
+
503
480
  processed = processed.replace(
504
481
  /@([\w\_\-\—]+)\s*\(([\s\S]*?)\)/g,
505
482
  (match, name, argsStr) => {
@@ -530,10 +507,48 @@ const dfv = xfVal[1]?xfVal[1]:'';
530
507
  return result;
531
508
  }
532
509
  );
533
- if(!pRegex.test(processed)) return processed;
534
510
 
535
- return procDef(processed);
511
+
512
+ if (!pRegex.test(processed)||defExdepth >= 10) {
513
+ for(let g=0;g<10;g++){
514
+ processed = processed.replace(
515
+ /@([\w\_\-\—]+)\s*\(([\s\S]*?)\)/g,
516
+ (match, name, argsStr) => {
517
+ const def = defExfscss[name];
518
+ if (!def){
519
+ return match;
520
+ }// Leave unknown Def macros unchanged. FIGSH-FSCSS
521
+
522
+ const args = argsStr?.split(',').map(a => a.trim());
523
+ if(args[0]==='') args[0] = undefined;
524
+ let result = def.body;
525
+
526
+ /* Replace each @use(param) with the corresponding argument. FIGSH-FSCSS */
527
+ let xfVal = [];
528
+ def.params.forEach((param, index) => {
529
+ const df = def.params[index];
530
+ if(df&&df.includes(':')){
531
+ xfVal = df?.split(':')?.map(i=>i.trim()).filter(i=>i);
532
+ }
533
+
534
+ const dfv = xfVal[1]?xfVal[1]:'';
535
+
536
+ const arg = args[index] !== (undefined) ? args[index] : dfv;
537
+ const regex = new RegExp(`@use\\(\\s*${param.replace(/(\s+)?(\:(\s+)?.*)/g, '')}\\s*\\)`, 'g');
538
+ result = result.replace(regex, arg);
539
+ });
540
+
541
+ return result;
542
+ }
543
+ );
544
+ }
545
+ return processed;
536
546
  }
547
+ defExdepth++;
548
+
549
+ return procDef(processed);
550
+ }
551
+
537
552
  function procExt(css) {
538
553
  let extractedVariables = {};
539
554
  let tempCSS = css;
@@ -542,7 +557,7 @@ function procExt(css) {
542
557
  tempCSS = tempCSS.replace(/("(?:[^"\\]|\\.)*")|('(?:[^'\\]|\\.)*')/g, function(fullMatch) {
543
558
  let quote = fullMatch[0];
544
559
  let content = fullMatch.slice(1, -1);
545
- const directiveRegex = /@ext\((-?\d+),(\d+):\s*([^)]+)\)/g;
560
+ const directiveRegex = /@ext\((?:\s+)?(-?\d+)(?:\s+)?,(?:\s+)?(\d+)(?:\s+)?:\s*([^)]+)(?:\s+)?\)/g;
546
561
  let match;
547
562
  let directivesToProcess = [];
548
563
 
@@ -579,7 +594,7 @@ function procExt(css) {
579
594
  });
580
595
 
581
596
  // Step 2: Outside strings
582
- tempCSS = tempCSS.replace(/([#.\w-]+)\s*@ext\((-?\d+),(\d+):\s*([^)]+)\)/g, function(match, token, start, len, varName) {
597
+ tempCSS = tempCSS.replace(/([#.\w-]+)\s*@ext\((?:\s+)?(-?\d+)(?:\s+)?,(?:\s+)?(\d+)(?:\s+)?:\s*([^)]+)(?:\s+)?\)/g, function(match, token, start, len, varName) {
583
598
  start = parseInt(start);
584
599
  len = parseInt(len);
585
600
  varName = varName.trim();
package/exec.js CHANGED
@@ -1,4 +1,3 @@
1
- /* Figsh-fscss light, source v3., fscss.devtem.org */
2
1
  function exec({ type = 'text', content, onError, onSuccess }) {
3
2
 
4
3
  // 1. Validation
@@ -49,8 +48,6 @@ function exec({ type = 'text', content, onError, onSuccess }) {
49
48
  function xfscssProcessorWrap(){(async ()=>{
50
49
  /**
51
50
  * FSCSS Processing Script
52
- * Note: Use official npm package/CDN instead of copying this directly.
53
- * visit: (fscss.devtem.org) for support.
54
51
  */
55
52
 
56
53
  function procCntInit(ntc,stc){
@@ -368,24 +365,23 @@ function procExC(css) {
368
365
 
369
366
  return modifiedCSS.trim();
370
367
  }
371
- async function initlibraries(css){
372
- css = css.replace(/exec\(\s*_init\sisjs\s*\)/g, "exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/isjs.fscss)");
373
- css = css.replace(/exec\(\s*_init\sthemes\s*\)/g, "exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/trshapes.fthemes.fscss)")
374
- css = css.replace(/exec\(_init\sarray1to500\s*\)/g, "exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/1to500.fscss)");
375
- css = css.replace(/exec\(_init\s+([\w\d\._—\-\%\*\+\&\$\=]+)(?:\/([\w\-]+))?\s*\)/g, (match, impName, impType)=>{
376
- if(!impType){
377
- //`
378
- return `exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${impName}.fscss)`;
368
+
369
+ async function initlibraries(css) {
370
+ const xfr = 'https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/';
371
+ css = css.replace(/exec\(_init\s+([\w\d\._—\-\%\*\+\@\&\$\=]+)(?:\/([\w\-]+))?\s*\)/g, (match, impName, impType) => {
372
+ if (!impType) {
373
+ //`
374
+ return `exec(${xfr+impName}.fscss)`;
379
375
  }
380
- return `exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${impName}.${impType})`;
376
+ return `exec(${xfr+impName}.${impType})`;
381
377
  });
382
- css = css.replace(/(\@import\((?:\s+)?(?:exec)?\((?:[\w\d\.\@\—\-_*\#\$\s\,]+)\)(?:\s+)?from(?:\s+)?)([\w\d\._—\-\%\*\+\&\$\=]+)(?:\/([\w\-]+))?(?:\s+)?\)/g, (match, state, impName, impType) => {
383
- if (!impType) {
384
- return `${state}'https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${impName}.fscss')`;
385
- }
386
- return `${state}'https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${impName}.${impType}')`;
387
- });
388
- return css;
378
+ css = css.replace(/(\@import\((?:\s+)?(?:exec)?\((?:[\w\d\.\@\—\-_*\#\$\s\,]+)\)(?:\s+)?from(?:\s+)?)([\w\d\._—\-\%\*\+\@\&\$\=]+)(?:\/([\w\-]+))?(?:\s+)?\)/g, (match, state, impName, impType) => {
379
+ if (!impType) {
380
+ return `${state}'${xfr+impName}.fscss')`;
381
+ }
382
+ return `${state}'${xfr+impName}.${impType}')`;
383
+ });
384
+ return css;
389
385
  }
390
386
 
391
387
  function procVar(vcss) {
@@ -460,11 +456,14 @@ function procVar(vcss) {
460
456
  return result.css;
461
457
  }
462
458
 
459
+ let defExdepth = 0;
463
460
 
464
461
  function procDef(fscss) {
462
+
465
463
  const pRegex = /@define\s+([\w\_\-\—]+)\s*\(([^)]*)\)\s*\$?\{\s*(?:"([^"]*)"|'([^']*)'|`([^`]*)`|([^\}^\{]*?))\s*\}/g;
466
464
 
467
465
  // First, extract all @define blocks and store them in defExfscss. FIGSH-FSCSS
466
+
468
467
  let processed = fscss.replace(pRegex,
469
468
  (match, name, paramsStr, body1, body2, body3, body4) => {
470
469
  const params = paramsStr.split(',').map(p =>p.trim()).filter(p =>p);
@@ -475,6 +474,7 @@ function procDef(fscss) {
475
474
  );
476
475
 
477
476
  // Now replace all @name(...) usages with their expanded bodies. FIGSH-FSCSS
477
+
478
478
  processed = processed.replace(
479
479
  /@([\w\_\-\—]+)\s*\(([\s\S]*?)\)/g,
480
480
  (match, name, argsStr) => {
@@ -505,10 +505,48 @@ const dfv = xfVal[1]?xfVal[1]:'';
505
505
  return result;
506
506
  }
507
507
  );
508
- if(!pRegex.test(processed)) return processed;
509
508
 
510
- return procDef(processed);
509
+
510
+ if (!pRegex.test(processed)||defExdepth >= 10) {
511
+ for(let g=0;g<10;g++){
512
+ processed = processed.replace(
513
+ /@([\w\_\-\—]+)\s*\(([\s\S]*?)\)/g,
514
+ (match, name, argsStr) => {
515
+ const def = defExfscss[name];
516
+ if (!def){
517
+ return match;
518
+ }// Leave unknown Def macros unchanged. FIGSH-FSCSS
519
+
520
+ const args = argsStr?.split(',').map(a => a.trim());
521
+ if(args[0]==='') args[0] = undefined;
522
+ let result = def.body;
523
+
524
+ /* Replace each @use(param) with the corresponding argument. FIGSH-FSCSS */
525
+ let xfVal = [];
526
+ def.params.forEach((param, index) => {
527
+ const df = def.params[index];
528
+ if(df&&df.includes(':')){
529
+ xfVal = df?.split(':')?.map(i=>i.trim()).filter(i=>i);
530
+ }
531
+
532
+ const dfv = xfVal[1]?xfVal[1]:'';
533
+
534
+ const arg = args[index] !== (undefined) ? args[index] : dfv;
535
+ const regex = new RegExp(`@use\\(\\s*${param.replace(/(\s+)?(\:(\s+)?.*)/g, '')}\\s*\\)`, 'g');
536
+ result = result.replace(regex, arg);
537
+ });
538
+
539
+ return result;
540
+ }
541
+ );
542
+ }
543
+ return processed;
511
544
  }
545
+ defExdepth++;
546
+
547
+ return procDef(processed);
548
+ }
549
+
512
550
  function procExt(css) {
513
551
  let extractedVariables = {};
514
552
  let tempCSS = css;
@@ -517,7 +555,7 @@ function procExt(css) {
517
555
  tempCSS = tempCSS.replace(/("(?:[^"\\]|\\.)*")|('(?:[^'\\]|\\.)*')/g, function(fullMatch) {
518
556
  let quote = fullMatch[0];
519
557
  let content = fullMatch.slice(1, -1);
520
- const directiveRegex = /@ext\((-?\d+),(\d+):\s*([^)]+)\)/g;
558
+ const directiveRegex = /@ext\((?:\s+)?(-?\d+)(?:\s+)?,(?:\s+)?(\d+)(?:\s+)?:\s*([^)]+)(?:\s+)?\)/g;
521
559
  let match;
522
560
  let directivesToProcess = [];
523
561
 
@@ -554,7 +592,7 @@ function procExt(css) {
554
592
  });
555
593
 
556
594
  // Step 2: Outside strings
557
- tempCSS = tempCSS.replace(/([#.\w-]+)\s*@ext\((-?\d+),(\d+):\s*([^)]+)\)/g, function(match, token, start, len, varName) {
595
+ tempCSS = tempCSS.replace(/([#.\w-]+)\s*@ext\((?:\s+)?(-?\d+)(?:\s+)?,(?:\s+)?(\d+)(?:\s+)?:\s*([^)]+)(?:\s+)?\)/g, function(match, token, start, len, varName) {
558
596
  start = parseInt(start);
559
597
  len = parseInt(len);
560
598
  varName = varName.trim();
@@ -584,8 +622,7 @@ function procExt(css) {
584
622
 
585
623
  return tempCSS;
586
624
  }
587
-
588
-
625
+
589
626
  function procRan(input) {
590
627
  return input.replace(/@random\(\[([^\]]+)\](?:, *ordered)?\)/g, (match, valuesStr) => {
591
628
  const isOrdered = /, *ordered\)/.test(match);
@@ -310,74 +310,24 @@ function procExC(css) {
310
310
 
311
311
  return modifiedCSS.trim();
312
312
  }
313
+
313
314
  async function initlibraries(css){
314
- css = css.replace(/exec\(\s*_init\sisjs\s*\)/g, "exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/isjs.fscss)");
315
- css = css.replace(/exec\(\s*_init\sthemes\s*\)/g, "exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/trshapes.fthemes.fscss)")
316
- css = css.replace(/exec\(_init\sarray1to500\s*\)/g, "exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/1to500.fscss)");
317
- css = css.replace(/exec\(_init\s+([\w\d\._—\-\%\*\+\&\$\=]+)(?:\/([\w\-]+))?\s*\)/g, (match, impName, impType)=>{
315
+ const xfr = 'https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/';
316
+ css = css.replace(/exec\(_init\s+([\w\d\._—\-\%\*\+\@\&\$\=]+)(?:\/([\w\-]+))?\s*\)/g, (match, impName, impType)=>{
318
317
  if(!impType){
319
- return `exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${impName}.fscss)`;
318
+ //`
319
+ return `exec(${xfr+impName}.fscss)`;
320
320
  }
321
- return `exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${impName}.${impType})`;
321
+ return `exec(${xfr+impName}.${impType})`;
322
322
  });
323
- css = css.replace(/(\@import\((?:\s+)?(?:exec)?\((?:[\w\d\.\@\—\-_*\#\$\s\,]+)\)(?:\s+)?from(?:\s+)?)([\w\d\._—\-\%\*\+\&\$\=]+)(?:\/([\w\-]+))?(?:\s+)?\)/g, (match, state, impName, impType) => {
323
+ css = css.replace(/(\@import\((?:\s+)?(?:exec)?\((?:[\w\d\.\@\—\-_*\#\$\s\,]+)\)(?:\s+)?from(?:\s+)?)([\w\d\._—\-\%\*\+\@\&\$\=]+)(?:\/([\w\-]+))?(?:\s+)?\)/g, (match, state, impName, impType) => {
324
324
  if (!impType) {
325
- return `${state}'https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${impName}.fscss')`;
325
+ return `${state}'${xfr+impName}.fscss')`;
326
326
  }
327
- return `${state}'https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${impName}.${impType}')`;
327
+ return `${state}'${xfr+impName}.${impType}')`;
328
328
  });
329
329
  return css;
330
- }
331
-
332
- function procDef(fscss) {
333
- const pRegex = /@define\s+([\w\_\-\—]+)\s*\(([^)]*)\)\s*\$?\{\s*(?:"([^"]*)"|'([^']*)'|`([^`]*)`|([^\}^\{]*?))\s*\}/g;
334
-
335
- // First, extract all @define blocks and store them in defExfscss. FIGSH-FSCSS
336
- let processed = fscss.replace(pRegex,
337
- (match, name, paramsStr, body1, body2, body3, body4) => {
338
- const params = paramsStr.split(',').map(p =>p.trim()).filter(p =>p);
339
- const body = body1 ?? body2 ?? body3 ?? body4 ?? '';
340
- defExfscss[name] = { params, body };
341
- return ''; // Remove the define block from the output. FIGSH-FSCSS
342
- }
343
- );
344
-
345
- // Now replace all @name(...) usages with their expanded bodies. FIGSH-FSCSS
346
- processed = processed.replace(
347
- /@([\w\_\-\—]+)\s*\(([\s\S]*?)\)/g,
348
- (match, name, argsStr) => {
349
- const def = defExfscss[name];
350
- if (!def){
351
- return match;
352
- }// Leave unknown Def macros unchanged. FIGSH-FSCSS
353
-
354
- const args = argsStr?.split(',').map(a => a.trim());
355
- if(args[0]==='') args[0] = undefined;
356
- let result = def.body;
357
-
358
- /* Replace each @use(param) with the corresponding argument. FIGSH-FSCSS */
359
- let xfVal = [];
360
- def.params.forEach((param, index) => {
361
- const df = def.params[index];
362
- if(df&&df.includes(':')){
363
- xfVal = df?.split(':')?.map(i=>i.trim()).filter(i=>i);
364
- }
365
-
366
- const dfv = xfVal[1]?xfVal[1]:'';
367
-
368
- const arg = args[index] !== (undefined) ? args[index] : dfv;
369
- const regex = new RegExp(`@use\\(\\s*${param.replace(/(\s+)?(\:(\s+)?.*)/g, '')}\\s*\\)`, 'g');
370
- result = result.replace(regex, arg);
371
- });
372
-
373
- return result;
374
- }
375
- );
376
- if(!pRegex.test(processed)) return processed;
377
-
378
- return procDef(processed);
379
- }
380
-
330
+ }
381
331
  function procVar(vcss) {
382
332
  function processSCSS(scssCode) {
383
333
  const globalVars = {};
@@ -449,6 +399,96 @@ function procVar(vcss) {
449
399
  const result = processSCSS(vcss);
450
400
  return result.css;
451
401
  }
402
+ let defExdepth = 0;
403
+
404
+ function procDef(fscss) {
405
+
406
+ const pRegex = /@define\s+([\w\_\-\—]+)\s*\(([^)]*)\)\s*\$?\{\s*(?:"([^"]*)"|'([^']*)'|`([^`]*)`|([^\}^\{]*?))\s*\}/g;
407
+
408
+ // First, extract all @define blocks and store them in defExfscss. FIGSH-FSCSS
409
+
410
+ let processed = fscss.replace(pRegex,
411
+ (match, name, paramsStr, body1, body2, body3, body4) => {
412
+ const params = paramsStr.split(',').map(p =>p.trim()).filter(p =>p);
413
+ const body = body1 ?? body2 ?? body3 ?? body4 ?? '';
414
+ defExfscss[name] = { params, body };
415
+ return ''; // Remove the define block from the output. FIGSH-FSCSS
416
+ }
417
+ );
418
+
419
+ // Now replace all @name(...) usages with their expanded bodies. FIGSH-FSCSS
420
+
421
+ processed = processed.replace(
422
+ /@([\w\_\-\—]+)\s*\(([\s\S]*?)\)/g,
423
+ (match, name, argsStr) => {
424
+ const def = defExfscss[name];
425
+ if (!def){
426
+ return match;
427
+ }// Leave unknown Def macros unchanged. FIGSH-FSCSS
428
+
429
+ const args = argsStr?.split(',').map(a => a.trim());
430
+ if(args[0]==='') args[0] = undefined;
431
+ let result = def.body;
432
+
433
+ /* Replace each @use(param) with the corresponding argument. FIGSH-FSCSS */
434
+ let xfVal = [];
435
+ def.params.forEach((param, index) => {
436
+ const df = def.params[index];
437
+ if(df&&df.includes(':')){
438
+ xfVal = df?.split(':')?.map(i=>i.trim()).filter(i=>i);
439
+ }
440
+
441
+ const dfv = xfVal[1]?xfVal[1]:'';
442
+
443
+ const arg = args[index] !== (undefined) ? args[index] : dfv;
444
+ const regex = new RegExp(`@use\\(\\s*${param.replace(/(\s+)?(\:(\s+)?.*)/g, '')}\\s*\\)`, 'g');
445
+ result = result.replace(regex, arg);
446
+ });
447
+
448
+ return result;
449
+ }
450
+ );
451
+
452
+
453
+ if (!pRegex.test(processed)||defExdepth >= 10) {
454
+ for(let g=0;g<10;g++){
455
+ processed = processed.replace(
456
+ /@([\w\_\-\—]+)\s*\(([\s\S]*?)\)/g,
457
+ (match, name, argsStr) => {
458
+ const def = defExfscss[name];
459
+ if (!def){
460
+ return match;
461
+ }// Leave unknown Def macros unchanged. FIGSH-FSCSS
462
+
463
+ const args = argsStr?.split(',').map(a => a.trim());
464
+ if(args[0]==='') args[0] = undefined;
465
+ let result = def.body;
466
+
467
+ /* Replace each @use(param) with the corresponding argument. FIGSH-FSCSS */
468
+ let xfVal = [];
469
+ def.params.forEach((param, index) => {
470
+ const df = def.params[index];
471
+ if(df&&df.includes(':')){
472
+ xfVal = df?.split(':')?.map(i=>i.trim()).filter(i=>i);
473
+ }
474
+
475
+ const dfv = xfVal[1]?xfVal[1]:'';
476
+
477
+ const arg = args[index] !== (undefined) ? args[index] : dfv;
478
+ const regex = new RegExp(`@use\\(\\s*${param.replace(/(\s+)?(\:(\s+)?.*)/g, '')}\\s*\\)`, 'g');
479
+ result = result.replace(regex, arg);
480
+ });
481
+
482
+ return result;
483
+ }
484
+ );
485
+ }
486
+ return processed;
487
+ }
488
+ defExdepth++;
489
+
490
+ return procDef(processed);
491
+ }
452
492
 
453
493
  function procExt(css) {
454
494
  let extractedVariables = {};
@@ -458,7 +498,7 @@ function procExt(css) {
458
498
  tempCSS = tempCSS.replace(/("(?:[^"\\]|\\.)*")|('(?:[^'\\]|\\.)*')/g, function(fullMatch) {
459
499
  let quote = fullMatch[0];
460
500
  let content = fullMatch.slice(1, -1);
461
- const directiveRegex = /@ext\((-?\d+),(\d+):\s*([^)]+)\)/g;
501
+ const directiveRegex = /@ext\((?:\s+)?(-?\d+)(?:\s+)?,(?:\s+)?(\d+)(?:\s+)?:\s*([^)]+)(?:\s+)?\)/g;
462
502
  let match;
463
503
  let directivesToProcess = [];
464
504
 
@@ -495,7 +535,7 @@ function procExt(css) {
495
535
  });
496
536
 
497
537
  // Step 2: Outside strings
498
- tempCSS = tempCSS.replace(/([#.\w-]+)\s*@ext\((-?\d+),(\d+):\s*([^)]+)\)/g, function(match, token, start, len, varName) {
538
+ tempCSS = tempCSS.replace(/([#.\w-]+)\s*@ext\((?:\s+)?(-?\d+)(?:\s+)?,(?:\s+)?(\d+)(?:\s+)?:\s*([^)]+)(?:\s+)?\)/g, function(match, token, start, len, varName) {
499
539
  start = parseInt(start);
500
540
  len = parseInt(len);
501
541
  varName = varName.trim();
@@ -526,7 +566,6 @@ function procExt(css) {
526
566
  return tempCSS;
527
567
  }
528
568
 
529
-
530
569
  function procRan(input) {
531
570
  return input.replace(/@random\(\[([^\]]+)\](?:, *ordered)?\)/g, (match, valuesStr) => {
532
571
  const isOrdered = /, *ordered\)/.test(match);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "fscss",
3
3
  "description": "Figured Shorthand Cascading Style Sheet",
4
- "version": "1.1.22",
4
+ "version": "1.1.23",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "bin": {
package/public/test.html CHANGED
@@ -1,24 +1,101 @@
1
+ <!DOCTYPE html>
1
2
  <head>
2
- <link href="./public/vars.fscss" rel="stylesheet" type='text/fscss'>
3
- <script src="index.js" async=""></script>
3
+ <script src="/exec.js" async=""></script>
4
4
  </head>
5
- <h1>HELLO WORLD!</h1>
6
- <div name='foo'></div>
7
- <style>
8
- /* styling ... */
9
- body{
10
- BACKGROUND: $init-background-stack!;
11
- COLOR: $init-color!;
12
- TEXT-ALIGN: CENTER;
13
- }
14
- h1{
15
- font-family: $init-font-family!;
16
- -*-text-stroke: $init-text-stroke!;
17
- color: #299221;
18
- }
19
- $(name: foo){
20
- BORDER: $init-border!;
21
- OUTLINE: $init-outline!;
22
- %2(width, height[: 70px;])
23
- }
24
5
  <style>
6
+ @import((
7
+ flex-wrap-center as flex-wrap,
8
+ star-clip as star
9
+ ) from "vars.fscss")
10
+
11
+ body{
12
+
13
+ background: #233332;
14
+
15
+ }
16
+
17
+ .box{
18
+
19
+ %2(width, height [: 400px;])
20
+
21
+ position: absolute;
22
+
23
+ transform-style: preserve-3d;
24
+
25
+ @flex-wrap()
26
+
27
+ }
28
+
29
+ @arr pos[count(360, 10)]
30
+
31
+ .box .star:nth-child(@arr.pos[]){
32
+
33
+ $pos: @arr.pos[];
34
+
35
+ background: #2FF200;
36
+
37
+ padding: 1px;
38
+
39
+ width: 100px;
40
+
41
+ position: absolute;
42
+
43
+ transform-origin: right;
44
+
45
+ transform: rotate($pos!deg);
46
+
47
+ }
48
+
49
+ .star:before{
50
+
51
+ content: " ";
52
+
53
+ position: absolute;
54
+
55
+ width: 20px;
56
+
57
+ height: 20px;
58
+
59
+ background: #C800F2;
60
+
61
+ top: -8.5px;
62
+
63
+ left: -7px;
64
+
65
+ transform: rotate(60deg);
66
+
67
+ clip-path: @star();
68
+
69
+ }
70
+
71
+ $(@keyframes rotate,.star &[360s linear infinite alternate]){
72
+
73
+ to{
74
+
75
+ transform: rotate(0);
76
+
77
+ }
78
+
79
+ }
80
+ </style>
81
+
82
+
83
+ <div class="box"></div>
84
+
85
+
86
+ <script>
87
+
88
+ const box = document.querySelector(".box");
89
+
90
+ for(let i =0; i<360;i++){
91
+
92
+ const star = document.createElement("div");
93
+
94
+ star.className="star";
95
+
96
+ box.appendChild(star)
97
+
98
+ }
99
+
100
+ </script>
101
+
package/public/vars.fscss CHANGED
@@ -5,3 +5,14 @@ $init-text-stroke: 0.2px #871;
5
5
  $init-caret-color: rgba(%3([190,])1);
6
6
  $init-font-family: Arial, Helvetica, sans-serif;
7
7
  $init-outline: 1px groove #235000;
8
+
9
+ @define flex-wrap-center(){
10
+ display: flex;
11
+ justify-content: center;
12
+ align-items: center;
13
+ flex-wrap: wrap;
14
+ }
15
+ @define star-clip(){
16
+ polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%)
17
+ }
18
+
package/xfscss.js CHANGED
@@ -1,4 +1,3 @@
1
- /* FIGSH-FSCSS light, source v3, fscss.devtem.org */
2
1
  export function exec({ type = 'text', content, onError, onSuccess }) {
3
2
 
4
3
  // 1. Validation
@@ -49,27 +48,6 @@ export function exec({ type = 'text', content, onError, onSuccess }) {
49
48
  function xfscssProcessorWrap(){(async ()=>{
50
49
  /**
51
50
  * FSCSS Processing Script
52
- * Note: Use official npm package/CDN instead of copying this directly.
53
- * visit: (fscss.devtem.org) for support.
54
- */
55
- /**
56
- * FSCSS Processing Script
57
- *
58
- * Credit:
59
- * - EKUYIK SAM as Figsh (Publisher)
60
- * - David-Hux (Writer)
61
- * - Current User (Implementer)
62
- *
63
- * Resources:
64
- * - fscss-ttr on dev.to
65
- * - Figsh on figsh.devtem.org, codepen.io, stackoverflow.com
66
- * - npm package: fscss (npm install -g fscss)
67
- *
68
- * Version: source v14, package v1+
69
- * Last Edited: Mar 5th, 2026
70
- *
71
- * Note: Use official npm package/CDN instead of copying this directly.
72
- * visit: (fscss.devtem.org) for support.
73
51
  */
74
52
 
75
53
  function procCntInit(ntc,stc){
@@ -203,40 +181,36 @@ function parseConditionBlocks(block) {
203
181
 
204
182
  function procExC(css) {
205
183
  const regex = /exec\((_log|_error|_warn|_info),\s*(?:"([^"]*)"|'([^']*)'|([^)]*))\)/g;
206
- let jsCode = '';
207
- let match;
208
184
 
209
- // Replace exec(...) with nothing (remove from CSS) while collecting code
185
+ const methodMap = {
186
+ _log: console.log,
187
+ _error: console.error,
188
+ _warn: console.warn,
189
+ _info: console.info,
190
+ };
191
+
210
192
  const cleanedCSS = css.replace(regex, (full, method, dQ, sQ, raw) => {
211
- const arg = dQ || sQ || raw;
193
+ const arg = dQ ?? sQ ?? raw;
212
194
 
213
- if (!['_log', '_error', '_warn', '_info'].includes(method)) {
195
+ if (!methodMap[method]) {
214
196
  console.warn(`fscss[exec(console)]: Unsupported method: ${method}`);
215
- return ''; // strip it from CSS
197
+ return '';
216
198
  }
217
199
 
218
200
  if (!arg) {
219
201
  console.warn(`fscss[exec(console)]: Empty argument for method: ${method}`);
220
- return ''; // strip it from CSS
202
+ return '';
221
203
  }
222
204
 
223
- jsCode += `console.${method.slice(1)}("${arg.replace(/"/g, '\\"')}");\n`;
224
- return ''; // ensure CSS isn’t broken
205
+ methodMap[method](arg);
206
+ return '';
225
207
  });
226
208
 
227
- // Run console code safely
228
- if (jsCode) {
229
- try {
230
- new Function(jsCode)();
231
- } catch (e) {
232
- console.error("fscss[exec(console)]: Error executing transformed code:", e);
233
- }
234
- }
235
-
236
209
  return cleanedCSS;
237
210
  }
238
211
 
239
212
 
213
+
240
214
  function procEv(css) {
241
215
  const functionMap = {};
242
216
  const funcDefRegex = /@event\s+([\w-]+)\(([^)]*)\)\s*:?{/g;
@@ -393,25 +367,24 @@ function procExC(css) {
393
367
 
394
368
  return modifiedCSS.trim();
395
369
  }
396
- async function initlibraries(css){
397
- css = css.replace(/exec\(\s*_init\sisjs\s*\)/g, "exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/isjs.fscss)");
398
- css = css.replace(/exec\(\s*_init\sthemes\s*\)/g, "exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/trshapes.fthemes.fscss)")
399
- css = css.replace(/exec\(_init\sarray1to500\s*\)/g, "exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/1to500.fscss)");
400
- css = css.replace(/exec\(_init\s+([\w\d\._—\-\%\*\+\&\$\=]+)(?:\/([\w\-]+))?\s*\)/g, (match, impName, impType)=>{
370
+
371
+ async function initlibraries(css){
372
+ const xfr = 'https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/';
373
+ css = css.replace(/exec\(_init\s+([\w\d\._—\-\%\*\+\@\&\$\=]+)(?:\/([\w\-]+))?\s*\)/g, (match, impName, impType)=>{
401
374
  if(!impType){
402
375
  //`
403
- return `exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${impName}.fscss)`;
376
+ return `exec(${xfr+impName}.fscss)`;
404
377
  }
405
- return `exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${impName}.${impType})`;
378
+ return `exec(${xfr+impName}.${impType})`;
406
379
  });
407
- css = css.replace(/(\@import\((?:\s+)?(?:exec)?\((?:[\w\d\.\@\—\-_*\#\$\s\,]+)\)(?:\s+)?from(?:\s+)?)([\w\d\._—\-\%\*\+\&\$\=]+)(?:\/([\w\-]+))?(?:\s+)?\)/g, (match, state, impName, impType) => {
380
+ css = css.replace(/(\@import\((?:\s+)?(?:exec)?\((?:[\w\d\.\@\—\-_*\#\$\s\,]+)\)(?:\s+)?from(?:\s+)?)([\w\d\._—\-\%\*\+\@\&\$\=]+)(?:\/([\w\-]+))?(?:\s+)?\)/g, (match, state, impName, impType) => {
408
381
  if (!impType) {
409
- return `${state}'https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${impName}.fscss')`;
382
+ return `${state}'${xfr+impName}.fscss')`;
410
383
  }
411
- return `${state}'https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${impName}.${impType}')`;
384
+ return `${state}'${xfr+impName}.${impType}')`;
412
385
  });
413
386
  return css;
414
- }
387
+ }
415
388
 
416
389
  function procVar(vcss) {
417
390
  function processSCSS(scssCode) {
@@ -485,11 +458,14 @@ function procVar(vcss) {
485
458
  return result.css;
486
459
  }
487
460
 
461
+ let defExdepth = 0;
488
462
 
489
463
  function procDef(fscss) {
464
+
490
465
  const pRegex = /@define\s+([\w\_\-\—]+)\s*\(([^)]*)\)\s*\$?\{\s*(?:"([^"]*)"|'([^']*)'|`([^`]*)`|([^\}^\{]*?))\s*\}/g;
491
466
 
492
467
  // First, extract all @define blocks and store them in defExfscss. FIGSH-FSCSS
468
+
493
469
  let processed = fscss.replace(pRegex,
494
470
  (match, name, paramsStr, body1, body2, body3, body4) => {
495
471
  const params = paramsStr.split(',').map(p =>p.trim()).filter(p =>p);
@@ -500,6 +476,7 @@ function procDef(fscss) {
500
476
  );
501
477
 
502
478
  // Now replace all @name(...) usages with their expanded bodies. FIGSH-FSCSS
479
+
503
480
  processed = processed.replace(
504
481
  /@([\w\_\-\—]+)\s*\(([\s\S]*?)\)/g,
505
482
  (match, name, argsStr) => {
@@ -530,10 +507,48 @@ const dfv = xfVal[1]?xfVal[1]:'';
530
507
  return result;
531
508
  }
532
509
  );
533
- if(!pRegex.test(processed)) return processed;
534
510
 
535
- return procDef(processed);
511
+
512
+ if (!pRegex.test(processed)||defExdepth >= 10) {
513
+ for(let g=0;g<10;g++){
514
+ processed = processed.replace(
515
+ /@([\w\_\-\—]+)\s*\(([\s\S]*?)\)/g,
516
+ (match, name, argsStr) => {
517
+ const def = defExfscss[name];
518
+ if (!def){
519
+ return match;
520
+ }// Leave unknown Def macros unchanged. FIGSH-FSCSS
521
+
522
+ const args = argsStr?.split(',').map(a => a.trim());
523
+ if(args[0]==='') args[0] = undefined;
524
+ let result = def.body;
525
+
526
+ /* Replace each @use(param) with the corresponding argument. FIGSH-FSCSS */
527
+ let xfVal = [];
528
+ def.params.forEach((param, index) => {
529
+ const df = def.params[index];
530
+ if(df&&df.includes(':')){
531
+ xfVal = df?.split(':')?.map(i=>i.trim()).filter(i=>i);
532
+ }
533
+
534
+ const dfv = xfVal[1]?xfVal[1]:'';
535
+
536
+ const arg = args[index] !== (undefined) ? args[index] : dfv;
537
+ const regex = new RegExp(`@use\\(\\s*${param.replace(/(\s+)?(\:(\s+)?.*)/g, '')}\\s*\\)`, 'g');
538
+ result = result.replace(regex, arg);
539
+ });
540
+
541
+ return result;
542
+ }
543
+ );
544
+ }
545
+ return processed;
536
546
  }
547
+ defExdepth++;
548
+
549
+ return procDef(processed);
550
+ }
551
+
537
552
  function procExt(css) {
538
553
  let extractedVariables = {};
539
554
  let tempCSS = css;
@@ -542,7 +557,7 @@ function procExt(css) {
542
557
  tempCSS = tempCSS.replace(/("(?:[^"\\]|\\.)*")|('(?:[^'\\]|\\.)*')/g, function(fullMatch) {
543
558
  let quote = fullMatch[0];
544
559
  let content = fullMatch.slice(1, -1);
545
- const directiveRegex = /@ext\((-?\d+),(\d+):\s*([^)]+)\)/g;
560
+ const directiveRegex = /@ext\((?:\s+)?(-?\d+)(?:\s+)?,(?:\s+)?(\d+)(?:\s+)?:\s*([^)]+)(?:\s+)?\)/g;
546
561
  let match;
547
562
  let directivesToProcess = [];
548
563
 
@@ -579,7 +594,7 @@ function procExt(css) {
579
594
  });
580
595
 
581
596
  // Step 2: Outside strings
582
- tempCSS = tempCSS.replace(/([#.\w-]+)\s*@ext\((-?\d+),(\d+):\s*([^)]+)\)/g, function(match, token, start, len, varName) {
597
+ tempCSS = tempCSS.replace(/([#.\w-]+)\s*@ext\((?:\s+)?(-?\d+)(?:\s+)?,(?:\s+)?(\d+)(?:\s+)?:\s*([^)]+)(?:\s+)?\)/g, function(match, token, start, len, varName) {
583
598
  start = parseInt(start);
584
599
  len = parseInt(len);
585
600
  varName = varName.trim();