« get me outta code hell

data, content: Contribution.artistText - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2026-01-26 19:52:39 -0400
committer(quasar) nebula <qznebula@protonmail.com>2026-01-26 19:52:39 -0400
commitdc0d479d6698bf1db3f5181f48332da26ebd47f7 (patch)
tree56822ab59d08474e1d6184a3b19aafcea4323a4d
parenta8f36db5eac0a6ba89127ef393a68ffe94cf79a0 (diff)
data, content: Contribution.artistText preview
-rw-r--r--src/content/dependencies/linkContribution.js7
-rw-r--r--src/data/composite/wiki-data/withResolvedContribs.js12
-rw-r--r--src/data/things/contrib/Contribution.js4
-rw-r--r--src/data/yaml.js30
-rw-r--r--src/validators.js1
5 files changed, 45 insertions, 9 deletions
diff --git a/src/content/dependencies/linkContribution.js b/src/content/dependencies/linkContribution.js
index 46c07e5d..f9c27724 100644
--- a/src/content/dependencies/linkContribution.js
+++ b/src/content/dependencies/linkContribution.js
@@ -11,6 +11,7 @@ export default {
   }),
 
   data: (contribution) => ({
+    artistText: contribution.artistText,
     annotationParts: contribution.annotationParts,
     urls: contribution.artist.urls,
   }),
@@ -51,6 +52,12 @@ export default {
           chronologyKind: slots.chronologyKind,
         });
 
+        if (data.artistText) {
+          relations.artistLink.setSlots({
+            content: language.sanitize(data.artistText),
+          });
+        }
+
         workingOptions.artist =
           (html.isBlank(relations.tooltip) || slots.preventTooltip
             ? relations.artistLink
diff --git a/src/data/composite/wiki-data/withResolvedContribs.js b/src/data/composite/wiki-data/withResolvedContribs.js
index 0d96f1b7..3bbe1f81 100644
--- a/src/data/composite/wiki-data/withResolvedContribs.js
+++ b/src/data/composite/wiki-data/withResolvedContribs.js
@@ -82,27 +82,33 @@ export default templateCompositeFrom({
 
     withPropertiesFromList({
       list: input('from'),
-      properties: input.value(['artist', 'annotation']),
+      properties: input.value(['artist', 'artistText', 'annotation']),
       prefix: input.value('#contribs'),
     }),
 
     {
       dependencies: [
         '#contribs.artist',
+        '#contribs.artistText',
         '#contribs.annotation',
         input('date'),
       ],
 
       compute(continuation, {
         ['#contribs.artist']: artist,
+        ['#contribs.artistText']: artistText,
         ['#contribs.annotation']: annotation,
         [input('date')]: date,
       }) {
-        filterMultipleArrays(artist, annotation, (artist, _annotation) => artist);
+        filterMultipleArrays(
+          artist,
+          artistText,
+          annotation,
+          (artist, _artistText, _annotation) => artist);
 
         return continuation({
           ['#details']:
-            stitchArrays({artist, annotation})
+            stitchArrays({artist, artistText, annotation})
               .map(details => ({
                 ...details,
                 date: date ?? null,
diff --git a/src/data/things/contrib/Contribution.js b/src/data/things/contrib/Contribution.js
index 57a5c301..4352b58a 100644
--- a/src/data/things/contrib/Contribution.js
+++ b/src/data/things/contrib/Contribution.js
@@ -7,7 +7,7 @@ import {empty} from '#sugar';
 import Thing from '#thing';
 import {isBoolean, isStringNonEmpty, isThing} from '#validators';
 
-import {simpleDate, singleReference, soupyFind}
+import {simpleDate, singleReference, simpleString, soupyFind}
   from '#composite/wiki-properties';
 
 import {
@@ -56,6 +56,8 @@ export class Contribution extends Thing {
       find: soupyFind.input('artist'),
     }),
 
+    artistText: simpleString(),
+
     annotation: {
       flags: {update: true, expose: true},
       update: {validate: isStringNonEmpty},
diff --git a/src/data/yaml.js b/src/data/yaml.js
index 50496c00..2afaffb5 100644
--- a/src/data/yaml.js
+++ b/src/data/yaml.js
@@ -646,6 +646,9 @@ export const extractAccentRegex =
 export const extractPrefixAccentRegex =
   /^(?:\((?<accent>.*)\) )?(?<main>.*?)$/;
 
+export const asNameRegex =
+  /^as (?<name>\S.+?)(?:(?<=\S)[,:] | +- |$)(?: *(?<annotation>.*))?$/;
+
 // TODO: Should this fit better within actual YAML loading infrastructure??
 export function parseArrayEntries(entries, mapFn) {
   // If this isn't something we can parse, just return it as-is.
@@ -679,12 +682,14 @@ export function parseContributors(entries) {
     if (typeof item === 'object' && item['Who'])
       return {
         artist: item['Who'],
+        artistText: item['As'] ?? null,
         annotation: item['What'] ?? null,
       };
 
     if (typeof item === 'object' && item['Artist'])
       return {
         artist: item['Artist'],
+        artistText: item['Artist Text'] ?? null,
         annotation: item['Annotation'] ?? null,
 
         countInContributionTotals: item['Count In Contribution Totals'] ?? null,
@@ -693,13 +698,28 @@ export function parseContributors(entries) {
 
     if (typeof item !== 'string') return item;
 
-    const match = item.match(extractAccentRegex);
+    let match;
+
+    match = item.match(extractAccentRegex);
     if (!match) return item;
 
-    return {
-      artist: match.groups.main,
-      annotation: match.groups.accent ?? null,
-    };
+    const {accent} = match.groups;
+
+    let artist = match.groups.main;
+    let artistText = null;
+    let annotation = null;
+
+    if (accent) {
+      match = accent.match(asNameRegex);
+      if (match) {
+        artistText = match.groups.name;
+        annotation = match.groups.annotation ?? null;
+      } else {
+        annotation = accent;
+      }
+    }
+
+    return {artist, artistText, annotation};
   });
 }
 
diff --git a/src/validators.js b/src/validators.js
index 63268ded..625df307 100644
--- a/src/validators.js
+++ b/src/validators.js
@@ -678,6 +678,7 @@ export function isThing(thing) {
 
 export const isContribution = validateProperties({
   artist: isArtistRef,
+  artistText: optional(isStringNonEmpty),
   annotation: optional(isStringNonEmpty),
 
   countInDurationTotals: optional(isBoolean),