forked from mirrors/org-mode
Compare commits
6 Commits
dev
...
ihor-pleas
Author | SHA1 | Date |
---|---|---|
TEC | caa23dcb70 | |
TEC | 87543ee6fb | |
TEC | 798fb3aaa9 | |
TEC | bc91d8e72b | |
TEC | 2e26a3757b | |
TEC | d035cc36cd |
|
@ -4,7 +4,7 @@ effectively.
|
|||
We value a nice tone in our discussions: please check and respect the
|
||||
[[https://www.gnu.org/philosophy/kind-communication.en.html][GNU Kind Communications Guidelines]].
|
||||
|
||||
* Contribute as an Org user
|
||||
* Contribute as a Org user
|
||||
|
||||
You can contribute by helping others in various channels.
|
||||
|
||||
|
@ -16,7 +16,7 @@ You can contribute with bug reports and patches.
|
|||
|
||||
See these [[https://orgmode.org/worg/org-contribute.html#org069b83a][directions]].
|
||||
|
||||
* As an Org maintainer
|
||||
* As a Org maintainer
|
||||
|
||||
We encourage you to volunteer to maintain one of the Org files.
|
||||
|
||||
|
|
1
Makefile
1
Makefile
|
@ -27,7 +27,6 @@ help helpall::
|
|||
$(info make all - ditto)
|
||||
$(info make compile - build Org ELisp files)
|
||||
$(info make single - build Org ELisp files, single Emacs per source)
|
||||
$(info make native - build Org natively compiled Elisp files)
|
||||
$(info make autoloads - create org-loaddefs.el to load Org in-place)
|
||||
$(info make test - build Org ELisp files and run test suite)
|
||||
$(info make vanilla - run Emacs with this Org-mode and no personal config)
|
||||
|
|
|
@ -9,9 +9,8 @@ Check the [[https://orgmode.org][Org Mode website]] for more.
|
|||
|
||||
Org is part of GNU Emacs: you probably don't need to install it.
|
||||
|
||||
To install a more recent version, please use command: =M-x
|
||||
list-packages=, find "org" in the list, click on it, and click
|
||||
"Install" in the popped up window.
|
||||
To install a more recent version, please do it from [[https://elpa.gnu.org/packages/org.html][GNU ELPA]] by
|
||||
running this command: =M-x package-install RET org RET=
|
||||
|
||||
* Join the GNU Project
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# SETUPFILE for Org manual
|
||||
|
||||
# Copyright (C) 2021-2024 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2021-2023 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Emacs.
|
||||
#
|
||||
|
|
File diff suppressed because it is too large
Load Diff
2404
doc/org-manual.org
2404
doc/org-manual.org
File diff suppressed because it is too large
Load Diff
|
@ -9,17 +9,13 @@
|
|||
% Specify how many you want here.
|
||||
\columnsperpage=3
|
||||
|
||||
% Set letterpaper to 0 for A4 paper, 1 for letter (US) paper. Useful
|
||||
% only when columnsperpage is 2 or 3.
|
||||
\letterpaper=1
|
||||
|
||||
% PDF output layout. 0 for A4, 1 for letter (US), a `l' is added for
|
||||
% a landscape layout.
|
||||
\input pdflayout.sty
|
||||
\pdflayout=(1l)
|
||||
\pdflayout=(0l)
|
||||
|
||||
% Nothing else needs to be changed below this line.
|
||||
% Copyright (C) 1987, 1993, 1996--1997, 2001--2024 Free Software
|
||||
% Copyright (C) 1987, 1993, 1996--1997, 2001--2023 Free Software
|
||||
% Foundation, Inc.
|
||||
|
||||
% This document is free software: you can redistribute it and/or modify
|
||||
|
@ -112,14 +108,17 @@
|
|||
\footline{\hss\folio}
|
||||
\def\makefootline{\baselineskip10pt\hsize6.5in\line{\the\footline}}
|
||||
\else %2 or 3 columns uses prereduced size
|
||||
\hsize 3.2in
|
||||
\if 1\the\letterpaper
|
||||
\hsize 3.2in
|
||||
\vsize 7.95in
|
||||
\hoffset -.75in
|
||||
\voffset -.745in
|
||||
\else
|
||||
\hsize 3.2in
|
||||
\vsize 7.65in
|
||||
\hoffset -.25in
|
||||
\voffset -.745in
|
||||
\fi
|
||||
\hoffset -.75in
|
||||
\voffset -.745in
|
||||
\font\titlefont=cmbx10 \scaledmag2
|
||||
\font\headingfont=cmbx10 \scaledmag1
|
||||
\font\smallfont=cmr6
|
||||
|
@ -276,7 +275,7 @@
|
|||
%**end of header
|
||||
|
||||
|
||||
\title{Org-Mode Reference Card}
|
||||
\title{Org-Mode Reference Card (1/2)}
|
||||
|
||||
\centerline{(for version \orgversionnumber)}
|
||||
|
||||
|
@ -478,7 +477,7 @@ after ``{\tt :}'', and dictionary words elsewhere.
|
|||
|
||||
|
||||
\newcolumn
|
||||
\title{Org-Mode Reference Card}
|
||||
\title{Org-Mode Reference Card (2/2)}
|
||||
|
||||
\centerline{(for version \orgversionnumber)}
|
||||
|
||||
|
|
1370
etc/ORG-NEWS
1370
etc/ORG-NEWS
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
The files OrgOdtContentTemplate.xml and OrgOdtStyles.xml have the
|
||||
following copyright information:
|
||||
|
||||
Copyright (C) 2010-2024 Free Software Foundation, Inc.
|
||||
Copyright (C) 2010-2023 Free Software Foundation, Inc.
|
||||
|
||||
These files are part of GNU Emacs.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
.NOTPARALLEL: # always run this make serially
|
||||
.SUFFIXES: # we don't need default suffix rules
|
||||
ifeq ($(MAKELEVEL), 0)
|
||||
$(error This make needs to be started as a sub-make from the toplevel directory.)
|
||||
|
@ -9,8 +10,7 @@ LISPA := $(LISPV) $(LISPI)
|
|||
LISPB := $(LISPA:%el=%elc) org-install.elc
|
||||
LISPF := $(filter-out $(LISPA),$(sort $(wildcard *.el)))
|
||||
LISPC := $(filter-out $(LISPB) $(LISPN:%el=%elc),$(LISPF:%el=%elc))
|
||||
LISPN := $(filter-out $(LISPB) $(LISPN:%el=%eln),$(LISPF:%el=%eln))
|
||||
_ORGCM_ := dirall single native source slint1 slint2
|
||||
_ORGCM_ := dirall single source slint1 slint2
|
||||
-include local.mk
|
||||
|
||||
.PHONY: all compile compile-dirty \
|
||||
|
@ -19,7 +19,7 @@ _ORGCM_ := dirall single native source slint1 slint2
|
|||
install clean cleanauto cleanall cleanelc clean-install
|
||||
|
||||
# do not clean here, done in toplevel make
|
||||
all compile compile-dirty:: | autoloads
|
||||
all compile compile-dirty:: autoloads
|
||||
ifeq ($(filter-out $(_ORGCM_),$(ORGCM)),)
|
||||
$(MAKE) compile-$(ORGCM)
|
||||
else
|
||||
|
@ -27,11 +27,10 @@ else
|
|||
endif
|
||||
|
||||
compile-dirall: dirall
|
||||
compile-single: $(LISPC) | single
|
||||
compile-native: $(LISPN) | native
|
||||
compile-source: | source dirall
|
||||
compile-slint1: | dirall slint1
|
||||
compile-slint2: | source dirall slint1
|
||||
compile-single: single $(LISPC)
|
||||
compile-source: source dirall
|
||||
compile-slint1: dirall slint1
|
||||
compile-slint2: source dirall slint1
|
||||
|
||||
# internal
|
||||
dirall:
|
||||
|
@ -39,8 +38,6 @@ dirall:
|
|||
@$(ELCDIR)
|
||||
single:
|
||||
@$(info ==================== $@ ====================)
|
||||
native:
|
||||
@$(info ==================== $@ ====================)
|
||||
source: cleanelc
|
||||
@$(info ==================== $@ ====================)
|
||||
@$(foreach elc,$(LISPC),$(MAKE) $(elc) && $(RM) $(elc);)
|
||||
|
@ -52,10 +49,6 @@ slint1:
|
|||
@$(info Compiling single $(abspath $<)...)
|
||||
-@$(ELC) $<
|
||||
|
||||
%.eln: %.el
|
||||
@$(info Native compiling single $(abspath $<)...)
|
||||
-@$(ELN) $<
|
||||
|
||||
autoloads: cleanauto $(LISPI) $(LISPV)
|
||||
|
||||
$(LISPV): $(LISPF)
|
||||
|
|
61
lisp/ob-C.el
61
lisp/ob-C.el
|
@ -1,6 +1,6 @@
|
|||
;;; ob-C.el --- Babel Functions for C and Similar Languages -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2010-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2010-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Thierry Banel
|
||||
|
@ -93,45 +93,44 @@ parameter may be used, like rdmd --chatty"
|
|||
is currently being evaluated.")
|
||||
|
||||
(defun org-babel-execute:cpp (body params)
|
||||
"Execute BODY according to its header arguments PARAMS.
|
||||
"Execute BODY according to PARAMS.
|
||||
This function calls `org-babel-execute:C++'."
|
||||
(org-babel-execute:C++ body params))
|
||||
|
||||
(defun org-babel-expand-body:cpp (body params)
|
||||
"Expand C++ BODY with org-babel according to its header arguments PARAMS."
|
||||
"Expand a block of C++ code with org-babel according to its header arguments."
|
||||
(org-babel-expand-body:C++ body params))
|
||||
|
||||
(defun org-babel-execute:C++ (body params)
|
||||
"Execute C++ BODY with org-babel according to its header arguments PARAMS.
|
||||
"Execute a block of C++ code with org-babel.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
(let ((org-babel-c-variant 'cpp)) (org-babel-C-execute body params)))
|
||||
|
||||
(defun org-babel-expand-body:C++ (body params)
|
||||
"Expand C++ BODY with org-babel according to its header arguments PARAMS."
|
||||
"Expand a block of C++ code with org-babel according to its header arguments."
|
||||
(let ((org-babel-c-variant 'cpp)) (org-babel-C-expand-C++ body params)))
|
||||
|
||||
(defun org-babel-execute:D (body params)
|
||||
"Execute D BODY with org-babel according to its header arguments PARAMS.
|
||||
"Execute a block of D code with org-babel.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
(let ((org-babel-c-variant 'd)) (org-babel-C-execute body params)))
|
||||
|
||||
(defun org-babel-expand-body:D (body params)
|
||||
"Expand D BODY with org-babel according to its header arguments PARAMS."
|
||||
"Expand a block of D code with org-babel according to its header arguments."
|
||||
(let ((org-babel-c-variant 'd)) (org-babel-C-expand-D body params)))
|
||||
|
||||
(defun org-babel-execute:C (body params)
|
||||
"Execute a C BODY according to its header arguments PARAMS.
|
||||
"Execute a block of C code with org-babel.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
(let ((org-babel-c-variant 'c)) (org-babel-C-execute body params)))
|
||||
|
||||
(defun org-babel-expand-body:C (body params)
|
||||
"Expand C BODY according to its header arguments PARAMS."
|
||||
"Expand a block of C code with org-babel according to its header arguments."
|
||||
(let ((org-babel-c-variant 'c)) (org-babel-C-expand-C body params)))
|
||||
|
||||
(defun org-babel-C-execute (body params)
|
||||
"Execute C/C++/D BODY according to its header arguments PARAMS.
|
||||
This function should only be called by `org-babel-execute:C' or
|
||||
`org-babel-execute:C++' or `org-babel-execute:D'."
|
||||
"This function should only be called by `org-babel-execute:C'
|
||||
or `org-babel-execute:C++' or `org-babel-execute:D'."
|
||||
(let* ((tmp-src-file (org-babel-temp-file
|
||||
"C-src-"
|
||||
(pcase org-babel-c-variant
|
||||
|
@ -197,11 +196,11 @@ This function should only be called by `org-babel-execute:C' or
|
|||
)))
|
||||
|
||||
(defun org-babel-C-expand-C++ (body params)
|
||||
"Expand C/C++ BODY with according to its header arguments PARAMS."
|
||||
"Expand a block of C/C++ code with org-babel according to its header arguments."
|
||||
(org-babel-C-expand-C body params))
|
||||
|
||||
(defun org-babel-C-expand-C (body params)
|
||||
"Expand C/C++ BODY according to its header arguments PARAMS."
|
||||
"Expand a block of C/C++ code with org-babel according to its header arguments."
|
||||
(let ((vars (org-babel--get-vars params))
|
||||
(colnames (cdr (assq :colname-names params)))
|
||||
(main-p (not (string= (cdr (assq :main params)) "no")))
|
||||
|
@ -213,9 +212,7 @@ This function should only be called by `org-babel-execute:C' or
|
|||
nil))
|
||||
(namespaces (org-babel-read
|
||||
(cdr (assq :namespaces params))
|
||||
nil))
|
||||
(prologue (cdr (assq :prologue params)))
|
||||
(epilogue (cdr (assq :epilogue params))))
|
||||
nil)))
|
||||
(when (stringp includes)
|
||||
(setq includes (split-string includes)))
|
||||
(when (stringp namespaces)
|
||||
|
@ -229,11 +226,6 @@ This function should only be called by `org-babel-execute:C' or
|
|||
(nconc result (list (concat y " " x)))
|
||||
(setq y nil)))
|
||||
(setq defines (cdr result))))
|
||||
(setq body
|
||||
(concat
|
||||
(and prologue (concat prologue "\n"))
|
||||
body
|
||||
(and epilogue (concat "\n" epilogue "\n"))))
|
||||
(mapconcat 'identity
|
||||
(list
|
||||
;; includes
|
||||
|
@ -277,7 +269,7 @@ This function should only be called by `org-babel-execute:C' or
|
|||
body) "\n") "\n")))
|
||||
|
||||
(defun org-babel-C-expand-D (body params)
|
||||
"Expand D BODY according to its header arguments PARAMS."
|
||||
"Expand a block of D code with org-babel according to its header arguments."
|
||||
(let ((vars (org-babel--get-vars params))
|
||||
(colnames (cdr (assq :colname-names params)))
|
||||
(main-p (not (string= (cdr (assq :main params)) "no")))
|
||||
|
@ -321,15 +313,13 @@ This function should only be called by `org-babel-execute:C' or
|
|||
(format "int main() {\n%s\nreturn 0;\n}\n" body)))
|
||||
|
||||
(defun org-babel-prep-session:C (_session _params)
|
||||
"Throw and error that sessions are not supported.
|
||||
This function does nothing as C is a compiled language with no support
|
||||
for sessions."
|
||||
"This function does nothing as C is a compiled language with no
|
||||
support for sessions."
|
||||
(error "C is a compiled language -- no support for sessions"))
|
||||
|
||||
(defun org-babel-load-session:C (_session _body _params)
|
||||
"Throw and error that sessions are not supported.
|
||||
This function does nothing as C is a compiled language with no support
|
||||
for sessions."
|
||||
"This function does nothing as C is a compiled language with no
|
||||
support for sessions."
|
||||
(error "C is a compiled language -- no support for sessions"))
|
||||
|
||||
;; helper functions
|
||||
|
@ -349,7 +339,7 @@ FORMAT can be either a format string or a function which is called with VAL."
|
|||
(type
|
||||
(pcase basetype
|
||||
(`integerp '("int" "%d"))
|
||||
(`floatp '("double" "%s")) ;; %f rounds, use %s to print the float literally
|
||||
(`floatp '("double" "%f"))
|
||||
(`stringp
|
||||
(list
|
||||
(if (eq org-babel-c-variant 'd) "string" "const char*")
|
||||
|
@ -389,11 +379,10 @@ FORMAT can be either a format string or a function which is called with VAL."
|
|||
type))))
|
||||
|
||||
(defun org-babel-C-val-to-base-type (val)
|
||||
"Determine the base type of VAL.
|
||||
The type is:
|
||||
- `integerp' if all base values are integers;
|
||||
- `floatp' if all base values are either floating points or integers;
|
||||
- `stringp' otherwise."
|
||||
"Determine the base type of VAL which may be
|
||||
`integerp' if all base values are integers
|
||||
`floatp' if all base values are either floating points or integers
|
||||
`stringp' otherwise."
|
||||
(cond
|
||||
((integerp val) 'integerp)
|
||||
((floatp val) 'floatp)
|
||||
|
@ -412,7 +401,7 @@ The type is:
|
|||
(t 'stringp)))
|
||||
|
||||
(defun org-babel-C-var-to-C (pair)
|
||||
"Convert PAIR of (var . val) C variable assignment."
|
||||
"Convert an elisp val into a string of C code specifying a var of the same value."
|
||||
;; TODO list support
|
||||
(let ((var (car pair))
|
||||
(val (cdr pair)))
|
||||
|
|
54
lisp/ob-R.el
54
lisp/ob-R.el
|
@ -1,6 +1,6 @@
|
|||
;;; ob-R.el --- Babel Functions for R -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Dan Davison
|
||||
|
@ -36,7 +36,7 @@
|
|||
(require 'ob)
|
||||
|
||||
(declare-function orgtbl-to-tsv "org-table" (table params))
|
||||
(declare-function run-ess-r "ext:ess-r-mode" (&optional start-args))
|
||||
(declare-function R "ext:essd-r" (&optional start-args))
|
||||
(declare-function inferior-ess-send-input "ext:ess-inf" ())
|
||||
(declare-function ess-make-buffer-current "ext:ess-inf" ())
|
||||
(declare-function ess-eval-buffer "ext:ess-inf" (vis))
|
||||
|
@ -64,7 +64,6 @@
|
|||
(colormodel . :any)
|
||||
(useDingbats . :any)
|
||||
(horizontal . :any)
|
||||
(async . ((yes no)))
|
||||
(results . ((file list vector table scalar verbatim)
|
||||
(raw html latex org code pp drawer)
|
||||
(replace silent none append prepend)
|
||||
|
@ -92,6 +91,15 @@ this variable.")
|
|||
:version "24.1"
|
||||
:type 'string)
|
||||
|
||||
(defvar ess-current-process-name) ; dynamically scoped
|
||||
(defvar ess-local-process-name) ; dynamically scoped
|
||||
(defun org-babel-edit-prep:R (info)
|
||||
(let ((session (cdr (assq :session (nth 2 info)))))
|
||||
(when (and session
|
||||
(string-prefix-p "*" session)
|
||||
(string-suffix-p "*" session))
|
||||
(org-babel-R-initiate-session session nil))))
|
||||
|
||||
;; The usage of utils::read.table() ensures that the command
|
||||
;; read.table() can be found even in circumstances when the utils
|
||||
;; package is not in the search path from R.
|
||||
|
@ -148,7 +156,7 @@ This function is used when the table does not contain a header.")
|
|||
"\n"))
|
||||
|
||||
(defun org-babel-execute:R (body params)
|
||||
"Execute a block of R code BODY according to PARAMS.
|
||||
"Execute a block of R code.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
(save-excursion
|
||||
(let* ((result-params (cdr (assq :result-params params)))
|
||||
|
@ -207,8 +215,7 @@ This function is called by `org-babel-execute-src-block'."
|
|||
;; helper functions
|
||||
|
||||
(defun org-babel-variable-assignments:R (params)
|
||||
"Return list of R statements assigning the block's variables.
|
||||
Retrieve variables from PARAMS."
|
||||
"Return list of R statements assigning the block's variables."
|
||||
(let ((vars (org-babel--get-vars params)))
|
||||
(mapcar
|
||||
(lambda (pair)
|
||||
|
@ -254,44 +261,41 @@ Retrieve variables from PARAMS."
|
|||
(t (format "%s <- %S" name (prin1-to-string value))))))
|
||||
|
||||
|
||||
(defvar ess-current-process-name) ; dynamically scoped
|
||||
(defvar ess-local-process-name) ; dynamically scoped
|
||||
(defvar ess-ask-for-ess-directory) ; dynamically scoped
|
||||
(defvar ess-gen-proc-buffer-name-function) ; defined in ess-inf.el
|
||||
(defun org-babel-R-initiate-session (session params)
|
||||
"Create or return the current R SESSION buffer.
|
||||
Use PARAMS to set default directory when creating a new session."
|
||||
"If there is not a current R process then create one."
|
||||
(unless (string= session "none")
|
||||
(let* ((session (or session "*R*"))
|
||||
(ess-ask-for-ess-directory
|
||||
(and (boundp 'ess-ask-for-ess-directory)
|
||||
ess-ask-for-ess-directory
|
||||
(not (cdr (assq :dir params)))))
|
||||
;; Make ESS name the process buffer as SESSION.
|
||||
(ess-gen-proc-buffer-name-function
|
||||
(lambda (_) session)))
|
||||
(let ((session (or session "*R*"))
|
||||
(ess-ask-for-ess-directory
|
||||
(and (boundp 'ess-ask-for-ess-directory)
|
||||
ess-ask-for-ess-directory
|
||||
(not (cdr (assq :dir params))))))
|
||||
(if (org-babel-comint-buffer-livep session)
|
||||
session
|
||||
(save-window-excursion
|
||||
(when (get-buffer session)
|
||||
;; Session buffer exists, but with dead process
|
||||
(set-buffer session))
|
||||
(org-require-package 'ess-r-mode "ESS")
|
||||
(set-buffer (run-ess-r))
|
||||
(org-require-package 'ess "ESS") (R)
|
||||
(let ((R-proc (get-process (or ess-local-process-name
|
||||
ess-current-process-name))))
|
||||
(while (process-get R-proc 'callbacks)
|
||||
(ess-wait-for-process R-proc)))
|
||||
(rename-buffer
|
||||
(if (bufferp session)
|
||||
(buffer-name session)
|
||||
(if (stringp session)
|
||||
session
|
||||
(buffer-name))))
|
||||
(current-buffer))))))
|
||||
|
||||
(defun org-babel-R-associate-session (session)
|
||||
"Associate R code buffer with an R session.
|
||||
Make SESSION be the inferior ESS process associated with the
|
||||
current code buffer."
|
||||
(when-let ((process (get-buffer-process session)))
|
||||
(setq ess-local-process-name (process-name process))
|
||||
(ess-make-buffer-current))
|
||||
(setq-local ess-gen-proc-buffer-name-function (lambda (_) session)))
|
||||
(setq ess-local-process-name
|
||||
(process-name (get-buffer-process session)))
|
||||
(ess-make-buffer-current))
|
||||
|
||||
(defvar org-babel-R-graphics-devices
|
||||
'((:bmp "bmp" "filename")
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-awk.el --- Babel Functions for Awk -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2011-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2011-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Maintainer: Tyler Smith <tyler@plantarum.ca>
|
||||
|
@ -48,18 +48,12 @@
|
|||
(defvar org-babel-awk-command "awk"
|
||||
"Name of the awk executable command.")
|
||||
|
||||
(defun org-babel-expand-body:awk (body params)
|
||||
(defun org-babel-expand-body:awk (body _params)
|
||||
"Expand BODY according to PARAMS, return the expanded body."
|
||||
(let ((prologue (cdr (assq :prologue params)))
|
||||
(epilogue (cdr (assq :epilogue params))))
|
||||
(concat
|
||||
(and prologue (concat prologue "\n"))
|
||||
body
|
||||
(and epilogue (concat "\n" epilogue "\n")))))
|
||||
body)
|
||||
|
||||
(defun org-babel-execute:awk (body params)
|
||||
"Execute a block of Awk code BODY with org-babel.
|
||||
PARAMS is a plist of src block parameters .
|
||||
"Execute a block of Awk code with org-babel.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
(message "Executing Awk source code block")
|
||||
(let* ((result-params (cdr (assq :result-params params)))
|
||||
|
@ -106,9 +100,7 @@ This function is called by `org-babel-execute-src-block'."
|
|||
(cdr (assq :rowname-names params)) (cdr (assq :rownames params))))))
|
||||
|
||||
(defun org-babel-awk-var-to-awk (var &optional sep)
|
||||
"Return a printed value of VAR suitable for parsing with awk.
|
||||
SEP, when non-nil is a separator used when converting list values to awk
|
||||
table."
|
||||
"Return a printed value of VAR suitable for parsing with awk."
|
||||
(let ((echo-var (lambda (v) (if (stringp v) v (format "%S" v)))))
|
||||
(cond
|
||||
((and (listp var) (listp (car var)))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-calc.el --- Babel Functions for Calc -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2010-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2010-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Maintainer: Tom Gillespie <tgbugs@gmail.com>
|
||||
|
@ -44,19 +44,13 @@
|
|||
(defvar org-babel-default-header-args:calc nil
|
||||
"Default arguments for evaluating a calc source block.")
|
||||
|
||||
(defun org-babel-expand-body:calc (body params)
|
||||
"Expand BODY according to PARAMS, return the expanded body."
|
||||
(let ((prologue (cdr (assq :prologue params)))
|
||||
(epilogue (cdr (assq :epilogue params))))
|
||||
(concat
|
||||
(and prologue (concat prologue "\n"))
|
||||
body
|
||||
(and epilogue (concat "\n" epilogue "\n")))))
|
||||
(defun org-babel-expand-body:calc (body _params)
|
||||
"Expand BODY according to PARAMS, return the expanded body." body)
|
||||
|
||||
(defvar org--var-syms) ; Dynamically scoped from org-babel-execute:calc
|
||||
|
||||
(defun org-babel-execute:calc (body params)
|
||||
"Execute BODY of calc code with Babel using PARAMS."
|
||||
"Execute a block of calc code with Babel."
|
||||
(unless (get-buffer "*Calculator*")
|
||||
(save-window-excursion (calc) (calc-quit)))
|
||||
(let* ((vars (org-babel--get-vars params))
|
||||
|
@ -64,19 +58,7 @@
|
|||
(var-names (mapcar #'symbol-name org--var-syms)))
|
||||
(mapc
|
||||
(lambda (pair)
|
||||
(let ((val (cdr pair)))
|
||||
(calc-push-list
|
||||
;; For a vector, Calc follows the format (vec 1 2 3 ...) so
|
||||
;; a matrix becomes (vec (vec 1 2 3) (vec 4 5 6) ...). See
|
||||
;; the comments in "Arithmetic routines." section of
|
||||
;; calc.el.
|
||||
(list (if (listp val)
|
||||
(cons 'vec
|
||||
(if (null (cdr val))
|
||||
(car val)
|
||||
(mapcar (lambda (x) (if (listp x) (cons 'vec x) x))
|
||||
val)))
|
||||
val))))
|
||||
(calc-push-list (list (cdr pair)))
|
||||
(calc-store-into (car pair)))
|
||||
vars)
|
||||
(mapc
|
||||
|
@ -117,8 +99,6 @@
|
|||
(calc-pop 1)))))
|
||||
|
||||
(defun org-babel-calc-maybe-resolve-var (el)
|
||||
"Resolve user variables in EL.
|
||||
EL is taken from the output of `math-read-exprs'."
|
||||
(if (consp el)
|
||||
(if (and (eq 'var (car el)) (member (cadr el) org--var-syms))
|
||||
(progn
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-clojure.el --- Babel Functions for Clojure -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Joel Boehland, Eric Schulte, Oleh Krehel, Frederick Giasson
|
||||
;; Maintainer: Daniel Kraus <daniel@kraus.my>
|
||||
|
@ -237,9 +237,7 @@ or set the `:backend' header argument"))))
|
|||
"clojure" (format "clojure -A%s" alias)
|
||||
cmd0)
|
||||
cmd0)))
|
||||
(setq
|
||||
org-babel-comint-prompt-regexp-old comint-prompt-regexp
|
||||
comint-prompt-regexp inf-clojure-comint-prompt-regexp)
|
||||
(setq comint-prompt-regexp inf-clojure-comint-prompt-regexp)
|
||||
(funcall-interactively #'inf-clojure cmd)
|
||||
(goto-char (point-max))))
|
||||
(sit-for 1))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-comint.el --- Babel Functions for Interaction with Comint Buffers -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Keywords: literate programming, reproducible research, comint
|
||||
|
@ -58,47 +58,6 @@ executed inside the protection of `save-excursion' and
|
|||
(let ((comint-input-filter (lambda (_input) nil)))
|
||||
,@body))))))
|
||||
|
||||
(defvar-local org-babel-comint-prompt-regexp-old nil
|
||||
"Fallback regexp used to detect prompt.")
|
||||
|
||||
(defcustom org-babel-comint-fallback-regexp-threshold 5.0
|
||||
"Waiting time until trying to use fallback regexp to detect prompt.
|
||||
This is useful when prompt unexpectedly changes."
|
||||
:type 'float
|
||||
:group 'org-babel)
|
||||
|
||||
(defun org-babel-comint--set-fallback-prompt ()
|
||||
"Swap `comint-prompt-regexp' and `org-babel-comint-prompt-regexp-old'."
|
||||
(when org-babel-comint-prompt-regexp-old
|
||||
(let ((tmp comint-prompt-regexp))
|
||||
(setq comint-prompt-regexp org-babel-comint-prompt-regexp-old
|
||||
org-babel-comint-prompt-regexp-old tmp))))
|
||||
|
||||
(defun org-babel-comint--prompt-filter (string &optional prompt-regexp)
|
||||
"Remove PROMPT-REGEXP from STRING.
|
||||
|
||||
PROMPT-REGEXP defaults to `comint-prompt-regexp'."
|
||||
(let* ((prompt-regexp (or prompt-regexp comint-prompt-regexp))
|
||||
;; We need newline in case if we do progressive replacement
|
||||
;; of agglomerated comint prompts with `comint-prompt-regexp'
|
||||
;; containing ^.
|
||||
(separator "org-babel-comint--prompt-filter-separator\n"))
|
||||
(while (string-match-p prompt-regexp string)
|
||||
(setq string
|
||||
(replace-regexp-in-string
|
||||
(format "\\(?:%s\\)?\\(?:%s\\)[ \t]*" separator prompt-regexp)
|
||||
separator string)))
|
||||
(delete "" (split-string string separator))))
|
||||
|
||||
(defun org-babel-comint--echo-filter (string &optional echo)
|
||||
"Remove ECHO from STRING."
|
||||
(and echo string
|
||||
(string-match
|
||||
(replace-regexp-in-string "\n" "[\r\n]+" (regexp-quote echo))
|
||||
string)
|
||||
(setq string (substring string (match-end 0))))
|
||||
string)
|
||||
|
||||
(defmacro org-babel-comint-with-output (meta &rest body)
|
||||
"Evaluate BODY in BUFFER and return process output.
|
||||
Will wait until EOE-INDICATOR appears in the output, then return
|
||||
|
@ -115,7 +74,9 @@ or user `keyboard-quit' during execution of body."
|
|||
(let ((buffer (nth 0 meta))
|
||||
(eoe-indicator (nth 1 meta))
|
||||
(remove-echo (nth 2 meta))
|
||||
(full-body (nth 3 meta)))
|
||||
(full-body (nth 3 meta))
|
||||
(org-babel-comint-prompt-separator
|
||||
"org-babel-comint-prompt-separator"))
|
||||
`(org-babel-comint-in-buffer ,buffer
|
||||
(let* ((string-buffer "")
|
||||
(comint-output-filter-functions
|
||||
|
@ -132,39 +93,43 @@ or user `keyboard-quit' during execution of body."
|
|||
;; pass FULL-BODY to process
|
||||
,@body
|
||||
;; wait for end-of-evaluation indicator
|
||||
(let ((start-time (current-time)))
|
||||
(while (progn
|
||||
(goto-char comint-last-input-end)
|
||||
(not (save-excursion
|
||||
(and (re-search-forward
|
||||
(regexp-quote ,eoe-indicator) nil t)
|
||||
(re-search-forward
|
||||
comint-prompt-regexp nil t)))))
|
||||
(accept-process-output
|
||||
(get-buffer-process (current-buffer))
|
||||
org-babel-comint-fallback-regexp-threshold)
|
||||
(when (and org-babel-comint-prompt-regexp-old
|
||||
(> (float-time (time-since start-time))
|
||||
org-babel-comint-fallback-regexp-threshold)
|
||||
(progn
|
||||
(goto-char comint-last-input-end)
|
||||
(save-excursion
|
||||
(and
|
||||
(re-search-forward
|
||||
(regexp-quote ,eoe-indicator) nil t)
|
||||
(re-search-forward
|
||||
org-babel-comint-prompt-regexp-old nil t)))))
|
||||
(org-babel-comint--set-fallback-prompt))))
|
||||
(while (progn
|
||||
(goto-char comint-last-input-end)
|
||||
(not (save-excursion
|
||||
(and (re-search-forward
|
||||
(regexp-quote ,eoe-indicator) nil t)
|
||||
(re-search-forward
|
||||
comint-prompt-regexp nil t)))))
|
||||
(accept-process-output (get-buffer-process (current-buffer))))
|
||||
;; replace cut dangling text
|
||||
(goto-char (process-mark (get-buffer-process (current-buffer))))
|
||||
(insert dangling-text)
|
||||
|
||||
;; remove echo'd FULL-BODY from input
|
||||
(and ,remove-echo ,full-body
|
||||
(setq string-buffer (org-babel-comint--echo-filter string-buffer ,full-body)))
|
||||
|
||||
;; Filter out prompts.
|
||||
(org-babel-comint--prompt-filter string-buffer)))))
|
||||
(setq string-buffer
|
||||
(replace-regexp-in-string
|
||||
;; Sometimes, we get multiple agglomerated
|
||||
;; prompts together in a single output:
|
||||
;; "prompt prompt prompt output"
|
||||
;; Remove them progressively, so that
|
||||
;; possible "^" in the prompt regexp gets to
|
||||
;; work as we remove the heading prompt
|
||||
;; instance.
|
||||
(if (string-prefix-p "^" comint-prompt-regexp)
|
||||
(format "^\\(%s\\)+" (substring comint-prompt-regexp 1))
|
||||
comint-prompt-regexp)
|
||||
,org-babel-comint-prompt-separator
|
||||
string-buffer))
|
||||
;; remove echo'd FULL-BODY from input
|
||||
(when (and ,remove-echo ,full-body
|
||||
(string-match
|
||||
(replace-regexp-in-string
|
||||
"\n" "[\r\n]+" (regexp-quote (or ,full-body "")))
|
||||
string-buffer))
|
||||
(setq string-buffer (substring string-buffer (match-end 0))))
|
||||
(delete "" (split-string
|
||||
string-buffer
|
||||
,org-babel-comint-prompt-separator))))))
|
||||
|
||||
(defun org-babel-comint-input-command (buffer cmd)
|
||||
"Pass CMD to BUFFER.
|
||||
|
@ -180,23 +145,11 @@ The input will not be echoed."
|
|||
Note: this is only safe when waiting for the result of a single
|
||||
statement (not large blocks of code)."
|
||||
(org-babel-comint-in-buffer buffer
|
||||
(let ((start-time (current-time)))
|
||||
(while (progn
|
||||
(goto-char comint-last-input-end)
|
||||
(not (and (re-search-forward comint-prompt-regexp nil t)
|
||||
(goto-char (match-beginning 0)))))
|
||||
(accept-process-output
|
||||
(get-buffer-process buffer)
|
||||
org-babel-comint-fallback-regexp-threshold)
|
||||
(when (and org-babel-comint-prompt-regexp-old
|
||||
(> (float-time (time-since start-time))
|
||||
org-babel-comint-fallback-regexp-threshold)
|
||||
(progn
|
||||
(goto-char comint-last-input-end)
|
||||
(save-excursion
|
||||
(re-search-forward
|
||||
org-babel-comint-prompt-regexp-old nil t))))
|
||||
(org-babel-comint--set-fallback-prompt))))))
|
||||
(while (progn
|
||||
(goto-char comint-last-input-end)
|
||||
(not (and (re-search-forward comint-prompt-regexp nil t)
|
||||
(goto-char (match-beginning 0)))))
|
||||
(accept-process-output (get-buffer-process buffer)))))
|
||||
|
||||
(defun org-babel-comint-eval-invisibly-and-wait-for-file
|
||||
(buffer file string &optional period)
|
||||
|
@ -239,8 +192,8 @@ comint process. It should return a string that will be passed
|
|||
to `org-babel-insert-result'.")
|
||||
|
||||
(defvar-local org-babel-comint-async-dangling nil
|
||||
"Dangling piece of the last process output, as a string.
|
||||
Used when `org-babel-comint-async-indicator' is spread across multiple
|
||||
"Dangling piece of the last process output, in case
|
||||
`org-babel-comint-async-indicator' is spread across multiple
|
||||
comint outputs due to buffering.")
|
||||
|
||||
(defun org-babel-comint-use-async (params)
|
||||
|
@ -268,8 +221,6 @@ STRING contains the output originally inserted into the comint buffer."
|
|||
(file-callback org-babel-comint-async-file-callback)
|
||||
(combined-string (concat org-babel-comint-async-dangling string))
|
||||
(new-dangling combined-string)
|
||||
;; Assumes comint filter called with session buffer current
|
||||
(session-dir default-directory)
|
||||
;; list of UUID's matched by `org-babel-comint-async-indicator'
|
||||
uuid-list)
|
||||
(with-temp-buffer
|
||||
|
@ -294,8 +245,7 @@ STRING contains the output originally inserted into the comint buffer."
|
|||
(let* ((info (org-babel-get-src-block-info))
|
||||
(params (nth 2 info))
|
||||
(result-params
|
||||
(cdr (assq :result-params params)))
|
||||
(default-directory session-dir))
|
||||
(cdr (assq :result-params params))))
|
||||
(org-babel-insert-result
|
||||
(funcall file-callback
|
||||
(nth
|
||||
|
@ -325,10 +275,9 @@ STRING contains the output originally inserted into the comint buffer."
|
|||
until (and (equal (match-string 1) "start")
|
||||
(equal (match-string 2) uuid))
|
||||
finally return (+ 1 (match-end 0)))))
|
||||
;; Remove prompt
|
||||
(res-promptless (org-trim (string-join (mapcar #'org-trim (org-babel-comint--prompt-filter res-str-raw)) "\n") "\n"))
|
||||
;; Apply user callback
|
||||
(res-str (funcall org-babel-comint-async-chunk-callback res-promptless)))
|
||||
;; Apply callback to clean up the result
|
||||
(res-str (funcall org-babel-comint-async-chunk-callback
|
||||
res-str-raw)))
|
||||
;; Search for uuid in associated org-buffers to insert results
|
||||
(cl-loop for buf in org-buffers
|
||||
until (with-current-buffer buf
|
||||
|
@ -339,8 +288,7 @@ STRING contains the output originally inserted into the comint buffer."
|
|||
(let* ((info (org-babel-get-src-block-info))
|
||||
(params (nth 2 info))
|
||||
(result-params
|
||||
(cdr (assq :result-params params)))
|
||||
(default-directory session-dir))
|
||||
(cdr (assq :result-params params))))
|
||||
(org-babel-insert-result
|
||||
res-str result-params info))
|
||||
t))))
|
||||
|
|
549
lisp/ob-core.el
549
lisp/ob-core.el
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
;;; ob-css.el --- Babel Functions for CSS -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Keywords: literate programming, reproducible research
|
||||
|
@ -36,7 +36,7 @@
|
|||
(defvar org-babel-default-header-args:css '())
|
||||
|
||||
(defun org-babel-execute:css (body _params)
|
||||
"Execute BODY of CSS code.
|
||||
"Execute a block of CSS code.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
body)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-ditaa.el --- Babel Functions for ditaa -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Keywords: literate programming, reproducible research
|
||||
|
@ -83,11 +83,11 @@ Do not leave leading or trailing spaces in this string."
|
|||
:type 'string)
|
||||
|
||||
(defun org-babel-execute:ditaa (body params)
|
||||
"Execute BODY of Ditaa code with org-babel according to PARAMS.
|
||||
"Execute a block of Ditaa code with org-babel.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
(let* ((out-file (or (cdr (assq :file params))
|
||||
(error
|
||||
"Ditaa code block requires :file header argument")))
|
||||
"ditaa code block requires :file header argument")))
|
||||
(cmdline (cdr (assq :cmdline params)))
|
||||
(java (cdr (assq :java params)))
|
||||
(in-file (org-babel-temp-file "ditaa-"))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-dot.el --- Babel Functions for dot -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Maintainer: Justin Abrahms <justin@abrah.ms>
|
||||
|
@ -51,9 +51,7 @@
|
|||
|
||||
(defun org-babel-expand-body:dot (body params)
|
||||
"Expand BODY according to PARAMS, return the expanded body."
|
||||
(let ((vars (org-babel--get-vars params))
|
||||
(prologue (cdr (assq :prologue params)))
|
||||
(epilogue (cdr (assq :epilogue params))))
|
||||
(let ((vars (org-babel--get-vars params)))
|
||||
(mapc
|
||||
(lambda (pair)
|
||||
(let ((name (symbol-name (car pair)))
|
||||
|
@ -66,13 +64,10 @@
|
|||
t
|
||||
t))))
|
||||
vars)
|
||||
(concat
|
||||
(and prologue (concat prologue "\n"))
|
||||
body
|
||||
(and epilogue (concat "\n" epilogue "\n")))))
|
||||
body))
|
||||
|
||||
(defun org-babel-execute:dot (body params)
|
||||
"Execute Dot BODY with org-babel according to PARAMS.
|
||||
"Execute a block of Dot code with org-babel.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
(let* ((out-file (cdr (or (assq :file params)
|
||||
(error "You need to specify a :file parameter"))))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-emacs-lisp.el --- Babel Functions for Emacs-lisp Code -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Keywords: literate programming, reproducible research
|
||||
|
@ -53,23 +53,18 @@ by `org-edit-src-code'.")
|
|||
"Expand BODY according to PARAMS, return the expanded body."
|
||||
(let ((vars (org-babel--get-vars params))
|
||||
(print-level nil)
|
||||
(print-length nil)
|
||||
(prologue (cdr (assq :prologue params)))
|
||||
(epilogue (cdr (assq :epilogue params))))
|
||||
(print-length nil))
|
||||
(if (null vars) (concat body "\n")
|
||||
(format "(let (%s)\n%s%s%s\n)"
|
||||
(format "(let (%s)\n%s\n)"
|
||||
(mapconcat
|
||||
(lambda (var)
|
||||
(format "%S" `(,(car var) ',(cdr var))))
|
||||
vars "\n ")
|
||||
(if prologue (concat prologue "\n ") "")
|
||||
body
|
||||
(if epilogue (concat "\n " epilogue "\n") "")))))
|
||||
body))))
|
||||
|
||||
(defun org-babel-execute:emacs-lisp (body params)
|
||||
"Execute emacs-lisp code BODY according to PARAMS."
|
||||
"Execute a block of emacs-lisp code with Babel."
|
||||
(let* ((lexical (cdr (assq :lexical params)))
|
||||
(session (cdr (assq :session params)))
|
||||
(result-params (cdr (assq :result-params params)))
|
||||
(body (format (if (member "output" result-params)
|
||||
"(with-output-to-string %s\n)"
|
||||
|
@ -80,8 +75,6 @@ by `org-edit-src-code'.")
|
|||
(concat "(pp " body ")")
|
||||
body))
|
||||
(org-babel-emacs-lisp-lexical lexical))))
|
||||
(when (and session (not (equal session "none")))
|
||||
(error "ob-emacs-lisp backend does not support sessions"))
|
||||
(org-babel-result-cond result-params
|
||||
(let ((print-level nil)
|
||||
(print-length nil))
|
||||
|
@ -107,17 +100,12 @@ and the LEXICAL argument to `eval'."
|
|||
(defun org-babel-edit-prep:emacs-lisp (info)
|
||||
"Set `lexical-binding' in Org edit buffer.
|
||||
Set `lexical-binding' in Org edit buffer according to the
|
||||
corresponding :lexical source block argument provide in the INFO
|
||||
channel, as returned by `org-babel-get-src-block-info'."
|
||||
corresponding :lexical source block argument."
|
||||
(setq lexical-binding
|
||||
(org-babel-emacs-lisp-lexical
|
||||
(org-babel-read
|
||||
(cdr (assq :lexical (nth 2 info)))))))
|
||||
|
||||
(defun org-babel-prep-session:emacs-lisp (_session _params)
|
||||
"Return an error because we do not support sessions."
|
||||
(error "ob-emacs-lisp backend does not support sessions"))
|
||||
|
||||
(org-babel-make-language-alias "elisp" "emacs-lisp")
|
||||
|
||||
(provide 'ob-emacs-lisp)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-eshell.el --- Babel Functions for Eshell -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2018-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2018-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: stardiviner <numbchild@gmail.com>
|
||||
;; Maintainer: stardiviner <numbchild@gmail.com>
|
||||
|
@ -94,11 +94,10 @@ The PARAMS are variables assignments."
|
|||
session))
|
||||
|
||||
(defun org-babel-variable-assignments:eshell (params)
|
||||
"Convert ob-eshell variables from PARAMS into Eshell variables assignments."
|
||||
"Convert ob-eshell :var specified variables into Eshell variables assignments."
|
||||
(mapcar
|
||||
(lambda (pair)
|
||||
;; Use `ignore' to suppress value in the command output.
|
||||
(format "(ignore (setq %s %S))" (car pair) (cdr pair)))
|
||||
(format "(setq %s %S)" (car pair) (cdr pair)))
|
||||
(org-babel--get-vars params)))
|
||||
|
||||
(defun org-babel-load-session:eshell (session body params)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-eval.el --- Babel Functions for External Code Evaluation -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Keywords: literate programming, reproducible research, comint
|
||||
|
@ -106,6 +106,11 @@ returned."
|
|||
(error-file (if error-buffer (org-babel-temp-file "ob-error-") nil))
|
||||
(shell-file-name (org-babel--get-shell-file-name))
|
||||
exit-status)
|
||||
;; There is an error in `process-file' when `error-file' exists.
|
||||
;; This is fixed in Emacs trunk as of 2012-12-21; let's use this
|
||||
;; workaround for now.
|
||||
(unless (file-remote-p default-directory)
|
||||
(delete-file error-file))
|
||||
;; we always call this with 'replace, remove conditional
|
||||
;; Replace specified region with output from command.
|
||||
(org-babel--write-temp-buffer-input-file input-file)
|
||||
|
|
121
lisp/ob-exp.el
121
lisp/ob-exp.el
|
@ -1,6 +1,6 @@
|
|||
;;; ob-exp.el --- Exportation of Babel Source Blocks -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Authors: Eric Schulte
|
||||
;; Dan Davison
|
||||
|
@ -32,10 +32,8 @@
|
|||
(declare-function org-babel-lob-get-info "ob-lob" (&optional datum no-eval))
|
||||
(declare-function org-element-at-point "org-element" (&optional pom cached-only))
|
||||
(declare-function org-element-context "org-element" (&optional element))
|
||||
(declare-function org-element-property "org-element-ast" (property node))
|
||||
(declare-function org-element-begin "org-element" (node))
|
||||
(declare-function org-element-end "org-element" (node))
|
||||
(declare-function org-element-type "org-element-ast" (node &optional anonymous))
|
||||
(declare-function org-element-property "org-element" (property element))
|
||||
(declare-function org-element-type "org-element" (element))
|
||||
(declare-function org-escape-code-in-string "org-src" (s))
|
||||
(declare-function org-export-copy-buffer "ox"
|
||||
(&optional buffer drop-visibility
|
||||
|
@ -43,7 +41,8 @@
|
|||
drop-locals))
|
||||
(declare-function org-in-commented-heading-p "org" (&optional no-inheritance element))
|
||||
(declare-function org-in-archived-heading-p "org" (&optional no-inheritance element))
|
||||
(declare-function org-src-preserve-indentation-p "org-src" (node))
|
||||
|
||||
(defvar org-src-preserve-indentation)
|
||||
|
||||
(defcustom org-export-use-babel t
|
||||
"Switch controlling code evaluation and header processing during export.
|
||||
|
@ -172,7 +171,7 @@ this template."
|
|||
;; buffer.
|
||||
(org-fold-core-ignore-modifications
|
||||
(while (re-search-forward regexp nil t)
|
||||
(setq element (save-match-data (org-element-at-point)))
|
||||
(setq element (org-element-at-point))
|
||||
(unless (save-match-data
|
||||
(or (org-in-commented-heading-p nil element)
|
||||
(org-in-archived-heading-p nil element)))
|
||||
|
@ -196,11 +195,11 @@ this template."
|
|||
nil)
|
||||
(type type)))
|
||||
(begin
|
||||
(copy-marker (org-element-begin element)))
|
||||
(copy-marker (org-element-property :begin element)))
|
||||
(end
|
||||
(copy-marker
|
||||
(save-excursion
|
||||
(goto-char (org-element-end element))
|
||||
(goto-char (org-element-property :end element))
|
||||
(skip-chars-backward " \r\t\n")
|
||||
(point)))))
|
||||
(pcase type
|
||||
|
@ -218,27 +217,22 @@ this template."
|
|||
(goto-char begin)
|
||||
(let ((replacement
|
||||
(org-babel-exp-do-export info 'inline)))
|
||||
(cond
|
||||
((equal replacement "")
|
||||
;; Replacement code is empty: remove
|
||||
;; inline source block, including extra
|
||||
;; white space that might have been
|
||||
;; created when inserting results.
|
||||
(delete-region begin
|
||||
(progn (goto-char end)
|
||||
(skip-chars-forward " \t")
|
||||
(point))))
|
||||
((not replacement)
|
||||
;; Replacement code cannot be determined.
|
||||
;; Leave the code block as is.
|
||||
(goto-char end))
|
||||
;; Otherwise: remove inline source block
|
||||
;; but preserve following white spaces.
|
||||
;; Then insert value.
|
||||
((not (string= replacement
|
||||
(buffer-substring begin end)))
|
||||
(delete-region begin end)
|
||||
(insert replacement))))))
|
||||
(if (equal replacement "")
|
||||
;; Replacement code is empty: remove
|
||||
;; inline source block, including extra
|
||||
;; white space that might have been
|
||||
;; created when inserting results.
|
||||
(delete-region begin
|
||||
(progn (goto-char end)
|
||||
(skip-chars-forward " \t")
|
||||
(point)))
|
||||
;; Otherwise: remove inline source block
|
||||
;; but preserve following white spaces.
|
||||
;; Then insert value.
|
||||
(unless (string= replacement
|
||||
(buffer-substring begin end))
|
||||
(delete-region begin end)
|
||||
(insert replacement))))))
|
||||
((or `babel-call `inline-babel-call)
|
||||
(org-babel-exp-do-export
|
||||
(or (org-babel-lob-get-info element)
|
||||
|
@ -254,27 +248,21 @@ this template."
|
|||
;; the object/element, including any extra
|
||||
;; white space that might have been created
|
||||
;; when including results.
|
||||
(cond
|
||||
((equal rep "")
|
||||
(delete-region
|
||||
begin
|
||||
(progn (goto-char end)
|
||||
(if (not (eq type 'babel-call))
|
||||
(progn (skip-chars-forward " \t")
|
||||
(point))
|
||||
(skip-chars-forward " \r\t\n")
|
||||
(line-beginning-position)))))
|
||||
((not rep)
|
||||
;; Replacement code cannot be determined.
|
||||
;; Leave the code block as is.
|
||||
(goto-char end))
|
||||
(t
|
||||
(if (equal rep "")
|
||||
(delete-region
|
||||
begin
|
||||
(progn (goto-char end)
|
||||
(if (not (eq type 'babel-call))
|
||||
(progn (skip-chars-forward " \t")
|
||||
(point))
|
||||
(skip-chars-forward " \r\t\n")
|
||||
(line-beginning-position))))
|
||||
;; Otherwise, preserve trailing
|
||||
;; spaces/newlines and then, insert
|
||||
;; replacement string.
|
||||
(goto-char begin)
|
||||
(delete-region begin end)
|
||||
(insert rep)))))
|
||||
(insert rep))))
|
||||
(`src-block
|
||||
(let ((match-start (copy-marker (match-beginning 0)))
|
||||
(ind (org-current-text-indentation)))
|
||||
|
@ -289,26 +277,28 @@ this template."
|
|||
((equal replacement "")
|
||||
(goto-char end)
|
||||
(skip-chars-forward " \r\t\n")
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(delete-region begin (point)))
|
||||
(t
|
||||
(if (org-src-preserve-indentation-p element)
|
||||
(if (or org-src-preserve-indentation
|
||||
(org-element-property
|
||||
:preserve-indent element))
|
||||
;; Indent only code block
|
||||
;; markers.
|
||||
(with-temp-buffer
|
||||
;; Do not use tabs for block
|
||||
;; indentation.
|
||||
(when (fboundp 'indent-tabs-mode)
|
||||
;; Do not use tabs for block
|
||||
;; indentation.
|
||||
(when (fboundp 'indent-tabs-mode)
|
||||
(indent-tabs-mode -1)
|
||||
;; FIXME: Emacs 26
|
||||
;; compatibility.
|
||||
(setq-local indent-tabs-mode nil))
|
||||
(insert replacement)
|
||||
(skip-chars-backward " \r\t\n")
|
||||
(indent-line-to ind)
|
||||
(goto-char 1)
|
||||
(indent-line-to ind)
|
||||
(setq replacement (buffer-string)))
|
||||
(insert replacement)
|
||||
(skip-chars-backward " \r\t\n")
|
||||
(indent-line-to ind)
|
||||
(goto-char 1)
|
||||
(indent-line-to ind)
|
||||
(setq replacement (buffer-string)))
|
||||
;; Indent everything.
|
||||
(with-temp-buffer
|
||||
;; Do not use tabs for block
|
||||
|
@ -342,12 +332,7 @@ this template."
|
|||
'(org-reference nil))))))
|
||||
|
||||
(defun org-babel-exp-do-export (info type &optional hash)
|
||||
"Return a string with the exported content of a code block defined by INFO.
|
||||
TYPE is the code block type: `block', `inline', or `lob'. HASH is the
|
||||
result hash.
|
||||
|
||||
Return nil when exported content cannot be determined.
|
||||
|
||||
"Return a string with the exported content of a code block.
|
||||
The function respects the value of the :exports header argument."
|
||||
(let ((silently (lambda () (let ((session (cdr (assq :session (nth 2 info)))))
|
||||
(unless (equal "none" session)
|
||||
|
@ -361,10 +346,7 @@ The function respects the value of the :exports header argument."
|
|||
("results" (org-babel-exp-results info type nil hash) "")
|
||||
("both"
|
||||
(org-babel-exp-results info type nil hash)
|
||||
(org-babel-exp-code info type))
|
||||
(unknown-value
|
||||
(warn "Unknown value of src block parameter :exports %S" unknown-value)
|
||||
nil))))
|
||||
(org-babel-exp-code info type)))))
|
||||
|
||||
(defcustom org-babel-exp-code-template
|
||||
"#+begin_src %lang%switches%flags\n%body\n#+end_src"
|
||||
|
@ -410,7 +392,7 @@ replaced with its value."
|
|||
:package-version '(Org . "8.3"))
|
||||
|
||||
(defun org-babel-exp-code (info type)
|
||||
"Return the original code block of TYPE defined by INFO, formatted for export."
|
||||
"Return the original code block formatted for export."
|
||||
(setf (nth 1 info)
|
||||
(if (string= "strip-export" (cdr (assq :noweb (nth 2 info))))
|
||||
(replace-regexp-in-string
|
||||
|
@ -440,9 +422,6 @@ replaced with its value."
|
|||
|
||||
(defun org-babel-exp-results (info type &optional silent hash)
|
||||
"Evaluate and return the results of the current code block for export.
|
||||
INFO is as returned by `org-babel-get-src-block-info'. TYPE is the
|
||||
code block type. HASH is the result hash.
|
||||
|
||||
Results are prepared in a manner suitable for export by Org mode.
|
||||
This function is called by `org-babel-exp-do-export'. The code
|
||||
block will be evaluated. Optional argument SILENT can be used to
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-forth.el --- Babel Functions for Forth -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2014-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2014-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Keywords: literate programming, reproducible research, forth
|
||||
|
@ -45,7 +45,7 @@
|
|||
"Default header arguments for forth code blocks.")
|
||||
|
||||
(defun org-babel-execute:forth (body params)
|
||||
"Execute Forth BODY according to PARAMS.
|
||||
"Execute a block of Forth code with org-babel.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
(if (string= "none" (cdr (assq :session params)))
|
||||
(error "Non-session evaluation not supported for Forth code blocks")
|
||||
|
@ -55,7 +55,6 @@ This function is called by `org-babel-execute-src-block'."
|
|||
(car (last all-results))))))
|
||||
|
||||
(defun org-babel-forth-session-execute (body params)
|
||||
"Execute Forth BODY in session defined via PARAMS."
|
||||
(org-require-package 'forth-mode)
|
||||
(let ((proc (forth-proc))
|
||||
(rx " \\(\n:\\|compiled\n\\|ok\n\\)")
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-fortran.el --- Babel Functions for Fortran -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2011-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2011-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Authors: Sergey Litvinov
|
||||
;; Eric Schulte
|
||||
|
@ -51,8 +51,7 @@
|
|||
:type 'string)
|
||||
|
||||
(defun org-babel-execute:fortran (body params)
|
||||
"Execute Fortran BODY according to PARAMS.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
"This function should only be called by `org-babel-execute:fortran'."
|
||||
(let* ((tmp-src-file (org-babel-temp-file "fortran-src-" ".F90"))
|
||||
(tmp-bin-file (org-babel-temp-file "fortran-bin-" org-babel-exeext))
|
||||
(cmdline (cdr (assq :cmdline params)))
|
||||
|
@ -83,10 +82,9 @@ This function is called by `org-babel-execute-src-block'."
|
|||
(cdr (assq :rowname-names params)) (cdr (assq :rownames params)))))))
|
||||
|
||||
(defun org-babel-expand-body:fortran (body params)
|
||||
"Expand a fortran BODY according to its header arguments defined in PARAMS."
|
||||
"Expand a block of fortran or fortran code with org-babel according to
|
||||
its header arguments."
|
||||
(let ((vars (org-babel--get-vars params))
|
||||
(prologue (cdr (assq :prologue params)))
|
||||
(epilogue (cdr (assq :epilogue params)))
|
||||
(main-p (not (string= (cdr (assq :main params)) "no")))
|
||||
(includes (or (cdr (assq :includes params))
|
||||
(org-babel-read (org-entry-get nil "includes" t))))
|
||||
|
@ -109,20 +107,12 @@ This function is called by `org-babel-execute-src-block'."
|
|||
(concat
|
||||
;; variables
|
||||
(mapconcat 'org-babel-fortran-var-to-fortran vars "\n")
|
||||
(and prologue (concat prologue "\n"))
|
||||
body
|
||||
(and prologue (concat prologue "\n")))
|
||||
body)
|
||||
params)
|
||||
(concat
|
||||
(and prologue (concat prologue "\n"))
|
||||
body
|
||||
(and epilogue (concat "\n" epilogue "\n"))))
|
||||
"\n")
|
||||
"\n")))
|
||||
body) "\n") "\n")))
|
||||
|
||||
(defun org-babel-fortran-ensure-main-wrap (body params)
|
||||
"Wrap BODY in a \"program ... end program\" block if none exists.
|
||||
Variable assignments are derived from PARAMS."
|
||||
"Wrap body in a \"program ... end program\" block if none exists."
|
||||
(if (string-match "^[ \t]*program\\>" (capitalize body))
|
||||
(let ((vars (org-babel--get-vars params)))
|
||||
(when vars (error "Cannot use :vars if `program' statement is present"))
|
||||
|
@ -130,22 +120,20 @@ Variable assignments are derived from PARAMS."
|
|||
(format "program main\n%s\nend program main\n" body)))
|
||||
|
||||
(defun org-babel-prep-session:fortran (_session _params)
|
||||
"Do nothing.
|
||||
This function does nothing as fortran is a compiled language with no
|
||||
"This function does nothing as fortran is a compiled language with no
|
||||
support for sessions."
|
||||
(error "Fortran is a compiled languages -- no support for sessions"))
|
||||
|
||||
(defun org-babel-load-session:fortran (_session _body _params)
|
||||
"Do nothing.
|
||||
This function does nothing as fortran is a compiled language with no
|
||||
"This function does nothing as fortran is a compiled language with no
|
||||
support for sessions."
|
||||
(error "Fortran is a compiled languages -- no support for sessions"))
|
||||
|
||||
;; helper functions
|
||||
|
||||
(defun org-babel-fortran-var-to-fortran (pair)
|
||||
"Convert PAIR of (VAR . VAL) into a string of fortran code.
|
||||
The fortran code will assign VAL to VAR variable."
|
||||
"Convert an elisp val into a string of fortran code specifying a var
|
||||
of the same value."
|
||||
;; TODO list support
|
||||
(let ((var (car pair))
|
||||
(val (cdr pair)))
|
||||
|
@ -176,7 +164,7 @@ The fortran code will assign VAL to VAR variable."
|
|||
(error "The type of parameter %s is not supported by ob-fortran" var)))))
|
||||
|
||||
(defun org-babel-fortran-transform-list (val)
|
||||
"Return a fortran representation of enclose syntactic list VAL."
|
||||
"Return a fortran representation of enclose syntactic lists."
|
||||
(if (listp val)
|
||||
(concat "(/" (mapconcat #'org-babel-fortran-transform-list val ", ") "/)")
|
||||
(format "%S" val)))
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
;;; ob-gnuplot.el --- Babel Functions for Gnuplot -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Maintainer: Ihor Radchenko <yantar92 at posteo dot net>
|
||||
;; Maintainer: Ihor Radchenko <yantar92@gmail.com>
|
||||
;; Keywords: literate programming, reproducible research
|
||||
;; URL: https://orgmode.org
|
||||
|
||||
|
@ -45,7 +45,6 @@
|
|||
|
||||
(require 'ob)
|
||||
(require 'org-macs)
|
||||
(require 'ox-ascii)
|
||||
|
||||
(declare-function org-time-string-to-time "org" (s))
|
||||
(declare-function orgtbl-to-generic "org-table" (table params))
|
||||
|
@ -187,7 +186,7 @@ code."
|
|||
;; value of the variable
|
||||
(mapc (lambda (pair)
|
||||
(setq body (replace-regexp-in-string
|
||||
(format "\\$%s" (car pair)) (cdr pair) body t t)))
|
||||
(format "\\$%s" (car pair)) (cdr pair) body)))
|
||||
vars)
|
||||
(when prologue (funcall add-to-body prologue))
|
||||
(when epilogue (setq body (concat body "\n" epilogue)))
|
||||
|
@ -197,7 +196,7 @@ code."
|
|||
body))
|
||||
|
||||
(defun org-babel-execute:gnuplot (body params)
|
||||
"Execute Gnuplot BODY according to PARAMS.
|
||||
"Execute a block of Gnuplot code.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
(org-require-package 'gnuplot)
|
||||
(let ((session (cdr (assq :session params)))
|
||||
|
@ -252,8 +251,7 @@ This function is called by `org-babel-execute-src-block'."
|
|||
buffer)))
|
||||
|
||||
(defun org-babel-variable-assignments:gnuplot (params)
|
||||
"Return list of gnuplot statements assigning the block's variables.
|
||||
PARAMS is src block parameters alist defining variable assignments."
|
||||
"Return list of gnuplot statements assigning the block's variables."
|
||||
(mapcar
|
||||
(lambda (pair) (format "%s = \"%s\"" (car pair) (cdr pair)))
|
||||
(org-babel-gnuplot-process-vars params)))
|
||||
|
@ -297,29 +295,14 @@ Pass PARAMS through to `orgtbl-to-generic' when exporting TABLE."
|
|||
(require 'ox-org)
|
||||
(with-temp-file data-file
|
||||
(insert (let ((org-babel-gnuplot-timestamp-fmt
|
||||
(or (plist-get params :timefmt) "%Y-%m-%d-%H:%M:%S"))
|
||||
;; Create custom limited backend that will disable
|
||||
;; advanced ASCII export features that may alter the
|
||||
;; original data.
|
||||
(ob-gnuplot-data
|
||||
(org-export-create-backend
|
||||
:parent 'ascii
|
||||
:transcoders
|
||||
`(;; Do not try to resolve links. Export them verbatim.
|
||||
(link . (lambda (link _ _) (org-element-interpret-data link)))
|
||||
;; Drop emphasis markers from verbatim and code.
|
||||
;; This way, data can use verbatim when escaping
|
||||
;; is necessary and yet be readable by Gnuplot,
|
||||
;; which is not aware about Org's markup.
|
||||
(verbatim . (lambda (verbatim _ _) (org-element-property :value verbatim)))
|
||||
(code . (lambda (code _ _) (org-element-property :value code)))))))
|
||||
(or (plist-get params :timefmt) "%Y-%m-%d-%H:%M:%S")))
|
||||
(orgtbl-to-generic
|
||||
table
|
||||
(org-combine-plists
|
||||
`( :sep "\t" :fmt org-babel-gnuplot-quote-tsv-field
|
||||
'( :sep "\t" :fmt org-babel-gnuplot-quote-tsv-field
|
||||
;; Two setting below are needed to make :fmt work.
|
||||
:raw t
|
||||
:backend ,ob-gnuplot-data)
|
||||
:backend ascii)
|
||||
params)))))
|
||||
data-file)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-groovy.el --- Babel Functions for Groovy -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2013-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2013-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Miro Bezjak <bezjak.miro@gmail.com>
|
||||
;; Maintainer: Palak Mathur <palakmathur@gmail.com>
|
||||
|
@ -50,7 +50,7 @@ parameters may be used, like groovy -v"
|
|||
:type 'string)
|
||||
|
||||
(defun org-babel-execute:groovy (body params)
|
||||
"Execute Groovy BODY according to PARAMS.
|
||||
"Execute a block of Groovy code with org-babel.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
(message "Executing Groovy source code block")
|
||||
(let* ((processed-params (org-babel-process-params params))
|
||||
|
@ -81,7 +81,6 @@ println(new Runner().run())
|
|||
(defun org-babel-groovy-evaluate
|
||||
(session body &optional result-type result-params)
|
||||
"Evaluate BODY in external Groovy process.
|
||||
SESSION must be nil as sessions are not yet supported.
|
||||
If RESULT-TYPE equals `output' then return standard output as a string.
|
||||
If RESULT-TYPE equals `value' then return the value of the last statement
|
||||
in BODY as elisp."
|
||||
|
@ -108,8 +107,9 @@ in BODY as elisp."
|
|||
(error "Sessions are not (yet) supported for Groovy"))
|
||||
|
||||
(defun org-babel-groovy-initiate-session (&optional _session)
|
||||
"Do nothing.
|
||||
Sessions are not supported in Groovy."
|
||||
"If there is not a current inferior-process-buffer in SESSION
|
||||
then create. Return the initialized session. Sessions are not
|
||||
supported in Groovy."
|
||||
nil)
|
||||
|
||||
(provide 'ob-groovy)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-haskell.el --- Babel Functions for Haskell -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Maintainer: Lawrence Bottorff <borgauf@gmail.com>
|
||||
|
@ -61,7 +61,7 @@
|
|||
|
||||
(defvar org-babel-haskell-lhs2tex-command "lhs2tex")
|
||||
|
||||
(defvar org-babel-haskell-eoe "org-babel-haskell-eoe")
|
||||
(defvar org-babel-haskell-eoe "\"org-babel-haskell-eoe\"")
|
||||
|
||||
(defvar haskell-prompt-regexp)
|
||||
|
||||
|
@ -77,35 +77,8 @@ a parameter, such as \"ghc -v\"."
|
|||
(defconst org-babel-header-args:haskell '((compile . :any))
|
||||
"Haskell-specific header arguments.")
|
||||
|
||||
|
||||
(defun org-babel-haskell-with-session--worker (params todo)
|
||||
"See `org-babel-haskell-with-session'."
|
||||
(let* ((sn (cdr (assq :session params)))
|
||||
(session (org-babel-haskell-initiate-session sn params))
|
||||
(one-shot (equal sn "none")))
|
||||
(unwind-protect
|
||||
(funcall todo session)
|
||||
(when (and one-shot (buffer-live-p session))
|
||||
;; As we don't control how the session temporary buffer is
|
||||
;; created, we need to explicitly work around the hooks and
|
||||
;; query functions.
|
||||
(with-current-buffer session
|
||||
(let ((kill-buffer-query-functions nil)
|
||||
(kill-buffer-hook nil))
|
||||
(kill-buffer session)))))))
|
||||
|
||||
(defmacro org-babel-haskell-with-session (session-symbol params &rest body)
|
||||
"Get the session identified by PARAMS and run BODY with it.
|
||||
|
||||
Get or create a session, as needed to match PARAMS. Assign the session to
|
||||
SESSION-SYMBOL. Execute BODY. Destroy the session if needed.
|
||||
Return the value of the last form of BODY."
|
||||
(declare (indent 2) (debug (symbolp form body)))
|
||||
`(org-babel-haskell-with-session--worker ,params (lambda (,session-symbol) ,@body)))
|
||||
|
||||
(defun org-babel-haskell-execute (body params)
|
||||
"Execute Haskell BODY according to PARAMS.
|
||||
This function should only be called by `org-babel-execute:haskell'."
|
||||
"This function should only be called by `org-babel-execute:haskell'."
|
||||
(let* ((tmp-src-file (org-babel-temp-file "Haskell-src-" ".hs"))
|
||||
(tmp-bin-file
|
||||
(org-babel-process-file-name
|
||||
|
@ -152,60 +125,36 @@ This function should only be called by `org-babel-execute:haskell'."
|
|||
(org-require-package 'inf-haskell "haskell-mode")
|
||||
(add-hook 'inferior-haskell-hook
|
||||
(lambda ()
|
||||
(setq-local
|
||||
org-babel-comint-prompt-regexp-old comint-prompt-regexp
|
||||
comint-prompt-regexp
|
||||
(concat haskell-prompt-regexp "\\|^λ?> "))))
|
||||
(org-babel-haskell-with-session session params
|
||||
(cl-labels
|
||||
((send-txt-to-ghci (txt)
|
||||
(insert txt) (comint-send-input nil t))
|
||||
(send-eoe ()
|
||||
(send-txt-to-ghci (concat "putStrLn \"" org-babel-haskell-eoe "\"\n")))
|
||||
(comint-with-output (todo)
|
||||
(let ((comint-preoutput-filter-functions
|
||||
(cons 'ansi-color-filter-apply
|
||||
comint-preoutput-filter-functions)))
|
||||
(org-babel-comint-with-output
|
||||
(session org-babel-haskell-eoe nil nil)
|
||||
(funcall todo)))))
|
||||
(let* ((result-type (cdr (assq :result-type params)))
|
||||
(full-body (org-babel-expand-body:generic
|
||||
body params
|
||||
(org-babel-variable-assignments:haskell params)))
|
||||
(raw (pcase result-type
|
||||
(`output
|
||||
(comint-with-output
|
||||
(lambda () (send-txt-to-ghci (org-trim full-body)) (send-eoe))))
|
||||
(`value
|
||||
;; We first compute the value and store it,
|
||||
;; ignoring any output.
|
||||
(comint-with-output
|
||||
(lambda ()
|
||||
(send-txt-to-ghci "__LAST_VALUE_IMPROBABLE_NAME__=()::()\n")
|
||||
(send-txt-to-ghci (org-trim full-body))
|
||||
(send-txt-to-ghci "__LAST_VALUE_IMPROBABLE_NAME__=it\n")
|
||||
(send-eoe)))
|
||||
;; We now display and capture the value.
|
||||
(comint-with-output
|
||||
(lambda()
|
||||
(send-txt-to-ghci "__LAST_VALUE_IMPROBABLE_NAME__\n")
|
||||
(send-eoe))))))
|
||||
(results (mapcar #'org-strip-quotes
|
||||
(cdr (member org-babel-haskell-eoe
|
||||
(reverse (mapcar #'org-trim raw)))))))
|
||||
(org-babel-reassemble-table
|
||||
(let ((result
|
||||
(pcase result-type
|
||||
(`output (mapconcat #'identity (reverse results) "\n"))
|
||||
(`value (car results)))))
|
||||
(org-babel-result-cond (cdr (assq :result-params params))
|
||||
result (when result (org-babel-script-escape result))))
|
||||
(org-babel-pick-name (cdr (assq :colname-names params))
|
||||
(cdr (assq :colname-names params)))
|
||||
(org-babel-pick-name (cdr (assq :rowname-names params))
|
||||
(cdr (assq :rowname-names params))))))))
|
||||
|
||||
(setq-local comint-prompt-regexp
|
||||
(concat haskell-prompt-regexp "\\|^λ?> "))))
|
||||
(let* ((session (cdr (assq :session params)))
|
||||
(result-type (cdr (assq :result-type params)))
|
||||
(full-body (org-babel-expand-body:generic
|
||||
body params
|
||||
(org-babel-variable-assignments:haskell params)))
|
||||
(session (org-babel-haskell-initiate-session session params))
|
||||
(comint-preoutput-filter-functions
|
||||
(cons 'ansi-color-filter-apply comint-preoutput-filter-functions))
|
||||
(raw (org-babel-comint-with-output
|
||||
(session org-babel-haskell-eoe nil full-body)
|
||||
(insert (org-trim full-body))
|
||||
(comint-send-input nil t)
|
||||
(insert org-babel-haskell-eoe)
|
||||
(comint-send-input nil t)))
|
||||
(results (mapcar #'org-strip-quotes
|
||||
(cdr (member org-babel-haskell-eoe
|
||||
(reverse (mapcar #'org-trim raw)))))))
|
||||
(org-babel-reassemble-table
|
||||
(let ((result
|
||||
(pcase result-type
|
||||
(`output (mapconcat #'identity (reverse results) "\n"))
|
||||
(`value (car results)))))
|
||||
(org-babel-result-cond (cdr (assq :result-params params))
|
||||
result (when result (org-babel-script-escape result))))
|
||||
(org-babel-pick-name (cdr (assq :colname-names params))
|
||||
(cdr (assq :colname-names params)))
|
||||
(org-babel-pick-name (cdr (assq :rowname-names params))
|
||||
(cdr (assq :rowname-names params))))))
|
||||
|
||||
(defun org-babel-execute:haskell (body params)
|
||||
"Execute a block of Haskell code."
|
||||
|
@ -214,65 +163,13 @@ This function should only be called by `org-babel-execute:haskell'."
|
|||
(org-babel-interpret-haskell body params)
|
||||
(org-babel-haskell-execute body params))))
|
||||
|
||||
|
||||
|
||||
|
||||
;; Variable defined in inf-haskell (haskell-mode package).
|
||||
(defvar inferior-haskell-buffer)
|
||||
(defvar inferior-haskell-root-dir)
|
||||
|
||||
(defun org-babel-haskell-initiate-session (&optional session-name _params)
|
||||
(defun org-babel-haskell-initiate-session (&optional _session _params)
|
||||
"Initiate a haskell session.
|
||||
Return the initialized session, i.e. the buffer for this session.
|
||||
When SESSION-NAME is nil, use a global session named
|
||||
\"*ob-haskell*\". When SESSION-NAME is the string \"none\", use
|
||||
a temporary buffer. Else, (re)use the session named
|
||||
SESSION-NAME. The buffer name is the session name. See also
|
||||
`org-babel-haskell-with-session'."
|
||||
If there is not a current inferior-process-buffer in SESSION
|
||||
then create one. Return the initialized session."
|
||||
(org-require-package 'inf-haskell "haskell-mode")
|
||||
(cond
|
||||
((equal "none" session-name)
|
||||
;; Temporary buffer name.
|
||||
(setq session-name (generate-new-buffer-name " *ob-haskell-tmp*")))
|
||||
((eq nil session-name)
|
||||
;; The global default session. As haskell-mode is using the buffer
|
||||
;; named "*haskell*", we stay away from it.
|
||||
(setq session-name "*ob-haskell*"))
|
||||
((not (stringp session-name))
|
||||
(error "session-name must be a string")))
|
||||
(let ((session (get-buffer session-name)))
|
||||
;; NOTE: By construction, as SESSION-NAME is a string, session is
|
||||
;; either nil or a live buffer.
|
||||
(save-window-excursion
|
||||
(or (org-babel-comint-buffer-livep session)
|
||||
(let ((inferior-haskell-buffer session))
|
||||
;; As inferior-haskell expects the buffer to be named
|
||||
;; "*haskell*", we temporarily rename it while executing
|
||||
;; `run-haskell' (unless the user explicitly requested to
|
||||
;; use the name "*haskell*").
|
||||
(when (not (equal "*haskell*" session-name))
|
||||
(when (bufferp session)
|
||||
(when (bufferp "*haskell*")
|
||||
(user-error "Conflicting buffer '*haskell*', rename it or kill it"))
|
||||
(with-current-buffer session (rename-buffer "*haskell*"))))
|
||||
(unwind-protect
|
||||
(let ((inferior-haskell-root-dir default-directory))
|
||||
(run-haskell)
|
||||
(sleep-for 0.25)
|
||||
(setq session inferior-haskell-buffer))
|
||||
(when (and (not (equal "*haskell*" session-name))
|
||||
(bufferp session))
|
||||
(with-current-buffer session (rename-buffer session-name))))
|
||||
;; Disable secondary prompt: If we do not do this,
|
||||
;; org-comint may treat secondary prompts as a part of
|
||||
;; output.
|
||||
(org-babel-comint-input-command
|
||||
session
|
||||
":set prompt-cont \"\"")
|
||||
session)
|
||||
))
|
||||
session))
|
||||
|
||||
(or (get-buffer "*haskell*")
|
||||
(save-window-excursion (run-haskell) (sleep-for 0.25) (current-buffer))))
|
||||
|
||||
(defun org-babel-load-session:haskell (session body params)
|
||||
"Load BODY into SESSION."
|
||||
|
@ -329,7 +226,7 @@ constructs (header arguments, no-web syntax etc...) are ignored."
|
|||
(let* ((contents (buffer-string))
|
||||
(haskell-regexp
|
||||
(concat "^\\([ \t]*\\)#\\+begin_src[ \t]haskell*\\(.*\\)[\r\n]"
|
||||
"\\(\\(?:.\\|\n\\)*?\\)[\r\n][ \t]*#\\+end_src.*"))
|
||||
"\\([^\000]*?\\)[\r\n][ \t]*#\\+end_src.*"))
|
||||
(base-name (file-name-sans-extension (buffer-file-name)))
|
||||
(tmp-file (org-babel-temp-file "haskell-"))
|
||||
(tmp-org-file (concat tmp-file ".org"))
|
||||
|
@ -339,7 +236,6 @@ constructs (header arguments, no-web syntax etc...) are ignored."
|
|||
(command (concat org-babel-haskell-lhs2tex-command
|
||||
" " (org-babel-process-file-name lhs-file)
|
||||
" > " (org-babel-process-file-name tex-file)))
|
||||
;; FIXME: What if src block has :preserve-indentation flag?
|
||||
(preserve-indentp org-src-preserve-indentation)
|
||||
indentation)
|
||||
;; escape haskell source-code blocks
|
||||
|
@ -374,7 +270,7 @@ constructs (header arguments, no-web syntax etc...) are ignored."
|
|||
(goto-char (point-min)) (forward-line 2)
|
||||
(insert "%include polycode.fmt\n")
|
||||
;; ensure all \begin/end{code} statements start at the first column
|
||||
(while (re-search-forward "^[ \t]+\\\\begin{code}\\(?:.\\|\n\\)+\\\\end{code}" nil t)
|
||||
(while (re-search-forward "^[ \t]+\\\\begin{code}[^\000]+\\\\end{code}" nil t)
|
||||
(replace-match (save-match-data (org-remove-indentation (match-string 0)))
|
||||
t t))
|
||||
;; save org exported latex to a .lhs file
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-java.el --- org-babel functions for java evaluation -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2011-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2011-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Authors: Eric Schulte
|
||||
;; Dan Davison
|
||||
|
@ -341,13 +341,9 @@ is simplest to expand the code block from the inside out."
|
|||
(imports-val (assq :imports params))
|
||||
(imports (if imports-val
|
||||
(split-string (org-babel-read (cdr imports-val) nil) " ")
|
||||
nil))
|
||||
(prologue (cdr (assq :prologue params)))
|
||||
(epilogue (cdr (assq :epilogue params))))
|
||||
nil)))
|
||||
(with-temp-buffer
|
||||
(when prologue (insert prologue "\n"))
|
||||
(insert body)
|
||||
(when epilogue (insert "\n" epilogue))
|
||||
|
||||
;; wrap main. If there are methods defined, but no main method
|
||||
;; and no class, wrap everything in a generic main method.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-js.el --- Babel Functions for Javascript -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2010-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2010-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Keywords: literate programming, reproducible research, js
|
||||
|
@ -69,14 +69,11 @@
|
|||
:safe #'stringp)
|
||||
|
||||
(defvar org-babel-js-function-wrapper
|
||||
;; Note that newline after %s - it makes sure that closing
|
||||
;; parenthesis are not shadowed if the last line of the body is a
|
||||
;; line comment.
|
||||
"require('process').stdout.write(require('util').inspect(function(){%s\n}()));"
|
||||
"require('process').stdout.write(require('util').inspect(function(){%s}()));"
|
||||
"Javascript code to print value of body.")
|
||||
|
||||
(defun org-babel-execute:js (body params)
|
||||
"Execute Javascript BODY according to PARAMS.
|
||||
"Execute a block of Javascript code with org-babel.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
(let* ((org-babel-js-cmd (or (cdr (assq :cmd params)) org-babel-js-cmd))
|
||||
(session (cdr (assq :session params)))
|
||||
|
@ -158,8 +155,7 @@ specifying a variable of the same value."
|
|||
session))
|
||||
|
||||
(defun org-babel-variable-assignments:js (params)
|
||||
"Return list of Javascript statements assigning the block's variables.
|
||||
The variables are defined in PARAMS."
|
||||
"Return list of Javascript statements assigning the block's variables."
|
||||
(mapcar
|
||||
(lambda (pair) (format "var %s=%s;"
|
||||
(car pair) (org-babel-js-var-to-js (cdr pair))))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-julia.el --- org-babel functions for julia code evaluation -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2013-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2013-2023 Free Software Foundation, Inc.
|
||||
;; Authors: G. Jay Kerns
|
||||
;; Maintainer: Pedro Bruel <pedro.bruel@gmail.com>
|
||||
;; Keywords: literate programming, reproducible research, scientific computing
|
||||
|
@ -70,15 +70,12 @@
|
|||
(defvar ess-local-process-name) ; dynamically scoped
|
||||
(defvar ess-eval-visibly-p) ; dynamically scoped
|
||||
(defvar ess-local-customize-alist); dynamically scoped
|
||||
(defvar ess-gen-proc-buffer-name-function) ; defined in ess-inf.el
|
||||
(defun org-babel-julia-associate-session (session)
|
||||
"Associate R code buffer with an R session.
|
||||
Make SESSION be the inferior ESS process associated with the
|
||||
current code buffer."
|
||||
(when-let ((process (get-buffer-process session)))
|
||||
(setq ess-local-process-name (process-name process))
|
||||
(ess-make-buffer-current))
|
||||
(setq-local ess-gen-proc-buffer-name-function (lambda (_) session)))
|
||||
(defun org-babel-edit-prep:julia (info)
|
||||
(let ((session (cdr (assq :session (nth 2 info)))))
|
||||
(when (and session
|
||||
(string-prefix-p "*" session)
|
||||
(string-suffix-p "*" session))
|
||||
(org-babel-julia-initiate-session session nil))))
|
||||
|
||||
(defun org-babel-expand-body:julia (body params &optional _graphics-file)
|
||||
"Expand BODY according to PARAMS, return the expanded body."
|
||||
|
@ -184,13 +181,10 @@ end"
|
|||
(defun org-babel-julia-initiate-session (session params)
|
||||
"If there is not a current julia process then create one."
|
||||
(unless (string= session "none")
|
||||
(let* ((session (or session "*Julia*"))
|
||||
(ess-ask-for-ess-directory
|
||||
(and (bound-and-true-p ess-ask-for-ess-directory)
|
||||
(not (cdr (assq :dir params)))))
|
||||
;; Make ESS name the process buffer as SESSION.
|
||||
(ess-gen-proc-buffer-name-function
|
||||
(lambda (_) session)))
|
||||
(let ((session (or session "*Julia*"))
|
||||
(ess-ask-for-ess-directory
|
||||
(and (bound-and-true-p ess-ask-for-ess-directory)
|
||||
(not (cdr (assq :dir params))))))
|
||||
(if (org-babel-comint-buffer-livep session)
|
||||
session
|
||||
;; FIXME: Depending on `display-buffer-alist', (julia) may end up
|
||||
|
@ -204,6 +198,12 @@ end"
|
|||
(set-buffer session))
|
||||
(org-require-package 'ess "ESS")
|
||||
(set-buffer (julia))
|
||||
(rename-buffer
|
||||
(if (bufferp session)
|
||||
(buffer-name session)
|
||||
(if (stringp session)
|
||||
session
|
||||
(buffer-name))))
|
||||
(current-buffer))))))
|
||||
|
||||
(defun org-babel-julia-graphical-output-file (params)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-latex.el --- Babel Functions for LaTeX -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Keywords: literate programming, reproducible research
|
||||
|
@ -37,7 +37,7 @@
|
|||
(require 'ob)
|
||||
(require 'org-macs)
|
||||
|
||||
(declare-function org-latex-preview-create-image "org-latex-preview" (string tofile options buffer &optional type))
|
||||
(declare-function org-create-formula-image "org" (string tofile options buffer &optional type))
|
||||
(declare-function org-latex-compile "ox-latex" (texfile &optional snippet))
|
||||
(declare-function org-latex-guess-inputenc "ox-latex" (header))
|
||||
(declare-function org-splice-latex-header "org" (tpl def-pkg pkg snippets-p &optional extra))
|
||||
|
@ -48,10 +48,10 @@
|
|||
(defvar org-babel-tangle-lang-exts)
|
||||
(add-to-list 'org-babel-tangle-lang-exts '("latex" . "tex"))
|
||||
|
||||
(defvar org-latex-preview-header) ; From org-latex-preview.el
|
||||
(defvar org-latex-preview-appearance-options) ; From org-latex-preview.el
|
||||
(defvar org-latex-default-packages-alist) ; From org-latex-preview.el
|
||||
(defvar org-latex-packages-alist) ; From org-latex-preview.el
|
||||
(defvar org-format-latex-header) ; From org.el
|
||||
(defvar org-format-latex-options) ; From org.el
|
||||
(defvar org-latex-default-packages-alist) ; From org.el
|
||||
(defvar org-latex-packages-alist) ; From org.el
|
||||
|
||||
(defvar org-babel-default-header-args:latex
|
||||
'((:results . "latex") (:exports . "results"))
|
||||
|
@ -136,18 +136,12 @@ exporting the literal LaTeX source."
|
|||
(regexp-quote (format "%S" (car pair)))
|
||||
(if (stringp (cdr pair))
|
||||
(cdr pair) (format "%S" (cdr pair)))
|
||||
body t t)))
|
||||
body)))
|
||||
(org-babel--get-vars params))
|
||||
(let ((prologue (cdr (assq :prologue params)))
|
||||
(epilogue (cdr (assq :epilogue params))))
|
||||
(org-trim
|
||||
(concat
|
||||
(and prologue (concat prologue "\n"))
|
||||
body
|
||||
(and epilogue (concat "\n" epilogue "\n"))))))
|
||||
(org-trim body))
|
||||
|
||||
(defun org-babel-execute:latex (body params)
|
||||
"Execute LaTeX BODY according to PARAMS.
|
||||
"Execute a block of LaTeX code with Babel.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
(setq body (org-babel-expand-body:latex body params))
|
||||
(if (cdr (assq :file params))
|
||||
|
@ -167,11 +161,11 @@ This function is called by `org-babel-execute-src-block'."
|
|||
(append (cdr (assq :packages params)) org-latex-packages-alist)))
|
||||
(cond
|
||||
((and (string-suffix-p ".png" out-file) (not imagemagick))
|
||||
(let ((org-latex-preview-header
|
||||
(concat org-latex-preview-header "\n"
|
||||
(let ((org-format-latex-header
|
||||
(concat org-format-latex-header "\n"
|
||||
(mapconcat #'identity headers "\n"))))
|
||||
(org-latex-preview-create-image
|
||||
body out-file org-latex-preview-appearance-options in-buffer)))
|
||||
(org-create-formula-image
|
||||
body out-file org-format-latex-options in-buffer)))
|
||||
((string= "svg" extension)
|
||||
(with-temp-file tex-file
|
||||
(insert (concat (funcall org-babel-latex-preamble params)
|
||||
|
@ -238,7 +232,7 @@ This function is called by `org-babel-execute-src-block'."
|
|||
(insert
|
||||
(org-latex-guess-inputenc
|
||||
(org-splice-latex-header
|
||||
org-latex-preview-header
|
||||
org-format-latex-header
|
||||
(delq
|
||||
nil
|
||||
(mapcar
|
||||
|
@ -279,9 +273,7 @@ This function is called by `org-babel-execute-src-block'."
|
|||
body))
|
||||
|
||||
(defun org-babel-latex-convert-pdf (pdffile out-file im-in-options im-out-options)
|
||||
"Generate OUT-FILE from PDFFILE using imagemagick.
|
||||
IM-IN-OPTIONS are command line options for input file, as a string;
|
||||
and IM-OUT-OPTIONS are the output file options."
|
||||
"Generate a file from a pdf file using imagemagick."
|
||||
(let ((cmd (concat "convert " im-in-options " " pdffile " "
|
||||
im-out-options " " out-file)))
|
||||
(message "Converting pdffile file %s..." cmd)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-lilypond.el --- Babel Functions for Lilypond -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2010-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2010-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Martyn Jago
|
||||
;; Keywords: babel language, literate programming
|
||||
|
@ -40,8 +40,10 @@
|
|||
|
||||
(declare-function org-fold-show-all "org-fold" (&optional types))
|
||||
|
||||
;; FIXME: Doesn't this rather belong in lilypond-mode.el?
|
||||
(defalias 'lilypond-mode 'LilyPond-mode)
|
||||
|
||||
(add-to-list 'org-babel-tangle-lang-exts '("LilyPond" . "ly"))
|
||||
(add-to-list 'org-src-lang-modes '("lilypond" . "LilyPond"))
|
||||
|
||||
(defvar org-babel-default-header-args:lilypond '()
|
||||
"Default header arguments for lilypond code blocks.
|
||||
|
@ -58,13 +60,23 @@ and stored in `org-babel-default-header-args:lilypond'
|
|||
See `org-babel-lilypond-set-header-args'.")
|
||||
|
||||
(defvar org-babel-lilypond-compile-post-tangle t
|
||||
"When non-nil, compile tangled file after `org-babel-tangle'.")
|
||||
"Following the org-babel-tangle (C-c C-v t) command,
|
||||
org-babel-lilypond-compile-post-tangle determines whether ob-lilypond should
|
||||
automatically attempt to compile the resultant tangled file.
|
||||
If the value is nil, no automated compilation takes place.
|
||||
Default value is t.")
|
||||
|
||||
(defvar org-babel-lilypond-display-pdf-post-tangle t
|
||||
"When non-nil, display pdf after successful LilyPond compilation.")
|
||||
"Following a successful LilyPond compilation
|
||||
org-babel-lilypond-display-pdf-post-tangle determines whether to automate the
|
||||
drawing / redrawing of the resultant pdf. If the value is nil,
|
||||
the pdf is not automatically redrawn. Default value is t.")
|
||||
|
||||
(defvar org-babel-lilypond-play-midi-post-tangle t
|
||||
"When non-nil, play midi file after successful LilyPond compilation.")
|
||||
"Following a successful LilyPond compilation
|
||||
org-babel-lilypond-play-midi-post-tangle determines whether to automate the
|
||||
playing of the resultant midi file. If the value is nil,
|
||||
the midi file is not automatically played. Default value is t")
|
||||
|
||||
(defvar org-babel-lilypond-ly-command ""
|
||||
"Command to execute lilypond on your system.
|
||||
|
@ -131,9 +143,7 @@ blocks.")
|
|||
|
||||
(defun org-babel-expand-body:lilypond (body params)
|
||||
"Expand BODY according to PARAMS, return the expanded body."
|
||||
(let ((vars (org-babel--get-vars params))
|
||||
(prologue (cdr (assq :prologue params)))
|
||||
(epilogue (cdr (assq :epilogue params))))
|
||||
(let ((vars (org-babel--get-vars params)))
|
||||
(mapc
|
||||
(lambda (pair)
|
||||
(let ((name (symbol-name (car pair)))
|
||||
|
@ -142,75 +152,54 @@ blocks.")
|
|||
(replace-regexp-in-string
|
||||
(concat "$" (regexp-quote name))
|
||||
(if (stringp value) value (format "%S" value))
|
||||
body t t))))
|
||||
body))))
|
||||
vars)
|
||||
(concat
|
||||
(and prologue (concat prologue "\n"))
|
||||
body
|
||||
(and epilogue (concat "\n" epilogue "\n")))))
|
||||
body))
|
||||
|
||||
(defun org-babel-execute:lilypond (body params)
|
||||
"Execute LilyPond src block according to arrange mode.
|
||||
See `org-babel-execute-src-block' for BODY and PARAMS.
|
||||
When in arrange mode, tangle all blocks and process the result.
|
||||
Otherwise, execute block according to header settings."
|
||||
"This function is called by `org-babel-execute-src-block'.
|
||||
Depending on whether we are in arrange mode either:
|
||||
1. Attempt to execute lilypond block according to header settings
|
||||
(This is the default basic mode)
|
||||
2. Tangle all lilypond blocks and process the result (arrange mode)"
|
||||
(org-babel-lilypond-set-header-args org-babel-lilypond-arrange-mode)
|
||||
(if org-babel-lilypond-arrange-mode
|
||||
(org-babel-lilypond-tangle)
|
||||
(org-babel-lilypond-process-basic body params)))
|
||||
|
||||
(defun org-babel-lilypond-tangle ()
|
||||
"Tangle lilypond blocks, then `org-babel-liypond-execute-tangled-ly'."
|
||||
"ob-lilypond specific tangle, attempts to invoke
|
||||
=ly-execute-tangled-ly= if tangle is successful. Also passes
|
||||
specific arguments to =org-babel-tangle=."
|
||||
(interactive)
|
||||
(if (org-babel-tangle nil "yes" "lilypond")
|
||||
(org-babel-lilypond-execute-tangled-ly) nil))
|
||||
|
||||
;; https://lilypond.org/doc/v2.24/Documentation/usage/other-programs
|
||||
(defvar org-babel-lilypond-paper-settings
|
||||
"#(if (ly:get-option 'use-paper-size-for-page)
|
||||
(begin (ly:set-option 'use-paper-size-for-page #f)
|
||||
(ly:set-option 'tall-page-formats '%s)))
|
||||
\\paper {
|
||||
indent=0\\mm
|
||||
tagline=\"\"
|
||||
oddFooterMarkup=##f
|
||||
oddHeaderMarkup=##f
|
||||
bookTitleMarkup=##f
|
||||
scoreTitleMarkup=##f
|
||||
}\n"
|
||||
"The paper settings required to generate music fragments.
|
||||
They are needed for mixing music and text in basic-mode.")
|
||||
|
||||
(defun org-babel-lilypond-process-basic (body params)
|
||||
"Execute a lilypond block in basic mode.
|
||||
See `org-babel-execute-src-block' for BODY and PARAMS."
|
||||
"Execute a lilypond block in basic mode."
|
||||
(let* ((out-file (cdr (assq :file params)))
|
||||
(file-type (file-name-extension out-file))
|
||||
(cmdline (or (cdr (assq :cmdline params))
|
||||
""))
|
||||
(in-file (org-babel-temp-file "lilypond-")))
|
||||
|
||||
(with-temp-file in-file
|
||||
(insert
|
||||
(format org-babel-lilypond-paper-settings file-type)
|
||||
(org-babel-expand-body:generic body params)))
|
||||
(insert (org-babel-expand-body:generic body params)))
|
||||
(org-babel-eval
|
||||
(concat
|
||||
org-babel-lilypond-ly-command
|
||||
" -dbackend=eps "
|
||||
"-dno-gs-load-fonts "
|
||||
"-dinclude-eps-fonts "
|
||||
(or (assoc-default file-type
|
||||
'(("pdf" . "--pdf ")
|
||||
("eps" . "--eps ")))
|
||||
(or (cdr (assoc (file-name-extension out-file)
|
||||
'(("pdf" . "--pdf ")
|
||||
("ps" . "--ps ")
|
||||
("png" . "--png "))))
|
||||
"--png ")
|
||||
"--output="
|
||||
(file-name-sans-extension out-file)
|
||||
" "
|
||||
cmdline
|
||||
in-file)
|
||||
""))
|
||||
nil)
|
||||
in-file) "")) nil)
|
||||
|
||||
(defun org-babel-prep-session:lilypond (_session _params)
|
||||
"Return an error because LilyPond exporter does not support sessions."
|
||||
|
@ -230,7 +219,7 @@ If error in compilation, attempt to mark the error in lilypond org file."
|
|||
(delete-file org-babel-lilypond-temp-file))
|
||||
(rename-file org-babel-lilypond-tangled-file
|
||||
org-babel-lilypond-temp-file))
|
||||
(switch-to-buffer-other-window "*lilypond*")
|
||||
(org-switch-to-buffer-other-window "*lilypond*")
|
||||
(erase-buffer)
|
||||
(org-babel-lilypond-compile-lilyfile org-babel-lilypond-temp-file)
|
||||
(goto-char (point-min))
|
||||
|
@ -240,20 +229,27 @@ If error in compilation, attempt to mark the error in lilypond org file."
|
|||
(org-babel-lilypond-attempt-to-open-pdf org-babel-lilypond-temp-file)
|
||||
(org-babel-lilypond-attempt-to-play-midi org-babel-lilypond-temp-file)))))
|
||||
|
||||
;;Ignoring second arg for pre Org 9.7 compatibility
|
||||
(defun org-babel-lilypond-compile-lilyfile (filename &optional _)
|
||||
"Compile Lilypond FILENAME and check for compile errors."
|
||||
(message "Compiling %s..." filename)
|
||||
(let ((args (delq nil (list
|
||||
(and org-babel-lilypond-gen-png "--png")
|
||||
(and org-babel-lilypond-gen-html "--html")
|
||||
(and org-babel-lilypond-gen-pdf "--pdf")
|
||||
(and org-babel-lilypond-use-eps "-dbackend=eps")
|
||||
(and org-babel-lilypond-gen-svg "-dbackend=svg")
|
||||
(concat "--output=" (file-name-sans-extension filename))
|
||||
filename))))
|
||||
(apply #'call-process org-babel-lilypond-ly-command nil
|
||||
"*lilypond*" 'display args)))
|
||||
(defun org-babel-lilypond-compile-lilyfile (file-name &optional test)
|
||||
"Compile lilypond file and check for compile errors.
|
||||
FILE-NAME is full path to lilypond (.ly) file."
|
||||
(message "Compiling LilyPond...")
|
||||
(let ((arg-1 org-babel-lilypond-ly-command) ;program
|
||||
;; (arg-2 nil) ;infile
|
||||
(arg-3 "*lilypond*") ;buffer
|
||||
(arg-4 t) ;display
|
||||
(arg-5 (if org-babel-lilypond-gen-png "--png" "")) ;&rest...
|
||||
(arg-6 (if org-babel-lilypond-gen-html "--html" ""))
|
||||
(arg-7 (if org-babel-lilypond-gen-pdf "--pdf" ""))
|
||||
(arg-8 (if org-babel-lilypond-use-eps "-dbackend=eps" ""))
|
||||
(arg-9 (if org-babel-lilypond-gen-svg "-dbackend=svg" ""))
|
||||
(arg-10 (concat "--output=" (file-name-sans-extension file-name)))
|
||||
(arg-11 file-name))
|
||||
(if test
|
||||
`(,arg-1 ,nil ,arg-3 ,arg-4 ,arg-5 ,arg-6 ;; arg-2
|
||||
,arg-7 ,arg-8 ,arg-9 ,arg-10 ,arg-11)
|
||||
(call-process
|
||||
arg-1 nil arg-3 arg-4 arg-5 arg-6 ;; arg-2
|
||||
arg-7 arg-8 arg-9 arg-10 arg-11))))
|
||||
|
||||
(defun org-babel-lilypond-check-for-compile-error (file-name &optional test)
|
||||
"Check for compile error.
|
||||
|
@ -280,7 +276,7 @@ FILE-NAME is full path to lilypond file."
|
|||
"Mark the erroneous lines in the lilypond org buffer.
|
||||
FILE-NAME is full path to lilypond file.
|
||||
LINE is the erroneous line."
|
||||
(switch-to-buffer-other-window
|
||||
(org-switch-to-buffer-other-window
|
||||
(concat (file-name-nondirectory
|
||||
(org-babel-lilypond-switch-extension file-name ".org"))))
|
||||
(let ((temp (point)))
|
||||
|
@ -294,7 +290,7 @@ LINE is the erroneous line."
|
|||
(goto-char temp))))
|
||||
|
||||
(defun org-babel-lilypond-parse-line-num (&optional buffer)
|
||||
"Extract error line number in BUFFER or `current-buffer'."
|
||||
"Extract error line number."
|
||||
(when buffer (set-buffer buffer))
|
||||
(let ((start
|
||||
(and (search-backward ":" nil t)
|
||||
|
@ -427,7 +423,8 @@ These depend upon whether we are in Arrange mode i.e. MODE is t."
|
|||
ob-lilypond-header-args)))
|
||||
|
||||
(defun org-babel-lilypond-set-header-args (mode)
|
||||
"Set lilypond babel header according to MODE."
|
||||
"Set org-babel-default-header-args:lilypond
|
||||
dependent on ORG-BABEL-LILYPOND-ARRANGE-MODE."
|
||||
(setq org-babel-default-header-args:lilypond
|
||||
(org-babel-lilypond-get-header-args mode)))
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-lisp.el --- Babel Functions for Common Lisp -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Authors: Joel Boehland
|
||||
;; Eric Schulte
|
||||
|
@ -74,19 +74,13 @@ current directory string."
|
|||
(let* ((vars (org-babel--get-vars params))
|
||||
(result-params (cdr (assq :result-params params)))
|
||||
(print-level nil) (print-length nil)
|
||||
(prologue (cdr (assq :prologue params)))
|
||||
(epilogue (cdr (assq :epilogue params)))
|
||||
(body (if (null vars) (org-trim body)
|
||||
(concat "(let ("
|
||||
(mapconcat
|
||||
(lambda (var)
|
||||
(format "(%S (quote %S))" (car var) (cdr var)))
|
||||
vars "\n ")
|
||||
")\n"
|
||||
(and prologue (concat prologue "\n"))
|
||||
body
|
||||
(and epilogue (concat "\n" epilogue "\n"))
|
||||
")"))))
|
||||
")\n" body ")"))))
|
||||
(if (or (member "code" result-params)
|
||||
(member "pp" result-params))
|
||||
(format "(pprint %s)" body)
|
||||
|
@ -96,41 +90,37 @@ current directory string."
|
|||
"Execute a block of Common Lisp code with Babel.
|
||||
BODY is the contents of the block, as a string. PARAMS is
|
||||
a property list containing the parameters of the block."
|
||||
(let (eval-and-grab-output)
|
||||
(pcase org-babel-lisp-eval-fn
|
||||
(`slime-eval (org-require-package 'slime "SLIME")
|
||||
(setq eval-and-grab-output 'swank:eval-and-grab-output))
|
||||
(`sly-eval (org-require-package 'sly "SLY")
|
||||
(setq eval-and-grab-output 'slynk:eval-and-grab-output)))
|
||||
(org-babel-reassemble-table
|
||||
(let ((result
|
||||
(funcall (if (member "output" (cdr (assq :result-params params)))
|
||||
#'car #'cadr)
|
||||
(with-temp-buffer
|
||||
(insert (org-babel-expand-body:lisp body params))
|
||||
(funcall org-babel-lisp-eval-fn
|
||||
`(,eval-and-grab-output
|
||||
,(let ((dir (if (assq :dir params)
|
||||
(cdr (assq :dir params))
|
||||
default-directory)))
|
||||
(format
|
||||
(if dir (format org-babel-lisp-dir-fmt dir)
|
||||
"(progn %s\n)")
|
||||
(buffer-substring-no-properties
|
||||
(point-min) (point-max)))))
|
||||
(cdr (assq :package params)))))))
|
||||
(org-babel-result-cond (cdr (assq :result-params params))
|
||||
(org-strip-quotes result)
|
||||
(condition-case nil
|
||||
(read (org-babel-lisp-vector-to-list result))
|
||||
(error result))))
|
||||
(org-babel-pick-name (cdr (assq :colname-names params))
|
||||
(cdr (assq :colnames params)))
|
||||
(org-babel-pick-name (cdr (assq :rowname-names params))
|
||||
(cdr (assq :rownames params))))))
|
||||
(pcase org-babel-lisp-eval-fn
|
||||
(`slime-eval (org-require-package 'slime "SLIME"))
|
||||
(`sly-eval (org-require-package 'sly "SLY")))
|
||||
(org-babel-reassemble-table
|
||||
(let ((result
|
||||
(funcall (if (member "output" (cdr (assq :result-params params)))
|
||||
#'car #'cadr)
|
||||
(with-temp-buffer
|
||||
(insert (org-babel-expand-body:lisp body params))
|
||||
(funcall org-babel-lisp-eval-fn
|
||||
`(swank:eval-and-grab-output
|
||||
,(let ((dir (if (assq :dir params)
|
||||
(cdr (assq :dir params))
|
||||
default-directory)))
|
||||
(format
|
||||
(if dir (format org-babel-lisp-dir-fmt dir)
|
||||
"(progn %s\n)")
|
||||
(buffer-substring-no-properties
|
||||
(point-min) (point-max)))))
|
||||
(cdr (assq :package params)))))))
|
||||
(org-babel-result-cond (cdr (assq :result-params params))
|
||||
(org-strip-quotes result)
|
||||
(condition-case nil
|
||||
(read (org-babel-lisp-vector-to-list result))
|
||||
(error result))))
|
||||
(org-babel-pick-name (cdr (assq :colname-names params))
|
||||
(cdr (assq :colnames params)))
|
||||
(org-babel-pick-name (cdr (assq :rowname-names params))
|
||||
(cdr (assq :rownames params)))))
|
||||
|
||||
(defun org-babel-lisp-vector-to-list (results)
|
||||
"Convert #(...) values in RESULTS string into a (...) list."
|
||||
;; TODO: better would be to replace #(...) with [...]
|
||||
(replace-regexp-in-string "#(" "(" results))
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-lob.el --- Functions Supporting the Library of Babel -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Authors: Eric Schulte
|
||||
;; Dan Davison
|
||||
|
@ -34,8 +34,8 @@
|
|||
(declare-function org-babel-ref-split-args "ob-ref" (arg-string))
|
||||
(declare-function org-element-at-point "org-element" (&optional pom cached-only))
|
||||
(declare-function org-element-context "org-element" (&optional element))
|
||||
(declare-function org-element-property "org-element-ast" (property node))
|
||||
(declare-function org-element-type "org-element-ast" (node &optional anonymous))
|
||||
(declare-function org-element-property "org-element" (property element))
|
||||
(declare-function org-element-type "org-element" (element))
|
||||
|
||||
(defvar org-babel-library-of-babel nil
|
||||
"Library of source-code blocks.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-lua.el --- Org Babel functions for Lua evaluation -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2014, 2016-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2014, 2016-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Authors: Dieter Schoen
|
||||
;; Keywords: literate programming, reproducible research
|
||||
|
@ -82,7 +82,7 @@ This will typically be `lua-mode'."
|
|||
:type 'symbol)
|
||||
|
||||
(defun org-babel-execute:lua (body params)
|
||||
"Execute Lua BODY according to PARAMS.
|
||||
"Execute a block of Lua code with Babel.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
(let* ((session (org-babel-lua-initiate-session
|
||||
(cdr (assq :session params))))
|
||||
|
@ -129,8 +129,7 @@ VARS contains resolved variable references."
|
|||
;; helper functions
|
||||
|
||||
(defun org-babel-variable-assignments:lua (params)
|
||||
"Return a list of Lua statements assigning the block's variables.
|
||||
The variable definitions are defining in PARAMS."
|
||||
"Return a list of Lua statements assigning the block's variables."
|
||||
(mapcar
|
||||
(lambda (pair)
|
||||
(format "%s=%s"
|
||||
|
@ -177,20 +176,13 @@ Emacs-lisp table, otherwise return the results as a string."
|
|||
(cdr (assoc session org-babel-lua-buffers)))
|
||||
|
||||
(defun org-babel-lua-with-earmuffs (session)
|
||||
"Return buffer name for SESSION, as *SESSION*."
|
||||
(let ((name (if (stringp session) session (format "%s" session))))
|
||||
(if (and (string= "*" (substring name 0 1))
|
||||
(string= "*" (substring name (- (length name) 1))))
|
||||
name
|
||||
(format "*%s*" name))))
|
||||
|
||||
(defun org-babel-session-buffer:lua (session &optional _)
|
||||
"Return session buffer name for SESSION."
|
||||
(or (org-babel-lua-session-buffer session)
|
||||
(org-babel-lua-with-earmuffs session)))
|
||||
|
||||
(defun org-babel-lua-without-earmuffs (session)
|
||||
"Remove stars around *SESSION*, leaving SESSION."
|
||||
(let ((name (if (stringp session) session (format "%s" session))))
|
||||
(if (and (string= "*" (substring name 0 1))
|
||||
(string= "*" (substring name (- (length name) 1))))
|
||||
|
@ -289,11 +281,7 @@ fd:close()")
|
|||
|
||||
(defun org-babel-lua-evaluate
|
||||
(session body &optional result-type result-params preamble)
|
||||
"Evaluate BODY in SESSION as Lua code.
|
||||
RESULT-TYPE and RESULT-PARAMS are passed to
|
||||
`org-babel-lua-evaluate-session' or
|
||||
`org-babel-lua-evaluate-external-process'.
|
||||
PREAMBLE is passed to `org-babel-lua-evaluate-external-process'."
|
||||
"Evaluate BODY as Lua code."
|
||||
(if session
|
||||
(org-babel-lua-evaluate-session
|
||||
session body result-type result-params)
|
||||
|
@ -302,12 +290,10 @@ PREAMBLE is passed to `org-babel-lua-evaluate-external-process'."
|
|||
|
||||
(defun org-babel-lua-evaluate-external-process
|
||||
(body &optional result-type result-params preamble)
|
||||
"Evaluate BODY in external Lua process.
|
||||
"Evaluate BODY in external lua process.
|
||||
If RESULT-TYPE equals `output' then return standard output as a
|
||||
string. If RESULT-TYPE equals `value' then return the value of the
|
||||
last statement in BODY, as elisp.
|
||||
RESULT-PARAMS list all the :result header arg parameters.
|
||||
PREAMBLE string is appended to BODY."
|
||||
last statement in BODY, as elisp."
|
||||
(let ((raw
|
||||
(pcase result-type
|
||||
(`output (org-babel-eval org-babel-lua-command
|
||||
|
@ -340,7 +326,7 @@ PREAMBLE string is appended to BODY."
|
|||
If RESULT-TYPE equals `output' then return standard output as a
|
||||
string. If RESULT-TYPE equals `value' then return the value of the
|
||||
last statement in BODY, as elisp."
|
||||
(let* ((send-wait (lambda () (comint-send-input nil t) (sleep-for 0.005)))
|
||||
(let* ((send-wait (lambda () (comint-send-input nil t) (sleep-for 0 5)))
|
||||
(dump-last-value
|
||||
(lambda
|
||||
(tmp-file pp)
|
||||
|
@ -413,7 +399,7 @@ fd:close()"
|
|||
(org-babel-lua-table-or-string results)))))
|
||||
|
||||
(defun org-babel-lua-read-string (string)
|
||||
"Strip single quotes from around Lua STRING."
|
||||
"Strip single quotes from around Lua string."
|
||||
(org-unbracket-string "'" "'" string))
|
||||
|
||||
(provide 'ob-lua)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-makefile.el --- Babel Functions for Makefile -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Thomas S. Dye
|
||||
|
@ -36,8 +36,7 @@
|
|||
(defvar org-babel-default-header-args:makefile '())
|
||||
|
||||
(defun org-babel-execute:makefile (body _params)
|
||||
"Execute makefile BODY.
|
||||
Second function argument is ignored.
|
||||
"Execute a block of makefile code.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
body)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-matlab.el --- Babel support for Matlab -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2010-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2010-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Dan Davison
|
||||
;; Keywords: literate programming, reproducible research
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-maxima.el --- Babel Functions for Maxima -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric S Fraga
|
||||
;; Eric Schulte
|
||||
|
@ -37,11 +37,6 @@
|
|||
|
||||
(require 'ob)
|
||||
|
||||
(defconst org-babel-header-args:maxima
|
||||
'((batch . ((batchload batch load)))
|
||||
(graphics-pkg . ((plot draw))))
|
||||
"Maxima-specific header arguments.")
|
||||
|
||||
(defvar org-babel-tangle-lang-exts)
|
||||
(add-to-list 'org-babel-tangle-lang-exts '("maxima" . "max"))
|
||||
|
||||
|
@ -53,102 +48,43 @@
|
|||
:group 'org-babel
|
||||
:type 'string)
|
||||
|
||||
(defvar org-babel-maxima--command-arguments-default
|
||||
"--very-quiet"
|
||||
"Command-line arguments sent to Maxima by default.
|
||||
If the `:batch' header argument is set to `batchload' or unset,
|
||||
then the `:cmdline' header argument is appended to this default;
|
||||
otherwise, if the `:cmdline' argument is set, it over-rides this
|
||||
default. See `org-babel-maxima-command' and
|
||||
`org-babel-execute:maxima'.")
|
||||
|
||||
(defvar org-babel-maxima--graphic-package-options
|
||||
'((plot . "(set_plot_option ('[gnuplot_term, %s]), set_plot_option ('[gnuplot_out_file, %S]))$")
|
||||
(draw . "(load(draw), set_draw_defaults(terminal='%s,file_name=%S))$"))
|
||||
"An alist of graphics packages and Maxima code.
|
||||
Each element is a cons (PACKAGE-NAME . FORMAT-STRING).
|
||||
FORMAT-STRING contains Maxima code to configure the graphics
|
||||
package; it must contain `%s' to set the terminal and `%S' to set
|
||||
the filename, in that order. The default graphics package is
|
||||
`plot'; `draw' is also supported. See
|
||||
`org-babel-maxima-expand'.")
|
||||
|
||||
(defvar org-babel-maxima--default-epilogue
|
||||
'((graphical-output . "gnuplot_close ()$")
|
||||
(non-graphical-output . ""))
|
||||
"The final Maxima code executed in a source block.
|
||||
An alist with the epilogue for graphical and non-graphical
|
||||
output. See `org-babel-maxima-expand'.")
|
||||
|
||||
(defun org-babel-maxima-expand (body params)
|
||||
"Expand Maxima BODY according to its header arguments from PARAMS."
|
||||
(let* ((vars (org-babel--get-vars params))
|
||||
(graphic-file (ignore-errors (org-babel-graphical-output-file params)))
|
||||
(epilogue (cdr (assq :epilogue params)))
|
||||
(prologue (cdr (assq :prologue params))))
|
||||
"Expand a block of Maxima code according to its header arguments."
|
||||
(let ((vars (org-babel--get-vars params))
|
||||
(epilogue (cdr (assq :epilogue params)))
|
||||
(prologue (cdr (assq :prologue params))))
|
||||
(mapconcat 'identity
|
||||
(delq nil
|
||||
(list
|
||||
;; Any code from the specified prologue at the start.
|
||||
prologue
|
||||
;; graphic output
|
||||
(if graphic-file
|
||||
(let* ((graphics-pkg (intern (or (cdr (assq :graphics-pkg params)) "plot")))
|
||||
(graphic-format-string (cdr (assq graphics-pkg org-babel-maxima--graphic-package-options)))
|
||||
(graphic-terminal (file-name-extension graphic-file))
|
||||
(graphic-file (if (eq graphics-pkg 'plot) graphic-file (file-name-sans-extension graphic-file))))
|
||||
(format graphic-format-string graphic-terminal graphic-file)))
|
||||
;; variables
|
||||
(mapconcat 'org-babel-maxima-var-to-maxima vars "\n")
|
||||
;; body
|
||||
body
|
||||
;; Any code from the specified epilogue at the end.
|
||||
epilogue
|
||||
(if graphic-file
|
||||
(cdr (assq :graphical-output org-babel-maxima--default-epilogue))
|
||||
(cdr (assq :non-graphical-output org-babel-maxima--default-epilogue)))))
|
||||
(list
|
||||
;; Any code from the specified prologue at the start.
|
||||
prologue
|
||||
;; graphic output
|
||||
(let ((graphic-file (ignore-errors (org-babel-graphical-output-file params))))
|
||||
(if graphic-file
|
||||
(format
|
||||
"set_plot_option ([gnuplot_term, png]); set_plot_option ([gnuplot_out_file, %S]);"
|
||||
graphic-file)
|
||||
""))
|
||||
;; variables
|
||||
(mapconcat 'org-babel-maxima-var-to-maxima vars "\n")
|
||||
;; body
|
||||
body
|
||||
;; Any code from the specified epilogue at the end.
|
||||
epilogue
|
||||
"gnuplot_close ()$")
|
||||
"\n")))
|
||||
|
||||
(defvar org-babel-maxima--output-filter-regexps
|
||||
'("batch" ;; remove the `batch' or `batchload' line
|
||||
"^rat: replaced .*$" ;; remove notices from `rat'
|
||||
"^;;; Loading #P" ;; remove notices from the lisp implementation
|
||||
"^read and interpret" ;; remove notice from `batch'
|
||||
"^(%\\([i]-?[0-9]+\\))[ ]$" ;; remove empty input lines from `batch'-ing
|
||||
)
|
||||
"Regexps to remove extraneous lines from Maxima's output.
|
||||
See `org-babel-maxima--output-filter'.")
|
||||
|
||||
(defun org-babel-maxima--output-filter (line)
|
||||
"Filter empty or undesired lines from Maxima output.
|
||||
Return nil if LINE is zero-length or it matches a regexp in
|
||||
`org-babel-maxima--output-filter'; otherwise, return LINE."
|
||||
(unless (or (= 0 (length line))
|
||||
(cl-some #'(lambda(r) (string-match r line))
|
||||
org-babel-maxima--output-filter-regexps))
|
||||
line))
|
||||
|
||||
(defun org-babel-execute:maxima (body params)
|
||||
"Execute Maxima BODY according to PARAMS.
|
||||
"Execute a block of Maxima entries with org-babel.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
(message "Executing Maxima source code block")
|
||||
(let ((result-params (split-string (or (cdr (assq :results params)) "")))
|
||||
(result
|
||||
(let* ((cmdline (or (cdr (assq :cmdline params)) ""))
|
||||
(batch/load (or (cdr (assq :batch params)) "batchload"))
|
||||
(cmdline (if (or (equal cmdline "") (equal batch/load "batchload"))
|
||||
;; legacy behaviour:
|
||||
;; ensure that --very-quiet is on command-line by default
|
||||
(concat cmdline " " org-babel-maxima--command-arguments-default)
|
||||
;; if using an alternate loader, :cmdline overwrites default
|
||||
cmdline))
|
||||
(in-file (org-babel-temp-file "maxima-" ".max"))
|
||||
(cmd (format "%s -r %s %s"
|
||||
(cmd (format "%s --very-quiet -r %s %s"
|
||||
org-babel-maxima-command
|
||||
(shell-quote-argument
|
||||
;; bind linenum to 0 so the first line
|
||||
;; of in-file has line number 1
|
||||
(format "(linenum:0, %s(%S))$" batch/load in-file))
|
||||
(format "batchload(%S)$" in-file))
|
||||
cmdline)))
|
||||
(with-temp-file in-file (insert (org-babel-maxima-expand body params)))
|
||||
(message cmd)
|
||||
|
@ -157,7 +93,12 @@ This function is called by `org-babel-execute-src-block'."
|
|||
(mapconcat
|
||||
#'identity
|
||||
(delq nil
|
||||
(mapcar #'org-babel-maxima--output-filter
|
||||
(mapcar (lambda (line)
|
||||
(unless (or (string-match "batch" line)
|
||||
(string-match "^rat: replaced .*$" line)
|
||||
(string-match "^;;; Loading #P" line)
|
||||
(= 0 (length line)))
|
||||
line))
|
||||
(split-string raw "[\r\n]"))) "\n")))))
|
||||
(if (ignore-errors (org-babel-graphical-output-file params))
|
||||
nil
|
||||
|
@ -169,11 +110,11 @@ This function is called by `org-babel-execute-src-block'."
|
|||
|
||||
|
||||
(defun org-babel-prep-session:maxima (_session _params)
|
||||
"Throw an error. Maxima does not support sessions."
|
||||
(error "Maxima does not support sessions"))
|
||||
|
||||
(defun org-babel-maxima-var-to-maxima (pair)
|
||||
"Convert an elisp variable-value PAIR to maxima code."
|
||||
"Convert an elisp val into a string of maxima code specifying a var
|
||||
of the same value."
|
||||
(let ((var (car pair))
|
||||
(val (cdr pair)))
|
||||
(when (symbolp val)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-ocaml.el --- Babel Functions for Ocaml -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Keywords: literate programming, reproducible research
|
||||
|
@ -63,7 +63,7 @@
|
|||
:type 'string)
|
||||
|
||||
(defun org-babel-execute:ocaml (body params)
|
||||
"Execute Ocaml BODY according to PARAMS."
|
||||
"Execute a block of Ocaml code with Babel."
|
||||
(let* ((full-body (org-babel-expand-body:generic
|
||||
body params
|
||||
(org-babel-variable-assignments:ocaml params)))
|
||||
|
@ -121,8 +121,7 @@
|
|||
(get-buffer tuareg-interactive-buffer-name)))
|
||||
|
||||
(defun org-babel-variable-assignments:ocaml (params)
|
||||
"Return list of ocaml statements assigning the block's variables.
|
||||
The variables are defined in PARAMS."
|
||||
"Return list of ocaml statements assigning the block's variables."
|
||||
(mapcar
|
||||
(lambda (pair) (format "let %s = %s;;" (car pair)
|
||||
(org-babel-ocaml-elisp-to-ocaml (cdr pair))))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-octave.el --- Babel Functions for Octave and Matlab -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2010-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2010-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Dan Davison
|
||||
;; Keywords: literate programming, reproducible research
|
||||
|
@ -70,12 +70,11 @@ end")
|
|||
(defvar org-babel-octave-eoe-output "ans = org_babel_eoe")
|
||||
|
||||
(defun org-babel-execute:matlab (body params)
|
||||
"Execute Matlab BODY according to PARAMS."
|
||||
"Execute a block of matlab code with Babel."
|
||||
(org-babel-execute:octave body params 'matlab))
|
||||
|
||||
(defun org-babel-execute:octave (body params &optional matlabp)
|
||||
"Execute Octave or Matlab BODY according to PARAMS.
|
||||
When MATLABP is non-nil, execute Matlab. Otherwise, execute Octave."
|
||||
"Execute a block of octave code with Babel."
|
||||
(let* ((session
|
||||
(funcall (intern (format "org-babel-%s-initiate-session"
|
||||
(if matlabp "matlab" "octave")))
|
||||
|
@ -110,8 +109,7 @@ When MATLABP is non-nil, execute Matlab. Otherwise, execute Octave."
|
|||
(org-babel-prep-session:octave session params 'matlab))
|
||||
|
||||
(defun org-babel-variable-assignments:octave (params)
|
||||
"Return list of octave statements assigning the block's variables.
|
||||
The variables are taken from PARAMS."
|
||||
"Return list of octave statements assigning the block's variables."
|
||||
(mapcar
|
||||
(lambda (pair)
|
||||
(format "%s=%s;"
|
||||
|
@ -122,22 +120,21 @@ The variables are taken from PARAMS."
|
|||
(defalias 'org-babel-variable-assignments:matlab
|
||||
'org-babel-variable-assignments:octave)
|
||||
|
||||
(defun org-babel-octave-var-to-octave (value)
|
||||
"Convert an emacs-lisp VALUE into an octave variable.
|
||||
(defun org-babel-octave-var-to-octave (var)
|
||||
"Convert an emacs-lisp value into an octave variable.
|
||||
Converts an emacs-lisp variable into a string of octave code
|
||||
specifying a variable of the same value."
|
||||
(if (listp value)
|
||||
(concat "[" (mapconcat #'org-babel-octave-var-to-octave value
|
||||
(if (listp (car value)) "; " ",")) "]")
|
||||
(if (listp var)
|
||||
(concat "[" (mapconcat #'org-babel-octave-var-to-octave var
|
||||
(if (listp (car var)) "; " ",")) "]")
|
||||
(cond
|
||||
((stringp value)
|
||||
(format "'%s'" value))
|
||||
((stringp var)
|
||||
(format "'%s'" var))
|
||||
(t
|
||||
(format "%s" value)))))
|
||||
(format "%s" var)))))
|
||||
|
||||
(defun org-babel-prep-session:octave (session params &optional matlabp)
|
||||
"Prepare SESSION according to the header arguments specified in PARAMS.
|
||||
The session will be an Octave session, unless MATLABP is non-nil."
|
||||
"Prepare SESSION according to the header arguments specified in PARAMS."
|
||||
(let* ((session (org-babel-octave-initiate-session session params matlabp))
|
||||
(var-lines (org-babel-variable-assignments:octave params)))
|
||||
(org-babel-comint-in-buffer session
|
||||
|
@ -150,14 +147,13 @@ The session will be an Octave session, unless MATLABP is non-nil."
|
|||
(defun org-babel-matlab-initiate-session (&optional session params)
|
||||
"Create a matlab inferior process buffer.
|
||||
If there is not a current inferior-process-buffer in SESSION then
|
||||
create. Return the initialized session. PARAMS are src block parameters."
|
||||
create. Return the initialized session."
|
||||
(org-babel-octave-initiate-session session params 'matlab))
|
||||
|
||||
(defun org-babel-octave-initiate-session (&optional session _params matlabp)
|
||||
"Create an octave inferior process buffer.
|
||||
If there is not a current inferior-process-buffer in SESSION then
|
||||
create. Return the initialized session. The session will be an
|
||||
Octave session, unless MATLABP is non-nil."
|
||||
create. Return the initialized session."
|
||||
(if matlabp
|
||||
(org-require-package 'matlab "matlab-mode")
|
||||
(or (require 'octave-inf nil 'noerror)
|
||||
|
@ -184,8 +180,7 @@ value of the last statement in BODY, as elisp."
|
|||
(org-babel-octave-evaluate-external-process body result-type matlabp)))
|
||||
|
||||
(defun org-babel-octave-evaluate-external-process (body result-type matlabp)
|
||||
"Evaluate BODY in an external Octave or Matalab process.
|
||||
Process the result as RESULT-TYPE. Use Octave, unless MATLABP is non-nil."
|
||||
"Evaluate BODY in an external octave process."
|
||||
(let ((cmd (if matlabp
|
||||
org-babel-matlab-shell-command
|
||||
org-babel-octave-shell-command)))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-org.el --- Babel Functions for Org Code Blocks -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2010-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2010-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Keywords: literate programming, reproducible research
|
||||
|
@ -45,25 +45,15 @@
|
|||
"Default header inserted during export of org blocks.")
|
||||
|
||||
(defun org-babel-expand-body:org (body params)
|
||||
"Expand Org BODY according to PARAMS.
|
||||
$VAR instances are replaced by VAR values defined in PARAMS."
|
||||
(dolist (var (org-babel--get-vars params))
|
||||
(setq body (replace-regexp-in-string
|
||||
(regexp-quote (format "$%s" (car var)))
|
||||
(format "%s" (cdr var))
|
||||
body 'fixedcase 'literal)))
|
||||
|
||||
(let ((prologue (cdr (assq :prologue params)))
|
||||
(epilogue (cdr (assq :epilogue params))))
|
||||
(concat
|
||||
(and prologue (concat prologue "\n"))
|
||||
body
|
||||
(and epilogue (concat "\n" epilogue "\n")))))
|
||||
body nil 'literal)))
|
||||
body)
|
||||
|
||||
(defun org-babel-execute:org (body params)
|
||||
"Execute a Org BODY according to PARAMS.
|
||||
The BODY is returned expanded as is or exported, if PARAMS define
|
||||
latex/html/ascii result type.
|
||||
"Execute a block of Org code with.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
(let ((result-params (split-string (or (cdr (assq :results params)) "")))
|
||||
(body (org-babel-expand-body:org
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-perl.el --- Babel Functions for Perl -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Authors: Dan Davison
|
||||
;; Eric Schulte
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-plantuml.el --- Babel Functions for Plantuml -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2010-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2010-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Zhang Weize
|
||||
;; Keywords: literate programming, reproducible research
|
||||
|
@ -57,7 +57,7 @@ The JAR can be configured via `org-plantuml-jar-path'.
|
|||
|
||||
`plantuml' means to use the PlantUML executable.
|
||||
The executable can be configured via `org-plantuml-executable-path'.
|
||||
You can also configure extra arguments via `org-plantuml-args'."
|
||||
You can also configure extra arguments via `org-plantuml-executable-args'."
|
||||
:group 'org-babel
|
||||
:package-version '(Org . "9.4")
|
||||
:type 'symbol
|
||||
|
@ -143,7 +143,6 @@ This function is called by `org-babel-execute-src-block'."
|
|||
("eps" '("-teps"))
|
||||
("pdf" '("-tpdf"))
|
||||
("tex" '("-tlatex"))
|
||||
("tikz" '("-tlatex:nopreamble"))
|
||||
("vdx" '("-tvdx"))
|
||||
("xmi" '("-txmi"))
|
||||
("scxml" '("-tscxml"))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-processing.el --- Babel functions for processing -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2015-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2015-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Jarmo Hurri (adapted from ob-asymptote.el written by Eric Schulte)
|
||||
;; Maintainer: Jarmo Hurri <jarmo.hurri@iki.fi>
|
||||
|
@ -118,7 +118,7 @@
|
|||
(message "Not inside a Processing source block."))))
|
||||
|
||||
(defun org-babel-execute:processing (body params)
|
||||
"Execute Processing code BODY according to PARAMS.
|
||||
"Execute a block of Processing code.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
(let ((sketch-code
|
||||
(org-babel-expand-body:generic
|
||||
|
@ -144,8 +144,7 @@ Processing does not support sessions."
|
|||
(error "Processing does not support sessions"))
|
||||
|
||||
(defun org-babel-variable-assignments:processing (params)
|
||||
"Return list of processing statements assigning the block's variables.
|
||||
The variable assignments are defined in PARAMS."
|
||||
"Return list of processing statements assigning the block's variables."
|
||||
(mapcar #'org-babel-processing-var-to-processing
|
||||
(org-babel--get-vars params)))
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-python.el --- Babel Functions for Python -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Authors: Eric Schulte
|
||||
;; Dan Davison
|
||||
|
@ -41,65 +41,35 @@
|
|||
|
||||
(defvar org-babel-default-header-args:python '())
|
||||
|
||||
(defconst org-babel-header-args:python
|
||||
'((return . :any)
|
||||
(python . :any)
|
||||
(async . ((yes no))))
|
||||
"Python-specific header arguments.")
|
||||
|
||||
(defcustom org-babel-python-command 'auto
|
||||
"Command (including arguments) for interactive and non-interactive Python code.
|
||||
When not `auto', it overrides `org-babel-python-command-session'
|
||||
and `org-babel-python-command-nonsession'."
|
||||
:package-version '(Org . "9.7")
|
||||
:group 'org-babel
|
||||
:type '(choice string (const auto)))
|
||||
|
||||
(defcustom org-babel-python-command-session 'auto
|
||||
"Command (including arguments) for starting interactive Python sessions.
|
||||
If `auto' (the default), uses the values from
|
||||
`python-shell-interpreter' and `python-shell-interpreter-args'.
|
||||
If `org-babel-python-command' is set, then it overrides this
|
||||
option."
|
||||
:package-version '(Org . "9.7")
|
||||
:group 'org-babel
|
||||
:type '(choice string (const auto)))
|
||||
|
||||
(defcustom org-babel-python-command-nonsession "python"
|
||||
"Command (including arguments) for executing non-interactive Python code.
|
||||
If `org-babel-python-command' is set, then it overrides this option."
|
||||
:package-version '(Org . "9.7")
|
||||
(defcustom org-babel-python-command "python"
|
||||
"Name of the command for executing Python code."
|
||||
:version "24.4"
|
||||
:package-version '(Org . "8.0")
|
||||
:group 'org-babel
|
||||
:type 'string)
|
||||
|
||||
(defcustom org-babel-python-hline-to "None"
|
||||
"Replace hlines in incoming tables with this when translating to python."
|
||||
:group 'org-babel
|
||||
:version "24.4"
|
||||
:package-version '(Org . "8.0")
|
||||
:type 'string)
|
||||
|
||||
(defcustom org-babel-python-None-to 'hline
|
||||
"Replace `None' in python tables with this before returning."
|
||||
:group 'org-babel
|
||||
:version "24.4"
|
||||
:package-version '(Org . "8.0")
|
||||
:type 'symbol)
|
||||
|
||||
(defun org-babel-python-associate-session (session)
|
||||
"Associate Python code buffer with an Python session.
|
||||
Make SESSION without earmuffs be the Python buffer name."
|
||||
(setq-local python-shell-buffer-name
|
||||
(org-babel-python-without-earmuffs session)))
|
||||
|
||||
(defun org-babel-execute:python (body params)
|
||||
"Execute Python BODY according to PARAMS.
|
||||
"Execute a block of Python code with Babel.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
(let* ((org-babel-python-command
|
||||
(or (cdr (assq :python params))
|
||||
org-babel-python-command))
|
||||
(session (org-babel-python-initiate-session
|
||||
(cdr (assq :session params))))
|
||||
(graphics-file (and (member "graphics" (assq :result-params params))
|
||||
(org-babel-graphical-output-file params)))
|
||||
(result-params (cdr (assq :result-params params)))
|
||||
(result-type (cdr (assq :result-type params)))
|
||||
(return-val (when (eq result-type 'value)
|
||||
|
@ -115,7 +85,7 @@ This function is called by `org-babel-execute-src-block'."
|
|||
(format (if session "\n%s" "\nreturn %s") return-val))))
|
||||
(result (org-babel-python-evaluate
|
||||
session full-body result-type
|
||||
result-params preamble async graphics-file)))
|
||||
result-params preamble async)))
|
||||
(org-babel-reassemble-table
|
||||
result
|
||||
(org-babel-pick-name (cdr (assq :colname-names params))
|
||||
|
@ -147,63 +117,8 @@ VARS contains resolved variable references."
|
|||
|
||||
;; helper functions
|
||||
|
||||
(defconst org-babel-python--output-graphics-wrapper "\
|
||||
import matplotlib.pyplot
|
||||
matplotlib.pyplot.gcf().clear()
|
||||
%s
|
||||
matplotlib.pyplot.savefig('%s')"
|
||||
"Format string for saving Python graphical output.
|
||||
Has two %s escapes, for the Python code to be evaluated, and the
|
||||
file to save the graphics to.")
|
||||
|
||||
(defconst org-babel-python--def-format-value "\
|
||||
def __org_babel_python_format_value(result, result_file, result_params):
|
||||
with open(result_file, 'w') as f:
|
||||
if 'graphics' in result_params:
|
||||
result.savefig(result_file)
|
||||
elif 'pp' in result_params:
|
||||
import pprint
|
||||
f.write(pprint.pformat(result))
|
||||
elif 'list' in result_params and isinstance(result, dict):
|
||||
f.write(str(['{} :: {}'.format(k, v) for k, v in result.items()]))
|
||||
else:
|
||||
if not set(result_params).intersection(\
|
||||
['scalar', 'verbatim', 'raw']):
|
||||
def dict2table(res):
|
||||
if isinstance(res, dict):
|
||||
return [(k, dict2table(v)) for k, v in res.items()]
|
||||
elif isinstance(res, list) or isinstance(res, tuple):
|
||||
return [dict2table(x) for x in res]
|
||||
else:
|
||||
return res
|
||||
if 'table' in result_params:
|
||||
result = dict2table(result)
|
||||
try:
|
||||
import pandas
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
if isinstance(result, pandas.DataFrame) and 'table' in result_params:
|
||||
result = [[result.index.name or ''] + list(result.columns)] + \
|
||||
[None] + [[i] + list(row) for i, row in result.iterrows()]
|
||||
elif isinstance(result, pandas.Series) and 'table' in result_params:
|
||||
result = list(result.items())
|
||||
try:
|
||||
import numpy
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
if isinstance(result, numpy.ndarray):
|
||||
if 'table' in result_params:
|
||||
result = result.tolist()
|
||||
else:
|
||||
result = repr(result)
|
||||
f.write(str(result))"
|
||||
"Python function to format value result and save it to file.")
|
||||
|
||||
(defun org-babel-variable-assignments:python (params)
|
||||
"Return a list of Python statements assigning the block's variables.
|
||||
The assignments are defined in PARAMS."
|
||||
"Return a list of Python statements assigning the block's variables."
|
||||
(mapcar
|
||||
(lambda (pair)
|
||||
(format "%s=%s"
|
||||
|
@ -225,13 +140,9 @@ specifying a variable of the same value."
|
|||
|
||||
(defun org-babel-python-table-or-string (results)
|
||||
"Convert RESULTS into an appropriate elisp value.
|
||||
If the results look like a list or tuple (but not a dict), then
|
||||
convert them into an Emacs-lisp table. Otherwise return the
|
||||
results as a string."
|
||||
(let ((res (if (and (> (length results) 0)
|
||||
(string-equal "{" (substring results 0 1)))
|
||||
results ;don't covert dicts to elisp
|
||||
(org-babel-script-escape results))))
|
||||
If the results look like a list or tuple, then convert them into an
|
||||
Emacs-lisp table, otherwise return the results as a string."
|
||||
(let ((res (org-babel-script-escape results)))
|
||||
(if (listp res)
|
||||
(mapcar (lambda (el) (if (eq el 'None)
|
||||
org-babel-python-None-to el))
|
||||
|
@ -245,7 +156,6 @@ results as a string."
|
|||
(cdr (assoc session org-babel-python-buffers)))
|
||||
|
||||
(defun org-babel-python-with-earmuffs (session)
|
||||
"Return SESSION name as string, ensuring *...* around."
|
||||
(let ((name (if (stringp session) session (format "%s" session))))
|
||||
(if (and (string= "*" (substring name 0 1))
|
||||
(string= "*" (substring name (- (length name) 1))))
|
||||
|
@ -253,113 +163,54 @@ results as a string."
|
|||
(format "*%s*" name))))
|
||||
|
||||
(defun org-babel-python-without-earmuffs (session)
|
||||
"Return SESSION name as string, without *...* around."
|
||||
(let ((name (if (stringp session) session (format "%s" session))))
|
||||
(if (and (string= "*" (substring name 0 1))
|
||||
(string= "*" (substring name (- (length name) 1))))
|
||||
(substring name 1 (- (length name) 1))
|
||||
name)))
|
||||
|
||||
(defun org-babel-session-buffer:python (session &optional _)
|
||||
"Return session buffer name for SESSION."
|
||||
(or (org-babel-python-session-buffer session)
|
||||
(org-babel-python-with-earmuffs session)))
|
||||
|
||||
(defun org-babel-python--python-util-comint-end-of-output-p ()
|
||||
"Return non-nil if the last prompt matches input prompt.
|
||||
Backport of `python-util-comint-end-of-output-p' to emacs28. To
|
||||
be removed after minimum supported version reaches emacs29."
|
||||
(when-let ((prompt (python-util-comint-last-prompt)))
|
||||
(python-shell-comint-end-of-output-p
|
||||
(buffer-substring-no-properties
|
||||
(car prompt) (cdr prompt)))))
|
||||
|
||||
(defun org-babel-python--command (is-session)
|
||||
"Helper function to return the Python command.
|
||||
This checks `org-babel-python-command', and then
|
||||
`org-babel-python-command-session' (if IS-SESSION) or
|
||||
`org-babel-python-command-nonsession' (if not IS-SESSION). If
|
||||
IS-SESSION, this might return `nil', which means to use
|
||||
`python-shell-calculate-command'."
|
||||
(or (unless (eq org-babel-python-command 'auto)
|
||||
org-babel-python-command)
|
||||
(if is-session
|
||||
(unless (eq org-babel-python-command-session 'auto)
|
||||
org-babel-python-command-session)
|
||||
org-babel-python-command-nonsession)))
|
||||
|
||||
(defvar-local org-babel-python--initialized nil
|
||||
"Flag used to mark that python session has been initialized.")
|
||||
(defun org-babel-python--setup-session ()
|
||||
"Babel Python session setup code, to be run once per session.
|
||||
Function should be run from within the Python session buffer.
|
||||
This is often run as a part of `python-shell-first-prompt-hook',
|
||||
unless the Python session was created outside Org."
|
||||
(python-shell-send-string-no-output org-babel-python--def-format-value)
|
||||
(setq-local org-babel-python--initialized t))
|
||||
(defun org-babel-python-initiate-session-by-key (&optional session)
|
||||
"Initiate a python session.
|
||||
If there is not a current inferior-process-buffer matching
|
||||
SESSION then create it. If inferior process already
|
||||
exists (e.g. if it was manually started with `run-python'), make
|
||||
sure it's configured to work with ob-python. If session has
|
||||
already been configured as such, do nothing. Return the
|
||||
initialized session."
|
||||
If there is not a current inferior-process-buffer in SESSION
|
||||
then create. Return the initialized session."
|
||||
(save-window-excursion
|
||||
(let* ((session (if session (intern session) :default))
|
||||
(py-buffer (org-babel-session-buffer:python session))
|
||||
(py-buffer (or (org-babel-python-session-buffer session)
|
||||
(org-babel-python-with-earmuffs session)))
|
||||
(cmd (if (member system-type '(cygwin windows-nt ms-dos))
|
||||
(concat org-babel-python-command " -i")
|
||||
org-babel-python-command))
|
||||
(python-shell-buffer-name
|
||||
(org-babel-python-without-earmuffs py-buffer))
|
||||
(existing-session-p (comint-check-proc py-buffer))
|
||||
(cmd (org-babel-python--command t)))
|
||||
(if cmd
|
||||
(let* ((cmd-split (split-string-and-unquote cmd))
|
||||
(python-shell-interpreter (car cmd-split))
|
||||
(python-shell-interpreter-args
|
||||
(combine-and-quote-strings
|
||||
(append (cdr cmd-split)
|
||||
(when (member system-type
|
||||
'(cygwin windows-nt ms-dos))
|
||||
(list "-i"))))))
|
||||
(run-python))
|
||||
(run-python))
|
||||
(existing-session-p (comint-check-proc py-buffer)))
|
||||
(run-python cmd)
|
||||
(with-current-buffer py-buffer
|
||||
(if existing-session-p
|
||||
;; Session was created outside Org. Assume first prompt
|
||||
;; already happened; run session setup code directly
|
||||
(unless org-babel-python--initialized
|
||||
;; Ensure first prompt. Based on python-tests.el
|
||||
;; (`python-tests-shell-wait-for-prompt')
|
||||
(while (not (org-babel-python--python-util-comint-end-of-output-p))
|
||||
(sit-for 0.1))
|
||||
(org-babel-python--setup-session))
|
||||
;; Adding to `python-shell-first-prompt-hook' immediately
|
||||
;; after `run-python' should be safe from race conditions,
|
||||
;; because subprocess output only arrives when Emacs is
|
||||
;; waiting (see elisp manual, "Output from Processes")
|
||||
(add-hook
|
||||
'python-shell-first-prompt-hook
|
||||
#'org-babel-python--setup-session
|
||||
nil 'local)))
|
||||
;; Wait until Python initializes
|
||||
;; This is more reliable compared to
|
||||
;; `org-babel-comint-wait-for-output' as python may emit
|
||||
;; multiple prompts during initialization.
|
||||
(with-current-buffer py-buffer
|
||||
(while (not org-babel-python--initialized)
|
||||
(sleep-for 0.010)))
|
||||
;; Adding to `python-shell-first-prompt-hook' immediately
|
||||
;; after `run-python' should be safe from race conditions,
|
||||
;; because subprocess output only arrives when Emacs is
|
||||
;; waiting (see elisp manual, "Output from Processes")
|
||||
(add-hook
|
||||
'python-shell-first-prompt-hook
|
||||
(lambda () (setq-local org-babel-python--initialized t))
|
||||
nil 'local))
|
||||
;; Don't hang if session was started externally
|
||||
(unless existing-session-p
|
||||
;; Wait until Python initializes
|
||||
;; This is more reliable compared to
|
||||
;; `org-babel-comint-wait-for-output' as python may emit
|
||||
;; multiple prompts during initialization.
|
||||
(with-current-buffer py-buffer
|
||||
(while (not org-babel-python--initialized)
|
||||
(org-babel-comint-wait-for-output py-buffer))))
|
||||
(setq org-babel-python-buffers
|
||||
(cons (cons session py-buffer)
|
||||
(assq-delete-all session org-babel-python-buffers)))
|
||||
session)))
|
||||
|
||||
(defun org-babel-python-initiate-session (&optional session _params)
|
||||
"Initiate Python session named SESSION according to PARAMS.
|
||||
If there is not a current inferior-process-buffer matching
|
||||
SESSION then create it. If inferior process already
|
||||
exists (e.g. if it was manually started with `run-python'), make
|
||||
sure it's configured to work with ob-python. If session has
|
||||
already been configured as such, do nothing."
|
||||
"Create a session named SESSION according to PARAMS."
|
||||
(unless (string= session "none")
|
||||
(org-babel-python-session-buffer
|
||||
(org-babel-python-initiate-session-by-key session))))
|
||||
|
@ -367,10 +218,31 @@ already been configured as such, do nothing."
|
|||
(defvar org-babel-python-eoe-indicator "org_babel_python_eoe"
|
||||
"A string to indicate that evaluation has completed.")
|
||||
|
||||
(defconst org-babel-python-wrapper-method
|
||||
"
|
||||
def main():
|
||||
%s
|
||||
|
||||
open('%s', 'w').write( str(main()) )")
|
||||
(defconst org-babel-python-pp-wrapper-method
|
||||
"
|
||||
import pprint
|
||||
def main():
|
||||
%s
|
||||
|
||||
open('%s', 'w').write( pprint.pformat(main()) )")
|
||||
|
||||
(defconst org-babel-python--exec-tmpfile "\
|
||||
with open('%s') as __org_babel_python_tmpfile:
|
||||
exec(compile(__org_babel_python_tmpfile.read(), __org_babel_python_tmpfile.name, 'exec'))"
|
||||
"Template for Python session command with output results.
|
||||
|
||||
Has a single %s escape, the tempfile containing the source code
|
||||
to evaluate.")
|
||||
|
||||
(defun org-babel-python-format-session-value
|
||||
(src-file result-file result-params)
|
||||
"Return Python code to evaluate SRC-FILE and write result to RESULT-FILE.
|
||||
RESULT-PARAMS defines the result type."
|
||||
"Return Python code to evaluate SRC-FILE and write result to RESULT-FILE."
|
||||
(format "\
|
||||
import ast
|
||||
with open('%s') as __org_babel_python_tmpfile:
|
||||
|
@ -381,25 +253,30 @@ if isinstance(__org_babel_python_final, ast.Expr):
|
|||
exec(compile(__org_babel_python_ast, '<string>', 'exec'))
|
||||
__org_babel_python_final = eval(compile(ast.Expression(
|
||||
__org_babel_python_final.value), '<string>', 'eval'))
|
||||
with open('%s', 'w') as __org_babel_python_tmpfile:
|
||||
if %s:
|
||||
import pprint
|
||||
__org_babel_python_tmpfile.write(pprint.pformat(__org_babel_python_final))
|
||||
else:
|
||||
__org_babel_python_tmpfile.write(str(__org_babel_python_final))
|
||||
else:
|
||||
exec(compile(__org_babel_python_ast, '<string>', 'exec'))
|
||||
__org_babel_python_final = None
|
||||
__org_babel_python_format_value(__org_babel_python_final, '%s', %s)"
|
||||
__org_babel_python_final = None"
|
||||
(org-babel-process-file-name src-file 'noquote)
|
||||
(org-babel-process-file-name result-file 'noquote)
|
||||
(org-babel-python-var-to-python result-params)))
|
||||
(if (member "pp" result-params) "True" "False")))
|
||||
|
||||
(defun org-babel-python-evaluate
|
||||
(session body &optional result-type result-params preamble async graphics-file)
|
||||
(session body &optional result-type result-params preamble async)
|
||||
"Evaluate BODY as Python code."
|
||||
(if session
|
||||
(if async
|
||||
(org-babel-python-async-evaluate-session
|
||||
session body result-type result-params graphics-file)
|
||||
session body result-type result-params)
|
||||
(org-babel-python-evaluate-session
|
||||
session body result-type result-params graphics-file))
|
||||
session body result-type result-params))
|
||||
(org-babel-python-evaluate-external-process
|
||||
body result-type result-params preamble graphics-file)))
|
||||
body result-type result-params preamble)))
|
||||
|
||||
(defun org-babel-python--shift-right (body &optional count)
|
||||
(with-temp-buffer
|
||||
|
@ -415,38 +292,31 @@ __org_babel_python_format_value(__org_babel_python_final, '%s', %s)"
|
|||
(buffer-string)))
|
||||
|
||||
(defun org-babel-python-evaluate-external-process
|
||||
(body &optional result-type result-params preamble graphics-file)
|
||||
(body &optional result-type result-params preamble)
|
||||
"Evaluate BODY in external python process.
|
||||
If RESULT-TYPE equals `output' then return standard output as a
|
||||
string. If RESULT-TYPE equals `value' then return the value of
|
||||
the last statement in BODY, as elisp. If GRAPHICS-FILE is
|
||||
non-nil, then save graphical results to that file instead."
|
||||
string. If RESULT-TYPE equals `value' then return the value of the
|
||||
last statement in BODY, as elisp."
|
||||
(let ((raw
|
||||
(pcase result-type
|
||||
(`output (org-babel-eval (org-babel-python--command nil)
|
||||
(`output (org-babel-eval org-babel-python-command
|
||||
(concat preamble (and preamble "\n")
|
||||
(if graphics-file
|
||||
(format org-babel-python--output-graphics-wrapper
|
||||
body graphics-file)
|
||||
body))))
|
||||
(`value (let ((results-file (or graphics-file
|
||||
(org-babel-temp-file "python-"))))
|
||||
(org-babel-eval (org-babel-python--command nil)
|
||||
body)))
|
||||
(`value (let ((tmp-file (org-babel-temp-file "python-")))
|
||||
(org-babel-eval
|
||||
org-babel-python-command
|
||||
(concat
|
||||
preamble (and preamble "\n")
|
||||
(format
|
||||
(concat org-babel-python--def-format-value "
|
||||
def main():
|
||||
%s
|
||||
|
||||
__org_babel_python_format_value(main(), '%s', %s)")
|
||||
(org-babel-python--shift-right body)
|
||||
(org-babel-process-file-name results-file 'noquote)
|
||||
(org-babel-python-var-to-python result-params))))
|
||||
(org-babel-eval-read-file results-file))))))
|
||||
(if (member "pp" result-params)
|
||||
org-babel-python-pp-wrapper-method
|
||||
org-babel-python-wrapper-method)
|
||||
(org-babel-python--shift-right body)
|
||||
(org-babel-process-file-name tmp-file 'noquote))))
|
||||
(org-babel-eval-read-file tmp-file))))))
|
||||
(org-babel-result-cond result-params
|
||||
raw
|
||||
(org-babel-python-table-or-string raw))))
|
||||
(org-babel-python-table-or-string (org-trim raw)))))
|
||||
|
||||
(defun org-babel-python-send-string (session body)
|
||||
"Pass BODY to the Python process in SESSION.
|
||||
|
@ -470,50 +340,41 @@ finally:
|
|||
(org-babel-python-without-earmuffs session)))
|
||||
(python-shell-send-string body))
|
||||
;; same as `python-shell-comint-end-of-output-p' in emacs-25.1+
|
||||
(while (not (and (python-shell-comint-end-of-output-p string-buffer)
|
||||
(string-match
|
||||
org-babel-python-eoe-indicator
|
||||
string-buffer)))
|
||||
(while (not (string-match
|
||||
org-babel-python-eoe-indicator
|
||||
string-buffer))
|
||||
(accept-process-output (get-buffer-process (current-buffer))))
|
||||
(org-babel-chomp (substring string-buffer 0 (match-beginning 0))))))
|
||||
|
||||
(defun org-babel-python-evaluate-session
|
||||
(session body &optional result-type result-params graphics-file)
|
||||
(session body &optional result-type result-params)
|
||||
"Pass BODY to the Python process in SESSION.
|
||||
If RESULT-TYPE equals `output' then return standard output as a
|
||||
string. If RESULT-TYPE equals `value' then return the value of
|
||||
the last statement in BODY, as elisp. If GRAPHICS-FILE is
|
||||
non-nil, then save graphical results to that file instead."
|
||||
string. If RESULT-TYPE equals `value' then return the value of the
|
||||
last statement in BODY, as elisp."
|
||||
(let* ((tmp-src-file (org-babel-temp-file "python-"))
|
||||
(results
|
||||
(progn
|
||||
(with-temp-file tmp-src-file
|
||||
(insert (if (and graphics-file (eq result-type 'output))
|
||||
(format org-babel-python--output-graphics-wrapper
|
||||
body graphics-file)
|
||||
body)))
|
||||
(with-temp-file tmp-src-file (insert body))
|
||||
(pcase result-type
|
||||
(`output
|
||||
(let ((body (format "\
|
||||
with open('%s') as f:
|
||||
exec(compile(f.read(), f.name, 'exec'))"
|
||||
(let ((body (format org-babel-python--exec-tmpfile
|
||||
(org-babel-process-file-name
|
||||
tmp-src-file 'noquote))))
|
||||
(org-babel-python-send-string session body)))
|
||||
(`value
|
||||
(let* ((results-file (or graphics-file
|
||||
(org-babel-temp-file "python-")))
|
||||
(let* ((tmp-results-file (org-babel-temp-file "python-"))
|
||||
(body (org-babel-python-format-session-value
|
||||
tmp-src-file results-file result-params)))
|
||||
tmp-src-file tmp-results-file result-params)))
|
||||
(org-babel-python-send-string session body)
|
||||
(sleep-for 0.010)
|
||||
(org-babel-eval-read-file results-file)))))))
|
||||
(sleep-for 0 10)
|
||||
(org-babel-eval-read-file tmp-results-file)))))))
|
||||
(org-babel-result-cond result-params
|
||||
results
|
||||
(org-babel-python-table-or-string results))))
|
||||
|
||||
(defun org-babel-python-read-string (string)
|
||||
"Strip \\='s from around Python STRING."
|
||||
"Strip \\='s from around Python string."
|
||||
(if (and (string-prefix-p "'" string)
|
||||
(string-suffix-p "'" string))
|
||||
(substring string 1 -1)
|
||||
|
@ -531,7 +392,7 @@ with open('%s') as f:
|
|||
(org-babel-python-table-or-string results))))
|
||||
|
||||
(defun org-babel-python-async-evaluate-session
|
||||
(session body &optional result-type result-params graphics-file)
|
||||
(session body &optional result-type result-params)
|
||||
"Asynchronously evaluate BODY in SESSION.
|
||||
Returns a placeholder string for insertion, to later be replaced
|
||||
by `org-babel-comint-async-filter'."
|
||||
|
@ -539,37 +400,28 @@ by `org-babel-comint-async-filter'."
|
|||
session (current-buffer)
|
||||
"ob_comint_async_python_\\(.+\\)_\\(.+\\)"
|
||||
'org-babel-chomp 'org-babel-python-async-value-callback)
|
||||
(pcase result-type
|
||||
(`output
|
||||
(let ((uuid (org-id-uuid)))
|
||||
(with-temp-buffer
|
||||
(insert (format org-babel-python-async-indicator "start" uuid))
|
||||
(insert "\n")
|
||||
(insert (if graphics-file
|
||||
(format org-babel-python--output-graphics-wrapper
|
||||
body graphics-file)
|
||||
body))
|
||||
(insert "\n")
|
||||
(insert (format org-babel-python-async-indicator "end" uuid))
|
||||
(let ((python-shell-buffer-name
|
||||
(org-babel-python-without-earmuffs session)))
|
||||
(python-shell-send-buffer)))
|
||||
uuid))
|
||||
(`value
|
||||
(let ((results-file (or graphics-file
|
||||
(org-babel-temp-file "python-")))
|
||||
(tmp-src-file (org-babel-temp-file "python-")))
|
||||
(with-temp-file tmp-src-file (insert body))
|
||||
(with-temp-buffer
|
||||
(insert (org-babel-python-format-session-value
|
||||
tmp-src-file results-file result-params))
|
||||
(insert "\n")
|
||||
(unless graphics-file
|
||||
(insert (format org-babel-python-async-indicator "file" results-file)))
|
||||
(let ((python-shell-buffer-name
|
||||
(org-babel-python-without-earmuffs session)))
|
||||
(python-shell-send-buffer)))
|
||||
results-file))))
|
||||
(let ((python-shell-buffer-name (org-babel-python-without-earmuffs session)))
|
||||
(pcase result-type
|
||||
(`output
|
||||
(let ((uuid (org-id-uuid)))
|
||||
(with-temp-buffer
|
||||
(insert (format org-babel-python-async-indicator "start" uuid))
|
||||
(insert "\n")
|
||||
(insert body)
|
||||
(insert "\n")
|
||||
(insert (format org-babel-python-async-indicator "end" uuid))
|
||||
(python-shell-send-buffer))
|
||||
uuid))
|
||||
(`value
|
||||
(let ((tmp-results-file (org-babel-temp-file "python-"))
|
||||
(tmp-src-file (org-babel-temp-file "python-")))
|
||||
(with-temp-file tmp-src-file (insert body))
|
||||
(with-temp-buffer
|
||||
(insert (org-babel-python-format-session-value tmp-src-file tmp-results-file result-params))
|
||||
(insert "\n")
|
||||
(insert (format org-babel-python-async-indicator "file" tmp-results-file))
|
||||
(python-shell-send-buffer))
|
||||
tmp-results-file)))))
|
||||
|
||||
(provide 'ob-python)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-ref.el --- Babel Functions for Referencing External Data -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Authors: Eric Schulte
|
||||
;; Dan Davison
|
||||
|
@ -59,9 +59,8 @@
|
|||
|
||||
(declare-function org-babel-lob-get-info "ob-lob" (&optional datum no-eval))
|
||||
(declare-function org-element-at-point "org-element" (&optional pom cached-only))
|
||||
(declare-function org-element-property "org-element-ast" (property node))
|
||||
(declare-function org-element-post-affiliated "org-element" (node))
|
||||
(declare-function org-element-type "org-element-ast" (node &optional anonymous))
|
||||
(declare-function org-element-property "org-element" (property element))
|
||||
(declare-function org-element-type "org-element" (element))
|
||||
(declare-function org-end-of-meta-data "org" (&optional full))
|
||||
(declare-function org-find-property "org" (property &optional value))
|
||||
(declare-function org-id-find-id-file "org-id" (id))
|
||||
|
@ -156,9 +155,8 @@ Emacs Lisp representation of the value of the variable."
|
|||
(when (string-match "^\\(.+\\):\\(.+\\)$" ref)
|
||||
(setq split-file (match-string 1 ref))
|
||||
(setq split-ref (match-string 2 ref))
|
||||
(when (file-exists-p split-file)
|
||||
(find-file split-file)
|
||||
(setq ref split-ref)))
|
||||
(find-file split-file)
|
||||
(setq ref split-ref))
|
||||
(org-with-wide-buffer
|
||||
(goto-char (point-min))
|
||||
(let* ((params (append args '((:results . "none"))))
|
||||
|
@ -173,7 +171,7 @@ Emacs Lisp representation of the value of the variable."
|
|||
(let ((e (org-element-at-point)))
|
||||
(when (equal (org-element-property :name e) ref)
|
||||
(goto-char
|
||||
(org-element-post-affiliated e))
|
||||
(org-element-property :post-affiliated e))
|
||||
(pcase (org-element-type e)
|
||||
(`babel-call
|
||||
(throw :found
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-ruby.el --- Babel Functions for Ruby -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Keywords: literate programming, reproducible research
|
||||
|
@ -73,7 +73,7 @@ It's possible to override it by using a header argument `:ruby'")
|
|||
:type 'symbol)
|
||||
|
||||
(defun org-babel-execute:ruby (body params)
|
||||
"Execute Ruby BODY according to PARAMS.
|
||||
"Execute a block of Ruby code with Babel.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
(let* ((session (org-babel-ruby-initiate-session
|
||||
(cdr (assq :session params)) params))
|
||||
|
@ -127,8 +127,7 @@ This function is called by `org-babel-execute-src-block'."
|
|||
;; helper functions
|
||||
|
||||
(defun org-babel-variable-assignments:ruby (params)
|
||||
"Return list of ruby statements assigning the block's variables.
|
||||
The assignments are defined in PARAMS."
|
||||
"Return list of ruby statements assigning the block's variables."
|
||||
(mapcar
|
||||
(lambda (pair)
|
||||
(format "%s=%s"
|
||||
|
@ -141,7 +140,7 @@ The assignments are defined in PARAMS."
|
|||
Convert an elisp value into a string of ruby source code
|
||||
specifying a variable of the same value."
|
||||
(if (listp var)
|
||||
(concat "[" (mapconcat #'org-babel-ruby-var-to-ruby var ", \n") "]")
|
||||
(concat "[" (mapconcat #'org-babel-ruby-var-to-ruby var ", ") "]")
|
||||
(if (eq var 'hline)
|
||||
org-babel-ruby-hline-to
|
||||
(format "%S" var))))
|
||||
|
@ -153,28 +152,20 @@ Emacs-lisp table, otherwise return the results as a string."
|
|||
(let ((res (org-babel-script-escape results)))
|
||||
(if (listp res)
|
||||
(mapcar (lambda (el) (if (not el)
|
||||
org-babel-ruby-nil-to el))
|
||||
org-babel-ruby-nil-to el))
|
||||
res)
|
||||
res)))
|
||||
|
||||
(defvar org-babel-ruby-prompt "_org_babel_ruby_prompt "
|
||||
"String used for unique prompt.")
|
||||
|
||||
(defvar org-babel-ruby-define-prompt
|
||||
(format "IRB.conf[:PROMPT][:CUSTOM] = { :PROMPT_I => \"%s\" }" org-babel-ruby-prompt))
|
||||
|
||||
(defun org-babel-ruby-initiate-session (&optional session params)
|
||||
"Initiate a ruby session.
|
||||
If there is not a current inferior-process-buffer in SESSION
|
||||
then create one. Return the initialized session.
|
||||
Session settings (`:ruby' header arg value) are taken from PARAMS."
|
||||
then create one. Return the initialized session."
|
||||
(unless (string= session "none")
|
||||
(org-require-package 'inf-ruby)
|
||||
(let* ((command (cdr (or (assq :ruby params)
|
||||
(assoc inf-ruby-default-implementation
|
||||
inf-ruby-implementations))))
|
||||
(buffer (get-buffer (format "*%s*" session)))
|
||||
(new-session? (not buffer))
|
||||
(session-buffer (or buffer (save-window-excursion
|
||||
(run-ruby-or-pop-to-buffer
|
||||
(if (functionp command)
|
||||
|
@ -185,32 +176,16 @@ Session settings (`:ruby' header arg value) are taken from PARAMS."
|
|||
(inf-ruby-buffer)))
|
||||
(current-buffer)))))
|
||||
(if (org-babel-comint-buffer-livep session-buffer)
|
||||
(progn
|
||||
(sit-for .25)
|
||||
;; Setup machine-readable prompt: no echo, prompts matching
|
||||
;; uniquely by regexp.
|
||||
(when new-session?
|
||||
(with-current-buffer session-buffer
|
||||
(setq-local
|
||||
org-babel-comint-prompt-regexp-old comint-prompt-regexp
|
||||
comint-prompt-regexp (concat "^" org-babel-ruby-prompt))
|
||||
(insert org-babel-ruby-define-prompt ";")
|
||||
(insert "_org_prompt_mode=conf.prompt_mode;conf.prompt_mode=:CUSTOM;")
|
||||
(insert "conf.echo=false\n")
|
||||
(comint-send-input nil t)))
|
||||
session-buffer)
|
||||
(progn (sit-for .25) session-buffer)
|
||||
(sit-for .5)
|
||||
(org-babel-ruby-initiate-session session)))))
|
||||
|
||||
(defvar org-babel-ruby-eoe-indicator ":org_babel_ruby_eoe"
|
||||
"String to indicate that evaluation has completed.")
|
||||
|
||||
(defvar org-babel-ruby-f-write
|
||||
"File.open('%s','w'){|f| f.write((_.class == String) ? _ : _.inspect)}")
|
||||
|
||||
(defvar org-babel-ruby-pp-f-write
|
||||
"File.open('%s','w'){|f| $stdout = f; pp(results); $stdout = orig_out}")
|
||||
|
||||
(defvar org-babel-ruby-wrapper-method
|
||||
"
|
||||
def main()
|
||||
|
@ -219,7 +194,6 @@ end
|
|||
results = main()
|
||||
File.open('%s', 'w'){ |f| f.write((results.class == String) ? results : results.inspect) }
|
||||
")
|
||||
|
||||
(defvar org-babel-ruby-pp-wrapper-method
|
||||
"
|
||||
require 'pp'
|
||||
|
@ -263,6 +237,7 @@ return the value of the last statement in BODY, as elisp."
|
|||
(org-babel-comint-with-output
|
||||
(buffer org-babel-ruby-eoe-indicator t eoe-string)
|
||||
(insert eoe-string) (comint-send-input nil t))
|
||||
;; Now we can start the evaluation.
|
||||
(mapconcat
|
||||
#'identity
|
||||
(butlast
|
||||
|
@ -271,9 +246,14 @@ return the value of the last statement in BODY, as elisp."
|
|||
#'org-trim
|
||||
(org-babel-comint-with-output
|
||||
(buffer org-babel-ruby-eoe-indicator t body)
|
||||
(insert (org-babel-chomp body) "\n" eoe-string)
|
||||
(comint-send-input nil t))
|
||||
"\n") "[\r\n]")) "\n")))
|
||||
(mapc
|
||||
(lambda (line)
|
||||
(insert (org-babel-chomp line)) (comint-send-input nil t))
|
||||
(list "conf.echo=false;_org_prompt_mode=conf.prompt_mode;conf.prompt_mode=:NULL"
|
||||
body
|
||||
"conf.prompt_mode=_org_prompt_mode;conf.echo=true"
|
||||
eoe-string)))
|
||||
"\n") "[\r\n]") 4) "\n")))
|
||||
(`value
|
||||
(let* ((tmp-file (org-babel-temp-file "ruby-"))
|
||||
(ppp (or (member "code" result-params)
|
||||
|
@ -293,7 +273,7 @@ return the value of the last statement in BODY, as elisp."
|
|||
"results=_" "require 'pp'" "orig_out = $stdout"
|
||||
(format org-babel-ruby-pp-f-write
|
||||
(org-babel-process-file-name tmp-file 'noquote))))
|
||||
(list (format "puts \"%s\"" org-babel-ruby-eoe-indicator))))
|
||||
(list org-babel-ruby-eoe-indicator)))
|
||||
(comint-send-input nil t))
|
||||
(org-babel-eval-read-file tmp-file))))))
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-sass.el --- Babel Functions for the Sass CSS generation language -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Keywords: literate programming, reproducible research
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-scheme.el --- Babel Functions for Scheme -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2010-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2010-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Authors: Eric Schulte
|
||||
;; Michael Gauland
|
||||
|
@ -54,7 +54,7 @@
|
|||
(defvar geiser-debug-jump-to-debug-p) ; Defined in geiser-debug.el
|
||||
(defvar geiser-repl-use-other-window) ; Defined in geiser-repl.el
|
||||
(defvar geiser-repl-window-allow-split) ; Defined in geiser-repl.el
|
||||
(declare-function geiser-connect "ext:geiser-repl" (impl &optional host port))
|
||||
|
||||
(declare-function run-geiser "ext:geiser-repl" (impl))
|
||||
(declare-function geiser "ext:geiser-repl" (impl))
|
||||
(declare-function geiser-mode "ext:geiser-mode" ())
|
||||
|
@ -78,17 +78,6 @@
|
|||
|
||||
(defvar org-babel-default-header-args:scheme '()
|
||||
"Default header arguments for scheme code blocks.")
|
||||
(defconst org-babel-header-args:scheme '((host . :any)
|
||||
(port . :any))
|
||||
"Header arguments supported in Scheme.")
|
||||
|
||||
(defun org-babel-scheme-expand-header-arg-vars (vars)
|
||||
"Expand :var header arguments given as VARS."
|
||||
(mapconcat
|
||||
(lambda (var)
|
||||
(format "(define %S %S)" (car var) (cdr var)))
|
||||
vars
|
||||
"\n"))
|
||||
|
||||
(defun org-babel-expand-body:scheme (body params)
|
||||
"Expand BODY according to PARAMS, return the expanded body."
|
||||
|
@ -97,7 +86,13 @@
|
|||
(postpends (cdr (assq :epilogue params))))
|
||||
(concat (and prepends (concat prepends "\n"))
|
||||
(if (null vars) body
|
||||
(concat (org-babel-scheme-expand-header-arg-vars vars) "\n" body))
|
||||
(format "(let (%s)\n%s\n)"
|
||||
(mapconcat
|
||||
(lambda (var)
|
||||
(format "%S" (print `(,(car var) ',(cdr var)))))
|
||||
vars
|
||||
"\n ")
|
||||
body))
|
||||
(and postpends (concat "\n" postpends)))))
|
||||
|
||||
|
||||
|
@ -124,17 +119,13 @@
|
|||
(with-current-buffer (set-buffer buffer)
|
||||
geiser-impl--implementation))
|
||||
|
||||
(defun org-babel-scheme-get-repl (impl name &optional host port)
|
||||
"Switch to a Scheme REPL, creating it if it doesn't exist.
|
||||
|
||||
If the variables HOST and PORT are set, connect to the running Scheme REPL."
|
||||
(defun org-babel-scheme-get-repl (impl name)
|
||||
"Switch to a scheme REPL, creating it if it doesn't exist."
|
||||
(let ((buffer (org-babel-scheme-get-session-buffer name)))
|
||||
(or buffer
|
||||
(progn
|
||||
(if (fboundp 'geiser)
|
||||
(if (and host port)
|
||||
(geiser-connect impl host port)
|
||||
(geiser impl))
|
||||
(geiser impl)
|
||||
;; Obsolete since Geiser 0.26.
|
||||
(run-geiser impl))
|
||||
(when name
|
||||
|
@ -171,7 +162,7 @@ org-babel-scheme-execute-with-geiser will use a temporary session."
|
|||
,@body
|
||||
(current-message))))
|
||||
|
||||
(defun org-babel-scheme-execute-with-geiser (code output impl repl &optional host port)
|
||||
(defun org-babel-scheme-execute-with-geiser (code output impl repl)
|
||||
"Execute code in specified REPL.
|
||||
If the REPL doesn't exist, create it using the given scheme
|
||||
implementation.
|
||||
|
@ -187,7 +178,7 @@ is true; otherwise returns the last value."
|
|||
(let ((geiser-repl-window-allow-split nil)
|
||||
(geiser-repl-use-other-window nil))
|
||||
(let ((repl-buffer (save-current-buffer
|
||||
(org-babel-scheme-get-repl impl repl host port))))
|
||||
(org-babel-scheme-get-repl impl repl))))
|
||||
(when (not (eq impl (org-babel-scheme-get-buffer-impl
|
||||
(current-buffer))))
|
||||
(message "Implementation mismatch: %s (%s) %s (%s)" impl (symbolp impl)
|
||||
|
@ -251,8 +242,6 @@ This function is called by `org-babel-execute-src-block'."
|
|||
geiser-scheme-implementation
|
||||
geiser-default-implementation
|
||||
(car geiser-active-implementations)))
|
||||
(host (cdr (assq :host params)))
|
||||
(port (cdr (assq :port params)))
|
||||
(session (org-babel-scheme-make-session-name
|
||||
source-buffer-name (cdr (assq :session params)) impl))
|
||||
(full-body (org-babel-expand-body:scheme body params))
|
||||
|
@ -262,9 +251,7 @@ This function is called by `org-babel-execute-src-block'."
|
|||
full-body ; code
|
||||
(string= result-type "output") ; output?
|
||||
impl ; implementation
|
||||
(and (not (string= session "none")) session) ; session
|
||||
host ; REPL host
|
||||
port))) ; REPL port
|
||||
(and (not (string= session "none")) session)))) ; session
|
||||
(let ((table
|
||||
(org-babel-reassemble-table
|
||||
result
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-screen.el --- Babel Support for Interactive Terminal -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Benjamin Andresen
|
||||
;; Maintainer: Ken Mankoff <mankoff@gmail.com>
|
||||
|
@ -50,8 +50,8 @@ In case you want to use a different screen than one selected by your $PATH")
|
|||
"Default arguments to use when running screen source blocks.")
|
||||
|
||||
(defun org-babel-execute:screen (body params)
|
||||
"Send BODY via screen to a terminal using Babel, according to PARAMS.
|
||||
\"default\" session is used when none is specified in the PARAMS."
|
||||
"Send a block of code via screen to a terminal using Babel.
|
||||
\"default\" session is used when none is specified."
|
||||
(message "Sending source code block to interactive terminal session...")
|
||||
(save-window-excursion
|
||||
(let* ((session (cdr (assq :session params)))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-sed.el --- Babel Functions for Sed Scripts -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2015-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2015-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Bjarte Johansen
|
||||
;; Keywords: literate programming, reproducible research
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-shell.el --- Babel Functions for Shell Evaluation -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Maintainer: Matthew Trzcinski <matt@excalamus.com>
|
||||
|
@ -45,11 +45,6 @@
|
|||
(declare-function orgtbl-to-generic "org-table" (table params))
|
||||
|
||||
(defvar org-babel-default-header-args:shell '())
|
||||
|
||||
(defconst org-babel-header-args:shell
|
||||
'((async . ((yes no))))
|
||||
"Shell-specific header arguments.")
|
||||
|
||||
(defvar org-babel-shell-names)
|
||||
|
||||
(defconst org-babel-shell-set-prompt-commands
|
||||
|
@ -57,6 +52,8 @@
|
|||
("fish" . "function fish_prompt\n\techo \"%s\"\nend")
|
||||
;; prompt2 is like PS2 in POSIX shells.
|
||||
("csh" . "set prompt=\"%s\"\nset prompt2=\"\"")
|
||||
;; PowerShell, similar to fish, does not have PS2 equivalent.
|
||||
("posh" . "function prompt { \"%s\" }")
|
||||
;; PROMPT_COMMAND can override PS1 settings. Disable it.
|
||||
;; Disable PS2 to avoid garbage in multi-line inputs.
|
||||
(t . "PROMPT_COMMAND=;PS1=\"%s\";PS2="))
|
||||
|
@ -70,6 +67,8 @@ that will be called with a single additional argument: prompt string.
|
|||
The fallback association template is defined in (t . \"template\")
|
||||
alist element.")
|
||||
|
||||
(defvar org-babel-prompt-command)
|
||||
|
||||
(defun org-babel-shell-initialize ()
|
||||
"Define execution functions associated to shell names.
|
||||
This function has to be called whenever `org-babel-shell-names'
|
||||
|
@ -81,8 +80,10 @@ is modified outside the Customize interface."
|
|||
(lambda (body params)
|
||||
(:documentation
|
||||
(format "Execute a block of %s commands with Babel." name))
|
||||
(let ((explicit-shell-file-name name)
|
||||
(shell-file-name name))
|
||||
(let ((shell-file-name name)
|
||||
(org-babel-prompt-command
|
||||
(or (cdr (assoc name org-babel-shell-set-prompt-commands))
|
||||
(alist-get t org-babel-shell-set-prompt-commands))))
|
||||
(org-babel-execute:shell body params))))
|
||||
(put fname 'definition-name 'org-babel-shell-initialize))
|
||||
(defalias (intern (concat "org-babel-variable-assignments:" name))
|
||||
|
@ -92,9 +93,6 @@ variables."
|
|||
name))
|
||||
(funcall (if (fboundp 'defvar-1) #'defvar-1 #'set) ;Emacs-29
|
||||
(intern (concat "org-babel-default-header-args:" name))
|
||||
nil)
|
||||
(funcall (if (fboundp 'defvar-1) #'defvar-1 #'set) ;Emacs-29
|
||||
(intern (concat "org-babel-header-args:" name))
|
||||
nil)))
|
||||
|
||||
(defcustom org-babel-shell-names
|
||||
|
@ -122,7 +120,7 @@ a shell execution being its exit code."
|
|||
:package-version '(Org . "9.4"))
|
||||
|
||||
(defun org-babel-execute:shell (body params)
|
||||
"Execute Shell BODY according to PARAMS.
|
||||
"Execute a block of Shell commands with Babel.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
(let* ((session (org-babel-sh-initiate-session
|
||||
(cdr (assq :session params))))
|
||||
|
@ -174,11 +172,6 @@ This function is called by `org-babel-execute-src-block'."
|
|||
"Return a list of statements declaring the values as a generic variable."
|
||||
(format "%s=%s" varname (org-babel-sh-var-to-sh values sep hline)))
|
||||
|
||||
(defun org-babel--variable-assignments:fish
|
||||
(varname values &optional sep hline)
|
||||
"Return a list of statements declaring the values as a fish variable."
|
||||
(format "set %s %s" varname (org-babel-sh-var-to-sh values sep hline)))
|
||||
|
||||
(defun org-babel--variable-assignments:bash_array
|
||||
(varname values &optional sep hline)
|
||||
"Return a list of statements declaring the values as a bash array."
|
||||
|
@ -224,11 +217,8 @@ This function is called by `org-babel-execute-src-block'."
|
|||
(if (string-suffix-p "bash" shell-file-name)
|
||||
(org-babel--variable-assignments:bash
|
||||
(car pair) (cdr pair) sep hline)
|
||||
(if (string-suffix-p "fish" shell-file-name)
|
||||
(org-babel--variable-assignments:fish
|
||||
(car pair) (cdr pair) sep hline)
|
||||
(org-babel--variable-assignments:sh-generic
|
||||
(car pair) (cdr pair) sep hline))))
|
||||
(org-babel--variable-assignments:sh-generic
|
||||
(car pair) (cdr pair) sep hline)))
|
||||
(org-babel--get-vars params))))
|
||||
|
||||
(defun org-babel-sh-var-to-sh (var &optional sep hline)
|
||||
|
@ -269,16 +259,10 @@ var of the same value."
|
|||
(org-babel-comint-wait-for-output (current-buffer))
|
||||
(org-babel-comint-input-command
|
||||
(current-buffer)
|
||||
(format
|
||||
(or (cdr (assoc (file-name-nondirectory shell-file-name)
|
||||
org-babel-shell-set-prompt-commands))
|
||||
(alist-get t org-babel-shell-set-prompt-commands))
|
||||
org-babel-sh-prompt))
|
||||
(setq-local
|
||||
org-babel-comint-prompt-regexp-old comint-prompt-regexp
|
||||
comint-prompt-regexp
|
||||
(concat "^" (regexp-quote org-babel-sh-prompt)
|
||||
" *"))
|
||||
(format org-babel-prompt-command org-babel-sh-prompt))
|
||||
(setq-local comint-prompt-regexp
|
||||
(concat "^" (regexp-quote org-babel-sh-prompt)
|
||||
" *"))
|
||||
;; Needed for Emacs 23 since the marker is initially
|
||||
;; undefined and the filter functions try to use it without
|
||||
;; checking.
|
||||
|
@ -373,13 +357,7 @@ return the value of the last statement in BODY."
|
|||
(when padline (insert "\n"))
|
||||
(insert body))
|
||||
(set-file-modes script-file #o755)
|
||||
(if (file-remote-p script-file)
|
||||
;; Run remote script using its local path as COMMAND.
|
||||
;; The remote execution is ensured by setting
|
||||
;; correct `default-directory'.
|
||||
(let ((default-directory (file-name-directory script-file)))
|
||||
(org-babel-eval (file-local-name script-file) ""))
|
||||
(org-babel-eval script-file ""))))
|
||||
(org-babel-eval script-file "")))
|
||||
(t (org-babel-eval shell-file-name (org-trim body))))))
|
||||
(when (and results value-is-exit-status)
|
||||
(setq results (car (reverse (split-string results "\n" t)))))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-sql.el --- Babel Functions for SQL -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Maintainer: Daniel Kraus <daniel@kraus.my>
|
||||
|
@ -113,7 +113,9 @@
|
|||
Set `sql-product' in Org edit buffer according to the
|
||||
corresponding :engine source block header argument."
|
||||
(let ((product (cdr (assq :engine (nth 2 info)))))
|
||||
(sql-set-product product)))
|
||||
(condition-case nil
|
||||
(sql-set-product product)
|
||||
(user-error "Cannot set `sql-product' in Org Src edit buffer"))))
|
||||
|
||||
(defun org-babel-sql-dbstring-mysql (host port user password database)
|
||||
"Make MySQL cmd line args for database connection. Pass nil to omit that arg."
|
||||
|
@ -407,11 +409,11 @@ argument mechanism."
|
|||
val (if sqlite
|
||||
nil
|
||||
'(:fmt (lambda (el) (if (stringp el)
|
||||
el
|
||||
(format "%S" el))))))))
|
||||
el
|
||||
(format "%S" el))))))))
|
||||
data-file)
|
||||
(if (stringp val) val (format "%S" val))))
|
||||
body t t)))
|
||||
body)))
|
||||
vars)
|
||||
body)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-sqlite.el --- Babel Functions for SQLite Databases -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2010-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2010-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Maintainer: Nick Savage <nick@nicksavage.ca>
|
||||
|
@ -57,20 +57,13 @@
|
|||
|
||||
(defun org-babel-expand-body:sqlite (body params)
|
||||
"Expand BODY according to the values of PARAMS."
|
||||
(let ((prologue (cdr (assq :prologue params)))
|
||||
(epilogue (cdr (assq :epilogue params))))
|
||||
(mapconcat 'identity
|
||||
(list
|
||||
prologue
|
||||
(org-babel-sql-expand-vars
|
||||
body (org-babel--get-vars params) t)
|
||||
epilogue)
|
||||
"\n")))
|
||||
(org-babel-sql-expand-vars
|
||||
body (org-babel--get-vars params) t))
|
||||
|
||||
(defvar org-babel-sqlite3-command "sqlite3")
|
||||
|
||||
(defun org-babel-execute:sqlite (body params)
|
||||
"Execute Sqlite BODY according to PARAMS.
|
||||
"Execute a block of Sqlite code with Babel.
|
||||
This function is called by `org-babel-execute-src-block'."
|
||||
(let ((result-params (split-string (or (cdr (assq :results params)) "")))
|
||||
(db (cdr (assq :db params)))
|
||||
|
@ -81,6 +74,7 @@ This function is called by `org-babel-execute-src-block'."
|
|||
(lambda (arg) (car (assq arg params)))
|
||||
(list :header :echo :bail :column
|
||||
:csv :html :line :list)))))
|
||||
(unless db (error "ob-sqlite: can't evaluate without a database"))
|
||||
(with-temp-buffer
|
||||
(insert
|
||||
(org-babel-eval
|
||||
|
@ -103,7 +97,7 @@ This function is called by `org-babel-execute-src-block'."
|
|||
(member :html others) separator)
|
||||
""
|
||||
"-csv"))
|
||||
(cons "db" (or db ""))))
|
||||
(cons "db " db)))
|
||||
;; body of the code block
|
||||
(org-babel-expand-body:sqlite body params)))
|
||||
(org-babel-result-cond result-params
|
||||
|
@ -128,8 +122,7 @@ This function is called by `org-babel-execute-src-block'."
|
|||
(org-babel-sql-expand-vars body vars t))
|
||||
|
||||
(defun org-babel-sqlite-table-or-scalar (result)
|
||||
"Cleanup cells in the RESULT table.
|
||||
If RESULT is a trivial 1x1 table, then unwrap it."
|
||||
"If RESULT looks like a trivial table, then unwrap it."
|
||||
(if (and (equal 1 (length result))
|
||||
(equal 1 (length (car result))))
|
||||
(org-babel-read (caar result) t)
|
||||
|
@ -140,7 +133,7 @@ If RESULT is a trivial 1x1 table, then unwrap it."
|
|||
result)))
|
||||
|
||||
(defun org-babel-sqlite-offset-colnames (table headers-p)
|
||||
"If HEADERS-P is non-nil then offset the first row as column names in TABLE."
|
||||
"If HEADERS-P is non-nil then offset the first row as column names."
|
||||
(if headers-p
|
||||
(cons (car table) (cons 'hline (cdr table)))
|
||||
table))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-table.el --- Support for Calling Babel Functions from Tables -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Keywords: literate programming, reproducible research
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob-tangle.el --- Extract Source Code From Org Files -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Keywords: literate programming, reproducible research
|
||||
|
@ -40,11 +40,11 @@
|
|||
(declare-function org-babel-update-block-body "ob-core" (new-body))
|
||||
(declare-function org-back-to-heading "org" (&optional invisible-ok))
|
||||
(declare-function org-before-first-heading-p "org" ())
|
||||
(declare-function org-element-lineage "org-element-ast" (datum &optional types with-self))
|
||||
(declare-function org-element-property "org-element-ast" (property node))
|
||||
(declare-function org-element-begin "org-element" (node))
|
||||
(declare-function org-element--cache-active-p "org-element" ())
|
||||
(declare-function org-element-lineage "org-element" (datum &optional types with-self))
|
||||
(declare-function org-element-property "org-element" (property element))
|
||||
(declare-function org-element-at-point "org-element" (&optional pom cached-only))
|
||||
(declare-function org-element-type-p "org-element-ast" (node types))
|
||||
(declare-function org-element-type "org-element" (element))
|
||||
(declare-function org-heading-components "org" ())
|
||||
(declare-function org-in-commented-heading-p "org" (&optional no-inheritance))
|
||||
(declare-function org-in-archived-heading-p "org" (&optional no-inheritance))
|
||||
|
@ -166,23 +166,6 @@ read-write permissions for the user, read-only for everyone else."
|
|||
:package-version '(Org . "9.6")
|
||||
:type 'integer)
|
||||
|
||||
(defcustom org-babel-tangle-remove-file-before-write 'auto
|
||||
"How to overwrite the existing tangle target.
|
||||
When set to nil, `org-babel-tangle' will replace contents of an existing
|
||||
tangle target (and fail when tangle target is read-only).
|
||||
When set to t, the tangle target (including read-only) will be deleted
|
||||
first and a new file, possibly with different ownership and
|
||||
permissions, will be created.
|
||||
When set to symbol `auto', overwrite read-only tangle targets and
|
||||
replace contents otherwise."
|
||||
:group 'org-babel-tangle
|
||||
:package-version '(Org . "9.7")
|
||||
:type '(choice
|
||||
(const :tag "Replace contents, but keep the same file" nil)
|
||||
(const :tag "Re-create file" t)
|
||||
(const :tag "Re-create when read-only" auto))
|
||||
:safe t)
|
||||
|
||||
(defun org-babel-find-file-noselect-refresh (file)
|
||||
"Find file ensuring that the latest changes on disk are
|
||||
represented in the file."
|
||||
|
@ -222,20 +205,21 @@ source code blocks by languages matching a regular expression.
|
|||
|
||||
Return list of the tangled file names."
|
||||
(interactive "fFile to tangle: \nP")
|
||||
(org-with-file-buffer file
|
||||
(org-with-wide-buffer
|
||||
(mapcar #'expand-file-name
|
||||
(org-babel-tangle nil target-file lang-re)))))
|
||||
(let* ((visited (find-buffer-visiting file))
|
||||
(buffer (or visited (find-file-noselect file))))
|
||||
(prog1
|
||||
(with-current-buffer buffer
|
||||
(org-with-wide-buffer
|
||||
(mapcar #'expand-file-name
|
||||
(org-babel-tangle nil target-file lang-re))))
|
||||
(unless visited (kill-buffer buffer)))))
|
||||
|
||||
(defun org-babel-tangle-publish (_ filename pub-dir)
|
||||
"Tangle FILENAME and place the results in PUB-DIR."
|
||||
(unless (file-exists-p pub-dir)
|
||||
(make-directory pub-dir t))
|
||||
(setq pub-dir (file-name-as-directory pub-dir))
|
||||
;; Rename files to avoid copying to same file when publishing to ./
|
||||
;; `copy-file' would throw an error when copying file to self.
|
||||
(mapc (lambda (el) (rename-file el pub-dir t))
|
||||
(org-babel-tangle-file filename)))
|
||||
(mapc (lambda (el) (copy-file el pub-dir t)) (org-babel-tangle-file filename)))
|
||||
|
||||
;;;###autoload
|
||||
(defun org-babel-tangle (&optional arg target-file lang-re)
|
||||
|
@ -269,8 +253,7 @@ matching a regular expression."
|
|||
(when (equal arg '(16))
|
||||
(or (cdr (assq :tangle (nth 2 (org-babel-get-src-block-info 'no-eval))))
|
||||
(user-error "Point is not in a source code block"))))
|
||||
path-collector
|
||||
(source-file buffer-file-name))
|
||||
path-collector)
|
||||
(mapc ;; map over file-names
|
||||
(lambda (by-fn)
|
||||
(let ((file-name (car by-fn)))
|
||||
|
@ -327,28 +310,10 @@ matching a regular expression."
|
|||
(compare-buffer-substrings
|
||||
nil nil nil
|
||||
tangle-buf nil nil)))))))
|
||||
(when (equal (if (file-name-absolute-p file-name)
|
||||
file-name
|
||||
(expand-file-name file-name))
|
||||
(if (file-name-absolute-p source-file)
|
||||
source-file
|
||||
(expand-file-name source-file)))
|
||||
(error "Not allowed to tangle into the same file as self"))
|
||||
;; We do not erase, but overwrite previous file
|
||||
;; to preserve any existing symlinks.
|
||||
;; This behavior is modified using
|
||||
;; `org-babel-tangle-remove-file-before-write' to
|
||||
;; tangle to read-only files.
|
||||
(when (and
|
||||
(file-exists-p file-name)
|
||||
(pcase org-babel-tangle-remove-file-before-write
|
||||
(`auto (not (file-writable-p file-name)))
|
||||
(`t t)
|
||||
(`nil nil)
|
||||
(_ (error "Invalid value of `org-babel-tangle-remove-file-before-write': %S"
|
||||
org-babel-tangle-remove-file-before-write))))
|
||||
;; erase previous file
|
||||
(when (file-exists-p file-name)
|
||||
(delete-file file-name))
|
||||
(write-region nil nil file-name)
|
||||
(write-region nil nil file-name)
|
||||
(mapc (lambda (mode) (set-file-modes file-name mode)) modes))
|
||||
(push file-name path-collector))))))
|
||||
(if (equal arg '(4))
|
||||
|
@ -413,7 +378,7 @@ references."
|
|||
(goto-char (point-min))
|
||||
(while (or (re-search-forward "\\[\\[file:.*\\]\\[.*\\]\\]" nil t)
|
||||
(re-search-forward (org-babel-noweb-wrap) nil t))
|
||||
(delete-region (save-excursion (forward-line) (point))
|
||||
(delete-region (save-excursion (beginning-of-line 1) (point))
|
||||
(save-excursion (end-of-line 1) (forward-char 1) (point)))))
|
||||
|
||||
(defun org-babel-spec-to-string (spec)
|
||||
|
@ -462,19 +427,17 @@ that the appropriate major-mode is set. SPEC has the form:
|
|||
org-babel-tangle-comment-format-end link-data)))))
|
||||
|
||||
(defun org-babel-effective-tangled-filename (buffer-fn src-lang src-tfile)
|
||||
"Return effective tangled absolute filename of a source-code block.
|
||||
BUFFER-FN is the absolute file name of the buffer, SRC-LANG the
|
||||
language of the block and SRC-TFILE is the value of the :tangle
|
||||
header argument, as computed by `org-babel-tangle-single-block'."
|
||||
(let* ((fnd (file-name-directory buffer-fn))
|
||||
(base-name (cond
|
||||
((string= "yes" src-tfile)
|
||||
;; Use the buffer name
|
||||
(file-name-sans-extension buffer-fn))
|
||||
((string= "no" src-tfile) nil)
|
||||
((> (length src-tfile) 0)
|
||||
(expand-file-name src-tfile fnd))))
|
||||
(ext (or (cdr (assoc src-lang org-babel-tangle-lang-exts)) src-lang)))
|
||||
"Return effective tangled filename of a source-code block.
|
||||
BUFFER-FN is the name of the buffer, SRC-LANG the language of the
|
||||
block and SRC-TFILE is the value of the :tangle header argument,
|
||||
as computed by `org-babel-tangle-single-block'."
|
||||
(let ((base-name (cond
|
||||
((string= "yes" src-tfile)
|
||||
;; Use the buffer name
|
||||
(file-name-sans-extension buffer-fn))
|
||||
((string= "no" src-tfile) nil)
|
||||
((> (length src-tfile) 0) src-tfile)))
|
||||
(ext (or (cdr (assoc src-lang org-babel-tangle-lang-exts)) src-lang)))
|
||||
(when base-name
|
||||
;; decide if we want to add ext to base-name
|
||||
(if (and ext (string= "yes" src-tfile))
|
||||
|
@ -491,16 +454,13 @@ source code blocks by languages matching a regular expression.
|
|||
|
||||
Optional argument TANGLE-FILE can be used to limit the collected
|
||||
code blocks by target file."
|
||||
(let ((counter 0)
|
||||
(buffer-fn (buffer-file-name (buffer-base-buffer)))
|
||||
last-heading-pos blocks)
|
||||
(let ((counter 0) last-heading-pos blocks)
|
||||
(org-babel-map-src-blocks (buffer-file-name)
|
||||
(let ((current-heading-pos
|
||||
(or (org-element-begin
|
||||
(org-element-lineage
|
||||
(org-element-at-point)
|
||||
'headline t))
|
||||
1)))
|
||||
(if (org-element--cache-active-p)
|
||||
(or (org-element-property :begin (org-element-lineage (org-element-at-point) '(headline) t)) 1)
|
||||
(org-with-wide-buffer
|
||||
(org-with-limited-levels (outline-previous-heading))))))
|
||||
(if (eq last-heading-pos current-heading-pos) (cl-incf counter)
|
||||
(setq counter 1)
|
||||
(setq last-heading-pos current-heading-pos)))
|
||||
|
@ -510,7 +470,6 @@ code blocks by target file."
|
|||
(src-lang (nth 0 info))
|
||||
(src-tfile (cdr (assq :tangle (nth 2 info)))))
|
||||
(unless (or (string= src-tfile "no")
|
||||
(not src-lang) ;; src block without lang
|
||||
(and tangle-file (not (equal tangle-file src-tfile)))
|
||||
(and lang-re (not (string-match-p lang-re src-lang))))
|
||||
;; Add the spec for this block to blocks under its tangled
|
||||
|
@ -518,7 +477,7 @@ code blocks by target file."
|
|||
(let* ((block (org-babel-tangle-single-block counter))
|
||||
(src-tfile (cdr (assq :tangle (nth 4 block))))
|
||||
(file-name (org-babel-effective-tangled-filename
|
||||
buffer-fn src-lang src-tfile))
|
||||
(nth 1 block) src-lang src-tfile))
|
||||
(by-fn (assoc file-name blocks)))
|
||||
(if by-fn (setcdr by-fn (cons (cons src-lang block) (cdr by-fn)))
|
||||
(push (cons file-name (list (cons src-lang block))) blocks)))))))
|
||||
|
@ -532,7 +491,12 @@ code blocks by target file."
|
|||
The PARAMS are the 3rd element of the info for the same src block."
|
||||
(unless (string= "no" (cdr (assq :comments params)))
|
||||
(save-match-data
|
||||
(let* ((l (org-no-properties
|
||||
(let* (;; The created link is transient. Using ID is not necessary,
|
||||
;; but could have side-effects if used. An ID property may
|
||||
;; be added to existing entries thus creating unexpected file
|
||||
;; modifications.
|
||||
(org-id-link-to-org-use-id nil)
|
||||
(l (org-no-properties
|
||||
(cl-letf (((symbol-function 'org-store-link-functions)
|
||||
(lambda () nil)))
|
||||
(org-store-link nil))))
|
||||
|
@ -549,7 +513,6 @@ The PARAMS are the 3rd element of the info for the same src block."
|
|||
(cdr (assq :tangle params)))))
|
||||
bare))))))
|
||||
|
||||
(defvar org-outline-regexp) ; defined in lisp/org.el
|
||||
(defun org-babel-tangle-single-block (block-counter &optional only-this-block)
|
||||
"Collect the tangled source for current block.
|
||||
Return the list of block attributes needed by
|
||||
|
@ -607,8 +570,8 @@ non-nil, return the full association list to be used by
|
|||
(buffer-substring
|
||||
(max (condition-case nil
|
||||
(save-excursion
|
||||
(org-back-to-heading t)
|
||||
(re-search-forward org-outline-regexp))
|
||||
(org-back-to-heading t) ; Sets match data
|
||||
(match-end 0))
|
||||
(error (point-min)))
|
||||
(save-excursion
|
||||
(if (re-search-backward
|
||||
|
@ -625,12 +588,13 @@ non-nil, return the full association list to be used by
|
|||
link
|
||||
source-name
|
||||
params
|
||||
(if (org-src-preserve-indentation-p) (org-trim body t)
|
||||
(if org-src-preserve-indentation
|
||||
(org-trim body t)
|
||||
(org-trim (org-remove-indentation body)))
|
||||
comment)))
|
||||
(if only-this-block
|
||||
(let* ((file-name (org-babel-effective-tangled-filename
|
||||
file src-lang src-tfile)))
|
||||
(nth 1 result) src-lang src-tfile)))
|
||||
(list (cons file-name (list (cons src-lang result)))))
|
||||
result)))
|
||||
|
||||
|
@ -651,12 +615,9 @@ by `org-babel-get-src-block-info'."
|
|||
|
||||
;; de-tangling functions
|
||||
(defun org-babel-detangle (&optional source-code-file)
|
||||
"Propagate changes from current source buffer back to the original Org file.
|
||||
"Propagate changes in source file back original to Org file.
|
||||
This requires that code blocks were tangled with link comments
|
||||
which enable the original code blocks to be found.
|
||||
|
||||
Optional argument SOURCE-CODE-FILE is the file path to be used instead
|
||||
of the current buffer."
|
||||
which enable the original code blocks to be found."
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(when source-code-file (find-file source-code-file))
|
||||
|
@ -711,7 +672,8 @@ of the current buffer."
|
|||
(org-back-to-heading t))
|
||||
;; Do not skip the first block if it begins at point min.
|
||||
(cond ((or (org-at-heading-p)
|
||||
(not (org-element-type-p (org-element-at-point) 'src-block)))
|
||||
(not (eq (org-element-type (org-element-at-point))
|
||||
'src-block)))
|
||||
(org-babel-next-src-block n))
|
||||
((= n 1))
|
||||
(t (org-babel-next-src-block (1- n)))))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ob.el --- Working with Code Blocks in Org -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Authors: Eric Schulte
|
||||
;; Keywords: literate programming, reproducible research
|
||||
|
|
182
lisp/oc-basic.el
182
lisp/oc-basic.el
|
@ -1,6 +1,6 @@
|
|||
;;; oc-basic.el --- basic backend for citations -*- lexical-binding: t; -*-
|
||||
;;; oc-basic.el --- basic back-end for citations -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2021-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2021-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Nicolas Goaziou <mail@nicolasgoaziou.fr>
|
||||
|
||||
|
@ -78,19 +78,9 @@
|
|||
(declare-function org-open-at-point "org" (&optional arg))
|
||||
(declare-function org-open-file "org" (path &optional in-emacs line search))
|
||||
|
||||
(declare-function org-element-create "org-element-ast" (type &optional props &rest children))
|
||||
(declare-function org-element-set "org-element-ast" (old new &optional keep-props))
|
||||
|
||||
(declare-function org-element-interpret-data "org-element" (data))
|
||||
(declare-function org-element-parse-secondary-string "org-element" (string restriction &optional parent))
|
||||
(declare-function org-element-map "org-element"
|
||||
( data types fun
|
||||
&optional
|
||||
info first-match no-recursion
|
||||
with-affiliated no-undefer))
|
||||
(declare-function org-element-property "org-element-ast" (property node))
|
||||
(declare-function org-element-type-p "org-element-ast" (node types))
|
||||
(declare-function org-element-contents "org-element-ast" (node))
|
||||
(declare-function org-element-property "org-element" (property element))
|
||||
(declare-function org-element-type "org-element" (element))
|
||||
|
||||
(declare-function org-export-data "org-export" (data info))
|
||||
(declare-function org-export-derived-backend-p "org-export" (backend &rest backends))
|
||||
|
@ -172,7 +162,7 @@ Return a hash table with citation references as keys and fields alist as values.
|
|||
(puthash (cdr (assq 'id item))
|
||||
(mapcar (pcase-lambda (`(,field . ,value))
|
||||
(pcase field
|
||||
((or 'author 'editor)
|
||||
((or 'author 'editors)
|
||||
;; Author and editors are arrays of
|
||||
;; objects, each of them designing a
|
||||
;; person. These objects may contain
|
||||
|
@ -282,9 +272,6 @@ Optional argument INFO is the export state, as a property list."
|
|||
(plist-get info :cite-basic/bibliography)
|
||||
(let ((results nil))
|
||||
(dolist (file (org-cite-list-bibliography-files))
|
||||
;; Follow symlinks, to look into modification time of the
|
||||
;; actual file, not its symlink.
|
||||
(setq file (file-truename file))
|
||||
(when (file-readable-p file)
|
||||
(with-temp-buffer
|
||||
(when (or (org-file-has-changed-p file)
|
||||
|
@ -343,9 +330,9 @@ FIELD is a symbol. ENTRY-OR-KEY is either an association list, as returned by
|
|||
|
||||
Optional argument INFO is the export state, as a property list.
|
||||
|
||||
Return value may be nil or a string. If current export backend is derived
|
||||
from `latex', return a raw string object instead, unless optional
|
||||
argument RAW is non-nil.
|
||||
Return value may be nil or a string. If current export back-end is derived
|
||||
from `latex', return a raw string instead, unless optional argument RAW is
|
||||
non-nil.
|
||||
|
||||
Throw an error if the field value is non-string and non-nil."
|
||||
(let ((value
|
||||
|
@ -368,27 +355,17 @@ Throw an error if the field value is non-string and non-nil."
|
|||
|
||||
(defun org-cite-basic--shorten-names (names)
|
||||
"Return a list of family names from a list of full NAMES.
|
||||
NAMES can be a string or raw string object.
|
||||
|
||||
To better accomomodate corporate names, this will only shorten
|
||||
personal names of the form \"family, given\"."
|
||||
(let (names-string raw-p)
|
||||
(cond
|
||||
((stringp names) (setq names-string names))
|
||||
((org-element-type-p names 'raw)
|
||||
(setq names-string (mapconcat #'identity (org-element-contents names) "")
|
||||
raw-p t)))
|
||||
(when names-string
|
||||
(setq names-string
|
||||
(mapconcat
|
||||
(lambda (name)
|
||||
(if (eq 1 (length name))
|
||||
(cdr (split-string name))
|
||||
(car (split-string name ", "))))
|
||||
(split-string names-string " and ")
|
||||
", "))
|
||||
(if raw-p (org-export-raw-string names-string)
|
||||
names-string))))
|
||||
(when (stringp names)
|
||||
(mapconcat
|
||||
(lambda (name)
|
||||
(if (eq 1 (length name))
|
||||
(cdr (split-string name))
|
||||
(car (split-string name ", "))))
|
||||
(split-string names " and ")
|
||||
", ")))
|
||||
|
||||
(defun org-cite-basic--number-to-suffix (n)
|
||||
"Compute suffix associated to number N.
|
||||
|
@ -444,7 +421,7 @@ necessary, unless optional argument NO-SUFFIX is non-nil."
|
|||
(year
|
||||
(or (org-cite-basic--get-field 'year entry-or-key info 'raw)
|
||||
(let ((date
|
||||
(org-cite-basic--get-field 'date entry-or-key info 'raw)))
|
||||
(org-cite-basic--get-field 'date entry-or-key info t)))
|
||||
(and (stringp date)
|
||||
(string-match (rx string-start
|
||||
(group (= 4 digit))
|
||||
|
@ -472,38 +449,6 @@ necessary, unless optional argument NO-SUFFIX is non-nil."
|
|||
new))))
|
||||
(if no-suffix year (concat year suffix)))))))
|
||||
|
||||
(defun org-cite-basic--print-bibtex-string (element &optional info)
|
||||
"Print Bibtex formatted string ELEMENT, according to Bibtex syntax.
|
||||
Remove all the {...} that are not a part of LaTeX macros and parse the
|
||||
LaTeX fragments. Do nothing when current backend is derived from
|
||||
LaTeX, according to INFO.
|
||||
|
||||
Return updated ELEMENT."
|
||||
(if (org-export-derived-backend-p (plist-get info :back-end) 'latex)
|
||||
;; Derived from LaTeX, no need to use manual ad-hoc LaTeX
|
||||
;; parser.
|
||||
element
|
||||
;; Convert ELEMENT to anonymous when ELEMENT is string.
|
||||
;; Otherwise, we cannot modify ELEMENT by side effect.
|
||||
(when (org-element-type-p element 'plain-text)
|
||||
(setq element (org-element-create 'anonymous nil element)))
|
||||
;; Approximately parse LaTeX fragments, assuming Org mode syntax
|
||||
;; (it is close to original LaTeX, and we do not want to
|
||||
;; re-implement complete LaTeX parser here))
|
||||
(org-element-map element t
|
||||
(lambda (str)
|
||||
(when (stringp str)
|
||||
(org-element-set
|
||||
str
|
||||
(org-element-parse-secondary-string
|
||||
str '(latex-fragment entity))))))
|
||||
;; Strip the remaining { and }.
|
||||
(org-element-map element t
|
||||
(lambda (str)
|
||||
(when (stringp str)
|
||||
(org-element-set str (replace-regexp-in-string "[{}]" "" str)))))
|
||||
element))
|
||||
|
||||
(defun org-cite-basic--print-entry (entry style &optional info)
|
||||
"Format ENTRY according to STYLE string.
|
||||
ENTRY is an alist, as returned by `org-cite-basic--get-entry'.
|
||||
|
@ -515,29 +460,27 @@ Optional argument INFO is the export state, as a property list."
|
|||
(org-cite-basic--get-field 'journal entry info)
|
||||
(org-cite-basic--get-field 'institution entry info)
|
||||
(org-cite-basic--get-field 'school entry info))))
|
||||
(org-cite-basic--print-bibtex-string
|
||||
(pcase style
|
||||
("plain"
|
||||
(let ((year (org-cite-basic--get-year entry info 'no-suffix)))
|
||||
(org-cite-concat
|
||||
(org-cite-basic--shorten-names author) ". "
|
||||
title (and from (list ", " from)) ", " year ".")))
|
||||
("numeric"
|
||||
(let ((n (org-cite-basic--key-number (cdr (assq 'id entry)) info))
|
||||
(year (org-cite-basic--get-year entry info 'no-suffix)))
|
||||
(org-cite-concat
|
||||
(format "[%d] " n) author ", "
|
||||
(org-cite-emphasize 'italic title)
|
||||
(and from (list ", " from)) ", "
|
||||
year ".")))
|
||||
;; Default to author-year. Use year disambiguation there.
|
||||
(_
|
||||
(let ((year (org-cite-basic--get-year entry info)))
|
||||
(org-cite-concat
|
||||
author " (" year "). "
|
||||
(org-cite-emphasize 'italic title)
|
||||
(and from (list ", " from)) "."))))
|
||||
info)))
|
||||
(pcase style
|
||||
("plain"
|
||||
(let ((year (org-cite-basic--get-year entry info 'no-suffix)))
|
||||
(org-cite-concat
|
||||
(org-cite-basic--shorten-names author) ". "
|
||||
title (and from (list ", " from)) ", " year ".")))
|
||||
("numeric"
|
||||
(let ((n (org-cite-basic--key-number (cdr (assq 'id entry)) info))
|
||||
(year (org-cite-basic--get-year entry info 'no-suffix)))
|
||||
(org-cite-concat
|
||||
(format "[%d] " n) author ", "
|
||||
(org-cite-emphasize 'italic title)
|
||||
(and from (list ", " from)) ", "
|
||||
year ".")))
|
||||
;; Default to author-year. Use year disambiguation there.
|
||||
(_
|
||||
(let ((year (org-cite-basic--get-year entry info)))
|
||||
(org-cite-concat
|
||||
author " (" year "). "
|
||||
(org-cite-emphasize 'italic title)
|
||||
(and from (list ", " from)) "."))))))
|
||||
|
||||
|
||||
;;; "Activate" capability
|
||||
|
@ -710,30 +653,22 @@ export communication channel, as a property list."
|
|||
;; "author" style.
|
||||
(`(,(or "author" "a") . ,variant)
|
||||
(let ((caps (member variant '("caps" "c"))))
|
||||
(org-cite-basic--format-author-year
|
||||
citation
|
||||
(lambda (p c s) (org-cite-concat p c s))
|
||||
(lambda (prefix author _ suffix)
|
||||
(org-cite-concat
|
||||
prefix
|
||||
(if caps (org-cite-capitalize author) author)
|
||||
suffix))
|
||||
(org-export-data
|
||||
(mapconcat
|
||||
(lambda (key)
|
||||
(or
|
||||
(let ((author (org-cite-basic--get-author key info)))
|
||||
(if caps (capitalize author) author))
|
||||
"??"))
|
||||
(org-cite-get-references citation t)
|
||||
org-cite-basic-author-year-separator)
|
||||
info)))
|
||||
;; "noauthor" style.
|
||||
(`(,(or "noauthor" "na") . ,variant)
|
||||
(let ((bare? (funcall has-variant-p variant 'bare)))
|
||||
(org-cite-basic--format-author-year
|
||||
citation
|
||||
(lambda (prefix contents suffix)
|
||||
(org-cite-concat
|
||||
(unless bare? "(")
|
||||
prefix
|
||||
contents
|
||||
suffix
|
||||
(unless bare? ")")))
|
||||
(lambda (prefix _ year suffix)
|
||||
(org-cite-concat prefix year suffix))
|
||||
info)))
|
||||
(format (if (funcall has-variant-p variant 'bare) "%s" "(%s)")
|
||||
(mapconcat (lambda (key) (or (org-cite-basic--get-year key info) "????"))
|
||||
(org-cite-get-references citation t)
|
||||
org-cite-basic-author-year-separator)))
|
||||
;; "nocite" style.
|
||||
(`(,(or "nocite" "n") . ,_) nil)
|
||||
;; "text" and "note" styles.
|
||||
|
@ -749,11 +684,10 @@ export communication channel, as a property list."
|
|||
(lambda (p c s) (org-cite-concat p c s))
|
||||
(lambda (p a y s)
|
||||
(org-cite-concat p
|
||||
(if caps (org-cite-capitalize a) a)
|
||||
(if caps (capitalize a) a)
|
||||
(if bare " " " (")
|
||||
y
|
||||
(and (not bare) ")")
|
||||
s))
|
||||
y s
|
||||
(and (not bare) ")")))
|
||||
info)))
|
||||
;; "numeric" style.
|
||||
;;
|
||||
|
@ -774,7 +708,7 @@ export communication channel, as a property list."
|
|||
(lambda (p c s)
|
||||
(org-cite-concat (and (not bare) "(") p c s (and (not bare) ")")))
|
||||
(lambda (p a y s)
|
||||
(org-cite-concat p (if caps (org-cite-capitalize a) a) ", " y s))
|
||||
(org-cite-concat p (if caps (capitalize a) a) ", " y s))
|
||||
info)))
|
||||
;; This should not happen.
|
||||
(_ (error "Invalid style: %S" style)))))
|
||||
|
@ -782,7 +716,7 @@ export communication channel, as a property list."
|
|||
(defun org-cite-basic-export-bibliography (keys _files style _props backend info)
|
||||
"Generate bibliography.
|
||||
KEYS is the list of cited keys, as strings. STYLE is the expected bibliography
|
||||
style, as a string. BACKEND is the export backend, as a symbol. INFO is the
|
||||
style, as a string. BACKEND is the export back-end, as a symbol. INFO is the
|
||||
export state, as a property list."
|
||||
(mapconcat
|
||||
(lambda (entry)
|
||||
|
@ -806,7 +740,7 @@ When DATUM is a citation reference, open bibliography entry referencing
|
|||
the citation key. Otherwise, select which key to follow among all keys
|
||||
present in the citation."
|
||||
(let* ((key
|
||||
(if (org-element-type-p datum 'citation-reference)
|
||||
(if (eq 'citation-reference (org-element-type datum))
|
||||
(org-element-property :key datum)
|
||||
(pcase (org-cite-get-references datum t)
|
||||
(`(,key) key)
|
||||
|
@ -878,7 +812,7 @@ Return nil if there are no bibliography files or no entries."
|
|||
(let ((date (org-cite-basic--get-year entry nil 'no-suffix)))
|
||||
(format "%4s" (or date "")))
|
||||
org-cite-basic-column-separator
|
||||
(org-cite-basic--get-field 'title entry nil 'raw))))
|
||||
(org-cite-basic--get-field 'title entry nil t))))
|
||||
(puthash completion key org-cite-basic--completion-cache)))
|
||||
(unless (map-empty-p org-cite-basic--completion-cache) ;no key
|
||||
(puthash entries t org-cite-basic--completion-cache)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; oc-biblatex.el --- biblatex citation processor for Org -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2021-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2021-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Nicolas Goaziou <mail@nicolasgoaziou.fr>
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
|||
|
||||
;; The processor relies on "biblatex" LaTeX package. As such it ensures that
|
||||
;; the package is properly required in the document's preamble. More
|
||||
;; accurately, it will reuse any "\usepackage{biblatex}" already present in
|
||||
;; accurately, it will re-use any "\usepackage{biblatex}" already present in
|
||||
;; the document (e.g., through `org-latex-packages-alist'), or insert one using
|
||||
;; options defined in `org-cite-biblatex-options'.
|
||||
|
||||
|
@ -70,8 +70,7 @@
|
|||
(require 'org-macs)
|
||||
(require 'oc)
|
||||
|
||||
(declare-function org-element-property "org-element-ast" (property node))
|
||||
(declare-function org-element-parent "org-element-ast" (node))
|
||||
(declare-function org-element-property "org-element" (property element))
|
||||
(declare-function org-export-data "org-export" (data info))
|
||||
|
||||
|
||||
|
@ -232,7 +231,7 @@ When NO-OPT argument is non-nil, only provide mandatory arguments."
|
|||
(let* ((origin (pcase references
|
||||
(`(,reference) reference)
|
||||
(`(,reference . ,_)
|
||||
(org-element-parent reference))))
|
||||
(org-element-property :parent reference))))
|
||||
(suffix (org-element-property :suffix origin))
|
||||
(prefix (org-element-property :prefix origin)))
|
||||
(concat (and prefix
|
||||
|
@ -376,47 +375,61 @@ INFO is the export state, as a property list."
|
|||
(other
|
||||
(user-error "Invalid entry %S in `org-cite-biblatex-styles'" other))))))
|
||||
|
||||
(defun org-cite-biblatex--generate-latex-usepackage (info)
|
||||
"Ensure that the biblatex package is loaded.
|
||||
This is performed by extracting relevant information from the
|
||||
INFO export plist, and modifying any existing
|
||||
\\usepackage{biblatex} statement in the LaTeX header."
|
||||
(let ((style (org-cite-bibliography-style info))
|
||||
(usepackage-rx (rx "\\usepackage"
|
||||
(opt (group "[" (*? anything) "]"))
|
||||
"{biblatex}")))
|
||||
(concat
|
||||
(if (string-match usepackage-rx (plist-get info :latex-full-header))
|
||||
;; "biblatex" package loaded, but with none (or different) options.
|
||||
;; Replace with style-including command.
|
||||
(plist-put info :latex-full-header
|
||||
(replace-match
|
||||
(format "\\usepackage%s{biblatex}"
|
||||
(save-match-data
|
||||
(org-cite-biblatex--package-options nil style)))
|
||||
t t
|
||||
(plist-get info :latex-full-header)))
|
||||
;; No "biblatex" package loaded. Insert "usepackage" command
|
||||
;; with appropriate options, including style.
|
||||
(format "\\usepackage%s{biblatex}\n"
|
||||
(org-cite-biblatex--package-options
|
||||
org-cite-biblatex-options style))))))
|
||||
(defun org-cite-biblatex-prepare-preamble (output _keys files style &rest _)
|
||||
"Prepare document preamble for \"biblatex\" usage.
|
||||
|
||||
(defun org-cite-biblatex--generate-latex-bibresources (info)
|
||||
"From INFO generate LaTeX that loads the relevant bibliography resource files."
|
||||
(let ((files (plist-get info :bibliography)))
|
||||
(mapconcat (lambda (f)
|
||||
(format "\\addbibresource%s{%s}"
|
||||
(if (org-url-p f) "[location=remote]" "")
|
||||
f))
|
||||
files
|
||||
"\n")))
|
||||
OUTPUT is the final output of the export process. FILES is the list of file
|
||||
names used as the bibliography.
|
||||
|
||||
This function ensures \"biblatex\" package is required. It also adds resources
|
||||
to the document, and set styles."
|
||||
(with-temp-buffer
|
||||
(save-excursion (insert output))
|
||||
(when (search-forward "\\begin{document}" nil t)
|
||||
;; Ensure there is a \usepackage{biblatex} somewhere or add one.
|
||||
;; Then set options.
|
||||
(goto-char (match-beginning 0))
|
||||
(let ((re (rx "\\usepackage"
|
||||
(opt (group "[" (*? anything) "]"))
|
||||
"{biblatex}")))
|
||||
(cond
|
||||
;; No "biblatex" package loaded. Insert "usepackage" command
|
||||
;; with appropriate options, including style.
|
||||
((not (re-search-backward re nil t))
|
||||
(save-excursion
|
||||
(insert
|
||||
(format "\\usepackage%s{biblatex}\n"
|
||||
(org-cite-biblatex--package-options
|
||||
org-cite-biblatex-options style)))))
|
||||
;; "biblatex" package loaded, but without any option.
|
||||
;; Include style only.
|
||||
((not (match-beginning 1))
|
||||
(search-forward "{" nil t)
|
||||
(insert (org-cite-biblatex--package-options nil style)))
|
||||
;; "biblatex" package loaded with some options set. Override
|
||||
;; style-related options with ours.
|
||||
(t
|
||||
(replace-match
|
||||
(save-match-data
|
||||
(org-cite-biblatex--package-options (match-string 1) style))
|
||||
nil nil nil 1))))
|
||||
;; Insert resources below.
|
||||
(forward-line)
|
||||
(insert (mapconcat (lambda (f)
|
||||
(format "\\addbibresource%s{%s}"
|
||||
(if (org-url-p f) "[location=remote]" "")
|
||||
f))
|
||||
files
|
||||
"\n")
|
||||
"\n"))
|
||||
(buffer-string)))
|
||||
|
||||
|
||||
;;; Register `biblatex' processor
|
||||
(org-cite-register-processor 'biblatex
|
||||
:export-bibliography #'org-cite-biblatex-export-bibliography
|
||||
:export-citation #'org-cite-biblatex-export-citation
|
||||
:export-finalizer #'org-cite-biblatex-prepare-preamble
|
||||
:cite-styles #'org-cite-biblatex-list-styles)
|
||||
|
||||
(provide 'oc-biblatex)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; oc-bibtex.el --- Vanilla citation processor for LaTeX -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2021-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2021-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Nicolas Goaziou <mail@nicolasgoaziou.fr>
|
||||
|
||||
|
@ -41,7 +41,7 @@
|
|||
|
||||
(require 'oc)
|
||||
|
||||
(declare-function org-element-property "org-element-ast" (property node))
|
||||
(declare-function org-element-property "org-element" (property element))
|
||||
|
||||
(declare-function org-export-data "org-export" (data info))
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; oc-csl.el --- csl citation processor for Org -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2021-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2021-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Nicolas Goaziou <mail@nicolasgoaziou.fr>
|
||||
;; Maintainer: András Simonyi <andras.simonyi@gmail.com>
|
||||
|
@ -137,8 +137,8 @@
|
|||
|
||||
(declare-function org-element-interpret-data "org-element" (data))
|
||||
(declare-function org-element-map "org-element" (data types fun &optional info first-match no-recursion with-affiliated))
|
||||
(declare-function org-element-property "org-element-ast" (property node))
|
||||
(declare-function org-element-put-property "org-element-ast" (node property value))
|
||||
(declare-function org-element-property "org-element" (property element))
|
||||
(declare-function org-element-put-property "org-element" (element property value))
|
||||
|
||||
(declare-function org-export-data "org-export" (data info))
|
||||
(declare-function org-export-derived-backend-p "org-export" (backend &rest backends))
|
||||
|
@ -184,8 +184,8 @@ looks for style files in this directory, too."
|
|||
:safe #'booleanp)
|
||||
|
||||
(defcustom org-cite-csl-no-citelinks-backends '(ascii)
|
||||
"List of export backends for which cite linking is disabled.
|
||||
Cite linking for export backends derived from any of the backends listed here,
|
||||
"List of export back-ends for which cite linking is disabled.
|
||||
Cite linking for export back-ends derived from any of the back-ends listed here,
|
||||
is also disabled."
|
||||
:group 'org-cite
|
||||
:package-version '(Org . "9.5")
|
||||
|
@ -215,20 +215,19 @@ Used only when `second-field-align' is activated by the used CSL style."
|
|||
:safe #'stringp)
|
||||
|
||||
(defcustom org-cite-csl-latex-label-separator "0.6em"
|
||||
"Distance between citation label and bibliography item for LaTeX output.
|
||||
The value is a string representing the distance in valid LaTeX units.
|
||||
Used only when `second-field-align' is activated by the used CSL
|
||||
style.
|
||||
"Distance between citation label and bibliography item for LaTeX
|
||||
output in valid LaTeX units. Used only when `second-field-align'
|
||||
is activated by the used CSL style.
|
||||
|
||||
The indentation length in these cases is computed as the sum of
|
||||
`org-cite-csl-latex-label-separator' and the maximal label width, for
|
||||
example,
|
||||
`org-cite-csl-latex-label-separator' and the maximal label width,
|
||||
for example,
|
||||
|
||||
indentation length
|
||||
<------------------------->
|
||||
max. label width separator
|
||||
max. label width separator
|
||||
<---------------><-------->
|
||||
[Doe22] John Doe. A title...
|
||||
[Doe22] John Doe. A title...
|
||||
[DoeSmithJones19] John Doe, Jane Smith and...
|
||||
[SmithDoe02] Jane Smith and John Doe...
|
||||
|
||||
|
@ -443,8 +442,8 @@ INFO is the export state, as a property list."
|
|||
|
||||
(defun org-cite-csl--create-structure-params (citation info)
|
||||
"Return citeproc structure creation params for CITATION object.
|
||||
STYLE is the citation style, as a string or nil. INFO is the export
|
||||
state, as a property list."
|
||||
STYLE is the citation style, as a string or nil. INFO is the export state, as
|
||||
a property list."
|
||||
(let ((style (org-cite-citation-style citation info)))
|
||||
(pcase style
|
||||
;; "author" style.
|
||||
|
@ -504,8 +503,7 @@ state, as a property list."
|
|||
(_ (error "Invalid style: %S" style)))))
|
||||
|
||||
(defun org-cite-csl--no-citelinks-p (info)
|
||||
"Non-nil when export backend should not create cite-reference links.
|
||||
INFO is the info channel plist."
|
||||
"Non-nil when export BACKEND should not create cite-reference links."
|
||||
(or (not org-cite-csl-link-cites)
|
||||
(and org-cite-csl-no-citelinks-backends
|
||||
(apply #'org-export-derived-backend-p
|
||||
|
@ -847,11 +845,27 @@ INFO is the export state, as a property list."
|
|||
;; process.
|
||||
(org-cite-parse-elements output)))))
|
||||
|
||||
(defun org-cite-csl-finalizer (output _keys _files _style _backend info)
|
||||
"Add \"hanging\" package if missing from LaTeX output.
|
||||
OUTPUT is the export document, as a string. INFO is the export state, as a
|
||||
property list."
|
||||
(org-cite-csl--barf-without-citeproc)
|
||||
(if (not (eq 'org-latex (org-cite-csl--output-format info)))
|
||||
output
|
||||
(with-temp-buffer
|
||||
(save-excursion (insert output))
|
||||
(when (search-forward "\\begin{document}" nil t)
|
||||
(goto-char (match-beginning 0))
|
||||
;; Insert the CSL-specific parts of the LaTeX preamble.
|
||||
(insert (org-cite-csl--generate-latex-preamble info)))
|
||||
(buffer-string))))
|
||||
|
||||
|
||||
;;; Register `csl' processor
|
||||
(org-cite-register-processor 'csl
|
||||
:export-citation #'org-cite-csl-render-citation
|
||||
:export-bibliography #'org-cite-csl-render-bibliography
|
||||
:export-finalizer #'org-cite-csl-finalizer
|
||||
:cite-styles
|
||||
'((("author" "a") ("bare" "b") ("caps" "c") ("full" "f") ("bare-caps" "bc") ("caps-full" "cf") ("bare-caps-full" "bcf"))
|
||||
(("noauthor" "na") ("bare" "b") ("caps" "c") ("bare-caps" "bc"))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; oc-natbib.el --- Citation processor using natbib LaTeX package -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2021-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2021-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Nicolas Goaziou <mail@nicolasgoaziou.fr>
|
||||
|
||||
|
@ -48,7 +48,7 @@
|
|||
|
||||
(require 'oc)
|
||||
|
||||
(declare-function org-element-property "org-element-ast" (property node))
|
||||
(declare-function org-element-property "org-element" (property element))
|
||||
|
||||
(declare-function org-export-data "org-export" (data info))
|
||||
|
||||
|
@ -168,25 +168,32 @@ state, as a property list."
|
|||
(org-cite-natbib--build-optional-arguments citation info)
|
||||
(org-cite-natbib--build-arguments citation)))
|
||||
|
||||
(defun org-cite-natbib--generate-latex-preamble (info)
|
||||
"Ensure that the \"natbib\" package is loaded.
|
||||
INFO is a plist used as a communication channel."
|
||||
(and (not (string-match
|
||||
(rx "\\usepackage" (opt "[" (*? nonl) "]") "{natbib}")
|
||||
(plist-get info :latex-full-header)))
|
||||
(format "\\usepackage%s{natbib}\n"
|
||||
(if (null org-cite-natbib-options)
|
||||
""
|
||||
(format "[%s]"
|
||||
(mapconcat #'symbol-name
|
||||
org-cite-natbib-options
|
||||
","))))))
|
||||
(defun org-cite-natbib-use-package (output &rest _)
|
||||
"Ensure output requires \"natbib\" package.
|
||||
OUTPUT is the final output of the export process."
|
||||
(with-temp-buffer
|
||||
(save-excursion (insert output))
|
||||
(when (search-forward "\\begin{document}" nil t)
|
||||
;; Ensure there is a \usepackage{natbib} somewhere or add one.
|
||||
(goto-char (match-beginning 0))
|
||||
(let ((re (rx "\\usepackage" (opt "[" (*? nonl) "]") "{natbib}")))
|
||||
(unless (re-search-backward re nil t)
|
||||
(insert
|
||||
(format "\\usepackage%s{natbib}\n"
|
||||
(if (null org-cite-natbib-options)
|
||||
""
|
||||
(format "[%s]"
|
||||
(mapconcat #'symbol-name
|
||||
org-cite-natbib-options
|
||||
","))))))))
|
||||
(buffer-string)))
|
||||
|
||||
|
||||
;;; Register `natbib' processor
|
||||
(org-cite-register-processor 'natbib
|
||||
:export-bibliography #'org-cite-natbib-export-bibliography
|
||||
:export-citation #'org-cite-natbib-export-citation
|
||||
:export-finalizer #'org-cite-natbib-use-package
|
||||
:cite-styles
|
||||
'((("author" "a") ("caps" "a") ("full" "f"))
|
||||
(("noauthor" "na") ("bare" "b"))
|
||||
|
|
225
lisp/oc.el
225
lisp/oc.el
|
@ -1,6 +1,6 @@
|
|||
;;; oc.el --- Org Cite library -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2021-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2021-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Nicolas Goaziou <mail@nicolasgoaziou.fr>
|
||||
|
||||
|
@ -46,13 +46,13 @@
|
|||
;; The "export" capability is slightly more involved as one need to
|
||||
;; select the processor providing it, but may also provide a default
|
||||
;; style for citations and bibliography. Also, the choice of an
|
||||
;; export processor may depend of the current export backend. The
|
||||
;; association between export backends and triplets of parameters can
|
||||
;; export processor may depend of the current export back-end. The
|
||||
;; association between export back-ends and triplets of parameters can
|
||||
;; be set in `org-cite-export-processors' variable, or in a document,
|
||||
;; through the "cite_export" keyword.
|
||||
|
||||
;; Eventually, this library provides some tools, mainly targeted at
|
||||
;; processor implementers. Most are export-specific and are located
|
||||
;; processor implementors. Most are export-specific and are located
|
||||
;; in the "Tools only available during export" and "Tools generating
|
||||
;; or operating on parsed data" sections.
|
||||
|
||||
|
@ -71,33 +71,25 @@
|
|||
(declare-function org-at-heading-p "org" (&optional _))
|
||||
(declare-function org-collect-keywords "org" (keywords &optional unique directory))
|
||||
|
||||
(declare-function org-element-adopt "org-element-ast" (parent &rest children))
|
||||
(declare-function org-element-adopt-elements "org-element" (parent &rest children))
|
||||
(declare-function org-element-citation-parser "org-element" ())
|
||||
(declare-function org-element-citation-reference-parser "org-element" ())
|
||||
(declare-function org-element-class "org-element" (datum &optional parent))
|
||||
(declare-function org-element-contents "org-element-ast" (node))
|
||||
(declare-function org-element-create "org-element-ast" (type &optional props &rest children))
|
||||
(declare-function org-element-extract "org-element-ast" (node))
|
||||
(declare-function org-element-insert-before "org-element-ast" (node location))
|
||||
(declare-function org-element-lineage "org-element-ast" (datum &optional types with-self))
|
||||
(declare-function org-element-contents "org-element" (element))
|
||||
(declare-function org-element-create "org-element" (type &optional props &rest children))
|
||||
(declare-function org-element-extract-element "org-element" (element))
|
||||
(declare-function org-element-insert-before "org-element" (element location))
|
||||
(declare-function org-element-lineage "org-element" (datum &optional types with-self))
|
||||
(declare-function org-element-map "org-element" (data types fun &optional info first-match no-recursion with-affiliated))
|
||||
(declare-function org-element-normalize-string "org-element" (s))
|
||||
(declare-function org-element-parse-buffer "org-element" (&optional granularity visible-only keep-deferred))
|
||||
(declare-function org-element-parse-buffer "org-element" (&optional granularity visible-only))
|
||||
(declare-function org-element-parse-secondary-string "org-element" (string restriction &optional parent))
|
||||
(declare-function org-element-context "org-element" (&optional element))
|
||||
(declare-function org-element-property "org-element-ast" (property node))
|
||||
(declare-function org-element-begin "org-element" (node))
|
||||
(declare-function org-element-end "org-element" (node))
|
||||
(declare-function org-element-post-affiliated "org-element" (node))
|
||||
(declare-function org-element-post-blank "org-element" (node))
|
||||
(declare-function org-element-contents-begin "org-element" (node))
|
||||
(declare-function org-element-contents-end "org-element" (node))
|
||||
(declare-function org-element-parent "org-element-ast" (node))
|
||||
(declare-function org-element-put-property "org-element-ast" (node property value))
|
||||
(declare-function org-element-property "org-element" (property element))
|
||||
(declare-function org-element-put-property "org-element" (element property value))
|
||||
(declare-function org-element-restriction "org-element" (element))
|
||||
(declare-function org-element-set "org-element-ast" (old new))
|
||||
(declare-function org-element-type "org-element-ast" (node &optional anonymous))
|
||||
(declare-function org-element-type-p "org-element-ast" (node types))
|
||||
(declare-function org-element-set-element "org-element" (old new))
|
||||
(declare-function org-element-type "org-element" (element))
|
||||
|
||||
(declare-function org-export-derived-backend-p "org-export" (backend &rest backends))
|
||||
(declare-function org-export-get-next-element "org-export" (blob info &optional n))
|
||||
|
@ -151,12 +143,12 @@ File names must be absolute."
|
|||
|
||||
When nil, citations and bibliography are not exported.
|
||||
|
||||
When non-nil, the value is an association list between export backends and
|
||||
When non-nil, the value is an association list between export back-ends and
|
||||
citation export processors:
|
||||
|
||||
(BACKEND . PROCESSOR)
|
||||
(BACK-END . PROCESSOR)
|
||||
|
||||
where BACKEND is the name of an export backend or t, and PROCESSOR is a
|
||||
where BACK-END is the name of an export back-end or t, and PROCESSOR is a
|
||||
triplet following the pattern
|
||||
|
||||
(NAME BIBLIOGRAPHY-STYLE CITATION-STYLE)
|
||||
|
@ -168,7 +160,7 @@ exporting a citation), as a string or nil. Both BIBLIOGRAPHY-STYLE and
|
|||
CITATION-STYLE are optional. NAME is mandatory.
|
||||
|
||||
The export process selects the citation processor associated to the current
|
||||
export backend, or the most specific backend the current one is derived from,
|
||||
export back-end, or the most specific back-end the current one is derived from,
|
||||
or, if all are inadequate, to the processor associated to t. For example, with
|
||||
the following value
|
||||
|
||||
|
@ -176,9 +168,9 @@ the following value
|
|||
(latex biblatex)
|
||||
(t csl))
|
||||
|
||||
exporting with `beamer' or any backend derived from it will use `natbib',
|
||||
whereas exporting with `latex' or any backend derived from it but different
|
||||
from `beamer' will use `biblatex' processor. Any other backend, such as
|
||||
exporting with `beamer' or any back-end derived from it will use `natbib',
|
||||
whereas exporting with `latex' or any back-end derived from it but different
|
||||
from `beamer' will use `biblatex' processor. Any other back-end, such as
|
||||
`html', will use `csl' processor.
|
||||
|
||||
CITATION-STYLE is overridden by adding a style to any citation object. A nil
|
||||
|
@ -195,7 +187,7 @@ or
|
|||
#+CITE_EXPORT: basic
|
||||
|
||||
In that case, `basic' processor is used on every export, independently on the
|
||||
backend."
|
||||
back-end."
|
||||
:group 'org-cite
|
||||
:package-version '(Org . "9.5")
|
||||
:type '(choice (const :tag "No export" nil)
|
||||
|
@ -353,7 +345,7 @@ optional keys can be set:
|
|||
arguments: the list of citation keys used in the document, as
|
||||
strings, a list of bibliography files, the style, as a string
|
||||
or nil, the local properties, as a property list, the export
|
||||
backend, as a symbol, and the communication channel, as a
|
||||
back-end, as a symbol, and the communication channel, as a
|
||||
property list.
|
||||
|
||||
It is called at each \"print_bibliography\" keyword in the
|
||||
|
@ -366,7 +358,7 @@ optional keys can be set:
|
|||
|
||||
Function rendering citations. It is called with four
|
||||
arguments: a citation object, the style, as a pair, the
|
||||
export backend, as a symbol, and the communication channel,
|
||||
export back-end, as a symbol, and the communication channel,
|
||||
as a property list.
|
||||
|
||||
It is called on each citation object in the parse tree. It
|
||||
|
@ -381,7 +373,7 @@ optional keys can be set:
|
|||
six arguments: the output, as a string, a list of citation
|
||||
keys used in the document, a list of bibliography files, the
|
||||
expected bibliography style, as a string or nil, the export
|
||||
backend, as a symbol, and the communication channel, as a
|
||||
back-end, as a symbol, and the communication channel, as a
|
||||
property list.
|
||||
|
||||
It must return a string, which will become the final output
|
||||
|
@ -476,11 +468,11 @@ PROCESSOR is the name of a cite processor, as a symbol. CAPABILITY is
|
|||
"Set `:post-blank' property from element or object before DATUM to BLANKS.
|
||||
DATUM is an element or object. BLANKS is an integer. DATUM is modified
|
||||
by side-effect."
|
||||
(if (not (org-element-type-p datum 'plain-text))
|
||||
(if (not (eq 'plain-text (org-element-type datum)))
|
||||
(org-element-put-property datum :post-blank blanks)
|
||||
;; Remove any blank from string before DATUM so it is exported
|
||||
;; with exactly BLANKS white spaces.
|
||||
(org-element-set
|
||||
(org-element-set-element
|
||||
datum
|
||||
(replace-regexp-in-string
|
||||
"[ \t\n]*\\'" (make-string blanks ?\s) datum))))
|
||||
|
@ -500,11 +492,11 @@ S is split at beginning of match group N upon matching REGEXP against it.
|
|||
This function assumes S precedes CITATION."
|
||||
;; When extracting the citation, remove white spaces before it, but
|
||||
;; preserve those after it.
|
||||
(let ((post-blank (org-element-post-blank citation)))
|
||||
(let ((post-blank (org-element-property :post-blank citation)))
|
||||
(when (and post-blank (> post-blank 0))
|
||||
(org-element-insert-before (make-string post-blank ?\s) citation)))
|
||||
(org-element-insert-before
|
||||
(org-element-put-property (org-element-extract citation)
|
||||
(org-element-put-property (org-element-extract-element citation)
|
||||
:post-blank 0)
|
||||
s)
|
||||
(string-match regexp s)
|
||||
|
@ -518,21 +510,21 @@ This function assumes S precedes CITATION."
|
|||
(substring s split))))
|
||||
(when (org-string-nw-p first-part)
|
||||
(org-element-insert-before first-part citation))
|
||||
(org-element-set s last-part)))
|
||||
(org-element-set-element s last-part)))
|
||||
|
||||
(defun org-cite--move-punct-before (punct citation s info)
|
||||
"Move punctuation PUNCT before CITATION object.
|
||||
String S contains PUNCT. INFO is the export state, as a property list.
|
||||
The function assumes S follows CITATION. Parse tree is modified by side-effect."
|
||||
(if (equal s punct)
|
||||
(org-element-extract s) ;it would be empty anyway
|
||||
(org-element-set s (substring s (length punct))))
|
||||
(org-element-extract-element s) ;it would be empty anyway
|
||||
(org-element-set-element s (substring s (length punct))))
|
||||
;; Remove blanks before citation.
|
||||
(org-cite--set-previous-post-blank citation 0 info)
|
||||
(org-element-insert-before
|
||||
;; Blanks between citation and punct are now before punct and
|
||||
;; citation.
|
||||
(concat (make-string (or (org-element-post-blank citation) 0) ?\s)
|
||||
(concat (make-string (or (org-element-property :post-blank citation) 0) ?\s)
|
||||
punct)
|
||||
citation))
|
||||
|
||||
|
@ -610,18 +602,7 @@ to (adaptive outside after)."
|
|||
(append (mapcar (lambda (value)
|
||||
(pcase value
|
||||
(`(,f . ,d)
|
||||
(setq f (org-strip-quotes f))
|
||||
(if (or (file-name-absolute-p f)
|
||||
(file-remote-p f)
|
||||
(equal d default-directory))
|
||||
;; Keep absolute paths, remote paths, and
|
||||
;; local relative paths.
|
||||
f
|
||||
;; Adjust relative bibliography path for
|
||||
;; #+SETUP files located in other directory.
|
||||
;; Also, see `org-export--update-included-link'.
|
||||
(file-relative-name
|
||||
(expand-file-name f d) default-directory)))))
|
||||
(expand-file-name (org-strip-quotes f) d))))
|
||||
(pcase (org-collect-keywords
|
||||
'("BIBLIOGRAPHY") nil '("BIBLIOGRAPHY"))
|
||||
(`(("BIBLIOGRAPHY" . ,pairs)) pairs)))
|
||||
|
@ -638,12 +619,12 @@ or from the current buffer."
|
|||
(let ((contents (org-element-contents citation)))
|
||||
(cond
|
||||
((null contents)
|
||||
(org-with-point-at (org-element-contents-begin citation)
|
||||
(narrow-to-region (point) (org-element-contents-end citation))
|
||||
(org-with-point-at (org-element-property :contents-begin citation)
|
||||
(narrow-to-region (point) (org-element-property :contents-end citation))
|
||||
(let ((references nil))
|
||||
(while (not (eobp))
|
||||
(let ((reference (org-element-citation-reference-parser)))
|
||||
(goto-char (org-element-end reference))
|
||||
(goto-char (org-element-property :end reference))
|
||||
(push (if keys-only
|
||||
(org-element-property :key reference)
|
||||
reference)
|
||||
|
@ -655,8 +636,8 @@ or from the current buffer."
|
|||
(defun org-cite-boundaries (citation)
|
||||
"Return the beginning and end strict position of CITATION.
|
||||
Returns a (BEG . END) pair."
|
||||
(let ((beg (org-element-begin citation))
|
||||
(end (org-with-point-at (org-element-end citation)
|
||||
(let ((beg (org-element-property :begin citation))
|
||||
(end (org-with-point-at (org-element-property :end citation)
|
||||
(skip-chars-backward " \t")
|
||||
(point))))
|
||||
(cons beg end)))
|
||||
|
@ -665,15 +646,15 @@ Returns a (BEG . END) pair."
|
|||
"Return citation REFERENCE's key boundaries as buffer positions.
|
||||
The function returns a pair (START . END) where START and END denote positions
|
||||
in the current buffer. Positions include leading \"@\" character."
|
||||
(org-with-point-at (org-element-begin reference)
|
||||
(let ((end (org-element-end reference)))
|
||||
(org-with-point-at (org-element-property :begin reference)
|
||||
(let ((end (org-element-property :end reference)))
|
||||
(re-search-forward org-element-citation-key-re end t)
|
||||
(cons (match-beginning 0) (match-end 0)))))
|
||||
|
||||
(defun org-cite-main-affixes (citation)
|
||||
"Return main affixes for CITATION object.
|
||||
|
||||
Some export backends only support a single pair of affixes per
|
||||
Some export back-ends only support a single pair of affixes per
|
||||
citation, even if it contains multiple keys. This function
|
||||
decides what affixes are the most appropriate.
|
||||
|
||||
|
@ -749,7 +730,7 @@ When removing the last reference, also remove the whole citation."
|
|||
(org-with-point-at begin
|
||||
(skip-chars-backward " \t")
|
||||
(point)))
|
||||
(pos-after-blank (org-element-end datum))
|
||||
(pos-after-blank (org-element-property :end datum))
|
||||
(first-on-line?
|
||||
(= pos-before-blank (line-beginning-position)))
|
||||
(last-on-line?
|
||||
|
@ -772,22 +753,22 @@ When removing the last reference, also remove the whole citation."
|
|||
(when (= pos-after-blank end)
|
||||
(org-with-point-at pos-before-blank (insert " ")))))))
|
||||
('citation-reference
|
||||
(let* ((citation (org-element-parent datum))
|
||||
(let* ((citation (org-element-property :parent datum))
|
||||
(references (org-cite-get-references citation))
|
||||
(begin (org-element-begin datum))
|
||||
(end (org-element-end datum)))
|
||||
(begin (org-element-property :begin datum))
|
||||
(end (org-element-property :end datum)))
|
||||
(cond
|
||||
;; Single reference.
|
||||
((= 1 (length references))
|
||||
(org-cite-delete-citation citation))
|
||||
;; First reference, no prefix.
|
||||
((and (= begin (org-element-contents-begin citation))
|
||||
((and (= begin (org-element-property :contents-begin citation))
|
||||
(not (org-element-property :prefix citation)))
|
||||
(org-with-point-at (org-element-begin datum)
|
||||
(org-with-point-at (org-element-property :begin datum)
|
||||
(skip-chars-backward " \t")
|
||||
(delete-region (point) end)))
|
||||
;; Last reference, no suffix.
|
||||
((and (= end (org-element-contents-end citation))
|
||||
((and (= end (org-element-property :contents-end citation))
|
||||
(not (org-element-property :suffix citation)))
|
||||
(delete-region (1- begin) (1- (cdr (org-cite-boundaries citation)))))
|
||||
;; Somewhere in-between.
|
||||
|
@ -961,12 +942,11 @@ the sole contents of the footnote, e.g., after calling `org-cite-wrap-citation'.
|
|||
|
||||
When non-nil, the return value if the footnote container."
|
||||
(let ((footnote
|
||||
(org-element-lineage
|
||||
citation
|
||||
'(footnote-definition footnote-reference))))
|
||||
(org-element-lineage citation
|
||||
'(footnote-definition footnote-reference))))
|
||||
(and footnote
|
||||
(or (not strict)
|
||||
(equal (org-element-contents (org-element-parent citation))
|
||||
(equal (org-element-contents (org-element-property :parent citation))
|
||||
(list citation)))
|
||||
;; Return value.
|
||||
footnote)))
|
||||
|
@ -984,15 +964,15 @@ Return newly created footnote object."
|
|||
(list 'footnote-reference
|
||||
(list :label nil
|
||||
:type 'inline
|
||||
:contents-begin (org-element-begin citation)
|
||||
:contents-end (org-element-end citation)
|
||||
:post-blank (org-element-post-blank citation)))))
|
||||
:contents-begin (org-element-property :begin citation)
|
||||
:contents-end (org-element-property :end citation)
|
||||
:post-blank (org-element-property :post-blank citation)))))
|
||||
;; Remove any white space before citation.
|
||||
(org-cite--set-previous-post-blank citation 0 info)
|
||||
;; Footnote swallows citation.
|
||||
(org-element-insert-before footnote citation)
|
||||
(org-element-adopt footnote
|
||||
(org-element-extract citation))))
|
||||
(org-element-adopt-elements footnote
|
||||
(org-element-extract-element citation))))
|
||||
|
||||
(defun org-cite-adjust-note (citation info &optional rule punct)
|
||||
"Adjust note number location for CITATION object, and punctuation around it.
|
||||
|
@ -1071,8 +1051,8 @@ the same object, call `org-cite-adjust-note' first."
|
|||
;; as an argument is not available.
|
||||
(rx-to-string `(seq string-start ,final-punct) t)
|
||||
"" next)))
|
||||
(org-element-set previous new-prev)
|
||||
(org-element-set next new-next)
|
||||
(org-element-set-element previous new-prev)
|
||||
(org-element-set-element next new-next)
|
||||
(setq previous new-prev)
|
||||
(setq next new-next)
|
||||
(setq punct final-punct)
|
||||
|
@ -1091,15 +1071,15 @@ the same object, call `org-cite-adjust-note' first."
|
|||
(replace-regexp-in-string
|
||||
previous-punct-re "" previous nil nil 1))
|
||||
(new-next (if (stringp next) (concat punct next) punct)))
|
||||
(org-element-set previous new-prev)
|
||||
(org-element-set-element previous new-prev)
|
||||
(cond
|
||||
((stringp next)
|
||||
(org-element-set next new-next))
|
||||
(org-element-set-element next new-next))
|
||||
(next
|
||||
(org-element-insert-before new-next next))
|
||||
(t
|
||||
(org-element-adopt
|
||||
(org-element-parent citation)
|
||||
(org-element-adopt-elements
|
||||
(org-element-property :parent citation)
|
||||
new-next)))
|
||||
(setq previous new-prev)
|
||||
(setq next new-next)
|
||||
|
@ -1166,7 +1146,7 @@ raises an error if S contains a headline."
|
|||
(insert s)
|
||||
(pcase (org-element-contents (org-element-parse-buffer))
|
||||
('nil nil)
|
||||
(`(,(and section (guard (org-element-type-p section 'section))))
|
||||
(`(,(and section (guard (eq 'section (org-element-type section)))))
|
||||
(org-element-contents section))
|
||||
(_
|
||||
(error "Headlines cannot replace a keyword")))))
|
||||
|
@ -1226,23 +1206,14 @@ and must return either a string, an object, or a secondary string."
|
|||
(org-cite-concat result separator (funcall function datum))))
|
||||
result)))
|
||||
|
||||
(defun org-cite-capitalize (str)
|
||||
"Capitalize string of raw string object STR."
|
||||
(cond
|
||||
((stringp str) (capitalize str))
|
||||
((org-element-type-p str 'raw)
|
||||
(org-export-raw-string
|
||||
(capitalize (mapconcat #'identity (org-element-contents str) ""))))
|
||||
(t (error "%S must be either a string or raw string object" str))))
|
||||
|
||||
|
||||
;;; Internal interface with fontification (activate capability)
|
||||
(defun org-cite-fontify-default (cite)
|
||||
"Fontify CITE with `org-cite' and `org-cite-key' faces.
|
||||
CITE is a citation object. The function applies `org-cite' face
|
||||
on the whole citation, and `org-cite-key' face on each key."
|
||||
(let ((beg (org-element-begin cite))
|
||||
(end (org-with-point-at (org-element-end cite)
|
||||
(let ((beg (org-element-property :begin cite))
|
||||
(end (org-with-point-at (org-element-property :end cite)
|
||||
(skip-chars-backward " \t")
|
||||
(point))))
|
||||
(add-text-properties beg end '(font-lock-multiline t))
|
||||
|
@ -1266,12 +1237,10 @@ from the processor set in `org-cite-activate-processor'."
|
|||
(let ((cite (org-with-point-at (match-beginning 0)
|
||||
(org-element-citation-parser))))
|
||||
(when cite
|
||||
;; Do not alter match data as font-lock expects us to set it
|
||||
;; appropriately.
|
||||
(save-match-data (funcall activate cite))
|
||||
(funcall activate cite)
|
||||
;; Move after cite object and make sure to return
|
||||
;; a non-nil value.
|
||||
(goto-char (org-element-end cite)))))))
|
||||
(goto-char (org-element-property :end cite)))))))
|
||||
|
||||
|
||||
;;; Internal interface with Org Export library (export capability)
|
||||
|
@ -1308,12 +1277,12 @@ side-effect."
|
|||
;; Value is an alist. It must come from
|
||||
;; `org-cite-export-processors' variable. Find the most
|
||||
;; appropriate processor according to current export
|
||||
;; backend.
|
||||
;; back-end.
|
||||
((and (pred consp) alist)
|
||||
(let* ((backend (plist-get info :back-end))
|
||||
(candidates
|
||||
;; Limit candidates to processors associated to
|
||||
;; backends derived from or equal to the current
|
||||
;; back-ends derived from or equal to the current
|
||||
;; one.
|
||||
(sort (seq-filter
|
||||
(pcase-lambda (`(,key . ,_))
|
||||
|
@ -1365,7 +1334,7 @@ selected citation processor."
|
|||
|
||||
(defun org-cite-export-bibliography (keyword _ info)
|
||||
"Return bibliography associated to \"print_bibliography\" KEYWORD.
|
||||
BACKEND is the export backend, as a symbol. INFO is a plist
|
||||
BACKEND is the export back-end, as a symbol. INFO is a plist
|
||||
used as a communication channel."
|
||||
(pcase (plist-get info :cite-export)
|
||||
('nil nil)
|
||||
|
@ -1389,7 +1358,7 @@ INFO is the communication channel, as a plist. Parse tree is modified
|
|||
by side-effect."
|
||||
(dolist (cite (org-cite-list-citations info))
|
||||
(let ((replacement (org-cite-export-citation cite nil info))
|
||||
(blanks (or (org-element-post-blank cite) 0)))
|
||||
(blanks (or (org-element-property :post-blank cite) 0)))
|
||||
(if (null replacement)
|
||||
;; Before removing the citation, transfer its `:post-blank'
|
||||
;; property to the object before, if any.
|
||||
|
@ -1423,7 +1392,7 @@ by side-effect."
|
|||
(_
|
||||
(error "Invalid return value from citation export processor: %S"
|
||||
replacement))))
|
||||
(org-element-extract cite))))
|
||||
(org-element-extract-element cite))))
|
||||
|
||||
(defun org-cite-process-bibliography (info)
|
||||
"Replace all \"print_bibliography\" keywords in the parse tree.
|
||||
|
@ -1434,18 +1403,18 @@ by side effect."
|
|||
(lambda (keyword)
|
||||
(when (equal "PRINT_BIBLIOGRAPHY" (org-element-property :key keyword))
|
||||
(let ((replacement (org-cite-export-bibliography keyword nil info))
|
||||
(blanks (or (org-element-post-blank keyword) 0)))
|
||||
(blanks (or (org-element-property :post-blank keyword) 0)))
|
||||
(pcase replacement
|
||||
;; Before removing the citation, transfer its
|
||||
;; `:post-blank' property to the element before, if any.
|
||||
('nil
|
||||
(org-cite--set-previous-post-blank keyword blanks info)
|
||||
(org-element-extract keyword))
|
||||
(org-element-extract-element keyword))
|
||||
;; Handle `:post-blank' before replacing keyword with string.
|
||||
((pred stringp)
|
||||
(let ((output (concat (org-element-normalize-string replacement)
|
||||
(make-string blanks ?\n))))
|
||||
(org-element-set keyword (org-export-raw-string output))))
|
||||
(org-element-set-element keyword (org-export-raw-string output))))
|
||||
;; List of elements: splice contents before keyword and
|
||||
;; remove the latter. Transfer `:post-blank' to last
|
||||
;; element.
|
||||
|
@ -1455,11 +1424,11 @@ by side effect."
|
|||
(setq last datum)
|
||||
(org-element-insert-before datum keyword))
|
||||
(org-cite--set-post-blank last blanks)
|
||||
(org-element-extract keyword)))
|
||||
(org-element-extract-element keyword)))
|
||||
;; Single element: replace the keyword.
|
||||
(`(,(pred symbolp) . ,_)
|
||||
(org-cite--set-post-blank replacement blanks)
|
||||
(org-element-set keyword replacement))
|
||||
(org-element-set-element keyword replacement))
|
||||
(_
|
||||
(error "Invalid return value from citation export processor: %S"
|
||||
replacement))))))
|
||||
|
@ -1515,7 +1484,7 @@ CONTEXT is the element or object at point, as returned by `org-element-context'.
|
|||
;;
|
||||
;; XXX: Inserting citation in a secondary value is not allowed
|
||||
;; yet. Is it useful?
|
||||
((let ((post (org-element-post-affiliated context)))
|
||||
((let ((post (org-element-property :post-affiliated context)))
|
||||
(and post (< (point) post)))
|
||||
(let ((case-fold-search t))
|
||||
(looking-back
|
||||
|
@ -1531,14 +1500,14 @@ CONTEXT is the element or object at point, as returned by `org-element-context'.
|
|||
((memq type '(nil paragraph)))
|
||||
;; So are contents of verse blocks.
|
||||
((eq type 'verse-block)
|
||||
(and (>= (point) (org-element-contents-begin context))
|
||||
(< (point) (org-element-contents-end context))))
|
||||
(and (>= (point) (org-element-property :contents-begin context))
|
||||
(< (point) (org-element-property :contents-end context))))
|
||||
;; In an headline or inlinetask, point must be either on the
|
||||
;; heading itself or on the blank lines below.
|
||||
((memq type '(headline inlinetask))
|
||||
(or (not (org-at-heading-p))
|
||||
(and (save-excursion
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(and (let ((case-fold-search t))
|
||||
(not (looking-at-p "\\*+ END[ \t]*$")))
|
||||
(let ((case-fold-search nil))
|
||||
|
@ -1557,43 +1526,43 @@ CONTEXT is the element or object at point, as returned by `org-element-context'.
|
|||
;; White spaces after an object or blank lines after an element
|
||||
;; are OK.
|
||||
((>= (point)
|
||||
(save-excursion (goto-char (org-element-end context))
|
||||
(skip-chars-backward " \r\t\n")
|
||||
(if (eq (org-element-class context) 'object) (point)
|
||||
(line-beginning-position 2)))))
|
||||
(save-excursion (goto-char (org-element-property :end context))
|
||||
(skip-chars-backward " \r\t\n")
|
||||
(if (eq (org-element-class context) 'object) (point)
|
||||
(line-beginning-position 2)))))
|
||||
;; At the beginning of a footnote definition, right after the
|
||||
;; label, is OK.
|
||||
((eq type 'footnote-definition) (looking-at (rx space)))
|
||||
;; At the start of a list item is fine, as long as the bullet is
|
||||
;; unaffected.
|
||||
((eq type 'item)
|
||||
(> (point) (+ (org-element-begin context)
|
||||
(> (point) (+ (org-element-property :begin context)
|
||||
(org-current-text-indentation)
|
||||
(if (org-element-property :checkbox context)
|
||||
5 1))))
|
||||
;; Other elements are invalid.
|
||||
((eq (org-element-class context) 'element) nil)
|
||||
;; Just before object is fine.
|
||||
((= (point) (org-element-begin context)))
|
||||
((= (point) (org-element-property :begin context)))
|
||||
;; Within recursive object too, but not in a link.
|
||||
((eq type 'link) nil)
|
||||
((eq type 'table-cell)
|
||||
;; :contents-begin is not reliable on empty cells, so special
|
||||
;; case it.
|
||||
(<= (save-excursion (skip-chars-backward " \t") (point))
|
||||
(org-element-contents-end context)))
|
||||
((let ((cbeg (org-element-contents-begin context))
|
||||
(cend (org-element-contents-end context)))
|
||||
(org-element-property :contents-end context)))
|
||||
((let ((cbeg (org-element-property :contents-begin context))
|
||||
(cend (org-element-property :contents-end context)))
|
||||
(and cbeg (>= (point) cbeg) (<= (point) cend)))))))
|
||||
|
||||
(defun org-cite--insert-string-before (string reference)
|
||||
"Insert STRING before citation REFERENCE object."
|
||||
(org-with-point-at (org-element-begin reference)
|
||||
(org-with-point-at (org-element-property :begin reference)
|
||||
(insert string ";")))
|
||||
|
||||
(defun org-cite--insert-string-after (string reference)
|
||||
"Insert STRING after citation REFERENCE object."
|
||||
(org-with-point-at (org-element-end reference)
|
||||
(org-with-point-at (org-element-property :end reference)
|
||||
;; Make sure to move forward when we're inserting at point, so the
|
||||
;; insertion can happen multiple times.
|
||||
(if (char-equal ?\; (char-before))
|
||||
|
@ -1664,7 +1633,7 @@ More specifically,
|
|||
;; action depends on the point.
|
||||
(if arg
|
||||
(org-cite-delete-citation context)
|
||||
(let* ((begin (org-element-begin context))
|
||||
(let* ((begin (org-element-property :begin context))
|
||||
(style-end (1- (org-with-point-at begin (search-forward ":")))))
|
||||
(if (>= style-end (point))
|
||||
;; On style part, edit the style.
|
||||
|
@ -1678,7 +1647,7 @@ More specifically,
|
|||
;; point.
|
||||
(let* ((references (org-cite-get-references context))
|
||||
(key (concat "@" (funcall select-key nil))))
|
||||
(if (< (point) (org-element-contents-begin context))
|
||||
(if (< (point) (org-element-property :contents-begin context))
|
||||
(org-cite--insert-string-before key (car references))
|
||||
(org-cite--insert-string-after key (org-last references))))))))
|
||||
;; On a citation reference. If ARG is not nil, remove the
|
||||
|
@ -1733,7 +1702,7 @@ ARG is the prefix argument received when calling interactively the function."
|
|||
(let ((context (org-element-context))
|
||||
(insert (org-cite-processor-insert (org-cite-get-processor name))))
|
||||
(cond
|
||||
((org-element-type-p context '(citation citation-reference))
|
||||
((memq (org-element-type context) '(citation citation-reference))
|
||||
(funcall insert context arg))
|
||||
((org-cite--allowed-p context)
|
||||
(funcall insert nil arg))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ol-bbdb.el --- Links to BBDB entries -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2004-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2004-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Authors: Carsten Dominik <carsten.dominik@gmail.com>
|
||||
;; Thomas Baumann <thomas dot baumann at ch dot tum dot de>
|
||||
|
@ -226,7 +226,7 @@ date year)."
|
|||
|
||||
;;; Implementation
|
||||
|
||||
(defun org-bbdb-store-link (&optional _interactive?)
|
||||
(defun org-bbdb-store-link ()
|
||||
"Store a link to a BBDB database entry."
|
||||
(when (eq major-mode 'bbdb-mode)
|
||||
;; This is BBDB, we make this link!
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ol-bibtex.el --- Links to BibTeX entries -*- lexical-binding: t; -*-
|
||||
;;
|
||||
;; Copyright (C) 2007-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2007-2023 Free Software Foundation, Inc.
|
||||
;;
|
||||
;; Authors: Bastien Guerry <bzg@gnu.org>
|
||||
;; Carsten Dominik <carsten dot dominik at gmail dot com>
|
||||
|
@ -266,7 +266,7 @@ a missing title field."
|
|||
:type 'boolean)
|
||||
|
||||
(defcustom org-bibtex-headline-format-function
|
||||
#'org-bibtex-headline-format-default
|
||||
(lambda (entry) (cdr (assq :title entry)))
|
||||
"Function returning the headline text for `org-bibtex-write'.
|
||||
It should take a single argument, the bibtex entry (an alist as
|
||||
returned by `org-bibtex-read'). The default value simply returns
|
||||
|
@ -507,7 +507,7 @@ ARG, when non-nil, is a universal prefix argument. See
|
|||
`org-open-file' for details."
|
||||
(org-link-open-as-file path arg))
|
||||
|
||||
(defun org-bibtex-store-link (&optional _interactive?)
|
||||
(defun org-bibtex-store-link ()
|
||||
"Store a link to a BibTeX entry."
|
||||
(when (eq major-mode 'bibtex-mode)
|
||||
(let* ((search (org-create-file-search-in-bibtex))
|
||||
|
@ -636,27 +636,22 @@ With prefix argument OPTIONAL also prompt for optional fields."
|
|||
With prefix argument OPTIONAL also prompt for optional fields."
|
||||
(interactive) (org-map-entries (lambda () (org-bibtex-check optional))))
|
||||
|
||||
(defun org-bibtex-headline-format-default (entry)
|
||||
"Return headline text according to ENTRY title."
|
||||
(cdr (assq :title entry)))
|
||||
|
||||
(defun org-bibtex-create (&optional arg update-heading)
|
||||
(defun org-bibtex-create (&optional arg nonew)
|
||||
"Create a new entry at the given level.
|
||||
With a prefix ARG, query for optional fields as well.
|
||||
If UPDATE-HEADING is non-nil, add data to the headline of the entry at
|
||||
point."
|
||||
With a prefix arg, query for optional fields as well.
|
||||
If nonew is t, add data to the headline of the entry at point."
|
||||
(interactive "P")
|
||||
(let* ((type (completing-read
|
||||
"Type: " (mapcar (lambda (type)
|
||||
(substring (symbol-name (car type)) 1))
|
||||
org-bibtex-types)
|
||||
nil nil (when update-heading
|
||||
(org-bibtex-get org-bibtex-type-property-name))))
|
||||
nil nil (when nonew
|
||||
(org-bibtex-get org-bibtex-type-property-name))))
|
||||
(type (if (keywordp type) type (intern (concat ":" type))))
|
||||
(org-bibtex-treat-headline-as-title (if update-heading nil t)))
|
||||
(org-bibtex-treat-headline-as-title (if nonew nil t)))
|
||||
(unless (assoc type org-bibtex-types)
|
||||
(error "Type:%s is not known" type))
|
||||
(if update-heading
|
||||
(if nonew
|
||||
(org-back-to-heading)
|
||||
(org-insert-heading)
|
||||
(let ((title (org-bibtex-ask :title)))
|
||||
|
@ -723,32 +718,29 @@ Return the number of saved entries."
|
|||
(interactive "fFile: ")
|
||||
(org-bibtex-read-buffer (find-file-noselect file 'nowarn 'rawfile)))
|
||||
|
||||
(defun org-bibtex-write (&optional noindent update-heading)
|
||||
(defun org-bibtex-write (&optional noindent)
|
||||
"Insert a heading built from the first element of `org-bibtex-entries'.
|
||||
When optional argument NOINDENT is non-nil, do not indent the properties
|
||||
drawer. If UPDATE-HEADING is non-nil, add data to the headline of the
|
||||
entry at point."
|
||||
drawer."
|
||||
(interactive)
|
||||
(unless org-bibtex-entries
|
||||
(error "No entries in `org-bibtex-entries'"))
|
||||
(let* ((entry (pop org-bibtex-entries))
|
||||
(org-special-properties nil) ; avoids errors with `org-entry-put'
|
||||
(val (lambda (field) (cdr (assoc field entry))))
|
||||
(togtag (lambda (tag) (org-toggle-tag tag 'on)))
|
||||
(insert-raw (not update-heading)))
|
||||
(unless update-heading
|
||||
(org-insert-heading)
|
||||
(insert (funcall org-bibtex-headline-format-function entry))
|
||||
(insert "\n:PROPERTIES:\n"))
|
||||
(org-bibtex-put "TITLE" (funcall val :title) insert-raw)
|
||||
(togtag (lambda (tag) (org-toggle-tag tag 'on))))
|
||||
(org-insert-heading)
|
||||
(insert (funcall org-bibtex-headline-format-function entry))
|
||||
(insert "\n:PROPERTIES:\n")
|
||||
(org-bibtex-put "TITLE" (funcall val :title) 'insert)
|
||||
(org-bibtex-put org-bibtex-type-property-name
|
||||
(downcase (funcall val :type))
|
||||
insert-raw)
|
||||
'insert)
|
||||
(dolist (pair entry)
|
||||
(pcase (car pair)
|
||||
(:title nil)
|
||||
(:type nil)
|
||||
(:key (org-bibtex-put org-bibtex-key-property (cdr pair) insert-raw))
|
||||
(:key (org-bibtex-put org-bibtex-key-property (cdr pair) 'insert))
|
||||
(:keywords (if org-bibtex-tags-are-keywords
|
||||
(dolist (kw (split-string (cdr pair) ", *"))
|
||||
(funcall
|
||||
|
@ -756,28 +748,22 @@ entry at point."
|
|||
(replace-regexp-in-string
|
||||
"[^[:alnum:]_@#%]" ""
|
||||
(replace-regexp-in-string "[ \t]+" "_" kw))))
|
||||
(org-bibtex-put (car pair) (cdr pair) insert-raw)))
|
||||
(_ (org-bibtex-put (car pair) (cdr pair) insert-raw))))
|
||||
(unless update-heading
|
||||
(insert ":END:\n"))
|
||||
(org-bibtex-put (car pair) (cdr pair) 'insert)))
|
||||
(_ (org-bibtex-put (car pair) (cdr pair) 'insert))))
|
||||
(insert ":END:\n")
|
||||
(mapc togtag org-bibtex-tags)
|
||||
(unless noindent
|
||||
(org-indent-region
|
||||
(save-excursion (org-back-to-heading t) (point))
|
||||
(point)))))
|
||||
|
||||
(defun org-bibtex-yank (&optional update-heading)
|
||||
"If kill ring holds a bibtex entry yank it as an Org headline.
|
||||
When called with non-nil prefix argument UPDATE-HEADING, add data to the
|
||||
headline of the entry at point."
|
||||
(interactive "P")
|
||||
(defun org-bibtex-yank ()
|
||||
"If kill ring holds a bibtex entry yank it as an Org headline."
|
||||
(interactive)
|
||||
(let (entry)
|
||||
(with-temp-buffer
|
||||
(yank 1)
|
||||
(bibtex-mode)
|
||||
(setf entry (org-bibtex-read)))
|
||||
(with-temp-buffer (yank 1) (setf entry (org-bibtex-read)))
|
||||
(if entry
|
||||
(org-bibtex-write nil update-heading)
|
||||
(org-bibtex-write)
|
||||
(error "Yanked text does not appear to contain a BibTeX entry"))))
|
||||
|
||||
(defun org-bibtex-import-from-file (file)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ol-docview.el --- Links to Docview mode buffers -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Jan Böcker <jan.boecker at jboecker dot de>
|
||||
;; Keywords: outlines, hypermedia, calendar, wp
|
||||
|
@ -57,21 +57,20 @@
|
|||
:export #'org-docview-export
|
||||
:store #'org-docview-store-link)
|
||||
|
||||
(defun org-docview-export (link description backend _info)
|
||||
"Export a docview LINK with DESCRIPTION for BACKEND."
|
||||
(defun org-docview-export (link description format)
|
||||
"Export a docview link from Org files."
|
||||
(let ((path (if (string-match "\\(.+\\)::.+" link) (match-string 1 link)
|
||||
link))
|
||||
(desc (or description link)))
|
||||
(when (stringp path)
|
||||
(setq path (expand-file-name path))
|
||||
(cond
|
||||
((eq backend 'html) (format "<a href=\"%s\">%s</a>" path desc))
|
||||
((eq backend 'latex) (format "\\href{%s}{%s}" path desc))
|
||||
((eq backend 'ascii) (format "[%s] (<%s>)" desc path))
|
||||
((eq format 'html) (format "<a href=\"%s\">%s</a>" path desc))
|
||||
((eq format 'latex) (format "\\href{%s}{%s}" path desc))
|
||||
((eq format 'ascii) (format "%s (%s)" desc path))
|
||||
(t path)))))
|
||||
|
||||
(defun org-docview-open (link _)
|
||||
"Open docview: LINK."
|
||||
(string-match "\\(.*?\\)\\(?:::\\([0-9]+\\)\\)?$" link)
|
||||
(let ((path (match-string 1 link))
|
||||
(page (and (match-beginning 2)
|
||||
|
@ -83,7 +82,7 @@
|
|||
(error "No such file: %s" path))
|
||||
(when page (doc-view-goto-page page))))
|
||||
|
||||
(defun org-docview-store-link (&optional _interactive?)
|
||||
(defun org-docview-store-link ()
|
||||
"Store a link to a docview buffer."
|
||||
(when (eq major-mode 'doc-view-mode)
|
||||
;; This buffer is in doc-view-mode
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ol-doi.el --- DOI links support in Org -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2021-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2021-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Nicolas Goaziou <mail@nicolasgoaziou.fr>
|
||||
|
||||
|
@ -40,8 +40,7 @@
|
|||
|
||||
(defun org-link-doi-open (path arg)
|
||||
"Open a \"doi\" type link.
|
||||
PATH is a the path to search for, as a string.
|
||||
ARG is passed to `browse-url'."
|
||||
PATH is a the path to search for, as a string."
|
||||
(browse-url (url-encode-url (concat org-link-doi-server-url path)) arg))
|
||||
|
||||
(defun org-link-doi-export (path desc backend info)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ol-eshell.el --- Links to Working Directories in Eshell -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2011-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2011-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Konrad Hinsen <konrad.hinsen AT fastmail.net>
|
||||
|
||||
|
@ -37,8 +37,8 @@
|
|||
:store #'org-eshell-store-link)
|
||||
|
||||
(defun org-eshell-open (link _)
|
||||
"Switch to an eshell buffer and execute a command line for LINK.
|
||||
The LINK can be just a command line (executed in the default
|
||||
"Switch to an eshell buffer and execute a command line.
|
||||
The link can be just a command line (executed in the default
|
||||
eshell buffer) or a command line prefixed by a buffer name
|
||||
followed by a colon."
|
||||
(let* ((buffer-and-command
|
||||
|
@ -60,10 +60,9 @@ followed by a colon."
|
|||
(insert command)
|
||||
(eshell-send-input)))
|
||||
|
||||
(defun org-eshell-store-link (&optional _interactive?)
|
||||
"Store eshell link.
|
||||
When opened, the link switches back to the current eshell buffer and
|
||||
the current working directory."
|
||||
(defun org-eshell-store-link ()
|
||||
"Store a link that, when opened, switches back to the current eshell buffer
|
||||
and the current working directory."
|
||||
(when (eq major-mode 'eshell-mode)
|
||||
(let* ((command (concat "cd " (eshell/pwd)))
|
||||
(link (concat (buffer-name) ":" command)))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ol-eww.el --- Store URL and kill from Eww mode -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2014-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2014-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Marco Wahl <marcowahlsoft>a<gmailcom>
|
||||
;; Keywords: link, eww
|
||||
|
@ -62,7 +62,7 @@
|
|||
"Open URL with Eww in the current buffer."
|
||||
(eww url))
|
||||
|
||||
(defun org-eww-store-link (&optional _interactive?)
|
||||
(defun org-eww-store-link ()
|
||||
"Store a link to the url of an EWW buffer."
|
||||
(when (eq major-mode 'eww-mode)
|
||||
(org-link-store-props
|
||||
|
@ -162,7 +162,6 @@ keep the structure of the Org file."
|
|||
;; Additional keys for eww-mode
|
||||
|
||||
(defun org-eww-extend-eww-keymap ()
|
||||
"Add ol-eww bindings to `eww-mode-map'."
|
||||
(define-key eww-mode-map "\C-c\C-x\M-w" 'org-eww-copy-for-org-mode)
|
||||
(define-key eww-mode-map "\C-c\C-x\C-w" 'org-eww-copy-for-org-mode))
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ol-gnus.el --- Links to Gnus Groups and Messages -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2004-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2004-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Carsten Dominik <carsten.dominik@gmail.com>
|
||||
;; Tassilo Horn <tassilo at member dot fsf dot org>
|
||||
|
@ -123,7 +123,7 @@ If `org-store-link' was called with a prefix arg the meaning of
|
|||
(url-encode-url message-id))
|
||||
(concat "gnus:" group "#" message-id)))
|
||||
|
||||
(defun org-gnus-store-link (&optional _interactive?)
|
||||
(defun org-gnus-store-link ()
|
||||
"Store a link to a Gnus folder or message."
|
||||
(pcase major-mode
|
||||
(`gnus-group-mode
|
||||
|
@ -137,23 +137,27 @@ If `org-store-link' was called with a prefix arg the meaning of
|
|||
(let* ((group
|
||||
(pcase (gnus-find-method-for-group gnus-newsgroup-name)
|
||||
(`(nnvirtual . ,_)
|
||||
(with-current-buffer gnus-summary-buffer
|
||||
(save-excursion
|
||||
(car (nnvirtual-map-article (gnus-summary-article-number))))))
|
||||
(save-excursion
|
||||
(car (nnvirtual-map-article (gnus-summary-article-number)))))
|
||||
(`(,(or `nnselect `nnir) . ,_) ; nnir is for Emacs < 28.
|
||||
(with-current-buffer gnus-summary-buffer
|
||||
(save-excursion
|
||||
(cond
|
||||
((fboundp 'nnselect-article-group)
|
||||
(nnselect-article-group (gnus-summary-article-number)))
|
||||
((fboundp 'nnir-article-group)
|
||||
(nnir-article-group (gnus-summary-article-number)))
|
||||
(t
|
||||
(error "No article-group variant bound"))))))
|
||||
(save-excursion
|
||||
(cond
|
||||
((fboundp 'nnselect-article-group)
|
||||
(nnselect-article-group (gnus-summary-article-number)))
|
||||
((fboundp 'nnir-article-group)
|
||||
(nnir-article-group (gnus-summary-article-number)))
|
||||
(t
|
||||
(error "No article-group variant bound")))))
|
||||
(_ gnus-newsgroup-name)))
|
||||
(header (with-current-buffer gnus-summary-buffer
|
||||
(save-excursion
|
||||
(gnus-summary-article-header))))
|
||||
(header (if (eq major-mode 'gnus-article-mode)
|
||||
;; When in an article, first move to summary
|
||||
;; buffer, with point on the summary of the
|
||||
;; current article before extracting headers.
|
||||
(save-window-excursion
|
||||
(save-excursion
|
||||
(gnus-article-show-summary)
|
||||
(gnus-summary-article-header)))
|
||||
(gnus-summary-article-header)))
|
||||
(from (mail-header-from header))
|
||||
(message-id (org-unbracket-string "<" ">" (mail-header-id header)))
|
||||
(date (org-trim (mail-header-date header)))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ol-info.el --- Links to Info Nodes -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2004-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2004-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Carsten Dominik <carsten.dominik@gmail.com>
|
||||
;; Keywords: outlines, hypermedia, calendar, wp
|
||||
|
@ -50,7 +50,7 @@
|
|||
:insert-description #'org-info-description-as-command)
|
||||
|
||||
;; Implementation
|
||||
(defun org-info-store-link (&optional _interactive?)
|
||||
(defun org-info-store-link ()
|
||||
"Store a link to an Info file and node."
|
||||
(when (eq major-mode 'Info-mode)
|
||||
(let ((link (concat "info:"
|
||||
|
@ -129,27 +129,23 @@ If LINK is not an info link then DESC is returned."
|
|||
|
||||
(defconst org-info-emacs-documents
|
||||
'("ada-mode" "auth" "autotype" "bovine" "calc" "ccmode" "cl" "dbus" "dired-x"
|
||||
"ebrowse" "ede" "ediff" "edt" "efaq-w32" "efaq" "eglot" "eieio" "eintr"
|
||||
"elisp" "emacs-gnutls" "emacs-mime" "emacs" "epa" "erc" "ert" "eshell"
|
||||
"eudc" "eww" "flymake" "forms" "gnus" "htmlfontify" "idlwave" "ido" "info"
|
||||
"mairix-el" "message" "mh-e" "modus-themes" "newsticker" "nxml-mode" "octave-mode"
|
||||
"org" "pcl-cvs" "pgg" "rcirc" "reftex" "remember" "sasl" "sc" "semantic"
|
||||
"ses" "sieve" "smtpmail" "speedbar" "srecode" "todo-mode" "tramp" "transient"
|
||||
"url" "use-package" "vhdl-mode" "vip" "viper" "vtable" "widget" "wisent" "woman")
|
||||
"ebrowse" "ede" "ediff" "edt" "efaq-w32" "efaq" "eieio" "eintr" "elisp"
|
||||
"emacs-gnutls" "emacs-mime" "emacs" "epa" "erc" "ert" "eshell" "eudc" "eww"
|
||||
"flymake" "forms" "gnus" "htmlfontify" "idlwave" "ido" "info" "mairix-el"
|
||||
"message" "mh-e" "newsticker" "nxml-mode" "octave-mode" "org" "pcl-cvs"
|
||||
"pgg" "rcirc" "reftex" "remember" "sasl" "sc" "semantic" "ses" "sieve"
|
||||
"smtpmail" "speedbar" "srecode" "todo-mode" "tramp" "url" "vip" "viper"
|
||||
"widget" "wisent" "woman")
|
||||
"List of Emacs documents available.
|
||||
Taken from <https://www.gnu.org/software/emacs/manual/html_mono/.>")
|
||||
|
||||
(defcustom org-info-other-documents
|
||||
(defconst org-info-other-documents
|
||||
'(("dir" . "https://www.gnu.org/manual/manual.html") ; index
|
||||
("libc" . "https://www.gnu.org/software/libc/manual/html_mono/libc.html")
|
||||
("make" . "https://www.gnu.org/software/make/manual/make.html"))
|
||||
"Alist of documents generated from Texinfo source.
|
||||
When converting info links to HTML, links to any one of these manuals are
|
||||
converted to use these URL."
|
||||
:group 'org-link
|
||||
:type '(alist :key-type string :value-type string)
|
||||
:package-version '(Org . "9.7")
|
||||
:safe t)
|
||||
converted to use these URL.")
|
||||
|
||||
(defun org-info-map-html-url (filename)
|
||||
"Return URL or HTML file associated to Info FILENAME.
|
||||
|
@ -157,11 +153,11 @@ If FILENAME refers to an official GNU document, return a URL pointing to
|
|||
the official page for that document, e.g., use \"gnu.org\" for all Emacs
|
||||
related documents. Otherwise, append \".html\" extension to FILENAME.
|
||||
See `org-info-emacs-documents' and `org-info-other-documents' for details."
|
||||
(cond ((cdr (assoc filename org-info-other-documents)))
|
||||
((member filename org-info-emacs-documents)
|
||||
(format "https://www.gnu.org/software/emacs/manual/html_mono/%s.html"
|
||||
filename))
|
||||
(t (concat filename ".html"))))
|
||||
(cond ((member filename org-info-emacs-documents)
|
||||
(format "https://www.gnu.org/software/emacs/manual/html_mono/%s.html"
|
||||
filename))
|
||||
((cdr (assoc filename org-info-other-documents)))
|
||||
(t (concat filename ".html"))))
|
||||
|
||||
(defun org-info--expand-node-name (node)
|
||||
"Expand Info NODE to HTML cross reference."
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ol-irc.el --- Links to IRC Sessions -*- lexical-binding: t; -*-
|
||||
;;
|
||||
;; Copyright (C) 2008-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2008-2023 Free Software Foundation, Inc.
|
||||
;;
|
||||
;; Author: Philip Jackson <emacs@shellarchive.co.uk>
|
||||
;; Keywords: erc, irc, link, org
|
||||
|
@ -103,7 +103,7 @@ attributes that are found."
|
|||
parts))
|
||||
|
||||
;;;###autoload
|
||||
(defun org-irc-store-link (&optional _interactive?)
|
||||
(defun org-irc-store-link ()
|
||||
"Dispatch to the appropriate function to store a link to an IRC session."
|
||||
(cond
|
||||
((eq major-mode 'erc-mode)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ol-man.el --- Links to man pages -*- lexical-binding: t; -*-
|
||||
;;
|
||||
;; Copyright (C) 2020-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2020-2023 Free Software Foundation, Inc.
|
||||
;; Author: Carsten Dominik <carsten.dominik@gmail.com>
|
||||
;; Maintainer: Bastien Guerry <bzg@gnu.org>
|
||||
;; Keywords: outlines, hypermedia, calendar, wp
|
||||
|
@ -24,17 +24,12 @@
|
|||
;;
|
||||
;;; Commentary:
|
||||
|
||||
;; This file implements links to man pages from within Org mode.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'org-macs)
|
||||
(org-assert-version)
|
||||
|
||||
(require 'ol)
|
||||
|
||||
(org-link-set-parameters "man"
|
||||
:complete #'org-man-complete
|
||||
:follow #'org-man-open
|
||||
:export #'org-man-export
|
||||
:store #'org-man-store-link)
|
||||
|
@ -42,29 +37,15 @@
|
|||
(defcustom org-man-command 'man
|
||||
"The Emacs command to be used to display a man page."
|
||||
:group 'org-link
|
||||
:type '(choice (const man) (const :tag "WoMan (obsolete)" woman)))
|
||||
:type '(choice (const man) (const woman)))
|
||||
|
||||
(declare-function Man-translate-references "man" (ref))
|
||||
(defun org-man-open (path _)
|
||||
"Visit the manpage on PATH.
|
||||
PATH should be a topic that can be thrown at the man command.
|
||||
If PATH contains extra ::STRING which will use `occur' to search
|
||||
matched strings in man buffer."
|
||||
(require 'man) ; For `Man-translate-references'
|
||||
(string-match "\\(.*?\\)\\(?:::\\(.*\\)\\)?$" path)
|
||||
(let* ((command (match-string 1 path))
|
||||
;; FIXME: Remove after we drop Emacs 29 support.
|
||||
;; Working around security bug #66390.
|
||||
(command (if (not (equal (Man-translate-references ";id") ";id"))
|
||||
;; We are on Emacs that escapes man command args
|
||||
;; (see Emacs commit 820f0793f0b).
|
||||
command
|
||||
;; Older Emacs without the fix - escape the
|
||||
;; arguments ourselves.
|
||||
(mapconcat 'identity
|
||||
(mapcar #'shell-quote-argument
|
||||
(split-string command "\\s-+"))
|
||||
" ")))
|
||||
(search (match-string 2 path))
|
||||
(buffer (funcall org-man-command command)))
|
||||
(when search
|
||||
|
@ -82,7 +63,7 @@ matched strings in man buffer."
|
|||
(set-window-point window point)
|
||||
(set-window-start window point)))))))
|
||||
|
||||
(defun org-man-store-link (&optional _interactive?)
|
||||
(defun org-man-store-link ()
|
||||
"Store a link to a README file."
|
||||
(when (memq major-mode '(Man-mode woman-mode))
|
||||
;; This is a man page, we do make this link
|
||||
|
@ -101,31 +82,18 @@ matched strings in man buffer."
|
|||
(match-string 1 (buffer-name))
|
||||
(error "Cannot create link to this man page")))
|
||||
|
||||
(defun org-man-export (link description backend)
|
||||
"Export a man page LINK with DESCRIPTION.
|
||||
BACKEND is the current export backend."
|
||||
(defun org-man-export (link description format)
|
||||
"Export a man page link from Org files."
|
||||
(let ((path (format "http://man.he.net/?topic=%s§ion=all" link))
|
||||
(desc (or description link)))
|
||||
(cond
|
||||
((eq backend 'html) (format "<a target=\"_blank\" href=\"%s\">%s</a>" path desc))
|
||||
((eq backend 'latex) (format "\\href{%s}{%s}" path desc))
|
||||
((eq backend 'texinfo) (format "@uref{%s,%s}" path desc))
|
||||
((eq backend 'ascii) (format "[%s] (<%s>)" desc path))
|
||||
((eq backend 'md) (format "[%s](%s)" desc path))
|
||||
((eq format 'html) (format "<a target=\"_blank\" href=\"%s\">%s</a>" path desc))
|
||||
((eq format 'latex) (format "\\href{%s}{%s}" path desc))
|
||||
((eq format 'texinfo) (format "@uref{%s,%s}" path desc))
|
||||
((eq format 'ascii) (format "%s (%s)" desc path))
|
||||
((eq format 'md) (format "[%s](%s)" desc path))
|
||||
(t path))))
|
||||
|
||||
(defvar Man-completion-cache) ; Defined in `man'.
|
||||
(defun org-man-complete (&optional _arg)
|
||||
"Complete man pages for `org-insert-link'."
|
||||
(require 'man)
|
||||
(concat
|
||||
"man:"
|
||||
(let ((completion-ignore-case t) ; See `man' comments.
|
||||
(Man-completion-cache)) ; See `man' implementation.
|
||||
(completing-read
|
||||
"Manual entry: "
|
||||
'Man-completion-table))))
|
||||
|
||||
(provide 'ol-man)
|
||||
|
||||
;;; ol-man.el ends here
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ol-mhe.el --- Links to MH-E Messages -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2004-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2004-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Thomas Baumann <thomas dot baumann at ch dot tum dot de>
|
||||
;; Keywords: outlines, hypermedia, calendar, wp
|
||||
|
@ -80,7 +80,7 @@ supported by MH-E."
|
|||
(org-link-set-parameters "mhe" :follow #'org-mhe-open :store #'org-mhe-store-link)
|
||||
|
||||
;; Implementation
|
||||
(defun org-mhe-store-link (&optional _interactive?)
|
||||
(defun org-mhe-store-link ()
|
||||
"Store a link to an MH-E folder or message."
|
||||
(when (or (eq major-mode 'mh-folder-mode)
|
||||
(eq major-mode 'mh-show-mode))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ol-rmail.el --- Links to Rmail Messages -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2004-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2004-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Carsten Dominik <carsten.dominik@gmail.com>
|
||||
;; Keywords: outlines, hypermedia, calendar, wp
|
||||
|
@ -51,7 +51,7 @@
|
|||
:store #'org-rmail-store-link)
|
||||
|
||||
;; Implementation
|
||||
(defun org-rmail-store-link (&optional _interactive?)
|
||||
(defun org-rmail-store-link ()
|
||||
"Store a link to an Rmail folder or message."
|
||||
(when (or (eq major-mode 'rmail-mode)
|
||||
(eq major-mode 'rmail-summary-mode))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; ol-w3m.el --- Copy and Paste From W3M -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2008-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2008-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Andy Stewart <lazycat dot manatee at gmail dot com>
|
||||
;; Keywords: outlines, hypermedia, calendar, wp
|
||||
|
|
624
lisp/ol.el
624
lisp/ol.el
|
@ -1,6 +1,6 @@
|
|||
;;; ol.el --- Org links library -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2018-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2018-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Carsten Dominik <carsten.dominik@gmail.com>
|
||||
;; Keywords: outlines, hypermedia, calendar, wp
|
||||
|
@ -52,19 +52,17 @@
|
|||
(declare-function org-do-occur "org" (regexp &optional cleanup))
|
||||
(declare-function org-element-at-point "org-element" (&optional pom cached-only))
|
||||
(declare-function org-element-cache-refresh "org-element" (pos))
|
||||
(declare-function org-element-cache-reset "org-element" (&optional all no-persistence))
|
||||
(declare-function org-element-context "org-element" (&optional element))
|
||||
(declare-function org-element-lineage "org-element-ast" (datum &optional types with-self))
|
||||
(declare-function org-element-lineage "org-element" (datum &optional types with-self))
|
||||
(declare-function org-element-link-parser "org-element" ())
|
||||
(declare-function org-element-property "org-element-ast" (property node))
|
||||
(declare-function org-element-begin "org-element" (node))
|
||||
(declare-function org-element-end "org-element" (node))
|
||||
(declare-function org-element-type-p "org-element-ast" (node types))
|
||||
(declare-function org-element-property "org-element" (property element))
|
||||
(declare-function org-element-type "org-element" (element))
|
||||
(declare-function org-element-update-syntax "org-element" ())
|
||||
(declare-function org-entry-get "org" (pom property &optional inherit literal-nil))
|
||||
(declare-function org-find-property "org" (property &optional value))
|
||||
(declare-function org-get-heading "org" (&optional no-tags no-todo no-priority no-comment))
|
||||
(declare-function org-id-find-id-file "org-id" (id))
|
||||
(declare-function org-id-store-link "org-id" ())
|
||||
(declare-function org-insert-heading "org" (&optional arg invisible-ok top))
|
||||
(declare-function org-load-modules-maybe "org" (&optional force))
|
||||
(declare-function org-mark-ring-push "org" (&optional pos buffer))
|
||||
|
@ -116,11 +114,11 @@ below.
|
|||
Function that accepts four arguments:
|
||||
- the path, as a string,
|
||||
- the description as a string, or nil,
|
||||
- the export backend,
|
||||
- the export back-end,
|
||||
- the export communication channel, as a plist.
|
||||
|
||||
When nil, export for that type of link is delegated to the
|
||||
backend.
|
||||
back-end.
|
||||
|
||||
`:store'
|
||||
|
||||
|
@ -198,16 +196,6 @@ link.
|
|||
:type '(alist :tag "Link display parameters"
|
||||
:value-type plist))
|
||||
|
||||
(defun org-link--set-link-display (symbol value)
|
||||
"Set `org-link-descriptive' (SYMBOL) to VALUE.
|
||||
Also, ensure that links are updated in current buffer.
|
||||
|
||||
This function is intended to be used as a :set function."
|
||||
(set symbol value)
|
||||
(dolist (buf (org-buffer-list))
|
||||
(with-current-buffer buf
|
||||
(org-link-descriptive-ensure))))
|
||||
|
||||
(defcustom org-link-descriptive t
|
||||
"Non-nil means Org displays descriptive links.
|
||||
|
||||
|
@ -219,7 +207,6 @@ literally.
|
|||
You can interactively set the value of this variable by calling
|
||||
`org-toggle-link-display' or from the \"Org > Hyperlinks\" menu."
|
||||
:group 'org-link
|
||||
:set #'org-link--set-link-display
|
||||
:type 'boolean
|
||||
:safe #'booleanp)
|
||||
|
||||
|
@ -247,7 +234,7 @@ adaptive Use relative path for files in the current directory and sub-
|
|||
directories of it. For other files, use an absolute path.
|
||||
|
||||
Alternatively, users may supply a custom function that takes the
|
||||
filename in the link as an argument and returns the path."
|
||||
full filename as an argument and returns the path."
|
||||
:group 'org-link
|
||||
:type '(choice
|
||||
(const relative)
|
||||
|
@ -308,7 +295,10 @@ or emacs-wiki packages to Org syntax.
|
|||
The function must accept two parameters, a TYPE containing the link
|
||||
protocol name like \"rmail\" or \"gnus\" as a string, and the linked path,
|
||||
which is everything after the link protocol. It should return a cons
|
||||
with possibly modified values of type and path."
|
||||
with possibly modified values of type and path.
|
||||
Org contains a function for this, so if you set this variable to
|
||||
`org-translate-link-from-planner', you should be able follow many
|
||||
links created by planner."
|
||||
:group 'org-link-follow
|
||||
:type '(choice (const nil) (function))
|
||||
:safe #'null)
|
||||
|
@ -369,17 +359,14 @@ another window."
|
|||
(const wl-other-frame)))))
|
||||
|
||||
(defcustom org-link-search-must-match-exact-headline 'query-to-create
|
||||
"Control fuzzy link behaviour when specific matches not found.
|
||||
"Non-nil means internal fuzzy links can only match headlines.
|
||||
|
||||
When nil, if a fuzzy link does not match a more specific
|
||||
target (such as a heading, named block, target, or code ref),
|
||||
attempt a regular text search. When set to the special value
|
||||
`query-to-create', offer to create a new heading matching the
|
||||
link instead. Otherwise, signal an error rather than attempting
|
||||
a regular text search.
|
||||
When nil, the fuzzy link may point to a target or a named
|
||||
construct in the document. When set to the special value
|
||||
`query-to-create', offer to create a new headline when none
|
||||
matched.
|
||||
|
||||
This option only affects behaviour in Org buffers. Spaces and
|
||||
statistics cookies are ignored during heading searches."
|
||||
Spaces and statistics cookies are ignored during heading searches."
|
||||
:group 'org-link-follow
|
||||
:version "24.1"
|
||||
:type '(choice
|
||||
|
@ -533,16 +520,6 @@ links more efficient."
|
|||
|
||||
(defvar-local org-target-link-regexp nil
|
||||
"Regular expression matching radio targets in plain text.")
|
||||
(defconst org-target-link-regexp-limit (ash 2 12)
|
||||
"Maximum allowed length of regexp.
|
||||
The number should generally be ~order of magnitude smaller than
|
||||
MAX_BUF_SIZE in src/regex-emacs.c. The number of regexp-emacs.c is
|
||||
for processed regexp, which appears to be larger compared to the
|
||||
original string length.")
|
||||
(defvar-local org-target-link-regexps nil
|
||||
"List of regular expressions matching radio targets in plain text.
|
||||
This list is non-nil, when a single regexp would be too long to match
|
||||
all the possible targets, exceeding Emacs' regexp length limit.")
|
||||
|
||||
(defvar org-link-types-re nil
|
||||
"Matches a link that has a url-like prefix like \"http:\".")
|
||||
|
@ -777,8 +754,8 @@ White spaces are not significant."
|
|||
(while (re-search-forward re nil t)
|
||||
(forward-char -1)
|
||||
(let ((object (org-element-context)))
|
||||
(when (org-element-type-p object 'radio-target)
|
||||
(goto-char (org-element-begin object))
|
||||
(when (eq (org-element-type object) 'radio-target)
|
||||
(goto-char (org-element-property :begin object))
|
||||
(org-fold-show-context 'link-search)
|
||||
(throw :radio-match nil))))
|
||||
(goto-char origin)
|
||||
|
@ -829,74 +806,6 @@ spec."
|
|||
(org-with-point-at (car region)
|
||||
(not (org-in-regexp org-link-any-re))))
|
||||
|
||||
(defun org-link--try-link-store-functions (interactive?)
|
||||
"Try storing external links, prompting if more than one is possible.
|
||||
|
||||
Each function returned by `org-store-link-functions' is called in
|
||||
turn. If multiple functions return non-nil, prompt for which
|
||||
link should be stored.
|
||||
|
||||
Argument INTERACTIVE? indicates whether `org-store-link' was
|
||||
called interactively and is passed to the link store functions.
|
||||
|
||||
Return t when a link has been stored in `org-link-store-props'."
|
||||
(let ((results-alist nil))
|
||||
(dolist (f (org-store-link-functions))
|
||||
(when (condition-case nil
|
||||
(funcall f interactive?)
|
||||
;; FIXME: The store function used (< Org 9.7) to accept
|
||||
;; no arguments; provide backward compatibility support
|
||||
;; for them.
|
||||
(wrong-number-of-arguments
|
||||
(funcall f)))
|
||||
;; FIXME: return value is not link's plist, so we store the
|
||||
;; new value before it is modified. It would be cleaner to
|
||||
;; ask store link functions to return the plist instead.
|
||||
(push (cons f (copy-sequence org-store-link-plist))
|
||||
results-alist)))
|
||||
(pcase results-alist
|
||||
(`nil nil)
|
||||
(`((,_ . ,_)) t) ;single choice: nothing to do
|
||||
(`((,name . ,_) . ,_)
|
||||
;; Reinstate link plist associated to the chosen
|
||||
;; function.
|
||||
(apply #'org-link-store-props
|
||||
(cdr (assoc-string
|
||||
(completing-read
|
||||
(format "Store link with (default %s): " name)
|
||||
(mapcar #'car results-alist)
|
||||
nil t nil nil (symbol-name name))
|
||||
results-alist)))
|
||||
t))))
|
||||
|
||||
(defun org-link--add-to-stored-links (link desc)
|
||||
"Add LINK to `org-stored-links' with description DESC."
|
||||
(cond
|
||||
((not (member (list link desc) org-stored-links))
|
||||
(push (list link desc) org-stored-links)
|
||||
(message "Stored: %s" (or desc link)))
|
||||
((equal (list link desc) (car org-stored-links))
|
||||
(message "This link has already been stored"))
|
||||
(t
|
||||
(setq org-stored-links
|
||||
(delete (list link desc) org-stored-links))
|
||||
(push (list link desc) org-stored-links)
|
||||
(message "Link moved to front: %s" (or desc link)))))
|
||||
|
||||
(defun org-link--file-link-to-here ()
|
||||
"Return as (LINK . DESC) a file link with search string to here."
|
||||
(let ((link (concat "file:"
|
||||
(abbreviate-file-name
|
||||
(buffer-file-name (buffer-base-buffer)))))
|
||||
desc)
|
||||
(when org-link-context-for-files
|
||||
(pcase (org-link-precise-link-target)
|
||||
(`nil nil)
|
||||
(`(,search-string ,search-desc ,_position)
|
||||
(setq link (format "%s::%s" link search-string))
|
||||
(setq desc search-desc))))
|
||||
(cons link desc)))
|
||||
|
||||
|
||||
;;; Public API
|
||||
|
||||
|
@ -923,13 +832,6 @@ PARAMETERS should be keyword value pairs. See
|
|||
(org-link-make-regexps)
|
||||
(when (featurep 'org-element) (org-element-update-syntax)))))
|
||||
|
||||
;; This way, one can add multiple functions as, say, :follow parameter.
|
||||
;; For example,
|
||||
;; (add-function :before-until (org-link-get-parameter "id" :follow) #'my-function)
|
||||
;; See https://orgmode.org/list/a123389c-8f86-4836-a4fe-1e3f4281d33b@app.fastmail.com
|
||||
(gv-define-setter org-link-get-parameter (value type key)
|
||||
`(org-link-set-parameters ,type ,key ,value))
|
||||
|
||||
(defun org-link-make-regexps ()
|
||||
"Update the link regular expressions.
|
||||
This should be called after the variable `org-link-parameters' has changed."
|
||||
|
@ -942,12 +844,12 @@ This should be called after the variable `org-link-parameters' has changed."
|
|||
org-link-plain-re
|
||||
(let* ((non-space-bracket "[^][ \t\n()<>]")
|
||||
(parenthesis
|
||||
`(seq (any "<([")
|
||||
`(seq "("
|
||||
(0+ (or (regex ,non-space-bracket)
|
||||
(seq (any "<([")
|
||||
(seq "("
|
||||
(0+ (regex ,non-space-bracket))
|
||||
(any "])>"))))
|
||||
(any "])>"))))
|
||||
")")))
|
||||
")")))
|
||||
;; Heuristics for an URL link inspired by
|
||||
;; https://daringfireball.net/2010/07/improved_regex_for_matching_urls
|
||||
(rx-to-string
|
||||
|
@ -980,8 +882,7 @@ This should be called after the variable `org-link-parameters' has changed."
|
|||
org-link-plain-re "\\)"))))
|
||||
|
||||
(defun org-link-complete-file (&optional arg)
|
||||
"Create a file link using completion.
|
||||
With optional ARG \\='(16), abbreviate the file name in the link."
|
||||
"Create a file link using completion."
|
||||
(let ((file (read-file-name "File: "))
|
||||
(pwd (file-name-as-directory (expand-file-name ".")))
|
||||
(pwd1 (file-name-as-directory (abbreviate-file-name
|
||||
|
@ -1026,7 +927,7 @@ according to FMT (default from `org-link-email-description-format')."
|
|||
(org-replace-escapes fmt table)))
|
||||
|
||||
(defun org-link-store-props (&rest plist)
|
||||
"Store link properties PLIST.
|
||||
"Store link properties.
|
||||
The properties are pre-processed by extracting names, addresses
|
||||
and dates."
|
||||
(let ((x (plist-get plist :from)))
|
||||
|
@ -1058,7 +959,7 @@ and dates."
|
|||
(setq org-store-link-plist plist))
|
||||
|
||||
(defun org-link-add-props (&rest plist)
|
||||
"Add these properties to the link property list PLIST."
|
||||
"Add these properties to the link property list."
|
||||
(let (key value)
|
||||
(while plist
|
||||
(setq key (pop plist) value (pop plist))
|
||||
|
@ -1130,9 +1031,7 @@ LINK is escaped with backslashes for inclusion in buffer."
|
|||
"List of functions that are called to create and store a link.
|
||||
|
||||
The functions are defined in the `:store' property of
|
||||
`org-link-parameters'. Each function should accept an argument
|
||||
INTERACTIVE? which indicates whether the user has initiated
|
||||
`org-store-link' interactively.
|
||||
`org-link-parameters'.
|
||||
|
||||
Each function will be called in turn until one returns a non-nil
|
||||
value. Each function should check if it is responsible for
|
||||
|
@ -1156,9 +1055,6 @@ and then used in capture templates."
|
|||
if store-func
|
||||
collect store-func))
|
||||
|
||||
(defvar org-link--abbrev-functions nil
|
||||
"Alist of abbrev link expressions and functions.")
|
||||
|
||||
(defun org-link-expand-abbrev (link)
|
||||
"Replace link abbreviations in LINK string.
|
||||
Abbreviations are defined in `org-link-abbrev-alist'."
|
||||
|
@ -1173,27 +1069,14 @@ Abbreviations are defined in `org-link-abbrev-alist'."
|
|||
(setq rpl (cdr as))
|
||||
(cond
|
||||
((symbolp rpl) (funcall rpl tag))
|
||||
((string-match "%(\\([^) ]+\\))" rpl) ; %(function)
|
||||
((string-match "%(\\([^)]+\\))" rpl)
|
||||
(replace-match
|
||||
(save-match-data
|
||||
(funcall (intern-soft (match-string 1 rpl)) tag))
|
||||
t t rpl))
|
||||
((string-match "%(\\(.+\\))" rpl) ; %(sexpr using tag)
|
||||
(replace-match
|
||||
(save-match-data
|
||||
(funcall (or (cdr (assoc (match-string 1 rpl)
|
||||
org-link--abbrev-functions))
|
||||
(cdar (push (cons (match-string 1 rpl)
|
||||
(eval (read (format
|
||||
"(lambda (tag) (%s))"
|
||||
(match-string 1 rpl)))))
|
||||
org-link--abbrev-functions)))
|
||||
tag))
|
||||
t t rpl))
|
||||
((string-match-p "%[0-<>^_]?[0-9]*\\(?:\\.[0-9]+\\)?s" rpl)
|
||||
(format-spec rpl `((?s . ,(or tag "")))))
|
||||
((string-match-p "%[0-<>^_]?[0-9]*\\(?:\\.[0-9]+\\)?h" rpl)
|
||||
(format-spec rpl `((?h . ,(url-hexify-string (or tag ""))))))
|
||||
((string-match "%s" rpl) (replace-match (or tag "") t t rpl))
|
||||
((string-match "%h" rpl)
|
||||
(replace-match (url-hexify-string (or tag "")) t t rpl))
|
||||
(t (concat rpl tag)))))))
|
||||
|
||||
(defun org-link-open (link &optional arg)
|
||||
|
@ -1235,7 +1118,7 @@ for internal and \"file\" links, or stored as a parameter in
|
|||
(_ path))
|
||||
;; Prevent fuzzy links from matching themselves.
|
||||
(and (equal type "fuzzy")
|
||||
(+ 2 (org-element-begin link)))))
|
||||
(+ 2 (org-element-property :begin link)))))
|
||||
(point))))
|
||||
(unless (and (<= (point-min) destination)
|
||||
(>= (point-max) destination))
|
||||
|
@ -1249,14 +1132,14 @@ for internal and \"file\" links, or stored as a parameter in
|
|||
;; argument, as it was mandatory before Org 9.4. This is
|
||||
;; deprecated, but support it for now.
|
||||
(condition-case nil
|
||||
(funcall f path arg)
|
||||
(funcall (org-link-get-parameter type :follow) path arg)
|
||||
(wrong-number-of-arguments
|
||||
(funcall f path)))))))))
|
||||
(funcall (org-link-get-parameter type :follow) path)))))))))
|
||||
|
||||
(defun org-link-open-from-string (s &optional arg)
|
||||
"Open a link in the string S, as if it was in Org mode.
|
||||
Optional argument ARG is passed to `org-open-file' when S is a
|
||||
\"file\" link."
|
||||
Optional argument is passed to `org-open-file' when S is
|
||||
a \"file\" link."
|
||||
(interactive "sLink: \nP")
|
||||
(pcase (with-temp-buffer
|
||||
(let ((org-inhibit-startup nil))
|
||||
|
@ -1267,8 +1150,8 @@ Optional argument ARG is passed to `org-open-file' when S is a
|
|||
(`nil (user-error "No valid link in %S" s))
|
||||
(link (org-link-open link arg))))
|
||||
|
||||
(defun org-link-search (s &optional avoid-pos stealth new-heading-container)
|
||||
"Search for a search string S in the accessible part of the buffer.
|
||||
(defun org-link-search (s &optional avoid-pos stealth)
|
||||
"Search for a search string S.
|
||||
|
||||
If S starts with \"#\", it triggers a custom ID search.
|
||||
|
||||
|
@ -1287,16 +1170,8 @@ When optional argument STEALTH is non-nil, do not modify
|
|||
visibility around point, thus ignoring `org-show-context-detail'
|
||||
variable.
|
||||
|
||||
When optional argument NEW-HEADING-CONTAINER is an element, any
|
||||
new heading that is created (see
|
||||
`org-link-search-must-match-exact-headline') will be added as a
|
||||
subheading of NEW-HEADING-CONTAINER. Otherwise, new headings are
|
||||
created at level 1 at the end of the accessible part of the
|
||||
buffer.
|
||||
|
||||
Search is case-insensitive and ignores white spaces. Return type
|
||||
of matched result, which is either `dedicated' or `fuzzy'. Search
|
||||
respects buffer narrowing."
|
||||
of matched result, which is either `dedicated' or `fuzzy'."
|
||||
(unless (org-string-nw-p s) (error "Invalid search string \"%s\"" s))
|
||||
(let* ((case-fold-search t)
|
||||
(origin (point))
|
||||
|
@ -1323,7 +1198,8 @@ respects buffer narrowing."
|
|||
(catch :coderef-match
|
||||
(while (re-search-forward re nil t)
|
||||
(let ((element (org-element-at-point)))
|
||||
(when (and (org-element-type-p element '(example-block src-block))
|
||||
(when (and (memq (org-element-type element)
|
||||
'(example-block src-block))
|
||||
(org-match-line
|
||||
(concat ".*?" (org-src-coderef-regexp
|
||||
(org-src-coderef-format element)
|
||||
|
@ -1347,9 +1223,9 @@ respects buffer narrowing."
|
|||
(while (re-search-forward target nil t)
|
||||
(backward-char)
|
||||
(let ((context (org-element-context)))
|
||||
(when (org-element-type-p context 'target)
|
||||
(when (eq (org-element-type context) 'target)
|
||||
(setq type 'dedicated)
|
||||
(goto-char (org-element-begin context))
|
||||
(goto-char (org-element-property :begin context))
|
||||
(throw :target-match t))))
|
||||
nil))))
|
||||
;; Look for elements named after S, only if not in a headline
|
||||
|
@ -1361,9 +1237,9 @@ respects buffer narrowing."
|
|||
(while (re-search-forward name nil t)
|
||||
(let* ((element (org-element-at-point))
|
||||
(name (org-element-property :name element)))
|
||||
(when (and name (equal (mapcar #'upcase words) (mapcar #'upcase (split-string name))))
|
||||
(when (and name (equal words (split-string name)))
|
||||
(setq type 'dedicated)
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(throw :name-match t))))
|
||||
nil))))
|
||||
;; Regular text search. Prefer headlines in Org mode buffers.
|
||||
|
@ -1378,38 +1254,24 @@ respects buffer narrowing."
|
|||
(goto-char (point-min))
|
||||
(catch :found
|
||||
(while (re-search-forward title-re nil t)
|
||||
(when (equal (mapcar #'upcase words)
|
||||
(mapcar #'upcase
|
||||
(split-string
|
||||
(org-link--normalize-string
|
||||
(org-get-heading t t t t)))))
|
||||
(when (equal words
|
||||
(split-string
|
||||
(org-link--normalize-string
|
||||
(org-get-heading t t t t))))
|
||||
(throw :found t)))
|
||||
nil)))
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(setq type 'dedicated))
|
||||
;; Offer to create non-existent headline depending on
|
||||
;; `org-link-search-must-match-exact-headline'.
|
||||
((and (derived-mode-p 'org-mode)
|
||||
(eq org-link-search-must-match-exact-headline 'query-to-create)
|
||||
(yes-or-no-p "No match - create this as a new heading? "))
|
||||
(let* ((container-ok (and new-heading-container
|
||||
(org-element-type-p new-heading-container '(headline))))
|
||||
(new-heading-position (if container-ok
|
||||
(- (org-element-end new-heading-container) 1)
|
||||
(point-max)))
|
||||
(new-heading-level (if container-ok
|
||||
(+ 1 (org-element-property :level new-heading-container))
|
||||
1)))
|
||||
;; Need to widen when target is outside accessible portion of
|
||||
;; buffer, since the we want the user to end up there.
|
||||
(unless (and (<= (point-min) new-heading-position)
|
||||
(>= (point-max) new-heading-position))
|
||||
(widen))
|
||||
(goto-char new-heading-position)
|
||||
(unless (bolp) (newline))
|
||||
(org-insert-heading nil t new-heading-level)
|
||||
(insert (if starred (substring s 1) s) "\n")
|
||||
(forward-line -1)))
|
||||
(goto-char (point-max))
|
||||
(unless (bolp) (newline))
|
||||
(org-insert-heading nil t t)
|
||||
(insert s "\n")
|
||||
(beginning-of-line 0))
|
||||
;; Only headlines are looked after. No need to process
|
||||
;; further: throw an error.
|
||||
((and (derived-mode-p 'org-mode)
|
||||
|
@ -1432,7 +1294,7 @@ respects buffer narrowing."
|
|||
(<= (match-end 3) (point)))
|
||||
(org-element-lineage
|
||||
(save-match-data (org-element-context))
|
||||
'link t)))
|
||||
'(link) t)))
|
||||
(goto-char (match-beginning 0))
|
||||
(setq type 'fuzzy)
|
||||
(throw :fuzzy-match t)))
|
||||
|
@ -1459,75 +1321,9 @@ priority cookie or tag."
|
|||
(org-link--normalize-string
|
||||
(or string (org-get-heading t t t t)))))
|
||||
|
||||
(defun org-link-precise-link-target ()
|
||||
"Determine search string and description for storing a link.
|
||||
|
||||
If a search string (see `org-link-search') is found, return
|
||||
list (SEARCH-STRING DESC POSITION). Otherwise, return nil.
|
||||
|
||||
If there is an active region, the contents (or a part of it, see
|
||||
`org-link-context-for-files') is used as the search string.
|
||||
|
||||
In Org buffers, if point is at a named element (such as a source
|
||||
block), the name is used for the search string. If at a heading,
|
||||
its CUSTOM_ID is used to form a search string of the form
|
||||
\"#id\", if present, otherwise the current heading text is used
|
||||
in the form \"*Heading\".
|
||||
|
||||
If none of those finds a suitable search string, the current line
|
||||
is used as the search string.
|
||||
|
||||
The description DESC is nil (meaning the user will be prompted
|
||||
for a description when inserting the link) for search strings
|
||||
based on a region or the current line. For other cases, DESC is
|
||||
a cleaned-up version of the name or heading at point.
|
||||
|
||||
POSITION is the buffer position at which the search string
|
||||
matches."
|
||||
(let* ((region (org-link--context-from-region))
|
||||
(result
|
||||
(cond
|
||||
(region
|
||||
(list (org-link--normalize-string region t)
|
||||
nil
|
||||
(region-beginning)))
|
||||
|
||||
((derived-mode-p 'org-mode)
|
||||
(let* ((element (org-element-at-point))
|
||||
(name (org-element-property :name element))
|
||||
(heading (org-element-lineage element '(headline inlinetask) t))
|
||||
(custom-id (org-entry-get heading "CUSTOM_ID")))
|
||||
(cond
|
||||
(name
|
||||
(list name
|
||||
name
|
||||
(org-element-begin element)))
|
||||
((org-before-first-heading-p)
|
||||
(list (org-link--normalize-string (org-current-line-string) t)
|
||||
nil
|
||||
(line-beginning-position)))
|
||||
(heading
|
||||
(list (if custom-id (concat "#" custom-id)
|
||||
(org-link-heading-search-string))
|
||||
(org-link--normalize-string
|
||||
(org-get-heading t t t t))
|
||||
(org-element-begin heading))))))
|
||||
|
||||
;; Not in an org-mode buffer, no region
|
||||
(t
|
||||
(list (org-link--normalize-string (org-current-line-string) t)
|
||||
nil
|
||||
(line-beginning-position))))))
|
||||
|
||||
;; Only use search option if there is some text.
|
||||
(when (org-string-nw-p (car result))
|
||||
result)))
|
||||
|
||||
(defun org-link-open-as-file (path in-emacs)
|
||||
(defun org-link-open-as-file (path arg)
|
||||
"Pretend PATH is a file name and open it.
|
||||
|
||||
IN-EMACS is passed to `org-open-file'.
|
||||
|
||||
According to \"file\"-link syntax, PATH may include additional
|
||||
search options, separated from the file name with \"::\".
|
||||
|
||||
|
@ -1537,12 +1333,11 @@ This function is meant to be used as a possible tool for
|
|||
(match-string 1 path)))
|
||||
(file-name (if (not option) path
|
||||
(substring path 0 (match-beginning 0)))))
|
||||
(if (and (string-match "[*?{]" (file-name-nondirectory file-name))
|
||||
(not (file-exists-p file-name)))
|
||||
(dired file-name)
|
||||
(if (string-match "[*?{]" (file-name-nondirectory file-name))
|
||||
(dired file-name)
|
||||
(apply #'org-open-file
|
||||
file-name
|
||||
in-emacs
|
||||
arg
|
||||
(cond ((not option) nil)
|
||||
((string-match-p "\\`[0-9]+\\'" option)
|
||||
(list (string-to-number option)))
|
||||
|
@ -1596,7 +1391,7 @@ PATH is a symbol name, as a string."
|
|||
((and (pred boundp) variable) (describe-variable variable))
|
||||
(name (user-error "Unknown function or variable: %s" name))))
|
||||
|
||||
(defun org-link--store-help (&optional _interactive?)
|
||||
(defun org-link--store-help ()
|
||||
"Store \"help\" type link."
|
||||
(when (eq major-mode 'help-mode)
|
||||
(let ((symbol
|
||||
|
@ -1678,10 +1473,10 @@ is non-nil, move backward."
|
|||
(let ((context (save-excursion
|
||||
(unless search-backward (forward-char -1))
|
||||
(org-element-context))))
|
||||
(pcase (org-element-lineage context 'link t)
|
||||
(pcase (org-element-lineage context '(link) t)
|
||||
(`nil nil)
|
||||
(link
|
||||
(goto-char (org-element-begin link))
|
||||
(goto-char (org-element-property :begin link))
|
||||
(when (org-invisible-p) (org-fold-show-context 'link-search))
|
||||
(throw :found t)))))
|
||||
(goto-char pos)
|
||||
|
@ -1714,12 +1509,10 @@ If the link is in hidden text, expose it."
|
|||
\\<org-mode-map>
|
||||
This link is added to `org-stored-links' and can later be inserted
|
||||
into an Org buffer with `org-insert-link' (`\\[org-insert-link]').
|
||||
When optional argument INTERACTIVE? is nil, the link is not stored in
|
||||
`org-stored-links', but returned as a string.
|
||||
|
||||
For some link types, a `\\[universal-argument]' prefix ARG is interpreted. \
|
||||
A single
|
||||
`\\[universal-argument]' negates `org-link-context-for-files' for file links or
|
||||
`\\[universal-argument]' negates `org-context-in-file-links' for file links or
|
||||
`org-gnus-prefer-web-links' for links to Usenet articles.
|
||||
|
||||
A `\\[universal-argument] \\[universal-argument]' prefix ARG forces \
|
||||
|
@ -1731,12 +1524,7 @@ prefix ARG forces storing a link for each line in the
|
|||
active region.
|
||||
|
||||
Assume the function is called interactively if INTERACTIVE? is
|
||||
non-nil.
|
||||
|
||||
In Org buffers, an additional \"human-readable\" simple file link
|
||||
is stored as an alternative to persistent org-id or other links,
|
||||
if at a heading with a CUSTOM_ID property or an element with a
|
||||
NAME."
|
||||
non-nil."
|
||||
(interactive "P\np")
|
||||
(org-load-modules-maybe)
|
||||
(if (and (equal arg '(64)) (org-region-active-p))
|
||||
|
@ -1751,19 +1539,36 @@ NAME."
|
|||
(move-beginning-of-line 2)
|
||||
(set-mark (point)))))
|
||||
(setq org-store-link-plist nil)
|
||||
;; Negate `org-context-in-file-links' when given a single universal arg.
|
||||
(let ((org-link-context-for-files (org-xor org-link-context-for-files
|
||||
(equal arg '(4))))
|
||||
link cpltxt desc search agenda-link) ;; description
|
||||
(let (link cpltxt desc search custom-id agenda-link) ;; description
|
||||
(cond
|
||||
;; Store a link using an external link type, if any function is
|
||||
;; available, unless external link types are skipped for this
|
||||
;; call using two universal args. If more than one function
|
||||
;; can generate a link from current location, ask the user
|
||||
;; which one to use.
|
||||
;; available. If more than one can generate a link from current
|
||||
;; location, ask which one to use.
|
||||
((and (not (equal arg '(16)))
|
||||
(org-link--try-link-store-functions interactive?))
|
||||
(setq link (plist-get org-store-link-plist :link))
|
||||
(let ((results-alist nil))
|
||||
(dolist (f (org-store-link-functions))
|
||||
(when (funcall f)
|
||||
;; XXX: return value is not link's plist, so we
|
||||
;; store the new value before it is modified. It
|
||||
;; would be cleaner to ask store link functions to
|
||||
;; return the plist instead.
|
||||
(push (cons f (copy-sequence org-store-link-plist))
|
||||
results-alist)))
|
||||
(pcase results-alist
|
||||
(`nil nil)
|
||||
(`((,_ . ,_)) t) ;single choice: nothing to do
|
||||
(`((,name . ,_) . ,_)
|
||||
;; Reinstate link plist associated to the chosen
|
||||
;; function.
|
||||
(apply #'org-link-store-props
|
||||
(cdr (assoc-string
|
||||
(completing-read
|
||||
(format "Store link with (default %s): " name)
|
||||
(mapcar #'car results-alist)
|
||||
nil t nil nil (symbol-name name))
|
||||
results-alist)))
|
||||
t))))
|
||||
(setq link (plist-get org-store-link-plist :link))
|
||||
;; If store function actually set `:description' property, use
|
||||
;; it, even if it is nil. Otherwise, fallback to nil (ask user).
|
||||
(setq desc (plist-get org-store-link-plist :description)))
|
||||
|
@ -1785,7 +1590,7 @@ NAME."
|
|||
(setq link nil))
|
||||
;; A code reference exists. Use it.
|
||||
((save-excursion
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(re-search-forward (org-src-coderef-regexp coderef-format)
|
||||
(line-end-position)
|
||||
t))
|
||||
|
@ -1814,7 +1619,6 @@ NAME."
|
|||
(org-with-point-at m
|
||||
(setq agenda-link (org-store-link nil interactive?))))))
|
||||
|
||||
;; Calendar mode
|
||||
((eq major-mode 'calendar-mode)
|
||||
(let ((cd (calendar-cursor-to-date)))
|
||||
(setq link
|
||||
|
@ -1823,7 +1627,6 @@ NAME."
|
|||
(org-encode-time 0 0 0 (nth 1 cd) (nth 0 cd) (nth 2 cd))))
|
||||
(org-link-store-props :type "calendar" :date cd)))
|
||||
|
||||
;; Image mode
|
||||
((eq major-mode 'image-mode)
|
||||
(setq cpltxt (concat "file:"
|
||||
(abbreviate-file-name buffer-file-name))
|
||||
|
@ -1841,22 +1644,15 @@ NAME."
|
|||
(setq cpltxt (concat "file:" file)
|
||||
link cpltxt)))
|
||||
|
||||
;; Try `org-create-file-search-functions`. If any are
|
||||
;; successful, create a file link to the current buffer with
|
||||
;; the provided search string. (sets `link` and `cpltxt` to
|
||||
;; the same thing; it looks like the intention originally was
|
||||
;; that cpltxt was a description, which might have been set by
|
||||
;; the search-function (removed in switch to lexical binding)).
|
||||
((setq search (run-hook-with-args-until-success
|
||||
'org-create-file-search-functions))
|
||||
(setq link (concat "file:" (abbreviate-file-name buffer-file-name)
|
||||
"::" search))
|
||||
(setq cpltxt (or link))) ;; description
|
||||
|
||||
;; Main logic for storing built-in link types in org-mode
|
||||
;; buffers
|
||||
((and (buffer-file-name (buffer-base-buffer)) (derived-mode-p 'org-mode))
|
||||
(org-with-limited-levels
|
||||
(setq custom-id (org-entry-get nil "CUSTOM_ID"))
|
||||
(cond
|
||||
;; Store a link using the target at point
|
||||
((org-in-regexp "[^<]<<\\([^<>]+\\)>>[^>]" 1)
|
||||
|
@ -1870,21 +1666,74 @@ NAME."
|
|||
;; links. Maybe the case of identical target and
|
||||
;; description should be handled by `org-insert-link'.
|
||||
cpltxt nil
|
||||
desc nil))
|
||||
(t
|
||||
desc nil
|
||||
;; Do not append #CUSTOM_ID link below.
|
||||
custom-id nil))
|
||||
((and (featurep 'org-id)
|
||||
(or (eq org-id-link-to-org-use-id t)
|
||||
(and interactive?
|
||||
(or (eq org-id-link-to-org-use-id 'create-if-interactive)
|
||||
(and (eq org-id-link-to-org-use-id
|
||||
'create-if-interactive-and-no-custom-id)
|
||||
(not custom-id))))
|
||||
(and org-id-link-to-org-use-id (org-entry-get nil "ID"))))
|
||||
;; Store a link using the ID at point
|
||||
(setq link (condition-case nil
|
||||
(prog1 (org-id-store-link)
|
||||
(setq desc (plist-get org-store-link-plist :description)))
|
||||
(error
|
||||
;; Probably before first headline, link only to file
|
||||
(concat "file:"
|
||||
(abbreviate-file-name
|
||||
(buffer-file-name (buffer-base-buffer))))))))
|
||||
(t
|
||||
;; Just link to current headline.
|
||||
(let ((here (org-link--file-link-to-here)))
|
||||
(setq cpltxt (car here))
|
||||
(setq desc (cdr here)))
|
||||
(setq link cpltxt)))))
|
||||
(setq cpltxt (concat "file:"
|
||||
(abbreviate-file-name
|
||||
(buffer-file-name (buffer-base-buffer)))))
|
||||
;; Add a context search string.
|
||||
(when (org-xor org-link-context-for-files (equal arg '(4)))
|
||||
(let* ((element (org-element-at-point))
|
||||
(name (org-element-property :name element))
|
||||
(context
|
||||
(cond
|
||||
((let ((region (org-link--context-from-region)))
|
||||
(and region (org-link--normalize-string region t))))
|
||||
(name)
|
||||
((org-before-first-heading-p)
|
||||
(org-link--normalize-string (org-current-line-string) t))
|
||||
(t (org-link-heading-search-string)))))
|
||||
(when (org-string-nw-p context)
|
||||
(setq cpltxt (format "%s::%s" cpltxt context))
|
||||
(setq desc
|
||||
(or name
|
||||
;; Although description is not a search
|
||||
;; string, use `org-link--normalize-string'
|
||||
;; to prettify it (contiguous white spaces)
|
||||
;; and remove volatile contents (statistics
|
||||
;; cookies).
|
||||
(and (not (org-before-first-heading-p))
|
||||
(org-link--normalize-string
|
||||
(org-get-heading t t t t)))
|
||||
"NONE")))))
|
||||
(setq link cpltxt)))))
|
||||
|
||||
;; Buffer linked to file, but not an org-mode buffer.
|
||||
((buffer-file-name (buffer-base-buffer))
|
||||
;; Just link to this file here.
|
||||
(let ((here (org-link--file-link-to-here)))
|
||||
(setq cpltxt (car here))
|
||||
(setq desc (cdr here)))
|
||||
(setq link cpltxt))
|
||||
(setq cpltxt (concat "file:"
|
||||
(abbreviate-file-name
|
||||
(buffer-file-name (buffer-base-buffer)))))
|
||||
;; Add a context search string.
|
||||
(when (org-xor org-link-context-for-files (equal arg '(4)))
|
||||
(let ((context (org-link--normalize-string
|
||||
(or (org-link--context-from-region)
|
||||
(org-current-line-string))
|
||||
t)))
|
||||
;; Only use search option if there is some text.
|
||||
(when (org-string-nw-p context)
|
||||
(setq cpltxt (format "%s::%s" cpltxt context))
|
||||
(setq desc "NONE"))))
|
||||
(setq link cpltxt))
|
||||
|
||||
(interactive?
|
||||
(user-error "No method for storing a link from this buffer"))
|
||||
|
@ -1900,18 +1749,17 @@ NAME."
|
|||
;; Store and return the link
|
||||
(if (not (and interactive? link))
|
||||
(or agenda-link (and link (org-link-make-string link desc)))
|
||||
(org-link--add-to-stored-links link desc)
|
||||
;; In org buffers, store an additional "human-readable" link
|
||||
;; using custom id, if available.
|
||||
(when (and (buffer-file-name (buffer-base-buffer))
|
||||
(derived-mode-p 'org-mode)
|
||||
(org-entry-get nil "CUSTOM_ID"))
|
||||
(let ((here (org-link--file-link-to-here)))
|
||||
(setq link (car here))
|
||||
(setq desc (cdr here)))
|
||||
(unless (equal (list link desc) (car org-stored-links))
|
||||
(org-link--add-to-stored-links link desc)))
|
||||
(car org-stored-links)))))
|
||||
(if (member (list link desc) org-stored-links)
|
||||
(message "This link has already been stored")
|
||||
(push (list link desc) org-stored-links)
|
||||
(message "Stored: %s" (or desc link))
|
||||
(when custom-id
|
||||
(setq link (concat "file:"
|
||||
(abbreviate-file-name
|
||||
(buffer-file-name (buffer-base-buffer)))
|
||||
"::#" custom-id))
|
||||
(push (list link desc) org-stored-links)))
|
||||
(car org-stored-links)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun org-insert-link (&optional complete-file link-location description)
|
||||
|
@ -1972,7 +1820,7 @@ non-interactively, don't allow to edit the default description."
|
|||
(all-prefixes (append (mapcar #'car abbrevs)
|
||||
(mapcar #'car org-link-abbrev-alist)
|
||||
(org-link-types)))
|
||||
entry link-original)
|
||||
entry)
|
||||
(cond
|
||||
(link-location) ; specified by arg, just use it.
|
||||
((org-in-regexp org-link-bracket-re 1)
|
||||
|
@ -1994,34 +1842,18 @@ non-interactively, don't allow to edit the default description."
|
|||
(t
|
||||
;; Read link, with completion for stored links.
|
||||
(org-link--fontify-links-to-this-file)
|
||||
(switch-to-buffer-other-window "*Org Links*")
|
||||
(org-switch-to-buffer-other-window "*Org Links*")
|
||||
(with-current-buffer "*Org Links*"
|
||||
(read-only-mode 1)
|
||||
(let ((inhibit-read-only t)
|
||||
;; FIXME Duplicate: Also in 'ox.el'.
|
||||
(propertize-help-key
|
||||
(lambda (key)
|
||||
;; Add `face' *and* `font-lock-face' to "work
|
||||
;; reliably in any buffer", per a comment in
|
||||
;; `help--key-description-fontified'.
|
||||
(propertize key
|
||||
'font-lock-face 'help-key-binding
|
||||
'face 'help-key-binding))))
|
||||
(erase-buffer)
|
||||
(insert
|
||||
(apply #'format "Type %s to complete link type, then %s to complete destination.\n"
|
||||
(mapcar propertize-help-key
|
||||
(list "TAB" "RET"))))
|
||||
(when org-stored-links
|
||||
(insert (apply #'format "\nStored links accessible with %s/%s or %s/%s are:\n\n"
|
||||
(mapcar propertize-help-key
|
||||
(list "<up>" "<down>"
|
||||
"M-p" "M-n"
|
||||
"RET"))))
|
||||
(insert (mapconcat #'org-link--prettify
|
||||
(reverse org-stored-links)
|
||||
"\n"))))
|
||||
(goto-char (point-min)))
|
||||
(erase-buffer)
|
||||
(insert "Insert a link.
|
||||
Use TAB to complete link prefixes, then RET for type-specific completion support\n")
|
||||
(when org-stored-links
|
||||
(insert "\nStored links are available with <up>/<down> or M-p/n \
|
||||
\(most recent with RET):\n\n")
|
||||
(insert (mapconcat #'org-link--prettify
|
||||
(reverse org-stored-links)
|
||||
"\n")))
|
||||
(goto-char (point-min)))
|
||||
(when (get-buffer-window "*Org Links*" 'visible)
|
||||
(let ((cw (selected-window)))
|
||||
(select-window (get-buffer-window "*Org Links*" 'visible))
|
||||
|
@ -2036,13 +1868,14 @@ non-interactively, don't allow to edit the default description."
|
|||
org-link--insert-history)))
|
||||
(setq link
|
||||
(org-completing-read
|
||||
(org-format-prompt "Insert link" (caar org-stored-links))
|
||||
"Link: "
|
||||
(append
|
||||
(mapcar (lambda (x) (concat x ":")) all-prefixes)
|
||||
(mapcar #'car org-stored-links)
|
||||
;; Allow description completion. Avoid "nil" option
|
||||
;; in the case of `completing-read-default' when
|
||||
;; some links have no description.
|
||||
;; in the case of `completing-read-default' and
|
||||
;; an error in `ido-completing-read' when some links
|
||||
;; have no description.
|
||||
(delq nil (mapcar 'cadr org-stored-links)))
|
||||
nil nil nil
|
||||
'org-link--history
|
||||
|
@ -2057,16 +1890,17 @@ non-interactively, don't allow to edit the default description."
|
|||
(setq link (substring link 0 -1))))
|
||||
(setq link (with-current-buffer origbuf
|
||||
(org-link--try-special-completion link)))))
|
||||
(when-let ((window (get-buffer-window "*Org Links*" t)))
|
||||
(quit-window 'kill window))
|
||||
(set-window-configuration wcf)
|
||||
(when (get-buffer "*Org Links*")
|
||||
(kill-buffer "*Org Links*")))
|
||||
(kill-buffer "*Org Links*"))
|
||||
(setq entry (assoc link org-stored-links))
|
||||
(or entry (push link org-link--insert-history))
|
||||
(setq desc (or desc (nth 1 entry)))))
|
||||
|
||||
(setq link-original link)
|
||||
(when (funcall (if (equal complete-file '(64)) 'not 'identity)
|
||||
(not org-link-keep-stored-after-insertion))
|
||||
(setq org-stored-links (delq (assoc link org-stored-links)
|
||||
org-stored-links)))
|
||||
|
||||
(when (and (string-match org-link-plain-re link)
|
||||
(not (string-match org-ts-regexp link)))
|
||||
;; URL-like link, normalize the use of angular brackets.
|
||||
|
@ -2109,7 +1943,8 @@ non-interactively, don't allow to edit the default description."
|
|||
((eq org-link-file-path-type 'relative)
|
||||
(setq path (file-relative-name path)))
|
||||
((functionp org-link-file-path-type)
|
||||
(setq path (funcall org-link-file-path-type path)))
|
||||
(setq path (funcall org-link-file-path-type
|
||||
(expand-file-name path))))
|
||||
(t
|
||||
(save-match-data
|
||||
(if (string-match (concat "^" (regexp-quote
|
||||
|
@ -2160,10 +1995,6 @@ non-interactively, don't allow to edit the default description."
|
|||
(read-string "Description: " initial-input)
|
||||
initial-input)))
|
||||
|
||||
(when (funcall (if (equal complete-file '(64)) 'not 'identity)
|
||||
(not org-link-keep-stored-after-insertion))
|
||||
(setq org-stored-links (delq (assoc link-original org-stored-links)
|
||||
org-stored-links)))
|
||||
(unless (org-string-nw-p desc) (setq desc nil))
|
||||
(when remove (apply #'delete-region remove))
|
||||
(insert (org-link-make-string link desc))
|
||||
|
@ -2208,39 +2039,6 @@ This command can be called in any mode to insert a link in Org syntax."
|
|||
(org-load-modules-maybe)
|
||||
(org-run-like-in-org-mode 'org-insert-link))
|
||||
|
||||
(defun org--re-list-search-forward (regexp-list &optional bound noerror count)
|
||||
"Like `re-search-forward', but REGEXP-LIST is a list of regexps.
|
||||
BOUND, NOERROR, and COUNT are passed to `re-search-forward'."
|
||||
(let (result (min-found most-positive-fixnum)
|
||||
(pos-found nil)
|
||||
(min-found-data nil)
|
||||
(tail regexp-list))
|
||||
(while tail
|
||||
(setq result (save-excursion (re-search-forward (pop tail) bound t count)))
|
||||
(when (and result (< result min-found))
|
||||
(setq min-found result
|
||||
pos-found (match-end 0)
|
||||
min-found-data (match-data))))
|
||||
(if (= most-positive-fixnum min-found)
|
||||
(pcase noerror
|
||||
(`t nil)
|
||||
(_ (re-search-forward (car regexp-list) bound noerror count)))
|
||||
(set-match-data min-found-data)
|
||||
(goto-char pos-found))))
|
||||
|
||||
(defun org--re-list-looking-at (regexp-list &optional inhibit-modify)
|
||||
"Like `looking-at', but REGEXP-LIST is a list of regexps.
|
||||
INHIBIT-MODIFY is passed to `looking-at'."
|
||||
(catch :found
|
||||
(while regexp-list
|
||||
(when
|
||||
(if inhibit-modify
|
||||
(looking-at-p (pop regexp-list))
|
||||
;; FIXME: In Emacs <29, `looking-at' does not accept
|
||||
;; optional INHIBIT-MODIFY argument.
|
||||
(looking-at (pop regexp-list)))
|
||||
(throw :found t)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun org-update-radio-target-regexp ()
|
||||
"Find all radio targets in this file and update the regular expression.
|
||||
|
@ -2260,7 +2058,7 @@ Also refresh fontification if needed."
|
|||
;; Make sure point is really within the object.
|
||||
(backward-char)
|
||||
(let ((obj (org-element-context)))
|
||||
(when (org-element-type-p obj 'radio-target)
|
||||
(when (eq (org-element-type obj) 'radio-target)
|
||||
(cl-pushnew (org-element-property :value obj) rtn
|
||||
:test #'equal))))
|
||||
rtn))))
|
||||
|
@ -2278,30 +2076,6 @@ Also refresh fontification if needed."
|
|||
targets
|
||||
"\\|")
|
||||
after-re)))
|
||||
(setq org-target-link-regexps nil)
|
||||
(let (current-length sub-targets)
|
||||
(when (<= org-target-link-regexp-limit (length org-target-link-regexp))
|
||||
(while (or targets sub-targets)
|
||||
(when (and sub-targets
|
||||
(or (not targets)
|
||||
(>= (+ current-length (length (car targets)))
|
||||
org-target-link-regexp-limit)))
|
||||
(push (concat before-re
|
||||
(mapconcat
|
||||
(lambda (x)
|
||||
(replace-regexp-in-string
|
||||
" +" "\\s-+" (regexp-quote x) t t))
|
||||
(nreverse sub-targets)
|
||||
"\\|")
|
||||
after-re)
|
||||
org-target-link-regexps)
|
||||
(setq current-length nil
|
||||
sub-targets nil))
|
||||
(unless current-length
|
||||
(setq current-length (+ (length before-re) (length after-re))))
|
||||
(when targets (push (pop targets) sub-targets))
|
||||
(cl-incf current-length (length (car sub-targets))))
|
||||
(setq org-target-link-regexps (nreverse org-target-link-regexps))))
|
||||
(unless (equal old-regexp org-target-link-regexp)
|
||||
;; Clean-up cache.
|
||||
(let ((regexp (cond ((not old-regexp) org-target-link-regexp)
|
||||
|
@ -2317,11 +2091,9 @@ Also refresh fontification if needed."
|
|||
after-re)))))
|
||||
(when (and (featurep 'org-element)
|
||||
(not (bound-and-true-p org-mode-loading)))
|
||||
(if org-target-link-regexps
|
||||
(org-element-cache-reset)
|
||||
(org-with-point-at 1
|
||||
(while (re-search-forward regexp nil t)
|
||||
(org-element-cache-refresh (match-beginning 1)))))))
|
||||
(org-with-point-at 1
|
||||
(while (re-search-forward regexp nil t)
|
||||
(org-element-cache-refresh (match-beginning 1))))))
|
||||
;; Re fontify buffer.
|
||||
(when (memq 'radio org-highlight-links)
|
||||
(org-restart-font-lock)))))
|
||||
|
|
1967
lisp/org-agenda.el
1967
lisp/org-agenda.el
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
;;; org-archive.el --- Archiving for Org -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2004-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2004-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Carsten Dominik <carsten.dominik@gmail.com>
|
||||
;; Keywords: outlines, hypermedia, calendar, wp
|
||||
|
@ -34,9 +34,9 @@
|
|||
(require 'org)
|
||||
(require 'cl-lib)
|
||||
|
||||
(declare-function org-element-type "org-element" (element))
|
||||
(declare-function org-datetree-find-date-create "org-datetree" (date &optional keep-restriction))
|
||||
(declare-function org-inlinetask-remove-END-maybe "org-inlinetask" ())
|
||||
(declare-function org-timestamp-to-now "org" (timestamp-string &optional seconds))
|
||||
|
||||
;; From org-element.el
|
||||
(defvar org-element--cache-avoid-synchronous-headline-re-parsing)
|
||||
|
@ -154,10 +154,10 @@ archive location, but not yet deleted from the original file.")
|
|||
|
||||
;;;###autoload
|
||||
(defun org-add-archive-files (files)
|
||||
"Splice the archive FILES into the list of files.
|
||||
"Splice the archive files into the list of files.
|
||||
This implies visiting all these files and finding out what the
|
||||
archive file is."
|
||||
(seq-uniq
|
||||
(org-uniquify
|
||||
(apply
|
||||
'append
|
||||
(mapcar
|
||||
|
@ -166,9 +166,7 @@ archive file is."
|
|||
nil
|
||||
(with-current-buffer (org-get-agenda-file-buffer f)
|
||||
(cons f (org-all-archive-files)))))
|
||||
files))
|
||||
#'file-equal-p
|
||||
))
|
||||
files))))
|
||||
|
||||
(defun org-all-archive-files ()
|
||||
"List of all archive files used in the current buffer."
|
||||
|
@ -254,7 +252,8 @@ direct children of this heading."
|
|||
(newfile-p (and (org-string-nw-p afile)
|
||||
(not (file-exists-p afile))))
|
||||
(buffer (cond ((not (org-string-nw-p afile)) this-buffer)
|
||||
((find-file-noselect afile 'nowarn))
|
||||
((find-buffer-visiting afile))
|
||||
((find-file-noselect afile))
|
||||
(t (error "Cannot access file \"%s\"" afile))))
|
||||
(org-odd-levels-only
|
||||
(if (local-variable-p 'org-odd-levels-only (current-buffer))
|
||||
|
@ -478,9 +477,9 @@ Archiving time is retained in the ARCHIVE_TIME node property."
|
|||
(goto-char e)
|
||||
(or (bolp) (newline))
|
||||
(insert leader org-archive-sibling-heading "\n")
|
||||
(forward-line -1)
|
||||
(beginning-of-line 0)
|
||||
(org-toggle-tag org-archive-tag 'on))
|
||||
(forward-line 0)
|
||||
(beginning-of-line 1)
|
||||
(if org-archive-reversed-order
|
||||
(outline-next-heading)
|
||||
(org-end-of-subtree t t))
|
||||
|
@ -525,12 +524,12 @@ When TAG is non-nil, don't move trees, but mark them with the ARCHIVE tag."
|
|||
(let (ts)
|
||||
(and (re-search-forward org-ts-regexp end t)
|
||||
(setq ts (match-string 0))
|
||||
(< (org-timestamp-to-now ts) 0)
|
||||
(< (org-time-stamp-to-now ts) 0)
|
||||
(if (not (looking-at
|
||||
(concat "--\\(" org-ts-regexp "\\)")))
|
||||
(concat "--\\(" org-ts-regexp "\\)")))
|
||||
(concat "old timestamp " ts)
|
||||
(setq ts (concat "old timestamp " ts (match-string 0)))
|
||||
(and (< (org-timestamp-to-now (match-string 1)) 0)
|
||||
(and (< (org-time-stamp-to-now (match-string 1)) 0)
|
||||
ts)))))
|
||||
tag))
|
||||
|
||||
|
@ -591,9 +590,8 @@ don't move trees, but mark them with the ARCHIVE tag."
|
|||
;;;###autoload
|
||||
(defun org-toggle-archive-tag (&optional find-done)
|
||||
"Toggle the archive tag for the current headline.
|
||||
With prefix argument FIND-DONE, check all children of current headline
|
||||
and offer tagging the children that do not contain any open TODO
|
||||
items."
|
||||
With prefix ARG, check all children of current headline and offer tagging
|
||||
the children that do not contain any open TODO items."
|
||||
(interactive "P")
|
||||
(if (and (org-region-active-p) org-loop-over-headlines-in-active-region)
|
||||
(let ((cl (if (eq org-loop-over-headlines-in-active-region 'start-level)
|
||||
|
@ -610,7 +608,7 @@ items."
|
|||
(org-back-to-heading t)
|
||||
(setq set (org-toggle-tag org-archive-tag))
|
||||
(when set (org-fold-subtree t)))
|
||||
(and set (forward-line 0))
|
||||
(and set (beginning-of-line 1))
|
||||
(message "Subtree %s" (if set "archived" "unarchived"))))))
|
||||
|
||||
(defun org-archive-set-tag ()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; org-attach-git.el --- Automatic git commit extension to org-attach -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2019-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2019-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Original Author: John Wiegley <johnw@newartisans.com>
|
||||
;; Restructurer: Gustav Wikström <gustav@whil.se>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; org-attach.el --- Manage file attachments to Org outlines -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2008-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2008-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: John Wiegley <johnw@newartisans.com>
|
||||
;; Keywords: org data attachment
|
||||
|
@ -44,12 +44,8 @@
|
|||
|
||||
(declare-function dired-dwim-target-directory "dired-aux")
|
||||
(declare-function dired-get-marked-files "dired" (&optional localp arg filter distinguish-one-marked error))
|
||||
(declare-function org-element-property "org-element-ast" (property node))
|
||||
(declare-function org-element-begin "org-element" (node))
|
||||
(declare-function org-element-end "org-element" (node))
|
||||
(declare-function org-element-contents-begin "org-element" (node))
|
||||
(declare-function org-element-contents-end "org-element" (node))
|
||||
(declare-function org-element-type-p "org-element-ast" (node types))
|
||||
(declare-function org-element-property "org-element" (property element))
|
||||
(declare-function org-element-type "org-element" (element))
|
||||
(declare-function org-inlinetask-goto-beginning "org-inlinetask" ())
|
||||
(declare-function org-inlinetask-in-task-p "org-inlinetask" ())
|
||||
|
||||
|
@ -142,7 +138,7 @@ Selective means to respect the inheritance setting in
|
|||
(const :tag "Inherit parent node attachments" t)
|
||||
(const :tag "Respect org-use-property-inheritance" selective)))
|
||||
|
||||
(defcustom org-attach-store-link-p 'attached
|
||||
(defcustom org-attach-store-link-p nil
|
||||
"Non-nil means store a link to a file when attaching it.
|
||||
When t, store the link to original file location.
|
||||
When `file', store link to the attached file location.
|
||||
|
@ -301,71 +297,68 @@ ask the user instead, else remove without asking."
|
|||
"The dispatcher for attachment commands.
|
||||
Shows a list of commands and prompts for another key to execute a command."
|
||||
(interactive)
|
||||
(let (c marker)
|
||||
(let ((dir (org-attach-dir nil 'no-fs-check))
|
||||
c marker)
|
||||
(when (eq major-mode 'org-agenda-mode)
|
||||
(setq marker (or (get-text-property (point) 'org-hd-marker)
|
||||
(get-text-property (point) 'org-marker)))
|
||||
(unless marker
|
||||
(error "No item in current line")))
|
||||
(org-with-point-at marker
|
||||
(let ((dir (org-attach-dir nil 'no-fs-check)))
|
||||
(if (and (featurep 'org-inlinetask)
|
||||
(not (org-inlinetask-in-task-p)))
|
||||
(org-with-limited-levels
|
||||
(org-back-to-heading-or-point-min t))
|
||||
(if (and (featurep 'org-inlinetask)
|
||||
(not (org-inlinetask-in-task-p)))
|
||||
(org-with-limited-levels
|
||||
(org-back-to-heading-or-point-min t))
|
||||
(if (and (featurep 'org-inlinetask)
|
||||
(org-inlinetask-in-task-p))
|
||||
(org-inlinetask-goto-beginning)
|
||||
(org-back-to-heading-or-point-min t)))
|
||||
(save-excursion
|
||||
(save-window-excursion
|
||||
(unless org-attach-expert
|
||||
(switch-to-buffer-other-window "*Org Attach*")
|
||||
(erase-buffer)
|
||||
(setq cursor-type nil
|
||||
header-line-format "Use C-v, M-v, C-n or C-p to navigate.")
|
||||
(insert
|
||||
(concat "Attachment folder:\n"
|
||||
(or dir
|
||||
"Can't find an existing attachment-folder")
|
||||
(unless (and dir (file-directory-p dir))
|
||||
"\n(Not yet created)")
|
||||
"\n\n"
|
||||
(format "Select an Attachment Command:\n\n%s"
|
||||
(mapconcat
|
||||
(lambda (entry)
|
||||
(pcase entry
|
||||
(`((,key . ,_) ,_ ,docstring)
|
||||
(format "%c %s"
|
||||
key
|
||||
(replace-regexp-in-string "\n\\([\t ]*\\)"
|
||||
" "
|
||||
docstring
|
||||
nil nil 1)))
|
||||
(_
|
||||
(user-error
|
||||
"Invalid `org-attach-commands' item: %S"
|
||||
entry))))
|
||||
org-attach-commands
|
||||
"\n"))))
|
||||
(goto-char (point-min)))
|
||||
(org-fit-window-to-buffer (get-buffer-window "*Org Attach*"))
|
||||
(unwind-protect
|
||||
(let ((msg (format "Select command: [%s]"
|
||||
(concat (mapcar #'caar org-attach-commands)))))
|
||||
(message msg)
|
||||
(while (and (setq c (read-char-exclusive))
|
||||
(memq c '(?\C-n ?\C-p ?\C-v ?\M-v)))
|
||||
(org-scroll c t)))
|
||||
(when-let ((window (get-buffer-window "*Org Attach*" t)))
|
||||
(quit-window 'kill window))
|
||||
(and (get-buffer "*Org Attach*") (kill-buffer "*Org Attach*")))))
|
||||
(let ((command (cl-some (lambda (entry)
|
||||
(and (memq c (nth 0 entry)) (nth 1 entry)))
|
||||
org-attach-commands)))
|
||||
(if (commandp command)
|
||||
(command-execute command)
|
||||
(error "No such attachment command: %c" c)))))))
|
||||
(org-inlinetask-in-task-p))
|
||||
(org-inlinetask-goto-beginning)
|
||||
(org-back-to-heading-or-point-min t)))
|
||||
(save-excursion
|
||||
(save-window-excursion
|
||||
(unless org-attach-expert
|
||||
(org-switch-to-buffer-other-window "*Org Attach*")
|
||||
(erase-buffer)
|
||||
(setq cursor-type nil
|
||||
header-line-format "Use C-v, M-v, C-n or C-p to navigate.")
|
||||
(insert
|
||||
(concat "Attachment folder:\n"
|
||||
(or dir
|
||||
"Can't find an existing attachment-folder")
|
||||
(unless (and dir (file-directory-p dir))
|
||||
"\n(Not yet created)")
|
||||
"\n\n"
|
||||
(format "Select an Attachment Command:\n\n%s"
|
||||
(mapconcat
|
||||
(lambda (entry)
|
||||
(pcase entry
|
||||
(`((,key . ,_) ,_ ,docstring)
|
||||
(format "%c %s"
|
||||
key
|
||||
(replace-regexp-in-string "\n\\([\t ]*\\)"
|
||||
" "
|
||||
docstring
|
||||
nil nil 1)))
|
||||
(_
|
||||
(user-error
|
||||
"Invalid `org-attach-commands' item: %S"
|
||||
entry))))
|
||||
org-attach-commands
|
||||
"\n"))))
|
||||
(goto-char (point-min)))
|
||||
(org-fit-window-to-buffer (get-buffer-window "*Org Attach*"))
|
||||
(let ((msg (format "Select command: [%s]"
|
||||
(concat (mapcar #'caar org-attach-commands)))))
|
||||
(message msg)
|
||||
(while (and (setq c (read-char-exclusive))
|
||||
(memq c '(?\C-n ?\C-p ?\C-v ?\M-v)))
|
||||
(org-scroll c t)))
|
||||
(and (get-buffer "*Org Attach*") (kill-buffer "*Org Attach*"))))
|
||||
(let ((command (cl-some (lambda (entry)
|
||||
(and (memq c (nth 0 entry)) (nth 1 entry)))
|
||||
org-attach-commands)))
|
||||
(if (commandp command)
|
||||
(command-execute command)
|
||||
(error "No such attachment command: %c" c))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun org-attach-dir (&optional create-if-not-exists-p no-fs-check)
|
||||
|
@ -440,26 +433,17 @@ ignoring nils. If EXISTING is non-nil, then return the first path
|
|||
found in the filesystem. Otherwise return the first non-nil value."
|
||||
(let ((fun-list org-attach-id-to-path-function-list)
|
||||
(base-dir (expand-file-name org-attach-id-dir))
|
||||
(default-base-dir (expand-file-name "data/"))
|
||||
preferred first)
|
||||
(while (and fun-list
|
||||
(not preferred))
|
||||
(let* ((name (funcall (car fun-list) id))
|
||||
(candidate (and name (expand-file-name name base-dir)))
|
||||
;; Try the default value `org-attach-id-dir' as a fallback.
|
||||
(candidate2 (and name (not (equal base-dir default-base-dir))
|
||||
(expand-file-name name default-base-dir))))
|
||||
(candidate (and name (expand-file-name name base-dir))))
|
||||
(setq fun-list (cdr fun-list))
|
||||
(when candidate
|
||||
(if (or (not existing) (file-directory-p candidate))
|
||||
(setq preferred candidate)
|
||||
(unless first
|
||||
(setq first candidate)))
|
||||
(when (and existing
|
||||
candidate2
|
||||
(not (file-directory-p candidate))
|
||||
(file-directory-p candidate2))
|
||||
(setq preferred candidate2)))))
|
||||
(setq first candidate))))))
|
||||
(or preferred first)))
|
||||
|
||||
(defun org-attach-check-absolute-path (dir)
|
||||
|
@ -529,13 +513,9 @@ DIR-property exists (that is different from the unset one)."
|
|||
(defun org-attach-tag (&optional off)
|
||||
"Turn the autotag on or (if OFF is set) off."
|
||||
(when org-attach-auto-tag
|
||||
;; FIXME: There is currently no way to set #+FILETAGS
|
||||
;; programatically. Do nothing when before first heading
|
||||
;; (attaching to file) to avoid blocking error.
|
||||
(unless (org-before-first-heading-p)
|
||||
(save-excursion
|
||||
(org-back-to-heading t)
|
||||
(org-toggle-tag org-attach-auto-tag (if off 'off 'on))))))
|
||||
(save-excursion
|
||||
(org-back-to-heading t)
|
||||
(org-toggle-tag org-attach-auto-tag (if off 'off 'on)))))
|
||||
|
||||
(defun org-attach-untag ()
|
||||
"Turn the autotag off."
|
||||
|
@ -594,7 +574,7 @@ METHOD may be `cp', `mv', `ln', `lns' or `url' default taken from
|
|||
((eq method 'url)
|
||||
(if (org--should-fetch-remote-resource-p file)
|
||||
(url-copy-file file attach-file)
|
||||
(error "The remote resource %S is considered unsafe, and will not be downloaded"
|
||||
(error "The remote resource %S is considered unsafe, and will not be downloaded."
|
||||
file))))
|
||||
(run-hook-with-args 'org-attach-after-change-hook attach-dir)
|
||||
(org-attach-tag)
|
||||
|
@ -757,20 +737,20 @@ It is meant to be added to `org-export-before-parsing-hook'."
|
|||
(save-excursion
|
||||
(while (re-search-forward "attachment:" nil t)
|
||||
(let ((link (org-element-context)))
|
||||
(when (and (org-element-type-p link 'link)
|
||||
(when (and (eq 'link (org-element-type link))
|
||||
(string-equal "attachment"
|
||||
(org-element-property :type link)))
|
||||
(let* ((description (and (org-element-contents-begin link)
|
||||
(let* ((description (and (org-element-property :contents-begin link)
|
||||
(buffer-substring-no-properties
|
||||
(org-element-contents-begin link)
|
||||
(org-element-contents-end link))))
|
||||
(org-element-property :contents-begin link)
|
||||
(org-element-property :contents-end link))))
|
||||
(file (org-element-property :path link))
|
||||
(new-link (org-link-make-string
|
||||
(concat "file:" (org-attach-expand file))
|
||||
description)))
|
||||
(goto-char (org-element-end link))
|
||||
(goto-char (org-element-property :end link))
|
||||
(skip-chars-backward " \t")
|
||||
(delete-region (org-element-begin link) (point))
|
||||
(delete-region (org-element-property :begin link) (point))
|
||||
(insert new-link)))))))
|
||||
|
||||
(defun org-attach-follow (file arg)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; org-capture.el --- Fast note taking in Org -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2010-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2010-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Carsten Dominik <carsten.dominik@gmail.com>
|
||||
;; Keywords: outlines, hypermedia, calendar, wp
|
||||
|
@ -58,13 +58,11 @@
|
|||
(declare-function org-at-table-p "org-table" (&optional table-type))
|
||||
(declare-function org-clock-update-mode-line "org-clock" (&optional refresh))
|
||||
(declare-function org-datetree-find-date-create "org-datetree" (date &optional keep-restriction))
|
||||
(declare-function org-datetree-find-month-create "org-datetree" (d &optional keep-restriction))
|
||||
(declare-function org-datetree-find-month-create (d &optional keep-restriction))
|
||||
(declare-function org-decrypt-entry "org-crypt" ())
|
||||
(declare-function org-element-at-point "org-element" (&optional pom cached-only))
|
||||
(declare-function org-element-lineage "org-element-ast" (datum &optional types with-self))
|
||||
(declare-function org-element-property "org-element-ast" (property node))
|
||||
(declare-function org-element-contents-end "org-element" (node))
|
||||
(declare-function org-element-post-affiliated "org-element" (node))
|
||||
(declare-function org-element-lineage "org-element" (datum &optional types with-self))
|
||||
(declare-function org-element-property "org-element" (property element))
|
||||
(declare-function org-encrypt-entry "org-crypt" ())
|
||||
(declare-function org-insert-link "ol" (&optional complete-file link-location default-description))
|
||||
(declare-function org-link-make-string "ol" (link &optional description))
|
||||
|
@ -222,9 +220,6 @@ target Specification of where the captured item should be placed.
|
|||
(clock)
|
||||
File to the entry that is currently being clocked
|
||||
|
||||
(here)
|
||||
The position of point
|
||||
|
||||
(function function-finding-location)
|
||||
Most general way: write your own function which both visits
|
||||
the file and moves point to the right location
|
||||
|
@ -371,10 +366,6 @@ be replaced with content and expanded:
|
|||
%^{prompt} Prompt the user for a string and replace this sequence with it.
|
||||
A default value and a completion table can be specified like this:
|
||||
%^{prompt|default|completion2|completion3|...}.
|
||||
%^{prompt}X where X is one of g, G, t, T, u, U, C, or L.
|
||||
Same as %^X (see above), but also supply custom
|
||||
prompt/completions. Default value and completions as in
|
||||
%^{prompt|default|...}X are allowed.
|
||||
%? After completing the template, position cursor here.
|
||||
%\\1 ... %\\N Insert the text entered at the nth %^{prompt}, where N
|
||||
is a number, starting from 1.
|
||||
|
@ -505,6 +496,12 @@ The capture buffer is current and still narrowed."
|
|||
:version "24.1"
|
||||
:type 'hook)
|
||||
|
||||
(defcustom org-capture-bookmark t
|
||||
"When non-nil, add bookmark pointing at the last stored position when capturing."
|
||||
:group 'org-capture
|
||||
:version "24.3"
|
||||
:type 'boolean)
|
||||
|
||||
;;; The property list for keeping information about the capture process
|
||||
|
||||
(defvar org-capture-plist nil
|
||||
|
@ -582,9 +579,7 @@ this template to be accessible only from `message-mode' buffers,
|
|||
use this:
|
||||
|
||||
(setq org-capture-templates-contexts
|
||||
\\='((\"c\" ((in-mode . \"message-mode\")))
|
||||
(\"d\" (my-context-function
|
||||
(in-mode . \"org-mode\")))))
|
||||
\\='((\"c\" ((in-mode . \"message-mode\")))))
|
||||
|
||||
Here are the available contexts definitions:
|
||||
|
||||
|
@ -996,15 +991,14 @@ Store them in the capture property list."
|
|||
(let ((target-entry-p t))
|
||||
(save-excursion
|
||||
(pcase (or target (org-capture-get :target))
|
||||
((or `here
|
||||
`(here))
|
||||
(`here
|
||||
(org-capture-put :exact-position (point) :insert-here t))
|
||||
(`(file ,path)
|
||||
(set-buffer (org-capture-target-buffer path))
|
||||
(org-capture-put-target-region-and-position)
|
||||
(widen)
|
||||
(setq target-entry-p nil))
|
||||
(`(id ,(and id (or (pred stringp) (pred symbolp))))
|
||||
(`(id ,id)
|
||||
(pcase (org-id-find id)
|
||||
(`(,path . ,position)
|
||||
(set-buffer (org-capture-target-buffer path))
|
||||
|
@ -1012,7 +1006,7 @@ Store them in the capture property list."
|
|||
(org-capture-put-target-region-and-position)
|
||||
(goto-char position))
|
||||
(_ (error "Cannot find target ID \"%s\"" id))))
|
||||
(`(file+headline ,path ,(and headline (pred stringp)))
|
||||
(`(file+headline ,path ,headline)
|
||||
(set-buffer (org-capture-target-buffer path))
|
||||
;; Org expects the target file to be in Org mode, otherwise
|
||||
;; it throws an error. However, the default notes files
|
||||
|
@ -1029,12 +1023,12 @@ Store them in the capture property list."
|
|||
(if (re-search-forward (format org-complex-heading-regexp-format
|
||||
(regexp-quote headline))
|
||||
nil t)
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(goto-char (point-max))
|
||||
(unless (bolp) (insert "\n"))
|
||||
(insert "* " headline "\n")
|
||||
(forward-line -1)))
|
||||
(`(file+olp ,path . ,(and outline-path (guard outline-path)))
|
||||
(beginning-of-line 0)))
|
||||
(`(file+olp ,path . ,outline-path)
|
||||
(let ((m (org-find-olp (cons (org-capture-expand-file path)
|
||||
outline-path))))
|
||||
(set-buffer (marker-buffer m))
|
||||
|
@ -1042,7 +1036,7 @@ Store them in the capture property list."
|
|||
(widen)
|
||||
(goto-char m)
|
||||
(set-marker m nil)))
|
||||
(`(file+regexp ,path ,(and regexp (pred stringp)))
|
||||
(`(file+regexp ,path ,regexp)
|
||||
(set-buffer (org-capture-target-buffer path))
|
||||
(org-capture-put-target-region-and-position)
|
||||
(widen)
|
||||
|
@ -1110,7 +1104,7 @@ Store them in the capture property list."
|
|||
;; the following is the keep-restriction argument for
|
||||
;; org-datetree-find-date-create
|
||||
(when outline-path 'subtree-at-point))))
|
||||
(`(file+function ,path ,(and function (pred functionp)))
|
||||
(`(file+function ,path ,function)
|
||||
(set-buffer (org-capture-target-buffer path))
|
||||
(org-capture-put-target-region-and-position)
|
||||
(widen)
|
||||
|
@ -1118,7 +1112,7 @@ Store them in the capture property list."
|
|||
(org-capture-put :exact-position (point))
|
||||
(setq target-entry-p
|
||||
(and (derived-mode-p 'org-mode) (org-at-heading-p))))
|
||||
(`(function ,(and fun (pred functionp)))
|
||||
(`(function ,fun)
|
||||
(funcall fun)
|
||||
(org-capture-put :exact-position (point))
|
||||
(setq target-entry-p
|
||||
|
@ -1174,9 +1168,9 @@ When INHIBIT-WCONF-STORE is non-nil, don't store the window configuration, as it
|
|||
may have been stored before."
|
||||
(unless inhibit-wconf-store
|
||||
(org-capture-put :return-to-wconf (current-window-configuration)))
|
||||
(pop-to-buffer
|
||||
(org-capture-get-indirect-buffer (org-capture-get :buffer) "CAPTURE")
|
||||
'(org-display-buffer-split))
|
||||
(delete-other-windows)
|
||||
(org-switch-to-buffer-other-window
|
||||
(org-capture-get-indirect-buffer (org-capture-get :buffer) "CAPTURE"))
|
||||
(widen)
|
||||
(org-fold-show-all)
|
||||
(goto-char (org-capture-get :pos))
|
||||
|
@ -1274,7 +1268,7 @@ may have been stored before."
|
|||
(catch :found
|
||||
(while (re-search-forward item-regexp end t)
|
||||
(when (setq item (org-element-lineage
|
||||
(org-element-at-point) 'plain-list t))
|
||||
(org-element-at-point) '(plain-list) t))
|
||||
(goto-char (org-element-property (if prepend? :post-affiliated
|
||||
:contents-end)
|
||||
item))
|
||||
|
@ -1316,7 +1310,7 @@ may have been stored before."
|
|||
(point-marker))))
|
||||
(when item
|
||||
(let ((i (save-excursion
|
||||
(goto-char (org-element-post-affiliated item))
|
||||
(goto-char (org-element-property :post-affiliated item))
|
||||
(org-current-text-indentation))))
|
||||
(save-excursion
|
||||
(goto-char beg)
|
||||
|
@ -1324,7 +1318,7 @@ may have been stored before."
|
|||
(while (< (point) end)
|
||||
(indent-to i)
|
||||
(forward-line)))
|
||||
;; Prepending an item could change the type of the list
|
||||
;; Pre-pending an item could change the type of the list
|
||||
;; if there is a mismatch. In this situation,
|
||||
;; prioritize the existing list.
|
||||
(when prepend?
|
||||
|
@ -1379,13 +1373,13 @@ may have been stored before."
|
|||
;; Narrow to the table, possibly creating one if necessary.
|
||||
(catch :found
|
||||
(while (re-search-forward org-table-dataline-regexp end t)
|
||||
(pcase (org-element-lineage (org-element-at-point) 'table t)
|
||||
(pcase (org-element-lineage (org-element-at-point) '(table) t)
|
||||
(`nil nil)
|
||||
((pred (lambda (e) (eq 'table.el (org-element-property :type e))))
|
||||
nil)
|
||||
(table
|
||||
(goto-char (org-element-contents-end table))
|
||||
(narrow-to-region (org-element-post-affiliated table)
|
||||
(goto-char (org-element-property :contents-end table))
|
||||
(narrow-to-region (org-element-property :post-affiliated table)
|
||||
(point))
|
||||
(throw :found t))))
|
||||
;; No table found. Create it with an empty header.
|
||||
|
@ -1415,7 +1409,7 @@ may have been stored before."
|
|||
(goto-char (point-min))
|
||||
(cond
|
||||
((not (re-search-forward org-table-hline-regexp nil t)))
|
||||
((re-search-forward org-table-dataline-regexp nil t) (forward-line 0))
|
||||
((re-search-forward org-table-dataline-regexp nil t) (beginning-of-line))
|
||||
(t (goto-char (org-table-end)))))
|
||||
(t
|
||||
(goto-char (org-table-end))))
|
||||
|
@ -1504,15 +1498,10 @@ Of course, if exact position has been required, just put it there."
|
|||
(point))))))
|
||||
(with-current-buffer (buffer-base-buffer (current-buffer))
|
||||
(org-with-point-at pos
|
||||
;; FIXME: `org-capture-bookmark' is obsolete. To be removed
|
||||
;; in future Org releases.
|
||||
(when (with-no-warnings org-capture-bookmark)
|
||||
(when org-capture-bookmark
|
||||
(let ((bookmark (plist-get org-bookmark-names-plist :last-capture)))
|
||||
(when bookmark
|
||||
(condition-case err
|
||||
(bookmark-set bookmark)
|
||||
(error
|
||||
(message "Bookmark set error: %S" err))))))
|
||||
(when bookmark (with-demoted-errors "Bookmark set error: %S"
|
||||
(bookmark-set bookmark)))))
|
||||
(move-marker org-capture-last-stored-marker (point))))))
|
||||
|
||||
(defun org-capture-narrow (beg end)
|
||||
|
@ -1675,8 +1664,11 @@ Expansion occurs in a temporary Org mode buffer."
|
|||
(org-no-properties org-clock-heading)
|
||||
""))
|
||||
(v-K (if (marker-buffer org-clock-marker)
|
||||
(org-with-point-at org-clock-marker
|
||||
(org-store-link nil nil))
|
||||
(org-link-make-string
|
||||
(format "%s::*%s"
|
||||
(buffer-file-name (marker-buffer org-clock-marker))
|
||||
v-k)
|
||||
v-k)
|
||||
""))
|
||||
(v-f (or (org-capture-get :original-file-nondirectory) ""))
|
||||
(v-F (or (org-capture-get :original-file) ""))
|
||||
|
@ -1694,7 +1686,7 @@ Expansion occurs in a temporary Org mode buffer."
|
|||
(message "no template") (ding)
|
||||
(sit-for 1))
|
||||
(save-window-excursion
|
||||
(switch-to-buffer-other-window (get-buffer-create "*Capture*"))
|
||||
(org-switch-to-buffer-other-window (get-buffer-create "*Capture*"))
|
||||
(erase-buffer)
|
||||
(setq buffer-file-name nil)
|
||||
(setq mark-active nil)
|
||||
|
@ -1866,7 +1858,7 @@ Expansion occurs in a temporary Org mode buffer."
|
|||
(let* ((upcase? (equal (upcase key) key))
|
||||
(org-end-time-was-given nil)
|
||||
(time (org-read-date upcase? t nil prompt)))
|
||||
(org-insert-timestamp
|
||||
(org-insert-time-stamp
|
||||
time (or org-time-was-given upcase?)
|
||||
(member key '("u" "U"))
|
||||
nil nil (list org-end-time-was-given))))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; org-clock.el --- The time clocking code for Org mode -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2004-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2004-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Carsten Dominik <carsten.dominik@gmail.com>
|
||||
;; Keywords: outlines, hypermedia, calendar, wp
|
||||
|
@ -36,11 +36,9 @@
|
|||
|
||||
(declare-function calendar-iso-to-absolute "cal-iso" (date))
|
||||
(declare-function notifications-notify "notifications" (&rest params))
|
||||
(declare-function org-element-property "org-element-ast" (property node))
|
||||
(declare-function org-element-contents-end "org-element" (node))
|
||||
(declare-function org-element-end "org-element" (node))
|
||||
(declare-function org-element-type "org-element-ast" (node &optional anonymous))
|
||||
(declare-function org-element-type-p "org-element-ast" (node types))
|
||||
(declare-function org-element-property "org-element" (property element))
|
||||
(declare-function org-element-type "org-element" (element))
|
||||
(declare-function org-element--cache-active-p "org-element" ())
|
||||
(defvar org-element-use-cache)
|
||||
(declare-function org-inlinetask-at-task-p "org-inlinetask" ())
|
||||
(declare-function org-inlinetask-goto-beginning "org-inlinetask" ())
|
||||
|
@ -130,7 +128,7 @@ clocking out."
|
|||
"Rounding minutes when clocking in or out.
|
||||
The default value is 0 so that no rounding is done.
|
||||
When set to a non-integer value, use the car of
|
||||
`org-timestamp-rounding-minutes', like for setting a timestamp.
|
||||
`org-time-stamp-rounding-minutes', like for setting a time-stamp.
|
||||
|
||||
E.g. if `org-clock-rounding-minutes' is set to 5, time is 14:47
|
||||
and you clock in: then the clock starts at 14:45. If you clock
|
||||
|
@ -350,15 +348,14 @@ For more information, see `org-clocktable-write-default'."
|
|||
:type 'function)
|
||||
|
||||
(defcustom org-clock-clocktable-language-setup
|
||||
'(("en" "File" "L" "Timestamp" "Headline" "Time" "ALL" "Total time" "File time" "Clock summary at")
|
||||
("de" "Datei" "E" "Zeitstempel" "Kopfzeile" "Dauer" "GESAMT" "Gesamtdauer" "Dateizeit" "Erstellt am")
|
||||
("es" "Archivo" "N" "Fecha y hora" "Tarea" "Duración" "TODO" "Duración total" "Tiempo archivo" "Generado el")
|
||||
("fr" "Fichier" "N" "Horodatage" "En-tête" "Durée" "TOUT" "Durée totale" "Durée fichier" "Horodatage sommaire à")
|
||||
("nl" "Bestand" "N" "Tijdstip" "Rubriek" "Duur" "ALLES" "Totale duur" "Bestandstijd" "Klok overzicht op")
|
||||
("nn" "Fil" "N" "Tidspunkt" "Overskrift" "Tid" "ALLE" "Total tid" "Filtid" "Tidsoversyn")
|
||||
("pl" "Plik" "P" "Data i godzina" "Nagłówek" "Czas" "WSZYSTKO" "Czas całkowity" "Czas pliku" "Poddumowanie zegara na")
|
||||
'(("en" "File" "L" "Timestamp" "Headline" "Time" "ALL" "Total time" "File time" "Clock summary at")
|
||||
("es" "Archivo" "N" "Fecha y hora" "Tarea" "Duración" "TODO" "Duración total" "Tiempo archivo" "Generado el")
|
||||
("fr" "Fichier" "N" "Horodatage" "En-tête" "Durée" "TOUT" "Durée totale" "Durée fichier" "Horodatage sommaire à")
|
||||
("nl" "Bestand" "N" "Tijdstip" "Rubriek" "Duur" "ALLES" "Totale duur" "Bestandstijd" "Klok overzicht op")
|
||||
("nn" "Fil" "N" "Tidspunkt" "Overskrift" "Tid" "ALLE" "Total tid" "Filtid" "Tidsoversyn")
|
||||
("de" "Datei" "E" "Zeitstempel" "Kopfzeile" "Dauer" "GESAMT" "Gesamtdauer" "Dateizeit" "Erstellt am")
|
||||
("pt-BR" "Arquivo" "N" "Data e hora" "Título" "Hora" "TODOS" "Hora total" "Hora do arquivo" "Resumo das horas em")
|
||||
("sk" "Súbor" "L" "Časová značka" "Záhlavie" "Čas" "VŠETKO" "Celkový čas" "Čas súboru" "Časový súhrn pre"))
|
||||
("sk" "Súbor" "L" "Časová značka" "Záhlavie" "Čas" "VŠETKO" "Celkový čas" "Čas súboru" "Časový súhrn pre"))
|
||||
"Terms used in clocktable, translated to different languages."
|
||||
:group 'org-clocktable
|
||||
:version "24.1"
|
||||
|
@ -418,8 +415,8 @@ play with them."
|
|||
:type 'string)
|
||||
|
||||
(defcustom org-clock-clocked-in-display 'mode-line
|
||||
"Where to display clocked in task and accumulated time when clocked in.
|
||||
|
||||
"When clocked in for a task, Org can display the current
|
||||
task and accumulated time in the mode line and/or frame title.
|
||||
Allowed values are:
|
||||
|
||||
both displays in both mode line and frame title
|
||||
|
@ -514,11 +511,7 @@ to add an effort property.")
|
|||
(defvar org-clock-in-hook nil
|
||||
"Hook run when starting the clock.")
|
||||
(defvar org-clock-out-hook nil
|
||||
"Hook run when stopping the current clock.
|
||||
The point is at the current clock line when the hook is executed.
|
||||
|
||||
The hook functions can access `org-clock-out-removed-last-clock' to
|
||||
check whether the latest CLOCK line has been cleared.")
|
||||
"Hook run when stopping the current clock.")
|
||||
|
||||
(defvar org-clock-cancel-hook nil
|
||||
"Hook run when canceling the current clock.")
|
||||
|
@ -572,10 +565,6 @@ of a different task.")
|
|||
Assume S in the English term to translate. Return S as-is if it
|
||||
cannot be translated."
|
||||
(or (nth (pcase s
|
||||
;; "L" stands for "Level"
|
||||
;; "ALL" stands for a line summarizing clock data across
|
||||
;; all the files, when the clocktable includes multiple
|
||||
;; files.
|
||||
("File" 1) ("L" 2) ("Timestamp" 3) ("Headline" 4) ("Time" 5)
|
||||
("ALL" 6) ("Total time" 7) ("File time" 8) ("Clock summary at" 9))
|
||||
(assoc-string language org-clock-clocktable-language-setup t))
|
||||
|
@ -590,7 +579,6 @@ cannot be translated."
|
|||
(org-no-properties (org-get-heading t t t t))))))
|
||||
|
||||
(defun org-clock-menu ()
|
||||
"Pop up org-clock menu."
|
||||
(interactive)
|
||||
(popup-menu
|
||||
'("Clock"
|
||||
|
@ -600,12 +588,7 @@ cannot be translated."
|
|||
["Switch task" (lambda () (interactive) (org-clock-in '(4))) :active t :keys "C-u C-c C-x C-i"])))
|
||||
|
||||
(defun org-clock-history-push (&optional pos buffer)
|
||||
"Push point marker to the clock history.
|
||||
When POS is provided, use it as marker point.
|
||||
When BUFFER and POS are provided, use marker at POS in base buffer of
|
||||
BUFFER."
|
||||
;; When buffer is provided, POS must be provided.
|
||||
(cl-assert (or (not buffer) pos))
|
||||
"Push a marker to the clock history."
|
||||
(setq org-clock-history-length (max 1 org-clock-history-length))
|
||||
(let ((m (move-marker (make-marker)
|
||||
(or pos (point)) (org-base-buffer
|
||||
|
@ -625,10 +608,7 @@ BUFFER."
|
|||
(push m org-clock-history)))
|
||||
|
||||
(defun org-clock-save-markers-for-cut-and-paste (beg end)
|
||||
"Save relative positions of markers in region BEG..END.
|
||||
Save `org-clock-marker', `org-clock-hd-marker',
|
||||
`org-clock-default-task', `org-clock-interrupted-task', and the
|
||||
markers in `org-clock-history'."
|
||||
"Save relative positions of markers in region."
|
||||
(org-check-and-save-marker org-clock-marker beg end)
|
||||
(org-check-and-save-marker org-clock-hd-marker beg end)
|
||||
(org-check-and-save-marker org-clock-default-task beg end)
|
||||
|
@ -654,7 +634,6 @@ markers in `org-clock-history'."
|
|||
|
||||
(defun org-clock-select-task (&optional prompt)
|
||||
"Select a task that was recently associated with clocking.
|
||||
PROMPT is the prompt text to be used, as a string.
|
||||
Return marker position of the selected task. Raise an error if
|
||||
there is no recent clock to choose from."
|
||||
(let (och chl sel-list rpl (i 0) s)
|
||||
|
@ -665,7 +644,7 @@ there is no recent clock to choose from."
|
|||
(if (zerop chl)
|
||||
(user-error "No recent clock")
|
||||
(save-window-excursion
|
||||
(switch-to-buffer-other-window
|
||||
(org-switch-to-buffer-other-window
|
||||
(get-buffer-create "*Clock Task Select*"))
|
||||
(erase-buffer)
|
||||
(when (marker-buffer org-clock-default-task)
|
||||
|
@ -695,11 +674,8 @@ there is no recent clock to choose from."
|
|||
;; `fit-window-to-buffer'
|
||||
(fit-window-to-buffer nil nil (if (< chl 10) chl (+ 5 chl)))
|
||||
(message (or prompt "Select task for clocking:"))
|
||||
(unwind-protect (setq cursor-type nil rpl (read-char-exclusive))
|
||||
(when-let ((window (get-buffer-window "*Clock Task Select*" t)))
|
||||
(quit-window 'kill window))
|
||||
(when (get-buffer "*Clock Task Select*")
|
||||
(kill-buffer "*Clock Task Select*")))
|
||||
(setq cursor-type nil rpl (read-char-exclusive))
|
||||
(kill-buffer)
|
||||
(cond
|
||||
((eq rpl ?q) nil)
|
||||
((eq rpl ?x) nil)
|
||||
|
@ -926,7 +902,7 @@ If CLOCK-SOUND is non-nil, it overrides `org-clock-sound'."
|
|||
(if (executable-find "aplay")
|
||||
(start-process "org-clock-play-notification" nil
|
||||
"aplay" file)
|
||||
(condition-case-unless-debug nil
|
||||
(condition-case nil
|
||||
(play-sound-file file)
|
||||
(error (beep t) (beep t))))))))))
|
||||
|
||||
|
@ -943,11 +919,9 @@ If CLOCK-SOUND is non-nil, it overrides `org-clock-sound'."
|
|||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward org-clock-re nil t)
|
||||
(when (save-match-data
|
||||
(org-element-type-p (org-element-at-point) 'clock))
|
||||
(push (cons (copy-marker (match-end 1) t)
|
||||
(org-time-string-to-time (match-string 1)))
|
||||
clocks)))))
|
||||
(push (cons (copy-marker (match-end 1) t)
|
||||
(org-time-string-to-time (match-string 1)))
|
||||
clocks))))
|
||||
clocks))
|
||||
|
||||
(defsubst org-is-active-clock (clock)
|
||||
|
@ -961,7 +935,7 @@ If CLOCK-SOUND is non-nil, it overrides `org-clock-sound'."
|
|||
`(with-current-buffer (marker-buffer (car ,clock))
|
||||
(org-with-wide-buffer
|
||||
(goto-char (car ,clock))
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
,@forms)))
|
||||
|
||||
(defmacro org-with-clock (clock &rest forms)
|
||||
|
@ -1067,8 +1041,8 @@ CLOCK is a cons cell of the form (MARKER START-TIME)."
|
|||
(catch 'exit
|
||||
(while (re-search-backward drawer-re beg t)
|
||||
(let ((element (org-element-at-point)))
|
||||
(when (org-element-type-p element 'drawer)
|
||||
(when (> (org-element-end element) (car clock))
|
||||
(when (eq (org-element-type element) 'drawer)
|
||||
(when (> (org-element-property :end element) (car clock))
|
||||
(org-fold-hide-drawer-toggle 'off nil element))
|
||||
(throw 'exit nil)))))))))))
|
||||
|
||||
|
@ -1336,6 +1310,8 @@ time as the start time. See `org-clock-continuously' to make this
|
|||
the default behavior."
|
||||
(interactive "P")
|
||||
(setq org-clock-notification-was-shown nil)
|
||||
(unless org-element-use-cache
|
||||
(org-refresh-effort-properties))
|
||||
(catch 'abort
|
||||
(let ((interrupting (and (not org-clock-resolving-clocks-due-to-idleness)
|
||||
(org-clocking-p)))
|
||||
|
@ -1413,8 +1389,8 @@ the default behavior."
|
|||
(when newstate (org-todo newstate))))
|
||||
((and org-clock-in-switch-to-state
|
||||
(not (looking-at (concat org-outline-regexp "[ \t]*"
|
||||
org-clock-in-switch-to-state
|
||||
"\\>"))))
|
||||
org-clock-in-switch-to-state
|
||||
"\\>"))))
|
||||
(org-todo org-clock-in-switch-to-state)))
|
||||
(setq org-clock-heading (org-clock--mode-line-heading))
|
||||
(org-clock-find-position org-clock-in-resume)
|
||||
|
@ -1440,15 +1416,12 @@ the default behavior."
|
|||
(sit-for 2)
|
||||
(throw 'abort nil))
|
||||
(t
|
||||
;; Make sure that point moves after clock line upon
|
||||
;; inserting it. Then, users can continue typing even if
|
||||
;; point was right where the clock is inserted.
|
||||
(insert-before-markers-and-inherit "\n")
|
||||
(backward-char 1)
|
||||
(when (and (save-excursion
|
||||
(end-of-line 0)
|
||||
(org-in-item-p)))
|
||||
(forward-line 0)
|
||||
(beginning-of-line 1)
|
||||
(indent-line-to (max 0 (- (current-indentation) 2))))
|
||||
(insert-and-inherit org-clock-string " ")
|
||||
(setq org-clock-effort (org-entry-get (point) org-effort-property))
|
||||
|
@ -1468,8 +1441,8 @@ the default behavior."
|
|||
leftover)
|
||||
start-time
|
||||
(org-current-time org-clock-rounding-minutes t)))
|
||||
(setq ts (org-insert-timestamp org-clock-start-time
|
||||
'with-hm 'inactive))
|
||||
(setq ts (org-insert-time-stamp org-clock-start-time
|
||||
'with-hm 'inactive))
|
||||
(org-indent-line)))
|
||||
(move-marker org-clock-marker (point) (buffer-base-buffer))
|
||||
(move-marker org-clock-hd-marker
|
||||
|
@ -1505,33 +1478,6 @@ the default behavior."
|
|||
(message "Clock starts at %s - %s" ts org--msg-extra)
|
||||
(run-hooks 'org-clock-in-hook))))))
|
||||
|
||||
(defvar org-clock--auto-clockout-timer-obj nil
|
||||
"Timer object holding the existing clockout timer.")
|
||||
(defun org-clock--auto-clockout-maybe ()
|
||||
"Clock out the currently clocked in task when idle.
|
||||
See `org-clock-auto-clockout-timer' to set the idle time span.
|
||||
|
||||
This function is to be called by a timer."
|
||||
(when (and (numberp org-clock-auto-clockout-timer)
|
||||
org-clock-current-task)
|
||||
(let ((user-idle-seconds (org-user-idle-seconds)))
|
||||
(cond
|
||||
;; Already idle. Clock out.
|
||||
((>= user-idle-seconds org-clock-auto-clockout-timer)
|
||||
(setq org-clock--auto-clockout-timer-obj nil)
|
||||
(org-clock-out))
|
||||
;; Emacs is idle but system is not. Retry assuming that system will remain idle.
|
||||
((>= (org-emacs-idle-seconds) org-clock-auto-clockout-timer)
|
||||
(setq org-clock--auto-clockout-timer-obj
|
||||
(run-with-timer
|
||||
(- org-clock-auto-clockout-timer user-idle-seconds)
|
||||
nil #'org-clock--auto-clockout-maybe)))
|
||||
;; Emacs is not idle. Check again next time we are idle.
|
||||
(t
|
||||
(setq org-clock--auto-clockout-timer-obj
|
||||
(run-with-idle-timer
|
||||
org-clock-auto-clockout-timer nil #'org-clock--auto-clockout-maybe)))))))
|
||||
|
||||
(defun org-clock-auto-clockout ()
|
||||
"Clock out the currently clocked in task if Emacs is idle.
|
||||
See `org-clock-auto-clockout-timer' to set the idle time span.
|
||||
|
@ -1539,11 +1485,9 @@ See `org-clock-auto-clockout-timer' to set the idle time span.
|
|||
This is only effective when `org-clock-auto-clockout-insinuate'
|
||||
is present in the user configuration."
|
||||
(when (and (numberp org-clock-auto-clockout-timer)
|
||||
org-clock-current-task
|
||||
(not (timerp org-clock--auto-clockout-timer-obj)))
|
||||
(setq org-clock--auto-clockout-timer-obj
|
||||
(run-with-idle-timer
|
||||
org-clock-auto-clockout-timer nil #'org-clock--auto-clockout-maybe))))
|
||||
org-clock-current-task)
|
||||
(run-with-idle-timer
|
||||
org-clock-auto-clockout-timer nil #'org-clock-out)))
|
||||
|
||||
;;;###autoload
|
||||
(defun org-clock-toggle-auto-clockout ()
|
||||
|
@ -1651,9 +1595,9 @@ line and position cursor in that line."
|
|||
" *\\sw+ +[012][0-9]:[0-5][0-9]\\)\\][ \t]*$")))
|
||||
(while (re-search-forward open-clock-re end t)
|
||||
(let ((element (org-element-at-point)))
|
||||
(when (and (org-element-type-p element 'clock)
|
||||
(when (and (eq (org-element-type element) 'clock)
|
||||
(eq (org-element-property :status element) 'running))
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(throw 'exit t))))))
|
||||
;; Look for an existing clock drawer.
|
||||
(when drawer
|
||||
|
@ -1661,8 +1605,8 @@ line and position cursor in that line."
|
|||
(let ((drawer-re (concat "^[ \t]*:" (regexp-quote drawer) ":[ \t]*$")))
|
||||
(while (re-search-forward drawer-re end t)
|
||||
(let ((element (org-element-at-point)))
|
||||
(when (org-element-type-p element 'drawer)
|
||||
(let ((cend (org-element-contents-end element)))
|
||||
(when (eq (org-element-type element) 'drawer)
|
||||
(let ((cend (org-element-property :contents-end element)))
|
||||
(if (and (not org-log-states-order-reversed) cend)
|
||||
(goto-char cend)
|
||||
(forward-line))
|
||||
|
@ -1675,7 +1619,7 @@ line and position cursor in that line."
|
|||
(save-excursion
|
||||
(while (re-search-forward clock-re end t)
|
||||
(let ((element (org-element-at-point)))
|
||||
(when (org-element-type-p element 'clock)
|
||||
(when (eq (org-element-type element) 'clock)
|
||||
(setq positions (cons (line-beginning-position) positions)
|
||||
count (1+ count))))))
|
||||
(cond
|
||||
|
@ -1683,18 +1627,19 @@ line and position cursor in that line."
|
|||
(org-fold-core-ignore-modifications
|
||||
;; Skip planning line and property drawer, if any.
|
||||
(org-end-of-meta-data)
|
||||
(unless (bolp) (insert-before-markers-and-inherit "\n"))
|
||||
(unless (bolp) (insert-and-inherit "\n"))
|
||||
;; Create a new drawer if necessary.
|
||||
(when (and org-clock-into-drawer
|
||||
(or (not (wholenump org-clock-into-drawer))
|
||||
(< org-clock-into-drawer 2)))
|
||||
(let ((beg (point)))
|
||||
;; Make sure that point moves after drawer upon
|
||||
;; inserting it. Then, users can continue typing even
|
||||
;; if point was right where the clock is inserted.
|
||||
(insert-before-markers-and-inherit ":" drawer ":\n:END:\n")
|
||||
(insert-and-inherit ":" drawer ":\n:END:\n")
|
||||
(org-indent-region beg (point))
|
||||
(org-fold-region (line-end-position -1) (1- (point)) t 'drawer)
|
||||
(if (eq org-fold-core-style 'text-properties)
|
||||
(org-fold-region
|
||||
(line-end-position -1) (1- (point)) t 'drawer)
|
||||
(org-fold-region
|
||||
(line-end-position -1) (1- (point)) t 'outline))
|
||||
(forward-line -1)))))
|
||||
;; When a clock drawer needs to be created because of the
|
||||
;; number of clock items or simply if it is missing, collect
|
||||
|
@ -1719,13 +1664,13 @@ line and position cursor in that line."
|
|||
"\n:END:\n")
|
||||
(let ((end (point-marker)))
|
||||
(goto-char beg)
|
||||
(save-excursion (insert-before-markers-and-inherit ":" drawer ":\n"))
|
||||
(save-excursion (insert-and-inherit ":" drawer ":\n"))
|
||||
(org-fold-region (line-end-position) (1- end) t 'outline)
|
||||
(org-indent-region (point) end)
|
||||
(forward-line)
|
||||
(unless org-log-states-order-reversed
|
||||
(goto-char end)
|
||||
(forward-line -2))
|
||||
(beginning-of-line -1))
|
||||
(set-marker end nil)))))
|
||||
(org-log-states-order-reversed (goto-char (car (last positions))))
|
||||
(t (goto-char (car positions))))))))
|
||||
|
@ -1738,11 +1683,6 @@ and current `frame-title-format' is equal to `org-clock-frame-title-format'."
|
|||
(equal frame-title-format org-clock-frame-title-format))
|
||||
(setq frame-title-format org-frame-title-format-backup)))
|
||||
|
||||
(defvar org-clock-out-removed-last-clock nil
|
||||
"When non-nil, the last `org-clock-out' removed the clock line.
|
||||
This can happen when `org-clock-out-remove-zero-time-clocks' is set to
|
||||
non-nil and the latest clock took 0 minutes.")
|
||||
|
||||
;;;###autoload
|
||||
(defun org-clock-out (&optional switch-to-state fail-quietly at-time)
|
||||
"Stop the currently running clock.
|
||||
|
@ -1773,7 +1713,7 @@ to, overriding the existing value of `org-clock-out-switch-to-state'."
|
|||
(save-restriction
|
||||
(widen)
|
||||
(goto-char org-clock-marker)
|
||||
(forward-line 0)
|
||||
(beginning-of-line 1)
|
||||
(if (and (looking-at (concat "[ \t]*" org-keyword-time-regexp))
|
||||
(equal (match-string 1) org-clock-string))
|
||||
(setq ts (match-string 2))
|
||||
|
@ -1782,7 +1722,7 @@ to, overriding the existing value of `org-clock-out-switch-to-state'."
|
|||
(delete-region (point) (line-end-position))
|
||||
(org-fold-core-ignore-modifications
|
||||
(insert-and-inherit "--")
|
||||
(setq te (org-insert-timestamp (or at-time now) 'with-hm 'inactive))
|
||||
(setq te (org-insert-time-stamp (or at-time now) 'with-hm 'inactive))
|
||||
(setq s (org-time-convert-to-integer
|
||||
(time-subtract
|
||||
(org-time-string-to-time te)
|
||||
|
@ -1821,10 +1761,10 @@ to, overriding the existing value of `org-clock-out-switch-to-state'."
|
|||
(when newstate (org-todo newstate))))
|
||||
((and org-clock-out-switch-to-state
|
||||
(not (looking-at
|
||||
(concat
|
||||
org-outline-regexp "[ \t]*"
|
||||
org-clock-out-switch-to-state
|
||||
"\\>"))))
|
||||
(concat
|
||||
org-outline-regexp "[ \t]*"
|
||||
org-clock-out-switch-to-state
|
||||
"\\>"))))
|
||||
(org-todo org-clock-out-switch-to-state))))))
|
||||
(force-mode-line-update)
|
||||
(message (if remove
|
||||
|
@ -1833,7 +1773,6 @@ to, overriding the existing value of `org-clock-out-switch-to-state'."
|
|||
te (org-duration-from-minutes (+ (* 60 h) m)))
|
||||
(unless (org-clocking-p)
|
||||
(setq org-clock-current-task nil))
|
||||
(setq org-clock-out-removed-last-clock remove)
|
||||
(run-hooks 'org-clock-out-hook)
|
||||
;; Add a note, but only if we didn't remove the clock line.
|
||||
(when (and org-log-note-clock-out (not remove))
|
||||
|
@ -2176,7 +2115,6 @@ Use `\\[org-clock-remove-overlays]' to remove the subtree times."
|
|||
h m))))
|
||||
|
||||
(defvar-local org-clock-overlays nil)
|
||||
(put 'org-clock-overlays 'permanent-local t)
|
||||
|
||||
(defun org-clock-put-overlay (time)
|
||||
"Put an overlay on the headline at point, displaying TIME.
|
||||
|
@ -2451,7 +2389,7 @@ have priority."
|
|||
d (+ d shift)))
|
||||
((or `week `thisweek)
|
||||
(let* ((ws (or wstart 1))
|
||||
(diff (+ (* -7 shift) (mod (+ dow 7 (- ws)) 7))))
|
||||
(diff (+ (* -7 shift) (if (= dow 0) (- 7 ws) (- dow ws)))))
|
||||
(setq m 0 h org-extend-today-until d (- d diff) d1 (+ 7 d))))
|
||||
((or `month `thismonth)
|
||||
(setq h org-extend-today-until m 0 d (or mstart 1)
|
||||
|
@ -2602,7 +2540,7 @@ the currently selected interval size."
|
|||
(goto-char b)
|
||||
(insert ins)
|
||||
(delete-region (point) (+ (point) (- e b)))
|
||||
(forward-line 0)
|
||||
(beginning-of-line 1)
|
||||
(org-update-dblock)
|
||||
t)))))
|
||||
|
||||
|
@ -2904,13 +2842,13 @@ from the dynamic block definition."
|
|||
(if timestamp (concat ts "|") "") ;timestamp, maybe
|
||||
(if tags (concat (mapconcat #'identity tgs ", ") "|") "") ;tags, maybe
|
||||
(if properties ;properties columns, maybe
|
||||
(concat (mapconcat (lambda (p) (or (cdr (assoc p props)) ""))
|
||||
properties
|
||||
"|")
|
||||
"|")
|
||||
(concat (mapconcat (lambda (p) (or (cdr (assoc p props)) ""))
|
||||
properties
|
||||
"|")
|
||||
"|")
|
||||
"")
|
||||
(if indent ;indentation
|
||||
(org-clocktable-indent-string level)
|
||||
(org-clocktable-indent-string level)
|
||||
"")
|
||||
(format-field headline)
|
||||
;; Empty fields for higher levels.
|
||||
|
@ -2918,7 +2856,7 @@ from the dynamic block definition."
|
|||
(format-field (org-duration-from-minutes time))
|
||||
(make-string (max 0 (- time-columns level)) ?|)
|
||||
(if (eq formula '%)
|
||||
(format "%.1f |" (* 100 (/ time (float total-time))))
|
||||
(format "%.1f |" (* 100 (/ time (float total-time))))
|
||||
"")
|
||||
"\n")))))))
|
||||
(delete-char -1)
|
||||
|
@ -2929,7 +2867,7 @@ from the dynamic block definition."
|
|||
(when (and contents (string-match "^\\([ \t]*#\\+tblfm:.*\\)" contents))
|
||||
(setq recalc t)
|
||||
(insert "\n" (match-string 1 contents))
|
||||
(forward-line -1))))
|
||||
(beginning-of-line 0))))
|
||||
;; Insert specified formula line.
|
||||
((stringp formula)
|
||||
(insert "\n#+TBLFM: " formula)
|
||||
|
@ -3170,58 +3108,57 @@ PROPERTIES: The list properties specified in the `:properties' parameter
|
|||
Otherwise, return nil."
|
||||
(interactive)
|
||||
(let ((origin (point))) ;; `save-excursion' may not work when deleting.
|
||||
(prog1
|
||||
(save-excursion
|
||||
(forward-line 0)
|
||||
(skip-chars-forward " \t")
|
||||
(when (looking-at org-clock-string)
|
||||
(let ((re (concat "[ \t]*" org-clock-string
|
||||
" *[[<]\\([^]>]+\\)[]>]\\(-+[[<]\\([^]>]+\\)[]>]"
|
||||
"\\([ \t]*=>.*\\)?\\)?"))
|
||||
ts te h m s neg)
|
||||
(cond
|
||||
((not (looking-at re))
|
||||
nil)
|
||||
((not (match-end 2))
|
||||
(when (and (equal (marker-buffer org-clock-marker) (current-buffer))
|
||||
(> org-clock-marker (point))
|
||||
(<= org-clock-marker (line-end-position)))
|
||||
;; The clock is running here
|
||||
(setq org-clock-start-time
|
||||
(org-time-string-to-time (match-string 1)))
|
||||
(org-clock-update-mode-line)))
|
||||
(t
|
||||
;; Prevent recursive call from `org-timestamp-change'.
|
||||
(cl-letf (((symbol-function 'org-clock-update-time-maybe) #'ignore))
|
||||
;; Update timestamps.
|
||||
(save-excursion
|
||||
(goto-char (match-beginning 1)) ; opening timestamp
|
||||
(save-match-data (org-timestamp-change 0 'day)))
|
||||
;; Refresh match data.
|
||||
(looking-at re)
|
||||
(save-excursion
|
||||
(goto-char (match-beginning 3)) ; closing timestamp
|
||||
(save-match-data (org-timestamp-change 0 'day))))
|
||||
;; Refresh match data.
|
||||
(looking-at re)
|
||||
(and (match-end 4) (delete-region (match-beginning 4) (match-end 4)))
|
||||
(end-of-line 1)
|
||||
(setq ts (match-string 1)
|
||||
te (match-string 3))
|
||||
(setq s (- (org-time-string-to-seconds te)
|
||||
(org-time-string-to-seconds ts))
|
||||
neg (< s 0)
|
||||
s (abs s)
|
||||
h (floor (/ s 3600))
|
||||
s (- s (* 3600 h))
|
||||
m (floor (/ s 60))
|
||||
s (- s (* 60 s)))
|
||||
(insert " => " (format (if neg "-%d:%02d" "%2d:%02d") h m))
|
||||
t)))))
|
||||
;; Move back to initial position, but never beyond updated
|
||||
;; clock.
|
||||
(unless (< (point) origin)
|
||||
(goto-char origin)))))
|
||||
(save-excursion
|
||||
(beginning-of-line 1)
|
||||
(skip-chars-forward " \t")
|
||||
(when (looking-at org-clock-string)
|
||||
(let ((re (concat "[ \t]*" org-clock-string
|
||||
" *[[<]\\([^]>]+\\)[]>]\\(-+[[<]\\([^]>]+\\)[]>]"
|
||||
"\\([ \t]*=>.*\\)?\\)?"))
|
||||
ts te h m s neg)
|
||||
(cond
|
||||
((not (looking-at re))
|
||||
nil)
|
||||
((not (match-end 2))
|
||||
(when (and (equal (marker-buffer org-clock-marker) (current-buffer))
|
||||
(> org-clock-marker (point))
|
||||
(<= org-clock-marker (line-end-position)))
|
||||
;; The clock is running here
|
||||
(setq org-clock-start-time
|
||||
(org-time-string-to-time (match-string 1)))
|
||||
(org-clock-update-mode-line)))
|
||||
(t
|
||||
;; Prevent recursive call from `org-timestamp-change'.
|
||||
(cl-letf (((symbol-function 'org-clock-update-time-maybe) #'ignore))
|
||||
;; Update timestamps.
|
||||
(save-excursion
|
||||
(goto-char (match-beginning 1)) ; opening timestamp
|
||||
(save-match-data (org-timestamp-change 0 'day)))
|
||||
;; Refresh match data.
|
||||
(looking-at re)
|
||||
(save-excursion
|
||||
(goto-char (match-beginning 3)) ; closing timestamp
|
||||
(save-match-data (org-timestamp-change 0 'day))))
|
||||
;; Refresh match data.
|
||||
(looking-at re)
|
||||
(and (match-end 4) (delete-region (match-beginning 4) (match-end 4)))
|
||||
(end-of-line 1)
|
||||
(setq ts (match-string 1)
|
||||
te (match-string 3))
|
||||
(setq s (- (org-time-string-to-seconds te)
|
||||
(org-time-string-to-seconds ts))
|
||||
neg (< s 0)
|
||||
s (abs s)
|
||||
h (floor (/ s 3600))
|
||||
s (- s (* 3600 h))
|
||||
m (floor (/ s 60))
|
||||
s (- s (* 60 s)))
|
||||
(insert " => " (format (if neg "-%d:%02d" "%2d:%02d") h m))
|
||||
t)))))
|
||||
;; Move back to initial position, but never beyond updated
|
||||
;; clock.
|
||||
(unless (< (point) origin)
|
||||
(goto-char origin))))
|
||||
|
||||
(defun org-clock-save ()
|
||||
"Persist various clock-related data to disk.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; org-colview.el --- Column View in Org -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2004-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2004-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Carsten Dominik <carsten.dominik@gmail.com>
|
||||
;; Keywords: outlines, hypermedia, calendar, wp
|
||||
|
@ -37,13 +37,13 @@
|
|||
(declare-function org-agenda-redo "org-agenda" (&optional all))
|
||||
(declare-function org-agenda-do-context-action "org-agenda" ())
|
||||
(declare-function org-clock-sum-today "org-clock" (&optional headline-filter))
|
||||
(declare-function org-element-extract "org-element-ast" (node))
|
||||
(declare-function org-element-extract-element "org-element" (element))
|
||||
(declare-function org-element-interpret-data "org-element" (data))
|
||||
(declare-function org-element-map "org-element" (data types fun &optional info first-match no-recursion with-affiliated))
|
||||
(declare-function org-element-parse-secondary-string "org-element" (string restriction &optional parent))
|
||||
(declare-function org-element-property "org-element-ast" (property node))
|
||||
(declare-function org-element-property "org-element" (property element))
|
||||
(declare-function org-element-restriction "org-element" (element))
|
||||
(declare-function org-element-type-p "org-element-ast" (node types))
|
||||
(declare-function org-element-type "org-element" (element))
|
||||
(declare-function org-dynamic-block-define "org" (type func))
|
||||
(declare-function org-link-display-format "ol" (s))
|
||||
(declare-function org-link-open-from-string "ol" (s &optional arg))
|
||||
|
@ -59,19 +59,6 @@
|
|||
|
||||
;;; Configuration
|
||||
|
||||
(defcustom org-columns-checkbox-allowed-values '("[ ]" "[X]")
|
||||
"Allowed values for columns with SUMMARY-TYPE that uses checkbox.
|
||||
The affected summary types are \"X%\", \"X/\", and \"X\" (see info
|
||||
node `(org)Column attributes')."
|
||||
:group 'org-properties
|
||||
:package-version '(Org . "9.6")
|
||||
:type '(repeat (choice
|
||||
(const :tag "Unchecked [ ]" "[ ]")
|
||||
(const :tag "Checked [X]" "[X]")
|
||||
(const :tag "No checkbox" "")
|
||||
(const :tag "Intermediate state [-]" "[-]")
|
||||
(string :tag "Arbitrary string"))))
|
||||
|
||||
(defcustom org-columns-modify-value-for-display-function nil
|
||||
"Function that modifies values for display in column view.
|
||||
For example, it can be used to cut out a certain part from a time stamp.
|
||||
|
@ -129,10 +116,6 @@ in `org-columns-summary-types-default', which see."
|
|||
|
||||
(defvar-local org-columns-overlays nil
|
||||
"Holds the list of current column overlays.")
|
||||
(put 'org-columns-overlays 'permanent-local t)
|
||||
|
||||
(defvar-local org-columns-global nil
|
||||
"Local variable, holds non-nil when current columns are global.")
|
||||
|
||||
(defvar-local org-columns-current-fmt nil
|
||||
"Local variable, holds the currently active column format.")
|
||||
|
@ -196,10 +179,28 @@ See `org-columns-summary-types' for details.")
|
|||
(org-defkey org-columns-map "\M-b" #'backward-char)
|
||||
(org-defkey org-columns-map "a" #'org-columns-edit-allowed)
|
||||
(org-defkey org-columns-map "s" #'org-columns-edit-attributes)
|
||||
(org-defkey org-columns-map "\M-f" #'forward-char)
|
||||
(org-defkey org-columns-map [right] #'forward-char)
|
||||
(org-defkey org-columns-map [up] #'org-columns-move-up)
|
||||
(org-defkey org-columns-map [down] #'org-columns-move-down)
|
||||
(org-defkey org-columns-map "\M-f"
|
||||
(lambda () (interactive) (goto-char (1+ (point)))))
|
||||
(org-defkey org-columns-map [right]
|
||||
(lambda () (interactive) (goto-char (1+ (point)))))
|
||||
(org-defkey org-columns-map [down]
|
||||
(lambda () (interactive)
|
||||
(let ((col (current-column)))
|
||||
(beginning-of-line 2)
|
||||
(while (and (org-invisible-p2) (not (eobp)))
|
||||
(beginning-of-line 2))
|
||||
(move-to-column col)
|
||||
(if (derived-mode-p 'org-agenda-mode)
|
||||
(org-agenda-do-context-action)))))
|
||||
(org-defkey org-columns-map [up]
|
||||
(lambda () (interactive)
|
||||
(let ((col (current-column)))
|
||||
(beginning-of-line 0)
|
||||
(while (and (org-invisible-p2) (not (bobp)))
|
||||
(beginning-of-line 0))
|
||||
(move-to-column col)
|
||||
(if (eq major-mode 'org-agenda-mode)
|
||||
(org-agenda-do-context-action)))))
|
||||
(org-defkey org-columns-map [(shift right)] #'org-columns-next-allowed-value)
|
||||
(org-defkey org-columns-map "n" #'org-columns-next-allowed-value)
|
||||
(org-defkey org-columns-map [(shift left)] #'org-columns-previous-allowed-value)
|
||||
|
@ -208,8 +209,6 @@ See `org-columns-summary-types' for details.")
|
|||
(org-defkey org-columns-map ">" #'org-columns-widen)
|
||||
(org-defkey org-columns-map [(meta right)] #'org-columns-move-right)
|
||||
(org-defkey org-columns-map [(meta left)] #'org-columns-move-left)
|
||||
(org-defkey org-columns-map [(meta down)] #'org-columns-move-row-down)
|
||||
(org-defkey org-columns-map [(meta up)] #'org-columns-move-row-up)
|
||||
(org-defkey org-columns-map [(shift meta right)] #'org-columns-new)
|
||||
(org-defkey org-columns-map [(shift meta left)] #'org-columns-delete)
|
||||
(dotimes (i 10)
|
||||
|
@ -231,8 +230,6 @@ See `org-columns-summary-types' for details.")
|
|||
"--"
|
||||
["Move column right" org-columns-move-right t]
|
||||
["Move column left" org-columns-move-left t]
|
||||
["Move row up" org-columns-move-row-up t]
|
||||
["Move row down" org-columns-move-row-down t]
|
||||
["Add column" org-columns-new t]
|
||||
["Delete column" org-columns-delete t]
|
||||
"--"
|
||||
|
@ -378,19 +375,17 @@ ORIGINAL is the real string, i.e., before it is modified by
|
|||
"Store the relative remapping of column header-line.
|
||||
This is needed to later remove this relative remapping.")
|
||||
|
||||
(defvar org-columns--read-only-string nil)
|
||||
(defun org-columns--display-here (columns &optional dateline)
|
||||
"Overlay the current line with column display.
|
||||
COLUMNS is an alist (SPEC VALUE DISPLAYED). Optional argument
|
||||
DATELINE is non-nil when the face used should be
|
||||
`org-agenda-column-dateline'."
|
||||
(when (and (not org-columns-header-line-remap)
|
||||
(or (fboundp 'face-remap-add-relative)
|
||||
(ignore-errors (require 'face-remap))))
|
||||
(when (and (ignore-errors (require 'face-remap))
|
||||
org-columns-header-line-remap)
|
||||
(setq org-columns-header-line-remap
|
||||
(face-remap-add-relative 'header-line '(:inherit default))))
|
||||
(save-excursion
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(let* ((level-face (and (looking-at "\\(\\**\\)\\(\\* \\)")
|
||||
(org-get-level-face 2)))
|
||||
(ref-face (or level-face
|
||||
|
@ -453,36 +448,18 @@ DATELINE is non-nil when the face used should be
|
|||
(line-end-position 0)
|
||||
(line-beginning-position 2)
|
||||
'read-only
|
||||
(or org-columns--read-only-string
|
||||
(setq org-columns--read-only-string
|
||||
(substitute-command-keys
|
||||
"Type \\<org-columns-map>`\\[org-columns-edit-value]' \
|
||||
to edit property")))))))))
|
||||
|
||||
(defun org-columns--truncate-below-width (string width)
|
||||
"Return a substring of STRING no wider than WIDTH.
|
||||
This substring must start at 0, and must be the longest possible
|
||||
substring whose `string-width' does not exceed WIDTH."
|
||||
(declare (side-effect-free t))
|
||||
(let ((end (min width (length string))) res)
|
||||
(while (and end (>= end 0))
|
||||
(let* ((curr (string-width (substring string 0 end)))
|
||||
(excess (- curr width)))
|
||||
(if (> excess 0)
|
||||
(cl-decf end (max 1 (/ excess 2)))
|
||||
(setq res (substring string 0 end) end nil))))
|
||||
res))
|
||||
(substitute-command-keys
|
||||
"Type \\<org-columns-map>`\\[org-columns-edit-value]' \
|
||||
to edit property")))))))
|
||||
|
||||
(defun org-columns-add-ellipses (string width)
|
||||
"Truncate STRING with WIDTH characters, with ellipses."
|
||||
(cond
|
||||
((<= (string-width string) width) string)
|
||||
((<= width (string-width org-columns-ellipses))
|
||||
(org-columns--truncate-below-width org-columns-ellipses width))
|
||||
(t (concat
|
||||
(org-columns--truncate-below-width
|
||||
string (- width (string-width org-columns-ellipses)))
|
||||
org-columns-ellipses))))
|
||||
((<= (length string) width) string)
|
||||
((<= width (length org-columns-ellipses))
|
||||
(substring org-columns-ellipses 0 width))
|
||||
(t (concat (substring string 0 (- width (length org-columns-ellipses)))
|
||||
org-columns-ellipses))))
|
||||
|
||||
(defvar org-columns-full-header-line-format nil
|
||||
"The full header line format, will be shifted by horizontal scrolling." )
|
||||
|
@ -547,8 +524,7 @@ for the duration of the command.")
|
|||
(setq header-line-format org-previous-header-line-format)
|
||||
(kill-local-variable 'org-previous-header-line-format)
|
||||
(remove-hook 'post-command-hook #'org-columns-hscroll-title 'local))
|
||||
(when (markerp org-columns-begin-marker)
|
||||
(set-marker org-columns-begin-marker nil))
|
||||
(set-marker org-columns-begin-marker nil)
|
||||
(when (markerp org-columns-top-level-marker)
|
||||
(set-marker org-columns-top-level-marker nil))
|
||||
(with-silent-modifications
|
||||
|
@ -750,7 +726,7 @@ an integer, select that value."
|
|||
(let ((all
|
||||
(or (org-property-get-allowed-values pom key)
|
||||
(pcase (nth column org-columns-current-fmt-compiled)
|
||||
(`(,_ ,_ ,_ ,(or "X" "X/" "X%") ,_) org-columns-checkbox-allowed-values))
|
||||
(`(,_ ,_ ,_ ,(or "X" "X/" "X%") ,_) '("[ ]" "[X]")))
|
||||
(org-colview-construct-allowed-dates value))))
|
||||
(if previous (reverse all) all))))
|
||||
(when (equal key "ITEM") (error "Cannot edit item headline from here"))
|
||||
|
@ -840,7 +816,7 @@ current specifications. This function also sets
|
|||
(let ((case-fold-search t))
|
||||
(while (re-search-forward "^[ \t]*#\\+COLUMNS: .+$" nil t)
|
||||
(let ((element (org-element-at-point)))
|
||||
(when (org-element-type-p element 'keyword)
|
||||
(when (eq (org-element-type element) 'keyword)
|
||||
(throw :found (org-element-property :value element)))))
|
||||
nil)))
|
||||
org-columns-default-format)))
|
||||
|
@ -873,7 +849,6 @@ turn on column view for the whole buffer unconditionally.
|
|||
When COLUMNS-FMT-STRING is non-nil, use it as the column format."
|
||||
(interactive "P")
|
||||
(org-columns-remove-overlays)
|
||||
(setq-local org-columns-global global)
|
||||
(save-excursion
|
||||
(when global (goto-char (point-min)))
|
||||
(if (markerp org-columns-begin-marker)
|
||||
|
@ -896,7 +871,7 @@ When COLUMNS-FMT-STRING is non-nil, use it as the column format."
|
|||
;; Collect contents of columns ahead of time so as to
|
||||
;; compute their maximum width.
|
||||
(org-scan-tags
|
||||
(lambda () (cons (point-marker) (org-columns--collect-values))) t org--matcher-tags-todo-only)))
|
||||
(lambda () (cons (point) (org-columns--collect-values))) t org--matcher-tags-todo-only)))
|
||||
(when cache
|
||||
(org-columns--set-widths cache)
|
||||
(org-columns--display-here-title)
|
||||
|
@ -994,30 +969,6 @@ details."
|
|||
(interactive "p")
|
||||
(org-columns-widen (- arg)))
|
||||
|
||||
(defun org-columns-move-up ()
|
||||
"In column view, move cursor up one row.
|
||||
When in agenda column view, also call `org-agenda-do-context-action'."
|
||||
(interactive)
|
||||
(let ((col (current-column)))
|
||||
(forward-line -1)
|
||||
(while (and (org-invisible-p2) (not (bobp)))
|
||||
(forward-line -1))
|
||||
(move-to-column col)
|
||||
(if (eq major-mode 'org-agenda-mode)
|
||||
(org-agenda-do-context-action))))
|
||||
|
||||
(defun org-columns-move-down ()
|
||||
"In column view, move cursor down one row.
|
||||
When in agenda column view, also call `org-agenda-do-context-action'."
|
||||
(interactive)
|
||||
(let ((col (current-column)))
|
||||
(forward-line 1)
|
||||
(while (and (org-invisible-p2) (not (eobp)))
|
||||
(forward-line 1))
|
||||
(move-to-column col)
|
||||
(if (derived-mode-p 'org-agenda-mode)
|
||||
(org-agenda-do-context-action))))
|
||||
|
||||
(defun org-columns-move-right ()
|
||||
"Swap this column with the one to the right."
|
||||
(interactive)
|
||||
|
@ -1052,27 +1003,6 @@ When in agenda column view, also call `org-agenda-do-context-action'."
|
|||
(org-columns-move-right)
|
||||
(backward-char 1)))
|
||||
|
||||
(defun org-columns--move-row (&optional up)
|
||||
"Move the current table row down.
|
||||
With non-nil optional argument UP, move it up."
|
||||
(let ((inhibit-read-only t)
|
||||
(col (current-column)))
|
||||
(if up (org-move-subtree-up)
|
||||
(org-move-subtree-down))
|
||||
(let ((org-columns-inhibit-recalculation t))
|
||||
(org-columns-redo)
|
||||
(move-to-column col))))
|
||||
|
||||
(defun org-columns-move-row-down ()
|
||||
"Move the current table row down."
|
||||
(interactive)
|
||||
(org-columns--move-row))
|
||||
|
||||
(defun org-columns-move-row-up ()
|
||||
"Move the current table row up."
|
||||
(interactive)
|
||||
(org-columns--move-row 'up))
|
||||
|
||||
(defun org-columns-store-format ()
|
||||
"Store the text version of the current columns format.
|
||||
The format is stored either in the COLUMNS property of the node
|
||||
|
@ -1090,7 +1020,7 @@ the current buffer."
|
|||
(catch :found
|
||||
(while (re-search-forward "^[ \t]*#\\+COLUMNS:\\(.*\\)" nil t)
|
||||
(let ((element (save-match-data (org-element-at-point))))
|
||||
(when (and (org-element-type-p element 'keyword)
|
||||
(when (and (eq (org-element-type element) 'keyword)
|
||||
(equal (org-element-property :key element)
|
||||
"COLUMNS"))
|
||||
(replace-match (concat " " fmt) t t nil 1)
|
||||
|
@ -1140,7 +1070,7 @@ the current buffer."
|
|||
(if (derived-mode-p 'org-mode)
|
||||
;; Since we already know the columns format, provide it
|
||||
;; instead of computing again.
|
||||
(funcall-interactively #'org-columns org-columns-global org-columns-current-fmt)
|
||||
(call-interactively #'org-columns org-columns-current-fmt)
|
||||
(org-agenda-redo)
|
||||
(call-interactively #'org-agenda-columns)))
|
||||
(message "Recomputing columns...done")))
|
||||
|
@ -1200,7 +1130,7 @@ This function updates `org-columns-current-fmt-compiled'."
|
|||
|
||||
(defun org-columns--age-to-minutes (s)
|
||||
"Turn age string S into a number of minutes.
|
||||
An age is either computed from a given timestamp, or indicated
|
||||
An age is either computed from a given time-stamp, or indicated
|
||||
as a canonical duration, i.e., using units defined in
|
||||
`org-duration-canonical-units'."
|
||||
(cond
|
||||
|
@ -1229,8 +1159,8 @@ Return the result as a duration."
|
|||
SPEC is a column format specification. When optional argument
|
||||
UPDATE is non-nil, summarized values can replace existing ones in
|
||||
properties drawers."
|
||||
(let* ((lmax (if (bound-and-true-p org-inlinetask-max-level)
|
||||
org-inlinetask-max-level
|
||||
(let* ((lmax (if (bound-and-true-p org-inlinetask-min-level)
|
||||
org-inlinetask-min-level
|
||||
29)) ;Hard-code deepest level.
|
||||
(lvals (make-vector (1+ lmax) nil))
|
||||
(level 0)
|
||||
|
@ -1266,9 +1196,9 @@ properties drawers."
|
|||
;; property `org-summaries', in alist whose key is SPEC.
|
||||
(let* ((summary
|
||||
(and summarize
|
||||
(let ((values
|
||||
(cl-loop for l from (1+ level) to lmax
|
||||
append (aref lvals l))))
|
||||
(let ((values (append (and (/= last-level inminlevel)
|
||||
(aref lvals last-level))
|
||||
(aref lvals inminlevel))))
|
||||
(and values (funcall summarize values printf))))))
|
||||
;; Leaf values are not summaries: do not mark them.
|
||||
(when summary
|
||||
|
@ -1492,7 +1422,7 @@ an inline src-block."
|
|||
(org-element-map data
|
||||
'(footnote-reference inline-babel-call inline-src-block target
|
||||
radio-target statistics-cookie)
|
||||
#'org-element-extract)
|
||||
#'org-element-extract-element)
|
||||
(org-no-properties (org-element-interpret-data data))))
|
||||
|
||||
;;;###autoload
|
||||
|
@ -1563,7 +1493,7 @@ PARAMS is a property list of parameters:
|
|||
(setq view-file filename)
|
||||
(setq view-pos position))
|
||||
(_ (user-error "Cannot find entry with :ID: %s" id)))
|
||||
(with-current-buffer (if view-file (org-get-agenda-file-buffer view-file)
|
||||
(with-current-buffer (if view-file (get-file-buffer view-file)
|
||||
(current-buffer))
|
||||
(org-with-wide-buffer
|
||||
(when view-pos (goto-char view-pos))
|
||||
|
@ -1572,10 +1502,7 @@ PARAMS is a property list of parameters:
|
|||
(plist-get params :skip-empty-rows)
|
||||
(plist-get params :exclude-tags)
|
||||
(plist-get params :format)
|
||||
view-pos)))))
|
||||
(width-specs
|
||||
(mapcar (lambda (spec) (nth 2 spec))
|
||||
org-columns-current-fmt-compiled)))
|
||||
view-pos))))))
|
||||
(when table
|
||||
;; Prune level information from the table. Also normalize
|
||||
;; headings: remove stars, add indentation entities, if
|
||||
|
@ -1611,11 +1538,6 @@ PARAMS is a property list of parameters:
|
|||
(append (mapcar (lambda (x) (if (eq 'hline x) x (cons "" x)))
|
||||
table)
|
||||
(list (cons "/" (make-list size "<>")))))))
|
||||
(when (seq-find #'identity width-specs)
|
||||
;; There are width specifiers in column format. Pass them
|
||||
;; to the resulting table, adding alignment field as the first
|
||||
;; row.
|
||||
(push (mapcar (lambda (width) (when width (format "<%d>" width))) width-specs) table))
|
||||
(let ((content-lines (org-split-string (plist-get params :content) "\n"))
|
||||
recalc)
|
||||
;; Insert affiliated keywords before the table.
|
||||
|
@ -1637,9 +1559,7 @@ PARAMS is a property list of parameters:
|
|||
(insert "\n" line)
|
||||
(unless recalc (setq recalc t))))))
|
||||
(when recalc (org-table-recalculate 'all t))
|
||||
(org-table-align)
|
||||
(when (seq-find #'identity width-specs)
|
||||
(org-table-shrink))))))
|
||||
(org-table-align)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun org-columns-insert-dblock ()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; org-compat.el --- Compatibility Code for Older Emacsen -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2004-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2004-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Carsten Dominik <carsten.dominik@gmail.com>
|
||||
;; Keywords: outlines, hypermedia, calendar, wp
|
||||
|
@ -52,15 +52,9 @@
|
|||
(declare-function org-element-at-point "org-element" (&optional pom cached-only))
|
||||
(declare-function org-element-at-point-no-context "org-element" (&optional pom))
|
||||
(declare-function org-element-context "org-element" (&optional element))
|
||||
(declare-function org-element-lineage "org-element-ast" (blob &optional types with-self))
|
||||
(declare-function org-element-type "org-element-ast" (node &optional anonymous))
|
||||
(declare-function org-element-type-p "org-element-ast" (node types))
|
||||
(declare-function org-element-property "org-element-ast" (property node))
|
||||
(declare-function org-element-begin "org-element" (node))
|
||||
(declare-function org-element-end "org-element" (node))
|
||||
(declare-function org-element-contents-begin "org-element" (node))
|
||||
(declare-function org-element-contents-end "org-element" (node))
|
||||
(declare-function org-element-post-affiliated "org-element" (node))
|
||||
(declare-function org-element-lineage "org-element" (blob &optional types with-self))
|
||||
(declare-function org-element-type "org-element" (element))
|
||||
(declare-function org-element-property "org-element" (property element))
|
||||
(declare-function org-end-of-subtree "org" (&optional invisible-ok to-heading))
|
||||
(declare-function org-get-heading "org" (&optional no-tags no-todo no-priority no-comment))
|
||||
(declare-function org-get-tags "org" (&optional pos local))
|
||||
|
@ -103,25 +97,6 @@
|
|||
|
||||
;;; Emacs < 29 compatibility
|
||||
|
||||
(if (fboundp 'display-buffer-full-frame)
|
||||
(defalias 'org-display-buffer-full-frame #'display-buffer-full-frame)
|
||||
(defun org-display-buffer-full-frame (buffer alist)
|
||||
"Display BUFFER in the current frame, taking the entire frame.
|
||||
ALIST is an association list of action symbols and values. See
|
||||
Info node `(elisp) Buffer Display Action Alists' for details of
|
||||
such alists.
|
||||
|
||||
This is an action function for buffer display, see Info
|
||||
node `(elisp) Buffer Display Action Functions'. It should be
|
||||
called only by `display-buffer' or a function directly or
|
||||
indirectly called by the latter."
|
||||
(when-let ((window (or (display-buffer-reuse-window buffer alist)
|
||||
(display-buffer-same-window buffer alist)
|
||||
(display-buffer-pop-up-window buffer alist)
|
||||
(display-buffer-use-some-window buffer alist))))
|
||||
(delete-other-windows window)
|
||||
window)))
|
||||
|
||||
(defvar org-file-has-changed-p--hash-table (make-hash-table :test #'equal)
|
||||
"Internal variable used by `org-file-has-changed-p'.")
|
||||
|
||||
|
@ -156,41 +131,9 @@ Upper-case and lower-case letters are treated as equal.
|
|||
Unibyte strings are converted to multibyte for comparison."
|
||||
(eq t (compare-strings string1 0 nil string2 0 nil t))))
|
||||
|
||||
(defun org-buffer-text-pixel-width ()
|
||||
"Return pixel width of text in current buffer.
|
||||
This function uses `buffer-text-pixel-size', when available, and falls
|
||||
back to `window-text-pixel-size' otherwise."
|
||||
(if (fboundp 'buffer-text-pixel-size)
|
||||
(car (buffer-text-pixel-size nil nil t))
|
||||
(if (get-buffer-window (current-buffer))
|
||||
;; FIXME: 10000 because `most-positive-fixnum' ain't working
|
||||
;; (tests failing) and this call will be removed after we drop
|
||||
;; Emacs 28 support anyway.
|
||||
(car (window-text-pixel-size
|
||||
nil (point-min) (point-max) 10000))
|
||||
(let ((dedicatedp (window-dedicated-p))
|
||||
(oldbuffer (window-buffer)))
|
||||
(unwind-protect
|
||||
(progn
|
||||
;; Do not throw error in dedicated windows.
|
||||
(set-window-dedicated-p nil nil)
|
||||
(set-window-buffer nil (current-buffer))
|
||||
(car (window-text-pixel-size
|
||||
nil (point-min) (point-max) 10000)))
|
||||
(set-window-buffer nil oldbuffer)
|
||||
(set-window-dedicated-p nil dedicatedp))))))
|
||||
|
||||
|
||||
;;; Emacs < 28.1 compatibility
|
||||
|
||||
(if (= 2 (cdr (subr-arity (symbol-function 'get-buffer-create))))
|
||||
;; Emacs >27.
|
||||
(defalias 'org-get-buffer-create #'get-buffer-create)
|
||||
(defun org-get-buffer-create (buffer-or-name &optional _)
|
||||
"Call `get-buffer-create' with BUFFER-OR-NAME argument.
|
||||
Ignore optional argument."
|
||||
(get-buffer-create buffer-or-name)))
|
||||
|
||||
(if (fboundp 'file-name-concat)
|
||||
(defalias 'org-file-name-concat #'file-name-concat)
|
||||
(defun org-file-name-concat (directory &rest components)
|
||||
|
@ -199,7 +142,7 @@ Ignore optional argument."
|
|||
Elements in COMPONENTS must be a string or nil.
|
||||
DIRECTORY or the non-final elements in COMPONENTS may or may not end
|
||||
with a slash -- if they don't end with a slash, a slash will be
|
||||
inserted before concatenating."
|
||||
inserted before contatenating."
|
||||
(save-match-data
|
||||
(mapconcat
|
||||
#'identity
|
||||
|
@ -251,18 +194,6 @@ removed."
|
|||
default)))
|
||||
": ")))
|
||||
|
||||
(if (fboundp 'ensure-list)
|
||||
(defalias 'org-ensure-list #'ensure-list)
|
||||
(defun org-ensure-list (object)
|
||||
"Return OBJECT as a list.
|
||||
If OBJECT is already a list, return OBJECT itself. If it's
|
||||
not a list, return a one-element list containing OBJECT.
|
||||
|
||||
Compatability substitute for `ensure-list' in Emacs 28."
|
||||
(if (listp object)
|
||||
object
|
||||
(list object))))
|
||||
|
||||
|
||||
;;; Emacs < 27.1 compatibility
|
||||
|
||||
|
@ -274,25 +205,6 @@ Compatability substitute for `ensure-list' in Emacs 28."
|
|||
`(progn ,@body))
|
||||
(defalias 'org-combine-change-calls 'combine-change-calls))
|
||||
|
||||
;; `flatten-tree' was added in Emacs 27.1.
|
||||
(if (fboundp 'flatten-tree)
|
||||
(defalias 'org--flatten-tree #'flatten-tree)
|
||||
;; The implementation is taken from Emacs subr.el 8664ba18c7c5.
|
||||
(defun org--flatten-tree (tree)
|
||||
"Return a \"flattened\" copy of TREE.
|
||||
|
||||
A `flatten-tree' polyfill for compatibility with Emacs versions
|
||||
older than 27.1"
|
||||
(let (elems)
|
||||
(while (consp tree)
|
||||
(let ((elem (pop tree)))
|
||||
(while (consp elem)
|
||||
(push (cdr elem) tree)
|
||||
(setq elem (car elem)))
|
||||
(if elem (push elem elems))))
|
||||
(if tree (push tree elems))
|
||||
(nreverse elems))))
|
||||
|
||||
(if (version< emacs-version "27.1")
|
||||
(defsubst org-replace-buffer-contents (source &optional _max-secs _max-costs)
|
||||
(replace-buffer-contents source))
|
||||
|
@ -379,24 +291,6 @@ Execute BODY, and unwind connection-local variables."
|
|||
`(with-connection-local-profiles (connection-local-get-profiles nil)
|
||||
,@body)))
|
||||
|
||||
;; assoc-delete-all missing from 26.1
|
||||
(if (fboundp 'assoc-delete-all)
|
||||
(defalias 'org-assoc-delete-all 'assoc-delete-all)
|
||||
;; from compat/compat-27.el
|
||||
(defun org-assoc-delete-all (key alist &optional test)
|
||||
"Delete all matching key from alist, default test equal"
|
||||
(unless test (setq test #'equal))
|
||||
(while (and (consp (car alist))
|
||||
(funcall test (caar alist) key))
|
||||
(setq alist (cdr alist)))
|
||||
(let ((tail alist) tail-cdr)
|
||||
(while (setq tail-cdr (cdr tail))
|
||||
(if (and (consp (car tail-cdr))
|
||||
(funcall test (caar tail-cdr) key))
|
||||
(setcdr tail (cdr tail-cdr))
|
||||
(setq tail tail-cdr))))
|
||||
alist))
|
||||
|
||||
|
||||
;;; Emacs < 26.1 compatibility
|
||||
|
||||
|
@ -493,8 +387,6 @@ Counting starts at 1."
|
|||
(define-obsolete-function-alias 'org-string-match-p 'string-match-p "9.0")
|
||||
|
||||
;;;; Functions and variables from previous releases now obsolete.
|
||||
(define-obsolete-variable-alias 'org-export-ignored-local-variables
|
||||
'org-element-ignored-local-variables "Org 9.7")
|
||||
(define-obsolete-function-alias 'org-habit-get-priority
|
||||
'org-habit-get-urgency "Org 9.7")
|
||||
(define-obsolete-function-alias 'org-timestamp-format
|
||||
|
@ -522,7 +414,7 @@ Counting starts at 1."
|
|||
'completing-read "9.0")
|
||||
(define-obsolete-function-alias 'org-iread-file-name 'read-file-name "9.0")
|
||||
(define-obsolete-function-alias 'org-days-to-time
|
||||
'org-timestamp-to-now "8.2")
|
||||
'org-time-stamp-to-now "8.2")
|
||||
(define-obsolete-variable-alias 'org-agenda-ignore-drawer-properties
|
||||
'org-agenda-ignore-properties "9.0")
|
||||
(define-obsolete-function-alias 'org-preview-latex-fragment
|
||||
|
@ -660,419 +552,14 @@ Counting starts at 1."
|
|||
(define-obsolete-function-alias 'org-file-url-p 'org-url-p "9.6")
|
||||
(define-obsolete-variable-alias 'org-plantuml-executable-args 'org-plantuml-args
|
||||
"Org 9.6")
|
||||
|
||||
(defconst org-latex-line-break-safe "\\\\[0pt]"
|
||||
"Linebreak protecting the following [...].
|
||||
|
||||
Without \"[0pt]\" it would be interpreted as an optional argument to
|
||||
the \\\\.
|
||||
|
||||
This constant, for example, makes the below code not err:
|
||||
|
||||
\\begin{tabular}{c|c}
|
||||
[t] & s\\\\[0pt]
|
||||
[I] & A\\\\[0pt]
|
||||
[m] & kg
|
||||
\\end{tabular}")
|
||||
(make-obsolete 'org-latex-line-break-safe
|
||||
"should not be used - it is not safe in all the scenarios."
|
||||
"9.7")
|
||||
|
||||
(defun org-in-fixed-width-region-p ()
|
||||
"Non-nil if point in a fixed-width region."
|
||||
(save-match-data
|
||||
(org-element-type-p (org-element-at-point) 'fixed-width)))
|
||||
(eq 'fixed-width (org-element-type (org-element-at-point)))))
|
||||
(make-obsolete 'org-in-fixed-width-region-p
|
||||
"use `org-element' library"
|
||||
"9.0")
|
||||
|
||||
(define-obsolete-variable-alias
|
||||
'org-format-latex-options 'org-latex-preview-appearance-options "9.7")
|
||||
(make-obsolete-variable
|
||||
'org-format-latex-signal-error "no longer used" "9.7")
|
||||
(define-obsolete-variable-alias
|
||||
'org-format-latex-header 'org-latex-preview-preamble "9.7")
|
||||
(define-obsolete-variable-alias
|
||||
'org-preview-latex-default-process 'org-latex-preview-process-default "9.7")
|
||||
(define-obsolete-variable-alias
|
||||
'org-preview-latex-process-alist 'org-latex-preview-process-alist "9.7")
|
||||
(define-obsolete-function-alias
|
||||
'org-clear-latex-preview 'org-latex-preview-clear-overlays "9.7")
|
||||
(make-obsolete
|
||||
'org-place-formula-image "no longer used" "9.7")
|
||||
(define-obsolete-function-alias
|
||||
'org-latex-color-format 'org-latex-preview--format-color "9.7")
|
||||
(define-obsolete-function-alias
|
||||
'org-latex-color 'org-latex-preview--attr-color "9.7")
|
||||
;; MathML related functions from org-latex-preview.el
|
||||
(define-obsolete-variable-alias
|
||||
'org-latex-to-mathml-jar-file 'org-mathml-converter-jar-file "9.7")
|
||||
(define-obsolete-variable-alias
|
||||
'org-latex-to-mathml-convert-command 'org-mathml-convert-command "9.7")
|
||||
(define-obsolete-function-alias
|
||||
'org-format-latex-mathml-available-p 'org-mathml-converter-available-p "9.7")
|
||||
(define-obsolete-function-alias
|
||||
'org-create-math-formula 'org-mathml-convert-latex "9.7")
|
||||
|
||||
;; FIXME: Unused; obsoleted; to be removed.
|
||||
(defun org-format-latex-as-mathml (latex-frag latex-frag-type
|
||||
prefix &optional dir)
|
||||
(let* ((absprefix (expand-file-name prefix dir))
|
||||
(print-length nil) (print-level nil)
|
||||
(formula-id (concat
|
||||
"formula-"
|
||||
(sha1
|
||||
(prin1-to-string
|
||||
(list latex-frag
|
||||
org-latex-to-mathml-convert-command)))))
|
||||
(formula-cache (format "%s-%s.mathml" absprefix formula-id))
|
||||
(formula-cache-dir (file-name-directory formula-cache)))
|
||||
(unless (file-directory-p formula-cache-dir)
|
||||
(make-directory formula-cache-dir t))
|
||||
(unless (file-exists-p formula-cache)
|
||||
(org-mathml-convert-latex latex-frag formula-cache))
|
||||
(if (file-exists-p formula-cache)
|
||||
;; Successful conversion. Return the link to MathML file.
|
||||
(org-add-props
|
||||
(format "[[file:%s]]" (file-relative-name formula-cache dir))
|
||||
(list 'org-latex-src (replace-regexp-in-string "\"" "" latex-frag)
|
||||
'org-latex-src-embed-type (if latex-frag-type
|
||||
'paragraph 'character)))
|
||||
;; Failed conversion. Return the LaTeX fragment verbatim
|
||||
latex-frag)))
|
||||
(make-obsolete #'org-format-latex-as-mathml "to be removed" "9.7")
|
||||
|
||||
;; FIXME: Unused; obsoleted; to be removed.
|
||||
(defun org-dvipng-color (attr)
|
||||
"Return a RGB color specification for dvipng."
|
||||
(org-dvipng-color-format (face-attribute 'default attr nil)))
|
||||
|
||||
;; FIXME: Unused; obsoleted; to be removed.
|
||||
(defun org-dvipng-color-format (color-name)
|
||||
"Convert COLOR-NAME to a RGB color value for dvipng."
|
||||
(apply #'format "rgb %s %s %s"
|
||||
(mapcar 'org-latex-preview--normalize-color
|
||||
(color-values color-name))))
|
||||
(make-obsolete
|
||||
'org-dvipng-color "to be removed" "9.7")
|
||||
(make-obsolete
|
||||
'org-dvipng-color-format "to be removed" "9.7")
|
||||
|
||||
;; FIXME: Unused; obsoleted; to be removed.
|
||||
(defun org-normalize-color (value)
|
||||
"Return string to be used as color value for an RGB component."
|
||||
(format "%g" (/ value 65535.0)))
|
||||
(make-obsolete 'org-normalize-color "to be removed" "9.7")
|
||||
|
||||
;; FIXME: Unused; obsoleted; to be removed.
|
||||
(defcustom org-preview-latex-image-directory "ltximg/"
|
||||
"Path to store latex preview images.
|
||||
A relative path here creates many directories relative to the
|
||||
processed Org files paths. An absolute path puts all preview
|
||||
images at the same place."
|
||||
:group 'org-latex
|
||||
:version "26.1"
|
||||
:package-version '(Org . "9.0")
|
||||
:type 'string)
|
||||
|
||||
(make-obsolete-variable
|
||||
'org-preview-latex-image-directory "replaced with org-persist" "9.7")
|
||||
|
||||
;; FIXME: Unused; obsoleted; to be removed.
|
||||
(defun org-format-latex
|
||||
(prefix &optional beg end dir overlays msg forbuffer processing-type)
|
||||
"Replace LaTeX fragments with links to an image.
|
||||
|
||||
The function takes care of creating the replacement image.
|
||||
|
||||
Only consider fragments between BEG and END when those are
|
||||
provided.
|
||||
|
||||
When optional argument OVERLAYS is non-nil, display the image on
|
||||
top of the fragment instead of replacing it.
|
||||
|
||||
PROCESSING-TYPE is the conversion method to use, as a symbol.
|
||||
|
||||
Some of the options can be changed using the variable
|
||||
`org-format-latex-options', which see."
|
||||
(when (and overlays (fboundp 'clear-image-cache)) (clear-image-cache))
|
||||
(unless (eq processing-type 'verbatim)
|
||||
(let* ((math-regexp "\\$\\|\\\\[([]\\|^[ \t]*\\\\begin{[A-Za-z0-9*]+}")
|
||||
(cnt 0)
|
||||
checkdir-flag)
|
||||
(goto-char (or beg (point-min)))
|
||||
;; Optimize overlay creation: (info "(elisp) Managing Overlays").
|
||||
(when (and overlays (memq processing-type '(dvipng imagemagick)))
|
||||
(overlay-recenter (or end (point-max))))
|
||||
(while (re-search-forward math-regexp end t)
|
||||
(unless (and overlays
|
||||
(eq (get-char-property (point) 'org-overlay-type)
|
||||
'org-latex-overlay))
|
||||
(let* ((context (org-element-context))
|
||||
(type (org-element-type context)))
|
||||
(when (memq type '(latex-environment latex-fragment))
|
||||
(let ((block-type (eq type 'latex-environment))
|
||||
(value (org-element-property :value context))
|
||||
(beg (org-element-property :begin context))
|
||||
(end (save-excursion
|
||||
(goto-char (org-element-property :end context))
|
||||
(skip-chars-backward " \r\t\n")
|
||||
(point))))
|
||||
(cond
|
||||
((eq processing-type 'mathjax)
|
||||
;; Prepare for MathJax processing.
|
||||
(if (not (string-match "\\`\\$\\$?" value))
|
||||
(goto-char end)
|
||||
(delete-region beg end)
|
||||
(if (string= (match-string 0 value) "$$")
|
||||
(insert "\\[" (substring value 2 -2) "\\]")
|
||||
(insert "\\(" (substring value 1 -1) "\\)"))))
|
||||
((eq processing-type 'html)
|
||||
(goto-char beg)
|
||||
(delete-region beg end)
|
||||
(insert (org-format-latex-as-html value)))
|
||||
((assq processing-type org-preview-latex-process-alist)
|
||||
;; Process to an image.
|
||||
(cl-incf cnt)
|
||||
(goto-char beg)
|
||||
(let* ((processing-info
|
||||
(cdr (assq processing-type org-preview-latex-process-alist)))
|
||||
(face (face-at-point))
|
||||
;; Get the colors from the face at point.
|
||||
(fg
|
||||
(let ((color (plist-get org-format-latex-options
|
||||
:foreground)))
|
||||
(if forbuffer
|
||||
(cond
|
||||
((eq color 'auto)
|
||||
(face-attribute face :foreground nil 'default))
|
||||
((eq color 'default)
|
||||
(face-attribute 'default :foreground nil))
|
||||
(t color))
|
||||
color)))
|
||||
(bg
|
||||
(let ((color (plist-get org-format-latex-options
|
||||
:background)))
|
||||
(if forbuffer
|
||||
(cond
|
||||
((eq color 'auto)
|
||||
(face-attribute face :background nil 'default))
|
||||
((eq color 'default)
|
||||
(face-attribute 'default :background nil))
|
||||
(t color))
|
||||
color)))
|
||||
(hash (sha1 (prin1-to-string
|
||||
(list org-format-latex-header
|
||||
org-latex-default-packages-alist
|
||||
org-latex-packages-alist
|
||||
org-format-latex-options
|
||||
forbuffer value fg bg))))
|
||||
(imagetype (or (plist-get processing-info :image-output-type) "png"))
|
||||
(absprefix (expand-file-name prefix dir))
|
||||
(linkfile (format "%s_%s.%s" prefix hash imagetype))
|
||||
(movefile (format "%s_%s.%s" absprefix hash imagetype))
|
||||
(sep (and block-type "\n\n"))
|
||||
(link (concat sep "[[file:" linkfile "]]" sep))
|
||||
(options
|
||||
(org-combine-plists
|
||||
org-format-latex-options
|
||||
`(:foreground ,fg :background ,bg))))
|
||||
(when msg (message msg cnt))
|
||||
(unless checkdir-flag ; Ensure the directory exists.
|
||||
(setq checkdir-flag t)
|
||||
(let ((todir (file-name-directory absprefix)))
|
||||
(unless (file-directory-p todir)
|
||||
(make-directory todir t))))
|
||||
(unless (file-exists-p movefile)
|
||||
(org-create-formula-image
|
||||
value movefile options forbuffer processing-type))
|
||||
(org-place-formula-image link block-type beg end value overlays movefile imagetype)))
|
||||
((eq processing-type 'mathml)
|
||||
;; Process to MathML.
|
||||
(unless (org-format-latex-mathml-available-p)
|
||||
(user-error "LaTeX to MathML converter not configured"))
|
||||
(cl-incf cnt)
|
||||
(when msg (message msg cnt))
|
||||
(goto-char beg)
|
||||
(delete-region beg end)
|
||||
(insert (org-format-latex-as-mathml
|
||||
value block-type prefix dir)))
|
||||
(t
|
||||
(error "Unknown conversion process %s for LaTeX fragments"
|
||||
processing-type)))))))))))
|
||||
|
||||
;; FIXME: Unused; obsoleted; to be removed.
|
||||
(defun org-place-formula-image (link block-type beg end value overlays movefile imagetype)
|
||||
"Place an overlay from BEG to END showing MOVEFILE.
|
||||
The overlay will be above BEG if OVERLAYS is non-nil."
|
||||
(if overlays
|
||||
(progn
|
||||
(dolist (o (overlays-in beg end))
|
||||
(when (eq (overlay-get o 'org-overlay-type)
|
||||
'org-latex-overlay)
|
||||
(delete-overlay o)))
|
||||
(let ((ov (make-overlay beg end))
|
||||
(imagetype (or (intern imagetype) 'png)))
|
||||
(overlay-put ov 'org-overlay-type 'org-latex-overlay)
|
||||
(overlay-put ov 'evaporate t)
|
||||
(overlay-put ov
|
||||
'modification-hooks
|
||||
(list (lambda (o _flag _beg _end &optional _l)
|
||||
(delete-overlay o))))
|
||||
(overlay-put ov
|
||||
'display
|
||||
(list 'image :type imagetype :file movefile :ascent 'center)))
|
||||
(goto-char end))
|
||||
(delete-region beg end)
|
||||
(insert
|
||||
(org-add-props link
|
||||
(list 'org-latex-src
|
||||
(replace-regexp-in-string "\"" "" value)
|
||||
'org-latex-src-embed-type
|
||||
(if block-type 'paragraph 'character))))))
|
||||
|
||||
|
||||
;; FIXME: Unused; obsoleted; to be removed.
|
||||
(defun org-create-formula-image
|
||||
(string tofile options buffer &optional processing-type)
|
||||
"Create an image from LaTeX source using external processes.
|
||||
|
||||
The LaTeX STRING is saved to a temporary LaTeX file, then
|
||||
converted to an image file by process PROCESSING-TYPE defined in
|
||||
`org-preview-latex-process-alist'. A nil value defaults to
|
||||
`org-preview-latex-default-process'.
|
||||
|
||||
The generated image file is eventually moved to TOFILE.
|
||||
|
||||
The OPTIONS argument controls the size, foreground color and
|
||||
background color of the generated image.
|
||||
|
||||
When BUFFER non-nil, this function is used for LaTeX previewing.
|
||||
Otherwise, it is used to deal with LaTeX snippets showed in
|
||||
a HTML file."
|
||||
(let* ((processing-type (or processing-type
|
||||
org-preview-latex-default-process))
|
||||
(processing-info
|
||||
(cdr (assq processing-type org-preview-latex-process-alist)))
|
||||
(programs (plist-get processing-info :programs))
|
||||
(error-message (or (plist-get processing-info :message) ""))
|
||||
(image-input-type (plist-get processing-info :image-input-type))
|
||||
(image-output-type (plist-get processing-info :image-output-type))
|
||||
(post-clean (or (plist-get processing-info :post-clean)
|
||||
'(".dvi" ".xdv" ".pdf" ".tex" ".aux" ".log"
|
||||
".svg" ".png" ".jpg" ".jpeg" ".out")))
|
||||
(latex-header
|
||||
(or (plist-get processing-info :latex-header)
|
||||
(org-latex-make-preamble
|
||||
(org-export-get-environment (org-export-get-backend 'latex))
|
||||
org-format-latex-header
|
||||
'snippet)))
|
||||
(latex-compiler (plist-get processing-info :latex-compiler))
|
||||
(tmpdir temporary-file-directory)
|
||||
(texfilebase (make-temp-name
|
||||
(expand-file-name "orgtex" tmpdir)))
|
||||
(texfile (concat texfilebase ".tex"))
|
||||
(image-size-adjust (or (plist-get processing-info :image-size-adjust)
|
||||
'(1.0 . 1.0)))
|
||||
(scale (* (if buffer (car image-size-adjust) (cdr image-size-adjust))
|
||||
(or (plist-get options (if buffer :scale :html-scale)) 1.0)))
|
||||
(dpi (* scale (if (and buffer (display-graphic-p)) (org--get-display-dpi) 140.0)))
|
||||
(fg (or (plist-get options (if buffer :foreground :html-foreground))
|
||||
"Black"))
|
||||
(bg (or (plist-get options (if buffer :background :html-background))
|
||||
"Transparent"))
|
||||
(image-converter
|
||||
(or (and (string= bg "Transparent")
|
||||
(plist-get processing-info :transparent-image-converter))
|
||||
(plist-get processing-info :image-converter)))
|
||||
(log-buf (get-buffer-create "*Org Preview LaTeX Output*"))
|
||||
(resize-mini-windows nil)) ;Fix Emacs flicker when creating image.
|
||||
(dolist (program programs)
|
||||
(org-check-external-command program error-message))
|
||||
(if (eq fg 'default)
|
||||
(setq fg (org-latex-color :foreground))
|
||||
(setq fg (org-latex-color-format fg)))
|
||||
(setq bg (cond
|
||||
((eq bg 'default) (org-latex-color :background))
|
||||
((string= bg "Transparent") nil)
|
||||
(t (org-latex-color-format bg))))
|
||||
;; Remove TeX \par at end of snippet to avoid trailing space.
|
||||
(if (string-suffix-p string "\n")
|
||||
(aset string (1- (length string)) ?%)
|
||||
(setq string (concat string "%")))
|
||||
(with-temp-file texfile
|
||||
(insert latex-header)
|
||||
(insert "\n\\begin{document}\n"
|
||||
"\\definecolor{fg}{rgb}{" fg "}%\n"
|
||||
(if bg
|
||||
(concat "\\definecolor{bg}{rgb}{" bg "}%\n"
|
||||
"\n\\pagecolor{bg}%\n")
|
||||
"")
|
||||
"\n{\\color{fg}\n"
|
||||
string
|
||||
"\n}\n"
|
||||
"\n\\end{document}\n"))
|
||||
(let* ((err-msg (format "Please adjust `%s' part of \
|
||||
`org-preview-latex-process-alist'."
|
||||
processing-type))
|
||||
(image-input-file
|
||||
(org-compile-file
|
||||
texfile latex-compiler image-input-type err-msg log-buf))
|
||||
(image-output-file
|
||||
(org-compile-file
|
||||
image-input-file image-converter image-output-type err-msg log-buf
|
||||
`((?D . ,(shell-quote-argument (format "%s" dpi)))
|
||||
(?S . ,(shell-quote-argument (format "%s" (/ dpi 140.0))))))))
|
||||
(copy-file image-output-file tofile 'replace)
|
||||
(dolist (e post-clean)
|
||||
(when (file-exists-p (concat texfilebase e))
|
||||
(delete-file (concat texfilebase e))))
|
||||
image-output-file)))
|
||||
|
||||
;; FIXME: Unused; obsoleted; to be removed.
|
||||
(defun org-html-format-latex (latex-frag processing-type info)
|
||||
"Format a LaTeX fragment LATEX-FRAG into HTML.
|
||||
PROCESSING-TYPE designates the tool used for conversion. It can
|
||||
be `mathjax', `verbatim', `html', nil, t or symbols in
|
||||
`org-preview-latex-process-alist', e.g., `dvipng', `dvisvgm' or
|
||||
`imagemagick'. See `org-html-with-latex' for more information.
|
||||
INFO is a plist containing export properties."
|
||||
(let ((cache-relpath "") (cache-dir ""))
|
||||
(unless (or (eq processing-type 'mathjax)
|
||||
(eq processing-type 'html))
|
||||
(let ((bfn (or (buffer-file-name)
|
||||
(make-temp-name
|
||||
(expand-file-name "latex" temporary-file-directory))))
|
||||
(latex-header
|
||||
(let ((header (plist-get info :latex-header)))
|
||||
(and header
|
||||
(concat (mapconcat
|
||||
(lambda (line) (concat "#+LATEX_HEADER: " line))
|
||||
(org-split-string header "\n")
|
||||
"\n")
|
||||
"\n")))))
|
||||
(setq cache-relpath
|
||||
(concat (file-name-as-directory org-preview-latex-image-directory)
|
||||
(file-name-sans-extension
|
||||
(file-name-nondirectory bfn)))
|
||||
cache-dir (file-name-directory bfn))
|
||||
;; Re-create LaTeX environment from original buffer in
|
||||
;; temporary buffer so that dvipng/imagemagick can properly
|
||||
;; turn the fragment into an image.
|
||||
(setq latex-frag (concat latex-header latex-frag))))
|
||||
(org-export-with-buffer-copy
|
||||
:to-buffer (get-buffer-create " *Org HTML Export LaTeX*")
|
||||
:drop-visibility t :drop-narrowing t :drop-contents t
|
||||
(erase-buffer)
|
||||
(insert latex-frag)
|
||||
(org-format-latex cache-relpath nil nil cache-dir nil
|
||||
"Creating LaTeX Image..." nil processing-type)
|
||||
(buffer-string))))
|
||||
|
||||
(make-obsolete #'org-format-latex "to be removed" "9.7")
|
||||
(make-obsolete #'org-create-formula-image "to be removed" "9.7")
|
||||
(make-obsolete #'org-html-format-latex "to be removed" "9.7")
|
||||
|
||||
;; FIXME: Unused; obsoleted; to be removed.
|
||||
(defun org-let (list &rest body) ;FIXME: So many kittens are suffering here.
|
||||
(declare (indent 1) (obsolete cl-progv "2021"))
|
||||
|
@ -1089,23 +576,6 @@ INFO is a plist containing export properties."
|
|||
(define-obsolete-function-alias 'org--math-always-on
|
||||
'org--math-p "9.7")
|
||||
|
||||
(defmacro org-no-popups (&rest body)
|
||||
"Suppress popup windows and evaluate BODY."
|
||||
`(let (pop-up-frames pop-up-windows)
|
||||
,@body))
|
||||
(make-obsolete 'org-no-popups "no longer used" "9.7")
|
||||
|
||||
(defun org-switch-to-buffer-other-window (&rest args)
|
||||
"Switch to buffer in a second window on the current frame.
|
||||
In particular, do not allow pop-up frames.
|
||||
Returns the newly created buffer."
|
||||
(let (pop-up-frames pop-up-windows)
|
||||
(apply #'switch-to-buffer-other-window args)))
|
||||
(make-obsolete 'org-switch-to-buffer-other-window "no longer used" "9.7")
|
||||
|
||||
(make-obsolete 'org-refresh-category-properties "no longer used" "9.7")
|
||||
(make-obsolete 'org-refresh-effort-properties "no longer used" "9.7")
|
||||
|
||||
(defun org-compatible-face (inherits specs)
|
||||
"Make a compatible face specification.
|
||||
If INHERITS is an existing face and if the Emacs version supports
|
||||
|
@ -1152,7 +622,7 @@ See `org-link-parameters' for documentation on the other parameters."
|
|||
(defun org-table-recognize-table.el ()
|
||||
"If there is a table.el table nearby, recognize it and move into it."
|
||||
(when (org-at-table.el-p)
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(unless (or (looking-at org-table-dataline-regexp)
|
||||
(not (looking-at org-table1-hline-regexp)))
|
||||
(forward-line)
|
||||
|
@ -1194,23 +664,13 @@ See `org-link-parameters' for documentation on the other parameters."
|
|||
(org-unbracket-string "<" ">" s))
|
||||
(make-obsolete 'org-remove-angle-brackets 'org-unbracket-string "9.0")
|
||||
|
||||
(defcustom org-capture-bookmark t
|
||||
"When non-nil, add bookmark pointing at the last stored position when capturing."
|
||||
:group 'org-capture
|
||||
:version "24.3"
|
||||
:type 'boolean)
|
||||
(make-obsolete-variable
|
||||
'org-capture-bookmark
|
||||
"use `org-bookmark-names-plist' instead."
|
||||
"9.7")
|
||||
|
||||
(defcustom org-publish-sitemap-file-entry-format "%t"
|
||||
"Format string for site-map file entry.
|
||||
You could use brackets to delimit on what part the link will be.
|
||||
|
||||
%t is the title.
|
||||
%a is the author.
|
||||
%d is the date."
|
||||
%d is the date formatted using `org-publish-sitemap-date-format'."
|
||||
:group 'org-export-publish
|
||||
:type 'string)
|
||||
(make-obsolete-variable
|
||||
|
@ -1427,21 +887,21 @@ When optional argument ELEMENT is a parsed drawer, as returned by
|
|||
When buffer positions BEG and END are provided, hide or show that
|
||||
region as a drawer without further ado."
|
||||
(declare (obsolete "use `org-hide-drawer-toggle' instead." "9.4"))
|
||||
(if (and beg end) (org-fold-region beg end flag 'drawer)
|
||||
(if (and beg end) (org-fold-region beg end flag (if (eq org-fold-core-style 'text-properties) 'drawer 'outline))
|
||||
(let ((drawer
|
||||
(or element
|
||||
(and (save-excursion
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(looking-at-p "^[ \t]*:\\(\\(?:\\w\\|[-_]\\)+\\):[ \t]*$"))
|
||||
(org-element-at-point)))))
|
||||
(when (org-element-type-p drawer '(drawer property-drawer))
|
||||
(let ((post (org-element-post-affiliated drawer)))
|
||||
(when (memq (org-element-type drawer) '(drawer property-drawer))
|
||||
(let ((post (org-element-property :post-affiliated drawer)))
|
||||
(org-fold-region
|
||||
(save-excursion (goto-char post) (line-end-position))
|
||||
(save-excursion (goto-char (org-element-end drawer))
|
||||
(save-excursion (goto-char (org-element-property :end drawer))
|
||||
(skip-chars-backward " \t\n")
|
||||
(line-end-position))
|
||||
flag 'drawer)
|
||||
flag (if (eq org-fold-core-style 'text-properties) 'drawer 'outline))
|
||||
;; When the drawer is hidden away, make sure point lies in
|
||||
;; a visible part of the buffer.
|
||||
(when (invisible-p (max (1- (point)) (point-min)))
|
||||
|
@ -1465,7 +925,7 @@ an error. Return a non-nil value when toggling is successful."
|
|||
(goto-char start)
|
||||
(while (and (< (point) end)
|
||||
(re-search-forward "^[ \t]*#\\+begin_?\
|
||||
\\([^ \n]+\\)\\(\\([^\n]+\\)\\)?\n\\(\\(?:.\\|\n\\)+?\\)#\\+end_?\\1[ \t]*$" end t))
|
||||
\\([^ \n]+\\)\\(\\([^\n]+\\)\\)?\n\\([^\000]+?\\)#\\+end_?\\1[ \t]*$" end t))
|
||||
(save-excursion
|
||||
(save-match-data
|
||||
(goto-char (match-beginning 0))
|
||||
|
@ -1673,15 +1133,6 @@ context. See the individual commands for more information."
|
|||
(define-obsolete-function-alias 'ob-clojure-eval-with-babashka
|
||||
#'ob-clojure-eval-with-cmd "9.7")
|
||||
|
||||
(define-obsolete-function-alias 'org-export-get-parent
|
||||
'org-element-parent "9.7")
|
||||
(define-obsolete-function-alias 'org-export-get-parent-element
|
||||
'org-element-parent-element "9.7")
|
||||
|
||||
(define-obsolete-function-alias 'org-print-speed-command
|
||||
'org--print-speed-command "9.7"
|
||||
"Internal function. Subject of unannounced changes.")
|
||||
|
||||
;;;; Obsolete link types
|
||||
|
||||
(eval-after-load 'ol
|
||||
|
@ -1932,7 +1383,7 @@ ELEMENT is the element at point."
|
|||
;; Only in inline footnotes, within the definition.
|
||||
(and (eq (org-element-property :type object) 'inline)
|
||||
(< (save-excursion
|
||||
(goto-char (org-element-begin object))
|
||||
(goto-char (org-element-property :begin object))
|
||||
(search-forward ":" nil t 2))
|
||||
(point))))
|
||||
(otherwise t))))
|
||||
|
@ -1941,7 +1392,7 @@ ELEMENT is the element at point."
|
|||
"Function used for `flyspell-generic-check-word-predicate'."
|
||||
(if (org-at-heading-p)
|
||||
;; At a headline or an inlinetask, check title only.
|
||||
(and (save-excursion (forward-line 0)
|
||||
(and (save-excursion (beginning-of-line)
|
||||
(and (let ((case-fold-search t))
|
||||
(not (looking-at-p "\\*+ END[ \t]*$")))
|
||||
(let ((case-fold-search nil))
|
||||
|
@ -1953,19 +1404,19 @@ ELEMENT is the element at point."
|
|||
;; Ignore checks in code, verbatim and others.
|
||||
(org--flyspell-object-check-p (org-element-at-point-no-context)))
|
||||
(let* ((element (org-element-at-point-no-context))
|
||||
(post-affiliated (org-element-post-affiliated element)))
|
||||
(post-affiliated (org-element-property :post-affiliated element)))
|
||||
(cond
|
||||
;; Ignore checks in all affiliated keywords but captions.
|
||||
((< (point) post-affiliated)
|
||||
(and (save-excursion
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(let ((case-fold-search t)) (looking-at "[ \t]*#\\+CAPTION:")))
|
||||
(> (point) (match-end 0))
|
||||
(org--flyspell-object-check-p element)))
|
||||
;; Ignore checks in LOGBOOK (or equivalent) drawer.
|
||||
((let ((log (org-log-into-drawer)))
|
||||
(and log
|
||||
(let ((drawer (org-element-lineage element 'drawer)))
|
||||
(let ((drawer (org-element-lineage element '(drawer))))
|
||||
(and drawer
|
||||
(org-string-equal-ignore-case
|
||||
log (org-element-property :drawer-name drawer))))))
|
||||
|
@ -1979,7 +1430,7 @@ ELEMENT is the element at point."
|
|||
(save-excursion
|
||||
(end-of-line)
|
||||
(skip-chars-forward " \r\t\n")
|
||||
(< (point) (org-element-end element)))))
|
||||
(< (point) (org-element-property :end element)))))
|
||||
;; Arbitrary list of keywords where checks are meaningful.
|
||||
;; Make sure point is on the value part of the element.
|
||||
(keyword
|
||||
|
@ -1991,8 +1442,8 @@ ELEMENT is the element at point."
|
|||
;; table rows (after affiliated keywords) but some objects
|
||||
;; must not be affected.
|
||||
((paragraph table-row verse-block)
|
||||
(let ((cbeg (org-element-contents-begin element))
|
||||
(cend (org-element-contents-end element)))
|
||||
(let ((cbeg (org-element-property :contents-begin element))
|
||||
(cend (org-element-property :contents-end element)))
|
||||
(and cbeg (>= (point) cbeg) (< (point) cend)
|
||||
(org--flyspell-object-check-p element))))))))))
|
||||
(put 'org-mode 'flyspell-mode-predicate 'org-mode-flyspell-verify)
|
||||
|
@ -2127,7 +1578,7 @@ key."
|
|||
"Run `org-back-to-heading' when in org-mode."
|
||||
(if (derived-mode-p 'org-mode)
|
||||
(progn
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(or (org-at-heading-p (not invisible-ok))
|
||||
(let (found)
|
||||
(save-excursion
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; org-crypt.el --- Public Key Encryption for Org Entries -*- lexical-binding: t; -*-
|
||||
;;
|
||||
;; Copyright (C) 2007-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2007-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: John Wiegley <johnw@gnu.org>
|
||||
|
||||
|
@ -71,18 +71,16 @@
|
|||
(defvar epg-context)
|
||||
|
||||
(declare-function org-back-over-empty-lines "org" ())
|
||||
(declare-function org-current-level "org" ())
|
||||
(declare-function org-back-to-heading "org" (&optional invisible-ok))
|
||||
(declare-function org-before-first-heading-p "org" ())
|
||||
(declare-function org-end-of-meta-data "org" (&optional full))
|
||||
(declare-function org-end-of-subtree "org" (&optional invisible-ok to-heading element))
|
||||
(declare-function org-end-of-subtree "org" (&optional invisible-ok to-heading))
|
||||
(declare-function org-entry-get "org" (pom property &optional inherit literal-nil))
|
||||
(declare-function org-fold-subtree "org-fold" (flag))
|
||||
(declare-function org-make-tags-matcher "org" (match &optional only-local-tags))
|
||||
(declare-function org-make-tags-matcher "org" (match))
|
||||
(declare-function org-previous-visible-heading "org" (arg))
|
||||
(declare-function org-scan-tags "org" (action matcher todo-only &optional start-level))
|
||||
(declare-function org-set-property "org" (property value))
|
||||
(declare-function org-cycle-set-startup-visibility "org-cycle" ())
|
||||
|
||||
(defgroup org-crypt nil
|
||||
"Org Crypt."
|
||||
|
@ -115,16 +113,16 @@ This setting can be overridden in the CRYPTKEY property."
|
|||
(defcustom org-crypt-disable-auto-save 'ask
|
||||
"What org-decrypt should do if `auto-save-mode' is enabled.
|
||||
|
||||
t : Disable `auto-save-mode' for the current buffer
|
||||
t : Disable auto-save-mode for the current buffer
|
||||
prior to decrypting an entry.
|
||||
|
||||
nil : Leave `auto-save-mode' enabled.
|
||||
nil : Leave auto-save-mode enabled.
|
||||
This may cause data to be written to disk unencrypted!
|
||||
|
||||
`ask' : Ask user whether or not to disable `auto-save-mode'
|
||||
`ask' : Ask user whether or not to disable auto-save-mode
|
||||
for the current buffer.
|
||||
|
||||
`encrypt': Leave `auto-save-mode' enabled for the current buffer,
|
||||
`encrypt': Leave auto-save-mode enabled for the current buffer,
|
||||
but automatically re-encrypt all decrypted entries
|
||||
*before* auto-saving.
|
||||
NOTE: This only works for entries which have a tag
|
||||
|
@ -167,7 +165,7 @@ and END are buffer positions delimiting the encrypted area."
|
|||
(cons start (line-beginning-position 2)))))))))
|
||||
|
||||
(defun org-crypt-check-auto-save ()
|
||||
"Check whether `auto-save-mode' is enabled for the current buffer.
|
||||
"Check whether auto-save-mode is enabled for the current buffer.
|
||||
|
||||
`auto-save-mode' may cause leakage when decrypting entries, so
|
||||
check whether it's enabled, and decide what to do about it.
|
||||
|
@ -179,7 +177,7 @@ See `org-crypt-disable-auto-save'."
|
|||
(eq org-crypt-disable-auto-save t)
|
||||
(and
|
||||
(eq org-crypt-disable-auto-save 'ask)
|
||||
(y-or-n-p "`org-decrypt': auto-save-mode may cause leakage. Disable it for current buffer? ")))
|
||||
(y-or-n-p "org-decrypt: auto-save-mode may cause leakage. Disable it for current buffer? ")))
|
||||
(message "org-decrypt: Disabling auto-save-mode for %s"
|
||||
(or (buffer-file-name) (current-buffer)))
|
||||
;; The argument to auto-save-mode has to be "-1", since
|
||||
|
@ -246,13 +244,12 @@ Assume `epg-context' is set."
|
|||
;; contents in the buffer.
|
||||
(error
|
||||
(insert contents)
|
||||
(error "%s" (error-message-string err)))))
|
||||
(error (error-message-string err)))))
|
||||
(when folded-heading
|
||||
(goto-char folded-heading)
|
||||
(org-fold-subtree t))
|
||||
nil)))))
|
||||
|
||||
(defvar org-outline-regexp-bol)
|
||||
;;;###autoload
|
||||
(defun org-decrypt-entry ()
|
||||
"Decrypt the content of the current headline."
|
||||
|
@ -268,44 +265,23 @@ Assume `epg-context' is set."
|
|||
(save-excursion
|
||||
(org-previous-visible-heading 1)
|
||||
(point))))
|
||||
(level (org-current-level))
|
||||
(encrypted-text (org-crypt--encrypted-text beg end))
|
||||
(decrypted-text
|
||||
(decode-coding-string
|
||||
(epg-decrypt-string epg-context encrypted-text)
|
||||
'utf-8))
|
||||
origin-marker)
|
||||
'utf-8)))
|
||||
;; Delete region starting just before point, because the
|
||||
;; outline property starts at the \n of the heading.
|
||||
(delete-region (1- (point)) end)
|
||||
(setq origin-marker (point-marker))
|
||||
(if (string-match (org-headline-re level) decrypted-text)
|
||||
;; If decrypted text contains other headings with levels
|
||||
;; below LEVEL, adjust the subtree.
|
||||
(let ((start 0) (min-level level))
|
||||
(while (string-match (org-headline-re level) decrypted-text start)
|
||||
(setq min-level (min min-level (1- (length (match-string 0 decrypted-text))))
|
||||
start (match-end 0)))
|
||||
(insert "\n"
|
||||
(replace-regexp-in-string
|
||||
org-outline-regexp-bol
|
||||
(concat (make-string (1+ (- level min-level)) ?*) "\\&")
|
||||
decrypted-text)))
|
||||
;; Store a checksum of the decrypted and the encrypted text
|
||||
;; value. This allows reusing the same encrypted text if the
|
||||
;; text does not change, and therefore avoid a re-encryption
|
||||
;; process.
|
||||
(insert "\n"
|
||||
(propertize decrypted-text
|
||||
'org-crypt-checksum (sha1 decrypted-text)
|
||||
'org-crypt-key (org-crypt-key-for-heading)
|
||||
'org-crypt-text encrypted-text)))
|
||||
;; Apply initial visibility.
|
||||
(save-restriction
|
||||
(narrow-to-region origin-marker (point))
|
||||
(set-marker origin-marker nil)
|
||||
(org-cycle-set-startup-visibility))
|
||||
;; ... but keep the previous folded state.
|
||||
;; Store a checksum of the decrypted and the encrypted text
|
||||
;; value. This allows reusing the same encrypted text if the
|
||||
;; text does not change, and therefore avoid a re-encryption
|
||||
;; process.
|
||||
(insert "\n"
|
||||
(propertize decrypted-text
|
||||
'org-crypt-checksum (sha1 decrypted-text)
|
||||
'org-crypt-key (org-crypt-key-for-heading)
|
||||
'org-crypt-text encrypted-text))
|
||||
(when folded-heading
|
||||
(goto-char folded-heading)
|
||||
(org-fold-subtree t))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; org-ctags.el --- Integrate Emacs "tags" Facility with Org -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2007-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2007-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Paul Sexton <eeeickythump@gmail.com>
|
||||
;; Keywords: org, wp
|
||||
|
@ -28,7 +28,7 @@
|
|||
;;
|
||||
;; Allows Org mode to make use of the Emacs `etags' system. Defines
|
||||
;; tag destinations in Org files as any text between <<double angled
|
||||
;; brackets>>. This allows the tags-generation program `exuberant
|
||||
;; brackets>>. This allows the tags-generation program `exuberant
|
||||
;; ctags' to parse these files and create tag tables that record where
|
||||
;; these destinations are found. Plain [[links]] in org mode files
|
||||
;; which do not have <<matching destinations>> within the same file
|
||||
|
@ -66,7 +66,7 @@
|
|||
;; search the entire text of the current buffer for 'tag'.
|
||||
;;
|
||||
;; This behavior can be modified by changing the value of
|
||||
;; ORG-CTAGS-OPEN-LINK-FUNCTIONS. For example, I have the following in my
|
||||
;; ORG-CTAGS-OPEN-LINK-FUNCTIONS. For example I have the following in my
|
||||
;; .emacs, which describes the same behavior as the above paragraph with
|
||||
;; one difference:
|
||||
;;
|
||||
|
@ -149,7 +149,7 @@
|
|||
(defvar org-ctags-enabled-p t
|
||||
"Activate ctags support in org mode?")
|
||||
|
||||
(defvar org-ctags-tag-regexp "/<<([^<>]+)>>/\\1/d,definition/"
|
||||
(defvar org-ctags-tag-regexp "/<<([^>]+)>>/\\1/d,definition/"
|
||||
"Regexp expression used by ctags external program.
|
||||
The regexp matches tag destinations in Org files.
|
||||
Format is: /REGEXP/TAGNAME/FLAGS,TAGTYPE/
|
||||
|
@ -484,11 +484,11 @@ its subdirectories contain large numbers of taggable files."
|
|||
(setq exitcode
|
||||
(shell-command
|
||||
(format (concat "%s --langdef=orgmode --langmap=orgmode:.org "
|
||||
"--regex-orgmode=\"%s\" -f \"%s\" -e -R %s")
|
||||
"--regex-orgmode=\"%s\" -f \"%s\" -e -R \"%s\"")
|
||||
org-ctags-path-to-ctags
|
||||
org-ctags-tag-regexp
|
||||
(expand-file-name (concat dir-name "/TAGS"))
|
||||
(expand-file-name (concat (shell-quote-argument dir-name) "/*")))))
|
||||
(expand-file-name (concat dir-name "/*")))))
|
||||
(cond
|
||||
((eql 0 exitcode)
|
||||
(setq-local org-ctags-tag-list
|
||||
|
@ -506,11 +506,12 @@ its subdirectories contain large numbers of taggable files."
|
|||
|
||||
(defun org-ctags-find-tag-interactive ()
|
||||
"Prompt for the name of a tag, with autocompletion, then visit the named tag.
|
||||
Uses `ido-mode' if available.
|
||||
If the user enters a string that does not match an existing tag, create
|
||||
a new topic."
|
||||
(interactive)
|
||||
(let* ((tag (completing-read "Topic: " org-ctags-tag-list
|
||||
nil 'confirm nil 'org-ctags-find-tag-history)))
|
||||
(let* ((tag (ido-completing-read "Topic: " org-ctags-tag-list
|
||||
nil 'confirm nil 'org-ctags-find-tag-history)))
|
||||
(when tag
|
||||
(cond
|
||||
((member tag org-ctags-tag-list)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
;;; org-cycle.el --- Visibility cycling of Org entries -*- lexical-binding: t; -*-
|
||||
;;
|
||||
;; Copyright (C) 2020-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2020-2023 Free Software Foundation, Inc.
|
||||
;;
|
||||
;; Maintainer: Ihor Radchenko <yantar92 at posteo dot net>
|
||||
;; Maintainer: Ihor Radchenko <yantar92 at gmail dot com>
|
||||
;; Keywords: folding, visibility cycling, invisible text
|
||||
;; URL: https://orgmode.org
|
||||
;;
|
||||
|
@ -35,10 +35,9 @@
|
|||
(require 'org-macs)
|
||||
(require 'org-fold)
|
||||
|
||||
(declare-function org-element-type-p "org-element-ast" (node types))
|
||||
(declare-function org-element-property "org-element-ast" (property node))
|
||||
(declare-function org-element-post-affiliated "org-element" (node))
|
||||
(declare-function org-element-lineage "org-element-ast" (datum &optional types with-self))
|
||||
(declare-function org-element-type "org-element" (element))
|
||||
(declare-function org-element-property "org-element" (property element))
|
||||
(declare-function org-element-lineage "org-element" (datum &optional types with-self))
|
||||
(declare-function org-element-at-point "org-element" (&optional pom cached-only))
|
||||
(declare-function org-display-inline-images "org" (&optional include-linked refresh beg end))
|
||||
(declare-function org-get-tags "org" (&optional pos local fontify))
|
||||
|
@ -116,7 +115,6 @@ than its value."
|
|||
(const :tag "No limit" nil)
|
||||
(integer :tag "Maximum level")))
|
||||
|
||||
(defvaralias 'org-hide-block-startup 'org-cycle-hide-block-startup)
|
||||
(defcustom org-cycle-hide-block-startup nil
|
||||
"Non-nil means entering Org mode will fold all blocks.
|
||||
This can also be set in on a per-file basis with
|
||||
|
@ -127,7 +125,6 @@ This can also be set in on a per-file basis with
|
|||
:group 'org-cycle
|
||||
:type 'boolean)
|
||||
|
||||
(defvaralias 'org-hide-drawer-startup 'org-cycle-hide-drawer-startup)
|
||||
(defcustom org-cycle-hide-drawer-startup t
|
||||
"Non-nil means entering Org mode will fold all drawers.
|
||||
This can also be set in on a per-file basis with
|
||||
|
@ -203,7 +200,6 @@ Special case: when 0, never leave empty lines in collapsed view."
|
|||
:type 'integer)
|
||||
(put 'org-cycle-separator-lines 'safe-local-variable 'integerp)
|
||||
|
||||
(defvaralias 'org-pre-cycle-hook 'org-cycle-pre-hook)
|
||||
(defcustom org-cycle-pre-hook nil
|
||||
"Hook that is run before visibility cycling is happening.
|
||||
The function(s) in this hook must accept a single argument which indicates
|
||||
|
@ -244,7 +240,6 @@ normal outline commands like `show-all', but not with the cycling commands."
|
|||
:package-version '(Org . "9.6")
|
||||
:type 'boolean)
|
||||
|
||||
(defvaralias 'org-tab-first-hook 'org-cycle-tab-first-hook)
|
||||
(defvar org-cycle-tab-first-hook nil
|
||||
"Hook for functions to attach themselves to TAB.
|
||||
See `org-ctrl-c-ctrl-c-hook' for more information.
|
||||
|
@ -340,10 +335,6 @@ same as `S-TAB') also when called without prefix argument."
|
|||
(and org-cycle-level-after-item/entry-creation
|
||||
(or (org-cycle-level)
|
||||
(org-cycle-item-indentation))))
|
||||
(when (and org-cycle-max-level
|
||||
(or (not (integerp org-cycle-max-level))
|
||||
(< org-cycle-max-level 1)))
|
||||
(user-error "`org-cycle-max-level' must be a positive integer"))
|
||||
(let* ((limit-level
|
||||
(or org-cycle-max-level
|
||||
(and (boundp 'org-inlinetask-min-level)
|
||||
|
@ -397,8 +388,8 @@ same as `S-TAB') also when called without prefix argument."
|
|||
((org-fold-hide-drawer-toggle nil t element))
|
||||
;; Table: enter it or move to the next field.
|
||||
((and (org-match-line "[ \t]*[|+]")
|
||||
(org-element-lineage element 'table t))
|
||||
(if (and (org-element-type-p element 'table)
|
||||
(org-element-lineage element '(table) t))
|
||||
(if (and (eq 'table (org-element-type element))
|
||||
(eq 'table.el (org-element-property :type element)))
|
||||
(message (substitute-command-keys "\\<org-mode-map>\
|
||||
Use `\\[org-edit-special]' to edit table.el tables"))
|
||||
|
@ -413,8 +404,8 @@ Use `\\[org-edit-special]' to edit table.el tables"))
|
|||
t)))
|
||||
(and item
|
||||
(= (line-beginning-position)
|
||||
(org-element-post-affiliated
|
||||
item)))))
|
||||
(org-element-property :post-affiliated
|
||||
item)))))
|
||||
(org-match-line org-outline-regexp))
|
||||
(or (bolp) (not (eq org-cycle-emulate-tab 'exc-hl-bol))))
|
||||
(org-cycle-internal-local))
|
||||
|
@ -430,7 +421,7 @@ Use `\\[org-edit-special]' to edit table.el tables"))
|
|||
(call-interactively (global-key-binding (kbd "TAB"))))
|
||||
((or (eq org-cycle-emulate-tab t)
|
||||
(and (memq org-cycle-emulate-tab '(white whitestart))
|
||||
(save-excursion (forward-line 0) (looking-at "[ \t]*"))
|
||||
(save-excursion (beginning-of-line 1) (looking-at "[ \t]*"))
|
||||
(or (and (eq org-cycle-emulate-tab 'white)
|
||||
(= (match-end 0) (line-end-position)))
|
||||
(and (eq org-cycle-emulate-tab 'whitestart)
|
||||
|
@ -489,7 +480,7 @@ Use `\\[org-edit-special]' to edit table.el tables"))
|
|||
(save-excursion
|
||||
(if (org-at-item-p)
|
||||
(progn
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(setq struct (org-list-struct))
|
||||
(setq eoh (line-end-position))
|
||||
(setq eos (org-list-get-item-end-before-blank (point) struct))
|
||||
|
@ -511,16 +502,16 @@ Use `\\[org-edit-special]' to edit table.el tables"))
|
|||
(save-excursion
|
||||
(org-list-search-forward (org-item-beginning-re) eos t))))))
|
||||
;; Determine end invisible part of buffer (EOL)
|
||||
(forward-line 1)
|
||||
(beginning-of-line 2)
|
||||
(if (eq org-fold-core-style 'text-properties)
|
||||
(while (and (not (eobp)) ;this is like `next-line'
|
||||
(org-fold-folded-p (1- (point))))
|
||||
(goto-char (org-fold-next-visibility-change nil nil t))
|
||||
(and (eolp) (forward-line 1)))
|
||||
(and (eolp) (beginning-of-line 2)))
|
||||
(while (and (not (eobp)) ;this is like `next-line'
|
||||
(get-char-property (1- (point)) 'invisible))
|
||||
(goto-char (next-single-char-property-change (point) 'invisible))
|
||||
(and (eolp) (forward-line 1))))
|
||||
(and (eolp) (beginning-of-line 2))))
|
||||
(setq eol (point)))
|
||||
;; Find out what to do next and set `this-command'
|
||||
(cond
|
||||
|
@ -554,7 +545,7 @@ Use `\\[org-edit-special]' to edit table.el tables"))
|
|||
(save-excursion
|
||||
(org-back-to-heading)
|
||||
(while (org-list-search-forward (org-item-beginning-re) eos t)
|
||||
(forward-line 0)
|
||||
(beginning-of-line 1)
|
||||
(let* ((struct (org-list-struct))
|
||||
(prevs (org-list-prevs-alist struct))
|
||||
(end (org-list-get-bottom-point struct)))
|
||||
|
@ -619,7 +610,7 @@ With a numeric prefix, show all headlines up to that level."
|
|||
(cond
|
||||
;; `fold' is technically not allowed value, but it is often
|
||||
;; intuitively tried by users by analogy with #+STARTUP: fold.
|
||||
((memq org-startup-folded '(t fold overview))
|
||||
((memq org-startup-folded '(t fold))
|
||||
(org-cycle-overview))
|
||||
((eq org-startup-folded 'content)
|
||||
(org-cycle-content))
|
||||
|
@ -647,21 +638,20 @@ With a numeric prefix, show all headlines up to that level."
|
|||
"Switch subtree visibility according to VISIBILITY property."
|
||||
(interactive)
|
||||
(let ((regexp (org-re-property "VISIBILITY")))
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(org-with-point-at 1
|
||||
(while (re-search-forward regexp nil t)
|
||||
(let ((state (match-string 3)))
|
||||
(let ((state (match-string 3)))
|
||||
(if (not (org-at-property-p)) (outline-next-heading)
|
||||
(save-excursion
|
||||
(org-back-to-heading t)
|
||||
(org-fold-subtree t)
|
||||
(pcase state
|
||||
("folded"
|
||||
("folded"
|
||||
(org-fold-subtree t))
|
||||
("children"
|
||||
("children"
|
||||
(org-fold-show-hidden-entry)
|
||||
(org-fold-show-children))
|
||||
("content"
|
||||
("content"
|
||||
;; Newline before heading will be outside the
|
||||
;; narrowing. Make sure that it is revealed.
|
||||
(org-fold-heading nil)
|
||||
|
@ -669,9 +659,10 @@ With a numeric prefix, show all headlines up to that level."
|
|||
(save-restriction
|
||||
(org-narrow-to-subtree)
|
||||
(org-cycle-content))))
|
||||
((or "all" "showall")
|
||||
((or "all" "showall")
|
||||
(org-fold-show-subtree))
|
||||
(_ nil)))))))))
|
||||
(_ nil)))
|
||||
(org-end-of-subtree t)))))))
|
||||
|
||||
(defun org-cycle-overview ()
|
||||
"Switch to overview mode, showing only top-level headlines."
|
||||
|
@ -696,7 +687,7 @@ With a numeric prefix, show all headlines up to that level."
|
|||
|
||||
(defun org-cycle-content (&optional arg)
|
||||
"Show all headlines in the buffer, like a table of contents.
|
||||
With numerical argument ARG, show content up to level ARG."
|
||||
With numerical argument N, show content up to level N."
|
||||
(interactive "p")
|
||||
(org-fold-show-all '(headings))
|
||||
(save-excursion
|
||||
|
@ -718,9 +709,7 @@ With numerical argument ARG, show content up to level ARG."
|
|||
"Temporarily store scroll position to restore.")
|
||||
(defun org-cycle-optimize-window-after-visibility-change (state)
|
||||
"Adjust the window after a change in outline visibility.
|
||||
This function is the default value of the hook `org-cycle-hook'.
|
||||
STATE is the current outline visibility state. It should be one of
|
||||
symbols `content', `all', `folded', `children', or `subtree'."
|
||||
This function is the default value of the hook `org-cycle-hook'."
|
||||
(when (get-buffer-window (current-buffer))
|
||||
(let ((repeat (eq last-command this-command)))
|
||||
(unless repeat
|
||||
|
@ -806,9 +795,7 @@ STATE should be one of the symbols listed in the docstring of
|
|||
|
||||
(defun org-cycle-display-inline-images (state)
|
||||
"Auto display inline images under subtree when cycling.
|
||||
It works when `org-cycle-inline-images-display' is non-nil.
|
||||
STATE is the current outline visibility state. It should be one of
|
||||
symbols `content', `all', `folded', `children', or `subtree'."
|
||||
It works when `org-cycle-inline-images-display' is non-nil."
|
||||
(when org-cycle-inline-images-display
|
||||
(pcase state
|
||||
('children
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; org-datetree.el --- Create date entries in a tree -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Carsten Dominik <carsten.dominik@gmail.com>
|
||||
;; Keywords: outlines, hypermedia, calendar, wp
|
||||
|
@ -198,9 +198,9 @@ inserted into the buffer."
|
|||
(unless (bolp) (insert "\n"))
|
||||
(org-datetree-insert-line year month day insert))
|
||||
((= (string-to-number (match-string 1)) (or day month year))
|
||||
(forward-line 0))
|
||||
(beginning-of-line))
|
||||
(t
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(org-datetree-insert-line year month day insert)))))
|
||||
|
||||
(defun org-datetree-insert-line (year &optional month day text)
|
||||
|
@ -222,11 +222,11 @@ inserted into the buffer."
|
|||
(save-excursion
|
||||
(insert "\n")
|
||||
(org-indent-line)
|
||||
(org-insert-timestamp
|
||||
(org-insert-time-stamp
|
||||
(org-encode-time 0 0 0 day month year)
|
||||
nil
|
||||
(eq org-datetree-add-timestamp 'inactive))))
|
||||
(forward-line 0))
|
||||
(beginning-of-line))
|
||||
|
||||
(defun org-datetree-file-entry-under (txt d)
|
||||
"Insert a node TXT into the date tree under date D."
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; org-duration.el --- Library handling durations -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2017-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2017-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Nicolas Goaziou <mail@nicolasgoaziou.fr>
|
||||
;; Keywords: outlines, hypermedia, calendar, wp
|
||||
|
|
File diff suppressed because it is too large
Load Diff
6284
lisp/org-element.el
6284
lisp/org-element.el
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
;;; org-entities.el --- Support for Special Entities -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2010-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2010-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Carsten Dominik <carsten.dominik@gmail.com>,
|
||||
;; Ulf Stegemann <ulf at zeitform dot de>
|
||||
|
@ -29,7 +29,6 @@
|
|||
|
||||
(require 'org-macs)
|
||||
(org-assert-version)
|
||||
(require 'seq) ; Emacs 27 does not preload seq.el; for `seq-every-p'.
|
||||
|
||||
(declare-function org-mode "org" ())
|
||||
(declare-function org-toggle-pretty-entities "org" ())
|
||||
|
@ -42,19 +41,14 @@
|
|||
|
||||
(defun org-entities--user-safe-p (v)
|
||||
"Non-nil if V is a safe value for `org-entities-user'."
|
||||
(cond
|
||||
((not v) t)
|
||||
((listp v)
|
||||
(seq-every-p
|
||||
(lambda (e)
|
||||
(pcase e
|
||||
(`(,(and (pred stringp)
|
||||
(pred (string-match-p "\\`[a-zA-Z][a-zA-Z0-9]*\\'")))
|
||||
,(pred stringp) ,(pred booleanp) ,(pred stringp)
|
||||
,(pred stringp) ,(pred stringp) ,(pred stringp))
|
||||
t)
|
||||
(_ nil)))
|
||||
v))))
|
||||
(pcase v
|
||||
(`nil t)
|
||||
(`(,(and (pred stringp)
|
||||
(pred (string-match-p "\\`[a-zA-Z][a-zA-Z0-9]*\\'")))
|
||||
,(pred stringp) ,(pred booleanp) ,(pred stringp)
|
||||
,(pred stringp) ,(pred stringp) ,(pred stringp))
|
||||
t)
|
||||
(_ nil)))
|
||||
|
||||
(defcustom org-entities-user nil
|
||||
"User-defined entities used in Org to produce special characters.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; org-faces.el --- Face definitions -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2004-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2004-2023 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Carsten Dominik <carsten.dominik@gmail.com>
|
||||
;; Keywords: outlines, hypermedia, calendar, wp
|
||||
|
@ -108,7 +108,7 @@ color of the frame."
|
|||
"Face used for drawers."
|
||||
:group 'org-faces)
|
||||
|
||||
(defface org-property-value '((t :inherit default))
|
||||
(defface org-property-value nil
|
||||
"Face used for the value of a property."
|
||||
:group 'org-faces)
|
||||
|
||||
|
@ -389,10 +389,6 @@ changes."
|
|||
"Face used for tables."
|
||||
:group 'org-faces)
|
||||
|
||||
(defface org-table-row '((t :inherit org-table))
|
||||
"Face used to fontify whole table rows (including newlines and indentation)."
|
||||
:group 'org-faces)
|
||||
|
||||
(defface org-table-header '((t :inherit org-table
|
||||
:background "LightGray"
|
||||
:foreground "Black"))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; org-feed.el --- Add RSS feed items to Org files -*- lexical-binding: t; -*-
|
||||
;;
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
;;
|
||||
;; Author: Carsten Dominik <carsten.dominik@gmail.com>
|
||||
;; Keywords: outlines, hypermedia, calendar, wp
|
||||
|
@ -475,7 +475,7 @@ This will find DRAWER and extract the alist."
|
|||
(goto-char pos)
|
||||
(let ((end (save-excursion (org-end-of-subtree t t))))
|
||||
(if (re-search-forward
|
||||
(concat "^[ \t]*:" drawer ":[ \t]*\n\\(\\(?:.\\|\n\\)*?\\)\n[ \t]*:END:")
|
||||
(concat "^[ \t]*:" drawer ":[ \t]*\n\\([^\000]*?\\)\n[ \t]*:END:")
|
||||
end t)
|
||||
(read (match-string 1))
|
||||
nil))))
|
||||
|
@ -495,7 +495,7 @@ This will find DRAWER and extract the alist."
|
|||
(match-beginning 0)))))
|
||||
(outline-next-heading)
|
||||
(insert " :" drawer ":\n :END:\n")
|
||||
(forward-line -1))
|
||||
(beginning-of-line 0))
|
||||
(insert (pp-to-string status)))))
|
||||
|
||||
(defun org-feed-add-items (pos entries)
|
||||
|
@ -508,7 +508,7 @@ This will find DRAWER and extract the alist."
|
|||
(setq level (org-get-valid-level (length (match-string 1)) 1))
|
||||
(org-end-of-subtree t t)
|
||||
(skip-chars-backward " \t\n")
|
||||
(forward-line 1)
|
||||
(beginning-of-line 2)
|
||||
(setq pos (point))
|
||||
(while (setq entry (pop entries))
|
||||
(org-paste-subtree level entry 'yank))
|
||||
|
@ -565,7 +565,7 @@ If that property is already present, nothing changes."
|
|||
(let ((v (plist-get entry (intern (concat ":" name)))))
|
||||
(save-excursion
|
||||
(save-match-data
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(if (looking-at
|
||||
(concat "^\\([ \t]*\\)%" name "[ \t]*$"))
|
||||
(org-feed-make-indented-block
|
||||
|
@ -633,7 +633,7 @@ containing the properties `:guid' and `:item-full-text'."
|
|||
end (and (re-search-forward "</item>" nil t)
|
||||
(match-beginning 0)))
|
||||
(setq item (buffer-substring beg end)
|
||||
guid (if (string-match "<guid\\>.*?>\\(\\(?:.\\|\n\\)*?\\)</guid>" item)
|
||||
guid (if (string-match "<guid\\>.*?>\\([^\000]*?\\)</guid>" item)
|
||||
(xml-substitute-special (match-string-no-properties 1 item))))
|
||||
(setq entry (list :guid guid :item-full-text item))
|
||||
(push entry entries)
|
||||
|
@ -647,7 +647,7 @@ containing the properties `:guid' and `:item-full-text'."
|
|||
(with-temp-buffer
|
||||
(insert (plist-get entry :item-full-text))
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "<\\([a-zA-Z]+\\>\\).*?>\\(\\(?:.\\|\n\\)*?\\)</\\1>"
|
||||
(while (re-search-forward "<\\([a-zA-Z]+\\>\\).*?>\\([^\000]*?\\)</\\1>"
|
||||
nil t)
|
||||
(setq entry (plist-put entry
|
||||
(intern (concat ":" (match-string 1)))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
;;; org-fold-core.el --- Folding buffer text -*- lexical-binding: t; -*-
|
||||
;;
|
||||
;; Copyright (C) 2020-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2020-2023 Free Software Foundation, Inc.
|
||||
;;
|
||||
;; Author: Ihor Radchenko <yantar92 at posteo dot net>
|
||||
;; Author: Ihor Radchenko <yantar92 at gmail dot com>
|
||||
;; Keywords: folding, invisible text
|
||||
;; URL: https://orgmode.org
|
||||
;;
|
||||
|
@ -280,13 +280,12 @@
|
|||
|
||||
;;; Customization
|
||||
|
||||
(defcustom org-fold-core-style (if (version< emacs-version "29")
|
||||
'text-properties
|
||||
'overlays)
|
||||
(defcustom org-fold-core-style 'text-properties
|
||||
"Internal implementation detail used to hide folded text.
|
||||
Can be either `text-properties' or `overlays'.
|
||||
The former is faster on large files in Emacs <29, while the latter is
|
||||
generally less error-prone with regard to third-party packages.
|
||||
The former is faster on large files, while the latter is generally
|
||||
less error-prone with regard to third-party packages that haven't yet
|
||||
adapted to the new folding implementation.
|
||||
|
||||
Important: This variable must be set before loading Org."
|
||||
:group 'org
|
||||
|
@ -381,9 +380,6 @@ The following properties are known:
|
|||
`buffer-invisibility-spec' will be used as is.
|
||||
Note that changing this property from nil to t may
|
||||
clear the setting in `buffer-invisibility-spec'.
|
||||
- :font-lock :: non-nil means that newlines after the fold should
|
||||
be re-fontified upon folding/unfolding. See
|
||||
`org-activate-folds'.
|
||||
- :alias :: a list of aliases for the SPEC-SYMBOL.
|
||||
- :fragile :: Must be a function accepting two arguments.
|
||||
Non-nil means that changes in region may cause
|
||||
|
@ -428,7 +424,7 @@ Return nil when there is no matching folding spec."
|
|||
(unless org-fold-core--spec-symbols
|
||||
(dolist (spec (org-fold-core-folding-spec-list))
|
||||
(push (cons spec spec) org-fold-core--spec-symbols)
|
||||
(dolist (alias (cdr (assq :alias (assq spec org-fold-core--specs))))
|
||||
(dolist (alias (assq :alias (assq spec org-fold-core--specs)))
|
||||
(push (cons alias spec) org-fold-core--spec-symbols))))
|
||||
(alist-get spec-or-alias org-fold-core--spec-symbols)))
|
||||
|
||||
|
@ -437,7 +433,7 @@ Return nil when there is no matching folding spec."
|
|||
(org-fold-core-get-folding-spec-from-alias spec-or-alias))
|
||||
|
||||
(defsubst org-fold-core--check-spec (spec-or-alias)
|
||||
"Throw an error if SPEC-OR-ALIAS is not in `org-fold-core-folding-spec-list'."
|
||||
"Throw an error if SPEC-OR-ALIAS is not in `org-fold-core--spec-priority-list'."
|
||||
(unless (org-fold-core-folding-spec-p spec-or-alias)
|
||||
(error "%s is not a valid folding spec" spec-or-alias)))
|
||||
|
||||
|
@ -506,34 +502,26 @@ hanging around."
|
|||
;; different buffer. This can happen, for example, when
|
||||
;; org-capture copies local variables into *Capture* buffer.
|
||||
(setq buffers (list (current-buffer)))
|
||||
(let ((all-buffers (buffer-local-value
|
||||
'org-fold-core--indirect-buffers
|
||||
(or (buffer-base-buffer) (current-buffer)))))
|
||||
(dolist (buf (cons (or (buffer-base-buffer) (current-buffer))
|
||||
(buffer-local-value 'org-fold-core--indirect-buffers (or (buffer-base-buffer) (current-buffer)))))
|
||||
(if (buffer-live-p buf)
|
||||
(push buf buffers)
|
||||
(dolist (spec (org-fold-core-folding-spec-list))
|
||||
(when (and (not (org-fold-core-get-folding-spec-property spec :global))
|
||||
(gethash (cons buf spec) org-fold-core--property-symbol-cache))
|
||||
;; Make sure that dead-properties variable can be passed
|
||||
;; as argument to `remove-text-properties'.
|
||||
(push t dead-properties)
|
||||
(push (gethash (cons buf spec) org-fold-core--property-symbol-cache)
|
||||
dead-properties)))))
|
||||
(when dead-properties
|
||||
(with-current-buffer (or (buffer-base-buffer) (current-buffer))
|
||||
(setq-local org-fold-core--indirect-buffers
|
||||
(seq-filter #'buffer-live-p all-buffers))))))
|
||||
(dolist (buf (cons (or (buffer-base-buffer) (current-buffer))
|
||||
(buffer-local-value 'org-fold-core--indirect-buffers (or (buffer-base-buffer) (current-buffer)))))
|
||||
(if (buffer-live-p buf)
|
||||
(push buf buffers)
|
||||
(dolist (spec (org-fold-core-folding-spec-list))
|
||||
(when (and (not (org-fold-core-get-folding-spec-property spec :global))
|
||||
(gethash (cons buf spec) org-fold-core--property-symbol-cache))
|
||||
;; Make sure that dead-properties variable can be passed
|
||||
;; as argument to `remove-text-properties'.
|
||||
(push t dead-properties)
|
||||
(push (gethash (cons buf spec) org-fold-core--property-symbol-cache)
|
||||
dead-properties))))))
|
||||
(dolist (buf buffers)
|
||||
(with-current-buffer buf
|
||||
(when dead-properties
|
||||
(with-silent-modifications
|
||||
(save-restriction
|
||||
(widen)
|
||||
(remove-text-properties
|
||||
(point-min) (point-max)
|
||||
dead-properties))))
|
||||
(with-silent-modifications
|
||||
(save-restriction
|
||||
(widen)
|
||||
(remove-text-properties
|
||||
(point-min) (point-max)
|
||||
dead-properties)))
|
||||
,@body))))
|
||||
|
||||
;; This is the core function used to fold text in buffers. We use
|
||||
|
@ -557,10 +545,7 @@ and the setup appears to be created for different buffer,
|
|||
copy the old invisibility state into new buffer-local text properties,
|
||||
unless RETURN-ONLY is non-nil."
|
||||
(if (eq org-fold-core-style 'overlays)
|
||||
(or (gethash (cons 'global spec) org-fold-core--property-symbol-cache)
|
||||
(puthash (cons 'global spec)
|
||||
(org-fold-core-get-folding-property-symbol spec nil 'global)
|
||||
org-fold-core--property-symbol-cache))
|
||||
(org-fold-core-get-folding-property-symbol spec nil 'global)
|
||||
(let* ((buf (or buffer (current-buffer))))
|
||||
;; Create unique property symbol for SPEC in BUFFER
|
||||
(let ((local-prop (or (gethash (cons buf spec) org-fold-core--property-symbol-cache)
|
||||
|
@ -640,10 +625,6 @@ unless RETURN-ONLY is non-nil."
|
|||
text-property-default-nonsticky
|
||||
full-prop-list))))))))))))))
|
||||
|
||||
(defun org-fold-core--update-buffer-folds ()
|
||||
"Copy folding state in a new buffer with text copied from old buffer."
|
||||
(org-fold-core--property-symbol-get-create (car (org-fold-core-folding-spec-list))))
|
||||
|
||||
(defun org-fold-core-decouple-indirect-buffer-folds ()
|
||||
"Copy and decouple folding state in a newly created indirect buffer.
|
||||
This function is mostly intended to be used in
|
||||
|
@ -651,7 +632,7 @@ This function is mostly intended to be used in
|
|||
(when (and (buffer-base-buffer)
|
||||
(eq org-fold-core-style 'text-properties)
|
||||
(not (memql 'ignore-indirect org-fold-core--optimise-for-huge-buffers)))
|
||||
(org-fold-core--update-buffer-folds)))
|
||||
(org-fold-core--property-symbol-get-create (car (org-fold-core-folding-spec-list)))))
|
||||
|
||||
;;; API
|
||||
|
||||
|
@ -794,19 +775,16 @@ corresponding folding spec (if the text is folded using that spec)."
|
|||
(when (and spec (not (eq spec 'all))) (org-fold-core--check-spec spec))
|
||||
(org-with-point-at pom
|
||||
(cond
|
||||
((or (null spec) (eq spec 'all))
|
||||
(catch :single-spec
|
||||
(let ((result))
|
||||
(dolist (lspec (org-fold-core-folding-spec-list))
|
||||
(let ((val (if (eq org-fold-core-style 'text-properties)
|
||||
(get-text-property (point) (org-fold-core--property-symbol-get-create lspec nil t))
|
||||
(get-char-property (point) (org-fold-core--property-symbol-get-create lspec nil t)))))
|
||||
(when (and val (null spec)) (throw :single-spec val))
|
||||
(when val (push val result))))
|
||||
(reverse result))))
|
||||
(t (if (eq org-fold-core-style 'text-properties)
|
||||
(get-text-property (point) (org-fold-core--property-symbol-get-create spec nil t))
|
||||
(get-char-property (point) (org-fold-core--property-symbol-get-create spec nil t))))))))
|
||||
((eq spec 'all)
|
||||
(let ((result))
|
||||
(dolist (spec (org-fold-core-folding-spec-list))
|
||||
(let ((val (get-char-property (point) (org-fold-core--property-symbol-get-create spec nil t))))
|
||||
(when val (push val result))))
|
||||
(reverse result)))
|
||||
((null spec)
|
||||
(let ((result (get-char-property (point) 'invisible)))
|
||||
(when (org-fold-core-folding-spec-p result) result)))
|
||||
(t (get-char-property (point) (org-fold-core--property-symbol-get-create spec nil t)))))))
|
||||
|
||||
(defun org-fold-core-get-folding-specs-in-region (beg end)
|
||||
"Get all folding specs in region from BEG to END."
|
||||
|
@ -918,19 +896,14 @@ Search backwards when PREVIOUS-P is non-nil."
|
|||
(unless spec-or-alias
|
||||
(setq spec-or-alias (org-fold-core-folding-spec-list)))
|
||||
(setq pos (or pos (point)))
|
||||
(let ((limit (or limit (if previous-p (point-min) (point-max)))))
|
||||
(catch :limit
|
||||
(dolist (prop (mapcar
|
||||
(lambda (el)
|
||||
(org-fold-core--property-symbol-get-create el nil t))
|
||||
spec-or-alias))
|
||||
(when (= limit pos) (throw :limit limit))
|
||||
(setq
|
||||
limit
|
||||
(if previous-p
|
||||
(previous-single-char-property-change pos prop nil limit)
|
||||
(next-single-char-property-change pos prop nil limit))))
|
||||
limit)))
|
||||
(apply (if previous-p
|
||||
#'max
|
||||
#'min)
|
||||
(mapcar (if previous-p
|
||||
(lambda (prop) (max (or limit (point-min)) (previous-single-char-property-change pos prop nil (or limit (point-min)))))
|
||||
(lambda (prop) (next-single-char-property-change pos prop nil (or limit (point-max)))))
|
||||
(mapcar (lambda (el) (org-fold-core--property-symbol-get-create el nil t))
|
||||
spec-or-alias))))
|
||||
|
||||
(defun org-fold-core-previous-folding-state-change (&optional spec-or-alias pos limit)
|
||||
"Call `org-fold-core-next-folding-state-change' searching backwards."
|
||||
|
@ -1011,24 +984,6 @@ WITH-MARKERS must be nil when RELATIVE is non-nil."
|
|||
|
||||
;;;;; Region visibility
|
||||
|
||||
(defvar org-fold-core--keep-overlays nil
|
||||
"When non-nil, `org-fold-core-region' will not remove existing overlays.")
|
||||
(defvar org-fold-core--isearch-overlays) ; defined below
|
||||
(defmacro org-fold-core--keep-overlays (&rest body)
|
||||
"Run BODY with `org-fold-core--keep-overlays' set to t."
|
||||
(declare (debug (body)))
|
||||
`(let ((org-fold-core--keep-overlays t))
|
||||
,@body))
|
||||
|
||||
(defvar org-fold-core--isearch-active nil
|
||||
"When non-nil, `org-fold-core-region' records created overlays.
|
||||
New overlays will be added to `org-fold-core--isearch-overlays'.")
|
||||
(defmacro org-fold-core--with-isearch-active (&rest body)
|
||||
"Run BODY with `org-fold-core--isearch-active' set to t."
|
||||
(declare (debug (body)))
|
||||
`(let ((org-fold-core--isearch-active t))
|
||||
,@body))
|
||||
|
||||
;; This is the core function performing actual folding/unfolding. The
|
||||
;; folding state is stored in text property (folding property)
|
||||
;; returned by `org-fold-core--property-symbol-get-create'. The value of the
|
||||
|
@ -1041,43 +996,7 @@ If SPEC-OR-ALIAS is omitted and FLAG is nil, unfold everything in the region."
|
|||
(when spec (org-fold-core--check-spec spec))
|
||||
(with-silent-modifications
|
||||
(org-with-wide-buffer
|
||||
;; Arrange fontifying newlines after all the folds between FROM
|
||||
;; and TO to match the first character before the fold; not the
|
||||
;; last as per Emacs defaults. This makes :extend faces span
|
||||
;; past the ellipsis. See bug#65896. The face properties are
|
||||
;; assigned via `org-activate-folds'.
|
||||
(when (or (not spec) (org-fold-core-get-folding-spec-property spec :font-lock))
|
||||
(when (equal ?\n (char-after from))
|
||||
(font-lock-flush from (1+ from)))
|
||||
(when (equal ?\n (char-after to))
|
||||
(font-lock-flush to (1+ to)))
|
||||
(dolist (region (org-fold-core-get-regions :from from :to to :specs spec))
|
||||
(when (equal ?\n (char-after (cadr region)))
|
||||
(font-lock-flush (cadr region) (1+ (cadr region))))
|
||||
;; Re-fontify beginning of the fold - we may
|
||||
;; unfold inside an existing fold, with FROM begin a newline
|
||||
;; after spliced fold.
|
||||
(when (equal ?\n (char-after (car region)))
|
||||
(font-lock-flush (car region) (1+ (car region))))))
|
||||
(when (eq org-fold-core-style 'overlays)
|
||||
(if org-fold-core--keep-overlays
|
||||
(mapc
|
||||
(lambda (ov)
|
||||
(when (or (not spec)
|
||||
(eq spec (overlay-get ov 'invisible)))
|
||||
(when (and org-fold-core--isearch-active
|
||||
(overlay-get ov 'invisible)
|
||||
(org-fold-core-get-folding-spec-property
|
||||
(overlay-get ov 'invisible) :isearch-open))
|
||||
(when (overlay-get ov 'invisible)
|
||||
(overlay-put ov 'org-invisible (overlay-get ov 'invisible)))
|
||||
(overlay-put ov 'invisible nil)
|
||||
(when org-fold-core--isearch-active
|
||||
(cl-pushnew ov org-fold-core--isearch-overlays)))))
|
||||
(overlays-in from to))
|
||||
(when spec
|
||||
(remove-overlays from to 'org-invisible spec)
|
||||
(remove-overlays from to 'invisible spec))))
|
||||
(when (eq org-fold-core-style 'overlays) (remove-overlays from to 'invisible spec))
|
||||
(if flag
|
||||
(if (not spec)
|
||||
(error "Calling `org-fold-core-region' with missing SPEC")
|
||||
|
@ -1087,15 +1006,17 @@ If SPEC-OR-ALIAS is omitted and FLAG is nil, unfold everything in the region."
|
|||
(let ((o (make-overlay from to nil
|
||||
(org-fold-core-get-folding-spec-property spec :front-sticky)
|
||||
(org-fold-core-get-folding-spec-property spec :rear-sticky))))
|
||||
(when org-fold-core--isearch-active
|
||||
(push o org-fold-core--isearch-overlays))
|
||||
(overlay-put o 'evaporate t)
|
||||
(overlay-put o (org-fold-core--property-symbol-get-create spec) spec)
|
||||
(overlay-put o 'invisible spec)
|
||||
;; Preserve priority.
|
||||
(overlay-put o 'priority (length (member spec (org-fold-core-folding-spec-list))))
|
||||
(overlay-put o 'isearch-open-invisible #'org-fold-core--isearch-show)
|
||||
(overlay-put o 'isearch-open-invisible-temporary #'org-fold-core--isearch-show-temporary))
|
||||
;; FIXME: Disabling to work around Emacs bug#60399
|
||||
;; and https://orgmode.org/list/87zgb6tk6h.fsf@localhost.
|
||||
;; The proper fix will require making sure that
|
||||
;; `org-fold-core-isearch-open-function' does not
|
||||
;; delete the overlays used by isearch.
|
||||
;; (overlay-put o 'isearch-open-invisible-temporary #'org-fold-core--isearch-show-temporary)
|
||||
)
|
||||
(put-text-property from to (org-fold-core--property-symbol-get-create spec) spec)
|
||||
(put-text-property from to 'isearch-open-invisible #'org-fold-core--isearch-show)
|
||||
(put-text-property from to 'isearch-open-invisible-temporary #'org-fold-core--isearch-show-temporary)
|
||||
|
@ -1119,13 +1040,7 @@ If SPEC-OR-ALIAS is omitted and FLAG is nil, unfold everything in the region."
|
|||
(setq pos next))
|
||||
(setq pos (next-single-char-property-change pos 'invisible nil to)))))))
|
||||
(when (eq org-fold-core-style 'text-properties)
|
||||
(remove-text-properties from to (list (org-fold-core--property-symbol-get-create spec) nil)))))
|
||||
;; Re-calculate trailing faces for all the folds revealed
|
||||
;; by unfolding or created by folding.
|
||||
(when (or (not spec) (org-fold-core-get-folding-spec-property spec :font-lock))
|
||||
(dolist (region (org-fold-core-get-regions :from from :to to :specs spec))
|
||||
(when (equal ?\n (char-after (cadr region)))
|
||||
(font-lock-flush (cadr region) (1+ (cadr region))))))))))
|
||||
(remove-text-properties from to (list (org-fold-core--property-symbol-get-create spec) nil)))))))))
|
||||
|
||||
(cl-defmacro org-fold-core-regions (regions &key override clean-markers relative)
|
||||
"Fold every region in REGIONS list in current buffer.
|
||||
|
@ -1188,19 +1103,13 @@ TYPE can be either `text-properties' or `overlays'."
|
|||
(setq-local isearch-filter-predicate #'org-fold-core--isearch-filter-predicate-text-properties))
|
||||
(`overlays
|
||||
(when (eq org-fold-core-style 'text-properties)
|
||||
(add-function :before (local 'isearch-filter-predicate) #'org-fold-core--create-isearch-overlays)
|
||||
;; When `isearch-filter-predicate' is called outside isearch,
|
||||
;; it is common that `isearch-mode-end-hook' does not get
|
||||
;; executed, but `isearch-clean-overlays' usually does.
|
||||
(advice-add
|
||||
'isearch-clean-overlays :after
|
||||
#'org-fold-core--clear-isearch-overlays
|
||||
'((name . isearch-clean-overlays@org-fold-core)))))
|
||||
(setq-local isearch-filter-predicate #'org-fold-core--isearch-filter-predicate-overlays)
|
||||
(add-hook 'isearch-mode-end-hook #'org-fold-core--clear-isearch-overlays nil 'local)))
|
||||
(_ (error "%s: Unknown type of setup for `org-fold-core--isearch-setup'" type))))
|
||||
|
||||
(defun org-fold-core--isearch-reveal (pos)
|
||||
"Default function used to reveal hidden text at POS for isearch."
|
||||
(let ((region (org-fold-core-get-region-at-point nil pos)))
|
||||
(let ((region (org-fold-core-get-region-at-point pos)))
|
||||
(org-fold-core-region (car region) (cdr region) nil)))
|
||||
|
||||
(defun org-fold-core--isearch-filter-predicate-text-properties (beg end)
|
||||
|
@ -1235,35 +1144,34 @@ This function is intended to be used as `isearch-filter-predicate'."
|
|||
"Clear `org-fold-core--isearch-local-regions'."
|
||||
(clrhash org-fold-core--isearch-local-regions))
|
||||
|
||||
(defun org-fold-core--isearch-show (overlay-or-region)
|
||||
"Reveal text at OVERLAY-OR-REGION found by isearch."
|
||||
(let (beg end)
|
||||
(if (overlayp overlay-or-region)
|
||||
(setq beg (overlay-start overlay-or-region)
|
||||
end (overlay-end overlay-or-region))
|
||||
(setq beg (car overlay-or-region)
|
||||
end (cdr overlay-or-region)))
|
||||
;; FIXME: Reveal the match (usually point, but may sometimes go beyond the region).
|
||||
(when (< beg (point) end)
|
||||
(funcall org-fold-core-isearch-open-function (point)))
|
||||
(org-fold-core-region beg end nil)))
|
||||
(defun org-fold-core--isearch-show (_)
|
||||
"Reveal text at point found by isearch."
|
||||
(funcall org-fold-core-isearch-open-function (point)))
|
||||
|
||||
(defun org-fold-core--isearch-show-temporary (region hide-p)
|
||||
"Temporarily reveal text in REGION.
|
||||
Hide text instead if HIDE-P is non-nil.
|
||||
REGION can also be an overlay in current buffer."
|
||||
(save-match-data ; match data must not be modified.
|
||||
(let ((org-fold-core-style (if (overlayp region) 'overlays 'text-properties)))
|
||||
(if hide-p
|
||||
(if (not (overlayp region))
|
||||
nil ;; FIXME: after isearch supports text properties.
|
||||
(when (overlay-get region 'org-invisible)
|
||||
(overlay-put region 'invisible (overlay-get region 'org-invisible))))
|
||||
;; isearch expects all the temporarily opened overlays to exist.
|
||||
;; See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=60399
|
||||
(org-fold-core--keep-overlays
|
||||
(org-fold-core--with-isearch-active
|
||||
(org-fold-core--isearch-show region)))))))
|
||||
(when (overlayp region)
|
||||
(setq region (cons (overlay-start region)
|
||||
(overlay-end region))))
|
||||
(if (not hide-p)
|
||||
(let ((pos (car region)))
|
||||
(while (< pos (cdr region))
|
||||
(let ((spec-no-open
|
||||
(catch :found
|
||||
(dolist (spec (org-fold-core-get-folding-spec 'all pos))
|
||||
(unless (org-fold-core-get-folding-spec-property spec :isearch-open)
|
||||
(throw :found spec))))))
|
||||
(if spec-no-open
|
||||
;; Skip regions folded with folding specs that cannot be opened.
|
||||
(setq pos (org-fold-core-next-folding-state-change spec-no-open pos (cdr region)))
|
||||
(dolist (spec (org-fold-core-get-folding-spec 'all pos))
|
||||
(push (cons spec (org-fold-core-get-region-at-point spec pos)) (gethash region org-fold-core--isearch-local-regions)))
|
||||
(org-fold-core--isearch-show region)
|
||||
(setq pos (org-fold-core-next-folding-state-change nil pos (cdr region)))))))
|
||||
(mapc (lambda (val) (org-fold-core-region (cadr val) (cddr val) t (car val))) (gethash region org-fold-core--isearch-local-regions))
|
||||
(remhash region org-fold-core--isearch-local-regions)))
|
||||
|
||||
(defvar-local org-fold-core--isearch-special-specs nil
|
||||
"List of specs that can break visibility state when converted to overlays.
|
||||
|
@ -1278,28 +1186,49 @@ instead of text properties. The created overlays will be stored in
|
|||
(while (< pos end)
|
||||
;; We need loop below to make sure that we clean all invisible
|
||||
;; properties, which may be nested.
|
||||
(catch :repeat
|
||||
(dolist (spec (org-fold-core-get-folding-spec 'all pos))
|
||||
(unless (org-fold-core-get-folding-spec-property spec :isearch-ignore)
|
||||
(let* ((region (org-fold-core-get-region-at-point spec pos)))
|
||||
(when (memq spec org-fold-core--isearch-special-specs)
|
||||
(setq end (max end (cdr region)))
|
||||
(when (< (car region) beg)
|
||||
(setq beg (car region))
|
||||
(setq pos beg)
|
||||
(throw :repeat t)))
|
||||
;; Changing text properties is considered buffer modification.
|
||||
;; We do not want it here.
|
||||
(with-silent-modifications
|
||||
(org-fold-core-region (car region) (cdr region) nil spec)
|
||||
(let ((org-fold-core-style 'overlays))
|
||||
(org-fold-core--with-isearch-active
|
||||
(org-fold-core-region (car region) (cdr region) t spec)))))))
|
||||
(setq pos (org-fold-core-next-folding-state-change nil pos end))))))
|
||||
(dolist (spec (org-fold-core-get-folding-spec 'all pos))
|
||||
(unless (org-fold-core-get-folding-spec-property spec :isearch-ignore)
|
||||
(let* ((region (org-fold-core-get-region-at-point spec pos)))
|
||||
(when (memq spec org-fold-core--isearch-special-specs)
|
||||
(setq pos (min pos (car region)))
|
||||
(setq end (max end (cdr region))))
|
||||
;; Changing text properties is considered buffer modification.
|
||||
;; We do not want it here.
|
||||
(with-silent-modifications
|
||||
(org-fold-core-region (car region) (cdr region) nil spec)
|
||||
;; The overlay is modeled after `outline-flag-region'
|
||||
;; [2020-05-09 Sat] overlay for 'outline blocks.
|
||||
(let ((o (make-overlay (car region) (cdr region) nil 'front-advance)))
|
||||
(overlay-put o 'evaporate t)
|
||||
(overlay-put o 'invisible spec)
|
||||
(overlay-put o 'org-invisible spec)
|
||||
;; Make sure that overlays are applied in the same order
|
||||
;; with the folding specs.
|
||||
;; Note: `memq` returns cdr with car equal to the first
|
||||
;; found matching element.
|
||||
(overlay-put o 'priority (length (memq spec (org-fold-core-folding-spec-list))))
|
||||
;; `delete-overlay' here means that spec information will be lost
|
||||
;; for the region. The region will remain visible.
|
||||
(if (org-fold-core-get-folding-spec-property spec :isearch-open)
|
||||
(overlay-put o 'isearch-open-invisible #'delete-overlay)
|
||||
(overlay-put o 'isearch-open-invisible #'ignore)
|
||||
(overlay-put o 'isearch-open-invisible-temporary #'ignore))
|
||||
(push o org-fold-core--isearch-overlays))))))
|
||||
(setq pos (org-fold-core-next-folding-state-change nil pos end)))))
|
||||
|
||||
(defun org-fold-core--isearch-filter-predicate-overlays (beg end)
|
||||
"Return non-nil if text between BEG and END is deemed visible by isearch.
|
||||
This function is intended to be used as `isearch-filter-predicate'."
|
||||
(org-fold-core--create-isearch-overlays beg end) ;; trick isearch by creating overlays in place of invisible text
|
||||
(isearch-filter-visible beg end))
|
||||
|
||||
(defun org-fold-core--clear-isearch-overlay (ov)
|
||||
"Convert OV region back into using text properties."
|
||||
(let ((spec (overlay-get ov 'invisible)))
|
||||
(let ((spec (if isearch-mode-end-hook-quit
|
||||
;; Restore all folds.
|
||||
(overlay-get ov 'org-invisible)
|
||||
;; Leave opened folds open.
|
||||
(overlay-get ov 'invisible))))
|
||||
;; Ignore deleted overlays.
|
||||
(when (and spec
|
||||
(overlay-buffer ov))
|
||||
|
@ -1308,6 +1237,8 @@ instead of text properties. The created overlays will be stored in
|
|||
(with-silent-modifications
|
||||
(when (<= (overlay-end ov) (point-max))
|
||||
(org-fold-core-region (overlay-start ov) (overlay-end ov) t spec)))))
|
||||
(when (member ov isearch-opened-overlays)
|
||||
(setq isearch-opened-overlays (delete ov isearch-opened-overlays)))
|
||||
(delete-overlay ov))
|
||||
|
||||
(defun org-fold-core--clear-isearch-overlays ()
|
||||
|
@ -1322,8 +1253,6 @@ instead of text properties. The created overlays will be stored in
|
|||
"Non-nil: skip processing modifications in `org-fold-core--fix-folded-region'.")
|
||||
(defvar org-fold-core--ignore-fragility-checks nil
|
||||
"Non-nil: skip fragility checks in `org-fold-core--fix-folded-region'.")
|
||||
(defvar org-fold-core--suppress-folding-fix nil
|
||||
"Non-nil: skip folding fix in `org-fold-core--fix-folded-region'.")
|
||||
|
||||
(defmacro org-fold-core-ignore-modifications (&rest body)
|
||||
"Run BODY ignoring buffer modifications in `org-fold-core--fix-folded-region'."
|
||||
|
@ -1332,47 +1261,12 @@ instead of text properties. The created overlays will be stored in
|
|||
(unwind-protect (progn ,@body)
|
||||
(setq org-fold-core--last-buffer-chars-modified-tick (buffer-chars-modified-tick)))))
|
||||
|
||||
(defmacro org-fold-core-suppress-folding-fix (&rest body)
|
||||
"Run BODY skipping re-folding checks in `org-fold-core--fix-folded-region'."
|
||||
(declare (debug (form body)) (indent 0))
|
||||
`(let ((org-fold-core--suppress-folding-fix t))
|
||||
(progn ,@body)))
|
||||
|
||||
(defmacro org-fold-core-ignore-fragility-checks (&rest body)
|
||||
"Run BODY skipping :fragility checks in `org-fold-core--fix-folded-region'."
|
||||
(declare (debug (form body)) (indent 0))
|
||||
`(let ((org-fold-core--ignore-fragility-checks t))
|
||||
(progn ,@body)))
|
||||
|
||||
(defvar org-fold-core--region-delayed-list nil
|
||||
"List holding (MKFROM MKTO FLAG SPEC-OR-ALIAS) arguments to process.
|
||||
The list is used by `org-fold-core--region-delayed'.")
|
||||
(defun org-fold-core--region-delayed (from to flag &optional spec-or-alias)
|
||||
"Call `org-fold-core-region' after current command.
|
||||
Pass the same FROM, TO, FLAG, and SPEC-OR-ALIAS."
|
||||
;; Setup delayed folding.
|
||||
(add-hook 'post-command-hook #'org-fold-core--process-delayed)
|
||||
(let ((frommk (make-marker))
|
||||
(tomk (make-marker)))
|
||||
(set-marker frommk from (current-buffer))
|
||||
(set-marker tomk to (current-buffer))
|
||||
(push (list frommk tomk flag spec-or-alias) org-fold-core--region-delayed-list)))
|
||||
|
||||
(defun org-fold-core--process-delayed ()
|
||||
"Perform folding for `org-fold-core--region-delayed-list'."
|
||||
(when org-fold-core--region-delayed-list
|
||||
(mapc (lambda (args)
|
||||
(when (and (buffer-live-p (marker-buffer (nth 0 args)))
|
||||
(buffer-live-p (marker-buffer (nth 1 args)))
|
||||
(< (nth 0 args) (nth 1 args)))
|
||||
(org-with-point-at (car args)
|
||||
(apply #'org-fold-core-region args))))
|
||||
;; Restore the initial folding order.
|
||||
(nreverse org-fold-core--region-delayed-list))
|
||||
;; Cleanup `post-command-hook'.
|
||||
(remove-hook 'post-command-hook #'org-fold-core--process-delayed)
|
||||
(setq org-fold-core--region-delayed-list nil)))
|
||||
|
||||
(defvar-local org-fold-core--last-buffer-chars-modified-tick nil
|
||||
"Variable storing the last return value of `buffer-chars-modified-tick'.")
|
||||
|
||||
|
@ -1390,19 +1284,19 @@ to :front-sticky/:rear-sticky folding spec property.
|
|||
If the folded region is folded with a spec with non-nil :fragile
|
||||
property, unfold the region if the :fragile function returns non-nil."
|
||||
;; If no insertions or deletions in buffer, skip all the checks.
|
||||
(unless (or org-fold-core--ignore-modifications
|
||||
(eq org-fold-core--last-buffer-chars-modified-tick (buffer-chars-modified-tick))
|
||||
(unless (or (eq org-fold-core--last-buffer-chars-modified-tick (buffer-chars-modified-tick))
|
||||
org-fold-core--ignore-modifications
|
||||
(memql 'ignore-modification-checks org-fold-core--optimise-for-huge-buffers))
|
||||
;; Store the new buffer modification state.
|
||||
(setq org-fold-core--last-buffer-chars-modified-tick (buffer-chars-modified-tick))
|
||||
(save-match-data
|
||||
;; Handle changes in all the indirect buffers and in the base
|
||||
;; buffer. Work around Emacs bug#46982.
|
||||
;; Re-hide text inserted in the middle/front/back of a folded
|
||||
;; region.
|
||||
(unless (or org-fold-core--suppress-folding-fix (equal from to)) ; Ignore deletions.
|
||||
(when (eq org-fold-core-style 'text-properties)
|
||||
(org-fold-core-cycle-over-indirect-buffers
|
||||
(when (eq org-fold-core-style 'text-properties)
|
||||
(org-fold-core-cycle-over-indirect-buffers
|
||||
;; Re-hide text inserted in the middle/front/back of a folded
|
||||
;; region.
|
||||
(unless (equal from to) ; Ignore deletions.
|
||||
(dolist (spec (org-fold-core-folding-spec-list))
|
||||
;; Reveal fully invisible text inserted in the middle
|
||||
;; of visible portion of the buffer. This is needed,
|
||||
|
@ -1490,10 +1384,7 @@ property, unfold the region if the :fragile function returns non-nil."
|
|||
(cons fold-begin fold-end)
|
||||
spec))
|
||||
;; Reveal completely, not just from the SPEC.
|
||||
;; Do it only after command is finished -
|
||||
;; some Emacs commands assume that
|
||||
;; visibility is not altered by `after-change-functions'.
|
||||
(org-fold-core--region-delayed fold-begin fold-end nil)))))
|
||||
(org-fold-core-region fold-begin fold-end nil)))))
|
||||
;; Move to next fold.
|
||||
(setq pos (org-fold-core-next-folding-state-change spec pos local-to)))))))))))))
|
||||
|
||||
|
|
149
lisp/org-fold.el
149
lisp/org-fold.el
|
@ -1,8 +1,8 @@
|
|||
;;; org-fold.el --- Folding of Org entries -*- lexical-binding: t; -*-
|
||||
;;
|
||||
;; Copyright (C) 2020-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2020-2023 Free Software Foundation, Inc.
|
||||
;;
|
||||
;; Author: Ihor Radchenko <yantar92 at posteo dot net>
|
||||
;; Author: Ihor Radchenko <yantar92 at gmail dot com>
|
||||
;; Keywords: folding, invisible text
|
||||
;; URL: https://orgmode.org
|
||||
;;
|
||||
|
@ -61,12 +61,11 @@
|
|||
(defvar org-element-headline-re)
|
||||
|
||||
(declare-function isearch-filter-visible "isearch" (beg end))
|
||||
(declare-function org-element-type "org-element-ast" (node &optional anonymous))
|
||||
(declare-function org-element-type "org-element" (element))
|
||||
(declare-function org-element-at-point "org-element" (&optional pom cached-only))
|
||||
(declare-function org-element-property "org-element-ast" (property node))
|
||||
(declare-function org-element-end "org-element" (node))
|
||||
(declare-function org-element-post-affiliated "org-element" (node))
|
||||
(declare-function org-element-property "org-element" (property element))
|
||||
(declare-function org-element--current-element "org-element" (limit &optional granularity mode structure))
|
||||
(declare-function org-element--cache-active-p "org-element" ())
|
||||
(declare-function org-toggle-custom-properties-visibility "org" ())
|
||||
(declare-function org-item-re "org-list" ())
|
||||
(declare-function org-up-heading-safe "org" ())
|
||||
|
@ -190,10 +189,7 @@ smart Make point visible, and do insertion/deletion if it is
|
|||
Never delete a previously invisible character or add in the
|
||||
middle or right after an invisible region. Basically, this
|
||||
allows insertion and backward-delete right before ellipses.
|
||||
FIXME: maybe in this case we should not even show?
|
||||
|
||||
This variable only affects commands listed in
|
||||
`org-fold-catch-invisible-edits-commands'."
|
||||
FIXME: maybe in this case we should not even show?"
|
||||
:group 'org-edit-structure
|
||||
:version "24.1"
|
||||
:type '(choice
|
||||
|
@ -203,33 +199,6 @@ This variable only affects commands listed in
|
|||
(const :tag "Show invisible part and do the edit" show)
|
||||
(const :tag "Be smart and do the right thing" smart)))
|
||||
|
||||
(defcustom org-fold-catch-invisible-edits-commands
|
||||
;; We do not add non-Org commands here by default to avoid advising
|
||||
;; globally. See `org-fold--advice-edit-commands'.
|
||||
'((org-self-insert-command . insert)
|
||||
(org-delete-backward-char . delete-backward)
|
||||
(org-delete-char . delete)
|
||||
(org-meta-return . insert)
|
||||
(org-return . insert))
|
||||
"Alist of commands where Org checks for invisible edits.
|
||||
Each element is (COMMAND . KIND), where COMMAND is symbol representing
|
||||
command as stored in `this-command' and KIND is symbol `insert',
|
||||
symbol `delete', or symbol `delete-backward'.
|
||||
|
||||
The checks are performed around `point'.
|
||||
|
||||
This variable must be set before loading Org in order to take effect.
|
||||
|
||||
Also, see `org-fold-catch-invisible-edits'."
|
||||
:group 'org-edit-structure
|
||||
:package-version '("Org" . "9.7")
|
||||
:type '(alist
|
||||
:key-type symbol
|
||||
:value-type (choice
|
||||
(const insert)
|
||||
(const delete)
|
||||
(const delete-backward))))
|
||||
|
||||
;;; Core functionality
|
||||
|
||||
;;; API
|
||||
|
@ -255,7 +224,6 @@ Also, see `org-fold-catch-invisible-edits'."
|
|||
(:ellipsis . ,ellipsis)
|
||||
(:fragile . ,#'org-fold--reveal-outline-maybe)
|
||||
(:isearch-open . t)
|
||||
(:font-lock . t)
|
||||
;; This is needed to make sure that inserting a
|
||||
;; new planning line in folded heading is not
|
||||
;; revealed. Also, the below combination of :front-sticky and
|
||||
|
@ -268,7 +236,6 @@ Also, see `org-fold-catch-invisible-edits'."
|
|||
(:ellipsis . ,ellipsis)
|
||||
(:fragile . ,#'org-fold--reveal-drawer-or-block-maybe)
|
||||
(:isearch-open . t)
|
||||
(:font-lock . t)
|
||||
(:front-sticky . t)
|
||||
(:alias . ( block center-block comment-block
|
||||
dynamic-block example-block export-block
|
||||
|
@ -278,7 +245,6 @@ Also, see `org-fold-catch-invisible-edits'."
|
|||
(:ellipsis . ,ellipsis)
|
||||
(:fragile . ,#'org-fold--reveal-drawer-or-block-maybe)
|
||||
(:isearch-open . t)
|
||||
(:font-lock . t)
|
||||
(:front-sticky . t)
|
||||
(:alias . (drawer property-drawer)))
|
||||
,org-link--description-folding-spec
|
||||
|
@ -392,7 +358,7 @@ of the current heading, or to 1 if the current line is not a heading."
|
|||
(interactive (list
|
||||
(cond
|
||||
(current-prefix-arg (prefix-numeric-value current-prefix-arg))
|
||||
((save-excursion (forward-line 0)
|
||||
((save-excursion (beginning-of-line)
|
||||
(looking-at outline-regexp))
|
||||
(funcall outline-level))
|
||||
(t 1))))
|
||||
|
@ -532,12 +498,12 @@ Return a non-nil value when toggling is successful."
|
|||
comment-block dynamic-block example-block export-block
|
||||
quote-block special-block src-block verse-block))
|
||||
(_ (error "Unknown category: %S" category))))
|
||||
(let* ((post (org-element-post-affiliated element))
|
||||
(let* ((post (org-element-property :post-affiliated element))
|
||||
(start (save-excursion
|
||||
(goto-char post)
|
||||
(line-end-position)))
|
||||
(end (save-excursion
|
||||
(goto-char (org-element-end element))
|
||||
(goto-char (org-element-property :end element))
|
||||
(skip-chars-backward " \t\n")
|
||||
(line-end-position))))
|
||||
;; Do nothing when not before or at the block opening line or
|
||||
|
@ -596,12 +562,10 @@ Return a non-nil value when toggling is successful."
|
|||
(interactive)
|
||||
(org-block-map (apply-partially #'org-fold-hide-block-toggle 'hide)))
|
||||
|
||||
(defun org-fold-hide-drawer-all (&optional begin end)
|
||||
"Fold all drawers in the current buffer or active region BEGIN..END."
|
||||
(interactive (list (and (use-region-p) (region-beginning))
|
||||
(and (use-region-p) (region-end))))
|
||||
(let ((begin (or begin (point-min)))
|
||||
(end (or end (point-max))))
|
||||
(defun org-fold-hide-drawer-all ()
|
||||
"Fold all drawers in the current buffer."
|
||||
(let ((begin (point-min))
|
||||
(end (point-max)))
|
||||
(org-fold--hide-drawers begin end)))
|
||||
|
||||
(defun org-fold--hide-drawers (begin end)
|
||||
|
@ -620,7 +584,7 @@ Return a non-nil value when toggling is successful."
|
|||
;; Make sure to skip drawer entirely or we might flag it
|
||||
;; another time when matching its ending line with
|
||||
;; `org-drawer-regexp'.
|
||||
(goto-char (org-element-end drawer))))))))
|
||||
(goto-char (org-element-property :end drawer))))))))
|
||||
|
||||
(defun org-fold-hide-archived-subtrees (beg end)
|
||||
"Re-hide all archived subtrees after a visibility state change."
|
||||
|
@ -629,7 +593,7 @@ Return a non-nil value when toggling is successful."
|
|||
(re (concat org-outline-regexp-bol ".*:" org-archive-tag ":")))
|
||||
(goto-char beg)
|
||||
;; Include headline point is currently on.
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(while (and (< (point) end) (re-search-forward re end t))
|
||||
(when (member org-archive-tag (org-get-tags nil t))
|
||||
(org-fold-subtree t)
|
||||
|
@ -664,33 +628,32 @@ DETAIL is either nil, `minimal', `local', `ancestors',
|
|||
(when (org-invisible-p)
|
||||
;; FIXME: No clue why, but otherwise the following might not work.
|
||||
(redisplay)
|
||||
;; Reveal emphasis markers.
|
||||
(when (eq detail 'local)
|
||||
(let (org-hide-emphasis-markers
|
||||
org-link-descriptive
|
||||
org-pretty-entities
|
||||
(org-hide-macro-markers nil)
|
||||
(region (or (org-find-text-property-region (point) 'org-emphasis)
|
||||
(org-find-text-property-region (point) 'org-macro)
|
||||
(org-find-text-property-region (point) 'invisible))))
|
||||
;; Silence byte-compiler.
|
||||
(ignore org-hide-macro-markers)
|
||||
(when region
|
||||
(org-with-point-at (car region)
|
||||
(forward-line 0)
|
||||
(let (font-lock-extend-region-functions)
|
||||
(font-lock-fontify-region (max (point-min) (1- (car region))) (cdr region))))))
|
||||
;; Unfold links.
|
||||
(let (region)
|
||||
(dolist (spec '(org-link org-link-description))
|
||||
(setq region (org-fold-get-region-at-point spec))
|
||||
(when region (org-fold-region (car region) (cdr region) nil spec)))))
|
||||
(let (region)
|
||||
(dolist (spec (org-fold-core-folding-spec-list))
|
||||
;; Links are taken care by above.
|
||||
(unless (memq spec '(org-link org-link-description))
|
||||
(setq region (org-fold-get-region-at-point spec))
|
||||
(let ((region (org-fold-get-region-at-point)))
|
||||
;; Reveal emphasis markers.
|
||||
(when (eq detail 'local)
|
||||
(let (org-hide-emphasis-markers
|
||||
org-link-descriptive
|
||||
org-pretty-entities
|
||||
(org-hide-macro-markers nil)
|
||||
(region (or (org-find-text-property-region (point) 'org-emphasis)
|
||||
(org-find-text-property-region (point) 'org-macro)
|
||||
(org-find-text-property-region (point) 'invisible)
|
||||
region)))
|
||||
;; Silence byte-compiler.
|
||||
(ignore org-hide-macro-markers)
|
||||
(when region
|
||||
(org-with-point-at (car region)
|
||||
(beginning-of-line)
|
||||
(let (font-lock-extend-region-functions)
|
||||
(font-lock-fontify-region (max (point-min) (1- (car region))) (cdr region))))))
|
||||
;; Unfold links.
|
||||
(when region
|
||||
(dolist (spec '(org-link org-link-description))
|
||||
(org-fold-region (car region) (cdr region) nil spec))))
|
||||
(when region
|
||||
(dolist (spec (org-fold-core-folding-spec-list))
|
||||
;; Links are taken care by above.
|
||||
(unless (memq spec '(org-link org-link-description))
|
||||
(org-fold-region (car region) (cdr region) nil spec))))))
|
||||
(unless (org-before-first-heading-p)
|
||||
(org-with-limited-levels
|
||||
|
@ -736,10 +699,9 @@ go to the parent and show the entire tree."
|
|||
|
||||
;;; Make isearch search in some text hidden via text properties.
|
||||
|
||||
(defun org-fold--isearch-reveal (pos)
|
||||
(defun org-fold--isearch-reveal (&rest _)
|
||||
"Reveal text at POS found by isearch."
|
||||
(org-with-point-at pos
|
||||
(org-fold-show-context 'isearch)))
|
||||
(org-fold-show-context 'isearch))
|
||||
|
||||
;;; Handling changes in folded elements
|
||||
|
||||
|
@ -764,7 +726,7 @@ the contents consists of blank lines.
|
|||
|
||||
Assume that point is located at the header line."
|
||||
(org-with-wide-buffer
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(org-fold-region
|
||||
(max (point-min) (1- (point)))
|
||||
(let ((endl (line-end-position)))
|
||||
|
@ -775,7 +737,7 @@ Assume that point is located at the header line."
|
|||
(if (equal (point)
|
||||
(save-excursion
|
||||
(goto-char endl)
|
||||
(org-end-of-subtree t)
|
||||
(org-end-of-subtree)
|
||||
(skip-chars-forward "\n\t\r ")))
|
||||
(point)
|
||||
endl)))
|
||||
|
@ -792,7 +754,7 @@ This function is intended to be used as :fragile property of
|
|||
;; The line before beginning of the fold should be either a
|
||||
;; headline or a list item.
|
||||
(backward-char)
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
;; Make sure that headline is not partially hidden.
|
||||
(unless (org-fold-folded-p nil 'headline)
|
||||
(org-fold--reveal-headline-at-point))
|
||||
|
@ -804,14 +766,14 @@ This function is intended to be used as :fragile property of
|
|||
(org-fold--reveal-headline-at-point))))
|
||||
;; Make sure that headline after is not partially hidden.
|
||||
(goto-char (cdr region))
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(unless (org-fold-folded-p nil 'headline)
|
||||
(when (looking-at-p org-element-headline-re)
|
||||
(org-fold--reveal-headline-at-point)))
|
||||
;; Check the validity of headline
|
||||
(goto-char (car region))
|
||||
(backward-char)
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(unless (let ((case-fold-search t))
|
||||
(looking-at (rx-to-string
|
||||
`(or (regex ,(org-item-re))
|
||||
|
@ -847,7 +809,7 @@ This function is intended to be used as :fragile property of
|
|||
;; The line before beginning of the fold should be the
|
||||
;; first line of the drawer/block.
|
||||
(backward-char)
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(unless (let ((case-fold-search t))
|
||||
(looking-at begin-re)) ; the match-data will be used later
|
||||
(throw :exit (setq unfold? t))))
|
||||
|
@ -867,7 +829,7 @@ This function is intended to be used as :fragile property of
|
|||
;; The last line of the folded text should match `end-re'.
|
||||
(save-excursion
|
||||
(goto-char fold-end)
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(unless (let ((case-fold-search t))
|
||||
(looking-at end-re))
|
||||
(throw :exit (setq unfold? t))))
|
||||
|
@ -941,19 +903,6 @@ The detailed reaction depends on the user option
|
|||
;; Don't do the edit, make the user repeat it in full visibility
|
||||
(user-error "Edit in invisible region aborted, repeat to confirm with text visible"))))))))
|
||||
|
||||
(defun org-fold-check-before-invisible-edit-maybe (&rest _)
|
||||
"Check before invisible command by `this-command'."
|
||||
(when (derived-mode-p 'org-mode)
|
||||
(pcase (alist-get this-command org-fold-catch-invisible-edits-commands)
|
||||
((pred null) nil)
|
||||
(kind (org-fold-check-before-invisible-edit kind)))))
|
||||
|
||||
(defun org-fold--advice-edit-commands ()
|
||||
"Advice editing commands according to `org-fold-catch-invisible-edits-commands'.
|
||||
The advices are installed in current buffer."
|
||||
(dolist (command (mapcar #'car org-fold-catch-invisible-edits-commands))
|
||||
(advice-add command :before #'org-fold-check-before-invisible-edit-maybe)))
|
||||
|
||||
(provide 'org-fold)
|
||||
|
||||
;;; org-fold.el ends here
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; org-footnote.el --- Footnote support in Org -*- lexical-binding: t; -*-
|
||||
;;
|
||||
;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
;;
|
||||
;; Author: Carsten Dominik <carsten.dominik@gmail.com>
|
||||
;; Keywords: outlines, hypermedia, calendar, wp
|
||||
|
@ -45,10 +45,9 @@
|
|||
(declare-function org-element-at-point "org-element" (&optional pom cached-only))
|
||||
(declare-function org-element-class "org-element" (datum &optional parent))
|
||||
(declare-function org-element-context "org-element" (&optional element))
|
||||
(declare-function org-element-lineage "org-element-ast" (blob &optional types with-self))
|
||||
(declare-function org-element-property "org-element-ast" (property node))
|
||||
(declare-function org-element-type "org-element-ast" (node &optional anonymous))
|
||||
(declare-function org-element-type-p "org-element-ast" (node types))
|
||||
(declare-function org-element-lineage "org-element" (blob &optional types with-self))
|
||||
(declare-function org-element-property "org-element" (property element))
|
||||
(declare-function org-element-type "org-element" (element))
|
||||
(declare-function org-end-of-subtree "org" (&optional invisible-ok to-heading))
|
||||
(declare-function org-fill-paragraph "org" (&optional justify region))
|
||||
(declare-function org-in-block-p "org" (names))
|
||||
|
@ -137,7 +136,6 @@ Possible values are:
|
|||
|
||||
nil Prompt the user for each label.
|
||||
t Create unique labels of the form [fn:1], [fn:2], etc.
|
||||
anonymous Create anonymous footnotes
|
||||
confirm Like t, but let the user edit the created value.
|
||||
The label can be removed from the minibuffer to create
|
||||
an anonymous footnote.
|
||||
|
@ -147,7 +145,6 @@ random Automatically generate a unique, random label."
|
|||
(const :tag "Prompt for label" nil)
|
||||
(const :tag "Create automatic [fn:N]" t)
|
||||
(const :tag "Offer automatic [fn:N] for editing" confirm)
|
||||
(const :tag "Create anoymous [fn::]" anonymous)
|
||||
(const :tag "Create a random label" random))
|
||||
:safe #'symbolp)
|
||||
|
||||
|
@ -186,21 +183,21 @@ extracted will be filled again."
|
|||
"Is point in a context where footnotes are allowed?"
|
||||
(save-match-data
|
||||
(not (or (org-at-comment-p)
|
||||
(org-inside-LaTeX-fragment-p)
|
||||
;; Avoid literal example.
|
||||
(org-in-verbatim-emphasis)
|
||||
(save-excursion
|
||||
(forward-line 0)
|
||||
(looking-at "[ \t]*:[ \t]+"))
|
||||
;; Avoid forbidden blocks.
|
||||
(org-in-block-p org-footnote-forbidden-blocks)))))
|
||||
(org-inside-LaTeX-fragment-p)
|
||||
;; Avoid literal example.
|
||||
(org-in-verbatim-emphasis)
|
||||
(save-excursion
|
||||
(beginning-of-line)
|
||||
(looking-at "[ \t]*:[ \t]+"))
|
||||
;; Avoid forbidden blocks.
|
||||
(org-in-block-p org-footnote-forbidden-blocks)))))
|
||||
|
||||
(defun org-footnote-at-reference-p ()
|
||||
"Non-nil if point is at a footnote reference.
|
||||
If so, return a list containing its label, beginning and ending
|
||||
positions, and the definition, when inline."
|
||||
(let ((reference (org-element-context)))
|
||||
(when (org-element-type-p reference 'footnote-reference)
|
||||
(when (eq 'footnote-reference (org-element-type reference))
|
||||
(let ((end (save-excursion
|
||||
(goto-char (org-element-property :end reference))
|
||||
(skip-chars-backward " \t")
|
||||
|
@ -226,7 +223,7 @@ defined locally.
|
|||
The return value is nil if not at a footnote definition, and
|
||||
a list with label, start, end and definition of the footnote
|
||||
otherwise."
|
||||
(pcase (org-element-lineage (org-element-at-point) 'footnote-definition t)
|
||||
(pcase (org-element-lineage (org-element-at-point) '(footnote-definition) t)
|
||||
(`nil nil)
|
||||
(definition
|
||||
(let* ((label (org-element-property :label definition))
|
||||
|
@ -272,7 +269,7 @@ otherwise."
|
|||
((memq type '(headline inlinetask))
|
||||
(or (not (org-at-heading-p))
|
||||
(and (save-excursion
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(and (let ((case-fold-search t))
|
||||
(not (looking-at-p "\\*+ END[ \t]*$")))
|
||||
(let ((case-fold-search nil))
|
||||
|
@ -284,10 +281,10 @@ otherwise."
|
|||
;; White spaces after an object or blank lines after an element
|
||||
;; are OK.
|
||||
((>= (point)
|
||||
(save-excursion (goto-char (org-element-property :end context))
|
||||
(skip-chars-backward " \r\t\n")
|
||||
(if (eq (org-element-class context) 'object) (point)
|
||||
(line-beginning-position 2)))))
|
||||
(save-excursion (goto-char (org-element-property :end context))
|
||||
(skip-chars-backward " \r\t\n")
|
||||
(if (eq (org-element-class context) 'object) (point)
|
||||
(line-beginning-position 2)))))
|
||||
;; At the beginning of a footnote definition, right after the
|
||||
;; label, is OK.
|
||||
((eq type 'footnote-definition) (looking-at (rx space)))
|
||||
|
@ -301,7 +298,7 @@ otherwise."
|
|||
;; :contents-begin is not reliable on empty cells, so special
|
||||
;; case it.
|
||||
(<= (save-excursion (skip-chars-backward " \t") (point))
|
||||
(org-element-property :contents-end context)))
|
||||
(org-element-property :contents-end context)))
|
||||
((let ((cbeg (org-element-property :contents-begin context))
|
||||
(cend (org-element-property :contents-end context)))
|
||||
(and cbeg (>= (point) cbeg) (<= (point) cend))))))))
|
||||
|
@ -371,14 +368,14 @@ References are sorted according to a deep-reading order."
|
|||
;; Ensure point is within the reference before parsing it.
|
||||
(backward-char)
|
||||
(let ((object (org-element-context)))
|
||||
(when (org-element-type-p object 'footnote-reference)
|
||||
(when (eq (org-element-type object) 'footnote-reference)
|
||||
(let* ((label (org-element-property :label object))
|
||||
(begin (org-element-property :begin object))
|
||||
(size
|
||||
(and (eq (org-element-property :type object) 'inline)
|
||||
(- (org-element-property :contents-end object)
|
||||
(org-element-property :contents-begin object)))))
|
||||
(let ((d (org-element-lineage object 'footnote-definition)))
|
||||
(let ((d (org-element-lineage object '(footnote-definition))))
|
||||
(push (list label (copy-marker begin) (not d) size)
|
||||
references)
|
||||
(when d
|
||||
|
@ -423,7 +420,7 @@ while collecting them."
|
|||
(backward-char)
|
||||
(let ((element (org-element-at-point)))
|
||||
(let ((label (org-element-property :label element)))
|
||||
(when (and (org-element-type-p element 'footnote-definition)
|
||||
(when (and (eq (org-element-type element) 'footnote-definition)
|
||||
(not (member label seen)))
|
||||
(push label seen)
|
||||
(let* ((beg (progn
|
||||
|
@ -519,7 +516,7 @@ This function is meant to be used for fontification only."
|
|||
;; Definition: also grab the last square bracket, matched in
|
||||
;; `org-footnote-re' for non-inline footnotes.
|
||||
((and (save-excursion
|
||||
(forward-line 0)
|
||||
(beginning-of-line)
|
||||
(save-match-data (org-footnote-in-valid-context-p)))
|
||||
(save-excursion
|
||||
(end-of-line)
|
||||
|
@ -636,8 +633,8 @@ This function ignores narrowing, if any."
|
|||
(while (re-search-forward org-footnote-re nil t)
|
||||
(backward-char)
|
||||
(let ((context (org-element-context)))
|
||||
(when (org-element-type-p
|
||||
context '(footnote-definition footnote-reference))
|
||||
(when (memq (org-element-type context)
|
||||
'(footnote-definition footnote-reference))
|
||||
(let ((label (org-element-property :label context)))
|
||||
(when label (cl-pushnew label all :test #'equal))))))
|
||||
all)))
|
||||
|
@ -668,16 +665,15 @@ or new, let the user edit the definition of the footnote."
|
|||
(user-error "Cannot insert a footnote here"))
|
||||
(let* ((all (org-footnote-all-labels))
|
||||
(label
|
||||
(unless (eq org-footnote-auto-label 'anonymous)
|
||||
(if (eq org-footnote-auto-label 'random)
|
||||
(format "%x" (abs (random)))
|
||||
(org-footnote-normalize-label
|
||||
(let ((propose (org-footnote-unique-label all)))
|
||||
(if (eq org-footnote-auto-label t) propose
|
||||
(completing-read
|
||||
"Label (leave empty for anonymous): "
|
||||
(mapcar #'list all) nil nil
|
||||
(and (eq org-footnote-auto-label 'confirm) propose)))))))))
|
||||
(if (eq org-footnote-auto-label 'random)
|
||||
(format "%x" (abs (random)))
|
||||
(org-footnote-normalize-label
|
||||
(let ((propose (org-footnote-unique-label all)))
|
||||
(if (eq org-footnote-auto-label t) propose
|
||||
(completing-read
|
||||
"Label (leave empty for anonymous): "
|
||||
(mapcar #'list all) nil nil
|
||||
(and (eq org-footnote-auto-label 'confirm) propose))))))))
|
||||
(cond ((not label)
|
||||
(insert "[fn::]")
|
||||
(backward-char 1))
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue