Compare commits
5 Commits
3f24f42c1f
...
astro
| Author | SHA1 | Date | |
|---|---|---|---|
| 67779ecd40 | |||
| eda7d3aa00 | |||
| e0af57e5b1 | |||
| 675ef1003d | |||
| 68bb25357b |
@@ -49,7 +49,7 @@ My word-search grid appears to be 140 characters by 140, so I'm just going to ha
|
|||||||
|
|
||||||
Not gonna lie here, this part took me _way_ longer than I expected it to. See, the standard way to read a file in Fortran is with the `read()` statement. (It looks like a function call, but it's not.) You use it something like this:
|
Not gonna lie here, this part took me _way_ longer than I expected it to. See, the standard way to read a file in Fortran is with the `read()` statement. (It looks like a function call, but it's not.) You use it something like this:
|
||||||
|
|
||||||
```fortran
|
```f90
|
||||||
read(file_handle, *) somevar, anothervar, anothervar2
|
read(file_handle, *) somevar, anothervar, anothervar2
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ Or at least, that's one way of using it. But here's the problem: by default, For
|
|||||||
|
|
||||||
Initially, I thought I might be able to do this:
|
Initially, I thought I might be able to do this:
|
||||||
|
|
||||||
```fortran
|
```f90
|
||||||
character, dimension(140, 140) :: grid
|
character, dimension(140, 140) :: grid
|
||||||
|
|
||||||
! ...later
|
! ...later
|
||||||
@@ -70,7 +70,7 @@ But sadly, this kept spitting out errors about how it had encountered the end of
|
|||||||
|
|
||||||
My next try looked something like this:
|
My next try looked something like this:
|
||||||
|
|
||||||
```fortran
|
```f90
|
||||||
do row = 1, 100
|
do row = 1, 100
|
||||||
read(file_handle, *) grid(row, :)
|
read(file_handle, *) grid(row, :)
|
||||||
end do
|
end do
|
||||||
@@ -82,7 +82,7 @@ I'm pretty sure the proper way to do this would be to figure out how to set the
|
|||||||
|
|
||||||
So instead, I decided to just make it dumber.
|
So instead, I decided to just make it dumber.
|
||||||
|
|
||||||
```fortran
|
```f90
|
||||||
program advent04
|
program advent04
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ S A M X M A S
|
|||||||
S . . S . . S
|
S . . S . . S
|
||||||
```
|
```
|
||||||
|
|
||||||
Which has all 8 possible orientationS of the word `XMAS` starting from the central X. Then, we can just take a sliding "window" of the same size into our puzzle grid and compare it to the test grid. This is a native operation in Fortran--comparing two arrays of the same size results in a third array whose elements are the result of each individual comparison from the original arrays. Then we can just call `count()` on the resulting array to get the number of true values, and we know how many characters matched up. Subtract 1 for the central X we already knew about, then divide by 3 since there are 3 letters remaining in each occurrence of `XMAS`, and Bob's your uncle, right?
|
Which has all 8 possible orientations of the word `XMAS` starting from the central X. Then, we can just take a sliding "window" of the same size into our puzzle grid and compare it to the test grid. This is a native operation in Fortran--comparing two arrays of the same size results in a third array whose elements are the result of each individual comparison from the original arrays. Then we can just call `count()` on the resulting array to get the number of true values, and we know how many characters matched up. Subtract 1 for the central X we already knew about, then divide by 3 since there are 3 letters remaining in each occurrence of `XMAS`, and Bob's your uncle, right?
|
||||||
|
|
||||||
...Wait, no. That won't work because it doesn't account for partial matches. Say we had a "window" that looked like this (I'm only showing the bottom-right quadrant of the window for simplicity):
|
...Wait, no. That won't work because it doesn't account for partial matches. Say we had a "window" that looked like this (I'm only showing the bottom-right quadrant of the window for simplicity):
|
||||||
|
|
||||||
@@ -164,7 +164,7 @@ Will this work? Is it even marginally more efficient than the stupidly obvious w
|
|||||||
|
|
||||||
Ok, first things first. Let's adjust the data-loading code to pad the grid with 3 bogus values on each edge, so that we can still generate our window correctly when we're looking at a point near the edge of the grid.
|
Ok, first things first. Let's adjust the data-loading code to pad the grid with 3 bogus values on each edge, so that we can still generate our window correctly when we're looking at a point near the edge of the grid.
|
||||||
|
|
||||||
```fortran
|
```f90
|
||||||
grid = '.' ! probably wouldn't matter if we skipped this, uninitialized memory just makes me nervous
|
grid = '.' ! probably wouldn't matter if we skipped this, uninitialized memory just makes me nervous
|
||||||
|
|
||||||
open(newunit=handle, file="data/04.txt", status="old", action="read")
|
open(newunit=handle, file="data/04.txt", status="old", action="read")
|
||||||
@@ -196,7 +196,7 @@ Oh. Oh, _noooo_.
|
|||||||
|
|
||||||
It's okay, I mean, uh, it's not _that_ much higher. Only two orders of magnitude, and what are the odds of all eight versions of `XMAS` appearing in the same window, anyway? Something like 1/4<sup>25</sup>? Maybe we can still make this work.
|
It's okay, I mean, uh, it's not _that_ much higher. Only two orders of magnitude, and what are the odds of all eight versions of `XMAS` appearing in the same window, anyway? Something like 1/4<sup>25</sup>? Maybe we can still make this work.
|
||||||
|
|
||||||
```fortran
|
```f90
|
||||||
integer function count_xmas(row, col) result(count)
|
integer function count_xmas(row, col) result(count)
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
@@ -277,7 +277,7 @@ Those `&`s are line-continuation characters, by the way. Apparently you can't ha
|
|||||||
|
|
||||||
Now we just have to put it all together:
|
Now we just have to put it all together:
|
||||||
|
|
||||||
```fortran
|
```f90
|
||||||
total = 0
|
total = 0
|
||||||
do col = 4, 143
|
do col = 4, 143
|
||||||
do row = 4, 143
|
do row = 4, 143
|
||||||
@@ -314,7 +314,7 @@ Hmm, I wonder if there's a way to take a single starting test grid and manipulat
|
|||||||
|
|
||||||
Turns out, yes! Yes there is. We can use a combination of slicing with a negative step, and transposing, which switches rows with columns, effectively rotating and flipping the array. So setting up our test grids looks like this:
|
Turns out, yes! Yes there is. We can use a combination of slicing with a negative step, and transposing, which switches rows with columns, effectively rotating and flipping the array. So setting up our test grids looks like this:
|
||||||
|
|
||||||
```fortran
|
```f90
|
||||||
character, dimension(3, 3) :: window, t1, t2, t3, t4
|
character, dimension(3, 3) :: window, t1, t2, t3, t4
|
||||||
|
|
||||||
t1 = reshape( &
|
t1 = reshape( &
|
||||||
@@ -332,7 +332,7 @@ t4 = t3(:, 3:1:-1) ! flip t3 left-to-right
|
|||||||
|
|
||||||
Then we can just compare the window to each test grid:
|
Then we can just compare the window to each test grid:
|
||||||
|
|
||||||
```fortran
|
```f90
|
||||||
window = grid(row - 1:row + 1, col - 1:col + 1)
|
window = grid(row - 1:row + 1, col - 1:col + 1)
|
||||||
if ( &
|
if ( &
|
||||||
count_matches(window, t1) == 5 &
|
count_matches(window, t1) == 5 &
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
title: Example after post
|
title: Example after post
|
||||||
date: 2026-02-28
|
date: 2026-02-28
|
||||||
|
draft: true
|
||||||
---
|
---
|
||||||
|
|
||||||
## After
|
## After
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
---
|
---
|
||||||
export interface Props {
|
export interface Props {
|
||||||
name: string,
|
name: string,
|
||||||
|
width?: string,
|
||||||
|
height?: string,
|
||||||
|
display?: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
const { name } = Astro.props;
|
const { name, width, height, display } = Astro.props;
|
||||||
|
|
||||||
const icons = import.meta.glob<{string: string}>('@components/icons/*.svg', { query: '?raw', import: 'default' });
|
const icons = import.meta.glob<{string: string}>('@components/icons/*.svg', { query: '?raw', import: 'default' });
|
||||||
const path = `/src/components/icons/${name}.svg`;
|
const path = `/src/components/icons/${name}.svg`;
|
||||||
@@ -13,11 +16,12 @@ if (icons[path] === undefined) {
|
|||||||
const icon = await icons[path]();
|
const icon = await icons[path]();
|
||||||
---
|
---
|
||||||
|
|
||||||
<Fragment set:html={icon} />
|
<span class="icon" set:html={icon} />
|
||||||
|
|
||||||
<style>
|
<style define:vars={{ width, height, display }}>
|
||||||
svg {
|
.icon :global(svg) {
|
||||||
width: 100%;
|
display: var(--display, block);
|
||||||
height: 100%;
|
width: var(--width, 100%);
|
||||||
|
height: var(--height, 100%);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ import { render } from 'astro:content';
|
|||||||
import Toc from '@components/Toc.vue';
|
import Toc from '@components/Toc.vue';
|
||||||
import { formatDate } from '@lib/datefmt';
|
import { formatDate } from '@lib/datefmt';
|
||||||
|
|
||||||
|
import Icon from '@components/Icon.astro';
|
||||||
|
import { headingElements } from '@components/headings';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
entry: CollectionEntry<'posts'>,
|
entry: CollectionEntry<'posts'>,
|
||||||
prevSlug?: string | null,
|
prevSlug?: string | null,
|
||||||
@@ -18,6 +21,41 @@ const { entry, prevSlug, nextSlug } = Astro.props;
|
|||||||
const { Content, headings } = await render(entry);
|
const { Content, headings } = await render(entry);
|
||||||
---
|
---
|
||||||
|
|
||||||
|
<article class="prose" data-dropcap-style={entry.data.dropcap}>
|
||||||
|
<header class="title">
|
||||||
|
<h1>
|
||||||
|
<!-- <SmallCaps text={entry.data.title} upperWeight={500} lowerWeight={800} /> -->
|
||||||
|
{ entry.data.title }
|
||||||
|
</h1>
|
||||||
|
<p class="subtitle">{ formatDate(entry.data.date) }</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div id="left-gutter">
|
||||||
|
<Toc client:load {headings} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section class="post">
|
||||||
|
<Content components={headingElements} />
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div id="right-gutter" />
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
{prevSlug && (
|
||||||
|
<div class="footer-link left">
|
||||||
|
<Icon name="arrow-left" height="1em" />
|
||||||
|
<a href={`/${prevSlug}`} data-astro-prefetch>Older</a>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{nextSlug && (
|
||||||
|
<div class="footer-link right">
|
||||||
|
<a href={`/${nextSlug}`} data-astro-prefetch>Newer</a>
|
||||||
|
<Icon name="arrow-right" height="1em" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</footer>
|
||||||
|
</article>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
/* 3-column grid: left gutter, center content, and right gutter */
|
/* 3-column grid: left gutter, center content, and right gutter */
|
||||||
article {
|
article {
|
||||||
@@ -59,7 +97,11 @@ footer {
|
|||||||
grid-column: 2 / 3;
|
grid-column: 2 / 3;
|
||||||
margin-bottom: 2.5rem;
|
margin-bottom: 2.5rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
|
||||||
|
color: var(--content-color-faded);
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
padding-top: 2.25rem;
|
||||||
|
border-top: 1px solid var(--content-color-faded);
|
||||||
|
|
||||||
& a {
|
& a {
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
@@ -77,6 +119,32 @@ footer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* basic styles */
|
||||||
|
.footer-link {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.25rem;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&.right {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* animate on hover */
|
||||||
|
.footer-link {
|
||||||
|
& :global(svg) {
|
||||||
|
transition: transform 150ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.right:hover :global(svg) {
|
||||||
|
transform: translateX(50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.left:hover :global(svg) {
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
article {
|
article {
|
||||||
& :global(section.post::first-letter) {
|
& :global(section.post::first-letter) {
|
||||||
font-family: 'Baskervville';
|
font-family: 'Baskervville';
|
||||||
@@ -94,32 +162,3 @@ article {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<article class="prose" data-dropcap-style={entry.data.dropcap}>
|
|
||||||
<header class="title">
|
|
||||||
<h1>
|
|
||||||
<!-- <SmallCaps text={entry.data.title} upperWeight={500} lowerWeight={800} /> -->
|
|
||||||
{ entry.data.title }
|
|
||||||
</h1>
|
|
||||||
<p class="subtitle">{ formatDate(entry.data.date) }</p>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div id="left-gutter">
|
|
||||||
<Toc client:load {headings} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<section class="post">
|
|
||||||
<Content />
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<div id="right-gutter" />
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
{prevSlug && (
|
|
||||||
<a href={`/${prevSlug}`} data-astro-prefetch>Older</a>
|
|
||||||
)}
|
|
||||||
{nextSlug && (
|
|
||||||
<a href={`/${nextSlug}`} data-astro-prefetch>Newer</a>
|
|
||||||
)}
|
|
||||||
</footer>
|
|
||||||
</article>
|
|
||||||
|
|||||||
7
src/components/headings/H1.astro
Normal file
7
src/components/headings/H1.astro
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
import Heading from './Heading.astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<Heading tag="h1" {...Astro.props}>
|
||||||
|
<slot />
|
||||||
|
</Heading>
|
||||||
7
src/components/headings/H2.astro
Normal file
7
src/components/headings/H2.astro
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
import Heading from './Heading.astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<Heading tag="h2" {...Astro.props}>
|
||||||
|
<slot />
|
||||||
|
</Heading>
|
||||||
7
src/components/headings/H3.astro
Normal file
7
src/components/headings/H3.astro
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
import Heading from './Heading.astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<Heading tag="h3" {...Astro.props}>
|
||||||
|
<slot />
|
||||||
|
</Heading>
|
||||||
7
src/components/headings/H4.astro
Normal file
7
src/components/headings/H4.astro
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
import Heading from './Heading.astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<Heading tag="h4" {...Astro.props}>
|
||||||
|
<slot />
|
||||||
|
</Heading>
|
||||||
7
src/components/headings/H5.astro
Normal file
7
src/components/headings/H5.astro
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
import Heading from './Heading.astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<Heading tag="h5" {...Astro.props}>
|
||||||
|
<slot />
|
||||||
|
</Heading>
|
||||||
7
src/components/headings/H6.astro
Normal file
7
src/components/headings/H6.astro
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
import Heading from './Heading.astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<Heading tag="h6" {...Astro.props}>
|
||||||
|
<slot />
|
||||||
|
</Heading>
|
||||||
45
src/components/headings/Heading.astro
Normal file
45
src/components/headings/Heading.astro
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
import Icon from '@components/Icon.astro';
|
||||||
|
|
||||||
|
export interface Props extends astroHTML.JSX.HTMLAttributes {
|
||||||
|
tag: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
const { tag: Tag, ...rest } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<Tag {...rest}>
|
||||||
|
<slot />
|
||||||
|
|
||||||
|
<a href={`#${Astro.props.id}`} class="deep-link" >
|
||||||
|
<Icon name="link" height="0.9em" width="0.9em" display="inline" />
|
||||||
|
</a>
|
||||||
|
</Tag>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:hover :global(svg) {
|
||||||
|
color: var(--accent-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
& :global(svg) {
|
||||||
|
color: var(--content-color-faded);
|
||||||
|
padding-bottom: 0.15em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover :global(svg), &:active :global(svg) {
|
||||||
|
color: var(--accent-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media(min-width: 60rem) {
|
||||||
|
position: absolute;
|
||||||
|
top: 0.1em;
|
||||||
|
left: -1.25em;
|
||||||
|
padding-right: 0.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
15
src/components/headings/index.ts
Normal file
15
src/components/headings/index.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import H1 from './H1.astro';
|
||||||
|
import H2 from './H2.astro';
|
||||||
|
import H3 from './H3.astro';
|
||||||
|
import H4 from './H4.astro';
|
||||||
|
import H5 from './H5.astro';
|
||||||
|
import H6 from './H6.astro';
|
||||||
|
|
||||||
|
export const headingElements = {
|
||||||
|
h1: H1,
|
||||||
|
h2: H2,
|
||||||
|
h3: H3,
|
||||||
|
h4: H4,
|
||||||
|
h5: H5,
|
||||||
|
h6: H6,
|
||||||
|
};
|
||||||
3
src/components/icons/arrow-left.svg
Normal file
3
src/components/icons/arrow-left.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 219 B |
3
src/components/icons/arrow-right.svg
Normal file
3
src/components/icons/arrow-right.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 219 B |
3
src/components/icons/link.svg
Normal file
3
src/components/icons/link.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622 1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 353 B |
@@ -1,10 +1,3 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21.752 15.002A9.72 9.72 0 0 1 18 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 0 0 3 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 0 0 9.002-5.998Z" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M21.752 15.002A9.72 9.72 0 0 1 18 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 0 0 3 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 0 0 9.002-5.998Z" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<style>
|
|
||||||
svg {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 425 B After Width: | Height: | Size: 364 B |
10
src/lib/content.ts
Normal file
10
src/lib/content.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { getCollection } from 'astro:content';
|
||||||
|
|
||||||
|
|
||||||
|
export async function listPosts() {
|
||||||
|
// all posts in dev, exlucde draft posts in prod
|
||||||
|
let entries = await getCollection('posts', ({ data }) => import.meta.env.DEV || !data.draft);
|
||||||
|
// sort by date descending
|
||||||
|
entries.sort((a, b) => b.data.date.getTime() - a.data.date.getTime());
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
@@ -1,18 +1,17 @@
|
|||||||
---
|
---
|
||||||
import { getCollection } from 'astro:content';
|
import { listPosts } from '@lib/content.ts';
|
||||||
import BaseLayout from '@layouts/BaseLayout.astro';
|
import BaseLayout from '@layouts/BaseLayout.astro';
|
||||||
import Post from '@components/Post.astro';
|
import Post from '@components/Post.astro';
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
const entries = await getCollection('posts');
|
const entries = await listPosts();
|
||||||
// unlike `/index` and `/posts`, we want to sort ascending by date here
|
|
||||||
entries.sort((a, b) => a.data.date.getTime() - b.data.date.getTime());
|
|
||||||
|
|
||||||
// for each route, the page gets passed the entry itself, plus the previous and next slugs
|
// for each route, the page gets passed the entry itself, plus the previous and next slugs
|
||||||
// (if any), so that it can render links to them
|
// (if any), so that it can render links to them
|
||||||
return entries.map((entry, idx) => {
|
return entries.map((entry, idx) => {
|
||||||
const prevSlug = entries[idx - 1]?.id || null;
|
// entries are sorted in by date descending, so prev has a higher index and next has lower
|
||||||
const nextSlug = entries[idx + 1]?.id || null;
|
const prevSlug = entries[idx + 1]?.id || null;
|
||||||
|
const nextSlug = entries[idx - 1]?.id || null;
|
||||||
return {
|
return {
|
||||||
params: { slug: entry.id },
|
params: { slug: entry.id },
|
||||||
props: { entry, prevSlug, nextSlug },
|
props: { entry, prevSlug, nextSlug },
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
---
|
---
|
||||||
import { getCollection } from 'astro:content';
|
import { listPosts } from '@lib/content.ts';
|
||||||
import BaseLayout from '@layouts/BaseLayout.astro';
|
import BaseLayout from '@layouts/BaseLayout.astro';
|
||||||
import Post from '@components/Post.astro';
|
import Post from '@components/Post.astro';
|
||||||
|
|
||||||
const entries = await getCollection('posts');
|
const entries = await listPosts();
|
||||||
entries.sort((a, b) => b.data.date.getTime() - a.data.date.getTime());
|
|
||||||
// there will always be at leaste one entry
|
// there will always be at leaste one entry
|
||||||
const entry = entries[0]!;
|
const entry = entries[0]!;
|
||||||
const prevSlug = entries[1] ? entries[1]?.id : null;
|
const prevSlug = entries[1] ? entries[1]?.id : null;
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
---
|
---
|
||||||
import '@styles/prose.css';
|
import '@styles/prose.css';
|
||||||
|
|
||||||
import { getCollection, render } from 'astro:content';
|
import { render } from 'astro:content';
|
||||||
|
import { listPosts } from '@lib/content.ts';
|
||||||
import BaseLayout from '@layouts/BaseLayout.astro';
|
import BaseLayout from '@layouts/BaseLayout.astro';
|
||||||
|
|
||||||
// return all posts
|
// return all posts in dev, only non-draft in prod
|
||||||
let entries = await getCollection('posts', ({ data }) => !data.draft || import.meta.env.PROD );
|
const entries = await listPosts();
|
||||||
entries.sort((a, b) => b.data.date.getTime() - a.data.date.getTime());
|
|
||||||
const posts = await Promise.all(entries.map(async entry => {
|
const posts = await Promise.all(entries.map(async entry => {
|
||||||
const { remarkPluginFrontmatter } = await render(entry);
|
const { remarkPluginFrontmatter } = await render(entry);
|
||||||
return { ...entry, remarkPluginFrontmatter };
|
return { ...entry, remarkPluginFrontmatter };
|
||||||
@@ -24,6 +24,7 @@ const posts = await Promise.all(entries.map(async entry => {
|
|||||||
<a href={`/${p.id}`} data-astro-prefetch>
|
<a href={`/${p.id}`} data-astro-prefetch>
|
||||||
{p.data.title}
|
{p.data.title}
|
||||||
</a>
|
</a>
|
||||||
|
{p.data.draft && <span class="draft-notice">Draft</span>}
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
{p.remarkPluginFrontmatter.description}
|
{p.remarkPluginFrontmatter.description}
|
||||||
@@ -55,6 +56,21 @@ const posts = await Promise.all(entries.map(async entry => {
|
|||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
display: flex;
|
||||||
|
gap: 01rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.draft-notice {
|
||||||
|
font-size: 0.5em;
|
||||||
|
font-family: 'Figtree Variable', sans-serif;
|
||||||
|
color: var(--nav-link-color);
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
padding: 0.05em 0.5em;
|
||||||
|
border-radius: 20% / 50%;
|
||||||
|
}
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
border: none;
|
border: none;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
|
|||||||
Reference in New Issue
Block a user