Merge pull request #8 from LambdaPaul/dev

This commit is contained in:
Paul W. 2022-04-28 12:40:26 -04:00 committed by GitHub
commit fb67086969
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 1454 additions and 61 deletions

View File

@ -1,16 +1,15 @@
import Link from 'next/link'; import Link from 'next/link';
import Pages from '../public/pages.json'; import Pages from '../public/pages.json';
import style from '../styles/quick-links.module.css'
function QuickLinks() { function QuickLinks() {
return (<> return (<>
<div className='h2'>Quick Links</div> <div className='h2'>Quick Links</div>
{ {
Pages.map((obj, i) => { Pages.map((obj, i) => {
const extern = obj.link.match(/^http/) && `blue ${style.blueButton}` || ''; const extern = obj.link.match(/^http/) && `blue extern` || '';
return ( return (
<Link key={i} href={obj.link}> <Link key={i} href={obj.link}>
<a className={`${extern} ${style.button} button`}>{obj.title}</a> <a className={`${extern} link button`}>{obj.title}</a>
</Link> </Link>
); );
}) })

View File

@ -0,0 +1,26 @@
import Link from "next/link";
import { NoteMeta } from "../util/slug";
function RecentNotes({ notesMeta }: { notesMeta: NoteMeta[] }) {
return (<>
<div className='h2'>Recent Notes</div>
{notesMeta?.slice(0, 10)
.map((note: any) => {
return <Link key={note.slug} href={`/notes/${note.slug}`}>
<a className={`button link`}>{note.title}</a>
</Link>
})
}
{
notesMeta.length > 10 &&
<div className={''}>
<Link href='/notes'>
<a className='h5'>More...</a>
</Link>
</div>
}
</>
);
}
export default RecentNotes;

View File

@ -0,0 +1,78 @@
---
title: Instructure Canvas
---
## [WIP] Basic Dark Mode Stylesheet
```css
:root {
--tm-bg: #333333;
--tm-col: #EEEEEE;
--tm-href: #42d3ff;
}
a {
color: var(--tm-href);
}
body,
#breadcrumbs,
.yyQPt_cSXm,
.Grouping-styles__title,
.ic-Dashboard-header__layout,
.with-left-side #left-side,
.PlannerHeader-styles__root,
.PlannerItem-styles__root,
.EmptyDays-styles__root,
.fLzZc_bGBk,
.jpyTq_bGBk,
.eoNrR_blJt,
.dLyYq_bXiG,
.Day-styles__root {
color: var(--tm-col);
background-color: var(--tm-bg);
}
.dLyYq_bGBk {
background-color: transparent;
}
.Grouping-styles__title::after {
display: none
}
.eHiXd_dnnz,
a.eHiXd_dnnz,
button.eHiXd_dnnz,
button.eHiXd_dnnz[type="button"],
button.eHiXd_dnnz[type="reset"],
button.eHiXd_dnnz[type="submit"] {
color: var(--tm-col);
}
.eHiXd_eYmo,
a.eHiXd_eYmo,
button.eHiXd_eYmo,
button.eHiXd_eYmo[type="button"],
button.eHiXd_eYmo[type="reset"],
button.eHiXd_eYmo[type="submit"] {
background: var(--tm-bg);
border-color: var(--tm-col);
color: var(--tm-col);
}
.PlannerItem-styles__due,
.PlannerItem-styles__score {
color: var(--tm-col);
}
.eHiXd_brAJ,
a.eHiXd_brAJ,
button.eHiXd_brAJ,
button.eHiXd_brAJ[type="button"],
button.eHiXd_brAJ[type="reset"],
button.eHiXd_brAJ[type="submit"] {
color: var(--tm-href);
}
.yyQPt_cSXm {
color: var(--tm-bg);
}
```

35
notes/mos-6502.md Normal file
View File

@ -0,0 +1,35 @@
---
title: MOS 6502 Microprocessor
---
Name | 6502
--- | ---
Introduced | 1975
Data Width | 8-bit
Address Width | 16-bit
Endianness | Little
Registers | 8-bit A, X, Y, Stack. 16-bit PC
Package | 40-pin DIP
Instruction Count | 56
## Addressing Modes
- Implied
- Immediate
- Absolute
- Indexed Absolute
- Indexed Zero-Page
- Relative
- Accumulator
- Indirect, X
- Indirect, Y
## Datasheets
- [WDC W65C02S NMOS Variant](https://www.westerndesigncenter.com/wdc/documentation/w65c02s.pdf)
## Notable Usage (includes variants)
- Nintendo Entertainment System
- Atari 2600
- Apple II
- Commodore 64
- BBC Micro

29
notes/steam.md Normal file
View File

@ -0,0 +1,29 @@
---
title: Steam Store Client
---
## Steam Console Commands
- [steam://nav/console](steam://nav/console)
- [steam://open/console](steam://open/console)
- The second one will not work if the Steam client is running in the background.
- The `-console` flag can also be used.
## Downloading Older Versions of Applications/Games
Download a single depot:
```
download_depot <appid> <depotid> [<target manifestid>] [<delta manifestid>] [<depot flags filter>]
```
[SteamDB](https://steamdb.info/) can be used to find the required argument values.
## Resources
- [Steam Web API Documentation](https://steamcommunity.com/dev/)
- [Steamworks Documentation](https://partner.steamgames.com/doc/home)
## Unaffiliated, Useful Sites
- [SteamDB](https://steamdb.info/): gives a lot more insight into their platform
- [SteamGifts](https://steamgifts.com/): giveaway Steam keys or take part in giveaways
- [SteamTradeMatcher](https://steamtradematcher.com/): one-to-one trading of items on Steam

31
notes/zilog-z80.md Normal file
View File

@ -0,0 +1,31 @@
---
title: Zilog Z80 Microprocessor
---
|Name | Z80
|--- | ---
|Introduced | 1976
|Data Width | 8-bit
|Address Width | 16-bit
|Binary Comp. | 8080A
|Endianness | Little
|Registers | 208 bits (18 &times; 8-bit + 4 &times; 16-bit) - Static RAM
|Package | 40-pin DIP
|Instruction Count | 158
## Addressing Modes
- Immediate
- Immediate Extended
- Modified Page Zero
- Relative
- Extended
- Indexed Addressing
- Register
- Implied
- Register Indirect
- Bit
## Notable Usage (includes variants)
- Home Computers
- TI Calculators
- Musical Equipment

949
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -14,11 +14,14 @@
"normalize.css": "^8.0.1", "normalize.css": "^8.0.1",
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-markdown": "^7.1.2" "react-markdown": "^7.1.2",
"react-syntax-highlighter": "^15.5.0",
"remark-gfm": "^3.0.1"
}, },
"devDependencies": { "devDependencies": {
"@svgr/webpack": "^5.5.0", "@svgr/webpack": "^5.5.0",
"@types/react-dom": "^17.0.11", "@types/react-dom": "^17.0.11",
"@types/react-syntax-highlighter": "^13.5.2",
"eslint": "^7.32.0", "eslint": "^7.32.0",
"eslint-config-next": "^11.1.4", "eslint-config-next": "^11.1.4",
"typescript": "^4.5.5" "typescript": "^4.5.5"

View File

@ -1,15 +1,22 @@
import Layout from "../components/layout"; import Link from 'next/link';
import Layout from '../components/layout';
function NotFoundPage() { function NotFoundPage() {
return ( return (
<Layout name="... ??? / 404: Not Found"> <Layout title='Page Not Found' name='... ??? / 404: Not Found'>
<section className="block"> <section className='block text center'>
<h1>Error 404: Not Found</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 />
<strong><a href="https://en.wikipedia.org/wiki/List_of_HTTP_status_codes">[Wikipedia] Learn more about HTTP status codes.</a></strong>
</p> </p>
<Link href='/'>
<a className='button green back link'>
Go Home
</a>
</Link>
<a className='button blue link extern' href='https://en.wikipedia.org/wiki/List_of_HTTP_status_codes'>
More on HTTP status codes
</a>
</section> </section>
</Layout> </Layout>
); );

View File

@ -6,7 +6,7 @@ import Layout from '../components/layout';
function AboutPage() { function AboutPage() {
return ( return (
<Layout name='About' title='About this website'> <Layout name='About' title='About PaulW.XYZ'>
<section className='block'> <section className='block'>
This is a personal website written by <a href='https://github.com/LambdaPaul'>@LambdaPaul</a>.<br /><br /> This is a personal website written by <a href='https://github.com/LambdaPaul'>@LambdaPaul</a>.<br /><br />
Why did I write this? Why did I write this?
@ -17,7 +17,9 @@ function AboutPage() {
Got any questions, concerns, or issues? Feel free to contact me via my email: <code>lambdapaul [at] pm [dot] me</code>. Got any questions, concerns, or issues? Feel free to contact me via my email: <code>lambdapaul [at] pm [dot] me</code>.
</section> </section>
<section className='block'> <section className='block'>
<ReactMarkdown>{ReadmeMd.replace(/#{1,5} /g, (s: string) => { return `#${s}` })}</ReactMarkdown> <ReactMarkdown>
{ReadmeMd.replace(/^#{1,5} /g, (s: string) => { return `#${s}` })}
</ReactMarkdown>
</section> </section>
</Layout> </Layout>
) )

View File

@ -1,10 +1,11 @@
import React from 'react'; import React from 'react';
import Layout from '../components/layout'; import Layout from '../components/layout';
import QuickLinks from '../components/quick-links'; import QuickLinks from '../components/quick-links';
import RecentNotes from '../components/recent-notes';
import RecentPosts from '../components/recent-posts'; import RecentPosts from '../components/recent-posts';
import { getPostsMeta, PostMeta } from '../util/slug'; import { getNotesMeta, getPostsMeta, NoteMeta, PostMeta } from '../util/slug';
function HomePage({ postsMeta }: { postsMeta: PostMeta[] }) { function HomePage({ postsMeta, notesMeta }: { postsMeta: PostMeta[], notesMeta: NoteMeta[] }) {
return ( return (
<Layout name='' title='PaulW.XYZ'> <Layout name='' title='PaulW.XYZ'>
<section className='block'> <section className='block'>
@ -13,13 +14,16 @@ function HomePage({ postsMeta }: { postsMeta: PostMeta[] }) {
<section className='block'> <section className='block'>
<RecentPosts postsMeta={postsMeta} /> <RecentPosts postsMeta={postsMeta} />
</section> </section>
<section className='block'>
<RecentNotes notesMeta={notesMeta} />
</section>
</Layout> </Layout>
) )
} }
export async function getStaticProps() { export async function getStaticProps() {
return { return {
props: { postsMeta: getPostsMeta() } props: { postsMeta: getPostsMeta(), notesMeta: getNotesMeta() }
}; };
} }

59
pages/notes/[page].tsx Normal file
View File

@ -0,0 +1,59 @@
import Layout from '../../components/layout';
import { getAllNotes, getNote } from '../../util/slug';
import ReactMarkdown from 'react-markdown';
import { Prism } from 'react-syntax-highlighter';
import dark from 'react-syntax-highlighter/dist/cjs/styles/prism/material-oceanic';
import remarkGfm from 'remark-gfm';
function Note({ note }: any) {
return (<>
<Layout name={note.title} title={note.title} ancestors={[{ name: 'Notes', path: 'notes' }]}>
<section className='block'>
<ReactMarkdown
remarkPlugins={[remarkGfm]}
components={{
code({ node, inline, className, children, ...props }) {
const match = /language-(\w+)/.exec(className || '')
return !inline && match ? (
<Prism
language={match[1]}
style={dark}
PreTag='div'
{...props}
>{String(children).replace(/\n$/, '')}</Prism>
) : <code className={className} {...props}>
{children}
</code>
}
}}
>{note.content}</ReactMarkdown>
</section>
</Layout>
</>
);
}
export async function getStaticProps({ params }: any) {
const note = getNote(params.page);
return {
props: { note }
};
}
export async function getStaticPaths() {
const notes = getAllNotes();
return {
paths: notes.map((note: any) => {
return {
params: {
page: note.slug
}
}
}),
fallback: false
};
}
export default Note;

25
pages/notes/index.tsx Normal file
View File

@ -0,0 +1,25 @@
import Link from 'next/link';
import Layout from '../../components/layout';
import { getNotesMeta, NoteMeta } from '../../util/slug';
function NotesPage({ notesMeta }: { notesMeta: NoteMeta[] }) {
return (
<Layout name='Notes'>
{notesMeta && notesMeta.map((note: NoteMeta, i) => {
return <section key={i} className='h5 block'>
<Link href={`/notes/${note.slug}`}>
{note.title}
</Link>
</section>
})}
</Layout>
)
}
export async function getStaticProps() {
return {
props: { notesMeta: getNotesMeta() }
};
}
export default NotesPage;

View File

@ -3,7 +3,7 @@ import Layout from '../../components/layout';
import date from '../../util/date'; import date from '../../util/date';
import { getPostsMeta, PostMeta } from '../../util/slug'; import { getPostsMeta, PostMeta } from '../../util/slug';
function HomePage({ postsMeta }: { postsMeta: PostMeta[] }) { function PostsPage({ postsMeta }: { postsMeta: PostMeta[] }) {
// todo: create a table-like user interface // todo: create a table-like user interface
return ( // wow this is horrible return ( // wow this is horrible
<Layout name='Posts'> <Layout name='Posts'>
@ -35,4 +35,4 @@ export async function getStaticProps() {
}; };
} }
export default HomePage; export default PostsPage;

View File

@ -9,5 +9,6 @@
{"title":"Matrix", "link": "https://matrix.to/#/@lambdapaul:matrix.org"}, {"title":"Matrix", "link": "https://matrix.to/#/@lambdapaul:matrix.org"},
{"title":"Keybase", "link": "https://keybase.io/lambdapaul"}, {"title":"Keybase", "link": "https://keybase.io/lambdapaul"},
{"title":"Playlists", "link": "/playlists"}, {"title":"Playlists", "link": "/playlists"},
{"title":"Posts", "link": "/posts"} {"title":"Posts", "link": "/posts"},
{"title":"Notes", "link": "/notes"}
] ]

View File

@ -1,5 +1,13 @@
:root { :root {
--main-background-color: #0d1117;
--main-border-color: #555555; --main-border-color: #555555;
--link-color: #009dff;
--primary-green: #099945;
--secondary-green: #1a3a15;
--tertiary-green: #0f200c;
--primary-blue: #0a82b1;
--secondary-blue: #05455f;
--tertiary-blue: #05232f;
} }
@font-face { @font-face {
@ -64,10 +72,10 @@ body {
font-size: 18px; font-size: 18px;
font-weight: 400; font-weight: 400;
line-height: 1.5; line-height: 1.5;
color: #fff; color: #ffffff;
text-align: left; text-align: left;
height: 100%; height: 100%;
background-color: #0d1117; background-color: var(--main-background-color);
background-size: cover; background-size: cover;
padding-bottom: 2.5rem; padding-bottom: 2.5rem;
} }
@ -128,14 +136,16 @@ p {
} }
a { a {
color: #009dff; color: var(--link-color);
text-decoration: underline; text-decoration: underline;
background-color: transparent; background-color: transparent;
outline: none; outline: none;
} }
a:hover { a:hover {
text-decoration: underline; text-decoration: underline;
} }
a:focus { a:focus {
text-decoration: underline dotted; text-decoration: underline dotted;
} }
@ -144,6 +154,39 @@ section {
margin: 0.5rem; margin: 0.5rem;
} }
pre {
width: 100%;
}
table {
display: flex;
flex-direction: column;
border: 1px solid var(--main-border-color);
border-radius: 1rem;
}
table thead {
background: var(--secondary-green);
border-top-left-radius: 1rem;
border-top-right-radius: 1rem;
}
table thead tr,
table tbody tr {
display: flex;
}
table tbody tr+tr {
border-top: 1px solid var(--main-border-color);
}
table thead tr th,
table tbody tr td {
display: flex;
flex: 1;
padding: .5em;
}
.lambda-logo { .lambda-logo {
width: 256px; width: 256px;
height: 256px; height: 256px;
@ -193,32 +236,87 @@ code {
.button { .button {
padding: 0.2rem 1rem; padding: 0.2rem 1rem;
margin: 0.3rem 0.3rem; margin: 0.3rem 0.3rem;
background:#1a3a15; color: #ffffff;
color: rgba(255, 255, 255); background: var(--primary-green);
display: inline-block; display: inline-block;
text-decoration: none; text-decoration: none;
transition: 100ms ease-in-out all; transition: 100ms ease-in-out all;
border: 1px solid #ffffff;
border-radius: 0.5rem; border-radius: 0.5rem;
box-shadow: none;
} }
.button:hover { .button:hover {
text-decoration: none; text-decoration: none;
background:#099945; background: var(--secondary-green);
border-color: #099945; box-shadow: 0 0 0 1px var(--secondary-green);
}
.button:focus {
box-shadow: 0 0 0 2px #ffffff;
} }
.button:active { .button:active {
text-decoration: none; text-decoration: none;
box-shadow: none; box-shadow: none;
transform: translate(1px, 1px); color: #cccccc;
background: var(--tertiary-green);
box-shadow: none;
} }
.button.blue { .button.blue {
background: #05455f; background: var(--primary-blue);
} }
.button.blue:hover { .button.blue:hover {
background:rgb(10, 130, 177); background: var(--secondary-blue);
border-color: rgb(10, 130, 177); box-shadow: 0 0 0 1px var(--secondary-blue);
}
.button.blue:active {
background: var(--tertiary-blue);
box-shadow: none;
}
.text.center {
text-align: center;
}
.no-display {
display: none;
}
.button.link::after {
content: ' \2192';
display: inline-block;
transition: 100ms ease-in-out all;
margin-left: 0.3rem;
}
.button.link:hover {
display: inline-block;
transition: 100ms ease-in-out all;
}
.button.link:hover::after {
transform: translateX(0.2rem) scale(1.3);
}
.button.link.extern:hover::after {
transform: rotateZ(-45deg) scale(1.5);
}
.button.link.back::before {
content: ' \2190';
display: inline-block;
transition: 100ms ease-in-out all;
margin-right: 0.3rem;
}
.button.link:hover::before {
transform: translateX(-0.2rem) scale(1.3);
}
.button.link.back::after {
content: '';
display: none;
} }

View File

@ -1,19 +0,0 @@
.button::after {
content: ' \2192';
display: inline-block;
transition: 100ms ease-in-out all;
margin-left: 0.3rem;
}
.button:hover {
display: inline-block;
transition: 100ms ease-in-out all;
}
.button:hover::after {
transform: translateX(0.2rem) scale(1.3);
}
.blueButton:hover::after {
transform: rotateZ(-45deg) scale(1.5);
}

11
util/slug.d.ts vendored
View File

@ -5,6 +5,12 @@ interface Post {
title?: string; title?: string;
}; };
interface NoteMeta {
title: string;
slug: string;
last_updated: string;
};
interface PostMeta { interface PostMeta {
title: string; title: string;
slug: string; slug: string;
@ -13,5 +19,10 @@ interface PostMeta {
}; };
export function getAllPosts(filter: Array<any> = []): Post[]; export function getAllPosts(filter: Array<any> = []): Post[];
export function getAllNotes(filter: Array<any> = []): Note[];
export function getPost(rawslug: string, filter: Array<any> = []): Post; export function getPost(rawslug: string, filter: Array<any> = []): Post;
export function getNote(rawslug: string, filter: Array<any> = []): Note;
export function getPostsMeta(): PostMeta[]; export function getPostsMeta(): PostMeta[];
export function getNotesMeta(): NoteMeta[];

View File

@ -2,12 +2,15 @@ const fs = require('fs');
const matter = require('gray-matter'); const matter = require('gray-matter');
const { join } = require('path'); const { join } = require('path');
const notesDir = join(process.cwd(), 'notes');
const postsDir = join(process.cwd(), 'posts'); const postsDir = join(process.cwd(), 'posts');
const cacheDir = join(process.cwd(), '.cache'); const cacheDir = join(process.cwd(), '.cache');
const postsCacheFile = join(cacheDir, 'posts.meta.json');
const notesCacheFile = join(cacheDir, 'notes.meta.json');
function getPost(rawslug, filter = []) { function get(dir, rawslug, filter = []) {
const slug = rawslug.replace(/\.md$/, ''); const slug = rawslug.replace(/\.md$/, '');
const path = join(postsDir, `${slug}.md`); const path = join(dir, `${slug}.md`);
const file = fs.readFileSync(path, 'utf-8'); const file = fs.readFileSync(path, 'utf-8');
const { data, content } = matter(file); const { data, content } = matter(file);
@ -41,7 +44,7 @@ function getAllPosts(filter = []) {
return files return files
.filter(c => (!c.match(/^\.]/) && c.match(/\.md$/))) .filter(c => (!c.match(/^\.]/) && c.match(/\.md$/)))
.map(file => { .map(file => {
return getPost(file, filter) return get(postsDir, file, filter)
}) })
.sort((a, b) => { .sort((a, b) => {
const dA = new Date(a['created_at']); const dA = new Date(a['created_at']);
@ -50,7 +53,20 @@ function getAllPosts(filter = []) {
}); });
} }
const postMetaCacheFile = join(cacheDir, 'posts.meta.json'); function getAllNotes(filter = []) {
const files = fs.readdirSync(notesDir);
return files
.filter(c => (!c.match(/^\.]/) && c.match(/\.md$/)))
.map(file => {
return get(notesDir, file, filter)
})
.sort((a, b) => {
const dA = new Date(a['last_updated']);
const dB = new Date(b['last_updated']);
return dB - dA;
});
}
function cachePostsMeta() { // public access cache function cachePostsMeta() { // public access cache
const posts = getAllPosts(['title', 'slug', 'created_at', 'last_updated']); const posts = getAllPosts(['title', 'slug', 'created_at', 'last_updated']);
@ -59,24 +75,69 @@ function cachePostsMeta() { // public access cache
fs.mkdirSync(cacheDir); fs.mkdirSync(cacheDir);
} }
fs.writeFile(postMetaCacheFile, JSON.stringify(posts), (e) => { fs.writeFile(postsCacheFile, JSON.stringify(posts), (e) => {
if (e) if (e)
console.error(e); console.error(e);
}); });
return posts; return posts;
} }
function getPostsMeta() { function cacheNotesMeta() {
const notes = getAllNotes(['title', 'slug', 'last_updated']);
if (!fs.existsSync(cacheDir)) {
fs.mkdirSync(cacheDir);
}
fs.writeFile(notesCacheFile, JSON.stringify(notes), (e) => {
if (e)
console.error(e);
});
return notes;
}
function getMetaFromFile(name) {
try { try {
const file = fs.readFileSync(postMetaCacheFile, 'utf-8'); const file = fs.readFileSync(name, 'utf-8');
return JSON.parse(file); return JSON.parse(file);
} catch (e) { } catch (e) {
if (name)
return cachePostsMeta(); return cachePostsMeta();
} }
} }
function cache() { function cache() {
cachePostsMeta(); cachePostsMeta();
cacheNotesMeta();
} }
module.exports = { getAllPosts, getPost, getPostsMeta, cache }; const getPostsMeta = () => {
try {
const file = fs.readFileSync(postsCacheFile, 'utf-8');
return JSON.parse(file);
} catch (e) {
return cachePostsMeta();
}
};
const getNotesMeta = () => {
try {
const file = fs.readFileSync(notesCacheFile, 'utf-8');
return JSON.parse(file);
} catch (e) {
return cacheNotesMeta();
}
};
const getPost = (s, f) => {return get(postsDir, s, f)};
const getNote = (s, f) => {return get(notesDir, s, f)};
module.exports = {
getAllPosts,
getAllNotes,
getPostsMeta,
getNotesMeta,
getPost,
getNote,
cache
};