Skip to content

Commit

Permalink
SASS: Fully functional; with tweaks. (Issue madskristensen#418)
Browse files Browse the repository at this point in the history
* Maps awaiting sass/node-sass#194.
* Error condition dodged sass/node-sass#207.
  • Loading branch information
am11 committed Jan 5, 2014
1 parent a7d1a0f commit 3e802c3
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace MadsKristensen.EditorExtensions
public class CoffeeScriptCompiler : NodeExecutorBase
{
private static readonly string _compilerPath = Path.Combine(WebEssentialsResourceDirectory, @"nodejs\node_modules\coffee-script\bin\coffee");
private static readonly Regex _errorParsingPattern = new Regex(@".*\\(?<fileName>.*):(?<line>.\d*):(?<column>.\d*): error: (?<message>.*\n.*)", RegexOptions.Multiline);
private static readonly Regex _errorParsingPattern = new Regex(@"(?<fileName>.*):(?<line>.\d*):(?<column>.\d*): error: (?<message>.*\n.*)", RegexOptions.Multiline);
private static readonly Regex _sourceMapInJs = new Regex(@"\/\*\n.*=(.*)\n\*\/", RegexOptions.Multiline);

protected override string ServiceName
Expand Down
11 changes: 6 additions & 5 deletions EditorExtensions/Compilers/NodeExecutorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ public async Task<CompilerResult> Compile(string sourceFileName, string targetFi
{
string errorText = "";

if (File.Exists(errorOutputFile) && process.ExitCode != 0)
errorText = File.ReadAllText(errorOutputFile);
// Subjected to change, depending on https://github.com/andrew/node-sass/issues/207
if (File.Exists(errorOutputFile))
errorText = File.ReadAllText(errorOutputFile).Trim();

return ProcessResult(process, errorText, sourceFileName, targetFileName);
}
Expand Down Expand Up @@ -82,8 +83,8 @@ private CompilerResult ProcessResult(Process process, string errorText, string s
private void ValidateResult(Process process, string outputFile, string errorText, CompilerResult result)
{
try
{
if (process.ExitCode == 0)
{ // Subjected to change, depending on https://github.com/andrew/node-sass/issues/207
if (string.IsNullOrEmpty(errorText) && process.ExitCode == 0)
{
result.Result = File.ReadAllText(outputFile);
result.IsSuccess = true;
Expand Down Expand Up @@ -133,7 +134,7 @@ protected IEnumerable<CompilerError> ParseErrorsWithRegex(string error)
{
FileName = match.Groups["fileName"].Value,
Message = match.Groups["message"].Value,
Column = int.Parse(match.Groups["column"].Value, CultureInfo.CurrentCulture),
Column = string.IsNullOrEmpty(match.Groups["column"].Value) ? 1 : int.Parse(match.Groups["column"].Value, CultureInfo.CurrentCulture),
Line = int.Parse(match.Groups["line"].Value, CultureInfo.CurrentCulture)
};
}
Expand Down
9 changes: 3 additions & 6 deletions EditorExtensions/Compilers/SASS/SassCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ namespace MadsKristensen.EditorExtensions
public class SassCompiler : NodeExecutorBase
{
private static readonly string _compilerPath = Path.Combine(WebEssentialsResourceDirectory, @"nodejs\node_modules\node-sass\bin\node-sass");
private static readonly Regex _endingCurlyBraces = new Regex(@"}\W*}|}", RegexOptions.Compiled);
private static readonly Regex _linesStartingWithTwoSpaces = new Regex("(\n( *))", RegexOptions.Compiled);
private static readonly Regex _errorParsingPattern = new Regex(@"^(?<message>.+) in (?<fileName>.+) on line (?<line>\d+), column (?<column>\d+):$", RegexOptions.Multiline);
private static readonly Regex _errorParsingPattern = new Regex(@"(?<fileName>.*):(?<line>.\d*): error: (?<message>.*\n.*)", RegexOptions.Multiline);
private static readonly Regex _sourceMapInCss = new Regex(@"\/\*#([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/", RegexOptions.Multiline);

protected override string ServiceName
Expand All @@ -33,11 +31,11 @@ protected override Regex ErrorParsingPattern
}
protected override string GetArguments(string sourceFileName, string targetFileName)
{
var args = new StringBuilder("--no-color --relative-urls ");
var args = new StringBuilder("--output-style=expanded ");

if (WESettings.GetBoolean(WESettings.Keys.SassSourceMaps) && !InUnitTests)
{
args.Append("--source-comments=map");
args.Append("--source-comments=map ");
}

args.AppendFormat(CultureInfo.CurrentCulture, "\"{0}\" \"{1}\"", sourceFileName, targetFileName);
Expand All @@ -48,7 +46,6 @@ protected override string GetArguments(string sourceFileName, string targetFileN
protected override string PostProcessResult(string resultSource, string sourceFileName, string targetFileName)
{
// Inserts an empty row between each rule and replace two space indentation with 4 space indentation
resultSource = _endingCurlyBraces.Replace(_linesStartingWithTwoSpaces.Replace(resultSource.Trim(), "$1$2"), "$&\n");
resultSource = UpdateSourceMapUrls(resultSource, targetFileName);

var message = "SASS: " + Path.GetFileName(sourceFileName) + " compiled.";
Expand Down
42 changes: 27 additions & 15 deletions EditorExtensions/EditorExtensions.vsct
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
<Group guid="guidBuildCmdSet" id="MyCompileMenuGroup" priority="0x0003">
<Parent guid="guidTopMenu" id="TopMenu"/>
</Group>

<Group guid="guidEditorExtensionsCmdSet" id="HtmlEncodingMenuGroup" priority="0x0002">
<Parent guid="guidEditorExtensionsCmdSet" id="SubMenu"/>
</Group>
Expand Down Expand Up @@ -119,7 +119,7 @@
<Group guid="guidMinifyCmdSet" id="MyMenuGroup" priority="0x0009">
<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_ITEMNODE"/>
</Group>

<Group guid="guidSolutionExplorerCmdSet" id="MyMenuGroup" priority="0x0001">
<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_ITEMNODE"/>
</Group>
Expand All @@ -141,7 +141,7 @@
</Group>
</Groups>

<Buttons>
<Buttons>
<Button guid="guidEditorExtensionsCmdSet" id="cmdidHtmlEncode" priority="0x0101" type="Button">
<Parent guid="guidEditorExtensionsCmdSet" id="HtmlEncodingMenuGroup" />
<CommandFlag>DynamicVisibility</CommandFlag>
Expand Down Expand Up @@ -278,7 +278,7 @@
<ButtonText>Sort Selection Lines Descending</ButtonText>
</Strings>
</Button>

<Button guid="guidEditorLinesCmdSet" id="RemoveDuplicateLines" priority="0x0106" type="Button">
<Parent guid="guidEditorLinesCmdSet" id="LinesMenuGroup" />
<CommandFlag>DynamicVisibility</CommandFlag>
Expand All @@ -304,7 +304,7 @@
<ButtonText>Remove Duplicate Properties</ButtonText>
</Strings>
</Button>

<Button guid="guidCssCmdSet" id="cmdidCssAddMissingStandard" priority="0x0101" type="Button">
<Parent guid="guidCssCmdSet" id="CssSubMenuGroup" />
<Icon guid="guidNumbers" id="pic2"/>
Expand Down Expand Up @@ -504,6 +504,7 @@
<ButtonText>Update All Bundles</ButtonText>
</Strings>
</Button>

<Button guid="guidBuildCmdSet" id="cmdBuildMinify" priority="0x0102" type="Button">
<Parent guid="guidBuildCmdSet" id="MyBuildMenuGroup"/>
<Icon guid="guidImages" id="bmpLogo"/>
Expand All @@ -512,14 +513,23 @@
<ButtonText>Re-minify All CSS/JS/HTML Files</ButtonText>
</Strings>
</Button>

<Button guid="guidBuildCmdSet" id="cmdBuildLess" priority="0x0103" type="Button">
<Parent guid="guidBuildCmdSet" id="MyCompileMenuGroup"/>
<CommandFlag>DynamicVisibility</CommandFlag>
<Strings>
<ButtonText>Re-compile All LESS Files</ButtonText>
</Strings>
</Button>


<Button guid="guidBuildCmdSet" id="cmdBuildSass" priority="0x0103" type="Button">
<Parent guid="guidBuildCmdSet" id="MyCompileMenuGroup"/>
<CommandFlag>DynamicVisibility</CommandFlag>
<Strings>
<ButtonText>Re-compile All SASS Files</ButtonText>
</Strings>
</Button>

<Button guid="guidBuildCmdSet" id="cmdBuildCoffeeScript" priority="0x0105" type="Button">
<Parent guid="guidBuildCmdSet" id="MyCompileMenuGroup"/>
<CommandFlag>DynamicVisibility</CommandFlag>
Expand Down Expand Up @@ -577,7 +587,7 @@
<ButtonText>Stop Recording (All Browsers)</ButtonText>
</Strings>
</Button>

<Button guid="guidUnusedCssCmdSet" id="UnusedCssResetCommandId" priority="0x2003" type="Button">
<Parent guid="guidBrowserLinkCmdSet" id="IDG_BROWSERLINK_COMMANDS"/>
<Strings>
Expand Down Expand Up @@ -609,7 +619,7 @@
</Bitmaps>
</Commands>

<KeyBindings>
<KeyBindings>
<KeyBinding guid="guidCssCmdSet" id="cmdidCssSortProperties" mod1="Shift Alt" key1="S" editor="guidVSStd97"/>
<KeyBinding guid="guidCssCmdSet" id="cmdidCssRemoveDuplicates" mod1="Shift Alt" key1="R" editor="guidVSStd97"/>
<KeyBinding guid="guidCssCmdSet" id="cmdidCssAddMissingStandard" mod1="Shift Alt" key1="P" editor="guidVSStd97"/>
Expand All @@ -621,14 +631,15 @@

<KeyBinding guid="guidBuildCmdSet" id="cmdBuildBundles" mod1="Shift Alt" key1="I" editor="guidVSStd97"/>
<KeyBinding guid="guidBuildCmdSet" id="cmdBuildLess" mod1="Shift Alt" key1="Y" editor="guidVSStd97"/>
<KeyBinding guid="guidBuildCmdSet" id="cmdBuildSass" mod1="Shift Alt" key1="Y" editor="guidVSStd97"/>
<KeyBinding guid="guidBuildCmdSet" id="cmdBuildMinify" mod1="Shift Alt" key1="F" editor="guidVSStd97"/>
<KeyBinding guid="guidBuildCmdSet" id="cmdBuildCoffeeScript" mod1="Shift Alt" key1="Z" editor="guidVSStd97"/>
<KeyBinding guid="guidFormattingCmdSet" id="SurroundWith" mod1="Shift Alt" key1="W" editor="guidVSStd97"/>
<KeyBinding guid="guidFormattingCmdSet" id="ExpandSelection" mod1="Alt" key1="1" editor="guidVSStd97"/>
<KeyBinding guid="guidFormattingCmdSet" id="ContractSelection" mod1="Alt" key1="2" editor="guidVSStd97"/>
<KeyBinding guid="guidEditorLinesCmdSet" id="SortAsc" mod1="Alt" key1="3" editor="guidVSStd97"/>
<KeyBinding guid="guidEditorLinesCmdSet" id="SortDesc" mod1="Alt" key1="4" editor="guidVSStd97"/>

</KeyBindings>

<CommandPlacements>
Expand Down Expand Up @@ -681,13 +692,13 @@

<Symbols>
<GuidSymbol name="guidEditorExtensionsPkg" value="{5fb7364d-2e8c-44a4-95eb-2a382e30fec8}" />

<GuidSymbol name="guidTopMenu" value="{30947ebe-9147-45f9-96cf-401bfc671a01}">
<IDSymbol name="TopMenu" value="0x3001" />
<IDSymbol name="TopMenuGroup" value="0x3002" />
<IDSymbol name="SolutionSubMenuGroup" value="0x3003" />
</GuidSymbol>

<GuidSymbol name="guidEditorExtensionsCmdSet" value="{e396b698-e00e-444b-9f5f-3dcb1ef74e41}">
<IDSymbol name="MyMenuGroup" value="0x1020" />
<IDSymbol name="cmdidHtmlEncode" value="0x0102" />
Expand Down Expand Up @@ -733,7 +744,7 @@
<IDSymbol name="cmdidCssAddMissingVendor" value="0x0127"/>
<IDSymbol name="cmdidCssAddMissingStandard" value="0x0128"/>
<IDSymbol name="cmdidCssRemoveDuplicates" value="0x0129"/>
<IDSymbol name="CssMinifyMenuGroup" value="0x0130"/>
<IDSymbol name="CssMinifyMenuGroup" value="0x0130"/>
</GuidSymbol>

<GuidSymbol name="guidCssIntellisenseCmdSet" value="{e396b698-e00e-444b-9f5f-3dcb1ef74e51}">
Expand Down Expand Up @@ -772,7 +783,7 @@
<IDSymbol name="cmdMinifyHtml" value="0x1058" />
</GuidSymbol>

<GuidSymbol name="guidExtractCmdSet" value="{e396b698-e00e-444b-9f5f-3dcb1ef74e64}">
<GuidSymbol name="guidExtractCmdSet" value="{e396b698-e00e-444b-9f5f-3dcb1ef74e64}">
<IDSymbol name="cmdExtractSelection" value="0x1054" />
<IDSymbol name="cmdExtractVariable" value="0x1056" />
<IDSymbol name="cmdExtractMixin" value="0x1057" />
Expand All @@ -783,6 +794,7 @@
<IDSymbol name="MyBuildMenuGroup" value="0x1082" />
<IDSymbol name="cmdBuildBundles" value="0x1083" />
<IDSymbol name="cmdBuildLess" value="0x1084" />
<IDSymbol name="cmdBuildSass" value="0x1085" />
<IDSymbol name="cmdBuildMinify" value="0x1086" />
<IDSymbol name="cmdBuildCoffeeScript" value="0x1087" />
<IDSymbol name="MyCompileMenuGroup" value="0x1088" />
Expand Down Expand Up @@ -824,7 +836,7 @@
<IDSymbol name="jsContextMenu" value="0x040d"/>
<!-- 52 in hex is 0x0034 -->
</GuidSymbol>

<GuidSymbol name="guidUnusedCssCmdSet" value="{47BA41E6-C7AB-49F1-984A-30E672AFF9FC}">
<IDSymbol name="UnusedCssExtensionGroup" value="0x2020" />
<IDSymbol name="UnusedCssSnapshotCommandId" value="0x2100" />
Expand All @@ -836,7 +848,7 @@
<GuidSymbol name="guidPixelPushingCmdSet" value="{EE755B3C-F6ED-414B-86BA-1AADB7DAE216}">
<IDSymbol name="PixelPushingToggleCommandId" value="0x2200" />
</GuidSymbol>

<GuidSymbol name="guidBrowserLinkCmdSet" value="{30947ebe-9147-45f9-96cf-401bfc671a82}">
<IDSymbol name="IDG_BROWSERLINK_COMMANDS" value="0x2001" />
</GuidSymbol>
Expand Down
1 change: 1 addition & 0 deletions EditorExtensions/EditorExtensionsPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace MadsKristensen.EditorExtensions
[ProvideOptionPage(typeof(CssOptions), "Web Essentials", "CSS", 101, 102, true, new[] { "Minify", "Minification", "W3C", "CSS3" })]
[ProvideOptionPage(typeof(JsHintOptions), "Web Essentials", "JSHint", 101, 103, true, new[] { "JSLint", "Lint" })]
[ProvideOptionPage(typeof(LessOptions), "Web Essentials", "LESS", 101, 105, true)]
[ProvideOptionPage(typeof(SassOptions), "Web Essentials", "SASS", 101, 113, true)]
[ProvideOptionPage(typeof(CoffeeScriptOptions), "Web Essentials", "CoffeeScript", 101, 106, true, new[] { "Iced", "JavaScript", "JS", "JScript" })]
[ProvideOptionPage(typeof(JavaScriptOptions), "Web Essentials", "JavaScript", 101, 107, true, new[] { "JScript", "JS", "Minify", "Minification", "EcmaScript" })]
[ProvideOptionPage(typeof(BrowserLinkOptions), "Web Essentials", "Browser Link", 101, 108, true, new[] { "HTML menu", "BrowserLink" })]
Expand Down
6 changes: 6 additions & 0 deletions EditorExtensions/Options/ProjectSettingsStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,12 @@ private static SortedDictionary<string, object> DefaultSettings()
dic.Add(Keys.LessMinify, true);
dic.Add(Keys.LessEnableCompiler, true);

// SASS
dic.Add(Keys.GenerateCssFileFromSass, true);
dic.Add(Keys.ShowSassPreviewWindow, true);
dic.Add(Keys.SassMinify, true);
dic.Add(Keys.SassEnableCompiler, true);

// TypeScript
dic.Add(Keys.ShowTypeScriptPreviewWindow, true);

Expand Down
72 changes: 72 additions & 0 deletions EditorExtensions/Options/Sass.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System.ComponentModel;
using Microsoft.VisualStudio.Shell;

namespace MadsKristensen.EditorExtensions
{
class SassOptions : DialogPage
{
public SassOptions()
{
Settings.Updated += delegate { LoadSettingsFromStorage(); };
}

public override void SaveSettingsToStorage()
{
Settings.SetValue(WESettings.Keys.GenerateCssFileFromSass, GenerateCssFileFromSass);
Settings.SetValue(WESettings.Keys.ShowSassPreviewWindow, ShowSassPreviewWindow);
Settings.SetValue(WESettings.Keys.SassMinify, SassMinify);
Settings.SetValue(WESettings.Keys.SassCompileOnBuild, SassCompileOnBuild);
Settings.SetValue(WESettings.Keys.SassSourceMaps, SassSourceMaps);
Settings.SetValue(WESettings.Keys.SassEnableCompiler, SassEnableCompiler);
Settings.SetValue(WESettings.Keys.SassCompileToLocation, SassCompileToLocation ?? string.Empty);

Settings.Save();
}

public override void LoadSettingsFromStorage()
{
GenerateCssFileFromSass = WESettings.GetBoolean(WESettings.Keys.GenerateCssFileFromSass);
ShowSassPreviewWindow = WESettings.GetBoolean(WESettings.Keys.ShowSassPreviewWindow);
SassMinify = WESettings.GetBoolean(WESettings.Keys.SassMinify);
SassCompileOnBuild = WESettings.GetBoolean(WESettings.Keys.SassCompileOnBuild);
SassSourceMaps = WESettings.GetBoolean(WESettings.Keys.SassSourceMaps);
SassEnableCompiler = WESettings.GetBoolean(WESettings.Keys.SassEnableCompiler);
SassCompileToLocation = WESettings.GetString(WESettings.Keys.SassCompileToLocation);
}

[LocDisplayName("Generate CSS file on save")]
[Description("Generate CSS file when SASS file is saved")]
[Category("SASS")]
public bool GenerateCssFileFromSass { get; set; }

[LocDisplayName("Minify generated CSS files on save")]
[Description("Creates a minified version of the compiled CSS file (file.min.css).")]
[Category("SASS")]
public bool SassMinify { get; set; }

[LocDisplayName("Generate source maps")]
[Description("Creates a source map when compiling the CSS file (file.css.map).")]
[Category("SASS")]
public bool SassSourceMaps { get; set; }

[LocDisplayName("Show preview window")]
[Description("Shows the preview window when editing a SASS file.")]
[Category("SASS")]
public bool ShowSassPreviewWindow { get; set; }

[LocDisplayName("Compile on build")]
[Description("Compiles all SASS files in the project that have a corresponding .css file.")]
[Category("SASS")]
public bool SassCompileOnBuild { get; set; }

[LocDisplayName("Enable SASS compiler")]
[Description("Enables compiling SASS files. When false, no SASS files will be compiled to CSS, including during a build.")]
[Category("SASS")]
public bool SassEnableCompiler { get; set; }

[LocDisplayName("Compile to a custom folder")]
[Description("Compiles each SASS file into a custom folder. Leave empty to save the compiled .css file to the same directory as the .scss file. Or, prefix your output directory with a `/` to indicate that it starts at the project's root directory (for example '/css' or '/styles') - this will apply to ALL .scss files! Otherwise, a relative path is assumed (starting from the file being compiled) - this may cause the output path to be different for each .scss file.")]
[Category("SASS")]
public string SassCompileToLocation { get; set; }
}
}
3 changes: 3 additions & 0 deletions EditorExtensions/WebEssentials2013.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,9 @@
<Compile Include="Options\Html.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Options\Sass.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Options\Markdown.cs">
<SubType>Component</SubType>
</Compile>
Expand Down

0 comments on commit 3e802c3

Please sign in to comment.