dep ver bump; clean-up; minor updates
Signed-off-by: Paul W. <lambdapaul@protonmail.com>
This commit is contained in:
parent
ff03bd50ff
commit
82ed74229b
@ -1,4 +1,6 @@
|
|||||||
export type ChildrenType = JSX.Element | Array<ChildrenType>;
|
import { JSX } from "react";
|
||||||
|
|
||||||
|
export type ChildrenType = JSX.Element| Array<ChildrenType>;
|
||||||
|
|
||||||
function Container(props: { children?: ChildrenType, ignore?: boolean }) {
|
function Container(props: { children?: ChildrenType, ignore?: boolean }) {
|
||||||
if (props.ignore)
|
if (props.ignore)
|
||||||
|
@ -1,20 +1,21 @@
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
|
import { Fragment } from 'react';
|
||||||
|
|
||||||
import style from '../styles/title.module.css';
|
import style from '../styles/title.module.css';
|
||||||
import SiteMap from '../public/sitemap.json';
|
import SiteMap from '../public/sitemap.json';
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import { SiteSubPages } from '../lib/site';
|
import { Sites } from '../lib/site';
|
||||||
|
|
||||||
function createPathElements(ancestors: Array<{ name: string, path: string }>) {
|
function createPathElements(ancestors: Array<{ name: string, path: string }>) {
|
||||||
let currentPath = '';
|
let currentPath = '';
|
||||||
return ancestors.map((ancestor, id) => {
|
return ancestors.map((ancestor, id) => {
|
||||||
currentPath += `/${ancestor.path}`
|
currentPath += `/${ancestor.path}`
|
||||||
return (
|
return (
|
||||||
<>
|
<Fragment key={currentPath} >
|
||||||
<Link key={currentPath} href={currentPath}>{ancestor.name}</Link>
|
<Link href={currentPath}>{ancestor.name}</Link>
|
||||||
<> / </>
|
<> / </>
|
||||||
</>
|
</Fragment>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -25,7 +26,8 @@ function Title() {
|
|||||||
const pagePath = router.asPath;
|
const pagePath = router.asPath;
|
||||||
const splitPath: Array<{ name: string, path: string }> = [];
|
const splitPath: Array<{ name: string, path: string }> = [];
|
||||||
|
|
||||||
let currRoot: SiteSubPages = SiteMap.subpages;
|
// TODO(Paul): clean this up
|
||||||
|
let currRoot: Sites = SiteMap.pages;
|
||||||
let title: string | null = null;
|
let title: string | null = null;
|
||||||
if (pagePath !== '/') {
|
if (pagePath !== '/') {
|
||||||
const subPaths = pagePath.split('?')[0].split('#')[0].split('/');
|
const subPaths = pagePath.split('?')[0].split('#')[0].split('/');
|
||||||
@ -36,9 +38,9 @@ function Title() {
|
|||||||
|
|
||||||
if (currRoot === undefined
|
if (currRoot === undefined
|
||||||
|| currRoot[p] === undefined
|
|| currRoot[p] === undefined
|
||||||
|| currRoot[p].subpages === undefined)
|
|| currRoot[p].pages === undefined)
|
||||||
break;
|
break;
|
||||||
currRoot = currRoot[p].subpages!;
|
currRoot = currRoot[p].pages!;
|
||||||
}
|
}
|
||||||
if (splitPath !== undefined && splitPath.length > 0)
|
if (splitPath !== undefined && splitPath.length > 0)
|
||||||
title = splitPath.pop()!.name;
|
title = splitPath.pop()!.name;
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
|
|
||||||
export interface Site {
|
export interface Site {
|
||||||
title: string;
|
title: string;
|
||||||
subpages?: SiteSubPages;
|
pages?: Sites;
|
||||||
mtime?: string;
|
mtime?: string;
|
||||||
otime?: string;
|
otime?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SiteSubPages {
|
export interface Sites {
|
||||||
[slug: string]: Site;
|
[slug: string]: Site;
|
||||||
}
|
}
|
||||||
|
2
next-env.d.ts
vendored
2
next-env.d.ts
vendored
@ -2,4 +2,4 @@
|
|||||||
/// <reference types="next/image-types/global" />
|
/// <reference types="next/image-types/global" />
|
||||||
|
|
||||||
// NOTE: This file should not be edited
|
// NOTE: This file should not be edited
|
||||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
|
||||||
|
@ -1,14 +1,18 @@
|
|||||||
const config = {
|
import type {NextConfig } from 'next';
|
||||||
|
import NextBundleAnalyzer from '@next/bundle-analyzer';
|
||||||
|
|
||||||
|
let config: NextConfig = {
|
||||||
|
reactStrictMode: true,
|
||||||
i18n: {
|
i18n: {
|
||||||
locales: ['en-US'],
|
locales: ['en-US'],
|
||||||
defaultLocale: 'en-US'
|
defaultLocale: 'en-US'
|
||||||
},
|
},
|
||||||
|
// not sure why this breaks prod build in the latest version
|
||||||
|
// aah it's so frustrating to deal with an warning log that
|
||||||
|
// shows up regardless of the config but its presence halts
|
||||||
|
// the entire thing.
|
||||||
webpack: (config, _options) => {
|
webpack: (config, _options) => {
|
||||||
config.module.rules.push(
|
config.module.rules.push(
|
||||||
{
|
|
||||||
test: /\.ya?ml$/,
|
|
||||||
use: 'js-yaml-loader',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
test: /\.svg$/,
|
test: /\.svg$/,
|
||||||
use: [{ loader: '@svgr/webpack' }],
|
use: [{ loader: '@svgr/webpack' }],
|
||||||
@ -25,10 +29,6 @@ const config = {
|
|||||||
test: /\.txt$/,
|
test: /\.txt$/,
|
||||||
type: 'asset/source',
|
type: 'asset/source',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
resourceQuery: /raw/,
|
|
||||||
type: 'asset/source',
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
@ -36,10 +36,9 @@ const config = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (process.env.ANALYZE) {
|
if (process.env.ANALYZE) {
|
||||||
const bundleAnalyzer = require('@next/bundle-analyzer')({
|
config = NextBundleAnalyzer({
|
||||||
enabled: true
|
enabled: true
|
||||||
});
|
})(config);
|
||||||
module.exports = bundleAnalyzer(config);
|
|
||||||
} else {
|
|
||||||
module.exports = config;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default config;
|
@ -1,15 +1,11 @@
|
|||||||
# Lua Programming Language
|
# Lua Programming Language
|
||||||
|
<!-- TODO ## Lua 5.4 C API-->
|
||||||
## Lua 5.4 C API
|
|
||||||
|
|
||||||
|
|
||||||
## Lua 5.4 Bytecode
|
## Lua 5.4 Bytecode
|
||||||
|
|
||||||
> [!note]
|
|
||||||
> These are **unstable** and may differ in different versions of the language.
|
> These are **unstable** and may differ in different versions of the language.
|
||||||
> They are not part of the language specification but an implementation detail, which in this case is the reference implementation.
|
> They are not part of the language specification but an implementation detail, which in this case is the reference implementation.
|
||||||
|
|
||||||
> [!note]
|
|
||||||
> The reference implementation used to have a stack based but now uses a register based VM similar to how modern real computer architectures.
|
> The reference implementation used to have a stack based but now uses a register based VM similar to how modern real computer architectures.
|
||||||
|
|
||||||
The instructions are 32 bits wide; every instruction has an opcode that takes up 7 bits, which leaves out 25 bits for the addresses and values.
|
The instructions are 32 bits wide; every instruction has an opcode that takes up 7 bits, which leaves out 25 bits for the addresses and values.
|
||||||
|
@ -33,8 +33,8 @@ Open it by exceuting the following command or saving it as a shortcut: `explorer
|
|||||||
|
|
||||||
### Video Players
|
### Video Players
|
||||||
|
|
||||||
- IINA
|
- [IINA](https://iina.io/)
|
||||||
- video player based on mpv with native macOS UI
|
- video player based on mpv with native macOS UI
|
||||||
- mpv
|
- [mpv](https://mpv.io/)
|
||||||
- mpv doesn't have a brew cask for Apple silicon; stolen-mpv exists but it is x86 only
|
- mpv doesn't have a brew cask for Apple silicon; stolen-mpv exists but it is x86 only
|
||||||
- mpv brew formula is the cli tool which works pretty well but it is not as nice as packaged applications
|
- mpv brew formula is the cli tool which works pretty well but it is not as nice as packaged applications
|
||||||
|
@ -61,3 +61,8 @@ Semi-paywalled
|
|||||||
## UTF-8 Everywhere
|
## UTF-8 Everywhere
|
||||||
|
|
||||||
- http://utf8everywhere.org
|
- http://utf8everywhere.org
|
||||||
|
|
||||||
|
## Parsing Gigabytes of JSON per Second
|
||||||
|
|
||||||
|
- https://arxiv.org/abs/1902.08318 [[PDF](https://arxiv.org/pdf/1902.08318)]
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
following XDG Desktop Configuration, for example, can be used and added as a
|
following XDG Desktop Configuration, for example, can be used and added as a
|
||||||
non-Steam game while in Desktop mode for access in gaming mode
|
non-Steam game while in Desktop mode for access in gaming mode
|
||||||
|
|
||||||
```cfg
|
```ini
|
||||||
#!/usr/bin/env xdg-open
|
#!/usr/bin/env xdg-open
|
||||||
[Desktop]
|
[Desktop]
|
||||||
Version=1.0
|
Version=1.0
|
||||||
@ -27,7 +27,8 @@ GenericName=Online Video Platform
|
|||||||
Comment=An online video-sharing, social media platform
|
Comment=An online video-sharing, social media platform
|
||||||
Exec=/usr/bin/flatpak run --branch=master --arch=x86_64 --file-forwarding org.chromium.Chrome @@ %F @@ --user-agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox Series X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.82 Safari/537.36 Edge/20.02' --kiosk 'https://www.youtube.com/tv'
|
Exec=/usr/bin/flatpak run --branch=master --arch=x86_64 --file-forwarding org.chromium.Chrome @@ %F @@ --user-agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox Series X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.82 Safari/537.36 Edge/20.02' --kiosk 'https://www.youtube.com/tv'
|
||||||
Terminal=false
|
Terminal=false
|
||||||
MimeType=text/plain; # $XDG_PATH contains the paths used to fetch icons, extensions for supported formats are optional Icon=com.youtube.tv
|
MimeType=text/plain;
|
||||||
|
# $XDG_PATH contains the paths used to fetch icons, extensions for supported formats are optional Icon=com.youtube.tv
|
||||||
```
|
```
|
||||||
|
|
||||||
- Firefox can also be used however the supported command-line options are
|
- Firefox can also be used however the supported command-line options are
|
||||||
|
@ -14,11 +14,11 @@
|
|||||||
- Alternatively, SteamCMD, a command-line only version of the Steam client, can
|
- Alternatively, SteamCMD, a command-line only version of the Steam client, can
|
||||||
be used
|
be used
|
||||||
- [Windows
|
- [Windows
|
||||||
Binary](https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip)
|
Binary (.zip)](https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip)
|
||||||
- [Linux
|
- [Linux
|
||||||
Binary](https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz)
|
Binary (.zip)](https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz)
|
||||||
- [macOS
|
- [macOS
|
||||||
Binary](https://steamcdn-a.akamaihd.net/client/installer/steamcmd_osx.tar.gz)
|
Binary (.zip)](https://steamcdn-a.akamaihd.net/client/installer/steamcmd_osx.tar.gz)
|
||||||
|
|
||||||
## Downloading Older Depots
|
## Downloading Older Depots
|
||||||
|
|
||||||
@ -51,4 +51,7 @@ values.
|
|||||||
- useful bot written in C# to farm trading cards for owned games that can be
|
- useful bot written in C# to farm trading cards for owned games that can be
|
||||||
sold
|
sold
|
||||||
- [SteamGridDB](https://steamgriddb.com/)
|
- [SteamGridDB](https://steamgriddb.com/)
|
||||||
- custom video game assets for games available and not available on steam
|
- custom video game assets for games available and not available on Steam
|
||||||
|
- [ProtonDB](https://www.protondb.com/)
|
||||||
|
- community-sourced Linux compatibility tracker
|
||||||
|
|
||||||
|
37
package.json
37
package.json
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
@ -7,28 +8,32 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dotenv": "^16.3.1",
|
"dotenv": "^16.3.1",
|
||||||
"js-yaml-loader": "^1.2.2",
|
"highlight.js": "^11.10.0",
|
||||||
"next": "^13.5.1",
|
"next": "^15.0.4",
|
||||||
"normalize.css": "^8.0.1",
|
"normalize.css": "^8.0.1",
|
||||||
"react": "^18.2.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^19.0.0",
|
||||||
"react-markdown": "^9.0.0",
|
"react-markdown": "^9.0.1",
|
||||||
"react-syntax-highlighter": "^15.5.0",
|
"rehype-autolink-headings": "^7.1.0",
|
||||||
|
"rehype-highlight": "^7.0.0",
|
||||||
|
"rehype-highlight-code-lines": "^1.0.4",
|
||||||
|
"rehype-katex": "^7.0.1",
|
||||||
"rehype-raw": "^7.0.0",
|
"rehype-raw": "^7.0.0",
|
||||||
"remark-directive": "^3.0.0",
|
"rehype-slug": "^6.0.0",
|
||||||
"remark-gfm": "^4.0.0",
|
"remark-gfm": "^4.0.0",
|
||||||
"remark-github-admonitions-to-directives": "^2.0.0",
|
"remark-loader": "^6.0.0",
|
||||||
|
"remark-math": "^6.0.0",
|
||||||
"uri-js": "^4.4.1"
|
"uri-js": "^4.4.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@next/bundle-analyzer": "^14.0.1",
|
"@next/bundle-analyzer": "^15.0.4",
|
||||||
"@svgr/webpack": "^6.5.1",
|
"@svgr/webpack": "^8.1.0",
|
||||||
"@types/node": "^18.17.17",
|
"@types/node": "^22.7.4",
|
||||||
"@types/react": "^18.2.22",
|
"@types/react": "^19.0.1",
|
||||||
"@types/react-dom": "^18.2.7",
|
"@types/react-dom": "^19.0.1",
|
||||||
"@types/react-syntax-highlighter": "^15.5.7",
|
"@types/react-syntax-highlighter": "^15.5.7",
|
||||||
"eslint": "^8.49.0",
|
"eslint": "^9.11.1",
|
||||||
"eslint-config-next": "^13.5.1",
|
"eslint-config-next": "^15.0.4",
|
||||||
"typescript": "^4.9.5"
|
"typescript": "^5.6.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,34 +4,34 @@ import Link from 'next/link';
|
|||||||
import style from '../styles/title.module.css';
|
import style from '../styles/title.module.css';
|
||||||
|
|
||||||
function NotFoundPage() {
|
function NotFoundPage() {
|
||||||
// clean this page up
|
// clean this page up
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
<title>404: Not Found | PaulW.XYZ</title>
|
<title>404: Not Found | PaulW.XYZ</title>
|
||||||
</Head>
|
</Head>
|
||||||
<div className={style.container}>
|
<div className={style.container}>
|
||||||
<h1 className={style.title}>
|
<h1 className={style.title}>
|
||||||
Page Not Found
|
Page Not Found
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div className={`${style.nav} h1`}>
|
<div className={`${style.nav} h1`}>
|
||||||
<Link href='/'>PaulW.XYZ</Link> / ... ??? / 404: Not Found </div>
|
<Link href='/'>PaulW.XYZ</Link> / ... ??? / 404: Not Found </div>
|
||||||
<div className='container'>
|
<div className='container'>
|
||||||
<section className='block text center'>
|
<section className='block text center'>
|
||||||
<h1>Error 404</h1>
|
<h1>Error 404</h1>
|
||||||
<p>
|
<p>
|
||||||
<strong>Uh oh! The page you are looking for does not exist...</strong><br />
|
<strong>Uh oh! The page you are looking for does not exist...</strong><br />
|
||||||
</p>
|
</p>
|
||||||
<Link href='/' className='button green back link'>Go Home</Link>
|
<Link href='/' className='button green back link'>Go Home</Link>
|
||||||
<a className='button blue link extern' href='https://en.wikipedia.org/wiki/List_of_HTTP_status_codes'>
|
<a className='button blue link extern' href='https://en.wikipedia.org/wiki/List_of_HTTP_status_codes'>
|
||||||
More on HTTP status codes
|
More on HTTP status codes
|
||||||
</a>
|
</a>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default NotFoundPage;
|
export default NotFoundPage;
|
||||||
|
13
pages/_document.tsx
Normal file
13
pages/_document.tsx
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { Html, Head, Main, NextScript } from "next/document";
|
||||||
|
|
||||||
|
export default function Document() {
|
||||||
|
return (
|
||||||
|
<Html lang="en">
|
||||||
|
<Head />
|
||||||
|
<body>
|
||||||
|
<Main />
|
||||||
|
<NextScript />
|
||||||
|
</body>
|
||||||
|
</Html>
|
||||||
|
);
|
||||||
|
}
|
@ -5,35 +5,35 @@ import License from '../LICENSE.txt';
|
|||||||
import Layout from '../components/layout';
|
import Layout from '../components/layout';
|
||||||
|
|
||||||
function AboutPage() {
|
function AboutPage() {
|
||||||
return (
|
return (
|
||||||
<Layout >
|
<Layout >
|
||||||
<section className='block'>
|
<section className='block'>
|
||||||
<p>Paul's Personal Website. I go by <a href='https://github.com/LambdaPaul'>@LambdaPaul</a> on GitHub and <a href='https://x.com/lambda_paul'>@lambda_paul</a> on X/Twitter.</p>
|
<p>Paul's Personal Website. I go by <a href='https://github.com/LambdaPaul'>@LambdaPaul</a> on GitHub and <a href='https://x.com/lambda_paul'>@lambda_paul</a> on X/Twitter.</p>
|
||||||
<p>I also have a Gitea server at <a href='https://git.paulw.xyz'>git.paulw.xyz</a> and a Pleroma (ActivityPub/Mastodon-compatible) server at <a href='https://social.paulw.xyz'>social.paulw.xyz</a> as back-ups for my GitHub and X/Twitter.</p>
|
<p>I also have a Gitea server at <a href='https://git.paulw.xyz'>git.paulw.xyz</a> and a Pleroma (ActivityPub/Mastodon-compatible) server at <a href='https://social.paulw.xyz'>social.paulw.xyz</a> as back-ups for my GitHub and X/Twitter.</p>
|
||||||
<p>Why did I create this? Why do I have the back-ups?</p>
|
<p>Why did I create this? Why do I have the back-ups?</p>
|
||||||
<p>
|
<p>
|
||||||
The original motivation was to just play with Next.js as it pretty much did the things I wanted web pages to do. But it came at the cost of needless complexity. As I use the JavaScript/ECMAScript/Whatever-you-want-to-call-it-script more and more, I am convinced that it is not a platform worth pursuing because the more complex it gets, the less control I have over what it does and this platform and its users seems to be okay with that sort of loss. I have been instead pivoting toward things that impressed and got me interested in working with computers.</p>
|
The original motivation was to just play with Next.js as it pretty much did the things I wanted web pages to do. But it came at the cost of needless complexity. As I use the JavaScript/ECMAScript/Whatever-you-want-to-call-it-script more and more, I am convinced that it is not a platform worth pursuing because the more complex it gets, the less control I have over what it does and this platform and its users seems to be okay with that sort of loss. I have been instead pivoting toward things that impressed and got me interested in working with computers.</p>
|
||||||
<p>Most services/products are keen on going against what Steph Ango calls <a href='https://stephango.com/file-over-app'>File over app</a>, a philosophy in which you prioritize data over software, and anticipate and embrace the eventual death of software. People instead want subscription services that barely support open formats and sometimes do not support exporting data to commonly used formats. The goal here is to avoid storing artifacts under locations that are easily not accessible, not under my control, and does not lock me out of using it with other software. The only reason I have not completely abandoned this is thanks to my decision to rely on Markdown files alone. Had it been reliant on any cloud software, I would have started over.</p>
|
<p>Most services/products are keen on going against what Steph Ango calls <a href='https://stephango.com/file-over-app'>File over app</a>, a philosophy in which you prioritize data over software, and anticipate and embrace the eventual death of software. People instead want subscription services that barely support open formats and sometimes do not support exporting data to commonly used formats. The goal here is to avoid storing artifacts under locations that are easily not accessible, not under my control, and does not lock me out of using it with other software. The only reason I have not completely abandoned this is thanks to my decision to rely on Markdown files alone. Had it been reliant on any cloud software, I would have started over.</p>
|
||||||
|
|
||||||
<p>Got any questions, concerns, or issues? Contact me via email: <code>contact [at] paulw [dot] xyz</code>.</p>
|
<p>Got any questions, concerns, or issues? Contact me via email: <code>contact [at] paulw [dot] xyz</code>.</p>
|
||||||
</section>
|
</section>
|
||||||
<hr />
|
<hr />
|
||||||
<section className='block'>
|
<section className='block'>
|
||||||
<p>Source for this site is available on GitHub: <a href='https://github.com/LambdaPaul/www'>github.com/LambdaPaul/www</a> and <a href='https://git.paulw.xyz/LambdaPaul/www'>git.paulw.xyz/LambdaPaul/www</a></p>
|
<p>Source for this site is available on GitHub: <a href='https://github.com/LambdaPaul/www'>github.com/LambdaPaul/www</a> and <a href='https://git.paulw.xyz/LambdaPaul/www'>git.paulw.xyz/LambdaPaul/www</a></p>
|
||||||
<p>Relevant information regarding the source is available on the repo and is also provided below.</p>
|
<p>Relevant information regarding the source is available on the repo and is also provided below.</p>
|
||||||
</section>
|
</section>
|
||||||
<section className='block'>
|
<section className='block'>
|
||||||
<h2>README</h2>
|
<h2>README</h2>
|
||||||
<ReactMarkdown>
|
<ReactMarkdown>
|
||||||
{ReadmeMd.replace(/^#{1,5} /g, (s: string) => { return `#${s}` })}
|
{ReadmeMd.replace(/^#{1,5} /g, (s: string) => { return `#${s}` })}
|
||||||
</ReactMarkdown>
|
</ReactMarkdown>
|
||||||
</section>
|
</section>
|
||||||
<section className='block'>
|
<section className='block'>
|
||||||
<h2>LICENSE</h2>
|
<h2>LICENSE</h2>
|
||||||
<pre className='license'>{License}</pre>
|
<pre className='license'>{License}</pre>
|
||||||
</section>
|
</section>
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AboutPage;
|
export default AboutPage;
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
import ReactMarkdown from 'react-markdown';
|
import ReactMarkdown from 'react-markdown';
|
||||||
import SyntaxHighlighter from 'react-syntax-highlighter';
|
import { PluggableList } from 'unified';
|
||||||
import { monokaiSublime as hlTheme } from 'react-syntax-highlighter/dist/cjs/styles/hljs';
|
|
||||||
import remarkGfm from 'remark-gfm';
|
import remarkGfm from 'remark-gfm';
|
||||||
|
import remarkMath from 'remark-math';
|
||||||
|
|
||||||
|
import rehypeKatex from 'rehype-katex';
|
||||||
import rehypeRaw from 'rehype-raw';
|
import rehypeRaw from 'rehype-raw';
|
||||||
import remarkDirective from 'remark-directive';
|
import rehypeSlug from 'rehype-slug';
|
||||||
import remarkGithubAdmonitionsToDirectives from 'remark-github-admonitions-to-directives';
|
import rehypeAutolinkHeadings from 'rehype-autolink-headings';
|
||||||
|
import rehypeHighlight from 'rehype-highlight';
|
||||||
|
import rehypeHighlightCodeLines, { type HighlightLinesOptions } from 'rehype-highlight-code-lines';
|
||||||
|
|
||||||
import Layout from '../../components/layout';
|
import Layout from '../../components/layout';
|
||||||
import readMarkdown from '../../lib/read-markdown';
|
import readMarkdown from '../../lib/read-markdown';
|
||||||
@ -12,86 +17,76 @@ import { toLocaleString } from '../../lib/date';
|
|||||||
import NotesInfo from '../../public/notes.json';
|
import NotesInfo from '../../public/notes.json';
|
||||||
|
|
||||||
import style from '../../styles/note.module.css';
|
import style from '../../styles/note.module.css';
|
||||||
|
import 'highlight.js/styles/monokai-sublime.css';
|
||||||
|
import 'katex/dist/katex.min.css';
|
||||||
|
|
||||||
interface Note {
|
interface Note {
|
||||||
title: string,
|
title: string,
|
||||||
mtime: string,
|
mtime: string,
|
||||||
content?: string,
|
content?: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Notes {
|
interface Notes {
|
||||||
[slug: string]: Note;
|
[slug: string]: Note;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Markdown({ content }: any) {
|
function Markdown({ content }: any) {
|
||||||
return <ReactMarkdown
|
const remarkPlugins: PluggableList = [
|
||||||
remarkPlugins={[remarkGithubAdmonitionsToDirectives, remarkDirective, remarkGfm]}
|
remarkGfm,
|
||||||
rehypePlugins={[rehypeRaw]}
|
remarkMath,
|
||||||
components={{
|
];
|
||||||
code({ node, className, children, ...props }) {
|
const rehypePlugins: PluggableList = [
|
||||||
const match = /language-(\w+)/.exec(className || '')
|
rehypeSlug,
|
||||||
return match
|
rehypeAutolinkHeadings,
|
||||||
? (
|
rehypeRaw,
|
||||||
<SyntaxHighlighter
|
rehypeHighlight,
|
||||||
showLineNumbers={true}
|
rehypeKatex,
|
||||||
language={match[1]}
|
];
|
||||||
//@ts-ignore
|
return <ReactMarkdown remarkPlugins={remarkPlugins} rehypePlugins={rehypePlugins}>
|
||||||
style={hlTheme}
|
{content}
|
||||||
PreTag='div'
|
</ReactMarkdown>
|
||||||
codeTagProps={{ style: { display: 'block' } }}
|
|
||||||
customStyle={{ padding: '0', borderRadius: '1rem' }}
|
|
||||||
{...props}
|
|
||||||
>{String(children).replace(/\n$/, '')}</SyntaxHighlighter>
|
|
||||||
)
|
|
||||||
: <code className={className} {...props}>
|
|
||||||
{children}
|
|
||||||
</code>
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>{content}</ReactMarkdown>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function Note({ note }: { note: Note } ) {
|
function Note({ note }: { note: Note }) {
|
||||||
return (<>
|
return (<>
|
||||||
<Layout >
|
<Layout >
|
||||||
<span className={style['last-updated']}>
|
<span className={style['last-updated']}>
|
||||||
Last updated: {toLocaleString(note.mtime)}
|
Last updated: {toLocaleString(note.mtime)}
|
||||||
</span>
|
</span>
|
||||||
<section className='block'>
|
<section className='block'>
|
||||||
<Markdown content={note.content} />
|
<Markdown content={note.content} />
|
||||||
</section>
|
</section>
|
||||||
</Layout>
|
</Layout>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getStaticProps({ params }: { params: { note: string } }) {
|
export async function getStaticProps({ params }: { params: { note: string } }) {
|
||||||
const note: string = params.note;
|
const note: string = params.note;
|
||||||
const notesInfo: Notes = NotesInfo;
|
const notesInfo: Notes = NotesInfo;
|
||||||
const noteInfo: Note = notesInfo[note];
|
const noteInfo: Note = notesInfo[note];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
note: {
|
note: {
|
||||||
...noteInfo,
|
...noteInfo,
|
||||||
content: await readMarkdown('notes', note, true)
|
content: await readMarkdown('notes', note, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
return {
|
return {
|
||||||
paths: Object.keys(NotesInfo).map((note: string) => {
|
paths: Object.keys(NotesInfo).map((note: string) => {
|
||||||
return {
|
return {
|
||||||
params: {
|
params: {
|
||||||
note
|
note
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
fallback: false
|
fallback: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default Note;
|
export default Note;
|
||||||
|
@ -6,52 +6,52 @@ import { toRelativeDate } from '../../lib/date';
|
|||||||
import NotesInfo from '../../public/notes.json';
|
import NotesInfo from '../../public/notes.json';
|
||||||
|
|
||||||
function NoteEntry({ note }: { note: { title: string, mtime: string, slug: string } }) {
|
function NoteEntry({ note }: { note: { title: string, mtime: string, slug: string } }) {
|
||||||
return (
|
return (
|
||||||
<tr>
|
<tr>
|
||||||
<td style={{ flex: '1 0 50%' }}>
|
<td style={{ flex: '1 0 50%' }}>
|
||||||
<Link href={`/notes/${note.slug}`}>
|
<Link href={`/notes/${note.slug}`}>
|
||||||
{note.title}
|
{note.title}
|
||||||
</Link>
|
</Link>
|
||||||
</td>
|
</td>
|
||||||
<td style={{ fontStyle: 'italic' }}>
|
<td style={{ fontStyle: 'italic' }}>
|
||||||
{note.mtime && toRelativeDate(note.mtime)}
|
{note.mtime && toRelativeDate(note.mtime)}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function NotesPage() {
|
function NotesPage() {
|
||||||
const notes = Object.entries(NotesInfo)
|
const notes = Object.entries(NotesInfo)
|
||||||
.map(([slug, note]) => {
|
.map(([slug, note]) => {
|
||||||
return {
|
return {
|
||||||
slug,
|
slug,
|
||||||
title: note.title,
|
title: note.title,
|
||||||
mtime: new Date(note.mtime)
|
mtime: new Date(note.mtime)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.sort(
|
.sort(
|
||||||
(a, b) => {
|
(a, b) => {
|
||||||
return b.mtime.getTime() - a.mtime.getTime();
|
return b.mtime.getTime() - a.mtime.getTime();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
{
|
{
|
||||||
!notes || notes.length === 0
|
!notes || notes.length === 0
|
||||||
&& <>No notes found</>
|
&& <>No notes found</>
|
||||||
|| <table>
|
|| <table>
|
||||||
<tbody>
|
<tbody>
|
||||||
{notes.map(
|
{notes.map(
|
||||||
(note: any) => {
|
(note: any) => {
|
||||||
return (<NoteEntry note={note} key={note.slug} />);
|
return (<NoteEntry note={note} key={note.slug} />);
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
}
|
}
|
||||||
</Layout>
|
</Layout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,102 +3,113 @@ import ReactMarkdown from 'react-markdown';
|
|||||||
import style from '../../styles/post.module.css';
|
import style from '../../styles/post.module.css';
|
||||||
import PostsInfo from '../../public/posts.json';
|
import PostsInfo from '../../public/posts.json';
|
||||||
import readMarkdown from '../../lib/read-markdown';
|
import readMarkdown from '../../lib/read-markdown';
|
||||||
import DateTool from '../../lib/date';
|
import DateTool, { toLocaleString } from '../../lib/date';
|
||||||
|
|
||||||
interface Post {
|
interface IPost {
|
||||||
title: string;
|
title: string;
|
||||||
mtime: string;
|
mtime: string;
|
||||||
otime?: string;
|
otime?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Posts {
|
interface IPosts {
|
||||||
[slug: string]: Post
|
[slug: string]: IPost
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function TimeBlock({ mtime, otime }: { mtime: string, otime: string }) {
|
function TimeBlock({ mtime, otime }: { mtime: string, otime: string }) {
|
||||||
const ampm = (h: number) => { if (h >= 12) return 'p.m.'; return 'a.m.'; };
|
const ampm = (h: number) => { if (h >= 12) return 'p.m.'; return 'a.m.'; };
|
||||||
|
|
||||||
const mdate = new Date(mtime);
|
const mdate = new Date(mtime);
|
||||||
const odate = new Date(otime);
|
const odate = new Date(otime);
|
||||||
|
|
||||||
const format = (date: Date) => {
|
const format = (date: Date) => {
|
||||||
const day = date.getDay();
|
const day = date.getDay();
|
||||||
const ord = <sup>{DateTool.getOrdinalDaySuffix(date.getDay())}</sup>;
|
const ord = <sup>{DateTool.getOrdinalDaySuffix(date.getDay())}</sup>;
|
||||||
const month = DateTool.getFullMonth(date.getMonth());
|
const month = DateTool.getFullMonth(date.getMonth());
|
||||||
const year = date.getFullYear();
|
const year = date.getFullYear();
|
||||||
const hours = date.getHours() > 12 ? date.getHours() - 12 : date.getHours();
|
const hours = date.getHours() > 12 ? date.getHours() - 12 : date.getHours();
|
||||||
const minPrefix = date.getMinutes() < 10 ? '0' : '';
|
const minPrefix = date.getMinutes() < 10 ? '0' : '';
|
||||||
const minutes = date.getMinutes();
|
const minutes = date.getMinutes();
|
||||||
const twelveSfx = ampm(date.getHours());
|
const twelveSfx = ampm(date.getHours());
|
||||||
return <>{day}{ord} {month} {year} at {hours}:{minPrefix}{minutes} {twelveSfx}</>
|
return <>{day}{ord} {month} {year} at {hours}:{minPrefix}{minutes} {twelveSfx}</>
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ textAlign: 'right', fontSize: '16px', fontFamily: 'Cantarell', fontStyle: 'italic' }}>
|
<div style={{ textAlign: 'right', fontSize: '16px', fontFamily: 'Cantarell', fontStyle: 'italic' }}>
|
||||||
{
|
{
|
||||||
mtime ?
|
mtime ?
|
||||||
<div className='mtime' data-text={mdate.toISOString()}>
|
<div className='mtime' data-text={mdate.toISOString()}>
|
||||||
Last updated: {format(mdate)}
|
Last updated: {format(mdate)}
|
||||||
</div>
|
</div>
|
||||||
:
|
:
|
||||||
<></>
|
<></>
|
||||||
}
|
}
|
||||||
<div className='otime'>
|
<div className='otime'>
|
||||||
{format(odate)}
|
{format(odate)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Post({ post }: { post: Post & { content: string, cover?: string, otime: string, mtime?: string } }) {
|
function Post({ post }: { post: IPost & { content: string, cover?: string, otime: string, mtime?: string } }) {
|
||||||
return (<>
|
if (!post)
|
||||||
<Layout removeContainer={true} >
|
return <></>;
|
||||||
{<div className={style.imageBlock}
|
return (<>
|
||||||
style={{
|
<Layout removeContainer={true} >
|
||||||
backgroundImage:
|
<div className='container'>
|
||||||
post.cover ?
|
{ post.otime !== post.mtime &&
|
||||||
`url(/assets/images/${post.cover})` :
|
<span className={style.time}>
|
||||||
'linear-gradient(to bottom right, rgb(5, 51, 11), rgb(5, 45, 13) 15%, rgb(5, 39,15) 40%, rgb(0, 30, 16) 80%)'
|
Last updated: {toLocaleString(post.mtime)}
|
||||||
}}></div>}
|
</span>
|
||||||
<div className={`${style.spacer} ${post.cover ? style.background : ''}`}></div>
|
}
|
||||||
<section className={`${style.block} block`}>
|
<span className={style.time}>
|
||||||
<div className='container'>
|
{toLocaleString(post.otime)}
|
||||||
<TimeBlock mtime={post.mtime} otime={post.otime} />
|
</span>
|
||||||
<ReactMarkdown>{post.content}</ReactMarkdown>
|
</div>
|
||||||
</div>
|
{<div className={style.imageBlock}
|
||||||
</section>
|
style={{
|
||||||
<div className={style.spacer}></div>
|
backgroundImage:
|
||||||
</Layout>
|
post.cover ?
|
||||||
|
`url(/assets/images/${post.cover})` :
|
||||||
|
'linear-gradient(to bottom right, rgb(5, 51, 11), rgb(5, 45, 13) 15%, rgb(5, 39,15) 40%, rgb(0, 30, 16) 80%)'
|
||||||
|
}}></div>}
|
||||||
|
<div className={`${style.spacer} ${post.cover ? style.background : ''}`}></div>
|
||||||
|
<section className={`${style.block} block`}>
|
||||||
|
<div className='container'>
|
||||||
|
<ReactMarkdown>{post.content}</ReactMarkdown>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<div className={style.spacer}></div>
|
||||||
|
</Layout>
|
||||||
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getStaticProps({ params }: any) {
|
export async function getStaticProps({ params }: any) {
|
||||||
const postsInfo: Posts = PostsInfo;
|
const postsInfo: IPosts = PostsInfo;
|
||||||
const post: Post = postsInfo[params.post];
|
const post: IPost = postsInfo[params.post];
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
post: {
|
post: {
|
||||||
...post,
|
...post,
|
||||||
content: await readMarkdown('posts', params.post, true)
|
content: await readMarkdown('posts', params.post, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
return {
|
return {
|
||||||
paths: Object.keys(PostsInfo).map((post: string) => {
|
paths: Object.keys(PostsInfo).map((post: string) => {
|
||||||
return {
|
return {
|
||||||
params: {
|
params: {
|
||||||
post
|
post
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
fallback: false
|
fallback: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,49 +4,47 @@ import date from '../../lib/date';
|
|||||||
import PostsInfo from '../../public/posts.json';
|
import PostsInfo from '../../public/posts.json';
|
||||||
|
|
||||||
function PostsPage() {
|
function PostsPage() {
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
{Object.keys(PostsInfo).length && <Posts /> || <NoPosts />}
|
{Object.keys(PostsInfo).length && <Posts /> || <NoPosts />}
|
||||||
</Layout>
|
</Layout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function NoPosts() {
|
function NoPosts() {
|
||||||
return (<><div className='text center'>
|
return (<div className='text center'>
|
||||||
<div>**crickets**</div>
|
<div>**crickets**</div>
|
||||||
<div>No posts found...</div>
|
<div>No posts found...</div>
|
||||||
<div><Link href='/' className='link button green back'>Go Home</Link></div>
|
<div><Link href='/' className='link button green back'>Go Home</Link></div>
|
||||||
</div></>);
|
</div>);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Posts() {
|
function Posts() {
|
||||||
const posts = Object.entries(PostsInfo);
|
const posts = Object.entries(PostsInfo);
|
||||||
return (
|
return (
|
||||||
<>
|
<table>
|
||||||
<table>
|
<tbody>
|
||||||
<tbody>
|
{
|
||||||
{
|
posts.map(([slug, post]: [string, any]) => {
|
||||||
posts.map(([slug, post]: [string, any]) => {
|
return (<tr key={slug} style={{ alignItems: 'center' }}>
|
||||||
return <tr key={slug} style={{ alignItems: 'center' }}>
|
<td style={{ display: 'inline-block', textAlign: 'right', fontSize: '0.9rem' }}>
|
||||||
<td style={{ display: 'inline-block', textAlign: 'right', fontSize: '0.9rem' }}>
|
<div style={{ fontStyle: 'italics', fontSize: '.8rem' }}>{
|
||||||
<div style={{ fontStyle: 'italics', fontSize: '.8rem' }}>{
|
post.mtime && (post.mtime != post.otime) && `Updated ${date.toRelativeDate(new Date(post.mtime))}`
|
||||||
post.mtime && (post.mtime != post.otime) && `Updated ${date.toRelativeDate(new Date(post.mtime))}`
|
}</div>
|
||||||
}</div>
|
<div>{date.toRelativeDate(new Date(post.otime))}</div>
|
||||||
<div>{date.toRelativeDate(new Date(post.otime))}</div>
|
</td>
|
||||||
</td>
|
<td style={{
|
||||||
<td style={{
|
fontFamily: `'EB Garamond', 'Garamond', 'Times New Roman', Times, serif`
|
||||||
flex: '1 1 60%',
|
, fontSize: '1.25rem'
|
||||||
alignItems: 'center',
|
}}>
|
||||||
fontFamily: `'EB Garamond', 'Garamond', 'Times New Roman', Times, serif`
|
<Link href={`/posts/${slug}`} style={{ textDecoration: 'none' }}>{post.title}</Link>
|
||||||
}}>
|
</td>
|
||||||
<Link href={`/posts/${slug}`} style={{ textDecoration: 'none' }}>{post.title}</Link>
|
</tr>)
|
||||||
</td>
|
})
|
||||||
</tr>
|
}
|
||||||
})}
|
</tbody>
|
||||||
</tbody>
|
</table>
|
||||||
</table>
|
)
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,46 +1,41 @@
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import Layout from '../components/layout';
|
import Layout from '../components/layout';
|
||||||
import { Site } from '../lib/site';
|
import { Sites } from '../lib/site';
|
||||||
import SiteMap from '../public/sitemap.json';
|
import SiteMap from '../public/sitemap.json';
|
||||||
|
|
||||||
function traverseMap(head: Site, cwd = '', depth = 0) {
|
function Desc(props: any) {
|
||||||
if (head.subpages === undefined)
|
return (
|
||||||
return [];
|
<dl style={props.style}>
|
||||||
let elements = [];
|
<dt>{props.term}</dt>
|
||||||
for (const [slug, info] of Object.entries(head.subpages)) {
|
<dd>{props.details}</dd>
|
||||||
if (slug === 'sitemap')
|
{props.children}
|
||||||
continue;
|
</dl>
|
||||||
if (slug.startsWith('http://')) {
|
);
|
||||||
elements.push(<>
|
}
|
||||||
<dt>{info.title}</dt>
|
|
||||||
<dd><Link href={slug}>{slug.substring(7)}</Link></dd>
|
function traverseMap(head?: Sites, cwd = '', depth = 0) {
|
||||||
</>);
|
if (!head) return [];
|
||||||
}
|
let elements = [];
|
||||||
else if (slug.startsWith('https://')) {
|
for (const [slug, site] of Object.entries(head)) {
|
||||||
elements.push(<>
|
if (slug === 'sitemap')
|
||||||
<dt>{info.title}</dt>
|
continue;
|
||||||
<dd><Link href={slug}>{slug.substring(8)}</Link></dd>
|
|
||||||
</>);
|
let details;
|
||||||
}
|
let list;
|
||||||
else {
|
|
||||||
const path = `${cwd}/${slug}`;
|
const path = `${cwd}/${slug}`;
|
||||||
const children = (<><dl style={{marginLeft: '3rem'}}> {traverseMap(info, path, depth + 1)}</dl></>);
|
details = <Link href={path}>paulw.xyz{path}</Link>;
|
||||||
elements.push(<>
|
list = traverseMap(site.pages, path, depth + 1);
|
||||||
<dt>{info.title}</dt>
|
|
||||||
<dd><Link href={path}>paulw.xyz{path}</Link></dd>
|
elements.push(<Desc style={{marginLeft: '3rem'}} key={site.title} term={site.title} details={details}>{list}</Desc>)
|
||||||
{children}
|
}
|
||||||
</>);
|
return elements;
|
||||||
}
|
|
||||||
}
|
|
||||||
return elements;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function SiteMapPage() {
|
function SiteMapPage() {
|
||||||
|
return <Layout>
|
||||||
|
{traverseMap(SiteMap.pages)}
|
||||||
return <Layout>
|
</Layout>;
|
||||||
<dl>{traverseMap(SiteMap)}</dl>
|
|
||||||
</Layout>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SiteMapPage;
|
export default SiteMapPage;
|
||||||
|
@ -1,20 +1,14 @@
|
|||||||
{
|
{
|
||||||
"posts": {
|
"posts": {
|
||||||
"title": "Posts"
|
"title": "Posts"
|
||||||
},
|
},
|
||||||
"notes": {
|
"notes": {
|
||||||
"title": "Notes"
|
"title": "Notes"
|
||||||
},
|
},
|
||||||
"about": {
|
"about": {
|
||||||
"title": "About"
|
"title": "About"
|
||||||
},
|
},
|
||||||
"sitemap": {
|
"sitemap": {
|
||||||
"title": "Site Map"
|
"title": "Site Map"
|
||||||
},
|
}
|
||||||
"https://git.paulw.xyz": {
|
|
||||||
"title": "Git.PaulW.XYZ"
|
|
||||||
},
|
|
||||||
"https://social.paulw.xyz": {
|
|
||||||
"title": "Social.PaulW.XYZ"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
{"mos-6502":{"title":"MOS 6502 Microprocessor","mtime":"2023-10-29T18:05:52.439Z"},"browsers":{"title":"Web Browsers","mtime":"2024-09-13T08:47:57.942Z"},"zilog-z80":{"title":"Zilog Z80 Microprocessor","mtime":"2023-10-29T18:07:08.579Z"},"steam":{"title":"Steam Client","mtime":"2024-10-10T04:56:04.393Z"},"programming-resources":{"title":"Programming Resources","mtime":"2024-10-10T05:04:27.709Z"},"steam-deck":{"title":"Steam Deck","mtime":"2024-10-10T05:19:16.140Z"},"lua":{"title":"Lua Programming Language","mtime":"2024-09-13T08:45:18.515Z"},"os":{"title":"Operating Systems","mtime":"2024-05-10T16:07:32.581Z"}}
|
{"mos-6502":{"title":"MOS 6502 Microprocessor","mtime":"2023-10-29T18:05:52.439Z"},"zilog-z80":{"title":"Zilog Z80 Microprocessor","mtime":"2023-10-29T18:07:08.579Z"},"browsers":{"title":"Web Browsers","mtime":"2024-09-13T08:47:57.942Z"},"steam":{"title":"Steam Client","mtime":"2024-12-28T17:07:10.689Z"},"lua":{"title":"Lua Programming Language","mtime":"2024-12-28T17:00:55.719Z"},"os":{"title":"Operating Systems","mtime":"2024-12-06T18:53:52.620Z"},"steam-deck":{"title":"Steam Deck","mtime":"2024-12-28T17:10:01.709Z"},"programming-resources":{"title":"Programming Resources","mtime":"2024-12-06T19:02:37.710Z"}}
|
@ -1 +1 @@
|
|||||||
{"title":"PaulW.XYZ","subpages":{"posts":{"title":"Posts","subpages":{}},"notes":{"title":"Notes","subpages":{"mos-6502":{"title":"MOS 6502 Microprocessor","mtime":"2023-10-29T18:05:52.439Z"},"browsers":{"title":"Web Browsers","mtime":"2024-09-13T08:47:57.942Z"},"zilog-z80":{"title":"Zilog Z80 Microprocessor","mtime":"2023-10-29T18:07:08.579Z"},"steam":{"title":"Steam Client","mtime":"2024-10-10T04:56:04.393Z"},"programming-resources":{"title":"Programming Resources","mtime":"2024-10-10T05:04:27.709Z"},"steam-deck":{"title":"Steam Deck","mtime":"2024-10-10T05:19:16.140Z"},"lua":{"title":"Lua Programming Language","mtime":"2024-09-13T08:45:18.515Z"},"os":{"title":"Operating Systems","mtime":"2024-05-10T16:07:32.581Z"}}},"about":{"title":"About"},"sitemap":{"title":"Site Map"},"https://git.paulw.xyz":{"title":"Git.PaulW.XYZ"},"https://social.paulw.xyz":{"title":"Social.PaulW.XYZ"}}}
|
{"title":"PaulW.XYZ","pages":{"posts":{"title":"Posts","pages":{}},"notes":{"title":"Notes","pages":{"mos-6502":{"title":"MOS 6502 Microprocessor","mtime":"2023-10-29T18:05:52.439Z"},"zilog-z80":{"title":"Zilog Z80 Microprocessor","mtime":"2023-10-29T18:07:08.579Z"},"browsers":{"title":"Web Browsers","mtime":"2024-09-13T08:47:57.942Z"},"steam":{"title":"Steam Client","mtime":"2024-12-28T17:07:10.689Z"},"lua":{"title":"Lua Programming Language","mtime":"2024-12-28T17:00:55.719Z"},"os":{"title":"Operating Systems","mtime":"2024-12-06T18:53:52.620Z"},"steam-deck":{"title":"Steam Deck","mtime":"2024-12-28T17:10:01.709Z"},"programming-resources":{"title":"Programming Resources","mtime":"2024-12-06T19:02:37.710Z"}}},"about":{"title":"About"},"sitemap":{"title":"Site Map"}}}
|
@ -122,12 +122,12 @@ async function generateSiteMap() {
|
|||||||
|
|
||||||
const sitemap = {
|
const sitemap = {
|
||||||
title: 'PaulW.XYZ',
|
title: 'PaulW.XYZ',
|
||||||
subpages: await readFilesMetadata('home')
|
pages: await readFilesMetadata('home')
|
||||||
};
|
};
|
||||||
|
|
||||||
const pages = ['posts', 'notes'];
|
const pages = ['posts', 'notes'];
|
||||||
for (const page of pages) {
|
for (const page of pages) {
|
||||||
sitemap.subpages[page].subpages = await readFilesMetadata(page);
|
sitemap.pages[page].pages = await readFilesMetadata(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
await writeFilesMetadata(jsonFilePath('sitemap'), sitemap);
|
await writeFilesMetadata(jsonFilePath('sitemap'), sitemap);
|
||||||
|
7
shims.d.ts
vendored
7
shims.d.ts
vendored
@ -1,8 +1,3 @@
|
|||||||
declare module '*.yaml' {
|
|
||||||
const record: Record<string, any>;
|
|
||||||
export default record;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module '*.md' {
|
declare module '*.md' {
|
||||||
const rawmd: string;
|
const rawmd: string;
|
||||||
export default rawmd;
|
export default rawmd;
|
||||||
@ -11,4 +6,4 @@ declare module '*.md' {
|
|||||||
declare module '*.txt' {
|
declare module '*.txt' {
|
||||||
const content: string;
|
const content: string;
|
||||||
export default content;
|
export default content;
|
||||||
}
|
}
|
||||||
|
@ -235,9 +235,8 @@ code {
|
|||||||
}
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
display: flex;
|
margin: 1rem auto;
|
||||||
flex-direction: column;
|
width:100%;
|
||||||
margin: 1rem 0;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
}
|
}
|
||||||
@ -258,11 +257,6 @@ table tr:last-of-type
|
|||||||
border-bottom-right-radius: 0.5rem;
|
border-bottom-right-radius: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
table thead tr,
|
|
||||||
table tbody tr {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
table tbody tr:nth-of-type(2n) {
|
table tbody tr:nth-of-type(2n) {
|
||||||
background-color: var(--table-even-color);
|
background-color: var(--table-even-color);
|
||||||
}
|
}
|
||||||
@ -273,12 +267,10 @@ table tbody tr:nth-of-type(2n+1) {
|
|||||||
|
|
||||||
table thead tr th,
|
table thead tr th,
|
||||||
table tbody tr td {
|
table tbody tr td {
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
padding: .25rem 0.75rem;
|
padding: .25rem 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
li {
|
ul li {
|
||||||
list-style-type: square;
|
list-style-type: square;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,4 +30,12 @@
|
|||||||
|
|
||||||
.background.spacer {
|
.background.spacer {
|
||||||
height: 25rem;
|
height: 25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.time {
|
||||||
|
text-align: center;
|
||||||
|
display: block;
|
||||||
|
font-style: italic;
|
||||||
|
font-size: 1rem;
|
||||||
|
margin: 0.5rem 0.75rem;
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es2017",
|
"target": "es2023",
|
||||||
"lib": [
|
"lib": [
|
||||||
"dom",
|
"dom",
|
||||||
"dom.iterable",
|
"dom.iterable",
|
||||||
@ -13,7 +13,7 @@
|
|||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "bundler",
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"jsx": "preserve",
|
"jsx": "preserve",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user