{"action":"created","issue":{"url":"https://api.github.com/repos/sass/libsass/issues/1000","labels_url":"https://api.github.com/repos/sass/libsass/issues/1000/labels{/name}","comments_url":"https://api.github.com/repos/sass/libsass/issues/1000/comments","events_url":"https://api.github.com/repos/sass/libsass/issues/1000/events","html_url":"https://github.com/sass/libsass/pull/1000","id":64965527,"number":1000,"title":"Implement support for multiple importers","user":{"login":"mgreter","id":282293,"avatar_url":"https://avatars.githubusercontent.com/u/282293?v=3","gravatar_id":"","url":"https://api.github.com/users/mgreter","html_url":"https://github.com/mgreter","followers_url":"https://api.github.com/users/mgreter/followers","following_url":"https://api.github.com/users/mgreter/following{/other_user}","gists_url":"https://api.github.com/users/mgreter/gists{/gist_id}","starred_url":"https://api.github.com/users/mgreter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mgreter/subscriptions","organizations_url":"https://api.github.com/users/mgreter/orgs","repos_url":"https://api.github.com/users/mgreter/repos","events_url":"https://api.github.com/users/mgreter/events{/privacy}","received_events_url":"https://api.github.com/users/mgreter/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/sass/libsass/labels/C%20API","name":"C API","color":"c7def8"},{"url":"https://api.github.com/repos/sass/libsass/labels/feature","name":"feature","color":"207de5"}],"state":"closed","locked":false,"assignee":{"login":"mgreter","id":282293,"avatar_url":"https://avatars.githubusercontent.com/u/282293?v=3","gravatar_id":"","url":"https://api.github.com/users/mgreter","html_url":"https://github.com/mgreter","followers_url":"https://api.github.com/users/mgreter/followers","following_url":"https://api.github.com/users/mgreter/following{/other_user}","gists_url":"https://api.github.com/users/mgreter/gists{/gist_id}","starred_url":"https://api.github.com/users/mgreter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mgreter/subscriptions","organizations_url":"https://api.github.com/users/mgreter/orgs","repos_url":"https://api.github.com/users/mgreter/repos","events_url":"https://api.github.com/users/mgreter/events{/privacy}","received_events_url":"https://api.github.com/users/mgreter/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/sass/libsass/milestones/3","html_url":"https://github.com/sass/libsass/milestones/3.2","labels_url":"https://api.github.com/repos/sass/libsass/milestones/3/labels","id":812844,"number":3,"title":"3.2","description":"","creator":{"login":"hcatlin","id":111,"avatar_url":"https://avatars.githubusercontent.com/u/111?v=3","gravatar_id":"","url":"https://api.github.com/users/hcatlin","html_url":"https://github.com/hcatlin","followers_url":"https://api.github.com/users/hcatlin/followers","following_url":"https://api.github.com/users/hcatlin/following{/other_user}","gists_url":"https://api.github.com/users/hcatlin/gists{/gist_id}","starred_url":"https://api.github.com/users/hcatlin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hcatlin/subscriptions","organizations_url":"https://api.github.com/users/hcatlin/orgs","repos_url":"https://api.github.com/users/hcatlin/repos","events_url":"https://api.github.com/users/hcatlin/events{/privacy}","received_events_url":"https://api.github.com/users/hcatlin/received_events","type":"User","site_admin":false},"open_issues":2,"closed_issues":151,"state":"open","created_at":"2014-10-03T16:44:45Z","updated_at":"2015-04-01T20:54:53Z","due_on":null,"closed_at":null},"comments":27,"created_at":"2015-03-28T17:00:39Z","updated_at":"2015-04-02T08:18:19Z","closed_at":"2015-03-30T00:01:42Z","pull_request":{"url":"https://api.github.com/repos/sass/libsass/pulls/1000","html_url":"https://github.com/sass/libsass/pull/1000","diff_url":"https://github.com/sass/libsass/pull/1000.diff","patch_url":"https://github.com/sass/libsass/pull/1000.patch"},"body":"This PR now implements all options I envisioned in #962. At this point I'm not sure if we want to include this in 3.2.0 or wait for 3.2.1, since it does bring a few breaking changes with custom importers and custom functions (not that many, but still noticeable). @am11 what do you think, do you have time to adjust this in node-sass before 3.0? It basically just involves setting a list of importers instead of a single one (plus passing an additional priority value on creation). Other than that everything can stay as it is. \r\n\r\n### How do custom importers work now?\r\n\r\nFor each `@import` libsass will call importers in priority order (highest priority first). If the importer returns `0`, libsass will skip to the next one. If no importer returns anything, libsass will continue to load the import on its own. Once an importer returns something (either a list of imports, an empty list of imports or an error), the chain is aborted and only the given return is handled. Additionally I fixed the behaviour when only a filename is returned to be exactly as with plain libsass imports.\r\n\r\n### Breaking C-API changes\r\n\r\nTo create custom importer list:\r\n```C\r\ndouble priority = 0; // default\r\nvoid* cookie = (void*) pointer_to_anything;\r\nSass_Importer_List importers = sass_make_importer_list(1);\r\nimporters[0] = sass_make_importer(sass_importer, priority, cookie);\r\n```\r\n\r\nNew function signatures for custom functions and importers:\r\n```C\r\nSass_Import_List sass_importer(const char* cur_path, Sass_Importer_Entry cb, struct Sass_Compiler* comp)\r\nunion Sass_Value* call_sass_function(const union Sass_Value* s_args, Sass_Function_Entry cb, struct Sass_Options* opts)\r\n```\r\n\r\nThe options that have previously been passed can now be fetched indirectly:\r\n```C\r\nvoid* cookie = sass_importer_get_cookie(cb);\r\nstruct Sass_Import* previous = sass_compiler_get_last_import(comp);\r\nconst char* prev_path = sass_import_get_path(previous);\r\nvoid* cookie = sass_function_get_cookie(cb);\r\n```\r\n\r\nYou should now be able to access all context options via API calls.\r\n```C\r\nstruct Sass_Context* ctx = sass_compiler_get_context(comp);\r\nstruct Sass_Options* opts = sass_context_get_options(ctx);\r\ndouble precision = sass_option_get_precision(opts);\r\n```\r\n\r\nRenamed a lot of typedefs regardings function and importer API. They should now make much more sense. Not sure how big of an impact this has on implementers though, but it should make it a lot more future-proof. Signatures for functions and importers should not need to change again, since they can now access all options available indirectly via the passed arguments.\r\n```C\r\n// Typedef helpers for import lists\r\ntypedef struct Sass_Import (*Sass_Import_Entry);\r\ntypedef struct Sass_Import* (*Sass_Import_List);\r\n// Typedef helpers for custom importer lists\r\ntypedef struct Sass_Importer (*Sass_Importer_Entry);\r\ntypedef struct Sass_Importer* (*Sass_Importer_List);\r\n// Typedef defining importer signature and return type\r\ntypedef Sass_Import_List (*Sass_Importer_Fn)\r\n  (const char* url, Sass_Importer_Entry cb, struct Sass_Compiler* compiler);\r\n\r\n// Typedef helpers for custom functions lists\r\ntypedef struct Sass_Function (*Sass_Function_Entry);\r\ntypedef struct Sass_Function* (*Sass_Function_List);\r\n// Typedef defining function signature and return type\r\ntypedef union Sass_Value* (*Sass_Function_Fn)\r\n  (const union Sass_Value*, Sass_Function_Entry cb, struct Sass_Options* options);\r\n```\r\n\r\nRenamed structs/typedefs (probably incomplete):\r\n```C\r\nSass_C_Function -> Sass_Function_Fn\r\nSass_C_Function_List -> Sass_Function_List\r\nSass_C_Function_Callback -> Sass_Function_Entry\r\nSass_C_Function_Descriptor -> Sass_Function\r\nSass_C_Import_Fn -> Sass_Importer_Fn\r\nstruct Sass_Importer** -> Sass_Importer_List\r\nSass_C_Import_Callback -> Sass_Importer_Entry\r\nSass_C_Import_Descriptor -> Sass_Importer\r\nstruct Sass_Import** -> Sass_Import_List\r\nstruct Sass_Import* -> Sass_Import_Entry\r\n```\r\n\r\n### New experimental feature\r\n\r\nCustom headers (#960) act like importers, but only run once at the beginning of each compilation. They are primarily meant to define custom mixins (via plugins or context options). Beside that they might be usefull for other cool things I currently cannot think of :smile: Opposite to custom importers, all custom headers will be executed in priority order and all imports will be accumulated (so many custom headers can add various custom mixins or css-code).\r\n\r\n### Include in 3.2.0 !?\r\n\r\nFrom a strict versioning stand-point, this should be included in 3.2 since it contains quite a few breaking changes in the API. The new plugins API would also benefit from it. Adding it to 3.2.1 seems wrong and since it is only stabilizing experimental features, I re-scope this to 3.2 (open for further discussions). I touches quite some code though to be added that late in the beta phase. IMO we should do at least another beta round to let node-sass catch-up to these changes.\r\n\r\n//CC @xzyfer @am11 @chriseppstein "},"comment":{"url":"https://api.github.com/repos/sass/libsass/issues/comments/88820318","html_url":"https://github.com/sass/libsass/pull/1000#issuecomment-88820318","issue_url":"https://api.github.com/repos/sass/libsass/issues/1000","id":88820318,"user":{"login":"xzyfer","id":579928,"avatar_url":"https://avatars.githubusercontent.com/u/579928?v=3","gravatar_id":"","url":"https://api.github.com/users/xzyfer","html_url":"https://github.com/xzyfer","followers_url":"https://api.github.com/users/xzyfer/followers","following_url":"https://api.github.com/users/xzyfer/following{/other_user}","gists_url":"https://api.github.com/users/xzyfer/gists{/gist_id}","starred_url":"https://api.github.com/users/xzyfer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xzyfer/subscriptions","organizations_url":"https://api.github.com/users/xzyfer/orgs","repos_url":"https://api.github.com/users/xzyfer/repos","events_url":"https://api.github.com/users/xzyfer/events{/privacy}","received_events_url":"https://api.github.com/users/xzyfer/received_events","type":"User","site_admin":false},"created_at":"2015-04-02T08:18:19Z","updated_at":"2015-04-02T08:18:19Z","body":"For the time being it's my opinion we should disable custom headers in 3.2.0. \r\n\r\nLet's open an RFC to discuss the intention, usecases, and implementation of this feature. The C API will be a major feature of Libsass and it's worth doing the due diligence on changes and features - this is especially important in cases where there is no Ruby Sass / Compass equivalent.\r\n\r\nIt's probably worth also opening an RFC regarding importer weights. I agree that it should be a list, rather than weight. The pragmatist in me sees this quickly becoming a race to the top ala z-indexes."}}