fscss 1.1.13 → 1.1.14

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,48 +1,48 @@
1
1
  # FSCSS
2
2
  FSCSS (Figured Shorthand CSS) is a CSS preprocessor that extends CSS with shorthand utilities, variables, functions, and advanced transformations.
3
- It works both in the browser and on the backend (Node.js).
4
3
 
5
4
 
6
5
  ---
7
6
 
8
7
 
9
8
 
10
- ## Features
9
+ ## Features
11
10
 
12
11
  Works in browser and backend (Node.js)
13
12
 
14
13
  Supports:
15
14
 
16
- - Variables ($var, str()) → define reusable values
17
-
18
- - Style Replacement (%n())shorthand repeated properties
15
+ - Variables ($var, str()) → define reusable values, str(boxBased, "..."), $var:...;
16
+
17
+ - Array Methods (@arr) → define array - https://github.com/fscss-ttr/FSCSS/blob/main/FSCSS_array_method.md
18
+
19
+ - Style Replacement (%n()) → shorthand repeated properties. %2(width, height[: 200px;])
20
+
19
21
  - Repeat Function (rpt()) → repeat values quickly
20
22
 
21
23
  - Copy Function (copy()) → copy parts of values
22
24
 
23
- - String Extractor (@ext()) → extract substrings from values
25
+ - String Extractor (@ext()) → extract substrings from values.
24
26
 
25
- - Drops / Shared Properties → reuse style groups
27
+ - Drops / Shared Properties → reuse style groups.
26
28
 
27
- - Attribute Selectors → dynamic selectors
29
+ - Attribute Selectors → dynamic selectors. $(attribute:value){...}
28
30
 
29
31
  - Keyframes ($(@keyframes …)) → generate animations easily
30
32
 
31
- - Vendor Prefixing (-*) → auto add prefixes
32
-
33
- - Function-based (@fun) → reusable function-like blocks
33
+ - Vendor Prefixing (-*) → auto add prefixes. -\*-webkit-text-stroke:...
34
34
 
35
- - Array Methods (@arr) → define & loop arrays
35
+ - Function-based (@fun) → reusable function-like blocks. @fun(name){...}
36
36
 
37
- - Random Function (@random()) → random values at runtime
37
+ - Random Function (@random()) → random values at runtime. @random([.,.,...]) or using array!.randint instead
38
38
 
39
- - Number Calculation (num()) → evaluate math expressions
39
+ - Number Calculation (num()) → evaluate math expressions. num(4+5)
40
40
 
41
- - Import (@import) → include external FSCSS files
41
+ - Import (@import) → include external FSCSS files. @import(exec(...))
42
42
 
43
43
  - @event → event-based styling logic
44
44
 
45
- - exec() → debugging and runtime helpers
45
+ - exec() → debugging and runtime helpers. exec(_log, "...")
46
46
 
47
47
  - Variable fallback chain (property: $/var || fallback;)
48
48
 
@@ -50,7 +50,7 @@ Supports:
50
50
  ### Example
51
51
  ```css
52
52
  /* FSCSS, Animation compact */
53
- $(@keyframes trans, .box .card &[3s ease-in infinite]) {
53
+ $(@keyframes trans, .box, .card &[3s ase-in infinite]) {
54
54
  from {
55
55
  %2(width, height [: 0;])
56
56
  background: red;
@@ -62,7 +62,7 @@ $(@keyframes trans, .box .card &[3s ease-in infinite]) {
62
62
  }
63
63
  ```
64
64
 
65
- ### 📦 Installation
65
+ ### Installation
66
66
 
67
67
  `npm install -g fscss`
68
68
 
@@ -72,7 +72,7 @@ Or locally to your project:
72
72
 
73
73
  **Browser CDN**
74
74
  ```html
75
- <script src="https://cdn.jsdelivr.net/npm/fscss@1.1.13/exec.min.js" defer></script>
75
+ <script src="https://cdn.jsdelivr.net/npm/fscss@1.1.14/exec.min.js" defer></script>
76
76
  ```
77
77
  Usage
78
78
 
@@ -86,7 +86,7 @@ Or import inside a style block:
86
86
  @import(exec(style.fscss))
87
87
  </style>
88
88
  ```
89
- **⚡ Async or defer is required for script loading.**
89
+ **Async or defer is required for script loading.**
90
90
 
91
91
 
92
92
  ---
package/example.fscss CHANGED
@@ -1,7 +1,16 @@
1
1
  @import(exec(_init themes))
2
2
  @import(exec(style.fscss).pick(body))
3
- div{
4
- background: @event.theme(forest);
5
- %2(width, height[: 200px;])
6
- tr Shape: @event.shape(star);
7
- }
3
+ @arr colors[#1E2783, #8C29B2, #C41348]
4
+ $colors: @arr.colors!;
5
+ div{
6
+ background: @event.theme(forest);
7
+ %2(width, height[: 200px;])
8
+ tr Shape: @event.shape(star);
9
+ }
10
+ .box{
11
+ background: radial-gradient(40deg, $colors.list);
12
+ }
13
+ .box-b{
14
+ background: radial-gradient(40deg, $colors.reverse);
15
+ }
16
+ exec(_log, "Hello World!")
@@ -260,10 +260,18 @@ function procExC(css) {
260
260
 
261
261
  return modifiedCSS.trim();
262
262
  }
263
+
263
264
  function initlibraries(css){
264
265
  css = css.replace(/exec\(\s*_init\sisjs\s*\)/g, "exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/isjs.fscss)");
265
266
  css = css.replace(/exec\(\s*_init\sthemes\s*\)/g, "exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/trshapes.fthemes.fscss)")
266
267
  css = css.replace(/exec\(_init\sarray1to500\s*\)/g, "exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/1to500.fscss)");
268
+ css = css.replace(/exec\(_init\s+([\w\d\._—\-\%\*\+\&\$\=]+)(?:\/([\w\-]+))?\s*\)/g, (match, impName, impType)=>{
269
+ if(!impType){
270
+ //`
271
+ return `exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${impName}.fscss)`;
272
+ }
273
+ return `exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${impName}.${impType})`;
274
+ });
267
275
  return css;
268
276
  }
269
277
  function procVar(vcss) {
@@ -453,6 +461,7 @@ function procRan(input) {
453
461
  }
454
462
  });
455
463
  }
464
+
456
465
  function procArr(input) {
457
466
  // 1. Parse array declarations
458
467
  const arrayDeclarationRegex = /@arr\(?\s*([\w\-_—0-9]+)\)?\[([^\]]+)\]\)?/g;
@@ -465,6 +474,99 @@ function procArr(input) {
465
474
 
466
475
  let output = input;
467
476
 
477
+ output = output.replace(/@arr\.([\w\-_—0-9]+)(?:\!\s*\+\s*\[([^\]]+)?\])/g, (match, arrName, newArr) => {
478
+ const arr = arraysExfscss[arrName];
479
+ if (!arr) {
480
+ console.warn(`fscss[@arr] Warning: Array '${arrName}' not found.`);
481
+ return match;
482
+ }
483
+ if (!newArr) {
484
+ console.warn(
485
+ `[FSCSS Warning] @arr push failed → Invalid or empty value at "${match}"`
486
+ );
487
+ return match;
488
+ }
489
+ newItems = newArr.split(',').map(item => item.trim());
490
+ arraysExfscss[arrName].push(...newItems);
491
+ return "";
492
+ })
493
+
494
+ output = output.replace(/@arr\.([\w\-_—0-9]+)(?:\!\s*\-\s*\[([\d\w\-_—\s]+)?\])/g, (match, arrName, ind) => {
495
+ const arr = arraysExfscss[arrName];
496
+ if (!arr) {
497
+ console.warn(`fscss[@arr] Warning: Array '${arrName}' not found.`);
498
+ return match;
499
+ }
500
+ ind = Number(ind?.trim());
501
+ if (!ind||ind<1||!Number(ind)) {
502
+ console.warn(
503
+ `[FSCSS Warning] @arr splice failed → Invalid or empty index at "${match}"`
504
+ );
505
+ return match;
506
+ }
507
+ if(ind>arr.length){
508
+ console.warn(
509
+ `[FSCSS Warning] @arr → @arr.${arrName}[${ind}] is undefined at "${match}"`);
510
+ return "";
511
+ }
512
+ ind = (ind-1);
513
+ arr.splice(ind,1);
514
+ return "";
515
+ })
516
+
517
+
518
+ output = output.replace(/@arr\.([\w\-_—0-9]+)(?:\!\s*\.(length|last|reverse|first|list|indices|randint|segment|sum|unique|sort|shuffle|min|max))/g, (match, arrName, obj) => {
519
+ const arr = arraysExfscss[arrName];
520
+ if (!arr) {
521
+ console.warn(`fscss[@arr] Warning: Array '${arrName}' not found.`);
522
+ return match;
523
+ }
524
+ if(obj){
525
+ if (obj==="length") {
526
+ return arr.length;
527
+ }
528
+ if(obj==="first"){
529
+ return arr[0];
530
+ }
531
+ if (obj==="last") {
532
+ return arr.at(-1);
533
+ }
534
+ if (obj==="indices") {
535
+ return Array(arr.length).fill().map((_, i)=>(i+1)*1);
536
+ }
537
+ if (obj==="list") {
538
+ return arr.join(',');
539
+ }
540
+ if (obj==="reverse") {
541
+ return arr.toReversed().join(',');
542
+ }
543
+ if (obj==="randint") {
544
+ return arr[Math.floor(Math.random() * arr.length)];
545
+ }
546
+ if(obj==="segment") {
547
+ return arr.map(u => `[${u}]`).join('')
548
+ }
549
+ if (obj === "unique") {
550
+ return [...new Set(arr)].join(',');
551
+ }
552
+ if (obj === "sort") {
553
+ return arr.slice().sort().join(',');
554
+ }
555
+ if (obj === "shuffle") {
556
+ return arr.slice().sort(() => Math.random() - 0.5).join(',');
557
+ }
558
+ if (obj === "sum") {
559
+ return arr.reduce((a, b) => a + Number(b), 0);
560
+ }
561
+ if (obj === "min") {
562
+ return Math.min(...arr.map(Number));
563
+ }
564
+ if (obj === "max") {
565
+ return Math.max(...arr.map(Number));
566
+ }
567
+ }
568
+ })
569
+
468
570
  // 2. Process loops using @arr.name[]
469
571
  output = output.replace(/([^\{\}]+)\{\s*([^}]*@arr\.([\w\-_—0-9]+)\[\][^}]*)\s*\}/g,
470
572
  (fullMatch, selector, content, arrayName) => {
@@ -493,8 +595,49 @@ function procArr(input) {
493
595
  return arr[idx] !== undefined ? arr[idx] : fullMatch;
494
596
  });
495
597
 
598
+ output = output.replace(/@arr\.([\w\-_—0-9]+)(?:!\s*\.unit)(?:\(([^)]*)\))/g,
599
+ (fullMatch, arrayName, pl) => {
600
+ const arr = arraysExfscss[arrayName];
601
+ if (!arr) {
602
+ console.warn(`fscss[@arr] Warning: Array '${arrayName}' not found for direct access.`);
603
+ return fullMatch;
604
+ }
605
+ const sep = (pl !== undefined && pl !== "") ? pl : ' ';
606
+ return arr.map(u=>`${u+sep}`).join(',');
607
+ });
608
+
609
+ output = output.replace(/@arr\.([\w\-_—0-9]+)(?:!\s*\.prefix)(?:\(([^)]*)\))/g,
610
+ (fullMatch, arrayName, pl) => {
611
+ const arr = arraysExfscss[arrayName];
612
+ if (!arr) {
613
+ console.warn(`fscss[@arr] Warning: Array '${arrayName}' not found for direct access.`);
614
+ return fullMatch;
615
+ }
616
+ const sep = (pl !== undefined && pl !== "") ? pl : ' ';
617
+ return arr.map(u=>`${sep+u}`).join(',');
618
+ });
619
+
620
+
621
+
622
+ output = output.replace(/@arr\.([\w\-_—0-9]+)(?:!\s*\.surround)(?:\(([^)]+)\))/g,
623
+ (fullMatch, arrayName, sur) => {
624
+ const arr = arraysExfscss[arrayName];
625
+ if (!arr) {
626
+ console.warn(`fscss[@arr] Warning: Array '${arrayName}' not found for direct access.`);
627
+ return fullMatch;
628
+ }
629
+ if(!sur||sur===undefined||sur===""||!sur.includes(",")){
630
+ console.warn(
631
+ `[FSCSS Warning] @arr surround failed → Invalid or empty value at "${fullMatch}"`);
632
+ return fullMatch;
633
+ }
634
+ surArr = sur.split(',');
635
+ return arr.map(u=>`${surArr[0]+u+surArr.at(-1)}`).join(' ');
636
+ });
637
+
638
+
496
639
  // 4. Direct array access: @arr.name or @arr.name(separator)
497
- output = output.replace(/@arr\.([\w\-_—0-9]+)(?:\(([^)]*)\))?/g,
640
+ output = output.replace(/@arr\.([\w\-_—0-9]+)(?:!\s*\.join)?(?:\(([^)]*)\))/g,
498
641
  (fullMatch, arrayName, separator) => {
499
642
  const arr = arraysExfscss[arrayName];
500
643
  if (!arr) {
@@ -504,8 +647,18 @@ function procArr(input) {
504
647
  const sep = (separator !== undefined && separator !== "") ? separator : ' ';
505
648
  return arr.join(sep);
506
649
  });
507
-
508
- // 5. Clean up array declarations
650
+ output = output.replace(/@arr\.([\w\-_—0-9]+)(!)?/g, (match, arrName, fos)=>{
651
+ const arr = arraysExfscss[arrName];
652
+ if (!arr) {
653
+ console.warn(`fscss[@arr] Warning: Array '${arrName}' not found for direct access.`);
654
+ return match;
655
+ }
656
+ if(fos){
657
+ return match;
658
+ }
659
+ return arr.join(' ');
660
+ })
661
+ // Clean up array declarations
509
662
  return output
510
663
  .replace(arrayDeclarationRegex, '')
511
664
  .replace(/\n{3,}/g, '\n\n')
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.13",
4
+ "version": "1.1.14",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "bin": {