From de83a3ea99275de9887618f1ea2f9d468a0d4e6a Mon Sep 17 00:00:00 2001 From: Thomas Letan Date: Sat, 13 Aug 2022 17:05:37 +0200 Subject: Goodbye, cleopatra MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As it is, it is just too slow. Plus, the literate program that was my toolchain is actually not documented, so it makes no sense. I’m sad, though. --- scripts/cleopatra.el | 67 ++++++++++++++++++++++++++++ scripts/css.sh | 12 +++++ scripts/export-lp.el | 18 ++++++++ scripts/export-org.el | 81 +++++++++++++++++++++++++++++++++ scripts/gen-deps.sh | 14 ++++++ scripts/history.sh | 106 ++++++++++++++++++++++++++++++++++++++++++++ scripts/init.el | 66 +++++++++++++++++++++++++++ scripts/packages.el | 5 +++ scripts/pretty-echo.sh | 6 +++ scripts/render-equations.js | 11 +++++ scripts/update-gitignore.sh | 16 +++++++ 11 files changed, 402 insertions(+) create mode 100644 scripts/cleopatra.el create mode 100755 scripts/css.sh create mode 100644 scripts/export-lp.el create mode 100644 scripts/export-org.el create mode 100755 scripts/gen-deps.sh create mode 100755 scripts/history.sh create mode 100644 scripts/init.el create mode 100644 scripts/packages.el create mode 100755 scripts/pretty-echo.sh create mode 100644 scripts/render-equations.js create mode 100755 scripts/update-gitignore.sh (limited to 'scripts') diff --git a/scripts/cleopatra.el b/scripts/cleopatra.el new file mode 100644 index 0000000..5977536 --- /dev/null +++ b/scripts/cleopatra.el @@ -0,0 +1,67 @@ +;;; cleopatra.el --- The cleopatra Emacs Library +;;; Commentary: +;;; Code: +(require 'package) + +(defun cleopatra:ensure-package-installed (&rest packages) + "Ensure every PACKAGES is installed." + (mapcar + (lambda (package) + (if (package-installed-p package) + nil + (package-install package)) + package) + packages)) + +(defvar cleopatra:*emacs-dir* (concat (getenv "ROOT") "/.cleopatra/emacs.d/")) + +(setq user-emacs-directory cleopatra:*emacs-dir*) +(setq package-user-dir (concat cleopatra:*emacs-dir* "packages")) + +(setq package-archives + '(("gnu" . "https://elpa.gnu.org/packages/") + ("melpa" . "https://melpa.org/packages/") + ("org" . "https://orgmode.org/elpa/"))) + +(package-initialize) + +(or (file-exists-p package-user-dir) + (package-refresh-contents)) + +(cleopatra:ensure-package-installed 'use-package) + +(require 'use-package) + +(use-package org :ensure org-plus-contrib :pin org) +(use-package htmlize :ensure t) + +(defun cleopatra:configure () + (setq backup-inhibited t) + (setq org-html-doctype "html5") + (setq org-html-html5-fancy t) + (setq org-src-fontify-natively t) + (setq org-export-with-sub-superscripts nil) + (setq org-confirm-babel-evaluate nil) + (setq org-publish-timestamp-directory + (concat cleopatra:*emacs-dir* "cache/")) + (setq org-confirm-babel-evaluate nil) + (setq org-src-preserve-indentation t) + (add-to-list 'org-babel-default-header-args + '(:mkdirp . "yes")) + (add-to-list 'org-babel-default-header-args + '(:noweb-sep . "\n\n"))) + +(defun cleopatra:tangle-publish (conf filename _pub-dir) + (let ((pub-dir (plist-get conf :publishing-directory))) + (if pub-dir + (with-temp-buffer + (find-file-read-only filename) + (cd (getenv "ROOT")) + (unless (file-exists-p pub-dir) + (make-directory pub-dir)) + (cd pub-dir) + (org-babel-tangle)) + (error "cleopatra: missing :publishing-directory option")))) + +(provide 'cleopatra) +;;; cleopatra.el ends here diff --git a/scripts/css.sh b/scripts/css.sh new file mode 100755 index 0000000..753bc8c --- /dev/null +++ b/scripts/css.sh @@ -0,0 +1,12 @@ +#!/bin/bash +minify="$(npm bin)/minify" +normalize="$(npm root)/normalize.css/normalize.css" +style="style.css" + +# minify add a newline character at the end of its input +# we remove it using `head' +echo " +@charset \"UTF-8\"; +$(cat ${normalize}) +$(cat ${style}) +" | ${minify} --css | head -c -1 > style.min.css diff --git a/scripts/export-lp.el b/scripts/export-lp.el new file mode 100644 index 0000000..bd17b0d --- /dev/null +++ b/scripts/export-lp.el @@ -0,0 +1,18 @@ +;; opinionated configuration provided by cleopatra +(cleopatra:configure) + +;; allow the execution of shell block code +(org-babel-do-load-languages + 'org-babel-load-languages + '((shell . t))) + +(setq org-publish-project-alist + '(("lp" + :base-directory "site/posts" + :publishing-directory "lp" + ;; hand-pick which files to tangle (this save a lots of time) + :exclude ".*" + :include ("CoqffiEcho.org") + :publishing-function cleopatra:tangle-publish))) + +(org-publish-all) diff --git a/scripts/export-org.el b/scripts/export-org.el new file mode 100644 index 0000000..1b20265 --- /dev/null +++ b/scripts/export-org.el @@ -0,0 +1,81 @@ +(cleopatra:configure) + +(org-babel-do-load-languages + 'org-babel-load-languages + '((dot . t) + (shell . t) + (ocaml . t))) + +(setq org-export-with-toc nil + org-html-htmlize-output-type nil + org-export-with-section-numbers nil) + +(add-to-list 'org-entities-user + '("im" "\\(" nil "" "" "" "")) +(add-to-list 'org-entities-user + '("mi" "\\)" nil "" "" "" "")) + +(defun with-keyword (keyword k) + "Look-up for keyword KEYWORD, and call continuation K with its value." + (pcase (org-collect-keywords `(,keyword)) + (`((,keyword . ,kw)) + (when kw (funcall k (string-join kw " ")))))) + +(defun get-keyword (keyword) + "Look-up for keyword KEYWORD, and returns its value" + (with-keyword keyword (lambda (x) x))) + +(defun get-org-title (path) + "Fetch the title of an Org file whose path is PATH." + (with-temp-buffer + (find-file-read-only path) + (get-keyword "TITLE"))) + +(defun insert-title () + "Insert the title of the article." + (with-keyword + "TITLE" + (lambda (title) + (insert + (format "\n\n@@html:

@@ %s @@html:

@@\n\n" title))))) + +(defun insert-series () + "Insert the series root link." + (with-keyword + "SERIES" + (lambda (series) + (insert "\n\n#+attr_html: :class series\n") + (insert series)))) + +(defun insert-series-prev () + "Insert the series previous article link." + (with-keyword + "SERIES_PREV" + (lambda (series-prev) + (insert "\n\n#+attr_html: :class series-prev\n") + (insert series-prev)))) + +(defun insert-series-next () + "Insert the series next article link." + (with-keyword + "SERIES_NEXT" + (lambda (series-next) + (insert "\n\n#+attr_html: :class series-next\n") + (insert series-next)))) + +(defun insert-nav () + "Insert the navigation links." + (when (get-keyword "SERIES") + (insert "\n\n#+begin_nav\n") + (insert-series) + (insert-series-prev) + (insert-series-next) + (insert "\n\n#+end_nav\n"))) + +(beginning-of-buffer) +(insert-nav) +(insert-title) + +(let ((outfile (org-export-output-file-name ".html")) + (org-html-footnotes-section "")) + (org-export-to-file 'tufte-html outfile nil nil nil t)) diff --git a/scripts/gen-deps.sh b/scripts/gen-deps.sh new file mode 100755 index 0000000..2283f9b --- /dev/null +++ b/scripts/gen-deps.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +input=${1} +output=${2} + +proc="$(basename ${input} | cut -f 1 -d '.')" + +echo "include ${input}" > ${output} +echo "prebuild : ${proc}-prebuild" >> ${output} +echo "build : ${proc}-build" >> ${output} +echo "postbuild : ${proc}-postbuild" >> ${output} +echo "${proc}-build : ${proc}-prebuild" >> ${output} +echo "${proc}-postbuild : ${proc}-build" >> ${output} +echo ".PHONY : ${proc}-prebuild ${proc}-build ${proc}-postbuild" >> ${output} diff --git a/scripts/history.sh b/scripts/history.sh new file mode 100755 index 0000000..1594714 --- /dev/null +++ b/scripts/history.sh @@ -0,0 +1,106 @@ +#!/usr/bin/bash +function main () { + local file="${1}" + local template="${2}" + + tmp_file=$(mktemp) + generate_json ${file} > ${tmp_file} + haskell-mustache ${template} ${tmp_file} + rm ${tmp_file} +} + +function gitlog () { + local file="${1}" + git --no-pager log \ + --follow \ + --stat=10000 \ + --pretty=format:'%s%n%h%n%H%n%cs%n' \ + "${file}" +} + +function parse_filename () { + local line="${1}" + local shrink='s/ *\(.*\) \+|.*/\1/' + local unfold='s/\(.*\){\(.*\) => \(.*\)}/\1\3/' + + echo ${line} | sed -e "${shrink}" | sed -e "${unfold}" +} + +function generate_json () { + local input="${1}" + local logs="$(gitlog ${input})" + + if [ ! $? -eq 0 ]; then + exit 1 + fi + + let "idx=0" + let "last_entry=$(echo "${logs}" | wc -l) / 8" + + local subject="" + local abbr_hash="" + local hash="" + local date="" + local file="" + local created="true" + local modified="false" + + echo -n "{" + echo -n "\"file\": \"${input}\"" + echo -n ",\"history\": [" + + while read -r subject; do + read -r abbr_hash + read -r hash + read -r date + read -r # empty line + read -r file + read -r # short log + read -r # empty line + + if [ ${idx} -ne 0 ]; then + echo -n "," + fi + + if [ ${idx} -eq ${last_entry} ]; then + created="true" + modified="false" + else + created="false" + modified="true" + fi + + output_json_entry "${subject}" \ + "${abbr_hash}" \ + "${hash}" \ + "${date}" \ + "$(parse_filename "${file}")" \ + "${created}" \ + "${modified}" + + let idx++ + done < <(echo "${logs}") + + echo -n "]}" +} + +function output_json_entry () { + local subject="${1}" + local abbr_hash="${2}" + local hash="${3}" + local date="${4}" + local file="${5}" + local created="${6}" + local last_entry="${7}" + + echo -n "{\"subject\": \"${subject}\"" + echo -n ",\"created\":${created}" + echo -n ",\"modified\":${modified}" + echo -n ",\"abbr_hash\":\"${abbr_hash}\"" + echo -n ",\"hash\":\"${hash}\"" + echo -n ",\"date\":\"${date}\"" + echo -n ",\"filename\":\"${file}\"" + echo -n "}" +} + +main "$(cat)" "${1}" diff --git a/scripts/init.el b/scripts/init.el new file mode 100644 index 0000000..f6f069c --- /dev/null +++ b/scripts/init.el @@ -0,0 +1,66 @@ +;;; cleopatra.el --- The cleopatra Emacs Library +;;; Commentary: +;;; Code: +(require 'package) + +(defun cleopatra:ensure-package-installed (&rest packages) + "Ensure every PACKAGES is installed." + (mapcar + (lambda (package) + (if (package-installed-p package) + nil + (package-install package)) + package) + packages)) + +(defvar cleopatra:*emacs-dir* (concat (getenv "ROOT") "/.emacs.d/")) + +(setq user-emacs-directory cleopatra:*emacs-dir*) +(setq package-user-dir (concat cleopatra:*emacs-dir* "packages")) + +(setq package-archives + '(("gnu" . "https://elpa.gnu.org/packages/") + ("melpa" . "https://melpa.org/packages/"))) + +(package-initialize) + +(or (file-exists-p package-user-dir) + (package-refresh-contents)) + +(cleopatra:ensure-package-installed 'use-package) + +(require 'use-package) + +(use-package org :ensure org-plus-contrib) +(use-package htmlize :ensure t) + +(defun cleopatra:configure () + (setq backup-inhibited t) + (setq org-html-doctype "html5") + (setq org-html-html5-fancy t) + (setq org-src-fontify-natively t) + (setq org-export-with-sub-superscripts nil) + (setq org-confirm-babel-evaluate nil) + (setq org-publish-timestamp-directory + (concat cleopatra:*emacs-dir* "cache/")) + (setq org-confirm-babel-evaluate nil) + (setq org-src-preserve-indentation t) + (add-to-list 'org-babel-default-header-args + '(:mkdirp . "yes")) + (add-to-list 'org-babel-default-header-args + '(:noweb-sep . "\n\n"))) + +(defun cleopatra:tangle-publish (conf filename _pub-dir) + (let ((pub-dir (plist-get conf :publishing-directory))) + (if pub-dir + (with-temp-buffer + (find-file-read-only filename) + (cd (getenv "ROOT")) + (unless (file-exists-p pub-dir) + (make-directory pub-dir)) + (cd pub-dir) + (org-babel-tangle)) + (error "cleopatra: missing :publishing-directory option")))) + +(provide 'cleopatra) +;;; cleopatra.el ends here diff --git a/scripts/packages.el b/scripts/packages.el new file mode 100644 index 0000000..9ed944a --- /dev/null +++ b/scripts/packages.el @@ -0,0 +1,5 @@ +(use-package ox-tufte :ensure t) + +(use-package tuareg :ensure t + :config + (require 'ob-ocaml)) diff --git a/scripts/pretty-echo.sh b/scripts/pretty-echo.sh new file mode 100755 index 0000000..8b4e149 --- /dev/null +++ b/scripts/pretty-echo.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +title=${1} +message=${2} + +printf "\033[0;32m%12s \e[0m%s\n" "${title}" "${message}" diff --git a/scripts/render-equations.js b/scripts/render-equations.js new file mode 100644 index 0000000..cae348a --- /dev/null +++ b/scripts/render-equations.js @@ -0,0 +1,11 @@ +var katex = require("katex"); +var fs = require("fs"); +var input = fs.readFileSync(0); +var displayMode = process.env.DISPLAY != undefined; + +var html = katex.renderToString(String.raw`${input}`, { + throwOnError : false, + displayModed : displayMode +}); + +console.log(html) diff --git a/scripts/update-gitignore.sh b/scripts/update-gitignore.sh new file mode 100755 index 0000000..7b9fafe --- /dev/null +++ b/scripts/update-gitignore.sh @@ -0,0 +1,16 @@ +#+/bin/bash +BEGIN_MARKER="# begin generated files" +END_MARKER="# end generated files" + +# remove the previous list of generated files to ignore +sed -i -e "/${BEGIN_MARKER}/,/${END_MARKER}/d" .gitignore +# remove trailing empty lines +sed -i -e :a -e '/^\n*$/{$d;N;};/\n$/ba' .gitignore + +# output the list of files to ignore +echo "" >> .gitignore +echo ${BEGIN_MARKER} >> .gitignore +for f in $@; do + echo "${f}" >> .gitignore +done +echo ${END_MARKER} >> .gitignore -- cgit v1.2.3