vowel 0.1.19 → 0.1.20

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vowel",
3
- "version": "0.1.19",
3
+ "version": "0.1.20",
4
4
  "bin": "./bin.js",
5
5
  "scripts": {
6
6
  "dev": "vite dev",
@@ -18,7 +18,6 @@
18
18
  "@sveltejs/adapter-static": "^3.0.1",
19
19
  "@sveltejs/kit": "^2.5.6",
20
20
  "@sveltejs/vite-plugin-svelte": "^4.0.0-next.3",
21
- "@vowel/styles": "^0.0.5",
22
21
  "any-date-parser": "^1.5.4",
23
22
  "change-case": "^5.4.1",
24
23
  "filter-console": "^1.0.0",
@@ -102,6 +102,10 @@
102
102
  margin-bottom: 2.5rem;
103
103
  }
104
104
 
105
+ dt {
106
+ font-size: 1.1em;
107
+ }
108
+
105
109
  dl.link dt {
106
110
  display: none;
107
111
  }
@@ -134,6 +138,20 @@
134
138
  content: '#';
135
139
  }
136
140
 
141
+ dl.contents ul {
142
+ list-style: none;
143
+ padding: 0;
144
+ }
145
+
146
+ dl.contents .depth-2 {
147
+ font-weight: 500;
148
+ }
149
+
150
+ dl.contents .depth-3 {
151
+ font-size: 0.95em;
152
+ padding-left: 0.5em;
153
+ }
154
+
137
155
  /* Header */
138
156
 
139
157
  header {
@@ -11,6 +11,7 @@
11
11
  let { props } = $props();
12
12
  // TODO: Normalize frontmatter props
13
13
  let { properties, website, format } = $derived(props);
14
+ const keys = $derived(Object.keys(properties || {}));
14
15
 
15
16
  const excludedProperties = [
16
17
  'title',
@@ -41,7 +42,7 @@
41
42
  </script>
42
43
 
43
44
  {#if properties}
44
- {#each Object.keys(properties) as key}
45
+ {#each keys as key}
45
46
  {#if !excludedProperties.includes(key)}
46
47
  {@const property = getProperty(properties, key)}
47
48
  {#if website.hasOwnProperty(key)}
@@ -33,7 +33,9 @@
33
33
  }
34
34
  </script>
35
35
 
36
- {#if urlObject}
36
+ {#if urlObject?.pathname?.endsWith('.svg')}
37
+ <object type="image/svg+xml" data={urlObject.href} title={alt}></object>
38
+ {:else if urlObject}
37
39
  <img src={urlObject.href} {alt} {srcset} />
38
40
  {/if}
39
41
 
@@ -87,7 +87,7 @@
87
87
  {:else if node.type === 'url'}
88
88
  <LinkPreview url={node.value} metadata={node.metadata} {format} />
89
89
  {:else if node.type === 'listItem'}
90
- {@const isChecklistItem = node.hasOwnProperty('checked')}
90
+ {@const isChecklistItem = node.checked !== null}
91
91
  {#if isChecklistItem}
92
92
  <li
93
93
  class={`checklist-item ${node.checked ? 'checked' : 'unchecked'}`}
@@ -21,7 +21,7 @@
21
21
  <nav class="top-bar">
22
22
  {#if !child}
23
23
  <a aria-current={isActiveLink(segments)} href={evergreen?.url || evergreen['$']?.url}
24
- >{getFolderLabel(evergreen)}</a
24
+ >{getFolderLabel(evergreen, true)}</a
25
25
  >
26
26
  {/if}
27
27
  {#each Object.keys(evergreen) as key}
@@ -1,5 +1,7 @@
1
1
  <script>
2
2
  import { Markdown, Frontmatter } from '$lib/components';
3
+ import { toString } from 'mdast-util-to-string';
4
+ import { kebabCase } from 'change-case';
3
5
  import Image from './Markdown/Image.svelte';
4
6
 
5
7
  let { page, content = true, link, level = 0, website = {}, format = 'html' } = $props();
@@ -7,6 +9,8 @@
7
9
 
8
10
  const dateObject = date?.type === 'date' && new Date(date.output);
9
11
  // TODO: Add conditional logic for format = 'xml'
12
+
13
+ const headings = ast.filter((child) => child.type === 'heading');
10
14
  </script>
11
15
 
12
16
  <!-- Image -->
@@ -52,6 +56,22 @@
52
56
  <p class="description">{page?.description || page?.imputedProperties.description}</p>
53
57
  {/if}
54
58
 
59
+ {#if format === 'html' && page.toc && headings.length > 1}
60
+ <dl class="contents">
61
+ <dt>Contents</dt>
62
+ <dd>
63
+ <ul>
64
+ {#each headings as heading, index}
65
+ {@const headingString = toString(heading.children)}
66
+ <li class={`heading depth-${heading.depth}`}>
67
+ <a href={`#${kebabCase(headingString)}`}>{headingString}</a>
68
+ </li>
69
+ {/each}
70
+ </ul>
71
+ </dd>
72
+ </dl>
73
+ {/if}
74
+
55
75
  {#if level < 2 && content}
56
76
  <div class="content">
57
77
  <Markdown props={{ ast, level, website, format }} />
@@ -39,7 +39,8 @@
39
39
  picture,
40
40
  video,
41
41
  canvas,
42
- svg {
42
+ svg,
43
+ object {
43
44
  display: block;
44
45
  max-width: 100%;
45
46
  }
@@ -124,4 +125,4 @@
124
125
  box-decoration-break: clone;
125
126
  }
126
127
  </style>
127
- </svelte:head>
128
+ </svelte:head>
@@ -22,9 +22,10 @@ export default function getFileLabel(page, shorter = false, date = true) {
22
22
  : false;
23
23
 
24
24
  return (
25
- page?.breadcrumb ||
25
+ (shorter && page?.breadcrumb) ||
26
26
  page?.title ||
27
27
  page?.imputedProperties?.title ||
28
+ page?.breadcrumb ||
28
29
  formattedDate ||
29
30
  (shorter && fileName) ||
30
31
  description ||
@@ -0,0 +1,110 @@
1
+ <script>
2
+ import { page } from '$app/stores';
3
+ import {
4
+ Nav,
5
+ Page,
6
+ Breadcrumbs,
7
+ Sitemap,
8
+ ResetStyles,
9
+ DefaultStyles,
10
+ TypographyStyles,
11
+ NoStyles
12
+ } from '$lib/components/index.js';
13
+ import { invalidateAll } from '$app/navigation';
14
+
15
+ const themes = {
16
+ none: NoStyles,
17
+ reset: ResetStyles,
18
+ typography: TypographyStyles,
19
+ default: DefaultStyles
20
+ };
21
+
22
+ let { error: data } = $page;
23
+
24
+ const { website } = $derived(data);
25
+
26
+ const { slogan, theme } = $derived(website?._);
27
+
28
+ // Import CSS for HMR in dev mode
29
+ if (data.dev && data.files.css.exists) {
30
+ import(/* @vite-ignore */ data.files.css.path);
31
+ }
32
+
33
+ const siteTitle = website._.title;
34
+
35
+ function makePageMetaTitle() {
36
+ if (siteTitle) return `Page not found = ${siteTitle}`;
37
+ return `Page not found`;
38
+ }
39
+
40
+ function getFavicon() {
41
+ if (website._?.icon)
42
+ return `data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 20 90 60%22><text y=%22.9em%22 font-size=%2290%22>${website._.icon}</text></svg>`;
43
+ if (data.files.favicon.exists) return '/favicon.png';
44
+ return false;
45
+ }
46
+
47
+ const favicon = getFavicon();
48
+
49
+ $effect(() => {
50
+ // Update website on file change
51
+ if (import.meta.hot) {
52
+ import.meta.hot.on('vowel:update', ({ path, file }) => {
53
+ invalidateAll().then(() => {
54
+ window.location.reload();
55
+ });
56
+ });
57
+ import.meta.hot.on('vowel:refresh', () => {
58
+ console.log('Refresh');
59
+ invalidateAll().then(() => {
60
+ window.location.reload();
61
+ });
62
+ });
63
+ }
64
+ });
65
+ </script>
66
+
67
+ <svelte:component this={themes[theme || 'default']} />
68
+
69
+ <svelte:head>
70
+ <title>{makePageMetaTitle()}</title>
71
+ <meta property="og:site_name" content={website._.title} />
72
+ {#if favicon}
73
+ <link rel="icon" href={favicon} />
74
+ {/if}
75
+ {#if !data.dev && data.files.css.exists}
76
+ <link rel="stylesheet" href="/styles.css" />
77
+ {/if}
78
+ </svelte:head>
79
+
80
+ <div data-sveltekit-preload-data="hover" class="page 404">
81
+ <header>
82
+ {#if website._.logo}
83
+ <a href="/" class="site-logo">
84
+ {#if website._.logo.endsWith('.svg')}
85
+ <object type="image/svg+xml" data={website._.logo} title={website._.title || undefined}
86
+ ></object>
87
+ {:else}
88
+ <img alt="website logo" src={website._.logo} />
89
+ {/if}
90
+ </a>
91
+ {/if}
92
+ {#if siteTitle}
93
+ <a href="/" class="site-title">{siteTitle}</a>
94
+ {/if}
95
+ {#if website._.slogan}
96
+ <p class="slogan">{website._.slogan}</p>
97
+ {/if}
98
+ <Nav folder={website} segments={['']} />
99
+ </header>
100
+ <main>
101
+ <h1>Page Not Found</h1>
102
+ </main>
103
+ <nav class="sidebar">
104
+ <Sitemap section={website} segments={['']} root />
105
+ </nav>
106
+ <footer>
107
+ © {website._.author ? website._.author + ' ' : ''}
108
+ {new Date().getFullYear()}
109
+ </footer>
110
+ </div>
@@ -4,6 +4,8 @@ import { constants } from 'fs';
4
4
  import { normalize, join, basename } from 'path';
5
5
  import { dev } from '$app/environment';
6
6
  import mri from 'mri';
7
+ import { getPage } from '../../lib/utilities';
8
+ import { error } from '@sveltejs/kit';
7
9
 
8
10
  const args = mri(process.argv);
9
11
  const isBuild = args._.includes('build');
@@ -1,11 +1,6 @@
1
- import {
2
- getPagesByFolder,
3
- processMarkdownFiles,
4
- loadCache,
5
- checkFileExists,
6
- readMarkdownFile
7
- } from '../../lib/utilities';
8
- import { join } from 'path';
1
+ import { getPagesByFolder, processMarkdownFiles, loadCache } from '../../lib/utilities';
2
+
3
+ export const prerender = true;
9
4
 
10
5
  /** @type {import('./$types').PageLoad} */
11
6
  export async function load({ params }) {
@@ -15,8 +10,6 @@ export async function load({ params }) {
15
10
  return { path, segments };
16
11
  }
17
12
 
18
- export const prerender = true;
19
-
20
13
  export async function entries() {
21
14
  const initialCache = await loadCache($home[0]);
22
15
 
@@ -14,7 +14,7 @@
14
14
  import { error } from '@sveltejs/kit';
15
15
  import { getFolder, getFolderLabel } from '../../lib/utilities';
16
16
  import { page as pageStore } from '$app/stores';
17
- import { goto, invalidate, invalidateAll } from '$app/navigation';
17
+ import { invalidateAll } from '$app/navigation';
18
18
 
19
19
  const themes = {
20
20
  none: NoStyles,
@@ -27,6 +27,8 @@
27
27
 
28
28
  const { website, folderName } = $derived(data);
29
29
 
30
+ throw error(404, { message: 'Page not found', ...data });
31
+
30
32
  const { slogan, theme } = $derived(website._);
31
33
 
32
34
  // Import CSS for HMR in dev mode
@@ -42,7 +44,7 @@
42
44
 
43
45
  const websiteTitle = data.website._.title || data.folderName;
44
46
  const pageMetaTitle = $derived(getFileLabel(page));
45
- const siteTitle = website._.title || folderName;
47
+ const siteTitle = website._.title;
46
48
 
47
49
  function getBreadcrumbs(level = 0) {
48
50
  const path = $pageStore.data.segments.slice(0, level).join('/');
@@ -73,8 +75,6 @@
73
75
 
74
76
  const favicon = getFavicon();
75
77
 
76
- let key = $state(Date.now());
77
-
78
78
  $effect(() => {
79
79
  // Update website on file change
80
80
  if (import.meta.hot) {
@@ -131,7 +131,12 @@
131
131
  <header>
132
132
  {#if website._.logo}
133
133
  <a href="/" class="site-logo">
134
- <img alt="website logo" src={website._.logo} />
134
+ {#if website._.logo.endsWith('.svg')}
135
+ <object type="image/svg+xml" data={website._.logo} title={website._.title || undefined}
136
+ ></object>
137
+ {:else}
138
+ <img alt="website logo" src={website._.logo} />
139
+ {/if}
135
140
  </a>
136
141
  {/if}
137
142
  {#if siteTitle}