From ad94fcfacc6b915400e0e664d2055fb79ba2c48d Mon Sep 17 00:00:00 2001 From: "Anantachai Saothong (Manta)" Date: Mon, 3 Apr 2017 17:51:20 +0700 Subject: [PATCH] Added support for hashes and iterations --- edge/format.js | 78 ++++++++++++++++++++++++--- spec/hash/formattingOptions.json | 13 +++++ spec/hash/input.styl | 15 ++++++ spec/hash/output.styl | 18 +++++++ spec/iteration/formattingOptions.json | 14 +++++ spec/iteration/input.styl | 13 +++++ spec/iteration/output.styl | 18 +++++++ 7 files changed, 163 insertions(+), 6 deletions(-) create mode 100644 spec/hash/formattingOptions.json create mode 100644 spec/hash/input.styl create mode 100644 spec/hash/output.styl create mode 100644 spec/iteration/formattingOptions.json create mode 100644 spec/iteration/input.styl create mode 100644 spec/iteration/output.styl diff --git a/edge/format.js b/edge/format.js index 6d0f055..b218a92 100644 --- a/edge/format.js +++ b/edge/format.js @@ -99,7 +99,11 @@ function format(content, options) { } if (inputNode instanceof stylus.nodes.Import) { - outputBuffer.append(indent + `@${options.alwaysUseImport || inputNode.once === false ? 'import' : 'require'} '${inputNode.path.nodes[0].val}'`) + const quote = options.stringQuoteChar || '\'' + + outputBuffer.append(indent) + outputBuffer.append(options.alwaysUseImport || inputNode.once === false ? 'import' : 'require') + outputBuffer.append(' ' + quote + inputNode.path.nodes[0].val + quote) if (options.insertSemicolons) { outputBuffer.append(';') @@ -308,6 +312,9 @@ function format(content, options) { } else if (inputNode.val instanceof stylus.nodes.Expression) { outputBuffer.append(' = ') outputBuffer.append(travel(inputNode, inputNode.val, indentLevel, true)) + + } else if (inputNode.val instanceof stylus.nodes.BinOp && inputNode.val.left instanceof stylus.nodes.Ident && inputNode.val.left.name === inputNode.name && inputNode.val.right) { + outputBuffer.append(' ' + inputNode.val.op + '= ' + travel(inputNode.val, inputNode.val.right, indentLevel, true)) } if (insideExpression === false) { @@ -397,12 +404,16 @@ function format(content, options) { outputBuffer.append(inputNode.op === '!' && options.alwaysUseNot ? 'not ' : inputNode.op).append(travel(inputNode, inputNode.expr, indentLevel, true)) } else if (inputNode instanceof stylus.nodes.BinOp) { - if (inputNode.op === '[]') { + if (inputNode.op === '[]') { // In case of array accessing outputBuffer.append(travel(inputNode, inputNode.left, indentLevel, true) + '[' + travel(inputNode, inputNode.right, indentLevel, true) + ']') - } else if (inputNode.op === '...') { + } else if (inputNode.op === '...') { // In case of ranges outputBuffer.append(travel(inputNode, inputNode.left, indentLevel, true) + '...' + travel(inputNode, inputNode.right, indentLevel, true)) + } else if (inputNode.op === '[]=') { // In case of object-property assignment + outputBuffer.append(travel(inputNode, inputNode.left, indentLevel, true) + '[' + travel(inputNode, inputNode.right, indentLevel, true) + '] = ') + outputBuffer.append(travel(inputNode, inputNode.val, indentLevel, true)) + } else { outputBuffer.append(travel(inputNode, inputNode.left, indentLevel, true) + ' ' + inputNode.op) if (inputNode.right) { @@ -443,6 +454,30 @@ function format(content, options) { } else if (inputNode instanceof stylus.nodes.RGBA) { outputBuffer.append(inputNode.raw.trim()) + } else if (inputNode instanceof stylus.nodes.Object) { + const keyValuePairs = _.toPairs(inputNode.vals) + if (keyValuePairs.length === 0) { + outputBuffer.append('{}') + + } else if (keyValuePairs.map(pair => pair[1]).every(node => node.lineno === inputNode.lineno)) { + outputBuffer.append('{ ') + outputBuffer.append(keyValuePairs.map(pair => + getProperVariableName(pair[0]) + ': ' + + travel(inputNode, pair[1], indentLevel, true) + ).join(', ')) + outputBuffer.append(' }') + + } else { + const childIndent = indent + options.indentChar + outputBuffer.append('{' + options.newLineChar) + outputBuffer.append(keyValuePairs.map(pair => + childIndent + + getProperVariableName(pair[0]) + ': ' + + travel(inputNode, pair[1], indentLevel + 1, true) + ).join(',' + options.newLineChar)) + outputBuffer.append(options.newLineChar + indent + '}') + } + } else if (inputNode instanceof stylus.nodes.If) { if (insideExpression === false) { outputBuffer.append(indent) @@ -464,10 +499,12 @@ function format(content, options) { outputBuffer.append(')') } - if (options.insertSemicolons) { - outputBuffer.append(';') + if (insideExpression === false) { + if (options.insertSemicolons) { + outputBuffer.append(';') + } + outputBuffer.append(options.newLineChar) } - outputBuffer.append(options.newLineChar) } else { if (insideExpression) { @@ -509,6 +546,27 @@ function format(content, options) { } } + } else if (inputNode instanceof stylus.nodes.Each) { + if (insideExpression === false) { + outputBuffer.append(indent) + } + + if (_.size(inputNode.block.nodes) === 1 && inputNode.lineno === inputNode.block.nodes[0].lineno && inputNode.block.nodes[0].column < inputNode.column) { // In case of postfix + outputBuffer.append(travel(inputNode, inputNode.block.nodes[0], indentLevel, true)) + outputBuffer.append(' for ' + _.compact([inputNode.val, inputNode.key]).join(', ') + ' in ' + travel(inputNode, inputNode.expr, indentLevel, true)) + + if (insideExpression === false) { + if (options.insertSemicolons) { + outputBuffer.append(';') + } + outputBuffer.append(options.newLineChar) + } + + } else { + outputBuffer.append('for ' + _.compact([inputNode.val, inputNode.key]).join(', ') + ' in ' + travel(inputNode, inputNode.expr, indentLevel, true)) + outputBuffer.append(travel(inputNode, inputNode.block, indentLevel, false)) + } + } else if (inputNode instanceof stylus.nodes.Comment && inputNode.str.startsWith('//')) { // In case of single-line comment if (insideExpression === false) { outputBuffer.append(indent) @@ -676,6 +734,14 @@ function format(content, options) { } } + function getProperVariableName(name) { + if (/^\d/.test(name) || /\s/.test(name)) { + return (options.stringQuoteChar || '\'') + name + (options.stringQuoteChar || '\'') + } else { + return name + } + } + let output = travel(null, rootNode, 0) if (output.startsWith(options.newLineChar)) { output = output.substring(options.newLineChar.length) diff --git a/spec/hash/formattingOptions.json b/spec/hash/formattingOptions.json new file mode 100644 index 0000000..3ac7dea --- /dev/null +++ b/spec/hash/formattingOptions.json @@ -0,0 +1,13 @@ +{ + "insertColons": true, + "insertSemicolons": true, + "insertBraces": true, + "insertNewLineBetweenGroups": 1, + "insertNewLineBetweenSelectors": false, + "insertSpaceBeforeComments": true, + "insertSpaceAfterComments": true, + "indentChar": "\t", + "newLineChar": "\r\n", + "sortProperties": false, + "alwaysUseImport": false +} \ No newline at end of file diff --git a/spec/hash/input.styl b/spec/hash/input.styl new file mode 100644 index 0000000..7b67b7e --- /dev/null +++ b/spec/hash/input.styl @@ -0,0 +1,15 @@ +foo={width:10px,height:20px} +foo={ + a1:{ + b1:true, + b2:false + }, + 'a2':{c2:true}, + 'a3':{}, + '0':false +} +foo['0']=bar + +body + {foo} + display a3 in foo \ No newline at end of file diff --git a/spec/hash/output.styl b/spec/hash/output.styl new file mode 100644 index 0000000..c0bfa9e --- /dev/null +++ b/spec/hash/output.styl @@ -0,0 +1,18 @@ +foo = { width: 10px, height: 20px }; +foo = { + '0': false, + a1: { + b1: true, + b2: false + }, + a2: { c2: true }, + a3: {} +}; + +foo['0'] = bar; + +body { + {foo}; + + display: a3 in foo; +} \ No newline at end of file diff --git a/spec/iteration/formattingOptions.json b/spec/iteration/formattingOptions.json new file mode 100644 index 0000000..c40f707 --- /dev/null +++ b/spec/iteration/formattingOptions.json @@ -0,0 +1,14 @@ +{ + "insertColons": true, + "insertSemicolons": true, + "insertBraces": true, + "insertNewLineBetweenGroups": 1, + "insertNewLineBetweenSelectors": false, + "insertSpaceBeforeComments": true, + "insertSpaceAfterComments": true, + "insertParenthesisAroundConditions": true, + "indentChar": "\t", + "newLineChar": "\r\n", + "sortProperties": false, + "alwaysUseImport": false +} \ No newline at end of file diff --git a/spec/iteration/input.styl b/spec/iteration/input.styl new file mode 100644 index 0000000..f890c67 --- /dev/null +++ b/spec/iteration/input.styl @@ -0,0 +1,13 @@ +body + for num,index in 1 2 3 + foo num + +for key,value in obj + {key}:value + +sum(nums) + sum = 0 + sum += n for n in nums + +get(hash,key) + return pair[1] if pair[0] == key for pair in hash \ No newline at end of file diff --git a/spec/iteration/output.styl b/spec/iteration/output.styl new file mode 100644 index 0000000..b8c3d96 --- /dev/null +++ b/spec/iteration/output.styl @@ -0,0 +1,18 @@ +body { + for num, index in 1 2 3 { + foo: num; + } +} + +for key, value in obj { + {key}: value; +} + +sum(nums) { + sum = 0; + + sum += n for n in nums; +} +get(hash, key) { + return pair[1] if (pair[0] == key) for pair in hash; +} \ No newline at end of file