diff options
| author | (quasar) nebula <qznebula@protonmail.com> | 2026-07-07 21:18:03 -0300 |
|---|---|---|
| committer | (quasar) nebula <qznebula@protonmail.com> | 2026-07-07 21:18:03 -0300 |
| commit | 2ccb0588a304b3ce8855651e8a30f895a57880c0 (patch) | |
| tree | f878792b2c8dbb632f9acbd7ac1ed85aed25923d | |
| parent | b15da97e76176344d8b977558940a7f4324c0876 (diff) | |
data, content, css: Aside Traack Section, Close Aside Track Section preview
| -rw-r--r-- | src/content/dependencies/generateAlbumTrackList.js | 56 | ||||
| -rw-r--r-- | src/content/dependencies/generateContentHeading.js | 1 | ||||
| -rw-r--r-- | src/data/files/album.js | 38 | ||||
| -rw-r--r-- | src/data/things/album/TrackSection.js | 14 | ||||
| -rw-r--r-- | src/data/things/album/index.js | 3 | ||||
| -rw-r--r-- | src/static/css/miscellany.css | 13 |
6 files changed, 109 insertions, 16 deletions
diff --git a/src/content/dependencies/generateAlbumTrackList.js b/src/content/dependencies/generateAlbumTrackList.js index 6c8a21c2..7a30fa02 100644 --- a/src/content/dependencies/generateAlbumTrackList.js +++ b/src/content/dependencies/generateAlbumTrackList.js @@ -82,7 +82,14 @@ export default { case 'trackSections': data.trackSectionNames = album.trackSections - .map(section => section.name); + .map(section => + (section.isDefaultTrackSection + ? null + : section.name)); + + data.trackSectionStyles = + album.trackSections + .map(section => section.style); data.trackSectionDurations = album.trackSections @@ -138,6 +145,7 @@ export default { items: relations.trackSectionItems, name: data.trackSectionNames, + style: data.trackSectionStyles, duration: data.trackSectionDurations, durationApproximate: data.trackSectionDurationsApproximate, hasTrackNumbers: data.trackSectionsHaveTrackNumbers, @@ -148,6 +156,7 @@ export default { items, name, + style, duration, durationApproximate, hasTrackNumbers, @@ -157,37 +166,54 @@ export default { heading.slots({ tag: 'dt', + attributes: [ + style === 'aside' && + {class: 'aside'}, + ], + title: - language.encapsulate(capsule, capsule => { - const options = {section: name}; + language.encapsulate(capsule, workingCapsule => { + const workingOptions = { + [language.onlyIfOptions]: ['section'], + section: name, + }; + + if (html.isBlank(name)) { + return html.blank(); + } if (duration) { - capsule += '.withDuration'; - options.duration = + workingCapsule += '.withDuration'; + workingOptions.duration = language.formatDuration(duration, { approximate: durationApproximate, }); } - return language.$(capsule, options); + return language.$(workingCapsule, workingOptions); }), stickyTitle: language.$(capsule, 'sticky', { + [language.onlyIfOptions]: ['section'], section: name, }), })), - html.tag('dd', [ - html.tag('blockquote', - {[html.onlyIfContent]: true}, - description), + html.tag('dd', + style === 'aside' && + {class: 'aside'}, + + [ + html.tag('blockquote', + {[html.onlyIfContent]: true}, + description), - (hasTrackNumbers - ? html.tag('ol', {start: startCountingFrom}, - slotItems(items)) - : html.tag('ul', slotItems(items))), - ]), + (hasTrackNumbers + ? html.tag('ol', {start: startCountingFrom}, + slotItems(items)) + : html.tag('ul', slotItems(items))), + ]), ])); case 'tracks': diff --git a/src/content/dependencies/generateContentHeading.js b/src/content/dependencies/generateContentHeading.js index a7cf201f..28e01b24 100644 --- a/src/content/dependencies/generateContentHeading.js +++ b/src/content/dependencies/generateContentHeading.js @@ -36,6 +36,7 @@ export default { generate: (relations, slots, {html}) => html.tag(slots.tag, {class: 'content-heading'}, {tabindex: '0'}, + {[html.onlyIfContent]: true}, {[html.onlyIfSiblings]: true}, slots.attributes, diff --git a/src/data/files/album.js b/src/data/files/album.js index 84cda226..da687ddf 100644 --- a/src/data/files/album.js +++ b/src/data/files/album.js @@ -3,10 +3,18 @@ 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}, + thingConstructors: { + Album, + Track, + TrackSection, + + AsideTrackSection, + CloseAsideTrackSection, + }, }) => ({ title: `Process album files`, @@ -21,6 +29,10 @@ export default ({ entryDocumentThing: document => ('Section' in document ? TrackSection + : 'Aside Section' in document + ? AsideTrackSection + : 'Close Aside Section' in document + ? CloseAsideTrackSection : Track), connect({header: album, entries}) { @@ -29,6 +41,8 @@ export default ({ let currentTrackSection = new TrackSection(); let currentTrackSectionTracks = []; + let latestNonAsideTrackSection = currentTrackSection; + Object.assign(currentTrackSection, { name: `Default Track Section`, isDefaultTrackSection: true, @@ -53,6 +67,28 @@ export default ({ 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; } diff --git a/src/data/things/album/TrackSection.js b/src/data/things/album/TrackSection.js index e579a0f6..86c754ac 100644 --- a/src/data/things/album/TrackSection.js +++ b/src/data/things/album/TrackSection.js @@ -50,6 +50,12 @@ export class TrackSection extends Thing { name: name(V('Unnamed Track Section')), + style: { + flags: {update: true, expose: true}, + update: {validate: is('section', 'aside')}, + expose: {transform: value => value ?? 'section'}, + }, + // Track sections don't have a Name Detail themselves, but they do provide // a value which tracks can reference via 'Name Detail: section'. nameDetailForTracks: { @@ -147,6 +153,14 @@ export class TrackSection extends Thing { validate: input.value(isBoolean), }), + { + dependencies: ['style'], + compute: (continuation, {style}) => + (style === 'aside' + ? true + : continuation()), + }, + withPropertyFromObject('album', V('hideTrackSectionDurations')), exposeDependency('#album.hideTrackSectionDurations'), ], diff --git a/src/data/things/album/index.js b/src/data/things/album/index.js index 67bf47ab..a19144d9 100644 --- a/src/data/things/album/index.js +++ b/src/data/things/album/index.js @@ -1,2 +1,5 @@ export * from './Album.js'; export * from './TrackSection.js'; + +export * from './AsideTrackSection.js'; +export * from './CloseAsideTrackSection.js'; diff --git a/src/static/css/miscellany.css b/src/static/css/miscellany.css index 24eeba44..5cff2d57 100644 --- a/src/static/css/miscellany.css +++ b/src/static/css/miscellany.css @@ -582,6 +582,19 @@ margin-left: 0; } + .album-group-list dt.aside { + margin-left: -5px; + } + + .album-group-list dd.aside { + border-left: 1px dashed; + margin-left: 3px; + } + + .album-group-list dd.aside :is(ul, ol) { + padding-left: 36px; + } + .album-group-list li { padding-left: 1.5ch; text-indent: -1.5ch; |