From 25798012d6a0ab3ba0c439f372bbedc5943ac47e Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Wed, 28 Oct 2020 17:33:03 -0300 Subject: this commit is very large because i am doing work and i would like to not lose progress in case i really screw those git moves up bad also it puts everything new into tracking which is kinda nice --- upd8.js | 1149 +++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 752 insertions(+), 397 deletions(-) (limited to 'upd8.js') diff --git a/upd8.js b/upd8.js index 439f6fb2..eb91e76b 100644 --- a/upd8.js +++ b/upd8.js @@ -108,6 +108,8 @@ const C = require('./common'); // const C.SITE_DIRECTORY = ''; const SITE_TITLE = 'Homestuck Music Wiki'; +const SITE_VERSION = 'autumnal polish haul'; +const SITE_RELEASE = '10 October 2020'; const SITE_ABOUT = fixWS`

Welcome to my fan-made Homestuck music wiki!

@@ -144,7 +146,8 @@ const SITE_ABOUT = fixWS` const SITE_CHANGELOG = fs.readFileSync('changelog.html').toString().trim(); // fight me bro const SITE_FEEDBACK = fixWS` -

Feature requests? Noticed any errors? Please let me know! I appreciate feedback a lot, and always want to make this site better.

+

Feature requests?
Noticed any errors?
Itching to see that one missing album on the wiki?

+

Please let me know! I appreciate feedback a lot, and always want to make this site better.

The best place to talk about this site is on its HomestuckXYZ forum thread.

Or, if forums aren't really the thing for you, I've got an email too: towerofnix at gmail dot beans. (You know the domain.)

I used to have a Twitter account, but Twitter is bad and poofing from it was probably my greatest decision.

@@ -344,7 +347,7 @@ function transformInline(text) { const nextCharacter = text[offset + 1]; const lastCharacter = name[name.length - 1]; if ( - ![' ', '\n'].includes(nextCharacter) && + ![' ', '\n', '<'].includes(nextCharacter) && lastCharacter === '.' ) { name = name.slice(0, -1); @@ -792,6 +795,8 @@ function getTotalDuration(tracks) { return tracks.reduce((duration, track) => duration + track.duration, 0); } +const stringifyIndent = 0; + function stringifyAlbumData() { return JSON.stringify(albumData, (key, value) => { if (['album', 'commentary'].includes(key)) { @@ -799,7 +804,7 @@ function stringifyAlbumData() { } return value; - }, 1); + }, stringifyIndent); } function stringifyFlashData() { @@ -809,16 +814,16 @@ function stringifyFlashData() { } return value; - }, 1); + }, stringifyIndent); } function stringifyArtistData() { - return JSON.stringify(artistData, null, 1); + return JSON.stringify(artistData, null, stringifyIndent); } // 8asic function for writing any site page. Handles all the 8asename, // directory, and site-template shenanigans! -async function writePage(directoryParts, titleOrHead, body) { +async function OLD_writePage(directoryParts, titleOrHead, body) { const directory = path.join(C.SITE_DIRECTORY, ...directoryParts); await mkdirp(directory); // This is sort of hard-coded, i.e. we don't do path.join(C.ROOT_DIRECTORY). @@ -855,69 +860,358 @@ async function writePage(directoryParts, titleOrHead, body) { `)); } +function escapeAttributeValue(value) { + return value.toString().replace(/"/g, '"'); +} + +function attributes(attribs) { + return Object.entries(attribs) + .filter(([ key, val ]) => val !== '') + .map(([ key, val ]) => `${key}="${escapeAttributeValue(val)}"`) + .join(' '); +} + +function img({ + src = '', + alt = '', + id = '', + link = false, + lazy = false, + square = false +}) { + const willSquare = square; + const willLink = typeof link === 'string' || link; + + const imgAttributes = attributes({ + id: link ? '' : id, + alt + }); + + const nonlazyHTML = wrap(``); + const lazyHTML = lazy && wrap(``, true); + + if (lazy) { + return fixWS` + + ${lazyHTML} + `; + } else { + return nonlazyHTML; + } + + function wrap(html, hide = false) { + if (willSquare) { + html = fixWS`
${html}
`; + } + + if (willLink) { + html = `${html}`; + } + + return html; + } +} + +async function writePage(directoryParts, { + title = '', + meta = {}, + + body = { + style: '' + }, + + main = { + classes: [], + content: '' + }, + + sidebar = { + collapse: true, + classes: [], + content: '' + }, + + nav = { + links: [], + classes: [], + content: '' + } +}) { + const directory = path.join(C.SITE_DIRECTORY, ...directoryParts); + const file = path.join(directory, 'index.html'); + const href = path.join(...directoryParts, 'index.html'); + + const mainHTML = main.content && fixWS` +
+ ${main.content} +
+ `; + + const { + collapse = true, + wide = false + } = sidebar; + + const sidebarHTML = sidebar.content && fixWS` + + `; + + if (nav.simple) { + nav.links = [ + ['index.html', 'Home'], + [href, title] + ] + } + + const navContentHTML = [ + nav.links && fixWS` + + `, + nav.content + ].filter(Boolean).join('\n'); + + const navHTML = navContentHTML && fixWS` + + `; + + const layoutHTML = [ + navHTML, + sidebar.content ? fixWS` +
+ ${sidebarHTML} + ${mainHTML} +
+ ` : mainHTML + ].filter(Boolean).join('\n'); + + await mkdirp(directory); + await writeFile(file, rebaseURLs(directory, fixWS` + + + + ${title} + + + ${Object.entries(meta).map(([ key, value ]) => ``).join('\n')} + + + + ${layoutHTML} + + + + + + + + + `)); +} + +function getGridHTML({ + entries, + srcFn, + hrefFn, + altFn, + lazy = true +}) { + return entries.map(({ large, item }, i) => fixWS` + + ${img({ + src: srcFn(item), + alt: altFn(item), + lazy: (typeof lazy === 'number' ? i >= lazy : lazy), + square: true + })} + ${item.name} + + `).join('\n'); +} + +function getAlbumGridHTML(props) { + return getGridHTML({ + srcFn: getAlbumCover, + hrefFn: album => `${C.ALBUM_DIRECTORY}/${album.directory}/index.html`, + altFn: () => 'album cover', + ...props + }); +} + +function getAlbumGridHTML(props) { + return getGridHTML({ + srcFn: getAlbumCover, + hrefFn: album => `${C.ALBUM_DIRECTORY}/${album.directory}/index.html`, + altFn: () => 'album cover', + ...props + }); +} + +function getFlashGridHTML(props) { + return getGridHTML({ + srcFn: getFlashCover, + hrefFn: flash => `${C.FLASH_DIRECTORY}/${flash.directory}/index.html`, + altFn: () => 'flash art', + ...props + }); +} + +function getNewReleases(numReleases) { + const latestFirst = albumData.slice().reverse(); + + // TODO: Major fan albums + const majorReleases = []; + majorReleases.push(latestFirst.find(album => album.isOfficial)); + + const otherReleases = latestFirst + .filter(album => !majorReleases.includes(album)) + .slice(0, numReleases - majorReleases.length); + + return [ + ...majorReleases.map(album => ({large: true, item: album})), + ...otherReleases.map(album => ({large: false, item: album})) + ]; +} + function writeMiscellaneousPages() { return progressPromiseAll('Writing miscellaneous pages.', [ - writePage([], fixWS` - ${SITE_TITLE} - - `, fixWS` - -
+ writePage([], { + title: SITE_TITLE, + meta: { + description: "Expansive resource for anyone interested in fan-made and official Homestuck music alike; an archive for all things related." + }, + main: { + classes: ['top-index'], + content: fixWS`

${SITE_TITLE}

-
-

Explore the site!

- Listings - Flashes & Games - About & Credits - Feedback & Suggestions - Changelog -

...or choose an album:

-
-

Beyond Canon

-

The future of Homestuck music, today.
Albums by the Homestuck^2 Music Team. 2020+.

+

New Releases

- ${albumData.filter(album => album.isBeyond).reverse().map(album => fixWS` - - cover art - ${album.name} - - `).join('\n')} + ${getAlbumGridHTML({ + entries: getNewReleases(4), + lazy: false + })}

Fandom

-

A look into Homestuck's world of music and art created—and organized—by fans.
The beginning of time, through the end.

- ${albumData.filter(album => album.isFanon).reverse().map(album => fixWS` - - cover art - ${album.name} - - `).join('\n')} - ...and more to be added at your request + ${getAlbumGridHTML({ + entries: (albumData + .filter(album => album.isFanon) + .reverse() + .slice(0, 7) + .map(album => ({item: album}))), + lazy: true + })} +

Official

-

The original discography: a replica of the Homestuck Bandcamp prior to the enmergening.
Albums organized by What Pumpkin. 2009–2019.

- ${albumData.filter(album => album.isCanon).reverse().map(album => fixWS` - - cover art - ${album.name} - - `).join('\n')} + ${getAlbumGridHTML({ + entries: (albumData + .filter(album => album.isOfficial) + .reverse() + .slice(0, 11) + .map(album => ({item: album}))), + lazy: true + })} +
-
- - `), - writePage([C.FLASH_DIRECTORY], `Flashes & Games`, fixWS` - -
-

Flashes & Games

-
- Home - Listings - About & Credits - Feedback & Suggestions - Changelog + ` + }, + sidebar: { + collapse: false, + wide: true, + content: fixWS` +

Get involved!

+ +
+

News

+

Todo.

+ ` + }, + nav: { + content: fixWS` +

+ Home + Listings + Flashes & Games + About & Credits + Feedback & Suggestions + Changelog (${SITE_RELEASE}: ${SITE_VERSION}) +

+ ` + } + }), + + writePage(['albums', 'fandom'], { + title: `Albums - Fandom`, + main: { + classes: ['top-index'], + content: fixWS` +

Albums - Fandom

+
+ ${getAlbumGridHTML({ + entries: (albumData + .filter(album => album.isFanon) + .reverse() + .map(album => ({item: album}))), + lazy: 4 + })}
+ ` + }, + nav: {simple: true} + }), + + writePage(['albums', 'official'], { + title: `Albums - Official`, + main: { + classes: ['top-index'], + content: fixWS` +

Albums - Official

+
+ ${getAlbumGridHTML({ + entries: (albumData + .filter(album => album.isOfficial) + .reverse() + .map(album => ({item: album}))), + lazy: 4 + })} +
+ ` + }, + nav: {simple: true} + }), + + writePage([C.FLASH_DIRECTORY], { + title: `Flashes & Games`, + main: { + classes: ['flash-index'], + content: fixWS` +

Flashes & Games

Also check out:

    @@ -925,60 +1219,72 @@ function writeMiscellaneousPages() {
  • bgreco.net's Homestuck HQ Audio Flashes: an index of all HS Flash animations with Bandcamp-quality audio built in. (Also the source for many thumbnails below!)
-
- ${flashData.map(flash => flash.act8r8k ? fixWS` -

${flash.act}

- ` : fixWS` - - cover art - ${flash.name} - - `).join('\n')} -
-
- - `), - writePage([C.ABOUT_DIRECTORY], 'About & Credits', fixWS` - -
+ ${flashData.filter(flash => flash.act8r8k).map((act, i) => fixWS` +

${act.act}

+
+ ${getFlashGridHTML({ + entries: (flashData + .filter(flash => !flash.act8r8k && flash.act === act.act) + .map(flash => ({item: flash}))), + lazy: i === 0 ? 4 : true + })} +
+ `).join('\n')} + ` + }, + nav: {simple: true} + }), + + writePage([C.ABOUT_DIRECTORY], { + title: `About & Credits`, + main: { + content: fixWS`

${SITE_TITLE}

-

(Home)

${transformMultiline(SITE_ABOUT, true)}
-
- - `), - writePage([C.CHANGELOG_DIRECTORY], `Changelog`, fixWS` - -
+ ` + }, + nav: {simple: true} + }), + + writePage([C.CHANGELOG_DIRECTORY], { + title: `Changelog`, + main: { + content: fixWS`

Changelog

-

(Home)

${transformMultiline(SITE_CHANGELOG, true)}
-
- - `), - writePage([C.FEEDBACK_DIRECTORY], 'Feedback & Suggestions!', fixWS` - -
+ ` + }, + nav: {simple: true} + }), + + writePage([C.FEEDBACK_DIRECTORY], { + title: `Feedback & Suggestions!`, + main: { + content: fixWS`

Feedback & Suggestions!

-

(Home)

${SITE_FEEDBACK}
-
- - `), - writePage([C.JS_DISABLED_DIRECTORY], 'JavaScript Disabled', fixWS` - -
+ ` + }, + nav: {simple: true} + }), + + writePage([C.JS_DISABLED_DIRECTORY], { + title: 'JavaScript Disabled', + main: { + content: fixWS`

JavaScript Disabled (or out of date)

${SITE_JS_DISABLED} -
- - `), + ` + }, + nav: {simple: true} + }), + writeFile('data.js', fixWS` // Yo, this file is gener8ted. Don't mess around with it! window.albumData = ${stringifyAlbumData()}; @@ -1008,155 +1314,189 @@ async function writeAlbumPage(album) { `; const listTag = getAlbumListTag(album); - await writePage([C.ALBUM_DIRECTORY, album.directory], album.name, fixWS` - - -
- -
- cover art -

${album.name}

-

- ${album.artists && `By ${getArtistString(album.artists, true)}.
` || ``} - ${album.coverArtists && `Cover art by ${getArtistString(album.coverArtists, true)}.
` || ``} - Released ${getDateString(album)}. - ${+album.artDate !== +album.date && `
Art released ${getDateString({date: album.artDate})}.` || ``} -
Duration: ~${getDurationString(getTotalDuration(album.tracks))}.

-

- ${album.urls.length && `

Listen on ${joinNoOxford(album.urls.map(url => fancifyURL(url, {album: true})), 'or')}.

` || ``} - ${album.usesGroups ? fixWS` -

This album listing is divided into groups:

-
- ${album.tracks.flatMap((track, i, arr) => [ - (i > 0 && track.group !== arr[i - 1].group) && ``, - (i === 0 || track.group !== arr[i - 1].group) && fixWS` -
${track.group}:
-
<${listTag}> - `, - trackToListItem(track), - i === arr.length && `
` - ].filter(Boolean)).join('\n')} -
- ` : fixWS` - <${listTag}> - ${album.tracks.map(trackToListItem).join('\n')} - - `} - ${album.commentary && fixWS` -

Artist commentary:

-
- ${transformMultiline(album.commentary)} -
- ` || ``} + await writePage([C.ALBUM_DIRECTORY, album.directory], { + title: album.name, + body: { + style: `${getThemeString(album)}; --album-directory: ${album.directory}` + }, + main: { + content: fixWS` + ${img({ + src: getAlbumCover(album), + id: 'cover-art', + link: true, + square: true + })} +

${album.name}

+

+ ${album.artists && `By ${getArtistString(album.artists, true)}.
` || ``} + ${album.coverArtists && `Cover art by ${getArtistString(album.coverArtists, true)}.
` || ``} + Released ${getDateString(album)}. + ${+album.artDate !== +album.date && `
Art released ${getDateString({date: album.artDate})}.` || ``} +
Duration: ~${getDurationString(getTotalDuration(album.tracks))}.

+

+ ${album.urls.length && `

Listen on ${joinNoOxford(album.urls.map(url => fancifyURL(url, {album: true})), 'or')}.

` || ``} + ${album.usesGroups ? fixWS` +

This album listing is divided into groups:

+
+ ${album.tracks.flatMap((track, i, arr) => [ + (i > 0 && track.group !== arr[i - 1].group) && ``, + (i === 0 || track.group !== arr[i - 1].group) && fixWS` +
${track.group}:
+
<${listTag}> + `, + trackToListItem(track), + i === arr.length && `
` + ].filter(Boolean)).join('\n')} +
+ ` : fixWS` + <${listTag}> + ${album.tracks.map(trackToListItem).join('\n')} + + `} + ${album.commentary && fixWS` +

Artist commentary:

+
+ ${transformMultiline(album.commentary)} +
+ ` || ``} + ` + }, + sidebar: { + content: generateSidebarForAlbum(album) + }, + nav: { + links: [ + ['index.html', 'Home'], + [`${C.ALBUM_DIRECTORY}/${album.directory}/index.html`, album.name], + [null, generateAlbumNavLinks(album)] + ], + content: fixWS` +
+ ${generateAlbumChronologyLinks(album)}
-
- - `); + ` + } + }); } async function writeTrackPage(track) { + const { album } = track; const tracksThatReference = getTracksThatReference(track); const ttrFanon = tracksThatReference.filter(t => t.album.isFanon); const ttrOfficial = tracksThatReference.filter(t => t.album.isOfficial); const tracksReferenced = getTracksReferencedBy(track); const flashesThatFeature = getFlashesThatFeature(track); - await writePage([C.TRACK_DIRECTORY, track.directory], track.name, fixWS` - - -
- -
- cover art -

${track.name}

-

- By ${getArtistString(track.artists, true)}. - ${track.coverArtists && `
Cover art by ${getArtistString(track.coverArtists, true)}.` || ``} - ${track.album.directory !== C.UNRELEASED_TRACKS_DIRECTORY && `
Released ${getDateString(track)}.` || ``} - ${+track.artDate !== +track.date && `
Art released ${getDateString({date: track.artDate})}.` || ``} - ${track.duration && `
Duration: ${getDurationString(track.duration)}.` || ``} -

- ${track.urls.length ? fixWS` -

Listen on ${joinNoOxford(track.urls.map(fancifyURL), 'or')}.

- ` : fixWS` -

This track has no URLs at which it can be listened.

- `} - ${track.contributors.textContent && fixWS` -

Contributors:
${transformInline(track.contributors.textContent)}

- `} - ${track.contributors.length && fixWS` -

Contributors:

-
    - ${track.contributors.map(contrib => `
  • ${getArtistString([contrib], true)}
  • `).join('\n')} -
- ` || ``} - ${tracksReferenced.length && fixWS` -

Tracks that ${track.name} references:

-
    - ${tracksReferenced.map(track => fixWS` -
  • - ${track.name} - by ${getArtistString(track.artists)} -
  • - `).join('\n')} -
- ` || ``} - ${tracksThatReference.length && fixWS` -

Tracks that reference ${track.name}:

-
- ${ttrOfficial.length && fixWS` -
Official:
-
    - ${ttrOfficial.map(track => fixWS` -
  • - ${track.name} - by ${getArtistString(track.artists)} -
  • - `).join('\n')} -
- ` || ``} - ${ttrFanon.length && fixWS` -
Fandom:
-
    - ${ttrFanon.map(track => fixWS` -
  • - ${track.name} - by ${getArtistString(track.artists)} -
  • - `).join('\n')} -
- ` || ``} -
- ` || ``} - ${flashesThatFeature.length && fixWS` -

Flashes & games that feature ${track.name}:

-
    - ${flashesThatFeature.map(flash => `
  • ${getFlashLinkHTML(flash)}
  • `).join('\n')} -
- ` || ``} - ${track.lyrics && fixWS` -

Lyrics:

-
- ${transformMultiline(track.lyrics)} -
- ` || ``} - ${track.commentary && fixWS` -

Artist commentary:

-
- ${transformMultiline(track.commentary)} -
- ` || ``} + await writePage([C.TRACK_DIRECTORY, track.directory], { + title: track.name, + body: { + style: `${getThemeString(track)}; --album-directory: ${album.directory}; --track-directory: ${track.directory}` + }, + sidebar: { + content: generateSidebarForAlbum(album, track) + }, + nav: { + links: [ + ['index.html', 'Home'], + [`${C.ALBUM_DIRECTORY}/${album.directory}/index.html`, album.name], + [`${C.TRACK_DIRECTORY}/${track.direcotry}/index.html`, track.name], + [null, generateAlbumNavLinks(album, track)] + ], + content: fixWS` +
+ ${generateAlbumChronologyLinks(album, track)}
-
- - `); + ` + }, + main: { + content: fixWS` + ${img({ + src: getTrackCover(track), + id: 'cover-art', + link: true, + square: true + })} +

${track.name}

+

+ By ${getArtistString(track.artists, true)}. + ${track.coverArtists && `
Cover art by ${getArtistString(track.coverArtists, true)}.` || ``} + ${album.directory !== C.UNRELEASED_TRACKS_DIRECTORY && `
Released ${getDateString(track)}.` || ``} + ${+track.artDate !== +track.date && `
Art released ${getDateString({date: track.artDate})}.` || ``} + ${track.duration && `
Duration: ${getDurationString(track.duration)}.` || ``} +

+ ${track.urls.length ? fixWS` +

Listen on ${joinNoOxford(track.urls.map(fancifyURL), 'or')}.

+ ` : fixWS` +

This track has no URLs at which it can be listened.

+ `} + ${track.contributors.textContent && fixWS` +

Contributors:
${transformInline(track.contributors.textContent)}

+ `} + ${track.contributors.length && fixWS` +

Contributors:

+
    + ${track.contributors.map(contrib => `
  • ${getArtistString([contrib], true)}
  • `).join('\n')} +
+ ` || ``} + ${tracksReferenced.length && fixWS` +

Tracks that ${track.name} references:

+
    + ${tracksReferenced.map(track => fixWS` +
  • + ${track.name} + by ${getArtistString(track.artists)} +
  • + `).join('\n')} +
+ ` || ``} + ${tracksThatReference.length && fixWS` +

Tracks that reference ${track.name}:

+
+ ${ttrOfficial.length && fixWS` +
Official:
+
    + ${ttrOfficial.map(track => fixWS` +
  • + ${track.name} + by ${getArtistString(track.artists)} +
  • + `).join('\n')} +
+ ` || ``} + ${ttrFanon.length && fixWS` +
Fandom:
+
    + ${ttrFanon.map(track => fixWS` +
  • + ${track.name} + by ${getArtistString(track.artists)} +
  • + `).join('\n')} +
+ ` || ``} +
+ ` || ``} + ${flashesThatFeature.length && fixWS` +

Flashes & games that feature ${track.name}:

+
    + ${flashesThatFeature.map(flash => `
  • ${getFlashLinkHTML(flash)}
  • `).join('\n')} +
+ ` || ``} + ${track.lyrics && fixWS` +

Lyrics:

+
+ ${transformMultiline(track.lyrics)} +
+ ` || ``} + ${track.commentary && fixWS` +

Artist commentary:

+
+ ${transformMultiline(track.commentary)} +
+ ` || ``} + ` + } + }); } async function writeArtistPages() { @@ -1202,7 +1542,7 @@ async function writeArtistPage(artistName) { // Shish! const kebab = C.getArtistDirectory(artistName); const index = `${C.ARTIST_DIRECTORY}/${kebab}/index.html`; - await writePage([C.ARTIST_DIRECTORY, kebab], artistName, fixWS` + await OLD_writePage([C.ARTIST_DIRECTORY, kebab], artistName, fixWS`
${ENABLE_ARTIST_AVATARS && await access(path.join(C.ARTIST_AVATAR_DIRECTORY, kebab + '.jpg')).then(() => true, () => false) && fixWS` @@ -1358,17 +1698,110 @@ async function writeFlashPage(flash) { next && `Next` ].filter(Boolean); - await writePage([C.FLASH_DIRECTORY, kebab], flash.name, fixWS` - - -
- -
-

${flash.name}

- cover art -

Released ${getDateString(flash)}.

- ${(flash.page || flash.urls.length) && `

Play on ${joinNoOxford( - [ - flash.page && getFlashLink(flash), - ...flash.urls - ].map(url => `${fancifyURL(url)}` + ( - url.includes('homestuck.com') ? ` (${isNaN(Number(flash.page)) ? 'secret page' : `page ${flash.page}`})` : - url.includes('bgreco.net') ? ` (HQ audio)` : - url.includes('youtu') ? ` (on any device)` : - '' - ) + ``), 'or')}.

` || ``} - ${flash.contributors.textContent && fixWS` -

Contributors:
${transformInline(flash.contributors.textContent)}

- `} - ${flash.tracks.length && fixWS` -

Tracks featured in ${flash.name.replace(/\.$/, '')}:

-
    - ${flash.tracks.map(ref => { - const track = getLinkedTrack(ref); - const neighm = ref.match(/(.*?\S):/) || [ref, ref]; - if (track) { - const neeeighm = neighm[1].replace('$$$$', ':'); - return fixWS` -
  • - ${neeeighm} - by ${getArtistString(track.artists)} -
  • - `; - } else { - const by = ref.match(/\(by .*\)/); - if (by) { - const name = ref.replace(by, '').trim(); - const contribs = by[0].replace(/\(by |\)/g, '').split(',').map(w => ({who: w.trim()})); - return `
  • ${name} by ${getArtistString(contribs)}
  • `; - } else { - return `
  • ${ref}
  • `; - } - } - }).join('\n')} -
- ` || ``} - ${flash.contributors.length && fixWS` -

Contributors:

-
    - ${flash.contributors.map(({ who, what }) => fixWS` -
  • ${artistNames.includes(who) - ? `${who}` - : who - }${what && ` (${getContributionString({what})})`}
  • - `).join('\n')} -
- ` || ``} -
-
- - `); + ` + } + }); } function writeListingPages() { @@ -1632,7 +1976,7 @@ function writeListingPages() { }; return progressPromiseAll(`Writing listing pages.`, [ - writePage([C.LISTING_DIRECTORY], `Listings Index`, fixWS` + OLD_writePage([C.LISTING_DIRECTORY], `Listings Index`, fixWS` `), - writePage([C.LISTING_DIRECTORY, 'all-commentary'], 'All Commentary', fixWS` + OLD_writePage([C.LISTING_DIRECTORY, 'all-commentary'], 'All Commentary', fixWS` `), - writePage([C.LISTING_DIRECTORY, 'random'], 'Random Pages', fixWS` + OLD_writePage([C.LISTING_DIRECTORY, 'random'], 'Random Pages', fixWS`