diff options
author | (quasar) nebula <qznebula@protonmail.com> | 2025-04-08 08:48:24 -0300 |
---|---|---|
committer | (quasar) nebula <qznebula@protonmail.com> | 2025-04-13 22:54:15 -0300 |
commit | a166bca8aef15855dea545e8335068f8e6714fc7 (patch) | |
tree | 0909351e74234b6be09463442f4176baa955d7eb /src | |
parent | 48dde4a388fd4c31dd5680f7535419874124e554 (diff) |
wip 2
Diffstat (limited to 'src')
-rw-r--r-- | src/common-util/wiki-data.js | 5 | ||||
-rw-r--r-- | src/content/dependencies/generateIntrapageDotSwitcher.js | 2 | ||||
-rw-r--r-- | src/content/dependencies/generateLyricsSection.js | 79 | ||||
-rw-r--r-- | src/content/dependencies/generateLyricsSwitcher.js | 49 | ||||
-rw-r--r-- | src/data/checks.js | 29 | ||||
-rw-r--r-- | src/data/composite/wiki-data/withParsedLyricsEntries.js | 35 | ||||
-rw-r--r-- | src/static/css/site.css | 1 | ||||
-rw-r--r-- | src/validators.js | 12 |
8 files changed, 131 insertions, 81 deletions
diff --git a/src/common-util/wiki-data.js b/src/common-util/wiki-data.js index 4bbef8ab..0aa18ddb 100644 --- a/src/common-util/wiki-data.js +++ b/src/common-util/wiki-data.js @@ -102,6 +102,11 @@ export const commentaryRegexCaseSensitive = export const commentaryRegexCaseSensitiveOneShot = new RegExp(commentaryRegexRaw); +// The #validators function isOldStyleLyrics() describes +// what this regular expression detects. +export const oldStyleLyricsDetectionRegex = + /^<i>.*:<\/i>/m; + export function filterAlbumsByCommentary(albums) { return albums .filter((album) => [album, ...album.tracks].some((x) => x.commentary)); diff --git a/src/content/dependencies/generateIntrapageDotSwitcher.js b/src/content/dependencies/generateIntrapageDotSwitcher.js index 3f300676..1d58367d 100644 --- a/src/content/dependencies/generateIntrapageDotSwitcher.js +++ b/src/content/dependencies/generateIntrapageDotSwitcher.js @@ -42,6 +42,8 @@ export default { }).map(({title, targetID}) => html.tag('a', {href: '#'}, {'data-target-id': targetID}, + {[html.onlyIfContent]: true}, + language.sanitize(title))), }), }; diff --git a/src/content/dependencies/generateLyricsSection.js b/src/content/dependencies/generateLyricsSection.js index 7e7718c7..f6b719a9 100644 --- a/src/content/dependencies/generateLyricsSection.js +++ b/src/content/dependencies/generateLyricsSection.js @@ -1,8 +1,10 @@ +import {stitchArrays} from '#sugar'; + export default { contentDependencies: [ 'generateContentHeading', + 'generateIntrapageDotSwitcher', 'generateLyricsEntry', - 'generateLyricsSwitcher', 'transformContent', ], @@ -13,30 +15,67 @@ export default { relation('generateContentHeading'), switcher: - relation('generateLyricsSwitcher', entries), + relation('generateIntrapageDotSwitcher'), entries: entries .map(entry => relation('generateLyricsEntry', entry)), + + annotations: + entries + .map(entry => entry.annotation) + .map(annotation => relation('transformContent', annotation)), }), - generate: (relations, {html, language}) => - html.tags([ - relations.heading - .slots({ - attributes: {id: 'lyrics'}, - title: language.$('releaseInfo.lyrics'), - }), - - relations.switcher, - - relations.entries - .map((entry, index) => - entry.slots({ - attributes: [ - index >= 1 && - {style: 'display: none'}, - ], + data: (entries) => ({ + ids: + Array.from( + {length: entries.length}, + (_, index) => 'lyrics-entry-' + index), + }), + + generate: (data, relations, {html, language}) => + language.encapsulate('releaseInfo.lyrics', capsule => + html.tags([ + relations.heading + .slots({ + attributes: {id: 'lyrics'}, + title: language.$(capsule), + }), + + html.tag('p', {class: 'lyrics-switcher'}, + {[html.onlyIfContent]: true}, + + language.$(capsule, 'switcher', { + [language.onlyIfOptions]: ['entries'], + + entries: + relations.switcher.slots({ + initialOptionIndex: 0, + + titles: + relations.annotations.map(annotation => + annotation.slots({ + mode: 'inline', + textOnly: true, + })), + + targetIDs: + data.ids, + }), })), - ]), + + stitchArrays({ + entry: relations.entries, + id: data.ids, + }).map(({entry, id}, index) => + entry.slots({ + attributes: [ + {id}, + + index >= 1 && + {style: 'display: none'}, + ], + })), + ])), }; diff --git a/src/content/dependencies/generateLyricsSwitcher.js b/src/content/dependencies/generateLyricsSwitcher.js deleted file mode 100644 index 1c9ee6a3..00000000 --- a/src/content/dependencies/generateLyricsSwitcher.js +++ /dev/null @@ -1,49 +0,0 @@ -export default { - contentDependencies: ['transformContent'], - extraDependencies: ['html', 'language'], - - relations: (relation, entries) => ({ - annotations: - entries - .map(entry => entry.annotation) - .map(annotation => relation('transformContent', annotation)), - }), - - slots: { - tag: {type: 'string', default: 'p'}, - }, - - generate: (relations, slots, {html, language}) => - html.tag(slots.tag, {class: 'lyrics-switcher'}, - language.$('releaseInfo.lyrics.switcher', { - entries: - language.formatListWithoutSeparator( - relations.annotations - .map((annotation, index) => - html.tag('span', {[html.joinChildren]: ''}, [ - html.tag('a', - {href: '#'}, - - index === 0 && - {style: 'display: none'}, - - annotation - .slots({ - mode: 'inline', - textOnly: true, - })), - - html.tag('a', - {class: 'current'}, - - index >= 1 && - {style: 'display: none'}, - - annotation - .slots({ - mode: 'inline', - textOnly: true, - })), - ]))), - })), -}; diff --git a/src/data/checks.js b/src/data/checks.js index b11b5d55..25863d2d 100644 --- a/src/data/checks.js +++ b/src/data/checks.js @@ -9,7 +9,6 @@ import {compareArrays, cut, cutStart, empty, getNestedProp, iterateMultiline} from '#sugar'; import Thing from '#thing'; import thingConstructors from '#things'; -import {combineWikiDataArrays, commentaryRegexCaseSensitive} from '#wiki-data'; import { annotateErrorWithIndex, @@ -20,6 +19,12 @@ import { withAggregate, } from '#aggregate'; +import { + combineWikiDataArrays, + commentaryRegexCaseSensitive, + oldStyleLyricsDetectionRegex, +} from '#wiki-data'; + function inspect(value, opts = {}) { return nodeInspect(value, {colors: ENABLE_COLOR, ...opts}); } @@ -568,6 +573,12 @@ export function reportContentTextErrors(wikiData, { annotation: 'commentary annotation', }; + const newStyleLyricsShape = { + body: 'lyrics body', + artistDisplayText: 'lyrics artist display text', + annotation: 'lyrics annotation', + }; + const contentTextSpec = [ ['albumData', { additionalFiles: additionalFileShape, @@ -614,7 +625,7 @@ export function reportContentTextErrors(wikiData, { additionalFiles: additionalFileShape, commentary: commentaryShape, creditSources: commentaryShape, - lyrics: '_content', + lyrics: '_lyrics', midiProjectFiles: additionalFileShape, sheetMusicFiles: additionalFileShape, }], @@ -737,8 +748,9 @@ export function reportContentTextErrors(wikiData, { for (const thing of things) { nest({message: `Content text errors in ${inspect(thing)}`}, ({nest, push}) => { - for (const [property, shape] of Object.entries(propSpec)) { - const value = thing[property]; + for (let [property, shape] of Object.entries(propSpec)) { + const rawValue = CacheableObject.getUpdateValue(thing, property); + let value = thing[property]; if (value === undefined) { push(new TypeError(`Property ${colors.red(property)} isn't valid for ${colors.green(thing.constructor.name)}`)); @@ -749,6 +761,15 @@ export function reportContentTextErrors(wikiData, { continue; } + if (shape === '_lyrics') { + if (oldStyleLyricsDetectionRegex.test(rawValue)) { + value = rawValue; + shape = '_content'; + } else { + shape = newStyleLyricsShape; + } + } + const fieldPropertyMessage = getFieldPropertyMessage( thing.constructor[Thing.yamlDocumentSpec], diff --git a/src/data/composite/wiki-data/withParsedLyricsEntries.js b/src/data/composite/wiki-data/withParsedLyricsEntries.js index 28e4c9b5..d13bfbaa 100644 --- a/src/data/composite/wiki-data/withParsedLyricsEntries.js +++ b/src/data/composite/wiki-data/withParsedLyricsEntries.js @@ -1,8 +1,8 @@ import {input, templateCompositeFrom} from '#composite'; -import find from '#find'; import {stitchArrays} from '#sugar'; import {isLyrics} from '#validators'; -import {commentaryRegexCaseSensitive} from '#wiki-data'; +import {commentaryRegexCaseSensitive, oldStyleLyricsDetectionRegex} + from '#wiki-data'; import { fillMissingListItems, @@ -11,10 +11,25 @@ import { withUnflattenedList, } from '#composite/data'; +import inputSoupyFind from './inputSoupyFind.js'; import processContentEntryDates from './processContentEntryDates.js'; import withParsedContentEntries from './withParsedContentEntries.js'; import withResolvedReferenceList from './withResolvedReferenceList.js'; +function constituteLyricsEntry(text) { + return { + artists: [], + artistDisplayText: null, + annotation: null, + date: null, + secondDate: null, + dateKind: null, + accessDate: null, + accessKind: null, + body: text, + }; +} + export default templateCompositeFrom({ annotation: `withParsedLyricsEntries`, @@ -25,6 +40,19 @@ export default templateCompositeFrom({ outputs: ['#parsedLyricsEntries'], steps: () => [ + { + dependencies: [input('from')], + compute: (continuation, { + [input('from')]: lyrics, + }) => + (oldStyleLyricsDetectionRegex.test(lyrics) + ? continuation() + : continuation.raiseOutput({ + ['#parsedLyricsEntries']: + [constituteLyricsEntry(lyrics)], + })), + }, + withParsedContentEntries({ from: input('from'), caseSensitiveRegex: input.value(commentaryRegexCaseSensitive), @@ -65,8 +93,7 @@ export default templateCompositeFrom({ withResolvedReferenceList({ list: '#flattenedList', - data: 'artistData', - find: input.value(find.artist), + find: inputSoupyFind.input('artist'), notFoundMode: input.value('null'), }), diff --git a/src/static/css/site.css b/src/static/css/site.css index 6b61af72..a4139624 100644 --- a/src/static/css/site.css +++ b/src/static/css/site.css @@ -1621,6 +1621,7 @@ p.content-heading:has(+ .commentary-entry-heading.dated) { .lyrics-entry { padding-left: 40px; + max-width: 600px; } .js-hide, diff --git a/src/validators.js b/src/validators.js index 5300d4ad..6badc93a 100644 --- a/src/validators.js +++ b/src/validators.js @@ -3,8 +3,12 @@ import {inspect as nodeInspect} from 'node:util'; import {openAggregate, withAggregate} from '#aggregate'; import {colors, ENABLE_COLOR} from '#cli'; import {cut, empty, matchMultiline, typeAppearance} from '#sugar'; -import {commentaryRegexCaseInsensitive, commentaryRegexCaseSensitiveOneShot} - from '#wiki-data'; + +import { + commentaryRegexCaseInsensitive, + commentaryRegexCaseSensitiveOneShot, + oldStyleLyricsDetectionRegex, +} from '#wiki-data'; function inspect(value) { return nodeInspect(value, {colors: ENABLE_COLOR}); @@ -371,9 +375,9 @@ export const isCommentary = export function isOldStyleLyrics(content) { isContentString(content); - if (/^<i>/m.test(content)) { + if (oldStyleLyricsDetectionRegex.test(content)) { throw new TypeError( - `Expected old-style lyrics block not to include <i> at start of any line`); + `Expected old-style lyrics block not to include "<i> ... :</i>" at start of any line`); } return true; |