diff --git a/build.boot b/build.boot index b0b062f..e02dcf6 100644 --- a/build.boot +++ b/build.boot @@ -19,7 +19,7 @@ (sift :move {#"^img/(.*)" "public/img/$1"}) (sift :to-resource #{#"^extra/(.*)"}) (sift :move {#"^extra/(.*)" "public/extra/$1"}) - (garden :styles-var 'site.styles/base :output-to "public/main.css") + (garden :styles-var 'site.styles/base :output-to "main.css") (perun/render :renderer 'site.core/page) (perun/sitemap :filename "sitemap.xml") (sift :move {#"^public/(.*)" "$1"}))) diff --git a/content/bash.md b/content/bash.md new file mode 100644 index 0000000..9ea40a5 --- /dev/null +++ b/content/bash.md @@ -0,0 +1,10 @@ +--- +title: Writing a Program in Bash +date: 2015-04-12 +--- + +I don't really know why, but writing code in Bash makes me kinda anxious. It feels really old, outdated, and confusing. Why can't a function return a string? And no classes, or even data types? After getting confused, usually, I just end up switching to Python. + +But this time, I decided to stick with Bash. And I am surprised. It is unbelievebly good. I must say, now I understand the Unix philosophy much better. Having small programs doing one thing very good allows you to combine the power of those programs in your scripts. You think your favourite programming language has a lot of libraries? Well, bash has access to more. The entire Unix ecosystem powers bash. Converting videos, taking screenshots, sending mails, downloading and processing pages; there are already command line tools for all of that, and you have great access to all of them. + +The program I've started writing is called [WoWutils](https://github.com/SeriousBug/WoWutils). And I'm still shocked at just how much functionality I have added with so little code. If you are considering writing a program in Bash too, just go through with it. It really is very powerful. diff --git a/content/customizing-emacs.md b/content/customizing-emacs.md new file mode 100644 index 0000000..f6de212 --- /dev/null +++ b/content/customizing-emacs.md @@ -0,0 +1,92 @@ +--- +title: Emacs and extensibility +date: 2015-10-06 +--- + +Update: I've put the small Emacs tools I have written to a +[gist](https://gist.github.com/91c38ddde617b98ffbcb). + +I have been using Emacs for some time, and I really love it. The +amount of power it has, and the customizability is incredible. What +other editor allow you to connect to a server over SSH and edit files, +which is what I am doing to write this post. How many editors or IDE's +have support for so many languages? + + + +One thing I didn't know in the past, however, is extensibility of +Emacs. I mean, I do use a lot of packages, but I had never written +Elisp and I didn't know how hard or easy it would be. But after +starting to learn Clojure a bit, and feeling more comfortable with +lots of parenthesis, I decided to extend Emacs a bit to make it fit +myself better. + +The first thing I added is an "insert date" function. I use Emacs to +take notes during lessons -using Org-mode- and I start every note with +the date of the lesson. Sure, glancing at the date to the corner of my +screen and writing it down takes just a few seconds, but why not write +a command to do it for me? Here is what I came up with: + +```commonlisp +(defun insert-current-date () + "Insert the current date in YYYY-MM-DD format." + (interactive) + (shell-command "date +'%Y-%m-%d'" t)) +``` + +Now that was easy and convenient. And being able to write my first +piece of Elisp so easily was really fun, so I decided to tackle +something bigger. + +It is not rare that I need to compile and run a single C file. Nothing +fancy, no libraries, no makefile, just a single C file to compile and +run. I searched around the internet like "Emacs compile and run C", but +couldn't find anything. I had been doing this by opening a shell in +Emacs and compiling/running the program, but again, why not automate +it? + +The code that follows is not really good. "It works" is as good as it +gets really, and actually considering that this is the first +substantial Elisp I have written, that is pretty impressive -for the +language and Emacs, which are both very helpful and powerful- I think. + + +```commonlisp +(require 's) +(defun compile-run-buffer () + "Compile and run buffer." + (interactive) + (let* ((split-file-path (split-string buffer-file-name "/")) + (file-name (car (last split-file-path))) + (file-name-noext (car (split-string file-name "[.]"))) + (buffer-name (concat "compile-run: " file-name-noext)) + (buffer-name* (concat "*" buffer-name "*"))) + (make-comint buffer-name "gcc" nil "-Wall" "-Wextra" "-o" file-name-noext file-name) + (switch-to-buffer-other-window buffer-name*) + (set-process-sentinel (get-buffer-process (current-buffer)) + (apply-partially + '(lambda (prog-name proc even) + (if (s-suffix? "finished\n" even) + (progn + (insert "Compilation successful.\n\n") + (comint-exec (current-buffer) prog-name (concat "./" prog-name) nil nil)) + (insert (concat "Compilation failed!\n" even)))) + file-name-noext)))) +``` + + +Again, the code is not really good. I'm uploading it here right now +because I'm actually very excited that I wrote this. Just now I can +think of ways to improve this, for example moving the compiler and the +flags to variables so that they can be customized. I could also +improve the presentation, because strings printed by this function, +comint and the running programs mixes up. I'll update this blog post +if I get to updating the code. + +If this is your first time hearing about Emacs, this post may look +very confusing. I don't to Emacs any justice here, so do check it out +somewhere like [Emacs rocks](http://emacsrocks.com/). On the other +hand, if you have been looking a functionality like this, hope this +helps. If you have any suggestions about the code, I'd love to hear +them, you can find my email on the "about me" page. Anyway, have a +good day! diff --git a/content/duplicity.md b/content/duplicity.md new file mode 100644 index 0000000..8c56db3 --- /dev/null +++ b/content/duplicity.md @@ -0,0 +1,57 @@ +--- +title: Taking Backups with Duplicity +date: 2015-05-16 +--- + + +I wanted to start taking backups for some time, but I haven't had the time to do any research and set everything up. After reading another [horror story that was saved by backups](https://www.reddit.com/r/linuxmasterrace/comments/35ljcq/couple_of_days_ago_i_did_rm_rf_in_my_home/), I decided to start taking some backups. + + + +After doing some research on backup options, I decided on [duplicity](http://duplicity.nongnu.org/). The backups are compressed, encrypted and incremental, both saving space and ensuring security. It supports both local and ssh files(as well as many other protocols), so it has everything I need. + +I first took a backup into my external hard drive, then VPS. The main problem I encountered was that duplicity uses [paramiko](https://github.com/paramiko/paramiko) for ssh, but it wasn't able to negotiate a key exchange algorithm with my VPS. Luckily, duplicity also supports [pexpect](http://pexpect.sourceforge.net/pexpect.html), which uses OpenSSH. If you encounter the same problem, you just need to tell duplicity to use pexpect backend by prepending your url with `pexpect+`, like `pexpect+ssh://example.com`. + +Duplicity doesn't seem to have any sort of configuration files of itself, so I ended up writing a small bash script to serve as a sort of configuration, and also keep me from running duplicity with wrong args. I kept forgetting to add an extra slash to `file://`, causing duplicity to backup my home directory into my home directory! :D + +If anyone is interested, here's the script: + +```bash +#!/bin/bash + +if [[ $(id -u) != "0" ]]; then + read -p "Backup should be run as root! Continue? [y/N]" yn + case $yn in + [Yy]*) break;; + *) exit;; + esac +fi + + +if [[ $1 = file://* ]]; then + echo "Doing local backup." + ARGS="--no-encryption" + if [[ $1 = file:///* ]]; then + URL=$1 + else + echo "Use absolute paths for backup." + exit 1 + fi +elif [[ $1 = scp* ]]; then + echo "Doing SSH backup." + ARGS="--ssh-askpass" + URL="pexpect+$1" +else + echo "Unknown URL, use scp:// or file://" + exit 1 +fi + + +if [[ -n "$1" ]]; then + duplicity $ARGS --exclude-filelist /home/kaan/.config/duplicity-files /home/kaan "$URL/backup" +else + echo "Please specify a location to backup into." + exit 1 +fi + +``` diff --git a/content/emacs-as-an-os.md b/content/emacs-as-an-os.md new file mode 100644 index 0000000..83e116f --- /dev/null +++ b/content/emacs-as-an-os.md @@ -0,0 +1,238 @@ +--- +title: Emacs as an operating system +date: 2016-04-14 +modified: 2016-05-29 +--- + +Emacs is sometimes jokingly called a good operating system with a bad +text editor. Over the last year, I found myself using more and more of +Emacs, so I decided to try out how much of an operating system it +is. Of course, operating system here is referring to the programs that +the user interacts with, although I would love to try out some sort of +Emacs-based kernel. + + + +# Emacs as a terminal emulator / multiplexer + +Terminals are all about text, and Emacs is all about text as well. Not +only that, but Emacs is also very good at running other processes and +interacting with them. It is no surprise, I think, that Emacs works +well as a terminal emulator. + +Emacs comes out of the box with `shell` and `term`. Both of these +commands run the shell of your choice, and give you a buffer to +interact with it. Shell gives you a more emacs-y experience, while +term overrides all default keymaps to give you a full terminal +experience. + +![Emacs as a terminal emulator](/img/emacs-terminal.png) + +To use emacs as a full terminal, you can bind these to a key in your +window manager. I'm using i3, and my keybinding looks like this: + +``` +bindsym $mod+Shift+Return exec --no-startup-id emacs --eval "(shell)" +``` + +You can also create a desktop file to have a symbol to run this on a +desktop environment. Try putting the following text in a file at +`~/.local/share/applications/emacs-terminal.desktop`: + +``` +[Desktop Entry] +Name=Emacs Terminal +GenericName=Terminal Emulator +Comment=Emacs as a terminal emulator. +Exec=emacs --eval '(shell)' +Icon=emacs +Type=Application +Terminal=false +StartupWMClass=Emacs +``` + +If you want to use term instead, replace `(shell)` above with `(term "/usr/bin/bash")`. + +A very useful feature of terminal multiplexers is the ability to leave +the shell running, even after the terminal is closed, or the ssh +connection has dropped if you are connection over that. Emacs can also +achieve this with it's server-client mode. To use that, start emacs +with `emacs --daemon`, and then create a terminal by running +`emacsclient -c --eval '(shell)'`. Even after you close emacsclient, +since Emacs itself is still running, you can run the same command +again to get back to your shell. + +One caveat is that if there is a terminal/shell already running, Emacs +will automatically open that whenever you try opening a new one. This +can be a problem if you are using Emacs in server-client mode, or want +to have multiple terminals in the same window. In that case, you can +either do `M-x rename-uniquely` to change the name of the existing +terminal, which will make Emacs create a new one next time, or you can +add that to hook in your `init.el` to always have that behaviour: + +```lisp +(add-hook 'shell-mode-hook 'rename-uniquely) +(add-hook 'term-mode-hook 'rename-uniquely) +``` + +# Emacs as a shell + +Of course, it is not enough that Emacs works as a terminal +emulator. Why not use Emacs as a shell directly, instead of bash/zsh? +Emacs has you covered for that too. You can use eshell, which is a +shell implementation, completely written in Emacs Lisp. All you need +to do is press `M-x eshell`. + +![Eshell, Emacs shell](/img/eshell.png) + +The upside is that eshell can evaluate and expand lisp expressions, as +well as redirecting the output to Emacs buffers. The downside is +however, eshell is not feature complete. It lacks some features such +as input redirection, and the documentation notes that it is +inefficient at piping output between programs. + +If you want to use eshell instead of shell or term, you can replace +`shell` in the examples of terminal emulator section with `eshell`. + +# Emacs as a mail cilent + +[Zawinski's Law](http://www.catb.org/~esr/jargon/html/Z/Zawinskis-Law.html): +Every program attempts to expand until it can read mail. Of course, it +would be disappointing for Emacs to not handle mail as well. + +Emacs already ships with some mail capability. To get a full +experience however, I'd recommend using +[mu4e](http://www.djcbsoftware.nl/code/mu/mu4e.html) (mu for emacs). I +have personally set up [OfflineIMAP](http://www.offlineimap.org/) to +retrieve my emails, and mu4e gives me a nice interface on top of that. + +![mu4e, mail client](/img/mu4e.png) + +I'm not going to talk about the configurations of these programs, I'd +recommend checking out their documentations. Before ending this +section, I also want to mention +[mu4e-alert](https://github.com/iqbalansari/mu4e-alert) though. + +# Emacs as a feed reader (RSS/Atom) + +Emacs handles feeds very well too. The packages I'm using here are +[Elfeed](https://github.com/skeeto/elfeed) and +[Elfeed goodies](https://github.com/algernon/elfeed-goodies). Emacs +can even show images in the feeds, so it covers everything I need from +a feed reader. + +![Elfeed, feed reader](/img/elfeed.png) + +# Emacs as a file manager + +Why use a different program to manage your files when you can use +Emacs? Emacs ships with dired, as well as image-dired. This gives you +a file browser, with optional image thumbnail support. + +# Emacs as a document viewer + +Want to read a pdf? Need a program to do a presentation? Again, Emacs. + +![Docview, document viewer](/img/docview.png) + +Emacs comes with +[DocView](https://www.gnu.org/software/emacs/manual/html_node/emacs/Document-View.html) +which has support for PDF, OpenDocument and Microsoft Office files. It +works surprisingly well. + +Also, [PDF Tools](https://github.com/politza/pdf-tools) brings even +more PDF viewing capabilities to Emacs, including annotations, text +search and outline. After installing PDF Tools, Emacs has become my +primary choice for reading PDF files. + +# Emacs as a browser + +Emacs comes out of box with +[eww](https://www.gnu.org/software/emacs/manual/html_node/eww/index.html#Top), +a text-based web browser with support for images as well. + +![eww, browser](/img/eww.png) + +Honestly, I don't think I'll be using Emacs to browse the web. But +still, it is nice that the functionality is there. + +# Emacs as a music player + +Emacs can also act as a music player thanks to +[EMMS](https://www.gnu.org/software/emms/), Emacs MultiMedia +System. If you are wondering, it doesn't play the music by itself but +instead uses other players like vlc or mpd. + +It has support for playlists, and can show thumbnails as well. For the +music types, it supports whatever the players it uses support, which +means that you can basically use file type. + +# Emacs as a IRC client + +I don't use IRC a lot, but Emacs comes out of the box with support for +that as well thanks to +[ERC](https://www.emacswiki.org/emacs?action=browse;oldid=EmacsIrcClient;id=ERC). + +![erc, Emacs IRC client](/img/erc.png) + +# Emacs as a text editor + +Finally, Emacs also can work well as a text editor. + +Emacs is a pretty fine text editor out of the box, but I want to +mention some packages here. + +First, +[multiple cursors](https://github.com/magnars/multiple-cursors.el). Multiple +cursors mode allows you to edit text at multiple places at the same +time. + +I also want to mention +[undo-tree](http://www.dr-qubit.org/emacs.php#undo-tree). It acts like +a mini revision control system, allowing you to undo and redo without +ever losing any text. + +Another great mode is +[iy-go-to-char](https://github.com/doitian/iy-go-to-char). It allows +you to quickly jump around by going to next/previous occurrances of a +character. It is very useful when you are trying to move around a +line. + +[Ace Jump Mode](https://github.com/winterTTr/ace-jump-mode/) allows +you to jump around the visible buffers. It can jump around based on +initial characters of words, or jump to specific lines. It can also +jump from one buffer to another, which is very useful when you have +several buffers open in your screen. + +![Ace Jump Mode](/img/ace-jump-mode.png) + +Finally, I want to mention [ag.el](https://github.com/Wilfred/ag.el), +which is an Emacs frontend for the silver searcher. If you don't know +about ag, it is a replacement for grep that recursively searches +directories, and has some special handling for projects, and is very +fast. + +# Emacs as an IDE + +People sometimes compare Emacs to IDE's and complain that a text +editor such as Emacs doesn't have enough features. What they are +forgetting, of course, is that Emacs is an operating system, and we +can have an IDE in it as well. + +There are different packages for every language, so I'll be only +speaking on language agnostic ones. + +For interacting with git, [magit](http://magit.vc/) is a wonderful +interface. + +![Magit, Git Porcelain](/img/magit.png) + +For auto-completion, [Company mode](https://company-mode.github.io/) +works wonders. I rely heavily on completion while writing code, and +company mode has support for anything I tried writing. + +If you like having your code checked as you type, +[flycheck](https://www.flycheck.org/) has you covered. It has support +for many tools and languages. + +![Company Mode and Flycheck](/img/company-flycheck.png) diff --git a/content/extra/cv.pdf b/content/extra/cv.pdf index 3087182..f0e8612 100755 Binary files a/content/extra/cv.pdf and b/content/extra/cv.pdf differ diff --git a/content/img/ace-jump-mode.png b/content/img/ace-jump-mode.png new file mode 100644 index 0000000..cf0a74b Binary files /dev/null and b/content/img/ace-jump-mode.png differ diff --git a/content/img/cc-by-sa-4.0-88x31.png b/content/img/cc-by-sa-4.0-88x31.png new file mode 100644 index 0000000..5d64b4a Binary files /dev/null and b/content/img/cc-by-sa-4.0-88x31.png differ diff --git a/content/img/company-flycheck.png b/content/img/company-flycheck.png new file mode 100644 index 0000000..ae15c68 Binary files /dev/null and b/content/img/company-flycheck.png differ diff --git a/content/img/docview.png b/content/img/docview.png new file mode 100644 index 0000000..5a9cc45 Binary files /dev/null and b/content/img/docview.png differ diff --git a/content/img/elfeed.png b/content/img/elfeed.png new file mode 100644 index 0000000..d10e80c Binary files /dev/null and b/content/img/elfeed.png differ diff --git a/content/img/emacs-terminal.png b/content/img/emacs-terminal.png new file mode 100644 index 0000000..908f937 Binary files /dev/null and b/content/img/emacs-terminal.png differ diff --git a/content/img/erc.png b/content/img/erc.png new file mode 100644 index 0000000..3fe02a5 Binary files /dev/null and b/content/img/erc.png differ diff --git a/content/img/eshell.png b/content/img/eshell.png new file mode 100644 index 0000000..f19df1d Binary files /dev/null and b/content/img/eshell.png differ diff --git a/content/img/eww.png b/content/img/eww.png new file mode 100644 index 0000000..58efe3d Binary files /dev/null and b/content/img/eww.png differ diff --git a/content/img/magit.png b/content/img/magit.png new file mode 100644 index 0000000..8aaf01c Binary files /dev/null and b/content/img/magit.png differ diff --git a/content/img/mu4e.png b/content/img/mu4e.png new file mode 100644 index 0000000..04bff37 Binary files /dev/null and b/content/img/mu4e.png differ diff --git a/content/img/passmenu.png b/content/img/passmenu.png new file mode 100644 index 0000000..514ae47 Binary files /dev/null and b/content/img/passmenu.png differ diff --git a/content/img/password_store.png b/content/img/password_store.png new file mode 100644 index 0000000..b4c3e0a Binary files /dev/null and b/content/img/password_store.png differ diff --git a/content/index.markdown b/content/index.markdown index c5eca0b..029944b 100644 --- a/content/index.markdown +++ b/content/index.markdown @@ -76,5 +76,5 @@ above the university mean for classes of similar size. ![A picture from a 3-D video game, showing a river flowing into the sea. The text "The Land Itself" is overlayed on the sea.](/img/game-cover.jpg)\ -On my free time, I develop small indie video games and release them open source. +In my free time, I develop small indie video games and release them open source. diff --git a/content/mpv.md b/content/mpv.md new file mode 100644 index 0000000..d83bb46 --- /dev/null +++ b/content/mpv.md @@ -0,0 +1,58 @@ +--- +title: Motion Interpolation, 24 FPS to 60 FPS with mpv, VapourSynth and MVTools +date: 2015-07-18 +modified: 2015-07-20 +--- + +Watching videos at 60 FPS is great. It makes the video significantly smoother and much more enjoyable. Sadly, lots of movies and TV shows are still at 24 FPS. However, I recently discovered that it is actually possible to interpolate the extra frames by using motion interpolation, and convert a video from 24 FPS to 60 FPS in real time. While it is far from perfect, I think the visual artifacts are a reasonable tradeoff for high framerate. + + + +Firstly, what we need is mpv with VapourSynth enabled, and MVTools plugin for VapourSynth. VapourSynth must be enabled while compiling mpv. I adopted an AUR package [mpv-vapoursynth](https://aur4.archlinux.org/packages/mpv-vapoursynth/) which you can use if you are on Arch. Otherwise, all you need to do is use `--enable-vapoursynth` flag when doing `./waf --configure`. They explain the compilation on their [repository](https://github.com/mpv-player/mpv), so look into there if you are compiling yourself. + +After that, we need MVTools plugin for VapourSynth. This is available on Arch via [vapoursynth-plugin-mvtools](https://www.archlinux.org/packages/community/x86_64/vapoursynth-plugin-mvtools/), otherwise you can find their repository [here](https://github.com/dubhater/vapoursynth-mvtools). There is also a [PPA for Ubuntu](https://launchpad.net/~djcj/+archive/ubuntu/vapoursynth) where you can find `vapoursynth-extra-plugins`, but I haven't used it myself so I can't comment on it. + +After both of these are enabled, we need a script to use MVTools from VapourSynth. There is one written by Niklas Haas, which you can find here as [mvtools.vpy](https://github.com/haasn/gentoo-conf/blob/master/home/nand/.mpv/filters/mvtools.vpy). Personally, I tweaked the block sizes and precision to my liking, as well as removing the resolution limit he added. I'll put the modified version here: + +```python +# vim: set ft=python: + +import vapoursynth as vs +core = vs.get_core() +clip = video_in + +dst_fps = display_fps +# Interpolating to fps higher than 60 is too CPU-expensive, smoothmotion can handle the rest. +while (dst_fps > 60): + dst_fps /= 2 + +# Skip interpolation for 60 Hz content +if not (container_fps > 59): + src_fps_num = int(container_fps * 1e8) + src_fps_den = int(1e8) + dst_fps_num = int(dst_fps * 1e4) + dst_fps_den = int(1e4) + # Needed because clip FPS is missing + clip = core.std.AssumeFPS(clip, fpsnum = src_fps_num, fpsden = src_fps_den) + print("Reflowing from ",src_fps_num/src_fps_den," fps to ",dst_fps_num/dst_fps_den," fps.") + + sup = core.mv.Super(clip, pel=1, hpad=8, vpad=8) + bvec = core.mv.Analyse(sup, blksize=8, isb=True , chroma=True, search=3, searchparam=1) + fvec = core.mv.Analyse(sup, blksize=8, isb=False, chroma=True, search=3, searchparam=1) + clip = core.mv.BlockFPS(clip, sup, bvec, fvec, num=dst_fps_num, den=dst_fps_den, mode=3, thscd2=12) + +clip.set_output() +``` + +At this point, you should be able to try this out as suggested in the script. To set this up more permanently, I'd suggest placing this script as `~/.config/mpv/mvtools.vpy`, and also writing the following as `~/.config/mpv/mpv.conf`: + +``` +hwdec=no +vf=vapoursynth=~/.config/mpv/mvtools.vpy +``` + +Now, whenever you open mpv, it will always use motion interpolation. + +The result is fairly good. I noticed some significant artifacts while watching anime, but it works well with movies. I'm guessing that it is harder to track the motion in animations since they are generally exaggerated. + +One thing to keep in mind, however, is performance. With `rel=2`, viewing a 1080p video results in around 90% CPU usage across all cores and 1.6 GBs of ram on my Intel i7 4700MQ. With `rel=1`, CPU usage goes down to about 60% per core. This process is very heavy on the processor, and you may have trouble unless you have a fast CPU. diff --git a/content/pass.md b/content/pass.md new file mode 100644 index 0000000..d7aed90 --- /dev/null +++ b/content/pass.md @@ -0,0 +1,18 @@ +--- +title: Switching to pass +date: 2015-03-30 +--- + +For some time, I used LastPass to store my passwords. While LastPass works well, it doesn't fit into the keyboard driven setup I have. I have been looking into alternatives for some time, I looked into KeePassX but just like LastPass, it doesn't give me any ways to set up keyboard shortcuts. On the other hand, and I recently came across [pass](http://www.passwordstore.org/), and it provides everything I want. + + + +Pass uses GPG keys to encrypt the passwords, and git to keep revisions and backups. It integrates well with the shell, and there is a dmenu script, a Firefox plugin and an Android app. All the passwords are just GPG enrypted files, stored in some folders anyway, so you don't need anything special to work with them. + +![passmenu, the dmenu pass script](/static/passmenu.png) + +So first, I needed to migrate my passwords from LastPass to pass. The website lists some scripts for migration, but sadly I missed that when I first looked at the page. So I decided to write a [python script to handle the migration](https://gist.github.com/SeriousBug/e9f33873d10ad944cbe6) myself. It inserts all passwords in `domain/username` format, and if there is any extra data written, it is added after the password as well. Secure notes are placed into their own folder, and any "Generated Password for ..." entries are skipped. If you're migrating from LastPass to pass, feel free to give it a try. If you are taking an export from their website however, do make sure that there is no whitespace before and after the csv. + +![Password Store, the pass Android app](/static/password_store.png) + +I certainly recommend trying out pass. It works very well, and it fits in with the unix philosophy. diff --git a/src/site/core.clj b/src/site/core.clj index 62091a7..72be5a8 100644 --- a/src/site/core.clj +++ b/src/site/core.clj @@ -1,27 +1,36 @@ (ns site.core - (:require [hiccup.page :as hp] - [garden.core :as gc])) + (:require [hiccup.page :as hp])) -(defn page [data] +(defn format-time [time] (.format (-> time .toInstant (.atZone (java.time.ZoneId/systemDefault)) .toLocalDate) (java.time.format.DateTimeFormatter/ofPattern "MMM d, yyyy"))) + + +(defn page [{global-meta :meta posts :entries post :entry}] (hp/html5 [:head [:meta {:charset "utf-8"}] [:link {:rel "stylesheet" :href "main.css"}]] - [:title "Homepage of Kaan Genç"] + [:title "Homepage of Kaan Genç"] [:link {:href "https://fonts.googleapis.com/css2?family=Ubuntu:ital,wght@0,400;0,700;1,400;1,700&display=swap" :rel "stylesheet"}] - (when (= "index" (-> data :entry :slug)) - [:div.sidebar.column - [:img.picture {:alt "A photo of Kaan Genç, after his OOPSLA 2019 talk." :src "/img/profile.jpg"}] - [:div.name "Kaan Genç"] - [:div.title "PhD Student"] - [:div.department "Computer Science & Engineering"] - [:div.affiliation "The Ohio State University"] - [:span [:a.email {:href "mailto:genc.5@osu.edu"} "genc.5@osu.edu"] [:a.gpg {:href "/extra/kaangenc.gpg"} "GPG key"]] - [:a.github {:href "https://github.com/SeriousBug"} "Github"] - [:a.researchr {:href "https://conf.researchr.org/profile/kaangenc"} "Researchr"] - [:a.cv {:href "/extra/cv.pdf"} "CV"]]) - [:div.main.column - (-> data :entry :content)])) + [:div.sidebar.column + [:img.picture {:alt "A photo of Kaan Genç, after his OOPSLA 2019 talk." :src "/img/profile.jpg"}] + [:div.name "Kaan Genç"] + [:div.title "PhD Student"] + [:div.department "Computer Science & Engineering"] + [:div.affiliation "The Ohio State University"] + [:span [:a.email {:href "mailto:genc.5@osu.edu"} "genc.5@osu.edu"] [:a.gpg {:href "/extra/kaangenc.gpg"} "GPG key"]] + [:a.github {:href "https://github.com/SeriousBug"} "Github"] + [:a.github {:href "https://twitter.com/KaanGencCS"} "Twitter"] + [:a.researchr {:href "https://conf.researchr.org/profile/kaangenc"} "Researchr"] + [:a.cv {:href "/extra/cv.pdf"} "CV"]] + (if (= "index" (:slug post)) + ;; Index page + [:div.main.column (:content post)] + ;; Blog post + [:div.main.column + [:h1.post-title (:title post)] + [:div.date "Written at " (-> post :date format-time)] + (when (:modified post) [:div.modified "Last edited at " (-> post :modified format-time)]) + (:content post)]))) diff --git a/src/site/styles.clj b/src/site/styles.clj index ead11b8..5d332bd 100644 --- a/src/site/styles.clj +++ b/src/site/styles.clj @@ -11,7 +11,7 @@ ["h1:not(:first-child)" {:margin-top "2em"}] [:h2 {:font-size "1.3em"}] [:h3 {:font-size "1.15em"}] - ["img, .img" {:border-radius "5px"}] + ["img, .img" {:border-radius "5px" :max-width "100%"}] [:.sidebar {:max-width "300px"} [">a,span" {:display "block" :padding "10px 0"}]