diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..45e4dcec704df4f5516da9544445415f3bdd4d3e
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,49 @@
+cmake_minimum_required(VERSION 3.10)
+
+project(laga-signatur VERSION 0.1)
+
+set(CMAKE_CXX_STANDARD 20)
+
+set(SOURCES laga-signatur.cpp translations.cpp main.cpp)
+set(HEADERS laga-signatur.h translations.h)
+
+add_compile_definitions(PROGRAM_VERSION="0.1")
+add_compile_definitions(TRANSLATIONS_DIR="/home/hugo/code/laga-signatur/build/dest/usr/local/share/locale")
+
+add_executable(laga-signatur ${SOURCES})
+
+target_compile_options(laga-signatur PRIVATE
+	-Wall -Wextra -Wconversion -pedantic)
+
+set(boost_USE_STATIC_LIBS OFF)
+set(boost_USE_STATIC_RUNTIME OFF)
+find_package(Boost 1.83.0 COMPONENTS program_options REQUIRED)
+
+if(Boost_FOUND)
+	include_directories(${Boost_INCLUDE_DIRS})
+	target_link_libraries(laga-signatur ${Boost_LIBRARIES})
+endif()
+
+find_package(Gettext REQUIRED)
+if (GETTEXT_FOUND)
+	include_directories(${GETTEXT_INCLUDE_DIRS})
+	link_directories(${GETTEXT_LIBRARY_DIRS})
+	add_definitions(${GETTEXT_DEFINITIONS})
+	target_link_libraries(laga-signatur ${GETTEXT_LIBRARIES})
+
+	GETTEXT_PROCESS_PO_FILES(
+		sv ALL
+		INSTALL_DESTINATION share/locale
+		PO_FILES po/sv/laga-signatur.po)
+endif()
+
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(XDG_BASEDIR REQUIRED libxdg-basedir)
+target_include_directories(laga-signatur PUBLIC ${XDG_BASEDIR_INCLUDE_DIRS})
+target_link_libraries(laga-signatur ${XDG_BASEDIR_LIBRARIES})
+target_compile_options(laga-signatur PUBLIC ${XDG_BASEDIR_CFLAGS_OTHERS})
+
+install(TARGETS laga-signatur DESTINATION bin/laga-signatur)
+install(FILES man/laga-signatur.1 DESTINATION share/man/man1)
+install(FILES man/sv/laga-signatur.1 DESTINATION share/man/sv/man1)
+install(FILES lagar.data DESTINATION share/laga-signatur)
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..eda4588cc946591c96045d0cf14d3f3bdee2cf24
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,13 @@
+.PHONY: all
+
+all:
+	@echo 'Use CMake to actually build this project'
+	@echo 'This makefile however sets up translation sources'
+	@echo 'Please see Makefile for details.'
+
+po/laga-signatur.pot:
+	xgettext --keyword=_ --language=c++ --from-code=utf-8 --add-comments -o $@ *.cpp
+
+po/%/laga-signatur.po: po/laga-signatur.pot
+	mkdir -p $(dir $@)
+	msginit --input=$< --locale=$(basename $(dir $@)) --output=$@
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..d2c5e13f2aa507a93dfbbe1f11cc5a3fd0b5adc8
--- /dev/null
+++ b/README.md
@@ -0,0 +1,13 @@
+Building
+--------
+
+Dependencies
+------------
+- boost-libs
+- libxdg-basedir
+
+Dev Dependencies
+----------------
+- boost development libraries
+- A C++ compiler
+- cmake
diff --git a/laga-signatur.cpp b/laga-signatur.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..47f888fac68b2173101e2038d09290e97b32d51c
--- /dev/null
+++ b/laga-signatur.cpp
@@ -0,0 +1,66 @@
+#include "laga-signatur.h"
+
+#include <fstream>
+#include <iostream>
+#include <random>
+#include <string>
+#include <vector>
+
+#include "translations.h"
+
+const char US = 0x1F; /* ASCII Unit Separator */
+
+std::ostream &operator<< (std::ostream &out, const law_entry &entry) {
+	out << entry.name << " <" << entry.url << ">";
+	return out;
+}
+
+std::ostream &operator<< (std::ostream &out, const signature_message &msg) {
+	out << msg.username << "\n";
+	if (! msg.title.empty()) {
+		out << msg.title << "\n";
+	}
+	out << "\n" << msg.association << " följer " << msg.law;
+	return out;
+}
+
+std::vector<law_entry> load_lagar(
+		std::ifstream &law_file,
+		const std::string &filename)
+{
+	std::vector<law_entry> entries;
+
+	std::string line;
+	while (true) {
+		std::getline(law_file, line);
+		if (law_file.bad()) {
+			throw std::runtime_error(_("Failed reading line from file: ") + filename);
+		}
+		if (law_file.eof()) break;
+		if (line.empty()) break;
+		// law_file.exceptions(law_file.failbit);
+
+		size_t delim = line.find(US);
+		if (delim == std::string::npos) continue;
+
+		law_entry entry {
+			.name = line.substr(0, delim),
+			.url = line.substr(delim),
+		};
+
+		entries.push_back(entry);
+	}
+
+	return entries;
+}
+
+template <typename T>
+static T &rand_choice(std::vector<T> &v) {
+	std::random_device rd;
+	std::uniform_int_distribution<size_t> dist(0, v.size());
+	return v[dist(rd)];
+}
+
+law_entry &random_law(std::vector<law_entry> entries) {
+	return rand_choice(entries);
+}
diff --git a/laga-signatur.h b/laga-signatur.h
new file mode 100644
index 0000000000000000000000000000000000000000..d3d76d8319496a7656487e631eb80e304094d30b
--- /dev/null
+++ b/laga-signatur.h
@@ -0,0 +1,32 @@
+#ifndef LAGA_SIGNATUR_H
+#define LAGA_SIGNATUR_H
+
+#include <string>
+#include <iostream>
+#include <vector>
+#include <fstream>
+
+struct law_entry {
+	std::string name;
+	std::string url;
+
+	friend std::ostream &operator<< (std::ostream &, const law_entry &);
+};
+
+
+struct signature_message {
+	std::string username;
+	std::string association;
+	std::string title;
+	law_entry law;
+
+	friend std::ostream &operator<< (std::ostream &, const signature_message &);
+};
+
+std::vector<law_entry> load_lagar(
+		std::ifstream &law_file,
+		const std::string &filename);
+
+law_entry &random_law(std::vector<law_entry> entries);
+
+#endif /* LAGA_SIGNATUR_H */
diff --git a/lagar.data b/lagar.data
new file mode 100644
index 0000000000000000000000000000000000000000..45dc0fa911e6acb030639c5096ecc290a3ddd3ee
--- /dev/null
+++ b/lagar.data
@@ -0,0 +1,95 @@
+föräldrabalkenhttps://lagen.nu/1949:381
+ärvdabalkenhttps://lagen.nu/1958:637
+äktenskapsbalkenhttps://lagen.nu/1987:230
+lagen om personnamnhttps://lagen.nu/2016:1013
+sambolagenhttps://lagen.nu/2003:376
+medbestämmandelagenhttps://lagen.nu/1976:580
+lagen om anställningsskyddhttps://lagen.nu/1982:80
+lagen om rättegången i arbetstvisterhttps://lagen.nu/1974:371
+semesterlagenhttps://lagen.nu/1977:480
+arbetstidslagenhttps://lagen.nu/1982:673
+lagen om offentlig anställninghttps://lagen.nu/1994:260
+visselblåsarlagenhttps://lagen.nu/2021:890
+avtalslagenhttps://lagen.nu/1915:218
+prokuralagenhttps://lagen.nu/1974:158
+lagen om avtalsvillkor mellan näringsidkarehttps://lagen.nu/1984:292
+lagen om avtalsvillkor i konsumentförhållandenhttps://lagen.nu/1994:1512
+kommissionslagenhttps://lagen.nu/2009:865
+köplagenhttps://lagen.nu/1990:931
+konsumentköplagenhttps://lagen.nu/2022:260
+gåvolagenhttps://lagen.nu/1936:83
+konsumenttjänstlagenhttps://lagen.nu/1985:716
+lagen om internationella köphttps://lagen.nu/1987:822
+distans- och hemförsäljningslagenhttps://lagen.nu/2005:59
+skuldebrevslagenhttps://lagen.nu/1936:81
+räntelagenhttps://lagen.nu/1975:635
+preskriptionslagenhttps://lagen.nu/1981:130
+lösöresköpslagenhttps://lagen.nu/1845:50_s.1
+samäganderättslagenhttps://lagen.nu/1904:48_s.1
+förmånsrättslagenhttps://lagen.nu/1970:979
+lagen om godtrosförvärv av lösörehttps://lagen.nu/1986:796
+skadeståndslagenhttps://lagen.nu/1972:207
+trafikskadelagenhttps://lagen.nu/1975:1410
+brottsskadelagenhttps://lagen.nu/2014:322
+produktansvarslagenhttps://lagen.nu/1992:18
+patientskadelagenhttps://lagen.nu/1996:799
+dataskyddslagenhttps://lagen.nu/2018:218
+BBS-lagenhttps://lagen.nu/1998:112
+e-handelslagenhttps://lagen.nu/2002:562
+lagen om elektronisk kommunikationhttps://lagen.nu/2022:482
+lagen om informationssäkerhet för samhällsviktiga och digitala tjänsterhttps://lagen.nu/2018:1174
+varumärkeslagenhttps://lagen.nu/2010:1877
+upphovsrättslagenhttps://lagen.nu/1960:729
+patentlagenhttps://lagen.nu/1967:837
+mönsterskyddslagenhttps://lagen.nu/1970:485
+lagen om företagsnamnhttps://lagen.nu/2018:653
+jordabalkenhttps://lagen.nu/1970:994
+fastighetsbildningslagenhttps://lagen.nu/1970:988
+expropriationslagenhttps://lagen.nu/1972:719
+plan- och bygglagenhttps://lagen.nu/2010:900
+bostadsrättslagenhttps://lagen.nu/1991:614
+miljöbalkenhttps://lagen.nu/1998:808
+lagen om handelsbolag och enkla bolaghttps://lagen.nu/1980:1102
+lagen om ekonomiska föreningarhttps://lagen.nu/2018:672
+stiftelselagenhttps://lagen.nu/1994:1220
+årsredovisningslagenhttps://lagen.nu/1995:1554
+bokföringslagenhttps://lagen.nu/1999:1078
+aktiebolagslagenhttps://lagen.nu/2005:551
+brottsbalkenhttps://lagen.nu/1962:700
+trafikbrottslagenhttps://lagen.nu/1951:649
+narkotikastrafflagenhttps://lagen.nu/1968:64
+skattebrottslagenhttps://lagen.nu/1971:69
+smugglingslagenhttps://lagen.nu/2000:1225
+rättegångsbalkenhttps://lagen.nu/1942:740
+utsökningsbalkenhttps://lagen.nu/1981:774
+konkurslagenhttps://lagen.nu/1987:672
+lagen om domstolsärendenhttps://lagen.nu/1996:242
+lagen om skiljeförfarandehttps://lagen.nu/1999:116
+tryckfrihetsförordningenhttps://lagen.nu/1949:105
+successionsordningenhttps://lagen.nu/1810:0926
+regeringsformenhttps://lagen.nu/1974:152
+riksdagsordningenhttps://lagen.nu/2014:801
+yttrandefrihetsgrundlagenhttps://lagen.nu/1991:1469
+europakonventionenhttps://lagen.nu/1994:1219
+utlänningslagenhttps://lagen.nu/2005:716
+inkomstskattelagenhttps://lagen.nu/1999:1229
+skatteförfarandelagenhttps://lagen.nu/1979:1152
+fastighetstaxeringslagenhttps://lagen.nu/1979:1152
+lagen om särskild inkomstskatt för utomlands bosattahttps://lagen.nu/1991:586
+mervärdesskattelagenhttps://lagen.nu/1994:200
+lagen mot skatteflykthttps://lagen.nu/1995:575
+förvaltningslagenhttps://lagen.nu/2017:900
+offentlighets- och sekretesslagenhttps://lagen.nu/2009:400
+förvaltningsprocesslagenhttps://lagen.nu/1971:291
+avgiftsförordningenhttps://lagen.nu/1992:191
+lagen om offentlig upphandlinghttps://lagen.nu/2016:1145
+socialförsäkringsbalkenhttps://lagen.nu/2010:110
+fängelselagenhttps://lagen.nu/2010:610
+hälso- och sjukvårdslagenhttps://lagen.nu/2017:30
+polislagenhttps://lagen.nu/1984:387
+ordningslagenhttps://lagen.nu/1993:1617
+socialtjänstlagenhttps://lagen.nu/2001:453
+lagen om signalspaning i försvarsunderrättelseverksamhethttps://lagen.nu/2008:717
+kommunallagenhttps://lagen.nu/2017:725
+marknadsföringslagenhttps://lagen.nu/2008:486
+konkurrenslagenhttps://lagen.nu/2008:579
diff --git a/lagar.json b/lagar.json
deleted file mode 100644
index 1ce85cc5d51625ad4daad2597209341185c3bc13..0000000000000000000000000000000000000000
--- a/lagar.json
+++ /dev/null
@@ -1,382 +0,0 @@
-[
-  [
-    "föräldrabalken",
-    "https://lagen.nu/1949:381"
-  ],
-  [
-    "ärvdabalken",
-    "https://lagen.nu/1958:637"
-  ],
-  [
-    "äktenskapsbalken",
-    "https://lagen.nu/1987:230"
-  ],
-  [
-    "lagen om personnamn",
-    "https://lagen.nu/2016:1013"
-  ],
-  [
-    "sambolagen",
-    "https://lagen.nu/2003:376"
-  ],
-  [
-    "medbestämmandelagen",
-    "https://lagen.nu/1976:580"
-  ],
-  [
-    "lagen om anställningsskydd",
-    "https://lagen.nu/1982:80"
-  ],
-  [
-    "lagen om rättegången i arbetstvister",
-    "https://lagen.nu/1974:371"
-  ],
-  [
-    "semesterlagen",
-    "https://lagen.nu/1977:480"
-  ],
-  [
-    "arbetstidslagen",
-    "https://lagen.nu/1982:673"
-  ],
-  [
-    "lagen om offentlig anställning",
-    "https://lagen.nu/1994:260"
-  ],
-  [
-    "visselblåsarlagen",
-    "https://lagen.nu/2021:890"
-  ],
-  [
-    "avtalslagen",
-    "https://lagen.nu/1915:218"
-  ],
-  [
-    "prokuralagen",
-    "https://lagen.nu/1974:158"
-  ],
-  [
-    "lagen om avtalsvillkor mellan näringsidkare",
-    "https://lagen.nu/1984:292"
-  ],
-  [
-    "lagen om avtalsvillkor i konsumentförhållanden",
-    "https://lagen.nu/1994:1512"
-  ],
-  [
-    "kommissionslagen",
-    "https://lagen.nu/2009:865"
-  ],
-  [
-    "köplagen",
-    "https://lagen.nu/1990:931"
-  ],
-  [
-    "konsumentköplagen",
-    "https://lagen.nu/2022:260"
-  ],
-  [
-    "gåvolagen",
-    "https://lagen.nu/1936:83"
-  ],
-  [
-    "konsumenttjänstlagen",
-    "https://lagen.nu/1985:716"
-  ],
-  [
-    "lagen om internationella köp",
-    "https://lagen.nu/1987:822"
-  ],
-  [
-    "distans- och hemförsäljningslagen",
-    "https://lagen.nu/2005:59"
-  ],
-  [
-    "skuldebrevslagen",
-    "https://lagen.nu/1936:81"
-  ],
-  [
-    "räntelagen",
-    "https://lagen.nu/1975:635"
-  ],
-  [
-    "preskriptionslagen",
-    "https://lagen.nu/1981:130"
-  ],
-  [
-    "lösöresköpslagen",
-    "https://lagen.nu/1845:50_s.1"
-  ],
-  [
-    "samäganderättslagen",
-    "https://lagen.nu/1904:48_s.1"
-  ],
-  [
-    "förmånsrättslagen",
-    "https://lagen.nu/1970:979"
-  ],
-  [
-    "lagen om godtrosförvärv av lösöre",
-    "https://lagen.nu/1986:796"
-  ],
-  [
-    "skadeståndslagen",
-    "https://lagen.nu/1972:207"
-  ],
-  [
-    "trafikskadelagen",
-    "https://lagen.nu/1975:1410"
-  ],
-  [
-    "brottsskadelagen",
-    "https://lagen.nu/2014:322"
-  ],
-  [
-    "produktansvarslagen",
-    "https://lagen.nu/1992:18"
-  ],
-  [
-    "patientskadelagen",
-    "https://lagen.nu/1996:799"
-  ],
-  [
-    "dataskyddslagen",
-    "https://lagen.nu/2018:218"
-  ],
-  [
-    "BBS-lagen",
-    "https://lagen.nu/1998:112"
-  ],
-  [
-    "e-handelslagen",
-    "https://lagen.nu/2002:562"
-  ],
-  [
-    "lagen om elektronisk kommunikation",
-    "https://lagen.nu/2022:482"
-  ],
-  [
-    "lagen om informationssäkerhet för samhällsviktiga och digitala tjänster",
-    "https://lagen.nu/2018:1174"
-  ],
-  [
-    "varumärkeslagen",
-    "https://lagen.nu/2010:1877"
-  ],
-  [
-    "upphovsrättslagen",
-    "https://lagen.nu/1960:729"
-  ],
-  [
-    "patentlagen",
-    "https://lagen.nu/1967:837"
-  ],
-  [
-    "mönsterskyddslagen",
-    "https://lagen.nu/1970:485"
-  ],
-  [
-    "lagen om företagsnamn",
-    "https://lagen.nu/2018:653"
-  ],
-  [
-    "jordabalken",
-    "https://lagen.nu/1970:994"
-  ],
-  [
-    "fastighetsbildningslagen",
-    "https://lagen.nu/1970:988"
-  ],
-  [
-    "expropriationslagen",
-    "https://lagen.nu/1972:719"
-  ],
-  [
-    "plan- och bygglagen",
-    "https://lagen.nu/2010:900"
-  ],
-  [
-    "bostadsrättslagen",
-    "https://lagen.nu/1991:614"
-  ],
-  [
-    "miljöbalken",
-    "https://lagen.nu/1998:808"
-  ],
-  [
-    "lagen om handelsbolag och enkla bolag",
-    "https://lagen.nu/1980:1102"
-  ],
-  [
-    "lagen om ekonomiska föreningar",
-    "https://lagen.nu/2018:672"
-  ],
-  [
-    "stiftelselagen",
-    "https://lagen.nu/1994:1220"
-  ],
-  [
-    "årsredovisningslagen",
-    "https://lagen.nu/1995:1554"
-  ],
-  [
-    "bokföringslagen",
-    "https://lagen.nu/1999:1078"
-  ],
-  [
-    "aktiebolagslagen",
-    "https://lagen.nu/2005:551"
-  ],
-  [
-    "brottsbalken",
-    "https://lagen.nu/1962:700"
-  ],
-  [
-    "trafikbrottslagen",
-    "https://lagen.nu/1951:649"
-  ],
-  [
-    "narkotikastrafflagen",
-    "https://lagen.nu/1968:64"
-  ],
-  [
-    "skattebrottslagen",
-    "https://lagen.nu/1971:69"
-  ],
-  [
-    "smugglingslagen",
-    "https://lagen.nu/2000:1225"
-  ],
-  [
-    "rättegångsbalken",
-    "https://lagen.nu/1942:740"
-  ],
-  [
-    "utsökningsbalken",
-    "https://lagen.nu/1981:774"
-  ],
-  [
-    "konkurslagen",
-    "https://lagen.nu/1987:672"
-  ],
-  [
-    "lagen om domstolsärenden",
-    "https://lagen.nu/1996:242"
-  ],
-  [
-    "lagen om skiljeförfarande",
-    "https://lagen.nu/1999:116"
-  ],
-  [
-    "tryckfrihetsförordningen",
-    "https://lagen.nu/1949:105"
-  ],
-  [
-    "successionsordningen",
-    "https://lagen.nu/1810:0926"
-  ],
-  [
-    "regeringsformen",
-    "https://lagen.nu/1974:152"
-  ],
-  [
-    "riksdagsordningen",
-    "https://lagen.nu/2014:801"
-  ],
-  [
-    "yttrandefrihetsgrundlagen",
-    "https://lagen.nu/1991:1469"
-  ],
-  [
-    "europakonventionen",
-    "https://lagen.nu/1994:1219"
-  ],
-  [
-    "utlänningslagen",
-    "https://lagen.nu/2005:716"
-  ],
-  [
-    "inkomstskattelagen",
-    "https://lagen.nu/1999:1229"
-  ],
-  [
-    "skatteförfarandelagen",
-    "https://lagen.nu/1979:1152"
-  ],
-  [
-    "fastighetstaxeringslagen",
-    "https://lagen.nu/1979:1152"
-  ],
-  [
-    "lagen om särskild inkomstskatt för utomlands bosatta",
-    "https://lagen.nu/1991:586"
-  ],
-  [
-    "mervärdesskattelagen",
-    "https://lagen.nu/1994:200"
-  ],
-  [
-    "lagen mot skatteflykt",
-    "https://lagen.nu/1995:575"
-  ],
-  [
-    "förvaltningslagen",
-    "https://lagen.nu/2017:900"
-  ],
-  [
-    "offentlighets- och sekretesslagen",
-    "https://lagen.nu/2009:400"
-  ],
-  [
-    "förvaltningsprocesslagen",
-    "https://lagen.nu/1971:291"
-  ],
-  [
-    "avgiftsförordningen",
-    "https://lagen.nu/1992:191"
-  ],
-  [
-    "lagen om offentlig upphandling",
-    "https://lagen.nu/2016:1145"
-  ],
-  [
-    "socialförsäkringsbalken",
-    "https://lagen.nu/2010:110"
-  ],
-  [
-    "fängelselagen",
-    "https://lagen.nu/2010:610"
-  ],
-  [
-    "hälso- och sjukvårdslagen",
-    "https://lagen.nu/2017:30"
-  ],
-  [
-    "polislagen",
-    "https://lagen.nu/1984:387"
-  ],
-  [
-    "ordningslagen",
-    "https://lagen.nu/1993:1617"
-  ],
-  [
-    "socialtjänstlagen",
-    "https://lagen.nu/2001:453"
-  ],
-  [
-    "lagen om signalspaning i försvarsunderrättelseverksamhet",
-    "https://lagen.nu/2008:717"
-  ],
-  [
-    "kommunallagen",
-    "https://lagen.nu/2017:725"
-  ],
-  [
-    "marknadsföringslagen",
-    "https://lagen.nu/2008:486"
-  ],
-  [
-    "konkurrenslagen",
-    "https://lagen.nu/2008:579"
-  ]
-]
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c4d6c1bd2a74b83b8f6c07f9ff78195e2ca8c619
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,118 @@
+#include <iostream>
+#include <string>
+
+#include <boost/program_options.hpp>
+
+#include <pwd.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <clocale>
+#include <basedir.h>
+
+#include "laga-signatur.h"
+#include "translations.h"
+
+using namespace boost::program_options;
+
+int main(int argc, const char *argv[]) {
+	std::setlocale (LC_ALL, "");
+	setup_translations();
+
+	try {
+		options_description desc{"Available (legal) options"};
+		desc.add_options()
+			("help,h", _("Display this help"))
+			("version", _("Display program version"))
+			("name,n", value<std::string>(), 
+			 _("Set name for signature, defaults to the comment field"
+				 " of the currently logged in user."))
+			("title,t", value<std::string>()->default_value(""), 
+			 _("Sets the position line of the signature, such as"
+				 " \"Chairman of the Board\". If unset, the position line"
+				 " will be omitted"))
+			("association,a", value<std::string>()->default_value("Lysator"), 
+			 _("Name of the association which follows laws."))
+			("file,f", value<std::string>(), 
+			 _("File to read laws from."));
+
+		variables_map vm;
+		store(parse_command_line(argc, argv, desc), vm);
+		notify(vm);
+
+		std::string title, username, association, filename;
+		std::ifstream law_file;
+
+		if (vm.count("help")) {
+			std::cout << desc << '\n';
+			return 0;
+		}
+
+		if (vm.count("version")) {
+			std::cout << PROGRAM_VERSION << '\n';
+			return 0;
+		}
+
+		if (vm.count("title")) {
+			title = vm["title"].as<std::string>();
+		}
+
+		if (vm.count("name")) {
+			username = vm["name"].as<std::string>();
+		} else {
+			username = getpwuid(geteuid())->pw_gecos;
+		}
+
+		if (vm.count("association")) {
+			association = vm["association"].as<std::string>();
+		}
+
+		if (vm.count("file")) {
+			filename = vm["file"].as<std::string>();
+
+			law_file.open(filename, std::ios::binary);
+			if (! law_file.is_open()) {
+				throw std::runtime_error(_("Failed to open file: ") + filename);
+			}
+
+		} else {
+			xdgHandle handle;
+			xdgInitHandle(&handle);
+			for (
+					const char *const *data_dirs = xdgSearchableDataDirectories(&handle); 
+					*data_dirs != NULL; 
+					data_dirs++
+				) 
+			{
+				filename = std::string(*data_dirs) + "/laga-signatur/lagar.data";
+				law_file.open(filename, std::ios::binary);
+				if (law_file.is_open()) {
+					break;
+				}
+			}
+			if (! law_file.is_open()) {
+				throw std::runtime_error(_("Failed to find any data file."));
+			}
+			xdgWipeHandle(&handle);
+		}
+
+		auto entries = load_lagar(law_file, filename);
+		auto law = random_law(entries);
+
+		signature_message msg {
+			.username = username,
+			.association = association,
+			.title = title,
+			.law = law,
+		};
+
+		std::cout << msg << "\n";
+
+	} catch (const std::ios_base::failure &fail) {
+		std::cerr << fail.what() << "\n";
+	} catch (const std::runtime_error &err) {
+		std::cerr << err.what() << "\n";
+	} catch (const error &ex) {
+		std::cerr << ex.what() << "\n";
+	}
+}
+
diff --git a/man/laga-signatur.1 b/man/laga-signatur.1
new file mode 100644
index 0000000000000000000000000000000000000000..cec8f6554d048b5261949a46d8ca167f8a480f95
--- /dev/null
+++ b/man/laga-signatur.1
@@ -0,0 +1,61 @@
+.TH LAGA-SIGNATUR 1 "2023-10-07" "1.0" "Laga Signaturer"
+.SH NAME
+laga-signatur \- Generate an email signature specifying which laws you follow
+
+.SH SYNOPSIS
+.B laga-signatur
+.RI [\| "options" \|]
+
+.SH OPTIONS
+.BI \-\-help\fR,\ \fB\-h
+Print basic usage information.
+.TP
+.BI \fB\-\-file\fI\ file\fR,\ \fB\-f\fI\ file 
+Specify file to read laws from.
+.TP
+.BI \fB\-\-title\fI\ title\fR,\ \fB\-t\fI\ title 
+An optional title for the position to indicate in the signature.
+For example, Chairman of the Board.
+.TP
+.BI \fB\-\-name\fI\ name\fR,\ \fB\-n\fI\ name 
+Name to start the signature with. Defaults to the comment field of the
+currently logged in user if not given.
+.TP
+.BI \fB\-\-association\fI\ association\fR,\ \fB\-a\fI\ association 
+Association which should be indicated to follow local laws.
+
+.SH OUTPUT FORMAT
+All output follows the following basic format. Note that the title line will be omitted if unset.
+
+.EX
+{name}
+{title}
+
+{association} följer {lawinfo}
+.EE
+
+Which renders as
+
+.EX
+Hugo Hörnquist
+Treasurer Lysator
+
+Lysator följer yttrandefrihetsgrundlagen <https://lagen.nu/1991:1469>
+.EE
+
+.SH DATAFILE FORMAT
+The data files containing laws are all on the format \fI Name of the
+law, as written locally\fR, followed by an ASCII Unit Separator \fT
+0x1F\fR\ followed by \fI an URL containing details.
+
+.SH FILES
+.TP
+.I /usr/share/laga-signatur/lagar.data
+
+Contains laws to choose from, as detailed above in Datafile Format.
+
+.SH SEE ALSO
+
+https://git.lysator.liu.se/hugo/laga-signatur
+
+For source code.
diff --git a/man/sv/laga-signatur.1 b/man/sv/laga-signatur.1
new file mode 100644
index 0000000000000000000000000000000000000000..508a181a1628d1f75669320031c7702da6408688
--- /dev/null
+++ b/man/sv/laga-signatur.1
@@ -0,0 +1,62 @@
+.TH LAGA-SIGNATUR 1 "2023-10-07" "1.0" "Laga Signaturer"
+.SH NAMN
+laga-signatur \- Genererar epostsignatur specificerande lagar som följs.
+
+.SH SYNOPSIS
+.B laga-signatur
+.RI [\| "alternativ" \|]
+
+.SH FLAGGOR
+.BI \-\-help\fR,\ \fB\-h
+Skriv ut grundläggande användarinstruktioner.
+.TP
+.BI \fB\-\-file\fI\ fil\fR,\ \fB\-f\fI\ fil
+Specificera fil att läsa lagtexter från.
+.TP
+.BI \fB\-\-title\fI\ titel\fR,\ \fB\-t\fI\ titel
+En frivilig beskrivning av ens befattning till signaturen, så som
+"Stolman av bordet".
+.TP
+.BI \fB\-\-name\fI\ namn\fR,\ \fB\-n\fI\ namn
+Namn att inleda signaturen med. Blir kommentarsfältet för nuvarande
+inloggade användare om inget anges.
+.TP
+.BI \fB\-\-association\fI\ förening\fR,\ \fB\-a\fI\ förening
+Förining vilken indikeras följa lokala lagar.
+
+.SH UTSKRIFTSFORMAT
+All utskrift följer följande format.
+Notea att titel-linjjen kommer utelämnas om osatt.
+
+.EX
+{namn}
+{titel}
+
+{förening} följer {laginfo}
+.EE
+
+Vilket renderas likt
+
+.EX
+Hugo Hörnquist
+Kassör Lysator
+
+Lysator följer yttrandefrihetsgrundlagen <https://lagen.nu/1991:1469>
+.EE
+
+.SH DATAFILSFORMAT
+Datafilerna vilka innehåller lagar är alla på formatet
+\fI Namn på lagen i fråga, som skrivet lokalt\fR, följt av ASCII-koden
+enhetssepparator \fT 0x1F\fR\ följt av \fi en URL förklarande detaljerna.
+
+.SH FILER
+.TP
+.I /usr/share/laga-signatur/lagar.data
+
+Inehåller lagar att välja från, i enhlighet med Datafilsformatrubriken ovan.
+
+.SH SE OCKSÅ
+
+https://git.lysator.liu.se/hugo/laga-signatur
+
+För källkod.
diff --git a/po/.gitignore b/po/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e3a8c5db201cf5e125c2f28effd93a079200d8d0
--- /dev/null
+++ b/po/.gitignore
@@ -0,0 +1 @@
+*.pot
diff --git a/po/sv/laga-signatur.po b/po/sv/laga-signatur.po
new file mode 100644
index 0000000000000000000000000000000000000000..1ad7c2d7d6c70b4276698a408df10df917fd37d2
--- /dev/null
+++ b/po/sv/laga-signatur.po
@@ -0,0 +1,53 @@
+# Language po/sv/ translations for PACKAGE package.
+# Copyright (C) 2023 THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# Hugo Hörnquist <hugo@lysator.liu.se>, 2023.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-07 04:48+0200\n"
+"PO-Revision-Date: 2023-10-07 04:49+0200\n"
+"Last-Translator: Hugo Hörnquist <hugo@lysator.liu.se>\n"
+"Language-Team: Language po/sv/\n"
+"Language: po/sv/\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: laga-signatur.cpp:33
+msgid "Failed to open file: "
+msgstr "Misslyckades att öppna filen: "
+
+#: laga-signatur.cpp:40
+msgid "Failed reading line from file: "
+msgstr "Misslyckades att läsa rad från filen: "
+
+#: main.cpp:33
+msgid "Display this help"
+msgstr "Visa den här hjälper"
+
+#: main.cpp:35
+msgid ""
+"Set name for signature, defaults to the comment field of the currently "
+"logged in user."
+msgstr ""
+"Set namn för signaturen, blir kommentarsfältet för nuvarande "
+"inloggad användar om utelämnat."
+
+#: main.cpp:38
+msgid ""
+"Sets the position line of the signature, such as \"Chairman of the Board\". "
+"If unset, the position line will be omitted"
+msgstr ""
+"Sätter befattning till signaturen, så som \"Stolman av bordet\". "
+"Om utelämnad kommer även resultatraden utelämnas"
+
+#: main.cpp:42
+msgid "Name of the association which follows laws."
+msgstr "Namn på föreningen vilken följer lagar."
+
+#: main.cpp:44
+msgid "File to read laws from."
+msgstr "Fil att läsa lagar från."
diff --git a/signatur.py b/signatur.py
deleted file mode 100755
index 7e5892a7f88da4ccbc3be3dd8a5cad875a2de54d..0000000000000000000000000000000000000000
--- a/signatur.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env python3
-
-
-"""
-Generate email signatures specifying which laws are followed.
-
-
-.. code-block:: muttrc
-
-    set signature = "/home/hugo/code/lagar/signatur.py|"
-"""
-
-
-import json
-import random
-import os.path
-import sys
-import pwd
-
-source_file = os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])),
-                           'lagar.json')
-
-with open(source_file, 'rb') as f:
-    lagar = json.load(f)
-
-lagnamn, url = random.choice(lagar)
-
-# namn = "Hugo Hörnquist"  # --namn, -n
-name = pwd.getpwuid(os.geteuid()).pw_gecos
-title = "Kassör Lysator"  # --title, -t
-association = "Lysator" # --association, -a
-
-print(f"""
-{name}
-{title}
-
-{association} följer {lagnamn} <{url}>
-""".strip())
diff --git a/translations.cpp b/translations.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..58bb70154c36d7bc1f44b21d0b0f27c522f4e847
--- /dev/null
+++ b/translations.cpp
@@ -0,0 +1,11 @@
+#include "translations.h"
+
+#ifndef TRANSLATIONS_DIR
+#define TRANSLATIONS_DIR "/usr/share"
+#endif
+
+void setup_translations() {
+	bindtextdomain ("laga-signatur", TRANSLATIONS_DIR);
+
+	textdomain ("laga-signatur");
+}
diff --git a/translations.h b/translations.h
new file mode 100644
index 0000000000000000000000000000000000000000..bfcb95ebe273ace37405fdf1780a7ce92128880f
--- /dev/null
+++ b/translations.h
@@ -0,0 +1,10 @@
+#ifndef TRANSLATIONS_H
+#define TRANSLATIONS_H
+
+#include <libintl.h>
+
+#define _(s) gettext(s)
+
+void setup_translations();
+
+#endif /* TRANSLATIONS_H */