Hyperlinks within org-babel source code blocks? - emacs

I'd like to have some hyperlinks on the comments of an org-babel source code block. My goal is to export a file as html and be able to track some references, as in the following minimal example:
#+BEGIN_SRC lisp
(princ "Hello World!") ;; [[stackoverflow.com/blabla1234][Got this from SO.]]
#+END_SRC
"Problem" is that links don't get embedded inside of source code blocks (which actually makes a lot of sense).
Is there a way of overriding this behaviour, or an alternative syntax to insert hyperlinks within src blocks?

It is probably not possible now (as of org-mode 8.3.4). The HTML export engine currently doesn't appear to have a mechanism for escaping protected characters. You should submit implement it or submit a feature request! (details)
Some workarounds:
Imitate the output with raw HTML
You can output raw HTML that would otherwise look like the source block and it will render with the link intact:
#+BEGIN_HTML
<pre class="src src-sh">
(princ "Hello World!") ;; Got this from SO.
</pre>
#+END_HTML
Prevent Substitution
If your code is free of greater than and less than symbols you may be able to prevent them from being substituted with
(setq org-html-protect-char-alist '(("&" . "&"))
or if that doesn't work:
(setq htmlize-basic-character-table
;; Map characters in the 0-127 range to either one-character strings
;; or to numeric entities.
(let ((table (make-vector 128 ?\0)))
;; Map characters in the 32-126 range to themselves, others to
;; &#CODE entities;
(dotimes (i 128)
(setf (aref table i) (if (and (>= i 32) (<= i 126))
(char-to-string i)
(format "&#%d;" i))))
;; Set exceptions manually.
(setf
;; Don't escape newline, carriage return, and TAB.
(aref table ?\n) "\n"
(aref table ?\r) "\r"
(aref table ?\t) "\t"
;; Escape &, <, and >.
(aref table ?&) "&"
;;(aref table ?<) "<"
;;(aref table ?>) ">"
;; Not escaping '"' buys us a measurable speedup. It's only
;; necessary to quote it for strings used in attribute values,
;; which htmlize doesn't typically do.
;(aref table ?\") """
)
table))
Note that both are hacks which simply don't escape the HTML tag delimiters themselves. If syntax highlighting applies to any characters it will break the resulting HTML link by inserting <span>'s.

Related

How to define whole line comment syntax in Emacs?

I want the sequence // to start a comment when it is at the beginning of a line. But inside of a line it should not start any comments.
// this is a comment
This is a URL: http://example.com
Is it possible?
I'd do it this way:
(defvar my-foo-mode-syntax-table
(let ((st (make-syntax-table)))
;; Add other entries appropriate for my-foo-mode.
(modify-syntax-entry ?/ ". 12" st)
(modify-syntax-entry ?\n "> " st)
st))
(defvar my-foo-font-lock-keywords
;; Add other rules appropriate for my-foo-mode.
())
(define-derived-mode my-foo-mode nil "My-Foo"
(setq-local font-lock-keywords '(my-foo-font-lock-keywords))
;; Add other settings appropriate for my-foo-mode.
(setq-local syntax-propertize-function
(syntax-propertize-rules ("./\\(/+\\)" (1 ".")))))
Notice: No need for any special font-lock rule since font-lock automatically highlights comments for you, based on the syntax-tables.
You can do this by writing a syntax-propertize-function
I have written an example major mode that shows this below.
Emacs built in parsing will call your syntax-propertize-function so that it can manually set the syntax-table text property on lines starting with //.
(define-derived-mode my-syntax-test-mode fundamental-mode
"A major mode where // denotes a comment but only if it is at the beginning of a line."
:syntax-table (make-syntax-table)
(setq mode-name "my syntax test")
;; our mode will use `apply-my-custom-syntax-table-appropriately' to manually set
;; the syntax-table text property on lines starting with //"
(setq syntax-propertize-function 'apply-my-custom-syntax-table-appropriately)
;; change `comment-dwim` to handle this type of comments correctly
(local-set-key [remap comment-dwim] 'my-comment-dwim))
(defvar my-custom-syntax-table
;; syntax table where // starts a comment and \n ends it
(let ((table (make-syntax-table)))
(modify-syntax-entry ?/ "< 1" table)
(modify-syntax-entry ?/ "< 2" table)
(modify-syntax-entry ?\n "> " table)
table))
(defun apply-my-custom-syntax-table-appropriately (beg end)
(save-excursion
(save-restriction
(widen)
(goto-char beg)
;; for every line between points BEG and END
(while (and (not (eobp)) (< (point) end))
(beginning-of-line)
;; if it starts with a //
(when (looking-at "^//")
;; remove current syntax-table property
(remove-text-properties (1- (line-beginning-position))
(1+ (line-end-position))
'(syntax-table))
;; set syntax-table property to our custom one
;; for the whole line including the beginning and ending newlines
(add-text-properties (1- (line-beginning-position))
(1+ (line-end-position))
(list 'syntax-table my-custom-syntax-table)))
(forward-line 1)))))
(defun my-comment-dwim (arg)
(interactive "*P")
(require 'newcomment)
(save-excursion
(let ((comment-start "//") (comment-end "")
(comment-column 0)
;; don't indent comments
(comment-style 'plain))
;; create the region containing current line if there is no active region
(unless (use-region-p)
(end-of-line)
(push-mark (line-beginning-position))
(setq mark-active t))
(comment-dwim nil))))
Answer: Use regexps
Short and simple
(define-derived-mode my-foo-mode prog-mode "My-Foo"
(setq-local font-lock-keywords t)
(setq-local syntax-propertize-function
(syntax-propertize-rules
((rx line-start (* whitespace) (group "//")) (1 "<"))
((rx (group "\n")) (1 ">")))))
That is all you need, but read on if you'd like to know more.
Explanation
This is based on #stefan's excellent solution which uses syntax-propertize-function to add to a syntax-table. While simpler isn't always better, #stefan's answer does more than what the original question asked for, so I've created this answer for people who only need a small hint or who just want to modify an existing mode.
It turns out directly manipulating a syntax table is unnecessary since the function syntax-propertize-rules makes it easy to map from regular expressions to syntax classes. For example, the syntax class < means "start of comment" and > means "end of comment". (See the Emacs lisp manual.)
I set font-lock-keywords to t as that is the minimum needed to enable syntax highlighting. If you are editing an existing mode, it likely already sets that variable and will not need to be changed.
And, finally, I use Emacs' rx function because it makes regular expressions sane in Lisp. (If you like Lisp, regular expressions, and sanity, I highly recommend using rx.)
About syntax-propertize-rules
I was going to link to the documentation for syntax-propertize-rules, but the Emacs manual does not (as of Emacs 28.1) even mention it. Until that gets remedied, I'll paste here the builtin documentation from C-hf:
syntax-propertize-rules is a Lisp macro in ‘syntax.el’.
(syntax-propertize-rules &rest RULES)
Probably introduced at or before Emacs version 24.1.
Make a function that applies RULES for use in
‘syntax-propertize-function’. The function will scan the buffer,
applying the rules where they match. The buffer is scanned a single
time, like "lex" would, rather than once per rule.
Each RULE can be a symbol, in which case that symbol’s value should
be, at macro-expansion time, a precompiled set of rules, as returned
by ‘syntax-propertize-precompile-rules’.
Otherwise, RULE should have the form (REGEXP HIGHLIGHT1 ...
HIGHLIGHTn), where REGEXP is an expression (evaluated at time of
macro-expansion) that returns a regexp, and where HIGHLIGHTs have the
form (NUMBER SYNTAX) which means to apply the property SYNTAX to the
chars matched by the subgroup NUMBER of the regular expression, if
NUMBER did match. SYNTAX is an expression that returns a value to
apply as ‘syntax-table’ property. Some expressions are handled
specially:
if SYNTAX is a string, then it is converted with ‘string-to-syntax’;
if SYNTAX has the form (prog1 EXP . EXPS) then the value returned by EXP will be applied to the buffer before running EXPS and if EXP is
a string it is also converted with ‘string-to-syntax’. The SYNTAX
expression is responsible to save the ‘match-data’ if needed for
subsequent HIGHLIGHTs. Also SYNTAX is free to move point, in which
case RULES may not be applied to some parts of the text or may be
applied several times to other parts.
Note: back-references in REGEXPs do not work.

Emacs-lisp: prettify-symbols-mode for LaTeX

I was trying to port over the "pretty entities" behaviour from org-mode to latex-mode using the Emacs builtin prettify-symbols-mode. This mode uses font-lock-mode to display character sequences in a buffer as a single (unicode) character. By default for instance emacs-lisp code
(lambda () t)
becomes
(λ () t)
It does however seem to require the character sequences to be separated by some characters, e.g. white-spaces. For instance in my setup, the replacement
\alpha \beta -> α β`
will work, but it will fail when the strings are not separated, e.g.
\alpha\beta -> \alphaβ
This is an issue specifically, because I wanted to use this prettification to make quantum mechanical equations more readable, where I e.g. the replacement like
|\psi\rangle -> |ψ⟩
Is it possible to avoid this delimiter-issue using prettify-symbols-mode? And if it is not, is it possible by using font-lock-mode on a lower level?
Here's the code that should do what you want:
(defvar pretty-alist
(cl-pairlis '("alpha" "beta" "gamma" "delta" "epsilon" "zeta" "eta"
"theta" "iota" "kappa" "lambda" "mu" "nu" "xi"
"omicron" "pi" "rho" "sigma_final" "sigma" "tau"
"upsilon" "phi" "chi" "psi" "omega")
(mapcar
(lambda (x) (make-char 'greek-iso8859-7 x))
(number-sequence 97 121))))
(add-to-list 'pretty-alist '("rangle" . ?\⟩))
(defun pretty-things ()
(mapc
(lambda (x)
(let ((word (car x))
(char (cdr x)))
(font-lock-add-keywords
nil
`((,(concat "\\(^\\|[^a-zA-Z0-9]\\)\\(" word "\\)[a-zA-Z]")
(0 (progn
(decompose-region (match-beginning 2) (match-end 2))
nil)))))
(font-lock-add-keywords
nil
`((,(concat "\\(^\\|[^a-zA-Z0-9]\\)\\(" word "\\)[^a-zA-Z]")
(0 (progn
(compose-region (1- (match-beginning 2)) (match-end 2)
,char)
nil)))))))
pretty-alist))
As you can see above, pretty-alist starts out with greek chars. Then I add
\rangle just to demonstrate how to add new things.
To enable it automatically, add it to the hook:
(add-hook 'LaTeX-mode-hook 'pretty-things)
I used the code from here as a starting
point, you can look there for a reference.
The code of prettify-symbols-mode derives from code developped for languages like Haskell and a few others, which don't use something like TeX's \. So you may indeed be in trouble. I suggest you M-x report-emacs-bug requesting prettify-symbol-mode be improved to support TeX-style syntax.
In the mean time, you'll have to "do it by hand" along the lines of what abo-abo suggests.
One note, tho: back in the days of Emacs-21, I ported X-Symbol to work on Emacs, specifically because I wanted to see such pretty things in LaTeX. Yet, I discovered that it was mostly useless to me. And I think it's even more the case now. Here's why:
You can just use an actual ψ character in your LaTeX code instead of \psi nowadays. So you don't need display tricks for it to look "right".
Rather than repeating |\psi\rangle I much prefer defining macros and then use \Qr{\Vangle} (where \Vangle turns into \psi ("V" stands for "metaVariable"), and \Qr wraps it in a braket) so I can easily tweak those macros and know that the document will stay consistent. At that point, pretty-display of \psi and \rangle is of no importance.

How to instruct Emacs auto-capitalize-mode to automatically lowercase any word that follows e.g. or i.e.?

Emacs auto-capitalize-mode misinterprets the words i.e. and e.g. to signify the end of a sentence, and, accordingly, erroneously capitalizes any word that follows them.
Does anyone have a function that can be called by entering, say, eg or ie, that will insert the characters e.g. and i.e. and then automatically lowercase whatever word gets typed next?
Bonus: Do the same thing... for ellipses.
Add this to your .emacs:
(setq auto-capitalize-predicate
(lambda () (not (looking-back
"\\([Ee]\\.g\\|[Ii]\\.e\\)\\.[^.]*" (- (point) 20)))))
Remember that the I in i.e. will be capitalized to I.e if your
auto-capitalize-words variable is set to contain “I”.
(setq auto-capitalize-words '()) This sets it to nothing.
Here’s a version that also deals with ellipses:
(setq auto-capitalize-predicate
(lambda () (not (looking-back
"\\([Ee]\\.g\\|[Ii]\\.e\\|\\.\\.\\)\\.[^.]*" (- (point) 20)))))
But you might want to look into some abbrev magic that turns three periods into a unicode ellipsis instead. It's up to you.
From auto-capitalize.el:
;; To prevent a word in the `auto-capitalize-words' list from being
;; capitalized or upcased in a particular context (e.g.
;; "GNU.emacs.sources"), insert the following whitespace or
;; punctuation character with `M-x quoted-insert' (e.g. `gnu C-q .').
I use it and it is a comfortable approach.

How do I create shy groups in Emacs with rx?

Generally, I can use the excellent rx macro to create readable regular expressions and be sure that I've escaped the correct metacharacters.
(rx (any "A-Z")) ;; "[A-Z]"
However, I can't work out how to create shy groups, e.g. \(?:AB\). rx sometimes produces them in its output:
(rx (or "ab" "bc")) ;; "\\(?:ab\\|bc\\)"
but I want to explicitly add them. I can do:
(rx (regexp "\\(?:AB\\)"))
but this defeats the point of rx.
In a perfect world, I'd like to be able to write:
(rx (shy-group "A"))
I'd settle for something like this (none of these work):
;; sadly, `regexp` only accepts literal strings
(rx (regexp (format "\\(?:%s\\)" (rx WHATEVER))))
;; also unfortunate, `eval` quotes the string it's given
(rx (eval (format "\\(?:%s\\)" (rx WHATEVER))))
How can I create regular expressions with shy groups using rx?
I think the structure of a rx form eliminates any need to explicitly create shy groups -- everything that a shy group could be needed for is accounted for by other syntax.
e.g. your own example:
(rx (or "ab" "bc")) ;; "\\(?:ab\\|bc\\)"
For other cases, it is also possible to extend the keywords used by rx.
Example (taken from EmacsWiki link above):
(defmacro rx-extra (&rest body-forms)
(let ((add-ins (list
`(file . ,(rx (+ (or alnum digit "." "/" "-" "_"))))
`(ws0 . ,(rx (0+ (any " " "\t"))))
`(ws+ . ,(rx (+ (any " " "\t"))))
`(int . ,(rx (+ digit))))))
`(let ((rx-constituents (append ',add-ins rx-constituents nil)))
,#body-forms)))

(re)number numbered lists in emacs (muse)

suppose I have a text list in emacs like this:
a
b
c
...
d
Is there a way to assign numbers to those items in Emacs, by selecting the region? End results should look like:
1. a
2. b
3. c
j. ...
n. d
Thanks.
The way I do this, which may not be optimal, is to use regex search and replace. This, of course, requires that you be able to define a regex to match the start of the lines you want numbers on. Taking your example, I'd use a search regex like this:
\([a-z]\)
note the capturing brackets, we'll need that first letter soon. And a replace regex like this:
\#. \1
where:
\# is a special form which is replaced, by Emacs, by the right number (though see the warning below);
. writes a stop; and
\1 writes a space and the captured group.
WARNING: Emacs will number your items 0, 1, 2, .... Until someone posts to tell us how to start at 1, I always insert a dummy 0th element before the edit, then delete it.
You can use the Emacs Keyboard Macro Counter.
Put the cursor one line ABOVE your list.
Start a macro: F3
Insert the counter value: C-x C-k C-i. A 0 will appear
Insert the DOT and a space: .
Move the cursor to the next line
Stop the macro: F4
Select your list
M-x apply-macro-to-region-lines
You can delete the 0 you added on the top and enjoy :)
NOTE: This will create a numbered list. It will not use letters.
A much simpler way is to use the CUA library's advanced rectangle editing commands. CUA is included in Emacs (at least 23.1, I think it's in earlier versions as well), so there isn't any new code to get.
You can use cua-set-rectangle-mark (bound to C-Return by default) to start a rectangle, and then use cua-sequence-rectangle to insert increasing values. It also gives you control over the format and starting value, so there is a lot of flexibility.
As an aside, CUA is primarily designed to make Emacs operate more like standard text editors (with C-c for copy, C-v for paste, etc), but it also includes some unrelated niceties, like rectangle editing. Don't ask me why :). If you want to use the rectangle editing without enabling the CUA keybindings (which is what I do), set cua-enable-cua-keys to nil, which can be done via customize.
(defun number-region (start end)
(interactive "r")
(let* ((count 1)
(indent-region-function (lambda (start end)
(save-excursion
(setq end (copy-marker end))
(goto-char start)
(while (< (point) end)
(or (and (bolp) (eolp))
(insert (format "%d. " count))
(setq count (1+ count)))
(forward-line 1))
(move-marker end nil)))))
(indent-region start end)))
Here's some elisp code to do it; would be easy to customize if you like tinkering.
This will number the current region (unless it is already numbered), and also the last line binds to the M-n keys. You could use a function key "[F6]" as needed.
Modified to take a format string to use. The default is 1. but you could do something like %d) to get a bracket instead of a . and so on.
(defun number-region(fmt)
(interactive "sFormat : ")
(if (or (null fmt) (= 0 (length fmt)))
(setf fmt "%d. "))
(save-excursion
(save-restriction
(narrow-to-region (point) (mark))
(goto-char (point-min))
(let ((num 1))
(while (> (point-max) (point))
(if (null (number-at-point))
(insert (format fmt num)))
(incf num)
(forward-line))))))
(global-set-key "\M-n" 'number-region)
Not a direct answer to your question, but if you find yourself manipulating numbered lists frequently, you may want to look into org-mode. In particular, the section on plain lists.