Add license; make corrections; cleanup
This commit is contained in:
parent
7d17d88b60
commit
24c2bcfff0
21
LICENSE.txt
Normal file
21
LICENSE.txt
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Paul W.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -1,105 +0,0 @@
|
||||
import { Dispatch, KeyboardEvent as ReactKeyboardEvent, MutableRefObject, SetStateAction } from 'react';
|
||||
import Result from './fuzzy-result';
|
||||
import style from '../styles/fuzzy.module.css';
|
||||
|
||||
export type FuzzyConstr = {
|
||||
pages: Page[],
|
||||
searchField: MutableRefObject<null>,
|
||||
searchValue: string,
|
||||
resultsValue: JSX.Element,
|
||||
setResultsValue: Dispatch<SetStateAction<JSX.Element>>,
|
||||
maxResults?: number
|
||||
};
|
||||
|
||||
export type Page = {
|
||||
title: string;
|
||||
link: string;
|
||||
};
|
||||
|
||||
export default class Fuzzy {
|
||||
searchValue: string = '';
|
||||
searchField: HTMLInputElement | null;
|
||||
pages: Page[];
|
||||
setResultsValue: Dispatch<SetStateAction<JSX.Element>>;
|
||||
resultsValue: JSX.Element;
|
||||
maxResults: number;
|
||||
|
||||
constructor(obj: FuzzyConstr) {
|
||||
this.searchField = obj.searchField.current;
|
||||
this.resultsValue = obj.resultsValue; // not yet implemented. have to look into lazy eval in js
|
||||
this.setResultsValue = obj.setResultsValue;
|
||||
this.searchValue = obj.searchValue || '';
|
||||
|
||||
this.pages = obj.pages
|
||||
this.maxResults = obj.maxResults || this.pages.length;
|
||||
}
|
||||
|
||||
searchKeyUpListener(e: ReactKeyboardEvent) {
|
||||
this.showSearchResults();
|
||||
}
|
||||
|
||||
showSearchResults(): void {
|
||||
let searchValue: string = this.searchValue.toLowerCase();
|
||||
searchValue = searchValue.trimStart().trimEnd();
|
||||
if (this.maxResults !== undefined && searchValue === ''){
|
||||
this.setResultsValue(
|
||||
<>
|
||||
<h2>Search PaulW.XYZ</h2>
|
||||
<div>Enter a page or directory name in the search bar above.</div>
|
||||
</>
|
||||
)
|
||||
return;
|
||||
}
|
||||
|
||||
let results = [];
|
||||
for (const [idx, page] of this.pages.entries()) {
|
||||
const ret = this.fuzzySearch(page.title, searchValue);
|
||||
if (ret === null)
|
||||
continue;
|
||||
results.push({ formatted: ret.formatted, link: page.link, score: ret.score });
|
||||
}
|
||||
|
||||
if (results.length <= 0)
|
||||
return this.setResultsValue(<>Unknown command or no matching pages found.</>);
|
||||
|
||||
results.sort((x, y) => { return x.score - y.score });
|
||||
|
||||
this.setResultsValue(
|
||||
<>
|
||||
{results.map((res: { formatted: JSX.Element[], link: string, score: number }, idx) => {
|
||||
return (<Result
|
||||
link={res.link}
|
||||
formatted={res.formatted}
|
||||
idx={idx}
|
||||
key={`res-${idx}`} />);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
fuzzySearch(findIn: string, find: string) {
|
||||
let search = find.replace(/\s/g, '');
|
||||
search = search.toLowerCase();
|
||||
let tokens: string[] = findIn.split('');
|
||||
let elements: JSX.Element[] = new Array(tokens.length);
|
||||
let pc = 0;
|
||||
let score = 0;
|
||||
|
||||
for (const [i, ch] of tokens.entries()) {
|
||||
if (ch.toLowerCase() === search[pc]) {
|
||||
score += i - pc;
|
||||
elements[i] = (<span className={style.highlight}>{ch}</span>);
|
||||
pc++;
|
||||
if (search.length < pc)
|
||||
return null;
|
||||
continue;
|
||||
}
|
||||
elements[i] = (<>{ch}</>); // not very nice :(
|
||||
}
|
||||
|
||||
if (search.length === pc)
|
||||
return { formatted: elements, score: (score / search.length) };
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
import { ChangeEvent, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import Fuzzy from './_fuzzy';
|
||||
import pages from '../public/pages.json';
|
||||
import style from '../styles/fuzzy.module.css';
|
||||
// @ts-ignore
|
||||
import posts from '../posts/meta.json' // I do not like this
|
||||
|
||||
function FuzzyBar(): JSX.Element {
|
||||
const searchField = useRef<any>(null);
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
const [resultsValue, setResultsValue] = useState(<></>);
|
||||
let [metaKey, setMetaKey] = useState('Ctrl');
|
||||
|
||||
const [show, setShow] = useState(false);
|
||||
|
||||
let fuzz: Fuzzy | null = null;
|
||||
|
||||
let entries = [...pages];
|
||||
|
||||
for (const [k,v] of posts.entries()) {
|
||||
const item = v as any;
|
||||
if (item.title && item.slug)
|
||||
entries.push({title: item.title, link: `posts/${item.slug}`});
|
||||
}
|
||||
|
||||
try {
|
||||
fuzz = new Fuzzy({
|
||||
pages: entries,
|
||||
searchField: searchField,
|
||||
searchValue: searchValue,
|
||||
resultsValue: resultsValue,
|
||||
setResultsValue: setResultsValue,
|
||||
maxResults: 5
|
||||
});
|
||||
} catch (e: any) {
|
||||
console.error(e.message);
|
||||
}
|
||||
|
||||
function searchInput(e: ChangeEvent<HTMLInputElement>) {
|
||||
setSearchValue(e.target.value);
|
||||
}
|
||||
|
||||
const toggleSearch = useCallback(() => {
|
||||
setShow(!show);
|
||||
fuzz?.showSearchResults();
|
||||
searchField.current?.focus();
|
||||
}, [fuzz, show]);
|
||||
|
||||
useEffect(() => {
|
||||
if (window.navigator.userAgent.match(/mac[\s]?os/i))
|
||||
setMetaKey('⌘ Cmd');
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const event = (e: KeyboardEvent) => {
|
||||
if (e.code === 'KeyK' && (e.ctrlKey || e.metaKey)) {
|
||||
e.preventDefault();
|
||||
toggleSearch();
|
||||
}
|
||||
|
||||
if (e.code === 'KeyP' && (e.ctrlKey || e.metaKey) && e.shiftKey) {
|
||||
e.preventDefault();
|
||||
alert('not really sure what to do here lol');
|
||||
}
|
||||
|
||||
if (show)
|
||||
searchField.current?.focus();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
window.addEventListener('keydown', event);
|
||||
|
||||
return () => { window.removeEventListener('keydown', event); }
|
||||
}, [fuzz, show, toggleSearch]);
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
{
|
||||
show ?
|
||||
<div className={`fuzzynav ${style.container}`}>
|
||||
<input type='text'
|
||||
className={style.search}
|
||||
value={searchValue}
|
||||
placeholder='Go to ...'
|
||||
ref={searchField}
|
||||
onChange={searchInput}
|
||||
onKeyUp={(e) => { fuzz?.searchKeyUpListener(e) }} />
|
||||
<div
|
||||
id='results'
|
||||
className={style.results}>{resultsValue}</div>
|
||||
</div>
|
||||
: <></>
|
||||
}
|
||||
|
||||
|
||||
<a className={style.searchBar} onClick={toggleSearch}>
|
||||
<span className={style.searchTerm}>Search</span>
|
||||
<div className={style.keybind}>
|
||||
<span className={style.key}>{metaKey}</span> <span className={style.key}>K</span>
|
||||
</div>
|
||||
</a>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default FuzzyBar;
|
@ -1,20 +0,0 @@
|
||||
import style from '../styles/fuzzy.module.css';
|
||||
import Link from 'next/link';
|
||||
|
||||
function Result(props: { formatted: JSX.Element[], key: string, link: string, idx: number }) {
|
||||
|
||||
return (
|
||||
<Link href={props.link}>
|
||||
<a className={style.hyperlink}>
|
||||
<div className={style['hyperlink-name']}>
|
||||
{props.formatted}
|
||||
</div>
|
||||
<div className={style['hyperlink-url']}>
|
||||
{props.link}
|
||||
</div>
|
||||
</a>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
export default Result;
|
@ -1,6 +1,5 @@
|
||||
import Meta from './meta';
|
||||
import Title from './title';
|
||||
// import FuzzyBar from './fuzzy-bar';
|
||||
|
||||
type ChildrenType = JSX.Element | Array<ChildrenType>;
|
||||
|
||||
@ -16,7 +15,6 @@ function Layout({ name, title, children, ancestors }: LayoutProps) {
|
||||
<>
|
||||
<Meta name={name} ancestors={ancestors} />
|
||||
<Title title={title} name={name} ancestors={ancestors} />
|
||||
{/* <FuzzyBar /> */}
|
||||
<div className='container'>
|
||||
{children}
|
||||
</div>
|
||||
|
@ -7,7 +7,7 @@ function Meta({name, ancestors}
|
||||
return name;
|
||||
|
||||
let path = '';
|
||||
ancestors.map((obj) => {
|
||||
ancestors.forEach((obj) => {
|
||||
path = `${path}${obj.name} /`;
|
||||
});
|
||||
|
||||
|
@ -2,19 +2,21 @@ import Link from 'next/link';
|
||||
import Pages from '../public/pages.json';
|
||||
|
||||
function QuickLinks() {
|
||||
return (<>
|
||||
<div className='h2'>Quick Links</div>
|
||||
{
|
||||
Pages.map((obj, i) => {
|
||||
const extern = obj.link.match(/^http/) && `blue extern` || '';
|
||||
return (
|
||||
<Link key={i} href={obj.link}>
|
||||
<a className={`${extern} link button`}>{obj.title}</a>
|
||||
</Link>
|
||||
);
|
||||
})
|
||||
}
|
||||
</>);
|
||||
return (
|
||||
<div className='block'>
|
||||
<div className='h2'>Quick Links</div>
|
||||
{
|
||||
Object.entries(Pages).map(([title, link], i) => {
|
||||
const extern = link.match(/^http/) && `blue extern` || '';
|
||||
return (
|
||||
<Link key={i} href={link}>
|
||||
<a className={`${extern} link button`}>{title}</a>
|
||||
</Link>
|
||||
);
|
||||
})
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default QuickLinks;
|
@ -2,24 +2,25 @@ 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}`}>
|
||||
return (
|
||||
<div className='block'>
|
||||
<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>
|
||||
}
|
||||
</>
|
||||
})
|
||||
}
|
||||
{
|
||||
notesMeta.length > 10 &&
|
||||
<div className={''}>
|
||||
<Link href='/notes'>
|
||||
<a className='h5'>More...</a>
|
||||
</Link>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -4,30 +4,31 @@ import { PostMeta } from "../util/slug";
|
||||
import style from '../styles/recent-posts.module.css';
|
||||
|
||||
function RecentPosts({ postsMeta }: { postsMeta: PostMeta[] }) {
|
||||
return (<>
|
||||
<div className='h2'>Recent Posts</div>
|
||||
<div className={style.container}>
|
||||
{postsMeta?.slice(0, 10)
|
||||
.map((post: any) => {
|
||||
return <div className={style.block} key={post.slug}>
|
||||
<Link href={`/posts/${post.slug}`}>
|
||||
<a className={`${style.postTitle} h5`}>{post.title}</a>
|
||||
</Link>
|
||||
<span className={style.postDate}>
|
||||
{date.prettyPrint(new Date(post.created_at))}
|
||||
</span>
|
||||
</div>
|
||||
})}
|
||||
</div>
|
||||
{
|
||||
postsMeta.length > 10 &&
|
||||
<div className={style.more}>
|
||||
<Link href='/posts'>
|
||||
<a className='h5'>More...</a>
|
||||
</Link>
|
||||
return (
|
||||
<div className='block'>
|
||||
<div className='h2'>Recent Posts</div>
|
||||
<div className={style.container}>
|
||||
{postsMeta?.slice(0, 10)
|
||||
.map((post: any) => {
|
||||
return <div className={style.block} key={post.slug}>
|
||||
<Link href={`/posts/${post.slug}`}>
|
||||
<a className={`${style.postTitle} h5`}>{post.title}</a>
|
||||
</Link>
|
||||
<span className={style.postDate}>
|
||||
{date.prettyPrint(new Date(post.created_at))}
|
||||
</span>
|
||||
</div>
|
||||
})}
|
||||
</div>
|
||||
}
|
||||
</>
|
||||
{
|
||||
postsMeta.length > 10 &&
|
||||
<div className={style.more}>
|
||||
<Link href='/posts'>
|
||||
<a className='h5'>More...</a>
|
||||
</Link>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -9,11 +9,11 @@ type propsObj = {
|
||||
|
||||
function createPathElements(ancestors: Array<{ name: string, path: string }>) {
|
||||
let currentPath = '';
|
||||
return ancestors.map((ancestor) => {
|
||||
return ancestors.map((ancestor, id) => {
|
||||
currentPath += `/${ancestor.path}`
|
||||
return (
|
||||
<>
|
||||
<Link href={currentPath}>
|
||||
<Link key={id + 1} href={currentPath}>
|
||||
<a>{ancestor.name}</a>
|
||||
</Link>
|
||||
<> / </>
|
||||
|
@ -36,6 +36,10 @@ module.exports = {
|
||||
test: /\.otf$/,
|
||||
type: 'asset/resource',
|
||||
},
|
||||
{
|
||||
test: /\.txt$/,
|
||||
type: 'asset/source',
|
||||
},
|
||||
{
|
||||
resourceQuery: /raw/,
|
||||
type: 'asset/source',
|
||||
|
@ -1,28 +1,36 @@
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
|
||||
// @ts-ignore
|
||||
import ReadmeMd from '../README.md';
|
||||
import License from '../LICENSE.txt';
|
||||
import Layout from '../components/layout';
|
||||
|
||||
function AboutPage() {
|
||||
return (
|
||||
<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?
|
||||
I do not really know, at least the content I put here. I guess I wanted a place on the web where I wanted to put everything I think is worth looking at some point in the future.
|
||||
<br />
|
||||
<br />
|
||||
It seems wise to have things up here even though they may embarrass me at some point in the future, as many of the things I have done in the past have.
|
||||
Got any questions, concerns, or issues? Feel free to contact me via my email: <code>lambdapaul [at] pm [dot] me</code>.
|
||||
<p>This is a personal website written by <a href='https://github.com/LambdaPaul'>@LambdaPaul</a>.</p>
|
||||
<p>Why did I write this?
|
||||
I do not really know, at least the content I put here.
|
||||
I guess I wanted a place on the web where I wanted to put everything I think is worth looking at some point in the future.
|
||||
It seems wise to have things up here even though they may not be worthwhile, as many things ultimately are not.</p>
|
||||
<p>Got any questions, concerns, or issues? Contact me via my email: <code>lambdapaul [at] pm [dot] me</code>.</p>
|
||||
</section>
|
||||
<hr />
|
||||
<section className='block'>
|
||||
<p>Source for this site is available at <a className='button link extern blue' href='https://github.com/LambdaPaul/www'>GitHub / LambdaPaul / www</a></p>
|
||||
<p>Relevant information regarding the source is available on the repo and is also provided below.</p>
|
||||
</section>
|
||||
<section className='block'>
|
||||
<h2>README</h2>
|
||||
<ReactMarkdown>
|
||||
{ReadmeMd.replace(/^#{1,5} /g, (s: string) => { return `#${s}` })}
|
||||
</ReactMarkdown>
|
||||
</section>
|
||||
<section className='block'>
|
||||
<h2>LICENSE</h2>
|
||||
<pre>{License}</pre>
|
||||
</section>
|
||||
</Layout>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default AboutPage;
|
||||
|
@ -8,15 +8,9 @@ import { getNotesMeta, getPostsMeta, NoteMeta, PostMeta } from '../util/slug';
|
||||
function HomePage({ postsMeta, notesMeta }: { postsMeta: PostMeta[], notesMeta: NoteMeta[] }) {
|
||||
return (
|
||||
<Layout name='' title='PaulW.XYZ'>
|
||||
<section className='block'>
|
||||
<QuickLinks />
|
||||
</section>
|
||||
<section className='block'>
|
||||
<RecentPosts postsMeta={postsMeta} />
|
||||
</section>
|
||||
<section className='block'>
|
||||
<RecentNotes notesMeta={notesMeta} />
|
||||
</section>
|
||||
<QuickLinks />
|
||||
<RecentPosts postsMeta={postsMeta} />
|
||||
<RecentNotes notesMeta={notesMeta} />
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
@ -22,8 +22,8 @@ function Note({ note }: any) {
|
||||
style={monokaiSublime}
|
||||
wrapLongLines={true}
|
||||
PreTag='div'
|
||||
codeTagProps={{style: {display: 'block'}}}
|
||||
customStyle={{padding:'0', borderRadius: '1rem', maxHeight: '400px'}}
|
||||
codeTagProps={{ style: { display: 'block' } }}
|
||||
customStyle={{ padding: '0', borderRadius: '1rem' }}
|
||||
{...props}
|
||||
>{children}</SyntaxHighlighter>
|
||||
)
|
||||
|
@ -6,13 +6,13 @@ import style from '../../styles/post.module.css';
|
||||
function Post({ post }: any) { // eh
|
||||
return (<>
|
||||
<Layout name={post.title} title={post.title} ancestors={[{ name: 'Posts', path: 'posts' }]}>
|
||||
<div className={style.imageBlock} style={{ backgroundImage: post.cover ? `url(/assets/images/${post.cover})` : '' }}></div>
|
||||
|
||||
<div className={style.spacer}></div>
|
||||
<section className={`${style.block} block`}>
|
||||
<ReactMarkdown>{post.content}</ReactMarkdown>
|
||||
</section>
|
||||
<div className={style.spacer}></div>
|
||||
{post.cover
|
||||
&& <div className={style.imageBlock} style={{ backgroundImage: `url(/assets/images/${post.cover})` }}></div>}
|
||||
<div className={style.spacer}></div>
|
||||
<section className={`${style.block} block`}>
|
||||
<ReactMarkdown>{post.content}</ReactMarkdown>
|
||||
</section>
|
||||
<div className={style.spacer}></div>
|
||||
</Layout>
|
||||
|
||||
</>
|
||||
|
Binary file not shown.
BIN
public/assets/fonts/EB_Garamond/EBGaramond-VariableFont_wght.ttf
Normal file
BIN
public/assets/fonts/EB_Garamond/EBGaramond-VariableFont_wght.ttf
Normal file
Binary file not shown.
93
public/assets/fonts/EB_Garamond/OFL.txt
Normal file
93
public/assets/fonts/EB_Garamond/OFL.txt
Normal file
@ -0,0 +1,93 @@
|
||||
Copyright 2017 The EB Garamond Project Authors (https://github.com/octaviopardo/EBGaramond12)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
73
public/assets/fonts/EB_Garamond/README.txt
Normal file
73
public/assets/fonts/EB_Garamond/README.txt
Normal file
@ -0,0 +1,73 @@
|
||||
EB Garamond Variable Font
|
||||
=========================
|
||||
|
||||
This download contains EB Garamond as both variable fonts and static fonts.
|
||||
|
||||
EB Garamond is a variable font with this axis:
|
||||
wght
|
||||
|
||||
This means all the styles are contained in these files:
|
||||
EBGaramond-VariableFont_wght.ttf
|
||||
EBGaramond-Italic-VariableFont_wght.ttf
|
||||
|
||||
If your app fully supports variable fonts, you can now pick intermediate styles
|
||||
that aren’t available as static fonts. Not all apps support variable fonts, and
|
||||
in those cases you can use the static font files for EB Garamond:
|
||||
static/EBGaramond-Regular.ttf
|
||||
static/EBGaramond-Medium.ttf
|
||||
static/EBGaramond-SemiBold.ttf
|
||||
static/EBGaramond-Bold.ttf
|
||||
static/EBGaramond-ExtraBold.ttf
|
||||
static/EBGaramond-Italic.ttf
|
||||
static/EBGaramond-MediumItalic.ttf
|
||||
static/EBGaramond-SemiBoldItalic.ttf
|
||||
static/EBGaramond-BoldItalic.ttf
|
||||
static/EBGaramond-ExtraBoldItalic.ttf
|
||||
|
||||
Get started
|
||||
-----------
|
||||
|
||||
1. Install the font files you want to use
|
||||
|
||||
2. Use your app's font picker to view the font family and all the
|
||||
available styles
|
||||
|
||||
Learn more about variable fonts
|
||||
-------------------------------
|
||||
|
||||
https://developers.google.com/web/fundamentals/design-and-ux/typography/variable-fonts
|
||||
https://variablefonts.typenetwork.com
|
||||
https://medium.com/variable-fonts
|
||||
|
||||
In desktop apps
|
||||
|
||||
https://theblog.adobe.com/can-variable-fonts-illustrator-cc
|
||||
https://helpx.adobe.com/nz/photoshop/using/fonts.html#variable_fonts
|
||||
|
||||
Online
|
||||
|
||||
https://developers.google.com/fonts/docs/getting_started
|
||||
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide
|
||||
https://developer.microsoft.com/en-us/microsoft-edge/testdrive/demos/variable-fonts
|
||||
|
||||
Installing fonts
|
||||
|
||||
MacOS: https://support.apple.com/en-us/HT201749
|
||||
Linux: https://www.google.com/search?q=how+to+install+a+font+on+gnu%2Blinux
|
||||
Windows: https://support.microsoft.com/en-us/help/314960/how-to-install-or-remove-a-font-in-windows
|
||||
|
||||
Android Apps
|
||||
|
||||
https://developers.google.com/fonts/docs/android
|
||||
https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts
|
||||
|
||||
License
|
||||
-------
|
||||
Please read the full license text (OFL.txt) to understand the permissions,
|
||||
restrictions and requirements for usage, redistribution, and modification.
|
||||
|
||||
You can use them freely in your products & projects - print or digital,
|
||||
commercial or otherwise.
|
||||
|
||||
This isn't legal advice, please consider consulting a lawyer and see the full
|
||||
license for all details.
|
BIN
public/assets/fonts/EB_Garamond/static/EBGaramond-Bold.ttf
Normal file
BIN
public/assets/fonts/EB_Garamond/static/EBGaramond-Bold.ttf
Normal file
Binary file not shown.
BIN
public/assets/fonts/EB_Garamond/static/EBGaramond-BoldItalic.ttf
Normal file
BIN
public/assets/fonts/EB_Garamond/static/EBGaramond-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
public/assets/fonts/EB_Garamond/static/EBGaramond-ExtraBold.ttf
Normal file
BIN
public/assets/fonts/EB_Garamond/static/EBGaramond-ExtraBold.ttf
Normal file
Binary file not shown.
Binary file not shown.
BIN
public/assets/fonts/EB_Garamond/static/EBGaramond-Italic.ttf
Normal file
BIN
public/assets/fonts/EB_Garamond/static/EBGaramond-Italic.ttf
Normal file
Binary file not shown.
BIN
public/assets/fonts/EB_Garamond/static/EBGaramond-Medium.ttf
Normal file
BIN
public/assets/fonts/EB_Garamond/static/EBGaramond-Medium.ttf
Normal file
Binary file not shown.
Binary file not shown.
BIN
public/assets/fonts/EB_Garamond/static/EBGaramond-Regular.ttf
Normal file
BIN
public/assets/fonts/EB_Garamond/static/EBGaramond-Regular.ttf
Normal file
Binary file not shown.
BIN
public/assets/fonts/EB_Garamond/static/EBGaramond-SemiBold.ttf
Normal file
BIN
public/assets/fonts/EB_Garamond/static/EBGaramond-SemiBold.ttf
Normal file
Binary file not shown.
Binary file not shown.
@ -1,14 +1,14 @@
|
||||
[
|
||||
{"title":"About", "link": "/about"},
|
||||
{"title":"Resources", "link": "/resources"},
|
||||
{"title":"Recommended", "link": "/recommended"},
|
||||
{"title":"GitHub", "link": "https://github.com/lambdapaul"},
|
||||
{"title":"GitLab", "link": "https://gitlab.com/lambdapaul"},
|
||||
{"title":"Twitter", "link": "https://twitter.com/lambda_paul"},
|
||||
{"title":"Mastodon", "link": "https://mastodon.social/@lambdapaul"},
|
||||
{"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":"Notes", "link": "/notes"}
|
||||
]
|
||||
{
|
||||
"About": "/about",
|
||||
"Resources": "/resources",
|
||||
"Recommended": "/recommended",
|
||||
"GitHub": "https://github.com/lambdapaul",
|
||||
"GitLab": "https://gitlab.com/lambdapaul",
|
||||
"Twitter": "https://twitter.com/lambda_paul",
|
||||
"Mastodon": "https://mastodon.social/@lambdapaul",
|
||||
"Matrix": "https://matrix.to/#/@lambdapaul:matrix.org",
|
||||
"Keybase": "https://keybase.io/lambdapaul",
|
||||
"Playlists": "/playlists",
|
||||
"Posts": "/posts",
|
||||
"Notes": "/notes"
|
||||
}
|
17
public/resources.alt.yaml
Normal file
17
public/resources.alt.yaml
Normal file
@ -0,0 +1,17 @@
|
||||
Programming:
|
||||
- The Aggregate Magic Algorithms: http://aggregate.org/MAGIC/
|
||||
- Typing is Hard: https://3fx.ch/typing-is-hard.html
|
||||
- Atlassian's Git Guide: https://www.atlassian.com/git/
|
||||
- LearnOpenGL.com: https://learnopengl.com/
|
||||
- "[PDF] LaTeX Symbols": http://ctan.math.utah.edu/ctan/tex-archive/info/symbols/comprehensive/symbols-letter.pdf
|
||||
- "[PDF] The Not So Short Introduction to LATEX 2ε": https://tobi.oetiker.ch/lshort/lshort.pdf
|
||||
- The MIT License, Line by Line by Kyle E. Mitchell: https://writing.kemitchell.com/2016/09/21/MIT-License-Line-by-Line.html
|
||||
- Posts:
|
||||
- How to Make Your Code Reviewer Fall in Love with You by Michael Lynch: https://mtlynch.io/code-review-love/
|
||||
- What's in the box? by @fasterthanlime: https://fasterthanli.me/articles/whats-in-the-box
|
||||
- Talks:
|
||||
- Concurrency is not Parallelism by Rob Pike: https://talks.golang.org/2012/waza.slide
|
||||
Electrical:
|
||||
- Common Wire-To-Board, Wire-To-Wire Connectors, And Crimp Tools: http://www.mattmillman.com/info/crimpconnectors/
|
||||
Other Topics:
|
||||
- Sight Reading Trainer: https://sightreading.training/
|
10
shims.d.ts
vendored
10
shims.d.ts
vendored
@ -2,3 +2,13 @@ declare module '*.yaml' {
|
||||
const record: Record<string, any>;
|
||||
export default record;
|
||||
}
|
||||
|
||||
declare module '*.md' {
|
||||
const rawmd: string;
|
||||
export default rawmd;
|
||||
}
|
||||
|
||||
declare module '*.txt' {
|
||||
const content: string;
|
||||
export default content;
|
||||
}
|
@ -1,145 +0,0 @@
|
||||
.container {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.9);
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.search {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 1018px;
|
||||
margin: 0 auto;
|
||||
font-size: 2rem;
|
||||
background: linear-gradient(to bottom right, #406b39, #225546) no-repeat center center fixed;
|
||||
box-shadow: inset 0 4px 8px 0 rgba(0, 0, 0, 0.2);
|
||||
padding: 0.5rem 1.75rem;
|
||||
color: rgb(255, 255, 255);
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.search::placeholder {
|
||||
color: rgb(214, 214, 214);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.results {
|
||||
max-width: 1018px;
|
||||
padding: 1rem;
|
||||
margin: 2rem auto;
|
||||
}
|
||||
|
||||
.hyperlink {
|
||||
color: #009dff;
|
||||
display: block;
|
||||
padding: 0.5rem;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
font-size: 1.2rem;
|
||||
transition: 300ms cubic-bezier(0.075, 0.82, 0.165, 1);
|
||||
text-decoration: none;
|
||||
border: 1px solid #AAAAAA;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.hyperlink:first-child {
|
||||
border-top: 1px solid #AAAAAA;
|
||||
border-radius: 0.5rem 0.5rem 0 0;
|
||||
}
|
||||
|
||||
.hyperlink:last-child {
|
||||
border-radius: 0 0 0.5rem 0.5rem;
|
||||
}
|
||||
|
||||
.hyperlink:only-child {
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.hyperlink:hover {
|
||||
color: #ccc;
|
||||
text-decoration: none;
|
||||
background: linear-gradient(to bottom right, #1a3a15, #09351b) no-repeat center center fixed;
|
||||
}
|
||||
|
||||
.hyperlink:focus {
|
||||
box-shadow: 0 0 1px 1px rgb(255, 255, 255);
|
||||
}
|
||||
|
||||
.hyperlink-name {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.hyperlink:hover .hyperlink-name {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.hyperlink-url {
|
||||
word-break: break-all;
|
||||
text-align: right;
|
||||
font-size: 1rem;
|
||||
transition: 200ms cubic-bezier(0.075, 0.82, 0.165, 1);
|
||||
}
|
||||
|
||||
.hyperlink:hover .hyperlink-url {
|
||||
color: #009dff;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.searchBar {
|
||||
user-select: none;
|
||||
background: linear-gradient(to bottom right, #406b39, #225546) no-repeat center center fixed;
|
||||
box-shadow: inset 0 4px 8px 0 rgba(0, 0, 0, 0.2);
|
||||
color: #CCCCCC;
|
||||
text-decoration: none;
|
||||
z-index: 1000;
|
||||
position: fixed;
|
||||
padding: 0 0.5rem;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.searchBar:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.searchTerm {
|
||||
display: block;
|
||||
margin: 0.5rem;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.searchTerm::before {
|
||||
display: inline-block;
|
||||
transform: rotate(-45deg) scale(1.4);
|
||||
content: '\26B2';
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.keybind {
|
||||
padding: 0;
|
||||
margin: 0.25rem;
|
||||
height: 2.25rem;
|
||||
font-family: monospace;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.keybind .key {
|
||||
background: #333333;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
margin: 0.25rem 0;
|
||||
font-size: 0.75rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
border: 1px solid #232323;
|
||||
border-radius: 0.5rem;
|
||||
box-shadow: 1.5px 1.5px 0 0 #222222;
|
||||
}
|
@ -12,46 +12,66 @@
|
||||
|
||||
@font-face {
|
||||
font-family: 'Cantarell';
|
||||
src: url('/assets/fonts/Cantarell-Regular.otf') format('opentype');
|
||||
src: url('/assets/fonts/Cantarell/Cantarell-Regular.otf') format('opentype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Cantarell';
|
||||
src: url('/assets/fonts/Cantarell-Thin.otf') format('opentype');
|
||||
src: url('/assets/fonts/Cantarell/Cantarell-Thin.otf') format('opentype');
|
||||
font-weight: 100;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Cantarell';
|
||||
src: url('/assets/fonts/Cantarell-Light.otf') format('opentype');
|
||||
src: url('/assets/fonts/Cantarell/Cantarell-Light.otf') format('opentype');
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Cantarell';
|
||||
src: url('/assets/fonts/Cantarell-Bold.otf') format('opentype');
|
||||
src: url('/assets/fonts/Cantarell/Cantarell-Bold.otf') format('opentype');
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Cantarell';
|
||||
src: url('/assets/fonts/Cantarell-ExtraBold.otf') format('opentype');
|
||||
src: url('/assets/fonts/Cantarell/Cantarell-ExtraBold.otf') format('opentype');
|
||||
font-weight: 800;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'EB Garamond';
|
||||
src: url('/assets/fonts/EB_Garamond/static/EBGaramond-Regular.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'EB Garamond';
|
||||
src: url('/assets/fonts/EB_Garamond/static/EBGaramond-Bold.ttf') format('truetype');
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'EB Garamond';
|
||||
src: url('/assets/fonts/EB_Garamond/static/EBGaramond-ExtraBold.ttf') format('truetype');
|
||||
font-weight: 800;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Cantarell', 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
|
||||
font-family: 'Cantarell', 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', 'Helvetica Neue', 'Helvetica', Arial, sans-serif;
|
||||
}
|
||||
|
||||
article,
|
||||
@ -161,7 +181,6 @@ pre {
|
||||
table {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-radius: 1rem;
|
||||
margin: 1rem 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
@ -169,7 +188,6 @@ table {
|
||||
table thead {
|
||||
background: var(--secondary-green);
|
||||
z-index: -1;
|
||||
border-bottom: 1px solid #999999;
|
||||
}
|
||||
|
||||
table thead tr,
|
||||
@ -185,12 +203,7 @@ table thead tr th,
|
||||
table tbody tr td {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
padding: .5em;
|
||||
}
|
||||
|
||||
table th+th,
|
||||
table td+td {
|
||||
border-left: 1px solid #999999;
|
||||
padding: .25rem 0.75rem;
|
||||
}
|
||||
|
||||
.lambda-logo {
|
||||
|
@ -6,13 +6,18 @@
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-position: top left;
|
||||
min-height: 100%;
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
.block {
|
||||
background-color: rgba(13, 17, 23, 0.9);
|
||||
font-family: 'EB Garamond', 'Garamond', 'Times New Roman', Times, serif;
|
||||
background-color: rgba(13, 17, 23, 0.95);
|
||||
margin: 0 auto;
|
||||
border-radius: 0;
|
||||
font-size: 1.25rem;
|
||||
line-height: 2rem;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
|
Loading…
Reference in New Issue
Block a user