astro-accelerator 5.9.21 → 5.10.1
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/astro.config.mjs +2 -0
- package/package.json +3 -3
- package/public/css/AtkinsonHyperlegibleMono-Regular.otf +0 -0
- package/public/css/AtkinsonHyperlegibleNext-Bold.otf +0 -0
- package/public/css/AtkinsonHyperlegibleNext-Regular.otf +0 -0
- package/public/css/main.css +498 -347
- package/public/css/vars.css +84 -65
- package/src/config.ts +9 -3
- package/src/themes/accelerator/components/AuthorsMini.astro +64 -26
- package/src/themes/accelerator/components/ReadingTime.astro +44 -0
- package/src/themes/accelerator/layouts/Default.astro +102 -83
- package/src/themes/accelerator/utilities/language.json +6 -0
- package/src/themes/accelerator/utilities/reading-time.mjs +18 -0
package/public/css/vars.css
CHANGED
|
@@ -1,94 +1,113 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
:root {
|
|
10
|
-
--fore: #333;
|
|
11
|
-
--fore-headings: #225;
|
|
12
|
-
--aft: #fbfbfc;
|
|
1
|
+
@font-face {
|
|
2
|
+
font-family: "hyper-reg";
|
|
3
|
+
font-weight: normal;
|
|
4
|
+
font-style: normal;
|
|
5
|
+
src: url("AtkinsonHyperlegibleNext-Regular.otf");
|
|
6
|
+
font-display: block;
|
|
7
|
+
}
|
|
13
8
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
@font-face {
|
|
10
|
+
font-family: "hyper-bold";
|
|
11
|
+
font-weight: bold;
|
|
12
|
+
font-style: normal;
|
|
13
|
+
src: url("AtkinsonHyperlegibleNext-Bold.otf");
|
|
14
|
+
font-display: block;
|
|
15
|
+
}
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
@font-face {
|
|
18
|
+
font-family: "hyper-mono";
|
|
19
|
+
font-weight: bold;
|
|
20
|
+
font-style: normal;
|
|
21
|
+
src: url("AtkinsonHyperlegibleMono-Regular.otf");
|
|
22
|
+
font-display: block;
|
|
23
|
+
}
|
|
21
24
|
|
|
22
|
-
|
|
23
|
-
--
|
|
25
|
+
:root {
|
|
26
|
+
--fore: #233;
|
|
27
|
+
--aft: #DFF;
|
|
28
|
+
--aft-image: #DFF;
|
|
24
29
|
|
|
25
|
-
--link
|
|
26
|
-
--link-alt
|
|
30
|
+
--fore-link: #355;
|
|
31
|
+
--fore-link-alt: #699;
|
|
32
|
+
--aft-link-alt: #e6e6eC;
|
|
33
|
+
|
|
34
|
+
--fore-input: var(--fore);
|
|
35
|
+
--aft-input: var(--aft);
|
|
27
36
|
|
|
28
37
|
--fore-block: #333;
|
|
29
|
-
--aft-block: #
|
|
30
|
-
--icon-block: #
|
|
38
|
+
--aft-block: #BEE;
|
|
39
|
+
--icon-block: #FF0;
|
|
31
40
|
|
|
32
|
-
--fore-table-head: #
|
|
33
|
-
--aft-table-head: #
|
|
41
|
+
--fore-table-head: #DFF;
|
|
42
|
+
--aft-table-head: #233;
|
|
34
43
|
--fore-table-row-odd: #333;
|
|
35
|
-
--aft-table-row-odd: #
|
|
44
|
+
--aft-table-row-odd: #DFF;
|
|
36
45
|
--fore-table-row-even: #333;
|
|
37
|
-
--aft-table-row-even: #
|
|
46
|
+
--aft-table-row-even: #CFF;
|
|
47
|
+
|
|
48
|
+
--heading-font: 'hyper-bold', sans-serif;
|
|
49
|
+
--content-font: 'hyper-reg', Verdana, Geneva, sans-serif;
|
|
50
|
+
--code-font: 'hyper-mono', Consolas, 'Courier New', Courier, monospace;
|
|
51
|
+
--unicode-font: font-family: "Segoe UI Symbol", "Arial Unicode MS", "DejaVu Sans", "Meiryo UI", "MS UI Gothic", "Everson Mono Unicode", Meiryo, "MS Gothic", "MS Mincho", "MS PGothic", "MS PMincho", "Meslo LG L", "Meslo LG L DZ", "Meslo M L", "Meslo M L DZ", "Meslo S L", "Meslo S L DZ", "Symbola", "DejaVu Sans Condensed", "DejaVu Sans Mono", Code2000, "Everson Mono", Quivira, sans-serif;
|
|
38
52
|
|
|
39
|
-
--
|
|
40
|
-
--
|
|
41
|
-
--
|
|
42
|
-
--
|
|
53
|
+
--font-size-meta: 0.9rem;
|
|
54
|
+
--font-size-h1: 3rem;
|
|
55
|
+
--font-size-h2: 2.3rem;
|
|
56
|
+
--font-size-h3: 2rem;
|
|
57
|
+
--font-size-h4: 1.7rem;
|
|
58
|
+
--font-size-h5: 1.7rem;
|
|
59
|
+
--font-size-h6: 1.7rem;
|
|
43
60
|
|
|
61
|
+
--paragraph-margin: 1.2rem;
|
|
44
62
|
--block-gap: 2rem;
|
|
63
|
+
--block-gap-l: 3rem;
|
|
45
64
|
--block-radius: 0.3rem;
|
|
65
|
+
--block-radius-round: 20px;
|
|
46
66
|
|
|
47
67
|
--marker-size: 1.2rem;
|
|
48
|
-
--paragraph-margin: 1.2rem;
|
|
49
68
|
|
|
50
|
-
--box-shadow: 0 12px 24px -12px rgb(0 0 0 /
|
|
69
|
+
--box-shadow: 0 12px 24px -12px rgb(0 0 0 / 50%);
|
|
51
70
|
--box-shadow-slight: 0 6px 12px -6px rgb(0 0 0 / 40%);
|
|
52
71
|
|
|
53
|
-
--
|
|
54
|
-
--
|
|
55
|
-
|
|
56
|
-
--
|
|
57
|
-
--
|
|
72
|
+
--box-shadow-unselected: rgb(0 0 0 / 6%) 0px 2px 4px, rgb(0 0 0 / 5%) 0px 0.5px 1px;
|
|
73
|
+
--transform-selected: translate3d(0px, -1px, 0px);
|
|
74
|
+
|
|
75
|
+
--content-width: 50rem;
|
|
76
|
+
--navigation-width: 300px;
|
|
77
|
+
--grid-gap: 1rem;
|
|
78
|
+
--grid-gap-s: 0.4rem;
|
|
79
|
+
|
|
80
|
+
/* Calculate the mobile width by removing l/r columns */
|
|
81
|
+
--content-width-mobile: calc(100vw - 1rem);
|
|
58
82
|
|
|
59
|
-
/*
|
|
60
|
-
--
|
|
83
|
+
/* Search variables */
|
|
84
|
+
--search-height: 2rem;
|
|
85
|
+
--search-dropdown-height: 65vh;
|
|
86
|
+
--search-dropdown-duration: 0.2s;
|
|
61
87
|
}
|
|
62
88
|
|
|
63
89
|
@media (prefers-color-scheme: dark) {
|
|
64
90
|
:root {
|
|
65
|
-
--fore: #
|
|
66
|
-
--
|
|
67
|
-
--aft: #
|
|
68
|
-
|
|
69
|
-
--fore-link: #
|
|
70
|
-
--fore-link-alt: #
|
|
91
|
+
--fore: #DFF;
|
|
92
|
+
--aft: #233;
|
|
93
|
+
--aft-image: #DDD;
|
|
94
|
+
|
|
95
|
+
--fore-link: #AFF;
|
|
96
|
+
--fore-link-alt: #FF0;
|
|
71
97
|
--aft-link-alt: #232323;
|
|
72
98
|
|
|
73
|
-
--fore-
|
|
74
|
-
--aft-
|
|
75
|
-
--icon-head: #abb9ef;
|
|
76
|
-
|
|
77
|
-
--fore-breadcrumb: #ccc;
|
|
78
|
-
--aft-breadcrumb: #2c2c2c;
|
|
79
|
-
|
|
80
|
-
--link-head: #abb9ef;
|
|
81
|
-
--link-alt-head: #6580ed;
|
|
99
|
+
--fore-input: #var(--fore);
|
|
100
|
+
--aft-input: var(--aft);
|
|
82
101
|
|
|
83
|
-
--fore-block: #
|
|
84
|
-
--aft-block: #
|
|
85
|
-
--icon-block: #
|
|
102
|
+
--fore-block: #DFF;
|
|
103
|
+
--aft-block: #011;
|
|
104
|
+
--icon-block: #FF0;
|
|
86
105
|
|
|
87
|
-
--fore-table-head: #
|
|
88
|
-
--aft-table-head: #
|
|
89
|
-
--fore-table-row-odd: #
|
|
90
|
-
--aft-table-row-odd: #
|
|
91
|
-
--fore-table-row-even: #
|
|
92
|
-
--aft-table-row-even: #
|
|
106
|
+
--fore-table-head: #DFF;
|
|
107
|
+
--aft-table-head: #244;
|
|
108
|
+
--fore-table-row-odd: #DFF;
|
|
109
|
+
--aft-table-row-odd: #355;
|
|
110
|
+
--fore-table-row-even: #DFF;
|
|
111
|
+
--aft-table-row-even: #466;
|
|
93
112
|
}
|
|
94
113
|
}
|
package/src/config.ts
CHANGED
|
@@ -33,6 +33,11 @@ const SITE: Site = {
|
|
|
33
33
|
month: 'long',
|
|
34
34
|
day: 'numeric',
|
|
35
35
|
},
|
|
36
|
+
shortDateOptions: {
|
|
37
|
+
year: 'numeric',
|
|
38
|
+
month: 'short',
|
|
39
|
+
day: 'numeric',
|
|
40
|
+
},
|
|
36
41
|
cacheMaxAge: 200,
|
|
37
42
|
featureFlags: {
|
|
38
43
|
stickyNav: { top: 100 },
|
|
@@ -45,8 +50,7 @@ const SITE: Site = {
|
|
|
45
50
|
},
|
|
46
51
|
images: {
|
|
47
52
|
// Generated using https://ausi.github.io/respimagelint/
|
|
48
|
-
contentSize:
|
|
49
|
-
'(min-width: 1280px) 668px, (min-width: 880px) calc(72.11vw - 241px), calc(100vw - 64px)',
|
|
53
|
+
contentSize: '(min-width: 1280px) 668px, (min-width: 880px) calc(72.11vw - 241px), calc(100vw - 64px)',
|
|
50
54
|
listerSize:
|
|
51
55
|
'(min-width: 1300px) 350px, (min-width: 880px) calc(34.25vw - 88px), (min-width: 700px) 50vw, calc(100vw - 32px)',
|
|
52
56
|
authorSize: '50px',
|
|
@@ -62,7 +66,9 @@ const OPEN_GRAPH = {
|
|
|
62
66
|
};
|
|
63
67
|
|
|
64
68
|
const HEADER_SCRIPTS = `
|
|
65
|
-
|
|
69
|
+
<meta name="copyright" content="Steve Fenton">
|
|
70
|
+
<link rel="preload" href="/css/AtkinsonHyperlegibleNext-Bold.otf" as="font" crossorigin>
|
|
71
|
+
<link rel="preload" href="/css/AtkinsonHyperlegibleNext-Regular.otf" as="font" crossorigin>
|
|
66
72
|
`.trim();
|
|
67
73
|
|
|
68
74
|
export { SITE, OPEN_GRAPH, HEADER_SCRIPTS };
|
|
@@ -4,16 +4,20 @@
|
|
|
4
4
|
import { Accelerator } from 'astro-accelerator-utils';
|
|
5
5
|
import type { Frontmatter } from 'astro-accelerator-utils/types/Frontmatter';
|
|
6
6
|
import { SITE } from '@config';
|
|
7
|
-
import { Translations, Lang } from '@util/Languages'
|
|
7
|
+
import { Translations, Lang } from '@util/Languages';
|
|
8
|
+
import { getImageInfo } from '@util/custom-markdown.mjs';
|
|
9
|
+
import ReadingTime from '@components/ReadingTime.astro';
|
|
8
10
|
|
|
9
11
|
const accelerator = new Accelerator(SITE);
|
|
10
|
-
const stats = new accelerator.statistics(
|
|
12
|
+
const stats = new accelerator.statistics(
|
|
13
|
+
'accelerator/components/AuthorsMini.astro'
|
|
14
|
+
);
|
|
11
15
|
stats.start();
|
|
12
16
|
|
|
13
17
|
// Properties
|
|
14
18
|
type Props = {
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
lang: string;
|
|
20
|
+
frontmatter: Frontmatter;
|
|
17
21
|
};
|
|
18
22
|
const { lang, frontmatter } = Astro.props satisfies Props;
|
|
19
23
|
|
|
@@ -22,29 +26,63 @@ const _ = Lang(lang);
|
|
|
22
26
|
|
|
23
27
|
// Logic
|
|
24
28
|
const authorList = accelerator.authors.forPost(frontmatter);
|
|
29
|
+
const dateToShow =
|
|
30
|
+
frontmatter.modDate == null ? frontmatter.pubDate : frontmatter.modDate;
|
|
31
|
+
|
|
32
|
+
// Get image info
|
|
33
|
+
const authorImage = authorList?.image?.src
|
|
34
|
+
? getImageInfo(authorList.image.src, 'author-image', SITE.images.authorSize)
|
|
35
|
+
: null;
|
|
25
36
|
|
|
26
37
|
stats.stop();
|
|
27
38
|
---
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
39
|
+
|
|
40
|
+
{
|
|
41
|
+
authorList.writers.length > 0 && (
|
|
42
|
+
<div class="post-meta mini">
|
|
43
|
+
<div class="author-info">
|
|
44
|
+
{authorImage && (
|
|
45
|
+
<img
|
|
46
|
+
srcset={authorImage.srcset}
|
|
47
|
+
sizes={authorImage.sizes}
|
|
48
|
+
src={authorImage.src}
|
|
49
|
+
alt={authorList?.image?.alt}
|
|
50
|
+
class={authorImage.class}
|
|
51
|
+
width={authorImage.metadata?.width}
|
|
52
|
+
height={authorImage.metadata?.height}
|
|
53
|
+
/>
|
|
54
|
+
)}
|
|
55
|
+
{authorList.mainAuthor && (
|
|
56
|
+
<a
|
|
57
|
+
href={
|
|
58
|
+
accelerator.urlFormatter.formatAddress(
|
|
59
|
+
authorList.mainAuthor.url
|
|
60
|
+
) + '1/'
|
|
61
|
+
}
|
|
62
|
+
class="author-name">
|
|
63
|
+
{authorList.mainAuthor.frontmatter.title}
|
|
64
|
+
</a>
|
|
65
|
+
)}
|
|
66
|
+
{authorList.contributors.map((writer) => (
|
|
67
|
+
<a
|
|
68
|
+
href={
|
|
69
|
+
accelerator.urlFormatter.formatAddress(writer.url) +
|
|
70
|
+
'1/'
|
|
71
|
+
}
|
|
72
|
+
class="contributor-name">
|
|
73
|
+
{writer.frontmatter.title}
|
|
74
|
+
</a>
|
|
75
|
+
))}
|
|
76
|
+
<time
|
|
77
|
+
class="post-date"
|
|
78
|
+
datetime={dateToShow.toString()}
|
|
79
|
+
set:html={accelerator.dateFormatter.formatShortDate(
|
|
80
|
+
dateToShow,
|
|
81
|
+
lang
|
|
82
|
+
)}
|
|
83
|
+
/>
|
|
84
|
+
<ReadingTime lang={lang} frontmatter={frontmatter} />
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
)
|
|
50
88
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
// warning: This file is overwritten by Astro Accelerator
|
|
3
|
+
|
|
4
|
+
import { Accelerator } from 'astro-accelerator-utils';
|
|
5
|
+
import type { Frontmatter } from 'astro-accelerator-utils/types/Frontmatter';
|
|
6
|
+
import { SITE } from '@config';
|
|
7
|
+
import { Translations, Lang } from '@util/Languages';
|
|
8
|
+
|
|
9
|
+
const accelerator = new Accelerator(SITE);
|
|
10
|
+
const stats = new accelerator.statistics(
|
|
11
|
+
'accelerator/components/ReadingTime.astro'
|
|
12
|
+
);
|
|
13
|
+
stats.start();
|
|
14
|
+
|
|
15
|
+
// Properties
|
|
16
|
+
type Props = {
|
|
17
|
+
lang: string;
|
|
18
|
+
frontmatter: Frontmatter;
|
|
19
|
+
};
|
|
20
|
+
const { lang, frontmatter } = Astro.props satisfies Props;
|
|
21
|
+
|
|
22
|
+
// Language
|
|
23
|
+
const _ = Lang(lang);
|
|
24
|
+
|
|
25
|
+
// Logic
|
|
26
|
+
const readingTimeText =
|
|
27
|
+
frontmatter?.readingTime === 1
|
|
28
|
+
? _(Translations.post.reading_time_one_minute).replace(
|
|
29
|
+
'{n}',
|
|
30
|
+
frontmatter.readingTime
|
|
31
|
+
)
|
|
32
|
+
: _(Translations.post.reading_time_many_minutes).replace(
|
|
33
|
+
'{n}',
|
|
34
|
+
frontmatter.readingTime
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
stats.stop();
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
{
|
|
41
|
+
frontmatter?.readingTime && (
|
|
42
|
+
<span class="reading-time" set:html={readingTimeText} />
|
|
43
|
+
)
|
|
44
|
+
}
|
|
@@ -1,116 +1,135 @@
|
|
|
1
1
|
---
|
|
2
2
|
// warning: This file is overwritten by Astro Accelerator
|
|
3
3
|
|
|
4
|
-
import { Accelerator, PostFiltering } from
|
|
5
|
-
import type { Frontmatter } from
|
|
6
|
-
import { getImageInfo } from
|
|
7
|
-
import { SITE } from
|
|
8
|
-
import Head from
|
|
9
|
-
import Header from
|
|
10
|
-
import Footer from
|
|
11
|
-
import Copyright from
|
|
12
|
-
import SkipLinks from
|
|
13
|
-
import Breadcrumbs from
|
|
14
|
-
import Navigation from
|
|
15
|
-
import TableOfContents from
|
|
16
|
-
import Authors from
|
|
17
|
-
import
|
|
18
|
-
import
|
|
4
|
+
import { Accelerator, PostFiltering } from 'astro-accelerator-utils';
|
|
5
|
+
import type { Frontmatter } from 'astro-accelerator-utils/types/Frontmatter';
|
|
6
|
+
import { getImageInfo } from '@util/custom-markdown.mjs';
|
|
7
|
+
import { SITE } from '@config';
|
|
8
|
+
import Head from '@components/HtmlHead.astro';
|
|
9
|
+
import Header from '@components/Header.astro';
|
|
10
|
+
import Footer from '@components/Footer.astro';
|
|
11
|
+
import Copyright from '@components/Copyright.astro';
|
|
12
|
+
import SkipLinks from '@components/SkipLinks.astro';
|
|
13
|
+
import Breadcrumbs from '@components/Breadcrumbs.astro';
|
|
14
|
+
import Navigation from '@components/Navigation.astro';
|
|
15
|
+
import TableOfContents from '@components/TableOfContents.astro';
|
|
16
|
+
import Authors from '@components/Authors.astro';
|
|
17
|
+
import AuthorsMini from '@components/AuthorsMini.astro';
|
|
18
|
+
import Taxonomy from '@components/Taxonomy.astro';
|
|
19
|
+
import Related from '@components/Related.astro';
|
|
19
20
|
|
|
20
21
|
const accelerator = new Accelerator(SITE);
|
|
21
|
-
const stats = new accelerator.statistics(
|
|
22
|
+
const stats = new accelerator.statistics('accelerator/layouts/Default.astro');
|
|
22
23
|
stats.start();
|
|
23
24
|
|
|
24
25
|
type Props = {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
frontmatter: Frontmatter;
|
|
27
|
+
headings: { depth: number; slug: string; text: string }[];
|
|
28
|
+
breadcrumbs?: { url: string; title: string; ariaCurrent?: string }[] | null;
|
|
28
29
|
};
|
|
29
|
-
const { frontmatter, headings, breadcrumbs } =
|
|
30
|
+
const { frontmatter, headings, breadcrumbs, data } =
|
|
31
|
+
Astro.props satisfies Props;
|
|
30
32
|
|
|
31
33
|
const lang = frontmatter.lang ?? SITE.default.lang;
|
|
32
34
|
const textDirection = frontmatter.dir ?? SITE.default.dir;
|
|
33
35
|
|
|
34
36
|
// Logic
|
|
35
37
|
const metaImage = frontmatter.bannerImage
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
? getImageInfo(frontmatter.bannerImage.src, '', SITE.images.contentSize)
|
|
39
|
+
: null;
|
|
38
40
|
|
|
39
41
|
const title = await accelerator.markdown.getInlineHtmlFrom(
|
|
40
|
-
|
|
42
|
+
frontmatter.title ?? SITE.title
|
|
41
43
|
);
|
|
42
44
|
const subtitle = frontmatter.subtitle
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
? await accelerator.markdown.getInlineHtmlFrom(frontmatter.subtitle)
|
|
46
|
+
: null;
|
|
45
47
|
|
|
46
48
|
const site_url = SITE.url;
|
|
47
49
|
const site_features = SITE.featureFlags;
|
|
48
50
|
const search =
|
|
49
|
-
|
|
51
|
+
accelerator.posts.all().filter(PostFiltering.isSearch).shift() ?? null;
|
|
50
52
|
const searchUrl = search && accelerator.urlFormatter.formatAddress(search.url);
|
|
51
53
|
const isSearchPage =
|
|
52
|
-
|
|
54
|
+
accelerator.urlFormatter.formatAddress(Astro.url.pathname) === searchUrl;
|
|
53
55
|
const showSearch = !isSearchPage;
|
|
54
56
|
|
|
55
57
|
stats.stop();
|
|
56
58
|
---
|
|
57
59
|
|
|
58
60
|
<html dir={textDirection} lang={lang} class="initial">
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
61
|
+
<Head frontmatter={frontmatter} headings={headings} lang={lang} />
|
|
62
|
+
<body>
|
|
63
|
+
<SkipLinks frontmatter={frontmatter} headings={headings} lang={lang} />
|
|
64
|
+
<Header
|
|
65
|
+
frontmatter={frontmatter}
|
|
66
|
+
headings={headings}
|
|
67
|
+
lang={lang}
|
|
68
|
+
showSearch={showSearch}
|
|
69
|
+
/>
|
|
70
|
+
<Breadcrumbs
|
|
71
|
+
frontmatter={frontmatter}
|
|
72
|
+
headings={headings}
|
|
73
|
+
lang={lang}
|
|
74
|
+
breadcrumbs={breadcrumbs}
|
|
75
|
+
/>
|
|
76
|
+
<div class="content-group">
|
|
77
|
+
<main id="site-main">
|
|
78
|
+
<article itemscope itemtype="https://schema.org/Article">
|
|
79
|
+
<header>
|
|
80
|
+
<h1 itemprop="name headline">
|
|
81
|
+
<Fragment set:html={title} />
|
|
82
|
+
</h1>
|
|
83
|
+
{
|
|
84
|
+
subtitle && (
|
|
85
|
+
<p>
|
|
86
|
+
<Fragment set:html={subtitle} />
|
|
87
|
+
</p>
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
</header>
|
|
91
|
+
<div
|
|
92
|
+
class="page-content anim-show-parent"
|
|
93
|
+
itemprop="articleBody">
|
|
94
|
+
<AuthorsMini frontmatter={frontmatter} lang={lang} />
|
|
95
|
+
<TableOfContents
|
|
96
|
+
frontmatter={frontmatter}
|
|
97
|
+
headings={headings}
|
|
98
|
+
lang={lang}
|
|
99
|
+
/>
|
|
100
|
+
<slot />
|
|
101
|
+
<Authors frontmatter={frontmatter} lang={lang} />
|
|
102
|
+
<Taxonomy frontmatter={frontmatter} lang={lang} />
|
|
103
|
+
<Related
|
|
104
|
+
frontmatter={frontmatter}
|
|
105
|
+
headings={headings}
|
|
106
|
+
lang={lang}
|
|
107
|
+
/>
|
|
108
|
+
{
|
|
109
|
+
metaImage && (
|
|
110
|
+
<meta
|
|
111
|
+
itemprop="image"
|
|
112
|
+
content={metaImage.src}
|
|
113
|
+
/>
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
</div>
|
|
117
|
+
</article>
|
|
118
|
+
</main>
|
|
119
|
+
<Navigation lang={lang} />
|
|
120
|
+
</div>
|
|
121
|
+
<Footer frontmatter={frontmatter} headings={headings} lang={lang}>
|
|
122
|
+
<Copyright
|
|
123
|
+
frontmatter={frontmatter}
|
|
124
|
+
headings={headings}
|
|
125
|
+
lang={lang}
|
|
92
126
|
/>
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
{metaImage && <meta itemprop="image" content={metaImage.src} />}
|
|
102
|
-
</div>
|
|
103
|
-
</article>
|
|
104
|
-
</main>
|
|
105
|
-
<Navigation lang={lang} />
|
|
106
|
-
</div>
|
|
107
|
-
<Footer frontmatter={frontmatter} headings={headings} lang={lang}>
|
|
108
|
-
<Copyright frontmatter={frontmatter} headings={headings} lang={lang} />
|
|
109
|
-
</Footer>
|
|
110
|
-
<script define:vars={{ site_url, site_features }}>
|
|
111
|
-
window.site_url = site_url;
|
|
112
|
-
window.site_features = site_features;
|
|
113
|
-
</script>
|
|
114
|
-
<script src={SITE.subfolder + "/js/main.js"} type="module" async></script>
|
|
115
|
-
</body>
|
|
127
|
+
</Footer>
|
|
128
|
+
<script define:vars={{ site_url, site_features }}>
|
|
129
|
+
window.site_url = site_url;
|
|
130
|
+
window.site_features = site_features;
|
|
131
|
+
</script>
|
|
132
|
+
<script src={SITE.subfolder + '/js/main.js'} type="module" async
|
|
133
|
+
></script>
|
|
134
|
+
</body>
|
|
116
135
|
</html>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** @format */
|
|
2
|
+
|
|
3
|
+
import { toString } from 'mdast-util-to-string';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Remark plugin for calculating reading time
|
|
7
|
+
*/
|
|
8
|
+
export function readingTime() {
|
|
9
|
+
return function (tree, { data }) {
|
|
10
|
+
const wordsPerMinute = 200;
|
|
11
|
+
const textOnPage = toString(tree);
|
|
12
|
+
const readingTime = Math.ceil(
|
|
13
|
+
textOnPage.split(' ').length / wordsPerMinute
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
data.astro.frontmatter.readingTime = readingTime;
|
|
17
|
+
};
|
|
18
|
+
}
|