1 | var utils = require('../utils')
|
---|
2 | , nodes = require('../nodes')
|
---|
3 | , readFile = require('fs').readFileSync;
|
---|
4 |
|
---|
5 | /**
|
---|
6 | * Convert a .json file into stylus variables or object.
|
---|
7 | * Nested variable object keys are joined with a dash (-)
|
---|
8 | *
|
---|
9 | * Given this sample media-queries.json file:
|
---|
10 | * {
|
---|
11 | * "small": "screen and (max-width:400px)",
|
---|
12 | * "tablet": {
|
---|
13 | * "landscape": "screen and (min-width:600px) and (orientation:landscape)",
|
---|
14 | * "portrait": "screen and (min-width:600px) and (orientation:portrait)"
|
---|
15 | * }
|
---|
16 | * }
|
---|
17 | *
|
---|
18 | * Examples:
|
---|
19 | *
|
---|
20 | * json('media-queries.json')
|
---|
21 | *
|
---|
22 | * @media small
|
---|
23 | * // => @media screen and (max-width:400px)
|
---|
24 | *
|
---|
25 | * @media tablet-landscape
|
---|
26 | * // => @media screen and (min-width:600px) and (orientation:landscape)
|
---|
27 | *
|
---|
28 | * vars = json('vars.json', { hash: true })
|
---|
29 | * body
|
---|
30 | * width: vars.width
|
---|
31 | *
|
---|
32 | * @param {String} path
|
---|
33 | * @param {Boolean} [local]
|
---|
34 | * @param {String} [namePrefix]
|
---|
35 | * @api public
|
---|
36 | */
|
---|
37 |
|
---|
38 | function json(path, local, namePrefix){
|
---|
39 | utils.assertString(path, 'path');
|
---|
40 |
|
---|
41 | // lookup
|
---|
42 | path = path.string;
|
---|
43 | var found = utils.lookup(path, this.options.paths, this.options.filename)
|
---|
44 | , options = (local && 'object' == local.nodeName) && local;
|
---|
45 |
|
---|
46 | if (!found) {
|
---|
47 | // optional JSON file
|
---|
48 | if (options && options.get('optional').toBoolean().isTrue) {
|
---|
49 | return nodes.null;
|
---|
50 | }
|
---|
51 | throw new Error('failed to locate .json file ' + path);
|
---|
52 | }
|
---|
53 |
|
---|
54 | // read
|
---|
55 | var json = JSON.parse(readFile(found, 'utf8'));
|
---|
56 |
|
---|
57 | if (options) {
|
---|
58 | return convert(json, options);
|
---|
59 | } else {
|
---|
60 | oldJson.call(this, json, local, namePrefix);
|
---|
61 | }
|
---|
62 |
|
---|
63 | function convert(obj, options){
|
---|
64 | var ret = new nodes.Object()
|
---|
65 | , leaveStrings = options.get('leave-strings').toBoolean();
|
---|
66 |
|
---|
67 | for (var key in obj) {
|
---|
68 | var val = obj[key];
|
---|
69 | if ('object' == typeof val) {
|
---|
70 | ret.set(key, convert(val, options));
|
---|
71 | } else {
|
---|
72 | val = utils.coerce(val);
|
---|
73 | if ('string' == val.nodeName && leaveStrings.isFalse) {
|
---|
74 | val = utils.parseString(val.string);
|
---|
75 | }
|
---|
76 | ret.set(key, val);
|
---|
77 | }
|
---|
78 | }
|
---|
79 | return ret;
|
---|
80 | }
|
---|
81 | };
|
---|
82 | json.params = ['path', 'local', 'namePrefix'];
|
---|
83 | module.exports = json;
|
---|
84 |
|
---|
85 | /**
|
---|
86 | * Old `json` BIF.
|
---|
87 | *
|
---|
88 | * @api private
|
---|
89 | */
|
---|
90 |
|
---|
91 | function oldJson(json, local, namePrefix){
|
---|
92 | if (namePrefix) {
|
---|
93 | utils.assertString(namePrefix, 'namePrefix');
|
---|
94 | namePrefix = namePrefix.val;
|
---|
95 | } else {
|
---|
96 | namePrefix = '';
|
---|
97 | }
|
---|
98 | local = local ? local.toBoolean() : new nodes.Boolean(local);
|
---|
99 | var scope = local.isTrue ? this.currentScope : this.global.scope;
|
---|
100 |
|
---|
101 | convert(json);
|
---|
102 | return;
|
---|
103 |
|
---|
104 | function convert(obj, prefix){
|
---|
105 | prefix = prefix ? prefix + '-' : '';
|
---|
106 | for (var key in obj){
|
---|
107 | var val = obj[key];
|
---|
108 | var name = prefix + key;
|
---|
109 | if ('object' == typeof val) {
|
---|
110 | convert(val, name);
|
---|
111 | } else {
|
---|
112 | val = utils.coerce(val);
|
---|
113 | if ('string' == val.nodeName) val = utils.parseString(val.string);
|
---|
114 | scope.add({ name: namePrefix + name, val: val });
|
---|
115 | }
|
---|
116 | }
|
---|
117 | }
|
---|
118 | };
|
---|