Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions lib/event-highlighter.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,8 @@ export default class EventHighlighter {
#removeHighlight({ colStart, eventId }) {

const highlightEvents = this.highlights.get(eventId);
// console.log("removeHighlight", highlightEvents, eventId, colStart);

if (!highlightEvents.size) return;
if (!highlightEvents || !highlightEvents.size) return;

highlightEvents.forEach(textEditorIdEvent => {
const marker = textEditorIdEvent.get(colStart);
Expand Down
112 changes: 57 additions & 55 deletions lib/line-processor.js
Original file line number Diff line number Diff line change
@@ -1,67 +1,69 @@
'use babel'

export default class LineProcessor {
// private static constants
static #DIGIT_MIN = 48;
static #DIGIT_MAX = 57;
static #UPPERCASE_MIN = 65;
static #UPPERCASE_MAX = 90;
static #LOWERCASE_MIN = 97;
static #LOWERCASE_MAX = 122;
static #DOT = 46;
static #MINUS = 45;
static #COLON = 58;
static #QUOTATION_MARK = 34;

// Valid TidalCycles word chars
static isValidTidalWordChar(character) {
const code = character.charCodeAt(0);
// 0-9
const digitMin = 48;
const digitMax = 57;
// A-Z
const upperCaseMin = 65;
const upperCaseMax = 90;
// a-z
const lowerCaseMin = 97;
const lowerCaseMax = 122;
// Valid TidalCycles word chars
static isValidTidalWordChar(character) {
const code = character.charCodeAt(0);

return (
(code >= digitMin && code <= digitMax) ||
(code >= upperCaseMin && code <= upperCaseMax) ||
(code >= lowerCaseMin && code <= lowerCaseMax)
);
}

static isQuotationMark(character) {
const code = character.charCodeAt(0);
// "
const quotationMark = 34;
return (
(code >= LineProcessor.#DIGIT_MIN && code <= LineProcessor.#DIGIT_MAX) ||
(code >= LineProcessor.#UPPERCASE_MIN && code <= LineProcessor.#UPPERCASE_MAX) ||
(code >= LineProcessor.#LOWERCASE_MIN && code <= LineProcessor.#LOWERCASE_MAX) ||
(code === LineProcessor.#DOT) ||
(code === LineProcessor.#MINUS) ||
(code === LineProcessor.#COLON)
);
}

return code === quotationMark;
}
static isQuotationMark(character) {
return character.charCodeAt(0) === LineProcessor.#QUOTATION_MARK;
}

static findTidalWordRanges(line, callback) {
let insideQuotes = false;
let start = null;
let end = null;
static findTidalWordRanges(line, callback) {
let insideQuotes = false;
let start = null;
let end = null;

Array.from(line).forEach((char, index) => {
if (LineProcessor.isQuotationMark(char)) {
insideQuotes = !insideQuotes;
}
Array.from(line).forEach((char, index) => {
if (LineProcessor.isQuotationMark(char)) {
insideQuotes = !insideQuotes;
}

if (insideQuotes && LineProcessor.isValidTidalWordChar(char)) {
if (!start) {
start = index;
end = index;
} else {
end++;
}
} else {
if (start && end) {
callback({start, end});
start = null;
end = null;
}
}
})
}
if (insideQuotes && LineProcessor.isValidTidalWordChar(char)) {
if (start === null) {
start = index;
end = index;
} else {
end++;
}
} else {
if (start !== null && end !== null) {
callback({ start, end });
start = null;
end = null;
}
}
});
}

static controlPatternsRegex() {
return new RegExp(/"([^"]*)"/g);
}
static controlPatternsRegex() {
return /"([^"]*)"/g;
}

static exceptedFunctionPatterns() {
return new RegExp(/numerals\s*=.*$|p\s.*$/);
}
static exceptedFunctionPatterns() {
return /numerals\s*=.*$|p\s.*$/;
}
}

102 changes: 57 additions & 45 deletions spec/line-processor-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,50 @@ const LineProcessor = require("../lib/line-processor");
describe('Line Processor', () => {

describe('isValidTidalWordChar', () => {
it('should truthify a valid digit', () => {
expect(LineProcessor.isValidTidalWordChar('5')).toBe(true);
})
it('should truthify a valid upper case char', () => {
expect(LineProcessor.isValidTidalWordChar('M')).toBe(true);
})

it('should truthify a valid lower case char', () => {
expect(LineProcessor.isValidTidalWordChar('t')).toBe(true);
})

it('should falsify an invalid char', () => {
expect(LineProcessor.isValidTidalWordChar('*')).toBe(false);
})
})
it('should truthify a valid digit', () => {
expect(LineProcessor.isValidTidalWordChar('5')).toBe(true);
})
it('should truthify a valid upper case char', () => {
expect(LineProcessor.isValidTidalWordChar('M')).toBe(true);
})

it('should truthify a valid lower case char', () => {
expect(LineProcessor.isValidTidalWordChar('t')).toBe(true);
})

it('should falsify an invalid char', () => {
expect(LineProcessor.isValidTidalWordChar('*')).toBe(false);
})

it('should truthify a valid minus', () => {
expect(LineProcessor.isValidTidalWordChar('-')).toBe(true);
})

it('should truthify a valid dot', () => {
expect(LineProcessor.isValidTidalWordChar('.')).toBe(true);
})

it('should truthify a valid colon', () => {
expect(LineProcessor.isValidTidalWordChar(':')).toBe(true);
})
})

describe('isQuotationMark', () => {
it('should truthify quotation mark', () => {
expect(LineProcessor.isQuotationMark('"')).toBe(true);
})
it('should truthify quotation mark', () => {
expect(LineProcessor.isQuotationMark('"')).toBe(true);
})

it('should falsify non quotation mark', () => {
expect(LineProcessor.isQuotationMark('*')).toBe(false);
})
})
it('should falsify non quotation mark', () => {
expect(LineProcessor.isQuotationMark('*')).toBe(false);
})
})

describe('isQuotationMark', () => {
it('should find the range for one ControlPattern and one word and execute the callback once', () => {
const results = [];
LineProcessor.findTidalWordRanges(
`d1 $ s "superpiano" # note 0`,
(result) => results.push(result));
`d1 $ s "superpiano" # note 0`,
(result) => results.push(result));

expect(results.length).toEqual(1);
expect(results[0]).toEqual({ start: 8, end: 17});
Expand All @@ -43,8 +55,8 @@ describe('Line Processor', () => {
it('should find the range for two ControlPatterns and several words and execute the callback accorgingly', () => {
const results = [];
LineProcessor.findTidalWordRanges(
`d1 $ s "<superpiano 808>" # note "0"`,
(result) => results.push(result));
`d1 $ s "<superpiano 808>" # note "0"`,
(result) => results.push(result));

expect(results.length).toEqual(3);
expect(results[0]).toEqual({ start: 9, end: 18});
Expand All @@ -56,8 +68,8 @@ describe('Line Processor', () => {
it('should find the range for one relatively complex ControlPattern and several words and execute the callback accordingly', () => {
const results = [];
LineProcessor.findTidalWordRanges(
`d1 $ s "superpiano" # note "c'maj'4*<1 2 3>"`,
(result) => results.push(result));
`d1 $ s "superpiano" # note "c'maj'4*<1 2 3>"`,
(result) => results.push(result));

expect(results.length).toEqual(7);
expect(results[0]).toEqual({ start: 8, end: 17});
Expand All @@ -72,30 +84,30 @@ describe('Line Processor', () => {

describe('controlPatternsRegex', () => {
it ('should match all strings and their quotation marks in a line', () => {
const testString = `d1 $ s "<superpiano 808>" # note "0"`;
const expected = [`"<superpiano 808>"`, `"0"`];
expect(testString.match(LineProcessor.controlPatternsRegex())).toEqual(expected);
})
const testString = `d1 $ s "<superpiano 808>" # note "0"`;
const expected = [`"<superpiano 808>"`, `"0"`];
expect(testString.match(LineProcessor.controlPatternsRegex())).toEqual(expected);
})
})

describe('exceptedFunctionPatterns', () => {
it ('should match numerals function occurance in a line', () => {
const testString = `numerals = "0 1 2 3"`;
const expected = 'numerals = "0 1 2 3"';
expect(testString.match(LineProcessor.exceptedFunctionPatterns())[0]).toEqual(expected);
})
const testString = `numerals = "0 1 2 3"`;
const expected = 'numerals = "0 1 2 3"';
expect(testString.match(LineProcessor.exceptedFunctionPatterns())[0]).toEqual(expected);
})

it ('should match p function occurance in a line', () => {
const testString = `p "hello" $ s "808"`;
const expected = 'p "hello" $ s "808"';
expect(testString.match(LineProcessor.exceptedFunctionPatterns())[0]).toEqual(expected);
})
const testString = `p "hello" $ s "808"`;
const expected = 'p "hello" $ s "808"';

expect(testString.match(LineProcessor.exceptedFunctionPatterns())[0]).toEqual(expected);
})

it ('should not match an allowed control pattern in a line', () => {
const testString = `d1 $ s "superpiano"`;
expect(testString.match(LineProcessor.exceptedFunctionPatterns())).toBeNull()
})
const testString = `d1 $ s "superpiano"`;
expect(testString.match(LineProcessor.exceptedFunctionPatterns())).toBeNull()
})
})
})
Loading