This commit is contained in:
Yann Esposito (Yogsototh) 2019-07-28 18:44:25 +02:00
parent b1ca6cb4ba
commit 5a96e41469
Signed by untrusted user who does not match committer: yogsototh
GPG Key ID: 7B19A4C650D59646
12 changed files with 4147 additions and 187 deletions

Binary file not shown.

View File

@ -2,6 +2,12 @@
#+AUTHOR: Yann Esposito
#+EMAIL: yann.esposito@gmail.com
* Articles
:PROPERTIES:
:ID: A238A3BD-18B5-42D8-8FB3-E522DB3795CC
:PUBDATE: <2019-07-28 Sun 15:11>
:END:
#+begin_archive
@@html:<li>@@ @@html:<span class="archive-item"><span class="archive-date">@@ 2019-07-28: @@html:</span>@@ [[file:posts/autoload-emacs-script-by-project.org][Autoload Script by project]] @@html:</span>@@ @@html:</li>@@
@@html:<li>@@ @@html:<span class="archive-item"><span class="archive-date">@@ 2019-07-07: @@html:</span>@@ [[file:posts/2019-07-04-static-org-publish.org][Static blog with org-mode]] @@html:</span>@@ @@html:</li>@@
#+end_archive

View File

@ -27,42 +27,14 @@ body {
-moz-hyphens:auto;
-ms-hyphens:auto;
}
#preamble {
border-bottom: solid 1px;
}
#preamble h1 {
margin-bottom: 0;
}
#postamble {
border-top: solid 1px;
}
#preamble,#postamble {
padding: 10px 0;
}
.menu {
opacity: 0.5;
}
.menu:hover, .menu:focus {
opacity:1;
}
#content,.content {
max-width: 50em;
margin: 0 auto;
padding: 10px;
}
#content *:first-child {
margin-top: 0;
}
h1, h2, h3, h4, h5, h6, pre, code, blockquote, ol, ul, ol ol, ul ul, ul ol, ol
ul, li, p, section, header, footer {
float: none;
margin: 0;
padding: 0;
}
h1, h2, h3, h4, h5, h6, pre, code, blockquote, p, ul, ol, section, header,
.figure {
figure {
margin-top: 20px;
margin-bottom: 20px;
}
@ -152,7 +124,6 @@ blockquote:after {
position: absolute;
top: 0;
left: 0;
opacity: 0.3;
}
li {
position: relative;
@ -176,8 +147,6 @@ ol > li:before {
opacity: 0.5;
}
/* colors */
img {
max-width: 100%;
max-height: 800px;
@ -188,13 +157,6 @@ p > img, li > img {
margin: 0;
vertical-align: middle;
}
footer {
font-size: 0.8em;
}
.article-date {
opacity: 0.5;
font-size: 0.8;
}
table {
width: 100%;
margin: 20px 0;
@ -219,15 +181,32 @@ navigation {
navigation > a {
margin-right: 10px;
}
.footpara { display: inline; }
.footdef > sup {
vertical-align: middle;
}
.footdef > sup::after {
content: ": ";
}
/* org mode statuses */
/* org mode ids and classes */
.figure {
margin-top: 20px;
margin-bottom: 20px;
}
#preamble {
border-bottom: solid 1px;
}
#preamble h1, #preamble h2 {
margin: 0;
}
#postamble {
border-top: solid 1px;
}
#preamble,#postamble {
padding: 10px 0;
}
#content,.content {
max-width: 50em;
margin: 0 auto;
padding: 10px;
}
#content *:first-child {
margin-top: 0;
}
.timestamp-wrapper {
font-size: 12px;
}
@ -236,6 +215,21 @@ navigation > a {
font-weight: bold;
padding: 1px 1ex;
}
.article-date {
font-size: 0.8;
font-style: italic;
float: right;
}
.footpara {
display: inline;
}
.footdef > sup {
vertical-align: middle;
}
.footdef > sup::after {
content: ": ";
}
/* colors theme */
:root {
@ -258,7 +252,8 @@ navigation > a {
--green: #859900;
--transparent: rgba(255,255,255,0);
--main-background: #00151b; /* 0.5 darker than #002b36; */
/* --main-background: #00151b; /* 0.5 darker than #002b36; */
--main-background: var(--base03); /* 0.5 darker than #002b36; */
--main-foreground: var(--base1);
--second-foreground: var(--base0);
--soft-foreground: var(--base01);
@ -279,7 +274,6 @@ navigation > a {
--todo-txt: #FFF;
}
}
body {
background: var(--main-background);
color: var(--main-foreground);
@ -301,6 +295,12 @@ pre::after,pre::before,hr:after {
a:hover, a:active, a:focus {
color: var(--yellow);
}
navigation a, navigation a:visited {
color: var(--soft-foreground);
}
navigation a:focus, navigation a:hover {
color: var(--yellow);
}
thead {
background-color: var(--reveal-background);
color: var(--second-fg);
@ -308,24 +308,20 @@ thead {
tr:hover {
background-color: var(--reveal-background);
}
#postamble:hover, #preamble:hover {
background-color: var(--reveal-background);
border-color: var(--border-color);
}
h1 {
color: var(--violet);
}
h2 {
color: var(--magenta);
}
h2 {
color: var(--violet);
}
h3 {
color: var(--red);
color: var(--blue);
}
h4 {
color: var(--orange);
color: var(--cyan);
}
h5 {
color: var(--yellow);
color: var(--green);
}
h6 {
color: var(--green);
@ -336,9 +332,15 @@ table, td, th {
code {
background: var(--reveal-background);
}
blockquote:after {
color: var(--soft-foreground);
}
#preamble,#postamble {
border-color: var(--transparent);
}
.article-date {
color: var(--soft-foreground);
}
/* -------- */
/* org colors */
.todo, .done {

BIN
src/assets/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -36,6 +36,9 @@ There should be a forced newline.
It lets you and others work together on projects from anywhere.
*** Level 3
:PROPERTIES:
:CUSTOM_ID: level-3
:END:
#+begin_quote
This is a blockquote following a header.
@ -45,6 +48,9 @@ There should be a forced newline.
#+end_quote
**** Level 4
:PROPERTIES:
:CUSTOM_ID: level-4
:END:
#+begin_src javascript
// Javascript code with syntax highlighting.
@ -78,6 +84,9 @@ There should be a forced newline.
#+end_src
***** Level 5
:PROPERTIES:
:CUSTOM_ID: level-5
:END:
- this is an unordered list following a header.
- this is an unordered list following a header.
@ -121,6 +130,9 @@ Bad too wide table...
------
*** Here is an unordered list:
:PROPERTIES:
:CUSTOM_ID: here-is-an-unordered-list-
:END:
- level 1 item
- level 2 item
@ -140,27 +152,39 @@ Bad too wide table...
- level 2 item
**** Image test
:PROPERTIES:
:CUSTOM_ID: image-test
:END:
an image:
#+CAPTION: Testing include an image
#+NAME: fig:test-image
#+ATTR_HTML: The Experiment
[[../assets/img/a.png]]
[[../img/a.png]]
We could try inline image
[[../assets/img/a.png]]
[[../img/a.png]]
just to check.
- [[../assets/img/a.png]] item with img
- [[../assets/img/a.png]] item with img
- [[../assets/img/a.png]] item with img
- [[../assets/img/a.png]] item with img
- [[../img/a.png]] item with img
- [[../img/a.png]] item with img
- [[../img/a.png]] item with img
- [[../img/a.png]] item with img
***** TODO todo
:PROPERTIES:
:CUSTOM_ID: todo
:END:
****** IN-PROGRESS in-progress
:PROPERTIES:
:CUSTOM_ID: in-progress
:END:
******* IN-REVIEW in-review
:PROPERTIES:
:CUSTOM_ID: in-review
:END:
****** HOLD on hold state
- State "HOLD" from "IN-REVIEW" [2019-07-09 Tue 13:44] \\
some reason

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,39 @@
#+TITLE: Detoxify the Web
#+SUBTITLE: Take back control of what we are exposed to on the web
#+AUTHOR: Yann Esposito
We are currently in an age were where you take your eyeball is a valuable resource.
As such there are professional, and a lot of smart ones, whose only job is to ensure
you pass more time looking at what there is best in their interrest, not yours.
There are a lot of techniques to grab your attention and not letting it go somewhere else.
- animation
- colors
- gaming the relationship
- entertaining
All of them are in fact not really problematic. But now, this is too much.
So in order to feel calm again we need to have better control of what we see, are exposed to.
If you take a look into the gopher sphere, you discover a lot text-oriented world.
Of course there are pictures, but not in the middle of the article.
So mostly text. No gif, no animation, no music, no video, just textual content.
We passed from a world where there was too much textual content, to a world filled
with meaningless animations, colors, pictures, effects, popups, etc...
*Detoxify the web*
Here is my solution:
- remove all the styles of all the websites so a lot of website cannot be used anymore that way.
- replace by a default focus oriented style.
My only solution is to start a proxy between me and the web, I take the content and do a lot of cleanup.
I remove all the CSS (faster), I use my own (nicer and contolled)
Simple and efficient.
This transformation should be done by the client.

View File

@ -0,0 +1,13 @@
#+TITLE: The sad state of text browsing
#+AUTHOR: Yann Esposito
1. sad state, show HN, Reddit, worse, news websites, etc...
2. bad for disabled people
3. why not change the concept and make the provider of content not also provide the Look & Feel
User controlled display of content. Less money, more quality, is it possible
- no js
- text only
- interaction? controlled one
- user facing code, yes, only signature, all the rest looks like bullshit to me
4. not web 3.0, more like, fuck it, we need a BRUTALIST, Hacker-only oriented
web. A safe place to talk between civilised people. What are the possible solutions

View File

@ -8,21 +8,8 @@
#+OPTIONS: H:5
#+STARTUP: showeverything
This is a new take on my personal blog.
I tried to have some minimalism in mind but not too much.
Welcome to my personal blog.
This is the 4th time I change the underlying technology behind my blog.
True minimalism would have been to only serve text files.
But I would prefer to have at least links working. Also
syntax highlighting of source code is nice.
But I dislike the new trend of design space and white colors.
It doesn't really fit the spirit of my website.
So it looks a bit more like a text into a colored terminal.
The CSS support dark/light theme.
If unknown, the default color scheme is dark in the hope to save a bit of energy
from screen.
You can have a basic demo about most supported content styles/type (paragraphs,
lists, tables, etc...) [[file:./demo.org][here]].
I write all the content with [[http://orgmode.org][org-mode]].
- [[./archive.html][posts]]
- [[./about][about me]]

View File

@ -1,15 +1,15 @@
#+TITLE: Static blog with org-mode
#+AUTHOR: Yann Esposito
#+EMAIL: yann.esposito@gmail.com
#+DATE: 2019-07-04
#+DATE: 2019-07-27
#+KEYWORDS: programming, blog, org-mode
#+OPTIONS: auto-id:t
#+begin_quote
/tl;dr/: [[#current-solution-0a92][Full code for the impatient↓]]. Read the full blog post to have all the details.
/tl;dr/: [[#current-solution][Full code for the impatient↓]].
Read the full blog post to have all the details.
#+end_quote
This is the first article using my new blog system.
Once in a while, I create a new personal website.
@ -63,6 +63,11 @@ You can add a task quite easily while doing other work in emacs.
:CUSTOM_ID: how--831e
:END:
You can easily follow the org-mode doc to make your own website.
But I have added a few "goodies".
- attempt to obfuscate contact email,
** Basic Blog
:PROPERTIES:
:CUSTOM_ID: basic-blog-a1fc
@ -70,8 +75,7 @@ You can add a task quite easily while doing other work in emacs.
I put the need minimal code in a =.project.el.gpg= file of my blog repository.
Inspired by this [[https://francismurillo.github.io/2017-02-15-Project-Script-Loader/][blog post]] I enhanced this version to be both more user friendly
and secure (see [[#digression]]).
and secure (see [[./autoload-emacs-script-by-project.org][Autoload Emacs Script by Project]]).
But even before that, I simply put the code in has an elisp code block of my
=index.org= that I exectued with =C-c C-c=.
@ -188,7 +192,7 @@ That's better. But for a blog you also generally want to have your own CSS.
* Current Solution
:PROPERTIES:
:CUSTOM_ID: current-solution-0a92
:CUSTOM_ID: current-solution
:END:
#+begin_src elisp
@ -201,7 +205,8 @@ That's better. But for a blog you also generally want to have your own CSS.
(setq rss-dir base-dir)
(setq publish-rss-dir publish-dir)
(setq css-name "minimalist.css")
(setq author-name "Yann Esposito")
(setq author-email "yann.esposito@gmail.com")
(require 'org)
(require 'ox-publish)
@ -211,8 +216,8 @@ That's better. But for a blog you also generally want to have your own CSS.
(defun org-blog-prepare (project-plist)
"With help from `https://github.com/howardabrams/dot-files'.
Touch `index.org' to rebuilt it.
Argument `PROJECT-PLIST' contains information about the current project."
Touch `index.org' to rebuilt it.
Argument `PROJECT-PLIST' contains information about the current project."
(let* ((base-directory (plist-get project-plist :base-directory))
(buffer (find-file-noselect (expand-file-name "index.org" base-directory) t)))
(with-current-buffer buffer
@ -224,7 +229,7 @@ That's better. But for a blog you also generally want to have your own CSS.
"<link rel=\"stylesheet\" type=\"text/css\" href=\"/assets/css/" css-name "\"/>"
"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">"
"<link rel=\"alternative\" type=\"application/rss+xml\" title=\"Subscribe to articles\" href=\"/archives.xml\" />"
"<link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/favicon.ico\">"))
"<link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/assets/img/favicon.ico\">"))
(defun menu (lst)
"Blog menu"
@ -320,8 +325,8 @@ That's better. But for a blog you also generally want to have your own CSS.
(defun org-blog-sitemap-function (title list)
"Return sitemap using TITLE and LIST returned by `org-blog-sitemap-format-entry'."
(concat "#+TITLE: " title "\n"
"#+AUTHOR: Yann Esposito\n"
"#+EMAIL: yann.esposito@gmail.com\n"
"#+AUTHOR: " author-name "\n"
"#+EMAIL: " author-email "\n"
"\n#+begin_archive\n"
(mapconcat (lambda (li)
(format "@@html:<li>@@ %s @@html:</li>@@" (car li)))
@ -399,96 +404,3 @@ That's better. But for a blog you also generally want to have your own CSS.
'my-org-export-add-target-blank-to-http-links)
#+end_src
* Digression
:PROPERTIES:
:CUSTOM_ID: digression
:END:
Auto loading a =.el= file when entering in a project.
It should be easy and safe.
The best solution I found.
Save your =.el= file as a =.el.gpg= file.
With =epa= emacs should encrypt the file for you using your own private key.
Great! Now we simply verify the file exists and load it only if it is encrypted
with one of you /trusted keys/.
The list of key fingerprint you trust is a configuration.
When opening a new file via projectile or dired
1. check the =.project.el.gpg= file is not already loaded for the current project
2. check the =.project.el.gpg= file exists
3. check the =.project.el.gpg= file is encrypted with a trusted key
4. decrypt and load =.project.el.gpg=
That's it.
You simply need to set the =y/trusted-gpg-key-fingerprints= variable with the
list of your own fingerprint.
You can get a list of them with =gpg --list-secret-keys=.
Now you can be happy, this is really safe, in the sense that if you clone a new
project from the internet with a =.project.el.gpg= file in it.
That file won't be run on your system.
Of course if you want to share that =.el= to other people, you need to adapt.
But for my use case, this is perfect.
Another use case would be to check the signature and trust people.
#+begin_src elisp
(defvar y/trusted-gpg-key-fingerprints
'("448E9FEF4F5B86DE79C1669B7B19A4C650D59646")
"The list of GPG fingerprint you trust when decrypting a gpg file.
You can retrieve the fingerprints of your own private keys with:
`gpg --list-secret-keys' (take care of removing the spaces when copy/pasting here)")
(defun y/get-encryption-key (file)
"given a gpg encrypted file, returns the fingerprint of they
key that encrypted it"
(string-trim-right
(shell-command-to-string
(concat
"gpg --status-fd 1 --decrypt -o /dev/null " file " 2>/dev/null"
"|grep DECRYPTION_KEY"
"|awk '{print $4}'"))))
(defun y/trusted-gpg-origin-p (file)
"Returns true if the file is encrypted with a trusted key"
(member (y/get-encryption-key file) y/trusted-gpg-key-fingerprints))
(defun y/project-el-auto-load ()
(with-eval-after-load 'projectile
(defconst y/project-file ".project.el.gpg"
"Filename looked after to be loaded and evaluated.")
(defvar y/loaded-projects (list)
"Projects that have been loaded by `y/load-project-file'.")
(defun y/load-project-file ()
"Loads the `y/project-file' for a project. This is run
once after the project is loaded signifying project setup."
(interactive)
(when (projectile-project-p)
(lexical-let* ((project-root (projectile-project-root))
(project-init-file (expand-file-name y/project-file project-root)))
(when (and (not (member project-root y/loaded-projects)) ;; project file not already loaded
(file-exists-p project-init-file) ;; project file exists
(y/trusted-gpg-origin-p project-init-file)) ;; project file is tursted
(message "Loading project init file for %s" (projectile-project-name))
(condition-case ex
(progn (load project-init-file)
(add-to-list 'y/loaded-projects project-root)
(message "%s loaded successfully" project-init-file))
('error
(message
"There was an error loading %s: %s"
project-init-file
(error-message-string ex))))))))
;; for some obscure reason there is not really a working hook
;; to be used with projectile to launch the `y/load-project-file'
;; only when switching to a new project.
;; Thus the `y/loaded-projects' state.
(add-hook 'find-file-hook #'y/load-project-file t)
(add-hook 'dired-mode-hook #'y/load-project-file t)))
#+end_src

View File

@ -0,0 +1,72 @@
;;; auto-load-project.el --- Auto load elisp file on project open
;; Copyright © 2019 Yann Esposito <yann.esposito@gmail.com>
;;; Commentary:
;;
;;; Code:
(provide :auto-load-project)
(require 'projectile)
(defvar y/trusted-gpg-key-fingerprints
'("448E9FEF4F5B86DE79C1669B0000000000000000")
"The list of GPG fingerprint you trust when decrypting a gpg file.
You can retrieve the fingerprints of your own private keys
with: `gpg --list-secret-keys' (take care of removing the
spaces when copy/pasting here)")
(defun y/get-encryption-key (file)
"given a gpg encrypted file, returns the fingerprint of
they key that encrypted it"
(string-trim-right
(shell-command-to-string
(concat
"gpg --status-fd 1 --decrypt -o /dev/null " file " 2>/dev/null"
"|grep DECRYPTION_KEY"
"|awk '{print $4}'"))))
(defun y/trusted-gpg-origin-p (file)
"Returns true if the file is encrypted with a trusted key"
(member (y/get-encryption-key file) y/trusted-gpg-key-fingerprints))
(defconst y/project-file ".project.el.gpg"
"Project configuration file name.")
(defun y/init-project-el-auto-load ()
"Initialize the autoload of .project.el.gpg for projects."
(with-eval-after-load 'projectile
(defvar y/loaded-projects (list)
"Projects that have been loaded by `y/load-project-file'.")
(defun y/load-project-file ()
"Loads the `y/project-file' for a project. This is run once
after the project is loaded signifying project setup."
(interactive)
(when (projectile-project-p)
(lexical-let* ((current-project-root (projectile-project-root))
(project-init-file (expand-file-name y/project-file current-project-root)))
(when (and (not (member current-project-root y/loaded-projects))
(file-exists-p project-init-file)
(y/trusted-gpg-origin-p project-init-file))
(message "Loading project init file for %s" (projectile-project-name))
(condition-case ex
(progn (load project-init-file)
(add-to-list 'y/loaded-projects current-project-root)
(message "%s loaded successfully" project-init-file))
('error
(message
"There was an error loading %s: %s"
project-init-file
(error-message-string ex))))))))
(add-hook 'find-file-hook #'y/load-project-file t)
(add-hook 'dired-mode-hook #'y/load-project-file t)))
(provide 'auto-load-project)
;;; auto-load-project.el ends here

View File

@ -0,0 +1,133 @@
#+TITLE: Autoload Script by project
#+SUBTITLE: fast, secure, easy autoload
#+AUTHOR: Yann Esposito
#+EMAIL: yann.esposito@gmail.com
#+DATE: 2019-07-28
#+KEYWORDS: programming, blog, org-mode
#+OPTIONS: auto-id:t
#+begin_quote
/tl;dr/: A script that use projectile and GPG to securely load
an emacs lisp script when opening a new project.
Check the [[#solution]] section to get the code.
#+end_quote
* Problem
:PROPERTIES:
:CUSTOM_ID: problem
:END:
When providing a repository containing only org files of my blog.
I also wanted to provide everything necessary for users to be able to publish my
website.
Emacs, org-publish mostly assume you should put all those details in a
centralised place in your =~/.emacs.d/.init.el= file.
The main principle is quite simple.
1. When finding a new file in a project, check for the presence of a
=.project.el.gpg= file.
2. Check the file was encrypted with by a trusted fingerprint
3. load the file
I found a solution that asked you each time you enter in a project if you trust
it.
This was both quite annoying and insecure as it is kind of easy to type 'y'
instead of 'n' and to load an untrusted 3rd party script.
With emacs epa, opening encrypted gpg files is seamless.
But here we not only want to open the gpg file but also check we trust the
person that did it.
Note that checking who's encrypted a gpg file is not straightforward:
#+begin_src elisp
(defun y/get-encryption-key (file)
"given a gpg encrypted file, returns the fingerprint of they
key that encrypted it"
(string-trim-right
(shell-command-to-string
(concat
"gpg --status-fd 1 --decrypt -o /dev/null " file " 2>/dev/null"
"|grep DECRYPTION_KEY"
"|awk '{print $4}'"))))
#+end_src
- The `--status-fd` should provide more script friendly output.
GPG provide localized output by default which are therefore hard to use in
script (for grep for example).
- we do not want to decrypt to a file so we redirect the output to =/dev/null=
We use =projectile= to detect the project-root and when we are in a new project.
Unfortunately the =projectile-after-switch-project-hooks= doesn't work as I
expected.
So I use the hooks =find-file-hook= and =dired-mode-hook= to try to load the
file.
In order not to load the code each time, I need to keep a local state of project
already loaded.
* Solution
:PROPERTIES:
:CUSTOM_ID: solution
:END:
#+begin_src elisp
(defun y/init-project-el-auto-load ()
"Initialize the autoload of .project.el.gpg for projects"
(with-eval-after-load 'projectile
(defvar y/trusted-gpg-key-fingerprints
'("448E9FEF4F5B86DE79C1669B0000000000000000")
"The list of GPG fingerprint you trust when decrypting a gpg file.
You can retrieve the fingerprints of your own private keys
with: `gpg --list-secret-keys' (take care of removing the
spaces when copy/pasting here)")
(defun y/get-encryption-key (file)
"given a gpg encrypted file, returns the fingerprint of
they key that encrypted it"
(string-trim-right
(shell-command-to-string
(concat
"gpg --status-fd 1 --decrypt -o /dev/null " file " 2>/dev/null"
"|grep DECRYPTION_KEY"
"|awk '{print $4}'"))))
(defun y/trusted-gpg-origin-p (file)
"Returns true if the file is encrypted with a trusted key"
(member (y/get-encryption-key file) y/trusted-gpg-key-fingerprints))
(defconst y/project-file ".project.el.gpg"
"Project configuration file name.")
(defvar y/loaded-projects (list)
"Projects that have been loaded by `y/load-project-file'.")
(defun y/load-project-file ()
"Loads the `y/project-file' for a project. This is run once
after the project is loaded signifying project setup."
(interactive)
(when (projectile-project-p)
(lexical-let* ((current-project-root (projectile-project-root))
(project-init-file (expand-file-name y/project-file current-project-root)))
(when (and (not (member current-project-root y/loaded-projects))
(file-exists-p project-init-file)
(y/trusted-gpg-origin-p project-init-file))
(message "Loading project init file for %s" (projectile-project-name))
(condition-case ex
(progn (load project-init-file)
(add-to-list 'y/loaded-projects current-project-root)
(message "%s loaded successfully" project-init-file))
('error
(message
"There was an error loading %s: %s"
project-init-file
(error-message-string ex))))))))
(add-hook 'find-file-hook #'y/load-project-file t)
(add-hook 'dired-mode-hook #'y/load-project-file t)))
(y/init-project-el-auto-load)
#+end_src