Skip to content

Commit

Permalink
Fix not honoring indent after inline text
Browse files Browse the repository at this point in the history
Lexer was silently ignoring indent after a tag with inline text
Now :

```
li foo
  span bar
```

throw an error and give you the solution
  • Loading branch information
Thomas-git authored and jescalan committed Jun 10, 2019
1 parent 5404556 commit a5da5bc
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 3 deletions.
2 changes: 1 addition & 1 deletion lib/index.js
Expand Up @@ -2,7 +2,7 @@ const lex = require('./lexer')
const parse = require('./parser')

module.exports = function SugarMLParser(input, options) {
return parse(lex(input, options))
return parse(lex(input, options),input,options)
}

module.exports.lex = lex
Expand Down
37 changes: 35 additions & 2 deletions lib/parser.js
Expand Up @@ -2,11 +2,11 @@ const SugarmlError = require('./error')

// Our target output is a reshape AST
// (https://github.com/reshape/reshape#reshape-ast)
module.exports = tokens => {
module.exports = (tokens,input,options={}) => {
let current = 0
let indentLevel = 0
let token = tokens[current]

function walk(ctx) {
token = tokens[current]

Expand Down Expand Up @@ -151,9 +151,42 @@ module.exports = tokens => {
// searching for contents
const currentIndent = indentLevel

var forbiddenChildren=false
var inlineText=''
//If next token is 'text', we must not have child tokens
if (token && token.type==='text'){
inlineText = token.value; //Remember inline text value for futur use (in case of error)
node.content.push(walk(node.content)) //Get text
forbiddenChildren=true
}

// now we recurse to get the contents, looping while the indent level is
// greater than that of the current node, to pick up everything nested
node.content.push(walk(node.content))
if (forbiddenChildren && indentLevel > currentIndent){
let errorLine
if (token){
errorLine = tokens[current-2].line; //With other token to parse, error line is 2 tokens before
}else{
errorLine = tokens[current-1].line; //Without anymore tokens to parse, error is on the last line
}
//Compute the awaited input
let splited = input.split('\n') //Split input line by line
let regex = inlineText.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '$'; //Make regex from inlineText
let firstLine = splited[errorLine - 2].replace(new RegExp(regex),'') //Remove inlineText from first Error line
let thirdLine = splited[errorLine - 1] //Second line become third
let secondLine = thirdLine.match(/^\s+/)[0] + '| ' + inlineText //Second line is *pipe* + inlineText we removed on first error line
let shouldBe = ` 1 | ${firstLine}\n 2 | ${secondLine}\n 3 | ${thirdLine}\n` //Pretty output
throw new SugarmlError({
message: `Inline text and nested tags cannot both be used at the same time. To resolve this error format your template as :\n\n${shouldBe}`,
location: {
filename: options.filename,
line: errorLine,
col: 0,
src: input
}
})
}
while (indentLevel > currentIndent) {
// eslint-disable-line
node.content.push(walk(node.content))
Expand Down
2 changes: 2 additions & 0 deletions test/fixtures/inline-text-nested-tag.sgr
@@ -0,0 +1,2 @@
li foo
span bar
6 changes: 6 additions & 0 deletions test/index.js
Expand Up @@ -103,6 +103,12 @@ test('sugarml own comments', t => {
return compare(t, 'sugarml-comments')
})

test('invalid nested tag after inline text error', t => {
return error('inline-text-nested-tag', t).catch(err => {
t.regex(err.toString(), /Inline text and nested tags cannot both be used at the same time. To resolve this error format your template as :\n\n 1 | li \n 2 | | foo\n 3 | span bar/)
})
})

function compare(t, name, log) {
let html, expected

Expand Down

0 comments on commit a5da5bc

Please sign in to comment.