Commit 07c42d3ad1

07c42d3ad17060131e822f5816d2057cd1753b1b

parent: c71a52cb7a

Unsigned

cmc <hello@cleberg.net> · 2024-03-29 06:30 UTC

massive re-write from org-publish to weblorg

Layout: unified · split

.gitignore +1 −2
@@ -1,3 +1,2 @@
11.DS_Store
2public/*
3sitemap.org
2.build
README.org +13 −49
@@ -5,54 +5,19 @@
55
66[[https://cleberg.net][cleberg.net]] is my personal webpage.
77
8This README is viewable on [[https://git.cleberg.net/cleberg.net.git/tree/README.org][cgit]] (raw), or on [[https://cleberg.net/README.html][my website]] (html).
8This README is viewable on [[https://git.cleberg.net/cleberg.net.git/tree/README.org][rgit]].
99
1010** Overview
1111
12This website & blog uses [[https://orgmode.org/][Org-Mode]], published with =org-publish=.
12This website & blog uses [[https://orgmode.org/][Org-Mode]], published with [[https://github.com/emacs-love/weblorg][weblorg]].
1313
1414** Configuration
1515
16In order to configure the project for publishing, add the following code to your =~/.emacs= file (for Doom, =~/.doom.d/config.el=).
17
18#+begin_src lisp
19;; org-publish
20(require 'ox-publish)
21
22(setq org-publish-project-alist
23 `(("blog"
24 :base-directory "~/Source/cleberg.net/"
25 :base-extension "org"
26 :recursive t
27 :publishing-directory "~/Source/cleberg.net/public/"
28 :publishing-function org-html-publish-to-html)
29 ;; HTML5
30 :html-doctype "html5"
31 :html-html5-fancy t
32 ;; Disable some Org's HTML defaults
33 :html-head-include-scripts nil
34 :html-head-include-default-style nil
35 ;; Generate sitemap
36 :auto-sitemap t
37 :sitemap-filename "sitemap.org"
38 ;; Customize head, preamble, & postamble
39 :html-head "<link rel='stylesheet' href='/static/styles.css' type='text/css'>"
40 :html-preamble ""
41 :html-postamble ""
42 ("static"
43 :base-directory "~/Source/cleberg.net/static/"
44 :base-extension "css\\|txt\\|jpg\\|gif\\|png"
45 :recursive t
46 :publishing-directory "~/Source/cleberg.net/public/"
47 :publishing-function org-publish-attachment)
48
49 ("cleberg.net" :components ("blog" "static"))));; org-publish
50(require 'ox-publish)
51#+end_src
16Everything is configured within the =publish.el= file. Refer to the weblorg documentation for further configuration options.
5217
5318** Building
5419
55Local testing can be done via [[https://www.gnu.org/software/emacs/][Emacs]].
20Local testing can be done via [[https://www.gnu.org/software/emacs/][Emacs]] or through the command line.
5621
5722To get running:
5823
@@ -62,22 +27,21 @@ cd cleberg.net
6227emacs -nw
6328#+end_src
6429
65Within Emacs, open any of the repository files. In Doom, I do this with =Spc f f= and selecting =README.org=. Once a file has been opened, you can publish the project with =C-c C-e P a=.
30Within Emacs, open any of the repository files. In Doom, I do this with =Spc f f= and selecting =README.org=. Make any changes necessary to customize the project.
31
32To publish, you can use the =build.sh= script (change the deployment target!) or you can run the following commands.
6633
67If you need to re-publish unchanged files, I recommend using the following command:
34Use the =ENV= environment variable to determine which base URL weblorg will use. If ENV is ommitted, it will default to =localhost:8000=. If =ENV=prod=, weblorg will look in the =publish.el= file for the production base URL.
6835
69#+begin_src lisp
70M-: (org-publish "project name" t)
36#+begin_src sh
37ENV=prod emacs --script publish.el
7138#+end_src
7239
73The files will be published to the =public= directory.
40The files will be published to the =.build= directory. You can deploy these files to the target through any number of methods, such as =scp= or SFTP.
7441
7542** Tasks
7643
77*** TODO Create RSS feed
78Possible Solution: [[https://writepermission.com/org-blogging-rss-feed.html][Org mode blogging: RSS feed]]
79Possible Solution: [[https://www.zoraster.org/blog/script-to-generate-rss-feed][Script to Generate RSS Feeds]]
44*** DONE Create RSS feed
8045*** TODO Format all blog posts with =M q=
81*** TODO Create script to auto-generate the =/blog/= list and =/= most recent posts
82Possible Solution: [[https://taingram.org/blog/org-mode-blog.html#orgde61a58][Sitemap]]
46*** DONE Create script to auto-generate the =/blog/= list and =/= most recent posts
8347*** TODO Figure out how to get filetags to show up
blog/index.org deleted −141
@@ -1,141 +0,0 @@
1#+title: Blog
2#+options: toc:nil
3
4Use =Ctrl + F= to search blog post titles for keywords.
5
6* TODO Create RSS Feed
7
8* 2024
9
10- 2024-02-26 [[./org-blog/][Blogging in Org-Mode]]
11- 2024-02-21 [[./self-hosting-otter-wiki/][Self-Hosting An Otter Wiki]]
12- 2024-02-13 [[./ubuntu-emergency-mode/][Stuck in Ubuntu's Emergency Mode? Try Fixing the Fstab File]]
13- 2024-02-06 [[./zfs/][How to Create a ZFS Pool on Ubuntu Linux]]
14- 2024-01-27 [[./tableau-dashboard/][Data Visualization: Mapping Omaha Crime Data with Tableau]]
15- 2024-01-26 [[./audit-dashboard/][Building an Audit Status Dashboard]]
16- 2024-01-13 [[./local-llm/][Running Local LLMs on macOS and iOS]]
17- 2024-01-09 [[./macos-customization/][Customizing macOS]]
18- 2024-01-08 [[./dont-say-hello/][Don't Say Hello]]
19
20* 2023
21
22- 2023-12-03 [[./unifi-nextdns/][How to Install NextDNS on the Unifi Dream Machine]]
23- 2023-11-08 [[./scli/][Installing scli on Alpine Linux (musl)]]
24- 2023-10-17 [[./self-hosting-anonymousoverflow/][Self-Hosting AnonymousOverflow]]
25- 2023-10-15 [[./alpine-ssh-hardening/][SSH Hardening for Alpine Linux]]
26- 2023-10-11 [[./self-hosting-authelia/][Self-Hosting Authelia]]
27- 2023-10-04 [[./digital-minimalism/][Digital Minimalism]]
28- 2023-09-19 [[./audit-sql-scripts/][Useful SQL Scripts for Auditing Logical Access]]
29- 2023-09-15 [[./self-hosting-gitweb/][Self-Hosting GitWeb via Nginx]]
30- 2023-08-18 [[./agile-auditing/][Agile Auditing: An Introduction]]
31- 2023-07-19 [[./plex-transcoder-errors/][How to Avoid Plex Error: 'Conversion failed. The transcoder failed to start up.']]
32- 2023-07-12 [[./wireguard-lan/][Enable LAN Access in Mullvad Wireguard Conf Files]]
33- 2023-06-30 [[./self-hosting-voyager/][Self-Hosting Voyager - A Lemmy Web Client]]
34- 2023-06-28 [[./backblaze-b2/][Getting Started with Backblaze B2 Cloud Storage]]
35- 2023-06-23 [[./self-hosting-convos/][Self-Hosting Convos IRC Web Client]]
36- 2023-06-23 [[./byobu/][Byobu]]
37- 2023-06-20 [[./audit-review-template/][Audit Testing Review Template]]
38- 2023-06-18 [[./unifi-ip-blocklist/][Block IP Addresses and Subnets with Unifi Network Firewall]]
39- 2023-06-08 [[./goaccess-geoip/][Inspecting Nginx Logs with GoAccess and MaxMind GeoIP Data]]
40- 2023-06-08 [[./self-hosting-baikal/][Self-Hosting Baikal Server (CalDAV & CardDAV)]]
41- 2023-05-22 [[./burnout/][RE: Burnout]]
42- 2023-02-02 [[./exploring-hare/][Exploring the Hare Programming Language]]
43- 2023-01-28 [[./self-hosting-wger/][Self-Hosting Wger Workout Manager]]
44- 2023-01-23 [[./random-wireguard/][Connecting to a Random Mullvad Wireguard Host on Boot]]
45- 2023-01-21 [[./flatpak-symlinks/][Running Flatpak Apps with Symlinks]]
46- 2023-01-08 [[./fedora-login-manager/][How to Remove the Login Manager from Fedora i3]]
47- 2023-01-05 [[./mass-unlike-tumblr-posts/][How to Easily Mass Unlike Tumblr Posts with Javascript]]
48- 2023-01-03 [[./recent-website-changes/][Recent Website Changes]]
49
50* 2022
51
52- 2022-12-23 [[./alpine-desktop/][Alpine Linux as a Desktop OS]]
53- 2022-12-17 [[./st/][Simple Terminal]]
54- 2022-12-07 [[./nginx-wildcard-redirect/][Redirect Nginx Subdomains & Trailing Content with Regex]]
55- 2022-12-01 [[./nginx-compression/][Enable GZIP Compression in Nginx]]
56- 2022-11-29 [[./nginx-referrer-ban-list/][Creating a Referrer Ban List in Nginx]]
57- 2022-11-27 [[./server-build/][Building a Custom Rack-Mounted Server]]
58- 2022-11-11 [[./nginx-tmp-errors/][Fixing Permission Errors in /var/lib/nginx]]
59- 2022-10-30 [[./linux-display-manager/][How to Disable or Change the Display Manager on Void Linux]]
60- 2022-10-22 [[./alpine-linux/][Alpine Linux: My New Server OS]]
61- 2022-10-04 [[./syncthing/][Syncthing: A Minimal Self-Hosted Cloud Storage Solution]]
62- 2022-10-04 [[./mtp-linux/][How to Mount an MTP Mobile Device on Fedora Linux]]
63- 2022-09-21 [[./graphene-os/][Installing Graphene OS on the Pixel 6 Pro]]
64- 2022-09-17 [[./serenity-os/][Serenity OS: Testing Out a Unique System]]
65- 2022-08-31 [[./privacy-com-changes/][Concerning Changes on Privacy.com]]
66- 2022-03-23 [[./cloudflare-dns-api/][Dynamic DNS with Cloudflare API]]
67- 2022-07-31 [[./bash-it/][Upgrade Bash with Bash-It & Ble.sh]]
68- 2022-07-30 [[./flac-to-opus/][Recursive Command-Line FLAC to Opus Conversion]]
69- 2022-07-25 [[./curseradio/][CurseRadio: Listening to the Radio on the Command Line]]
70- 2022-07-14 [[./gnupg/][GNU Privacy Guard (GPG)]]
71- 2022-07-01 [[./git-server/][Self-Hosting a Personal Git Server]]
72- 2022-06-24 [[./fedora-i3/][Rebooting My Love Affair with Linux]]
73- 2022-06-22 [[./daily-poetry/][Daily Plaintext Poetry via Email]]
74- 2022-06-16 [[./terminal-lifestyle/][A Terminal Lifestyle]]
75- 2022-06-07 [[./self-hosting-freshrss/][Self-Hosting FreshRSS]]
76- 2022-06-01 [[./ditching-cloudflare/][Ditching Cloudflare for Njalla]]
77- 2022-04-09 [[./pinetime/][PineTime: An Open-Source Smart Watch]]
78- 2022-04-02 [[./nginx-reverse-proxy/][Set-Up a Reverse Proxy with Nginx]]
79- 2022-03-26 [[./ssh-mfa/][Enable TOTP MFA for SSH]]
80- 2022-03-24 [[./server-hardening/][Hardening a Public-Facing Home Server]]
81- 2022-03-23 [[./nextcloud-on-ubuntu/][Nextcloud on Ubuntu]]
82- 2022-03-08 [[./plex-migration/][Migrating Plex to a New Server (& Nvidia Transcoding)]]
83- 2022-03-03 [[./financial-database/][Maintaining a Personal Financial Database]]
84- 2022-03-02 [[./reliable-notes/][Easy, Reliable Note-Taking]]
85- 2022-02-22 [[./tuesday/][Tuesday]]
86- 2022-02-20 [[./nginx-caching/][Caching Static Content with Nginx]]
87- 2022-02-17 [[./exiftool/][Stripping Image Metadata with exiftool]]
88- 2022-02-16 [[./debian-and-nginx/][Migrating to a New Web Server Setup with Debian, Nginx, and Agate]]
89- 2022-02-10 [[./leaving-the-office/][Leaving Office-Based Work in the Past]]
90- 2022-02-10 [[./njalla-dns-api/][Dynamic DNS with Njalla API]]
91
92* 2021
93
94- 2021-12-04 [[./cisa/][I Passed the CISA!]]
95- 2021-10-09 [[./apache-redirect/][Apache Redirect HTML Files to a Directory]]
96- 2021-08-25 [[./audit-sampling/][Audit Sampling with Python]]
97- 2021-07-15 [[./delete-gitlab-repos/][How to Delete All GitLab Repositories]]
98- 2021-05-30 [[./changing-git-authors/][Changing Git Authors]]
99- 2021-04-28 [[./photography/][Jumping Back Into Photography]]
100- 2021-04-23 [[./php-comment-system/][Roll Your Own Static Commenting System in PHP]]
101- 2021-04-17 [[./gemini-server/][Hosting a Gemini Server]]
102- 2021-03-30 [[./vps-web-server/][How to Set Up a VPS Web Server]]
103- 2021-03-28 [[./vaporwave-vs-outrun/][Vaporwave vs Outrun]]
104- 2021-03-28 [[./gemini-capsule/][Launching a Gemini Capsule]]
105- 2021-03-19 [[./clone-github-repos/][How to Clone All Repositories from a GitHub or Sourcehut Account]]
106- 2021-02-19 [[./macos/][macOS: Testing Out A New OS]]
107- 2021-01-04 [[./fediverse/][A Simple Guide to the Fediverse]]
108- 2021-01-07 [[./ufw/][Secure Your Network with the Uncomplicated Firewall (ufw)]]
109- 2021-01-01 [[./seum/][SEUM: Speedrunners from Hell]]
110
111* 2020
112
113- 2020-12-29 [[./zork/][Zork: Let's Explore a Classic]]
114- 2020-12-27 [[./website-redesign/][Redesigning My Website: The 5 KB Result]]
115- 2020-12-28 [[./neon-drive/][Neon Drive: A Nostalgic 80s Arcade Racing Game]]
116- 2020-10-12 [[./mediocrity/][On the Pursuit of Mediocrity]]
117- 2020-09-25 [[./happiness-map/][Data Visualization: World Choropleth Map of Happiness]]
118- 2020-09-22 [[./internal-audit/][What is Internal Audit?]]
119- 2020-09-01 [[./visual-recognition/][IBM Watson Visual Recognition]]
120- 2020-08-29 [[./php-auth-flow/][PHP Authentication Flow]]
121- 2020-08-22 [[./redirect-github-pages/][Redirect GitHub Pages from Subdomain to the Top-Level Domain]]
122- 2020-07-26 [[./business-analysis/][Algorithmically Analyzing Local Businesses]]
123- 2020-07-20 [[./video-game-sales/][Data Exploration: Video Game Sales]]
124- 2020-05-19 [[./customizing-ubuntu/][Beginner's Guide: Customizing Ubuntu]]
125- 2020-05-03 [[./homelab/][An Inside Look at My Homelab]]
126- 2020-03-25 [[./session-manager/][Session Private Messenger]]
127- 2020-02-09 [[./cryptography-basics/][Cryptography Basics]]
128- 2020-01-26 [[./steam-on-ntfs/][Linux Gaming Tweak: Steam on NTFS Drives]]
129- 2020-01-25 [[./linux-software/][Linux Software]]
130
131* 2019
132
133- 2019-12-16 [[./password-security//][Password Security]]
134- 2019-12-03 [[./the-ansoff-matrix//][The Ansoff Matrix]]
135- 2019-09-09 [[./audit-analytics//][Data Analysis in Auditing]]
136- 2019-01-07 [[./useful-css//][Useful CSS Snippets]]
137
138* 2018
139
140- 2018-12-08 [[./aes-encryption//][AES Encryption]]
141- 2018-11-28 [[./cpp-compiler//][The C++ Compiler]]
blog/org-blog/index.org deleted −71
@@ -1,71 +0,0 @@
1#+title: Blogging in Org-Mode
2#+date: 2024-02-26
3#+description: A guide to blogging with org-mode, no third-party tools required.
4#+filetags: :dev:
5
6* TODO Write a post on emacs first?
7
8- Could write-up my Doom Emacs config and workflow first, then reference here.
9
10* TODO Configure Emacs
11
12#+begin_src sh
13emacs -nw
14#+end_src
15
16=SPC f f= ---> =~/.doom.d/config.el=
17
18#+begin_src lisp
19;; org-publish
20(require 'ox-publish)
21
22(setq org-publish-project-alist
23 `(("blog"
24 :base-directory "~/Source/cleberg.net/"
25 :base-extension "org"
26 :recursive t
27 :publishing-directory "~/Source/cleberg.net/public/"
28 :publishing-function org-html-publish-to-html
29 ;; HTML5
30 :html-doctype "html5"
31 :html-html5-fancy t
32 ;; Disable some Org's HTML defaults
33 :html-head-include-scripts nil
34 :html-head-include-default-style nil
35 :section-numbers nil
36 :with-title nil
37 ;; Generate sitemap
38 :auto-sitemap t
39 :sitemap-filename "sitemap.org"
40 ;; Customize HTML output
41 :html-divs ((preamble "header" "preamble")
42 (content "main" "content")
43 (postamble "footer" "postamble"))
44 :html-head "<link rel='stylesheet' href='/styles.css' type='text/css'>"
45 :html-preamble "<nav class='site-nav' aria-label='site-nav' role='navigation'>
46 <ul>
47 <li><a href='/'>Home</a></li>
48 <li><a href='/blog/'>Blog</a></li>
49 <li><a href='/services/'>Services</a></li>
50 <li><a href='/wiki/'>Wiki</a></li>
51 </ul></nav>
52 <h1>%t</h1>
53 <time datetime='%d'>%d</time>"
54 :html-postamble "
55 <p>Last build: %T</p>
56 <p>Created with %c</p>"
57 )
58
59 ("static"
60 :base-directory "~/Source/cleberg.net/static/"
61 :base-extension "css\\|txt\\|jpg\\|gif\\|png"
62 :recursive t
63 :publishing-directory "~/Source/cleberg.net/public/"
64 :publishing-function org-publish-attachment)
65
66 ("cleberg.net" :components ("blog" "static"))))
67#+end_src
68
69* TODO Build Process
70
71* TODO Deploy Process
build.sh added +3
@@ -0,0 +1,3 @@
1rm -rf .build/* && \
2ENV=prod emacs --script publish.el && \
3scp -r .build/* ubuntu:/var/www/cleberg.net/
blog/aes-encryption/index.org → content/blog/2018-11-28-aes-encryption.org renamed
blog/cpp-compiler/index.org → content/blog/2018-11-28-cpp-compiler.org renamed
blog/useful-css/index.org → content/blog/2019-01-07-useful-css.org renamed
blog/audit-analytics/index.org → content/blog/2019-09-09-audit-analytics.org renamed
blog/the-ansoff-matrix/index.org → content/blog/2019-12-03-the-ansoff-matrix.org renamed +10 −33
@@ -9,11 +9,11 @@ planning and strategy with a contemporary mindset. According to Dess,
99McNamara, Eisner, and Lee, managers must be willing to adapt to the
1010modern business environment by going beyond "'incremental management',
1111whereby they view their job as making a series of small, minor changes
12to improve the efficiency of the firm's operations"[fn:1].
12to improve the efficiency of the firm's operations"(2019).
1313
1414One reason that strategic management is crucial is because most
1515businesses that fail in the United States each year fail due to a lack
16of strategic focus or direction[fn:2]. The rate of failure for
16of strategic focus or direction(2019). The rate of failure for
1717businesses with poor strategies shows that strategic planning and
1818management are crucial to a business's strength and longevity, injecting
1919the critical factors of growth and direction into a company's business
@@ -25,7 +25,7 @@ that companies can use is the
2525this framework has unique purposes and use-cases, it can effectively
2626help an organization grow and compete. Specifically, the Ansoff matrix
2727is one of the most effective frameworks for companies who want to focus
28on increasing sales revenue or profitability[fn:3].
28on increasing sales revenue or profitability(2019).
2929
3030This framework uses a two-by-two figure to show the four strategic
3131options for companies to use in this framework: market penetration,
@@ -43,7 +43,7 @@ their existing products or explore new products.
4343** Market Penetration
4444The most straightforward strategy in the Ansoff matrix is to focus on
4545existing products in existing markets, also known as market
46penetration[fn:4]. Companies such as Coca-Cola have used market
46penetration(2019). Companies such as Coca-Cola have used market
4747penetration successfully by investing a lot of money to get further
4848value out of their current markets. Coca-Cola does this by introducing
4949new features such as Christmas-themed bottles, personal names on the
@@ -53,19 +53,19 @@ bottles, and other marketing schemes.
5353Market development extends existing products into new markets in an
5454attempt to increase the number of buyers. One interesting way that
5555Coca-Cola used this strategy comes from the stigma that Diet Coke is a
56woman's drink[fn:5]. Coca-Cola introduced Coca-Cola Zero, which
56woman's drink(2019). Coca-Cola introduced Coca-Cola Zero, which
5757contained the same nutritional content as Diet Coke, but was packaged in
58a dark black can to appear more "manly"[fn:6].
58a dark black can to appear more "manly"(2019).
5959
6060** Product Development
6161Product development uses existing markets to introduce new products so
62that the firm can better meet customer needs[fn:7]. The extreme end of
62that the firm can better meet customer needs(2019). The extreme end of
6363diversification is home to companies such as Johnson & Johnson, a
6464healthcare company that has developed a business portfolio of more than
6560,000 different products[fn:8]. Johnson & Johnson's dedication to
6560,000 different products(2019). Johnson & Johnson's dedication to
6666continuous diversification has led them to a balance sheet rating of
6767"AAA", industry recognition for diversification, and increases in their
68investor dividends for 57 consecutive years[fn:9].
68investor dividends for 57 consecutive years(2019).
6969
7070** Related Diversification
7171Diversification, the final strategy of the Ansoff Matrix, is more
@@ -73,7 +73,7 @@ difficult than the others since it involves exploring both new markets
7373and new products. Related diversification is a diversification strategy
7474that closely relates to the firm's core business. Coca-Cola's best
7575example of related diversification is its acquisition of Glaceau and
76Vitamin Water, which expanded their drinking lines of business[fn:10].
76Vitamin Water, which expanded their drinking lines of business(2019).
7777
7878** Unrelated Diversification
7979Unrelated diversification is a diversification strategy that does not
@@ -115,26 +115,3 @@ analysis]] to explain the mistake of companies who overuse analysis and
115115spend too much time planning. Companies need to understand the utility
116116of a strategic management framework while ensuring that the company is
117117poised to execute as efficiently as they have planned.
118
119* Footnotes
120
121[fn:1] Dess, G. G., McNamara, G., Eisner, A. B., Lee, S. H. (2019). Strategic management: Text & cases, ninth edition. New York, NY: McGraw-Hill Education.
122
123[fn:2] Juneja, P. (n.d.). Benefits of strategic management. Management Study Guide. Retrieved from [[https://www.managementstudyguide.com/strategic-management-benefits.htm]].
124
125[fn:3] Meldrum M., McDonald M. (1995) The Ansoff matrix. In: Key Marketing Concepts. London: Palgrave.
126
127[fn:4] Meldrum M., McDonald M. (1995) The Ansoff matrix. In: Key Marketing Concepts. London: Palgrave.
128
129[fn:5] Oakley, T. (2015). Coca-Cola: The Ansoff matrix. The Marketing Agenda. Retrieved from [[https://themarketingagenda.com/2015/03/28/coca-cola-ansoff-matrix/]].
130
131[fn:6] Oakley, T. (2015). Coca-Cola: The Ansoff matrix. The Marketing Agenda. Retrieved from [[https://themarketingagenda.com/2015/03/28/coca-cola-ansoff-matrix/]].
132
133[fn:7] Oakley, T. (2015). Coca-Cola: The Ansoff matrix. The Marketing Agenda. Retrieved from [[https://themarketingagenda.com/2015/03/28/coca-cola-ansoff-matrix/]].
134
135[fn:8] Lemke, T. (2019). The most diversified companies in the stock market. The balance. Retrieved from [[https://www.thebalance.com/the-most-diversified-companies-in-the-stock-market-4169730]].
136
137[fn:9] Johnson & Johnson. (2018). 2018 Investor Fact Sheet. [PDF file]. Retrieved from [[http://www.investor.jnj.com/_document/2018-investor-fact-sheet-4-19'id=0000016a-5681-d475-a17f-d78db54a0000][http://www.investor.jnj.com/_document/2018-investor-fact-sheet-4-19'id=0000016a-5681-d475-a17f-d78db54a0000]].
138
139[fn:10] Oakley, T. (2015). Coca-Cola: The Ansoff matrix. The Marketing Agenda. Retrieved from [[https://themarketingagenda.com/2015/03/28/coca-cola-ansoff-matrix/]].
140
blog/password-security/index.org → content/blog/2019-12-16-password-security.org renamed
blog/linux-software/index.org → content/blog/2020-01-25-linux-software.org renamed
blog/steam-on-ntfs/index.org → content/blog/2020-01-26-steam-on-ntfs.org renamed
blog/cryptography-basics/index.org → content/blog/2020-02-09-cryptography-basics.org renamed
blog/session-manager/index.org → content/blog/2020-03-25-session-manager.org renamed
blog/homelab/index.org → content/blog/2020-05-03-homelab.org renamed
blog/customizing-ubuntu/index.org → content/blog/2020-05-19-customizing-ubuntu.org renamed
blog/video-game-sales/index.org → content/blog/2020-07-20-video-game-sales.org renamed
blog/business-analysis/index.org → content/blog/2020-07-26-business-analysis.org renamed
blog/redirect-github-pages/index.org → content/blog/2020-08-22-redirect-github-pages.org renamed
blog/php-auth-flow/index.org → content/blog/2020-08-29-php-auth-flow.org renamed
blog/visual-recognition/index.org → content/blog/2020-09-01-visual-recognition.org renamed
blog/internal-audit/index.org → content/blog/2020-09-22-internal-audit.org renamed
blog/happiness-map/index.org → content/blog/2020-09-25-happiness-map.org renamed
blog/mediocrity/index.org → content/blog/2020-10-12-mediocrity.org renamed
blog/website-redesign/index.org → content/blog/2020-12-27-website-redesign.org renamed
blog/neon-drive/index.org → content/blog/2020-12-28-neon-drive.org renamed
blog/zork/index.org → content/blog/2020-12-29-zork.org renamed
blog/seum/index.org → content/blog/2021-01-01-seum.org renamed
blog/fediverse/index.org → content/blog/2021-01-04-fediverse.org renamed
blog/ufw/index.org → content/blog/2021-01-07-ufw.org renamed
blog/macos/index.org → content/blog/2021-02-19-macos.org renamed
blog/clone-github-repos/index.org → content/blog/2021-03-19-clone-github-repos.org renamed
blog/gemini-capsule/index.org → content/blog/2021-03-28-gemini-capsule.org renamed
blog/vaporwave-vs-outrun/index.org → content/blog/2021-03-28-vaporwave-vs-outrun.org renamed
blog/vps-web-server/index.org → content/blog/2021-03-30-vps-web-server.org renamed
blog/gemini-server/index.org → content/blog/2021-04-17-gemini-server.org renamed
blog/php-comment-system/index.org → content/blog/2021-04-23-php-comment-system.org renamed
blog/photography/index.org → content/blog/2021-04-28-photography.org renamed
blog/changing-git-authors/index.org → content/blog/2021-05-30-changing-git-authors.org renamed
blog/delete-gitlab-repos/index.org → content/blog/2021-07-15-delete-gitlab-repos.org renamed
blog/audit-sampling/index.org → content/blog/2021-08-25-audit-sampling.org renamed
blog/apache-redirect/index.org → content/blog/2021-10-09-apache-redirect.org renamed
blog/cisa/index.org → content/blog/2021-12-04-cisa.org renamed
blog/leaving-the-office/index.org → content/blog/2022-02-10-leaving-the-office.org renamed
blog/njalla-dns-api/index.org → content/blog/2022-02-10-njalla-dns-api.org renamed
blog/debian-and-nginx/index.org → content/blog/2022-02-16-debian-and-nginx.org renamed
blog/exiftool/index.org → content/blog/2022-02-17-exiftool.org renamed
blog/nginx-caching/index.org → content/blog/2022-02-20-nginx-caching.org renamed
blog/tuesday/index.org → content/blog/2022-02-22-tuesday.org renamed
blog/reliable-notes/index.org → content/blog/2022-03-02-reliable-notes.org renamed
blog/financial-database/index.org → content/blog/2022-03-03-financial-database.org renamed
blog/plex-migration/index.org → content/blog/2022-03-08-plex-migration.org renamed
blog/cloudflare-dns-api/index.org → content/blog/2022-03-23-cloudflare-dns-api.org renamed
blog/nextcloud-on-ubuntu/index.org → content/blog/2022-03-23-nextcloud-on-ubuntu.org renamed
blog/server-hardening/index.org → content/blog/2022-03-24-server-hardening.org renamed
blog/ssh-mfa/index.org → content/blog/2022-03-26-ssh-mfa.org renamed
blog/nginx-reverse-proxy/index.org → content/blog/2022-04-02-nginx-reverse-proxy.org renamed
blog/pinetime/index.org → content/blog/2022-04-09-pinetime.org renamed
blog/ditching-cloudflare/index.org → content/blog/2022-06-01-ditching-cloudflare.org renamed
blog/self-hosting-freshrss/index.org → content/blog/2022-06-07-self-hosting-freshrss.org renamed
blog/terminal-lifestyle/index.org → content/blog/2022-06-16-terminal-lifestyle.org renamed
blog/daily-poetry/index.org → content/blog/2022-06-22-daily-poetry.org renamed
blog/fedora-i3/index.org → content/blog/2022-06-24-fedora-i3.org renamed
blog/git-server/index.org → content/blog/2022-07-01-git-server.org renamed
blog/gnupg/index.org → content/blog/2022-07-14-gnupg.org renamed
blog/curseradio/index.org → content/blog/2022-07-25-curseradio.org renamed
blog/flac-to-opus/index.org → content/blog/2022-07-30-flac-to-opus.org renamed
blog/bash-it/index.org → content/blog/2022-07-31-bash-it.org renamed
blog/privacy-com-changes/index.org → content/blog/2022-08-31-privacy-com-changes.org renamed
blog/serenity-os/index.org → content/blog/2022-09-17-serenity-os.org renamed
blog/graphene-os/index.org → content/blog/2022-09-21-graphene-os.org renamed
blog/mtp-linux/index.org → content/blog/2022-10-04-mtp-linux.org renamed
blog/syncthing/index.org → content/blog/2022-10-04-syncthing.org renamed
blog/alpine-linux/index.org → content/blog/2022-10-22-alpine-linux.org renamed
blog/linux-display-manager/index.org → content/blog/2022-10-30-linux-display-manager.org renamed
blog/self-hosting-matrix/index.org → content/blog/2022-11-07-self-hosting-matrix.org renamed
blog/nginx-tmp-errors/index.org → content/blog/2022-11-11-nginx-tmp-errors.org renamed
blog/server-build/index.org → content/blog/2022-11-27-server-build.org renamed
blog/nginx-referrer-ban-list/index.org → content/blog/2022-11-29-nginx-referrer-ban-list.org renamed
blog/nginx-compression/index.org → content/blog/2022-12-01-nginx-compression.org renamed
blog/nginx-wildcard-redirect/index.org → content/blog/2022-12-07-nginx-wildcard-redirect.org renamed
blog/st/index.org → content/blog/2022-12-17-st.org renamed
blog/alpine-desktop/index.org → content/blog/2022-12-23-alpine-desktop.org renamed
blog/recent-website-changes/index.org → content/blog/2023-01-03-recent-website-changes.org renamed
blog/mass-unlike-tumblr-posts/index.org → content/blog/2023-01-05-mass-unlike-tumblr-posts.org renamed
blog/fedora-login-manager/index.org → content/blog/2023-01-08-fedora-login-manager.org renamed
blog/flatpak-symlinks/index.org → content/blog/2023-01-21-flatpak-symlinks.org renamed
blog/random-wireguard/index.org → content/blog/2023-01-23-random-wireguard.org renamed
blog/self-hosting-wger/index.org → content/blog/2023-01-28-self-hosting-wger.org renamed
blog/exploring-hare/index.org → content/blog/2023-02-02-exploring-hare.org renamed
blog/burnout/index.org → content/blog/2023-05-22-burnout.org renamed
blog/goaccess-geoip/index.org → content/blog/2023-06-08-goaccess-geoip.org renamed
blog/self-hosting-baikal/index.org → content/blog/2023-06-08-self-hosting-baikal.org renamed
blog/unifi-ip-blocklist/index.org → content/blog/2023-06-18-unifi-ip-blocklist.org renamed
blog/audit-review-template/index.org → content/blog/2023-06-20-audit-review-template.org renamed
blog/byobu/index.org → content/blog/2023-06-23-byobu.org renamed
blog/self-hosting-convos/index.org → content/blog/2023-06-23-self-hosting-convos.org renamed
blog/backblaze-b2/index.org → content/blog/2023-06-28-backblaze-b2.org renamed
blog/self-hosting-voyager/index.org → content/blog/2023-06-30-self-hosting-voyager.org renamed
blog/wireguard-lan/index.org → content/blog/2023-07-12-wireguard-lan.org renamed
blog/plex-transcoder-errors/index.org → content/blog/2023-07-19-plex-transcoder-errors.org renamed
blog/agile-auditing/index.org → content/blog/2023-08-18-agile-auditing.org renamed
blog/self-hosting-gitweb/index.org → content/blog/2023-09-15-self-hosting-gitweb.org renamed
blog/audit-sql-scripts/index.org → content/blog/2023-09-19-audit-sql-scripts.org renamed
blog/digital-minimalism/index.org → content/blog/2023-10-04-digital-minimalism.org renamed
blog/self-hosting-authelia/index.org → content/blog/2023-10-11-self-hosting-authelia.org renamed
blog/alpine-ssh-hardening/index.org → content/blog/2023-10-15-alpine-ssh-hardening.org renamed
blog/self-hosting-anonymousoverflow/index.org → content/blog/2023-10-17-self-hosting-anonymousoverflow.org renamed
blog/scli/index.org → content/blog/2023-11-08-scli.org renamed
blog/unifi-nextdns/index.org → content/blog/2023-12-03-unifi-nextdns.org renamed
blog/dont-say-hello/index.org → content/blog/2024-01-08-dont-say-hello.org renamed
blog/macos-customization/index.org → content/blog/2024-01-09-macos-customization.org renamed
blog/local-llm/index.org → content/blog/2024-01-13-local-llm.org renamed
blog/audit-dashboard/index.org → content/blog/2024-01-26-audit-dashboard.org renamed
blog/tableau-dashboard/index.org → content/blog/2024-01-27-tableau-dashboard.org renamed
blog/zfs/index.org → content/blog/2024-02-06-zfs.org renamed
blog/ubuntu-emergency-mode/index.org → content/blog/2024-02-13-ubuntu-emergency-mode.org renamed
blog/self-hosting-otter-wiki/index.org → content/blog/2024-02-21-self-hosting-otter-wiki.org renamed
content/blog/2024-03-13-doom-emacs.org added +354
@@ -0,0 +1,354 @@
1#+title: Doom Emacs & Org-Mode
2#+date: <2024-03-14 Thu 16:19:23>
3#+description: A quick look at my setup with Doom Emacs and the Org-Mode syntax.
4
5** Screenshots
6
7These screenshots are showing a project opened with projectile, a
8treemacs side pane open with the project contents, multiple buffers
9tiled next to each other, and the help pane open at the bottomm.
10
11The themes are =doom-homage-white= and =doom-homage-black=.
12
13#+caption: Doom Emacs Light Mode
14[[https://img.cleberg.net/blog/20240314-doom-emacs/light.png]]
15
16#+caption: Doom Emacs Dark Mode
17[[https://img.cleberg.net/blog/20240314-doom-emacs/dark.png]]
18
19** Getting Started
20
21I have been switching back and forth between
22[[https://en.wikipedia.org/wiki/Markdown][markdown]] and
23[[https://en.wikipedia.org/wiki/Org-mode][org-mode]] recently for my
24personal note taking, wiki, and even this blog. As a result, I have been
25stumbling further into the world of Emacs and found myself at a point
26where I now prefer to do most of my basic editing within Emacs.
27
28I'll leave the markdown vs. org-mode debate for another post, but I love
29org-mode's extensibility and interactive nature within Emacs, but it
30becomes very unwieldy in any other client implementation of org-mode -
31especially on iOS. On the flip side, markdown is limited in
32functionality and fractured into different standards, but it's simple
33and popular enough that there are a plethora of great clients to choose
34from that will get the job done.
35
36For now, I want to focus on how I have been using Emacs and some of the
37things that would have helped me learn it faster had I known where to
38start.
39
40*** Installation
41
42This post focuses on [[https://github.com/doomemacs/doomemacs][Doom
43Emacs]], which is an Emacs framework that provides an alternative
44experience to the vanilla [[https://www.gnu.org/software/emacs/][GNU
45Emacs]].
46
47The
48[[https://github.com/doomemacs/doomemacs/blob/master/docs/getting_started.org][Getting
49Start Guide]] has an extremely detailed walkthrough of installation for
50all systems, so please refer to that guide for up-to-date instructions.
51
52I chose to install on macOS, using the Homebrew option with the
53=railwaycat/emacsmacport= version of Emacs.
54
55Once the program is installed, you can run the program by typing =emacs=
56in a terminal. If you installed a version of Emacs that supports both a
57GUI and TUI, you will have to run =emacs -nw= to get the TUI instead of
58the default GUI.
59
60*** Configuration
61
62Once installed, you can configure Doom by editing the files within the
63=~/.doom.d/= directory. This directory holds four files:
64
651. =config.el= - Personal configuration file
662. =custom.el= - Custom set variables
673. =init.el= - Doom modules and load order, must run =doom sync= after
68 modifying
694. =packages.el= - Declare packages to install in this file, then run
70 =doom sync= to install
71
72I only needed a few customizations for my configuration, so I'll list
73them below.
74
75#+begin_src lisp
76;; ~/.doom.d/config.el
77(setq doom-theme 'doom-homage-black)
78(setq display-line-numbers-type t)
79(setq org-directory "~/Documents/Notes/")
80
81;; lengthy org-publish directives at the bottom of the file
82#+end_src
83
84#+begin_src lisp
85;; ~/.doom.d/init.el
86(doom! :input
87 :completion
88 company ; the ultimate code completion backend
89 vertico ; the search engine of the future
90
91 :ui
92 doom ; what makes DOOM look the way it does
93 doom-dashboard ; a nifty splash screen for Emacs
94 (emoji +unicode) ; 🙂
95 hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
96 minimap ; show a map of the code on the side
97 modeline ; snazzy, Atom-inspired modeline, plus API
98 ophints ; highlight the region an operation acts on
99 (popup +defaults) ; tame sudden yet inevitable temporary windows
100 tabs ; a tab bar for Emacs
101 treemacs ; a project drawer, like neotree but cooler
102 (vc-gutter +pretty) ; vcs diff in the fringe
103 vi-tilde-fringe ; fringe tildes to mark beyond EOB
104 workspaces ; tab emulation, persistence & separate workspaces
105
106 :editor
107 (evil +everywhere); come to the dark side, we have cookies
108 file-templates ; auto-snippets for empty files
109 fold ; (nigh) universal code folding
110 snippets ; my elves. They type so I don't have to
111
112 :emacs
113 dired ; making dired pretty [functional]
114 electric ; smarter, keyword-based electric-indent
115 undo ; persistent, smarter undo for your inevitable mistakes
116 vc ; version-control and Emacs, sitting in a tree
117
118 :term
119 term ; basic terminal emulator for Emacs
120
121 :checkers
122 syntax ; tasing you for every semicolon you forget
123
124 :tools
125 (eval +overlay) ; run code, run (also, repls)
126 lookup ; navigate your code and its documentation
127 magit ; a git porcelain for Emacs
128
129 :os
130 (:if (featurep :system 'macos) macos) ; improve compatibility with macOS
131
132 :lang
133 common-lisp ; if you've seen one lisp, you've seen them all
134 emacs-lisp ; drown in parentheses
135 markdown ; writing docs for people to ignore
136 org ; organize your plain life in plain text
137 python ; beautiful is better than ugly
138 sh ; she sells {ba,z,fi}sh shells on the C xor
139
140 :app
141 irc ; how neckbeards socialize
142 (rss +org) ; emacs as an RSS reader
143
144 (default +bindings +smartparens))
145#+end_src
146
147If you're editing these files within Doom directly, remember to run
148=SPC h r r= to reload the configuration. Also remember to run
149=doom sync= for any changes to the =init.el= or =packages.el= files.
150
151** Basic Functionality
152
153I kept a cheat sheet note open at first with all of the basic functions
154typed out, copied as I went through the tutorial. After a little while,
155I no longer needed it. I highly recommend writing down the most
156applicable shortcuts for your preferred functionality and refer back to
157it until you've memorized it.
158
159Memorizing the shortcuts will differ based on the type of Emacs
160framework being used. Personally, migrating from vanilla Emacs to Doom
161Emacs simplified everything by a large factor and instantly enabled me
162to start working on my projects, eliminating most of the hurdles I was
163running into. The vanilla emacs hotkeys became obnoxious and I actually
164stopped using Emacs entirely for about a month before trying Doom.
165
166For me, the first logical step is to interact with the local filesystem.
167To do this, I needed to know how to open directories, open files, save
168files, discard changes, close files, and switch between open files. Here
169are some example shortcuts I've written down in order to accomplish
170file-based actions.
171
172| Doom Hotkey | Emacs Hotkey | Description |
173|-----------------+--------------+----------------------------------------|
174| =SPC := | =C-x= | Run functions |
175| =SPC f f= | =C-x f= | Open file in buffer |
176| =SPC f d= | =C-x d= | Open directory with =dired= |
177| =i= | =C-x C-q= | Edit current buffer (insert mode) |
178| =q= | =C-x C-q= | Quit out of insert mode |
179| =SPC f s= | =C-x s= | Save current buffer |
180| =SPC b k= | =C-x k= | Kill current buffer |
181| =SPC w h/j/k/l= | =C-x o=[^1] | Move left/down/up/right to next buffer |
182
183[^1] Doom's evil-window functionality is a bit different from GNU Emacs,
184but you can always switch to the "other" buffer with =C-x o= or =C-x b=
185to get a list of buffers to select.
186
187In general, when in Doom, you can press =SPC= and wait a second for the
188help pane to appear with all available hotkey options. For example, you
189can press =SPC=, wait for the help pane, and then select a key such as
190=g= to enter the git help pane and explore further command options.
191
192** Editing
193
194Next in my process is to dive into editing for any languages I'm
195currently using. In this post, I will just cover Markdown and Org-Mode
196but I have also been slowly adoping some Python and general web dev
197tools as well.
198
199*** Markdown
200
201#+caption: Markdown Preview
202[[https://img.cleberg.net/blog/20240314-doom-emacs/markdown.png]]
203
204Markdown is fairly simple as the syntax is limited, so just make sure
205the =~/.doom.d/init.el= includes the =markdown= declaration in the
206=:lang= section.
207
208This package includes the following hotkey menus. The insert and toggle
209menu expands further, allowing you to insert various markdown elements
210and toggle things like link hiding.
211
212| Doom Hotkey | Function |
213|------------------------------+--------------------------|
214| =SPC m '= | markdown-edit-code-block |
215| =SPC m e= | markdown-export |
216| =SPC m i= | +insert |
217| =SPC m o= | markdown-open |
218| =SPC m p= | markdown-preview |
219| =SPC m t= | +toggle |
220| =SPC : markdown-table-align= | markdown-table-align |
221
222*** Org-Mode
223
224#+caption: Org-Mode Preview
225[[https://img.cleberg.net/blog/20240314-doom-emacs/org.png]]
226
227Similar to the markdown section above, ensure that the
228=~/.doom.d/init.el= includes the =org= declaration in the =:lang=
229section.
230
231There are a few hot keys, but a quick search with =SPC : org= shows that
232there are 865 possible org-related functions you can run. I won't
233possibly be able to list them all, so I will simply cover a few of the
234basic commands I use myself.
235
236| Doom Hotkey | Function |
237|----------------+---------------------------------------|
238| =SPC m t= | org-todo |
239| =SPC n t= | org-todo-list |
240| =SPC o A= | org-agenda |
241| =SPC X= | org-capture |
242| =SPC m p p= | org-priority |
243| =SPC m d s= | org-schedule |
244| =TAB= | org-cycle |
245| =SHIFT TAB= | Collapse/open all headings in buffer |
246| =M-q= | Format/wrap current section |
247| =M-Left/Right= | Demote/promote current heading |
248| =M-Down/Up= | Shift current heading section down/up |
249
250**** Org-Publish
251
252Org includes a [[https://orgmode.org/manual/Publishing.html][publishing
253management system]] by default that allows you to export org files to
254Org, iCalendar, HTML, LaTex, Markdown, ODT, and Plain Text. Most of
255these can be exported into another buffer and opened, or simply to an
256external file.
257
258While inside an org file, simply run =SPC m e= or
259=M-x org-export-dispatch= to open the export menu. This menu will show
260all options and ask you to select an option. If you want to export to
261HTML, simply press =h= and then =H= (As HTML buffer), =h= (As HTML
262file), or =o= (As HTML file and open).
263
264**** Projects
265
266Some publishing options are easier with a defined project in Emacs. To
267create a project within Emacs, I use two methods:
268
2691. Add the project via the projectile command =SPC p a=. Does not always
270 work for me.
2712. Add an empty =.projectile= file in the project root.
272
273Once a project has been created, you can create custom publishing
274actions within your =~/.doom.d/config.el= file. For example, here's a
275test project I created to try and convert this blog to org-mode
276recently.
277
278#+begin_src lisp
279;; org-publish
280(require 'ox-publish)
281
282(defun my/org-sitemap-date-entry-format (entry style project) "Format ENTRY in
283 org-publish PROJECT Sitemap format ENTRY ENTRY STYLE format that includes
284 date." (let ((filename (org-publish-find-title entry project))) (if (= (length
285 filename) 0) (format "*%s*" entry) (format "{{{timestamp(%s)}}}
286 [[file:%s][%s]]" (format-time-string "%Y-%m-%d" (org-publish-find-date entry
287 project)) entry filename))))
288
289(setq org-export-global-macros '(("timestamp" . "@@html:<time datetime='[$1]'
290 class='timestamp'>[$1]</time>@@")))
291
292(setq org-publish-project-alist
293 `(("blog"
294 :base-directory "~/Source/cleberg.net/"
295 :base-extension "org"
296 :recursive t
297 :publishing-directory "~/Source/cleberg.net/public/"
298 :publishing-function org-html-publish-to-html
299 ;; HTML5
300 :html-doctype "html5"
301 :html-html5-fancy t
302 ;; Disable some Org's HTML defaults
303 :html-head-include-scripts nil
304 :html-head-include-default-style nil
305 :section-numbers nil
306 :with-title nil
307 ;; Sitemap
308 :auto-sitemap t
309 :sitemap-title: "Sitemap"
310 :sitemap-sort-files anti-chronologically
311 ; :sitemap-function my/org-sitemap-date-entry-format
312 ;; Customize HTML output
313 :html-divs ((preamble "header" "preamble")
314 (content "main" "content")
315 (postamble "footer" "postamble"))
316 :html-head "<meta name='theme-color' content='#111' media='(prefers-color-scheme: dark)'>
317 <meta name='theme-color' content='#fff' media='(prefers-color-scheme: light)'>
318 <link rel='stylesheet' href='/syntax-theme-dark.css' media='(prefers-color-scheme: dark)'>
319 <link rel='stylesheet' href='/syntax-theme-light.css' media='(prefers-color-scheme: light)'>
320 <link rel='stylesheet' href='/styles.css' type='text/css'>"
321 :html-preamble "<nav class='site-nav' aria-label='site-nav' role='navigation'>
322 <ul>
323 <li><a href='/'>Home</a></li>
324 <li><a href='/blog/'>Blog</a></li>
325 <li><a href='/services/'>Services</a></li>
326 <li><a href='/wiki/'>Wiki</a></li>
327 </ul></nav>
328 <h1>%t</h1>
329 <time datetime='%d'>%d</time>"
330 :html-postamble "
331 <p>Last build: %T</p>
332 <p>Created with %c</p>"
333 )
334
335 ("static"
336 :base-directory "~/Source/cleberg.net/static/"
337 :base-extension "css\\|txt\\|jpg\\|gif\\|png"
338 :recursive t
339 :publishing-directory "~/Source/cleberg.net/public/"
340 :publishing-function org-publish-attachment)
341
342 ("cleberg.net" :components ("blog" "static"))))
343#+end_src
344
345** General Thoughts
346
347I have enjoyed Doom Emacs (far more than GNU Emacs) and will likely
348continue to use it as my main editor for the time being. Org-Mode is
349certainly the largest factor here, as I far prefer it over Markdown due
350to its inherent features and detailed markup options. However, working
351with org-mode on iOS has been a pain and I will have to see if there's
352an easier way to resolve those issues or if going back to separate
353Markdown, Reminders, and Calendar apps is easier to work with than an
354all-in-one org solution.
content/blog/2024-03-15-self-hosting-ddns-updater.org added +314
@@ -0,0 +1,314 @@
1#+title: Self-Hosting DDNS Updater
2#+date: <2024-03-15 Fri 14:49:59>
3#+description: A guide to self-hosting the DDNS Updater container.
4
5#+caption: DDNS Updater Web View
6[[https://img.cleberg.net/blog/20240315-ddns-updater/ddns.png]]
7
8[[https://github.com/qdm12/ddns-updater][DDNS Updater]] is a program to
9keep DNS A and/or AAAA records updated for multiple DNS providers.
10
11If you've read any of my other posts, you'll notice that I have been
12searching for and using a few different DDNS updating solutions for
13years. You'll also notice that I love any projects that offer a Docker
14Compose solution.
15
16Luckily, DDNS Upater fits both of these preferences.
17
18** Installation
19
20To get started, always make sure to review the project's
21[[https://github.com/qdm12/ddns-updater/blob/master/README.md][README]].
22I'll be documenting my steps below, but they may have changed by the
23time you read this.
24
25The first step is to set up the directories and files required for the
26project.
27
28#+begin_src sh
29mkdir ~/ddns-updater
30mkdir ~/ddns-updater/data
31touch ~/ddns-updater/data/config.json
32#+end_src
33
34*** Configuration
35
36The main configuration you need to update is the =data/config.json=
37file. There is a large list of supported providers in the README, but
38I'm going to use Cloudflare in this example.
39
40#+begin_src sh
41nano ~/ddns-updater/data/config.json
42#+end_src
43
44When setting up the configuration for Cloudflare, you'll need the
45following:
46
47- Required Parameters
48 - ="zone_identifier"= is the Zone ID of your site from the domain
49 overview page
50 - ="host"= is your host and can be ="@"=, a subdomain or the wildcard
51 ="*"=. See
52 [[https://github.com/qdm12/ddns-updater/issues/243#issuecomment-928313949][this
53 issue comment for context]].
54 - ="ttl"= integer value for record TTL in seconds (specify 1 for
55 automatic)
56 - One of the following
57 ([[https://developers.cloudflare.com/fundamentals/api/get-started/][how
58 to find API keys]]):
59 - Email ="email"= and Global API Key ="key"=
60 - User service key ="user_service_key"=
61 - API Token ="token"=, configured with DNS edit permissions for your
62 DNS name's zone
63- Optional Parameters
64 - ="proxied"= can be set to =true= to use the proxy services of
65 Cloudflare
66 - ="ip_version"= can be =ipv4= (A records), or =ipv6= (AAAA records)
67 or =ipv4 or ipv6= (update one of the two, depending on the public
68 ip found). It defaults to =ipv4 or ipv6=.
69 - ="ipv6_suffix"= is the IPv6 interface identifier suffix to use. It
70 can be for example =0:0:0:0:72ad:8fbb:a54e:bedd/64=. If left empty,
71 it defaults to no suffix and the raw public IPv6 address obtained is
72 used in the record updating.
73
74#+begin_src conf
75{
76 "settings": [
77 {
78 "provider": "cloudflare",
79 "zone_identifier": "some id",
80 "domain": "domain.com",
81 "host": "@",
82 "ttl": 1,
83 "proxied": true,
84 "token": "yourtoken",
85 "ip_version": "ipv4",
86 "ipv6_suffix": ""
87 }
88 ]
89}
90#+end_src
91
92Once you have configured the provider of your choice, correct the file
93and directory permissions and ownership.
94
95#+begin_src sh
96cd ~/ddns_updater
97# Owned by user ID of Docker container (1000)
98chown -R 1000 data
99# all access (for creating json database file data/updates.json)
100chmod 700 data
101# read access only
102chmod 400 data/config.json
103#+end_src
104
105*** Docker Compose
106
107After creating the project structure, let's create the
108=docker-compose.yml= file.
109
110#+begin_src sh
111nano ~/ddns_-pdater/docker-compose.yml
112#+end_src
113
114#+begin_src config
115version: "3.7"
116services:
117 ddns-updater:
118 image: qmcgaw/ddns-updater
119 container_name: ddns-updater
120 network_mode: bridge
121 ports:
122 - 8097:8000/tcp # Change the 8097 value to whichever port you want to use
123 volumes:
124 - ./data:/updater/data
125 environment:
126 - CONFIG=
127 - PERIOD=5m
128 - UPDATE_COOLDOWN_PERIOD=5m
129 - PUBLICIP_FETCHERS=all
130 - PUBLICIP_HTTP_PROVIDERS=all
131 - PUBLICIPV4_HTTP_PROVIDERS=all
132 - PUBLICIPV6_HTTP_PROVIDERS=all
133 - PUBLICIP_DNS_PROVIDERS=all
134 - PUBLICIP_DNS_TIMEOUT=3s
135 - HTTP_TIMEOUT=10s
136
137 # Web UI
138 - LISTENING_ADDRESS=:8000
139 - ROOT_URL=/
140
141 # Backup
142 - BACKUP_PERIOD=0 # 0 to disable
143 - BACKUP_DIRECTORY=/updater/data
144
145 # Other
146 - LOG_LEVEL=info
147 - LOG_CALLER=hidden
148 - SHOUTRRR_ADDRESSES=
149 restart: always
150#+end_src
151
152After configuring your preferences in the =docker-compose.yml=, launch
153the container.
154
155#+begin_src sh
156cd ~/ddns-updater
157sudo docker-compose up -d
158#+end_src
159
160If you've launched this on your local machine, you can launch
161=localhost:8097= in your browser to see the results.
162
163*** Nginx Reverse Proxy
164
165If you launched this service on a server, other machine, or just want to
166access it remotely via a domain name, you can use Nginx as a reverse
167proxy to expose the service publicly.
168
169Start by creating the Nginx configuration file.
170
171#+begin_src sh
172sudo nano /etc/nginx/sites-available/ddns
173#+end_src
174
175Here's a basic example that should work properly.
176
177#+begin_src conf
178server {
179 # If using 443, remember to include your ssl_certificate
180 # and ssl_certificate_key
181 listen [::]:80;
182 listen 80;
183 server_name ddns.example.com;
184
185 location / {
186 set $upstream_ao http://127.0.0.1:9380;
187 proxy_pass $upstream_ao;
188
189 # May need some additional proxy_* parameters,
190 # see the full example below if necessary
191 }
192}
193#+end_src
194
195Here's a full example that uses my Authelia authentication service to
196require authentication before someone can access the web page.
197
198#+begin_src conf
199server {
200 if ($host ~ ^[^.]+\.example\.com$) {
201 return 301 https://$host$request_uri;
202 }
203
204 listen [::]:80;
205 listen 80;
206 server_name ddns.example.com;
207 return 404;
208}
209
210server {
211 listen [::]:443 ssl http2;
212 listen 443 ssl http2;
213 server_name ddns.example.com;
214 access_log /var/log/nginx/ddns.access.log;
215 error_log /var/log/nginx/ddns.error.log;
216
217 add_header X-Content-Type-Options "nosniff";
218 add_header X-XSS-Protection "1; mode=block";
219 add_header X-Frame-Options "DENY";
220 add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
221 add_header Referrer-Policy "no-referrer";
222
223 ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
224 ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
225 include /etc/letsencrypt/options-ssl-nginx.conf;
226 ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
227
228 location /authelia {
229 internal;
230 set $upstream_authelia http://127.0.0.1:9091/api/verify; #change the IP and Port to match the IP and Port of your Authelia container
231 proxy_pass_request_body off;
232 proxy_pass $upstream_authelia;
233 proxy_set_header Content-Length "";
234
235 # Timeout if the real server is dead
236 proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
237 client_body_buffer_size 128k;
238 proxy_set_header Host $host;
239 proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
240 proxy_set_header X-Real-IP $remote_addr;
241 proxy_set_header X-Forwarded-For $remote_addr;
242 proxy_set_header X-Forwarded-Proto $scheme;
243 proxy_set_header X-Forwarded-Host $http_host;
244 proxy_set_header X-Forwarded-Uri $request_uri;
245 proxy_set_header X-Forwarded-Ssl on;
246 proxy_redirect http:// $scheme://;
247 proxy_http_version 1.1;
248 proxy_set_header Connection "";
249 proxy_cache_bypass $cookie_session;
250 proxy_no_cache $cookie_session;
251 proxy_buffers 4 32k;
252
253 send_timeout 5m;
254 proxy_read_timeout 240;
255 proxy_send_timeout 240;
256 proxy_connect_timeout 240;
257 }
258
259 location / {
260 set $upstream_ddns http://127.0.0.1:8097; #change ddns to match your container name: $upstream_some-container-name or $upstream_somecontainername
261 proxy_pass $upstream_ddns; #change ddns to match your container name: $upstream_some-container-name or $upstream_somecontainername
262
263 auth_request /authelia;
264 auth_request_set $target_url https://$http_host$request_uri;
265 auth_request_set $user $upstream_http_remote_user;
266 auth_request_set $email $upstream_http_remote_email;
267 auth_request_set $groups $upstream_http_remote_groups;
268 proxy_set_header Remote-User $user;
269 proxy_set_header Remote-Email $email;
270 proxy_set_header Remote-Groups $groups;
271
272 error_page 401 =302 https://auth.example.com/?rd=$target_url; #change this to match your authentication domain/subdomain
273
274 client_body_buffer_size 128k;
275
276 proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
277
278 send_timeout 5m;
279 proxy_read_timeout 360;
280 proxy_send_timeout 360;
281 proxy_connect_timeout 360;
282
283 proxy_set_header Host $host;
284 proxy_set_header Upgrade $http_upgrade;
285 proxy_set_header Connection upgrade;
286 proxy_set_header Accept-Encoding gzip;
287 proxy_set_header X-Real-IP $remote_addr;
288 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
289 proxy_set_header X-Forwarded-Proto $scheme;
290 proxy_set_header X-Forwarded-Host $http_host;
291 proxy_set_header X-Forwarded-Uri $request_uri;
292 proxy_set_header X-Forwarded-Ssl on;
293 proxy_redirect http:// $scheme://;
294 proxy_http_version 1.1;
295 proxy_set_header Connection "";
296 proxy_cache_bypass $cookie_session;
297 proxy_no_cache $cookie_session;
298 proxy_buffers 64 256k;
299
300 # set_real_ip_from 192.168.1.0/16; #make sure this matches your network setup
301 # real_ip_header CF-Connecting-IP;
302 # real_ip_recursive on;
303 }
304}
305#+end_src
306
307When complete, simply link the file and restart the web server.
308
309#+begin_src sh
310sudo ln -s /etc/nginx/sites-available/ddns /etc/nginx/sites-enabled/ddns
311sudo systemctl restart nginx.service
312#+end_src
313
314Your ddns-updater service will now be available via =ddns.example.com=!
content/blog/2024-03-29-org-blog.org added +43
@@ -0,0 +1,43 @@
1#+title: Blogging in Org-Mode
2#+date: 2024-03-29
3#+description: A guide to blogging with org-mode, no third-party tools required.
4#+filetags: :dev:
5#+draft: t
6#+slug: org-blog
7
8Refer to the post I wrote about [[/blog/doom-emacs-org-mode.html][Doom Emacs & Org-Mode]] for more information about
9my base Emacs configuration.
10
11* TODO Weblorg
12
13[[https://github.com/emacs-love/weblorg][Weblorg]] is a static site generator for [[https://orgmode.org/][org-mode]], built for use within [[https://www.gnu.org/software/emacs/][Emacs]].
14
15** Installation
16
17macOS, use Doom's package installation process, link proper files in =publish.el=
18
19** Configuration
20
21* Project
22
23** TODO Structure
24
25** TODO Configuration
26
27** TODO Build & Deploy
28
29#+begin_src sh
30touch build.sh && chmod +x build.sh && nano build.sh
31#+end_src
32
33#+begin_src sh
34rm -rf .build/* && \
35ENV=prod emacs --script publish.el && \
36scp -r .build/* ubuntu:/var/www/cleberg.net/
37#+end_src
38
39#+begin_src sh
40> time ./build.sh
41
42./build.sh 35.46s user 0.59s system 85% cpu 41.965 total
43#+end_src
content/index.org added +2
@@ -0,0 +1,2 @@
1#+title: cleberg.net
2#+description: Just a blip of ones and zeroes.
salary/index.org → content/salary/index.org renamed +8 −4
@@ -1,5 +1,6 @@
11#+title: Salary
22#+description: A historical log of my jobs and salaries.
3#+slug: index
34
45* Salary Transparency
56
@@ -30,8 +31,7 @@ raise while in the same role.
3031
3132| Title | Company | Location | Start | End | Salary |
3233|------------------------------------------------+------------------------+----------------+---------+---------+----------|
33| Senior IT & Security Auditor | Gemini | Remote | 2024-03 | Current | $122,000 |
34| Senior Associate, Technology Assurance - Audit | KPMG | Omaha, NE | 2023-10 | 2024-03 | $116,700 |
34| Senior Associate, Technology Assurance - Audit | KPMG | Omaha, NE | 2023-10 | Current | $116,700 |
3535| Senior Associate, Technology Assurance - Audit | KPMG | Omaha, NE | 2022-06 | 2023-10 | $110,000 |
3636| Senior Technology Risk Consultant | Ernst & Young | Des Moines, IA | 2021-09 | 2022-06 | $89,500 |
3737| Senior IT Auditor | Ameritas | Lincoln, NE | 2021-05 | 2021-09 | $72,000 |
@@ -42,9 +42,13 @@ raise while in the same role.
4242| Teaching Assistant | University of Nebraska | Lincoln, NE | 2017-08 | 2018-05 | $7/hour |
4343| Community Management Intern | Walgreens | Lincoln, NE | 2017-06 | 2018-02 | $14/hour |
4444
45This page was inspired by [[https://xeiaso.net/][Xe]], and I'm quoting the following wording from them as
45This page was inspired by [[https://xeiaso.net/salary-transparency/][Xe]], and I'm quoting the following wording from them as
4646I want to reiterate this piece:
4747
4848#+begin_quote
49Please consider publishing your salary data like this as well. By open, voluntary transparency we can help to end stigmas around discussing pay and help ensure that the next generations of people in tech are treated fairly. Stigmas thrive in darkness but die in the light of day. You can help end the stigma by playing your cards out in the open like this.
49Please consider publishing your salary data like this as well. By open,
50voluntary transparency we can help to end stigmas around discussing pay and help
51ensure that the next generations of people in tech are treated fairly. Stigmas
52thrive in darkness but die in the light of day. You can help end the stigma by
53playing your cards out in the open like this.
5054#+end_quote
services/index.org → content/services/index.org renamed +2
@@ -1,5 +1,6 @@
11#+title: Services
22#+description: Publicly-available services hosted on cleberg.net.
3#+slug: index
34
45- [[https://ao.cleberg.net/][AnonymousOverflow]] - A StackOverflow proxy
56- [[https://cyberchef.cleberg.net/][CyberChef]] - The Cyber Swiss Army Knife
@@ -9,6 +10,7 @@
910- [[https://ip.cleberg.net/][ifconfig.php]] - A "whatsmyip" tool
1011- [[https://invidious.cleberg.net/][Invidious]] - A YouTube proxy
1112- [[https://office.cleberg.net/][Office]] - The world's smallest office suite
13- [[https://org.cleberg.net/][Org-Live]] - A basic org-mode editor for the web I built
1214- [[https://search.cleberg.net/][SearXNG]] - A privacy-respecting, open metasearch engine
1315
1416See the [[https://git.cleberg.net/cleberg.net.git/log][git log]] if you want to see changes that have been made.
content/wiki/blogroll.org added +32
@@ -0,0 +1,32 @@
1#+title: Blogroll
2#+date: <2024-03-15 Fri 21:50>
3
4** Aggregators
5
6- [[https://1mb.club/][1MB Club]]
7- [[https://250kb.club/][250KB Club]]
8- [[https://512kb.club/][512KB Club]]
9- [[https://darktheme.club/][Darktheme Club]]
10- [[https://nocss.club/][No CSS Club]]
11- [[https://no-js.club/][No-JS Club]]
12- [[https://blogroll.org/][Ye Olde Blogroll]]
13
14** Plain Text
15
16A list of various plaintext websites and lists.
17
18- [[https://greycoder.com/a-list-of-text-only-new-sites/][A List Of
19 Text-Only & Minimalist News Sites]]
20- [[https://harvardlawreview.org/][Harvard Law Review]]
21- [[https://sjmulder.nl/en/textonly.html][Hyperlinked Text]]
22- [[https://medium.com/@letsworkshop/plain-text-web-design-a78ccaf9dbc0][Plain-text
23 web design]]
24- [[https://plaintextworld.com/][Plaintext World]]
25- [[https://justinjackson.ca/words.html][Words]]
26
27** Webrings
28
29Instead of listing my personal favorites, I'm just going to drop a link
30to [[https://brisray.com/web/webring-list.htm][brisay's webring list]],
31which contains 237 webrings for a total of 7078 websites, as of
322024-03-15.
content/wiki/hardware.org added +114
@@ -0,0 +1,114 @@
1#+title: Hardware
2#+date: <2024-03-16 Sat 15:42:58>
3
4** Desktop
5
6*** macOS
7
8Probably should have added more RAM but Macbooks are stupid expensive.
9
10| Category | Details |
11|----------+---------------------------------------------------------|
12| Model | [[https://www.apple.com/macbook-pro/][Macbook Pro 16”]] |
13| CPU | Apple M2 Pro |
14| RAM | 16GB |
15| Storage | 512GB SSD |
16
17*** Linux
18
19A beauty.
20
21| Category | Details |
22|----------+----------------------------------------------------------------------------------------------------------------------------------------------------------|
23| Model | [[https://www.lenovo.com/us/en/p/laptops/thinkpad/thinkpade/thinkpad--e15-gen-4-(15-inch-amd)/len101t0023][Lenovo ThinkPad E15 Gen 4, model 21ED0048US]] |
24| CPU | AMD Ryzen 5 5625U with Radeon Graphics |
25| RAM | 16 GB |
26| Storage | 256 GB SSD |
27
28** Mobile
29
30Previously used a Pixel 6 & Pixel 7 with GrapheneOS.
31
32| Category | Details |
33|----------+-------------------------------------------------------------|
34| Model | [[https://www.apple.com/iphone-15-pro/][iPhone 15 Pro Max]] |
35| CPU | A17 Pro |
36| RAM | 8GB |
37| Storage | 256GB |
38
39** Homelab
40
41I run a small homelab with a mix of consumer (compute/storage) and
42enterprise (network) hardware. I try to keep the lab energy efficient
43and quiet as my top priorities.
44
45*** IoT
46
47A collection of mainly smart lights, sensors, and smart appliances. My
48first preference is to disable all networking for new smart devices or
49simply not connect internet in the first place (e.g. I never enable
50internet on my smart TVs). If the smart device requires LAN access, I
51will connect the device to my guest-restricted IoT network. As a last
52resort, I will set-up the internet but monitor the DNS lookups via
53NextDNS and forcibly block any domains I do not want the device to be
54using. If the device is egregious or shady, I'll just sell it and either
55replace it or live without it.
56
57- Other Appliances (washer, dryer, humidifier, fans, etc.)
58- [[https://about.irobot.com/sitecore/content/north-america/irobot-us/home/roomba/i7-series][Roomba
59 i7+]]
60- [[https://www.philips-hue.com/en-us/p/hue-white-and-color-ambiance-a19---e26-smart-bulb---60-w--3-pack-/046677562786][Philips
61 Hue A19 Bulbs]] x 15
62- [[https://www.philips-hue.com/en-us/p/hue-bundle-play-blk-ext/33001][Philips
63 Hue Play Light Bars]]
64- [[https://www.philips-hue.com/en-us/p/hue-bridge/046677458478][Philips
65 Hue Smart Bridge]] + play light bars and a ton of bulbs
66- [[https://store.ui.com/us/en/collections/unifi-camera-security-special-chime][UP
67 Chime]]
68- [[https://store.ui.com/us/en/collections/unifi-camera-security-special-sensor][UP-Sense]]
69 x 2
70- [[https://store.ui.com/us/en/products/unifi-smart-power][USP-Plug]]
71- [[https://store.ui.com/us/en/collections/unifi-camera-security-compact-wifi-connected][UVC
72 G4 Instant]] x 3
73- [[https://store.ui.com/us/en/collections/unifi-camera-security-special-wifi-doorbell][UVC
74 G4 Doorbell Pro]]
75
76*** Network
77
78A rack-mounted Dream Machine Pro, connected downstream to an access
79point, mesh extender, and a couple ethernet switches.
80
81- [[https://store.ui.com/us/en/collections/unifi-dream-machine/products/udm-pro][UDM-Pro]]
82- [[https://store.ui.com/us/en/collections/unifi-switching-standard-power-over-ethernet/products/usw-24-poe][USW-24-PoE]]
83- [[https://store.ui.com/us/en/collections/unifi-switching-utility-poe/products/usw-lite-8-poe][USW-Lite-8-PoE]]
84- [[https://store.ui.com/us/en/collections/unifi-wifi-flagship-high-capacity/products/u6-pro][U6-Pro]]
85- [[https://store.ui.com/us/en/collections/unifi-wifi-inwall-outlet-mesh][U6-Extender]]
86- [[https://store.ui.com/us/en/collections/unifi-accessory-tech-installations-rackmount/products/uacc-rack-panel-patch-blank-24][USW
87 24-Port Patch Panel]]
88
89*** Servers
90
91**** Rack-Mount Server
92
93I wasn't happy with using low-powered PCs as servers and I knew I did
94not want the ear-shattering enterprise rack-mounted servers, so I built
95my own.
96
97| Category | Details |
98|--------------------+----------------------------------------|
99| Case | Rosewill RSV-R4100U 4U |
100| Motherboard | NZXT B550 |
101| CPU | AMD Ryzen 7 5700G with Radeon Graphics |
102| RAM | 64GB RAM (2x32GB) |
103| Storage (On-board) | Western Digital 500GB M.2 NVME SSD |
104| Storage (HDD Bay) | 48TB HDD |
105| PSU | Corsair RM850 PSU |
106
107**** Other
108
109These ran as my main servers before I built the rack-mounted server
110above. I have shut these down indefinitely for now as I have no use for
111them.
112
113- Dell OptiPlex
114- Raspberry Pi 4
content/wiki/ios.org added +198
@@ -0,0 +1,198 @@
1#+title: iOS
2#+date: <2024-03-13 Wed 00:00:00>
3
4Related:
5
6- [[/wiki/hardware.html][Hardware]]
7
8My primary mobile OS. Currently running iOS 17. This wiki page contains
9most of the apps I have used at one point or another across my different
10iPhones.
11
12[=*=] = My favorites
13
14** Configuration
15
16*** Display
17
18- Light Mode
19 - 10:00 to 16:00
20- Dark Mode
21 - 16:00 to 10:00
22
23*** Focus Modes
24
25- Personal Focus
26 - 06:00 to 21:00
27 - Allow Notifications From:
28 - Alarms
29 - Calendar
30 - Contacts (1 person)
31 - Messages
32 - Phone
33 - Reminders
34 - Signal
35 - UniFi Protect
36- Sleep Focus
37 - 21:00 to 06:00
38 - Allow Notifications From:
39 - Alarms
40 - Contacts (1 person)
41 - Reminders
42 - Signal
43
44*** Privacy & Security
45
46I generally follow the
47[[https://en.wikipedia.org/wiki/Principle_of_least_privilege][principle
48of least privilege]] by only permitting the bare minimum privileges and
49revoking as soon as they are no longer required.
50
51Here's the baseline I start with:
52
53- Disable:
54 - Analytics & Improvements
55 - Apple Advertising
56 - Apple ID > Sign-In & Security > Two-Factor Authentication
57 - Location Services > System Services > Product Improvement
58 - Tracking > Allow Apps to Request to Track
59 - Safari > Advanced > Privacy Preserving Ad Measurement
60- Enable:
61 - Apple ID > iCloud > Advanced Data Protection
62 - Apple ID > Personal Information > Communication Preferences
63 - App Privacy Report
64 - Location Services only for Camera, Find My, UDisc, & WiFiman
65 (=While Using=)
66 - Safari > Prevent Cross-Site Tracking
67 - Safari > Hide IP Address
68 - Safari > Advanced > Advanced Tracking and Fingerprinting Protection
69
70** Native Apps
71
72*** Business
73
74- [[https://apps.apple.com/us/app/element-messenger/id1083446067][Element]] -
75 A cross-platform messenger, based on Matrix
76- [[https://apps.apple.com/us/app/linkedin-network-job-finder/id288429040][LinkedIn]] -
77 One of the only social media apps I use
78
79*** Developer Tools
80
81- [[https://testflight.apple.com/join/F2vK7xo4][Harbour]] - Easily
82 manage your Portainer service
83- [[https://apps.apple.com/us/app/ish-shell/id1436902243][iSH]] - A
84 local shell with SSH functionality
85
86*** Entertainment
87
88- [[https://apps.apple.com/us/app/plex-watch-live-tv-and-movies/id383457673][Plex]] -
89 A client for the Plex Media Server
90- [[https://apps.apple.com/us/app/steam-mobile/id495369748][Steam]] -
91 The top gaming marketplace for computers
92
93*** Lifestyle
94
95- [[https://apps.apple.com/us/app/home/id1110145103][Home]] [=*=] -
96 Apple homekit powered smart home manager
97- [[https://apps.apple.com/us/app/philips-hue/id1055281310][Hue]] -
98 Philips Hue smart home manager
99- [[https://apps.apple.com/us/app/irobot-home/id1012014442][iRobot]] -
100 Manage iRobot Roomba devices
101- [[https://apps.apple.com/us/app/unifi-protect/id1392492235][UniFi
102 Protect]] - View and manage most UniFi Protect cameras and settings
103
104*** Music
105
106- [[https://apps.apple.com/us/app/apple-music/id1108187390][Apple
107 Music]] [=*=] - Apple's native music streaming app
108- [[https://apps.apple.com/us/app/plexamp/id1500797510][Plexamp]]
109 [=*=] - Top-notch music app for your Plex Media Server, with a neural
110 network that provides excellent radio/shuffle suggestions
111
112*** News
113
114- [[https://apps.apple.com/us/app/netnewswire-rss-reader/id1480640210][NetNewsWire]] -
115 A free and open source RSS reader for Mac, iPhone, and iPad
116
117*** Photo & Video
118
119- [[https://testflight.apple.com/join/Q6WyyEpS][Aislingeach]] - A quick
120 way to generate and rate images from the Stable Horde
121- [[https://apps.apple.com/us/app/unsplash/id1290631746][Unsplash]] -
122 Premium images, mostly free
123
124*** Productivity
125
126- [[https://apps.apple.com/us/app/beorg-to-do-list-agenda/id1238649962][beorg]] -
127 An org-mode editor, outline, and scheduler with paid extensions
128- [[https://apps.apple.com/us/app/bitwarden-password-manager/id1137397744][Bitwarden]]
129 [=*=] - An open source password manager
130- [[https://apps.apple.com/us/app/cryptomator/id1560822163][Cryptomator]] -
131 A cross-platform encryption program
132- [[https://apps.apple.com/us/app/obsidian-connected-notes/id1557175442][Obsidian]]
133 [=*=] - A nice Markdown-based editor based on a "vault" structure.
134 Offers a paid sync solution and community extensions
135- [[https://apps.apple.com/us/app/strongbox-password-manager/id897283731][Strongbox]] -
136 Keepass password manager for iOS & macOS
137- [[https://apps.apple.com/us/app/unifi/id1057750338][UniFi Network]] -
138 View and manage most UniFi Network settings
139
140*** Safari Extensions
141
142- [[https://apps.apple.com/us/app/adguard-adblock-privacy/id1047223162][AdGuard]] -
143 Ad blocker
144- [[https://apps.apple.com/us/app/dark-reader-for-safari/id1438243180][Dark
145 Reader]] - Dark mode for all the sites
146- [[https://apps.apple.com/us/app/pipifier/id1234771095][PiPifier]] -
147 Force videos to support PiP
148- [[https://apps.apple.com/us/app/privacy-redirect/id1578144015][Privacy
149 Redirect]] - Redirect select websites to others, usually to
150 privacy-focused alternatives
151
152*** Social Networking
153
154- [[https://apps.apple.com/us/app/multitab-for-tumblr/id1071533778][MultiTab
155 T]] [=*=] - A gallery-based Tumblr client with some unique features,
156 such as tab history and sync
157- [[https://apps.apple.com/us/app/signal-private-messenger/id874139669][Signal]]
158 [=*=] - A simple, powerful, and secure messenger
159- [[https://testflight.apple.com/join/mpVk1qIy][Three Cheers]] - A
160 client for Tildes.net with a design focus that matches the intent of
161 Tildes
162- [[https://apps.apple.com/us/app/voyager-for-lemmy/id6451429762][Voyager]] -
163 A Lemmy client
164
165*** Sports
166
167- [[https://apps.apple.com/us/app/apple-sports/id6446788829][Apple
168 Sports]] - Apple's new sports app - lacks notifications and live
169 events
170- [[https://apps.apple.com/us/app/udisc-disc-golf/id1072228953][UDisc]] -
171 Disc golf course maps, score cards, and more
172
173*** Utilities
174
175- [[https://apps.apple.com/us/app/backblaze/id628638330][Backblaze]] -
176 Quickly view and manage Backblaze b2 cloud storage
177- [[https://apps.apple.com/us/app/mullvad-vpn/id1488466513][Mullvad
178 VPN]] [=*=] - A private VPN service
179- [[https://apps.apple.com/us/app/otp-auth/id659877384][OTP Auth]]
180 [=*=] - A minimalistic OTP app with support for biometrics, custom
181 icons, import/export, and iCloud sync
182- [[https://apps.apple.com/us/app/plex-dash/id1500797677][Plex Dash]] -
183 Stats about your Plex Media Server
184- [[https://apps.apple.com/us/app/safari/id1146562112][Safari]] - iOS
185 default browser
186- [[https://apps.apple.com/us/app/ubiquiti-wifiman/id1385561119][Unifi
187 WiFiman]] - Create visual layouts of WiFi strength and save heat maps
188 to your phone
189
190** Web Apps & Shortcuts
191
192- [[https://brutalist.report/][Brutalist Report]] - Minimal news
193 aggregator
194- [[https://cyber.report/][_Cyber.Report]] - Cybersecurity news
195 aggregator
196- [[https://news.ycombinator.com/][Hacker News]] - Mostly technical news
197- [[https://nextdns.io/][NextDNS]] - NextDNS statistics dashboard
198- [[https://readspike.com/][Readspike]] - Minimal news aggregator
content/wiki/macos.org added +192
@@ -0,0 +1,192 @@
1#+title: macOS
2#+date: <2024-03-13 Wed 00:00:00>
3
4Related:
5
6- [[/wiki/hardware.html][Hardware]]
7
8My primary OS. Currently running macOS Sonoma 14. This wiki page
9contains most of the apps I have used at one point or another across my
10different Macbooks.
11
12[=*=] = My favorites
13
14** Configuration
15
16*** Disable System Services
17
18- [[https://developer.apple.com/documentation/security/disabling_and_enabling_system_integrity_protection][Disabling
19 and Enabling System Integrity Protection]]
20- Disable Gatekeeper: =sudo spctl --master-disable=
21
22*** Dotfiles
23
24These are probably out of date, but they give a general idea of how I
25configure my machine.
26
27#+begin_src config
28# ~/.zshrc
29export PATH="/opt/homebrew/bin:$PATH"
30export PATH="$HOME/.emacs.d/bin:$PATH"
31export EDITOR="/opt/homebrew/bin/emacs -nw"
32ZSH_THEME="bureau"
33plugins=(git zsh-autosuggestions)
34source $ZSH/oh-my-zsh.sh
35#+end_src
36
37#+begin_src config
38# ~/.zprofile
39eval "$(/opt/homebrew/bin/brew shellenv)"
40#+end_src
41
42#+begin_src config
43# ~/.config/skhd/skhdrc
44cmd - return : /Applications/iTerm.app/Contents/MacOS/iTerm2
45cmd + shift - return : /Applications/LibreWolf.app/Contents/MacOS/librewolf
46#+end_src
47
48#+begin_src config
49# ~/.config/yabai/yabairc
50yabai -m config \
51 mouse_follows_focus off \
52 focus_follows_mouse off \
53 window_origin_display default \
54 window_placement second_child \
55 window_zoom_persist on \
56 window_shadow on \
57 window_animation_duration 0.0 \
58 window_animation_frame_rate 120 \
59 window_opacity_duration 0.0 \
60 active_window_opacity 1.0 \
61 normal_window_opacity 0.90 \
62 window_opacity off \
63 insert_feedback_color 0xffd75f5f \
64 split_ratio 0.50 \
65 split_type auto \
66 auto_balance off \
67 top_padding 15 \
68 bottom_padding 15 \
69 left_padding 15 \
70 right_padding 15 \
71 window_gap 10 \
72 layout bsp \
73 mouse_modifier fn \
74 mouse_action1 move \
75 mouse_action2 resize \
76 mouse_drop_action swap
77echo "yabai configuration loaded.."
78#+end_src
79
80** Software
81
82*** Browsers
83
84- [[https://librewolf.net/][Librewolf]] [=*=] - Custom version of
85 Firefox, focused on privacy and security
86 - [[https://bitwarden.com/][Bitwarden]] - An open source password
87 manager
88 - [[https://darkreader.org/][Dark Reader]] - Dark mode for all the
89 websites
90 - [[https://libredirect.github.io/][Libredirect]] - Automatic web
91 redirections
92 - [[https://strongboxsafe.com/][Strongbox]] - Keepass password manager
93 for iOS & macOS
94 - [[https://ublockorigin.com/][uBlock Origin]] - Free, open-source ad
95 content blocker
96- [[https://github.com/ungoogled-software/ungoogled-chromium][Ungoogled
97 Chromium]] - Google Chromium, sans integration with Google
98- [[https://www.gnu.org/software/emacs/manual/html_mono/eww.html][eww]] -
99 Emacs Web Wowser, for TUI browsing
100
101*** Communications
102
103- [[https://github.com/tulir/gomuks][gomuks]] - A terminal based Matrix
104 client
105- [[https://www.thunderbird.net/][Thunderbird]] [=*=] - An open source
106 email client by Mozilla
107- [[https://signal.org/][Signal]] [=*=] - A simple, powerful, and secure
108 messenger
109
110*** Development
111
112- [[https://www.docker.com/products/docker-desktop/][Docker Desktop]] -
113 Docker containers for your desktop
114 - [[https://github.com/open-webui/open-webui][open-webui]] -
115 User-friendly WebUI for LLMs
116- [[https://iterm2.com/][iTerm2]] [=*=] - The best terminal for macOS,
117 hands down
118- [[https://developer.apple.com/xcode/][Xcode]] - Apple's IDE
119- [[https://en.wikipedia.org/wiki/Z_shell][zsh]] [=*=] - My shell
120 preference due to its plugin and theme community
121 - [[https://github.com/zsh-users/zsh-autosuggestions][zsh-autosuggestions]] -
122 Fish-like autosuggestions for zsh
123 - [[https://github.com/zsh-users/zsh-syntax-highlighting][zsh-syntax-highlighting]] -
124 Fish shell like syntax highlighting for Zsh
125
126*** Editors
127
128- [[https://github.com/doomemacs/doomemacs][Doom Emacs]] - An Emacs
129 framework, great for working in org-mode
130- [[https://obsidian.md/][Obsidian]] [=*=] - A nice Markdown-based
131 editor based on a "vault" structure. Offers a paid sync solution and
132 community extensions
133- [[https://standardnotes.com/][Standard Notes]] - A simple text editor
134 focused on privacy and security. Offers a paid sync solution and
135 community extensions
136- [[https://vscodium.com/][VSCodium]] [=*=] - VS Code without
137 proprietary blobs
138
139*** Media
140
141- [[https://skylum.com/luminar][Luminar]] - Luminar offers top-notch
142 photo editing features
143- [[https://www.minecraft.net/][Minecraft]] - Block mining simulator
144- [[https://netnewswire.com/][NetNewsWire]] - A free and open source RSS
145 reader for Mac, iPhone, and iPad
146- [[https://www.plex.tv/][Plex]] [=*=] - Desktop client for the Plex
147 Media Server
148- [[https://store.steampowered.com/][Steam]] - The top gaming
149 marketplace for computers
150- [[https://transmissionbt.com/][Transmission]] [=*=] - A Fast, Easy and
151 Free Bittorrent Client
152- [[https://www.videolan.org/vlc/][VLC]] - A free and open source
153 cross-platform multimedia player
154
155** Package Management
156
157- [[https://brew.sh/][Homebrew]] [=*=] - The Missing Package Manager for
158 macOS (or Linux)
159- [[https://www.macports.org/][MacPorts]] - A system to compile,
160 install, and manage open source software
161
162*** Utilities
163
164- [[https://www.macbartender.com/Bartender5/][Bartender 5]] [=*=] - Easy
165 control and customization over the native macOS menu bar
166- [[https://betterdisplay.pro/][BetterDisplay]] - Allows you to tweak a
167 ton of features of built-in and external screens, such as scaling,
168 configuration overrides, and color/brightness upscaling
169- [[https://bitwarden.com/][Bitwarden]] - An open source password
170 manager
171- [[https://ollama.com/][Ollama]] - Run Llama 2, Code Llama, and other
172 models locally on your machine
173 - [[https://github.com/kghandour/Ollama-SwiftUI][Ollama Swift]] - User
174 Interface made for Ollama.ai using Swift
175- [[https://obdev.at/products/littlesnitch/index.html][LittleSnitch]] -
176 Shows all network connections on your Macbook, including system and
177 privileged services
178- [[https://obdev.at/products/microsnitch/index.html][MicroSnitch]] -
179 Camera & microphone monitoring and alterting service
180- [[https://mullvad.net/][Mullvad]] [=*=] - A private VPN service
181- [[https://github.com/koekeishiya/skhd][skhd]] [=*=] - Simple hotkey
182 daemon for macOS
183- [[https://strongboxsafe.com/][Strongbox]] - Keepass password manager
184 for iOS & macOS
185- [[https://syncthing.net/][Syncthing]] [=*=] - Continuous file
186 synchronization
187- [[https://www.bresink.com/osx/TinkerTool.html][TinkerTool]] - Unlock
188 hidden configuration options for macOS
189- [[https://github.com/koekeishiya/yabai][yabai]] [=*=] - Automatic
190 window tiling
191- [[https://github.com/yt-dlp/yt-dlp][yt-dlp]] - A youtube-dl fork with
192 additional features and fixes
index.org deleted −28
@@ -1,28 +0,0 @@
1#+title: cleberg.net
2#+options: toc:nil
3#+options: \n:t
4
5#+begin_quote
6Do AIs dream in electric sheep?
7He hoped it had nanosecond nightmares.
8#+end_quote
9
10* Recent Blog Posts
11
12- 2024-02-21 [[./blog/self-hosting-otter-wiki/][Self-Hosting An Otter Wiki]]
13- 2024-02-13 [[./blog/ubuntu-emergency-mode/][Stuck in Ubuntu's Emergency Mode? Try Fixing the Fstab File]]
14- 2024-02-06 [[./blog/zfs/][How to Create a ZFS Pool on Ubuntu Linux]]
15
16[[./blog/][All Posts →]]
17
18* Everything Else
19
20- [[./salary/][Salary]]
21- [[./services/][Services]]
22- [[./wiki/][Wiki]]
23
24* Contact
25
26- hello [at] cleberg.net ([[./gpg.txt][GPG]])
27- [[https://matrix.to/#/@cyborg:matrix.tchncs.de][@cyborg:@matrix.tchncs.de]]
28- [[https://git.cleberg.net/cleberg.net.git][Git]]
publish.el added +98
@@ -0,0 +1,98 @@
1;; explicity load packages since I'm using Doom Emacs
2(add-to-list 'load-path "~/.emacs.d/.local/straight/repos/emacs-htmlize")
3(add-to-list 'load-path "~/.emacs.d/.local/straight/repos/weblorg")
4(add-to-list 'load-path "~/.emacs.d/.local/straight/repos/templatel")
5(require 'htmlize)
6(require 'weblorg)
7
8;; defaults to http://localhost:8000
9;; ENV=prod emacs --script publish.el
10(if (string= (getenv "ENV") "prod")
11 (setq weblorg-default-url "https://cleberg.net"))
12
13(weblorg-site
14 :theme nil
15 :template-vars '(("site_name" . "cleberg.net")
16 ("site_owner" . "hello@cleberg.net")
17 ("site_description" . "Just a blip of ones and zeroes.")))
18
19;; route for rendering the index page of the website
20(weblorg-route
21 :name "index"
22 :input-pattern "content/index.org"
23 :template "index.html"
24 :output ".build/index.html"
25 :url "/")
26
27;; route for rendering each post
28(weblorg-route
29 :name "blog"
30 :input-pattern "content/blog/*.org"
31 :template "post.html"
32 :output ".build/blog/{{ slug }}.html"
33 :url "/blog/{{ slug }}.html")
34
35;; route for rendering the index page of the blog
36(weblorg-route
37 :name "blog-index"
38 :input-pattern "content/blog/*.org"
39 :input-aggregate #'weblorg-input-aggregate-all-desc
40 :template "blog.html"
41 :output ".build/blog/index.html"
42 :url "/blog/")
43
44;; route for rendering each wiki post
45(weblorg-route
46 :name "wiki"
47 :input-pattern "content/wiki/*.org"
48 :template "post.html"
49 :output ".build/wiki/{{ slug }}.html"
50 :url "/wiki/{{ slug }}.html")
51
52;; route for rendering the index page of the wiki
53(weblorg-route
54 :name "wiki-index"
55 :input-pattern "content/wiki/*.org"
56 :input-aggregate #'weblorg-input-aggregate-all
57 :template "wiki.html"
58 :output ".build/wiki/index.html"
59 :url "/wiki/")
60
61;; route for rendering each page
62(weblorg-route
63 :name "pages"
64 :input-pattern "content/*.org"
65 :template "page.html"
66 :output ".build/{{ slug }}.html"
67 :url "/{{ slug }}.html")
68
69(weblorg-route
70 :name "salary"
71 :input-pattern "content/salary/*.org"
72 :template "page.html"
73 :output ".build/salary/{{ slug }}.html"
74 :url "/salary/{{ slug }}.html")
75
76(weblorg-route
77 :name "services"
78 :input-pattern "content/services/*.org"
79 :template "page.html"
80 :output ".build/services/{{ slug }}.html"
81 :url "/services/{{ slug }}.html")
82
83;; RSS Feed
84(weblorg-route
85 :name "rss"
86 :input-pattern "content/blog/*.org"
87 :input-aggregate #'weblorg-input-aggregate-all-desc
88 :template "atom.xml"
89 :output ".build/atom.xml"
90 :url "/atom.xml")
91
92;; route for static assets that also copies files to .build directory
93(weblorg-copy-static
94 :output ".build/{{ file }}"
95 :url "/{{ file }}")
96
97;; fire the engine and export all the files declared in the routes above
98(weblorg-export)
static/styles.css deleted −807
@@ -1,807 +0,0 @@
1/*!normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css*/
2html {
3 line-height: 1.15;
4 -webkit-text-size-adjust: 100%;
5}
6
7body {
8 margin: 0;
9}
10
11main {
12 display: block;
13}
14
15h1 {
16 font-size: 2em;
17 margin: 0.67em 0;
18}
19
20hr {
21 box-sizing: content-box;
22 height: 0;
23 overflow: visible;
24}
25
26pre {
27 font-family: monospace, monospace;
28 font-size: 1em;
29}
30
31a {
32 background-color: initial;
33}
34
35abbr[title] {
36 border-bottom: none;
37 text-decoration: underline;
38 text-decoration: underline dotted;
39}
40
41b,
42strong {
43 font-weight: bolder;
44}
45
46code,
47kbd,
48samp {
49 font-family: monospace, monospace;
50 font-size: 1em;
51}
52
53small {
54 font-size: 80%;
55}
56
57sub,
58sup {
59 font-size: 75%;
60 line-height: 0;
61 position: relative;
62 vertical-align: baseline;
63}
64
65sub {
66 bottom: -0.25em;
67}
68
69sup {
70 top: -0.5em;
71}
72
73img {
74 border-style: none;
75}
76
77button,
78input,
79optgroup,
80select,
81textarea {
82 font-family: inherit;
83 font-size: 100%;
84 line-height: 1.15;
85 margin: 0;
86}
87
88button,
89input {
90 overflow: visible;
91}
92
93button,
94select {
95 text-transform: none;
96}
97
98button,
99[type="button"],
100[type="reset"],
101[type="submit"] {
102 -webkit-appearance: button;
103}
104
105button::-moz-focus-inner,
106[type="button"]::-moz-focus-inner,
107[type="reset"]::-moz-focus-inner,
108[type="submit"]::-moz-focus-inner {
109 border-style: none;
110 padding: 0;
111}
112
113button:-moz-focusring,
114[type="button"]:-moz-focusring,
115[type="reset"]:-moz-focusring,
116[type="submit"]:-moz-focusring {
117 outline: 1px dotted ButtonText;
118}
119
120fieldset {
121 padding: 0.35em 0.75em 0.625em;
122}
123
124legend {
125 box-sizing: border-box;
126 color: inherit;
127 display: table;
128 max-width: 100%;
129 padding: 0;
130 white-space: normal;
131}
132
133progress {
134 vertical-align: baseline;
135}
136
137textarea {
138 overflow: auto;
139}
140
141[type="checkbox"],
142[type="radio"] {
143 box-sizing: border-box;
144 padding: 0;
145}
146
147[type="number"]::-webkit-inner-spin-button,
148[type="number"]::-webkit-outer-spin-button {
149 height: auto;
150}
151
152[type="search"] {
153 -webkit-appearance: textfield;
154 outline-offset: -2px;
155}
156
157[type="search"]::-webkit-search-decoration {
158 -webkit-appearance: none;
159}
160
161::-webkit-file-upload-button {
162 -webkit-appearance: button;
163 font: inherit;
164}
165
166details {
167 display: block;
168}
169
170summary {
171 display: list-item;
172}
173
174template {
175 display: none;
176}
177
178[hidden] {
179 display: none;
180}
181
182:root {
183 --bg: #fff;
184 --bg-bright: #eee;
185 --fg: #111;
186 --link: #00f;
187 --code: #f00;
188}
189
190@media (prefers-reduced-motion: no-preference) {
191 :root {
192 scroll-behavior: smooth;
193 }
194}
195
196body {
197 background-color: var(--bg);
198 color: var(--fg);
199 font-family:
200 -apple-system,
201 BlinkMacSystemFont,
202 avenir next,
203 avenir,
204 segoe ui,
205 helvetica neue,
206 helvetica,
207 Cantarell,
208 Ubuntu,
209 roboto,
210 noto,
211 arial,
212 sans-serif;
213 font-size: 1rem;
214 line-height: 1.5;
215 max-width: 45em;
216 margin: 0 auto;
217 padding: 0 1rem;
218}
219
220.site-nav,
221footer {
222 border-color: var(--fg);
223}
224
225footer {
226 border-top: 1px dotted;
227 padding-top: 1rem;
228 margin: 1rem 0;
229}
230
231footer p {
232 font-size: 90%;
233 margin: 0;
234}
235
236.site-nav {
237 border-bottom: 1px dotted;
238}
239
240.site-nav ul {
241 list-style-type: none;
242 display: flex;
243 align-items: center;
244 padding: 0;
245}
246
247.site-nav ul li {
248 margin-right: 0.5rem;
249}
250
251h1,
252h2,
253h3,
254h4 {
255 color: var(--fg);
256}
257
258a,
259a:visited {
260 color: var(--link);
261 text-decoration: none;
262}
263
264a:hover {
265 text-decoration: underline;
266}
267
268img {
269 width: 100%;
270}
271
272table {
273 border-collapse: collapse;
274 color: var(--fg);
275 border-color: var(--bg-bright);
276 font-family:
277 Menlo,
278 Consolas,
279 Monaco,
280 Liberation Mono,
281 Lucida Console,
282 monospace;
283}
284
285thead,
286th,
287tr,
288td {
289 border: 1px solid var(--bg-bright);
290 padding: 0.25rem;
291}
292
293pre > code,
294time,
295code {
296 font-family:
297 Menlo,
298 Consolas,
299 Monaco,
300 Liberation Mono,
301 Lucida Console,
302 monospace;
303 font-size: 1rem;
304}
305
306pre {
307 background-color: var(--bg-bright) !important;
308 border-radius: 5px;
309 margin: 0.5rem 0;
310 padding: 0.5rem;
311 overflow-x: auto;
312}
313
314:not(pre) > code {
315 color: var(--code);
316 font-family: inherit;
317}
318
319aside {
320 background-color: var(--bg-bright);
321 padding: 1rem;
322}
323
324blockquote {
325 background-color: var(--bg-bright);
326 border-left: 10px solid var(--link);
327 border-radius: 5px;
328 margin: 1rem 0;
329 padding: 0.5rem 1rem;
330}
331
332blockquote p {
333 margin: 0;
334}
335
336.post {
337 display: flex;
338}
339
340.post time {
341 flex-shrink: 0;
342 margin-right: 0.5rem;
343}
344
345.post-metadata {
346 border: 1px dotted var(--fg);
347 border-top: none;
348 padding: 1rem;
349}
350
351.post-metadata h1 {
352 margin: 0;
353}
354
355.post-metadata p {
356 margin: 0;
357}
358
359details {
360 margin-top: 1rem;
361}
362
363summary {
364 font-weight: 700;
365}
366
367.footnote-definition {
368 display: flex;
369 justify-content: flex-start;
370 align-items: top;
371 margin: 1rem 0;
372}
373
374.footnote-definition sup {
375 font-size: inherit;
376 top: 0;
377 line-height: inherit;
378 padding-right: 0.5rem;
379}
380
381.footnote-definition sup::after {
382 content: ".";
383}
384
385.footnote-definition p {
386 display: inline-block;
387 margin: 0;
388}
389
390@media (prefers-color-scheme: dark) {
391 :root {
392 --bg: #111111;
393 --bg-bright: #2a2a2a;
394 --fg: #c9c9c9;
395 --link: #f07178;
396 --code: #ffb454;
397 }
398}
399
400/* Org Styles */
401p.verse {
402 margin-left: 3%;
403}
404.timestamp {
405 color: var(--bg-light);
406}
407.timestamp-kwd {
408 color: var(--timestamp-kwd);
409}
410.org-right {
411 margin-left: auto;
412 margin-right: 0px;
413 text-align: right;
414}
415.org-left {
416 margin-left: 0px;
417 margin-right: auto;
418 text-align: left;
419}
420.org-center {
421 margin-left: auto;
422 margin-right: auto;
423 text-align: center;
424}
425.underline {
426 text-decoration: underline;
427}
428.todo {
429 font-family: monospace;
430 color: red;
431}
432.done {
433 font-family: monospace;
434 color: green;
435}
436.priority {
437 font-family: monospace;
438 color: orange;
439}
440.tag {
441 background-color: #eee;
442 font-family: monospace;
443 padding: 2px;
444 font-size: 80%;
445 font-weight: normal;
446}
447
448.code-highlighted {
449 background-color: var(--highlight);
450}
451.org-info-js_info-navigation {
452 border-style: none;
453}
454#org-info-js_console-label {
455 font-size: 10px;
456 font-weight: bold;
457 white-space: nowrap;
458}
459.org-info-js_search-highlight {
460 background-color: var(--highlight);
461 color: var(--fg);
462 font-weight: bold;
463}
464
465caption.t-above {
466 caption-side: top;
467}
468caption.t-bottom {
469 caption-side: bottom;
470}
471td,
472th {
473 vertical-align: top;
474}
475th.org-right {
476 text-align: center;
477}
478th.org-left {
479 text-align: center;
480}
481th.org-center {
482 text-align: center;
483}
484td.org-right {
485 text-align: right;
486}
487td.org-left {
488 text-align: left;
489}
490td.org-center {
491 text-align: center;
492}
493dt {
494 font-weight: bold;
495}
496.footpara {
497 display: inline;
498}
499.footdef {
500 margin-bottom: 1em;
501}
502.figure {
503 padding: 1em;
504}
505.figure p {
506 text-align: center;
507}
508.equation-container {
509 display: table;
510 text-align: center;
511 width: 100%;
512}
513.equation {
514 vertical-align: middle;
515}
516.equation-label {
517 display: table-cell;
518 text-align: right;
519 vertical-align: middle;
520}
521.inlinetask {
522 padding: 10px;
523 border: 2px solid var(--bg);
524 margin: 10px;
525 background: var(--task);
526}
527#org-div-home-and-up {
528 text-align: right;
529 font-size: 70%;
530 white-space: nowrap;
531}
532
533pre.src {
534 position: relative;
535 overflow: auto;
536}
537pre.src:before {
538 display: none;
539 position: absolute;
540 top: -8px;
541 right: 12px;
542 padding: 3px;
543 color: var(--fg);
544 background-color: var(--bg-lightest-opac);
545}
546pre.src:hover:before {
547 display: inline;
548 margin-top: 14px;
549}
550
551/* Languages per Org manual */
552pre.src-asymptote:before {
553 content: "Asymptote";
554}
555pre.src-awk:before {
556 content: "Awk";
557}
558pre.src-authinfo::before {
559 content: "Authinfo";
560}
561pre.src-C:before {
562 content: "C";
563}
564/* pre.src-C++ doesn't work in CSS */
565pre.src-clojure:before {
566 content: "Clojure";
567}
568pre.src-css:before {
569 content: "CSS";
570}
571pre.src-D:before {
572 content: "D";
573}
574pre.src-ditaa:before {
575 content: "ditaa";
576}
577pre.src-dot:before {
578 content: "Graphviz";
579}
580pre.src-calc:before {
581 content: "Emacs Calc";
582}
583pre.src-emacs-lisp:before {
584 content: "Emacs Lisp";
585}
586pre.src-fortran:before {
587 content: "Fortran";
588}
589pre.src-gnuplot:before {
590 content: "gnuplot";
591}
592pre.src-haskell:before {
593 content: "Haskell";
594}
595pre.src-hledger:before {
596 content: "hledger";
597}
598pre.src-java:before {
599 content: "Java";
600}
601pre.src-js:before {
602 content: "Javascript";
603}
604pre.src-latex:before {
605 content: "LaTeX";
606}
607pre.src-ledger:before {
608 content: "Ledger";
609}
610pre.src-lisp:before {
611 content: "Lisp";
612}
613pre.src-lilypond:before {
614 content: "Lilypond";
615}
616pre.src-lua:before {
617 content: "Lua";
618}
619pre.src-matlab:before {
620 content: "MATLAB";
621}
622pre.src-mscgen:before {
623 content: "Mscgen";
624}
625pre.src-ocaml:before {
626 content: "Objective Caml";
627}
628pre.src-octave:before {
629 content: "Octave";
630}
631pre.src-org:before {
632 content: "Org mode";
633}
634pre.src-oz:before {
635 content: "OZ";
636}
637pre.src-plantuml:before {
638 content: "Plantuml";
639}
640pre.src-processing:before {
641 content: "Processing.js";
642}
643pre.src-python:before {
644 content: "Python";
645}
646pre.src-R:before {
647 content: "R";
648}
649pre.src-ruby:before {
650 content: "Ruby";
651}
652pre.src-sass:before {
653 content: "Sass";
654}
655pre.src-scheme:before {
656 content: "Scheme";
657}
658pre.src-screen:before {
659 content: "Gnu Screen";
660}
661pre.src-sed:before {
662 content: "Sed";
663}
664pre.src-sh:before {
665 content: "shell";
666}
667pre.src-sql:before {
668 content: "SQL";
669}
670pre.src-sqlite:before {
671 content: "SQLite";
672}
673/* additional languages in org.el's org-babel-load-languages alist */
674pre.src-forth:before {
675 content: "Forth";
676}
677pre.src-io:before {
678 content: "IO";
679}
680pre.src-J:before {
681 content: "J";
682}
683pre.src-makefile:before {
684 content: "Makefile";
685}
686pre.src-maxima:before {
687 content: "Maxima";
688}
689pre.src-perl:before {
690 content: "Perl";
691}
692pre.src-picolisp:before {
693 content: "Pico Lisp";
694}
695pre.src-scala:before {
696 content: "Scala";
697}
698pre.src-shell:before {
699 content: "Shell Script";
700}
701pre.src-ebnf2ps:before {
702 content: "ebfn2ps";
703}
704/* additional language identifiers per "defun org-babel-execute"
705 in ob-*.el */
706pre.src-cpp:before {
707 content: "C++";
708}
709pre.src-abc:before {
710 content: "ABC";
711}
712pre.src-coq:before {
713 content: "Coq";
714}
715pre.src-groovy:before {
716 content: "Groovy";
717}
718/* additional language identifiers from org-babel-shell-names in
719 ob-shell.el: ob-shell is the only babel language using a lambda to put
720 the execution function name together. */
721pre.src-bash:before {
722 content: "bash";
723}
724pre.src-csh:before {
725 content: "csh";
726}
727pre.src-ash:before {
728 content: "ash";
729}
730pre.src-dash:before {
731 content: "dash";
732}
733pre.src-ksh:before {
734 content: "ksh";
735}
736pre.src-mksh:before {
737 content: "mksh";
738}
739pre.src-posh:before {
740 content: "posh";
741}
742/* Additional Emacs modes also supported by the LaTeX listings package */
743pre.src-ada:before {
744 content: "Ada";
745}
746pre.src-asm:before {
747 content: "Assembler";
748}
749pre.src-caml:before {
750 content: "Caml";
751}
752pre.src-delphi:before {
753 content: "Delphi";
754}
755pre.src-html:before {
756 content: "HTML";
757}
758pre.src-idl:before {
759 content: "IDL";
760}
761pre.src-mercury:before {
762 content: "Mercury";
763}
764pre.src-metapost:before {
765 content: "MetaPost";
766}
767pre.src-modula-2:before {
768 content: "Modula-2";
769}
770pre.src-pascal:before {
771 content: "Pascal";
772}
773pre.src-ps:before {
774 content: "PostScript";
775}
776pre.src-prolog:before {
777 content: "Prolog";
778}
779pre.src-simula:before {
780 content: "Simula";
781}
782pre.src-tcl:before {
783 content: "tcl";
784}
785pre.src-tex:before {
786 content: "TeX";
787}
788pre.src-plain-tex:before {
789 content: "Plain TeX";
790}
791pre.src-verilog:before {
792 content: "Verilog";
793}
794pre.src-vhdl:before {
795 content: "VHDL";
796}
797pre.src-xml:before {
798 content: "XML";
799}
800pre.src-nxml:before {
801 content: "XML";
802}
803/* add a generic configuration mode; LaTeX export needs an additional
804 (add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
805pre.src-conf:before {
806 content: "Configuration File";
807}
theme/static/gpg.txt added +52
@@ -0,0 +1,52 @@
1-----BEGIN PGP PUBLIC KEY BLOCK-----
2
3mQINBGN0Z8YBEAC6gWrNuB0nyAVkIuCsErIqpO7ngH0HV2sZD54t0ge9on0Fb+QA
4S/oRSK3bcwgR09lnIwPDWpQqlPpzKib2bZ9USBMD0lcgPb0hMr0fafs/+/FCRQV1
5Pvc/e37n2/KHRW2KoiM4sOFT9LYxi7LBGgXffusx6uVBzrNUacTFFd/pMNkPd5uX
6/J4IT+QbDh1bKw4CtLNvoh7xTcfdpzdqpHfNkjm+24pEnbrv6QrSpBzol4uulaB+
75I8JF938/FBHBndVMT9UQcGRtX+ttZTp9U7m0TzCAsyrVV/V8rEbcGTMlU+yyUjR
8TDRX4Dwj79IfL+vLZgFGLd8GwO08AirNkHYaZwzvYi42I5Bh8cX1L2IippYL8YYF
9ASX26pXC6mxTwC/hjCA7rzyIMD5sf1UailYm5MvrhEujRYOPWDU+kex2t2HJpzvN
10vYSVIS0sKi7iHr82VA+/spR6Ii07/84zZPQ1h/sXJLaDolQV2pU7WJBPyFO957Er
11BggugSpB1U/blgU+B9vOR+2sMEReRQwVF7aVhQ2Wy5wOZRHlmTZVMNO5SawXkiTp
12Bt4IwhThzMcUQstXxf5V44pPsB5uQE3n4WdROfJTOiB2cZJZOiXe3iPiiTsVsBc2
13tcqxJmwplMS4jNddJ9Nh0NTCKNk3Yt0iZzWlQDKAzR1uSGW9fQGAdh/UZQARAQAB
14tCVDaHJpc3RpYW4gQ2xlYmVyZyA8aGVsbG9AY2xlYmVyZy5uZXQ+iQJRBBMBCAA7
15FiEEOReXP7FZu7hhlFOFaUUaUXrAyzcFAmN0Z8YCGwMFCwkIBwICIgIGFQoJCAsC
16BBYCAwECHgcCF4AACgkQaUUaUXrAyzcrIQ//ZzCvcNKi2exZ4MfH68q9cIrJtHA3
17+FQ/3yTwAMiXmaTctHTcME+4Um12TCJMH/PwOkmxjolln5LfNHC8emcNs9Uaoga7
181Cy8ihqKbQMaZN1ZHrgaddeTs7+N1+/u8yAZPXo+N6pmLaeuPfn1MMhcejTbo+C/
19c22/yj97ym6Iuc9oodnbHb2rxhGKReQLJmqzBHWd0syFbYDopmhY2MjMawVirPG7
20vt6EbiFHkWLBY08FYbOQWT4bXdSHlLxT3q5m+j0HdVjHxd/vOk+dc3FPtK8ZpTVC
21qKa2oQ6dl4fjp8GVbu4f4SMDDJRR1iOoLTNEhKDSZHkZdjH0/LQRLsf49cqbff1Y
22mpxJcNv1/RmgzctTmBAoGt2RS8mT97H8AUW7v7PGs3eS/OkrY1e4cuTrmcafEaMy
23J2L7aUxDVVUCvRKsONXx+zSLin7ByRHypqRfxGqnpQUDPW4Oty6CewsSXktDjIUx
24FXzMwfuNXKS/KHqcUxamE0rL8O2d3CJI4YAbWu2Y0GtBetfuaaOgi56cYqv86zGu
25os0oga1ZakiCeRPgEaipPaZZMf6pCvucF2VyaUHwIOMcSVEH5nhHO4McgYLSZucx
26na5qcLk06EP+1HjmifGqPmkxHTW/ez5x6m/QT9jOzyRu94p3IG5DT1Lh8kl6gid7
27YntCGrwcsvw8zKi5Ag0EY3RnxgEQANj1c0ZS3npmtj1V5m+vsq1mK2g4K66senuC
28Gf+wTudYgcUzBhcTtEwzFJTwFFUMkfpgmkgYrlMB7iH+85YxiDR2sBhMg56haJXn
29LGnSaWqHVE4P0yyHI/6QasYxdJWfYkSH9m3B8yW1VKs4eSSL6S/U/qdHzDRRZCEX
30lNhvplrWcWv6Ifk/aYJ+njwn+jhXT4j8lbhem5oCbg4olY84bs+rfvWHTrWdGD1N
31sHkbLEwLgnmJou7vkVY9vkIMhbgpvNp1CEx0zOGTMhlPrCYBCFUGR7Bnoqwwl/C4
32CTBwZxBE5bNBpsEdySYhmHW+YHRHIxeboLmOyoc0CpT/zhu2y5JxqJBiGEDYhTM/
33V2nNqKGDgUenXqjwoBw5oCNQJ35NNgFgEbphhs71W7VVwEPRdppcem33TcpFBeoE
34vTzCfK6xJA82ASJHKz0hajEQchJ5jJZYo4wRZJGFv2jMIhq24DLIqxgjZeBKLEzl
35RigfuuCrAsQBIMtTUSUUvxjB/b+UDYssqi9Q+8F7FcwqE9egaj7xVQprTAYcGW7S
36zxfjzFSbJSl+b4WQSewFtmFIx62RYemBH+YPxbwOhQAuRWgEg0E6xeuILu22xydf
37DEkbk1GEXH3ilYxl4LhFy2EmUbvB8rxh5Vk3A1KVaBe/ndPhwznTe7X9ypRHzQiV
38Jkc2vVGjABEBAAGJAjYEGAEIACAWIQQ5F5c/sVm7uGGUU4VpRRpResDLNwUCY3Rn
39xgIbDAAKCRBpRRpResDLN60xD/9pEDZK7SXZy/nhVdHMKn2UyF7F8dEXYxILmXp0
4053zDDVN5D7luHjcI5pYynWqlgXWPAaCOthWtexr3r3b8fVSc7yxi497fFa3jiVkn
41VNYjDCa4SK5H6Rdf6I5rv+SS1PPmiVFKL7xuWcJ9YucHACdeH0UUmPCMmHHDc9SY
42MGUPjadFxjCGtBz8itS+ufDiZsTU9ov7XRE+pVyrDlMSVD1Ex02vMRtr+UD9lkYb
43KGs32TEDw28+OgvSZc81P6/BuxmG2XxgvU5OOrlVFOs4VU5P0TnZVxbVuKyO4fkZ
44sxSApn+U4lU89dM0M1l1S2NZtvkWTIW2jFvzwXDCPxs5GAXAGtnEO8gjGICo2QV3
45VovHMTmPz7Bo87fqGZkfZatzvAeHW92FIhQBOdgSiCwSDRPVVdPTpQ27BaUrfH8p
46aS81RhlCWgKptFKj4+MAqGEf9V6jUIKn5EvdSxCZ5XXHmaBL/kXxTPaDJiK8nMKv
47dr/iwtb23SwNrBLQkYcI+6aZj4jcqr5T0H2EsC8h9jQWMG+S9/BzhJOI/QeepHvD
48VJQve5jozXbz+iBRLrWbEgbNydL/LT9iQCWaWt2HCPQ7bPrxKqya8fUMPxi3VCZZ
49AuXpJzywCyVuzpuChuvdMflHbmx1r8uJjSmUCJf6ngt0TQMXiwL3vsECTV7ZtVge
500jZ4tA==
51=pl2G
52-----END PGP PUBLIC KEY BLOCK-----
theme/static/robots.txt added +3
@@ -0,0 +1,3 @@
1User-agent: *
2Disallow:
3Allow: /
theme/static/styles.css added +578
@@ -0,0 +1,578 @@
1/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
2
3/* Document
4 ========================================================================== */
5
6/**
7 * 1. Correct the line height in all browsers.
8 * 2. Prevent adjustments of font size after orientation changes in iOS.
9 */
10
11html {
12 line-height: 1.15; /* 1 */
13 -webkit-text-size-adjust: 100%; /* 2 */
14}
15
16/* Sections
17 ========================================================================== */
18
19/**
20 * Remove the margin in all browsers.
21 */
22
23body {
24 margin: 0;
25}
26
27/**
28 * Render the `main` element consistently in IE.
29 */
30
31main {
32 display: block;
33}
34
35/**
36 * Correct the font size and margin on `h1` elements within `section` and
37 * `article` contexts in Chrome, Firefox, and Safari.
38 */
39
40h1 {
41 font-size: 2em;
42 margin: 0.67em 0;
43}
44
45/* Grouping content
46 ========================================================================== */
47
48/**
49 * 1. Add the correct box sizing in Firefox.
50 * 2. Show the overflow in Edge and IE.
51 */
52
53hr {
54 box-sizing: content-box; /* 1 */
55 height: 0; /* 1 */
56 overflow: visible; /* 2 */
57}
58
59/**
60 * 1. Correct the inheritance and scaling of font size in all browsers.
61 * 2. Correct the odd `em` font sizing in all browsers.
62 */
63
64pre {
65 font-family: monospace, monospace; /* 1 */
66 font-size: 1em; /* 2 */
67}
68
69/* Text-level semantics
70 ========================================================================== */
71
72/**
73 * Remove the gray background on active links in IE 10.
74 */
75
76a {
77 background-color: transparent;
78}
79
80/**
81 * 1. Remove the bottom border in Chrome 57-
82 * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
83 */
84
85abbr[title] {
86 border-bottom: none; /* 1 */
87 text-decoration: underline; /* 2 */
88 text-decoration: underline dotted; /* 2 */
89}
90
91/**
92 * Add the correct font weight in Chrome, Edge, and Safari.
93 */
94
95b,
96strong {
97 font-weight: bolder;
98}
99
100/**
101 * 1. Correct the inheritance and scaling of font size in all browsers.
102 * 2. Correct the odd `em` font sizing in all browsers.
103 */
104
105code,
106kbd,
107samp {
108 font-family: monospace, monospace; /* 1 */
109 font-size: 1em; /* 2 */
110}
111
112/**
113 * Add the correct font size in all browsers.
114 */
115
116small {
117 font-size: 80%;
118}
119
120/**
121 * Prevent `sub` and `sup` elements from affecting the line height in
122 * all browsers.
123 */
124
125sub,
126sup {
127 font-size: 75%;
128 line-height: 0;
129 position: relative;
130 vertical-align: baseline;
131}
132
133sub {
134 bottom: -0.25em;
135}
136
137sup {
138 top: -0.5em;
139}
140
141/* Embedded content
142 ========================================================================== */
143
144/**
145 * Remove the border on images inside links in IE 10.
146 */
147
148img {
149 border-style: none;
150}
151
152/* Forms
153 ========================================================================== */
154
155/**
156 * 1. Change the font styles in all browsers.
157 * 2. Remove the margin in Firefox and Safari.
158 */
159
160button,
161input,
162optgroup,
163select,
164textarea {
165 font-family: inherit; /* 1 */
166 font-size: 100%; /* 1 */
167 line-height: 1.15; /* 1 */
168 margin: 0; /* 2 */
169}
170
171/**
172 * Show the overflow in IE.
173 * 1. Show the overflow in Edge.
174 */
175
176button,
177input {
178 /* 1 */
179 overflow: visible;
180}
181
182/**
183 * Remove the inheritance of text transform in Edge, Firefox, and IE.
184 * 1. Remove the inheritance of text transform in Firefox.
185 */
186
187button,
188select {
189 /* 1 */
190 text-transform: none;
191}
192
193/**
194 * Correct the inability to style clickable types in iOS and Safari.
195 */
196
197button,
198[type="button"],
199[type="reset"],
200[type="submit"] {
201 -webkit-appearance: button;
202}
203
204/**
205 * Remove the inner border and padding in Firefox.
206 */
207
208button::-moz-focus-inner,
209[type="button"]::-moz-focus-inner,
210[type="reset"]::-moz-focus-inner,
211[type="submit"]::-moz-focus-inner {
212 border-style: none;
213 padding: 0;
214}
215
216/**
217 * Restore the focus styles unset by the previous rule.
218 */
219
220button:-moz-focusring,
221[type="button"]:-moz-focusring,
222[type="reset"]:-moz-focusring,
223[type="submit"]:-moz-focusring {
224 outline: 1px dotted ButtonText;
225}
226
227/**
228 * Correct the padding in Firefox.
229 */
230
231fieldset {
232 padding: 0.35em 0.75em 0.625em;
233}
234
235/**
236 * 1. Correct the text wrapping in Edge and IE.
237 * 2. Correct the color inheritance from `fieldset` elements in IE.
238 * 3. Remove the padding so developers are not caught out when they zero out
239 * `fieldset` elements in all browsers.
240 */
241
242legend {
243 box-sizing: border-box; /* 1 */
244 color: inherit; /* 2 */
245 display: table; /* 1 */
246 max-width: 100%; /* 1 */
247 padding: 0; /* 3 */
248 white-space: normal; /* 1 */
249}
250
251/**
252 * Add the correct vertical alignment in Chrome, Firefox, and Opera.
253 */
254
255progress {
256 vertical-align: baseline;
257}
258
259/**
260 * Remove the default vertical scrollbar in IE 10+.
261 */
262
263textarea {
264 overflow: auto;
265}
266
267/**
268 * 1. Add the correct box sizing in IE 10.
269 * 2. Remove the padding in IE 10.
270 */
271
272[type="checkbox"],
273[type="radio"] {
274 box-sizing: border-box; /* 1 */
275 padding: 0; /* 2 */
276}
277
278/**
279 * Correct the cursor style of increment and decrement buttons in Chrome.
280 */
281
282[type="number"]::-webkit-inner-spin-button,
283[type="number"]::-webkit-outer-spin-button {
284 height: auto;
285}
286
287/**
288 * 1. Correct the odd appearance in Chrome and Safari.
289 * 2. Correct the outline style in Safari.
290 */
291
292[type="search"] {
293 -webkit-appearance: textfield; /* 1 */
294 outline-offset: -2px; /* 2 */
295}
296
297/**
298 * Remove the inner padding in Chrome and Safari on macOS.
299 */
300
301[type="search"]::-webkit-search-decoration {
302 -webkit-appearance: none;
303}
304
305/**
306 * 1. Correct the inability to style clickable types in iOS and Safari.
307 * 2. Change font properties to `inherit` in Safari.
308 */
309
310::-webkit-file-upload-button {
311 -webkit-appearance: button; /* 1 */
312 font: inherit; /* 2 */
313}
314
315/* Interactive
316 ========================================================================== */
317
318/*
319 * Add the correct display in Edge, IE 10+, and Firefox.
320 */
321
322details {
323 display: block;
324}
325
326/*
327 * Add the correct display in all browsers.
328 */
329
330summary {
331 display: list-item;
332}
333
334/* Misc
335 ========================================================================== */
336
337/**
338 * Add the correct display in IE 10+.
339 */
340
341template {
342 display: none;
343}
344
345/**
346 * Add the correct display in IE 10.
347 */
348
349[hidden] {
350 display: none;
351}
352
353/* CUSTOM CSS */
354:root {
355 --bg: #fff;
356 --bg-bright: #eee;
357 --fg: #111;
358 --link: #00f;
359 --code: #f00;
360 --border: #ccc;
361}
362
363@media (prefers-reduced-motion: no-preference) {
364 :root {
365 scroll-behavior: smooth;
366 }
367}
368
369body {
370 background-color: var(--bg);
371 color: var(--fg);
372 font-family:
373 Menlo,
374 Consolas,
375 Monaco,
376 Liberation Mono,
377 Lucida Console,
378 monospace;
379 font-size: 0.9rem;
380 line-height: 1.5;
381 max-width: 50em;
382 margin: 0 auto;
383 padding: 0 1rem;
384}
385
386.site-nav,
387footer {
388 border-color: var(--fg);
389}
390
391footer {
392 border-top: 1px dotted;
393 padding-top: 1rem;
394 margin: 1rem 0;
395}
396
397footer p {
398 margin: 0;
399}
400
401.site-nav {
402 border-bottom: 1px dotted;
403}
404
405.site-nav ul {
406 list-style-type: none;
407 display: flex;
408 align-items: center;
409 padding: 0;
410}
411
412.site-nav ul li {
413 margin-right: 0.5rem;
414}
415
416h1,
417h2,
418h3,
419h4 {
420 color: var(--fg);
421}
422
423a,
424a:visited {
425 color: var(--link);
426 text-decoration: none;
427}
428
429a:hover {
430 text-decoration: underline;
431}
432
433img {
434 width: 100%;
435}
436
437table {
438 border-collapse: collapse;
439 color: var(--fg);
440 border-color: var(--bg-bright);
441 font-family:
442 Menlo,
443 Consolas,
444 Monaco,
445 Liberation Mono,
446 Lucida Console,
447 monospace;
448 font-size: 0.9rem;
449}
450
451thead,
452th,
453tr,
454td {
455 border: 1px solid var(--border);
456 padding: 0.25rem;
457}
458
459pre > code,
460time,
461code {
462 font-family:
463 Menlo,
464 Consolas,
465 Monaco,
466 Liberation Mono,
467 Lucida Console,
468 monospace;
469 font-size: inherit;
470}
471
472pre {
473 background-color: var(--bg-bright) !important;
474 margin: 0.5rem 0;
475 padding: 0.5rem;
476 overflow-x: auto;
477}
478
479:not(pre) > code {
480 color: var(--code);
481 font-family: inherit;
482}
483
484aside {
485 background-color: var(--bg-bright);
486 padding: 1rem;
487}
488
489blockquote {
490 background-color: var(--bg-bright);
491 border-left: 5px solid var(--link);
492 margin: 1rem 0;
493 padding: 0.5rem 1rem;
494}
495
496blockquote p {
497 margin: 0;
498}
499
500.post,
501.wiki-post {
502 display: flex;
503}
504
505.post time {
506 flex-shrink: 0;
507 margin-right: 0.5rem;
508}
509
510.wiki-post {
511justify-content: space-between;
512}
513
514.wiki-post:first-of-type {
515border-bottom: 1px dotted var(--fg);
516margin-bottom: 1rem;
517}
518
519.wiki-post p {
520margin: 0;
521}
522
523.post-metadata {
524 border: 1px dotted var(--fg);
525 border-top: none;
526 padding: 1rem;
527}
528
529.post-metadata h1 {
530 margin: 0;
531}
532
533.post-metadata p {
534 margin: 0;
535}
536
537details {
538 margin-top: 1rem;
539}
540
541summary {
542 font-weight: bold;
543}
544
545.footnote-definition {
546 display: flex;
547 justify-content: flex-start;
548 align-items: top;
549 margin: 1rem 0;
550}
551
552.footnote-definition sup {
553 font-size: inherit;
554 top: 0;
555 line-height: inherit;
556 padding-right: 0.5rem;
557}
558
559.footnote-definition sup::after {
560 content: ".";
561}
562
563.footnote-definition p {
564 display: inline-block;
565 margin: 0;
566}
567
568@media (prefers-color-scheme: dark) {
569 :root {
570 --bg: #141617;
571 --bg-bright: #191c1d;
572 --fg: #b2aea9;
573 /* --link: #2b8ad9; */
574 --link: #ff79c6;
575 --code: #ffb454;
576 --border: #333;
577 }
578}
theme/static/styles.min.css added +1
@@ -0,0 +1 @@
1/*!normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css*/html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:initial}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}:root{--bg:#fff;--bg-bright:#eee;--fg:#111;--link:#00f;--code:#f00;--border:#ccc}@media(prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{background-color:var(--bg);color:var(--fg);font-family:Menlo,Consolas,Monaco,Liberation Mono,Lucida Console,monospace;font-size:.9rem;line-height:1.5;max-width:50em;margin:0 auto;padding:0 1rem}.site-nav,footer{border-color:var(--fg)}footer{border-top:1px dotted;padding-top:1rem;margin:1rem 0}footer p{margin:0}.site-nav{border-bottom:1px dotted}.site-nav ul{list-style-type:none;display:flex;align-items:center;padding:0}.site-nav ul li{margin-right:.5rem}h1,h2,h3,h4{color:var(--fg)}a,a:visited{color:var(--link);text-decoration:none}a:hover{text-decoration:underline}img{width:100%}table{border-collapse:collapse;color:var(--fg);border-color:var(--bg-bright);font-family:Menlo,Consolas,Monaco,Liberation Mono,Lucida Console,monospace;font-size:.9rem}thead,th,tr,td{border:1px solid var(--border);padding:.25rem}pre>code,time,code{font-family:Menlo,Consolas,Monaco,Liberation Mono,Lucida Console,monospace;font-size:inherit}pre{background-color:var(--bg-bright)!important;margin:.5rem 0;padding:.5rem;overflow-x:auto}:not(pre)>code{color:var(--code);font-family:inherit}aside{background-color:var(--bg-bright);padding:1rem}blockquote{background-color:var(--bg-bright);border-left:5px solid var(--link);margin:1rem 0;padding:.5rem 1rem}blockquote p{margin:0}.post,.wiki-post{display:flex}.post time{flex-shrink:0;margin-right:.5rem}.wiki-post{justify-content:space-between}.wiki-post:first-of-type{border-bottom:1px dotted var(--fg);margin-bottom:1rem}.wiki-post p{margin:0}.post-metadata{border:1px dotted var(--fg);border-top:none;padding:1rem}.post-metadata h1{margin:0}.post-metadata p{margin:0}details{margin-top:1rem}summary{font-weight:700}.footnote-definition{display:flex;justify-content:flex-start;align-items:top;margin:1rem 0}.footnote-definition sup{font-size:inherit;top:0;line-height:inherit;padding-right:.5rem}.footnote-definition sup::after{content:"."}.footnote-definition p{display:inline-block;margin:0}@media(prefers-color-scheme:dark){:root{--bg:#141617;--bg-bright:#191c1d;--fg:#b2aea9;--link:#ff79c6;--code:#ffb454;--border:#333}}
\ No newline at end of file
static/syntax-theme-dark.css → theme/static/syntax-theme-dark.css renamed
static/syntax-theme-light.css → theme/static/syntax-theme-light.css renamed
theme/templates/atom.xml added +42
@@ -0,0 +1,42 @@
1<?xml version="1.0" encoding="UTF-8" ?>
2<rss version="2.0"
3 xmlns:content="http://purl.org/rss/1.0/modules/content/"
4 xmlns:wfw="http://wellformedweb.org/CommentAPI/"
5 xmlns:dc="http://purl.org/dc/elements/1.1/"
6 xmlns:atom="http://www.w3.org/2005/Atom"
7 xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
8 xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
9 xmlns:georss="http://www.georss.org/georss"
10 xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
11 xmlns:media="http://search.yahoo.com/mrss/">
12 <channel>
13 <title>{{ site_name | default("Simple Blog") }}</title>
14 <atom:link
15 href="{{ url_for("rss") }}"
16 rel="self" type="application/rss+xml" />
17 <link>{{ url_for("index") }}</link>
18 <description><![CDATA[]]></description>
19 <language>en</language>
20 <pubDate>{{ posts | first | getattr("date") | strftime("%a, %d %b %Y %H:%M:%S %z") }}</pubDate>
21 <lastBuildDate>{{ now() | strftime("%a, %d %b %Y %H:%M:%S %z") }}</lastBuildDate>
22 <generator>{{ meta.generator }}</generator>
23 <webMaster>{{ site_owner | default("hello@cleberg.net") }}</webMaster>
24 <image>
25 <url>{{ url_for("index") }}media/img/8bitme.png</url>
26 <title>Blog Author</title>
27 <link>{{ url_for("index") }}</link>
28 </image>
29
30 {% for post in posts %}
31 <item>
32 <title>{{ post.title }}</title>
33 <link>{{ url_for("blog", slug=post.slug) }}</link>
34 <author>{{ post.author|default("hello@cleberg.net") }}</author>
35 <guid isPermaLink="false">{{ url_for("blog", slug=post.slug) }}</guid>
36 <pubDate>{{ post.date|strftime("%a, %d %b %Y %H:%M:%S %z") }}</pubDate>
37 <description><![CDATA[{{ post.html|safe }}]]></description>
38 </item>
39 {% endfor %}
40
41 </channel>
42</rss>
theme/templates/base.html added +41
@@ -0,0 +1,41 @@
1
2<!doctype html>
3<html lang="en-us">
4<head>
5 {% block head %}
6 <meta charset="utf-8">
7 <title>
8 {% block subtitle %}{% endblock %}
9 {% block title %}{{ site_name | default("weblorg website") }}{% endblock %}
10 </title>
11 <meta name="viewport" content="width=device-width, initial-scale=1">
12 {% if site_owner is defined %}<meta name="author" content="{{ site_owner }}" >{% endif %}
13 {% if site_description is defined %}<meta name="description" content="{{ site_description }}" >{% endif %}
14 {% if site_keywords is defined %}<meta name="keywords" content="{{ site_keywords }}" >{% endif %}
15 <link rel="stylesheet" href="{{ url_for("static", file="styles.min.css") }}" type="text/css">
16 {% block meta %}{% endblock %}
17 {% endblock %}
18</head>
19<body>
20 {% block nav %}
21 <nav class="site-nav" aria-label="site-nav" role="navigation">
22 <ul>
23 <li><a href="/">Home</a></li>
24 <li><a href="/blog/">Blog</a></li>
25 <li><a href="/services/">Services</a></li>
26 <li><a href="/wiki/">Wiki</a></li>
27 </ul>
28 </nav>
29 {% endblock %}
30
31 <main>{% block main %}{% endblock %}</main>
32
33 {% block footer %}
34 <footer>
35 <p>Last Build: &lt;{{ now() | strftime("%Y-%m-%d %a %H:%M:%S") }}&gt;</p>
36 <p><a href="https://git.cleberg.net/cleberg.net.git" target="_blank" rel="noopener">Source Code</a></p>
37 <p><a href="/atom.xml">Atom RSS Feed</a></p>
38 </footer>
39 {% endblock %}
40</body>
41</html>
theme/templates/blog.html added +14
@@ -0,0 +1,14 @@
1{% extends "base.html" %}
2
3{% block subtitle %}Blog | {% endblock %}
4{% block main %}
5 <h1>Blog</h1>
6 <p>Use <code>Ctrl + F</code> to search blog post titles for keywords.</p>
7 <p>You can also add the <a href="/feed.xml">RSS Feed</a> to your feed reader.</p>
8 {% for post in posts %}
9 <div class="post">
10 <time datetime="{{ post.date | strftime("%Y-%m-%d") }}">&lt;{{ post.date|strftime("%Y-%m-%d") }}&gt;</time>
11 <a href="{{ url_for("blog", slug=post.slug) }}">{{ post.title }}</a>
12 </div>
13 {% endfor %}
14{% endblock %}
theme/templates/index.html added +41
@@ -0,0 +1,41 @@
1{% extends "base.html" %}
2
3{% block main %}
4<section>
5 <h1>cleberg.net</h1>
6 <blockquote>Do AIs dream in electric sheep?<br>He hoped it had nanosecond nightmares.</blockquote>
7</section>
8<section>
9 <h2>Recent Blog Posts</h2>
10 <div class="post">
11 <time datetime="2024-03-15">&lt;2024-03-15&gt;</time>
12 <a href="/blog/self-hosting-ddns-updater.html">Self-Hosting DDNS Updater</a>
13 </div>
14 <div class="post">
15 <time datetime="2024-03-14">&lt;2024-03-14&gt;</time>
16 <a href="/blog/doom-emacs-org-mode.html">Doom Emacs & Org-Mode</a>
17 </div>
18 <div class="post">
19 <time datetime="2024-02-21">&lt;2024-02-21&gt;</time>
20 <a href="/blog/self-hosting-an-otter-wiki.html">Self-Hosting An Otter Wiki</a>
21 </div>
22 <br>
23 <a href="/blog/">All Posts &rarr;</a>
24</section>
25<section>
26 <h2>Everything Else</h2>
27 <ul>
28 <li><a href="/salary/">Salary</a></li>
29 <li><a href="/services/">Services</a></li>
30 <li><a href="/wiki/">Wiki</a></li>
31 </ul>
32</section>
33<section>
34 <h2>Contact</h2>
35 <ul>
36 <li>hello [at] cleberg.net (<a href="/gpg.txt">GPG</a>)</li>
37 <li><a href="https://matrix.to/#/@cyborg:matrix.tchncs.de" target="_blank" rel="noopener">@cyborg:@matrix.tchncs.de</a></li>
38 <li><a href="https://git.cleberg.net/cleberg.net.git" target="_blank" rel="noopener">Git</a></li>
39 </ul>
40</section>
41{% endblock %}
theme/templates/page.html added +11
@@ -0,0 +1,11 @@
1{% extends "base.html" %}
2
3{% block subtitle %}
4 {{ post.title }} |
5{% endblock %}
6{% block main %}
7<article role="article">
8 <h1>{{ post.title }}</h1>
9 <section>{{ post.html | safe }}</section>
10</article>
11{% endblock %}
theme/templates/post.html added +30
@@ -0,0 +1,30 @@
1{% extends "base.html" %}
2
3{% block subtitle %}
4 {{ post.title }} |
5{% endblock %}
6{% block meta %}
7<meta property="og:title" content="{{ post.title }}">
8<meta property="og:url" content="{{ post.url }}">
9{% if post.description is defined %}
10<meta property="og:description" content="{{ post.description }}">
11{% elif project_description is defined %}
12<meta property="og:description" content="{{ project_description }}">
13{% endif %}
14<link rel="stylesheet" href="/syntax-theme-dark.css" media="(prefers-color-scheme: dark)">
15<link rel="stylesheet" href="/syntax-theme-light.css" media="(prefers-color-scheme: light)">
16{% endblock %}
17
18{% block main %}
19<article role="article">
20 <section class="post-metadata">
21 <h1 class="post__title">{{ post.title }}</h1>
22 {% if post.date is defined %}
23 <time datetime="{{ post.date|strftime("%Y-%m-%d") }}">&lt;{{ post.date|strftime("%Y-%m-%d %a %H:%M:%S") }}&gt;</time>
24 {% endif %}
25 </section>
26 <section>
27 {{ post.html | safe }}
28 </section>
29</article>
30{% endblock %}
theme/templates/wiki.html added +17
@@ -0,0 +1,17 @@
1{% extends "base.html" %}
2
3{% block subtitle %}Wiki | {% endblock %}
4{% block main %}
5<h1>Wiki</h1>
6<p>Use <code>Ctrl + F</code> to search wiki pages for keywords.</p>
7<div class="wiki-post">
8 <p>Wiki Page</p>
9 <p>Last Updated</p>
10</div>
11{% for post in posts %}
12 <div class="wiki-post">
13 <a href="{{ url_for("wiki", slug=post.slug) }}">{{ post.title }}</a>
14 <time datetime="{{ post.date | strftime("%Y-%m-%d") }}">&lt;{{ post.date|strftime("%Y-%m-%d") }}&gt;</time>
15 </div>
16{% endfor %}
17{% endblock %}
wiki/index.org deleted −145
@@ -1,145 +0,0 @@
1#+title: Wiki
2#+description: An informal wiki of sorts.
3
4An informal wiki of sorts.
5
6* Digital Garden
7
8#+begin_quote
9At times, wilderness is exactly what readers want: a rich collection of
10resources and links. At times, rigid formality suits readers perfectly,
11providing precisely the information they want, no more and no less.
12Indeed, individual hypertexts and Web sites may contain sections that
13tend toward each extreme.
14
15#+end_quote
16
17#+begin_quote
18Often, however, designers should strive for the comfort, interest, and
19habitability of parks and gardens: places that invite visitors to
20remain, and that are designed to engage and delight them, to invite them
21to linger, to explore, and to reflect.
22
23#+end_quote
24
25[[https://www.eastgate.com/garden/][Hypertext Garden]]
26
27* Git
28
29I want to get rid of all local modifications and go back to the working
30tree of the most recent commit:
31
32#+begin_src sh
33git restore .
34#+end_src
35
36Revert a specified commit:
37
38#+begin_src sh
39git revert commit-id
40#+end_src
41
42Reset the repository to a specific commit in the git log:
43
44#+begin_src sh
45git reset --mixed commit-id
46#+end_src
47
48I need to commit and push changes to a remote that has been changed
49since my most recent pull:
50
51#+begin_src sh
52git pull --rebase
53#+end_src
54
55* Hardware
56
57** Laptops
58
59*** macOS
60
61| Category | Details |
62|----------+-----------------|
63| Model | Macbook Pro 16” |
64| CPU | Apple M2 Pro |
65| RAM | 16GB |
66| Storage | 512GB SSD |
67
68*** Linux
69
70| Category | Details |
71|----------+---------------------------------------------|
72| Model | Lenovo ThinkPad E15 Gen 4, model 21ED0048US |
73| CPU | AMD Ryzen 5 5625U with Radeon Graphics |
74| RAM | 16 GB |
75| Storage | 256 GB SSD |
76
77** Servers
78
79| Category | Details |
80|--------------------+----------------------------------------|
81| Case | Rosewill RSV-R4100U 4U |
82| Motherboard | NZXT B550 |
83| CPU | AMD Ryzen 7 5700G with Radeon Graphics |
84| RAM | 64GB RAM (2x32GB) |
85| Storage (On-board) | Western Digital 500GB M.2 NVME SSD |
86| Storage (HDD Bay) | 48TB HDD |
87| PSU | Corsair RM850 PSU |
88
89** Networking Equipment
90
91- UDM-Pro
92- USW-24-PoE
93- USW-Lite-8-PoE
94- U6-Pro
95- U6-Extender
96- USP-Plug
97- UVC G4 Instant x 3
98- UVC G4 Doorbell Pro
99- UP Chime
100- USW 24-Port Patch Panel
101- USW Switch Lite 8 PoE
102
103* Software
104
105** Laptop
106
107Alpine 3.18.2; no DE.
108
109I currently run my Alpine laptop via the default login shell - no
110desktop environment. From here, I use a mix of byobu and emacs to split
111my screen into tabs and panes. All programs run through the shell and do
112not use visual libraries such as X or Wayland.
113
114I have Sway installed and configured, but only launch it when I must.
115
116- brightnessctl
117- byobu
118- emacs
119- [font-dejavu, font-noto, font-noto-cjk, font-noto-cjk-extra]
120- glances
121- gnupg
122- irssi
123- lynx
124- nano
125- neomutt
126- newsboat
127- ohmyzsh
128- [pango, pango-tools]
129- pipewire
130- syncthing
131- wireguard
132- zola
133- zsh
134
135** Server
136
137Ubuntu 22.04.1; no DE.
138
139See my services page for a list of the publicly-available services
140running on this server.
141
142- certbot
143- [docker, docker-compose]
144- nginx
145- zsh