/// <summary> /// Converts the specified scss content string. /// </summary> /// <param name="scss">A scss content.</param> /// <param name="options">The options.</param> /// <returns>The result of the conversion</returns> /// <exception cref="System.ArgumentNullException">if scss is null</exception> public static ScssResult ConvertToCss(string scss, ScssOptions options = null) { if (scss == null) { throw new ArgumentNullException(nameof(scss)); } return(FromCore(scss, false, options)); }
/// <summary> /// Converts a scss content from the specified scss file. /// </summary> /// <param name="scssFile">A scss file.</param> /// <param name="options">The options.</param> /// <returns>The result of the conversion</returns> /// <exception cref="System.ArgumentNullException">if scss is null</exception> public static ScssResult ConvertFileToCss(string scssFile, ScssOptions options = null) { if (scssFile == null) { throw new ArgumentNullException(nameof(scssFile)); } return(FromCore(scssFile, true, options)); }
/// <summary> /// Shared conversion method. /// </summary> /// <param name="fromStringOrFile">From string or file.</param> /// <param name="fromFile">if set to <c>true</c> <paramref name="fromStringOrFile"/> is a scss file; otherwise it is a scss content.</param> /// <param name="options">The options.</param> /// <returns>The result of the conversion</returns> private static ScssResult FromCore(string fromStringOrFile, bool fromFile, ScssOptions options = null) { var compiler = new LibSass.Sass_Compiler(); GCHandle?tryImportHandle = null; var context = new LibSass.Sass_Context(); try { options = options ?? DefaultOptions; if (fromFile) { var fileContext = LibSass.sass_make_file_context(fromStringOrFile); context = fileContext; if (options.InputFile == null) { options.InputFile = fromStringOrFile; } tryImportHandle = MarshalOptions(fileContext, options); compiler = LibSass.sass_make_file_compiler(fileContext); } else { var dataContext = LibSass.sass_make_data_context(fromStringOrFile); context = dataContext; tryImportHandle = MarshalOptions(dataContext, options); compiler = LibSass.sass_make_data_compiler(dataContext); } LibSass.sass_compiler_parse(compiler); CheckStatus(context); LibSass.sass_compiler_execute(compiler); CheckStatus(context); // Gets the result of the conversion var css = LibSass.sass_context_get_output_string(context); // Gets the map if it was enabled string map = null; if (options != null && options.GenerateSourceMap) { map = LibSass.sass_context_get_source_map_string(context); } // Gets the list of included files var includedFiles = GetIncludedFiles(context); // Returns the result return(new ScssResult(css, map, includedFiles)); } finally { // Release the cookie handle if any if (tryImportHandle.HasValue && tryImportHandle.Value.IsAllocated) { tryImportHandle.Value.Free(); } if (compiler.Pointer != IntPtr.Zero) { LibSass.sass_delete_compiler(compiler); } if (context.Pointer != IntPtr.Zero) { if (fromFile) { LibSass.sass_delete_file_context((LibSass.Sass_File_Context)context); } else { LibSass.sass_delete_data_context((LibSass.Sass_Data_Context)context); } } } }
private static GCHandle?MarshalOptions(LibSass.Sass_Context context, ScssOptions options) { var nativeOptions = LibSass.sass_context_get_options(context); // TODO: The C function is not working? //LibSass.sass_option_set_precision(nativeOptions, options.Precision); LibSass.sass_option_set_output_style(nativeOptions, options.OutputStyle); LibSass.sass_option_set_source_comments(nativeOptions, options.SourceComments); LibSass.sass_option_set_source_map_embed(nativeOptions, options.SourceMapEmbed); LibSass.sass_option_set_source_map_contents(nativeOptions, options.SourceMapContents); LibSass.sass_option_set_omit_source_map_url(nativeOptions, options.OmitSourceMapUrl); LibSass.sass_option_set_is_indented_syntax_src(nativeOptions, options.IsIndentedSyntaxSource); // Handle TryImport GCHandle?cookieHandle = null; if (options.TryImport != null) { unsafe { var importerList = LibSass.sass_make_importer_list(1); cookieHandle = GCHandle.Alloc(options.TryImport, GCHandleType.Normal); var cookie = GCHandle.ToIntPtr(cookieHandle.Value); var importer = LibSass.sass_make_importer(new LibSass.Sass_Importer_Fn(ScssImporterPtr), 0, (void *)cookie); LibSass.sass_importer_set_list_entry(importerList, 0, importer); LibSass.sass_option_set_c_importers(nativeOptions, importerList); // TODO: Should we deallocate with sass_delete_importer at some point? } } if (options.Indent != null) { LibSass.sass_option_set_indent(nativeOptions, options.Indent); } if (options.Linefeed != null) { LibSass.sass_option_set_linefeed(nativeOptions, options.Linefeed); } if (options.InputFile != null) { var inputFile = GetRootedPath(options.InputFile); LibSass.sass_option_set_input_path(nativeOptions, inputFile); } string outputFile = null; if (options.OutputFile != null) { outputFile = GetRootedPath(options.OutputFile); LibSass.sass_option_set_output_path(nativeOptions, outputFile); } //if (options.PluginPaths.Count > 0) //{ // foreach (var path in options.PluginPaths) // { // LibSass.sass_option_push_plugin_path(nativeOptions, path); // } //} if (options.IncludePaths.Count > 0) { foreach (var path in options.IncludePaths) { var fullPath = GetRootedPath(path); LibSass.sass_option_push_include_path(nativeOptions, fullPath); } } if (options.GenerateSourceMap) { var sourceMapFile = GetRootedPath(options.SourceMapFile ?? (outputFile ?? "result.css") + ".map"); if (options.SourceMapFile == null) { options.SourceMapFile = sourceMapFile; } LibSass.sass_option_set_source_map_file(nativeOptions, sourceMapFile); } if (options.SourceMapRoot != null) { LibSass.sass_option_set_source_map_root(nativeOptions, options.SourceMapRoot); } return(cookieHandle); }