diff options
Diffstat (limited to 'src/content/dependencies')
-rw-r--r-- | src/content/dependencies/transformContent.js | 246 |
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 |