Skip to content

Commit

Permalink
fully migrate old code, v0.3
Browse files Browse the repository at this point in the history
  • Loading branch information
CypherPotato committed Mar 9, 2024
1 parent 69a74a8 commit 20a7873
Show file tree
Hide file tree
Showing 19 changed files with 340 additions and 181 deletions.
12 changes: 6 additions & 6 deletions simple-css-nesting.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.002.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cascadium", "src\Cascadium.csproj", "{ACD2DBA9-BF07-4F18-95ED-BC69DCC59A3C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cascadium-Utility", "tool\Cascadium-Utility.csproj", "{CB7E8644-3094-44DB-94C9-068CB12C4993}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{650184C6-E955-4D15-B478-15BB312B79AF}"
Expand All @@ -13,16 +11,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{EF0FD356
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CssTests", "tests\build\CssTests\CssTests.csproj", "{9C391FB9-77C4-420D-88DC-2863B759AA64}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CascadiumLexer", "src\CascadiumLexer.csproj", "{7043E166-FDAC-4ACB-B44E-1EE018CADAE8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{ACD2DBA9-BF07-4F18-95ED-BC69DCC59A3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ACD2DBA9-BF07-4F18-95ED-BC69DCC59A3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ACD2DBA9-BF07-4F18-95ED-BC69DCC59A3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ACD2DBA9-BF07-4F18-95ED-BC69DCC59A3C}.Release|Any CPU.Build.0 = Release|Any CPU
{CB7E8644-3094-44DB-94C9-068CB12C4993}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CB7E8644-3094-44DB-94C9-068CB12C4993}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CB7E8644-3094-44DB-94C9-068CB12C4993}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -31,6 +27,10 @@ Global
{9C391FB9-77C4-420D-88DC-2863B759AA64}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9C391FB9-77C4-420D-88DC-2863B759AA64}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9C391FB9-77C4-420D-88DC-2863B759AA64}.Release|Any CPU.Build.0 = Release|Any CPU
{7043E166-FDAC-4ACB-B44E-1EE018CADAE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7043E166-FDAC-4ACB-B44E-1EE018CADAE8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7043E166-FDAC-4ACB-B44E-1EE018CADAE8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7043E166-FDAC-4ACB-B44E-1EE018CADAE8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
63 changes: 43 additions & 20 deletions src/CascadiumCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,17 @@
namespace Cascadium;

/// <summary>
/// Provides a CSS compiler that compiles higher-level code with single-line comments, nesting into a legacy CSS file.
/// Provides a compiler that compiles Cascadium code into an legacy CSS file.
/// </summary>
public sealed partial class CascadiumCompiler
public static class CascadiumCompiler
{
/// <summary>
/// Compiles a top-module CSS stylesheet to legacy CSS, with the code already minified.
/// Compiles an Cascadium stylesheet to legacy CSS.
/// </summary>
/// <param name="xcss">The byte array including the top module CSS code.</param>
/// <param name="encoder">The encoder which will be used to decode the CSS output.</param>
/// <param name="options">Optional options and parameters to the compilation.</param>
/// <returns>The compiled and minified UTF-8 CSS.</returns>
public static string Compile(ReadOnlySpan<byte> xcss, Encoding encoder, CascadiumOptions? options = null)
{
return Compile(encoder.GetString(xcss), options);
}

/// <summary>
/// Compiles a top-module CSS stylesheet to legacy CSS, with the code already minified.
/// </summary>
/// <param name="xcss">The top module CSS code.</param>
/// <param name="options">Optional options and parameters to the compilation.</param>
/// <param name="xcss">The Cascadium source code.</param>
/// <param name="options">Optional. Options and parameters to the compiler.</param>
/// <returns>The compiled and minified CSS.</returns>
public static string Compile(string xcss, CascadiumOptions? options = null)
public static CssStylesheet Parse(string xcss, CascadiumOptions? options = null)
{
CascadiumOptions _options = options ?? new CascadiumOptions();

Expand All @@ -55,13 +43,48 @@ public static string Compile(string xcss, CascadiumOptions? options = null)
//// build the css body, assembling the flat rules into an valid
//// css string
CssStylesheet css = new Assembler(_options).AssemblyCss(flattenStylesheet, _options);
css.Options = _options;

//// apply cascadium extensions
if (_options.UseVarShortcut) ValueHandler.TransformVarShortcuts(css);
if (_options.AtRulesRewrites.Count > 0) MediaRewriter.ApplyRewrites(css, _options);
if (_options.Converters.Count > 0) Converter.ConvertAll(css, _options);

//// export the css into an string
return css.Export(_options);
return css;
}

/// <summary>
/// Compiles an Cascadium stylesheet to legacy CSS.
/// </summary>
/// <param name="xcss">The Cascadium source code.</param>
/// <param name="options">Optional. Options and parameters to the compiler.</param>
/// <returns>The compiled and minified CSS.</returns>
public static string Compile(string xcss, CascadiumOptions? options = null)
{
CascadiumOptions _options = options ?? new CascadiumOptions();
return Parse(xcss, _options).Export();
}

/// <summary>
/// Compiles an Cascadium stylesheet to legacy CSS.
/// </summary>
/// <param name="xcss">The byte array including the Cascadium source code.</param>
/// <param name="options">Optional. Options and parameters to the compiler.</param>
/// <returns>The compiled UTF-8 CSS.</returns>
public static string Compile(ReadOnlySpan<byte> xcss, CascadiumOptions? options = null)
{
return Compile(xcss, Encoding.UTF8, options);
}

/// <summary>
/// Compiles an Cascadium stylesheet to legacy CSS.
/// </summary>
/// <param name="xcss">The byte array including the Cascadium source code.</param>
/// <param name="encoder">The encoder which will be used to decode the CSS output.</param>
/// <param name="options">Optional. Options and parameters to the compiler.</param>
/// <returns>The compiled CSS.</returns>
public static string Compile(ReadOnlySpan<byte> xcss, Encoding encoder, CascadiumOptions? options = null)
{
return Compile(encoder.GetString(xcss), options);
}
}
50 changes: 8 additions & 42 deletions src/CascadiumLexer.csproj
Original file line number Diff line number Diff line change
@@ -1,44 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>Cascadium</RootNamespace>
<AssemblyName>Cascadium.Core</AssemblyName>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>

<Title>Cascadium Compiler</Title>
<PackageId>Cascadium.Compiler</PackageId>

<Authors>CypherPotato</Authors>
<Company>Project Principium</Company>
<Product>Cascadium</Product>
<Description>Provides a CSS compiler that compiles higher-level code with single-line comments, nesting and more into a legacy CSS file.</Description>
<PackageReadmeFile>README.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/CypherPotato/cascadium</RepositoryUrl>
<PackageTags>css,scss,sass,less</PackageTags>
<RepositoryType>git</RepositoryType>

<Version>0.2.0</Version>
<AssemblyVersion>0.2.0</AssemblyVersion>
<FileVersion>0.2.0</FileVersion>

<NeutralLanguage>en</NeutralLanguage>
<IncludeSymbols>True</IncludeSymbols>
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
</PropertyGroup>

<ItemGroup>
<None Include="..\README.md">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
<None Include="..\LICENSE.txt">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>

</Project>
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>Cascadium</RootNamespace>
</PropertyGroup>

</Project>
36 changes: 18 additions & 18 deletions src/Compiler/Assembler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ public CssStylesheet AssemblyCss(FlatStylesheet flatStylesheet, CascadiumOptions
{
cssRule = new CssRule()
{
Declarations = rule.Declarations,
Selector = rule.Selectors[0][0],
Order = ++ruleIndex
_declarations = rule.Declarations,
Selector = BuildCssSelector(rule.Selectors),
_order = ++ruleIndex
};
result.Rules.Add(cssRule);
result._rules.Add(cssRule);
}
else
{
Expand All @@ -49,29 +49,29 @@ public CssStylesheet AssemblyCss(FlatStylesheet flatStylesheet, CascadiumOptions

cssRule = new CssRule()
{
Declarations = rule.Declarations,
_declarations = rule.Declarations,
Selector = selector,
Order = ++ruleIndex
_order = ++ruleIndex
};

if (atRule != null)
{
CssStylesheet atRuleStylesheet = result.GetOrCreateStylesheet(atRule, options.Merge.HasFlag(MergeOption.AtRules));
atRuleStylesheet.Rules.Add(cssRule);
atRuleStylesheet._rules.Add(cssRule);
}
else
{
result.Rules.Add(cssRule);
result._rules.Add(cssRule);
}
}
}

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

if (options.Merge != MergeOption.None)
{
Merge(result, options);
foreach(CssStylesheet subCss in result.Stylesheets)
foreach(CssStylesheet subCss in result._stylesheets)
{
Merge(subCss, options);
}
Expand Down Expand Up @@ -166,7 +166,7 @@ public void Merge(CssStylesheet stylesheet, CascadiumOptions options)
{
List<CssRule> newRules = new List<CssRule>();

foreach (CssRule rule in stylesheet.Rules)
foreach (CssRule rule in stylesheet._rules)
{
CssRule? existingRule = newRules
.FirstOrDefault(r => Helper.IsSelectorsEqual(r.Selector, rule.Selector));
Expand All @@ -177,28 +177,28 @@ public void Merge(CssStylesheet stylesheet, CascadiumOptions options)
}
else
{
foreach (var prop in rule.Declarations)
foreach (var prop in rule._declarations)
{
existingRule.Declarations[prop.Key] = prop.Value;
existingRule._declarations[prop.Key] = prop.Value;

if (options.MergeOrderPriority == MergeOrderPriority.PreserveLast)
{
if (rule.Order > existingRule.Order)
existingRule.Order = rule.Order;
if (rule._order > existingRule._order)
existingRule._order = rule._order;
}
}
}
}

stylesheet.Rules = newRules;
stylesheet._rules = newRules;
}

if (options.Merge.HasFlag(MergeOption.Declarations))
{
// merge top-level only
List<CssRule> newRules = new List<CssRule>();

foreach (CssRule rule in stylesheet.Rules)
foreach (CssRule rule in stylesheet._rules)
{
CssRule? existingRule = newRules
.FirstOrDefault(r => r.GetHashCode() == rule.GetHashCode());
Expand All @@ -213,7 +213,7 @@ public void Merge(CssStylesheet stylesheet, CascadiumOptions options)
}
}

stylesheet.Rules = newRules;
stylesheet._rules = newRules;
}
}
}
49 changes: 49 additions & 0 deletions src/Compiler/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,55 @@ namespace Cascadium.Compiler;

internal static class Helper
{
public static int SafeCountIncidences(string value, char op)
{
int incidences = 0;
bool inSingleString = false;
bool inDoubleString = false;
int expressionIndex = 0, groupIndex = 0;

for (int i = 0; i < value.Length; i++)
{
char c = value[i];
char b = i > 0 ? value[i - 1] : '\0';

if (c == '\'' && b != '\\' && !inDoubleString)
{
inSingleString = !inSingleString;
}
else if (c == '"' && b != '\\' && !inSingleString)
{
inDoubleString = !inDoubleString;
}
else if (c == '(' && !(inDoubleString || inSingleString))
{
expressionIndex++;
}
else if (c == ')' && !(inDoubleString || inSingleString))
{
expressionIndex--;
}
else if (c == '[' && !(inDoubleString || inSingleString))
{
groupIndex++;
}
else if (c == ']' && !(inDoubleString || inSingleString))
{
groupIndex--;
}

if ((inDoubleString || inSingleString) == false && expressionIndex == 0 && groupIndex == 0)
{
if (c == op)
{
incidences++;
}
}
}

return incidences;
}

public static string[] SafeSplit(string? value, char op)
{
if (value == null) return Array.Empty<string>();
Expand Down
3 changes: 1 addition & 2 deletions src/Compiler/TextInterpreter.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Text;
using System.Text;
using Cascadium.Object;

namespace Cascadium.Compiler;
Expand Down
8 changes: 6 additions & 2 deletions src/Compiler/Tokenizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,13 @@ IEnumerable<Token> ReadCurrentDeclaration(string declaration)
string property = declaration.Substring(0, dotPos).Trim();
string value = declaration.Substring(dotPos + 1).Trim();

if (property == "")
if (!Token.IsValidPropertyName(property))
{
throw new CascadiumException(Interpreter.TakeSnapshot(declaration), "syntax error: property name cannot be empty");
throw new CascadiumException(Interpreter.TakeSnapshot(declaration), "syntax error: invalid property name");
}
else if (Token.IsPropertyValueUnescapedDoubleDots(value))
{
throw new CascadiumException(Interpreter.TakeSnapshot(declaration), "syntax error: unclosed declaration");
}
else
{
Expand Down
Loading

0 comments on commit 20a7873

Please sign in to comment.