1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
import * as path from 'node:path';
import {traverse} from '#node-utils';
import {sortAlbumsTracksChronologically, sortChronologically} from '#sort';
import {empty} from '#sugar';
import Thing from '#thing';
export default ({
documentModes: {headerAndEntries},
thingConstructors: {
Album,
Track,
TrackSection,
AsideTrackSection,
CloseAsideTrackSection,
},
}) => ({
title: `Process album files`,
files: dataPath =>
traverse(path.join(dataPath, 'album'), {
filterFile: name => path.extname(name) === '.yaml',
prefixPath: 'album',
}),
documentMode: headerAndEntries,
headerDocumentThing: Album,
entryDocumentThing: document =>
('Section' in document
? TrackSection
: 'Aside Section' in document
? AsideTrackSection
: 'Close Aside Section' in document
? CloseAsideTrackSection
: Track),
connect({header: album, entries}) {
const trackSections = [];
let currentTrackSection = new TrackSection();
let currentTrackSectionTracks = [];
let latestNonAsideTrackSection = currentTrackSection;
Object.assign(currentTrackSection, {
name: `Default Track Section`,
isDefaultTrackSection: true,
});
const closeCurrentTrackSection = () => {
if (
currentTrackSection.isDefaultTrackSection &&
empty(currentTrackSectionTracks)
) {
return;
}
currentTrackSection.tracks = currentTrackSectionTracks;
currentTrackSection.album = album;
trackSections.push(currentTrackSection);
};
for (const entry of entries) {
if (entry instanceof TrackSection) {
closeCurrentTrackSection();
currentTrackSection = entry;
currentTrackSectionTracks = [];
if (entry.style !== 'aside') {
latestNonAsideTrackSection = entry;
}
continue;
}
if (entry instanceof CloseAsideTrackSection) {
if (currentTrackSection.style !== 'aside') {
throw new Error(`Current track section "${currentTrackSection.name}" is not an aside`);
}
if (entry.name !== currentTrackSection.name) {
throw new Error(`Expected "Close Aside Section: ${currentTrackSection.name}", got "${entry.name}"`);
}
closeCurrentTrackSection();
currentTrackSection = Thing.clone(latestNonAsideTrackSection);
currentTrackSection.tracks = [];
currentTrackSectionTracks = [];
continue;
}
entry.album = album;
entry.trackSection = currentTrackSection;
currentTrackSectionTracks.push(entry);
}
closeCurrentTrackSection();
album.trackSections = trackSections;
},
sort({albumData, trackData}) {
sortChronologically(albumData);
sortAlbumsTracksChronologically(trackData);
},
});
|