diff options
author | (quasar) nebula <qznebula@protonmail.com> | 2023-11-24 15:05:03 -0400 |
---|---|---|
committer | (quasar) nebula <qznebula@protonmail.com> | 2023-11-24 15:05:03 -0400 |
commit | eab0e06d148b5445feab453b8042d5e93e1fa1a2 (patch) | |
tree | 62dab7600a89ca73cd1bffc19092c97fe4d58450 /src/content | |
parent | ca30b07b9e116f6d42d6ea6a2623e1500c289383 (diff) | |
parent | 9f58ba688c8a6ac3acf7b4bc435e2ccaed20b011 (diff) |
Merge branch 'commentary-entries' into preview
Diffstat (limited to 'src/content')
-rw-r--r-- | src/content/dependencies/generateAlbumCommentaryPage.js | 30 | ||||
-rw-r--r-- | src/content/dependencies/generateAlbumInfoPage.js | 22 | ||||
-rw-r--r-- | src/content/dependencies/generateCommentaryEntry.js | 99 | ||||
-rw-r--r-- | src/content/dependencies/generateCommentarySection.js | 29 | ||||
-rw-r--r-- | src/content/dependencies/generateTrackInfoPage.js | 22 | ||||
-rw-r--r-- | src/content/dependencies/transformContent.js | 55 |
6 files changed, 185 insertions, 72 deletions
diff --git a/src/content/dependencies/generateAlbumCommentaryPage.js b/src/content/dependencies/generateAlbumCommentaryPage.js index e2415516..001003ae 100644 --- a/src/content/dependencies/generateAlbumCommentaryPage.js +++ b/src/content/dependencies/generateAlbumCommentaryPage.js @@ -6,13 +6,12 @@ export default { 'generateAlbumNavAccent', 'generateAlbumSidebarTrackSection', 'generateAlbumStyleRules', - 'generateColorStyleVariables', + 'generateCommentaryEntry', 'generateContentHeading', 'generateTrackCoverArtwork', 'generatePageLayout', 'linkAlbum', 'linkTrack', - 'transformContent', ], extraDependencies: ['html', 'language'], @@ -38,8 +37,9 @@ export default { relation('generateAlbumCoverArtwork', album); } - relations.albumCommentaryContent = - relation('transformContent', album.commentary); + relations.albumCommentaryEntries = + album.commentary + .map(entry => relation('generateCommentaryEntry', entry)); } const tracksWithCommentary = @@ -61,16 +61,11 @@ export default { ? relation('generateTrackCoverArtwork', track) : null)); - relations.trackCommentaryContent = - tracksWithCommentary - .map(track => relation('transformContent', track.commentary)); - - relations.trackCommentaryColorVariables = + relations.trackCommentaryEntries = tracksWithCommentary .map(track => - (track.color === album.color - ? null - : relation('generateColorStyleVariables'))); + track.commentary + .map(entry => relation('generateCommentaryEntry', entry))); relations.sidebarAlbumLink = relation('linkAlbum', album); @@ -163,10 +158,9 @@ export default { link: relations.trackCommentaryLinks, directory: data.trackCommentaryDirectories, cover: relations.trackCommentaryCovers, - content: relations.trackCommentaryContent, - colorVariables: relations.trackCommentaryColorVariables, + entries: relations.trackCommentaryEntries, color: data.trackCommentaryColors, - }).map(({heading, link, directory, cover, content, colorVariables, color}) => [ + }).map(({heading, link, directory, cover, entries, color}) => [ heading.slots({ tag: 'h3', id: directory, @@ -175,11 +169,7 @@ export default { cover?.slots({mode: 'commentary'}), - html.tag('blockquote', - (color - ? {style: colorVariables.slot('color', color).content} - : {}), - content), + entries.map(entry => entry.slot('color', color)), ]), ], diff --git a/src/content/dependencies/generateAlbumInfoPage.js b/src/content/dependencies/generateAlbumInfoPage.js index 5fe27caf..90a120ca 100644 --- a/src/content/dependencies/generateAlbumInfoPage.js +++ b/src/content/dependencies/generateAlbumInfoPage.js @@ -17,6 +17,7 @@ export default { 'generateAlbumStyleRules', 'generateAlbumTrackList', 'generateChronologyLinks', + 'generateCommentarySection', 'generateContentHeading', 'generatePageLayout', 'linkAlbum', @@ -126,13 +127,8 @@ export default { // Section: Artist commentary if (album.commentary) { - const artistCommentary = sections.artistCommentary = {}; - - artistCommentary.heading = - relation('generateContentHeading'); - - artistCommentary.content = - relation('transformContent', album.commentary); + sections.artistCommentary = + relation('generateCommentarySection', album.commentary); } return relations; @@ -235,17 +231,7 @@ export default { sec.additionalFiles.additionalFilesList, ], - sec.artistCommentary && [ - sec.artistCommentary.heading - .slots({ - id: 'artist-commentary', - title: language.$('releaseInfo.artistCommentary') - }), - - html.tag('blockquote', - sec.artistCommentary.content - .slot('mode', 'multiline')), - ], + sec.artistCommentary, ], navLinkStyle: 'hierarchical', diff --git a/src/content/dependencies/generateCommentaryEntry.js b/src/content/dependencies/generateCommentaryEntry.js new file mode 100644 index 00000000..0b2b2558 --- /dev/null +++ b/src/content/dependencies/generateCommentaryEntry.js @@ -0,0 +1,99 @@ +import {empty} from '#sugar'; + +export default { + contentDependencies: [ + 'generateColorStyleVariables', + 'linkArtist', + 'transformContent', + ], + + extraDependencies: ['html', 'language'], + + relations: (relation, entry) => ({ + artistLinks: + (!empty(entry.artists) && !entry.artistDisplayText + ? entry.artists + .map(artist => relation('linkArtist', artist)) + : null), + + artistsContent: + (entry.artistDisplayText + ? relation('transformContent', entry.artistDisplayText) + : null), + + annotationContent: + (entry.annotation + ? relation('transformContent', entry.annotation) + : null), + + bodyContent: + (entry.body + ? relation('transformContent', entry.body) + : null), + + colorVariables: + relation('generateColorStyleVariables'), + }), + + data: (entry) => ({ + date: entry.date, + }), + + slots: { + color: {validate: v => v.isColor}, + }, + + generate(data, relations, slots, {html, language}) { + const artistsSpan = + html.tag('span', {class: 'commentary-entry-artists'}, + (relations.artistsContent + ? relations.artistsContent.slot('mode', 'inline') + : relations.artistLinks + ? language.formatConjunctionList(relations.artistLinks) + : language.$('misc.artistCommentary.entry.title.noArtists'))); + + const accentParts = ['misc.artistCommentary.entry.title.accent']; + const accentOptions = {}; + + if (relations.annotationContent) { + accentParts.push('withAnnotation'); + accentOptions.annotation = + relations.annotationContent.slot('mode', 'inline'); + } + + if (data.date) { + accentParts.push('withDate'); + accentOptions.date = + language.formatDate(data.date); + } + + const accent = + (accentParts.length > 1 + ? html.tag('span', {class: 'commentary-entry-accent'}, + language.$(...accentParts, accentOptions)) + : null); + + const titleParts = ['misc.artistCommentary.entry.title']; + const titleOptions = {artists: artistsSpan}; + + if (accent) { + titleParts.push('withAccent'); + titleOptions.accent = accent; + } + + const style = + (slots.color + ? relations.colorVariables + .slot('color', slots.color) + .content + : null); + + return html.tags([ + html.tag('p', {class: 'commentary-entry-heading', style}, + language.$(...titleParts, titleOptions)), + + html.tag('blockquote', {class: 'commentary-entry-body', style}, + relations.bodyContent.slot('mode', 'multiline')), + ]); + }, +}; diff --git a/src/content/dependencies/generateCommentarySection.js b/src/content/dependencies/generateCommentarySection.js new file mode 100644 index 00000000..8ae1b2d0 --- /dev/null +++ b/src/content/dependencies/generateCommentarySection.js @@ -0,0 +1,29 @@ +export default { + contentDependencies: [ + 'transformContent', + 'generateCommentaryEntry', + 'generateContentHeading', + ], + + extraDependencies: ['html', 'language'], + + relations: (relation, entries) => ({ + heading: + relation('generateContentHeading'), + + entries: + entries.map(entry => + relation('generateCommentaryEntry', entry)), + }), + + generate: (relations, {html, language}) => + html.tags([ + relations.heading + .slots({ + id: 'artist-commentary', + title: language.$('misc.artistCommentary') + }), + + relations.entries, + ]), +}; diff --git a/src/content/dependencies/generateTrackInfoPage.js b/src/content/dependencies/generateTrackInfoPage.js index 180e5c29..2848b15c 100644 --- a/src/content/dependencies/generateTrackInfoPage.js +++ b/src/content/dependencies/generateTrackInfoPage.js @@ -12,6 +12,7 @@ export default { 'generateAlbumSidebar', 'generateAlbumStyleRules', 'generateChronologyLinks', + 'generateCommentarySection', 'generateContentHeading', 'generateContributionList', 'generatePageLayout', @@ -274,13 +275,8 @@ export default { // Section: Artist commentary if (track.commentary) { - const artistCommentary = sections.artistCommentary = {}; - - artistCommentary.heading = - relation('generateContentHeading'); - - artistCommentary.content = - relation('transformContent', track.commentary); + sections.artistCommentary = + relation('generateCommentarySection', track.commentary); } return relations; @@ -499,17 +495,7 @@ export default { sec.additionalFiles.list, ], - sec.artistCommentary && [ - sec.artistCommentary.heading - .slots({ - id: 'artist-commentary', - title: language.$('releaseInfo.artistCommentary') - }), - - html.tag('blockquote', - sec.artistCommentary.content - .slot('mode', 'multiline')), - ], + sec.artistCommentary, ], navLinkStyle: 'hierarchical', diff --git a/src/content/dependencies/transformContent.js b/src/content/dependencies/transformContent.js index 3c2c3521..7b2d0573 100644 --- a/src/content/dependencies/transformContent.js +++ b/src/content/dependencies/transformContent.js @@ -1,7 +1,7 @@ import {bindFind} from '#find'; import {parseInput} from '#replacer'; -import {marked} from 'marked'; +import {Marked} from 'marked'; export const replacerSpec = { album: { @@ -147,6 +147,29 @@ const linkIndexRelationMap = { newsIndex: 'linkNewsIndex', }; +const commonMarkedOptions = { + headerIds: false, + mangle: false, +}; + +const multilineMarked = new Marked({ + ...commonMarkedOptions, +}); + +const inlineMarked = new Marked({ + ...commonMarkedOptions, + + renderer: { + paragraph(text) { + return text; + }, + }, +}); + +const lyricsMarked = new Marked({ + ...commonMarkedOptions, +}); + function getPlaceholder(node, content) { return {type: 'text', data: content.slice(node.i, node.iEnd)}; } @@ -447,19 +470,9 @@ export default { return link.data; } - // In inline mode, no further processing is needed! - - if (slots.mode === 'inline') { - return html.tags(contentFromNodes.map(node => node.data)); - } - - // Multiline mode has a secondary processing stage where it's passed... - // through marked! Rolling your own Markdown only gets you so far :D - - const markedOptions = { - headerIds: false, - mangle: false, - }; + // Content always goes through marked (i.e. parsing as Markdown). + // This does require some attention to detail, mostly to do with line + // breaks (in multiline mode) and extracting/re-inserting non-text nodes. // The content of non-text nodes can end up getting mangled by marked. // To avoid this, we replace them with mundane placeholders, then @@ -534,6 +547,16 @@ export default { return html.tags(tags, {[html.joinChildren]: ''}); }; + if (slots.mode === 'inline') { + const markedInput = + extractNonTextNodes(); + + const markedOutput = + inlineMarked.parse(markedInput); + + return reinsertNonTextNodes(markedOutput); + } + // This is separated into its own function just since we're gonna reuse // it in a minute if everything goes to heck in lyrics mode. const transformMultiline = () => { @@ -550,7 +573,7 @@ export default { .replace(/(?<=^>.*)\n+(?!^>)/gm, '\n\n'); const markedOutput = - marked.parse(markedInput, markedOptions); + multilineMarked.parse(markedInput); return reinsertNonTextNodes(markedOutput); } @@ -600,7 +623,7 @@ export default { }); const markedOutput = - marked.parse(markedInput, markedOptions); + lyricsMarked.parse(markedInput); return reinsertNonTextNodes(markedOutput); } |