mirror of
https://git.savannah.gnu.org/git/emacs/org-mode.git
synced 2024-11-23 07:18:53 +00:00
Coderefs: Revamp label syntax.
This commit revamps the syntax used for code line references in literal examples. See the documentation for details about the new format.
This commit is contained in:
parent
f6fa33eceb
commit
1a3abc8018
@ -124,8 +124,8 @@ increasing Org-mode's utility for writing tutorials and other
|
||||
similar documents.
|
||||
|
||||
Code references use special labels embedded directly into the
|
||||
source code. Such labels look like "((name))" and must be unique
|
||||
within a document. Org-mode links with the coderef cookie in the
|
||||
source code. Such labels look like "(ref:name)" and must be
|
||||
unique within a document. Org-mode links with "(name)" in the
|
||||
link part will be correctly interpreted, both while working with
|
||||
an Org file (internal links), and while exporting to the
|
||||
different backends. Line numbering and code references are
|
||||
@ -142,28 +142,32 @@ The options for the BEGIN lines are:
|
||||
links to this reference with line numbers. This option
|
||||
takes only effect if either -n or +n are given as well.
|
||||
If -r is not given, coderefs simply use the label name.
|
||||
|
||||
- -l "fmt" :: Define a local format for coderef labels, see the
|
||||
variable =org-coderef-label-format= for details. Use this
|
||||
of the default syntax causes conflicts with the code in the
|
||||
code snippet you are using.
|
||||
|
||||
Here is an example:
|
||||
|
||||
#+begin_example -k
|
||||
#+begin_src emacs-lisp -n -r
|
||||
(defmacro org-unmodified (&rest body) ((def))
|
||||
(defmacro org-unmodified (&rest body) (ref:def)
|
||||
"Execute body without changing `buffer-modified-p'."
|
||||
`(set-buffer-modified-p ((back))
|
||||
`(set-buffer-modified-p (ref:back)
|
||||
(prog1 (buffer-modified-p) ,@body)))
|
||||
#+end_src
|
||||
[[((def))][Line ((def))]] contains the macro name. Later at line [[((back))]],
|
||||
[[(def)][Line (def)]] contains the macro name. Later at line [[(back)]],
|
||||
backquoting is used.
|
||||
#+end_example
|
||||
|
||||
When exported, this is translated to:
|
||||
#+begin_src emacs-lisp -n -r
|
||||
(defmacro org-unmodified (&rest body) ((def))
|
||||
(defmacro org-unmodified (&rest body) (ref:def)
|
||||
"Execute body without changing `buffer-modified-p'."
|
||||
`(set-buffer-modified-p ((back))
|
||||
`(set-buffer-modified-p (ref:back)
|
||||
(prog1 (buffer-modified-p) ,@body)))
|
||||
#+end_src
|
||||
[[((def))][Line ((def))]] contains the macro name. Later at line [[((back))]],
|
||||
[[(def)][Line (def)]] contains the macro name. Later at line [[(back)]],
|
||||
backquoting is used.
|
||||
|
||||
Thanks to Ilya Shlyakhter for proposing this feature set. Thanks
|
||||
|
34
doc/org.texi
34
doc/org.texi
@ -7391,24 +7391,30 @@ Both in @code{example} and in @code{src} snippets, you can add a @code{-n}
|
||||
switch to the end of the @code{BEGIN} line, to get the lines of the example
|
||||
numbered. If you use a @code{+n} switch, the numbering from the previous
|
||||
numbered snippet will be continued in the current one. In literal examples,
|
||||
Org will interpret strings like @samp{((name))} as labels, and use them as
|
||||
targets for hyperlinks like @code{[[((name))]]}. In HTML, hoovering the
|
||||
mouse over such a link will remote-highlight the corresponding code line,
|
||||
which is kind of cool. If the example/src snippet is numbered, you can also
|
||||
add a @code{-r} switch. Then labels will be @i{removed} from the source code
|
||||
and the links will be @i{replaced}@footnote{If you want to explain the use of
|
||||
such labels themelves in an example, you can use the @code{-k} switch to make
|
||||
Org will interpret strings like @samp{(ref:name)} as labels, and use them as
|
||||
targets for special hyperlinks like @code{[[(name)]]} (i.e. the reference
|
||||
name enclosed in single parenthesis). In HTML, hoovering the mouse over such
|
||||
a link will remote-highlight the corresponding code line, which is kind of
|
||||
cool. If the example/src snippet is numbered, you can also add a @code{-r}
|
||||
switch. Then labels will be @i{removed} from the source code and the links
|
||||
will be @i{replaced}@footnote{If you want to explain the use of such labels
|
||||
themelves in org-mode example code, you can use the @code{-k} switch to make
|
||||
sure they are not touched.} with line numbers from the code listing. Here is
|
||||
an exmmple:
|
||||
an example:
|
||||
|
||||
@example
|
||||
#+BEGIN_SRC emacs-lisp -n -r
|
||||
(save-excursion
|
||||
(goto-char (point-min)) ((jump))
|
||||
(save-excursion (ref:sc)
|
||||
(goto-char (point-min)) (ref:jump)
|
||||
#+END SRC
|
||||
In [[((jump))][line ((jump))]] we go to .....
|
||||
In line [[(sc)]] we remember the current positon. [[(jump)][Line (jump)]]
|
||||
jumps to point-min.
|
||||
@end example
|
||||
|
||||
If the syntax for the label format conflicts with the language syntax, use a
|
||||
@code{-l} switch to change the format, for example @samp{#+BEGIN_SRC pascal
|
||||
-n -r -l "((%s))"}. See also the variable @code{org-coderef-label-format}.
|
||||
|
||||
@table @kbd
|
||||
@kindex C-c '
|
||||
@item C-c '
|
||||
@ -7428,9 +7434,9 @@ fixed-width region.
|
||||
@item C-c l
|
||||
Calling @code{org-store-link} while editing a source code example in a
|
||||
temporary buffer created with @kbd{C-c '} will prompt for a label, make sure
|
||||
that it is unique in the current buffer, and insert it as @samp{((label))} at
|
||||
the end of the current line. Then the label is stored as a link, for
|
||||
retrieval with @kbd{C-c C-l}.
|
||||
that it is unique in the current buffer, and insert it with the proper
|
||||
formatting like @samp{(ref:label)} at the end of the current line. Then the
|
||||
label is stored as a link @samp{(label)}, for retrieval with @kbd{C-c C-l}.
|
||||
@end table
|
||||
|
||||
@node Include files, Tables exported, Literal examples, Markup rules
|
||||
|
@ -1,5 +1,14 @@
|
||||
2009-01-05 Carsten Dominik <carsten.dominik@gmail.com>
|
||||
|
||||
* org.el (org-edit-src-get-label-format): New function.
|
||||
(org-coderef-label-format): New option.
|
||||
(org-edit-src-code, org-edit-src-find-region-and-lang): Parse for
|
||||
a label format specification and make sure it is used in the edit
|
||||
buffer.
|
||||
(org-edit-src-get-label-format): New function.
|
||||
(org-store-link): Handle new coderef formats.
|
||||
(org-link-search): Handle new coderef formats.
|
||||
|
||||
* org-footnote.el (org-footnote-create-definition)
|
||||
(org-footnote-goto-local-insertion-point): Make footnote insertion
|
||||
work correctly when the "Footnotes" headline is the last line in
|
||||
|
@ -1700,7 +1700,7 @@ the current file."
|
||||
((cdr (assoc slink target-alist)))
|
||||
((and (string-match "^id:" link)
|
||||
(cdr (assoc (substring link 3) target-alist))))
|
||||
((string-match "^((\\(.*\\)))$" link)
|
||||
((string-match "^(\\(.*\\))$" link)
|
||||
(setq cref (match-string 1 link))
|
||||
(concat "coderef:" cref))
|
||||
((string-match org-link-types-re link) nil)
|
||||
@ -2305,11 +2305,14 @@ and `+n' for continuing previous numering.
|
||||
Code formatting according to language currently only works for HTML.
|
||||
Numbering lines works for all three major backends (html, latex, and ascii)."
|
||||
(save-match-data
|
||||
(let (num cont rtn named rpllbl keepp)
|
||||
(setq num (string-match "[-+]n\\>" (or opts ""))
|
||||
cont (string-match "\\+n\\>" (or opts ""))
|
||||
rpllbl (string-match "-r\\>" (or opts ""))
|
||||
keepp (string-match "-k\\>" (or opts "")))
|
||||
(let (num cont rtn named rpllbl keepp fmt)
|
||||
(setq opts (or opts "")
|
||||
num (string-match "[-+]n\\>" opts)
|
||||
cont (string-match "\\+n\\>" opts)
|
||||
rpllbl (string-match "-r\\>" opts)
|
||||
keepp (string-match "-k\\>" opts)
|
||||
fmt (if (string-match "-l[ \t]+\"\\([^\"\n]+\\)\"" opts)
|
||||
(match-string 1 opts)))
|
||||
(if keepp (setq rpllbl 'keep))
|
||||
(setq rtn code)
|
||||
(when (equal lang "org")
|
||||
@ -2350,15 +2353,15 @@ Numbering lines works for all three major backends (html, latex, and ascii)."
|
||||
(format "<pre class=\"src src-%s\">\n" lang)
|
||||
t t rtn))))
|
||||
(setq rtn (concat "<pre class=\"example\">\n" rtn "</pre>\n")))
|
||||
(setq rtn (org-export-number-lines rtn 'html 1 1 num cont rpllbl))
|
||||
(setq rtn (org-export-number-lines rtn 'html 1 1 num cont rpllbl fmt))
|
||||
(concat "\n#+BEGIN_HTML\n" rtn "\n#+END_HTML\n\n"))
|
||||
((eq backend 'latex)
|
||||
(setq rtn (org-export-number-lines rtn 'latex 0 0 num cont rpllbl))
|
||||
(setq rtn (org-export-number-lines rtn 'latex 0 0 num cont rpllbl fmt))
|
||||
(concat "\n#+BEGIN_LaTeX\n\\begin{verbatim}\n" rtn
|
||||
"\n\\end{verbatim}\n#+END_LaTeX\n\n"))
|
||||
((eq backend 'ascii)
|
||||
;; This is not HTML or LaTeX, so just make it an example.
|
||||
(setq rtn (org-export-number-lines rtn 'ascii 0 0 num cont rpllbl))
|
||||
(setq rtn (org-export-number-lines rtn 'ascii 0 0 num cont rpllbl fmt))
|
||||
(concat "#+BEGIN_ASCII\n"
|
||||
(mapconcat
|
||||
(lambda (l) (concat " " l))
|
||||
@ -2368,7 +2371,7 @@ Numbering lines works for all three major backends (html, latex, and ascii)."
|
||||
|
||||
(defun org-export-number-lines (text backend
|
||||
&optional skip1 skip2 number cont
|
||||
replace-labels)
|
||||
replace-labels label-format)
|
||||
(if (and (not number) (not (eq replace-labels 'keep)))
|
||||
(setq replace-labels nil)) ;; must use names if no numbers
|
||||
(setq skip1 (or skip1 0) skip2 (or skip2 0))
|
||||
@ -2390,6 +2393,20 @@ Numbering lines works for all three major backends (html, latex, and ascii)."
|
||||
((eq backend 'ascii) fmt)
|
||||
((eq backend 'latex) fmt)
|
||||
(t "")))
|
||||
(label-format (or label-format org-coderef-label-format))
|
||||
(label-pre (if (string-match "%s" label-format)
|
||||
(substring label-format 0 (match-beginning 0))
|
||||
label-format))
|
||||
(label-post (if (string-match "%s" label-format)
|
||||
(substring label-format (match-end 0))
|
||||
""))
|
||||
(lbl-re
|
||||
(concat
|
||||
".*?\\S-.*?\\([ \t]*\\("
|
||||
(regexp-quote label-pre)
|
||||
"\\([-a-zA-Z0-9_]+\\)"
|
||||
(regexp-quote label-post)
|
||||
"\\)\\)"))
|
||||
ref)
|
||||
|
||||
(goto-line (1+ skip1))
|
||||
@ -2398,7 +2415,7 @@ Numbering lines works for all three major backends (html, latex, and ascii)."
|
||||
(insert (format fm (incf n)))
|
||||
(forward-char 1))
|
||||
(when (and (not (eq replace-labels 'keep))
|
||||
(looking-at ".*?\\([ \t]+\\(((\\(.*?\\)))\\)\\)"))
|
||||
(looking-at lbl-re))
|
||||
(setq ref (match-string 3))
|
||||
(if replace-labels
|
||||
(progn
|
||||
@ -3869,7 +3886,7 @@ lang=\"%s\" xml:lang=\"%s\">
|
||||
(defun org-export-get-coderef-format (path desc)
|
||||
(save-match-data
|
||||
(if (and desc (string-match
|
||||
(regexp-quote (concat "((" path "))"))
|
||||
(regexp-quote (concat "(" path ")"))
|
||||
desc))
|
||||
(replace-match "%s" t t desc)
|
||||
"%s")))
|
||||
|
64
lisp/org.el
64
lisp/org.el
@ -729,6 +729,23 @@ there are kept outside the narrowed region."
|
||||
(const :tag "from `lang' element")
|
||||
(const :tag "from `style' element")))))
|
||||
|
||||
(defcustom org-coderef-label-format "(ref:%s)"
|
||||
"The default coderef format.
|
||||
This format string will be used to search for coderef labels in literal
|
||||
examples (EXAMPLE and SRC blocks). The format can be overwritten
|
||||
an individual literal example with the -f option, like
|
||||
|
||||
#+BEGIN_SRC pascal +n -r -l \"((%s))\"
|
||||
...
|
||||
#+END_SRC
|
||||
|
||||
If you want to use this for HTML export, make sure that the format does
|
||||
not introduce special font-locking, and avoid the HTML special
|
||||
characters `<', `>', and `&'. The reason for this restriction is that
|
||||
the labels are searched for only after htmlize has done its job."
|
||||
:group 'org-edit-structure ; FIXME this is not in the right group
|
||||
:type 'string)
|
||||
|
||||
(defcustom org-edit-fixed-width-region-mode 'artist-mode
|
||||
"The mode that should be used to edit fixed-width regions.
|
||||
These are the regions where each line starts with a colon."
|
||||
@ -5729,13 +5746,14 @@ exit by killing the buffer with \\[org-edit-src-exit]."
|
||||
"Edit, then exit with C-c ' (C-c and single quote)"))
|
||||
(info (org-edit-src-find-region-and-lang))
|
||||
(org-mode-p (eq major-mode 'org-mode))
|
||||
beg end lang lang-f single)
|
||||
beg end lang lang-f single lfmt)
|
||||
(if (not info)
|
||||
nil
|
||||
(setq beg (nth 0 info)
|
||||
end (nth 1 info)
|
||||
lang (nth 2 info)
|
||||
single (nth 3 info)
|
||||
lfmt (nth 4 info)
|
||||
lang-f (intern (concat lang "-mode")))
|
||||
(unless (functionp lang-f)
|
||||
(error "No such language mode: %s" lang-f))
|
||||
@ -5751,6 +5769,8 @@ exit by killing the buffer with \\[org-edit-src-exit]."
|
||||
(funcall lang-f))
|
||||
(set (make-local-variable 'org-edit-src-force-single-line) single)
|
||||
(set (make-local-variable 'org-edit-src-from-org-mode) org-mode-p)
|
||||
(when lfmt
|
||||
(set (make-local-variable 'org-coderef-label-format) lfmt))
|
||||
(when org-mode-p
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "^," nil t)
|
||||
@ -5841,7 +5861,7 @@ the language, a switch telling of the content should be in a single line."
|
||||
("^#\\+ascii:" "\n" "ascii" single-line)
|
||||
)))
|
||||
(pos (point))
|
||||
re re1 re2 single beg end lang)
|
||||
re re1 re2 single beg end lang lfmt match-re1)
|
||||
(catch 'exit
|
||||
(while (setq entry (pop re-list))
|
||||
(setq re1 (car entry) re2 (nth 1 entry) lang (nth 2 entry)
|
||||
@ -5850,19 +5870,27 @@ the language, a switch telling of the content should be in a single line."
|
||||
(if (or (looking-at re1)
|
||||
(re-search-backward re1 nil t))
|
||||
(progn
|
||||
(setq beg (match-end 0) lang (org-edit-src-get-lang lang))
|
||||
(setq match-re1 (match-string 0))
|
||||
(setq beg (match-end 0)
|
||||
lang (org-edit-src-get-lang lang)
|
||||
lfmt (org-edit-src-get-label-format match-re1))
|
||||
(if (and (re-search-forward re2 nil t)
|
||||
(>= (match-end 0) pos))
|
||||
(throw 'exit (list beg (match-beginning 0) lang single))))
|
||||
(throw 'exit (list beg (match-beginning 0)
|
||||
lang single lfmt))))
|
||||
(if (or (looking-at re2)
|
||||
(re-search-forward re2 nil t))
|
||||
(progn
|
||||
(setq end (match-beginning 0))
|
||||
(if (and (re-search-backward re1 nil t)
|
||||
(<= (match-beginning 0) pos))
|
||||
(throw 'exit
|
||||
(list (match-end 0) end
|
||||
(org-edit-src-get-lang lang) single)))))))))))
|
||||
(progn
|
||||
(setq lfmt (org-edit-src-get-label-format
|
||||
(match-string 0)))
|
||||
(throw 'exit
|
||||
(list (match-end 0) end
|
||||
(org-edit-src-get-lang lang)
|
||||
single lfmt))))))))))))
|
||||
|
||||
(defun org-edit-src-get-lang (lang)
|
||||
"Extract the src language."
|
||||
@ -5878,6 +5906,12 @@ the language, a switch telling of the content should be in a single line."
|
||||
(match-string 1 m))
|
||||
(t "fundamental"))))
|
||||
|
||||
(defun org-edit-src-get-label-format (s)
|
||||
"Extract the label format."
|
||||
(save-match-data
|
||||
(if (string-match "-l[ \t]+\\\\?\"\\([^\t\r\n\"]+\\)\\\\?\"" s)
|
||||
(match-string 1 s))))
|
||||
|
||||
(defun org-edit-src-exit ()
|
||||
"Exit special edit and protect problematic lines."
|
||||
(interactive)
|
||||
@ -6265,15 +6299,17 @@ For file links, arg negates `org-context-in-file-links'."
|
||||
(save-restriction
|
||||
(widen)
|
||||
(goto-char (point-min))
|
||||
(re-search-forward (concat "((" label "))") nil t))))
|
||||
(re-search-forward
|
||||
(regexp-quote (format org-coderef-label-format label))
|
||||
nil t))))
|
||||
(when label (message "Label exists already") (sit-for 2))
|
||||
(setq label (read-string "Code line label: " label)))
|
||||
(end-of-line 1)
|
||||
(setq link (format "((%s))" label))
|
||||
(setq link (format org-coderef-label-format label))
|
||||
(setq gc (- 79 (length link)))
|
||||
(if (< (current-column) gc) (org-move-to-column gc t) (insert " "))
|
||||
(insert link)
|
||||
(setq desc nil)))
|
||||
(setq link (concat "(" label ")") desc nil)))
|
||||
|
||||
((eq major-mode 'calendar-mode)
|
||||
(let ((cd (calendar-cursor-to-date)))
|
||||
@ -7170,11 +7206,15 @@ in all files. If AVOID-POS is given, ignore matches near that position."
|
||||
pos (match-beginning 0))))
|
||||
;; There is an exact target for this
|
||||
(goto-char pos))
|
||||
((and (string-match "^((.*))$" s0)
|
||||
((and (string-match "^(\\(.*\\))$" s0)
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(and
|
||||
(re-search-forward (concat "[^[]" (regexp-quote s0)) nil t)
|
||||
(re-search-forward
|
||||
(concat "[^[]" (regexp-quote
|
||||
(format org-coderef-label-format
|
||||
(match-string 1 s0))))
|
||||
nil t)
|
||||
(setq type 'dedicated
|
||||
pos (1+ (match-beginning 0))))))
|
||||
;; There is a coderef target for this
|
||||
|
Loading…
Reference in New Issue
Block a user