Skip to content

Commit 1b31444

Browse files
committed
0.9.2
1 parent 72c4c4b commit 1b31444

9 files changed

+114
-76
lines changed

README.md

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,53 @@
22

33
Cascadium is an lightweight pre-processor for the CSS styling language.
44

5-
This small module can compile CSS with the following features into a legacy CSS file that is more compatible with most browsers.
5+
This small module can compile CSS with the following features into a legacy CSS file that is more compatible with most browsers. It is written in C#, built to run in any operating system without .NET installed. Also, it's source code is open-source.
66

7-
It is written in C#, built to run in any operating system without .NET installed. Also, it's source code is open-source.
7+
Cascadium, unlike other CSS preprocessors, tends to be an extension of the CSS language and not another language. It has some developer-specific quirks, but all of them are aimed at still being "CSS".
88

9-
Some of what it can do:
9+
Main features:
1010

11-
- nesting
12-
- single line comments
13-
- minify and compress
14-
- merge equivalent queries and selectors
15-
- converters
16-
- rewriters
11+
- Convert nested CSS into plain CSS
12+
- Single line comments
13+
- Minify, compress and merge CSS files
14+
- Custom property converters
15+
- Media query rewriters
1716

1817
## Getting started
1918

20-
Learn how to [get started](https://cascadium.project-principium.dev/get-started) with Cascadium and optimize your CSS development.
19+
You can use the library in your C# project or use the cross-platform tool compatible with absolutely any type of project.
20+
21+
To use the library in your code, you can start by adding the reference to Cascadium:
22+
23+
```
24+
dotnet add package Cascadium.Compiler
25+
```
26+
27+
And use as the example below:
28+
29+
```csharp
30+
static void Main(string[] args)
31+
{
32+
string xcss = """
33+
div {
34+
color: red;
35+
36+
> span {
37+
color: blue;
38+
font-weight: 500;
39+
}
40+
}
41+
""";
42+
43+
var stylesheet = CascadiumCompiler.Parse(xcss);
44+
var css = stylesheet.Export();
45+
46+
Console.WriteLine(css);
47+
}
48+
```
49+
50+
And get the result:
51+
52+
```css
53+
div{color:red}div>span{color:blue;font-weight:500}
54+
```

src/CascadiumLexer.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121
<PackageTags>css,scss,sass,less</PackageTags>
2222
<RepositoryType>git</RepositoryType>
2323

24-
<Version>0.9.1</Version>
25-
<AssemblyVersion>0.9.1</AssemblyVersion>
26-
<FileVersion>0.9.1</FileVersion>
24+
<Version>0.9.2</Version>
25+
<AssemblyVersion>0.9.2</AssemblyVersion>
26+
<FileVersion>0.9.2</FileVersion>
2727

2828
<NeutralLanguage>en</NeutralLanguage>
2929
<IncludeSymbols>True</IncludeSymbols>

src/Compiler/Assembler.cs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
using System;
1+
using Cascadium.Entity;
2+
using Cascadium.Object;
3+
using System;
24
using System.Collections.Generic;
35
using System.Linq;
46
using System.Text;
5-
using Cascadium.Entity;
6-
using Cascadium.Object;
77

88
namespace Cascadium.Compiler;
99

@@ -13,14 +13,14 @@ class Assembler
1313

1414
public Assembler(CompilationContext context)
1515
{
16-
Context = context;
16+
this.Context = context;
1717
}
1818

1919
public CssStylesheet AssemblyCss(FlatStylesheet flatStylesheet)
2020
{
2121
CssStylesheet result = new CssStylesheet()
2222
{
23-
Options = Context.Options
23+
Options = this.Context.Options
2424
};
2525
int ruleIndex = 0;
2626

@@ -38,15 +38,15 @@ public CssStylesheet AssemblyCss(FlatStylesheet flatStylesheet)
3838
cssRule = new CssRule()
3939
{
4040
_declarations = rule.Declarations,
41-
Selector = BuildCssSelector(rule.Selectors),
41+
Selector = this.BuildCssSelector(rule.Selectors),
4242
_order = ++ruleIndex
4343
};
4444
result._rules.Add(cssRule);
4545
}
4646
else
4747
{
4848
string? atRule = rule.PopAtRule();
49-
string selector = BuildCssSelector(rule.Selectors);
49+
string selector = this.BuildCssSelector(rule.Selectors);
5050

5151
cssRule = new CssRule()
5252
{
@@ -57,7 +57,7 @@ public CssStylesheet AssemblyCss(FlatStylesheet flatStylesheet)
5757

5858
if (atRule != null)
5959
{
60-
bool canMerge = Context.Options.Merge.HasFlag(MergeOption.AtRules)
60+
bool canMerge = this.Context.Options.Merge.HasFlag(MergeOption.AtRules)
6161
|| IsGroupAtRule(atRule);
6262
CssStylesheet atRuleStylesheet = result.GetOrCreateStylesheet(atRule, canMerge);
6363
atRuleStylesheet._rules.Add(cssRule);
@@ -71,12 +71,12 @@ public CssStylesheet AssemblyCss(FlatStylesheet flatStylesheet)
7171

7272
result._statements.AddRange(flatStylesheet.Statements);
7373

74-
if (Context.Options.Merge != MergeOption.None)
74+
if (this.Context.Options.Merge != MergeOption.None)
7575
{
76-
Merge(result, Context.Options);
76+
this.Merge(result, this.Context.Options);
7777
foreach (CssStylesheet subCss in result._stylesheets)
7878
{
79-
Merge(subCss, Context.Options);
79+
this.Merge(subCss, this.Context.Options);
8080
}
8181
}
8282

@@ -108,16 +108,16 @@ string BuildCssSelector(IList<string[]> selectors)
108108
}
109109
if (flatCount == 1)
110110
{
111-
return BuildCssSelector(selectors[0], Array.Empty<string>());
111+
return this.BuildCssSelector(selectors[0], Array.Empty<string>());
112112
}
113113
else
114114
{
115-
string carry = BuildCssSelector(selectors[0], Array.Empty<string>());
115+
string carry = this.BuildCssSelector(selectors[0], Array.Empty<string>());
116116
for (int i = 1; i < flatCount; i++)
117117
{
118118
string[] current = selectors[i];
119119
if (current.Length == 0) continue;
120-
carry = BuildCssSelector(current, Helper.SafeSplit(carry, ','));
120+
carry = this.BuildCssSelector(current, Helper.SafeSplit(carry, ','));
121121
}
122122
return carry;
123123
}
@@ -130,10 +130,10 @@ string BuildCssSelector(string[] currentSelectors, string[] parentSelectors)
130130
{
131131
foreach (string cSelector in currentSelectors)
132132
{
133-
string prepared = Helper.PrepareSelectorUnit(cSelector, Context.Options.KeepNestingSpace, Context.Options.Pretty);
133+
string prepared = Helper.PrepareSelectorUnit(cSelector, this.Context.Options.KeepNestingSpace, this.Context.Options.Pretty);
134134
sb.Append(prepared);
135135
sb.Append(',');
136-
if (Context.Options.Pretty)
136+
if (this.Context.Options.Pretty)
137137
sb.Append(' ');
138138
}
139139
goto finish;
@@ -151,7 +151,7 @@ string BuildCssSelector(string[] currentSelectors, string[] parentSelectors)
151151
{
152152
sb.Append(b);
153153
s = c.Substring(1);
154-
if (!Context.Options.KeepNestingSpace)
154+
if (!this.Context.Options.KeepNestingSpace)
155155
{
156156
s = s.TrimStart();
157157
}
@@ -172,17 +172,17 @@ string BuildCssSelector(string[] currentSelectors, string[] parentSelectors)
172172
s = c;
173173
}
174174

175-
s = Helper.PrepareSelectorUnit(s, Context.Options.KeepNestingSpace, Context.Options.Pretty);
175+
s = Helper.PrepareSelectorUnit(s, this.Context.Options.KeepNestingSpace, this.Context.Options.Pretty);
176176
sb.Append(s);
177177
sb.Append(',');
178-
if (Context.Options.Pretty)
178+
if (this.Context.Options.Pretty)
179179
sb.Append(' ');
180180
}
181181
}
182182

183183
finish:
184184
if (sb.Length > 0) sb.Length--;
185-
if (sb.Length > 0 && Context.Options.Pretty) sb.Length--;
185+
if (sb.Length > 0 && this.Context.Options.Pretty) sb.Length--;
186186
return sb.ToString();
187187
}
188188

src/Compiler/Sanitizer.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Text;
1+
using System;
2+
using System.Text;
23

34
namespace Cascadium.Compiler;
45

@@ -7,8 +8,7 @@ class Sanitizer
78
public static string SanitizeInput(string input)
89
{
910
StringBuilder output = new StringBuilder(input.Length);
10-
11-
char[] inputChars = input.ToCharArray();
11+
ReadOnlySpan<char> inputChars = input;
1212

1313
bool inSingleString = false;
1414
bool inDoubleString = false;
@@ -18,10 +18,12 @@ public static string SanitizeInput(string input)
1818
var inString = () => inSingleString || inDoubleString;
1919
var inComment = () => inMultilineComment || inSinglelineComment;
2020

21-
for (int i = 0; i < inputChars.Length; i++)
21+
int len = inputChars.Length;
22+
for (int i = 0; i < len; i++)
2223
{
2324
char current = inputChars[i];
2425
char before = i > 0 ? inputChars[i - 1] : '\0';
26+
char next = len - 1 > i ? inputChars[i + 1] : '\0';
2527

2628
if (current == '\'' && before != '\\' && !inDoubleString && !inComment())
2729
{
@@ -42,13 +44,13 @@ public static string SanitizeInput(string input)
4244
inMultilineComment = false;
4345
continue;
4446
}
45-
else if (current == '/' && before == '/' && !inString() && !inMultilineComment)
47+
else if (current == '/' && before == '/' && next != '*' && !inString() && !inMultilineComment)
4648
{
4749
inSinglelineComment = true;
4850
if (output.Length > 0) output.Length--;
4951
continue;
5052
}
51-
else if (current == '\n' || current == '\r' && !inString() && inSinglelineComment)
53+
else if ((current == '\n' || current == '\r') && !inString() && inSinglelineComment)
5254
{
5355
inSinglelineComment = false;
5456
}

src/Compiler/TextInterpreter.cs

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ public int Line
1414
get
1515
{
1616
int ocurrences = 1; // line start at 1
17-
for (int i = 0; i < this.Position; i++)
17+
for (int i = 0; i < Position; i++)
1818
{
19-
if (this.InputString[i] == '\n')
19+
if (InputString[i] == '\n')
2020
{
2121
ocurrences++;
2222
}
@@ -30,9 +30,9 @@ public int Column
3030
get
3131
{
3232
int col = 1;
33-
for (int n = 0; n < this.Position; n++)
33+
for (int n = 0; n < Position; n++)
3434
{
35-
if (this.InputString[n] == '\n')
35+
if (InputString[n] == '\n')
3636
{
3737
col = 0;
3838
}
@@ -44,48 +44,48 @@ public int Column
4444

4545
public TextInterpreter(string s)
4646
{
47-
this.InputString = s;
48-
this.Length = this.InputString.Length;
47+
InputString = s;
48+
Length = InputString.Length;
4949
}
5050

5151
public TokenDebugInfo TakeSnapshot(string text)
5252
{
53-
int textIndex = this.InputString.Substring(0, this.Position).LastIndexOf(text.Trim());
54-
return this.TakeSnapshot(-(this.Position - textIndex));
53+
int textIndex = InputString.Substring(0, Position).LastIndexOf(text.Trim());
54+
return TakeSnapshot(-(Position - textIndex));
5555
}
5656

5757
public TokenDebugInfo TakeSnapshot(int offset = 0)
5858
{
59-
this.Move(offset);
59+
Move(offset);
6060
var snapshot = new TokenDebugInfo()
6161
{
62-
Column = this.Column,
63-
Line = this.Line
62+
Column = Column,
63+
Line = Line
6464
};
65-
this.Move(offset * -1);
65+
Move(offset * -1);
6666

6767
return snapshot;
6868
}
6969

7070
public bool CanRead()
7171
{
72-
return this.Position < this.InputString.Length - 1;
72+
return Position < InputString.Length - 1;
7373
}
7474

7575
public void Move(int count)
7676
{
77-
this.Position = Math.Min(Math.Max(this.Position + count, 0), this.InputString.Length);
77+
Position = Math.Min(Math.Max(Position + count, 0), InputString.Length);
7878
}
7979

8080
public int Read(out char c)
8181
{
82-
if (this.InputString.Length <= this.Position)
82+
if (InputString.Length <= Position)
8383
{
8484
c = '\0';
8585
return -1;
8686
}
87-
c = this.InputString[this.Position];
88-
this.Position++;
87+
c = InputString[Position];
88+
Position++;
8989
return 1;
9090
}
9191

@@ -96,7 +96,7 @@ public string ReadAtLeast(int count)
9696
int n = 0;
9797
while (n < count)
9898
{
99-
int j = this.Read(out char c);
99+
int j = Read(out char c);
100100
if (j >= 0)
101101
{
102102
sb.Append(c);
@@ -117,7 +117,7 @@ public char ReadUntil(Span<char> untilChars, bool wrapStringToken, out string re
117117
bool inSingleString = false;
118118
char b = '\0';
119119

120-
while (this.Read(out char c) > 0)
120+
while (Read(out char c) > 0)
121121
{
122122
if (wrapStringToken && !inSingleString && c == Token.Ch_DoubleStringQuote && b != Token.Ch_CharEscape)
123123
{
@@ -154,15 +154,15 @@ public void SkipIgnoreTokens()
154154
bool skipping = true;
155155
while (skipping)
156156
{
157-
if (this.Read(out char c) > 0)
157+
if (Read(out char c) > 0)
158158
{
159159
if (Token.IsWhitespaceChr(c))
160160
{
161161
continue; // whitespace
162162
}
163163
else
164164
{
165-
this.Move(-1);
165+
Move(-1);
166166
break;
167167
}
168168
}

src/Compiler/Tokenizer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
using System.Collections.Generic;
2-
using Cascadium.Object;
1+
using Cascadium.Object;
2+
using System.Collections.Generic;
33

44
namespace Cascadium.Compiler;
55

0 commit comments

Comments
 (0)