1
0
Fork 0
arcology-elixir/README.org

129 lines
6.6 KiB
Org Mode

#+TITLE: Arcology: An Org Roam Publishing System
#+ROAM_ALIAS: "Arcology README"
#+ROAM_TAGS: Arcology
#+ROAM_KEY: https://code.rix.si/rrix/arcology
#+CREATED: [2020-09-22]
#+MODIFIED: [2020-09-22]
#+ARCOLOGY_KEY: arcology/index
#+AUTO_TANGLE: t
The Arcology is a system for publishing my org-mode documents to the web, an important component of Ryan Rix's [[file:../cce/cce.org][Complete Computing Environment]]. Rather than a pure static-site design, a directory full of "compiled HTML", the Arcology aims to provide *just enough* dynamicity to make publishing on the web simple, transparent, and powerful. Arcology uses the same database caching that Org Roam uses with some custom extensions to provide a web-view of a *subset of documents in my knowledge base*, and "indieweb" facilities around this like microformats, webmentions, indieauth, and some day a full ActivityPub implementation for my Journal and a "link blog" of my Archive posts.
This project is a repository of [[https://orgmode.org/][Org Mode]] formatted documents which describe and implement a web service written in [[https://elixir-lang.org/][Elixir]] using the [[https://www.phoenixframework.org/][Phoenix Framework]]. Rather than directly editing the source code, these documents are edited instead -- source code, justification and the links between disparate modules and data-flows expressed in text as well as code.
* Table of Contents
- Framework Support
- [[file:phoenix.org][Project Configuration, Mix, etc]]
- [[file:arcology.org][Arcology Backend Application]]
- [[file:aesthetics.org][The Visual Identity of Arcology]]
- [[file:testing.org][arcology Test Support]]
- [[file:page_controller.org][Org Mode Page Controller]]
- [[file:arcology_web.org][arcology Phoenix Frontend]]
- [[file:page_controller.org][Controller for static ArcologyWeb pages]]
- [[file:arcology_roam.org][Arcology Roam Models]]
- [[file:arcology_db.org][Arcology DB Creates a Queryable Cache of Knowledge]]
- [[file:inotify-tools.org][Rebuilding Arcology DB Automatically]]
- [[file:arcology_page.org][Arcology Page Module]]
- includes cached pandoc output for page and links (with built-in invalidation)
- [[file:link_routers.org][Arcology Link Routers]] rewrite org-mode links to key-based paths with support for local development routing
- =ARCOLOGY_KEY: cce/cce= -> =localhost:4000/cce/cce.html= -> =cce.arcology.garden/cce.html= for example
- [[file:arcology_media_store.org][Arcology Media Store]] is a simple Key/Value store for images and docs in the Arcology.
- [[file:deploying.org][Deploying the Arcology]]
- Endpoint to update the arcology-db
* Building
There is a [[file:Makefile][Makefile]] to make it easier to tangle the files. You will need Emacs and Org-mode installed for this to work. Some day all of this will be in Mix tasks that can contain the whole set of dependencies.
=make tangle= will tangle any org document which is newer than a handle left in =_build=. It's important to keep your tangled documents up to date with the file system, but for development it's likely that you're sending the Elixir code to a running =IEx= session, there will be an org-mode documentation providing for this at some point soon.
=make init= will tangle, download dependencies, and compile them.
* Nix Shell for Development Environment
#+begin_src nix :tangle shell.nix
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
packages = with pkgs; [
emacs-nox
sqlite
pandoc
redis
nodejs
inotify-tools
elixir_1_12
elixir_ls
];
}
#+end_src
* Developing in a REPL and a Babel doc
Arcology development requires a postgres database with a database called =arcology_dev=. run [[shell:mix ecto.setup]] (or click on that link!)
Executing this code will allow you to send the org-babel block under point to the REPL. I don't know how that handles =noweb=, blocks but it kinda works. Most of the time, I rely on *automatically tangling and recompiling*.
#+CCE_MODULE: arcology-dev
#+begin_src emacs-lisp :results none :tangle ~/org/cce/arcology-dev.el
(use-package eval-in-repl
:config
(require 'eval-in-repl-ielm)
; i disable transient mark mode
(defun eir-eval-in-iex ()
"Provides eval-in-repl for Elixir."
(interactive)
;; Define local variables
(let* ()
(eir-repl-start "\\*Alchemist-IEx\\*" #'alchemist-iex-run t)
(eir-send-to-iex (buffer-substring-no-properties (point) (mark)))))
(setq eir-repl-placement 'left)
(setq eir-jump-after-eval nil)
(setq eir-ielm-eval-in-current-buffer t))
(use-package org-babel-eval-in-repl
:after ob
:config
(add-to-list 'ober-org-babel-type-list '("elixir" . (eval-in-repl-iex eir-eval-in-iex)))
(evil-define-key 'normal 'org-mode-map (kbd "C-<return>") #'ober-eval-in-repl)
(evil-define-key 'normal 'org-mode-map (kbd "M-<return>") #'ober-eval-block-in-repl))
(use-package alchemist)
#+end_src
Alchemist can run an IEx shell with [[elisp:(alchemist-iex-run " -S mix phx.server")][=iex -S mix phx.server=]], and run tests with [[elisp:(alchemist-mix-execute '("test.watch"))][=mix test.watch=]].
Run this with =Alt-Return= to disable colors and see the =IEx= shell in action. Many "naked" code blocks can be evaluated in this fashion, but EIR doesn't support =noweb= blocks.
#+begin_src elixir
alias Arcology.{Repo,Roam,Page}
IEx.configure(colors: [enabled: false])
#+end_src
=use-package= [[https://github.com/yilkalargaw/org-auto-tangle][org-auto-tangle]] and enable =org-auto-tangle-mode= to get automatic tangling.
To trigger a recompile in =iex= after tangle, execute this block. It'll also touch the files which the =Makefile= checks for "up-to-date"-ness in the =tangle= task which'll need to be run by build scripts. This code is kind of cursed; you see, org-babel has a pre-tangle hook which isn't so useful, but =current-buffer= is the org-mode doc. The post-tangle hook is ran in *each output file*. So this cursed code runs an idle timer!
#+begin_src emacs-lisp :results none
(defun arcology/idle-file-for-make-command ()
(run-with-idle-timer 1 nil #'arcology/recompile-iex))
(defun arcology/recompile-iex ()
(let* ((file (or org-src-source-file-name (buffer-file-name)))
(touch-file (replace-regexp-in-string "\\([^/]+\\)\\.org$" "_build/\\1.touch" file)))
(when (s-contains? "arcology" file)
(message "touch %s" touch-file)
(call-process-shell-command (format "touch %s" touch-file))
(eir-send-to-iex "recompile"))))
(add-hook #'org-babel-pre-tangle-hook #'arcology/idle-file-for-make-command)
#+end_src
* Footnotes
[fn:1] Some restrictions apply, segments that are part of a noweb block will need to be run in the module-level block...