Compare commits

..

1 commit

Author SHA1 Message Date
9ea7accfb7 Merge pull request 'main' (#3) from main into hpx-spa
Reviewed-on: #3
2024-01-10 19:49:12 -05:00
54 changed files with 237 additions and 6627 deletions

30
.gitignore vendored
View file

@ -1,21 +1,13 @@
# build output # Nimcache
dist/ nimcache/
# generated types cache/
.astro/ build/
# dependencies # Garbage
node_modules/ *.exe
*.js
*.log
*.lg
# logs # ignore test articles
npm-debug.log* src/public/Blog/*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# environment variables
.env
.env.production
# macOS-specific files
.DS_Store

View file

@ -1,12 +0,0 @@
{
"recommendations": [
"astro-build.astro-vscode",
"unifiedjs.vscode-mdx",
"formulahendry.auto-rename-tag",
"aaron-bond.better-comments",
"oderwat.indent-rainbow",
"ms-vscode.vscode-typescript-next",
"davidanson.vscode-markdownlint"
],
"unwantedRecommendations": []
}

11
.vscode/launch.json vendored
View file

@ -1,11 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}

143
LICENSE
View file

@ -1,5 +1,5 @@
GNU AFFERO GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
Version 3, 19 November 2007 Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
@ -7,15 +7,17 @@
Preamble Preamble
The GNU Affero General Public License is a free, copyleft license for The GNU General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure software and other kinds of works.
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast, to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free share and change all versions of a program--to make sure it remains free
software for all its users. software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you price. Our General Public Licenses are designed to make sure that you
@ -24,34 +26,44 @@ them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things. free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights To protect your rights, we need to prevent others from denying you
with two steps: (1) assert copyright on the software, and (2) offer these rights or asking you to surrender the rights. Therefore, you have
you this License which gives you legal permission to copy, distribute certain responsibilities if you distribute copies of the software, or if
and/or modify the software. you modify it: responsibilities to respect the freedom of others.
A secondary benefit of defending all users' freedom is that For example, if you distribute copies of such a program, whether
improvements made in alternate versions of the program, if they gratis or for a fee, you must pass on to the recipients the same
receive widespread use, become available for other developers to freedoms that you received. You must make sure that they, too, receive
incorporate. Many developers of free software are heartened and or can get the source code. And you must show them these terms so they
encouraged by the resulting cooperation. However, in the case of know their rights.
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to Developers that use the GNU GPL protect your rights with two steps:
ensure that, in such cases, the modified source code becomes available (1) assert copyright on the software, and (2) offer you this License
to the community. It requires the operator of a network server to giving you legal permission to copy, distribute and/or modify it.
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and For the developers' and authors' protection, the GPL clearly explains
published by Affero, was designed to accomplish similar goals. This is that there is no warranty for this free software. For both users' and
a different license, not a version of the Affero GPL, but Affero has authors' sake, the GPL requires that modified versions be marked as
released a new version of the Affero GPL which permits relicensing under changed, so that their problems will not be attributed erroneously to
this license. authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and The precise terms and conditions for copying, distribution and
modification follow. modification follow.
@ -60,7 +72,7 @@ modification follow.
0. Definitions. 0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License. "This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks. works, such as semiconductor masks.
@ -537,45 +549,35 @@ to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program. License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License. 13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work, License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version but the special requirements of the GNU Affero General Public License,
3 of the GNU General Public License. section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License. 14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions the GNU General Public License from time to time. Such new versions will
will be similar in spirit to the present version, but may differ in detail to be similar in spirit to the present version, but may differ in detail to
address new problems or concerns. address new problems or concerns.
Each version is given a distinguishing version number. If the Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published GNU General Public License, you may choose any version ever published
by the Free Software Foundation. by the Free Software Foundation.
If the Program specifies that a proxy can decide which future If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you public statement of acceptance of a version permanently authorizes you
to choose that version for the Program. to choose that version for the Program.
@ -633,29 +635,40 @@ the "copyright" line and a pointer to where the full notice is found.
Copyright (C) <year> <name of author> Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published it under the terms of the GNU General Public License as published by
by the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail. Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer If the program does terminal interaction, make it output a short
network, you should also make sure that it provides a way for users to notice like this when it starts in an interactive mode:
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive <program> Copyright (C) <year> <name of author>
of the code. There are many ways you could offer source, and different This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
solutions will be better for different programs; see section 13 for the This is free software, and you are welcome to redistribute it
specific requirements. under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school, You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary. if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>. <https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

View file

@ -1,39 +1,21 @@
# Blog in a Matrix # [Blog in a Matrix](https://bloginamatrix.xyz)
New blog site using [Astro](https://astro.build/). New blog site written in Nim.
## Workflow Articles/blogs written in markdown using [Joplin](https://github.com/laurent22/joplin/ "The best notes app/markdown editor ever made.") then exported as a HTML directory to `/src/public` where it will create a `Blog` folder.
Articles are written in markdown or MDX (I am using [Joplin](https://github.com/laurent22/joplin/)) then exported to `/src/content/blog`. The site can render [$\KaTeX$](https://katex.org/) and [Mermaid](https://mermaid.js.org/) content. Joplin has support for [the extended markdown](https://github.com/laurent22/joplin/blob/dev/readme/markdown.md), [KaTeX](https://khan.github.io/KaTeX/), and [Mermaid.js](https://mermaidjs.github.io/) out of the box and can be farther extended with [plugins](https://github.com/joplin/plugins/) like [music sheet notation](https://github.com/joplin/plugin-abc-sheet-music).
## Development ## Development
### Setup Install Nim dependencies:
Install dependencies:
```sh ```sh
pnpm install nimble install happyx@#head
``` ```
### Dev Server Development server:
Start a development server using the following command:
```sh ```sh
pnpm dev --open --host hpx dev --reload
``` ```
The site should be now accessible at [http://localhost:4321/](http://localhost:4321/). A specific port can be specified using `--port` flag.
### Build Site
Build deployable site:
```sh
pnpm exec playwright install
pnpm exec playwright install-deps # or you can manually install the dependencies
pnpm astro build
```
Built site can now be found at `/dist`.

View file

@ -1,32 +0,0 @@
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import sitemap from '@astrojs/sitemap';
import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';
import rehypeMermaid from 'rehype-mermaid';
import remarkRehype from 'remark-rehype';
import compress from 'vite-plugin-compression';
export default defineConfig({
site: 'https://bloginamatrix.xyz',
integrations: [
mdx({
gfm: true,
extendMarkdownConfig: true,
optimize: true,
remarkPlugins: [remarkMath, remarkRehype],
rehypePlugins: [rehypeKatex, rehypeMermaid]
}),
sitemap()],
markdown: {
gfm: true,
extendMarkdownConfig: true,
optimize: true,
remarkPlugins: [remarkMath, remarkRehype],
rehypePlugins: [rehypeKatex, rehypeMermaid],
},
vite: {
plugins: [compress({ ext: '.br', algorithm: 'brotliCompress' }), compress({ ext: '.gz', algorithm: 'gzip' })],
},
});

10
happyx.cfg Normal file
View file

@ -0,0 +1,10 @@
# HappyX project configuration.
[Main]
projectName = Blog in a Matrix
projectType = SPA
mainFile = main # main script filename (without extension) that should be launched with hpx dev command
srcDir = src # source directory in project root
buildDir = build # build directory in project root
assetsDir = public # assets directory in srcDir, will copied into build/public
language = nim # programming language

View file

@ -1,24 +0,0 @@
{
"name": "",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/mdx": "^2.3.1",
"@astrojs/rss": "^4.0.12",
"@astrojs/sitemap": "^3.4.1",
"astro": "^4.16.18",
"playwright": "^1.53.1",
"rehype-katex": "^7.0.1",
"rehype-mermaid": "^2.1.0",
"remark-math": "^6.0.0",
"remark-rehype": "^11.1.2",
"vite-plugin-compression": "^0.5.1"
}
}

5145
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

View file

@ -1,9 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
<style>
path { fill: #000; }
@media (prefers-color-scheme: dark) {
path { fill: #FFF; }
}
</style>
</svg>

Before

Width:  |  Height:  |  Size: 749 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

View file

@ -1,50 +0,0 @@
---
// Import the global.css file here so that it is included on
// all pages through the use of the <BaseHead /> component.
import '../styles/global.css';
interface Props {
title: string;
description: string;
image?: string;
}
const canonicalURL = new URL(Astro.url.pathname, Astro.site);
const { title, description, image = '/blog-placeholder-1.jpg' } = Astro.props;
---
<!-- Global Metadata -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />
<!-- Font preloads -->
<link rel="preload" href="/fonts/atkinson-regular.woff" as="font" type="font/woff" crossorigin />
<link rel="preload" href="/fonts/atkinson-bold.woff" as="font" type="font/woff" crossorigin />
<!-- Canonical URL -->
<link rel="canonical" href={canonicalURL} />
<!-- Primary Meta Tags -->
<title>{title}</title>
<meta name="title" content={title} />
<meta name="description" content={description} />
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website" />
<meta property="og:url" content={Astro.url} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={new URL(image, Astro.url)} />
<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:url" content={Astro.url} />
<meta property="twitter:title" content={title} />
<meta property="twitter:description" content={description} />
<meta property="twitter:image" content={new URL(image, Astro.url)} />
<!-- KaTeX Stylesheet -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css" integrity="sha384-n8MVd4RsNIU0tAv4ct0nTaAbDJwPJzDEaqSD1odI+WdtXRGWt2kTvGFasHpSy3SV" crossorigin="anonymous">

View file

@ -1,17 +0,0 @@
---
interface Props {
date: Date;
}
const { date } = Astro.props;
---
<time datetime={date.toISOString()}>
{
date.toLocaleDateString('en-us', {
year: 'numeric',
month: 'short',
day: 'numeric',
})
}
</time>

View file

@ -1,69 +0,0 @@
---
import { SITE_TITLE } from '../consts';
---
<header>
<nav>
<h2><a href="/">{SITE_TITLE}</a></h2>
<div class="internal-links">
<a href="https://arrayinamatrix.xyz">Main</a>
<a href="https://git.inamatrix.xyz/array-in-a-matrix/bloginamatrix.xyz">Source</a>
</div>
</nav>
</header>
<style>
header {
margin: 0;
background: white;
box-shadow: 0 2px 8px rgba(var(--black), 50%);
}
@media (max-width: 720px) {
header{
display: flex;
justify-content: center;
}
}
@media (min-width: 720px) {
nav{
height: 100vh;
}
}
h2 {
margin: 0;
font-size: 1em;
}
h2 a,
h2 a.active {
text-decoration: none;
}
nav {
display: flex;
align-items: center;
justify-content: space-between;
flex-flow: column wrap;
width: 200px;
position: sticky;
top: 0;
left: 0;
}
nav div{
display: grid;
justify-items: center;
width: 100%;
text-align: center;
}
nav a {
padding: 1em 0.5em;
color: var(--black);
border-bottom: 4px solid transparent;
text-decoration: none;
display: inline-block;
width: 100%;
}
nav a.active {
text-decoration: none;
border-bottom-color: var(--accent);
font-weight: bolder;
text-decoration: underline;
}
</style>

17
src/components/glass.nim Normal file
View file

@ -0,0 +1,17 @@
import happyx
var
newClass = "flex items-center justify-center flex-1 m-14 max-md:m-7 max-sm:m-0 rounded-3xl max-sm:rounded-none bg-white/20 backdrop-blur-xl drop-shadow-lg noise text-5xl"
newHomeClass = newClass & " font-giga"
component Glass:
text: string
`template`:
tH(class=newClass):
{self.text}
component GlassHome:
text: string
`template`:
tH(class=newHomeClass):
{self.text}

17
src/components/nav.nim Normal file
View file

@ -0,0 +1,17 @@
import os, happyx, navButton
component Nav:
`template`:
tNav(class="text-center text-white w-64 max-md:w-32 max-sm:w-full bg-black"):
tP(class="font-asix"):
"Sidebar"
tUl(class="list-none"):
component NavButton("Home", "/")
# component NavButton("Test Article", "/read/test")
# component NavButton("Example Article", "/read/Example 1")
# component NavButton("Example 2 Article", "/read/Example 2")
# TODO: automatically create a button for each html file in /src/public/Blog
#! this dont worky idk
for kind, path in walkDir("/src/public/Blog"):
if kind == pcFile:
component NavButton(path, "/read/" & path)

View file

@ -0,0 +1,11 @@
import happyx
component NavButton:
text: string
path: cstring = "/"
`template`:
tLi(class="list-item cursor-pointer text-white mx-2 my-2 ring-1 ring-white/20 hover:ring-white/50 rounded"):
tButton:
{self.text}
@click:
route self.path

12
src/components/read.nim Normal file
View file

@ -0,0 +1,12 @@
import os, happyx
component Read:
title: string
# TODO: fix
# if !fileExists("/public/Blog/{self.title}.html"):
# route "/404"
# else:
`template`:
tIframe(src="/public/Blog/{self.title}.html", class="flex items-center flex-1 m-14 max-md:m-7 max-sm:m-0 rounded-3xl max-sm:rounded-none")

View file

@ -1,5 +0,0 @@
// Place any global data in this file.
// You can import this data from anywhere in your site by using the `import` keyword.
export const SITE_TITLE = 'Blog in a Matrix';
export const SITE_DESCRIPTION = 'Array\'s blog site.';

View file

@ -1,408 +0,0 @@
---
title: 'Arch Linux - A comprehensive installation guide (kinda)'
description: 'A guide about installing Arch Linux.'
pubDate: 'Sep 27 2022'
---
### Table of Contents
* [Introduction](#mcetoc_1fu5q8lm8sj)
* [What this guide is (and Fedora shilling)](#mcetoc_1fu9gse0f1sv)
* [Arch Linux installation scripts](#mcetoc_1fuethrb77f)
* [Step-by-step guides](#mcetoc_1fuetj9t17j)
* [Post installation tweaks](#mcetoc_1gb9h6rrm9)
* [Pre-installation](#mcetoc_1fu5q67sfs3)
* [Requirements](#mcetoc_1fu5sculjuu)
* [Arch Linux ISO](#mcetoc_1fu5q67sfs4)
* [Verifying the signature](#mcetoc_1fu5q67sfs5)
* [Etching software](#mcetoc_1fu5q67sfs6)
* [Bootable USB](#mcetoc_1fu5q67sfs7)
* [Booting into the live medium](#mcetoc_1fu5tt5c4117)
* [Installation](#mcetoc_1fu5tuj4n11e)
* [Partitioning](#mcetoc_1fu7a9k3o1j0)
*  [Partition tables](#mcetoc_1fu9gr9ou1so)
* [Storage device naming scheme](#mcetoc_1fu7ermq61k5)
* [Home partition](#mcetoc_1fu7a9k3o1j1)
* [Swap](#mcetoc_1fu7a9k3o1j2)
* [File systems](#mcetoc_1fu7a9k3o1j3)
* [Encryption](#mcetoc_1fuedjkjm2)
* [Unix/Linux file system structure](#mcetoc_1fu7am1tj1jj)
* [Mounting](#mcetoc_1fu7am1tj1jk)
* [Mounting encrypted partition](#mcetoc_1fuep9r7i5t)
* [Pacstrap](#mcetoc_1fud09h0gvk)
* [Linux kernels](#mcetoc_1fud09h0gvl)
* [Mandatory Access Control](#mcetoc_1fud09h0gvm)
* [SELinux](#mcetoc_1gf6pli851l)
* [File system table](#mcetoc_1fud09h0gvm)
* [Configuration](#mcetoc_1fud09h0gvn)
* [Initial ramdisk](#mcetoc_1gav9chi02v)
* [Hooks](#mcetoc_1gav9chi030)
* [Bootloader](#mcetoc_1fud09h0gvo)
*  [Encrypted system](#mcetoc_1fuep9r7i5u) 
* [Multibooting](#mcetoc_1fuep9r7i5v)
* [Hibernation](#mcetoc_1fuep9r7i60)
* [Plymouth](#mcetoc_1gav9iib63q)
* [Init systems](#mcetoc_1fud09h0gvp)
* [Post-installation](#mcetoc_1fudcpbbo1ji)
* [Desktop environments](#mcetoc_1fud84m3l1ik)
* [Window managers](#mcetoc_1fud84m3m1il)
* [Display managers](#mcetoc_1fuud1rme3e)
* [Users](#mcetoc_1fupat89vr7)
* [Privilege escalation](#mcetoc_1fupat89vr8)
* [Permissions](#mcetoc_1fuuggr11170)
* [Arch User Repository](#mcetoc_1fupat89vr9)
* [AUR helpers](#mcetoc_1fupat89vra)
Introduction
------------
* * *
### What this guide is (and Fedora shilling)
This guide is a detailed explanation of the installation process and things relating to it. This is not a guide that takes you step by step through the commands you need to run to install Arch Linux. If you want that take a look at the "Recommended guides" section below. This guide is meant to help you understand the commands you are running allowing you to install Arch Linux (or any DIY distro) the way **YOU** want or the way that best suits your needs. This guide should be used as a collection of useful links and ideas. A lot of information here can carry over to other operating systems installations but the focus of this guide is Arch Linux. If you are new to linux or never used it, what are you doing here? Go earn some _Tux exp. points™_ by using [Fedora](https://getfedora.org/en/), its cutting edge, stable and better than Arch in a lot of areas. Linus Torvalds doesn't use Fedora without reason. This guide gets updated from time to time as the writer gains more _Tux exp. points™._ 
#### Arch Linux installation scripts
People have created Arch Linux installation scripts plenty of times. However [Arch Installer](https://github.com/archlinux/archinstall) is the only official automated script. This installer is optional. If the user desires to install Arch Linux manually they can still do so. 
### Step-by-step guides
There isn't a single correct way to install Arch Linux, however, the most up-to-date and accurate is the official guide by the [Arch Linux wiki](https://wiki.archlinux.org/title/installation_guide). Remember none official guides tend to go out of date and become obsolete, some are linked here for reference and to show the various ways an installation can be configured.
* [It's FOSS (Gnome)](https://itsfoss.com/install-arch-linux/), [extra steps for KDE](https://itsfoss.com/install-kde-arch-linux/).
* [EF - Linux Made Simple](https://www.youtube.com/c/EFLinuxMadeSimple)
* [Thomas Forgione](https://tforgione.fr/posts/arch-linux-encrypted/)
* [Memory Imprint Studio](https://tech.memoryimprintstudio.com/dual-boot-installation-of-arch-linux-with-preinstalled-windows-10-with-encryption/)
* [Huntrar](https://gist.github.com/huntrar/e42aee630bee3295b2c671d098c81268)
#### Post installation tweaks
After installing the base system there are some things that you might want to tweak afterwards.
* [Post-installation](https://wiki.archlinux.org/title/General_recommendations)
* [Improving performance](https://wiki.archlinux.org/title/Improving_performance)
* [lbrame's Arch Linux tweaks](https://gist.github.com/lbrame/1678c00213c2bd069c0a59f8733e0ee6)
Pre-installation
----------------
* * *
### Requirements
This guide assumes you have a x86\_64 1 computer which has 2GB of RAM, 20GB of disk space 2, an internet connection, a USB with at least 2GB of storage 3.
1  Arch Linux only supports x86\_64 architecture, however a [fork](https://archlinuxarm.org/) of it exists for ARM CPUs.
2 Arch Linux can be installed on a smaller disk space and use less RAM but you probably (and should) use more.
3 The USB is not needed if you [Netboot](https://archlinux.org/releng/netboot/) into the live medium. An optical disc can also be used instead of a USB.
### Arch Linux ISO
The first thing we must do is to get the ISO file and USB device. Head over to [Arch Linux website](https://archlinux.org/download/) to download the official ISO using either a magnet link or a torrent file.  To make use of the ISO file, we will need a bootable USB.
### Verifying the signature
Verifying the signature of the file is important to make sure the ISO you have is not compromised, malicious, or broken. The [Arch Linux wiki](https://wiki.archlinux.org/title/installation_guide#Verify_signature) covers this pretty well thus going over it would be redundant.
#### Etching software
Most guides recommend tools like [UNetBootin](https://unetbootin.github.io/), [Balena Etcher](https://www.balena.io/etcher/) or [Rufus](https://rufus.ie/en/) to etch an ISO file onto a USB device. These tools are great but they uses the entire USB (which could be 16GB or more) to etch a single distro in which the ISO might be 2GB large. Arch Linux's disk image takes up less than 1GB of space! Even if you aren't going to use all that space, It is time consuming and tedious to rerun the etching software every time you want to use a different operating system. If you are distro-hopping or would like to keep multiple operating systems (not just different distributions!) on a single USB, this guide recommends using a tool called [Ventoy](https://www.ventoy.net/en/index.html) 1. 
1  Ventoy is not the only program that can do this, [YUMI](https://www.pendrivelinux.com/yumi-multiboot-usb-creator/) (**Y**our **U**SB **M**ultiboot **I**nstaller) is another program that can be used.
### [](https://www.ventoy.net/en/index.html)Bootable USB
To make a bootable USB we will need to create it using [Ventoy](https://www.ventoy.net/en/index.html). Ventoy has both a GUI and a CLI clients therefore its perfect for any user. When you run Ventoy on your desired USB device, It will create 2 partitions. We only need to worry about one of these partitions, the empty one, this is were we will be putting our image files. After downloading the Arch Linux ISO (or any other ISO file), just move it to the empty Ventoy partition and we will be able to boot into it. 
### Booting into the live medium
Reboot your machine and enter the BIOS/UEFI to disable "Secure Boot" if its enabled. Then boot into your USB device from the boot loader menu. Secure boot can be set up after the installation.
Installation
------------
* * *
### Partitioning
This is where things get interesting! Partitioning a disk is just dividing up your storage device into smaller chinks which may have different file systems. There is a plethora of partitioning tools you can use 1. The easiest non-GUI tool is "cfdisk". Some guides use "fdisk" which is more intimidating. There is multiple partitions you can make for many reasons. The simplest installation only requires 2 on a UEFI system, an EFI partition and a root partition. The EFI partition is needed to boot the system, it is your boot partition. The root partition is where everything else is stored. A BIOS system only need 1 root partition which contains everything. 
1 Some partitioning tools are parted, fdisk, cfdisk, sfdisk, gdisk, cgdisk, and sgdisk. More can be found [here](https://wikiless.org/wiki/List_of_disk_partitioning_software).
####  Partition tables
A partition table describes how a disk is partitioned. There are 2 types of partition tables, the "Master Boot Record" (MBR) and "GUID Partition Table" (GPT). The GPT partitioning table is newer and is more feature rich than its predecessor. If you are installing an operating system you will want to use GPT unless you have a specific reason not to. GPT allows you  to create more partitions and supports disks larger than 2TB.
#### Storage device naming scheme
When you are formatting your drives, you probably want to know which device is being used. In Linux, storage devices can be found in "/dev". HDD and USB storage devices are usually labeled as sdX. Where "X" is a lower case letter starting in alphabetical order (sda, sdb, sdc, etc.). each of these is a separate storage device. 
An example list of storage devices names could look like this:
PATH NAME
/dev/sda sda <-- HDD
/dev/sdb sdb <-- Secondary HDD
/dev/sdc sdc <-- USB drive
/dev/nvme0n1 nvme0n1 <-- SSD
/dev/nvme0n2 nvme0n2 <-- Secondary SSD
Number of partitions on a single disk is also taken into account. The number after the device name (sda**1**, nvme0n1**p1**) is the partition number. 
An example output of the command "lsblk -o NAME,TYPE" is this:
$ lsblk -o NAME,TYPE
NAME          TYPE
sda           disk
├─sda1        part <-- EFI - boot partition
├─sda2        part <-- Ext4 - root partition
└─sda3        part <-- swap - swap partition
sdb           disk
└─sda1        part <-- FAT32 - extra storage partition
nvme0n1       disk
└─nvme0n1p1   part <-- Ext4 - home partition
### Home partition
Creating more partitions allows you to better organize or even backup your data. A home partition will only hold the user(s) files (all of "/home"). The root partition will contain everything else (packages, operating system files, etc.).
### Swap
[Swap](https://wiki.archlinux.org/title/Swap) can be used to off load data from RAM, essentially giving you more ram at the cost of disk space using a process called paging. You can create either a swap file or a swap partition. Swap is also used for hibernation 1 of your system. Hibernation allows you to completely power off your computer which is why its more useful than normal sleep which keep the system on 2. Restoring from hibernation is slower compared to restoration from sleep. Having swap is recommended for lower end systems which may have less memory.
1 Hibernation is like entering sleep mode, however the data is stored in the swap partition/file. \`Normal\` sleep just keeps the data in RAM.
2 Sleep powers off all of the computers hardware (networking, display, etc.) with the exception of RAM. If RAM was powered off, nothing would be saved.
### File systems
After creating your partitions you have to format them. There is multiple [file system types](https://wiki.archlinux.org/title/File_systems). Different operating systems tend to use different file systems usually because these systems are proprietary. A variant of the [FAT](https://wikiless.org/wiki/File_Allocation_Table) file system, [FAT32](https://wikiless.org/wiki/File_Allocation_Table#FAT32), is widely used in storage devices of computers, cameras, embedded systems and game systems. Windows uses FAT32 for a boot partition and [NTFS](https://docs.microsoft.com/en-us/windows-server/storage/file-server/ntfs-overview) for its root partition. macOS uses [APFS](https://support.apple.com/en-ca/guide/disk-utility/dsku19ed921c/mac). Most guides tell you to format the EFI partition has FAT32 1 and the root partition as Ext4. Some guides use [BTRFS](https://btrfs.wiki.kernel.org/index.php/Main_Page) file system for the root partition, because it is faster than Ext4 and has more features, however it comes at the cost of [stability](https://btrfs.wiki.kernel.org/index.php/Status) 2. [](https://wiki.archlinux.org/title/ZFS) [XFS](https://wiki.archlinux.org/title/XFS) and [ZFS](https://wiki.archlinux.org/title/ZFS) can also be used instead of Ext4 for a root partition. If you created a swap partition you want to format it as such. If in doubt when choosing file system for your root or home partition, choose either BTRFS or Ext4.
1 If you are using a BIOS system you only have 1 partition which typically is formatted as Ext4.
2 Stability on BTRFS has not been an issue for a long time.
#### Encryption
If you plan on encrypting one or more partitions you should do so using the "cryptsetup" command. To setup encryption on a partition, format that partition as "LUKS" (either LUKS1 or LUKS2) using the command "cryptsetup --type luks2 luksFormat <path to partition>". Then you will be prompted to type a passphrase, make sure to memorize this passphrase because without it you will not be able to boot into your operating system 1. Before you can use the partition, you will need to create and form the virtual disk. To access the encrypted partition, type the command "cryptsetup open <path to partition> <name>" (the example below uses "crypthome" as the name). Then you can mount the virtual drive and use it. The path of the virtual drive is "/dev/mapper/<name>". 
Example of an encrypted partition.
$ lsblk -o NAME,TYPE,MOUNTPOINTS
NAME          TYPE  MOUNTPOINTS
sda           disk  
├─sda1        part  /boot
├─sda2        part  /
└─sda3        part
└─crypthome crypt /home <-- full path is "/dev/mapper/crypthome"
A more detailed explanation of how to encrypt your drives can be found on the [Arch Linux wiki](https://wiki.archlinux.org/title/Dm-crypt).
1 You will be prompted to enter this passphrase every time you boot your system (assuming the partition will get mounted by the bootloader).
#### Unix/Linux file system structure
In a Unix/Linux system, everything is a file. If you wanted to know the specifications of your CPU, you can just look at the file in "/proc/cpuinfo". On a windows system, you would need to make an API call to get this information. In a Unix/Linux system, there is a single folder that contains everything. This folder is called root "/". Running processes can be found in "/proc" (notice that "proc" is inside "/"). [Linux Journey](https://linuxjourney.com/lesson/filesystem-hierarchy) explains the different directories well.
### Mounting
After partitioning and creating the needed file systems you need to [mount](https://man.archlinux.org/man/mount.8) them to write data to them. Mounting allows you to attach other partitions onto your root partition. For example, when you plug in a USB storage device into a Linux system the OS will automatically mount it to a specific directory such as "/run/media/<user's name>". To install Arch Linux, you will need to manually mount the created partitions on to the live system to install the necessary programs. You would need to mount "/dev/<root partition>" on to "/mnt" to install the system programs and you will also need to mount "/dev/<EFI partition>" on to "/mnt/boot" to be able to boot. The "/mnt" directory will become the new root directory once the installation is finished. Files located at "/mnt/var" in the live environment will be at "/var" on the new system. [](https://wikiless.org/wiki/Hard_disk_drive)
#### Mounting encrypted partition
If you encrypted your root partition you would need to mount "/dev/mapper/root" to "/mnt". If you created a separate home partition and is also encrypted you would need to mount it to its corresponding mounting point. each encrypted partition will need its own passphrase 1.
1 If you got an encrypted root and home partitions you will need to type 2 passphrase to actually use your system.
### Pacstrap
Pacstrap is a script which you will need to install the base system, Linux kernel 1, and the kernel's firmware. The pacstrap is essentially the "pacman" command but installs packages to a different root partition. The script can also be used to install programs into the new root partition. It is a good idea to install a text editor when you run this command because it will make life easier later. 
1 There are different kernels officially supported by Arch Linux. 
#### Linux kernels
There are 4 official variants of the Linux kernel. The "Stable kernel" is the main vanilla Linux kernel. The "Hardened kernel" is more security orientated and mitigates exploits better. The "Long term kernel" is aimed at providing long term support (LTS). The LTS kernel is better suited for servers and for older hardware.  The "Zen kernel" is optimized for performance and speed. The actual linux kernel executable is located at "/boot/vmlinux" (assuming the vanilla kernel).
1 A list of kernels can be found [here](https://wiki.archlinux.org/title/Kernel).
#### Mandatory Access Control
A base Linux install usually defines restrictions to users based on what group they are in and what permissions a certain file has (i.e. [**D**iscretionary **A**ccess **C**ontrol](https://wikiless.org/wiki/Discretionary_Access_Control)). [**M**andatory **A**ccess **C**ontrol](https://wiki.archlinux.org/title/Mandatory_Access_Control) adds extra restrains to better improve security. Actions done in a system with MAC is checked against a set of rules and policies (which can not be changed by users) to allow or deny the action. There are different implementations of MAC for Linux systems, most popular being [**S**ecurity-**E**nhanced **L**inux (SELinux)](https://wiki.archlinux.org/title/SELinux). There are other implementations such as [AppArmor](https://wiki.archlinux.org/title/AppArmor) (which is used by default on Ubuntu and SUSE) and [TOMOYO](https://wiki.archlinux.org/title/TOMOYO_Linux).
##### SELinux
SELinux is [currently not officially supported](https://wiki.archlinux.org/title/SELinux#Current_status_in_Arch_Linux) but can be installed. SELinux works by replacing the DAC system and is used by RHEL by default. Using SELinux means a lot of packages, including the kernel, would need to be recompiled with SELinux support flags. Commonly used packages are recompiled with the needed flags and can be installed from the AUR.
### File system table
The new operating system will need to know where each partition is located and where to mount it. The command "genfstab" will **gen**erate a **f**ile **s**ystem **tab**le to define where those partitions mount. 
### Configuration
This section is not necessary for the installation process 1, however some programs might not work properly without them. To configure the new system you will need to run the "arch-chroot" command on the new root partition "/mnt". [Chroot](https://wiki.archlinux.org/title/Chroot#Using_arch-chroot) is an important command to keep in mind in case the system breaks in the future. This command will **ch**ange the **root** user of the live system into the root user of the new system. Inside the chroot environment you can set up the timezone, locale and networking, but this can be done after installation. One thing you should do in the chroot environment is setting up the bootloader. You should give the new root user a password using the "passwd" command.
1 If you consider the bootloader unnecessary.
### Initial ramdisk
During the boot process the Linux kernel's modules need to be loaded. The initial ramdisk loads these before handing them over to the init system (systemd when using vanilla Arch Linux). The "mkinitcpio" 1 command creates the initial ramdisk using the configuration file located at "/etc/mkinitcpio.conf". Executing "mkinitcpio" creates kernel images in your boot partition. If  you plan on messing with boot process, having an understanding of the [initial ramdisk](https://wiki.archlinux.org/title/mkinitcpio) helps.
1 "mkinitcpio" is not the only program that can be used to create the initramfs image, others such as [dracut](https://wiki.archlinux.org/title/Dracut) and [booster](https://wiki.archlinux.org/title/Booster) can also be used. A list can be found [here](https://github.com/LaszloGombos/awesome-initramfs#projects).
#### Hooks
Hooks are extra scripts that extend what the initial ramdisk can do. For example, they allow the kernel to open encrypted partitions, resume from hibernation, allow useage of BTRFS partitions or access to file systems on LVM and more,
### Bootloader
Most guides use GRUB as the bootloader however you can use other bootloaders such as systemd-boot. A list of bootloaders can be found [here](https://wikiless.org/wiki/Comparison_of_boot_loaders). Inside the chroot environment you want to configure the bootloader because you can not boot into the operating system to configure it there (there no bootloader yet!). Setting up the bootloader on a UEFI system will need a package called "efibootmgr" and (obviously) your bootloader of choice. For a GRUB installation, you will want to create a directory inside"/boot" the name doesn't matter (in our example we will use "/boot/efi"). The following sections will assume you are using GRUB. GRUB configuration file is located at "/etc/default/grub" and after editing it you will need to run "grub-install" 1.
1 When running "grub-install" make sure to point it to the efi directory you created earlier.
When configuring the bootloader or the initial ramdisk it is recommended to use a [persistent block device naming](https://wiki.archlinux.org/title/Persistent_block_device_naming) scheme like the **U**niversal **U**nique **Id**entifier (UUID) of the partition rather than using the device name. 
GRUB\_CMDLINE\_LINUX="root=/dev/sda2"
GRUB\_CMDLINE\_LINUX="root=UUID=0a3407de-014b-458b-b5c1-848e92a327a3" <-- recommended
####  Encrypted system 
The bootloader will need to know which partition is encrypted to it can open it properly. You need to tell GRUB what partition is encrypted using "cryptdevice". You will also need to allow GRUB to boot from a LUKS device.
GRUB\_CMDLINE\_LINUX="cryptdevice=/dev/<partition>:<virtual device name>"
GRUB\_ENABLE\_CRYPTODISK="y"
This is an example of what the above lines may look like:
GRUB\_CMDLINE\_LINUX="cryptdevice=/dev/sda3:crypthome"
GRUB\_ENABLE\_CRYPTODISK="y"
#### Multibooting
If you have multiple operating systems you will need to run "os-prober" so GRUB can detect other OSes. Also you should enable "GRUB\_DISABLE\_OS\_PROBER" in your GRUB config.
#### Hibernation
To be able to restore from hibernating you will need to add "resume" and point it to your swap partition/file. You should also add it to "GRUB\_CMDLINE\_LINUX\_DEFAULT".
GRUB\_CMDLINE\_LINUX\_DEFAULT="resume=/dev/<location to swap>"
resume=/dev/<location to swap>
#### Plymouth
Plymouth is not part of the installation process however it looks good. To use plymouth you will need to add the necessary strings to the "mkinitcpio.conf" and to the bootloader (GRUB in this example). "plymouth" needs to be after "base" and "udev".
MODULES=(i915) < for Intel
MODULES=(amdgpu) <-- for AMD
HOOKS=(plymouth encrypt)
The following command line entries need to be added for a smooth experience. The "splash" entry is absolutely needed for plymouth (or any other graphical boot process).
GRUB\_CMDLINE\_LINUX\_DEFAULT="splash rd.udev.log\_priority=3 vt.g
lobal\_cursor\_default=0"
Plymouth is a fantastic program, [here](https://github.com/adi1090x/plymouth-themes) is a list of some themes some of which are ported from android.
#### Secure Boot
Secure Boot adds a layer of security to the boot process by checking the cryptographic signature of the kernel and bootloader. Arch Linux's installation does not support Secure Boot; however, it can be setup easily using [sbctl](https://wiki.archlinux.org/title/Unified_Extensible_Firmware_Interface/Secure_Boot). To use you would need to enroll your own keys into the UEFI and sign the kernel and the bootloader EFI executable binaries. 
### Init systems
The most used init system is systemd however many people consider it bloated. Arch Linux uses systemd. Other init systems are openrc, runit, s6, sysvinit, dinit, sinit, epoch, upstart and GNU Shepherd. If you do not wish to use systemd but still want a DIY distribution then consider using an alternative operating system such as Artix Linux, Void Linux, Gentoo Linux, Linux from scratch (LFS) or even a BSD distro. Swapping out systemd on Arch Linux will guarantee detrimental damage to the operating system. 
IDK where to squeeze this in so I'm putting it [here](https://wiki.archlinux.org/title/Arch_boot_process).
Post-installation
-----------------
* * *
### Desktop environments
There are many desktop environments (DEs) for Linux and BSD systems. Most commonly used are Gnome and KDE. A DE is just collection of packages which setup the GUI and install some user applications 1 that share a common graphical framework 2 to reduce bloat and graphical inconsistency. All DEs install with a window manager however you can install a window manager without installing a DE. A list of all DEs can be found [here](https://wikiless.org/wiki/Desktop_environment) and for officially supported DEs on Arch Linux [here](https://wiki.archlinux.org/title/desktop_environment#Officially_supported). The Arch Linux wiki has a desktop environment [comparison page](https://wiki.archlinux.org/title/Comparison_of_desktop_environments).
1 The applications installed vary with each DE but usually include an application center, terminal, file manager, settings application, screenshot utility, text editor, web browser, office suite, and similar applications.
2 The most used Libraries are [GTK](https://www.gtk.org/), [QT](https://www.qt.io/) however others exist such as [Enlightenment](https://www.enlightenment.org/about-efl.md). More libraries can be found [here](https://wikiless.org/wiki/List_of_platform-independent_GUI_libraries).
### Window managers
Window managers (WMs) are programs that work with the window server 1 to produce a graphical interface. Window managers control the behavior and appearance of the windows running inside it. There are 3 types of window managers, floating/stacking, tiling, and dynamic. Floating window managers are what Windows and macOS use. In a floating WM, the windows may overlap other windows. Floating window managers require the mouse to resize and move the windows. Tiling WM is where windows are automatically organized into tiles to maximize the screen real estate. These tiles do not over lap. Tiling window managers are minimal in nature and do not depend on the mouse to move and resize windows. Dynamic window managers are a combination of Floating and tiling WMs. A list of window managers can be found [here](https://wiki.archlinux.org/title/Window_manager#Dynamic_window_managers).
1 The window server usually is either X.Org or Wayland. Other window servers can be found [here](https://wikiless.org/wiki/Windowing_system#SurfaceFlinger).
### Display managers
The graphical interface where you login to a specific user is the display manager 1 (DM). From it you can choose which desktop environment or window manager to use. DE tend to ship their own DMs for example, Gnome uses the Gnome Display Manager (GDM) and KDE uses Simple Desktop Display Manager (SDDM). DM are usually graphical but CLI/TUI DMs exist. The [Arch Linux wiki](https://wiki.archlinux.org/title/Display_manager#List_of_display_managers) has a list of display managers you can use.
1 Also referred to as the login/session manager.
### Users
Limiting access to certain commands is needed for good security. You can create a new user account using the command "useradd -g <name>", the "-g" flag is for creating a home directory for that user. You can assign a password to that user using the "passwd" command. Add a user to a group using the "usermod" command. To allow user accounts to elevate their privileges to root, add them to the "wheel" group 1.
1 The "wheel" group isn't necessary for privilege escalation but its widely used. Other groups or manually giving a user privilege also works. More information about the "wheel" group [here](https://thecustomizewindows.com/2014/03/what-is-wheel-group-in-unix-unix-like-os/).
#### Privilege escalation
To change the privilege of a user or group you edit the file "/etc/sudoers" using the command "visudo" 1. Other commands commands like "sudo" exists such as "su" and "doas". "su" is the predecessor of "sudo". "doas" is alot simpler than "sudo" also it is significantly smaller in size. The "doas" config is alot nicer and less intimidating than "sudo"'s. I can not recommend "doas" for beginners because "makepkg" fails (requires a patch to work with "doas"). If don't plan on using "makepkg" then replace sudo!
1 [Why use "visudo" instead of manually editing the file directly?](#INTERNAL_LINK#/post/null)
#### Permissions
Files and directories have specific permissions based on certain criteria. Using a command like "ls" 1 we can see the permissions of a file or directory: 
$ ls -l
drwxr-xr-x linux linux 4.0 KB Wed Mar 16 14:15:14 2022 Documents
\-rw-r--r-- linux linux 143 B  Thu Nov 11 17:30:07 2021 file.txt
^^^ ^^^ ^^^
│ | |
| | Group.
│ |
| Owner of file/directory.
|
These are the permissions.
To better understand this we will split the sting into 4 smaller strings:
╭───────────────── Tells us if entry is a directory or a file.
│ ╭────────────── Tells us the permission of the file's owner. (Think "Can the owner of this file read/write/execute it?")
│ │
│ │ ╭────────── Tells us the permission of users in the assigned group.
│ │ │
│ │ │ ╭────── Tells us the permission of every other user.
│ │ │ │
d rwx r-x r-x
The letter "r" means read, "w" means write, and "x" means execute. The lack of a letter "-" means no permission is given.
\- rwx r-x r--
│ │ │
│ │ ╰───── Any other user (not the owner or in the group) can only read the file.
│ │
│ │
│ │
│ ╰─────────── Users in the group can only read and execute the file.
╰───────────────── The owner of this file can read, write and execute it.
Keep in mind that the root user has read, write and execute permissions to everything. This is one of the reasons why using root for everything is dangerous.
1 The command "namei" can be used to follow the path of a file/directory and list permissions of its parent directories.  
### Arch User Repository
There are 2 main repositories to install packages from, the [official stable repo](https://archlinux.org/packages/) and the [AUR](https://aur.archlinux.org/packages).  The AUR is a collection of user submitted packages while the official repo are selected and verified by the Arch Linux developers and repo maintainers. Since the AUR is based on user submissions, you should inspect the "PKGBUILD" of a program before installing it (in case it is malicious or broken). The are more repositories you can download software from but often it is unneeded and may break package dependencies. List of [official](https://wiki.archlinux.org/title/Official_repositories) and [unofficial](https://wiki.archlinux.org/title/Unofficial_user_repositories#arch4edu) repositories. Anyone can create a repository, instructions on how to do so can be found [here](https://wiki.archlinux.org/title/Pacman/Tips_and_tricks#Custom_local_repository).
#### AUR helpers
Using an AUR helper is not needed but makes installing packages easier. A list of them can be found [here](https://wiki.archlinux.org/title/AUR_helpers). To manually install an AUR package you should download it from the AUR site and then compile it's "makepkg" after inspecting the "PKGBUILD". A list of AUR helpers can be found on the [Arch Linux wiki](https://wiki.archlinux.org/title/AUR_helpers) 1.
1 I have contributed the one of the AUR helpers, [Aura](https://github.com/fosskers/aura)!

View file

@ -1,84 +0,0 @@
---
title: 'Cool CLI Applications'
description: 'A list of some awesome commandline tools.'
pubDate: 'May 31 2022'
---
Learning how to use the terminal is a side effect I gained after switching to GNU/Linux. It is absolutely not necessary to know how to use it, but it makes you more productive (and look cooler?). These are some command line applications I use:
* [Chafa](https://github.com/hpjansson/chafa)
* Displays images and gifs in the terminal
* [Lf](https://github.com/gokcehan/lf) + [lfimg](https://github.com/cirala/lfimg)
* \`lf\` (**l**ist **f**iles) is a terminal file manager. I use \`lf\` with \`lfimg\` which allows you to preview the text files, render images/gifs and shows properties of binary files.
* [Neovim](https://neovim.io)
* Text editor. If you are too lazy to customize it with plugins you should use [LunarVim](https://lunarvim.org). I use \`neovim\` whenever I need to make a small change to a file, I tend to use "VS Code" for actual heavy-duty programming.
* [Glow](https://github.com/charmbracelet/glow)
* Fast and simple markdown renderer. Definitely worth checking out [charm.sh](https://charm.sh/).
* [Cmus](https://cmus.github.io)
* fast and feature rich music player. Honestly I prefer \`cmus\` over any music player GUI or non-GUI.
* [Doas](https://github.com/Duncaen/OpenDoas)
* \`sudo\` but less bloated and better security due to less surface attack. There is only one problem with \`doas\` and that is it currently does not work with \`makepkg\`.
* [Jdupes](https://github.com/jbruchon/jdupes)
* A powerful duplicate file finder and an enhanced fork of \`fdupes\`. 
* [Optipng](https://optipng.sourceforge.net/)
* Optimize and compress images.
* [Exiftool](https://exiftool.org/)
* Remove or manipulate metadata of files.
* [Trash-cli](https://github.com/andreafrancia/trash-cli)
* I have \`rm\` aliased to this command ([the documentation says not to](https://github.com/andreafrancia/trash-cli#can-i-alias-rm-to-trash-put)). This can be the difference between life and death. \`rm -rf\` is a dangerous command to run. Its safer to trash the file/folder than permanently deleting it.
* [Chezmoi](https://www.chezmoi.io)
* Manages dotfiles and configurations of various programs (like the ones in this list).
* [Mosh](https://mosh.org)
* Alternative \`ssh\` which maintains connection after changing networks, running commands using it is faster than regular \`ssh\`. Use \`screen\` with \`mosh\` to maintain a connection after closing the client.
* [Pwgen](https://sourceforge.net/projects/pwgen)
* generates passwords or random strings.
* [Bat](https://github.com/sharkdp/bat)
* \`cat\` but with syntax highlighting and integration with \`git\`. I have \`bat --paging=never\` aliased to this command.
* [Zoxide](https://github.com/ajeetdsouza/zoxide)
* \`cd\` but remembers previous directories.
* [Lsd](https://github.com/Peltoche/lsd)
* \`ls\` but deluxe. Its a rewrite of \`ls\` in rust. I have \`ls\` aliased to this command.
* [Tokei](https://github.com/XAMPPRocky/tokei)
* Counts number of files, code written, comments, blank spaces, and lines of code used within a directory.  
* [Ripgrep](https://github.com/BurntSushi/ripgrep)
* \`grep\` but modernized and faster. I have \`grep\` aliased to this command.
* [Pfetch](https://github.com/dylanaraps/pfetch)
* Minimal system information and shows OS's logo. One can say its \`neofetch\` but with one less config file.
* hostnamectl
* Changes hostname and lists information about the host machine.
* [Inxi](https://smxi.org/docs/inxi.htm)
* Provides a ton of system information. 
* [Pipes.sh](https://github.com/pipeseroni/pipes.sh)
* Cool looking screensaver.
* [Unimatrix](https://github.com/will8211/unimatrix)
* Cool looking screensaver, inspired by "The Matrix" movie but better than \`cmatrix\`.
* [TTY-clock](https://github.com/xorg62/tty-clock)
* Clock that displays the time.
* [Htop](https://htop.dev)
* Process viewer.
* [Gotop](https://github.com/xxxserxxx/gotop)
* Activity monitor.
* [Radeontop](https://github.com/clbr/radeontop)
* Shows GPU usage. This program is aimed at AMD graphics based systems.
* [Powertop](https://github.com/fenrus75/powertop)
* Power consumption monitor and power saving tool.
* [Speedometer](https://excess.org/speedometer)
* Shows network usage. This program has a lot of configuration options!
* [Lolcat](https://github.com/busyloop/lolcat)
* Makes output of last command rainbow.
* [Pywal](https://github.com/dylanaraps/pywal)
* Generates color schemes based of a provided images. I use \`pywal\` in a script to automatically choose a random image (or I can manually choose one) to use as my wallpaper and theme my desktop to match its colors.
* [Ansi2html](https://github.com/pycontribs/ansi2html)
* Command that converts text with ANSI colors to HTML or LaTeX.
* Script
* Linux kernel command which records commands ran by the user and their outputs (stdin/stdout) to a file.
* [Cheat](https://github.com/cheat/cheat)
* List common hard to remember terminal programs usage.
* [Fd](https://github.com/sharkdp/fd)
* User-friendly alternative to \`find\`.
* Ncdu
* Disk usage analyzer with an ncurses interface.
* Gdu
* Disk usage analyzer but written in go.
* shellcheck
* konsave
* nvtop

View file

@ -1,28 +0,0 @@
---
title: 'Gemini Capsule'
description: 'I run my own Gemini site!'
pubDate: 'Apr 24 2022'
heroImage: '/kristall-gemini.png'
---
[What is Gemini?](https://gemini.circumlunar.space/docs/faq.gmi)
----------------------------------------------------------------
[Gemini](https://gemini.circumlunar.space/) is a HTTP/HTTPS alternative protocol. Other protocols like Gemini are [Gopher](https://wikiless.org/wiki/Gopher_(protocol)?lang=en) and [Finger](https://wikiless.org/wiki/Finger_%28protocol%29?lang=en), all of which render webpages. The HTTP/HTTPS sites are extremely bloated with JavaScript, user tracking, and  generally slower than what it can and should be. Gemini and other alternative protocols want to being back a lightweight text-based internet back! If there is demand for it (or if I feel like it) I will make a Gopher and Finger sites.
I have launched a Gemini site which you can access using this link: [gemini://arrayinamatrix.xyz/](gemini://arrayinamatrix.xyz/)
This link will take you nowhere if you don't have a browser/client that is compatible with the Gemini protocol. I recommend the [Kristall browser](https://github.com/MasterQ32/kristall/) which can access not only Gemini sites but also other web-pages using HTTP, HTTPS, Gopher and Finger. Like always, there are [other clients](https://gemini.circumlunar.space/clients.html) you can use. You can visit sites using Gemini using a proxy like this [one](https://gemproxy.koyu.space/).
Screenshots of the Kristall client:
[![Kristall displaying my Gemini site.](/kristall-gemini.png)](/kristall-gemini.png)
Kristall displaying my Gemini site.
[![Kristall displaying my HTTPS site.](/kristall-https.png)](/kristall-https.png)
Kristall displaying my HTTPS site.
I have Mirrored my [website](https://arrayinamatrix.xyz/) and the [Arch Linux wiki](https://wiki.archlinux.org/) on Gemini:
My site: [gemini://arrayinamatrix.xyz/](gemini://arrayinamatrix.xyz/)
Arch Wiki: [gemini://arrayinamatrix.xyz/arch-wiki/en/Table\_of\_contents.gmi](gemini://arrayinamatrix.xyz/arch-wiki/en/Table_of_contents.gmi)

View file

@ -1,40 +0,0 @@
---
title: 'Home-wide Ad-block'
description: 'How I setup adblock on all my devices at home.'
pubDate: 'Jun 30 2022'
---
### Table of Contents
* [Choosing an OS](#mcetoc_1gk98jdno10a)
* [Background](#mcetoc_1gk98jdno10b)
* [Setting up](#mcetoc_1gk98jdno10c) 
* [Mapping IPs](#mcetoc_1gk98jdno10d)
* [Switching to Void Linux](#mcetoc_1gk98jdno10e)
I am writing this because I am waiting for Gentoo (specifically Portage) to finish compiling and installing packages (It is taking forever!). This isn't a guide, I'm just documenting what I'm doing. I recently _acquired_ a Raspberry π 3 B and want to setup a network-wide ad-block on my home network.
### Choosing an OS
First thing to do was choose an operating system to run on the device. I used Gentoo for a bit but now I'm running [Void Linux](#mcetoc_1gk98jdno10e). I have pretty much no experience with Gentoo or any \*BSD OS. So I [Startpage](https://www.startpage.com/)\-ed a little and settled on choosing between Gentoo or FreeBSD. If you read the first line of this blog, you already know what I went with. I installed Gentoo not in a traditional way (compiling kernel from source with [USE flags](https://wiki.gentoo.org/wiki/Handbook:AMD64/Working/USE), based) but I used an install script (cringe). I used Sakaki's [gentoo-on-rpi-64bit](https://github.com/sakaki-/gentoo-on-rpi-64bit) (unmaintained) script but after the installation I found the (maintained-ish) [fork](https://github.com/GenPi64/gentoo-on-rpi-64bit), which is what I should have been using.
### Background
The easiest way to setup an ad-block is to get a list of ad/tracker domains and just forward them to 0.0.0.0 (nullifying the request) in `/etc/hosts` ([like this](https://github.com/StevenBlack/hosts)) but this is not complicated enough for me (and isn't network-wide), so what I have chosen to do is install [Pi-hole](https://pi-hole.net/), which happens to also uses the previously mentioned list. Pi-hole's list of supported OSes does not include Void Linux either Gentoo or FreeBSD so why did I chose to run an advanced-level operating system which isn't officially support to do such a mundane task? This question is left as an exercise for the reader.
### Setting up 
Now, we do the usual stuff when installing a new system, syncing repositories, updating preinstalled packages (not like there were many to begin with), installing docker and docker compose, installing a good text editor (i.e. neovim), changing the shell and themeing it, setting up ssh keys, etc. The Pi-hole project provides a docker image which can be used on any OS. I used the [project's quick start yaml script](https://github.com/pi-hole/docker-pi-hole/#quick-start) and created an executable shell script with `docker compose -f docker-compose.yml up -d` to easily update Pi-hole. I appended the domains and their respective IP addresses to the file `custom.list` located in `/etc/pihole` inside the docker container (on the host system, the folder `etc-pihole` relative to the working directory).
### Mapping IPs
On my home internet, I have to type the local IP address of my server to actually access it which is inconvenient due to numerous reasons. Pi-hole can be used as a DNS server which can be used to map my domains to my server using the local IP. Mapping domain names to IP address can be done using the hosts file but editing this for every device is inconvenient and tedious. Using pi-hole, services which rely on a domain name or a SSL certificate (e.g. [Matrix](https://arrayinamatrix.xyz/index/apps/matrix/)) work without a VPN or proxy on the same network it is hosted on.
_Client and server without DNS server:_
client ---> server (local/public IP address)
_Client and server with DNS server:_
client ---> Pi-hole DNS server ---> server (domain name)
### Switching to Void Linux
After using the π with Gentoo for a couple months, I have decided to switch the operating system to Void Linux. Firstly, using prebuilt binaries is against the philosophy of using a source-based OS. Compiling packages on the π takes longer than I would like. Void Linux has better support for ARM CPUs, they even have [builds](https://voidlinux.org/download/) specific for the Raspberry π. Installing on the Void on the π is far easier and quicker than Gentoo. I used Void's  rpi-aarch64 glibc live image. I would use the musl build for better security (i.e. less attack surface) among other things but some software may be [incomparable](https://docs.voidlinux.org/installation/musl.html#incompatible-software) (it probably does not matter in my use case, might actually be better to use musl but I do not want to run into any surprises).

View file

@ -1,114 +0,0 @@
---
title: 'New blog site'
description: 'A little post about the new site.'
pubDate: 'Jan 15 2024'
---
Hello readers, this is the first article on my new site! I'll be showcasing some of its features here! The source code for it can be found [here](https://git.inamatrix.xyz/array-in-a-matrix/bloginamatrix.xyz).
## Technologies
The original blog site was created using [Publii](https://getpublii.com/). It is a nice application if you want to create a site without any coding. The reason I am not going to be using it anymore is because I want my blog site to reflect me better. Publii isn't flexible enough for me to do that.
### Framework
This website is built using the [Astro](https://astro.build/) framework with several plugins. This site is my first experience with it so it may not be the best or most unique looking. Surprisingly, it was not as hard as I expected it to be. I initially wanted to build this site using the Nim programming language but it's web frameworks can not compete with JavaScript or TypeScript just yet (and I do not want to write bindings). The site is not completely written by me from scratch as I used Astro's blog template.
### Editor
I really like Markdown and I've been using it everywhere from writing notes, documentation[^1] or even in my messages with others ~~assuming the chat app supports it like [Matrix](https://matrix.org/)~~. My favorite Markdown editor right now is [Joplin](https://joplinapp.org/), which is FOSS and cross-platform. It supports the extended Markdown syntax and has many community made [plugins](#plugins).
[^1]: I'm lying about documentation. I use [VSCodium](https://vscodium.com/) instead.
### Plugins
The plugins are the most exciting part of this whole thing I think. You can find the plugins for Joplin and Astro [here](https://github.com/joplin/plugins/) and [here](https://astro.build/integrations/) respectively.
> "***Actually***, Astro calls them **integrations** not *plugins*." - 🤓
A lot of heavy lifting is done using [Unified](https://github.com/unifiedjs) and the plugins they maintain. I heavily recommend checking the project out as it opens the doors to so many possibilities!
### Rendered
#### Basic and Extended Markdown
You have seen some throughout the article but did you know <mark>this text is highlighted</mark>? Did you know that <sup>this is superscripted</sup> and <sub>this is subscripted</sub>? <sub><sup>What about both</sup></sub>?
To do:
- [ ] Do this thing
- [ ] Do that thing
- [x] procrastinate
> There is a list! - 💩
+ Days of the Week
+ Weeknotend
1. Monday
2. Tuesday
3. Wednesday
4. Thursday
5. Friday
- Weekend
- Saturday
- Sunday
Extended Markdown brings some much needed elements.
Can't wait to put food on the table.
| Fruit | Sandwich | Cheese |
| :--------- | :--------: | ------: |
| 🥝 | 🥙 | 🧀 |
| 🍑 | 🌭 | 🧀 |
| 🍉 | 🏖️🧙 | 🧀 |
This document is actually MDX not pure Markdown.
MDX can be used for UI component stuff like JSX. You can import MDX into other MDX or into `.astro` files and the reverse works too!
Here is a code block:
```c hello.c
#include <stdio.h>
int main(void) {
printf("Hello World!\n");
return 0;
}
```
#### KaTeX
Markdown renders that can not render mathematical equations suck because you are then forced to either create an image or write the equation using special unicodes.
Time-dependent Schrödinger equation:
$$
i \hbar \frac{\partial}{\partial t} \ket{\Psi(t)} = \hat H \ket{\Psi(t)}
$$
$\mathcal{L}$aplace Transform:
$$
\mathcal{L}\{f(t)\}=\int_{t=0}^{\infty}f(t)e^{-st}dt
$$
A simple square matrix:
```math
\begin{bmatrix}
ت & ب & ا \\
a & b & c \\
α & β & γ \\
\end{bmatrix}
```
Before you ask, yes, $e^{i\pi}+1=0$, it can also do inline as well. Gone are the days of writing math using unicodes or drawing an image.
#### Mermaid
Mermaid lets you create diagrams super easily.
```mermaid
graph TD;
A --> B --> C --> D --> A
A(Wake up)
B(Eat)
C(AAAAAAAAAAAAAAAA)
D(Sleep)
```

View file

@ -1,46 +0,0 @@
---
title: 'iPhone Modifications: Hardware'
description: 'Hardware mods I have done.'
pubDate: 'Aug 24 2022'
heroImage: '/2-3.gif'
---
### Table of Contents
* [Introduction](#mcetoc_1gm48savao5)
* [Hardware](#mcetoc_1gm48savao6)
* [RGB Apple Logo](#mcetoc_1gm48savao7)
* [RGB Speakers](#mcetoc_1gm48savao8)
Introduction
------------
There are 2 types of modifications that can be done on a phone, hardware and software. I have jailbroken my phone on many occasions because I like being able to customize it and add functionality to make IOS a more usable operating system. Hardware mods can extend the life of your device or turn it into a explosive.
Hardware
--------
I have done 2 hardware modifications so far, LED in the Apple logo and LEDs in the speaker grill, both of which were done on an iPhone 7 Plus which I dragged through software and hardware (I skateboard) hell. I have also repaired the displays and buttons of a couple IOS devices (yes, this isn't relevant, I don't care). Other mods exist which actually make the device better like [replacing the Lightning port with a USB-C port](https://kenp.io/iphone_usbc_mod_part_1/), [adding duel SIM support](https://youtu.be/MgK4-RB35do) and expanding the device's storage as seen [here](https://youtu.be/rHP-OPXK2ig) and [here](https://youtu.be/oPHZodRrkt0). 
### RGB Apple Logo
The RGB Apple logo mod was the more successful mod out of the two I've done, which is also the first. Installing it went flawlessly and I didn't notice any extra power drain using it. The LED Apple logo is touch sensitive which switches between different color animations and can be used to turn the LED off. Below are all of the states the LED can be in, 7 color cycles and the off state.
[![](/3-2.gif)](/3-2.gif)
[![](/8-2.gif)](/8-2.gif)
[![](/7-2.gif)](/7-2.gif)
[![](/6-2.gif)](/6-2.gif)
[![](/5-2.gif)](/5-2.gif)
[![](/4-2.gif)](/4-2.gif)
[![](/2-3.gif)](/2-3.gif)
[![](/1-3.gif)](/1-3.gif)
### RGB Speakers
I wouldn't consider this mod a success. I damaged the ribbon cable which connected the power/side and volume buttons, which then I had to get a replacement part and somewhat fixed (the power button is super mushy and very unresponsive as the part does not properly fit). I also partially damaged the speaker LEDs so only one grill had working lights. I didn't take any presentable pictures of this mod (pain) and a couple weeks after installing it, I dropped the phone and killed off the speaker, mic and broke the display. [The mod looks like this](https://youtu.be/07bTt0BTi-U). This mod considerably affects the amount of power the mic gets (keep in mind I was using this mod along side the light up Apple logo and never tested it alone) which can, if on a call for example, make the other person unable to hear you. The lights are very visible in the dark (that's a thing light emitting things do) but not so bright outside in the day time which is understandable.

View file

@ -1,16 +0,0 @@
import { defineCollection, z } from 'astro:content';
const blog = defineCollection({
type: 'content',
// Type-check frontmatter using a schema
schema: z.object({
title: z.string(),
description: z.string(),
// Transform string to Date object
pubDate: z.coerce.date(),
updatedDate: z.coerce.date().optional(),
heroImage: z.string().optional(),
}),
});
export const collections = { blog };

2
src/env.d.ts vendored
View file

@ -1,2 +0,0 @@
/// <reference path="../.astro/types.d.ts" />
/// <reference types="astro/client" />

24
src/fonts.css Normal file
View file

@ -0,0 +1,24 @@
.noise {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAMAAAAp4XiDAAAAUVBMVEWFhYWDg4N3d3dtbW17e3t1dXWBgYGHh4d5eXlzc3OLi4ubm5uVlZWPj4+NjY19fX2JiYl/f39ra2uRkZGZmZlpaWmXl5dvb29xcXGTk5NnZ2c8TV1mAAAAG3RSTlNAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAvEOwtAAAFVklEQVR4XpWWB67c2BUFb3g557T/hRo9/WUMZHlgr4Bg8Z4qQgQJlHI4A8SzFVrapvmTF9O7dmYRFZ60YiBhJRCgh1FYhiLAmdvX0CzTOpNE77ME0Zty/nWWzchDtiqrmQDeuv3powQ5ta2eN0FY0InkqDD73lT9c9lEzwUNqgFHs9VQce3TVClFCQrSTfOiYkVJQBmpbq2L6iZavPnAPcoU0dSw0SUTqz/GtrGuXfbyyBniKykOWQWGqwwMA7QiYAxi+IlPdqo+hYHnUt5ZPfnsHJyNiDtnpJyayNBkF6cWoYGAMY92U2hXHF/C1M8uP/ZtYdiuj26UdAdQQSXQErwSOMzt/XWRWAz5GuSBIkwG1H3FabJ2OsUOUhGC6tK4EMtJO0ttC6IBD3kM0ve0tJwMdSfjZo+EEISaeTr9P3wYrGjXqyC1krcKdhMpxEnt5JetoulscpyzhXN5FRpuPHvbeQaKxFAEB6EN+cYN6xD7RYGpXpNndMmZgM5Dcs3YSNFDHUo2LGfZuukSWyUYirJAdYbF3MfqEKmjM+I2EfhA94iG3L7uKrR+GdWD73ydlIB+6hgref1QTlmgmbM3/LeX5GI1Ux1RWpgxpLuZ2+I+IjzZ8wqE4nilvQdkUdfhzI5QDWy+kw5Wgg2pGpeEVeCCA7b85BO3F9DzxB3cdqvBzWcmzbyMiqhzuYqtHRVG2y4x+KOlnyqla8AoWWpuBoYRxzXrfKuILl6SfiWCbjxoZJUaCBj1CjH7GIaDbc9kqBY3W/Rgjda1iqQcOJu2WW+76pZC9QG7M00dffe9hNnseupFL53r8F7YHSwJWUKP2q+k7RdsxyOB11n0xtOvnW4irMMFNV4H0uqwS5ExsmP9AxbDTc9JwgneAT5vTiUSm1E7BSflSt3bfa1tv8Di3R8n3Af7MNWzs49hmauE2wP+ttrq+AsWpFG2awvsuOqbipWHgtuvuaAE+A1Z/7gC9hesnr+7wqCwG8c5yAg3AL1fm8T9AZtp/bbJGwl1pNrE7RuOX7PeMRUERVaPpEs+yqeoSmuOlokqw49pgomjLeh7icHNlG19yjs6XXOMedYm5xH2YxpV2tc0Ro2jJfxC50ApuxGob7lMsxfTbeUv07TyYxpeLucEH1gNd4IKH2LAg5TdVhlCafZvpskfncCfx8pOhJzd76bJWeYFnFciwcYfubRc12Ip/ppIhA1/mSZ/RxjFDrJC5xifFjJpY2Xl5zXdguFqYyTR1zSp1Y9p+tktDYYSNflcxI0iyO4TPBdlRcpeqjK/piF5bklq77VSEaA+z8qmJTFzIWiitbnzR794USKBUaT0NTEsVjZqLaFVqJoPN9ODG70IPbfBHKK+/q/AWR0tJzYHRULOa4MP+W/HfGadZUbfw177G7j/OGbIs8TahLyynl4X4RinF793Oz+BU0saXtUHrVBFT/DnA3ctNPoGbs4hRIjTok8i+algT1lTHi4SxFvONKNrgQFAq2/gFnWMXgwffgYMJpiKYkmW3tTg3ZQ9Jq+f8XN+A5eeUKHWvJWJ2sgJ1Sop+wwhqFVijqWaJhwtD8MNlSBeWNNWTa5Z5kPZw5+LbVT99wqTdx29lMUH4OIG/D86ruKEauBjvH5xy6um/Sfj7ei6UUVk4AIl3MyD4MSSTOFgSwsH/QJWaQ5as7ZcmgBZkzjjU1UrQ74ci1gWBCSGHtuV1H2mhSnO3Wp/3fEV5a+4wz//6qy8JxjZsmxxy5+4w9CDNJY09T072iKG0EnOS0arEYgXqYnXcYHwjTtUNAcMelOd4xpkoqiTYICWFq0JSiPfPDQdnt+4/wuqcXY47QILbgAAAABJRU5ErkJggg==);
}
@font-face {
font-family: 'FiraCode';
src: url("/public/fonts/FiraCode-Regular.woff2") format("woff2");
}
@font-face {
font-family: 'asix';
src: url("/public/fonts/ASIX-FOUNDER.woff2") format("woff2");
}
@font-face {
font-family: 'asix';
src: url("/public/fonts/ASIX-FOUNDER-Italic.woff2") format("woff2");
font-style: italic;
}
@font-face {
font-family: 'giga';
src: url("/public/fonts/Giga.woff2") format("woff2");
}

27
src/index.html Normal file
View file

@ -0,0 +1,27 @@
<!DOCTYPE html><html>
<head>
<meta charset="utf-8">
<title>Blog in a Matrix</title>
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
fontFamily: {
'sans': ['FiraCode'],
'serif': ['FiraCode'],
'mono': ['FiraCode'],
'asix': ['asix'],
'giga': ['giga']
}
},
}
};
</script>
<link rel="stylesheet" type="text/css" href="fonts.css" />
</head>
<body class="flex flex-col min-h-screen m-0 bg-gradient-to-br from-yellow-400 to-green-900">
<main id="app" class="flex flex-1 w-full max-sm:flex-col"></main>
<script src="main.js"></script>
</body>
</html>

View file

@ -1,90 +0,0 @@
---
import type { CollectionEntry } from 'astro:content';
import BaseHead from '../components/BaseHead.astro';
import Header from '../components/Header.astro';
import FormattedDate from '../components/FormattedDate.astro';
type Props = CollectionEntry<'blog'>['data'];
const { title, description, pubDate, updatedDate, heroImage } = Astro.props;
---
<html lang="en">
<head>
<BaseHead title={title} description={description} />
<style>
main {
width: calc(100% - 2em);
max-width: 100%;
margin: 0;
}
.hero-image {
width: 100%;
}
.hero-image img {
display: block;
margin: 0 auto;
border-radius: 12px;
box-shadow: var(--box-shadow);
}
.prose {
width: 720px;
max-width: calc(100% - 2em);
margin: auto;
padding: 1em;
color: rgb(var(--gray-dark));
}
.title {
margin-bottom: 1em;
padding: 1em 0;
text-align: center;
line-height: 1;
}
.title h1 {
margin: 0 0 0.5em 0;
}
.date {
margin-bottom: 0.5em;
color: rgb(var(--gray));
}
.last-updated-on {
font-style: italic;
}
</style>
<script>
function randomColor() {return "#000000".replace(/0/g,function(){return (~~(Math.random()*16)).toString(16);});}
var noImage = document.getElementsByClassName("gradient");
var i = 0;
while(i <= noImage.length){
noImage[i++].style.cssText += `background: linear-gradient(${randomColor()},${randomColor()})`;
}
</script>
</head>
<body>
<Header />
<main>
<article>
<div class="hero-image">
{heroImage ? <img width={1020} height={510} src={heroImage} alt="" /> : <img width={1020} height={510} class="gradient" alt="" />}
</div>
<div class="prose">
<div class="title">
<div class="date">
<FormattedDate date={pubDate} />
{
updatedDate && (
<div class="last-updated-on">
Last updated on <FormattedDate date={updatedDate} />
</div>
)
}
</div>
<h1>{title}</h1>
<hr />
</div>
<slot />
</div>
</article>
</main>
</body>
</html>

18
src/main.nim Normal file
View file

@ -0,0 +1,18 @@
import
os,
happyx,
path_params,
components/[nav, glass, read]
appRoutes("app"):
"/":
component Nav
component GlassHome("Blog in a Matrix")
"/read/<article>":
component Nav
component Read($article)
notfound:
component Nav
component Glass("404 page diverges.")

View file

@ -1,20 +0,0 @@
---
import { type CollectionEntry, getCollection } from 'astro:content';
import BlogPost from '../layouts/BlogPost.astro';
export async function getStaticPaths() {
const posts = await getCollection('blog');
return posts.map((post) => ({
params: { slug: post.slug },
props: post,
}));
}
type Props = CollectionEntry<'blog'>;
const post = Astro.props;
const { Content } = await post.render();
---
<BlogPost {...post.data}>
<Content />
</BlogPost>

View file

@ -1,116 +0,0 @@
---
import BaseHead from '../components/BaseHead.astro';
import Header from '../components/Header.astro';
import { SITE_TITLE, SITE_DESCRIPTION } from '../consts';
import { getCollection } from 'astro:content';
import FormattedDate from '../components/FormattedDate.astro';
const posts = (await getCollection('blog')).sort(
(a, b) => a.data.pubDate.valueOf() - b.data.pubDate.valueOf()
);
---
<!doctype html>
<html lang="en">
<head>
<BaseHead title={SITE_TITLE} description={SITE_DESCRIPTION} />
<style>
main {
width: 960px;
}
ul {
display: flex;
flex-wrap: wrap;
gap: 2rem;
list-style-type: none;
margin: 0;
padding: 0;
}
ul li {
width: calc(50% - 1rem);
}
ul li * {
text-decoration: none;
transition: 0.2s ease;
}
ul li:first-child {
width: 100%;
margin-bottom: 1rem;
text-align: center;
}
ul li:first-child img {
width: 100%;
}
ul li:first-child .title {
font-size: 2.369rem;
}
ul li img {
margin-bottom: 0.5rem;
border-radius: 12px;
}
ul li a {
display: block;
}
.title {
margin: 0;
color: rgb(var(--black));
line-height: 1;
}
.date {
margin: 0;
color: rgb(var(--gray));
}
ul li a:hover h4,
ul li a:hover .date {
color: rgb(var(--accent));
}
ul a:hover img {
box-shadow: var(--box-shadow);
}
@media (max-width: 720px) {
ul {
gap: 0.5em;
}
ul li {
width: 100%;
text-align: center;
}
ul li:first-child {
margin-bottom: 0;
}
ul li:first-child .title {
font-size: 1.563em;
}
}
</style>
<script>
function randomColor() {return "#000000".replace(/0/g,function(){return (~~(Math.random()*16)).toString(16);});}
var noImage = document.getElementsByClassName("gradient");
var i = 0;
while(i <= noImage.length){
noImage[i++].style.cssText += `background: linear-gradient(${randomColor()},${randomColor()})`;
}
</script>
</head>
<body>
<Header />
<main>
<section>
<ul>
{
posts.map((post) => (
<li>
<a href={`/${post.slug}/`}>
{ post.data.heroImage ? <img width={720} height={360} src={post.data.heroImage} alt="" /> : <img width={720} height={360} class="gradient" alt="" />}
<h4 class="title">{post.data.title}</h4>
<p class="date">
<FormattedDate date={post.data.pubDate} />
</p>
</a>
</li>
))
}
</ul>
</section>
</main>
</body>
</html>

View file

@ -1,16 +0,0 @@
import rss from '@astrojs/rss';
import { getCollection } from 'astro:content';
import { SITE_TITLE, SITE_DESCRIPTION } from '../consts';
export async function GET(context) {
const posts = await getCollection('blog');
return rss({
title: SITE_TITLE,
description: SITE_DESCRIPTION,
site: context.site,
items: posts.map((post) => ({
...post.data,
link: `/${post.slug}/`,
})),
});
}

4
src/path_params.nim Normal file
View file

@ -0,0 +1,4 @@
import happyx
pathParams:
article string

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
src/public/fonts/Giga.woff2 Normal file

Binary file not shown.

View file

@ -1,156 +0,0 @@
/*
The CSS in this style tag is based off of Bear Blog's default CSS.
https://github.com/HermanMartinus/bearblog/blob/297026a877bc2ab2b3bdfbd6b9f7961c350917dd/templates/styles/blog/default.css
License MIT: https://github.com/HermanMartinus/bearblog/blob/master/LICENSE.md
*/
:root {
--accent: #2337ff;
--accent-dark: #000d8a;
--black: 15, 18, 25;
--gray: 96, 115, 159;
--gray-light: 229, 233, 240;
--gray-dark: 34, 41, 57;
--gray-gradient: rgba(var(--gray-light), 50%), #fff;
--box-shadow: 0 2px 6px rgba(var(--gray), 25%), 0 8px 24px rgba(var(--gray), 33%),
0 16px 32px rgba(var(--gray), 33%);
}
@font-face {
font-family: 'Atkinson';
src: url('/fonts/atkinson-regular.woff') format('woff');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Atkinson';
src: url('/fonts/atkinson-bold.woff') format('woff');
font-weight: 700;
font-style: normal;
font-display: swap;
}
body {
font-family: 'Atkinson', sans-serif;
margin: 0;
padding: 0;
text-align: left;
background: linear-gradient(var(--gray-gradient)) no-repeat;
background-size: 100% 600px;
word-wrap: break-word;
overflow-wrap: break-word;
color: rgb(var(--gray-dark));
font-size: 20px;
line-height: 1.7;
display: flex;
}
main {
width: 720px;
max-width: calc(100% - 2em);
margin: auto;
padding: 3em 1em;
}
h1,
h2,
h3,
h4,
h5,
h6 {
margin: 0 0 0.5rem 0;
color: rgb(var(--black));
line-height: 1.2;
}
h1 {
font-size: 3.052em;
}
h2 {
font-size: 2.441em;
}
h3 {
font-size: 1.953em;
}
h4 {
font-size: 1.563em;
}
h5 {
font-size: 1.25em;
}
strong,
b {
font-weight: 700;
}
a {
color: var(--accent);
}
a:hover {
color: var(--accent);
}
p {
margin-bottom: 1em;
}
.prose p {
margin-bottom: 2em;
}
textarea {
width: 100%;
font-size: 16px;
}
input {
font-size: 16px;
}
table {
width: 100%;
}
img {
max-width: 100%;
height: auto;
border-radius: 8px;
}
code {
padding: 2px 5px;
background-color: rgb(var(--gray-light));
border-radius: 2px;
}
pre {
padding: 1.5em;
border-radius: 8px;
}
pre > code {
all: unset;
}
blockquote {
border-left: 4px solid var(--accent);
padding: 0 0 0 20px;
margin: 0px;
font-size: 1.333em;
}
hr {
border: none;
border-top: 1px solid rgb(var(--gray-light));
}
@media (max-width: 720px) {
body {
font-size: 18px;
flex-direction: column;
}
main {
padding: 1em;
}
}
.sr-only {
border: 0;
padding: 0;
margin: 0;
position: absolute !important;
height: 1px;
width: 1px;
overflow: hidden;
/* IE6, IE7 - a 0 height clip, off to the bottom right of the visible 1px box */
clip: rect(1px 1px 1px 1px);
/* maybe deprecated but we need to support legacy browsers */
clip: rect(1px, 1px, 1px, 1px);
/* modern browsers, clip-path works inwards from each corner */
clip-path: inset(50%);
/* added line to stop words getting smushed together (as they go onto seperate lines and some screen readers do not understand line feeds as a space */
white-space: nowrap;
}

View file

@ -1,7 +0,0 @@
{
"extends": "astro/tsconfigs/base",
"compilerOptions": {
"strictNullChecks": true,
"allowJs": true
}
}