Initial commit
[yaffs-website] / node_modules / node-sass / src / libsass / docs / custom-functions-internal.md
1 # Developer Documentation
2
3 Custom functions are internally represented by `struct Sass_C_Function_Descriptor`.
4
5 ## Sass_C_Function_Descriptor
6
7 ```C
8 struct Sass_C_Function_Descriptor {
9   const char*      signature;
10   Sass_C_Function  function;
11   void*            cookie;
12 };
13 ```
14
15 - `signature`: The function declaration, like `foo($bar, $baz:1)`
16 - `function`:  Reference to the C function callback
17 - `cookie`:    any pointer you want to attach
18
19 ### signature
20
21 The signature defines how the function can be invoked. It also declares which arguments are required and which are optional.  Required arguments will be enforced by LibSass and a Sass error is thrown in the event a call as missing an argument. Optional arguments only need to be present when you want to overwrite the default value.
22
23     foo($bar, $baz: 2)
24
25 In this example, `$bar` is required and will error if not passed. `$baz` is optional and the default value of it is 2. A call like `foo(10)` is therefore equal to `foo(10, 2)`, while `foo()` will produce an error.
26
27 ### function
28
29 The callback function needs to be of the following form:
30
31 ```C
32 union Sass_Value* call_sass_function(
33     const union Sass_Value* s_args,
34     void*                   cookie
35 ) {
36   return sass_clone_value(s_args);
37 }
38 ```
39
40 ### cookie
41
42 The cookie can hold any pointer you want. In the `perl-libsass` implementation it holds the structure with the reference of the actual registered callback into the perl interpreter. Before that call `perl-libsass` will convert all `Sass_Values` to corresponding perl data types (so they can be used natively inside the perl interpretor). The callback can also return a `Sass_Value`. In `perl-libsass` the actual function returns a perl value, which has to be converted before `libsass` can work with it again!
43
44 ## Sass_Values
45
46 ```C
47 // allocate memory (copies passed strings)
48 union Sass_Value* sass_make_null    (void);
49 union Sass_Value* sass_make_boolean (bool val);
50 union Sass_Value* sass_make_string  (const char* val);
51 union Sass_Value* sass_make_qstring (const char* val);
52 union Sass_Value* sass_make_number  (double val, const char* unit);
53 union Sass_Value* sass_make_color   (double r, double g, double b, double a);
54 union Sass_Value* sass_make_list    (size_t len, enum Sass_Separator sep, bool is_bracketed);
55 union Sass_Value* sass_make_map     (size_t len);
56 union Sass_Value* sass_make_error   (const char* msg);
57 union Sass_Value* sass_make_warning (const char* msg);
58
59 // Make a deep cloned copy of the given sass value
60 union Sass_Value* sass_clone_value (const union Sass_Value* val);
61
62 // deallocate memory (incl. all copied memory)
63 void sass_delete_value (const union Sass_Value* val);
64 ```
65
66 ## Example main.c
67
68 ```C
69 #include <stdio.h>
70 #include <stdint.h>
71 #include "sass/context.h"
72
73 union Sass_Value* call_fn_foo(const union Sass_Value* s_args, void* cookie)
74 {
75   // we actually abuse the void* to store an "int"
76   return sass_make_number((size_t)cookie, "px");
77 }
78
79 int main( int argc, const char* argv[] )
80 {
81
82   // get the input file from first argument or use default
83   const char* input = argc > 1 ? argv[1] : "styles.scss";
84
85   // create the file context and get all related structs
86   struct Sass_File_Context* file_ctx = sass_make_file_context(input);
87   struct Sass_Context* ctx = sass_file_context_get_context(file_ctx);
88   struct Sass_Options* ctx_opt = sass_context_get_options(ctx);
89
90   // allocate a custom function caller
91   Sass_C_Function_Callback fn_foo =
92     sass_make_function("foo()", call_fn_foo, (void*)42);
93
94   // create list of all custom functions
95   Sass_C_Function_List fn_list = sass_make_function_list(1);
96   sass_function_set_list_entry(fn_list, 0, fn_foo);
97   sass_option_set_c_functions(ctx_opt, fn_list);
98
99   // context is set up, call the compile step now
100   int status = sass_compile_file_context(file_ctx);
101
102   // print the result or the error to the stdout
103   if (status == 0) puts(sass_context_get_output_string(ctx));
104   else puts(sass_context_get_error_message(ctx));
105
106   // release allocated memory
107   sass_delete_file_context(file_ctx);
108
109   // exit status
110   return status;
111
112 }
113 ```
114
115 ## Compile main.c
116
117 ```bash
118 gcc -c main.c -o main.o
119 gcc -o sample main.o -lsass
120 echo "foo { margin: foo(); }" > foo.scss
121 ./sample foo.scss => "foo { margin: 42px }"
122 ```