Timothy
ebd82256fd
Project/Manifest.toml detection is done rather crudely here, this could be improved in future.
202 lines
6.2 KiB
EmacsLisp
202 lines
6.2 KiB
EmacsLisp
;;; ox-pluto.el --- Export to Pluto.jl notebooks -*- lexical-binding: t; -*-
|
|
;;
|
|
;; Copyright (C) 2022 TEC
|
|
;;
|
|
;; Author: TEC <https://github.com/tecosaur>
|
|
;; Maintainer: TEC <tec@tecosaur.com>
|
|
;; Created: March 07, 2022
|
|
;; Modified: March 07, 2022
|
|
;; Version: 0.1.0
|
|
;; Keywords: tools
|
|
;; Homepage: https://github.com/tecosaur/ox-pluto
|
|
;; Package-Requires: ((emacs "26.3") (uuidgen "1.2"))
|
|
;;
|
|
;; This file is not part of GNU Emacs.
|
|
;;
|
|
;;; Commentary:
|
|
;;
|
|
;; This library provides a Pluto.jl backend to
|
|
;; the Org exporter.
|
|
;;
|
|
;;; Code:
|
|
|
|
(require 'ox)
|
|
(require 'ox-org)
|
|
|
|
(defvar ox-pluto--preamble
|
|
"### A Pluto.jl notebook ###
|
|
# Generated by ox-pluto for Pluto v0.18+
|
|
# Created %s
|
|
|
|
using InteractiveUtils\n\n")
|
|
|
|
(defun ox-pluto--org-cell (content)
|
|
(cons (cons :folded (uuidgen-4))
|
|
(concat "org\"\"\"\n"
|
|
(replace-regexp-in-string
|
|
"\"\"\"" "\"\\quot\""
|
|
content)
|
|
"\"\"\"")))
|
|
|
|
(defun ox-pluto--julia-cell (content)
|
|
(cons (cons :unfolded (uuidgen-4))
|
|
content))
|
|
|
|
(defun ox-pluto--render-cell (cell)
|
|
(concat "# ╔═╡ " (cdar cell) "\n" (cdr cell) "\n"))
|
|
|
|
(defun ox-pluto--cell-list (cells)
|
|
(concat "# ╔═╡ Cell order:\n"
|
|
(mapconcat
|
|
(lambda (cell)
|
|
(concat
|
|
(if (eq :folded (caar cell))
|
|
"# ╟─" "# ╠═")
|
|
(cdar cell)))
|
|
cells
|
|
"\n")))
|
|
|
|
(defun ox-pluto--form-cells (content _backend _info)
|
|
(let (cells)
|
|
(push (cons (cons :folded (uuidgen-4)) "using Org")
|
|
cells)
|
|
(with-temp-buffer
|
|
(insert content)
|
|
(goto-char (point-min))
|
|
(re-search-forward "\\=# Created .*?\n" nil t)
|
|
(while (< (point) (point-max))
|
|
(if (and (looking-at-p "^[ \t]*#\\+begin_src julia")
|
|
(not (looking-at-p "^[^\n]*:eval no")))
|
|
(progn
|
|
(push
|
|
(ox-pluto--julia-cell
|
|
(buffer-substring-no-properties
|
|
(progn (forward-line 1) (point))
|
|
(progn
|
|
(re-search-forward "^[ \t]*#\\+end_src")
|
|
(forward-line -1)
|
|
(line-end-position))))
|
|
cells)
|
|
(forward-line 2))
|
|
(push
|
|
(ox-pluto--org-cell
|
|
(buffer-substring-no-properties
|
|
(point)
|
|
(goto-char
|
|
(or (and (re-search-forward
|
|
"^\\*+ \\|^[ \t]*#\\+begin_src julia" nil t)
|
|
(line-beginning-position))
|
|
(point-max)))))
|
|
cells))
|
|
(re-search-forward "\\=\\(?:[ \t\r]*\n\\)+" nil t)))
|
|
(when (file-exists-p "Project.toml")
|
|
(push
|
|
(cons (cons :unfolded "00000000-0000-0000-0000-000000000001")
|
|
(with-temp-buffer
|
|
(insert "PLUTO_PROJECT_TOML_CONTENTS = \"\"\"\n")
|
|
(insert-file-contents "Project.toml")
|
|
(insert "\n\"\"\"")
|
|
(buffer-string)))
|
|
cells))
|
|
(when (file-exists-p "Manifest.toml")
|
|
(push
|
|
(cons (cons :unfolded "00000000-0000-0000-0000-000000000002")
|
|
(with-temp-buffer
|
|
(insert "PLUTO_MANIFEST_TOML_CONTENTS = \"\"\"\n")
|
|
(insert-file-contents "Manifest.toml")
|
|
(insert "\n\"\"\"")
|
|
(buffer-string)))
|
|
cells))
|
|
(setq cells (nreverse cells))
|
|
(concat
|
|
(format ox-pluto--preamble (format-time-string "%Y-%m-%d %a %H:%M"))
|
|
(mapconcat #'ox-pluto--render-cell cells "\n")
|
|
"\n"
|
|
(ox-pluto--cell-list cells)
|
|
"\n")))
|
|
|
|
;; REVIEW it may be posslible to do this via AST manipulation,
|
|
;; which would be preferable.
|
|
|
|
(org-export-define-derived-backend 'pluto 'org
|
|
:filters-alist '((:filter-final-output . ox-pluto--form-cells)))
|
|
|
|
;;;###autoload
|
|
(defun ox-pluto-export-as-pluto
|
|
(&optional async subtreep visible-only body-only ext-plist)
|
|
"Export current buffer to an Pluto notebook buffer.
|
|
|
|
If narrowing is active in the current buffer, only export its
|
|
narrowed part.
|
|
|
|
If a region is active, export that region.
|
|
|
|
A non-nil optional argument ASYNC means the process should happen
|
|
asynchronously. The resulting buffer should be accessible
|
|
through the `org-export-stack' interface.
|
|
|
|
When optional argument SUBTREEP is non-nil, export the sub-tree
|
|
at point, extracting information from the headline properties
|
|
first.
|
|
|
|
When optional argument VISIBLE-ONLY is non-nil, don't export
|
|
contents of hidden elements.
|
|
|
|
When optional argument BODY-ONLY is non-nil, strip document
|
|
keywords from output.
|
|
|
|
EXT-PLIST, when provided, is a property list with external
|
|
parameters overriding Org default settings, but still inferior to
|
|
file-local settings.
|
|
|
|
Export is done in a buffer named \"*Org ORG Export*\", which will
|
|
be displayed when `org-export-show-temporary-export-buffer' is
|
|
non-nil."
|
|
(interactive)
|
|
;; TODO find a way to only disable Julia execution
|
|
(let (org-export-use-babel)
|
|
(org-export-to-buffer 'pluto "*Org Pluto Export*"
|
|
async subtreep visible-only body-only ext-plist
|
|
(lambda ()
|
|
(if (require 'julia-mode nil t)
|
|
(julia-mode)
|
|
(prog-mode))))))
|
|
|
|
;;;###autoload
|
|
(defun ox-pluto-export-to-pluto
|
|
(&optional async subtreep visible-only body-only ext-plist)
|
|
"Export current buffer to an Pluto notebook file.
|
|
|
|
If narrowing is active in the current buffer, only export its
|
|
narrowed part.
|
|
|
|
If a region is active, export that region.
|
|
|
|
A non-nil optional argument ASYNC means the process should happen
|
|
asynchronously. The resulting file should be accessible through
|
|
the `org-export-stack' interface.
|
|
|
|
When optional argument SUBTREEP is non-nil, export the sub-tree
|
|
at point, extracting information from the headline properties
|
|
first.
|
|
|
|
When optional argument VISIBLE-ONLY is non-nil, don't export
|
|
contents of hidden elements.
|
|
|
|
When optional argument BODY-ONLY is non-nil, strip document
|
|
keywords from output.
|
|
|
|
EXT-PLIST, when provided, is a property list with external
|
|
parameters overriding Org default settings, but still inferior to
|
|
file-local settings.
|
|
|
|
Return output file name."
|
|
(interactive)
|
|
(let ((outfile (org-export-output-file-name ".jl" subtreep))
|
|
org-export-use-babel)
|
|
(org-export-to-file 'pluto outfile
|
|
async subtreep visible-only body-only ext-plist)))
|
|
|
|
(provide 'ox-pluto)
|
|
;;; ox-pluto.el ends here
|