mirror of
https://github.com/eliasstepanik/strudel.git
synced 2026-01-11 05:38:35 +00:00
metadata: add quotes syntax for titles
This commit is contained in:
parent
185318a70c
commit
51e8174689
@ -63,6 +63,51 @@ describe.concurrent('Metadata parser', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('loads a title tag with quotes syntax', async () => {
|
||||
const tune = `// "Awesome song"`;
|
||||
expect(getMetadata(tune)).toStrictEqual({
|
||||
title: 'Awesome song',
|
||||
});
|
||||
});
|
||||
|
||||
it('loads a title tag with quotes syntax among other tags', async () => {
|
||||
const tune = `// "Awesome song" made @by Sam`;
|
||||
expect(getMetadata(tune)).toStrictEqual({
|
||||
title: 'Awesome song',
|
||||
by: ['Sam'],
|
||||
});
|
||||
});
|
||||
|
||||
it('loads a title tag with quotes syntax from block comment', async () => {
|
||||
const tune = `/* "Awesome song"
|
||||
@by Sam */`;
|
||||
expect(getMetadata(tune)).toStrictEqual({
|
||||
title: 'Awesome song',
|
||||
by: ['Sam'],
|
||||
});
|
||||
});
|
||||
|
||||
it('does not load a title tag with quotes syntax after a prefix', async () => {
|
||||
const tune = `// I don't care about those "metadata".`;
|
||||
expect(getMetadata(tune)).toStrictEqual({});
|
||||
});
|
||||
|
||||
it('does not load a title tag with quotes syntax after an other comment', async () => {
|
||||
const tune = `// I don't care about those
|
||||
// "metadata"`;
|
||||
expect(getMetadata(tune)).toStrictEqual({});
|
||||
});
|
||||
|
||||
it('does not load a title tag with quotes syntax after other tags', async () => {
|
||||
const tune = `/*
|
||||
@by Sam aka "Lady Strudel"
|
||||
"Sandyyy"
|
||||
*/`;
|
||||
expect(getMetadata(tune)).toStrictEqual({
|
||||
by: ['Sam aka "Lady Strudel"', '"Sandyyy"'],
|
||||
});
|
||||
});
|
||||
|
||||
it('loads a tag list with comma-separated values syntax', async () => {
|
||||
const tune = `// @by Sam, Sandy`;
|
||||
expect(getMetadata(tune)).toStrictEqual({
|
||||
@ -159,15 +204,6 @@ describe.concurrent('Metadata parser', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('loads empty tags from block comment', async () => {
|
||||
const tune = `/* @title
|
||||
@by */`;
|
||||
expect(getMetadata(tune)).toStrictEqual({
|
||||
title: '',
|
||||
by: [],
|
||||
});
|
||||
});
|
||||
|
||||
it('loads tags with whitespaces from inline comments', async () => {
|
||||
const tune = ` // @title Awesome song
|
||||
// @by Sam Tagada `;
|
||||
@ -186,6 +222,20 @@ describe.concurrent('Metadata parser', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('loads empty tags from block comment', async () => {
|
||||
const tune = `/* @title
|
||||
@by */`;
|
||||
expect(getMetadata(tune)).toStrictEqual({
|
||||
title: '',
|
||||
by: [],
|
||||
});
|
||||
});
|
||||
|
||||
it('does not load tags if there is not', async () => {
|
||||
const tune = `note("a3 c#4 e4 a4")`;
|
||||
expect(getMetadata(tune)).toStrictEqual({});
|
||||
});
|
||||
|
||||
it('does not load code that looks like a metadata tag', async () => {
|
||||
const tune = `const str1 = '@title Awesome song'`;
|
||||
// need a lexer to avoid this one, but it's a pretty rare use case:
|
||||
|
||||
@ -67,7 +67,7 @@ It is a handy way to quickly turn code on and off.
|
||||
Try uncommenting this line by deleting `//` and refreshing the pattern.
|
||||
You can also use the keyboard shortcut `cmd-/` to toggle comments on and off.
|
||||
|
||||
You might noticed that some comments in the REPL samples include some words starting with a "@", like `@title` or `@license`.
|
||||
You might noticed that some comments in the REPL samples include some words starting with a "@", like `@by` or `@license`.
|
||||
Those are just a convention to define some information about the music. We will talk about it in the [Music metadata](/learn/metadata) section.
|
||||
|
||||
# Strings
|
||||
|
||||
@ -38,6 +38,12 @@ Or define multiple tags in one line:
|
||||
// @title Hey Hoo @by Sam Tagada @license CC BY-NC-SA
|
||||
```
|
||||
|
||||
The `title` tag has an alternative syntax using quotes (must be defined at the very begining):
|
||||
|
||||
```js
|
||||
// "Hey Hoo" @by Sam Tagada
|
||||
```
|
||||
|
||||
## Tags list
|
||||
|
||||
Available tags are:
|
||||
|
||||
@ -2,10 +2,16 @@ const ALLOW_MANY = ['by', 'url', 'genre', 'license'];
|
||||
|
||||
export function getMetadata(raw_code) {
|
||||
const comment_regexp = /\/\*([\s\S]*?)\*\/|\/\/(.*)$/gm;
|
||||
const comments = [...raw_code.matchAll(comment_regexp)].map((c) => (c[1] || c[2] || '').trim());
|
||||
const tags = {};
|
||||
|
||||
for (const match of raw_code.matchAll(comment_regexp)) {
|
||||
const tag_matches = (match[1] || match[2] || '').trim().split('@').slice(1);
|
||||
const [prefix, title] = (comments[0] || '').split('"');
|
||||
if (prefix.trim() === '' && title !== undefined) {
|
||||
tags['title'] = title;
|
||||
}
|
||||
|
||||
for (const comment of comments) {
|
||||
const tag_matches = comment.split('@').slice(1);
|
||||
for (const tag_match of tag_matches) {
|
||||
let [tag, tag_value] = tag_match.split(/ (.*)/s);
|
||||
tag = tag.trim();
|
||||
|
||||
@ -121,7 +121,7 @@ stack(
|
||||
.room(1)
|
||||
//.pianoroll({fold:1})`;
|
||||
|
||||
export const caverave = `// @title Caverave
|
||||
export const caverave = `// "Caverave"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -186,7 +186,7 @@ export const barryHarris = `// adapted from a Barry Harris excercise
|
||||
.color('#00B8D4')
|
||||
`;
|
||||
|
||||
export const blippyRhodes = `// @title Blippy Rhodes
|
||||
export const blippyRhodes = `// "Blippy Rhodes"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -230,7 +230,7 @@ stack(
|
||||
).fast(3/2)
|
||||
//.pianoroll({fold:1})`;
|
||||
|
||||
export const wavyKalimba = `// @title Wavy kalimba
|
||||
export const wavyKalimba = `// "Wavy kalimba"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -262,7 +262,7 @@ stack(
|
||||
.delay(.2)
|
||||
`;
|
||||
|
||||
export const festivalOfFingers = `// @title Festival of fingers
|
||||
export const festivalOfFingers = `// "Festival of fingers"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -279,7 +279,7 @@ stack(
|
||||
.note().piano()`;
|
||||
|
||||
// iter, echo, echoWith
|
||||
export const undergroundPlumber = `// @title Underground plumber
|
||||
export const undergroundPlumber = `// "Underground plumber"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
// @details inspired by Friendship - Let's not talk about it (1979) :)
|
||||
@ -307,7 +307,7 @@ stack(
|
||||
.fast(2/3)
|
||||
.pianoroll({})`;
|
||||
|
||||
export const bridgeIsOver = `// @title Bridge is over
|
||||
export const bridgeIsOver = `// "Bridge is over"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos, bassline by BDP - The Bridge Is Over
|
||||
|
||||
@ -330,7 +330,7 @@ stack(
|
||||
.pianoroll()
|
||||
`;
|
||||
|
||||
export const goodTimes = `// @title Good times
|
||||
export const goodTimes = `// "Good times"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -375,7 +375,7 @@ stack(
|
||||
.pianoroll({maxMidi:100,minMidi:20})`;
|
||||
*/
|
||||
|
||||
export const echoPiano = `// @title Echo piano
|
||||
export const echoPiano = `// "Echo piano"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -424,7 +424,7 @@ stack(
|
||||
.legato(.5)
|
||||
).fast(2).note()`;
|
||||
|
||||
export const randomBells = `// @title Random bells
|
||||
export const randomBells = `// "Random bells"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -449,7 +449,7 @@ stack(
|
||||
.pianoroll({minMidi:20,maxMidi:120,background:'transparent'})
|
||||
`;
|
||||
|
||||
export const waa2 = `// @title Waa2
|
||||
export const waa2 = `// "Waa2"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -467,7 +467,7 @@ n(
|
||||
.room(.5)
|
||||
`;
|
||||
|
||||
export const hyperpop = `// @title Hyperpop
|
||||
export const hyperpop = `// "Hyperpop"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -520,7 +520,7 @@ stack(
|
||||
).slow(2)
|
||||
// strudel disable-highlighting`;
|
||||
|
||||
export const festivalOfFingers3 = `// @title Festival of fingers 3
|
||||
export const festivalOfFingers3 = `// "Festival of fingers 3"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -540,7 +540,7 @@ export const festivalOfFingers3 = `// @title Festival of fingers 3
|
||||
.note().piano()
|
||||
//.pianoroll({maxMidi:160})`;
|
||||
|
||||
export const meltingsubmarine = `// @title Melting submarine
|
||||
export const meltingsubmarine = `// "Melting submarine"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -580,7 +580,7 @@ stack(
|
||||
)
|
||||
.slow(3/2)`;
|
||||
|
||||
export const outroMusic = `// @title Outro music
|
||||
export const outroMusic = `// "Outro music"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -611,7 +611,7 @@ samples({
|
||||
//.pianoroll({autorange:1,vertical:1,fold:0})
|
||||
`;
|
||||
|
||||
export const bassFuge = `// @title Bass fuge
|
||||
export const bassFuge = `// "Bass fuge"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -639,7 +639,7 @@ x=>x.add(7).color('steelblue')
|
||||
.stack(s("bd:1*2,~ sd:0,[~ hh:0]*2"))
|
||||
.pianoroll({vertical:1})`;
|
||||
|
||||
export const chop = `// @title Chop
|
||||
export const chop = `// "Chop"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -654,7 +654,7 @@ s("p")
|
||||
.sustain(.6)
|
||||
`;
|
||||
|
||||
export const delay = `// @title Delay
|
||||
export const delay = `// "Delay"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -665,7 +665,7 @@ stack(
|
||||
.delayfeedback(".6 | .8")
|
||||
).sometimes(x=>x.speed("-1"))`;
|
||||
|
||||
export const orbit = `// @title Orbit
|
||||
export const orbit = `// "Orbit"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -681,7 +681,7 @@ stack(
|
||||
.orbit(2)
|
||||
).sometimes(x=>x.speed("-1"))`;
|
||||
|
||||
export const belldub = `// @title Belldub
|
||||
export const belldub = `// "Belldub"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -716,7 +716,7 @@ stack(
|
||||
.mask("<1 0>/8")
|
||||
).slow(5)`;
|
||||
|
||||
export const dinofunk = `// @title Dinofunk
|
||||
export const dinofunk = `// "Dinofunk"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -739,7 +739,7 @@ note("Abm7".voicings('lefthand').struct("x(3,8,1)".slow(2))),
|
||||
note("<b4 eb4>").s('dino').delay(.8).slow(8).room(.5)
|
||||
)`;
|
||||
|
||||
export const sampleDemo = `// @title Sample demo
|
||||
export const sampleDemo = `// "Sample demo"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -757,7 +757,7 @@ stack(
|
||||
.release(.1).room(.5)
|
||||
)`;
|
||||
|
||||
export const holyflute = `// @title Holy flute
|
||||
export const holyflute = `// "Holy flute"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -772,7 +772,7 @@ export const holyflute = `// @title Holy flute
|
||||
.pianoroll({fold:0,autorange:0,vertical:0,cycles:12,smear:0,minMidi:40})
|
||||
`;
|
||||
|
||||
export const flatrave = `// @title Flatrave
|
||||
export const flatrave = `// "Flatrave"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -797,7 +797,7 @@ stack(
|
||||
.decay(.05).sustain(0).delay(.2).degradeBy(.5).mask("<0 1>/16")
|
||||
)`;
|
||||
|
||||
export const amensister = `// @title Amensister
|
||||
export const amensister = `// "Amensister"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -833,7 +833,7 @@ stack(
|
||||
n("0 1").s("east").delay(.5).degradeBy(.8).speed(rand.range(.5,1.5))
|
||||
).reset("<x@7 x(5,8,-1)>")`;
|
||||
|
||||
export const juxUndTollerei = `// @title Jux und tollerei
|
||||
export const juxUndTollerei = `// "Jux und tollerei"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -848,7 +848,7 @@ note("c3 eb3 g3 bb3").palindrome()
|
||||
.delay(.5).delaytime(.1).delayfeedback(.4)
|
||||
.pianoroll()`;
|
||||
|
||||
export const csoundDemo = `// @title CSound demo
|
||||
export const csoundDemo = `// "CSound demo"
|
||||
// @license with CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
@ -884,7 +884,7 @@ endin\`
|
||||
//.pianoroll()
|
||||
.csound('CoolSynth')`;
|
||||
|
||||
export const loungeSponge = `// @title Lounge sponge
|
||||
export const loungeSponge = `// "Lounge sponge"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos, livecode.orc by Steven Yi
|
||||
|
||||
@ -904,7 +904,7 @@ stack(
|
||||
s("bd*2,[~ hh]*2,~ cp").bank('RolandTR909')
|
||||
)`;
|
||||
|
||||
export const arpoon = `// @title Arpoon
|
||||
export const arpoon = `// "Arpoon"
|
||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
// @by Felix Roos
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user