« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/content
diff options
context:
space:
mode:
Diffstat (limited to 'src/content')
-rw-r--r--src/content/dependencies/transformContent.js246
1 files changed, 198 insertions, 48 deletions
diff --git a/src/content/dependencies/transformContent.js b/src/content/dependencies/transformContent.js
index 03bd7bcc..2c0a8e41 100644
--- a/src/content/dependencies/transformContent.js
+++ b/src/content/dependencies/transformContent.js
@@ -2,7 +2,115 @@ import {marked} from 'marked';
 
 import {bindFind} from '../../util/find.js';
 import {parseInput} from '../../util/replacer.js';
-import {replacerSpec} from '../../util/transform-content.js';
+
+export const replacerSpec = {
+  album: {
+    find: 'album',
+    link: 'album',
+  },
+  'album-commentary': {
+    find: 'album',
+    link: 'albumCommentary',
+  },
+  'album-gallery': {
+    find: 'album',
+    link: 'albumGallery',
+  },
+  artist: {
+    find: 'artist',
+    link: 'artist',
+  },
+  'artist-gallery': {
+    find: 'artist',
+    link: 'artistGallery',
+  },
+  'commentary-index': {
+    find: null,
+    link: 'commentaryIndex',
+  },
+  date: {
+    find: null,
+    value: (ref) => new Date(ref),
+    html: (date, {html, language}) =>
+      html.tag('time',
+        {datetime: date.toString()},
+        language.formatDate(date)),
+  },
+  'flash-index': {
+    find: null,
+    link: 'flashIndex',
+  },
+  flash: {
+    find: 'flash',
+    link: 'flash',
+    transformName(name, node, input) {
+      const nextCharacter = input[node.iEnd];
+      const lastCharacter = name[name.length - 1];
+      if (![' ', '\n', '<'].includes(nextCharacter) && lastCharacter === '.') {
+        return name.slice(0, -1);
+      } else {
+        return name;
+      }
+    },
+  },
+  group: {
+    find: 'group',
+    link: 'groupInfo',
+  },
+  'group-gallery': {
+    find: 'group',
+    link: 'groupGallery',
+  },
+  home: {
+    find: null,
+    link: 'home',
+  },
+  'listing-index': {
+    find: null,
+    link: 'listingIndex',
+  },
+  listing: {
+    find: 'listing',
+    link: 'listing',
+  },
+  media: {
+    find: null,
+    link: 'media',
+  },
+  'news-index': {
+    find: null,
+    link: 'newsIndex',
+  },
+  'news-entry': {
+    find: 'newsEntry',
+    link: 'newsEntry',
+  },
+  root: {
+    find: null,
+    link: 'root',
+  },
+  site: {
+    find: null,
+    link: 'site',
+  },
+  static: {
+    find: 'staticPage',
+    link: 'staticPage',
+  },
+  string: {
+    find: null,
+    value: (ref) => ref,
+    html: (ref, {language, args}) => language.$(ref, args),
+  },
+  tag: {
+    find: 'artTag',
+    link: 'tag',
+  },
+  track: {
+    find: 'track',
+    link: 'track',
+  },
+};
 
 const linkThingRelationMap = {
   album: 'linkAlbum',
@@ -43,9 +151,10 @@ export default {
     ...Object.values(linkThingRelationMap),
     ...Object.values(linkValueRelationMap),
     ...Object.values(linkIndexRelationMap),
+    'image',
   ],
 
-  extraDependencies: ['html', 'language', 'wikiData'],
+  extraDependencies: ['html', 'language', 'to', 'wikiData'],
 
   sprawl(wikiData, content) {
     const find = bindFind(wikiData);
@@ -140,14 +249,16 @@ export default {
       nodes:
         sprawl.nodes
           .map(node => {
-            // Replace link nodes with a stub. It'll be replaced (by position)
-            // with an item from relations.
-            if (node.type === 'link') {
-              return {type: 'link'};
+            switch (node.type) {
+              // Replace link nodes with a stub. It'll be replaced (by position)
+              // with an item from relations.
+              case 'link':
+                return {type: 'link'};
+
+              // Other nodes will get processed in generate.
+              default:
+                return node;
             }
-
-            // Other nodes will get processed in generate.
-            return node;
           }),
     };
   },
@@ -181,6 +292,12 @@ export default {
               return relationOrPlaceholder(node, linkIndexRelationMap[key]);
             }
           }),
+
+      images:
+        nodes
+          .filter(({type}) => type === 'image')
+          .filter(({inline}) => !inline)
+          .map(() => relation('image')),
     };
   },
 
@@ -200,63 +317,96 @@ export default {
     },
   },
 
-  generate(data, relations, slots, {html, language}) {
+  generate(data, relations, slots, {html, language, to}) {
     let linkIndex = 0;
+    let imageIndex = 0;
 
     // This array contains only straight text and link nodes, which are directly
     // representable in html (so no further processing is needed on the level of
     // individual nodes).
     const contentFromNodes =
       data.nodes.map(node => {
-        if (node.type === 'text') {
-          return {type: 'text', data: node.data};
-        }
+        switch (node.type) {
+          case 'text':
+            return {type: 'text', data: node.data};
+
+          case 'image': {
+            const src =
+              (node.src.startsWith('media/')
+                ? to('media.path', node.src.slice('media/'.length))
+                : node.src);
+
+            const {width, height} = node;
+
+            if (node.inline) {
+              return {
+                type: 'image',
+                data:
+                  html.tag('img', {src, width, height}),
+              };
+            }
 
-        if (node.type === 'link') {
-          const linkNode = relations.links[linkIndex++];
-          if (linkNode.type === 'text') {
-            return {type: 'text', data: linkNode.data};
+            const image = relations.images[imageIndex++];
+
+            return {
+              type: 'image',
+              data:
+                image.slots({
+                  src,
+                  link: true,
+                  width: width ?? null,
+                  height: height ?? null,
+                }),
+            };
           }
 
-          const {link, label, hash, toIndex} = linkNode;
-
-          return {
-            type: 'link',
-            data:
-              (toIndex
-                ? link.slots({content: label, hash})
-                : link.slots({
-                    content: label, hash,
-                    preferShortName: slots.preferShortLinkNames,
-                  })),
-          };
-        }
+          case 'link': {
+            const linkNode = relations.links[linkIndex++];
+            if (linkNode.type === 'text') {
+              return {type: 'text', data: linkNode.data};
+            }
 
-        if (node.type === 'tag') {
-          const {replacerKey, replacerValue} = node.data;
+            const {link, label, hash, toIndex} = linkNode;
+
+            return {
+              type: 'link',
+              data:
+                (toIndex
+                  ? link.slots({content: label, hash})
+                  : link.slots({
+                      content: label, hash,
+                      preferShortName: slots.preferShortLinkNames,
+                    })),
+            };
+          }
 
-          const spec = replacerSpec[replacerKey];
+          case 'tag': {
+            const {replacerKey, replacerValue} = node.data;
 
-          if (!spec) {
-            return getPlaceholder(node, data.content);
-          }
+            const spec = replacerSpec[replacerKey];
 
-          const {value: valueFn, html: htmlFn} = spec;
+            if (!spec) {
+              return getPlaceholder(node, data.content);
+            }
 
-          const value =
-            (valueFn
-              ? valueFn(replacerValue)
-              : replacerValue);
+            const {value: valueFn, html: htmlFn} = spec;
 
-          const contents =
-            (htmlFn
-              ? htmlFn(value, {html, language})
-              : value);
+            const value =
+              (valueFn
+                ? valueFn(replacerValue)
+                : replacerValue);
 
-          return {type: 'text', data: contents};
-        }
+            const contents =
+              (htmlFn
+                ? htmlFn(value, {html, language})
+                : value);
+
+            return {type: 'text', data: contents};
+          }
 
-        return getPlaceholder(node, data.content);
+          default:
+            return getPlaceholder(node, data.content);
+        }
       });
 
     // In single-link mode, return the link node exactly as is - exposing