vowel 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/plugins/images/index.js +31 -1
- package/plugins/markdown/index.js +58 -17
- package/utils.js +40 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vowel",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.6.0",
|
|
5
5
|
"bin": "bin.js",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"scripts": {
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"remark-html": "^16.0.1",
|
|
59
59
|
"remark-parse": "^11.0.0",
|
|
60
60
|
"remark-rehype": "^11.1.2",
|
|
61
|
+
"sharp": "^0.35.3",
|
|
61
62
|
"unified": "^11.0.5",
|
|
62
63
|
"unist-util-find": "^3.0.0",
|
|
63
64
|
"unist-util-is": "^6.0.0",
|
package/plugins/images/index.js
CHANGED
|
@@ -1,10 +1,38 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto"
|
|
1
2
|
import fs from "fs/promises"
|
|
3
|
+
import sharp from 'sharp'
|
|
4
|
+
import path from "node:path"
|
|
5
|
+
import {createImagePath, imageSizes, imageExts } from "./../../utils.js"
|
|
2
6
|
|
|
3
7
|
/** @import * as Votive from "votive" */
|
|
4
8
|
|
|
9
|
+
|
|
5
10
|
/** @type {Votive.ProcessorWrite} */
|
|
6
11
|
async function writeImage(destination, database, config) {
|
|
12
|
+
const { uuid, sourcePath } = destination.abstract
|
|
13
|
+
|
|
14
|
+
const defaultFormat = path.extname(sourcePath)
|
|
15
|
+
|
|
16
|
+
const image = sharp(destination.path)
|
|
17
|
+
|
|
18
|
+
const images = imageSizes.flatMap(size => {
|
|
19
|
+
[...imageExts, defaultFormat].map(ext => {
|
|
20
|
+
const filePath = createImagePath({
|
|
21
|
+
targetFilePath: sourcePath,
|
|
22
|
+
size,
|
|
23
|
+
ext,
|
|
24
|
+
targetDirectory: config.destinationFolder,
|
|
25
|
+
uuid
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
return image.clone().resize(size).toFile(filePath)
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
await Promise.all(images)
|
|
33
|
+
|
|
7
34
|
const buffer = await fs.readFile(destination.path)
|
|
35
|
+
|
|
8
36
|
return {
|
|
9
37
|
data: buffer,
|
|
10
38
|
}
|
|
@@ -12,11 +40,13 @@ async function writeImage(destination, database, config) {
|
|
|
12
40
|
|
|
13
41
|
/** @type {Votive.ProcessorRead} */
|
|
14
42
|
function readImagePath(string) {
|
|
43
|
+
const uuid =randomUUID()
|
|
15
44
|
|
|
16
45
|
const data = {
|
|
17
46
|
metadata: {},
|
|
18
47
|
abstract: {
|
|
19
|
-
|
|
48
|
+
sourcePath: string,
|
|
49
|
+
uuid
|
|
20
50
|
}
|
|
21
51
|
}
|
|
22
52
|
|
|
@@ -19,7 +19,7 @@ import { h } from 'hastscript'
|
|
|
19
19
|
import { normalizeHeadings } from 'mdast-normalize-headings'
|
|
20
20
|
import { readFileSync } from "fs"
|
|
21
21
|
import { remove } from "unist-util-remove"
|
|
22
|
-
import { testURL, testHashtags, createHashtagPage, toTitleCase, hashtagRegexSingle } from "./../../utils.js"
|
|
22
|
+
import { testURL, testHashtags, createHashtagPage, toTitleCase, hashtagRegexSingle, createImagePaths, imageSizes } from "./../../utils.js"
|
|
23
23
|
import { toHast } from 'mdast-util-to-hast'
|
|
24
24
|
import { toString as hastToString } from 'hast-util-to-string'
|
|
25
25
|
import { toString as mdastToString } from 'mdast-util-to-string'
|
|
@@ -50,7 +50,46 @@ User-agent: CCBot
|
|
|
50
50
|
Disallow: /`
|
|
51
51
|
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @param {string} imagePath
|
|
56
|
+
* @param {Votive.Database} database
|
|
57
|
+
* @param {string} dependent
|
|
58
|
+
*/
|
|
59
|
+
function createDynamicImage(imagePath, database, dependent, alt, itemprop) {
|
|
60
|
+
console.log({ imagePath })
|
|
61
|
+
const relativePath = imagePath.startsWith("/") ? path.relative("/", imagePath) : imagePath
|
|
62
|
+
const image = database.target.getWithTrackers(relativePath, dependent)
|
|
63
|
+
console.log({ relativePath, image })
|
|
64
|
+
const formats = createImagePaths(image.abstract.sourcePath, "./", image.abstract.uuid)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
const sources = formats.map((format, index) => {
|
|
68
|
+
const isImg = index === formats.length - 1
|
|
69
|
+
|
|
70
|
+
const sizes = format.map((size, index) => `/${size} ${imageSizes[index]}w`).join(", ")
|
|
71
|
+
const type = "image/" + path.extname(format[0]).slice(1)
|
|
72
|
+
return h(isImg ? "img" : "source", {
|
|
73
|
+
type,
|
|
74
|
+
srcset: sizes,
|
|
75
|
+
loading: isImg && "lazy",
|
|
76
|
+
src: isImg && "/" + format.at(-1),
|
|
77
|
+
sizes: "100vw",
|
|
78
|
+
alt: isImg && alt
|
|
79
|
+
})
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
return h("picture", { itemprop: itemprop && "image" }, sources)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @param {object} metadata
|
|
88
|
+
* @param {string} url
|
|
89
|
+
* @param {Votive.Database} database
|
|
90
|
+
* @param {Votive.VotiveConfig} config
|
|
91
|
+
*/
|
|
92
|
+
function makeHead(metadata, url, database, config) {
|
|
54
93
|
|
|
55
94
|
const treeMainHead = []
|
|
56
95
|
|
|
@@ -75,19 +114,16 @@ function makeHead(metadata, url) {
|
|
|
75
114
|
)
|
|
76
115
|
}
|
|
77
116
|
|
|
78
|
-
if (metadata.image) treeMainHead.push(
|
|
79
|
-
h("img", {
|
|
80
|
-
src: metadata.image,
|
|
81
|
-
itemprop: "image"
|
|
82
|
-
})
|
|
83
|
-
)
|
|
84
117
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
if (metadata.image || (metadata.first_image && url)) {
|
|
121
|
+
const metaImage = metadata.image || metadata.first_image
|
|
122
|
+
|
|
123
|
+
treeMainHead.push(
|
|
124
|
+
createDynamicImage(metaImage, database, url, null, true)
|
|
125
|
+
)
|
|
126
|
+
}
|
|
91
127
|
|
|
92
128
|
if (metadata.fm_description) treeMainHead.push(
|
|
93
129
|
h("p",
|
|
@@ -991,7 +1027,12 @@ function writeFile(destination, database, config) {
|
|
|
991
1027
|
|
|
992
1028
|
const treeContentSlugged = slugger.runSync(treeContent)
|
|
993
1029
|
|
|
994
|
-
const treeMainHead = makeHead(metadata)
|
|
1030
|
+
const treeMainHead = makeHead(metadata, null, database, config)
|
|
1031
|
+
|
|
1032
|
+
visit(treeContent, { tagName: "img" }, (node, index, parent) => {
|
|
1033
|
+
const { src, alt } = node.properties
|
|
1034
|
+
parent.children.splice(index, 1, createDynamicImage(src, database, destination.path, alt))
|
|
1035
|
+
})
|
|
995
1036
|
|
|
996
1037
|
visit(treeContent, testPaths, ({ children: [child] }, i, p) => {
|
|
997
1038
|
|
|
@@ -1011,7 +1052,7 @@ function writeFile(destination, database, config) {
|
|
|
1011
1052
|
const target = database.target.getWithTrackers(targetFilePath, destination.path)
|
|
1012
1053
|
|
|
1013
1054
|
if (target) {
|
|
1014
|
-
const article = h('article', makeHead(target.metadata, target.metadata.prettyURL))
|
|
1055
|
+
const article = h('article', makeHead(target.metadata, target.metadata.prettyURL, database, config))
|
|
1015
1056
|
|
|
1016
1057
|
p.children.splice(i, 1, article)
|
|
1017
1058
|
}
|
|
@@ -1046,7 +1087,7 @@ function writeFile(destination, database, config) {
|
|
|
1046
1087
|
const list = h(`ul.${dirClasses}`,
|
|
1047
1088
|
targets.map(target => {
|
|
1048
1089
|
return h('li',
|
|
1049
|
-
h('article', makeHead(target.metadata, target.metadata.prettyURL))
|
|
1090
|
+
h('article', makeHead(target.metadata, target.metadata.prettyURL, database, config))
|
|
1050
1091
|
)
|
|
1051
1092
|
})
|
|
1052
1093
|
)
|
package/utils.js
CHANGED
|
@@ -1,7 +1,47 @@
|
|
|
1
1
|
import {fromMarkdown} from 'mdast-util-from-markdown'
|
|
2
2
|
import {toHast} from 'mdast-util-to-hast'
|
|
3
3
|
import {toHtml} from 'hast-util-to-html'
|
|
4
|
+
import path from "node:path"
|
|
5
|
+
import { randomUUID } from "node:crypto"
|
|
4
6
|
|
|
7
|
+
export const imageSizes = [414, 768, 1440, 1920]
|
|
8
|
+
export const imageExts = ["avif", "webp"]
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @param {object} params
|
|
12
|
+
* @property {string} targetFilePath
|
|
13
|
+
* @property {number} size
|
|
14
|
+
* @property {string} targetDirectory
|
|
15
|
+
* @property {string} uuid
|
|
16
|
+
*/
|
|
17
|
+
export function createImagePath({ targetFilePath, size, ext, targetDirectory, uuid }) {
|
|
18
|
+
const { dir, name } = path.parse(targetFilePath)
|
|
19
|
+
return path.format({
|
|
20
|
+
dir: path.relative(".", path.normalize(path.join(targetDirectory, dir))),
|
|
21
|
+
name: `${name}-${uuid}-${size}`,
|
|
22
|
+
ext
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {string} targetFilePath
|
|
28
|
+
* @param {string} targetDirectory
|
|
29
|
+
* @param {string} uuid
|
|
30
|
+
*/
|
|
31
|
+
export function createImagePaths(targetFilePath, targetDirectory, uuid) {
|
|
32
|
+
const defaultExt = path.extname(targetFilePath)
|
|
33
|
+
return [...imageExts, defaultExt].map(ext => {
|
|
34
|
+
return imageSizes.map(size => {
|
|
35
|
+
return createImagePath({
|
|
36
|
+
targetFilePath,
|
|
37
|
+
size,
|
|
38
|
+
ext,
|
|
39
|
+
targetDirectory,
|
|
40
|
+
uuid
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
})
|
|
44
|
+
}
|
|
5
45
|
|
|
6
46
|
/** @param {string} text */
|
|
7
47
|
export function testURL(text) {
|