Analytics for notes

I don’t care very much but I would like to know roughly how much my notes pages are getting looked at. It looks like quartz supports a couple of analytics providers.

tinylytics

  • Free as just a hit counter
  • $50 / year
  • Super easy to setup

plausible

Moving presentation to Cloudflare

Cloudflare wasn’t building my presentation because it was using a different version of yarn. I got around this by setting an explicit yarn version in package.json:

{
  "name": "friend",
  "type": "module",
  "private": true,
  "scripts": {
    "build": "slidev build",
    "dev": "slidev --open",
    "export": "slidev export"
  },
  "packageManager": "yarn@1.22.22",
  "dependencies": {
    "@slidev/cli": "^0.50.0-beta.5",
    "@slidev/theme-default": "latest",
    "@slidev/theme-seriph": "latest",
    "vue": "^3.5.12"
  }
}

Eventually I would like to have everything on cloudflare because it’s fast and it’s free and doesn’t have any real limits right now.

Presentation Wrapup

A couple of things I wanted to do before the presentation gets shared out more widely:

  • Add a note on the title slide about how to interact with it
  • Add a letter at the end about what’s going on in this presentation, who I am, and how to contact me
  • Setup a way to contact me
  • Add super basic analytics

Contact me

I used jotform as a suuuper quick way to have a “contact me” form. Ideally I would like something that’s mine and fully customizable but this gets something up and going after 15 minutes of fussing with their online editor.

Analytics

I used tinylytics. It’s mostly just a hit counter but it gives me something to get an idea of how much/often people are looking at the slides (and my notes).

Add analytics to the vite project was easy but not intuitive. I had to add an index.html and include just the head portion:

<head>
    <script src="https://tinylytics.app/embed/<secret code>.js" defer></script>
</head>

xargs

So far in the missing semester book club I’ve been pretty familiar with all of the tools and techniques we’ve used (although I very frequently have to go lookup what all of the ! + <something else> variables are in bash, !! is the only one I know). But there is a command that I avoid and am slightly afraid of, xargs (truthfully anytime I have a feel that it could be the right solution I end up writing a tiny script that does looping and stores things into variables). So today is my day to be at my growth-edge and figure it out.

  • Some commands don’t read from standard input, they need arguments passed to them, but you want to use standard in and xargs fills in the gaps
    • Does the find command’s exec argument function act like a built in xargs?
  • Basic form cmd1 | xargs cmd2 - The output from cmd is used as an argument for cmd
friend main 
❯ echo hi | echo

Has no output but:

friend main 
❯ echo hi | xargs echo
hi

Does has output

  • Another example showing how the output gets all mushed together:
friend main 
❯ seq 2 6
2
3
4
5
6

friend main 
❯ seq 2 6 | xargs echo
2 3 4 5 6
  • If args isn’t passed a command to run it automatically uses echo
  • -t says “Show me what command you’re actually running”
❯ seq 2 6 | xargs -t echo
echo 2 3 4 5 6
2 3 4 5 6
  • Using xargs to do a ls on a series of folders from ls
~/workspace/play 
❯ ls
one  three  two

~/workspace/play 
❯ ls | xargs -t ls 
ls one three two
one:
ella  gretchen	henry  lion  rene

three:
'a court of mist and fury'  'we are ok'  'wintering the power of rest in difficult times'  'yerba buena'

two:
aphrodite  artemis  athena  hera  zeus

Note: ls isn’t getting input for-each file. It’s getting a list of files at the end of it and then it knows what to do with them (command run: ls one three two).

  • We can also use arguments and flags on the command that xargs is running. This is running ls WITH the -l command
~/workspace/play 
❯ ls | xargs -t ls -l
ls -l one three two
one:
total 0
-rw------- 1 nicole nicole 0 Nov 16 13:11 ella
-rw------- 1 nicole nicole 0 Nov 16 13:11 gretchen
-rw------- 1 nicole nicole 0 Nov 16 13:11 henry
-rw------- 1 nicole nicole 0 Nov 16 13:11 lion
-rw------- 1 nicole nicole 0 Nov 16 13:11 rene

three:
total 0
-rw------- 1 nicole nicole 0 Nov 16 13:12 'a court of mist and fury'
-rw------- 1 nicole nicole 0 Nov 16 13:12 'we are ok'
-rw------- 1 nicole nicole 0 Nov 16 13:13 'wintering the power of rest in difficult times'
-rw------- 1 nicole nicole 0 Nov 16 13:13 'yerba buena'

two:
total 0
-rw------- 1 nicole nicole 0 Nov 16 13:11 aphrodite
-rw------- 1 nicole nicole 0 Nov 16 13:12 artemis
-rw------- 1 nicole nicole 0 Nov 16 13:11 athena
-rw------- 1 nicole nicole 0 Nov 16 13:11 hera
-rw------- 1 nicole nicole 0 Nov 16 13:11 zeus

Here’s an example of getting a list of all users on the machine and putting them in alphabetical order then sticking the list all on one line:

❯ less /etc/passwd | cut -d: -f1 | sort | xargs echo 
alpm avahi bin colord cups daemon dbus dnsmasq flatpak ftp geoclue git http lightdm mail nicole nm-openconnect nm-openvpn nobody ntp openvpn polkitd root rpc rpcuser rtkit systemd-coredump systemd-journal-remote systemd-network systemd-oom systemd-resolve systemd-timesync _talkd tss usbmux uuidd
  • -I lets us set a placeholder for the output from the previous step and then use the output somewhere in the command that we’re passing. A common placeholder is {}
❯ ls | xargs -I {} echo "$(pwd)/{}"
/home/nicole/workspace/play/one
/home/nicole/workspace/play/three
/home/nicole/workspace/play/two

This command is running ls then passing the result to xargs which then stores the result into a sort-of variable called {} and then runs the echo command which then gets the current working directory and outputs the current spot + the result from ls. Here’s what xargs says when we ask it to show us what its doing:

~/workspace/play 
❯ ls | xargs -t -I {} echo "$(pwd)/{}"
echo /home/nicole/workspace/play/one
/home/nicole/workspace/play/one
echo /home/nicole/workspace/play/three
/home/nicole/workspace/play/three
echo /home/nicole/workspace/play/two
/home/nicole/workspace/play/two
  • Why does this run the command once per line???

  • Using xargs to make files 1 through 100 in a directory

~/workspace/play 
❯ mkdir numbers 

~/workspace/play 
❯ cd numbers 

workspace/play/numbers 
❯ seq 1 100 | xargs -I {} touch {}

workspace/play/numbers 
❯ ls
1    12  16  2	23  27  30  34  38  41  45  49  52  56  6   63  67  70  74  78  81  85  89  92  96
10   13  17  20  24  28  31  35  39  42  46  5	53  57  60  64  68  71  75  79  82  86  9   93  97
100  14  18  21  25  29  32  36  4   43  47  50  54  58  61  65  69  72  76  8	83  87  90  94  98
11   15  19  22  26  3	33  37  40  44  48  51  55  59  62  66  7   73  77  80  84  88  91  95  99

This is runs the seq command which generates numbers from a <start> to an <end> then passes the result of that through to xargs which uses the variable {} which we then use as input to the touch command which then creates a new file. 🙀

And then to clean up (without using substitutions ) I could do:

workspace/play/numbers 
❯ ls | xargs -I {} rm {}

workspace/play/numbers 
❯ ls

Orrrrr to make each of them into .md files:

workspace/play/numbers 
❯ ls | cut -d. -f1 | xargs -I {} mv "{}.txt" "{}.md"

workspace/play/numbers 
❯ ls
100.md	16.md  22.md  29.md  35.md  41.md  48.md  54.md  60.md	67.md  73.md  7.md   86.md  92.md  99.md
10.md	17.md  23.md  2.md   36.md  42.md  49.md  55.md  61.md	68.md  74.md  80.md  87.md  93.md  9.md
11.md	18.md  24.md  30.md  37.md  43.md  4.md   56.md  62.md	69.md  75.md  81.md  88.md  94.md
12.md	19.md  25.md  31.md  38.md  44.md  50.md  57.md  63.md	6.md   76.md  82.md  89.md  95.md
13.md	1.md   26.md  32.md  39.md  45.md  51.md  58.md  64.md	70.md  77.md  83.md  8.md   96.md
14.md	20.md  27.md  33.md  3.md   46.md  52.md  59.md  65.md	71.md  78.md  84.md  90.md  97.md
15.md	21.md  28.md  34.md  40.md  47.md  53.md  5.md	66.md	72.md  79.md  85.md  91.md  98.md
  • -n lets us take n-items at a time and do something with them. This can’t be used with -I because -I is basically -n 1 with variable support on top
workspace/play/numbers 
❯ seq 1 10 | xargs -I {} touch {}.md

workspace/play/numbers 
❯ ls
10.md  1.md  2.md  3.md  4.md  5.md  6.md  7.md  8.md  9.md

workspace/play/numbers 
❯ ls | xargs -tn 2 echo
echo 10.md 1.md
10.md 1.md
echo 2.md 3.md
2.md 3.md
echo 4.md 5.md
4.md 5.md
echo 6.md 7.md
6.md 7.md
echo 8.md 9.md
8.md 9.md

And here’s using the -n flag in a kind of interesting way:

workspace/play/numbers 
❯ ls | xargs -tn 2 mv  
mv 10.md 1.md
mv 2.md 3.md
mv 4.md 5.md
mv 6.md 7.md
mv 8.md 9.md

workspace/play/numbers 
❯ ls
1.md  3.md  5.md  7.md	9.md

Because we’re taking 2-at-a-time we can use those arguments as the first and second arguments to mv. (This is a wild example and no one would ever actually do THIS but they would do this idea)

  • -P is the max number of processes
  • The exec argument to find is slow which is why you might choose to use xargs instead of it (also note that the exec flag uses {} as its substitution)

Find all of the markdown files and just print out single line with each file:

~/workspace/play 
❯ tree 
.
├── books
│   ├── a court of mist and fury
│   ├── highlights.md
│   ├── we are ok
│   ├── wintering the power of rest in difficult times
│   └── yerba buena
├── gods
│   ├── aphrodite
│   ├── artemis
│   ├── athena
│   ├── gossip.md
│   ├── hera
│   └── zeus
├── numbers
│   ├── 10.md
│   ├── 1.md
│   ├── 2.md
│   ├── 3.md
│   ├── 4.md
│   ├── 5.md
│   ├── 6.md
│   ├── 7.md
│   ├── 8.md
│   └── 9.md
├── secret-thoughts.md
└── squishes
    ├── ella
    ├── gretchen
    ├── henry
    ├── lion
    └── rene

5 directories, 27 files

~/workspace/play 
❯ find -name "*.md" | xargs echo 
./books/highlights.md ./numbers/4.md ./numbers/1.md ./numbers/8.md ./numbers/10.md ./numbers/5.md ./numbers/9.md ./numbers/2.md ./numbers/6.md ./numbers/3.md ./numbers/7.md ./secret-thoughts.md ./gods/gossip.md

A nicer ls

One thing I had setup on my mac is aliasing ls to eza. A quick install and an alias that looks like

alias ls="eza --icons"

A nicer cat

bat is new to me but oh-so-nice for getting syntax highlighting.

alias cat='bat --theme="Catppuccin Mocha"'

Linux annoyance

On my mac I have a bunch of global hotkeys that I depend upon:

  • Bring up terminal
  • Alfred
  • Move windows - left, right, full screen
  • Clipboard history

Missing Semester Lecture 2 homework

xargs

As we covered in the lecture find’s -exec can be very powerful for performing operations over the files we are searching for. However, what if we want to do something with all the files, like creating a zip file? As you have seen so far commands will take input from both arguments and STDIN. When piping commands, we are connecting STDOUT to STDIN, but some commands like tar take inputs from arguments. To bridge this disconnect there’s the xargs command which will execute a command using STDIN as arguments. For example ls | xargs rm will delete the files in the current directory.

Your task is to write a command that recursively finds all HTML files in the folder and makes a zip with them. Note that your command should work even if the files have spaces (hint: check -d flag for xargs).

If you’re on macOS, note that the default BSD find is different from the one included in GNU coreutils. You can use -print0 on find and the -0 flag on xargs. As a macOS user, you should be aware that command-line utilities shipped with macOS may differ from the GNU counterparts; you can install the GNU versions if you like by using brew.

I modified this slightly since I’ve been playing with a folder of markdown all morning:

~/workspace/play 
❯ find . -name "*.md" -print0 | xargs -0 echo
./books/parts i didnt like.md ./books/highlights.md ./numbers/4.md ./numbers/1.md ./numbers/8.md ./numbers/10.md ./numbers/5.md ./numbers/9.md ./numbers/2.md ./numbers/6.md ./numbers/3.md ./numbers/7.md ./secret-thoughts.md ./gods/gossip.md

~/workspace/play 
❯ find . -name "*.md" -print0 | xargs -0 zip -r archive.zip 
  adding: books/parts i didnt like.md (stored 0%)
  adding: books/highlights.md (stored 0%)
  adding: numbers/4.md (stored 0%)
  adding: numbers/1.md (stored 0%)
  adding: numbers/8.md (stored 0%)
  adding: numbers/10.md (stored 0%)
  adding: numbers/5.md (stored 0%)
  adding: numbers/9.md (stored 0%)
  adding: numbers/2.md (stored 0%)
  adding: numbers/6.md (stored 0%)
  adding: numbers/3.md (stored 0%)
  adding: numbers/7.md (stored 0%)
  adding: secret-thoughts.md (deflated 32%)
  adding: gods/gossip.md (stored 0%)

And if we take a look at the zip:

❯ unzip -l archive.zip 
Archive:  archive.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2024-11-16 14:36   books/parts i didnt like.md
        0  2024-11-16 14:26   books/highlights.md
        0  2024-11-16 14:26   numbers/4.md
        0  2024-11-16 14:26   numbers/1.md
        0  2024-11-16 14:26   numbers/8.md
        0  2024-11-16 14:26   numbers/10.md
        0  2024-11-16 14:26   numbers/5.md
        0  2024-11-16 14:26   numbers/9.md
        0  2024-11-16 14:26   numbers/2.md
        0  2024-11-16 14:26   numbers/6.md
        0  2024-11-16 14:26   numbers/3.md
        0  2024-11-16 14:26   numbers/7.md
      296  2024-11-16 14:22   secret-thoughts.md
        0  2024-11-16 14:26   gods/gossip.md
---------                     -------
      296                     14 files

Find most recently modified files

~/workspace/play 
❯ find . -printf "%T@ | %Tc | %p\n" | sort -rn | head -n 8
1731786108.4763963550 | Sat 16 Nov 2024 02:41:48 PM EST | ./archive.zip
1731786108.4763963550 | Sat 16 Nov 2024 02:41:48 PM EST | .
1731786063.2726562920 | Sat 16 Nov 2024 02:41:03 PM EST | ./numbers
1731785799.0167644310 | Sat 16 Nov 2024 02:36:39 PM EST | ./books/parts i didnt like.md
1731785799.0167644310 | Sat 16 Nov 2024 02:36:39 PM EST | ./books
1731785213.3907332660 | Sat 16 Nov 2024 02:26:53 PM EST | ./gods/gossip.md
1731785213.3907332660 | Sat 16 Nov 2024 02:26:53 PM EST | ./gods
1731785203.2306722210 | Sat 16 Nov 2024 02:26:43 PM EST | ./books/highlights.md

Here’s a first attempt. The first column is important because it’s how sort is able to do its work but I don’t actually want to see it. This fixes that up with the cut command:

~/workspace/play 
❯ find . -printf "%T@ | %Tc | %p\n" | sort -rn | cut -d"|" -f2,3 | head -n 8
 Sat 16 Nov 2024 02:41:48 PM EST | ./archive.zip
 Sat 16 Nov 2024 02:41:48 PM EST | .
 Sat 16 Nov 2024 02:41:03 PM EST | ./numbers
 Sat 16 Nov 2024 02:36:39 PM EST | ./books/parts i didnt like.md
 Sat 16 Nov 2024 02:36:39 PM EST | ./books
 Sat 16 Nov 2024 02:26:53 PM EST | ./gods/gossip.md
 Sat 16 Nov 2024 02:26:53 PM EST | ./gods
 Sat 16 Nov 2024 02:26:43 PM EST | ./books/highlights.md

And I’m even happier with this:

~/workspace/play 
❯ find . -type f -printf "%T@ | %TY-%Tm-%Td %TH:%TM %p\n" | sort -n -r | cut -d "|" -f 2 | head -n 8
 2024-11-16 14:41 ./archive.zip
 2024-11-16 14:36 ./books/parts i didnt like.md
 2024-11-16 14:26 ./gods/gossip.md
 2024-11-16 14:26 ./books/highlights.md
 2024-11-16 14:26 ./numbers/10.md
 2024-11-16 14:26 ./numbers/9.md
 2024-11-16 14:26 ./numbers/8.md
 2024-11-16 14:26 ./numbers/7.md

Nicer manpage reading

We can have much nicer manpages by setting a variable for the manpager. This goes in my ~/.zshrc

export MANPAGER="nvim +Man\!"

End of day

Today was a quiet day of working from my apartment before having a big adventure exploring NYC and seeing the a fancy event at the library and exploring grand central station.

Worked on Today

Tomorrow

  • Maybe secret project stuff
  • Working on a small silly website to show off pictures of my stuffed Lion exploring NY
  • more xargs practice (until it feels comfortable and familiar)