UNPKG

4.06 kBJavaScriptView Raw
1
2/*!
3 * Stylus - utils
4 * Copyright(c) 2010 LearnBoost <dev@learnboost.com>
5 * MIT Licensed
6 */
7
8/**
9 * Module dependencies.
10 */
11
12var nodes = require('./nodes')
13 , inspect = require('sys').inspect
14 , fs = require('fs');
15
16/**
17 * Attempt to lookup `path` within `paths` from tail to head.
18 * Optionally a path to `ignore` may be passed.
19 *
20 * @param {String} path
21 * @param {String} paths
22 * @param {String} ignore
23 * @return {String}
24 * @api private
25 */
26
27exports.lookup = function(path, paths, ignore){
28 var lookup
29 , i = paths.length;
30
31 // Absolute
32 if ('/' == path[0]) {
33 try {
34 fs.statSync(path);
35 return path;
36 } catch (err) {
37 // Ignore, continue on
38 // to trying relative lookup.
39 // Needed for url(/images/foo.png)
40 // for example
41 }
42 }
43
44 // Relative
45 while (i--) {
46 try {
47 lookup = paths[i] + '/' + path;
48 if (ignore == lookup) continue;
49 fs.statSync(lookup);
50 return lookup;
51 } catch (err) {
52 // Ignore
53 }
54 }
55};
56
57/**
58 * Format the given `err` in context to `renderer`.
59 *
60 * @param {Renderer} renderer
61 * @param {Error} err
62 * @param {Object} options
63 * @return {Error}
64 * @api private
65 */
66
67exports.formatException = function(renderer, err, options){
68 var lineno = renderer.evaluator
69 ? renderer.evaluator.lineno
70 : renderer.parser.lexer.lineno
71 , contextLineno = lineno - 2
72 , contextLines = options.context || 8
73 , lastWidth = (contextLineno + contextLines).toString().length;
74
75 var src = (err.str || renderer.str).split('\n')
76 .slice(contextLineno, contextLineno + contextLines)
77 .map(function(line){
78 var n = ++contextLineno
79 , width = n.toString().length
80 , pad = Array(lastWidth - width + 1).join(' ');
81 return ' ' + pad + n + ': ' + inspect(line);
82 }).join('\n');
83
84 err.message = renderer.options.filename
85 + ':' + lineno
86 + '\n' + src
87 + '\n\n' + err.message + '\n'
88 + (err.stylusStack ? err.stylusStack + '\n' : '');
89
90 return err;
91};
92
93/**
94 * Assert that `node` is of the given `type`, or throw.
95 *
96 * @param {Node} node
97 * @param {Function} type
98 * @param {String} param
99 * @api public
100 */
101
102exports.assertType = function(node, type, param){
103 exports.assertPresent(node, param);
104 if (node instanceof type) return;
105 var actual = node.constructor.name
106 , msg = 'expected ' + type.name + ', but got ' + actual + ':' + node;
107 throw new Error('TypeError: ' + msg);
108};
109
110/**
111 * Assert that `node` is a `String` or `Ident`.
112 *
113 * @param {Node} node
114 * @param {String} param
115 * @api public
116 */
117
118exports.assertString = function(node, param){
119 exports.assertPresent(node, param);
120 if (node instanceof nodes.String) return;
121 if (node instanceof nodes.Ident) return;
122 var actual = node.constructor.name
123 , msg = 'expected String or Ident, but got ' + actual + ':' + node;
124 throw new Error('TypeError: ' + msg);
125};
126
127/**
128 * Assert that `node` is a `Color` or `HSLA`.
129 *
130 * @param {Node} node
131 * @param {String} param
132 * @api public
133 */
134
135exports.assertColor = function(node, param){
136 exports.assertPresent(node, param);
137 if (node instanceof nodes.Color) return;
138 if (node instanceof nodes.HSLA) return;
139 var actual = node.constructor.name
140 , msg = 'expected Color or HSLA, but got ' + actual + ':' + node;
141 throw new Error('TypeError: ' + msg);
142};
143
144/**
145 * Assert that param `name` is given, aka the `node` is passed.
146 *
147 * @param {Node} node
148 * @param {String} name
149 * @api public
150 */
151
152exports.assertPresent = function(node, name){
153 if (node) return;
154 if (name) throw new Error('ArgumentError: argument ' + name + ' required');
155 throw new Error('ArgumentError: argument missing');
156};
157
158/**
159 * Unwrap `expr`.
160 *
161 * Takes an expressions with length of 1
162 * such as `(1 2 3)` and unwraps it to `1 2 3`.
163 *
164 * @param {Expression} expr
165 * @return {Node}
166 * @api public
167 */
168
169exports.unwrap = function(expr){
170 if ('expression' != expr.nodeName) return expr;
171 if (1 != expr.nodes.length) return expr;
172 if ('expression' != expr.nodes[0].nodeName) return expr;
173 return expr.nodes[0];
174};
\No newline at end of file