Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
119 changes: 64 additions & 55 deletions lib/line-processor.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,66 +2,75 @@

export default class LineProcessor {

// 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);
// 0-9
const digitMin = 48;
const digitMax = 57;
// A-Z
const upperCaseMin = 65;
const upperCaseMax = 90;
// a-z
const lowerCaseMin = 97;
const lowerCaseMax = 122;
// .
const dot = 46;
// -
const minus = 45;
// :
const colon = 58;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these const could be kept at the class level, so it will keep the isValidTidalWordChar tidier

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes! what a pity that in js there's the need to prepone the class name on every constant call

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree!


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 >= digitMin && code <= digitMax) ||
(code >= upperCaseMin && code <= upperCaseMax) ||
(code >= lowerCaseMin && code <= lowerCaseMax) ||
(code == dot) ||
(code == minus) ||
(code == colon)
);
}

return code === quotationMark;
}
static isQuotationMark(character) {
const code = character.charCodeAt(0);
// "
const quotationMark = 34;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same


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

Array.from(line).forEach((char, index) => {
if (LineProcessor.isQuotationMark(char)) {
insideQuotes = !insideQuotes;
}
static findTidalWordRanges(line, callback) {
let insideQuotes = false;
let start = null;
let end = null;

if (insideQuotes && LineProcessor.isValidTidalWordChar(char)) {
if (!start) {
start = index;
end = index;
} else {
end++;
}
} else {
if (start && end) {
callback({start, end});
start = null;
end = null;
}
}
})
}
Array.from(line).forEach((char, index) => {
if (LineProcessor.isQuotationMark(char)) {
insideQuotes = !insideQuotes;
}

static controlPatternsRegex() {
return new RegExp(/"([^"]*)"/g);
}
if (insideQuotes && LineProcessor.isValidTidalWordChar(char)) {
if (!start) {
start = index;
end = index;
} else {
end++;
}
} else {
if (start && end) {
callback({start, end});
start = null;
end = null;
}
}
})
}

static exceptedFunctionPatterns() {
return new RegExp(/numerals\s*=.*$|p\s.*$/);
}
static controlPatternsRegex() {
return new RegExp(/"([^"]*)"/g);
}

static exceptedFunctionPatterns() {
return new RegExp(/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