Skip to content

Commit 1e94c03

Browse files
authored
[Event Highlighting]: White label minus, dot and colon chars in mini notation (#224)
* White label minus and dot chars in mini notation * Fix whitespaces * Remove whitespace * Add colon * Extract private constants
1 parent 1393e3a commit 1e94c03

File tree

3 files changed

+115
-102
lines changed

3 files changed

+115
-102
lines changed

lib/event-highlighter.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,8 @@ export default class EventHighlighter {
199199
#removeHighlight({ colStart, eventId }) {
200200

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

204-
if (!highlightEvents.size) return;
203+
if (!highlightEvents || !highlightEvents.size) return;
205204

206205
highlightEvents.forEach(textEditorIdEvent => {
207206
const marker = textEditorIdEvent.get(colStart);

lib/line-processor.js

Lines changed: 57 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,69 @@
11
'use babel'
22

33
export default class LineProcessor {
4+
// private static constants
5+
static #DIGIT_MIN = 48;
6+
static #DIGIT_MAX = 57;
7+
static #UPPERCASE_MIN = 65;
8+
static #UPPERCASE_MAX = 90;
9+
static #LOWERCASE_MIN = 97;
10+
static #LOWERCASE_MAX = 122;
11+
static #DOT = 46;
12+
static #MINUS = 45;
13+
static #COLON = 58;
14+
static #QUOTATION_MARK = 34;
415

5-
// Valid TidalCycles word chars
6-
static isValidTidalWordChar(character) {
7-
const code = character.charCodeAt(0);
8-
// 0-9
9-
const digitMin = 48;
10-
const digitMax = 57;
11-
// A-Z
12-
const upperCaseMin = 65;
13-
const upperCaseMax = 90;
14-
// a-z
15-
const lowerCaseMin = 97;
16-
const lowerCaseMax = 122;
16+
// Valid TidalCycles word chars
17+
static isValidTidalWordChar(character) {
18+
const code = character.charCodeAt(0);
1719

18-
return (
19-
(code >= digitMin && code <= digitMax) ||
20-
(code >= upperCaseMin && code <= upperCaseMax) ||
21-
(code >= lowerCaseMin && code <= lowerCaseMax)
22-
);
23-
}
24-
25-
static isQuotationMark(character) {
26-
const code = character.charCodeAt(0);
27-
// "
28-
const quotationMark = 34;
20+
return (
21+
(code >= LineProcessor.#DIGIT_MIN && code <= LineProcessor.#DIGIT_MAX) ||
22+
(code >= LineProcessor.#UPPERCASE_MIN && code <= LineProcessor.#UPPERCASE_MAX) ||
23+
(code >= LineProcessor.#LOWERCASE_MIN && code <= LineProcessor.#LOWERCASE_MAX) ||
24+
(code === LineProcessor.#DOT) ||
25+
(code === LineProcessor.#MINUS) ||
26+
(code === LineProcessor.#COLON)
27+
);
28+
}
2929

30-
return code === quotationMark;
31-
}
30+
static isQuotationMark(character) {
31+
return character.charCodeAt(0) === LineProcessor.#QUOTATION_MARK;
32+
}
3233

33-
static findTidalWordRanges(line, callback) {
34-
let insideQuotes = false;
35-
let start = null;
36-
let end = null;
34+
static findTidalWordRanges(line, callback) {
35+
let insideQuotes = false;
36+
let start = null;
37+
let end = null;
3738

38-
Array.from(line).forEach((char, index) => {
39-
if (LineProcessor.isQuotationMark(char)) {
40-
insideQuotes = !insideQuotes;
41-
}
39+
Array.from(line).forEach((char, index) => {
40+
if (LineProcessor.isQuotationMark(char)) {
41+
insideQuotes = !insideQuotes;
42+
}
4243

43-
if (insideQuotes && LineProcessor.isValidTidalWordChar(char)) {
44-
if (!start) {
45-
start = index;
46-
end = index;
47-
} else {
48-
end++;
49-
}
50-
} else {
51-
if (start && end) {
52-
callback({start, end});
53-
start = null;
54-
end = null;
55-
}
56-
}
57-
})
58-
}
44+
if (insideQuotes && LineProcessor.isValidTidalWordChar(char)) {
45+
if (start === null) {
46+
start = index;
47+
end = index;
48+
} else {
49+
end++;
50+
}
51+
} else {
52+
if (start !== null && end !== null) {
53+
callback({ start, end });
54+
start = null;
55+
end = null;
56+
}
57+
}
58+
});
59+
}
5960

60-
static controlPatternsRegex() {
61-
return new RegExp(/"([^"]*)"/g);
62-
}
61+
static controlPatternsRegex() {
62+
return /"([^"]*)"/g;
63+
}
6364

64-
static exceptedFunctionPatterns() {
65-
return new RegExp(/numerals\s*=.*$|p\s.*$/);
66-
}
65+
static exceptedFunctionPatterns() {
66+
return /numerals\s*=.*$|p\s.*$/;
67+
}
6768
}
69+

spec/line-processor-spec.js

Lines changed: 57 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,50 @@ const LineProcessor = require("../lib/line-processor");
33
describe('Line Processor', () => {
44

55
describe('isValidTidalWordChar', () => {
6-
it('should truthify a valid digit', () => {
7-
expect(LineProcessor.isValidTidalWordChar('5')).toBe(true);
8-
})
9-
it('should truthify a valid upper case char', () => {
10-
expect(LineProcessor.isValidTidalWordChar('M')).toBe(true);
11-
})
12-
13-
it('should truthify a valid lower case char', () => {
14-
expect(LineProcessor.isValidTidalWordChar('t')).toBe(true);
15-
})
16-
17-
it('should falsify an invalid char', () => {
18-
expect(LineProcessor.isValidTidalWordChar('*')).toBe(false);
19-
})
20-
})
6+
it('should truthify a valid digit', () => {
7+
expect(LineProcessor.isValidTidalWordChar('5')).toBe(true);
8+
})
9+
it('should truthify a valid upper case char', () => {
10+
expect(LineProcessor.isValidTidalWordChar('M')).toBe(true);
11+
})
12+
13+
it('should truthify a valid lower case char', () => {
14+
expect(LineProcessor.isValidTidalWordChar('t')).toBe(true);
15+
})
16+
17+
it('should falsify an invalid char', () => {
18+
expect(LineProcessor.isValidTidalWordChar('*')).toBe(false);
19+
})
20+
21+
it('should truthify a valid minus', () => {
22+
expect(LineProcessor.isValidTidalWordChar('-')).toBe(true);
23+
})
24+
25+
it('should truthify a valid dot', () => {
26+
expect(LineProcessor.isValidTidalWordChar('.')).toBe(true);
27+
})
28+
29+
it('should truthify a valid colon', () => {
30+
expect(LineProcessor.isValidTidalWordChar(':')).toBe(true);
31+
})
32+
})
2133

2234
describe('isQuotationMark', () => {
23-
it('should truthify quotation mark', () => {
24-
expect(LineProcessor.isQuotationMark('"')).toBe(true);
25-
})
35+
it('should truthify quotation mark', () => {
36+
expect(LineProcessor.isQuotationMark('"')).toBe(true);
37+
})
2638

27-
it('should falsify non quotation mark', () => {
28-
expect(LineProcessor.isQuotationMark('*')).toBe(false);
29-
})
30-
})
39+
it('should falsify non quotation mark', () => {
40+
expect(LineProcessor.isQuotationMark('*')).toBe(false);
41+
})
42+
})
3143

3244
describe('isQuotationMark', () => {
3345
it('should find the range for one ControlPattern and one word and execute the callback once', () => {
3446
const results = [];
3547
LineProcessor.findTidalWordRanges(
36-
`d1 $ s "superpiano" # note 0`,
37-
(result) => results.push(result));
48+
`d1 $ s "superpiano" # note 0`,
49+
(result) => results.push(result));
3850

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

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

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

7385
describe('controlPatternsRegex', () => {
7486
it ('should match all strings and their quotation marks in a line', () => {
75-
const testString = `d1 $ s "<superpiano 808>" # note "0"`;
76-
const expected = [`"<superpiano 808>"`, `"0"`];
77-
78-
expect(testString.match(LineProcessor.controlPatternsRegex())).toEqual(expected);
79-
})
87+
const testString = `d1 $ s "<superpiano 808>" # note "0"`;
88+
const expected = [`"<superpiano 808>"`, `"0"`];
89+
90+
expect(testString.match(LineProcessor.controlPatternsRegex())).toEqual(expected);
91+
})
8092
})
8193

8294
describe('exceptedFunctionPatterns', () => {
8395
it ('should match numerals function occurance in a line', () => {
84-
const testString = `numerals = "0 1 2 3"`;
85-
const expected = 'numerals = "0 1 2 3"';
86-
expect(testString.match(LineProcessor.exceptedFunctionPatterns())[0]).toEqual(expected);
87-
})
96+
const testString = `numerals = "0 1 2 3"`;
97+
const expected = 'numerals = "0 1 2 3"';
98+
expect(testString.match(LineProcessor.exceptedFunctionPatterns())[0]).toEqual(expected);
99+
})
88100

89101
it ('should match p function occurance in a line', () => {
90-
const testString = `p "hello" $ s "808"`;
91-
const expected = 'p "hello" $ s "808"';
92-
93-
expect(testString.match(LineProcessor.exceptedFunctionPatterns())[0]).toEqual(expected);
94-
})
102+
const testString = `p "hello" $ s "808"`;
103+
const expected = 'p "hello" $ s "808"';
104+
105+
expect(testString.match(LineProcessor.exceptedFunctionPatterns())[0]).toEqual(expected);
106+
})
95107

96108
it ('should not match an allowed control pattern in a line', () => {
97-
const testString = `d1 $ s "superpiano"`;
98-
expect(testString.match(LineProcessor.exceptedFunctionPatterns())).toBeNull()
99-
})
109+
const testString = `d1 $ s "superpiano"`;
110+
expect(testString.match(LineProcessor.exceptedFunctionPatterns())).toBeNull()
111+
})
100112
})
101113
})

0 commit comments

Comments
 (0)