From b161a5fb89abeb5d5a544f36242c0c169b829351 Mon Sep 17 00:00:00 2001 From: tjvr Date: Mon, 24 Jul 2017 11:58:32 +0100 Subject: [PATCH 1/6] Add moo/indent --- indent.js | 92 ++++++++++++++++++++++++++ package.json | 3 +- test/__snapshots__/indent.test.js.snap | 87 ++++++++++++++++++++++++ test/indent.test.js | 32 +++++++++ 4 files changed, 213 insertions(+), 1 deletion(-) create mode 100644 indent.js create mode 100644 test/__snapshots__/indent.test.js.snap create mode 100644 test/indent.test.js diff --git a/indent.js b/indent.js new file mode 100644 index 0000000..81c66cf --- /dev/null +++ b/indent.js @@ -0,0 +1,92 @@ +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + define(['moo'], factory) /* global define */ + } else if (typeof module === 'object' && module.exports) { + module.exports = factory(require('./moo')) + } else { + root.moo.indent = factory(root.moo) + } +}(this, function(moo) { + 'use strict'; + + function* indented(lexer, source) { + let iter = peekable(lexer.reset(source)) + let stack = [] + + // absorb initial blank lines and indentation + let indent = iter.nextIndent() + + for (let tok; tok = iter.next(); ) { + if (tok.type === 'nl') { + const newIndent = iter.nextIndent() + if (newIndent == null) break // eof + + if (newIndent === indent) { + yield {type: 'nl'} + + } else if (newIndent > indent) { + stack.push(indent) + indent = newIndent + yield {type: 'indent'} + + } else { + while (newIndent < indent) { + indent = stack.pop() + yield {type: 'dedent'} + } + if (newIndent !== indent) { + throw new Error('inconsistent indentation') + } + } + indent = newIndent + + // ignore whitespace within lines + } else if (tok.type !== 'ws') { + yield tok + } + } + + // dedent remaining blocks at eof + for (let i = stack.length; i--;) { + yield {type: 'dedent'} + } + } + + function peekable(lexer) { + let here = lexer.next() + return { + next() { + const old = here + here = lexer.next() + return old + }, + peek() { + return here + }, + nextIndent() { + for (let tok; tok = this.peek(); ) { + if (tok.type === 'nl') { + this.next() + continue + } + if (tok.type === 'ws') { + const indent = tok.value.length + this.next() + + const next = this.peek() + if (!next) return + if (next.type === 'nl') { + this.next() + continue + } + return indent + } + return 0 + } + }, + } + } + + return indented + +})) diff --git a/package.json b/package.json index d16e631..d714202 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "description": "Optimised tokenizer/lexer generator! 🐄 Uses /y for performance. Moo!", "main": "moo.js", "files": [ - "moo.js" + "moo.js", + "indent.js" ], "repository": "https://github.com/tjvr/moo.git", "author": "Tim Radvan ", diff --git a/test/__snapshots__/indent.test.js.snap b/test/__snapshots__/indent.test.js.snap new file mode 100644 index 0000000..02a56bd --- /dev/null +++ b/test/__snapshots__/indent.test.js.snap @@ -0,0 +1,87 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`indent example 1`] = ` +Array [ + Object { + "col": 5, + "line": 2, + "lineBreaks": 0, + "offset": 5, + "toString": [Function], + "type": "id", + "value": "if", + }, + Object { + "col": 8, + "line": 2, + "lineBreaks": 0, + "offset": 8, + "toString": [Function], + "type": "id", + "value": "this", + }, + Object { + "type": "indent", + }, + Object { + "col": 7, + "line": 3, + "lineBreaks": 0, + "offset": 19, + "toString": [Function], + "type": "id", + "value": "if", + }, + Object { + "col": 10, + "line": 3, + "lineBreaks": 0, + "offset": 22, + "toString": [Function], + "type": "id", + "value": "that", + }, + Object { + "type": "indent", + }, + Object { + "col": 9, + "line": 4, + "lineBreaks": 0, + "offset": 35, + "toString": [Function], + "type": "id", + "value": "another", + }, + Object { + "type": "dedent", + }, + Object { + "type": "dedent", + }, + Object { + "col": 5, + "line": 5, + "lineBreaks": 0, + "offset": 47, + "toString": [Function], + "type": "id", + "value": "else", + }, + Object { + "type": "indent", + }, + Object { + "col": 7, + "line": 6, + "lineBreaks": 0, + "offset": 58, + "toString": [Function], + "type": "id", + "value": "there", + }, + Object { + "type": "dedent", + }, +] +`; diff --git a/test/indent.test.js b/test/indent.test.js new file mode 100644 index 0000000..ca92f3b --- /dev/null +++ b/test/indent.test.js @@ -0,0 +1,32 @@ + +const fs = require('fs') + +const moo = require('../moo') +const indented = require('../indent') +const compile = moo.compile + +describe('indent', () => { + + test("example", () => { + + const lexer = moo.compile({ + ws: /[ \t]+/, + nl: { match: /(?:\r\n?|\n)+/, lineBreaks: true }, + id: /\w+/, + }) + + const tokens = indented(lexer, ` + if this + if that + another + else + there + `) + + const output = Array.from(tokens) + //for (const tok of output) console.log(tok) + expect(output).toMatchSnapshot() + + }) + +}) From 081e53ad857bde3d400e9ec81324630ca65fceb5 Mon Sep 17 00:00:00 2001 From: tjvr Date: Mon, 24 Jul 2017 12:27:16 +0100 Subject: [PATCH 2/6] Convert indented to ES5ish --- indent.js | 169 ++++++++++++++++++++++++++++++-------------- test/indent.test.js | 7 +- 2 files changed, 119 insertions(+), 57 deletions(-) diff --git a/indent.js b/indent.js index 81c66cf..90191d5 100644 --- a/indent.js +++ b/indent.js @@ -9,84 +9,145 @@ }(this, function(moo) { 'use strict'; - function* indented(lexer, source) { - let iter = peekable(lexer.reset(source)) - let stack = [] + function proxy(a, name) { + a.prototype[name] = function() { + return this.lexer[name].apply(this.lexer, arguments) + } + } + + function Indented(lexer, options) { + this.options = Object.assign({ + // TODO + // whitespace: 'ws', + // newline: 'nl', + // indent: 'indent', + // dedent: 'dedent', + }, options) + this.lexer = lexer + this.reset() + } + proxy(Indented, 'formatError') + proxy(Indented, 'setState') + proxy(Indented, 'has') + + Indented.prototype.clone = function() { + return new Indented(this.lexer.clone(), this.options) + } + + Indented.prototype.reset = function(data, info) { + this.indent = info ? info.indent : null + this.stack = info ? info.stack.slice() : [] + this.queue = info ? info.queue.slice() : [] + this.lexer.reset(data, info) + this.here = info ? info.here : null + } + + Indented.prototype.save = function() { + return Object.assign(this.lexer.save(), { + here: this.here, + indent: this.indent, + stack: this.stack.slice(), + queue: this.queue.slice(), + }) + } + + Indented.prototype._peek = function() { + return this.here || (this.here = this.lexer.next()) + } + + Indented.prototype._next = function() { + if (this.here) { + var old = this.here + this.here = null + return old + } + return this.lexer.next() + } - // absorb initial blank lines and indentation - let indent = iter.nextIndent() + Indented.prototype._nextIndent = function() { + for (var tok; tok = this._peek(); ) { + if (tok.type === 'nl') { + this._next() + continue + } + if (tok.type === 'ws') { + var indent = tok.value.length + this._next() + + var next = this._peek() + if (!next) return + if (next.type === 'nl') { + this._next() + continue + } + return indent + } + return 0 + } + } - for (let tok; tok = iter.next(); ) { + Indented.prototype.next = function() { + if (this.indent === null) { + // absorb initial blank lines and indentation + this.indent = this._nextIndent() + } + if (this.queue.length) { + return this.queue.shift() + } + + var tok + while (tok = this._next()) { if (tok.type === 'nl') { - const newIndent = iter.nextIndent() + var newIndent = this._nextIndent() if (newIndent == null) break // eof - if (newIndent === indent) { - yield {type: 'nl'} + if (newIndent === this.indent) { + this.indent = newIndent + return {type: 'nl'} // TODO tok? - } else if (newIndent > indent) { - stack.push(indent) - indent = newIndent - yield {type: 'indent'} + } else if (newIndent > this.indent) { + this.stack.push(this.indent) + this.indent = newIndent + return {type: 'indent'} } else { - while (newIndent < indent) { - indent = stack.pop() - yield {type: 'dedent'} + while (newIndent < this.indent) { + this.indent = this.stack.pop() + this.queue.push({type: 'dedent'}) } - if (newIndent !== indent) { + if (newIndent !== this.indent) { throw new Error('inconsistent indentation') } + this.indent = newIndent + return this.queue.shift() } - indent = newIndent // ignore whitespace within lines } else if (tok.type !== 'ws') { - yield tok + return tok } } // dedent remaining blocks at eof - for (let i = stack.length; i--;) { - yield {type: 'dedent'} + for (let i = this.stack.length; i--; ) { + this.queue.push({type: 'dedent'}) } + this.stack = [] + if (this.queue.length) return this.queue.shift() } - function peekable(lexer) { - let here = lexer.next() - return { - next() { - const old = here - here = lexer.next() - return old - }, - peek() { - return here - }, - nextIndent() { - for (let tok; tok = this.peek(); ) { - if (tok.type === 'nl') { - this.next() - continue - } - if (tok.type === 'ws') { - const indent = tok.value.length - this.next() - - const next = this.peek() - if (!next) return - if (next.type === 'nl') { - this.next() - continue - } - return indent - } - return 0 - } - }, + if (typeof Symbol !== 'undefined' && Symbol.iterator) { + var lexer = moo.compile([]) + var iter = lexer[Symbol.iterator]() + var LexerIterator = iter.constructor + Indented.prototype[Symbol.iterator] = function() { + return new LexerIterator(this) } } - return indented + + return function indented(lexer, options) { + return new Indented(lexer, options) + } })) diff --git a/test/indent.test.js b/test/indent.test.js index ca92f3b..3343c50 100644 --- a/test/indent.test.js +++ b/test/indent.test.js @@ -9,13 +9,14 @@ describe('indent', () => { test("example", () => { - const lexer = moo.compile({ + const lexer = indented(moo.compile({ ws: /[ \t]+/, nl: { match: /(?:\r\n?|\n)+/, lineBreaks: true }, id: /\w+/, }) - const tokens = indented(lexer, ` + + lexer.reset(` if this if that another @@ -23,7 +24,7 @@ describe('indent', () => { there `) - const output = Array.from(tokens) + const output = Array.from(lexer) //for (const tok of output) console.log(tok) expect(output).toMatchSnapshot() From ee1e18772c5977946a658137b3071cc0b2ebf0b0 Mon Sep 17 00:00:00 2001 From: tjvr Date: Mon, 24 Jul 2017 15:28:19 +0100 Subject: [PATCH 3/6] Introduce token() helper --- indent.js | 14 ++++++++++---- test/__snapshots__/indent.test.js.snap | 6 ++++++ test/indent.test.js | 3 +-- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/indent.js b/indent.js index 90191d5..deb0f15 100644 --- a/indent.js +++ b/indent.js @@ -15,6 +15,11 @@ } } + function token(name) { + return {type: name, value: ""} + } + + function Indented(lexer, options) { this.options = Object.assign({ // TODO @@ -40,6 +45,7 @@ this.queue = info ? info.queue.slice() : [] this.lexer.reset(data, info) this.here = info ? info.here : null + return this } Indented.prototype.save = function() { @@ -103,17 +109,17 @@ if (newIndent === this.indent) { this.indent = newIndent - return {type: 'nl'} // TODO tok? + return token('nl') // TODO tok? } else if (newIndent > this.indent) { this.stack.push(this.indent) this.indent = newIndent - return {type: 'indent'} + return token('indent') } else { while (newIndent < this.indent) { this.indent = this.stack.pop() - this.queue.push({type: 'dedent'}) + this.queue.push(token('dedent')) } if (newIndent !== this.indent) { throw new Error('inconsistent indentation') @@ -130,7 +136,7 @@ // dedent remaining blocks at eof for (let i = this.stack.length; i--; ) { - this.queue.push({type: 'dedent'}) + this.queue.push(token('dedent')) } this.stack = [] if (this.queue.length) return this.queue.shift() diff --git a/test/__snapshots__/indent.test.js.snap b/test/__snapshots__/indent.test.js.snap index 02a56bd..64c427b 100644 --- a/test/__snapshots__/indent.test.js.snap +++ b/test/__snapshots__/indent.test.js.snap @@ -22,6 +22,7 @@ Array [ }, Object { "type": "indent", + "value": "", }, Object { "col": 7, @@ -43,6 +44,7 @@ Array [ }, Object { "type": "indent", + "value": "", }, Object { "col": 9, @@ -55,9 +57,11 @@ Array [ }, Object { "type": "dedent", + "value": "", }, Object { "type": "dedent", + "value": "", }, Object { "col": 5, @@ -70,6 +74,7 @@ Array [ }, Object { "type": "indent", + "value": "", }, Object { "col": 7, @@ -82,6 +87,7 @@ Array [ }, Object { "type": "dedent", + "value": "", }, ] `; diff --git a/test/indent.test.js b/test/indent.test.js index 3343c50..50b3f6c 100644 --- a/test/indent.test.js +++ b/test/indent.test.js @@ -13,8 +13,7 @@ describe('indent', () => { ws: /[ \t]+/, nl: { match: /(?:\r\n?|\n)+/, lineBreaks: true }, id: /\w+/, - }) - + })) lexer.reset(` if this From 3d0be8c7597c80349ba0a1456b8ed40d7162255e Mon Sep 17 00:00:00 2001 From: tjvr Date: Mon, 24 Jul 2017 15:29:37 +0100 Subject: [PATCH 4/6] Indented: Add name options --- indent.js | 40 +++++++++++++++++++++------------------- test/indent.test.js | 8 ++++++-- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/indent.js b/indent.js index deb0f15..cafe0c9 100644 --- a/indent.js +++ b/indent.js @@ -22,11 +22,11 @@ function Indented(lexer, options) { this.options = Object.assign({ - // TODO - // whitespace: 'ws', - // newline: 'nl', - // indent: 'indent', - // dedent: 'dedent', + whitespace: 'ws', + newline: 'nl', + indent: 'indent', + dedent: 'dedent', + ignoreNewline: false, }, options) this.lexer = lexer this.reset() @@ -72,17 +72,18 @@ Indented.prototype._nextIndent = function() { for (var tok; tok = this._peek(); ) { - if (tok.type === 'nl') { + if (tok.type === this.options.newline) { + if (!this.options.ignoreNewline) this.queue.push(tok) this._next() continue } - if (tok.type === 'ws') { + if (tok.type === this.options.whitespace) { var indent = tok.value.length this._next() var next = this._peek() if (!next) return - if (next.type === 'nl') { + if (next.type === this.options.newline) { this._next() continue } @@ -103,40 +104,41 @@ var tok while (tok = this._next()) { - if (tok.type === 'nl') { + if (tok.type === this.options.newline) { + if (!this.options.ignoreNewline) this.queue.push(tok) var newIndent = this._nextIndent() if (newIndent == null) break // eof if (newIndent === this.indent) { - this.indent = newIndent - return token('nl') // TODO tok? + if (this.options.ignoreNewline) { + this.queue.push(tok) + } } else if (newIndent > this.indent) { this.stack.push(this.indent) - this.indent = newIndent - return token('indent') + this.queue.push(token(this.options.indent)) } else { while (newIndent < this.indent) { this.indent = this.stack.pop() - this.queue.push(token('dedent')) + this.queue.push(token(this.options.dedent)) } if (newIndent !== this.indent) { - throw new Error('inconsistent indentation') + throw new Error(this.formatError(tok, 'inconsistent indentation')) } - this.indent = newIndent - return this.queue.shift() } + this.indent = newIndent + return this.queue.shift() // ignore whitespace within lines - } else if (tok.type !== 'ws') { + } else if (tok.type !== this.options.whitespace) { return tok } } // dedent remaining blocks at eof for (let i = this.stack.length; i--; ) { - this.queue.push(token('dedent')) + this.queue.push(token(this.options.dedent)) } this.stack = [] if (this.queue.length) return this.queue.shift() diff --git a/test/indent.test.js b/test/indent.test.js index 50b3f6c..12215ee 100644 --- a/test/indent.test.js +++ b/test/indent.test.js @@ -9,11 +9,15 @@ describe('indent', () => { test("example", () => { - const lexer = indented(moo.compile({ + const base = moo.compile({ ws: /[ \t]+/, nl: { match: /(?:\r\n?|\n)+/, lineBreaks: true }, id: /\w+/, - })) + }) + + const lexer = indented(base, { + ignoreNewline: true, + }) lexer.reset(` if this From 0fb48c943f6d65d49af93d69bc8df4685061db41 Mon Sep 17 00:00:00 2001 From: tjvr Date: Mon, 24 Jul 2017 15:18:12 +0100 Subject: [PATCH 5/6] Use moo/indented for Python example --- indent.js | 9 +- test/__snapshots__/test.js.snap | 828 ++++++++++++++++---------------- test/python.js | 170 +++---- test/test.js | 7 +- 4 files changed, 490 insertions(+), 524 deletions(-) diff --git a/indent.js b/indent.js index cafe0c9..7373f04 100644 --- a/indent.js +++ b/indent.js @@ -72,8 +72,8 @@ Indented.prototype._nextIndent = function() { for (var tok; tok = this._peek(); ) { - if (tok.type === this.options.newline) { - if (!this.options.ignoreNewline) this.queue.push(tok) + if (tok.type === this.options.newline || tok.type === this.options.comment) { + if (tok.type !== this.options.newline || !this.options.ignoreNewline) this.queue.push(tok) this._next() continue } @@ -83,7 +83,8 @@ var next = this._peek() if (!next) return - if (next.type === this.options.newline) { + if (next.type === this.options.newline || next.type === this.options.comment) { + if (next.type === this.options.comment) this.queue.push(next) this._next() continue } @@ -99,7 +100,7 @@ this.indent = this._nextIndent() } if (this.queue.length) { - return this.queue.shift() + return this.queue.shift() // TODO optimize } var tok diff --git a/test/__snapshots__/test.js.snap b/test/__snapshots__/test.js.snap index 932d3d7..865d198 100644 --- a/test/__snapshots__/test.js.snap +++ b/test/__snapshots__/test.js.snap @@ -60,7 +60,7 @@ Array [ "NAME \\"try\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"from\\"", "NAME \\"cStringIO\\"", "NAME \\"import\\"", @@ -71,7 +71,7 @@ Array [ "NAME \\"ImportError\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"from\\"", "NAME \\"StringIO\\"", "NAME \\"import\\"", @@ -100,7 +100,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Strip non-alphanumeric characters to makes name safe to be used as\\\\n filename.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"return\\"", @@ -129,7 +129,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"The main kurt class. Stores the contents of a project file.\\\\n\\\\n Contents include global variables and lists, the :attr:\`stage\` and\\\\n :attr:\`sprites\`, each with their own :attr:\`scripts\`, :attr:\`costumes\`,\\\\n :attr:\`sounds\`, :attr:\`variables\` and :attr:\`lists\`.\\\\n\\\\n A Project can be loaded from or saved to disk in a format which can be read\\\\n by a Scratch program or one of its derivatives.\\\\n\\\\n Loading a project::\\\\n\\\\n p = kurt.Project.load(\\\\\\"tests/game.sb\\\\\\")\\\\n\\\\n Getting all the scripts::\\\\n\\\\n for scriptable in p.sprites + [p.stage]:\\\\n for script in scriptable.scripts:\\\\n print script\\\\n\\\\n Creating a new project::\\\\n\\\\n p = kurt.Project()\\\\n\\\\n Converting between formats::\\\\n\\\\n p = kurt.Project.load(\\\\\\"tests/game.sb\\\\\\")\\\\n p.convert(\\\\\\"scratch20\\\\\\")\\\\n # []\\\\n p.save()\\\\n # 'tests/game.sb2'\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -140,7 +140,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"name\\"", @@ -267,7 +267,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "STRING \\"<%s.%s()>\\"", "OP \\"%\\"", @@ -297,7 +297,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Get a sprite from :attr:\`sprites\` by name.\\\\n\\\\n Returns None if the sprite isn't found.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"for\\"", @@ -308,7 +308,7 @@ Array [ "NAME \\"sprites\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"sprite\\"", "OP \\".\\"", @@ -317,7 +317,7 @@ Array [ "NAME \\"name\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"sprite\\"", "NEWLINE \\"\\\\n\\"", @@ -335,7 +335,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"The file format of the project.\\\\n\\\\n :class:\`Project\` is mainly a universal representation, and so a project\\\\n has no specfic format. This is the format the project was loaded with.\\\\n To convert to a different format, use :attr:\`save()\`.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"if\\"", @@ -344,7 +344,7 @@ Array [ "NAME \\"_plugin\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -371,7 +371,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Load project from file.\\\\n\\\\n Use \`\`format\`\` to specify the file format to use.\\\\n\\\\n Path can be a file-like object, in which case format is required.\\\\n Otherwise, can guess the appropriate format from the extension.\\\\n\\\\n If you pass a file-like object, you're responsible for closing the\\\\n file.\\\\n\\\\n :param path: Path or file pointer.\\\\n :param format: :attr:\`KurtFileFormat.name\` eg. \`\`\\\\\\"scratch14\\\\\\"\`\`.\\\\n Overrides the extension.\\\\n\\\\n :raises: :class:\`UnknownFormat\` if the extension is unrecognised.\\\\n :raises: :py:class:\`ValueError\` if the format doesn't exist.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"path_was_string\\"", @@ -387,7 +387,7 @@ Array [ "NAME \\"path_was_string\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "OP \\"(\\"", "NAME \\"folder\\"", "OP \\",\\"", @@ -424,7 +424,7 @@ Array [ "NAME \\"None\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"plugin\\"", "OP \\"=\\"", "NAME \\"kurt\\"", @@ -445,7 +445,7 @@ Array [ "NAME \\"plugin\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"raise\\"", "NAME \\"UnknownFormat\\"", "OP \\"(\\"", @@ -467,7 +467,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"fp\\"", "OP \\"=\\"", "NAME \\"path\\"", @@ -497,7 +497,7 @@ Array [ "NAME \\"plugin\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"raise\\"", "NAME \\"ValueError\\"", "OP \\",\\"", @@ -520,7 +520,7 @@ Array [ "NAME \\"path_was_string\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"fp\\"", "OP \\".\\"", "NAME \\"close\\"", @@ -544,7 +544,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"project\\"", "OP \\".\\"", "NAME \\"path\\"", @@ -558,7 +558,7 @@ Array [ "NAME \\"name\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"project\\"", "OP \\".\\"", "NAME \\"name\\"", @@ -579,7 +579,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return a new Project instance, deep-copying all the attributes.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"p\\"", @@ -641,7 +641,7 @@ Array [ "NAME \\"sprites\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"s\\"", "OP \\"=\\"", "NAME \\"sprite\\"", @@ -675,7 +675,7 @@ Array [ "NAME \\"actors\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"isinstance\\"", "OP \\"(\\"", @@ -685,7 +685,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"p\\"", "OP \\".\\"", "NAME \\"actors\\"", @@ -706,7 +706,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"a\\"", "OP \\"=\\"", "NAME \\"actor\\"", @@ -724,7 +724,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"isinstance\\"", "OP \\"(\\"", @@ -736,7 +736,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"a\\"", "OP \\".\\"", "NAME \\"target\\"", @@ -755,7 +755,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"a\\"", "OP \\".\\"", "NAME \\"target\\"", @@ -768,7 +768,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"a\\"", "OP \\".\\"", "NAME \\"target\\"", @@ -906,7 +906,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Convert the project in-place to a different file format.\\\\n\\\\n Returns a list of :class:\`UnsupportedFeature\` objects, which may give\\\\n warnings about the conversion.\\\\n\\\\n :param format: :attr:\`KurtFileFormat.name\` eg. \`\`\\\\\\"scratch14\\\\\\"\`\`.\\\\n\\\\n :raises: :class:\`ValueError\` if the format doesn't exist.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"self\\"", @@ -951,7 +951,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Save project to file.\\\\n\\\\n :param path: Path or file pointer.\\\\n\\\\n If you pass a file pointer, you're responsible for closing\\\\n it.\\\\n\\\\n If path is not given, the :attr:\`path\` attribute is used,\\\\n usually the original path given to :attr:\`load()\`.\\\\n\\\\n If \`path\` has the extension of an existing plugin, the\\\\n project will be converted using :attr:\`convert\`.\\\\n Otherwise, the extension will be replaced with the\\\\n extension of the current plugin.\\\\n\\\\n (Note that log output for the conversion will be printed\\\\n to stdout. If you want to deal with the output, call\\\\n :attr:\`convert\` directly.)\\\\n\\\\n If the path ends in a folder instead of a file, the\\\\n filename is based on the project's :attr:\`name\`.\\\\n\\\\n :param debug: If true, return debugging information from the format\\\\n plugin instead of the path.\\\\n\\\\n :raises: :py:class:\`ValueError\` if there's no path or name.\\\\n\\\\n :returns: path to the saved file.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -989,7 +989,7 @@ Array [ "NAME \\"path\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"raise\\"", "NAME \\"ValueError\\"", "OP \\",\\"", @@ -1010,7 +1010,7 @@ Array [ "NEWLINE \\"\\\\n\\"", "COMMENT \\"# split path\\"", "NL \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "OP \\"(\\"", "NAME \\"folder\\"", "OP \\",\\"", @@ -1050,12 +1050,12 @@ Array [ "NAME \\"path\\"", "OP \\":\\"", "COMMENT \\"# only if not using self.path\\"", - "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "NL \\"\\\\n\\"", + "INDENT \\"\\"", "NAME \\"try\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"plugin\\"", "OP \\"=\\"", "NAME \\"kurt\\"", @@ -1076,7 +1076,7 @@ Array [ "NAME \\"ValueError\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"pass\\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -1089,7 +1089,7 @@ Array [ "NAME \\"name\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"name\\"", "OP \\"=\\"", "NAME \\"_clean_filename\\"", @@ -1104,7 +1104,7 @@ Array [ "NAME \\"name\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"raise\\"", "NAME \\"ValueError\\"", "OP \\",\\"", @@ -1153,7 +1153,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"fp\\"", "OP \\"=\\"", "NAME \\"p\\"", @@ -1171,7 +1171,7 @@ Array [ "NAME \\"plugin\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"raise\\"", "NAME \\"ValueError\\"", "OP \\",\\"", @@ -1190,7 +1190,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"print\\"", "NAME \\"m\\"", "NEWLINE \\"\\\\n\\"", @@ -1208,7 +1208,7 @@ Array [ "NAME \\"path\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"fp\\"", "OP \\".\\"", "NAME \\"close\\"", @@ -1236,7 +1236,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -1258,7 +1258,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Convert the project to a standardised form for the current plugin.\\\\n\\\\n Called after loading, before saving, and when converting to a new\\\\n format.\\\\n\\\\n Yields UnsupportedFeature instances.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -1291,7 +1291,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"raise\\"", "NAME \\"ValueError\\"", "OP \\",\\"", @@ -1309,7 +1309,7 @@ Array [ "NAME \\"sprites\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"sprite\\"", "NAME \\"not\\"", @@ -1319,7 +1319,7 @@ Array [ "NAME \\"actors\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"actors\\"", @@ -1339,7 +1339,7 @@ Array [ "NAME \\"actors\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"isinstance\\"", "OP \\"(\\"", @@ -1349,7 +1349,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"actor\\"", "NAME \\"not\\"", @@ -1359,7 +1359,7 @@ Array [ "NAME \\"sprites\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"raise\\"", "NAME \\"ValueError\\"", "OP \\",\\"", @@ -1387,7 +1387,7 @@ Array [ "NAME \\"sprites\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"sprite\\"", "OP \\".\\"", "NAME \\"_normalize\\"", @@ -1406,7 +1406,7 @@ Array [ "NAME \\"actors\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"not\\"", "NAME \\"isinstance\\"", @@ -1417,7 +1417,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"actor\\"", "OP \\".\\"", "NAME \\"_normalize\\"", @@ -1445,7 +1445,7 @@ Array [ "NAME \\"sprites\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"for\\"", "OP \\"(\\"", "NAME \\"name\\"", @@ -1462,7 +1462,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"not\\"", "NAME \\"var\\"", @@ -1470,7 +1470,7 @@ Array [ "NAME \\"watcher\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"var\\"", "OP \\".\\"", "NAME \\"watcher\\"", @@ -1525,7 +1525,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"not\\"", "NAME \\"list_\\"", @@ -1533,7 +1533,7 @@ Array [ "NAME \\"watcher\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"list_\\"", "OP \\".\\"", "NAME \\"watcher\\"", @@ -1610,11 +1610,11 @@ Array [ "NEWLINE \\"\\\\n\\"", "COMMENT \\"# convert block\\"", "NL \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"try\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"isinstance\\"", "OP \\"(\\"", @@ -1626,7 +1626,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "STRING \\"Custom Blocks\\"", "NAME \\"not\\"", @@ -1638,7 +1638,7 @@ Array [ "NAME \\"features\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"raise\\"", "NAME \\"BlockNotSupported\\"", "OP \\"(\\"", @@ -1659,8 +1659,8 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "COMMENT \\"# BlockType\\"", - "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "NL \\"\\\\n\\"", + "INDENT \\"\\"", "NAME \\"pbt\\"", "OP \\"=\\"", "NAME \\"block\\"", @@ -1682,7 +1682,7 @@ Array [ "NAME \\"err\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"err\\"", "OP \\".\\"", "NAME \\"message\\"", @@ -1727,7 +1727,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"block\\"", "OP \\"=\\"", "NAME \\"block\\"", @@ -1744,7 +1744,7 @@ Array [ "NAME \\"block\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"raise\\"", "NEWLINE \\"\\\\n\\"", "DEDENT \\"\\"", @@ -1752,7 +1752,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"raise\\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -1773,7 +1773,7 @@ Array [ "NAME \\"args\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"isinstance\\"", "OP \\"(\\"", @@ -1783,7 +1783,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"arg\\"", "OP \\"=\\"", "NAME \\"convert_block\\"", @@ -1801,7 +1801,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"arg\\"", "OP \\"=\\"", "NAME \\"map\\"", @@ -1846,7 +1846,7 @@ Array [ "NAME \\"sprites\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"for\\"", "NAME \\"script\\"", "NAME \\"in\\"", @@ -1855,7 +1855,7 @@ Array [ "NAME \\"scripts\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"isinstance\\"", "OP \\"(\\"", @@ -1865,7 +1865,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"script\\"", "OP \\".\\"", "NAME \\"blocks\\"", @@ -1901,7 +1901,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"feature\\"", "NAME \\"not\\"", @@ -1913,7 +1913,7 @@ Array [ "NAME \\"features\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"for\\"", "NAME \\"x\\"", "NAME \\"in\\"", @@ -1925,7 +1925,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"yield\\"", "NAME \\"UnsupportedFeature\\"", "OP \\"(\\"", @@ -1950,7 +1950,7 @@ Array [ "NAME \\"features\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"feature\\"", "OP \\".\\"", "NAME \\"normalize\\"", @@ -1968,7 +1968,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"def\\"", "NAME \\"get_broadcasts\\"", "OP \\"(\\"", @@ -1976,7 +1976,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"for\\"", "OP \\"(\\"", "NAME \\"arg\\"", @@ -1998,7 +1998,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"isinstance\\"", "OP \\"(\\"", @@ -2008,7 +2008,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"for\\"", "NAME \\"b\\"", "NAME \\"in\\"", @@ -2018,7 +2018,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"yield\\"", "NAME \\"b\\"", "NEWLINE \\"\\\\n\\"", @@ -2033,14 +2033,14 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"for\\"", "NAME \\"arg_block\\"", "NAME \\"in\\"", "NAME \\"arg\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"for\\"", "NAME \\"b\\"", "NAME \\"in\\"", @@ -2050,7 +2050,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"yield\\"", "NAME \\"b\\"", "NEWLINE \\"\\\\n\\"", @@ -2065,7 +2065,7 @@ Array [ "STRING \\"broadcast\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"yield\\"", "NAME \\"arg\\"", "NEWLINE \\"\\\\n\\"", @@ -2087,7 +2087,7 @@ Array [ "NAME \\"sprites\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"for\\"", "NAME \\"script\\"", "NAME \\"in\\"", @@ -2096,7 +2096,7 @@ Array [ "NAME \\"scripts\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"for\\"", "NAME \\"block\\"", "NAME \\"in\\"", @@ -2105,7 +2105,7 @@ Array [ "NAME \\"blocks\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"for\\"", "NAME \\"b\\"", "NAME \\"in\\"", @@ -2115,7 +2115,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"yield\\"", "NAME \\"b\\"", "NEWLINE \\"\\\\n\\"", @@ -2134,7 +2134,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"The plugin doesn't support this Feature.\\\\n\\\\n Output once by Project.convert for each occurence of the feature.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"def\\"", @@ -2148,7 +2148,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"feature\\"", @@ -2179,7 +2179,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "STRING \\"<%s.%s(%s)>\\"", "OP \\"%\\"", @@ -2212,7 +2212,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "STRING \\"UnsupportedFeature: %s\\"", "OP \\"%\\"", @@ -2230,7 +2230,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"u\\"", "STRING \\"%r: %r\\"", @@ -2262,7 +2262,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"The file extension is not recognised.\\\\n\\\\n Raised when :class:\`Project\` can't find a valid format plugin to handle the\\\\n file extension.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"pass\\"", @@ -2277,7 +2277,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"A :class:\`Block\` with the given command or type cannot be found.\\\\n\\\\n Raised by :attr:\`BlockType.get\`.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -2290,7 +2290,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"The plugin doesn't support this Block.\\\\n\\\\n Raised by :attr:\`Block.convert\` when it can't find a\\\\n :class:\`PluginBlockType\` for the given plugin.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"pass\\"", @@ -2305,7 +2305,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Tried to construct a raster image from a vector format image file.\\\\n\\\\n You shouldn't usally get this error, because Feature(\\\\\\"Vector Images\\\\\\") will\\\\n give a warning instead when the Project is converted.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"pass\\"", @@ -2324,7 +2324,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"An object that goes on the project stage.\\\\n\\\\n Subclasses include :class:\`Watcher\` or :class:\`Sprite\`.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -2337,7 +2337,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Superclass for all scriptable objects.\\\\n\\\\n Subclasses are :class:\`Stage\` and :class:\`Sprite\`.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -2350,7 +2350,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"project\\"", @@ -2448,7 +2448,7 @@ Array [ "NEWLINE \\"\\\\n\\"", "COMMENT \\"# costumes\\"", "NL \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -2457,7 +2457,7 @@ Array [ "NEWLINE \\"\\\\n\\"", "COMMENT \\"# Make sure it's in costumes\\"", "NL \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -2469,7 +2469,7 @@ Array [ "NAME \\"costumes\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"costumes\\"", @@ -2488,14 +2488,14 @@ Array [ "NEWLINE \\"\\\\n\\"", "COMMENT \\"# No costume!\\"", "NL \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"costumes\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"costume\\"", @@ -2511,7 +2511,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"BLACK\\"", "OP \\"=\\"", "OP \\"(\\"", @@ -2567,7 +2567,7 @@ Array [ "NAME \\"scripts\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"script\\"", "OP \\".\\"", "NAME \\"_normalize\\"", @@ -2658,7 +2658,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return a new instance, deep-copying all the attributes.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"if\\"", @@ -2824,7 +2824,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"The index of :attr:\`costume\` in :attr:\`costumes\`.\\\\n\\\\n None if no costume is selected.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"if\\"", @@ -2833,7 +2833,7 @@ Array [ "NAME \\"costume\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -2863,14 +2863,14 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"index\\"", "NAME \\"is\\"", "NAME \\"None\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"costume\\"", @@ -2881,7 +2881,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"costume\\"", @@ -2905,7 +2905,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Parse the given code and add it to :attr:\`scripts\`.\\\\n\\\\n The syntax matches :attr:\`Script.stringify()\`. See :mod:\`kurt.text\` for\\\\n reference.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"self\\"", @@ -2937,7 +2937,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Represents the background of the project. The stage is similar to a\\\\n :class:\`Sprite\`, but has a fixed position. The stage has a fixed size of\\\\n \`\`480x360\`\` pixels.\\\\n\\\\n The stage does not require a costume. If none is given, it is assumed to be\\\\n white (#FFF).\\\\n\\\\n Not all formats have stage-specific variables and lists. Global variables\\\\n and lists are stored on the :class:\`Project\`.\\\\n\\\\n :param project: The :class:\`Project\` this Stage belongs to.\\\\n Note that you still need to set :attr:\`Project.stage\` to\\\\n this Stage instance.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -2982,7 +2982,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"Scriptable\\"", "OP \\".\\"", "NAME \\"__init__\\"", @@ -3004,7 +3004,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Alias for :attr:\`costumes\`.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"return\\"", @@ -3028,7 +3028,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"costumes\\"", @@ -3044,7 +3044,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "STRING \\"<%s.%s()>\\"", "OP \\"%\\"", @@ -3072,7 +3072,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"not\\"", "NAME \\"self\\"", @@ -3085,7 +3085,7 @@ Array [ "NAME \\"costumes\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"costume\\"", @@ -3129,7 +3129,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"A scriptable object displayed on the project stage. Can be moved and\\\\n rotated, unlike the :class:\`Stage\`.\\\\n\\\\n Sprites require a :attr:\`costume\`, and will raise an error when saving\\\\n without one.\\\\n\\\\n :param project: The :class:\`Project\` this Sprite belongs to.\\\\n Note that you still need to add this sprite to\\\\n :attr:\`Project.sprites\`.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -3144,7 +3144,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"Scriptable\\"", "OP \\".\\"", "NAME \\"__init__\\"", @@ -3233,7 +3233,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"Scriptable\\"", "OP \\".\\"", "NAME \\"_normalize\\"", @@ -3263,7 +3263,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return a new instance, deep-copying all the attributes.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"o\\"", @@ -3353,7 +3353,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "STRING \\"<%s.%s(%r)>\\"", "OP \\"%\\"", @@ -3387,7 +3387,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"A monitor for displaying a data value on the stage.\\\\n\\\\n Some formats won't save hidden watchers, and so their position won't be\\\\n remembered.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -3415,7 +3415,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"Actor\\"", "OP \\".\\"", "NAME \\"__init__\\"", @@ -3514,7 +3514,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"assert\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -3534,7 +3534,7 @@ Array [ "NAME \\"value\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"value\\"", @@ -3553,7 +3553,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return a new instance with the same attributes.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"o\\"", @@ -3622,7 +3622,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"The type of value to watch, based on :attr:\`block\`.\\\\n\\\\n One of \`\`variable\`\`, \`\`list\`\`, or \`\`block\`\`.\\\\n\\\\n \`\`block\`\` watchers watch the value of a reporter block.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"if\\"", @@ -3638,7 +3638,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "STRING \\"variable\\"", "NEWLINE \\"\\\\n\\"", @@ -3656,7 +3656,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "STRING \\"list\\"", "NEWLINE \\"\\\\n\\"", @@ -3664,7 +3664,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "STRING \\"block\\"", "NEWLINE \\"\\\\n\\"", @@ -3681,7 +3681,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return the :class:\`Variable\` or :class:\`List\` to watch.\\\\n\\\\n Returns \`\`None\`\` if it's a block watcher.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"if\\"", @@ -3692,7 +3692,7 @@ Array [ "STRING \\"variable\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -3719,7 +3719,7 @@ Array [ "STRING \\"list\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -3747,7 +3747,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"r\\"", "OP \\"=\\"", "STRING \\"%s.%s(%r, %r\\"", @@ -3783,7 +3783,7 @@ Array [ "STRING \\"normal\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"r\\"", "OP \\"+=\\"", "STRING \\", style=%r\\"", @@ -3800,7 +3800,7 @@ Array [ "NAME \\"is_visible\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"r\\"", "OP \\"+=\\"", "STRING \\", is_visible=False\\"", @@ -3812,7 +3812,7 @@ Array [ "NAME \\"pos\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"r\\"", "OP \\"+=\\"", "STRING \\", pos=%s\\"", @@ -3847,7 +3847,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"A memory value used in scripts.\\\\n\\\\n There are both :attr:\`global variables \` and\\\\n :attr:\`sprite-specific variables \`.\\\\n\\\\n Some formats also have :attr:\`stage-specific variables \`.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -3866,7 +3866,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"value\\"", @@ -3905,7 +3905,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return a new instance with the same attributes.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"return\\"", @@ -3931,7 +3931,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"r\\"", "OP \\"=\\"", "STRING \\"%s.%s(%r\\"", @@ -3961,7 +3961,7 @@ Array [ "NAME \\"is_cloud\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"r\\"", "OP \\"+=\\"", "STRING \\", is_cloud=%r\\"", @@ -3989,7 +3989,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"A sequence of items used in scripts.\\\\n\\\\n Each item takes a :class:\`Variable\`-like value.\\\\n\\\\n Lists cannot be nested. However, for some formats, variables can take\\\\n list values, and this class is not used.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"def\\"", @@ -4007,7 +4007,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"items\\"", @@ -4061,7 +4061,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"items\\"", @@ -4084,7 +4084,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return a new instance with the same attributes.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"return\\"", @@ -4110,7 +4110,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"r\\"", "OP \\"=\\"", "STRING \\"<%s.%s(%i items)>\\"", @@ -4143,7 +4143,7 @@ Array [ "NAME \\"is_cloud\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"r\\"", "OP \\"+=\\"", "STRING \\", is_cloud=%r\\"", @@ -4175,7 +4175,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"A 24-bit RGB color value.\\\\n\\\\n Accepts tuple or hexcode arguments::\\\\n\\\\n >>> kurt.Color('#f08')\\\\n kurt.Color(255, 0, 136)\\\\n\\\\n >>> kurt.Color((255, 0, 136))\\\\n kurt.Color(255, 0, 136)\\\\n\\\\n >>> kurt.Color('#f0ffee')\\\\n kurt.Color(240, 255, 238)\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -4196,7 +4196,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"g\\"", "NAME \\"is\\"", @@ -4207,7 +4207,7 @@ Array [ "NAME \\"None\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"isinstance\\"", "OP \\"(\\"", @@ -4217,7 +4217,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"r\\"", "OP \\"=\\"", "NAME \\"r\\"", @@ -4234,7 +4234,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"not\\"", "NAME \\"r\\"", @@ -4245,7 +4245,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"raise\\"", "NAME \\"ValueError\\"", "OP \\",\\"", @@ -4271,7 +4271,7 @@ Array [ "NUMBER \\"3\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"r\\"", "OP \\"=\\"", "NAME \\"r\\"", @@ -4405,7 +4405,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return \`\`(r, g, b)\`\` tuple.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"return\\"", @@ -4439,7 +4439,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "OP \\"(\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -4467,7 +4467,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"isinstance\\"", "OP \\"(\\"", @@ -4495,7 +4495,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"not\\"", "NAME \\"self\\"", @@ -4511,7 +4511,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"iter\\"", "OP \\"(\\"", @@ -4529,7 +4529,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "STRING \\"%s.%s(%s)\\"", "OP \\"%\\"", @@ -4569,7 +4569,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Returns the color value in hexcode format.\\\\n\\\\n eg. \`\`'#ff1056'\`\`\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"hexcode\\"", @@ -4584,7 +4584,7 @@ Array [ "NAME \\"value\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"part\\"", "OP \\"=\\"", "NAME \\"hex\\"", @@ -4630,7 +4630,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"f\\"", "OP \\"=\\"", "NAME \\"lambda\\"", @@ -4675,7 +4675,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"The specification for an argument to a :class:\`BlockType\`.\\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -5207,7 +5207,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"shape\\"", @@ -5252,7 +5252,7 @@ Array [ "NAME \\"None\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"unevaluated\\"", "OP \\"=\\"", "NAME \\"True\\"", @@ -5290,7 +5290,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"r\\"", "OP \\"=\\"", "STRING \\"%s.%s(%r\\"", @@ -5322,7 +5322,7 @@ Array [ "NAME \\"None\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"r\\"", "OP \\"+=\\"", "STRING \\", %r\\"", @@ -5351,7 +5351,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"r\\"", "OP \\"+=\\"", "STRING \\", default=%r\\"", @@ -5367,7 +5367,7 @@ Array [ "NAME \\"unevaluated\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"r\\"", "OP \\"+=\\"", "STRING \\", unevaluated=%r\\"", @@ -5383,7 +5383,7 @@ Array [ "NAME \\"name\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"r\\"", "OP \\"+=\\"", "STRING \\", name=%r\\"", @@ -5411,7 +5411,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"isinstance\\"", "OP \\"(\\"", @@ -5421,7 +5421,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"for\\"", "NAME \\"name\\"", "NAME \\"in\\"", @@ -5436,7 +5436,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"getattr\\"", "OP \\"(\\"", @@ -5453,7 +5453,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"False\\"", "NEWLINE \\"\\\\n\\"", @@ -5462,7 +5462,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"True\\"", "NEWLINE \\"\\\\n\\"", @@ -5479,7 +5479,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"not\\"", "NAME \\"self\\"", @@ -5495,7 +5495,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"Insert\\"", "OP \\"(\\"", @@ -5538,7 +5538,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"value\\"", "NAME \\"is\\"", @@ -5557,7 +5557,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"value\\"", "OP \\"=\\"", "NAME \\"self\\"", @@ -5570,7 +5570,7 @@ Array [ "NAME \\"None\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"value\\"", "OP \\"=\\"", "STRING \\"\\\\\\"\\\\\\"\\"", @@ -5586,8 +5586,8 @@ Array [ "OP \\")\\"", "OP \\":\\"", "COMMENT \\"# use block's shape\\"", - "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "NL \\"\\\\n\\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"value\\"", "OP \\".\\"", @@ -5604,7 +5604,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"hasattr\\"", "OP \\"(\\"", @@ -5614,7 +5614,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"value\\"", "OP \\"=\\"", "NAME \\"value\\"", @@ -5633,7 +5633,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"value\\"", "OP \\"=\\"", "STRING \\"\\\\\\\\n\\"", @@ -5662,7 +5662,7 @@ Array [ "STRING \\"stack\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"value\\"", "OP \\"=\\"", "NAME \\"value\\"", @@ -5686,7 +5686,7 @@ Array [ "STRING \\"stack\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"value\\"", "OP \\"=\\"", "NAME \\"Insert\\"", @@ -5722,7 +5722,7 @@ Array [ "STRING \\"broadcast\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"value\\"", "OP \\"=\\"", "NAME \\"unicode\\"", @@ -5736,7 +5736,7 @@ Array [ "NAME \\"value\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"value\\"", "OP \\"=\\"", "STRING \\"\\\\\\"%s\\\\\\"\\"", @@ -5754,7 +5754,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"value\\"", "OP \\"=\\"", "STRING \\"'%s'\\"", @@ -5787,7 +5787,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return a list of valid options to a menu insert, given a\\\\n Scriptable for context.\\\\n\\\\n Mostly complete, excepting 'attribute'.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"options\\"", @@ -5813,7 +5813,7 @@ Array [ "NAME \\"scriptable\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -5822,7 +5822,7 @@ Array [ "STRING \\"var\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"options\\"", "OP \\"+=\\"", "NAME \\"scriptable\\"", @@ -5854,7 +5854,7 @@ Array [ "STRING \\"list\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"options\\"", "OP \\"+=\\"", "NAME \\"scriptable\\"", @@ -5886,7 +5886,7 @@ Array [ "STRING \\"costume\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"options\\"", "OP \\"+=\\"", "OP \\"[\\"", @@ -5910,7 +5910,7 @@ Array [ "STRING \\"backdrop\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"options\\"", "OP \\"+=\\"", "OP \\"[\\"", @@ -5938,7 +5938,7 @@ Array [ "STRING \\"sound\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"options\\"", "OP \\"+=\\"", "OP \\"[\\"", @@ -5989,7 +5989,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"options\\"", "OP \\"+=\\"", "OP \\"[\\"", @@ -6015,10 +6015,10 @@ Array [ "STRING \\"attribute\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"pass\\"", "COMMENT \\"# TODO\\"", - "NEWLINE \\"\\\\n\\"", + "NL \\"\\\\n\\"", "DEDENT \\"\\"", "NAME \\"elif\\"", "NAME \\"self\\"", @@ -6028,7 +6028,7 @@ Array [ "STRING \\"broadcast\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"options\\"", "OP \\"+=\\"", "NAME \\"list\\"", @@ -6061,7 +6061,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Base for :class:\`BlockType\` and :class:\`PluginBlockType\`.\\\\n\\\\n Defines common attributes.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -6093,7 +6093,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"shape\\"", @@ -6123,7 +6123,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"The text displayed on the block.\\\\n\\\\n String containing \`\`\\\\\\"%s\\\\\\"\`\` in place of inserts.\\\\n\\\\n eg. \`\`'say %s for %s secs'\`\`\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"parts\\"", @@ -6167,7 +6167,7 @@ Array [ "NAME \\"parts\\"", "OP \\"]\\"", "COMMENT \\"# escape percent\\"", - "NEWLINE \\"\\\\n\\"", + "NL \\"\\\\n\\"", "NAME \\"return\\"", "STRING \\"\\\\\\"\\\\\\"\\"", "OP \\".\\"", @@ -6188,7 +6188,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"The type of each argument to the block.\\\\n\\\\n List of :class:\`Insert\` instances.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"return\\"", @@ -6221,7 +6221,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Default values for block inserts. (See :attr:\`Block.args\`.)\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"return\\"", @@ -6249,7 +6249,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"The :attr:\`text\`, with spaces and inserts removed.\\\\n\\\\n Used by :class:\`BlockType.get\` to look up blocks.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"return\\"", @@ -6299,7 +6299,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Returns text with spaces and inserts removed.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"text\\"", @@ -6326,7 +6326,7 @@ Array [ "STRING \\"-%\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"new_text\\"", "OP \\"=\\"", "NAME \\"text\\"", @@ -6342,7 +6342,7 @@ Array [ "NAME \\"new_text\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"text\\"", "OP \\"=\\"", "NAME \\"new_text\\"", @@ -6365,7 +6365,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "STRING \\"<%s.%s(%r shape=%r)>\\"", "OP \\"%\\"", @@ -6431,7 +6431,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"args\\"", "NAME \\"is\\"", @@ -6489,7 +6489,7 @@ Array [ "NAME \\"inserts\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"insert\\"", "OP \\".\\"", @@ -6498,7 +6498,7 @@ Array [ "STRING \\"stack\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"r\\"", "OP \\"+\\"", @@ -6527,7 +6527,7 @@ Array [ "NAME \\"block_plugin\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"fmt\\"", "OP \\"=\\"", "STRING \\"%s\\"", @@ -6547,7 +6547,7 @@ Array [ "STRING \\"%s\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"fmt\\"", "OP \\"=\\"", "STRING \\"{%s}\\"", @@ -6570,7 +6570,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Returns True if any of the inserts have the given shape.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"for\\"", @@ -6581,7 +6581,7 @@ Array [ "NAME \\"inserts\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"insert\\"", "OP \\".\\"", @@ -6590,7 +6590,7 @@ Array [ "NAME \\"shape\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"True\\"", "NEWLINE \\"\\\\n\\"", @@ -6610,7 +6610,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"The specification for a type of :class:\`Block\`.\\\\n\\\\n These are initialiased by :class:\`Kurt\` by combining\\\\n :class:\`PluginBlockType\` objects from individual format plugins to\\\\n create a single :class:\`BlockType\` for each command.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -6621,7 +6621,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"lambda functions are not pickleable so drop them.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"copy\\"", @@ -6655,7 +6655,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"isinstance\\"", "OP \\"(\\"", @@ -6665,7 +6665,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"raise\\"", "NAME \\"ValueError\\"", "OP \\"(\\"", @@ -6713,7 +6713,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Add a new PluginBlockType conversion.\\\\n\\\\n If the plugin already exists, do nothing.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"assert\\"", @@ -6759,7 +6759,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"assert\\"", "NAME \\"i\\"", "OP \\".\\"", @@ -6797,7 +6797,7 @@ Array [ "NAME \\"_plugins\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"_plugins\\"", @@ -6821,14 +6821,14 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return a :class:\`PluginBlockType\` for the given plugin name.\\\\n\\\\n If plugin is \`\`None\`\`, return the first registered plugin.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"if\\"", "NAME \\"plugin\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"plugin\\"", "OP \\"=\\"", "NAME \\"kurt\\"", @@ -6852,7 +6852,7 @@ Array [ "NAME \\"_plugins\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -6867,7 +6867,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"err\\"", "OP \\"=\\"", "NAME \\"BlockNotSupported\\"", @@ -6898,7 +6898,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -6920,7 +6920,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return the list of :class:\`PluginBlockType\` instances.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"return\\"", @@ -6943,7 +6943,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return True if the plugin supports this block.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"plugin\\"", @@ -6979,7 +6979,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Returns True if any of the plugins have the given command.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"for\\"", @@ -6994,7 +6994,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"pbt\\"", "OP \\".\\"", @@ -7003,7 +7003,7 @@ Array [ "NAME \\"command\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"True\\"", "NEWLINE \\"\\\\n\\"", @@ -7024,7 +7024,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -7046,7 +7046,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -7070,7 +7070,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return a :class:\`BlockType\` instance from the given parameter.\\\\n\\\\n * If it's already a BlockType instance, return that.\\\\n\\\\n * If it exactly matches the command on a :class:\`PluginBlockType\`,\\\\n return the corresponding BlockType.\\\\n\\\\n * If it loosely matches the text on a PluginBlockType, return the\\\\n corresponding BlockType.\\\\n\\\\n * If it's a PluginBlockType instance, look for and return the\\\\n corresponding BlockType.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"if\\"", @@ -7086,7 +7086,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"block_type\\"", "NEWLINE \\"\\\\n\\"", @@ -7101,7 +7101,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"block_type\\"", "OP \\"=\\"", "NAME \\"block_type\\"", @@ -7127,7 +7127,7 @@ Array [ "NAME \\"block\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"block\\"", "NEWLINE \\"\\\\n\\"", @@ -7152,8 +7152,8 @@ Array [ "NAME \\"blocks\\"", "OP \\":\\"", "COMMENT \\"# check the blocks' commands map to unique blocks\\"", - "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "NL \\"\\\\n\\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"kurt\\"", "OP \\".\\"", @@ -7179,7 +7179,7 @@ Array [ "OP \\"]\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"raise\\"", "NAME \\"ValueError\\"", "OP \\"(\\"", @@ -7213,7 +7213,7 @@ Array [ "NAME \\"blocks\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"blocks\\"", "OP \\"[\\"", @@ -7241,7 +7241,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"isinstance\\"", "OP \\"(\\"", @@ -7251,7 +7251,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -7270,7 +7270,7 @@ Array [ "NAME \\"inserts\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"for\\"", "NAME \\"plugin\\"", "NAME \\"in\\"", @@ -7279,7 +7279,7 @@ Array [ "NAME \\"_plugins\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"plugin\\"", "NAME \\"in\\"", @@ -7288,7 +7288,7 @@ Array [ "NAME \\"_plugins\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -7322,7 +7322,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"not\\"", "NAME \\"self\\"", @@ -7340,7 +7340,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"_workaround\\"", @@ -7358,7 +7358,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Holds plugin-specific :class:\`BlockType\` attributes.\\\\n\\\\n For each block concept, :class:\`Kurt\` builds a single BlockType that\\\\n references a corresponding PluginBlockType for each plugin that\\\\n supports that block.\\\\n\\\\n Note that whichever plugin is loaded first takes precedence.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -7381,7 +7381,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"BaseBlockType\\"", "OP \\".\\"", "NAME \\"__init__\\"", @@ -7438,7 +7438,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -7477,7 +7477,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"isinstance\\"", "OP \\"(\\"", @@ -7487,7 +7487,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -7506,7 +7506,7 @@ Array [ "NAME \\"inserts\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"for\\"", "NAME \\"t\\"", "NAME \\"in\\"", @@ -7515,7 +7515,7 @@ Array [ "NAME \\"_plugins\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"t\\"", "NAME \\"in\\"", @@ -7524,7 +7524,7 @@ Array [ "NAME \\"_plugins\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"True\\"", "NEWLINE \\"\\\\n\\"", @@ -7541,7 +7541,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"for\\"", "NAME \\"name\\"", "NAME \\"in\\"", @@ -7558,7 +7558,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"getattr\\"", "OP \\"(\\"", @@ -7575,7 +7575,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"False\\"", "NEWLINE \\"\\\\n\\"", @@ -7584,7 +7584,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"True\\"", "NEWLINE \\"\\\\n\\"", @@ -7604,7 +7604,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"A user-specified :class:\`BlockType\`.\\\\n\\\\n The script defining the custom block starts with::\\\\n\\\\n kurt.Block(\\\\\\"procDef\\\\\\", )\\\\n\\\\n And the scripts definining the block follow.\\\\n\\\\n The same CustomBlockType instance can then be used in a block in another\\\\n script::\\\\n\\\\n kurt.Block(, [args ...,])\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -7619,7 +7619,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"BaseBlockType\\"", "OP \\".\\"", "NAME \\"__init__\\"", @@ -7655,7 +7655,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"A statement in a graphical programming language. Blocks can connect\\\\n together to form sequences of commands, which are stored in a\\\\n :class:\`Script\`. Blocks perform different commands depending on their\\\\n type.\\\\n\\\\n :param type: A :class:\`BlockType\` instance, used to identify the\\\\n command the block performs.\\\\n Will also exact match a :attr:\`command\` or loosely match\\\\n :attr:\`text\`.\\\\n\\\\n :param \`\`*args\`\`: List of the block's arguments. Arguments can be numbers,\\\\n strings, Blocks, or lists of Blocks (for 'stack' shaped\\\\n Inserts).\\\\n\\\\n The following constructors are all equivalent::\\\\n\\\\n >>> block = kurt.Block('say:duration:elapsed:from:', 'Hello!', 2)\\\\n >>> block = kurt.Block('say %s for %s secs', 'Hello!', 2)\\\\n >>> block = kurt.Block('sayforsecs', 'Hello!', 2)\\\\n\\\\n Using BlockType::\\\\n\\\\n >>> block.type\\\\n \\\\n >>> block.args\\\\n ['Hello!', 2]\\\\n >>> block2 = kurt.Block(block.type, 'Goodbye!', 5)\\\\n >>> block.stringify()\\\\n 'say [Hello!] for (2) secs'\\\\n >>> block2.stringify()\\\\n 'say [Goodbye!] for (5) secs'\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -7671,7 +7671,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"type\\"", @@ -7711,7 +7711,7 @@ Array [ "NAME \\"type\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"args\\"", @@ -7739,7 +7739,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"i\\"", "OP \\"<\\"", @@ -7751,7 +7751,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"args\\"", @@ -7768,7 +7768,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"args\\"", @@ -7799,7 +7799,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"type\\"", @@ -7837,7 +7837,7 @@ Array [ "NAME \\"args\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"insert\\"", "OP \\"=\\"", "NAME \\"inserts\\"", @@ -7865,7 +7865,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"isinstance\\"", "OP \\"(\\"", @@ -7875,11 +7875,11 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"try\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"arg\\"", "OP \\"=\\"", "NAME \\"float\\"", @@ -7908,7 +7908,7 @@ Array [ "NAME \\"ValueError\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"pass\\"", "NEWLINE \\"\\\\n\\"", "DEDENT \\"\\"", @@ -7948,7 +7948,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return a new Block instance with the same attributes.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"args\\"", @@ -7964,7 +7964,7 @@ Array [ "NAME \\"args\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"isinstance\\"", "OP \\"(\\"", @@ -7974,7 +7974,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"arg\\"", "OP \\"=\\"", "NAME \\"arg\\"", @@ -7993,7 +7993,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"arg\\"", "OP \\"=\\"", "OP \\"[\\"", @@ -8039,7 +8039,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "OP \\"(\\"", "NL \\"\\\\n\\"", @@ -8081,7 +8081,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"not\\"", "NAME \\"self\\"", @@ -8097,7 +8097,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"string\\"", "OP \\"=\\"", "STRING \\"%s.%s(%s, \\"", @@ -8153,7 +8153,7 @@ Array [ "NAME \\"args\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"isinstance\\"", "OP \\"(\\"", @@ -8163,7 +8163,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"string\\"", "OP \\"=\\"", "NAME \\"string\\"", @@ -8199,7 +8199,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"string\\"", "OP \\".\\"", @@ -8209,7 +8209,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"string\\"", "OP \\"+=\\"", "STRING \\" \\"", @@ -8218,7 +8218,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"string\\"", "OP \\"+=\\"", "STRING \\" \\"", @@ -8234,7 +8234,7 @@ Array [ "NAME \\"arg\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"string\\"", "OP \\"+=\\"", "STRING \\" \\"", @@ -8266,7 +8266,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"string\\"", "OP \\"+=\\"", "NAME \\"repr\\"", @@ -8314,7 +8314,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"s\\"", "OP \\"=\\"", "NAME \\"self\\"", @@ -8338,7 +8338,7 @@ Array [ "NAME \\"comment\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"i\\"", "OP \\"=\\"", "NAME \\"s\\"", @@ -8413,7 +8413,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"A single sequence of blocks. Each :class:\`Scriptable\` can have many\\\\n Scripts.\\\\n\\\\n The first block, \`\`self.blocks[0]\`\` is usually a \\\\\\"when\\\\\\" block, eg. an\\\\n EventHatMorph.\\\\n\\\\n Scripts implement the \`\`list\`\` interface, so can be indexed directly, eg.\\\\n \`\`script[0]\`\`. All other methods like \`\`append\`\` also work.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -8432,7 +8432,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"blocks\\"", @@ -8480,7 +8480,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"pos\\"", @@ -8508,7 +8508,7 @@ Array [ "NAME \\"blocks\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"block\\"", "OP \\".\\"", "NAME \\"_normalize\\"", @@ -8525,7 +8525,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return a new instance with the same attributes.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"return\\"", @@ -8573,7 +8573,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "OP \\"(\\"", "NL \\"\\\\n\\"", @@ -8606,7 +8606,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"not\\"", "NAME \\"self\\"", @@ -8622,7 +8622,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"r\\"", "OP \\"=\\"", "STRING \\"%s.%s([\\\\\\\\n\\"", @@ -8650,7 +8650,7 @@ Array [ "NAME \\"blocks\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"r\\"", "OP \\"+=\\"", "STRING \\" \\"", @@ -8691,7 +8691,7 @@ Array [ "NAME \\"pos\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"r\\"", "OP \\"+=\\"", "STRING \\", pos=%r\\"", @@ -8722,7 +8722,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "STRING \\"\\\\\\\\n\\"", "OP \\".\\"", @@ -8757,7 +8757,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"name\\"", "OP \\".\\"", @@ -8774,7 +8774,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"super\\"", "OP \\"(\\"", @@ -8808,7 +8808,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"iter\\"", "OP \\"(\\"", @@ -8826,7 +8826,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"len\\"", "OP \\"(\\"", @@ -8846,7 +8846,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -8868,7 +8868,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"blocks\\"", @@ -8889,7 +8889,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"del\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -8909,7 +8909,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"A free-floating comment in :attr:\`Scriptable.scripts\`.\\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -8926,7 +8926,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"text\\"", @@ -8963,7 +8963,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -8996,7 +8996,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"r\\"", "OP \\"=\\"", "STRING \\"%s.%s(%r\\"", @@ -9026,7 +9026,7 @@ Array [ "NAME \\"pos\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"r\\"", "OP \\"+=\\"", "STRING \\", pos=%r\\"", @@ -9053,7 +9053,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "STRING \\"// \\"", "OP \\"+\\"", @@ -9077,7 +9077,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"pos\\"", @@ -9112,7 +9112,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Describes the look of a sprite.\\\\n\\\\n The raw image data is stored in :attr:\`image\`.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -9131,7 +9131,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"name\\"", @@ -9149,7 +9149,7 @@ Array [ "NAME \\"rotation_center\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"rotation_center\\"", "OP \\"=\\"", "OP \\"(\\"", @@ -9202,7 +9202,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return a new instance with the same attributes.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"return\\"", @@ -9235,7 +9235,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Load costume from image file.\\\\n\\\\n Uses :attr:\`Image.load\`, but will set the Costume's name based on the\\\\n image filename.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "OP \\"(\\"", @@ -9292,7 +9292,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Save the costume to an image file at the given path.\\\\n\\\\n Uses :attr:\`Image.save\`, but if the path ends in a folder instead of a\\\\n file, the filename is based on the costume's :attr:\`name\`.\\\\n\\\\n The image format is guessed from the extension. If path has no\\\\n extension, the image's :attr:\`format\` is used.\\\\n\\\\n :returns: Path to the saved file.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "OP \\"(\\"", @@ -9315,7 +9315,7 @@ Array [ "NAME \\"filename\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"filename\\"", "OP \\"=\\"", "NAME \\"_clean_filename\\"", @@ -9360,7 +9360,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Resize :attr:\`image\` in-place.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"self\\"", @@ -9385,7 +9385,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "STRING \\"<%s.%s name=%r rotation_center=%d,%d at 0x%X>\\"", "OP \\"%\\"", @@ -9440,7 +9440,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"name\\"", "NAME \\"in\\"", @@ -9453,7 +9453,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"getattr\\"", "OP \\"(\\"", @@ -9489,7 +9489,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"The contents of an image file.\\\\n\\\\n Constructing from raw file contents::\\\\n\\\\n Image(file_contents, \\\\\\"JPEG\\\\\\")\\\\n\\\\n Constructing from a :class:\`PIL.Image.Image\` instance::\\\\n\\\\n pil_image = PIL.Image.new(\\\\\\"RGBA\\\\\\", (480, 360))\\\\n Image(pil_image)\\\\n\\\\n Loading from file path::\\\\n\\\\n Image.load(\\\\\\"path/to/image.jpg\\\\\\")\\\\n\\\\n Images are immutable. If you want to modify an image, get a\\\\n :class:\`PIL.Image.Image\` instance from :attr:\`pil_image\`, modify that, and\\\\n use it to construct a new Image. Modifying images in-place may break\\\\n things.\\\\n\\\\n The reason for having multiple constructors is so that kurt can implement\\\\n lazy loading of image data -- in many cases, a PIL image will never need to\\\\n be created.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -9506,7 +9506,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"_path\\"", @@ -9550,7 +9550,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"_pil_image\\"", @@ -9561,7 +9561,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"_contents\\"", @@ -9589,7 +9589,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"isinstance\\"", "OP \\"(\\"", @@ -9605,7 +9605,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"copy\\"", "OP \\"=\\"", "NAME \\"self\\"", @@ -9672,7 +9672,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"__dict__\\"", @@ -9688,7 +9688,7 @@ Array [ "NAME \\"_pil_image\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"_pil_image\\"", @@ -9721,7 +9721,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"A :class:\`PIL.Image.Image\` instance containing the image data.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"if\\"", @@ -9731,7 +9731,7 @@ Array [ "NAME \\"_pil_image\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -9740,7 +9740,7 @@ Array [ "STRING \\"SVG\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"raise\\"", "NAME \\"VectorImageError\\"", "OP \\"(\\"", @@ -9784,7 +9784,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"The raw file contents as a string.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"if\\"", @@ -9794,7 +9794,7 @@ Array [ "NAME \\"_contents\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -9803,7 +9803,7 @@ Array [ "NEWLINE \\"\\\\n\\"", "COMMENT \\"# Read file into memory so we don't run out of file descriptors\\"", "NL \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"f\\"", "OP \\"=\\"", "NAME \\"open\\"", @@ -9840,7 +9840,7 @@ Array [ "NEWLINE \\"\\\\n\\"", "COMMENT \\"# Write PIL image to string\\"", "NL \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"f\\"", "OP \\"=\\"", "NAME \\"StringIO\\"", @@ -9889,7 +9889,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"The format of the image file.\\\\n\\\\n An uppercase string corresponding to the\\\\n :attr:\`PIL.ImageFile.ImageFile.format\` attribute. Valid values include\\\\n \`\`\\\\\\"JPEG\\\\\\"\`\` and \`\`\\\\\\"PNG\\\\\\"\`\`.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"if\\"", @@ -9898,7 +9898,7 @@ Array [ "NAME \\"_format\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -9911,7 +9911,7 @@ Array [ "NAME \\"pil_image\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -9932,7 +9932,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"The extension of the image's :attr:\`format\` when written to file.\\\\n\\\\n eg \`\`\\\\\\".png\\\\\\"\`\`\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"return\\"", @@ -9957,7 +9957,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"\`\`(width, height)\`\` in pixels.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"if\\"", @@ -9971,7 +9971,7 @@ Array [ "NAME \\"_pil_image\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -9981,7 +9981,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -10002,7 +10002,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -10023,7 +10023,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -10049,7 +10049,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Load image from file.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"assert\\"", @@ -10138,7 +10138,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return an Image instance with the first matching format.\\\\n\\\\n For each format in \`\`*args\`\`: If the image's :attr:\`format\` attribute\\\\n is the same as the format, return self, otherwise try the next format.\\\\n\\\\n If none of the formats match, return a new Image instance with the\\\\n last format.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"for\\"", @@ -10147,7 +10147,7 @@ Array [ "NAME \\"formats\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"format\\"", "OP \\"=\\"", "NAME \\"Image\\"", @@ -10165,7 +10165,7 @@ Array [ "NAME \\"format\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "NEWLINE \\"\\\\n\\"", @@ -10174,7 +10174,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -10195,7 +10195,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return a new Image instance with the given format.\\\\n\\\\n Returns self if the format is already the same.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"if\\"", @@ -10206,7 +10206,7 @@ Array [ "NAME \\"format\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "NEWLINE \\"\\\\n\\"", @@ -10214,7 +10214,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"image\\"", "OP \\"=\\"", "NAME \\"Image\\"", @@ -10245,7 +10245,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Save image to file path.\\\\n\\\\n The image format is guessed from the extension. If path has no\\\\n extension, the image's :attr:\`format\` is used.\\\\n\\\\n :returns: Path to the saved file.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "OP \\"(\\"", @@ -10284,7 +10284,7 @@ Array [ "NAME \\"name\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"raise\\"", "NAME \\"ValueError\\"", "OP \\",\\"", @@ -10296,7 +10296,7 @@ Array [ "NAME \\"extension\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"format\\"", "OP \\"=\\"", "NAME \\"Image\\"", @@ -10310,7 +10310,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"format\\"", "OP \\"=\\"", "NAME \\"self\\"", @@ -10355,7 +10355,7 @@ Array [ "NAME \\"_contents\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"f\\"", "OP \\"=\\"", "NAME \\"open\\"", @@ -10384,7 +10384,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"image\\"", "OP \\".\\"", "NAME \\"pil_image\\"", @@ -10417,7 +10417,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return a new Image instance filled with a color.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"return\\"", @@ -10448,7 +10448,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return a new Image instance with the given size.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"return\\"", @@ -10481,7 +10481,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return a new Image with the given image pasted on top.\\\\n\\\\n This image will show through transparent areas of the given image.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NAME \\"r\\"", @@ -10546,12 +10546,12 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"format_or_extension\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"format\\"", "OP \\"=\\"", "NAME \\"format_or_extension\\"", @@ -10571,7 +10571,7 @@ Array [ "STRING \\"JPG\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"format\\"", "OP \\"=\\"", "STRING \\"JPEG\\"", @@ -10593,12 +10593,12 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"format_or_extension\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"extension\\"", "OP \\"=\\"", "NAME \\"format_or_extension\\"", @@ -10618,7 +10618,7 @@ Array [ "STRING \\"jpeg\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"extension\\"", "OP \\"=\\"", "STRING \\"jpg\\"", @@ -10645,7 +10645,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"A sound a :class:\`Scriptable\` can play.\\\\n\\\\n The raw sound data is stored in :attr:\`waveform\`.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -10660,7 +10660,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"name\\"", @@ -10687,7 +10687,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return a new instance with the same attributes.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"return\\"", @@ -10716,7 +10716,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Load sound from wave file.\\\\n\\\\n Uses :attr:\`Waveform.load\`, but will set the Waveform's name based on\\\\n the sound filename.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "OP \\"(\\"", @@ -10773,7 +10773,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Save the sound to a wave file at the given path.\\\\n\\\\n Uses :attr:\`Waveform.save\`, but if the path ends in a folder instead of\\\\n a file, the filename is based on the project's :attr:\`name\`.\\\\n\\\\n :returns: Path to the saved file.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "OP \\"(\\"", @@ -10796,7 +10796,7 @@ Array [ "NAME \\"filename\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"filename\\"", "OP \\"=\\"", "NAME \\"_clean_filename\\"", @@ -10839,7 +10839,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "STRING \\"<%s.%s name=%r at 0x%X>\\"", "OP \\"%\\"", @@ -10878,7 +10878,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"The contents of a wave file. Only WAV format files are supported.\\\\n\\\\n Constructing from raw file contents::\\\\n\\\\n Sound(file_contents)\\\\n\\\\n Loading from file path::\\\\n\\\\n Sound.load(\\\\\\"path/to/sound.wav\\\\\\")\\\\n\\\\n Waveforms are immutable.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "NL \\"\\\\n\\"", @@ -10904,7 +10904,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"self\\"", "OP \\".\\"", "NAME \\"_path\\"", @@ -10945,7 +10945,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"The raw file contents as a string.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"if\\"", @@ -10955,7 +10955,7 @@ Array [ "NAME \\"_contents\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"if\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -10964,7 +10964,7 @@ Array [ "NEWLINE \\"\\\\n\\"", "COMMENT \\"# Read file into memory so we don't run out of file descriptors\\"", "NL \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"f\\"", "OP \\"=\\"", "NAME \\"open\\"", @@ -11011,13 +11011,13 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Return a wave.Wave_read instance from the \`\`wave\`\` module.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"try\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"wave\\"", "OP \\".\\"", @@ -11040,7 +11040,7 @@ Array [ "NAME \\"err\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"err\\"", "OP \\".\\"", "NAME \\"message\\"", @@ -11075,7 +11075,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"The sampling rate of the sound.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"if\\"", @@ -11084,7 +11084,7 @@ Array [ "NAME \\"_rate\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -11094,7 +11094,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -11117,7 +11117,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"The number of samples in the sound.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"if\\"", @@ -11126,7 +11126,7 @@ Array [ "NAME \\"_sample_count\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -11136,7 +11136,7 @@ Array [ "NAME \\"else\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"return\\"", "NAME \\"self\\"", "OP \\".\\"", @@ -11165,7 +11165,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Load Waveform from file.\\"", "NEWLINE \\"\\\\n\\"", "NAME \\"assert\\"", @@ -11241,7 +11241,7 @@ Array [ "OP \\")\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "STRING \\"Save waveform to file path as a WAV file.\\\\n\\\\n :returns: Path to the saved file.\\\\n\\\\n \\"", "NEWLINE \\"\\\\n\\"", "OP \\"(\\"", @@ -11280,7 +11280,7 @@ Array [ "NAME \\"name\\"", "OP \\":\\"", "NEWLINE \\"\\\\n\\"", - "INDENT \\" \\"", + "INDENT \\"\\"", "NAME \\"raise\\"", "NAME \\"ValueError\\"", "OP \\",\\"", diff --git a/test/python.js b/test/python.js index f657826..aea6c1f 100644 --- a/test/python.js +++ b/test/python.js @@ -1,4 +1,6 @@ -var moo = require('../moo') + +const moo = require('../moo') +const indented = require('../indent') function assert(x) { @@ -17,7 +19,6 @@ function err(name, message) { var opPat = [ // operators - '(',')', '[', ']', '{', '}', ',',':', '.', ';', '@', '->', '+=','-=', '*=', '/=', '//=', '%=', '@=', '&=','|=', '^=', '>>=', '<<=', '**=', @@ -32,13 +33,17 @@ var opPat = [ '=', ]; -var pythonLexer = moo.compile({ +var rules = { Whitespace: /[ ]+/, // TODO tabs NAME: /[A-Za-z_][A-Za-z0-9_]*/, - OP: opPat, + OP: [ + {match: ['(', '[', '{'], push: 'paren'}, + {match: [')', ']', '}'], pop: 1}, + opPat, + ], COMMENT: /#.*/, - NEWLINE: { match: /\r|\r\n|\n/, lineBreaks: true }, - Continuation: /\\/, + // TODO "unexpected character after line continuation character" + Continuation: {match: /\\(?:\r|\r\n|\n)/, lineBreaks: true}, // Continuation ERRORTOKEN: {match: /[\$?`]/, error: true}, // TODO literals: str, long, float, imaginary NUMBER: [ @@ -52,113 +57,68 @@ var pythonLexer = moo.compile({ {match: /"(?:\\["\\rn]|[^"\\\n])*?"/, value: x => x.slice(1, -1)}, {match: /'(?:\\['\\rn]|[^'\\\n])*?'/, value: x => x.slice(1, -1)}, ], +} + +var base = moo.states({ + start: Object.assign({}, rules, { + NEWLINE: {match: /\r|\r\n|\n/, lineBreaks: true}, + }), + paren: Object.assign({}, rules, { + NL: {match: /\r|\r\n|\n/, lineBreaks: true}, + }), +}) + +var pythonLexer = indented(base, { + whitespace: 'Whitespace', + newline: 'NEWLINE', + indent: 'INDENT', + dedent: 'DEDENT', + comment: 'COMMENT', + // TODO: Continuations shouldn't emit INDENT }) var tokenize = function(input, emit) { var lexer = pythonLexer.reset(input); - var lex = function() { return lexer.next(); } - var tok = lex(); - var last; - var peeked; - function next() { - if (peeked) { - peeked = null; - return peeked; - } - last = tok; - tok = lex(); - } - function peek() { - return peeked = lex(); - // return peeked ? peeked : peeked = lex(); - } - - var stack = []; - var currentIndent = 0; - - while (tok) { - var indent = 0; - var indentation = ''; - if (tok.type === 'Whitespace' && (!last || last.type === 'NEWLINE' || last.type === 'NL')) { - indentation = tok.value; - indent = indentation.length; - next(); - } - if (tok.type === 'COMMENT') { - // TODO encoding declarations - emit(tok); - next(); - // assert tok.type === 'NEWLINE' ? - } - if (tok.type === 'NEWLINE') { - tok.type = 'NL'; - emit(tok); - next(); - continue; - } - - var parenlev = 0; - var isLine = true; - while (tok && isLine) { - switch (tok.type) { - case 'Whitespace': - next(); - continue; - case 'Continuation': - next(); - if (tok.type === 'NEWLINE') { - next(); - } - continue; - case 'NEWLINE': - if (parenlev) { - // implicit line continuation - tok.type = 'NL'; - } else { - isLine = false; - } - emit(tok); - next(); - break; - case 'OP': - if (/[([{]/.test(tok.value[0])) { - parenlev++; - } else if (/[)\]}]/.test(tok.value[0])) { - parenlev = Math.max(0, parenlev - 1); - } - // fall-thru - default: - if (indent !== null) { - // emit INDENT or DEDENT - if (indent > currentIndent) { - stack.push(currentIndent); - currentIndent = indent; - emit({ type: 'INDENT', value: indentation }); - } else { - while (indent < currentIndent) { - currentIndent = stack.pop(); - emit({ type: 'DEDENT', value: '' }); - } - if (indent > currentIndent) { - throw err('IndentationError', "unindent does not match any outer indentation level"); - } - } - indent = null; - } - emit(tok); - next(); - } + var parens = 0 + var isLine = false + var tok + while (tok = lexer.next()) { + + switch (tok.type) { + case 'COMMENT': + emit(tok) + tok = lexer.next() + if (tok.type === 'NEWLINE') tok.type = 'NL' + break + case 'Continuation': + continue + case 'NEWLINE': + if (parens) { + tok.type = 'NL' + } else if (isLine) { + tok.type = 'NEWLINE' + isLine = false + } else { + tok.type = 'NL' + } + break + case 'OP': + if (/[([{]/.test(tok.value[0])) { + parens++ + } else if (/[)\]}]/.test(tok.value[0])) { + parens = Math.max(0, parens - 1) + } + // FALL-THRU + default: + isLine = true } + emit(tok) } + emit({type: 'ENDMARKER', value: ''}) +} - while (currentIndent) { - currentIndent = stack.pop(); - emit({ type: 'DEDENT', value: '' }); - } - emit({ type: 'ENDMARKER', value: '' }); -}; function outputTokens(source) { var tokens = []; @@ -227,7 +187,7 @@ let pythonTokens = [ 'OP ")"', 'OP ":"', 'NEWLINE "\\n"', - 'INDENT " "', + 'INDENT ""', 'NAME "print"', 'OP "("', 'NAME "tok_name"', diff --git a/test/test.js b/test/test.js index 2271cff..0e3a444 100644 --- a/test/test.js +++ b/test/test.js @@ -705,7 +705,7 @@ describe('example: python', () => { test('triple-quoted strings', () => { let example = '"""abc""" 1+1 """def"""' expect(lexAll(pythonLexer.reset(example)).map(t => t.value)).toEqual( - ['abc', " ", "1", "+", "1", " ", 'def'] + ['abc', "1", "+", "1", 'def'] ) }) @@ -721,6 +721,11 @@ describe('example: python', () => { expect(tokens.pop()).not.toBe('ERRORTOKEN ""') }) + // TODO: continuations + // TODO: indent after comment + // TODO: always NL after COMMENT + // TODO: line numbers vs. strings + }) From d1c570ff190e5124d8dcb312d0280294f7f66756 Mon Sep 17 00:00:00 2001 From: tjvr Date: Mon, 24 Jul 2017 14:16:21 +0100 Subject: [PATCH 6/6] Python lexer uses states to keep track of parens --- test/python.js | 31 ++++++++----------------------- test/test.js | 1 + 2 files changed, 9 insertions(+), 23 deletions(-) diff --git a/test/python.js b/test/python.js index aea6c1f..3248f62 100644 --- a/test/python.js +++ b/test/python.js @@ -34,7 +34,7 @@ var opPat = [ ]; var rules = { - Whitespace: /[ ]+/, // TODO tabs + ws: /[ \t]+/, NAME: /[A-Za-z_][A-Za-z0-9_]*/, OP: [ {match: ['(', '[', '{'], push: 'paren'}, @@ -43,7 +43,7 @@ var rules = { ], COMMENT: /#.*/, // TODO "unexpected character after line continuation character" - Continuation: {match: /\\(?:\r|\r\n|\n)/, lineBreaks: true}, // Continuation + continuation: {match: /\\(?:\r|\r\n|\n)/, lineBreaks: true}, ERRORTOKEN: {match: /[\$?`]/, error: true}, // TODO literals: str, long, float, imaginary NUMBER: [ @@ -69,7 +69,7 @@ var base = moo.states({ }) var pythonLexer = indented(base, { - whitespace: 'Whitespace', + whitespace: 'ws', newline: 'NEWLINE', indent: 'INDENT', dedent: 'DEDENT', @@ -81,36 +81,21 @@ var pythonLexer = indented(base, { var tokenize = function(input, emit) { var lexer = pythonLexer.reset(input); - var parens = 0 var isLine = false var tok while (tok = lexer.next()) { - switch (tok.type) { + case 'NEWLINE': + if (!isLine) tok.type = 'NL' + isLine = false + break case 'COMMENT': emit(tok) tok = lexer.next() if (tok.type === 'NEWLINE') tok.type = 'NL' break - case 'Continuation': + case 'continuation': continue - case 'NEWLINE': - if (parens) { - tok.type = 'NL' - } else if (isLine) { - tok.type = 'NEWLINE' - isLine = false - } else { - tok.type = 'NL' - } - break - case 'OP': - if (/[([{]/.test(tok.value[0])) { - parens++ - } else if (/[)\]}]/.test(tok.value[0])) { - parens = Math.max(0, parens - 1) - } - // FALL-THRU default: isLine = true } diff --git a/test/test.js b/test/test.js index 0e3a444..d0a1a9c 100644 --- a/test/test.js +++ b/test/test.js @@ -725,6 +725,7 @@ describe('example: python', () => { // TODO: indent after comment // TODO: always NL after COMMENT // TODO: line numbers vs. strings + // TODO: NL inside parens })