#!/usr/bin/env bash
":"; exec emacs --quick --script "$0" -- "$@" # -*- mode: emacs-lisp; lexical-binding: t; -*-
;;; bin/org-tangle

;; Extracts source blocks from org files and prints them to stdout. Debug/info
;; messages are directed to stderr and can be ignored. -l/--lang can be used to
;; only tangle blocks of a certain language.
;;
;; Usage: org-tangle [[-l|--lang] LANG] some-file.org another.org
;; Examples:
;;   org-tangle modules/ui/doom/README.org > install_fira_mono.sh
;;   org-tangle -l sh modules/lang/go/README.org | sh

(load (expand-file-name "../core/core.el" (file-name-directory load-file-name)) nil t)

(require 'org-install)
(require 'org)
(require 'ob-tangle)

(defun *org-babel-tangle (orig-fn &rest args)
  "Don't write tangled blocks to files, print them to stdout."
  (cl-letf (((symbol-function 'write-region)
             (lambda (start end filename &optional append visit lockname mustbenew)
               (princ (buffer-string)))))
    (apply orig-fn args)))
(advice-add #'org-babel-tangle :around #'*org-babel-tangle)

(let (lang srcs)
  (pop argv)
  (while argv
    (let ((arg (pop argv)))
      (pcase arg
        ((or "--lang" "-l")
         (setq lang (pop argv)))
        ((guard (string-match-p "^--lang=" arg))
         (setq lang (cadr (split-string arg "=" t t))))
        ((guard (file-exists-p arg))
         (push arg srcs))
        (_
         (error "Unknown option or file: %s" arg)))))

  (dolist (file srcs)
    (org-babel-tangle-file file nil lang))
  (kill-emacs 0))
