Skip to content

Commit

Permalink
Parse multiline variables
Browse files Browse the repository at this point in the history
- Closes #37
- Makes hacky implementatin of inline_script.from_string() redundant
  • Loading branch information
smathot committed Sep 30, 2020
1 parent 1887a69 commit c2b84c3
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 51 deletions.
33 changes: 33 additions & 0 deletions src/js/osweb/classes/syntax.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,39 @@ export default class Syntax {
// return line.replace(/(?<!\\)\\(?=['"\\])/mg, '')
return line.replace(/\\(?=['"])/mg, '').replace(/\\\\/mg, '\\')
}

/**
* Removes tab indentation from a script, if all lines are indented by a
* single tab.
* @param {String} script - A script
* @return {String} - A dedented script
*/
dedent (script) {
const lines = script.split('\n')
let dedented = []
for (const line of lines) {
if (line[0] !== '\t') {
return script
}
dedented.push(line.slice(1))
}
return dedented.join('\n')
}

/**
* Extracts all multineline variable definitions from an OpenSesame script
* @param {String} script - The OpenSesame script of an item
* @return {Array} - An array of key, value mappings
*/
parse_multiline_vars (script) {
const pattern = /__(\w+)__\n(.*?)\n__end__/gms
let match
let vars = []
while ((match = pattern.exec(script)) !== null) {
vars[match[1]] = match[2]
}
return vars
}

/**
* Parses an instruction line of OpenSesame script
Expand Down
48 changes: 0 additions & 48 deletions src/js/osweb/items/inline_script.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,54 +56,6 @@ export default class InlineScript extends Item {
this.vars._run = ''
}

/**
* Parse a definition string and retrieve all properties of the item.
* @param {String} script - The script containing the properties of the item.
*/
from_string (script) {
// Parses a definition string.
this.reset()

// Split the string into an array of lines.
if (script !== null) {
var read_run_lines = false
var read_prepare_lines = false
var lines = script.split('\n')
for (var i = 0; i < lines.length; i++) {
var tokens = this.syntax.split(lines[i])
if ((tokens !== null) && (tokens.length > 0)) {
switch (tokens[0]) {
case 'set':
this.parse_variable(lines[i])
break
case '__end__':
read_run_lines = false
read_prepare_lines = false
break
case '___prepare__':
read_prepare_lines = true
break
case '___run__':
read_run_lines = true
break
default:
if (read_run_lines === true) {
this.vars._run = this.vars._run + lines[i] + '\n'
} else if (read_prepare_lines === true) {
this.vars._prepare = this.vars._prepare + lines[i] + '\n'
}
}
} else {
if (read_run_lines === true) {
this.vars._run = this.vars._run + lines[i] + '\n'
} else if (read_prepare_lines === true) {
this.vars._prepare = this.vars._prepare + lines[i] + '\n'
}
}
}
}
}

/** Implements the prepare phase of an item. */
prepare () {
// Compile the script code to ast trees.
Expand Down
18 changes: 15 additions & 3 deletions src/js/osweb/items/item.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,22 @@ export default class Item {
}
}
}

/**
* Parses multiline variables from a script
* @param {String} script - The definition script line to be parsed.
*/
parse_multiline_vars (script) {
const vars = this.syntax.parse_multiline_vars(script)
for (const key in vars) {
this.vars.set(key, vars[key])
}
}

/**
* Parses the item from a definition string.
. * @param {String} script - The definition script line to be parsed.
*/
* Parses the item from a definition string.
* @param {String} script - The definition script line to be parsed.
*/
from_string (script) {
// Parses the item from a definition string.
this.variables = {}
Expand All @@ -134,6 +145,7 @@ export default class Item {

// Split the string into an array of lines.
if (script !== null) {
this.parse_multiline_vars(script)
var lines = script.split('\n')
for (var i = 0; i < lines.length; i++) {
if ((lines[i] !== '') && (this.parse_variable(lines[i]) === false)) {
Expand Down
38 changes: 38 additions & 0 deletions src/js/tests/classes/syntax.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,44 @@ describe('Syntax', function () {
}).toThrow()
})
})

describe('dedent()', function () {
it('Should dedent dedentable script', function () {
expect(syntax.dedent(` define sketchpad sketchpad
set duration "keypress"`)).toBe(`define sketchpad sketchpad
set duration "keypress"`)
})
it('Should not dedent non-dedentable script', function () {
expect(syntax.dedent(`define sketchpad sketchpad
set duration "keypress"`)).toBe(`define sketchpad sketchpad
set duration "keypress"`)
})
})

describe('parse_multiline_vars()', function () {
const script = `__condition__
[var] = "yes"
__end__
___run__
x = 0
print("This is Python code")
__end__`
const script2 = `set description "Optionally repeat a cycle from a loop"
__condition__
[response] = "space"
__end__
`
let vars
it('Should parse multiple multine variables', function () {
vars = syntax.parse_multiline_vars(script)
expect(vars["condition"]).toBe('[var] = "yes"')
expect(vars["_run"]).toBe('x = 0\nprint("This is Python code")')
})
it('Should parse multine variables from a script', function () {
vars = syntax.parse_multiline_vars(script2)
expect(vars["condition"]).toBe('[response] = "space"')
})
})

describe('eval_text()', function () {
var tmpVarStore = new VarStore({
Expand Down

0 comments on commit c2b84c3

Please sign in to comment.