Merge pull request #8 from LambdaPaul/dev
This commit is contained in:
commit
fb67086969
@ -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>
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
26
components/recent-notes.tsx
Normal file
26
components/recent-notes.tsx
Normal 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;
|
78
notes/instructure-canvas.md
Normal file
78
notes/instructure-canvas.md
Normal 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
35
notes/mos-6502.md
Normal 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
29
notes/steam.md
Normal 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
31
notes/zilog-z80.md
Normal 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 × 8-bit + 4 × 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
949
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -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"
|
||||||
|
@ -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>
|
||||||
);
|
);
|
||||||
|
@ -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>
|
||||||
)
|
)
|
||||||
|
@ -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
59
pages/notes/[page].tsx
Normal 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
25
pages/notes/index.tsx
Normal 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;
|
@ -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;
|
@ -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"}
|
||||||
]
|
]
|
||||||
|
@ -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;
|
||||||
}
|
}
|
@ -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);
|
|
||||||
}
|
|
13
util/slug.d.ts
vendored
13
util/slug.d.ts
vendored
@ -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 getPostsMeta(): PostMeta[];
|
export function getNote(rawslug: string, filter: Array<any> = []): Note;
|
||||||
|
|
||||||
|
export function getPostsMeta(): PostMeta[];
|
||||||
|
export function getNotesMeta(): NoteMeta[];
|
77
util/slug.js
77
util/slug.js
@ -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
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user