vowel 0.2.3 → 0.2.5
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/404.md +3 -0
- package/README.md +171 -25
- package/bin.js +209 -1
- package/config.js +20 -0
- package/docs-source/.votive.db +0 -0
- package/docs-source/blog/url-ui.md +1 -5
- package/docs-source/blog.md +5 -0
- package/docs-source/docs/items.md +1 -1
- package/docs-source/home.md +1 -1
- package/docs-source/output/about.html +1 -0
- package/docs-source/output/blog/url-ui.html +8 -0
- package/docs-source/output/blog.html +1 -0
- package/docs-source/output/default.css +1 -0
- package/docs-source/output/docs/deploy.html +34 -0
- package/docs-source/output/docs/file-structure.html +24 -0
- package/docs-source/output/docs/folder-settings.html +20 -0
- package/docs-source/output/docs/images.html +2 -0
- package/docs-source/output/docs/items.html +6 -0
- package/docs-source/output/docs/pages.html +101 -0
- package/docs-source/output/docs/styling.html +18 -0
- package/docs-source/output/docs/taxonomies.html +20 -0
- package/docs-source/output/docs.html +28 -0
- package/docs-source/output/features/cards.html +1 -0
- package/docs-source/output/features/editing.html +1 -0
- package/docs-source/output/features/emoji.html +1 -0
- package/docs-source/output/features/frontmatter.html +1 -0
- package/docs-source/output/features/lists.html +1 -0
- package/docs-source/output/features/navigation.html +1 -0
- package/docs-source/output/features/rich-previews.html +1 -0
- package/docs-source/output/features/robots.html +1 -0
- package/docs-source/output/features/rss.html +1 -0
- package/docs-source/output/features/sitemap.html +1 -0
- package/docs-source/output/features/speed.html +1 -0
- package/docs-source/output/features/static.html +1 -0
- package/docs-source/output/features/taxonomies.html +1 -0
- package/docs-source/output/features.html +1 -0
- package/docs-source/output/feed.xml +1 -0
- package/docs-source/output/index.html +21 -0
- package/docs-source/output/reset.css +1 -0
- package/docs-source/output/roadmap.html +87 -0
- package/docs-source/output/robots.txt +14 -0
- package/docs-source/output/sitemap.xml +16 -0
- package/docs-source/output/typography.css +1 -0
- package/docs-source/settings.md +1 -0
- package/getMetadata.js +1 -1
- package/index.js +5 -660
- package/package.json +17 -2
- package/plugins/fonts/index.js +26 -0
- package/plugins/icons/index.js +26 -0
- package/plugins/images/index.js +45 -0
- package/plugins/markdown/index.js +1097 -0
- package/plugins/robots/index.js +23 -0
- package/plugins/styles/index.js +69 -0
- package/plugins/vectors/index.js +38 -0
- package/plugins/xml/index.js +196 -0
- package/stylesheets/DefaultStyles.css +329 -263
- package/stylesheets/ResetStyles.css +119 -123
- package/stylesheets/TypographyStyles.css +259 -242
- package/docs-source/assets/styles.css +0 -51
- package/docs-source/blog/home.md +0 -5
- /package/docs-source/{$features → features}/cards.md +0 -0
- /package/docs-source/{$features → features}/editing.md +0 -0
- /package/docs-source/{$features → features}/emoji.md +0 -0
- /package/docs-source/{$features → features}/frontmatter.md +0 -0
- /package/docs-source/{$features → features}/lists.md +0 -0
- /package/docs-source/{$features → features}/navigation.md +0 -0
- /package/docs-source/{$features → features}/rich-previews.md +0 -0
- /package/docs-source/{$features → features}/robots.md +0 -0
- /package/docs-source/{$features → features}/rss.md +0 -0
- /package/docs-source/{$features → features}/sitemap.md +0 -0
- /package/docs-source/{$features → features}/speed.md +0 -0
- /package/docs-source/{$features → features}/static.md +0 -0
- /package/docs-source/{$features → features}/taxonomies.md +0 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** @import * as Votive from "votive" */
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
/** @type {Votive.VotiveProcessor} */
|
|
6
|
+
const processor = {
|
|
7
|
+
extensions: [".txt"],
|
|
8
|
+
format: "text",
|
|
9
|
+
writeFile: (target) => ({ data: target.abstract.content })
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** @type {Votive.VotivePlugin} */
|
|
13
|
+
const plugin = {
|
|
14
|
+
name: "vowel-robots",
|
|
15
|
+
processors: [processor],
|
|
16
|
+
router: ({ name, dir, ext }) => {
|
|
17
|
+
return {
|
|
18
|
+
name, dir, ext
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default plugin
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import path from "node:path"
|
|
2
|
+
import { transform } from "lightningcss"
|
|
3
|
+
|
|
4
|
+
/** @import * as Votive from "votive" */
|
|
5
|
+
|
|
6
|
+
/** @type {Votive.ProcessorWrite} */
|
|
7
|
+
function writeCSS(destination, database, config) {
|
|
8
|
+
const { code, map } = transform({
|
|
9
|
+
filename: destination.path,
|
|
10
|
+
code: Buffer.from(destination.abstract.css),
|
|
11
|
+
minify: true,
|
|
12
|
+
targets: {
|
|
13
|
+
chrome: 146 << 16,
|
|
14
|
+
firefox: 149 << 16,
|
|
15
|
+
safari: 26 << 16
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
const processedCSS = code.toString()
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
data: processedCSS,
|
|
23
|
+
encoding: "utf-8"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
/** @type {Votive.ReadText} */
|
|
30
|
+
function readCSS(text, filePath, destinationPath, database, config) {
|
|
31
|
+
const pathInfo = path.parse(filePath)
|
|
32
|
+
|
|
33
|
+
database.setting.create(
|
|
34
|
+
pathInfo.dir,
|
|
35
|
+
"stylesheets",
|
|
36
|
+
filePath
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
const metadata = {}
|
|
40
|
+
const abstract = {
|
|
41
|
+
css: text
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
metadata,
|
|
46
|
+
abstract
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** @type {Votive.VotiveProcessor} */
|
|
51
|
+
const cssWriter = {
|
|
52
|
+
extensions: [".css"],
|
|
53
|
+
format: "text",
|
|
54
|
+
readFile: readCSS,
|
|
55
|
+
writeFile: writeCSS
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** @type {Votive.VotivePlugin} */
|
|
59
|
+
const vowelStylesPlugin = {
|
|
60
|
+
name: "vowel-styles",
|
|
61
|
+
processors: [cssWriter],
|
|
62
|
+
router: ({ name, dir, ext }) => {
|
|
63
|
+
return {
|
|
64
|
+
name, dir, ext
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export default vowelStylesPlugin
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import fs from "fs/promises"
|
|
2
|
+
/** @import * as Votive from "votive" */
|
|
3
|
+
|
|
4
|
+
/** @type {Votive.ProcessorWrite} */
|
|
5
|
+
async function writeFile(target) {
|
|
6
|
+
return {
|
|
7
|
+
data: target.abstract.svg
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
/** @type {Votive.VotiveProcessor} */
|
|
14
|
+
const processor = {
|
|
15
|
+
extensions: [".svg"],
|
|
16
|
+
format: "text",
|
|
17
|
+
readFile: (text, filePath, destinationPath, database) => {
|
|
18
|
+
const monochrome = text.includes("currentColor") || Boolean(text.match(/#000\b/))
|
|
19
|
+
return {
|
|
20
|
+
abstract: { svg: text },
|
|
21
|
+
metadata: { monochrome }
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
writeFile
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** @type {Votive.VotivePlugin} */
|
|
28
|
+
const plugin = {
|
|
29
|
+
name: "vowel-vectors",
|
|
30
|
+
processors: [processor],
|
|
31
|
+
router: ({ name, dir, ext }) => {
|
|
32
|
+
return {
|
|
33
|
+
name, dir, ext
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default plugin
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import xml from "xml"
|
|
2
|
+
|
|
3
|
+
/** @import * as Votive from "votive" */
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
/** @type {Votive.VotiveProcessor} */
|
|
7
|
+
const processor = {
|
|
8
|
+
extensions: [".xml"],
|
|
9
|
+
format: "text",
|
|
10
|
+
writeFile: (target, database) => {
|
|
11
|
+
if (target.path === "sitemap.xml") {
|
|
12
|
+
|
|
13
|
+
// FIXME move the filter to SQLite
|
|
14
|
+
const pages = database.target
|
|
15
|
+
.getManyWithTrackers({
|
|
16
|
+
folder: "",
|
|
17
|
+
recursive: true,
|
|
18
|
+
query: {},
|
|
19
|
+
dependent: "sitemap.xml"
|
|
20
|
+
})
|
|
21
|
+
.filter(a => a.syntax === ".html" && a.path)
|
|
22
|
+
|
|
23
|
+
const domain = target.metadata.domain
|
|
24
|
+
&& target.metadata.domain.startsWith("http")
|
|
25
|
+
? target.metadata.domain
|
|
26
|
+
: "http://" + target.metadata.domain
|
|
27
|
+
|
|
28
|
+
// FIXME allow falsey returns from writeFile to abort write
|
|
29
|
+
if (!domain) return { data: "" }
|
|
30
|
+
|
|
31
|
+
function createEntry(page) {
|
|
32
|
+
const url = new URL(page.path, domain)
|
|
33
|
+
const entry = `<url><loc>${url.href}</loc><changefreq>daily</changefreq><priority>0.7</priority></url>`
|
|
34
|
+
return entry
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function createSitemap(pages, domain) {
|
|
38
|
+
const entries = pages.map(createEntry).join('')
|
|
39
|
+
return `<?xml version="1.0" encoding="UTF-8" ?>
|
|
40
|
+
<urlset
|
|
41
|
+
xmlns="https://www.sitemaps.org/schemas/sitemap/0.9"
|
|
42
|
+
xmlns:news="https://www.google.com/schemas/sitemap-news/0.9"
|
|
43
|
+
xmlns:xhtml="https://www.w3.org/1999/xhtml"
|
|
44
|
+
xmlns:mobile="https://www.google.com/schemas/sitemap-mobile/1.0"
|
|
45
|
+
xmlns:image="https://www.google.com/schemas/sitemap-image/1.1"
|
|
46
|
+
xmlns:video="https://www.google.com/schemas/sitemap-video/1.1"
|
|
47
|
+
>
|
|
48
|
+
<url>
|
|
49
|
+
<loc>${domain}</loc>
|
|
50
|
+
<changefreq>daily</changefreq>
|
|
51
|
+
<priority>0.7</priority>
|
|
52
|
+
</url>
|
|
53
|
+
${entries}
|
|
54
|
+
</urlset>`
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const sitemap = createSitemap(pages, domain)
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
data: sitemap,
|
|
61
|
+
jobs: []
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
} else if (target.path === "feed.xml") {
|
|
65
|
+
|
|
66
|
+
const pages = database.target.getManyWithTrackers({
|
|
67
|
+
query: {},
|
|
68
|
+
folder: "",
|
|
69
|
+
recursive: true,
|
|
70
|
+
dependent: "feed.xml"
|
|
71
|
+
})
|
|
72
|
+
.filter(a => a.metadata.date)
|
|
73
|
+
.sort((a, b) => b.metadata.date - a.metadata.date)
|
|
74
|
+
|
|
75
|
+
const domain = target.metadata.domain
|
|
76
|
+
&& target.metadata.domain.startsWith("http")
|
|
77
|
+
? target.metadata.domain
|
|
78
|
+
: "http://" + target.metadata.domain
|
|
79
|
+
|
|
80
|
+
const feed = [];
|
|
81
|
+
|
|
82
|
+
feed.push(
|
|
83
|
+
{
|
|
84
|
+
_attr: {
|
|
85
|
+
xmlns: 'http://www.w3.org/2005/Atom'
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
title: target.metadata.title
|
|
90
|
+
}
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
feed.push(
|
|
95
|
+
{
|
|
96
|
+
link: {
|
|
97
|
+
_attr: {
|
|
98
|
+
rel: 'self',
|
|
99
|
+
href: `${domain}/feed`
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
id: `${domain}/feed`
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
if (target.metadata.author)
|
|
109
|
+
feed.push(
|
|
110
|
+
{
|
|
111
|
+
author: {
|
|
112
|
+
name: target.metadata.author
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
{ rights: `Copyright (c) ${new Date().getFullYear()} ${target.metadata.author}` }
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
feed.push(
|
|
119
|
+
...pages.map((page) => {
|
|
120
|
+
const url = (new URL(page.path, domain)).href
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
/** @type {object[]} */
|
|
124
|
+
const entry = [
|
|
125
|
+
{
|
|
126
|
+
title: page.metadata.title
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
link: {
|
|
130
|
+
_attr: {
|
|
131
|
+
rel: 'alternate',
|
|
132
|
+
href: url
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
{ id: url },
|
|
137
|
+
{ updated: page.metadata.date }
|
|
138
|
+
];
|
|
139
|
+
|
|
140
|
+
if (page.metadata.description) {
|
|
141
|
+
entry.push({
|
|
142
|
+
summary: page.metadata.description
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (page.metadata.author) {
|
|
147
|
+
entry.push({
|
|
148
|
+
author: {
|
|
149
|
+
name: page.metadata.author
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// TODO consider rendering full page in RSS
|
|
155
|
+
|
|
156
|
+
/*
|
|
157
|
+
entry.push({
|
|
158
|
+
content: [
|
|
159
|
+
{ _attr: { type: 'html' } },
|
|
160
|
+
render(Page, { props: { page, level: 0, format: 'rss' } }).html
|
|
161
|
+
]
|
|
162
|
+
});
|
|
163
|
+
*/
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
entry
|
|
167
|
+
};
|
|
168
|
+
})
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
const xmlFeed = xml({ feed }, { declaration: true })
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
data: xmlFeed
|
|
176
|
+
}
|
|
177
|
+
} else {
|
|
178
|
+
return {
|
|
179
|
+
data: ""
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** @type {Votive.VotivePlugin} */
|
|
186
|
+
const vowelXMLPlugin = {
|
|
187
|
+
name: "vowel-xml",
|
|
188
|
+
processors: [processor],
|
|
189
|
+
router: ({ name, dir, ext }) => {
|
|
190
|
+
return {
|
|
191
|
+
name, dir, ext
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export default vowelXMLPlugin
|