diff options
| -rw-r--r-- | .nojekyll | 0 | ||||
| -rw-r--r-- | Makefile | 14 | ||||
| -rw-r--r-- | assets/dna-sequence/benchmarks.ods (renamed from src/files/dna-sequence/benchmarks.ods) | bin | 21911 -> 21911 bytes | |||
| -rw-r--r-- | assets/dna-sequence/chart-encoding-speed.png (renamed from src/files/dna-sequence/chart-encoding-speed.png) | bin | 14201 -> 14201 bytes | |||
| -rw-r--r-- | assets/dna-sequence/chart-file-sizes.png (renamed from src/files/dna-sequence/chart-file-sizes.png) | bin | 12391 -> 12391 bytes | |||
| -rw-r--r-- | assets/dna-sequence/dna-basics.jpg (renamed from src/files/dna-sequence/dna-basics.jpg) | bin | 165883 -> 165883 bytes | |||
| -rw-r--r-- | assets/dna-sequence/quote.png (renamed from src/files/dna-sequence/quote.png) | bin | 1068 -> 1068 bytes | |||
| -rw-r--r-- | assets/dna-sequence/sample-binary-file.png (renamed from src/files/dna-sequence/sample-binary-file.png) | bin | 66417 -> 66417 bytes | |||
| -rw-r--r-- | assets/dna-sequence/sample.png (renamed from src/files/dna-sequence/sample.png) | bin | 65930 -> 65930 bytes | |||
| -rw-r--r-- | assets/do-fuse/copy-benchmarks.tsv (renamed from src/files/do-fuse/copy-benchmarks.tsv) | 0 | ||||
| -rw-r--r-- | assets/do-fuse/fuse-droplets.png (renamed from src/files/do-fuse/fuse-droplets.png) | bin | 42891 -> 42891 bytes | |||
| -rw-r--r-- | assets/do-fuse/fuse-spaces.png (renamed from src/files/do-fuse/fuse-spaces.png) | bin | 32450 -> 32450 bytes | |||
| -rw-r--r-- | assets/do-fuse/sqlite-benchmarks.tsv (renamed from src/files/do-fuse/sqlite-benchmarks.tsv) | 0 | ||||
| -rw-r--r-- | assets/go-profiling/golang-profiling-cpu.pdf (renamed from src/files/go-profiling/golang-profiling-cpu.pdf) | bin | 16518 -> 16518 bytes | |||
| -rw-r--r-- | assets/go-profiling/golang-profiling-mem.pdf (renamed from src/files/go-profiling/golang-profiling-mem.pdf) | bin | 19221 -> 19221 bytes | |||
| -rw-r--r-- | assets/iot-application/iot-app-output.png (renamed from src/files/iot-application/iot-app-output.png) | bin | 23767 -> 23767 bytes | |||
| -rw-r--r-- | assets/iot-application/iot-rest-example.png (renamed from src/files/iot-application/iot-rest-example.png) | bin | 33912 -> 33912 bytes | |||
| -rw-r--r-- | assets/iot-application/iot-sqlite-db.png (renamed from src/files/iot-application/iot-sqlite-db.png) | bin | 199821 -> 199821 bytes | |||
| -rw-r--r-- | assets/iot-application/kcachegrind.png (renamed from src/files/iot-application/kcachegrind.png) | bin | 88486 -> 88486 bytes | |||
| -rw-r--r-- | assets/iot-application/profiling-viewer.png (renamed from src/files/iot-application/profiling-viewer.png) | bin | 173672 -> 173672 bytes | |||
| -rw-r--r-- | assets/iot-application/simple-iot-application-overview.svg (renamed from src/files/iot-application/simple-iot-application-overview.svg) | 0 | ||||
| -rw-r--r-- | assets/iot-application/simple-iot-application.zip (renamed from src/files/iot-application/simple-iot-application.zip) | bin | 6406 -> 6406 bytes | |||
| -rw-r--r-- | assets/iot-application/snakeviz.png (renamed from src/files/iot-application/snakeviz.png) | bin | 59601 -> 59601 bytes | |||
| -rw-r--r-- | assets/python-profiling/kcachegrind.png (renamed from src/files/python-profiling/kcachegrind.png) | bin | 88486 -> 88486 bytes | |||
| -rw-r--r-- | assets/python-profiling/profiling-viewer.png (renamed from src/files/python-profiling/profiling-viewer.png) | bin | 173672 -> 173672 bytes | |||
| -rw-r--r-- | assets/python-profiling/snakeviz.png (renamed from src/files/python-profiling/snakeviz.png) | bin | 59601 -> 59601 bytes | |||
| -rw-r--r-- | assets/sentiment-analysis/.ipynb_checkpoints/TF Test-checkpoint.ipynb (renamed from src/files/sentiment-analysis/.ipynb_checkpoints/TF Test-checkpoint.ipynb) | 0 | ||||
| -rw-r--r-- | assets/sentiment-analysis/.ipynb_checkpoints/sentiment-analysis-checkpoint.ipynb (renamed from src/files/sentiment-analysis/.ipynb_checkpoints/sentiment-analysis-checkpoint.ipynb) | 0 | ||||
| -rw-r--r-- | assets/sentiment-analysis/guardian-sa-title-desc-relationship.png (renamed from src/files/sentiment-analysis/guardian-sa-title-desc-relationship.png) | bin | 15404 -> 15404 bytes | |||
| -rw-r--r-- | assets/sentiment-analysis/sentiment-analysis.ipynb (renamed from src/files/sentiment-analysis/sentiment-analysis.ipynb) | 0 | ||||
| -rw-r--r-- | config | 40 | ||||
| -rw-r--r-- | content/curriculum-vitae.md (renamed from src/curriculum-vitae.md) | 10 | ||||
| -rw-r--r-- | content/encoding-binary-data-into-dna-sequence.md (renamed from src/experiments/encoding-binary-data-into-dna-sequence.md) | 26 | ||||
| -rw-r--r-- | content/golang-profiling-simplified.md (renamed from src/notes/golang-profiling-simplified.md) | 16 | ||||
| -rw-r--r-- | content/profiling-python-web-applications-with-visual-tools.md (renamed from src/experiments/profiling-python-web-applications-with-visual-tools.md) | 18 | ||||
| -rw-r--r-- | content/simple-iot-application.md (renamed from src/experiments/simple-iot-application.md) | 22 | ||||
| -rw-r--r-- | content/simplifying-and-reducing-clutter.md (renamed from src/notes/simplifying-and-reducing-clutter.md) | 12 | ||||
| -rw-r--r-- | content/using-digitalocean-spaces-object-storage-with-fuse.md (renamed from src/experiments/using-digitalocean-spaces-object-storage-with-fuse.md) | 24 | ||||
| -rw-r--r-- | content/using-sentiment-analysis-for-click-bait-detection-in-rss-feeds.md (renamed from src/experiments/using-sentiment-analysis-for-click-bait-detection-in-rss-feeds.md) | 16 | ||||
| -rw-r--r-- | content/what-i-ve-learned-developing-ad-server.md (renamed from src/notes/what-i-ve-learned-developing-ad-server.md) | 12 | ||||
| -rw-r--r-- | site.tmpl | 140 | ||||
| -rw-r--r-- | src/404.html | 3 | ||||
| -rw-r--r-- | src/comments.html | 100 | ||||
| -rw-r--r-- | src/feed.atom | 55 | ||||
| -rw-r--r-- | src/index.html | 21 | ||||
| -rw-r--r-- | src/static/comments.js | 65 | ||||
| -rw-r--r-- | src/static/style.css | 319 | ||||
| -rw-r--r-- | static/avatar-512x512.png (renamed from src/static/avatar-512x512.png) | bin | 244569 -> 244569 bytes | |||
| -rw-r--r-- | static/avatar-64x64.png (renamed from src/static/avatar-64x64.png) | bin | 16769 -> 16769 bytes | |||
| -rw-r--r-- | static/style.css | 172 | ||||
| -rw-r--r-- | staticgen.yml | 21 | ||||
| -rw-r--r-- | templates/index.twig | 56 | ||||
| -rw-r--r-- | templates/page.twig | 52 | ||||
| -rw-r--r-- | templates/partials/navigation.twig | 6 | ||||
| -rw-r--r-- | templates/post.twig | 59 |
55 files changed, 450 insertions, 829 deletions
diff --git a/.nojekyll b/.nojekyll deleted file mode 100644 index e69de29..0000000 --- a/.nojekyll +++ /dev/null | |||
| @@ -1,13 +1,11 @@ | |||
| 1 | GS ?= gostatic | 1 | dev: |
| 2 | 2 | browser-sync ./public/ -w --no-notify --no-open | |
| 3 | compile: clean | ||
| 4 | $(GS) config | ||
| 5 | 3 | ||
| 6 | clean: | 4 | clean: |
| 7 | -rm public -rf | 5 | rm -rf public/* |
| 8 | 6 | ||
| 9 | dev: clean | 7 | generate: |
| 10 | $(GS) -w config | 8 | staticgen --generate |
| 11 | 9 | ||
| 12 | deploy: clean compile | 10 | deploy: clean generate |
| 13 | firebase deploy | 11 | firebase deploy |
diff --git a/src/files/dna-sequence/benchmarks.ods b/assets/dna-sequence/benchmarks.ods index 62a8e30..62a8e30 100644 --- a/src/files/dna-sequence/benchmarks.ods +++ b/assets/dna-sequence/benchmarks.ods | |||
| Binary files differ | |||
diff --git a/src/files/dna-sequence/chart-encoding-speed.png b/assets/dna-sequence/chart-encoding-speed.png index 7fb106d..7fb106d 100644 --- a/src/files/dna-sequence/chart-encoding-speed.png +++ b/assets/dna-sequence/chart-encoding-speed.png | |||
| Binary files differ | |||
diff --git a/src/files/dna-sequence/chart-file-sizes.png b/assets/dna-sequence/chart-file-sizes.png index 31bfa66..31bfa66 100644 --- a/src/files/dna-sequence/chart-file-sizes.png +++ b/assets/dna-sequence/chart-file-sizes.png | |||
| Binary files differ | |||
diff --git a/src/files/dna-sequence/dna-basics.jpg b/assets/dna-sequence/dna-basics.jpg index c2e7f52..c2e7f52 100644 --- a/src/files/dna-sequence/dna-basics.jpg +++ b/assets/dna-sequence/dna-basics.jpg | |||
| Binary files differ | |||
diff --git a/src/files/dna-sequence/quote.png b/assets/dna-sequence/quote.png index 09fb01c..09fb01c 100644 --- a/src/files/dna-sequence/quote.png +++ b/assets/dna-sequence/quote.png | |||
| Binary files differ | |||
diff --git a/src/files/dna-sequence/sample-binary-file.png b/assets/dna-sequence/sample-binary-file.png index 1e4622a..1e4622a 100644 --- a/src/files/dna-sequence/sample-binary-file.png +++ b/assets/dna-sequence/sample-binary-file.png | |||
| Binary files differ | |||
diff --git a/src/files/dna-sequence/sample.png b/assets/dna-sequence/sample.png index 30f12da..30f12da 100644 --- a/src/files/dna-sequence/sample.png +++ b/assets/dna-sequence/sample.png | |||
| Binary files differ | |||
diff --git a/src/files/do-fuse/copy-benchmarks.tsv b/assets/do-fuse/copy-benchmarks.tsv index c7a7af4..c7a7af4 100644 --- a/src/files/do-fuse/copy-benchmarks.tsv +++ b/assets/do-fuse/copy-benchmarks.tsv | |||
diff --git a/src/files/do-fuse/fuse-droplets.png b/assets/do-fuse/fuse-droplets.png index d7ce243..d7ce243 100644 --- a/src/files/do-fuse/fuse-droplets.png +++ b/assets/do-fuse/fuse-droplets.png | |||
| Binary files differ | |||
diff --git a/src/files/do-fuse/fuse-spaces.png b/assets/do-fuse/fuse-spaces.png index 4dcc1c5..4dcc1c5 100644 --- a/src/files/do-fuse/fuse-spaces.png +++ b/assets/do-fuse/fuse-spaces.png | |||
| Binary files differ | |||
diff --git a/src/files/do-fuse/sqlite-benchmarks.tsv b/assets/do-fuse/sqlite-benchmarks.tsv index daa2c21..daa2c21 100644 --- a/src/files/do-fuse/sqlite-benchmarks.tsv +++ b/assets/do-fuse/sqlite-benchmarks.tsv | |||
diff --git a/src/files/go-profiling/golang-profiling-cpu.pdf b/assets/go-profiling/golang-profiling-cpu.pdf index 15241cb..15241cb 100644 --- a/src/files/go-profiling/golang-profiling-cpu.pdf +++ b/assets/go-profiling/golang-profiling-cpu.pdf | |||
| Binary files differ | |||
diff --git a/src/files/go-profiling/golang-profiling-mem.pdf b/assets/go-profiling/golang-profiling-mem.pdf index 822e445..822e445 100644 --- a/src/files/go-profiling/golang-profiling-mem.pdf +++ b/assets/go-profiling/golang-profiling-mem.pdf | |||
| Binary files differ | |||
diff --git a/src/files/iot-application/iot-app-output.png b/assets/iot-application/iot-app-output.png index 1c80589..1c80589 100644 --- a/src/files/iot-application/iot-app-output.png +++ b/assets/iot-application/iot-app-output.png | |||
| Binary files differ | |||
diff --git a/src/files/iot-application/iot-rest-example.png b/assets/iot-application/iot-rest-example.png index 3ed86aa..3ed86aa 100644 --- a/src/files/iot-application/iot-rest-example.png +++ b/assets/iot-application/iot-rest-example.png | |||
| Binary files differ | |||
diff --git a/src/files/iot-application/iot-sqlite-db.png b/assets/iot-application/iot-sqlite-db.png index 82e1e29..82e1e29 100644 --- a/src/files/iot-application/iot-sqlite-db.png +++ b/assets/iot-application/iot-sqlite-db.png | |||
| Binary files differ | |||
diff --git a/src/files/iot-application/kcachegrind.png b/assets/iot-application/kcachegrind.png index 0dc48ab..0dc48ab 100644 --- a/src/files/iot-application/kcachegrind.png +++ b/assets/iot-application/kcachegrind.png | |||
| Binary files differ | |||
diff --git a/src/files/iot-application/profiling-viewer.png b/assets/iot-application/profiling-viewer.png index a450513..a450513 100644 --- a/src/files/iot-application/profiling-viewer.png +++ b/assets/iot-application/profiling-viewer.png | |||
| Binary files differ | |||
diff --git a/src/files/iot-application/simple-iot-application-overview.svg b/assets/iot-application/simple-iot-application-overview.svg index 817666d..817666d 100644 --- a/src/files/iot-application/simple-iot-application-overview.svg +++ b/assets/iot-application/simple-iot-application-overview.svg | |||
diff --git a/src/files/iot-application/simple-iot-application.zip b/assets/iot-application/simple-iot-application.zip index 46d3205..46d3205 100644 --- a/src/files/iot-application/simple-iot-application.zip +++ b/assets/iot-application/simple-iot-application.zip | |||
| Binary files differ | |||
diff --git a/src/files/iot-application/snakeviz.png b/assets/iot-application/snakeviz.png index 5bab395..5bab395 100644 --- a/src/files/iot-application/snakeviz.png +++ b/assets/iot-application/snakeviz.png | |||
| Binary files differ | |||
diff --git a/src/files/python-profiling/kcachegrind.png b/assets/python-profiling/kcachegrind.png index 0dc48ab..0dc48ab 100644 --- a/src/files/python-profiling/kcachegrind.png +++ b/assets/python-profiling/kcachegrind.png | |||
| Binary files differ | |||
diff --git a/src/files/python-profiling/profiling-viewer.png b/assets/python-profiling/profiling-viewer.png index a450513..a450513 100644 --- a/src/files/python-profiling/profiling-viewer.png +++ b/assets/python-profiling/profiling-viewer.png | |||
| Binary files differ | |||
diff --git a/src/files/python-profiling/snakeviz.png b/assets/python-profiling/snakeviz.png index 5bab395..5bab395 100644 --- a/src/files/python-profiling/snakeviz.png +++ b/assets/python-profiling/snakeviz.png | |||
| Binary files differ | |||
diff --git a/src/files/sentiment-analysis/.ipynb_checkpoints/TF Test-checkpoint.ipynb b/assets/sentiment-analysis/.ipynb_checkpoints/TF Test-checkpoint.ipynb index e2a85c4..e2a85c4 100644 --- a/src/files/sentiment-analysis/.ipynb_checkpoints/TF Test-checkpoint.ipynb +++ b/assets/sentiment-analysis/.ipynb_checkpoints/TF Test-checkpoint.ipynb | |||
diff --git a/src/files/sentiment-analysis/.ipynb_checkpoints/sentiment-analysis-checkpoint.ipynb b/assets/sentiment-analysis/.ipynb_checkpoints/sentiment-analysis-checkpoint.ipynb index 2c0934c..2c0934c 100644 --- a/src/files/sentiment-analysis/.ipynb_checkpoints/sentiment-analysis-checkpoint.ipynb +++ b/assets/sentiment-analysis/.ipynb_checkpoints/sentiment-analysis-checkpoint.ipynb | |||
diff --git a/src/files/sentiment-analysis/guardian-sa-title-desc-relationship.png b/assets/sentiment-analysis/guardian-sa-title-desc-relationship.png index 7195bbf..7195bbf 100644 --- a/src/files/sentiment-analysis/guardian-sa-title-desc-relationship.png +++ b/assets/sentiment-analysis/guardian-sa-title-desc-relationship.png | |||
| Binary files differ | |||
diff --git a/src/files/sentiment-analysis/sentiment-analysis.ipynb b/assets/sentiment-analysis/sentiment-analysis.ipynb index 2c0934c..2c0934c 100644 --- a/src/files/sentiment-analysis/sentiment-analysis.ipynb +++ b/assets/sentiment-analysis/sentiment-analysis.ipynb | |||
| @@ -1,40 +0,0 @@ | |||
| 1 | TEMPLATES = site.tmpl | ||
| 2 | SOURCE = src | ||
| 3 | OUTPUT = public | ||
| 4 | TITLE = Mitja Felicijan | ||
| 5 | DESCRIPTION = Fan of science fiction and dabbler in code | ||
| 6 | GOOGLE_VERIFICATION = EwUGW1WlCkRIQuyQ9AE1-bLitWthw-eVMZFTAMZVZaA | ||
| 7 | TWITTER_HANDLE = @mitjafelicijan | ||
| 8 | URL = https://mitjafelicijan.com | ||
| 9 | AUTHOR = Mitja Felicijan | ||
| 10 | |||
| 11 | notes/*.md: | ||
| 12 | config | ||
| 13 | ext .html | ||
| 14 | tags tags/*.tag | ||
| 15 | markdown | ||
| 16 | template post | ||
| 17 | template page | ||
| 18 | |||
| 19 | experiments/*.md: | ||
| 20 | config | ||
| 21 | ext .html | ||
| 22 | tags tags/*.tag | ||
| 23 | markdown | ||
| 24 | template post | ||
| 25 | template page | ||
| 26 | |||
| 27 | feed.atom: notes/*.md | ||
| 28 | inner-template | ||
| 29 | |||
| 30 | *.md: | ||
| 31 | config | ||
| 32 | ext .html | ||
| 33 | markdown | ||
| 34 | template post | ||
| 35 | template page | ||
| 36 | |||
| 37 | index.html: blog/*.md | ||
| 38 | config | ||
| 39 | inner-template | ||
| 40 | template page | ||
diff --git a/src/curriculum-vitae.md b/content/curriculum-vitae.md index acbd83e..b215b03 100644 --- a/src/curriculum-vitae.md +++ b/content/curriculum-vitae.md | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | title: Curriculum Vitae | 1 | ~ title: Curriculum Vitae |
| 2 | date: 2018-01-16 | 2 | ~ slug: /curriculum-vitae.html |
| 3 | type: page | 3 | ~ date: 2018-01-16 |
| 4 | hide: false | 4 | ~ template: page |
| 5 | ---- | 5 | ~ hide: true |
| 6 | 6 | ||
| 7 | **Mitja Felicijan** | 7 | **Mitja Felicijan** |
| 8 | 8 | ||
diff --git a/src/experiments/encoding-binary-data-into-dna-sequence.md b/content/encoding-binary-data-into-dna-sequence.md index bfcf710..a4f8b86 100644 --- a/src/experiments/encoding-binary-data-into-dna-sequence.md +++ b/content/encoding-binary-data-into-dna-sequence.md | |||
| @@ -1,9 +1,9 @@ | |||
| 1 | title: Encoding binary data into DNA sequence | 1 | ~ title: Encoding binary data into DNA sequence |
| 2 | description: Imagine a world where you could go outside and take a leaf from a tree and put it through your personal DNA sequencer and get data like music, videos or computer programs from it | 2 | ~ description: Imagine a world where you could go outside and take a leaf from a tree and put it through your ~ personal DNA sequencer and get data like music, videos or computer programs from it |
| 3 | date: 2019-01-03 | 3 | ~ slug: /experiments/encoding-binary-data-into-dna-sequence.html |
| 4 | type: post | 4 | ~ date: 2019-01-03 |
| 5 | hide: false | 5 | ~ template: post |
| 6 | ---- | 6 | ~ hide: false |
| 7 | 7 | ||
| 8 | ## Initial thoughts | 8 | ## Initial thoughts |
| 9 | 9 | ||
| @@ -81,7 +81,7 @@ Deoxyribonucleic acid, a self-replicating material which is **present in nearly | |||
| 81 | 81 | ||
| 82 | The nucleotide in DNA consists of a sugar (deoxyribose), one of four bases (cytosine (C), thymine (T), adenine (A), guanine (G)), and a phosphate. Cytosine and thymine are pyrimidine bases, while adenine and guanine are purine bases. The sugar and the base together are called a nucleoside. | 82 | The nucleotide in DNA consists of a sugar (deoxyribose), one of four bases (cytosine (C), thymine (T), adenine (A), guanine (G)), and a phosphate. Cytosine and thymine are pyrimidine bases, while adenine and guanine are purine bases. The sugar and the base together are called a nucleoside. |
| 83 | 83 | ||
| 84 |  | 84 |  |
| 85 | 85 | ||
| 86 | *DNA (a) forms a double stranded helix, and (b) adenine pairs with thymine and cytosine pairs with guanine. (credit a: modification of work by Jerome Walker, Dennis Myts) [^3]* | 86 | *DNA (a) forms a double stranded helix, and (b) adenine pairs with thymine and cytosine pairs with guanine. (credit a: modification of work by Jerome Walker, Dennis Myts) [^3]* |
| 87 | 87 | ||
| @@ -114,7 +114,7 @@ using a single nucleotide. In this way, we are able to use the 4 bases that comp | |||
| 114 | 114 | ||
| 115 | With this in mind we can simply encode any data by using two-bit to Nucleotides conversion | 115 | With this in mind we can simply encode any data by using two-bit to Nucleotides conversion |
| 116 | 116 | ||
| 117 | ```pascal | 117 | ```python |
| 118 | { Algorithm 1: Naive byte array to DNA encode } | 118 | { Algorithm 1: Naive byte array to DNA encode } |
| 119 | procedure EncodeToDNASequence(f) string | 119 | procedure EncodeToDNASequence(f) string |
| 120 | begin | 120 | begin |
| @@ -179,7 +179,7 @@ FASTA format was extended by [FASTQ](https://en.wikipedia.org/wiki/FASTQ_format) | |||
| 179 | 179 | ||
| 180 | With this in mind we can create a simple algorithm to create PNG representation of a DNA sequence. | 180 | With this in mind we can create a simple algorithm to create PNG representation of a DNA sequence. |
| 181 | 181 | ||
| 182 | ```pascal | 182 | ```python |
| 183 | { Algorithm 2: Naive DNA to PNG encode from FASTA file } | 183 | { Algorithm 2: Naive DNA to PNG encode from FASTA file } |
| 184 | procedure EncodeDNASequenceToPNG(f) | 184 | procedure EncodeDNASequenceToPNG(f) |
| 185 | begin | 185 | begin |
| @@ -246,11 +246,11 @@ Then we encode FASTA file from previous operation to encode this data into PNG. | |||
| 246 | 246 | ||
| 247 | After encoding into PNG format this file looks like this. | 247 | After encoding into PNG format this file looks like this. |
| 248 | 248 | ||
| 249 |  | 249 |  |
| 250 | 250 | ||
| 251 | The larger the input stream is the larger the PNG file would be. | 251 | The larger the input stream is the larger the PNG file would be. |
| 252 | 252 | ||
| 253 | Compiled basic Hello World C program with [GCC](https://www.gnu.org/software/gcc/) would [look like](/files/dna-sequence/sample.png). | 253 | Compiled basic Hello World C program with [GCC](https://www.gnu.org/software/gcc/) would [look like](/assets/dna-sequence/sample.png). |
| 254 | 254 | ||
| 255 | ```c | 255 | ```c |
| 256 | // gcc -O3 -o sample sample.c | 256 | // gcc -O3 -o sample sample.c |
| @@ -313,7 +313,7 @@ dd if=<(openssl enc -aes-256-ctr -pass pass:"$(dd if=/dev/urandom bs=128 count= | |||
| 313 | 313 | ||
| 314 | Our freshly generated 1KB file looks something like this (its full of garbage data as intended). | 314 | Our freshly generated 1KB file looks something like this (its full of garbage data as intended). |
| 315 | 315 | ||
| 316 |  | 316 |  |
| 317 | 317 | ||
| 318 | We create following binary files: | 318 | We create following binary files: |
| 319 | - 1KB.bin | 319 | - 1KB.bin |
| @@ -335,7 +335,7 @@ Then we GZIP all the FASTA files to see how much the can be compressed. | |||
| 335 | gzip -9 < 10MB.fa > 10MB.fa.gz | 335 | gzip -9 < 10MB.fa > 10MB.fa.gz |
| 336 | ``` | 336 | ``` |
| 337 | 337 | ||
| 338 | [Download ODS file with benchmarks](/files/dna-sequence/benchmarks.ods). | 338 | [Download ODS file with benchmarks](/assets/dna-sequence/benchmarks.ods). |
| 339 | 339 | ||
| 340 | ## References | 340 | ## References |
| 341 | 341 | ||
diff --git a/src/notes/golang-profiling-simplified.md b/content/golang-profiling-simplified.md index 29e07d6..7b60580 100644 --- a/src/notes/golang-profiling-simplified.md +++ b/content/golang-profiling-simplified.md | |||
| @@ -1,9 +1,9 @@ | |||
| 1 | title: Golang profiling simplified | 1 | ~ title: Golang profiling simplified |
| 2 | description: Golang profiling demystified | 2 | ~ description: Golang profiling demystified |
| 3 | date: 2017-03-07 | 3 | ~ slug: /notes/golang-profiling-simplified.html |
| 4 | type: post | 4 | ~ date: 2017-03-07 |
| 5 | hide: false | 5 | ~ template: post |
| 6 | ---- | 6 | ~ hide: false |
| 7 | 7 | ||
| 8 | Many posts have been written regarding profiling in Golang and I haven’t found proper tutorial regarding this. Almost all of them are missing some part of important information and it gets pretty frustrating when you have a deadline and are not finding simple distilled solution. | 8 | Many posts have been written regarding profiling in Golang and I haven’t found proper tutorial regarding this. Almost all of them are missing some part of important information and it gets pretty frustrating when you have a deadline and are not finding simple distilled solution. |
| 9 | 9 | ||
| @@ -107,5 +107,5 @@ go tool pprof -pdf ./cpu cpu.pprof > cpu.pdf | |||
| 107 | 107 | ||
| 108 | This will generate PDF document with visualized profile. | 108 | This will generate PDF document with visualized profile. |
| 109 | 109 | ||
| 110 | - [Memory PDF profile example](/files/go-profiling/golang-profiling-mem.pdf) | 110 | - [Memory PDF profile example](/assets/go-profiling/golang-profiling-mem.pdf) |
| 111 | - [CPU PDF profile example](/files/go-profiling/golang-profiling-cpu.pdf) | 111 | - [CPU PDF profile example](/assets/go-profiling/golang-profiling-cpu.pdf) |
diff --git a/src/experiments/profiling-python-web-applications-with-visual-tools.md b/content/profiling-python-web-applications-with-visual-tools.md index cf7164c..dd9a692 100644 --- a/src/experiments/profiling-python-web-applications-with-visual-tools.md +++ b/content/profiling-python-web-applications-with-visual-tools.md | |||
| @@ -1,9 +1,9 @@ | |||
| 1 | title: Profiling Python web applications with visual tools | 1 | ~ title: Profiling Python web applications with visual tools |
| 2 | description: Missing link when debugging and profiling python web application | 2 | ~ description: Missing link when debugging and profiling python web application |
| 3 | date: 2017-04-21 | 3 | ~ slug: /experiments/profiling-python-web-applications-with-visual-tools.html |
| 4 | type: post | 4 | ~ date: 2017-04-21 |
| 5 | hide: false | 5 | ~ template: post |
| 6 | ---- | 6 | ~ hide: false |
| 7 | 7 | ||
| 8 | I have been profiling my software with KCachegrind for a long time now and I was missing this option when I am developing API's or other web services. I always knew that this is possible but never really took the time and dive into it. | 8 | I have been profiling my software with KCachegrind for a long time now and I was missing this option when I am developing API's or other web services. I always knew that this is possible but never really took the time and dive into it. |
| 9 | 9 | ||
| @@ -16,7 +16,7 @@ Before we begin there are some requirements. We will need to: | |||
| 16 | 16 | ||
| 17 | If you are using MacOS you should check out [Profiling Viewer](http://www.profilingviewer.com/) or [MacCallGrind](http://www.maccallgrind.com/). | 17 | If you are using MacOS you should check out [Profiling Viewer](http://www.profilingviewer.com/) or [MacCallGrind](http://www.maccallgrind.com/). |
| 18 | 18 | ||
| 19 |  | 19 |  |
| 20 | 20 | ||
| 21 | We will be dividing this post into two main categories: | 21 | We will be dividing this post into two main categories: |
| 22 | 22 | ||
| @@ -135,7 +135,7 @@ $ pyprof2calltree -i awesome_random_number.prof | |||
| 135 | 135 | ||
| 136 | This file can be opened with visualizing tools listed above. In this case we will be using Profilling Viewer under MacOS. You can open image in new tab. As you can see from this example there is hierarchy of execution order of your code. | 136 | This file can be opened with visualizing tools listed above. In this case we will be using Profilling Viewer under MacOS. You can open image in new tab. As you can see from this example there is hierarchy of execution order of your code. |
| 137 | 137 | ||
| 138 |  | 138 |  |
| 139 | 139 | ||
| 140 | > Make sure you convert output of the cProfile output every time you want to refresh and take a look at your possible optimizations because cProfile updates .prof file every time browser hits the function. | 140 | > Make sure you convert output of the cProfile output every time you want to refresh and take a look at your possible optimizations because cProfile updates .prof file every time browser hits the function. |
| 141 | 141 | ||
| @@ -158,7 +158,7 @@ $ snakeviz awesome_random_number.prof | |||
| 158 | # shows visualized profile | 158 | # shows visualized profile |
| 159 | ``` | 159 | ``` |
| 160 | 160 | ||
| 161 |  | 161 |  |
| 162 | 162 | ||
| 163 | Reddit user [ccharles](https://www.reddit.com/user/ccharles) suggested a better way for installing pip software by targeting user level instead of using sudo. | 163 | Reddit user [ccharles](https://www.reddit.com/user/ccharles) suggested a better way for installing pip software by targeting user level instead of using sudo. |
| 164 | 164 | ||
diff --git a/src/experiments/simple-iot-application.md b/content/simple-iot-application.md index c7f59cf..6a8c733 100644 --- a/src/experiments/simple-iot-application.md +++ b/content/simple-iot-application.md | |||
| @@ -1,9 +1,9 @@ | |||
| 1 | title: Simple IOT application supported by real-time monitoring and data history | 1 | ~ title: Simple IOT application supported by real-time monitoring and data history |
| 2 | description: Develop simple IOT application with Arduino MKR1000 and Python | 2 | ~ description: Develop simple IOT application with Arduino MKR1000 and Python |
| 3 | date: 2017-08-11 | 3 | ~ slug: /experiments/simple-iot-application.html |
| 4 | type: post | 4 | ~ date: 2017-08-11 |
| 5 | hide: false | 5 | ~ template: post |
| 6 | ---- | 6 | ~ hide: false |
| 7 | 7 | ||
| 8 | ## Initial thoughts | 8 | ## Initial thoughts |
| 9 | 9 | ||
| @@ -27,7 +27,7 @@ Step 1. and 3. will share the same web application. One route will be dedicated | |||
| 27 | 27 | ||
| 28 | Schema below represents what we will try to achieve and how different parts correlates to each other. | 28 | Schema below represents what we will try to achieve and how different parts correlates to each other. |
| 29 | 29 | ||
| 30 |  | 30 |  |
| 31 | 31 | ||
| 32 | ## Simple Python API | 32 | ## Simple Python API |
| 33 | 33 | ||
| @@ -148,11 +148,11 @@ To run this simply go to folder containing python file and run ```python webapp. | |||
| 148 | 148 | ||
| 149 | After testing the service with Restlet Client you should be able to view your data in a database file ```data.db```. | 149 | After testing the service with Restlet Client you should be able to view your data in a database file ```data.db```. |
| 150 | 150 | ||
| 151 |  | 151 |  |
| 152 | 152 | ||
| 153 | You can also check the contents of new database file by using desktop client for SQLite → [DB Browser for SQLite](http://sqlitebrowser.org/). | 153 | You can also check the contents of new database file by using desktop client for SQLite → [DB Browser for SQLite](http://sqlitebrowser.org/). |
| 154 | 154 | ||
| 155 |  | 155 |  |
| 156 | 156 | ||
| 157 | Table structure is as simple as it can be. We have ts (timestamp) and value (value from Arduino). As you can see timestamp is generated on API side. If you would happen to have atomic clock on Arduino it would be then better to generate and send timestamp with the value. This would be particularity useful if we would be collecting sensor data at a higher frequency and then sending this data in bulk to API. | 157 | Table structure is as simple as it can be. We have ts (timestamp) and value (value from Arduino). As you can see timestamp is generated on API side. If you would happen to have atomic clock on Arduino it would be then better to generate and send timestamp with the value. This would be particularity useful if we would be collecting sensor data at a higher frequency and then sending this data in bulk to API. |
| 158 | 158 | ||
| @@ -469,9 +469,9 @@ If everything goes well you should be seeing new data-points rendered on chart e | |||
| 469 | 469 | ||
| 470 | If you navigate to ```http://0.0.0.0:5000``` you should see rendered chart as shown on picture below. | 470 | If you navigate to ```http://0.0.0.0:5000``` you should see rendered chart as shown on picture below. |
| 471 | 471 | ||
| 472 |  | 472 |  |
| 473 | 473 | ||
| 474 | Complete application with all the code is available for [download](/files/iot-application/simple-iot-application.zip). | 474 | Complete application with all the code is available for [download](/assets/iot-application/simple-iot-application.zip). |
| 475 | 475 | ||
| 476 | ## Conclusion | 476 | ## Conclusion |
| 477 | 477 | ||
diff --git a/src/notes/simplifying-and-reducing-clutter.md b/content/simplifying-and-reducing-clutter.md index 483d0dc..7182a4e 100644 --- a/src/notes/simplifying-and-reducing-clutter.md +++ b/content/simplifying-and-reducing-clutter.md | |||
| @@ -1,9 +1,9 @@ | |||
| 1 | title: Simplifying and reducing clutter in my life and work | 1 | ~ title: Simplifying and reducing clutter in my life and work |
| 2 | description: Simplifying and reducing clutter in my life and work | 2 | ~ description: Simplifying and reducing clutter in my life and work |
| 3 | date: 2019-10-14 | 3 | ~ slug: /notes/simplifying-and-reducing-clutter.html |
| 4 | type: post | 4 | ~ date: 2019-10-14 |
| 5 | hide: false | 5 | ~ template: post |
| 6 | ---- | 6 | ~ hide: false |
| 7 | 7 | ||
| 8 | I recently moved my main working machine back from Hachintosh to Linux. Well the experiment was interesting and I have done some great work on macOS but it was time to move back. | 8 | I recently moved my main working machine back from Hachintosh to Linux. Well the experiment was interesting and I have done some great work on macOS but it was time to move back. |
| 9 | 9 | ||
diff --git a/src/experiments/using-digitalocean-spaces-object-storage-with-fuse.md b/content/using-digitalocean-spaces-object-storage-with-fuse.md index 1d3fe48..e2b3ad8 100644 --- a/src/experiments/using-digitalocean-spaces-object-storage-with-fuse.md +++ b/content/using-digitalocean-spaces-object-storage-with-fuse.md | |||
| @@ -1,9 +1,9 @@ | |||
| 1 | title: Using DigitalOcean Spaces Object Storage with FUSE | 1 | ~ title: Using DigitalOcean Spaces Object Storage with FUSE |
| 2 | description: Using DigitalOcean Spaces Object Storage with FUSE | 2 | ~ description: Using DigitalOcean Spaces Object Storage with FUSE |
| 3 | date: 2018-01-16 | 3 | ~ slug: /experiments/using-digitalocean-spaces-object-storage-with-fuse.html |
| 4 | type: post | 4 | ~ date: 2018-01-16 |
| 5 | hide: false | 5 | ~ template: post |
| 6 | ---- | 6 | ~ hide: false |
| 7 | 7 | ||
| 8 | Couple of months ago [DigitalOcean](https://www.digitalocean.com) introduced new product called [Spaces](https://blog.digitalocean.com/introducing-spaces-object-storage/) which is Object Storage very similar to Amazon's S3. This really peaked my interest, because this was something I was missing and even the thought of going over the internet for such functionality was in no interest to me. Also in fashion with their previous pricing this also is very cheap and pricing page is a no-brainer compared to AWS or GCE. [Prices are clearly and precisely defined and outlined](https://www.digitalocean.com/pricing/). You must love them for that :) | 8 | Couple of months ago [DigitalOcean](https://www.digitalocean.com) introduced new product called [Spaces](https://blog.digitalocean.com/introducing-spaces-object-storage/) which is Object Storage very similar to Amazon's S3. This really peaked my interest, because this was something I was missing and even the thought of going over the internet for such functionality was in no interest to me. Also in fashion with their previous pricing this also is very cheap and pricing page is a no-brainer compared to AWS or GCE. [Prices are clearly and precisely defined and outlined](https://www.digitalocean.com/pricing/). You must love them for that :) |
| 9 | 9 | ||
| @@ -26,13 +26,13 @@ To make this work you will need DigitalOcean account. If you don't have one you | |||
| 26 | 26 | ||
| 27 | Instuctions on how to use SSH keys and how to setup them are available in article [How To Use SSH Keys with DigitalOcean Droplets](https://www.digitalocean.com/community/tutorials/how-to-use-ssh-keys-with-digitalocean-droplets). | 27 | Instuctions on how to use SSH keys and how to setup them are available in article [How To Use SSH Keys with DigitalOcean Droplets](https://www.digitalocean.com/community/tutorials/how-to-use-ssh-keys-with-digitalocean-droplets). |
| 28 | 28 | ||
| 29 |  | 29 |  |
| 30 | 30 | ||
| 31 | After we created Droplet it's time to create new Space. This is done by clicking on a button [Create](https://cloud.digitalocean.com/spaces/new) (right top corner) and selecting Spaces. Choose pronounceable ```Unique name``` because we will use it in examples below. You can either choose Private or Public, it doesn't matter in our case. And you can always change that in the future. | 31 | After we created Droplet it's time to create new Space. This is done by clicking on a button [Create](https://cloud.digitalocean.com/spaces/new) (right top corner) and selecting Spaces. Choose pronounceable ```Unique name``` because we will use it in examples below. You can either choose Private or Public, it doesn't matter in our case. And you can always change that in the future. |
| 32 | 32 | ||
| 33 | When you have created new Space we should [generate Access key](https://cloud.digitalocean.com/settings/api/tokens). This link will guide to the page when you can generate this key. After you create new one, please save provided Key and Secret because Secret will not be shown again. | 33 | When you have created new Space we should [generate Access key](https://cloud.digitalocean.com/settings/api/tokens). This link will guide to the page when you can generate this key. After you create new one, please save provided Key and Secret because Secret will not be shown again. |
| 34 | 34 | ||
| 35 |  | 35 |  |
| 36 | 36 | ||
| 37 | Now that we have new Space and Access key we should SSH into our machine. | 37 | Now that we have new Space and Access key we should SSH into our machine. |
| 38 | 38 | ||
| @@ -102,14 +102,14 @@ As I suspected, object size is not really that important. Sadly I don't have the | |||
| 102 | 102 | ||
| 103 | **Here are plotted results** | 103 | **Here are plotted results** |
| 104 | 104 | ||
| 105 | You can download [raw result here](/files/do-fuse/copy-benchmarks.tsv). Measurements are in seconds. | 105 | You can download [raw result here](/assets/do-fuse/copy-benchmarks.tsv). Measurements are in seconds. |
| 106 | 106 | ||
| 107 | <script src="//cdn.plot.ly/plotly-latest.min.js"></script> | 107 | <script src="//cdn.plot.ly/plotly-latest.min.js"></script> |
| 108 | <div id="copy-benchmarks"></div> | 108 | <div id="copy-benchmarks"></div> |
| 109 | <script> | 109 | <script> |
| 110 | (function(){ | 110 | (function(){ |
| 111 | var request = new XMLHttpRequest(); | 111 | var request = new XMLHttpRequest(); |
| 112 | request.open("GET", "/files/do-fuse/copy-benchmarks.tsv", true); | 112 | request.open("GET", "/assets/do-fuse/copy-benchmarks.tsv", true); |
| 113 | request.onload = function() { | 113 | request.onload = function() { |
| 114 | if (request.status >= 200 && request.status < 400) { | 114 | if (request.status >= 200 && request.status < 400) { |
| 115 | var payload = request.responseText.trim(); | 115 | var payload = request.responseText.trim(); |
| @@ -218,13 +218,13 @@ result_time = CLOSE = end_time - start_time | |||
| 218 | print("CLOSE: %g seconds" % (result_time)) | 218 | print("CLOSE: %g seconds" % (result_time)) |
| 219 | ``` | 219 | ``` |
| 220 | 220 | ||
| 221 | You can download [raw result here](/files/do-fuse/sqlite-benchmarks.tsv). And again, these results are done on a local block storage and do not represent capabilities of object storage. With my current approach and state of the test code these can not be done. I would need to make Python code much more robust and check locking etc. | 221 | You can download [raw result here](/assets/do-fuse/sqlite-benchmarks.tsv). And again, these results are done on a local block storage and do not represent capabilities of object storage. With my current approach and state of the test code these can not be done. I would need to make Python code much more robust and check locking etc. |
| 222 | 222 | ||
| 223 | <div id="sqlite-benchmarks"></div> | 223 | <div id="sqlite-benchmarks"></div> |
| 224 | <script> | 224 | <script> |
| 225 | (function(){ | 225 | (function(){ |
| 226 | var request = new XMLHttpRequest(); | 226 | var request = new XMLHttpRequest(); |
| 227 | request.open("GET", "/files/do-fuse/sqlite-benchmarks.tsv", true); | 227 | request.open("GET", "/assets/do-fuse/sqlite-benchmarks.tsv", true); |
| 228 | request.onload = function() { | 228 | request.onload = function() { |
| 229 | if (request.status >= 200 && request.status < 400) { | 229 | if (request.status >= 200 && request.status < 400) { |
| 230 | var payload = request.responseText.trim(); | 230 | var payload = request.responseText.trim(); |
diff --git a/src/experiments/using-sentiment-analysis-for-click-bait-detection-in-rss-feeds.md b/content/using-sentiment-analysis-for-click-bait-detection-in-rss-feeds.md index ad0362b..d849763 100644 --- a/src/experiments/using-sentiment-analysis-for-click-bait-detection-in-rss-feeds.md +++ b/content/using-sentiment-analysis-for-click-bait-detection-in-rss-feeds.md | |||
| @@ -1,9 +1,9 @@ | |||
| 1 | title: Using sentiment analysis for click‑bait detection in RSS feeds | 1 | ~ title: Using sentiment analysis for click‑bait detection in RSS feeds |
| 2 | description: Using Python with sentiment analysis to detect if titles in RSS feeds are click-bait | 2 | ~ description: Using Python with sentiment analysis to detect if titles in RSS feeds are click-bait |
| 3 | date: 2019-10-19 | 3 | ~ slug: /experiments/using-sentiment-analysis-for-click-bait-detection-in-rss-feeds.html |
| 4 | type: post | 4 | ~ date: 2019-10-19 |
| 5 | hide: false | 5 | ~ template: post |
| 6 | ---- | 6 | ~ hide: false |
| 7 | 7 | ||
| 8 | ## Initial thoughts | 8 | ## Initial thoughts |
| 9 | 9 | ||
| @@ -72,11 +72,11 @@ plt.show() | |||
| 72 | 2. Rule-based approach may not be the best way of doing this. By using deep learning we would be able to get better insights. | 72 | 2. Rule-based approach may not be the best way of doing this. By using deep learning we would be able to get better insights. |
| 73 | 3. **Next step would be to** periodically fetch RSS items and store them over a longer period of time and then perform analysis again and use either machine learning or deep learning on top of it. | 73 | 3. **Next step would be to** periodically fetch RSS items and store them over a longer period of time and then perform analysis again and use either machine learning or deep learning on top of it. |
| 74 | 74 | ||
| 75 |  | 75 |  |
| 76 | 76 | ||
| 77 | Figure above displays difference between title and description sentiment for specific RSS feed item. 1 means positive and -1 means negative sentiment. | 77 | Figure above displays difference between title and description sentiment for specific RSS feed item. 1 means positive and -1 means negative sentiment. |
| 78 | 78 | ||
| 79 | [» Download Jupyter Notebook](/files/sentiment-analysis/sentiment-analysis.ipynb) | 79 | [» Download Jupyter Notebook](/assets/sentiment-analysis/sentiment-analysis.ipynb) |
| 80 | 80 | ||
| 81 | ## Going further | 81 | ## Going further |
| 82 | 82 | ||
diff --git a/src/notes/what-i-ve-learned-developing-ad-server.md b/content/what-i-ve-learned-developing-ad-server.md index 25f11a3..e546775 100644 --- a/src/notes/what-i-ve-learned-developing-ad-server.md +++ b/content/what-i-ve-learned-developing-ad-server.md | |||
| @@ -1,9 +1,9 @@ | |||
| 1 | title: What I've learned developing ad server | 1 | ~ title: What I've learned developing ad server |
| 2 | description: Lessons I learned developing contextual ad server | 2 | ~ description: Lessons I learned developing contextual ad server |
| 3 | date: 2017-04-17 | 3 | ~ slug: /notes/what-i-ve-learned-developing-ad-server.html |
| 4 | type: post | 4 | ~ date: 2017-04-17 |
| 5 | hide: false | 5 | ~ template: post |
| 6 | ---- | 6 | ~ hide: false |
| 7 | 7 | ||
| 8 | For the past year and half I have been developing native advertising server that contextually matches ads and displays them in different template forms on variety of websites. This project grew from serving thousands of ads per day to millions. | 8 | For the past year and half I have been developing native advertising server that contextually matches ads and displays them in different template forms on variety of websites. This project grew from serving thousands of ads per day to millions. |
| 9 | 9 | ||
diff --git a/site.tmpl b/site.tmpl deleted file mode 100644 index c745997..0000000 --- a/site.tmpl +++ /dev/null | |||
| @@ -1,140 +0,0 @@ | |||
| 1 | {{ define "header" }} | ||
| 2 | <!doctype html> | ||
| 3 | <html lang="en"> | ||
| 4 | |||
| 5 | <head> | ||
| 6 | <meta charset="utf-8"> | ||
| 7 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| 8 | <meta name="theme-color" content="#ffffff"> | ||
| 9 | <meta name="google-site-verification" content="{{ html .Site.Other.Google_verification }}"> | ||
| 10 | <meta http-equiv="X-UA-Compatible" content="ie=edge"> | ||
| 11 | |||
| 12 | <link rel="preconnect" href="https://www.google-analytics.com"> | ||
| 13 | |||
| 14 | <link rel="alternate" type="application/atom+xml" title="{{ html .Site.Other.Title }} feed" href="{{ .Rel "feed.atom" }}"> | ||
| 15 | <link rel="stylesheet" type="text/css" href="{{ .Rel "static/style.css" }}?v={{ .ModTime.Format "20060102150405" }}"> | ||
| 16 | <link rel="icon" type="image/png" href="{{ .Rel "static/avatar-64x64.png" }}?v={{ .ModTime.Format "20060102150405" }}"> | ||
| 17 | |||
| 18 | <title>{{ if .Title }}{{ .Title }} - {{ end }}{{ .Site.Other.Title }}</title> | ||
| 19 | <meta name="author" content="{{ html .Site.Other.Author }}"> | ||
| 20 | <meta name="description" content="{{ if .Other.Description }}{{ .Other.Description }}{{ else }}{{ html .Site.Other.Description }}{{ end }}"> | ||
| 21 | |||
| 22 | <meta property="og:title" content="{{ if .Title }}{{ .Title }} - {{ end }}{{ .Site.Other.Title }}"> | ||
| 23 | <meta property="og:description" content="{{ if .Other.Description }}{{ .Other.Description }}{{ else }}{{ html .Site.Other.Description }}{{ end }}"> | ||
| 24 | <meta property="og:url" content="{{ .Site.Other.Url }}/{{ .Url }}"> | ||
| 25 | |||
| 26 | <meta name="twitter:card" content="summary"> | ||
| 27 | <meta name="twitter:site" content="{{ html .Site.Other.Twitter_handle }}"> | ||
| 28 | </head> | ||
| 29 | |||
| 30 | <body> | ||
| 31 | <main> | ||
| 32 | {{ end }} | ||
| 33 | {{ define "footer" }} | ||
| 34 | </main> | ||
| 35 | {{ template "ga" . }} | ||
| 36 | </body> | ||
| 37 | |||
| 38 | </html> | ||
| 39 | {{ end }} | ||
| 40 | |||
| 41 | {{ define "navigation" }} | ||
| 42 | <nav> | ||
| 43 | <a href="/">{{ html .Site.Other.Author }}</a> | ||
| 44 | <a href="/curriculum-vitae.html">CV</a> | ||
| 45 | <a href="https://twitter.com/mitjafelicijan" target="_blank" rel="noopener nofollow">Twitter</a> | ||
| 46 | <a href="https://github.com/mitjafelicijan" target="_blank" rel="noopener nofollow">Github</a> | ||
| 47 | </nav> | ||
| 48 | {{ end }} | ||
| 49 | |||
| 50 | {{ define "author" }} | ||
| 51 | <span>by {{ html .Site.Other.Author }}</span> | ||
| 52 | {{ end }} | ||
| 53 | |||
| 54 | {{define "date"}} | ||
| 55 | <time datetime="{{ .Format "2006-01-02T15:04:05Z07:00" }}"> | ||
| 56 | {{ .Format "2006, January 02" }} | ||
| 57 | </time> | ||
| 58 | {{end}} | ||
| 59 | |||
| 60 | {{define "modified"}} | ||
| 61 | <p class="modified">Modified on {{ .ModTime.Format "2006-01-02T15:04:05" }}</p> | ||
| 62 | {{end}} | ||
| 63 | |||
| 64 | {{ define "page" }} | ||
| 65 | {{ template "header" . }} | ||
| 66 | {{ template "navigation" . }} | ||
| 67 | {{ .Content }} | ||
| 68 | {{ template "prism" . }} | ||
| 69 | {{ template "mathjax" . }} | ||
| 70 | {{ template "footer" . }} | ||
| 71 | {{ end }} | ||
| 72 | |||
| 73 | {{ define "post" }} | ||
| 74 | <article> | ||
| 75 | <header> | ||
| 76 | <h1>{{ .Title }}</h1> | ||
| 77 | {{ if eq .Other.Type "post" }} | ||
| 78 | <div class="info"> | ||
| 79 | {{ template "date" .Date }} | ||
| 80 | {{ template "author" . }} | ||
| 81 | </div> | ||
| 82 | {{ end }} | ||
| 83 | </header> | ||
| 84 | <section> | ||
| 85 | {{ .Content }} | ||
| 86 | </section> | ||
| 87 | </article> | ||
| 88 | |||
| 89 | {{ if eq .Other.Type "post" }} | ||
| 90 | {{ template "comments" . }} | ||
| 91 | {{ end }} | ||
| 92 | |||
| 93 | {{ template "modified" . }} | ||
| 94 | {{ end }} | ||
| 95 | |||
| 96 | {{ define "mathjax" }} | ||
| 97 | <script type="text/x-mathjax-config"> | ||
| 98 | MathJax.Hub.Config({ | ||
| 99 | TeX: { equationNumbers: { autoNumber: "AMS" } }, | ||
| 100 | tex2jax: { | ||
| 101 | inlineMath: [ [ '$', '$' ], [ '\\(', '\\)' ] ], | ||
| 102 | displayMath: [ ['$$', '$$'] ], | ||
| 103 | processEscapes: true | ||
| 104 | }}); | ||
| 105 | </script> | ||
| 106 | <script src="//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS-MML_HTMLorMML" async="async"></script> | ||
| 107 | {{ end }} | ||
| 108 | |||
| 109 | {{ define "ga" }} | ||
| 110 | <script async="async" src="https://www.googletagmanager.com/gtag/js?id=UA-12769079-10"></script> | ||
| 111 | <script> | ||
| 112 | window.dataLayer = window.dataLayer || []; | ||
| 113 | function gtag() { | ||
| 114 | dataLayer.push(arguments); | ||
| 115 | } | ||
| 116 | gtag('js', new Date()); | ||
| 117 | gtag('config', 'UA-12769079-10'); | ||
| 118 | </script> | ||
| 119 | {{ end }} | ||
| 120 | |||
| 121 | {{ define "prism" }} | ||
| 122 | <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/components/prism-core.min.js"></script> | ||
| 123 | <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/plugins/autoloader/prism-autoloader.min.js"></script> | ||
| 124 | {{ end }} | ||
| 125 | |||
| 126 | {{ define "comments" }} | ||
| 127 | <div class="comments"> | ||
| 128 | <h3>Comments</h3> | ||
| 129 | <div class="form"> | ||
| 130 | <div><input id="name" placeholder="Your name" maxlength="20"></div> | ||
| 131 | <div><textarea id="comment" placeholder="Your comment" maxlength="500"></textarea></div> | ||
| 132 | <div><button id="submit">Post a comment</button></div> | ||
| 133 | </div> | ||
| 134 | <ul></ul> | ||
| 135 | </div> | ||
| 136 | |||
| 137 | <script src="https://www.gstatic.com/firebasejs/7.2.1/firebase-app.js"></script> | ||
| 138 | <script src="https://www.gstatic.com/firebasejs/7.2.1/firebase-database.js"></script> | ||
| 139 | <script src="{{ .Rel "static/comments.js" }}?v={{ .ModTime.Format "20060102150405" }}" async></script> | ||
| 140 | {{ end }} | ||
diff --git a/src/404.html b/src/404.html deleted file mode 100644 index 0f0a0b9..0000000 --- a/src/404.html +++ /dev/null | |||
| @@ -1,3 +0,0 @@ | |||
| 1 | <h1>Content you are looking for is not here.</h1> | ||
| 2 | |||
| 3 | <a href="/">« Return to main page</a> | ||
diff --git a/src/comments.html b/src/comments.html deleted file mode 100644 index 3d990da..0000000 --- a/src/comments.html +++ /dev/null | |||
| @@ -1,100 +0,0 @@ | |||
| 1 | <!DOCTYPE html> | ||
| 2 | <html lang="en"> | ||
| 3 | |||
| 4 | <head> | ||
| 5 | <meta charset="utf-8"> | ||
| 6 | <meta name="theme-color" content="#ffffff"> | ||
| 7 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| 8 | <meta http-equiv="X-UA-Compatible" content="ie=edge"> | ||
| 9 | <title>Commenta dashboard</title> | ||
| 10 | |||
| 11 | <style> | ||
| 12 | th { | ||
| 13 | text-align: left; | ||
| 14 | } | ||
| 15 | |||
| 16 | .comment-item { | ||
| 17 | padding: 10px 0 30px 0; | ||
| 18 | border-bottom: 2px inset gray; | ||
| 19 | } | ||
| 20 | </style> | ||
| 21 | |||
| 22 | </head> | ||
| 23 | |||
| 24 | <body> | ||
| 25 | |||
| 26 | <h1>Comments</h1> | ||
| 27 | <div id="results"></div> | ||
| 28 | |||
| 29 | <script src="https://www.gstatic.com/firebasejs/7.2.1/firebase-app.js"></script> | ||
| 30 | <script src="https://www.gstatic.com/firebasejs/7.2.1/firebase-database.js"></script> | ||
| 31 | <script src="static/comments.js"></script> | ||
| 32 | |||
| 33 | <script> | ||
| 34 | |||
| 35 | // var tableResults = document.querySelector('#results tbody'); | ||
| 36 | var resultsPlaceholder = document.querySelector('#results'); | ||
| 37 | |||
| 38 | function snapshotToArray(snapshot) { | ||
| 39 | var returnArr = []; | ||
| 40 | snapshot.forEach(function (childSnapshot) { | ||
| 41 | var arrItem = childSnapshot.val(); | ||
| 42 | arrItem.key = childSnapshot.key; | ||
| 43 | returnArr.push(arrItem); | ||
| 44 | }); | ||
| 45 | |||
| 46 | var comments = []; | ||
| 47 | returnArr.forEach(function (item) { | ||
| 48 | var keys = Object.keys(item); | ||
| 49 | for (var key of keys) { | ||
| 50 | let group = item.key; | ||
| 51 | if (key !== 'key') { | ||
| 52 | for (var itemKey of Object.keys(item[key])) { | ||
| 53 | item[key][itemKey].slug = key; | ||
| 54 | item[key][itemKey].group = group; | ||
| 55 | item[key][itemKey].itemKey = itemKey | ||
| 56 | comments.push(item[key][itemKey]); | ||
| 57 | } | ||
| 58 | } | ||
| 59 | } | ||
| 60 | }); | ||
| 61 | |||
| 62 | return comments; | ||
| 63 | }; | ||
| 64 | |||
| 65 | var path = window.location.hostname.replace('.', '-') + '/comments'; | ||
| 66 | var ref = firebase.database().ref(path); | ||
| 67 | ref.on("value", function (snap) { | ||
| 68 | resultsPlaceholder.innerHTML = ''; | ||
| 69 | var comments = snapshotToArray(snap); | ||
| 70 | comments.forEach(function (item) { | ||
| 71 | var commentContent = document.createElement('div'); | ||
| 72 | |||
| 73 | commentContent.classList.add('comment-item'); | ||
| 74 | commentContent.innerHTML = ` | ||
| 75 | <p><b>${item.name} (${item.published})</b><br> | ||
| 76 | <i>${item.group}/${item.slug}</i></p> | ||
| 77 | <p>${item.comment}</p> | ||
| 78 | `; | ||
| 79 | |||
| 80 | var buttonDelete = document.createElement('button'); | ||
| 81 | buttonDelete.innerText = 'Delete comment'; | ||
| 82 | buttonDelete.dataset.id = `${window.location.hostname.replace('.', '-')}/comments/${item.group}/${item.slug}/${item.itemKey}`; | ||
| 83 | buttonDelete.addEventListener('click', function (evt) { | ||
| 84 | if (confirm('Are you sure you want to delete this comment?')) { | ||
| 85 | firebase.database().ref(evt.target.dataset.id).remove(); | ||
| 86 | } | ||
| 87 | }); | ||
| 88 | |||
| 89 | commentContent.appendChild(buttonDelete); | ||
| 90 | resultsPlaceholder.appendChild(commentContent); | ||
| 91 | }); | ||
| 92 | }, function (errorObject) { | ||
| 93 | console.log(`The read failed: ${errorObject.code}`); | ||
| 94 | }); | ||
| 95 | |||
| 96 | </script> | ||
| 97 | |||
| 98 | </body> | ||
| 99 | |||
| 100 | </html> | ||
diff --git a/src/feed.atom b/src/feed.atom deleted file mode 100644 index dda420c..0000000 --- a/src/feed.atom +++ /dev/null | |||
| @@ -1,55 +0,0 @@ | |||
| 1 | <?xml version="1.0" encoding="utf-8"?> | ||
| 2 | <feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0"> | ||
| 3 | <id>{{ .Site.Other.Url }}</id> | ||
| 4 | <title>{{ .Site.Other.Title }}</title> | ||
| 5 | {{ with .Site.Pages.Children "notes/" }} | ||
| 6 | <updated>{{ .First.Date.Format "2006-01-02T15:04:05Z07:00" }}</updated> | ||
| 7 | {{ end }} | ||
| 8 | <author><name>{{ .Site.Other.Author }}</name></author> | ||
| 9 | <link href="{{ .Site.Other.Url }}" rel="alternate"></link> | ||
| 10 | <generator uri="https://github.com/piranha/gostatic">gostatic</generator> | ||
| 11 | |||
| 12 | {{ with .Site.Pages.Children "notes/" }} | ||
| 13 | {{ range .Slice 0 5 }} | ||
| 14 | <entry> | ||
| 15 | <id>{{ .Url }}</id> | ||
| 16 | <author><name>{{ or .Other.Author .Site.Other.Author }}</name></author> | ||
| 17 | <title type="html">{{ html .Title }}</title> | ||
| 18 | <published>{{ .Date.Format "2006-01-02T15:04:05Z07:00" }}</published> | ||
| 19 | {{ range .Tags }} | ||
| 20 | <category term="{{ . }}"></category> | ||
| 21 | {{ end }} | ||
| 22 | <link href="{{ .Site.Other.Url }}/{{ .Url }}" rel="alternate"></link> | ||
| 23 | <content type="html"> | ||
| 24 | {{/* .Process runs here in case only feed changed */}} | ||
| 25 | {{ with cut "<section>" "</section>" .Process.Content }} | ||
| 26 | {{ html . }} | ||
| 27 | {{ end }} | ||
| 28 | </content> | ||
| 29 | </entry> | ||
| 30 | {{ end }} | ||
| 31 | {{ end }} | ||
| 32 | |||
| 33 | {{ with .Site.Pages.Children "experiments/" }} | ||
| 34 | {{ range .Slice 0 5 }} | ||
| 35 | <entry> | ||
| 36 | <id>{{ .Url }}</id> | ||
| 37 | <author><name>{{ or .Other.Author .Site.Other.Author }}</name></author> | ||
| 38 | <title type="html">{{ html .Title }}</title> | ||
| 39 | <published>{{ .Date.Format "2006-01-02T15:04:05Z07:00" }}</published> | ||
| 40 | {{ range .Tags }} | ||
| 41 | <category term="{{ . }}"></category> | ||
| 42 | {{ end }} | ||
| 43 | <link href="{{ .Site.Other.Url }}/{{ .Url }}" rel="alternate"></link> | ||
| 44 | <content type="html"> | ||
| 45 | {{/* .Process runs here in case only feed changed */}} | ||
| 46 | {{ with cut "<section>" "</section>" .Process.Content }} | ||
| 47 | {{ html . }} | ||
| 48 | {{ end }} | ||
| 49 | </content> | ||
| 50 | </entry> | ||
| 51 | {{ end }} | ||
| 52 | {{ end }} | ||
| 53 | |||
| 54 | |||
| 55 | </feed> | ||
diff --git a/src/index.html b/src/index.html deleted file mode 100644 index 6b987f7..0000000 --- a/src/index.html +++ /dev/null | |||
| @@ -1,21 +0,0 @@ | |||
| 1 | <h2>Experiments</h2> | ||
| 2 | <ul class="article-list"> | ||
| 3 | {{ range .Site.Pages.Children "experiments/" }} | ||
| 4 | <li> | ||
| 5 | <div> | ||
| 6 | <time>{{ template "date" .Date }}</time> | ||
| 7 | <a href="{{ $.Rel .Url }}" title="{{ .Title }}">{{ .Title }}</a> | ||
| 8 | </div> | ||
| 9 | </li> | ||
| 10 | {{ end }} | ||
| 11 | </ul> | ||
| 12 | |||
| 13 | <h2>General notes</h2> | ||
| 14 | <ul class="article-list"> | ||
| 15 | {{ range .Site.Pages.Children "notes/" }} | ||
| 16 | <li> | ||
| 17 | <time>{{ template "date" .Date }}</time> | ||
| 18 | <a href="{{ $.Rel .Url }}" title="{{ .Title }}">{{ .Title }}</a> | ||
| 19 | </li> | ||
| 20 | {{ end }} | ||
| 21 | </ul> | ||
diff --git a/src/static/comments.js b/src/static/comments.js deleted file mode 100644 index 3f373e5..0000000 --- a/src/static/comments.js +++ /dev/null | |||
| @@ -1,65 +0,0 @@ | |||
| 1 | var firebaseConfig = { | ||
| 2 | apiKey: "AIzaSyD3E0XtiUJI4-JIxcIPZziNLGVaTdojz20", | ||
| 3 | authDomain: "mitja-felicijan-blog.firebaseapp.com", | ||
| 4 | databaseURL: "https://mitja-felicijan-blog.firebaseio.com", | ||
| 5 | projectId: "mitja-felicijan-blog", | ||
| 6 | storageBucket: "mitja-felicijan-blog.appspot.com", | ||
| 7 | messagingSenderId: "41650892882", | ||
| 8 | appId: "1:41650892882:web:b308f0a9c47198bdf7ef8b" | ||
| 9 | }; | ||
| 10 | firebase.initializeApp(firebaseConfig); | ||
| 11 | |||
| 12 | var database = firebase.database(); | ||
| 13 | var docPath = window.location.hostname.replace('.', '-') + '/comments' + window.location.pathname.replace('.html', ''); | ||
| 14 | var submit = document.querySelector('#submit'); | ||
| 15 | var comments = document.querySelector('.comments ul'); | ||
| 16 | var textName = document.querySelector('#name'); | ||
| 17 | var textComment = document.querySelector('#comment'); | ||
| 18 | var ref = firebase.database().ref(docPath); | ||
| 19 | |||
| 20 | function encodeHTML(s) { | ||
| 21 | return s.replace(/&/g, '&').replace(/</g, '<').replace(/"/g, '"'); | ||
| 22 | } | ||
| 23 | |||
| 24 | if (submit) { | ||
| 25 | ref.on("value", function (snapshot) { | ||
| 26 | comments.innerHTML = ''; | ||
| 27 | var commentList = Array(); | ||
| 28 | |||
| 29 | // generating normal array | ||
| 30 | snapshot.forEach(function (item) { | ||
| 31 | commentList.push(item.val()) | ||
| 32 | }); | ||
| 33 | |||
| 34 | // rendering html | ||
| 35 | commentList.reverse().forEach(function (item) { | ||
| 36 | var liItem = `<li> | ||
| 37 | <div><b>${encodeHTML(item.name)}</b> - ${encodeHTML(item.published)}</div> | ||
| 38 | <div>${encodeHTML(item.comment)}</div> | ||
| 39 | </li>`; | ||
| 40 | comments.innerHTML += liItem; | ||
| 41 | }); | ||
| 42 | |||
| 43 | }, function (errorObject) { | ||
| 44 | console.log("The read failed: " + errorObject.code); | ||
| 45 | }); | ||
| 46 | |||
| 47 | submit.addEventListener('click', function (evt) { | ||
| 48 | if (textName.value && textComment.value) { | ||
| 49 | submit.disabled = true; | ||
| 50 | firebase.database().ref(docPath + '/' + Date.now()).set({ | ||
| 51 | name: textName.value, | ||
| 52 | comment: textComment.value, | ||
| 53 | published: new Date().toISOString().slice(0, 16).replace('T', ' '), | ||
| 54 | }, function (error) { | ||
| 55 | if (error) { | ||
| 56 | alert('Data could not be saved.' + error); | ||
| 57 | } else { | ||
| 58 | textName.value = ''; | ||
| 59 | textComment.value = ''; | ||
| 60 | submit.disabled = false; | ||
| 61 | } | ||
| 62 | }); | ||
| 63 | } | ||
| 64 | }); | ||
| 65 | } | ||
diff --git a/src/static/style.css b/src/static/style.css deleted file mode 100644 index d2b3203..0000000 --- a/src/static/style.css +++ /dev/null | |||
| @@ -1,319 +0,0 @@ | |||
| 1 | * { | ||
| 2 | box-sizing: border-box; | ||
| 3 | } | ||
| 4 | |||
| 5 | body { | ||
| 6 | line-height: 150%; | ||
| 7 | margin-bottom: 100px; | ||
| 8 | font-family: serif; | ||
| 9 | } | ||
| 10 | |||
| 11 | main { | ||
| 12 | max-width: 760px; | ||
| 13 | padding: 20px 30px; | ||
| 14 | } | ||
| 15 | |||
| 16 | nav { | ||
| 17 | margin-bottom: 50px; | ||
| 18 | } | ||
| 19 | |||
| 20 | nav a { | ||
| 21 | display: inline-block; | ||
| 22 | margin-right: 20px; | ||
| 23 | } | ||
| 24 | |||
| 25 | h1 { | ||
| 26 | font-size: 280%; | ||
| 27 | line-height: initial; | ||
| 28 | } | ||
| 29 | |||
| 30 | h2 { | ||
| 31 | font-size: 200%; | ||
| 32 | line-height: initial; | ||
| 33 | } | ||
| 34 | |||
| 35 | h3 { | ||
| 36 | font-size: 160%; | ||
| 37 | line-height: initial; | ||
| 38 | } | ||
| 39 | |||
| 40 | img { | ||
| 41 | max-width: 100%; | ||
| 42 | margin: 30px auto; | ||
| 43 | display: block; | ||
| 44 | } | ||
| 45 | |||
| 46 | ul.article-list li { | ||
| 47 | margin-bottom: 10px; | ||
| 48 | } | ||
| 49 | |||
| 50 | ul.article-list li div { | ||
| 51 | display: flex; | ||
| 52 | } | ||
| 53 | |||
| 54 | ul.article-list time { | ||
| 55 | display: inline-block; | ||
| 56 | min-width: 160px; | ||
| 57 | } | ||
| 58 | |||
| 59 | |||
| 60 | article .info { | ||
| 61 | font-style: oblique; | ||
| 62 | } | ||
| 63 | |||
| 64 | pre { | ||
| 65 | overflow: auto; | ||
| 66 | } | ||
| 67 | |||
| 68 | table { | ||
| 69 | width: 100%; | ||
| 70 | } | ||
| 71 | |||
| 72 | table, th, td { | ||
| 73 | border: 1px solid black; | ||
| 74 | text-align: left; | ||
| 75 | } | ||
| 76 | |||
| 77 | th, td { | ||
| 78 | padding: 5px 10px; | ||
| 79 | } | ||
| 80 | |||
| 81 | code, pre { | ||
| 82 | font-size: 14px; | ||
| 83 | } | ||
| 84 | |||
| 85 | code { | ||
| 86 | background: rgb(255, 241, 177); | ||
| 87 | padding: 2px 5px; | ||
| 88 | } | ||
| 89 | |||
| 90 | pre > code { | ||
| 91 | background: unset; | ||
| 92 | padding: unset; | ||
| 93 | } | ||
| 94 | |||
| 95 | p.modified { | ||
| 96 | font-style: oblique; | ||
| 97 | font-size: 90%; | ||
| 98 | margin-top: 50px; | ||
| 99 | } | ||
| 100 | |||
| 101 | ::selection { | ||
| 102 | background: #ff0; | ||
| 103 | color: #000; | ||
| 104 | } | ||
| 105 | |||
| 106 | ::-moz-selection { | ||
| 107 | background: #ff0; | ||
| 108 | color: #000; | ||
| 109 | } | ||
| 110 | |||
| 111 | .comments { | ||
| 112 | margin-top: 50px; | ||
| 113 | } | ||
| 114 | .comments ul { | ||
| 115 | margin-top: 30px; | ||
| 116 | padding-left: 15px; | ||
| 117 | } | ||
| 118 | .comments ul li { | ||
| 119 | margin-bottom: 20px; | ||
| 120 | } | ||
| 121 | .comments input, | ||
| 122 | .comments textarea { | ||
| 123 | width: 100%; | ||
| 124 | padding: 10px; | ||
| 125 | margin-bottom: 10px; | ||
| 126 | font-family: inherit; | ||
| 127 | font-size: inherit; | ||
| 128 | border: 1px solid lightgray; | ||
| 129 | } | ||
| 130 | .comments textarea { | ||
| 131 | resize: vertical; | ||
| 132 | height: 100px; | ||
| 133 | } | ||
| 134 | |||
| 135 | @media only screen and (max-width:480px) { | ||
| 136 | main { | ||
| 137 | padding: 20px; | ||
| 138 | } | ||
| 139 | |||
| 140 | nav { | ||
| 141 | text-align: center; | ||
| 142 | margin-bottom: initial; | ||
| 143 | } | ||
| 144 | |||
| 145 | nav a { | ||
| 146 | margin-bottom: 10px; | ||
| 147 | } | ||
| 148 | |||
| 149 | ul.article-list { | ||
| 150 | padding-left: 20px; | ||
| 151 | |||
| 152 | } | ||
| 153 | |||
| 154 | ul.article-list li { | ||
| 155 | margin-bottom: 20px; | ||
| 156 | |||
| 157 | } | ||
| 158 | |||
| 159 | ul.article-list li div { | ||
| 160 | display: block; | ||
| 161 | margin-top: 15px; | ||
| 162 | } | ||
| 163 | |||
| 164 | ul.article-list a { | ||
| 165 | display: block; | ||
| 166 | margin-top: 5px; | ||
| 167 | } | ||
| 168 | |||
| 169 | h1 { | ||
| 170 | font-size: 220%; | ||
| 171 | } | ||
| 172 | |||
| 173 | h2 { | ||
| 174 | font-size: 180%; | ||
| 175 | } | ||
| 176 | |||
| 177 | h3 { | ||
| 178 | font-size: 160%; | ||
| 179 | } | ||
| 180 | } | ||
| 181 | |||
| 182 | @media (prefers-color-scheme: light) { | ||
| 183 | body { | ||
| 184 | background-color: white; | ||
| 185 | color: black; | ||
| 186 | } | ||
| 187 | } | ||
| 188 | |||
| 189 | @media (prefers-color-scheme: dark) { | ||
| 190 | body { | ||
| 191 | background-color: rgb(30, 30, 30); | ||
| 192 | color: white; | ||
| 193 | } | ||
| 194 | |||
| 195 | a { | ||
| 196 | color: white; | ||
| 197 | } | ||
| 198 | } | ||
| 199 | |||
| 200 | /* prism theme */ | ||
| 201 | |||
| 202 | /** | ||
| 203 | * GHColors theme by Avi Aryan (http://aviaryan.in) | ||
| 204 | * Inspired by Github syntax coloring | ||
| 205 | */ | ||
| 206 | |||
| 207 | code[class*="language-"], | ||
| 208 | pre[class*="language-"] { | ||
| 209 | color: #393A34; | ||
| 210 | font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace; | ||
| 211 | direction: ltr; | ||
| 212 | text-align: left; | ||
| 213 | white-space: pre; | ||
| 214 | word-spacing: normal; | ||
| 215 | word-break: normal; | ||
| 216 | line-height: 1.2em; | ||
| 217 | |||
| 218 | -moz-tab-size: 4; | ||
| 219 | -o-tab-size: 4; | ||
| 220 | tab-size: 4; | ||
| 221 | |||
| 222 | -webkit-hyphens: none; | ||
| 223 | -moz-hyphens: none; | ||
| 224 | -ms-hyphens: none; | ||
| 225 | hyphens: none; | ||
| 226 | } | ||
| 227 | |||
| 228 | pre > code[class*="language-"] { | ||
| 229 | |||
| 230 | } | ||
| 231 | |||
| 232 | pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, | ||
| 233 | code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { | ||
| 234 | background: #b3d4fc; | ||
| 235 | } | ||
| 236 | |||
| 237 | pre[class*="language-"]::selection, pre[class*="language-"] ::selection, | ||
| 238 | code[class*="language-"]::selection, code[class*="language-"] ::selection { | ||
| 239 | background: #b3d4fc; | ||
| 240 | } | ||
| 241 | |||
| 242 | /* Code blocks */ | ||
| 243 | pre[class*="language-"] { | ||
| 244 | padding: 1em; | ||
| 245 | margin: .5em 0; | ||
| 246 | overflow: auto; | ||
| 247 | border: 1px solid #dddddd; | ||
| 248 | background-color: white; | ||
| 249 | } | ||
| 250 | |||
| 251 | /* Inline code */ | ||
| 252 | :not(pre) > code[class*="language-"] { | ||
| 253 | padding: .2em; | ||
| 254 | padding-top: 1px; padding-bottom: 1px; | ||
| 255 | background: #f8f8f8; | ||
| 256 | border: 1px solid #dddddd; | ||
| 257 | } | ||
| 258 | |||
| 259 | .token.comment, | ||
| 260 | .token.prolog, | ||
| 261 | .token.doctype, | ||
| 262 | .token.cdata { | ||
| 263 | color: #999988; font-style: italic; | ||
| 264 | } | ||
| 265 | |||
| 266 | .token.namespace { | ||
| 267 | opacity: .7; | ||
| 268 | } | ||
| 269 | |||
| 270 | .token.string, | ||
| 271 | .token.attr-value { | ||
| 272 | color: #e3116c; | ||
| 273 | } | ||
| 274 | .token.punctuation, | ||
| 275 | .token.operator { | ||
| 276 | color: #393A34; /* no highlight */ | ||
| 277 | } | ||
| 278 | |||
| 279 | .token.entity, | ||
| 280 | .token.url, | ||
| 281 | .token.symbol, | ||
| 282 | .token.number, | ||
| 283 | .token.boolean, | ||
| 284 | .token.variable, | ||
| 285 | .token.constant, | ||
| 286 | .token.property, | ||
| 287 | .token.regex, | ||
| 288 | .token.inserted { | ||
| 289 | color: #36acaa; | ||
| 290 | } | ||
| 291 | |||
| 292 | .token.atrule, | ||
| 293 | .token.keyword, | ||
| 294 | .token.attr-name, | ||
| 295 | .language-autohotkey .token.selector { | ||
| 296 | color: #00a4db; | ||
| 297 | } | ||
| 298 | |||
| 299 | .token.function, | ||
| 300 | .token.deleted, | ||
| 301 | .language-autohotkey .token.tag { | ||
| 302 | color: #9a050f; | ||
| 303 | } | ||
| 304 | |||
| 305 | .token.tag, | ||
| 306 | .token.selector, | ||
| 307 | .language-autohotkey .token.keyword { | ||
| 308 | color: #00009f; | ||
| 309 | } | ||
| 310 | |||
| 311 | .token.important, | ||
| 312 | .token.function, | ||
| 313 | .token.bold { | ||
| 314 | font-weight: bold; | ||
| 315 | } | ||
| 316 | |||
| 317 | .token.italic { | ||
| 318 | font-style: italic; | ||
| 319 | } | ||
diff --git a/src/static/avatar-512x512.png b/static/avatar-512x512.png index fc34eee..fc34eee 100644 --- a/src/static/avatar-512x512.png +++ b/static/avatar-512x512.png | |||
| Binary files differ | |||
diff --git a/src/static/avatar-64x64.png b/static/avatar-64x64.png index 1406f46..1406f46 100644 --- a/src/static/avatar-64x64.png +++ b/static/avatar-64x64.png | |||
| Binary files differ | |||
diff --git a/static/style.css b/static/style.css new file mode 100644 index 0000000..1254dc9 --- /dev/null +++ b/static/style.css | |||
| @@ -0,0 +1,172 @@ | |||
| 1 | * { | ||
| 2 | box-sizing: border-box; | ||
| 3 | } | ||
| 4 | |||
| 5 | body { | ||
| 6 | line-height: 150%; | ||
| 7 | margin-bottom: 100px; | ||
| 8 | font-family: serif; | ||
| 9 | } | ||
| 10 | |||
| 11 | main { | ||
| 12 | max-width: 760px; | ||
| 13 | padding: 20px 30px; | ||
| 14 | } | ||
| 15 | |||
| 16 | nav { | ||
| 17 | margin-bottom: 50px; | ||
| 18 | } | ||
| 19 | |||
| 20 | nav a { | ||
| 21 | display: inline-block; | ||
| 22 | margin-right: 20px; | ||
| 23 | } | ||
| 24 | |||
| 25 | h1 { | ||
| 26 | font-size: 280%; | ||
| 27 | line-height: initial; | ||
| 28 | } | ||
| 29 | |||
| 30 | h2 { | ||
| 31 | font-size: 200%; | ||
| 32 | line-height: initial; | ||
| 33 | } | ||
| 34 | |||
| 35 | h3 { | ||
| 36 | font-size: 160%; | ||
| 37 | line-height: initial; | ||
| 38 | } | ||
| 39 | |||
| 40 | img { | ||
| 41 | max-width: 100%; | ||
| 42 | margin: 30px auto; | ||
| 43 | display: block; | ||
| 44 | } | ||
| 45 | |||
| 46 | ul.article-list li { | ||
| 47 | margin-bottom: 10px; | ||
| 48 | } | ||
| 49 | |||
| 50 | ul.article-list li div { | ||
| 51 | display: flex; | ||
| 52 | } | ||
| 53 | |||
| 54 | ul.article-list time { | ||
| 55 | display: inline-block; | ||
| 56 | min-width: 160px; | ||
| 57 | } | ||
| 58 | |||
| 59 | article .info { | ||
| 60 | font-style: oblique; | ||
| 61 | } | ||
| 62 | |||
| 63 | pre { | ||
| 64 | overflow: auto; | ||
| 65 | } | ||
| 66 | |||
| 67 | table { | ||
| 68 | width: 100%; | ||
| 69 | } | ||
| 70 | |||
| 71 | table, th, td { | ||
| 72 | border: 1px solid black; | ||
| 73 | text-align: left; | ||
| 74 | } | ||
| 75 | |||
| 76 | th, td { | ||
| 77 | padding: 5px 10px; | ||
| 78 | } | ||
| 79 | |||
| 80 | code, pre { | ||
| 81 | font-size: 13px; | ||
| 82 | } | ||
| 83 | |||
| 84 | code { | ||
| 85 | background: rgb(255, 241, 177); | ||
| 86 | padding: 2px 5px; | ||
| 87 | } | ||
| 88 | |||
| 89 | pre > code { | ||
| 90 | background: unset; | ||
| 91 | padding: unset; | ||
| 92 | } | ||
| 93 | |||
| 94 | p.modified { | ||
| 95 | font-style: oblique; | ||
| 96 | font-size: 90%; | ||
| 97 | margin-top: 50px; | ||
| 98 | } | ||
| 99 | |||
| 100 | ::selection { | ||
| 101 | background: #ff0; | ||
| 102 | color: #000; | ||
| 103 | } | ||
| 104 | |||
| 105 | ::-moz-selection { | ||
| 106 | background: #ff0; | ||
| 107 | color: #000; | ||
| 108 | } | ||
| 109 | |||
| 110 | @media only screen and (max-width:480px) { | ||
| 111 | main { | ||
| 112 | padding: 20px; | ||
| 113 | } | ||
| 114 | |||
| 115 | nav { | ||
| 116 | text-align: center; | ||
| 117 | margin-bottom: initial; | ||
| 118 | } | ||
| 119 | |||
| 120 | nav a { | ||
| 121 | margin-bottom: 10px; | ||
| 122 | } | ||
| 123 | |||
| 124 | ul { | ||
| 125 | padding-left: 20px; | ||
| 126 | } | ||
| 127 | |||
| 128 | ul.article-list li { | ||
| 129 | margin-bottom: 20px; | ||
| 130 | |||
| 131 | } | ||
| 132 | |||
| 133 | ul.article-list li div { | ||
| 134 | display: block; | ||
| 135 | margin-top: 15px; | ||
| 136 | } | ||
| 137 | |||
| 138 | ul.article-list a { | ||
| 139 | display: block; | ||
| 140 | margin-top: 5px; | ||
| 141 | } | ||
| 142 | |||
| 143 | h1 { | ||
| 144 | font-size: 220%; | ||
| 145 | } | ||
| 146 | |||
| 147 | h2 { | ||
| 148 | font-size: 180%; | ||
| 149 | } | ||
| 150 | |||
| 151 | h3 { | ||
| 152 | font-size: 160%; | ||
| 153 | } | ||
| 154 | } | ||
| 155 | |||
| 156 | @media (prefers-color-scheme: light) { | ||
| 157 | body { | ||
| 158 | background-color: white; | ||
| 159 | color: black; | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 163 | @media (prefers-color-scheme: dark) { | ||
| 164 | body { | ||
| 165 | background-color: rgb(30, 30, 30); | ||
| 166 | color: white; | ||
| 167 | } | ||
| 168 | |||
| 169 | a { | ||
| 170 | color: white; | ||
| 171 | } | ||
| 172 | } | ||
diff --git a/staticgen.yml b/staticgen.yml new file mode 100644 index 0000000..447daa2 --- /dev/null +++ b/staticgen.yml | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | # folders | ||
| 2 | content: content/ | ||
| 3 | public: public/ | ||
| 4 | templates: templates/ | ||
| 5 | static: static/ | ||
| 6 | assets: assets/ | ||
| 7 | |||
| 8 | # global settings | ||
| 9 | title: Mitja Felicijan | ||
| 10 | description: Fan of science fiction and dabbler in code | ||
| 11 | author: Mitja Felicijan | ||
| 12 | email: mitja.felicijan@gmail.com | ||
| 13 | domain: https://mitjafelicijan.com | ||
| 14 | twitter: @mitjafelicijan | ||
| 15 | |||
| 16 | # use name of css file without .css extension | ||
| 17 | # https://github.com/highlightjs/highlight.js/tree/master/src/styles | ||
| 18 | highlightStye: github | ||
| 19 | |||
| 20 | # google analytics | ||
| 21 | ga: UA-12769079-10 | ||
diff --git a/templates/index.twig b/templates/index.twig new file mode 100644 index 0000000..4a0eb00 --- /dev/null +++ b/templates/index.twig | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | <!DOCTYPE html> | ||
| 2 | <html lang="en"> | ||
| 3 | |||
| 4 | <head> | ||
| 5 | |||
| 6 | <meta charset="utf-8"> | ||
| 7 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| 8 | <meta http-equiv="X-UA-Compatible" content="ie=edge"> | ||
| 9 | |||
| 10 | <meta name="theme-color" content="#ffffff"> | ||
| 11 | <meta name="generator" content="https://github.com/mitjafelicijan/staticgen"> | ||
| 12 | |||
| 13 | <link rel="preconnect" href="https://www.google-analytics.com"> | ||
| 14 | |||
| 15 | <title>{{ global.title }}</title> | ||
| 16 | <meta name="author" content="{{ global.author }}"> | ||
| 17 | <meta name="description" content="{{ global.description }}"> | ||
| 18 | |||
| 19 | <meta property="og:title" content="{{ global.title }}"> | ||
| 20 | <meta property="og:description" content="{{ global.description }}"> | ||
| 21 | <meta property="og:url" content="{{ global.domain }}"> | ||
| 22 | |||
| 23 | <meta name="twitter:card" content="summary"> | ||
| 24 | <meta name="twitter:site" content="{{ global.twitter }}"> | ||
| 25 | |||
| 26 | <link rel="alternate" type="application/atom+xml" title="{{ global.author }}'s feed" href="/feed.atom"> | ||
| 27 | <link rel="stylesheet" href="/static/style.css?v={{ "now"|date("YmdHi") }}"> | ||
| 28 | <link rel="icon" type="image/png" href="/static/avatar-64x64.png?v={{ "now"|date("YmdHi") }}"> | ||
| 29 | |||
| 30 | </head> | ||
| 31 | |||
| 32 | <body> | ||
| 33 | |||
| 34 | <main> | ||
| 35 | |||
| 36 | {% include "partials/navigation.twig" %} | ||
| 37 | |||
| 38 | <h2>Notes</h2> | ||
| 39 | |||
| 40 | <ul class="article-list"> | ||
| 41 | {% for item in list %} | ||
| 42 | <li> | ||
| 43 | <time datetime="{{ item.date|date("Y, F j") }}">{{ item.date|date("Y, F j") }}</time> | ||
| 44 | <a href="{{ item.slug }}">{{ item.title }}</a> | ||
| 45 | </li> | ||
| 46 | {% endfor %} | ||
| 47 | </ul> | ||
| 48 | |||
| 49 | </main> | ||
| 50 | |||
| 51 | <!-- google analytics --> | ||
| 52 | {{ global.ga }} | ||
| 53 | |||
| 54 | </body> | ||
| 55 | |||
| 56 | </html> | ||
diff --git a/templates/page.twig b/templates/page.twig new file mode 100644 index 0000000..128e321 --- /dev/null +++ b/templates/page.twig | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | <!DOCTYPE html> | ||
| 2 | <html lang="en"> | ||
| 3 | |||
| 4 | <head> | ||
| 5 | |||
| 6 | <meta charset="utf-8"> | ||
| 7 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| 8 | <meta http-equiv="X-UA-Compatible" content="ie=edge"> | ||
| 9 | |||
| 10 | <meta name="theme-color" content="#ffffff"> | ||
| 11 | <meta name="generator" content="https://github.com/mitjafelicijan/staticgen"> | ||
| 12 | |||
| 13 | <link rel="preconnect" href="https://www.google-analytics.com"> | ||
| 14 | |||
| 15 | <title>{{ options.title }}</title> | ||
| 16 | <meta name="author" content="{{ global.author }}"> | ||
| 17 | <meta name="description" content="{{ options.description }}"> | ||
| 18 | |||
| 19 | <meta property="og:title" content="{{ options.title }}"> | ||
| 20 | <meta property="og:description" content="{{ options.description }}"> | ||
| 21 | <meta property="og:url" content="{{ global.domain }}{{ options.slug }}"> | ||
| 22 | |||
| 23 | <meta name="twitter:card" content="summary"> | ||
| 24 | <meta name="twitter:site" content="{{ global.twitter }}"> | ||
| 25 | |||
| 26 | <link rel="alternate" type="application/atom+xml" title="{{ global.author }}'s feed" href="/feed.atom"> | ||
| 27 | <link rel="stylesheet" href="/static/style.css?v={{ "now"|date("YmdHi") }}"> | ||
| 28 | <link rel="icon" type="image/png" href="/static/avatar-64x64.png?v={{ "now"|date("YmdHi") }}"> | ||
| 29 | |||
| 30 | </head> | ||
| 31 | |||
| 32 | <body> | ||
| 33 | |||
| 34 | <main> | ||
| 35 | |||
| 36 | {% include "partials/navigation.twig" %} | ||
| 37 | |||
| 38 | <article> | ||
| 39 | <header> | ||
| 40 | <h1>{{ options.title }}</h1> | ||
| 41 | </header> | ||
| 42 | {{ content }} | ||
| 43 | </article> | ||
| 44 | |||
| 45 | </main> | ||
| 46 | |||
| 47 | <!-- google analytics --> | ||
| 48 | {{ global.ga }} | ||
| 49 | |||
| 50 | </body> | ||
| 51 | |||
| 52 | </html> | ||
diff --git a/templates/partials/navigation.twig b/templates/partials/navigation.twig new file mode 100644 index 0000000..cff6152 --- /dev/null +++ b/templates/partials/navigation.twig | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | <nav> | ||
| 2 | <a href="/">Mitja Felicijan</a> | ||
| 3 | <a href="/curriculum-vitae.html">CV</a> | ||
| 4 | <a href="https://twitter.com/mitjafelicijan" target="_blank" rel="noopener nofollow">Twitter</a> | ||
| 5 | <a href="https://github.com/mitjafelicijan" target="_blank" rel="noopener nofollow">Github</a> | ||
| 6 | </nav> | ||
diff --git a/templates/post.twig b/templates/post.twig new file mode 100644 index 0000000..bd9fdaa --- /dev/null +++ b/templates/post.twig | |||
| @@ -0,0 +1,59 @@ | |||
| 1 | <!DOCTYPE html> | ||
| 2 | <html lang="en"> | ||
| 3 | |||
| 4 | <head> | ||
| 5 | |||
| 6 | <meta charset="utf-8"> | ||
| 7 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| 8 | <meta http-equiv="X-UA-Compatible" content="ie=edge"> | ||
| 9 | |||
| 10 | <meta name="theme-color" content="#ffffff"> | ||
| 11 | <meta name="generator" content="https://github.com/mitjafelicijan/staticgen"> | ||
| 12 | |||
| 13 | <link rel="preconnect" href="https://www.google-analytics.com"> | ||
| 14 | |||
| 15 | <title>{{ options.title }}</title> | ||
| 16 | <meta name="author" content="{{ global.author }}"> | ||
| 17 | <meta name="description" content="{{ options.description }}"> | ||
| 18 | |||
| 19 | <meta property="og:title" content="{{ options.title }}"> | ||
| 20 | <meta property="og:description" content="{{ options.description }}"> | ||
| 21 | <meta property="og:url" content="{{ global.domain }}{{ options.slug }}"> | ||
| 22 | |||
| 23 | <meta name="twitter:card" content="summary"> | ||
| 24 | <meta name="twitter:site" content="{{ global.twitter }}"> | ||
| 25 | |||
| 26 | <link rel="alternate" type="application/atom+xml" title="{{ global.author }}'s feed" href="/feed.atom"> | ||
| 27 | <link rel="stylesheet" href="/static/style.css?v={{ "now"|date("YmdHi") }}"> | ||
| 28 | <link rel="icon" type="image/png" href="/static/avatar-64x64.png?v={{ "now"|date("YmdHi") }}"> | ||
| 29 | |||
| 30 | </head> | ||
| 31 | |||
| 32 | <body> | ||
| 33 | |||
| 34 | <main> | ||
| 35 | |||
| 36 | {% include "partials/navigation.twig" %} | ||
| 37 | |||
| 38 | <article> | ||
| 39 | <header> | ||
| 40 | <h1>{{ options.title }}</h1> | ||
| 41 | <div class="info"> | ||
| 42 | <time datetime="{{ item.date|date("Y, F j") }}">{{ item.date|date("Y, F j") }}</time> | ||
| 43 | <span>by {{ global.author }}</span> | ||
| 44 | </div> | ||
| 45 | </header> | ||
| 46 | {{ content }} | ||
| 47 | </article> | ||
| 48 | |||
| 49 | </main> | ||
| 50 | |||
| 51 | <!-- code highlighting --> | ||
| 52 | {{ global.highlight }} | ||
| 53 | |||
| 54 | <!-- google analytics --> | ||
| 55 | {{ global.ga }} | ||
| 56 | |||
| 57 | </body> | ||
| 58 | |||
| 59 | </html> | ||
