Merge pull request #8 from LambdaPaul/dev
This commit is contained in:
commit
fb67086969
@ -1,16 +1,15 @@
|
||||
import Link from 'next/link';
|
||||
import Pages from '../public/pages.json';
|
||||
import style from '../styles/quick-links.module.css'
|
||||
|
||||
function QuickLinks() {
|
||||
return (<>
|
||||
<div className='h2'>Quick Links</div>
|
||||
{
|
||||
Pages.map((obj, i) => {
|
||||
const extern = obj.link.match(/^http/) && `blue ${style.blueButton}` || '';
|
||||
const extern = obj.link.match(/^http/) && `blue extern` || '';
|
||||
return (
|
||||
<Link key={i} href={obj.link}>
|
||||
<a className={`${extern} ${style.button} button`}>{obj.title}</a>
|
||||
<a className={`${extern} link button`}>{obj.title}</a>
|
||||
</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",
|
||||
"react": "^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": {
|
||||
"@svgr/webpack": "^5.5.0",
|
||||
"@types/react-dom": "^17.0.11",
|
||||
"@types/react-syntax-highlighter": "^13.5.2",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-next": "^11.1.4",
|
||||
"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() {
|
||||
|
||||
return (
|
||||
<Layout name="... ??? / 404: Not Found">
|
||||
<section className="block">
|
||||
<h1>Error 404: Not Found</h1>
|
||||
<Layout title='Page Not Found' name='... ??? / 404: Not Found'>
|
||||
<section className='block text center'>
|
||||
<h1>Error 404</h1>
|
||||
<p>
|
||||
<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>
|
||||
<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>
|
||||
</Layout>
|
||||
);
|
||||
|
@ -6,7 +6,7 @@ import Layout from '../components/layout';
|
||||
|
||||
function AboutPage() {
|
||||
return (
|
||||
<Layout name='About' title='About this website'>
|
||||
<Layout name='About' title='About PaulW.XYZ'>
|
||||
<section className='block'>
|
||||
This is a personal website written by <a href='https://github.com/LambdaPaul'>@LambdaPaul</a>.<br /><br />
|
||||
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>.
|
||||
</section>
|
||||
<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>
|
||||
</Layout>
|
||||
)
|
||||
|
@ -1,10 +1,11 @@
|
||||
import React from 'react';
|
||||
import Layout from '../components/layout';
|
||||
import QuickLinks from '../components/quick-links';
|
||||
import RecentNotes from '../components/recent-notes';
|
||||
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 (
|
||||
<Layout name='' title='PaulW.XYZ'>
|
||||
<section className='block'>
|
||||
@ -13,13 +14,16 @@ function HomePage({ postsMeta }: { postsMeta: PostMeta[] }) {
|
||||
<section className='block'>
|
||||
<RecentPosts postsMeta={postsMeta} />
|
||||
</section>
|
||||
<section className='block'>
|
||||
<RecentNotes notesMeta={notesMeta} />
|
||||
</section>
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
export async function getStaticProps() {
|
||||
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 { getPostsMeta, PostMeta } from '../../util/slug';
|
||||
|
||||
function HomePage({ postsMeta }: { postsMeta: PostMeta[] }) {
|
||||
function PostsPage({ postsMeta }: { postsMeta: PostMeta[] }) {
|
||||
// todo: create a table-like user interface
|
||||
return ( // wow this is horrible
|
||||
<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":"Keybase", "link": "https://keybase.io/lambdapaul"},
|
||||
{"title":"Playlists", "link": "/playlists"},
|
||||
{"title":"Posts", "link": "/posts"}
|
||||
{"title":"Posts", "link": "/posts"},
|
||||
{"title":"Notes", "link": "/notes"}
|
||||
]
|
||||
|
@ -1,5 +1,13 @@
|
||||
:root {
|
||||
--main-background-color: #0d1117;
|
||||
--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 {
|
||||
@ -64,10 +72,10 @@ body {
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
color: #fff;
|
||||
color: #ffffff;
|
||||
text-align: left;
|
||||
height: 100%;
|
||||
background-color: #0d1117;
|
||||
background-color: var(--main-background-color);
|
||||
background-size: cover;
|
||||
padding-bottom: 2.5rem;
|
||||
}
|
||||
@ -128,14 +136,16 @@ p {
|
||||
}
|
||||
|
||||
a {
|
||||
color: #009dff;
|
||||
color: var(--link-color);
|
||||
text-decoration: underline;
|
||||
background-color: transparent;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:focus {
|
||||
text-decoration: underline dotted;
|
||||
}
|
||||
@ -144,6 +154,39 @@ section {
|
||||
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 {
|
||||
width: 256px;
|
||||
height: 256px;
|
||||
@ -193,32 +236,87 @@ code {
|
||||
.button {
|
||||
padding: 0.2rem 1rem;
|
||||
margin: 0.3rem 0.3rem;
|
||||
background:#1a3a15;
|
||||
color: rgba(255, 255, 255);
|
||||
color: #ffffff;
|
||||
background: var(--primary-green);
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
transition: 100ms ease-in-out all;
|
||||
border: 1px solid #ffffff;
|
||||
border-radius: 0.5rem;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
text-decoration: none;
|
||||
background:#099945;
|
||||
border-color: #099945;
|
||||
background: var(--secondary-green);
|
||||
box-shadow: 0 0 0 1px var(--secondary-green);
|
||||
}
|
||||
|
||||
.button:focus {
|
||||
box-shadow: 0 0 0 2px #ffffff;
|
||||
}
|
||||
|
||||
.button:active {
|
||||
text-decoration: none;
|
||||
box-shadow: none;
|
||||
transform: translate(1px, 1px);
|
||||
color: #cccccc;
|
||||
background: var(--tertiary-green);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.button.blue {
|
||||
background: #05455f;
|
||||
background: var(--primary-blue);
|
||||
}
|
||||
|
||||
.button.blue:hover {
|
||||
background:rgb(10, 130, 177);
|
||||
border-color: rgb(10, 130, 177);
|
||||
background: var(--secondary-blue);
|
||||
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;
|
||||
};
|
||||
|
||||
interface NoteMeta {
|
||||
title: string;
|
||||
slug: string;
|
||||
last_updated: string;
|
||||
};
|
||||
|
||||
interface PostMeta {
|
||||
title: string;
|
||||
slug: string;
|
||||
@ -13,5 +19,10 @@ interface PostMeta {
|
||||
};
|
||||
|
||||
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 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 { join } = require('path');
|
||||
|
||||
const notesDir = join(process.cwd(), 'notes');
|
||||
const postsDir = join(process.cwd(), 'posts');
|
||||
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 path = join(postsDir, `${slug}.md`);
|
||||
const path = join(dir, `${slug}.md`);
|
||||
const file = fs.readFileSync(path, 'utf-8');
|
||||
const { data, content } = matter(file);
|
||||
|
||||
@ -41,7 +44,7 @@ function getAllPosts(filter = []) {
|
||||
return files
|
||||
.filter(c => (!c.match(/^\.]/) && c.match(/\.md$/)))
|
||||
.map(file => {
|
||||
return getPost(file, filter)
|
||||
return get(postsDir, file, filter)
|
||||
})
|
||||
.sort((a, b) => {
|
||||
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
|
||||
const posts = getAllPosts(['title', 'slug', 'created_at', 'last_updated']);
|
||||
@ -59,24 +75,69 @@ function cachePostsMeta() { // public access cache
|
||||
fs.mkdirSync(cacheDir);
|
||||
}
|
||||
|
||||
fs.writeFile(postMetaCacheFile, JSON.stringify(posts), (e) => {
|
||||
fs.writeFile(postsCacheFile, JSON.stringify(posts), (e) => {
|
||||
if (e)
|
||||
console.error(e);
|
||||
});
|
||||
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 {
|
||||
const file = fs.readFileSync(postMetaCacheFile, 'utf-8');
|
||||
const file = fs.readFileSync(name, 'utf-8');
|
||||
return JSON.parse(file);
|
||||
} catch (e) {
|
||||
if (name)
|
||||
return cachePostsMeta();
|
||||
}
|
||||
}
|
||||
|
||||
function cache() {
|
||||
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