Ejemplo n.º 1
0
        private static unsafe LibSass.Sass_Import_List CustomScssImporter(LibSass.StringUtf8 currentPath, LibSass.Sass_Importer_Entry cb, LibSass.Sass_Compiler compiler)
        {
            var cookie = LibSass.sass_importer_get_cookie(cb);

            var    previous     = LibSass.sass_compiler_get_last_import(compiler);
            string previousPath = LibSass.sass_import_get_abs_path(previous);

            var cookieHandle = GCHandle.FromIntPtr(cookie);
            var tryImport    = (ScssOptions.TryImportDelegate)cookieHandle.Target;

            var    file         = (string)currentPath;
            var    importList   = LibSass.sass_make_import_list(1);
            uint   line         = 0;
            uint   column       = 0;
            string errorMessage = null;

            if (tryImport != null)
            {
                try
                {
                    if (tryImport(file, previousPath, out var scss, out var map))
                    {
                        var entry = LibSass.sass_make_import_entry(file, scss, map);
                        *(LibSass.Sass_Import_Entry *)importList.Pointer = entry;
                        return(importList);
                    }
                }
                catch (ScssException ex)
                {
                    errorMessage = ex.Message;
                    line         = (uint)ex.Line;
                    column       = (uint)ex.Column;
                }
                catch (Exception ex)
                {
                    errorMessage = ex.ToString();
                }
            }

            if (errorMessage == null)
            {
                errorMessage = $"Unable to find include file for @import \"{file}\" with dynamic import";
            }
            {
                var entry = LibSass.sass_make_import_entry(file, null, null);
                *(LibSass.Sass_Import_Entry *)importList.Pointer = entry;

                LibSass.sass_import_set_error(entry, errorMessage, line, column);
            }
            return(importList);
        }
Ejemplo n.º 2
0
        private static void CheckStatus(LibSass.Sass_Context context)
        {
            var status = LibSass.sass_context_get_error_status(context);

            if (status != 0)
            {
                var column    = LibSass.sass_context_get_error_column(context);
                var line      = LibSass.sass_context_get_error_line(context);
                var file      = (string)LibSass.sass_context_get_error_file(context);
                var message   = (string)LibSass.sass_context_get_error_message(context);
                var errorText = (string)LibSass.sass_context_get_error_text(context);

                throw new ScssException((int)line, (int)column, file, message, errorText);
            }
        }
Ejemplo n.º 3
0
        private static unsafe List <string> GetIncludedFiles(LibSass.Sass_Context context)
        {
            var           filesCount = (int)LibSass.sass_context_get_included_files_size(context);
            var           files      = (LibSass.StringUtf8 *)LibSass.sass_context_get_included_files(context);
            List <string> list       = null;

            for (var i = 0; i < filesCount; i++)
            {
                if (!files->IsEmpty)
                {
                    if (list == null)
                    {
                        list = new List <string>();
                    }
                    list.Add(*files);
                }
                files++;
            }
            return(list);
        }
Ejemplo n.º 4
0
        /// <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)
        {
            if (string.IsNullOrEmpty(fromStringOrFile) && (string.IsNullOrEmpty(options?.InputFile) || !File.Exists(options.InputFile)))
            {
                throw new Exception("You must provide the scss file contents or file path in the ScssOptions");
            }

            if (string.IsNullOrEmpty(fromStringOrFile))
            {
                fromStringOrFile = File.ReadAllText(options.InputFile);
            }

            var      compiler        = new LibSass.Sass_Compiler();
            GCHandle?tryImportHandle = null;
            var      context         = new LibSass.Sass_Context();

            try
            {
                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);
                    }
                }
            }
        }
Ejemplo n.º 5
0
        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, (LibSass.Sass_Output_Style)(int) 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, 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);
        }