Update the publish script and config

This commit is contained in:
TEC 2024-01-11 14:23:32 +08:00
parent 93f4a16661
commit b67cc0a39c
Signed by: tec
SSH Key Fingerprint: SHA256:eobz41Mnm0/iYWBvWThftS0ElEs1ftBr6jamutnXc/A
7 changed files with 469 additions and 221 deletions

View File

@ -1,4 +0,0 @@
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* 404.html [L]

View File

@ -5,7 +5,7 @@
</a>
To the extent possible under law,
<a rel="dct:publisher"
href="https://blog.tecosaur.com/">
href="https://blog.tecosaur.net/">
<span property="dct:title">TEC</span></a>
has waived all copyright and related or neighboring rights to
<span property="dct:title" style="font-style:italic">This Month in Org</span>.

View File

@ -1,6 +1,6 @@
<header>
<h4><a href="https://orgmode.org" class="orgicorn"><img src="org-icon-monochrome.svg" class="invertible"></a>
<a href="https://blog.tecosaur.com/tmio/" class="title">
<a href="https://blog.tecosaur.net/tmio/" class="title">
This Month in Org</a>
<a href="rss.xml" title="RSS Feed" type="application/rss+xml" class="rss">
<img src="rss.svg" alt="RSS icon" />

View File

@ -75,45 +75,87 @@ summary {
display: list-item; }
/*! end normalise.css */
#page {
--accent: #002642;
--accent-dark: #00151c;
--code-foreground: #2c3e50;
--code-background: #efefef;
--code-func: #6c3163;
--code-const: #4e3163;
--code-regex: #655370;
--back-white: #fff;
--back-light: #f0eeed;
--back-medium: #c8c8c8;
--text-light: #7b7b7b;
--text-gray: #444;
--text-medium: #222;
--text-dark: #000;
--switch-icon: "🌚";
--switch-shadow-color: #373d4e;
--switch-text: "dark mode?"; }
@media (prefers-color-scheme: light) {
#page {
--accent: #002642;
--accent-dark: #00151c;
--code-foreground: #2c3e50;
--code-background: #f5f5f5;
--code-func: #6c3163;
--code-const: #4e3163;
--code-regex: #655370;
--back-white: #fff;
--back-light: #f0eeed;
--back-medium: #c8c8c8;
--text-light: #7b7b7b;
--text-gray: #444;
--text-medium: #222;
--text-dark: #000;
--switch-icon: "🌚";
--switch-shadow-color: #373d4e;
--switch-text: "dark mode?"; }
#theme-switch:checked ~ #page {
--accent: #002642;
--accent-dark: #daf1ff;
--code-foreground: #a1a8ae;
--code-background: #222;
--code-func: #bd56ad;
--code-const: #8755ab;
--code-regex: #a184b3;
--back-white: #000;
--back-light: #181818;
--back-medium: #444;
--text-light: #7b7b7b;
--text-gray: #c8c8c8;
--text-medium: #ddd;
--text-dark: #efefef;
--switch-icon: "🌝";
--switch-shadow-color: #fce477;
--switch-text: "light mode?"; }
#theme-switch:checked ~ #page img.invertible, #theme-switch:checked ~ #page object[type="image/svg+xml"].invertible, #theme-switch:checked ~ #page img.org-latex {
filter: invert(90.5%) hue-rotate(180deg) sepia(1%); } }
#theme-switch:checked ~ #page {
--accent: #002642;
--accent-dark: #daf1ff;
--code-foreground: #a1a8ae;
--code-background: #222;
--code-func: #bd56ad;
--code-const: #8755ab;
--code-regex: #a184b3;
--back-white: #000;
--back-light: #181818;
--back-medium: #444;
--text-light: #7b7b7b;
--text-gray: #c8c8c8;
--text-medium: #ddd;
--text-dark: #efefef;
--switch-icon: "🌝";
--switch-shadow-color: #fce477;
--switch-text: "light mode?"; }
#theme-switch:checked ~ #page img.invertible, #theme-switch:checked ~ #page object.invertible[type="image/svg+xml"] {
filter: invert(90%) hue-rotate(180deg) sepia(1%); }
@media (prefers-color-scheme: dark) {
#theme-switch:checked ~ #page {
--accent: #002642;
--accent-dark: #00151c;
--code-foreground: #2c3e50;
--code-background: #f5f5f5;
--code-func: #6c3163;
--code-const: #4e3163;
--code-regex: #655370;
--back-white: #fff;
--back-light: #f0eeed;
--back-medium: #c8c8c8;
--text-light: #7b7b7b;
--text-gray: #444;
--text-medium: #222;
--text-dark: #000;
--switch-icon: "🌚";
--switch-shadow-color: #373d4e;
--switch-text: "dark mode?"; }
#theme-switch:checked ~ #page img.invertible, #theme-switch:checked ~ #page object[type="image/svg+xml"].invertible, #theme-switch:checked ~ #page img.org-latex {
filter: invert(7%) sepia(4%); }
#page {
--accent: #002642;
--accent-dark: #daf1ff;
--code-foreground: #a1a8ae;
--code-background: #222;
--code-func: #bd56ad;
--code-const: #8755ab;
--code-regex: #a184b3;
--back-white: #000;
--back-light: #181818;
--back-medium: #444;
--text-light: #7b7b7b;
--text-gray: #c8c8c8;
--text-medium: #ddd;
--text-dark: #efefef;
--switch-icon: "🌝";
--switch-shadow-color: #fce477;
--switch-text: "light mode?"; }
#page img.invertible, #page object[type="image/svg+xml"].invertible, #page img.org-latex {
filter: invert(90.5%) hue-rotate(180deg) sepia(1%); } }
#theme-switch {
display: none; }
@ -356,23 +398,22 @@ aside {
border-radius: 5px;
font-family: "Open Sans", sans;
font-weight: normal;
font-size: 15px;
font-size: 14px;
line-height: 1.6;
color: var(--text-gray);
margin: 20px 0;
padding: 5px 20px 10px;
line-height: 1.6 !important; }
aside p {
font-family: "Open Sans", sans;
font-weight: normal;
font-size: 15px;
line-height: 1.6;
color: var(--text-gray);
line-height: 1.6 !important; }
aside pre {
font-size: 12px;
border: none;
padding-left: 0; }
aside :first-child {
margin-top: 0.5em; }
aside :last-child {
margin-bottom: 0.5em; }
@media (min-width: 1280px) {
aside {
@ -394,7 +435,9 @@ blockquote {
padding-left: 15px; }
blockquote p {
display: inline;
font-size: 13px; }
font-size: 14px; }
blockquote ol, blockquote ul {
margin-left: 1em; }
blockquote footer {
font-family: "Open Sans", sans;
font-weight: normal;
@ -528,6 +571,37 @@ div.error::before {
line-height: 1.1;
text-align: center; }
div.notes {
background: rgba(113, 90, 177, 0.15);
border-left: 4px solid rgba(113, 90, 177, 0.45);
margin: 1.8rem 0 1.25rem 15px;
padding: 0.8em;
line-height: 1.4;
text-align: center;
position: relative;
clear: both; }
div.notes p {
margin: 0; }
div.notes::before {
content: "✎";
color: var(--back-white);
background: rgba(113, 90, 177, 0.8);
align-items: flex-end;
top: -1rem;
font-weight: 700;
font-size: 1.4rem;
-webkit-clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
width: 32px;
height: 32px;
display: inline-flex;
justify-content: center;
position: absolute;
left: -1.2rem;
line-height: 1.3;
text-align: center; }
.org-ref-bib-h1 {
margin-top: 70px;
padding-top: 30px;
@ -606,8 +680,8 @@ pre.src:empty {
code {
font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
color: var(--code-foreground);
font-size: 15px;
padding: 0 5px; }
font-size: 14px;
padding: 0 2px; }
kbd {
display: inline-block;
@ -633,7 +707,7 @@ details.code {
position: relative; }
details.code summary {
position: relative;
left: -3px;
left: -2.5px;
padding-left: 10px;
padding-bottom: 4px;
margin-left: -10px;
@ -1187,7 +1261,8 @@ hr {
margin-top: 40px; }
a {
color: inherit; }
color: inherit;
position: relative; }
figcaption a,
p a,
@ -1195,12 +1270,12 @@ p a,
table a,
li a,
dl a {
background-image: linear-gradient(var(--text-dark), var(--text-dark));
background-size: 1px 1px;
background-repeat: repeat-x;
background-position: 0% 95%;
border-radius: 1px;
text-decoration: none; }
text-decoration-line: underline;
text-decoration-style: dotted;
text-decoration-color: var(--text-light);
text-decoration-thickness: .1em;
text-underline-offset: 1.5px;
border-radius: 1px; }
figcaption a::selection,
p a::selection,
.page-tags a::selection,
@ -1252,31 +1327,35 @@ dl a {
dl a:hover {
opacity: 0.9;
filter: drop-shadow(1px 1px 1px var(--back-white));
background-image: linear-gradient(var(--text-dark), var(--text-dark));
background-size: 1px 1px;
background-repeat: repeat-x;
background-position: 0% 95%;
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg id='squiggle-link' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:ev='http://www.w3.org/2001/xml-events' viewBox='0 0 20 4'%3E%3Cstyle type='text/css'%3E.squiggle{animation:shift .3s linear infinite;}@keyframes shift {from {transform:translateX(0);}to {transform:translateX(-20px);}}%3C/style%3E%3Cpath fill='none' stroke='%23000000' stroke-width='2' class='squiggle' d='M0,3.5 c 5,0,5,-3,10,-3 s 5,3,10,3 c 5,0,5,-3,10,-3 s 5,3,10,3'/%3E%3C/svg%3E") !important;
background-position: 0% 100%;
background-size: 0.8em auto;
text-decoration: none; }
figcaption a:hover::selection,
p a:hover::selection,
.page-tags a:hover::selection,
table a:hover::selection,
li a:hover::selection,
dl a:hover::selection {
background: var(--back-white); }
figcaption a:hover::before,
p a:hover::before,
.page-tags a:hover::before,
table a:hover::before,
li a:hover::before,
dl a:hover::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
mask-image: url("data:image/svg+xml;charset=utf8,%3Csvg id='squiggle-link' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:ev='http://www.w3.org/2001/xml-events' viewBox='0 0 20 4'%3E%3Cstyle type='text/css'%3E.squiggle{animation:shift .3s linear infinite;}@keyframes shift {from {transform:translateX(0);}to {transform:translateX(-20px);}}%3C/style%3E%3Cpath fill='none' stroke='%23000000' stroke-width='2' class='squiggle' d='M0,3.5 c 5,0,5,-3,10,-3 s 5,3,10,3 c 5,0,5,-3,10,-3 s 5,3,10,3'/%3E%3C/svg%3E") !important;
mask-position: 0% 100%;
mask-size: 0.8em auto;
mask-repeat: repeat-x;
background: var(--text-light); }
figcaption a[href^="#"],
p a[href^="#"],
.page-tags a[href^="#"],
table a[href^="#"],
li a[href^="#"],
dl a[href^="#"] {
background-image: linear-gradient(var(--text-gray), var(--text-gray));
background-size: 1px 1px;
background-repeat: repeat-x;
background-position: 0% 95%; }
text-decoration-line: underline;
text-decoration-style: dotted;
text-decoration-color: var(--text-light);
text-decoration-thickness: .1em;
text-underline-offset: 1.5px; }
figcaption a[href^="#"]::selection,
p a[href^="#"]::selection,
.page-tags a[href^="#"]::selection,
@ -1292,10 +1371,11 @@ dl a {
dl a[href^="#"]:hover {
opacity: 0.9;
filter: drop-shadow(1px 1px 1px var(--back-white));
background-image: linear-gradient(var(--text-medium), var(--text-medium));
background-size: 1px 1px;
background-repeat: repeat-x;
background-position: 0% 95%; }
text-decoration-line: underline;
text-decoration-style: dotted;
text-decoration-color: var(--text-light);
text-decoration-thickness: .1em;
text-underline-offset: 1.5px; }
figcaption a[href^="#"]:hover::selection,
p a[href^="#"]:hover::selection,
.page-tags a[href^="#"]:hover::selection,
@ -1312,7 +1392,26 @@ dl a {
#theme-switch:checked ~ #page #crosslinks a:not(.highlight):hover,
#theme-switch:checked ~ #page li a:hover,
#theme-switch:checked ~ #page dl a:hover {
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg id='squiggle-link' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:ev='http://www.w3.org/2001/xml-events' viewBox='0 0 20 4'%3E%3Cstyle type='text/css'%3E.squiggle{animation:shift .3s linear infinite;}@keyframes shift {from {transform:translateX(0);}to {transform:translateX(-20px);}}%3C/style%3E%3Cpath fill='none' stroke='%23ffffff' stroke-width='2' class='squiggle' d='M0,3.5 c 5,0,5,-3,10,-3 s 5,3,10,3 c 5,0,5,-3,10,-3 s 5,3,10,3'/%3E%3C/svg%3E"); }
text-decoration: none; }
#theme-switch:checked ~ #page #breadcrumbs a:hover::before,
#theme-switch:checked ~ #page figcaption a:hover::before,
#theme-switch:checked ~ #page p a:hover::before,
#theme-switch:checked ~ #page .page-tags a:hover::before,
#theme-switch:checked ~ #page table a:hover::before,
#theme-switch:checked ~ #page #crosslinks a:not(.highlight):hover::before,
#theme-switch:checked ~ #page li a:hover::before,
#theme-switch:checked ~ #page dl a:hover::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
mask-image: url("data:image/svg+xml;charset=utf8,%3Csvg id='squiggle-link' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:ev='http://www.w3.org/2001/xml-events' viewBox='0 0 20 4'%3E%3Cstyle type='text/css'%3E.squiggle{animation:shift .3s linear infinite;}@keyframes shift {from {transform:translateX(0);}to {transform:translateX(-20px);}}%3C/style%3E%3Cpath fill='none' stroke='%23000000' stroke-width='2' class='squiggle' d='M0,3.5 c 5,0,5,-3,10,-3 s 5,3,10,3 c 5,0,5,-3,10,-3 s 5,3,10,3'/%3E%3C/svg%3E") !important;
mask-position: 0% 100%;
mask-size: 0.8em auto;
mask-repeat: repeat-x;
background: var(--text-light); }
*:target::before {
content: "🠖";
@ -1330,12 +1429,12 @@ dl a {
right: 0; } }
#content .page-intro p a,
#footnotes a {
background-image: linear-gradient(var(--text-gray), var(--text-gray));
background-size: 1px 1px;
background-repeat: repeat-x;
background-position: 0% 95%;
border-radius: 1px;
text-decoration: none; }
text-decoration-line: underline;
text-decoration-style: dotted;
text-decoration-color: var(--text-light);
text-decoration-thickness: .1em;
text-underline-offset: 1.5px;
border-radius: 1px; }
#content .page-intro p a::selection,
#footnotes a::selection {
background: var(--back-medium); }
@ -1353,12 +1452,12 @@ dl a {
color: var(--text-gray); }
#content .page-intro p a:hover,
#footnotes a:hover {
background-image: linear-gradient(var(--text-gray), var(--text-gray));
background-size: 1px 1px;
background-repeat: repeat-x;
background-position: 0% 95%;
border-radius: 1px;
text-decoration: none; }
text-decoration-line: underline;
text-decoration-style: dotted;
text-decoration-color: var(--text-light);
text-decoration-thickness: .1em;
text-underline-offset: 1.5px;
border-radius: 1px; }
#content .page-intro p a:hover::selection,
#footnotes a:hover::selection {
background: var(--back-medium); }
@ -1444,6 +1543,7 @@ div.link-preview {
max-height: 5em;
padding-left: 0.5em; }
div.link-preview a {
color: inherit;
text-decoration: none; }
div.link-preview img {
border-right: 1px solid var(--back-medium);
@ -1452,7 +1552,7 @@ div.link-preview {
margin-left: -0.5em;
margin-right: 0.5em; }
div.link-preview p {
margin: 0;
margin: 0 0.6em 0 0;
font-size: 10pt; }
div.link-preview p b {
font-size: 11pt; }
@ -1486,14 +1586,16 @@ ul li::before {
ol {
counter-reset: li; }
ol li:not([value]) {
counter-increment: li; }
ol li::before {
content: counter(li);
margin-left: -1.5em;
margin-right: 0.5em;
text-align: right;
direction: rtl; }
ol li {
counter-increment: li; }
ol li[value]::before {
content: attr(value); }
ul ul, ol ol {
padding-left: 20px; }
@ -1786,6 +1888,7 @@ table {
line-height: 1.9; }
table caption {
margin-bottom: 10px;
min-width: 20em;
font-family: "Open Sans", sans;
font-weight: normal;
font-size: 15px;

56
engraved-theme.el Normal file
View File

@ -0,0 +1,56 @@
;;; engraved-theme.el -*- lexical-binding: t; -*-
(require 'engrave-faces)
(add-to-list 'engrave-faces-themes
'(doom-opera-light
(default :short "default" :slug "D" :family "JetBrains Mono" :foreground "#2a2a2a" :background "#fafafa" :slant normal :weight regular)
(bold :short "bold" :slug "b" :weight bold)
(italic :short "italic" :slug "i" :slant italic)
(variable-pitch :short "var-pitch" :slug "vp" :family "Overpass" :height 196)
(shadow :short "shadow" :slug "h" :foreground "#9e9e9e")
(success :short "success" :slug "sc" :foreground "#4f894c")
(warning :short "warning" :slug "w" :foreground "#9a7500")
(error :short "error" :slug "e" :foreground "#99324b")
(link :short "link" :slug "l" :foreground "#3b6ea8" :weight bold)
(link-visited :short "link" :slug "lv" :foreground "#8b008b" :weight bold)
(highlight :short "link" :slug "hi" :foreground "#fafafa" :background "#3b6ea8")
(font-lock-comment-face :short "fl-comment" :slug "c" :foreground "#b1b1b1")
(font-lock-comment-delimiter-face :short "fl-comment-delim" :slug "cd" :foreground "#b1b1b1")
(font-lock-string-face :short "fl-string" :slug "s" :foreground "#4f894c")
(font-lock-doc-face :short "fl-doc" :slug "d" :foreground "#b6b6b6")
(font-lock-doc-markup-face :short "fl-doc-markup" :slug "m" :foreground "#97365b")
(font-lock-keyword-face :short "fl-keyword" :slug "k" :foreground "#3b6ea8")
(font-lock-builtin-face :short "fl-builtin" :slug "bi" :foreground "#29838d")
(font-lock-function-name-face :short "fl-function" :slug "f" :foreground "#29838d")
(font-lock-variable-name-face :short "fl-variable" :slug "v" :foreground "#cb9aad")
(font-lock-type-face :short "fl-type" :slug "t" :foreground "#9a7500")
(font-lock-constant-face :short "fl-constant" :slug "o" :foreground "#97365b")
(font-lock-warning-face :short "fl-warning" :slug "wr" :foreground "#9a7500")
(font-lock-negation-char-face :short "fl-neg-char" :slug "nc" :foreground "#3b6ea8" :weight bold)
(font-lock-preprocessor-face :short "fl-preprocessor" :slug "pp" :foreground "#3b6ea8" :weight bold)
(font-lock-regexp-grouping-construct :short "fl-regexp" :slug "rc" :foreground "#3b6ea8" :weight bold)
(font-lock-regexp-grouping-backslash :short "fl-regexp-backslash" :slug "rb" :foreground "#3b6ea8" :weight bold)
(org-block :short "org-block" :slug "ob" :background "#e0e0e0")
(org-block-begin-line :short "org-block-begin" :slug "obb" :foreground "#b1b1b1" :background "#e0e0e0")
(org-block-end-line :short "org-block-end" :slug "obe" :foreground "#b1b1b1" :background "#e0e0e0")
(outline-1 :short "outline-1" :slug "Oa" :foreground "#3b6ea8" :weight extra-bold :height 1.25)
(outline-2 :short "outline-2" :slug "Ob" :foreground "#97365b" :weight bold :height 1.15)
(outline-3 :short "outline-3" :slug "Oc" :foreground "#842879" :weight bold :height 1.12)
(outline-4 :short "outline-4" :slug "Od" :foreground "#6c92bd" :weight semi-bold :height 1.09)
(outline-5 :short "outline-5" :slug "Oe" :foreground "#b16883" :weight semi-bold :height 1.06)
(outline-6 :short "outline-6" :slug "Of" :foreground "#9db6d3" :weight semi-bold :height 1.03)
(outline-7 :short "outline-7" :slug "Og" :foreground "#cb9aad" :weight bold)
(outline-8 :short "outline-8" :slug "Oh" :foreground "#d7e2ed" :weight semi-bold)
(highlight-numbers-number :short "hl-number" :slug "hn" :foreground "#97365b" :weight bold)
(highlight-quoted-quote :short "hl-qquote" :slug "hq" :foreground "#3b6ea8")
(highlight-quoted-symbol :short "hl-qsymbol" :slug "hs" :foreground "#9a7500")
(rainbow-delimiters-depth-1-face :short "rd-1" :slug "rda" :foreground "#3b6ea8")
(rainbow-delimiters-depth-2-face :short "rd-2" :slug "rdb" :foreground "#97365b")
(rainbow-delimiters-depth-3-face :short "rd-3" :slug "rdc" :foreground "#4f894c")
(rainbow-delimiters-depth-4-face :short "rd-4" :slug "rdd" :foreground "#842879")
(rainbow-delimiters-depth-5-face :short "rd-5" :slug "rde" :foreground "#29838d")
(rainbow-delimiters-depth-6-face :short "rd-6" :slug "rdf" :foreground "#3b6ea8")
(rainbow-delimiters-depth-7-face :short "rd-7" :slug "rdg" :foreground "#97365b")
(rainbow-delimiters-depth-8-face :short "rd-8" :slug "rdh" :foreground "#4f894c")
(rainbow-delimiters-depth-9-face :short "rd-9" :slug "rdi" :foreground "#842879")))

View File

@ -1,77 +0,0 @@
#!/usr/bin/env sh
":"; exec script -eqfc "TERM=xterm-direct emacs --quick -nw --eval '(progn (setq file-to-htmlize \"$1\" output-file \"$2\") (load (expand-file-name \"$0\")))' && rm typescript" 1>/dev/null # -*- mode: emacs-lisp; lexical-binding: t; -*-
(defvar htmlize-theme 'doom-opera-light)
;; Need output file
(when (string= "" output-file)
(kill-emacs 2))
(setq output-file (expand-file-name output-file))
;;; Doom initialisation
(unless (bound-and-true-p doom-init-p)
(setq gc-cons-threshold 16777216
gcmh-high-cons-threshold 16777216)
(setq doom-disabled-packages '(doom-themes))
(load (expand-file-name "core/core.el" user-emacs-directory) nil t)
(require 'core-cli)
(doom-initialize))
(advice-add 'undo-tree-mode :override #'ignore) ; Undo tree is a pain
(load-theme htmlize-theme t)
;;; No recentf please
(recentf-mode -1)
(advice-add 'recentf-mode :override #'ignore)
(advice-add 'recentf-cleanup :override #'ignore)
;;; Writegood is not desired
(advice-add 'writegood-mode :override #'ignore)
;;; Quit without fuss
(setq kill-emacs-hook nil
noninteractive t)
;;; Lighten org-mode
(when (string= "org" (file-name-extension file-to-htmlize))
(setcdr (assoc 'org after-load-alist) nil)
(setq org-load-hook nil)
(require 'org)
(setq org-mode-hook nil))
;; Start htmlizing
(require 'htmlize)
(ignore-errors
(with-temp-buffer
(insert-file-contents file-to-htmlize)
(setq buffer-file-name file-to-htmlize)
(ignore-errors
(normal-mode)
(if (eq major-mode 'org-mode)
(org-show-all))
(font-lock-ensure))
(with-current-buffer (htmlize-buffer-1)
(goto-char (point-min))
(replace-string "</title>\n"
"</title>
<style>
body { background: #f0eeed !important; }
body > pre {
font-size: 1rem;
max-width: min(100rem, 100%);
width: max-content;
white-space: pre-wrap;
margin: auto;
}
</style>\n")
(write-file output-file)
(kill-emacs 0))))
(kill-emacs 1)

View File

@ -1,35 +1,109 @@
#!/usr/bin/env sh
":"; exec emacs --quick --script "$0" -- "$@" # -*- mode: emacs-lisp; lexical-binding: t; -*-
(message "Publising")
(if load-file-name
(message "Publising")
(error "This is designed to be run as a script file, not within Emacs"))
(defvar force nil) ; -f --force
(defvar update-commit nil) ; -u --update
(defvar update-draft nil) ; -d --draft
(pop argv) ; $0
(setq force (string= "-f" (pop argv)))
;;; Doom initialisation
(while argv
(pcase (pop argv)
((or "-f" "--force")
(setq force t))
((or "-u" "--update")
(setq update-commit t))
((or "-d" "--draft")
(setq update-draft t))))
(unless (bound-and-true-p doom-init-p)
(setq gc-cons-threshold 16777216
gcmh-high-cons-threshold 16777216)
(setq doom-disabled-packages '(doom-themes))
(load (expand-file-name "core/core.el" user-emacs-directory) nil t)
(require 'core-cli)
(doom-initialize))
(when (and update-commit update-draft)
(warn! "--update and --draft are mutually exclusive, --draft will take priority"))
(advice-add 'undo-tree-mode :override #'ignore) ; Undo tree is a pain
(setq gc-cons-threshold (* 4 1024 1024)
gcmh-high-cons-threshold (* 4 1024 1024))
;;; Package initialisation
(unless (file-directory-p "~/.config/doom")
(error "This publishing script currently assumes a Doom emacs install exists."))
;; Assumes that the doom install is already fully-functional.
(push "~/.config/emacs/lisp" load-path)
(push "~/.config/emacs/lisp/lib" load-path)
(require 'doom-lib)
(require 'doom)
(doom-require 'doom-lib 'files)
(require 'doom-modules)
(require 'doom-packages)
(doom-initialize-packages)
;;I don't like this, but it works.
(dolist (subdir (directory-files (file-name-concat straight-base-dir "straight" straight-build-dir) t))
(push subdir load-path))
(require 'doom-cli)
(doom-require 'doom-cli 'doctor)
(doom-module-context-with '(:config . use-package)
(doom-load (abbreviate-file-name
(file-name-sans-extension
(doom-module-locate-path :config 'use-package doom-module-init-file)))))
(defun doom-shut-up-a (fn &rest args)
;;`quiet!' is defined in doom-lib.el
(quiet! (apply fn args)))
(push "~/.config/doom/subconf" load-path)
;;; General publishing setup
(section! "Initialising")
(require 'org)
(require 'ox-publish)
(require 'ox-html)
(require 'ox-latex)
(require 'ox-ascii)
(require 'ox-org) ; For the word count
(require 'org-persist)
(remove-hook 'kill-emacs-hook #'org-persist-gc)
(setq site-root "https://blog.tecosaur.com/tmio/")
(require 's) ; Needed for my config
(let ((css-src (expand-file-name "misc/org-css/main.css" doom-private-dir))
(css-dest (expand-file-name "assets/org-style.css" (file-name-directory load-file-name)))
(js-src (expand-file-name "misc/org-css/main.js" doom-private-dir))
(js-dest (expand-file-name "assets/org-style.js" (file-name-directory load-file-name))))
(provide 'config-org-behaviour) ; We *don't* want this
(require 'config-org-exports)
(require 'config-ox-html)
(require 'config-ox-latex)
(require 'config-ox-ascii)
(require 'engrave-faces-html)
(load (expand-file-name "engraved-theme.el" (file-name-directory load-file-name)))
(engrave-faces-use-theme 'doom-opera-light)
;; For faces
(require 'highlight-quoted)
(require 'highlight-numbers)
(require 'rainbow-delimiters)
;; Setup
(setq site-root "https://blog.tecosaur.net/tmio/"
publish-root (file-name-directory load-file-name)
content-dir (file-name-concat publish-root "content")
html-dir (file-name-concat publish-root "html")
assets-dir (file-name-concat publish-root "assets")
git-publish-branch "html")
(setq default-directory publish-root)
(let ((css-src (expand-file-name "misc/org-css/main.css" doom-user-dir))
(css-dest (file-name-concat assets-dir "org-style.css"))
(js-src (expand-file-name "misc/org-css/main.js" doom-user-dir))
(js-dest (file-name-concat assets-dir "org-style.js")))
(when (file-newer-than-file-p css-src css-dest)
(copy-file css-src css-dest t))
(when (file-newer-than-file-p js-src js-dest)
@ -48,12 +122,17 @@
:width "464"
:height "512"
:alt "Org unicorn logo")
org-export-with-broken-links t
org-id-locations-file (expand-file-name ".orgids")
org-babel-default-inline-header-args '((:eval . "no") (:exports . "code")))
org-babel-default-inline-header-args '((:eval . "no") (:exports . "code"))
org-confirm-babel-evaluate nil
org-resource-download-policy t
user-full-name "TEC"
user-mail-address "contact.tmio@tecosaur.net")
;;; For some reason emoji detection doesn't seem to work, so let's just turn it on
(setcar (rassoc 'emoji org-latex-conditional-features) t)
;; (setcar (rassoc 'emoji org-latex-conditional-features) t)
;;; Remove generated .tex/.pdf files from the base directory
@ -136,7 +215,7 @@ Return output file name."
;;; Htmlized file publishing
(defun org-publish-to-htmlized (_plist filename pub-dir)
(defun org-publish-to-engraved (_plist filename pub-dir)
"Publish a file with no change other than maybe optimisation.
FILENAME is the filename of the Org file to be published. PLIST
@ -146,7 +225,7 @@ publishing directory.
Return output file name."
(unless (file-directory-p pub-dir)
(make-directory pub-dir t))
(call-process (expand-file-name "./htmlize-file.el") nil nil nil filename (expand-file-name (concat (file-name-base filename) ".org.html") pub-dir)))
(engrave-faces-html-file filename (expand-file-name (concat (file-name-base filename) ".org.html") pub-dir)))
;;; RSS
@ -176,6 +255,7 @@ PROJECT is the current project."
(date (format-time-string "%Y-%m-%d" (org-publish-find-date entry project)))
(link (concat (file-name-sans-extension entry) ".html")))
(with-temp-buffer
(org-mode)
(insert (format "* [[file:%s][%s]]\n" file title))
(org-set-property "RSS_TITLE" title)
(org-set-property "RSS_PERMALINK" link)
@ -233,17 +313,18 @@ PROJECT is the current project."
"This Month in Org - Assets"
"This Month in Org - RSS"))
("This Month in Org - Pages"
:base-directory "./content"
:base-directory ,content-dir
:base-extension "org"
:publishing-directory "./html"
:publishing-directory ,html-dir
:exclude "rss\\.org"
:recursive t
:publishing-function
(org-html-publish-to-html
org-org-publish-to-org
org-publish-to-htmlized
org-publish-to-engraved
org-ascii-publish-to-utf8
org-latex-publish-to-pdf)
;; org-latex-publish-to-pdf
)
:headline-levels 4
:section-numbers nil
:with-toc nil
@ -252,9 +333,9 @@ PROJECT is the current project."
:html-postamble t
:html-postamble-format (("en" ,html-postamble)))
("This Month in Org - Index"
:base-directory "./assets"
:base-directory ,assets-dir
:base-extension "org"
:publishing-directory "./html"
:publishing-directory ,html-dir
:exclude ".*"
:include ("index.org")
:recursive nil
@ -262,14 +343,14 @@ PROJECT is the current project."
:headline-levels 4
:section-numbers nil
:with-toc nil
:html-head-extra ,(file-contents "assets/index-head-extra.html")
:html-head-extra ,(file-contents (file-name-concat assets-dir "index-head-extra.html"))
:html-preamble nil
:html-postamble t
:html-postamble-format (("en" ,html-postamble)))
("This Month in Org - Archive,404"
:base-directory "./assets"
:base-directory ,assets-dir
:base-extension "org"
:publishing-directory "./html"
:publishing-directory ,html-dir
:exclude ".*"
:include ("archive.org" "404.org")
:recursive nil
@ -282,19 +363,19 @@ PROJECT is the current project."
:html-postamble t
:html-postamble-format (("en" ,html-postamble)))
("This Month in Org - Assets"
:base-directory "./assets"
:base-directory ,assets-dir
:base-extension any
:exclude "\\.html$" ; template files
:publishing-directory "./html"
:publishing-directory ,html-dir
:recursive t
:publishing-function org-publish-attachment-optimised)
("This Month in Org - RSS"
:base-directory "./content"
:base-directory ,content-dir
:base-extension "org"
:recursive nil
:exclude ,(rx (or "rss.org" (regexp "DRAFT.*\\.org")))
:publishing-function org-rss-publish-to-rss-only
:publishing-directory "./html"
:publishing-directory ,html-dir
:rss-extension "xml"
:html-link-home ,site-root
:html-link-use-abs-url t
@ -309,21 +390,110 @@ PROJECT is the current project."
))
(section! "Publishing files")
(when force
(warn! "Force flag set"))
(when force
(delete-directory "./html" t))
(when (and force (file-directory-p html-dir))
(call-process "git" nil nil nil "worktree" "remove" "-f" git-publish-branch)
(call-process "git" nil nil nil "worktree" "prune")
(delete-directory html-dir t)
(call-process "git" nil nil nil "worktree" "add" html-dir git-publish-branch)
(if (file-directory-p html-dir)
(dolist (child (directory-files html-dir))
(unless (member child '("." ".." ".git"))
(if (file-directory-p child)
(delete-directory child t)
(delete-file child))))
(warn! "Failed to create html worktree")))
(unless (file-directory-p html-dir)
(call-process "git" nil nil nil "worktree" "add" html-dir git-publish-branch)
(unless (file-directory-p html-dir)
(warn! "Failed to create html worktree")))
(org-publish "This Month in Org" force)
(section! "Uploading")
(let ((rsync-status
(with-temp-buffer
(cons (call-process "rsync" nil t nil "-avzL" "--delete"
(expand-file-name "html/" (file-name-directory load-file-name))
"imh:/home/thedia18/public_html/tecosaur.com/blog/tmio/")
(message "\033[0;33m%s\033[0m" (buffer-string))))))
(if (= (car rsync-status) 0)
(success! "Content uploaded")
(error! "Content failed to upload, rsync exited with code %d" rsync-code)))
(section! "Pushing")
;; To make somewhat nice git history in the HTML branch, we'll want to collect
;; information on the current state off affairs and commit accordingly.
;;
;; We start by checking to see if we should make a "publish" style commit or a
;; "draft" style commit. This is determied by seeing if there are any
;; =content/...= lines in the git status, the assumption being that at each
;; publish point everything under =content/= has been comitted.
;;
;; Then we check to see if the last commit in the html branch is a "publish"
;; style commit or a "draft" style commit. We make this easy for ourselves by
;; prepending draft commits messages with the keyword "DRAFT". Should the last
;; commit be a draft, we replace it. Otherwise, a new commit is created.
;;
;; Lastly, we actually push the HTML branch.
(defun last-commit-log (fmt &optional branch)
"Get the log line for the last commit in FMT (optionally for BRANCH)."
(with-temp-buffer
(apply #'call-process "git" nil t nil "log"
(delq nil (list (and branch (format "refs/heads/%s" branch)) "-1"
(format "--pretty=format:%s" fmt))))
(buffer-string)))
(defun last-commit-subject (&optional branch)
"Get the commit subject line."
(last-commit-log "%s" branch))
(defun last-commit-hash (&optional branch)
"Get the commit subject line."
(last-commit-log "%h" branch))
(defun get-unstaged-changes ()
(with-temp-buffer
(call-process "git" nil t nil "status" "--porcelain=v1")
(goto-char (point-min))
(let (changes)
(while (re-search-forward "^\\(..\\) +" nil t)
(push (cons (match-string 1)
(and (re-search-forward "[^\n]+" nil t)
(match-string 0)))
changes))
changes)))
(defun git-try-command (&rest args)
(with-temp-buffer
(setq args (delq nil args))
(let ((exit-code (apply #'call-process "git" nil t nil args)))
(or (eq exit-code 0)
(progn
(error! "Failed to %s" (car args))
(message " Git command: git %s" (mapconcat #'shell-quote-argument args " "))
(message " Error: %s" (mapconcat #'identity (split-string (buffer-string) "\n") "\n "))
nil)))))
(let* ((source-draft-p (and (or update-draft (not update-commit))
(member (file-name-base content-dir)
(mapcar
(lambda (change) (car (file-name-split (cdr change))))
(get-unstaged-changes)))))
(html-draft-p (string-prefix-p "DRAFT " (last-commit-subject git-publish-branch)))
(html-changed-files (length (let ((default-directory html-dir)) (get-unstaged-changes))))
(commit-message
(if source-draft-p
(format "DRAFT update (%s files changed)\nLast source commit: %s\nLocal time: %s"
html-changed-files
(last-commit-hash)
(format-time-string "%F %T (UTC%z)"))
(format "Publish update based on %s" (last-commit-hash)))))
(if (= html-changed-files 0)
(warn! "No changes to push")
(let ((default-directory html-dir))
(unless source-draft-p
(dolist (file (mapcar #'cdr (get-unstaged-changes)))
(when (and (file-exists-p file)
(string-prefix-p "DRAFT-" (file-name-base file)))
(delete-file file))))
(and (git-try-command "add" "-A")
(git-try-command "commit" (and html-draft-p "--amend") "--message" commit-message)
(git-try-command "push" (and html-draft-p "--force-with-lease"))))))
(section! "Finished")