[Orgmode] Useful utility function: org-sort-multi

2009-08-29 Thread Ryan C. Thompson
I found myself having to sort by multiple criteria, and I was doing it 
with multiple calls to org-sort-entries-or-items. Then I decided to 
abstract the repetition into a function. Here it is:


(defun org-sort-multi (&rest sort-types)
  "Sort successively by a list of criteria, in descending order of 
importance.
For example, sort first by TODO status, then by priority, then by date, 
then alphabetically, case-sensitive.
Each criterion is either a character or a cons pair (BOOL . CHAR), where 
BOOL is whether or not to sort case-sensitively, and CHAR is one of the 
characters defined in ``org-sort-entries-or-items''.

So, the example above could be accomplished with:
 (org-sort-multi ?o ?p ?t (t . ?a))"
  (interactive)
  (mapc #'(lambda (sort-type)
(when (characterp sort-type) (setq sort-type (cons nil 
sort-type)))

(org-sort-entries-or-items (car sort-type) (cdr sort-type)))
(reverse sort-types)))

Note the call to reverse. This makes it so that the first criterion you 
provide is the dominant criterion. Try it out to see how it works, and 
let me know if there's a better way to pass the arguments.


Just as an example, the particular sorting function I wanted to write 
now becomes this:


(defun org-sort-custom ()
  "Sort children of node by todo status and by priority and by date, so 
the * TODO [#A] items with latest dates go to the top."

  (interactive)
  (org-sort-multi ?o ?p ?T))


___
Emacs-orgmode mailing list
Remember: use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode


[Orgmode] Re: Useful utility function: org-sort-multi

2009-08-30 Thread Ryan C. Thompson

Benjamin Andresen wrote:


if you have the following list
* Test Sorting
** TODO Charlie
** WAITING Beta
** TODO Alpha
** STARTED Beta
** STARTED Charlie
** TODO Beta
** STARTED Alpha
** WAITING Charlie
** WAITING Alpha



calling org-multi-sort with ?o ?a will sort it like this
* Test Sorting
** TODO Alpha
** TODO Beta
** TODO Charlie
** STARTED Alpha
** STARTED Beta
** STARTED Charlie
** WAITING Alpha
** WAITING Beta
** WAITING Charlie



but just ?a would completely ignore the TODO, STARTED, WAITING order.



Thanks Ryan, pretty useful.




br,
benny




___
Emacs-orgmode mailing list
Remember: use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode


That's right, the function relies on the fact that org's sorting is 
stable. So the results of earlier sorts are preserved as much as 
possible in later sorts. Of course, this is really inefficient, but oh well.


As another test case, try using (org-sort-multi ?o ?p) on this:
* Multi-sort test
** DONE [#B]
** TODO [#C]
** STARTED [#C]
** STARTED [#A]
** DONE [#C]
** TODO [#B]
** TODO [#A]
** STARTED [#B]
** DONE [#A]


Anyway, Carsten, if you think this would be useful, feel free to include 
some variant of this in org-mode itself. You'd probably want to 
implement it as a one-pass sort in which the set of sorting criteria 
function as a series of fallbacks for tiebreakers, rather than a series 
of sorts.


Ryan



___
Emacs-orgmode mailing list
Remember: use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode


[Orgmode] Easier customization of TODO keyword colors

2009-09-03 Thread Ryan C. Thompson
Here is some code I came up with some code to make it easier to 
customize the colors of various TODO keywords. As long as you just want 
a different color and nothing else, you can customize the variable 
org-todo-keyword-faces and use just a string color (i.e. a string of the 
color name) as the face, and then org-get-todo-face will convert the 
color to a face, inheriting everything else from the standard org-todo face.


To demonstrate, I currently have org-todo-keyword-faces set to
(("IN PROGRESS" . "dark orange")
 ("WAITING" . "red4")
 ("CANCELED" . "saddle brown"))

Here's the code, in a form you can put in your .emacs.

(eval-after-load 'org-faces
  '(progn
 (defcustom org-todo-keyword-faces nil
   "Faces for specific TODO keywords.
This is a list of cons cells, with TODO keywords in the car and
faces in the cdr.  The face can be a symbol, a color, or a
property list of attributes, like (:foreground \"blue\" :weight
bold :underline t)."
   :group 'org-faces
   :group 'org-todo
   :type '(repeat
   (cons
(string :tag "Keyword")
(choice color (sexp :tag "Face")))

(eval-after-load 'org
  '(progn
 (defun org-get-todo-face-from-color (color)
   "Returns a specification for a face that inherits from org-todo
  face and has the given color as foreground. Returns nil if
  color is nil."
   (when color
 `(:inherit org-warning :foreground ,color)))

 (defun org-get-todo-face (kwd)
   "Get the right face for a TODO keyword KWD.
If KWD is a number, get the corresponding match group."
   (if (numberp kwd) (setq kwd (match-string kwd)))
   (or (let ((face (cdr (assoc kwd org-todo-keyword-faces
 (if (stringp face)
 (org-get-todo-face-from-color face)
   face))
   (and (member kwd org-done-keywords) 'org-done)
   'org-todo


___
Emacs-orgmode mailing list
Remember: use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode


Re: [Orgmode] Easier customization of TODO keyword colors

2009-09-04 Thread Ryan C. Thompson

Bastien wrote:

Interesting - would you like to add this in org-hacks?

  http://orgmode.org/worg/org-hacks.php

If so, please send me your username on repo.or.cz (if you are not
already a Worger...)

Thank!
  
I'm not on either, actually. I'm a relative newcomer to org-mode and 
elisp hacking in general. But I'd love to see it on Worg.



___
Emacs-orgmode mailing list
Remember: use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode


[Orgmode] Setting org-remember-store-without-prompt specifically for certain templates?

2009-10-21 Thread Ryan C. Thompson

Hi,

I want to be prompted for a location to file some org-remember 
templates, but not others. How can I set 
org-remember-store-without-prompt in a template-specific fashion? I 
tried putting code in the template with %(sexp) that would set a 
buffer-local value for this variable, but I can't seem to make it work.


-Ryan


___
Emacs-orgmode mailing list
Remember: use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode


Re: [Orgmode] Setting org-remember-store-without-prompt specifically for certain templates?

2009-10-21 Thread Ryan C. Thompson
That's a fine solution for now, but I have one template that I *always* 
want to be prompted about. (It's an "assignment" template, and I want to 
refile it under the appropriate class.) For others, I don't want a 
prompt. I feel there should be a way to implement this and stick it 
inside a %(sexp) in my template of choice.


Darlan Cavalcante Moreira wrote:

I just leave org-remember-store-without-prompt as t and use C-c C-c in the
remember buffer to put the note in the default location. When I want to specify
a different location I use M-1 C-c C-c instead and org asks me where to refile
it to.

Darlan

At Wed, 21 Oct 2009 11:15:23 -0700,
"Ryan C. Thompson"  wrote:
  



___
Emacs-orgmode mailing list
Remember: use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode


Re: [Orgmode] Setting org-remember-store-without-prompt specifically for certain templates?

2009-10-24 Thread Ryan C. Thompson

Carsten Dominik wrote:


All you need to do is *not* to specify file and headline for this
template - then you will be prompted.
If I don't specify a file and headline, won't the note just be stored 
under org-default-notes file and org-remember-default-headline? Or even 
remember-data-file?



___
Emacs-orgmode mailing list
Remember: use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode


Re: [Orgmode] Setting org-remember-store-without-prompt specifically for certain templates?

2009-10-25 Thread Ryan C. Thompson
My original idea for a per-template solution was to create a function to 
set buffer-local values of the appropriate variables in the rememebr 
buffer, and have that function return an empty string, and then put it 
inside a %(sexp) in the template itself. Should this work? Would 
buffer-local values take precedence when I press C-c C-c after finishing 
my note?


My first few attempts were unsuccessful, but I'm not sure I got the code 
right. I suppose I should try manually setting buffer-local values and 
observing the effects.


- Ryan

Carsten Dominik wrote:


On Oct 24, 2009, at 11:00 PM, Ryan C. Thompson wrote:


Hi Ryan,

you are completely right, I was mistaken.

No, you cannot currently do what you want on a per-template basis.

- Carsten






___
Emacs-orgmode mailing list
Remember: use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode


[Orgmode] Bug Report: org-blocker-hook and org-trigger-hook are named incorrectly

2009-11-27 Thread Ryan C. Thompson
I believe it is the emacs convention to distinguish between hooks that 
take no arguments and hooks that do. Since org-blocker-hook and 
org-trigger-hook pass an argument to their functions, they should 
actually be called org-blocker-functions and org-trigger-functions.


From the elisp info, 23.1 Hooks:

   If the hook variable's name does not end with `-hook', that
indicates it is probably an "abnormal hook".  That means the hook
functions are called with arguments, or their return values are used in
some way.  The hook's documentation says how the functions are called.
You can use `add-hook' to add a function to an abnormal hook, but you
must write the function to follow the hook's calling convention.
   By convention, abnormal hook names end in `-functions' or `-hooks'.
If the variable's name ends in `-function', then its value is just a
single function, not a list of functions.

-Ryan


___
Emacs-orgmode mailing list
Please use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode


[Orgmode] Bug Report: TAB on empty headline cycles through the wrong levels

2009-11-27 Thread Ryan C. Thompson
I have discovered a possible bug with the new 6.33 feature of cycling 
empty headline levels with TAB. IT seems that org will always assume 
that the initial level of the headline is the "base" level. Pressing TAB 
once will always go one level deeper than that, to the "child" level, 
TAB a second time will go one level shallower than the base level, and 
so on.


the problem is that I expect the "base" level to be based on the 
previous headline's level, not on the initial level of the empty 
headline itself. The problem would not usually show itself, because if 
you press meta+RET  at the end of a headline, you get a new empty one at 
the same level as the previous headline. However, if you press meta+RET 
at the *beginning* of a headline (before the stars), you get a new empty 
headline at the same level as the *next* headline, which might not be 
the same level as the previous headline.

Here's a simple test case:

* Head1
** Head2


Put the point at the very beginning of the second heading, and press 
meta+RET, then TAB. You should get this:



* Head1
*** [point is here]
** Head2

The following is what I would *expect* to get:

* Head1
* [point is here]
** Head2


So basically, the base level for depth cycling should be determined from 
the previous headline, not the new blank headline. At least, that's what 
I expected, and I can't think of any reason you would want to put a 
level-3 headline under a level-1 headline.


-Ryan


___
Emacs-orgmode mailing list
Please use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode


[Orgmode] Org-remember: How to unambiguously store notes to level-2 and deeper headlines?

2009-11-27 Thread Ryan C. Thompson

Hi,

Is there a way to unambiguously specify non-top-level headers as 
org-remember targets in templates? My specific use case is that I want 
to split my "Tasks" entries list into sublists, and I want to store new 
tasks in Tasks/Unsorted by default. I know I could just specify 
"Unsorted" as the target, but that seems really easy to break, for 
example, if I also had Events/Unsorted in the same file. So, is there a 
good way to specify a level-2 headline as a target in 
org-remember-templates?


-Ryan


___
Emacs-orgmode mailing list
Please use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode


[Orgmode] Org-remember-handler fix for empty remember buffer

2009-06-07 Thread Ryan C. Thompson

Hi,

I ran into a problem with org's remember functionality, and found a fix 
for it. The problem is that if you attempt to either abort or remember 
an empty buffer (that is, a buffer containing only whitespace and 
comments), then org-mode hits an error and fails to do either, leaving 
the buffer annoyingly open.


The bug is in the loop that deletes trailing comments and whitespace. If 
the buffer is empty, then this loop reaches the first line, and attempts 
to delete a region starting at position zero, which causes the error. 
Here is the modified function definition that checks for this condition.


As a bonus, the function also auto-aborts instead of saving if the 
buffer is empty.


Thank you,

Ryan Thompson



;; Fix for empty remember buffer.
(defun org-remember-handler ()
 "Store stuff from remember.el into an org file.
When the template has specified a file and a headline, the entry is filed
there, or in the location defined by `org-default-notes-file' and
`org-remember-default-headline'.

If no defaults have been defined, or if the current prefix argument
is 1 (so you must use `C-1 C-c C-c' to exit remember), an interactive
process is used to select the target location.

When the prefix is 0 (i.e. when remember is exited with `C-0 C-c C-c'),
the entry is filed to the same location as the previous note.

When the prefix is 2 (i.e. when remember is exited with `C-2 C-c C-c'),
the entry is filed as a subentry of the entry where the clock is
currently running.

When `C-u' has been used as prefix argument, the note is stored and emacs
moves point to the new location of the note, so that editing can be
continued there (similar to inserting \"%&\" into the template).

Before storing the note, the function ensures that the text has an
org-mode-style headline, i.e. a first line that starts with
a \"*\".  If not, a headline is constructed from the current date and
some additional data.

If the variable `org-adapt-indentation' is non-nil, the entire text is
also indented so that it starts in the same column as the headline
\(i.e. after the stars).

See also the variable `org-reverse-note-order'."
 (interactive)
 (when (and (equal current-prefix-arg 2)
(not (marker-buffer org-clock-marker)))
   (error "No running clock"))
 (when (org-bound-and-true-p org-jump-to-target-location)
   (let* ((end (min (point-max) (1+ (point
  (beg (point)))
 (if (= end beg) (setq beg (1- beg)))
 (put-text-property beg end 'org-position-cursor t)))
 (goto-char (point-min))
 (while (looking-at "^[ \t]*\n\\|^##.*\n")
   (replace-match ""))
 (goto-char (point-max))
 (beginning-of-line 1)
 (catch 'quit
   (while (looking-at "[ \t]*$\\|##.*")
 ;; Abort on empty buffer
 (if (= (point) (point-min))
 (throw 'quit nil)
   (previous-line)))
   (delete-region (point) (point-max))
   (backward-delete-char 1)
   (if org-note-abort (throw 'quit nil))
   ;; Also abort on an empty (i.e. whitespace-only) buffer
   ;; (if (not (string-match "[^[:space:]]" 
(buffer-substring-no-properties (point-min) (point-max (return t))

   (let* ((visitp (org-bound-and-true-p org-jump-to-target-location))
  (previousp (and (member current-prefix-arg '((16) 0))
  org-remember-previous-location))
  (clockp (equal current-prefix-arg 2))
  (fastp (org-xor (equal current-prefix-arg 1)
  org-remember-store-without-prompt))
  (file (cond
 (fastp org-default-notes-file)
 ((and (eq org-remember-interactive-interface 'refile)
   org-refile-targets)
  org-default-notes-file)
 ((not previousp)
  (org-get-org-file
  (heading org-remember-default-headline)
  (visiting (and file (org-find-base-buffer-visiting file)))
  (org-startup-folded nil)
  (org-startup-align-all-tables nil)
  (org-goto-start-pos 1)
  spos exitcmd level reversed txt)
 (when (equal current-prefix-arg '(4))
   (setq visitp t))
 (when previousp
   (setq file (car org-remember-previous-location)
 visiting (and file (org-find-base-buffer-visiting file))
 heading (cdr org-remember-previous-location)
 fastp t))
 (when clockp
   (setq file (buffer-file-name (marker-buffer org-clock-marker))
 visiting (and file (org-find-base-buffer-visiting file))
 heading org-clock-heading-for-remember
 fastp t))
 (setq current-prefix-arg nil)
 ;; Modify text so that it becomes a nice subtree which can be inserted
 ;; into an org tree.
 (goto-char (point-min))
 (if (re-search-forward "[ \t\n]+\\'" nil t)
 ;; remove empty lines at end
 (replace-match ""))
 (goto-char (point-min))
 (unless (looking-at org-outline-regexp)
   ;; add a headline
   (insert (concat "* " (current-time-string)
   " (" (remember-buffer-desc) ")\n"))
   (backward-char 1)
   (when org-adapt-indentation
 (while (re-search-forward "^" nil t)
   (insert "  "
 (goto-char (poin

Re: [Orgmode] Org-remember-handler fix for empty remember buffer

2009-06-08 Thread Ryan C. Thompson

Carsten Dominik wrote:

Fixed, thanks.

- Carsten

On Jun 4, 2009, at 7:45 PM, Ryan C. Thompson wrote:


If you used the code I sent in my previous email, I discovered a bug in 
it. It would delete the last nonblank line as well. I have fixed this in 
my code. I've fixed things by copying the function into my .emacs and 
then editing it, so generating a diff -u is nontrivial. I'll do it now 
though.


Also, I should mention that I'm not an experienced elisp hacker, so the 
solution that I came up with might not be the best. If you know a better 
way to do the same thing, go for it.
--- /usr/share/emacs/site-lisp/org-mode/org-remember.el	2009-03-13 10:00:34.0 -0400
+++ org-remember.el	2009-06-08 15:43:04.708905961 -0400
@@ -740,10 +740,14 @@
 (replace-match ""))
   (goto-char (point-max))
   (beginning-of-line 1)
-  (while (looking-at "[ \t]*$\\|##.*")
-(delete-region (1- (point)) (point-max))
-(beginning-of-line 1))
   (catch 'quit
+(while (looking-at "[ \t]*$\\|##.*")
+  ;; Abort on empty buffer
+  (if (= (point) (point-min))
+  (throw 'quit nil)
+(previous-line)))
+(end-of-line 1) ; end of last nonblank line
+(delete-region (point) (point-max))
 (if org-note-abort (throw 'quit nil))
 (let* ((visitp (org-bound-and-true-p org-jump-to-target-location))
 	   (previousp (and (member current-prefix-arg '((16) 0))
___
Emacs-orgmode mailing list
Remember: use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode


[Orgmode] Setting custom frame parameters for org remember frame

2009-07-03 Thread Ryan C. Thompson
I am using org-remember set to open a new frame when used, and the 
default frame size is much too large. To fix this, I have designed some 
advice and a custom variable to implement custom parameters for the 
remember frame:


(defcustom remember-frame-alist nil
 "Additional frame parameters for dedicated remember frame."
 :type 'alist
 :group 'remember)

(defadvice remember (around remember-frame-parameters activate)
 "Set some frame parameters for the remember frame."
 (let ((default-frame-alist (append remember-frame-alist 
default-frame-alist)))

   ad-do-it))

I have set remember-frame-alist to
((width . 80) (height . 15))

which gives me a reasonable-sized frame, and provides and easy way to 
change it later.



___
Emacs-orgmode mailing list
Remember: use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode


[Orgmode] Setting custom frame parameters for org remember frame

2009-07-03 Thread Ryan C. Thompson

I am using org-remember set to open a new frame when used, and the
default frame size is much too large. To fix this, I have designed some
advice and a custom variable to implement custom parameters for the
remember frame:

(defcustom remember-frame-alist nil
 "Additional frame parameters for dedicated remember frame."
 :type 'alist
 :group 'remember)

(defadvice remember (around remember-frame-parameters activate)
 "Set some frame parameters for the remember frame."
 (let ((default-frame-alist (append remember-frame-alist
default-frame-alist)))
   ad-do-it))

I have set remember-frame-alist to
((width . 80) (height . 15))

which gives me a reasonable-sized frame, and provides and easy way to
change it later.

(I accidentally sent this from the wrong address before. Admins, please 
delete/ignore the other one.)



___
Emacs-orgmode mailing list
Remember: use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode


[Orgmode] Re: Vertical split in Emacs 23

2009-07-31 Thread Ryan C. Thompson
I believe the function you're looking for is split-window-sensibly. Try 
M-x describe-function split-window-sensibly. It describes all the 
relevant variables that control its behavior.


If you wish to affect the behavior of only a specific case of splitting 
windows (for example, the org-todo function) you can use advice to 
temporarily modify one or more of these variables for the duration of 
the function call. For example, the following (untested!) code should 
guarantee a vertical split for org-todo:


(defadvice org-todo (around tweak-splitting-behavior activate)
  "Tweak the sensible window splitting behavior for org-todo."
  (let ((split-height-threshold 0))
ad-do-it))



___
Emacs-orgmode mailing list
Remember: use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode


Bug: org-eldoc should require org-refile [9.3.6 (release_9.3.6-442-g97f0f1 @ /home/ryan/.emacs.d/straight/build/org-plus-contrib/)]

2020-04-07 Thread Ryan C. Thompson

Remember to cover the basics, that is, what you expected to happen and
what in fact did happen. You don't know how to make a good report? See

https://orgmode.org/manual/Feedback.html#Feedback

Your bug report will be posted to the Org mailing list.


`org-eldoc-get-breadcrumb' in org-eldoc.el calls `org-get-outline-path' 
which is defined in org-refile.el, but org-eldoc does not load 
org-refile. This results in void-function errors when the Eldoc idle 
timer runs in an org buffer, unless you manually load org-refile. To fix 
this, org-eldoc should load org-refile.


Emacs : GNU Emacs 26.3 (build 1, x86_64-pc-linux-gnu, X toolkit, Xaw3d 
scroll bars)

of 2019-09-23, modified by Debian
Package: Org mode version 9.3.6 (release_9.3.6-442-g97f0f1 @ 
/home/ryan/.emacs.d/straight/build/org-plus-contrib/)


current state:
==
(setq
org-src-mode-hook '(org-src-babel-configure-edit-buffer 
org-src-mode-configure-edit-buffer)

org-after-todo-state-change-hook '(org-checklist)
org-link-shell-confirm-function 'yes-or-no-p
org-metadown-hook '(org-babel-pop-to-session-maybe)
org-clock-out-hook '(org-clock-remove-empty-clock-drawer)
org-html-format-inlinetask-function 
'org-html-format-inlinetask-default-function

org-odt-format-headline-function 'org-odt-format-headline-default-function
org-ascii-format-inlinetask-function 'org-ascii-format-inlinetask-default
org-reveal-start-hook '(org-decrypt-entry)
org-mode-hook '((lambda nil (org-bullets-mode 1))
#[0 "\301\211\207" [imenu-create-index-function org-imenu-get-tree] 2]
#[0 "\300\301\302\303\304$\207" [add-hook change-major-mode-hook 
org-show-all append local] 5]

#[0 "\300\301\302\303\304$\207"
[add-hook change-major-mode-hook org-babel-show-result-all append local] 5]
org-babel-result-hide-spec org-babel-hide-all-hashes org-eldoc-load)
org-odt-format-drawer-function #[514 "\207" [] 3 "\n\n(fn NAME CONTENTS)"]
org-archive-hook '(org-attach-archive-delete-maybe)
org-confirm-elisp-link-function 'yes-or-no-p
org-agenda-before-write-hook '(org-agenda-add-entry-text)
org-metaup-hook '(org-babel-load-in-session-maybe)
org-bibtex-headline-format-function #[257 "\300\236A\207" [:title] 3 
"\n\n(fn ENTRY)"]

org-adapt-indentation nil
org-latex-format-drawer-function #[514 "\207" [] 3 "\n\n(fn _ CONTENTS)"]
org-babel-pre-tangle-hook '(save-buffer)
org-tab-first-hook '(org-babel-hide-result-toggle-maybe 
org-babel-header-arg-expand)

org-checklist-export-function 'org-export-as-ascii
org-ascii-format-drawer-function #[771 "\207" [] 4 "\n\n(fn NAME 
CONTENTS WIDTH)"]

org-agenda-loop-over-headlines-in-active-region nil
org-src-lang-modes '(("arduino" . arduino) ("redis" . redis) ("php" . 
php) ("C" . c) ("C++" . c++)
("asymptote" . asy) ("bash" . sh) ("beamer" . latex) ("calc" . 
fundamental) ("cpp" . c++)
("ditaa" . artist) ("dot" . fundamental) ("elisp" . emacs-lisp) ("ocaml" 
. tuareg)

("screen" . shell-script) ("shell" . sh) ("sqlite" . sql))
org-occur-hook '(org-first-headline-recenter)
org-cycle-hook '(org-cycle-hide-archived-subtrees 
org-cycle-show-empty-lines

org-optimize-window-after-visibility-change)
org-todo-keywords '((sequence "TODO" "|" "DONE" "CANCELLED"))
org-support-shift-select t
org-speed-command-hook '(org-speed-command-activate 
org-babel-speed-command-activate)
org-odt-format-inlinetask-function 
'org-odt-format-inlinetask-default-function

org-html-allow-name-attribute-in-anchors t
org-export-async-init-file 
"/home/ryan/.emacs.d/.temp-org-export-async-init.el"
org-export-before-parsing-hook '(org-attach-expand-links 
org-latex-header-blocks-filter)

org-confirm-shell-link-function 'yes-or-no-p
org-link-parameters '(("attachment" :follow org-attach-follow :complete 
org-attach-complete-link)

("id" :follow org-id-open) ("message" :follow org-mac-message-open)
("x-devonthink-item" :follow org-devonthink-item-open)
("mac-evernote" :follow org-mac-evernote-note-open)
("mac-outlook" :follow org-mac-outlook-message-open)
("acrobat" :follow org-mac-acrobat-open) ("skim" :follow org-mac-skim-open)
("addressbook" :follow org-mac-addressbook-item-open)
("x-together-item" :follow org-mac-together-item-open)
("mairix" :follow org-mairix-open :store org-mairix-store-gnus-link)
("eww" :follow org-eww-open :store org-eww-store-link)
("rmail" :follow org-rmail-open :store org-rmail-store-link)
("mhe" :follow org-mhe-open :store org-mhe-store-link)
("irc" :follow org-irc-visit :store org-irc-store-link :export 
org-irc-export)
("info" :follow org-info-open :export org-info-export :store 
org-info-store-link)

("gnus" :follow org-gnus-open :store org-gnus-store-link)
("docview" :follow org-docview-open :export org-docview-export :store
org-docview-store-link)
("bibtex" :follow org-bibtex-open :store org-bibtex-store-link)
("bbdb" :follow org-bbdb-open :export org-bbdb-export :complete 
org-bbdb-complete-link

:store org-bbdb-store-link)
("w3m" :store org-w3m-store-link)
("roll" :follow 

Re: Feature request: Allow export to convert broken links to plain text

2023-09-09 Thread Ryan C. Thompson


On 1/13/19 5:34 PM, Berry, Charles wrote:

Looks like your original idea to revise `org-export-data' might be best.

IIUC, you need to add the link text to the SIGNAL-DATA in each of the places 
where `org-export-resolve-*-link' functions call `signal', then modify 
`org-export-data' to ignore the addition for `mark' and add it back for your 
new `mark-with-text' option.

HTH,

Chuck


Years later, I became annoyed enough by this to attempt to fix it again. 
Unfortunately, I looked into changing all the functions that signal 
org-link-broken, and not all of them can be modified in the way you 
described, at least not easily. Instead, I came up with a fairly clean 
alternative solution: define a new link type "maybe" using 
org-link-set-parameters with an :export function that pulls out the real 
link transcoder from the backend and calls it, but then implements my 
desired behavior if that transcoder throws an error. This allows you to 
prefix any link's path with "maybe:" to have it magically become plain 
text if it can't be resolved during export. Here's the implementation:



(org-link-set-parameters
 "maybe"
 :follow
 (lambda (path prefix)
   (condition-case err
   (org-link-open-from-string (format "[[%s]]" path))
 (error (message "Failed to open maybe link %S" path
 ;; This must be a lambda so it is self-contained
 :export
 (lambda (path desc backend &optional info)
   (when (symbolp backend)
 (setq backend (org-export-get-backend backend)))
   ;; Generate the non-maybe version of the link, and call the
   ;; backend's appropriate transcoder on it, but catch any error
   ;; thrown and just replace the link with its text instead.
   (let* ((real-link
   (with-temp-buffer
     (save-excursion (insert "[[" path "][" desc "]]"))
     (org-element-link-parser)))
  (real-link-transcoder (cdr (assoc 'link 
(org-export-get-all-transcoders backend)

 (condition-case err
 (funcall real-link-transcoder real-link desc info)
   (error
    (message "Skipping error during maybe link transcoding: %S" err)
    (or desc path))


Using the above code, the following org file can be successfully 
exported to HTML, with the broken/invalid links converted to just plain 
text.



* First heading
:PROPERTIES:
:CUSTOM_ID: heading1
:END:
- [[maybe:maybe:maybe:https://google.com][Maybe google]]
- [[maybe:#heading1][Link to first heading]]
- [[maybe:#heading2][Link to second heading]]
- [[maybe:#heading3][Link to third(?) heading]]
- [[maybe:blarg:notalink][This is an invalid link]]
* Second heading
:PROPERTIES:
:CUSTOM_ID: heading2
:END:


So, this isn't an ideal solution, since it requires me to prefix any 
potential offending links with "maybe:". But it's good enough for me.



Regards,

Ryan