diff options
author | Christian Cleberg <hello@cleberg.net> | 2024-09-01 22:03:26 -0500 |
---|---|---|
committer | Christian Cleberg <hello@cleberg.net> | 2024-09-01 22:03:26 -0500 |
commit | a0578880ef14f54647d7cfd96382395ab1e3cddb (patch) | |
tree | 3b48908939708db6580a90d99bf88ff045311e9d | |
parent | 17d0e7fa0f46eae4ef284af4593e33ad24da3bef (diff) | |
download | cleberg.net-a0578880ef14f54647d7cfd96382395ab1e3cddb.tar.gz cleberg.net-a0578880ef14f54647d7cfd96382395ab1e3cddb.tar.bz2 cleberg.net-a0578880ef14f54647d7cfd96382395ab1e3cddb.zip |
format 2024 blog posts
-rw-r--r-- | content/blog/2024-01-08-dont-say-hello.org | 32 | ||||
-rw-r--r-- | content/blog/2024-01-09-macos-customization.org | 120 | ||||
-rw-r--r-- | content/blog/2024-01-13-local-llm.org | 94 | ||||
-rw-r--r-- | content/blog/2024-01-26-audit-dashboard.org | 123 | ||||
-rw-r--r-- | content/blog/2024-01-27-tableau-dashboard.org | 89 | ||||
-rw-r--r-- | content/blog/2024-02-06-zfs.org | 122 | ||||
-rw-r--r-- | content/blog/2024-02-13-ubuntu-emergency-mode.org | 43 | ||||
-rw-r--r-- | content/blog/2024-02-21-self-hosting-otter-wiki.org | 37 | ||||
-rw-r--r-- | content/blog/2024-03-13-doom-emacs.org | 205 | ||||
-rw-r--r-- | content/blog/2024-03-15-self-hosting-ddns-updater.org | 93 | ||||
-rw-r--r-- | content/blog/2024-03-29-org-blog.org | 123 | ||||
-rw-r--r-- | content/blog/2024-04-06-convert-onenote-to-markdown.org | 88 | ||||
-rw-r--r-- | content/blog/2024-04-08-docker-local-web-server.org | 73 | ||||
-rw-r--r-- | content/blog/2024-04-18-mu4e.org | 78 | ||||
-rw-r--r-- | content/blog/2024-05-03-ubuntu-on-macos.org | 80 | ||||
-rw-r--r-- | content/blog/2024-06-19-deprecated-trusted-gpg-fix.org | 68 | ||||
-rw-r--r-- | content/blog/2024-07-11-emacs-on-ipad.org | 52 |
17 files changed, 700 insertions, 820 deletions
diff --git a/content/blog/2024-01-08-dont-say-hello.org b/content/blog/2024-01-08-dont-say-hello.org index b2926bf..eaeae61 100644 --- a/content/blog/2024-01-08-dont-say-hello.org +++ b/content/blog/2024-01-08-dont-say-hello.org @@ -3,25 +3,25 @@ #+description: #+slug: dont-say-hello -I recently came back from a winter break and have started working -again... only to immediately run into the dilemma of people sending me -cliffhanger messages again. +I recently came back from a winter break and have started working again... only +to immediately run into the dilemma of people sending me cliffhanger messages +again. * No Hello -A year or two ago, I discovered [[https://nohello.net/en/][no hello]] -and have thought about it often since then. I've even sent it to a few -people since then (who wouldn't take offense to it). +A year or two ago, I discovered [[https://nohello.net/en/][no hello]] and have thought about it often since +then. I've even sent it to a few people since then (who wouldn't take offense to +it). -I work in a fast-paced environment where efficiency is extremely -valuable. Therefore, I have always held a deep displeasure for -conversations where people start with "Hello" and then. +I work in a fast-paced environment where efficiency is extremely valuable. +Therefore, I have always held a deep displeasure for conversations where people +start with "Hello" and then. -I searched back through my work messages and found that I received ~50 -messages from ~10 people last year from people that contained "hi", -"hey", or "hello" and did not contain any indication of the purpose of -the conversation. I also noticed that a few of the users were -responsible for the large majority of the cliffhangers. +I searched back through my work messages and found that I received ~50 messages +from ~10 people last year from people that contained "hi", "hey", or "hello" and +did not contain any indication of the purpose of the conversation. I also +noticed that a few of the users were responsible for the large majority of the +cliffhangers. -There's no real point to this post, just a desparate request for people -to please stop doing this. +There's no real point to this post, just a desparate request for people to +please stop doing this. diff --git a/content/blog/2024-01-09-macos-customization.org b/content/blog/2024-01-09-macos-customization.org index 82fda5e..6fe3b9a 100644 --- a/content/blog/2024-01-09-macos-customization.org +++ b/content/blog/2024-01-09-macos-customization.org @@ -3,73 +3,65 @@ #+description: #+slug: macos-customization -I have been using macOS more than Linux lately, so I wrote this post to -describe some simple options to customize macOS beyond the normal -built-in settings menu. +I have been using macOS more than Linux lately, so I wrote this post to describe +some simple options to customize macOS beyond the normal built-in settings menu. -While not all-encompassing, the options below should be a good start for -anyone looking to dive down the rabbit hole. +While not all-encompassing, the options below should be a good start for anyone +looking to dive down the rabbit hole. * Basics ** Package Management -To install a lot of software on macOS, you will need -[[https://brew.sh/][Homebrew]]. You can use their installation script to -get started. Simply open the =Terminal= application and paste the -following snippet: +To install a lot of software on macOS, you will need [[https://brew.sh/][Homebrew]]. You can use their +installation script to get started. Simply open the =Terminal= application and +paste the following snippet: #+begin_src sh /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" #+end_src -This will allow you to easily install and manage applications and other -software easily through the =brew= command. +This will allow you to easily install and manage applications and other software +easily through the =brew= command. ** Terminal -If you're serious about customizing your macOS system, I highly -recommend installing a terminal emulator that you like and if you're not -comfortable on the command line yet, start learning. A lot of -customization options require you to edit hidden files, which is easiest -in a terminal. +If you're serious about customizing your macOS system, I highly recommend +installing a terminal emulator that you like and if you're not comfortable on +the command line yet, start learning. A lot of customization options require you +to edit hidden files, which is easiest in a terminal. -There are options like iTerm2, Kitty, Alacritty, Hyper, Warp, or the -built-in Terminal app. +There are options like iTerm2, Kitty, Alacritty, Hyper, Warp, or the built-in +Terminal app. -I use [[https://iterm2.com/][iTerm2]], which can be installed with -Homebrew: +I use [[https://iterm2.com/][iTerm2]], which can be installed with Homebrew: #+begin_src sh brew install iterm2 #+end_src -To install color schemes, such as the Dracula scheme, you visit -[[https://iterm2colorschemes.com/][iTerm Themes]] and follow their -installation instructions to install any of the themes. +To install color schemes, such as the Dracula scheme, you visit [[https://iterm2colorschemes.com/][iTerm Themes]] and +follow their installation instructions to install any of the themes. * Desktop ** Window Management -[[https://github.com/koekeishiya/yabai][yabai]] is a tiling window -manager for macOS. While other window managers exist, I found that most -of them struggled to create logical layouts and to allow me to easily -move windows around the screen. +[[https://github.com/koekeishiya/yabai][yabai]] is a tiling window manager for macOS. While other window managers exist, I +found that most of them struggled to create logical layouts and to allow me to +easily move windows around the screen. -Some advanced settings for yabai are only available if partially disable -System Integrity Protection (SIP). However, I chose not to do this and -it hasn't affected my basic usage of yabai at all. +Some advanced settings for yabai are only available if partially disable System +Integrity Protection (SIP). However, I chose not to do this and it hasn't +affected my basic usage of yabai at all. -Refer to the -[[https://github.com/koekeishiya/yabai/wiki/Installing-yabai-(latest-release)][yabai -wiki]] for installation instructions. You will need to ensure that yabai -is allowed to access the accessibility and screen recording APIs. +Refer to the [[https://github.com/koekeishiya/yabai/wiki/Installing-yabai-(latest-release)][yabai wiki]] for installation instructions. You will need to ensure +that yabai is allowed to access the accessibility and screen recording APIs. ** Keyboard Shortcuts -[[https://github.com/koekeishiya/skhd][skhd]] is a simple hotkey daemon -that allows you to define hotkeys in a file for usage on your system. +[[https://github.com/koekeishiya/skhd][skhd]] is a simple hotkey daemon that allows you to define hotkeys in a file for +usage on your system. Installation is simple: @@ -78,8 +70,8 @@ brew install koekeishiya/formulae/skhd skhd --start-service #+end_src -After installation, be sure to allow =skhd= access to the accessibility -API in the macOS privacy settings. +After installation, be sure to allow =skhd= access to the accessibility API in +the macOS privacy settings. You can configure your hotkeys in the =~/.config/skhd/skhdrc= file: @@ -99,53 +91,45 @@ cmd + shift - return : /Applications/LibreWolf.app/Contents/MacOS/librewolf ** Widgets -[[https://github.com/felixhageloh/uebersicht/][uebersicht]] is a handy -desktop-based widget tool with a plethora of community-made widgets -available in the [[https://tracesof.net/uebersicht-widgets/][widgets -gallery]]. You can also write your own widgets with this tool. +[[https://github.com/felixhageloh/uebersicht/][uebersicht]] is a handy desktop-based widget tool with a plethora of +community-made widgets available in the [[https://tracesof.net/uebersicht-widgets/][widgets gallery]]. You can also write your +own widgets with this tool. -To install, simply download the latest release from the -[[https://tracesof.net/uebersicht/][uebersicht website]] and copy it to -the Applications folder. +To install, simply download the latest release from the [[https://tracesof.net/uebersicht/][uebersicht website]] and +copy it to the Applications folder. -See below for an example of the -[[https://tracesof.net/uebersicht-widgets/#Mond][Mond]] widget in -action. +See below for an example of the [[https://tracesof.net/uebersicht-widgets/#Mond][Mond]] widget in action. ** Status Bar -[[https://github.com/FelixKratz/SketchyBar][SketchyBar]] is a -customizable replacement for the macOS status or menu bar. +[[https://github.com/FelixKratz/SketchyBar][SketchyBar]] is a customizable replacement for the macOS status or menu bar. -You can browse a discussion where various users shared their -[[https://github.com/FelixKratz/SketchyBar/discussions/47?sort=top][configurations]] -for inspiration or to copy their dotfiles. +You can browse a discussion where various users shared their [[https://github.com/FelixKratz/SketchyBar/discussions/47?sort=top][configurations]] for +inspiration or to copy their dotfiles. ** Dock -The easiest way to customize the dock is to install -[[https://ubarapp.com/][uBar]], which uses a Windows-like menu bar as -the default style. +The easiest way to customize the dock is to install [[https://ubarapp.com/][uBar]], which uses a +Windows-like menu bar as the default style. -However, the built-in macOS dock cannot be disabled and can only be set -to "always hidden". This can be annoying as it will pop out any time -your mouse cursor passes closely to the dock edge of the screen. Because -of this, I simply use the built-in dock instead of customizing it with -third-party software. +However, the built-in macOS dock cannot be disabled and can only be set to +"always hidden". This can be annoying as it will pop out any time your mouse +cursor passes closely to the dock edge of the screen. Because of this, I simply +use the built-in dock instead of customizing it with third-party software. Regardless, see below for the default installation style of uBar. ** Application Icons -You can also customize the icon of any application in macOS, which will -show up in Finder, the Dock, Launchpad, search results, etc. I recommend -using [[https://macosicons.com/][macOSicons]] to download icons you -want, and then apply them by following this process. +You can also customize the icon of any application in macOS, which will show up +in Finder, the Dock, Launchpad, search results, etc. I recommend using +[[https://macosicons.com/][macOSicons]] to download icons you want, and then apply them by following this +process. 1. Open the Finder application. 2. Navigate to the =Applications= folder. 3. Right-click an application of your choice, and select =Get Info=. -4. Drag the image you downloaded on top of the application's icon at the - top of information window (you will see a green "plus" symbol when - you're hovering over it). +4. Drag the image you downloaded on top of the application's icon at the top of + information window (you will see a green "plus" symbol when you're hovering + over it). 5. Release the new icon on top of the old icon and it will update! diff --git a/content/blog/2024-01-13-local-llm.org b/content/blog/2024-01-13-local-llm.org index d6f173b..0240d81 100644 --- a/content/blog/2024-01-13-local-llm.org +++ b/content/blog/2024-01-13-local-llm.org @@ -5,11 +5,10 @@ * Requirements -I've recently started playing with large language models (LLMs), mostly -in the popular chatbot form, as part of my job and have decided to see -if there's a consistent and reliable way to interact with these models -on Apple devices without sacrificing privacy or requiring in-depth -technical setup. +I've recently started playing with large language models (LLMs), mostly in the +popular chatbot form, as part of my job and have decided to see if there's a +consistent and reliable way to interact with these models on Apple devices +without sacrificing privacy or requiring in-depth technical setup. My requirements for this test: @@ -18,12 +17,12 @@ My requirements for this test: - Minimal required configuration - Preferably pre-built, but a simple build process is acceptable -I tested a handful of apps and have summarized my favorite (so far) for -macOS and iOS below. +I tested a handful of apps and have summarized my favorite (so far) for macOS +and iOS below. #+begin_quote -TL;DR - Here are the two that met my requirements and I have found the -easiest to install and use so far: +TL;DR - Here are the two that met my requirements and I have found the easiest +to install and use so far: #+end_quote - macOS: [[https://ollama.ai/][Ollama]] @@ -31,13 +30,12 @@ easiest to install and use so far: * macOS -[[https://ollama.ai/][Ollama]] is a simple Go application for macOS and -Linux that can run various LLMs locally. +[[https://ollama.ai/][Ollama]] is a simple Go application for macOS and Linux that can run various LLMs +locally. -For macOS, you can download the pplication on the -[[https://ollama.ai/download/mac][Ollama download page]] and install it -by unzipping the =Ollama.app= file and moving it to the =Applications= -folder. +For macOS, you can download the pplication on the [[https://ollama.ai/download/mac][Ollama download page]] and +install it by unzipping the =Ollama.app= file and moving it to the +=Applications= folder. If you prefer the command line, you can run these commands after the download finished: @@ -48,49 +46,43 @@ unzip Ollama-darwin.zip && \ mv ~/Downloads/Ollama.app /Applications/ #+end_src -After running the app, the app will ask you to open a terminal and run -the default =llama2= model, which will open an interactive chat session -in the terminal. You can startfully using the application at this point. +After running the app, the app will ask you to open a terminal and run the +default =llama2= model, which will open an interactive chat session in the +terminal. You can startfully using the application at this point. -If you don't want to use the default =llama2= model, you can download -and run additional models found on the -[[https://ollama.ai/library][Models]] page. +If you don't want to use the default =llama2= model, you can download and run +additional models found on the [[https://ollama.ai/library][Models]] page. To see the information for the currently-used model, you can run the =/show info= command in the chat. ** Community Integrations -I highly recommend browsing the -[[https://github.com/jmorganca/ollama#community-integrations][Community -Integrations]] section of the project to see how you would prefer to -extend Ollama beyond a simple command-line interface. There are options -for APIs, browser UIs, advanced terminal configurations, and more. +I highly recommend browsing the [[https://github.com/jmorganca/ollama#community-integrations][Community Integrations]] section of the project to +see how you would prefer to extend Ollama beyond a simple command-line +interface. There are options for APIs, browser UIs, advanced terminal +configurations, and more. * iOS -While there are a handful of decent macOS options, it was quite -difficult to find an iOS app that offered an open source platform -without an extensive configuration and building process. I found LLM -Farm to be decent enough in quality to sit at the top of my list - -however, it's definitely not user friendly enough for me to consider -using it on a daily basis. - -[[https://llmfarm.site/][LLM Farm]] is available on TestFlight, so -there's no manual build process required. However, you can view the -[[https://github.com/guinmoon/LLMFarm][LLMFarm repository]] if you wish. - -The caveat is that you will have to manually download the model files -from the links in the -[[https://github.com/guinmoon/LLMFarm/blob/main/models.md][models.md]] -file to your iPhone to use the app - there's currently no option in the -app to reach out and grab the latest version of any supported model. - -Once you have a file downloaded, you simply create a new chat and select -the downloaded model file and ensure the inference matches the -requirement in the =models.md= file. - -[[https://github.com/AugustDev/enchanted][Enchanted]] is also an iOS for -private AI models, but it requires a public-facing Ollama API, which did -not meet my "on device requirement." Nonetheless, it's an interesting -looking app and I will likely set it up to test soon. +While there are a handful of decent macOS options, it was quite difficult to +find an iOS app that offered an open source platform without an extensive +configuration and building process. I found LLM Farm to be decent enough in +quality to sit at the top of my list - however, it's definitely not user +friendly enough for me to consider using it on a daily basis. + +[[https://llmfarm.site/][LLM Farm]] is available on TestFlight, so there's no manual build process +required. However, you can view the [[https://github.com/guinmoon/LLMFarm][LLMFarm repository]] if you wish. + +The caveat is that you will have to manually download the model files from the +links in the [[https://github.com/guinmoon/LLMFarm/blob/main/models.md][models.md]] file to your iPhone to use the app - there's currently no +option in the app to reach out and grab the latest version of any supported +model. + +Once you have a file downloaded, you simply create a new chat and select the +downloaded model file and ensure the inference matches the requirement in the +=models.md= file. + +[[https://github.com/AugustDev/enchanted][Enchanted]] is also an iOS for private AI models, but it requires a public-facing +Ollama API, which did not meet my "on device requirement." Nonetheless, it's an +interesting looking app and I will likely set it up to test soon. diff --git a/content/blog/2024-01-26-audit-dashboard.org b/content/blog/2024-01-26-audit-dashboard.org index 6b165bf..e2c41ad 100644 --- a/content/blog/2024-01-26-audit-dashboard.org +++ b/content/blog/2024-01-26-audit-dashboard.org @@ -3,9 +3,9 @@ #+description: #+slug: audit-dashboard -Alteryx and Power BI are powerful tools that can help turn your -old-school audit trackers into interactive tools that provide useful -insights and potential action plans. +Alteryx and Power BI are powerful tools that can help turn your old-school audit +trackers into interactive tools that provide useful insights and potential +action plans. With these tools, we are going to build a dashboard that can effectively communicate project status. @@ -15,30 +15,28 @@ communicate project status. This project assumes the following: - You have access to Alteryx Designer and Power BI Desktop. - - If you only have Power BI Desktop, you may need to perform some - analysis in Power BI instead of Alteryx. -- Your data is in a format that can be imported into Alteryx and/or - Power BI. + - If you only have Power BI Desktop, you may need to perform some analysis in + Power BI instead of Alteryx. +- Your data is in a format that can be imported into Alteryx and/or Power BI. - You have a basic understanding of data types and visualization. * Alteryx: Data Preparation & Analysis ** Import Data -With Alteryx, importing data is easy with the use of the =Input Data= -tool. Simply drag this tool onto the canvas from the =In/Out= tab in the -Ribbon to create it as a node. +With Alteryx, importing data is easy with the use of the =Input Data= tool. +Simply drag this tool onto the canvas from the =In/Out= tab in the Ribbon to +create it as a node. -You can choose the File Format manually or simply connect to your -file/database and let Alteryx determine the format for you. For this -example, we will be importing an Excel file and changing the -=Start Data Import on Line= variable to =2=. +You can choose the File Format manually or simply connect to your file/database +and let Alteryx determine the format for you. For this example, we will be +importing an Excel file and changing the =Start Data Import on Line= variable to +=2=. ** Transform Data -Next, let's replace null data and remove whitespace to clean up our -data. We can do this with the =Data Cleansing= tool in the =Preparation= -tab in the Ribbon. +Next, let's replace null data and remove whitespace to clean up our data. We can +do this with the =Data Cleansing= tool in the =Preparation= tab in the Ribbon. Ensure that the following options are enabled: @@ -48,49 +46,48 @@ Ensure that the following options are enabled: - Remove Unwanted Characters - Leading and Trailing Whitespace -For our next step, we will transform the date fields from strings to -datetime format. Add a =Datetime= tool for each field you want to -transform - in the example below, I am using the tool twice for the -"Started On" and "Submitted On" fields. +For our next step, we will transform the date fields from strings to datetime +format. Add a =Datetime= tool for each field you want to transform - in the +example below, I am using the tool twice for the "Started On" and "Submitted On" +fields. -Now that the dates are in the correct format, let's perform a -calculation based on those fields. Start by adding a =Filter= tool, -naming a new Output Column, and pasting the formula below into it (the -two fields used in this formula must match the output of the =Datetime= -tools above): +Now that the dates are in the correct format, let's perform a calculation based +on those fields. Start by adding a =Filter= tool, naming a new Output Column, +and pasting the formula below into it (the two fields used in this formula must +match the output of the =Datetime= tools above): -``=txt DateTimeDiff([SubmittedOn_Out],[StartedOn_Out], "days")= +```txt +DateTimeDiff([SubmittedOn_Out],[StartedOn_Out], "days") +``` ** Export Data -Finalize the process by exporting the transformed data set to a new -file, for use in the following visualization step. +Finalize the process by exporting the transformed data set to a new file, for +use in the following visualization step. * Power BI: Data Visualization ** Import Data -To start, open the Power BI Desktop application. Upon first use, Power -BI will ask if you want to open an existing dashboard or import new -data. +To start, open the Power BI Desktop application. Upon first use, Power BI will +ask if you want to open an existing dashboard or import new data. -As we are creating our first dashboard, let's import our data. In my -example below, I'm importing data from the "Tracker" sheet of the Excel -file I'm using for this project. +As we are creating our first dashboard, let's import our data. In my example +below, I'm importing data from the "Tracker" sheet of the Excel file I'm using +for this project. -During this process, I also imported the export from the Alteryx -workflow above. Therefore, we have two different files available for use -in our dashboard. +During this process, I also imported the export from the Alteryx workflow above. +Therefore, we have two different files available for use in our dashboard. ** Add Visuals -To create the dashboard, you will need to follow the list instructions -below and format as needed. +To create the dashboard, you will need to follow the list instructions below and +format as needed. Instructions to create the visuals above: -- =Text Box=: Explain the name and purpose of the dashboard. You can - also add images and logos at the top of the dashboard. +- =Text Box=: Explain the name and purpose of the dashboard. You can also add + images and logos at the top of the dashboard. - =Donut Chart=: Overall status of the project. - =Legend=: Status - =Values=: Count of Status @@ -111,13 +108,12 @@ Instructions to create the visuals above: ** Format the Dashboard -You can choose a theme in the View tab of the Ribbon. You can even -browse for custom JSON files that define themes, such as ones found -online or custom ones created by your organization. +You can choose a theme in the View tab of the Ribbon. You can even browse for +custom JSON files that define themes, such as ones found online or custom ones +created by your organization. -For each visual, you can click the =Format= button in the -=Visualizations= side pane and explore the options. You can custom -options such as: +For each visual, you can click the =Format= button in the =Visualizations= side +pane and explore the options. You can custom options such as: - Visual - Legend @@ -132,22 +128,21 @@ options such as: - Tooltips - Alt text -You can always look online for inspiration when trying to decide how -best to organize and style your dashboard. +You can always look online for inspiration when trying to decide how best to +organize and style your dashboard. * Sharing the Results -Generally, you have a few different options for sharing your dashboards -with others: - -1. Export the dashboard as a PDF in the file menu of Power BI. This will - export all tabs and visuals as they are set when the export button is - pressed. You will lose all interactivity with this option. -2. Send the full Power BI file to those you wish to share the dashboard. - This will retain all settings and interactivity. However, you will - also need to send the source files if they need to refresh the - dashboard and you will need to re-send the files if you make updates. -3. Store the dashboard in a synced location, such as a shared drive or - Microsoft Teams. Depending on how a user configures their local - Windows paths, the data source paths may not be compatible for all - users with such a setup. +Generally, you have a few different options for sharing your dashboards with +others: + +1. Export the dashboard as a PDF in the file menu of Power BI. This will export + all tabs and visuals as they are set when the export button is pressed. You + will lose all interactivity with this option. +2. Send the full Power BI file to those you wish to share the dashboard. This + will retain all settings and interactivity. However, you will also need to + send the source files if they need to refresh the dashboard and you will need + to re-send the files if you make updates. +3. Store the dashboard in a synced location, such as a shared drive or Microsoft + Teams. Depending on how a user configures their local Windows paths, the data + source paths may not be compatible for all users with such a setup. diff --git a/content/blog/2024-01-27-tableau-dashboard.org b/content/blog/2024-01-27-tableau-dashboard.org index 7e0e078..f1efc36 100644 --- a/content/blog/2024-01-27-tableau-dashboard.org +++ b/content/blog/2024-01-27-tableau-dashboard.org @@ -3,14 +3,12 @@ #+description: #+slug: tableau-dashboard -In this project, I am going to show you how to use Tableau Public for -free to create simple dashboards. +In this project, I am going to show you how to use Tableau Public for free to +create simple dashboards. -I will be creating simple visuals from an Omaha crime data set and -combining them to create the dashboard below. You can view this -dashboard interactively online here: -[[https://public.tableau.com/app/profile/c.c7042/viz/OmahaCrimeData2015-2023/OmahaCrimeData2015-2023#1][Omaha -Crime Data (2015 - 2023)]]. +I will be creating simple visuals from an Omaha crime data set and combining +them to create the dashboard below. You can view this dashboard interactively +online here: [[https://public.tableau.com/app/profile/c.c7042/viz/OmahaCrimeData2015-2023/OmahaCrimeData2015-2023#1][Omaha Crime Data (2015 - 2023)]]. #+caption: Tableau Dashboard [[https://img.cleberg.net/blog/20240127-tableau-dashboard/dashboard.png]] @@ -18,18 +16,17 @@ Crime Data (2015 - 2023)]]. * Gather the Data You can download incident data from the Omaha Police Department on their -[[https://police.cityofomaha.org/crime-information/incident-data-download][Incident -Data Download]] page. They currently have files for the years 2015 +[[https://police.cityofomaha.org/crime-information/incident-data-download][Incident Data Download]] page. They currently have files for the years 2015 through 2023. Each file will be downloaded as a CSV file, approximately 3 MB - 8 MB. * Clean and Transform the Data -I have used Python to combine the files into a single CSV file, as well -as adding a custom =datetime= column. You could do this step in any -software you prefer, but I prefer Python as its free, easy to use, and -has a plethora of support resources online. +I have used Python to combine the files into a single CSV file, as well as +adding a custom =datetime= column. You could do this step in any software you +prefer, but I prefer Python as its free, easy to use, and has a plethora of +support resources online. Start by opening a terminal, navigating to your Downloads directory, and creating a python script. @@ -76,38 +73,37 @@ Once pasted, save and close the file. You can execute the file like so: python3 data_processing.py #+end_src -After this, you should have a combined data file that contains all -incidents between 2015 and 2023. Mine was approximately 55 MB. +After this, you should have a combined data file that contains all incidents +between 2015 and 2023. Mine was approximately 55 MB. * Tableau Public -[[https://public.tableau.com/][Tableau Public]] is a free-to-use web -application that allows you to create visualizations by uploading data -sources. Note that there's no way to keep the data and visualizations -private, so don't upload anything private. +[[https://public.tableau.com/][Tableau Public]] is a free-to-use web application that allows you to create +visualizations by uploading data sources. Note that there's no way to keep the +data and visualizations private, so don't upload anything private. -After creating an account, you can click the =Create= > =Web Authoring= -link to create your first visualization. +After creating an account, you can click the =Create= > =Web Authoring= link to +create your first visualization. ** Upload the Data -Once you've opened your first project, Tableau will ask you to connect -to your data. For this project, click the =Upload from computer= button -and select the CSV file previously combined in the step above. +Once you've opened your first project, Tableau will ask you to connect to your +data. For this project, click the =Upload from computer= button and select the +CSV file previously combined in the step above. -Once connected, you can refresh the preview of the data with the -=Refresh Data Source= button in the toolbar. +Once connected, you can refresh the preview of the data with the =Refresh Data +Source= button in the toolbar. -If you need to edit any of the data types, column names, etc., you can -do so now. Once complete, generate an extract so that you can start -creating visualizations. +If you need to edit any of the data types, column names, etc., you can do so +now. Once complete, generate an extract so that you can start creating +visualizations. ** Create Visualizations To start, create a worksheet in the toolbar at the bottom of the screen. -Within this screen, select a column from the =Data= side bar on the left -and drag it into the =Columns= or =Rows= area of the canvas. +Within this screen, select a column from the =Data= side bar on the left and +drag it into the =Columns= or =Rows= area of the canvas. See below for the map visualization. You can recreate this by adding the following fields: @@ -119,30 +115,29 @@ following fields: - Datetime - =Filters=: Datetime -You can repeat this process for each visualization you want to create. -Explore your options by dragging data fields to different areas and by -opening the field options to explore what operations can be performed on -different data types (e.g., average, count, etc.). +You can repeat this process for each visualization you want to create. Explore +your options by dragging data fields to different areas and by opening the field +options to explore what operations can be performed on different data types +(e.g., average, count, etc.). ** Create Dashboard -To create a dashboard, click the button on the toolbar at the bottom of -the screen. Within the dashboard, drag each sheet from the left side bar -onto the dashboard canvas. +To create a dashboard, click the button on the toolbar at the bottom of the +screen. Within the dashboard, drag each sheet from the left side bar onto the +dashboard canvas. ** Formatting -You can explore a ton of different formatting options throughout the -worksheets and dashboard. Specifically for maps, you can alter the map -layers, background, and visible features through the =Map= menu in the -top file menu of the editing screen. +You can explore a ton of different formatting options throughout the worksheets +and dashboard. Specifically for maps, you can alter the map layers, background, +and visible features through the =Map= menu in the top file menu of the editing +screen. -In the finished dashboard below, I opted for a dark mode with a map that -showed county lines and city names. +In the finished dashboard below, I opted for a dark mode with a map that showed +county lines and city names. -There's a ton of other options available to be used in a dashboard like -this, but this project shows a quick preview of what you can do in -Tableau Public. +There's a ton of other options available to be used in a dashboard like this, +but this project shows a quick preview of what you can do in Tableau Public. #+caption: Tableau Dashboard [[https://img.cleberg.net/blog/20240127-tableau-dashboard/dashboard.png]] diff --git a/content/blog/2024-02-06-zfs.org b/content/blog/2024-02-06-zfs.org index 410b030..a870a2c 100644 --- a/content/blog/2024-02-06-zfs.org +++ b/content/blog/2024-02-06-zfs.org @@ -6,14 +6,11 @@ This post details the process I used to create ZFS pools, datasets, and snapshots on Ubuntu Server. -I found the following pages very helpful while going through this -process: +I found the following pages very helpful while going through this process: -- [[https://ubuntu.com/tutorials/setup-zfs-storage-pool][Setup a ZFS - storage pool]] +- [[https://ubuntu.com/tutorials/setup-zfs-storage-pool][Setup a ZFS storage pool]] - [[https://wiki.ubuntu.com/Kernel/Reference/ZFS][Kernel/Reference/ZFS]] -- [[https://blog.victormendonca.com/2020/11/03/zfs-for-dummies/][ZFS for - Dummies]] +- [[https://blog.victormendonca.com/2020/11/03/zfs-for-dummies/][ZFS for Dummies]] * Installation @@ -23,8 +20,7 @@ To start, I installed the ZFS package with the following command: sudo apt install zfsutils-linux #+end_src -Once installed, you can check the version to see if it installed -correctly. +Once installed, you can check the version to see if it installed correctly. #+begin_src sh > zsf --version @@ -37,9 +33,9 @@ zfs-kmod-2.1.5-1ubuntu6~22.04.1 Now that ZFS is installed, we can create and configure the pool. -You have various options for configuring ZFS pools that all come -different pros and cons. I suggest visiting the links at the top of this -post or searching online for the best configuration for your use-case. +You have various options for configuring ZFS pools that all come different pros +and cons. I suggest visiting the links at the top of this post or searching +online for the best configuration for your use-case. - Striped VDEVs (Raid0) - Mirrored VDEVs (Raid1) @@ -49,20 +45,20 @@ post or searching online for the best configuration for your use-case. - RAIDz3 - Nested RAIDz (Raid50, Raid60) -I will be using Raid10 in this guide. However, the majority of the steps -are the same regardless of your chosen pool configuration. +I will be using Raid10 in this guide. However, the majority of the steps are the +same regardless of your chosen pool configuration. ** Creating the Pool -To start, let's list the disks available to use. You can use =fdisk= -command to see all available disks. +To start, let's list the disks available to use. You can use =fdisk= command to +see all available disks. #+begin_src sh sudo fdisk -l #+end_src -Or, if you currently have them mounted, you can use the =df= command to -view your disks. +Or, if you currently have them mounted, you can use the =df= command to view +your disks. #+begin_src sh > sudo df -h @@ -77,17 +73,16 @@ Filesystem Size Used Avail Use% Mounted on /dev/sdf1 7.3T 28K 6.9T 1% /mnt/red-04 #+end_src -If you're going to use mounted disks, make sure to umount them before -creating the pool. +If you're going to use mounted disks, make sure to umount them before creating +the pool. #+begin_src sh sudo umount /dev/sda1 sudo umount /dev/sdb1 #+end_src -Now that I've identified the disks I want to use and have them -unmounted, let's create the pool. For this example, I will call it -=tank=. +Now that I've identified the disks I want to use and have them unmounted, let's +create the pool. For this example, I will call it =tank=. #+begin_src sh sudo zpool create -f -m /mnt/pool tank mirror /dev/sda /dev/sdb @@ -119,8 +114,8 @@ config: errors: No known data errors #+end_src -We can also look at the mounted filesystem to see where the pool is -mounted and some quick stats. +We can also look at the mounted filesystem to see where the pool is mounted and +some quick stats. #+begin_src sh > df -h @@ -132,28 +127,25 @@ tank 7.2T 128K 7.2T 1% /tank ** Expanding the Pool -If you want to expand this pool, you will need to add a new VDEV to the -pool. Since I am using 2 disks per VDEV, I will need to add a new 2-disk -VDEV to the existing =tank= pool. +If you want to expand this pool, you will need to add a new VDEV to the pool. +Since I am using 2 disks per VDEV, I will need to add a new 2-disk VDEV to the +existing =tank= pool. #+begin_src sh sudo zpool add tank mirror /dev/sdX /dev/sdY #+end_src -If you're adding disks of different sizes, you'll need to use the =-f= -flag. Keep in mind that the max size will be limited to the smallest -disk added. +If you're adding disks of different sizes, you'll need to use the =-f= flag. +Keep in mind that the max size will be limited to the smallest disk added. #+begin_src sh sudo zpool add -f tank mirror /dev/sdX /dev/sdY #+end_src -I added two 8TB hard drives and this process took around 10 seconds to -complete. +I added two 8TB hard drives and this process took around 10 seconds to complete. -When viewing the pool again, you can see that the pool has now doubled -in size. We have 14.3 TB useable space and the same space used for -mirroring. +When viewing the pool again, you can see that the pool has now doubled in size. +We have 14.3 TB useable space and the same space used for mirroring. #+begin_src sh > zfs list @@ -166,8 +158,8 @@ tank/media 96K 14.3T 96K /tank/media *** Converting Disks -Some disks, such as NTFS-formatted drives, will need to be partitioned -and formatted prior to being added to the pool. +Some disks, such as NTFS-formatted drives, will need to be partitioned and +formatted prior to being added to the pool. Start by identifying the disks you want to format and add to the pool. @@ -178,8 +170,8 @@ sudo fdisk -l | grep /dev I am going to format my =/dev/sdc= and =/dev/sdd= disks with the =fdisk= command. -See below for instructions on how to use =fdisk=. Here's what I did to -create basic Linux formatted disks: +See below for instructions on how to use =fdisk=. Here's what I did to create +basic Linux formatted disks: - =g= : Create GPT partition table - =n= : Create a new partition, hit Enter for all default options @@ -191,13 +183,12 @@ I repeated this process for both disks. #+begin_src sh > sudo fdisk /dev/sdc -Welcome to fdisk (util-linux 2.37.2). -Changes will remain in memory only, until you decide to write them. -Be careful before using the write command. +Welcome to fdisk (util-linux 2.37.2). Changes will remain in memory only, until +you decide to write them. Be careful before using the write command. -This disk is currently in use - repartitioning is probably a bad idea. -It's recommended to umount all file systems, and swapoff all swap -partitions on this disk. +This disk is currently in use - repartitioning is probably a bad idea. It's +recommended to umount all file systems, and swapoff all swap partitions on this +disk. Command (m for help): m @@ -243,9 +234,9 @@ sudo zpool add tank mirror /dev/sdc /dev/sdd #+end_src When we list the pool again, we can see that our size is now updated to -approximately 22TB. This represents my hard drives totalling 45.6TB when -shown with =fdisk -l=, with a Raid10 configuration using 22TB for -mirroring and 22TB of useable space. +approximately 22TB. This represents my hard drives totalling 45.6TB when shown +with =fdisk -l=, with a Raid10 configuration using 22TB for mirroring and 22TB +of useable space. #+begin_src sh > zfs list @@ -258,17 +249,15 @@ tank/media 145GT 21.7T 96K /tank/media ** Creating Datasets -According to -[[https://docs.oracle.com/cd/E18752_01/html/819-5461/ftyue.html][ZFS -Terminology]], a =dataset= can refer to “clones, file systems, +According to [[https://docs.oracle.com/cd/E18752_01/html/819-5461/ftyue.html][ZFS Terminology]], a =dataset= can refer to “clones, file systems, snapshots, and volumes. -For this guide, I will use the =dataset= term to refer to file systems -created under a pool. +For this guide, I will use the =dataset= term to refer to file systems created +under a pool. -Within my =tank= pool, I am going to create some datasets to help -organize my files. This will give me location to store data rather than -simply dumping everything at the =/tank/= location. +Within my =tank= pool, I am going to create some datasets to help organize my +files. This will give me location to store data rather than simply dumping +everything at the =/tank/= location. #+begin_src sh sudo zfs create tank/cloud @@ -288,9 +277,9 @@ tank/media 96K 7.14T 96K /tank/media ** Creating Snapshots -Next, let's create our first snapshot. We can do this by calling the -=snapshot= command and give it an output name. I will be throwing the -current date and time into my example. +Next, let's create our first snapshot. We can do this by calling the =snapshot= +command and give it an output name. I will be throwing the current date and time +into my example. #+begin_src sh sudo zfs snapshot tank@$(date '+%Y-%m-%d_%H-%M') @@ -321,13 +310,10 @@ no datasets available * My Thoughts on ZFS So Far -- I sacrificed 25TB to be able to mirror my data, but I feel more - comfortable with the potential to save my data by quickly replacing a - disk if I need to. +- I sacrificed 25TB to be able to mirror my data, but I feel more comfortable + with the potential to save my data by quickly replacing a disk if I need to. - The set-up was surprisingly easy and fast. -- Disk I/O is fast as well. I was worried that the data transfer speeds - would be slower due to the RAID configuration. -- Media streaming and transcoding has seen no noticeable drop in - performance. -- My only limitation really is the number of HDD bays in my server HDD - cage. +- Disk I/O is fast as well. I was worried that the data transfer speeds would be + slower due to the RAID configuration. +- Media streaming and transcoding has seen no noticeable drop in performance. +- My only limitation really is the number of HDD bays in my server HDD cage. diff --git a/content/blog/2024-02-13-ubuntu-emergency-mode.org b/content/blog/2024-02-13-ubuntu-emergency-mode.org index e910468..e02c6ec 100644 --- a/content/blog/2024-02-13-ubuntu-emergency-mode.org +++ b/content/blog/2024-02-13-ubuntu-emergency-mode.org @@ -5,12 +5,12 @@ * The Problem -I recently [[../zfs/][migrated my hard drives to a ZFS pool]] and found -myself stuck in Ubuntu's emergency mode after the first reboot I -performed after creating the ZFS pool. +I recently [[../zfs/][migrated my hard drives to a ZFS pool]] and found myself stuck in +Ubuntu's emergency mode after the first reboot I performed after creating the +ZFS pool. -My server was stuck in the boot process and showed the following error -on the screen: +My server was stuck in the boot process and showed the following error on the +screen: #+begin_src txt You are in emergency mode. @@ -19,34 +19,33 @@ After logging in, type "journalctl -xb" to view system logs, or ^D to try again to boot into default mode". #+end_src -After rebooting the server and watching the logs scroll on a monitor, I -noticed the root cause was related to a very long search for certain -drives. I kept seeing errors like this: +After rebooting the server and watching the logs scroll on a monitor, I noticed +the root cause was related to a very long search for certain drives. I kept +seeing errors like this: #+begin_src txt [ TIME ] Timed out waiting of device dev-disk-by/[disk-uuid] #+end_src -I realized that I had not removed the =/etc/fstab= references that asked -Ubuntu to mount two disks on boot, but I had recently changed those -disks to be part of my ZFS pool instead. Therefore, Ubuntu was trying to -identify and mount a disk that was not available. +I realized that I had not removed the =/etc/fstab= references that asked Ubuntu +to mount two disks on boot, but I had recently changed those disks to be part of +my ZFS pool instead. Therefore, Ubuntu was trying to identify and mount a disk +that was not available. Now that we have an idea of the issue, let's move to solution. * The Solution -In order to fix the issue, I waited until I was allowed to type the root -user's password, and then I executed the following command: +In order to fix the issue, I waited until I was allowed to type the root user's +password, and then I executed the following command: #+begin_src sh nano /etc/fstab #+end_src -Within the =fstab= file, I needed to comment/remove the following lines -at the bottom of the file. You can comment-out a line by prepending a -=#= symbol at the beginning of the line. You can also delete the line -entirely. +Within the =fstab= file, I needed to comment/remove the following lines at the +bottom of the file. You can comment-out a line by prepending a =#= symbol at the +beginning of the line. You can also delete the line entirely. #+begin_src conf # What it looked like when running into the issue: @@ -58,8 +57,8 @@ UUID=E69867E59867B32B /mnt/white-02 ntfs-3g uid=1000,gid=1000 0 0 # UUID=E69867E59867B32B /mnt/white-02 ntfs-3g uid=1000,gid=1000 0 0 #+end_src -Once removing the lines above from the =/etc/fstab= file, save and exit -the file by hitting the =Ctrl= + =x= key combo. +Once removing the lines above from the =/etc/fstab= file, save and exit the file +by hitting the =Ctrl= + =x= key combo. You can now hit =Ctrl= + =D= to continue, or reboot: @@ -67,5 +66,5 @@ You can now hit =Ctrl= + =D= to continue, or reboot: systemctl reboot #+end_src -Once rebooted, I was able to watch the machine boot properly and launch -to the TTY login screen without errors! +Once rebooted, I was able to watch the machine boot properly and launch to the +TTY login screen without errors! diff --git a/content/blog/2024-02-21-self-hosting-otter-wiki.org b/content/blog/2024-02-21-self-hosting-otter-wiki.org index b682db7..844396c 100644 --- a/content/blog/2024-02-21-self-hosting-otter-wiki.org +++ b/content/blog/2024-02-21-self-hosting-otter-wiki.org @@ -5,14 +5,14 @@ * An Otter Wiki -[[https://otterwiki.com/][An Otter Wiki]] is an easy to use wiki -software that takes almost no effort to set up and maintain. +[[https://otterwiki.com/][An Otter Wiki]] is an easy to use wiki software that takes almost no effort to set +up and maintain. * Installation To install An Otter Wiki, I'm going to use Docker Compose to create the -container and then use Nginx as a reverse proxy to allow external access -via a subdomain I own. +container and then use Nginx as a reverse proxy to allow external access via a +subdomain I own. ** Docker Compose @@ -22,16 +22,14 @@ Start by creating a directory for the container's files. mkdir ~/otterwiki #+end_src -Next, create the =docker-compose.yml= file to define the container's -parameters. +Next, create the =docker-compose.yml= file to define the container's parameters. #+begin_src sh nano ~/otterwiki/docker-compose.yml #+end_src Within the file, paste the following content. You can read the project's -documentation if you want to further override or customize the -container. +documentation if you want to further override or customize the container. #+begin_src conf version: '3' @@ -54,22 +52,22 @@ cd ~/otterwiki sudo docker-compose up -d #+end_src -The container is now available at =localhost:8337=. Next, we will use -Nginx to serve this app externally. +The container is now available at =localhost:8337=. Next, we will use Nginx to +serve this app externally. ** Nginx -To access the app externally, let's set up a reverse proxy. I'll start -by creating the Nginx configuration file for my wiki. +To access the app externally, let's set up a reverse proxy. I'll start by +creating the Nginx configuration file for my wiki. #+begin_src sh sudo nano /etc/nginx/sites-available/wiki #+end_src -Within the file, I have saved the following content. This assumes you -already have a TLS/SSL cert to use with this subdomain. If not, simply -remove the =ssl_*= variables, remove the =80= server block, and change -the =443= server block to =80= to serve the app without SSL. +Within the file, I have saved the following content. This assumes you already +have a TLS/SSL cert to use with this subdomain. If not, simply remove the +=ssl_*= variables, remove the =80= server block, and change the =443= server +block to =80= to serve the app without SSL. #+begin_src conf server { @@ -107,15 +105,14 @@ server { } #+end_src -Save and close the configuration file. On Nginx, we need to symlink the -file to enable it. +Save and close the configuration file. On Nginx, we need to symlink the file to +enable it. #+begin_src sh sudo ln -s /etc/nginx/sites-available/wiki /etc/nginx/sites-enabled/wiki #+end_src -Once enabled, restart the Nginx server to start serving the app -externally. +Once enabled, restart the Nginx server to start serving the app externally. #+begin_src sh sudo systemctl restart nginx.service diff --git a/content/blog/2024-03-13-doom-emacs.org b/content/blog/2024-03-13-doom-emacs.org index 96b22be..d4f0c19 100644 --- a/content/blog/2024-03-13-doom-emacs.org +++ b/content/blog/2024-03-13-doom-emacs.org @@ -5,9 +5,9 @@ ** Screenshots -These screenshots are showing a project opened with projectile, a -treemacs side pane open with the project contents, multiple buffers -tiled next to each other, and the help pane open at the bottomm. +These screenshots are showing a project opened with projectile, a treemacs side +pane open with the project contents, multiple buffers tiled next to each other, +and the help pane open at the bottomm. The themes are =doom-homage-white= and =doom-homage-black=. @@ -19,44 +19,35 @@ The themes are =doom-homage-white= and =doom-homage-black=. ** Getting Started -I have been switching back and forth between -[[https://en.wikipedia.org/wiki/Markdown][markdown]] and -[[https://en.wikipedia.org/wiki/Org-mode][org-mode]] recently for my -personal note taking, wiki, and even this blog. As a result, I have been -stumbling further into the world of Emacs and found myself at a point -where I now prefer to do most of my basic editing within Emacs. +I have been switching back and forth between [[https://en.wikipedia.org/wiki/Markdown][markdown]] and [[https://en.wikipedia.org/wiki/Org-mode][org-mode]] recently for +my personal note taking, wiki, and even this blog. As a result, I have been +stumbling further into the world of Emacs and found myself at a point where I +now prefer to do most of my basic editing within Emacs. I'll leave the markdown vs. org-mode debate for another post, but I love -org-mode's extensibility and interactive nature within Emacs, but it -becomes very unwieldy in any other client implementation of org-mode - -especially on iOS. On the flip side, markdown is limited in -functionality and fractured into different standards, but it's simple -and popular enough that there are a plethora of great clients to choose -from that will get the job done. +org-mode's extensibility and interactive nature within Emacs, but it becomes +very unwieldy in any other client implementation of org-mode - especially on +iOS. On the flip side, markdown is limited in functionality and fractured into +different standards, but it's simple and popular enough that there are a +plethora of great clients to choose from that will get the job done. -For now, I want to focus on how I have been using Emacs and some of the -things that would have helped me learn it faster had I known where to -start. +For now, I want to focus on how I have been using Emacs and some of the things +that would have helped me learn it faster had I known where to start. *** Installation -This post focuses on [[https://github.com/doomemacs/doomemacs][Doom -Emacs]], which is an Emacs framework that provides an alternative -experience to the vanilla [[https://www.gnu.org/software/emacs/][GNU -Emacs]]. +This post focuses on [[https://github.com/doomemacs/doomemacs][Doom Emacs]], which is an Emacs framework that provides an +alternative experience to the vanilla [[https://www.gnu.org/software/emacs/][GNU Emacs]]. -The -[[https://github.com/doomemacs/doomemacs/blob/master/docs/getting_started.org][Getting -Start Guide]] has an extremely detailed walkthrough of installation for -all systems, so please refer to that guide for up-to-date instructions. +The [[https://github.com/doomemacs/doomemacs/blob/master/docs/getting_started.org][Getting Start Guide]] has an extremely detailed walkthrough of installation +for all systems, so please refer to that guide for up-to-date instructions. I chose to install on macOS, using the Homebrew option with the =railwaycat/emacsmacport= version of Emacs. -Once the program is installed, you can run the program by typing =emacs= -in a terminal. If you installed a version of Emacs that supports both a -GUI and TUI, you will have to run =emacs -nw= to get the TUI instead of -the default GUI. +Once the program is installed, you can run the program by typing =emacs= in a +terminal. If you installed a version of Emacs that supports both a GUI and TUI, +you will have to run =emacs -nw= to get the TUI instead of the default GUI. *** Configuration @@ -65,13 +56,12 @@ Once installed, you can configure Doom by editing the files within the 1. =config.el= - Personal configuration file 2. =custom.el= - Custom set variables -3. =init.el= - Doom modules and load order, must run =doom sync= after - modifying -4. =packages.el= - Declare packages to install in this file, then run - =doom sync= to install +3. =init.el= - Doom modules and load order, must run =doom sync= after modifying +4. =packages.el= - Declare packages to install in this file, then run =doom + sync= to install -I only needed a few customizations for my configuration, so I'll list -them below. +I only needed a few customizations for my configuration, so I'll list them +below. #+begin_src lisp ;; ~/.doom.d/config.el @@ -145,30 +135,28 @@ them below. (default +bindings +smartparens)) #+end_src -If you're editing these files within Doom directly, remember to run -=SPC h r r= to reload the configuration. Also remember to run -=doom sync= for any changes to the =init.el= or =packages.el= files. +If you're editing these files within Doom directly, remember to run =SPC h r r= +to reload the configuration. Also remember to run =doom sync= for any changes to +the =init.el= or =packages.el= files. ** Basic Functionality -I kept a cheat sheet note open at first with all of the basic functions -typed out, copied as I went through the tutorial. After a little while, -I no longer needed it. I highly recommend writing down the most -applicable shortcuts for your preferred functionality and refer back to -it until you've memorized it. - -Memorizing the shortcuts will differ based on the type of Emacs -framework being used. Personally, migrating from vanilla Emacs to Doom -Emacs simplified everything by a large factor and instantly enabled me -to start working on my projects, eliminating most of the hurdles I was -running into. The vanilla emacs hotkeys became obnoxious and I actually -stopped using Emacs entirely for about a month before trying Doom. - -For me, the first logical step is to interact with the local filesystem. -To do this, I needed to know how to open directories, open files, save -files, discard changes, close files, and switch between open files. Here -are some example shortcuts I've written down in order to accomplish -file-based actions. +I kept a cheat sheet note open at first with all of the basic functions typed +out, copied as I went through the tutorial. After a little while, I no longer +needed it. I highly recommend writing down the most applicable shortcuts for +your preferred functionality and refer back to it until you've memorized it. + +Memorizing the shortcuts will differ based on the type of Emacs framework being +used. Personally, migrating from vanilla Emacs to Doom Emacs simplified +everything by a large factor and instantly enabled me to start working on my +projects, eliminating most of the hurdles I was running into. The vanilla emacs +hotkeys became obnoxious and I actually stopped using Emacs entirely for about a +month before trying Doom. + +For me, the first logical step is to interact with the local filesystem. To do +this, I needed to know how to open directories, open files, save files, discard +changes, close files, and switch between open files. Here are some example +shortcuts I've written down in order to accomplish file-based actions. | Doom Hotkey | Emacs Hotkey | Description | |-----------------+---------------+----------------------------------------| @@ -181,30 +169,28 @@ file-based actions. | =SPC b k= | =C-x k= | Kill current buffer | | =SPC w h/j/k/l= | =C-x o=[fn:2] | Move left/down/up/right to next buffer | -In general, when in Doom, you can press =SPC= and wait a second for the -help pane to appear with all available hotkey options. For example, you -can press =SPC=, wait for the help pane, and then select a key such as -=g= to enter the git help pane and explore further command options. +In general, when in Doom, you can press =SPC= and wait a second for the help +pane to appear with all available hotkey options. For example, you can press +=SPC=, wait for the help pane, and then select a key such as =g= to enter the +git help pane and explore further command options. ** Editing -Next in my process is to dive into editing for any languages I'm -currently using. In this post, I will just cover Markdown and Org-Mode -but I have also been slowly adoping some Python and general web dev -tools as well. +Next in my process is to dive into editing for any languages I'm currently +using. In this post, I will just cover Markdown and Org-Mode but I have also +been slowly adoping some Python and general web dev tools as well. *** Markdown #+caption: Markdown Preview [[https://img.cleberg.net/blog/20240314-doom-emacs/markdown.png]] -Markdown is fairly simple as the syntax is limited, so just make sure -the =~/.doom.d/init.el= includes the =markdown= declaration in the -=:lang= section. +Markdown is fairly simple as the syntax is limited, so just make sure the +=~/.doom.d/init.el= includes the =markdown= declaration in the =:lang= section. -This package includes the following hotkey menus. The insert and toggle -menu expands further, allowing you to insert various markdown elements -and toggle things like link hiding. +This package includes the following hotkey menus. The insert and toggle menu +expands further, allowing you to insert various markdown elements and toggle +things like link hiding. | Doom Hotkey | Function | |------------------------------+--------------------------| @@ -221,14 +207,12 @@ and toggle things like link hiding. #+caption: Org-Mode Preview [[https://img.cleberg.net/blog/20240314-doom-emacs/org.png]] -Similar to the markdown section above, ensure that the -=~/.doom.d/init.el= includes the =org= declaration in the =:lang= -section. +Similar to the markdown section above, ensure that the =~/.doom.d/init.el= +includes the =org= declaration in the =:lang= section. -There are a few hot keys, but a quick search with =SPC : org= shows that -there are 865 possible org-related functions you can run. I won't -possibly be able to list them all, so I will simply cover a few of the -basic commands I use myself. +There are a few hot keys, but a quick search with =SPC : org= shows that there +are 865 possible org-related functions you can run. I won't possibly be able to +list them all, so I will simply cover a few of the basic commands I use myself. | Doom Hotkey | Function | |----------------+---------------------------------------| @@ -246,32 +230,28 @@ basic commands I use myself. 1. Org-Publish - Org includes a - [[https://orgmode.org/manual/Publishing.html][publishing management - system]] by default that allows you to export org files to Org, - iCalendar, HTML, LaTex, Markdown, ODT, and Plain Text. Most of these - can be exported into another buffer and opened, or simply to an - external file. + Org includes a [[https://orgmode.org/manual/Publishing.html][publishing management system]] by default that allows you to + export org files to Org, iCalendar, HTML, LaTex, Markdown, ODT, and Plain + Text. Most of these can be exported into another buffer and opened, or simply + to an external file. - While inside an org file, simply run =SPC m e= or - =M-x org-export-dispatch= to open the export menu. This menu will - show all options and ask you to select an option. If you want to - export to HTML, simply press =h= and then =H= (As HTML buffer), =h= - (As HTML file), or =o= (As HTML file and open). + While inside an org file, simply run =SPC m e= or =M-x org-export-dispatch= + to open the export menu. This menu will show all options and ask you to + select an option. If you want to export to HTML, simply press =h= and then + =H= (As HTML buffer), =h= (As HTML file), or =o= (As HTML file and open). 2. Projects - Some publishing options are easier with a defined project in Emacs. - To create a project within Emacs, I use two methods: + Some publishing options are easier with a defined project in Emacs. To create + a project within Emacs, I use two methods: - 1. Add the project via the projectile command =SPC p a=. Does not - always work for me. + 1. Add the project via the projectile command =SPC p a=. Does not always work + for me. 2. Add an empty =.projectile= file in the project root. - Once a project has been created, you can create custom publishing - actions within your =~/.doom.d/config.el= file. For example, here's a - test project I created to try and convert this blog to org-mode - recently. + Once a project has been created, you can create custom publishing actions + within your =~/.doom.d/config.el= file. For example, here's a test project I + created to try and convert this blog to org-mode recently. #+begin_src lisp ;; org-publish @@ -342,19 +322,18 @@ basic commands I use myself. ** General Thoughts -I have enjoyed Doom Emacs (far more than GNU Emacs) and will likely -continue to use it as my main editor for the time being. Org-Mode is -certainly the largest factor here, as I far prefer it over Markdown due -to its inherent features and detailed markup options. However, working -with org-mode on iOS has been a pain and I will have to see if there's -an easier way to resolve those issues or if going back to separate -Markdown, Reminders, and Calendar apps is easier to work with than an -all-in-one org solution. - -[fn:1] Doom's evil-window functionality is a bit different from GNU - Emacs, but you can always switch to the "other" buffer with - =C-x o= or =C-x b= to get a list of buffers to select. - -[fn:2] Doom's evil-window functionality is a bit different from GNU - Emacs, but you can always switch to the "other" buffer with - =C-x o= or =C-x b= to get a list of buffers to select. +I have enjoyed Doom Emacs (far more than GNU Emacs) and will likely continue to +use it as my main editor for the time being. Org-Mode is certainly the largest +factor here, as I far prefer it over Markdown due to its inherent features and +detailed markup options. However, working with org-mode on iOS has been a pain +and I will have to see if there's an easier way to resolve those issues or if +going back to separate Markdown, Reminders, and Calendar apps is easier to work +with than an all-in-one org solution. + +[fn:1] Doom's evil-window functionality is a bit different from GNU Emacs, but + you can always switch to the "other" buffer with =C-x o= or =C-x b= to + get a list of buffers to select. + +[fn:2] Doom's evil-window functionality is a bit different from GNU Emacs, but + you can always switch to the "other" buffer with =C-x o= or =C-x b= to + get a list of buffers to select. diff --git a/content/blog/2024-03-15-self-hosting-ddns-updater.org b/content/blog/2024-03-15-self-hosting-ddns-updater.org index 4add649..64e7a6c 100644 --- a/content/blog/2024-03-15-self-hosting-ddns-updater.org +++ b/content/blog/2024-03-15-self-hosting-ddns-updater.org @@ -6,25 +6,21 @@ #+caption: DDNS Updater Web View [[https://img.cleberg.net/blog/20240315-ddns-updater/ddns.png]] -[[https://github.com/qdm12/ddns-updater][DDNS Updater]] is a program to -keep DNS A and/or AAAA records updated for multiple DNS providers. +[[https://github.com/qdm12/ddns-updater][DDNS Updater]] is a program to keep DNS A and/or AAAA records updated for multiple +DNS providers. -If you've read any of my other posts, you'll notice that I have been -searching for and using a few different DDNS updating solutions for -years. You'll also notice that I love any projects that offer a Docker -Compose solution. +If you've read any of my other posts, you'll notice that I have been searching +for and using a few different DDNS updating solutions for years. You'll also +notice that I love any projects that offer a Docker Compose solution. Luckily, DDNS Upater fits both of these preferences. ** Installation -To get started, always make sure to review the project's -[[https://github.com/qdm12/ddns-updater/blob/master/README.md][README]]. -I'll be documenting my steps below, but they may have changed by the -time you read this. +To get started, always make sure to review the project's [[https://github.com/qdm12/ddns-updater/blob/master/README.md][README]]. I'll be +documenting my steps below, but they may have changed by the time you read this. -The first step is to set up the directories and files required for the -project. +The first step is to set up the directories and files required for the project. #+begin_src sh mkdir ~/ddns-updater @@ -34,43 +30,36 @@ touch ~/ddns-updater/data/config.json *** Configuration -The main configuration you need to update is the =data/config.json= -file. There is a large list of supported providers in the README, but -I'm going to use Cloudflare in this example. +The main configuration you need to update is the =data/config.json= file. There +is a large list of supported providers in the README, but I'm going to use +Cloudflare in this example. #+begin_src sh nano ~/ddns-updater/data/config.json #+end_src -When setting up the configuration for Cloudflare, you'll need the -following: +When setting up the configuration for Cloudflare, you'll need the following: - Required Parameters - - ="zone_identifier"= is the Zone ID of your site from the domain - overview page - - ="host"= is your host and can be ="@"=, a subdomain or the wildcard - ="*"=. See - [[https://github.com/qdm12/ddns-updater/issues/243#issuecomment-928313949][this - issue comment for context]]. - - ="ttl"= integer value for record TTL in seconds (specify 1 for - automatic) - - One of the following - ([[https://developers.cloudflare.com/fundamentals/api/get-started/][how - to find API keys]]): + - ="zone_identifier"= is the Zone ID of your site from the domain overview + page + - ="host"= is your host and can be ="@"=, a subdomain or the wildcard ="*"=. + See [[https://github.com/qdm12/ddns-updater/issues/243#issuecomment-928313949][this issue comment for context]]. + - ="ttl"= integer value for record TTL in seconds (specify 1 for automatic) + - One of the following ([[https://developers.cloudflare.com/fundamentals/api/get-started/][how to find API keys]]): - Email ="email"= and Global API Key ="key"= - User service key ="user_service_key"= - - API Token ="token"=, configured with DNS edit permissions for your - DNS name's zone + - API Token ="token"=, configured with DNS edit permissions for your DNS + name's zone - Optional Parameters - - ="proxied"= can be set to =true= to use the proxy services of - Cloudflare - - ="ip_version"= can be =ipv4= (A records), or =ipv6= (AAAA records) - or =ipv4 or ipv6= (update one of the two, depending on the public - ip found). It defaults to =ipv4 or ipv6=. - - ="ipv6_suffix"= is the IPv6 interface identifier suffix to use. It - can be for example =0:0:0:0:72ad:8fbb:a54e:bedd/64=. If left empty, - it defaults to no suffix and the raw public IPv6 address obtained is - used in the record updating. + - ="proxied"= can be set to =true= to use the proxy services of Cloudflare + - ="ip_version"= can be =ipv4= (A records), or =ipv6= (AAAA records) or =ipv4 + or ipv6= (update one of the two, depending on the public ip found). It + defaults to =ipv4 or ipv6=. + - ="ipv6_suffix"= is the IPv6 interface identifier suffix to use. It can be + for example =0:0:0:0:72ad:8fbb:a54e:bedd/64=. If left empty, it defaults to + no suffix and the raw public IPv6 address obtained is used in the record + updating. #+begin_src conf { @@ -90,8 +79,8 @@ following: } #+end_src -Once you have configured the provider of your choice, correct the file -and directory permissions and ownership. +Once you have configured the provider of your choice, correct the file and +directory permissions and ownership. #+begin_src sh cd ~/ddns_updater @@ -105,8 +94,8 @@ chmod 400 data/config.json *** Docker Compose -After creating the project structure, let's create the -=docker-compose.yml= file. +After creating the project structure, let's create the =docker-compose.yml= +file. #+begin_src sh nano ~/ddns_-pdater/docker-compose.yml @@ -150,22 +139,22 @@ services: restart: always #+end_src -After configuring your preferences in the =docker-compose.yml=, launch -the container. +After configuring your preferences in the =docker-compose.yml=, launch the +container. #+begin_src sh cd ~/ddns-updater sudo docker-compose up -d #+end_src -If you've launched this on your local machine, you can launch -=localhost:8097= in your browser to see the results. +If you've launched this on your local machine, you can launch =localhost:8097= +in your browser to see the results. *** Nginx Reverse Proxy -If you launched this service on a server, other machine, or just want to -access it remotely via a domain name, you can use Nginx as a reverse -proxy to expose the service publicly. +If you launched this service on a server, other machine, or just want to access +it remotely via a domain name, you can use Nginx as a reverse proxy to expose +the service publicly. Start by creating the Nginx configuration file. @@ -193,8 +182,8 @@ server { } #+end_src -Here's a full example that uses my Authelia authentication service to -require authentication before someone can access the web page. +Here's a full example that uses my Authelia authentication service to require +authentication before someone can access the web page. #+begin_src conf server { diff --git a/content/blog/2024-03-29-org-blog.org b/content/blog/2024-03-29-org-blog.org index db60c65..5ae1a2b 100644 --- a/content/blog/2024-03-29-org-blog.org +++ b/content/blog/2024-03-29-org-blog.org @@ -3,48 +3,41 @@ #+description: #+slug: org-blog -First and foremost, apologies to those who subscribe via RSS as I know -that my feed duplicated itself when I moved this blog over to org-mode -last night. +First and foremost, apologies to those who subscribe via RSS as I know that my +feed duplicated itself when I moved this blog over to org-mode last night. -This post focuses specifically on the configuration and tools I use to -blog from Emacs with Org-Mode and does not focus on Emacs or Org-Mode -themselves. Refer to the post I wrote about -[[https://cleberg.net/blog/doom-emacs-org-mode.html][Doom Emacs & Org-Mode]] for -more information about my base Emacs configuration. +This post focuses specifically on the configuration and tools I use to blog from +Emacs with Org-Mode and does not focus on Emacs or Org-Mode themselves. Refer to +the post I wrote about [[https://cleberg.net/blog/doom-emacs-org-mode.html][Doom Emacs & Org-Mode]] for more information about my base +Emacs configuration. * Weblorg -The first step in blogging with Org-Mode is to choose a method to -convert the source files to HTML and publish them. The Worg site -maintains a nice list of -[[https://orgmode.org/worg/org-blog-wiki.html][Blogs and Wikis with -Org]], but the tools are inevitably different and opinionated, so you'll -need to find what works for you. - -I tried using Jekyll, Hugo, ox-hugo, Nikola, Blorg, org-static-blog, and -the native org-publish functions before finally settling on Weblorg. For -one reason or another, the other solutions were a drastic step down from -my previous workflow that used [[https://www.getzola.org/][Zola]] with -Markdown content. - -[[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]]. Since it's written in -Emacs Lisp, there's no need to install other languages or frameworks to -get started. More than that, you can write in any editor you please and -simply invoke the Emacs build process with the =--script= parameter +The first step in blogging with Org-Mode is to choose a method to convert the +source files to HTML and publish them. The Worg site maintains a nice list of +[[https://orgmode.org/worg/org-blog-wiki.html][Blogs and Wikis with Org]], but the tools are inevitably different and +opinionated, so you'll need to find what works for you. + +I tried using Jekyll, Hugo, ox-hugo, Nikola, Blorg, org-static-blog, and the +native org-publish functions before finally settling on Weblorg. For one reason +or another, the other solutions were a drastic step down from my previous +workflow that used [[https://www.getzola.org/][Zola]] with Markdown content. + +[[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]]. +Since it's written in Emacs Lisp, there's no need to install other languages or +frameworks to get started. More than that, you can write in any editor you +please and simply invoke the Emacs build process with the =--script= parameter instead of requiring you to blog inside Emacs. ** Installation -The [[https://emacs.love/weblorg/doc/index.html][Getting Started]] page -details broad installation requirements. I am using Doom Emacs on macOS, -which requires you to add the package to the =~/.doom.d/packages.el= -file and configure the =publish.el= file slightly differently. +The [[https://emacs.love/weblorg/doc/index.html][Getting Started]] page details broad installation requirements. I am using +Doom Emacs on macOS, which requires you to add the package to the +=~/.doom.d/packages.el= file and configure the =publish.el= file slightly +differently. -To start, add the =htmlize= and =weblorg= packages to Doom, sync the -changes, and reload. +To start, add the =htmlize= and =weblorg= packages to Doom, sync the changes, +and reload. #+begin_src sh nano ~/.doom.d/packages.el @@ -63,18 +56,17 @@ Either re-open Emacs or hit =SPC h r r= to reload the changes. ** Configuration -Now that I've installed weblorg, I need to configure the project. I'll -start by navigating to my site's source code and creating a =publish.el= -file. +Now that I've installed weblorg, I need to configure the project. I'll start by +navigating to my site's source code and creating a =publish.el= file. #+begin_src sh cd ~/Source/cleberg.net && nano publish.el #+end_src -Since I'm using Doom, Emacs will not automatically load the packages I -need later in the build process. To compensate, my =publish.el= file -needs to explicitly tell Emacs where Doom stores the =htmlize=, -=weblorg=, and =templatel= packages. +Since I'm using Doom, Emacs will not automatically load the packages I need +later in the build process. To compensate, my =publish.el= file needs to +explicitly tell Emacs where Doom stores the =htmlize=, =weblorg=, and +=templatel= packages. #+begin_src lisp ;; explicity load packages since I'm using Doom Emacs @@ -184,12 +176,10 @@ needs to explicitly tell Emacs where Doom stores the =htmlize=, ** Structure The project structure for weblorg is highly customizable and the main -restriction is that the =publish.el= file must point to the correct -paths. +restriction is that the =publish.el= file must point to the correct paths. -For my blog, I prefer to keep the blog content out of the top-level -directory. This results in the following structure (shortened for -brevity): +For my blog, I prefer to keep the blog content out of the top-level directory. +This results in the following structure (shortened for brevity): #+begin_src txt .build/ @@ -217,17 +207,17 @@ build.sh publish.el #+end_src -This is simply my preferred structure and you can alter it to fit your -needs. The key here really is that you can customize at will, as long as -the =publish.el= file matches. +This is simply my preferred structure and you can alter it to fit your needs. +The key here really is that you can customize at will, as long as the +=publish.el= file matches. ** Build & Deploy -Once you're content with the status of the project, you're ready to -build and deploy the blog. +Once you're content with the status of the project, you're ready to build and +deploy the blog. -My process utilizes a =build.sh= script that combines the steps I take -every time. +My process utilizes a =build.sh= script that combines the steps I take every +time. #+begin_src sh touch build.sh && chmod +x build.sh && nano build.sh @@ -235,16 +225,16 @@ touch build.sh && chmod +x build.sh && nano build.sh Within this script, I do the following: -1. Remove any files within the =.build= directory that I use to store - published files. -2. Set the environment variable to =prod= to ensure the =base_url= - matches my configuration in =publish.el=. +1. Remove any files within the =.build= directory that I use to store published + files. +2. Set the environment variable to =prod= to ensure the =base_url= matches my + configuration in =publish.el=. 3. Build the site with Emacs & =publish.el=. 4. Use =scp= to copy files to my site's public directory on my server. #+begin_src sh -rm -rf .build/* && \ -ENV=prod emacs --script publish.el && \ +rm -rf .build/* && \ +ENV=prod emacs--script publish.el && \ scp -r .build/* ubuntu:/var/www/cleberg.net/ #+end_src @@ -252,13 +242,12 @@ scp -r .build/* ubuntu:/var/www/cleberg.net/ My only current complaints are: -1. Errors messages are not helpful. It takes work to determine what the - error is and where it's coming from. I generally have to sit and - watch the build process to see the file that weblorg pubslishes right - before the error occurred. -2. The build process re-builds every single file on each run, which - takes a long time for a blog of my size. See below for the last time - I measured. +1. Errors messages are not helpful. It takes work to determine what the error is + and where it's coming from. I generally have to sit and watch the build + process to see the file that weblorg pubslishes right before the error + occurred. +2. The build process re-builds every single file on each run, which takes a long + time for a blog of my size. See below for the last time I measured. #+begin_src sh > time ./build.sh @@ -266,5 +255,5 @@ My only current complaints are: ./build.sh 35.46s user 0.59s system 85% cpu 41.965 total #+end_src -Overall, I have thoroughly enjoyed using weblog and will continue to use -it going forward until I find something better. +Overall, I have thoroughly enjoyed using weblog and will continue to use it +going forward until I find something better. diff --git a/content/blog/2024-04-06-convert-onenote-to-markdown.org b/content/blog/2024-04-06-convert-onenote-to-markdown.org index 543b2db..87a2cad 100644 --- a/content/blog/2024-04-06-convert-onenote-to-markdown.org +++ b/content/blog/2024-04-06-convert-onenote-to-markdown.org @@ -3,54 +3,49 @@ #+description: #+slug: convert-onenote-to-markdown -If you're looking to convert your OneNote content to another format, -such as Markdown or Org-Mode, you're in luck. I use a solution that -doesn't require other programs, such as Evernote or Notion. Personally, -I used this solution on a managed corporate laptop that doesn't allow -installation of other programs like these. +If you're looking to convert your OneNote content to another format, such as +Markdown or Org-Mode, you're in luck. I use a solution that doesn't require +other programs, such as Evernote or Notion. Personally, I used this solution on +a managed corporate laptop that doesn't allow installation of other programs +like these. This solution uses OneNote and Pandoc on Windows 10. * Export OneNote Content to Word -To start, export any pages or tabs from OneNote to the Word format -(=.docx=): +To start, export any pages or tabs from OneNote to the Word format (=.docx=): 1. Open OneNote desktop. 2. Select =File= and then =Export=. 3. Select the scope of content to export, such as =Tab= or =Page=. -4. Name and save the file in an easy to remember location. I recommend - your Downloads or Desktop folder. +4. Name and save the file in an easy to remember location. I recommend your + Downloads or Desktop folder. See below for a visual walkthrough of the export process. * Download Pandoc -Start by downloading Pandoc from their -[[https://github.com/jgm/pandoc/releases][GitHub releases]] page. I -cannot install =.msi= files on my corporate laptop, so I downloaded the -=pandoc-3.1.12.3-windows-x86_64.zip= file, which contains a simple -=.exe= file that you do not need to install - you will simply run it -from the command line below. +Start by downloading Pandoc from their [[https://github.com/jgm/pandoc/releases][GitHub releases]] page. I cannot install +=.msi= files on my corporate laptop, so I downloaded the +=pandoc-3.1.12.3-windows-x86_64.zip= file, which contains a simple =.exe= file +that you do not need to install - you will simply run it from the command line +below. -Once downloaded, unzip the archive and move the =pandoc.exe= file to the -same folder where your Word documents were saved above. If you prefer, -you can move this file to an easier location, such as -=C:\Users\youruser\Downloads=. +Once downloaded, unzip the archive and move the =pandoc.exe= file to the same +folder where your Word documents were saved above. If you prefer, you can move +this file to an easier location, such as =C:\Users\youruser\Downloads=. * Convert Word to Markdown -In this example, I will be converting the Word documents to Markdown, -but Pandoc supports -[[https://github.com/jgm/pandoc?tab=readme-ov-file#the-universal-markup-converter][a -ton of different formats for conversion]]. Choose the format you prefer +In this example, I will be converting the Word documents to Markdown, but Pandoc +supports [[https://github.com/jgm/pandoc?tab=readme-ov-file#the-universal-markup-converter][a ton of different formats for conversion]]. Choose the format you prefer and then modify the following commands as needed. -To perform the conversion, open the Command Prompt. If you can't find -it, open the start menu and search for it. +To perform the conversion, open the Command Prompt. If you can't find it, open +the start menu and search for it. -Within the command prompt, navigate to the directory where you stored -the =pandoc.exe= file and the Word documents. +Within the command prompt, navigate to the directory where you stored the +=pandoc.exe= file and the Word documents. #+begin_src ps1 cd "C:\Users\yourusername\Downloads" @@ -63,9 +58,9 @@ command. dir #+end_src -Once you have verified that you have the command prompt open in the -correct directory with the =pandoc.exe= and the Word documents, you can -run the following loop to convert all Word documents to Markdown. +Once you have verified that you have the command prompt open in the correct +directory with the =pandoc.exe= and the Word documents, you can run the +following loop to convert all Word documents to Markdown. #+begin_src ps1 for %f in (*.docx) do (pandoc.exe --extract-media=. --wrap=preserve "%f" -o "%f.md") @@ -73,25 +68,24 @@ for %f in (*.docx) do (pandoc.exe --extract-media=. --wrap=preserve "%f" -o "%f. This loop will perform the following actions: -1. Find all documents matching the pattern =*.docx=, which means all - Word documents ending with that file extension. +1. Find all documents matching the pattern =*.docx=, which means all Word + documents ending with that file extension. 2. Iterate through all files found in step 1. 3. For each file, perform the pandoc command. -4. Within the pandoc command, =--extract-media= saves all media found in - the files to the current folder, with pandoc automatically creating a - =media= subfolder to hold all images. -5. Within the pandoc command, =--wrap=preserve= will attempt to prseerve - the wrapping from the source document. -6. Within the pandoc command, the final step is to specify the output - path with =-o=. This option adds the =.md= file extension to - recognize the output files as Markdown files. - -If you want to export to another format, simply specify the -=-f==/=--from== and =-t==/=--to== options. - -For example, you can convert the Word document to org-mode. You can also -convert to one format and subsequently convert to other formats as -needed. +4. Within the pandoc command, =--extract-media= saves all media found in the + files to the current folder, with pandoc automatically creating a =media= + subfolder to hold all images. +5. Within the pandoc command, =--wrap=preserve= will attempt to prseerve the + wrapping from the source document. +6. Within the pandoc command, the final step is to specify the output path with + =-o=. This option adds the =.md= file extension to recognize the output files + as Markdown files. + +If you want to export to another format, simply specify the =-f==/=--from== and +=-t==/=--to== options. + +For example, you can convert the Word document to org-mode. You can also convert +to one format and subsequently convert to other formats as needed. #+begin_src ps1 pandoc.exe -f docx -t org file.docx diff --git a/content/blog/2024-04-08-docker-local-web-server.org b/content/blog/2024-04-08-docker-local-web-server.org index 7333bef..f551450 100644 --- a/content/blog/2024-04-08-docker-local-web-server.org +++ b/content/blog/2024-04-08-docker-local-web-server.org @@ -3,43 +3,42 @@ #+description: #+slug: docker-local-web-server -When developing websites locally, I often use a simple Python web server -to observe the changes. +When developing websites locally, I often use a simple Python web server to +observe the changes. #+begin_src sh python3 -m http.server #+end_src -However, this approach has its limitations. For example, this approach -does not enable logging or access controls. You also need to customize -=SimpleHTTPServer= if you have advanced needs from your web server. +However, this approach has its limitations. For example, this approach does not +enable logging or access controls. You also need to customize =SimpleHTTPServer= +if you have advanced needs from your web server. -So, I went to find an alternative that is almost as easy and far more -extensible and found Docker Desktop to be a suitable replacement. +So, I went to find an alternative that is almost as easy and far more extensible +and found Docker Desktop to be a suitable replacement. * Docker Desktop ** Installation -[[https://www.docker.com/products/docker-desktop/][Docker Desktop]] is a -desktop GUI for the phenomenal Docker container software. This allows -you to manage containers, images, volumes, environments, and extensions -via an easy-to-use GUI. +[[https://www.docker.com/products/docker-desktop/][Docker Desktop]] is a desktop GUI for the phenomenal Docker container software. +This allows you to manage containers, images, volumes, environments, and +extensions via an easy-to-use GUI. To install, open the link above and click the =Download= button for your -platform. I'm going through this process on an M2 Macbook, so I -downloaded the Mac - Apple Chip version. +platform. I'm going through this process on an M2 Macbook, so I downloaded the +Mac - Apple Chip version. -Open the installer and follow the installation process until the -application finishes the installation process. +Open the installer and follow the installation process until the application +finishes the installation process. #+caption: Docker Desktop on macOS [[https://img.cleberg.net/blog/20240408-docker-local-web-server/docker-desktop.png]] ** Creating an Nginx Container -I prefer to use the command line to create containers, so the following -commands will be input via the terminal. +I prefer to use the command line to create containers, so the following commands +will be input via the terminal. The following command will create a container, using the =nginx= image: @@ -61,20 +60,20 @@ You can navigate to [[http://localhost:8000]] to see the resulting page. ** Customizing the Nginx Container -Now that I have a container running the Nginx web server, I need to link -some volumes so that I can modify the site configuration and provide the -web files to serve. +Now that I have a container running the Nginx web server, I need to link some +volumes so that I can modify the site configuration and provide the web files to +serve. Let's start with the new command, which adds two volumes: -1. =<your_content>:/usr/share/nginx/html=: This is the directory where - you will provide the web pages for the server to serve. +1. =<your_content>:/usr/share/nginx/html=: This is the directory where you will + provide the web pages for the server to serve. 2. =<your_config>:/etc/nginx/conf.d/default.conf=: This is the Nginx configuration file for your site. -To see the updates, you can delete the previous container in the GUI or -run =docker stop web= to stop the container. Once stopped, you can run -the new =docker run= command below. +To see the updates, you can delete the previous container in the GUI or run +=docker stop web= to stop the container. Once stopped, you can run the new +=docker run= command below. #+begin_src sh docker run -it -d -p 8000:80 --name web -v ~/Source/cleberg.net/.build:/usr/share/nginx/html -v ~/Source/cleberg.net/nginx-config.conf:/etc/nginx/conf.d/default.conf nginx @@ -107,16 +106,15 @@ server { * Customizing Deployment Actions -I am currently blogging with [[https://emacs.love/weblorg/][weblorg]], -which uses a custom =publish.el= file to build the static site. Within -this file, I have configured my deployment process to check for the -=ENV= variable in thesh and if it's set to =prod=, the script will set -the base URLs to =https://cleberg.net=. If not, it sets the base URLs to -=localhost:8000= (which matches the port used in the container above). +I am currently blogging with [[https://emacs.love/weblorg/][weblorg]], which uses a custom =publish.el= file to +build the static site. Within this file, I have configured my deployment process +to check for the =ENV= variable in thesh and if it's set to =prod=, the script +will set the base URLs to =https://cleberg.net=. If not, it sets the base URLs +to =localhost:8000= (which matches the port used in the container above). -Therefore, I have modified my =build.sh= script to build with -=localhost= URLs if =ENV= is not set to =prod=. It also prevents the -build process from sending the built files to the production web server. +Therefore, I have modified my =build.sh= script to build with =localhost= URLs +if =ENV= is not set to =prod=. It also prevents the build process from sending +the built files to the production web server. #+begin_src sh #!/bin/bash @@ -133,7 +131,6 @@ else fi #+end_src -You can modify the container in numerous ways and this approach allows -you to create complex scenarios for your web development purposes. I -highly recommend switching over to a container-based approach for -simple, local web development. +You can modify the container in numerous ways and this approach allows you to +create complex scenarios for your web development purposes. I highly recommend +switching over to a container-based approach for simple, local web development. diff --git a/content/blog/2024-04-18-mu4e.org b/content/blog/2024-04-18-mu4e.org index e422f88..dadfc0b 100644 --- a/content/blog/2024-04-18-mu4e.org +++ b/content/blog/2024-04-18-mu4e.org @@ -3,20 +3,18 @@ #+description: #+slug: mu4e -This post was heavily inspired by -[[https://macowners.club/posts/email-emacs-mu4e-macos/][Email setup in -Emacs with Mu4e on macOS]], but with my own tweaks for a single-account -configuration and some Doom-specific configurations. +This post was heavily inspired by [[https://macowners.club/posts/email-emacs-mu4e-macos/][Email setup in Emacs with Mu4e on macOS]], but +with my own tweaks for a single-account configuration and some Doom-specific +configurations. * Overview -[[https://github.com/emacsmirror/mu4e][Mu4e]] is an Emacs-based email -client based on [[https://www.djcbsoftware.nl/code/mu/][mu]], an indexer -that stores email in the Maildir format. +[[https://github.com/emacsmirror/mu4e][Mu4e]] is an Emacs-based email client based on [[https://www.djcbsoftware.nl/code/mu/][mu]], an indexer that stores email in +the Maildir format. -This blog post covers the installation of Mu4e in Doom Emacs on macOS. -This guide should be very similar to GNU Emacs and Linux-based systems, -with a few tweaks required in the various configuration files. +This blog post covers the installation of Mu4e in Doom Emacs on macOS. This +guide should be very similar to GNU Emacs and Linux-based systems, with a few +tweaks required in the various configuration files. * Installation @@ -34,21 +32,21 @@ mkdir ~/.maildir/certificates # used to store system root certificates *** Store Email Account Passwords in macOS Keychain -Next, I will be using the macOS Keychain to store my email account -passwords using the command below. +Next, I will be using the macOS Keychain to store my email account passwords +using the command below. #+begin_src sh security add-generic-password -s mu4e-example -a you@example.com -w #+end_src This will prompt you to input your password twice to confirm. Keep the -=mu4e-example= name in mind, as you will need to reference it later in -the IMAP and SMTP configuration files. +=mu4e-example= name in mind, as you will need to reference it later in the IMAP +and SMTP configuration files. *** Store Root Certificates -In order to use IMAP and SMTP, we need to provide certificates to the -local services. We will use the macOS defaults for this. +In order to use IMAP and SMTP, we need to provide certificates to the local +services. We will use the macOS defaults for this. 1. Open =Keychain Access.app=. 2. Select =System Roots= in the sidebar. @@ -58,8 +56,8 @@ local services. We will use the macOS defaults for this. *** Install Dependencies -Install =mbsync= (via =isync=) to fetch emails via IMAP, =mu= to index -emails, and =msmtp= to send emails via SMTP. +Install =mbsync= (via =isync=) to fetch emails via IMAP, =mu= to index emails, +and =msmtp= to send emails via SMTP. #+begin_src sh brew install mu isync msmtp @@ -73,8 +71,8 @@ Within Doom Emacs, we can install Mu4e by enabling the package. nano ~/.doom.d/init.el #+end_src -In this file, uncomment the =mu4e= line within the =:email= section. You -can also enable the =+org= and =+gmail= options if you prefer. +In this file, uncomment the =mu4e= line within the =:email= section. You can +also enable the =+org= and =+gmail= options if you prefer. #+begin_src lisp (doom! :input @@ -88,9 +86,9 @@ can also enable the =+org= and =+gmail= options if you prefer. * Configuration -As an overall suggestion, I create the following configuration files in -the =~/.maildir= directory and using symlinks to their proper locations -so that I can backup and restore these files easily. +As an overall suggestion, I create the following configuration files in the +=~/.maildir= directory and using symlinks to their proper locations so that I +can backup and restore these files easily. #+begin_src sh touch ~/.maildir/.mbsyncrc && \ @@ -99,14 +97,13 @@ ln -s /Users/username/.maildir/.mbsyncrc /Users/username/.mbsyncrc && \ ln -s /Users/username/.maildir/.msmtprc /Users/username/.msmtprc #+end_src -You can also create these files in your home directory and skip the -symlinking process above. +You can also create these files in your home directory and skip the symlinking +process above. ** IMAP -Next, let's configure =mbsync= in the file created above. Paste the -following information and customize it to match your mail provider's -information. +Next, let's configure =mbsync= in the file created above. Paste the following +information and customize it to match your mail provider's information. #+begin_src sh nano ~/.maildir/.mbsyncrc @@ -142,9 +139,8 @@ SyncState * ** SMTP -Next, let's configured =msmtprc= in the file created above. Paste the -following information and customize it to match your mail provider's -information. +Next, let's configured =msmtprc= in the file created above. Paste the following +information and customize it to match your mail provider's information. #+begin_src sh nano ~/.maildir/.msmtprc @@ -176,8 +172,8 @@ account default : startmail ** Doom Emacs -Finally, we need to configure Doom Emacs to use the proper packages and -set some variables and functions. +Finally, we need to configure Doom Emacs to use the proper packages and set some +variables and functions. #+begin_src sh nano ~/.doom.d/config.el @@ -275,14 +271,12 @@ Be sure to sync Doom to update the current configurations. doom sync #+end_src -If you have Doom open, execute =SPC h r r= to reload the new -configurations. +If you have Doom open, execute =SPC h r r= to reload the new configurations. * Initial Sync -Once you have configured all of the relevant files, you can perform an -initial sync. Note that you can perform syncing within Mu4e itself after -this. +Once you have configured all of the relevant files, you can perform an initial +sync. Note that you can perform syncing within Mu4e itself after this. #+begin_src sh mbsync -aV @@ -299,11 +293,11 @@ The emails will now to be ready to use! * Screenshots -You can now launch Doom and open Mu4e with =SPC o m=. You can also -explore the Mu4e options with =SPC : mu4e=. +You can now launch Doom and open Mu4e with =SPC o m=. You can also explore the +Mu4e options with =SPC : mu4e=. -The home page shows various options and metadata about the account -you've opened. +The home page shows various options and metadata about the account you've +opened. #+caption: Mu4e Home Page [[https://img.cleberg.net/blog/20240418-mu4e/mu4e.png]] diff --git a/content/blog/2024-05-03-ubuntu-on-macos.org b/content/blog/2024-05-03-ubuntu-on-macos.org index fea8162..e474a0d 100644 --- a/content/blog/2024-05-03-ubuntu-on-macos.org +++ b/content/blog/2024-05-03-ubuntu-on-macos.org @@ -3,24 +3,24 @@ #+description: Learn how to run Linux machines as applications on macOS with minimal hassle. #+slug: ubuntu-on-macos -Being a macOS user who previously used Linux for many years, I often -find myself searching for alternatives to the Linux-native tools and -methods that I had become used to over the years. +Being a macOS user who previously used Linux for many years, I often find myself +searching for alternatives to the Linux-native tools and methods that I had +become used to over the years. -Luckily, there's an option to simply use Linux directly on your macOS -device without having to boot the whole device into Linux or having to -SSH into another Linux machine. +Luckily, there's an option to simply use Linux directly on your macOS device +without having to boot the whole device into Linux or having to SSH into another +Linux machine. -In this post, I use [[https://orbstack.dev/][OrbStack]] to create an -Ubuntu Linux machine to take advantage of the Linux system. +In this post, I use [[https://orbstack.dev/][OrbStack]] to create an Ubuntu Linux machine to take advantage +of the Linux system. ** Installing OrbStack -OrbStack has a [[https://orbstack.dev/download][download page]] if you -prefer to use =*.dmg= files to install applications. +OrbStack has a [[https://orbstack.dev/download][download page]] if you prefer to use =*.dmg= files to install +applications. -Personally, I prefer to install everything through Homebrew. For -OrbStack, run the following to install the application via Homebrew: +Personally, I prefer to install everything through Homebrew. For OrbStack, run +the following to install the application via Homebrew: #+begin_src sh brew install orbstack @@ -28,72 +28,68 @@ brew install orbstack ** Creating a Linux Machine -Once installed, you can launch OrbStack and create a Linux machine in a -matter of seconds. The creation dialog defaults to Ubuntu. +Once installed, you can launch OrbStack and create a Linux machine in a matter +of seconds. The creation dialog defaults to Ubuntu. #+caption: OrbStack's Linux Machine Creation Page [[https://img.cleberg.net/blog/20240503-ubuntu-on-macos/create.png]] ** Launching the Machine -Once created, the dialog will close and you will be presented with your -new list of machines. Simply double-click on a machine to run it. +Once created, the dialog will close and you will be presented with your new list +of machines. Simply double-click on a machine to run it. -When you run the machine for the first time, it may warn you that a -program is attempting to run a shell script. You can choose to manually -inspect this shell script via the provided path if you wish. When you're -comfortable with the script, you can toggle the -=Suppress this message permanently= button and click OK to run the -machine. +When you run the machine for the first time, it may warn you that a program is +attempting to run a shell script. You can choose to manually inspect this shell +script via the provided path if you wish. When you're comfortable with the +script, you can toggle the =Suppress this message permanently= button and click +OK to run the machine. #+begin_quote *Quick Tip*! -You will always be able to launch the OrbStack application and control -the machine via the Machines page, but you can also use the OrbStack -icon in the macOS menu bar to quickly control the machine without -launching OrbStack itself. +You will always be able to launch the OrbStack application and control the +machine via the Machines page, but you can also use the OrbStack icon in the +macOS menu bar to quickly control the machine without launching OrbStack itself. #+end_quote ** Working in Linux -Once successful, OrbStack will launch your default terminal and log you -into the Linux machine you created above. +Once successful, OrbStack will launch your default terminal and log you into the +Linux machine you created above. -In the example below, we can see that the machine is using -=Linux ubuntu 6.9.6= and operates similar to a fresh Ubuntu install on -bare metal. +In the example below, we can see that the machine is using =Linux ubuntu 6.9.6= +and operates similar to a fresh Ubuntu install on bare metal. #+caption: Ubuntu CLI [[https://img.cleberg.net/blog/20240503-ubuntu-on-macos/cli.png]] -You can also click the machine's folder icon in OrbStack to open the -machine's file system within macOS's native Files app. Within Files, you -can double-click to open any files and they will open in the macOS -defaults for those file types (e.g., TextEdit). +You can also click the machine's folder icon in OrbStack to open the machine's +file system within macOS's native Files app. Within Files, you can double-click +to open any files and they will open in the macOS defaults for those file types +(e.g., TextEdit). #+caption: Ubuntu Files [[https://img.cleberg.net/blog/20240503-ubuntu-on-macos/files.png]] -Here's an example of opening the =test.md= file in the screenshot above, -which defaults to opening in Xcode on my system. +Here's an example of opening the =test.md= file in the screenshot above, which +defaults to opening in Xcode on my system. #+caption: Ubuntu Files [[https://img.cleberg.net/blog/20240503-ubuntu-on-macos/xcode.png]] *** Test Examples -As a quick example of the system, I installed =neofetch=, switched to -the =zsh= shell, and ran a few common commands. +As a quick example of the system, I installed =neofetch=, switched to the =zsh= +shell, and ran a few common commands. #+caption: Test Examples [[https://img.cleberg.net/blog/20240503-ubuntu-on-macos/test.png]] ** Thoughts -The installation, creation, and launch processes are seamless and -provide an easy way to test or use Linux on macOS with little to no -hassle. +The installation, creation, and launch processes are seamless and provide an +easy way to test or use Linux on macOS with little to no hassle. The shell and file integrations are incredibly snappy and I have not experienced any lag so far. Further, being able to open files in the diff --git a/content/blog/2024-06-19-deprecated-trusted-gpg-fix.org b/content/blog/2024-06-19-deprecated-trusted-gpg-fix.org index 532e89d..6041614 100644 --- a/content/blog/2024-06-19-deprecated-trusted-gpg-fix.org +++ b/content/blog/2024-06-19-deprecated-trusted-gpg-fix.org @@ -5,8 +5,8 @@ ** System Warning -When running an update on an Ubuntu system, you may have run into a -system warning that looks like the example below. +When running an update on an Ubuntu system, you may have run into a system +warning that looks like the example below. #+begin_src txt W: https://dl.yarnpkg.com/debian/dists/stable/InRelease: Key is stored in legacy @@ -14,34 +14,33 @@ trusted.gpg keyring (/etc/apt/trusted.gpg), see the DEPRECATION section in apt-key(8) for details. #+end_src -While this example references the =yarn= package, the warning message is -the same for any repository using the deprecated =trusted.gpg= key ring. +While this example references the =yarn= package, the warning message is the +same for any repository using the deprecated =trusted.gpg= key ring. -The issue arises from managing keys with the =apt-key= command, which -utilizes the =/etc/apt/trusted.gpg= file by default. Instead, Ubuntu has -moved to managing key rings with individual =.gpg= files in the -=/etc/apt/trusted.gpg.d/= directory. +The issue arises from managing keys with the =apt-key= command, which utilizes +the =/etc/apt/trusted.gpg= file by default. Instead, Ubuntu has moved to +managing key rings with individual =.gpg= files in the =/etc/apt/trusted.gpg.d/= +directory. -To fix this issue, let's check to see which keys are using the -=trusted.gpg= key ring and move them into their own dedicated key ring. +To fix this issue, let's check to see which keys are using the =trusted.gpg= key +ring and move them into their own dedicated key ring. ** Finding All Keys in the Keyring -Let's start by simply listing the keys used by the =apt= commands. To do -this, run the following command. +Let's start by simply listing the keys used by the =apt= commands. To do this, +run the following command. #+begin_src sh sudo apt-key list #+end_src This command will show an output similar to the one below. You may see -additional keys in the =/etc/apt/trusted.gpg.d/= directory - this is -where we will be moving any keys currently found in the =trusted.gpg= -key ring. +additional keys in the =/etc/apt/trusted.gpg.d/= directory - this is where we +will be moving any keys currently found in the =trusted.gpg= key ring. -In the below example, we can see that this system has four different GPG -keys stored within the =trusted.gpg= key ring. Let's go ahead and move -them into their own files. +In the below example, we can see that this system has four different GPG keys +stored within the =trusted.gpg= key ring. Let's go ahead and move them into +their own files. #+begin_src txt Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead @@ -73,24 +72,24 @@ uid [ unknown] nginx signing key <signing-key-3@nginx.com> *** Exporting Keys to New Files -Now that we know the keys, we will need to move them into their own key -ring. We can do this by copying the last eight (8) characters from the -key's signature and exporting it from this key ring into its own. +Now that we know the keys, we will need to move them into their own key ring. We +can do this by copying the last eight (8) characters from the key's signature +and exporting it from this key ring into its own. -Using the yarn example from the beginning, here's the command to move -this key into its own key ring. +Using the yarn example from the beginning, here's the command to move this key +into its own key ring. #+begin_src sh sudo apt-key export 86E50310 | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/yarn.gpg #+end_src -You can repeat this process for any other keys, such as the =nginx= keys -in the example above. +You can repeat this process for any other keys, such as the =nginx= keys in the +example above. *** Cleaning Up -If you run =sudo apt-key list= again, you should see the keys within -their own key rings: +If you run =sudo apt-key list= again, you should see the keys within their own +key rings: #+begin_src txt /etc/apt/trusted.gpg.d/nginx-archive-keyring.gpg @@ -117,17 +116,16 @@ sub rsa4096 2019-01-02 [S] [expires: 2026-01-23] sub rsa4096 2019-01-11 [S] [expires: 2026-01-23] #+end_src -Once you have verified that the keys are valid and stored in their own -key rings, you can archive the =trusted.gpg= file and run a system -update to test the new files. +Once you have verified that the keys are valid and stored in their own key +rings, you can archive the =trusted.gpg= file and run a system update to test +the new files. #+begin_src sh sudo mv /etc/apt/trusted.gpg /etc/apt/trusted.gpg.bkp sudo apt update #+end_src -Once you've verified that updates work as expected and that the keys are -working as intended, you can delete the =.bkp= file created above. If -you're storing keys that are not easily re-attainable, I suggest keeping -the =.bkp= file stored in a safe location until you are positive that -you no longer need it. +Once you've verified that updates work as expected and that the keys are working +as intended, you can delete the =.bkp= file created above. If you're storing +keys that are not easily re-attainable, I suggest keeping the =.bkp= file stored +in a safe location until you are positive that you no longer need it. diff --git a/content/blog/2024-07-11-emacs-on-ipad.org b/content/blog/2024-07-11-emacs-on-ipad.org index 25e752f..662cac3 100644 --- a/content/blog/2024-07-11-emacs-on-ipad.org +++ b/content/blog/2024-07-11-emacs-on-ipad.org @@ -5,25 +5,23 @@ #+slug: emacs-on-ipad -This post describes the process to install and use Emacs on the iPad Air -13-inch (M2). The iPad used in this post is running iPadOS 17.6. +This post describes the process to install and use Emacs on the iPad Air 13-inch +(M2). The iPad used in this post is running iPadOS 17.6. ** Shell Application -In order to use Emacs on an iPad, you will need a terminal emulator -application. I recommend -[[https://apps.apple.com/us/app/ish-shell/id1436902243][iSH]], since it -runs a version of Alpine Linux within the app itself and will allow you -to install packages that you need. +In order to use Emacs on an iPad, you will need a terminal emulator application. +I recommend [[https://apps.apple.com/us/app/ish-shell/id1436902243][iSH]], since it runs a version of Alpine Linux within the app itself +and will allow you to install packages that you need. #+caption: iSH Application [[https://img.cleberg.net/blog/20240711-emacs-on-ipad/ish.png]] ** Require Packages -I started by adding the required packages directly within iSH. Emacs -should install dependencies by default, but I include a few other -packages that I use in my terminal as well. +I started by adding the required packages directly within iSH. Emacs should +install dependencies by default, but I include a few other packages that I use +in my terminal as well. #+begin_src sh apk add emacs ripgrep fd findutils @@ -34,39 +32,37 @@ apk add emacs ripgrep fd findutils ** Emacs -Once this is complete, you should be able to run Emacs natively on your -iPad. It's effective, but can be slow at times. +Once this is complete, you should be able to run Emacs natively on your iPad. +It's effective, but can be slow at times. -I attempted to also install Doom Emacs, which technically worked, but -was so incredibly slow and buggy that I was not even able to take -screenshots. Someone smarter than me could likely get it to work with a -little tinkering. +I attempted to also install Doom Emacs, which technically worked, but was so +incredibly slow and buggy that I was not even able to take screenshots. Someone +smarter than me could likely get it to work with a little tinkering. #+caption: Emacs [[https://img.cleberg.net/blog/20240711-emacs-on-ipad/emacs.png]] *** MELPA -You also have to remember to hook up MELPA yourself in the =.emacs= file -to be able to search through their 5700+ packages instead of just ELPA -packages. If you don't, you will only have access to ELPA packages like -the ones below. +You also have to remember to hook up MELPA yourself in the =.emacs= file to be +able to search through their 5700+ packages instead of just ELPA packages. If +you don't, you will only have access to ELPA packages like the ones below. #+caption: package-install [[https://img.cleberg.net/blog/20240711-emacs-on-ipad/melpa.png]] -Once you have MELPA, you can install packages like the =dashboard= -package shown below. +Once you have MELPA, you can install packages like the =dashboard= package shown +below. #+caption: emacs-dashboard [[https://img.cleberg.net/blog/20240711-emacs-on-ipad/dashboard.png]] *** Speed -While Emacs will run on my iPad, it's not perfect. The largest issue on -my iPad is speed - loading Emacs takes 6-7 seconds and installing the -=magit= package took 129 seconds. +While Emacs will run on my iPad, it's not perfect. The largest issue on my iPad +is speed - loading Emacs takes 6-7 seconds and installing the =magit= package +took 129 seconds. -I haven't played around enough to optimize loading times and poke around -to see why the network requests take so long, but it's a big enough -issue that I wouldn't see casual Emacs users dealing with the lag. +I haven't played around enough to optimize loading times and poke around to see +why the network requests take so long, but it's a big enough issue that I +wouldn't see casual Emacs users dealing with the lag. |