| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470 | ;;; org-src.el --- Source code examples in Org;;;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009;;   Free Software Foundation, Inc.;;;; Author: Carsten Dominik <carsten at orgmode dot org>;;	   Bastien Guerry <bzg AT altern DOT org>;; Keywords: outlines, hypermedia, calendar, wp;; Homepage: http://orgmode.org;; Version: 6.28c;;;; This file is part of GNU Emacs.;;;; GNU Emacs is free software: you can redistribute it and/or modify;; it under the terms of the GNU General Public License as published by;; the Free Software Foundation, either version 3 of the License, or;; (at your option) any later version.;; GNU Emacs is distributed in the hope that it will be useful,;; but WITHOUT ANY WARRANTY; without even the implied warranty of;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the;; GNU General Public License for more details.;; You should have received a copy of the GNU General Public License;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Commentary:;; This file contains the code dealing with source code examples in Org-mode.;;; Code:(require 'org-macs)(require 'org-compat)(declare-function org-do-remove-indentation "org" (&optional n))(declare-function org-get-indentation "org" (&optional line))(defcustom org-edit-src-region-extra nil  "Additional regexps to identify regions for editing with `org-edit-src-code'.For examples see the function `org-edit-src-find-region-and-lang'.The regular expression identifying the begin marker should end with a newline,and the regexp marking the end line should start with a newline, to make surethere are kept outside the narrowed region."  :group 'org-edit-structure  :type '(repeat	  (list	   (regexp :tag "begin regexp")	   (regexp :tag "end regexp")	   (choice :tag "language"		   (string :tag "specify")		   (integer :tag "from match group")		   (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 literalexamples (EXAMPLE and SRC blocks).  The format can be overwrittenan individual literal example with the -f option, like#+BEGIN_SRC pascal +n -r -l \"((%s))\"...#+END_SRCIf you want to use this for HTML export, make sure that the format doesnot introduce special font-locking, and avoid the HTML specialcharacters `<', `>', and `&'.  The reason for this restriction is thatthe 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."  :group 'org-edit-structure  :type '(choice	  (const artist-mode)	  (const picture-mode)	  (const fundamental-mode)	  (function :tag "Other (specify)")))(defcustom org-edit-src-content-indentation 2  "Indentation for the content is a source code block.This should be the number of spaces added to the indentation of the #+beginline in order to compute the indentation of the block content afterediting it with \\[org-edit-src-code]."  :group 'org-edit-structure  :type 'integer)(defcustom org-edit-src-persistent-message t  "Non-nil means show persistent exit help message while editing src examples.The message is shown in the header-line, which will be created in thefirst line of the window showing the editing buffer.When nil, the message will only be shown intermittently in the echo area."  :group 'org-edit-structure  :type 'boolean)(defvar org-src-mode-hook nil  "Hook  run after Org switched a source code snippet to its Emacs mode.This hook will run- when editing a source code snippet with \"C-c '\".- When formatting a source code snippet for export with htmlize.You may want to use this hook for example to turn off `outline-minor-mode'or similar things which you want to have when editing a source code file,but which mess up the display of a snippet in Org exported files.");;; Editing source examples(defvar org-src-mode-map (make-sparse-keymap))(define-key org-src-mode-map "\C-c'" 'org-edit-src-exit)(define-key org-src-mode-map "\C-x\C-s" 'org-edit-src-save)(defvar org-edit-src-force-single-line nil)(defvar org-edit-src-from-org-mode nil)(defvar org-edit-src-picture nil)(defvar org-edit-src-beg-marker nil)(defvar org-edit-src-end-marker nil)(defvar org-edit-src-overlay nil)(defvar org-edit-src-nindent nil)(define-minor-mode org-src-mode  "Minor mode for language major mode buffers generated by org.This minor mode is turned on in two situations:- when editing a source code snippet with \"C-c '\".- When formatting a source code snippet for export with htmlize.There is a mode hook, and keybindings for `org-edit-src-exit' and`org-edit-src-save'")(defun org-edit-src-code ()  "Edit the source code example at point.The example is copied to a separate buffer, and that buffer is switchedto the correct language mode.  When done, exit with \\[org-edit-src-exit].This will remove the original code in the Org buffer, and replace it withthe edited version."  (interactive)  (let ((line (org-current-line))	(case-fold-search t)	(msg (substitute-command-keys	      "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 (make-marker))	(end (make-marker))	nindent	ovl lang lang-f single lfmt code begline buffer)    (if (not info)	nil      (setq beg (move-marker beg (nth 0 info))	    end (move-marker end (nth 1 info))	    code (buffer-substring-no-properties beg end)	    lang (nth 2 info)	    single (nth 3 info)	    lfmt (nth 4 info)	    nindent (nth 5 info)	    lang-f (intern (concat lang "-mode"))	    begline (save-excursion (goto-char beg) (org-current-line)))      (unless (functionp lang-f)	(error "No such language mode: %s" lang-f))      (goto-line line)      (if (and (setq buffer (org-edit-src-find-buffer beg end))	       (y-or-n-p "Return to existing edit buffer? [n] will revert changes: "))	  (switch-to-buffer buffer)	(when buffer	  (with-current-buffer buffer	    (if (boundp 'org-edit-src-overlay)		(org-delete-overlay org-edit-src-overlay)))	  (kill-buffer buffer))	(setq buffer (generate-new-buffer "*Org Edit Src Example*"))	(setq ovl (org-make-overlay beg end))	(org-overlay-put ovl 'face 'secondary-selection)	(org-overlay-put ovl 'edit-buffer buffer)	(org-overlay-put ovl 'help-echo "Click with mouse-1 to switch to buffer editing this segment")	(org-overlay-put ovl 'face 'secondary-selection)	(org-overlay-put ovl			 'keymap			 (let ((map (make-sparse-keymap)))			   (define-key map [mouse-1] 'org-edit-src-continue)			   map))	(org-overlay-put ovl :read-only "Leave me alone")	(switch-to-buffer buffer)	(insert code)	(remove-text-properties (point-min) (point-max)				'(display nil invisible nil intangible nil))	(org-do-remove-indentation)	(let ((org-inhibit-startup t))	  (funcall lang-f)	  (org-src-mode))	(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)	    (replace-match "")))	(goto-line (1+ (- line begline)))	(org-set-local 'org-edit-src-beg-marker beg)	(org-set-local 'org-edit-src-end-marker end)	(org-set-local 'org-edit-src-overlay ovl)	(org-set-local 'org-edit-src-nindent nindent)	(and org-edit-src-persistent-message	     (org-set-local 'header-line-format msg)))      (message "%s" msg)      t)))(defun org-edit-src-continue (e)  (interactive "e")  (mouse-set-point e)  (let ((buf (get-char-property (point) 'edit-buffer)))    (if buf (switch-to-buffer buf)      (error "Something is wrong here"))))(defun org-edit-src-find-buffer (beg end)  "Find a source editing buffer that is already editing the region BEG to END."  (catch 'exit    (mapc      (lambda (b)       (with-current-buffer b	 (if (and (string-match "\\`*Org Edit " (buffer-name))		  (local-variable-p 'org-edit-src-beg-marker (current-buffer))		  (local-variable-p 'org-edit-src-end-marker (current-buffer))		  (equal beg org-edit-src-beg-marker)		  (equal end org-edit-src-end-marker))	     (throw 'exit (current-buffer)))))     (buffer-list))    nil))(defun org-edit-fixed-width-region ()  "Edit the fixed-width ascii drawing at point.This must be a region where each line starts with a colon followed bya space character.An new buffer is created and the fixed-width region is copied into it,and the buffer is switched into `artist-mode' for editing.  When done,exit with \\[org-edit-src-exit].  The edited text will then replacethe fragment in the Org-mode buffer."  (interactive)  (let ((line (org-current-line))	(case-fold-search t)	(msg (substitute-command-keys	      "Edit, then exit with C-c ' (C-c and single quote)"))	(org-mode-p (eq major-mode 'org-mode))	(beg (make-marker))	(end (make-marker))	nindent ovl beg1 end1 code begline buffer)    (beginning-of-line 1)    (if (looking-at "[ \t]*[^:\n \t]")	nil      (if (looking-at "[ \t]*\\(\n\\|\\'\\)")	  (setq beg1 (point) end1 beg1)	(save-excursion	  (if (re-search-backward "^[ \t]*[^: \t]" nil 'move)	      (setq beg1 (point-at-bol 2))	    (setq beg1 (point))))	(save-excursion	  (if (re-search-forward "^[ \t]*[^: \t]" nil 'move)	      (setq end1 (1- (match-beginning 0)))	    (setq end1 (point))))	(goto-line line))      (setq beg (move-marker beg beg1)	    end (move-marker end end1)	    code (buffer-substring-no-properties beg end)	    begline (save-excursion (goto-char beg) (org-current-line)))      (if (and (setq buffer (org-edit-src-find-buffer beg end))	       (y-or-n-p "Return to existing edit buffer? [n] will revert changes: "))	  (switch-to-buffer buffer)	(when buffer	  (with-current-buffer buffer	    (if (boundp 'org-edit-src-overlay)		(org-delete-overlay org-edit-src-overlay)))	  (kill-buffer buffer))	(setq buffer (generate-new-buffer "*Org Edit Src Example*"))	(setq ovl (org-make-overlay beg end))	(org-overlay-put ovl 'face 'secondary-selection)	(org-overlay-put ovl 'edit-buffer buffer)	(org-overlay-put ovl 'help-echo "Click with mouse-1 to switch to buffer editing this segment")	(org-overlay-put ovl 'face 'secondary-selection)	(org-overlay-put ovl			 'keymap			 (let ((map (make-sparse-keymap)))			   (define-key map [mouse-1] 'org-edit-src-continue)			   map))	(org-overlay-put ovl :read-only "Leave me alone")	(switch-to-buffer buffer)	(insert code)	(remove-text-properties (point-min) (point-max)				'(display nil invisible nil intangible nil))	(setq nindent (org-do-remove-indentation))	(cond	 ((eq org-edit-fixed-width-region-mode 'artist-mode)	  (fundamental-mode)	  (artist-mode 1))       (t (funcall org-edit-fixed-width-region-mode)))	(set (make-local-variable 'org-edit-src-force-single-line) nil)	(set (make-local-variable 'org-edit-src-from-org-mode) org-mode-p)	(set (make-local-variable 'org-edit-src-picture) t)	(goto-char (point-min))	(while (re-search-forward "^[ \t]*: ?" nil t)	  (replace-match ""))	(goto-line (1+ (- line begline)))	(org-src-mode)	(org-set-local 'org-edit-src-beg-marker beg)	(org-set-local 'org-edit-src-end-marker end)	(org-set-local 'org-edit-src-overlay ovl)	(org-set-local 'org-edit-src-nindent nindent)	(and org-edit-src-persistent-message	     (org-set-local 'header-line-format msg)))      (message "%s" msg)      t)))(defun org-edit-src-find-region-and-lang ()  "Find the region and language for a local edit.Return a list with beginning and end of the region, a string representingthe language, a switch telling of the content should be in a single line."  (let ((re-list	 (append	  org-edit-src-region-extra	  '(	    ("<src\\>[^<]*>[ \t]*\n?" "\n?[ \t]*</src>" lang)	    ("<literal\\>[^<]*>[ \t]*\n?" "\n?[ \t]*</literal>" style)	    ("<example>[ \t]*\n?" "\n?[ \t]*</example>" "fundamental")	    ("<lisp>[ \t]*\n?" "\n?[ \t]*</lisp>" "emacs-lisp")	    ("<perl>[ \t]*\n?" "\n?[ \t]*</perl>" "perl")	    ("<python>[ \t]*\n?" "\n?[ \t]*</python>" "python")	    ("<ruby>[ \t]*\n?" "\n?[ \t]*</ruby>" "ruby")	    ("^[ \t]*#\\+begin_src\\( \\([^ \t\n]+\\)\\)?.*\n" "\n[ \t]*#\\+end_src" 2)	    ("^[ \t]*#\\+begin_example.*\n" "\n[ \t]*#\\+end_example" "fundamental")	    ("^[ \t]*#\\+html:" "\n" "html" single-line)	    ("^[ \t]*#\\+begin_html.*\n" "\n[ \t]*#\\+end_html" "html")	    ("^[ \t]*#\\+latex:" "\n" "latex" single-line)	    ("^[ \t]*#\\+begin_latex.*\n" "\n[ \t]*#\\+end_latex" "latex")	    ("^[ \t]*#\\+ascii:" "\n" "fundamental" single-line)	    ("^[ \t]*#\\+begin_ascii.*\n" "\n[ \t]*#\\+end_ascii" "fundamental")	    ("^[ \t]*#\\+docbook:" "\n" "xml" single-line)	    ("^[ \t]*#\\+begin_docbook.*\n" "\n[ \t]*#\\+end_docbook" "xml")	    )))	(pos (point))	re1 re2 single beg end lang lfmt match-re1 ind entry)    (catch 'exit      (while (setq entry (pop re-list))	(setq re1 (car entry) re2 (nth 1 entry) lang (nth 2 entry)	      single (nth 3 entry))	(save-excursion	  (if (or (looking-at re1)		  (re-search-backward re1 nil t))	      (progn		(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)		      ind (org-edit-src-get-indentation (match-beginning 0)))		(if (and (re-search-forward re2 nil t)			 (>= (match-end 0) pos))		    (throw 'exit (list beg (match-beginning 0)				       lang single lfmt ind))))	    (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))		      (progn			(setq lfmt (org-edit-src-get-label-format				    (match-string 0))			      ind (org-edit-src-get-indentation				   (match-beginning 0)))			(throw 'exit			       (list (match-end 0) end				     (org-edit-src-get-lang lang)				     single lfmt ind))))))))))))(defun org-edit-src-get-lang (lang)  "Extract the src language."  (let ((m (match-string 0)))    (cond     ((stringp lang) lang)     ((integerp lang) (match-string lang))     ((and (eq lang 'lang)	   (string-match "\\<lang=\"\\([^ \t\n\"]+\\)\"" m))      (match-string 1 m))     ((and (eq lang 'style)	   (string-match "\\<style=\"\\([^ \t\n\"]+\\)\"" m))      (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-get-indentation (pos)  "Extract the label format."  (save-match-data    (goto-char pos)    (org-get-indentation)))(defun org-edit-src-exit ()  "Exit special edit and protect problematic lines."  (interactive)  (unless (string-match "\\`*Org Edit " (buffer-name (current-buffer)))    (error "This is not an sub-editing buffer, something is wrong..."))  (let ((beg org-edit-src-beg-marker)	(end org-edit-src-end-marker)	(ovl org-edit-src-overlay)	(buffer (current-buffer))	(nindent org-edit-src-nindent)	code line)    (save-excursion      (goto-char (point-min))      (if (looking-at "[ \t\n]*\n") (replace-match ""))      (if (re-search-forward "\n[ \t\n]*\\'" nil t) (replace-match "")))    (setq line (if (org-bound-and-true-p org-edit-src-force-single-line)		   1		 (org-current-line)))    (when (org-bound-and-true-p org-edit-src-force-single-line)      (goto-char (point-min))      (while (re-search-forward "\n" nil t)	(replace-match " "))      (goto-char (point-min))      (if (looking-at "\\s-*") (replace-match " "))      (if (re-search-forward "\\s-+\\'" nil t)	  (replace-match "")))    (when (org-bound-and-true-p org-edit-src-from-org-mode)      (goto-char (point-min))      (while (re-search-forward	      (if (org-mode-p) "^\\(.\\)" "^\\([*]\\|[ \t]*#\\+\\)") nil t)	(replace-match ",\\1")))    (when (org-bound-and-true-p org-edit-src-picture)      (untabify (point-min) (point-max))      (goto-char (point-min))      (while (re-search-forward "^" nil t)	(replace-match ": ")))    (when nindent      (setq nindent (make-string (+ org-edit-src-content-indentation nindent)				 ?\ ))      (goto-char (point-min))      (while (re-search-forward "^" nil t)      (replace-match nindent)))    (setq code (buffer-string))    (switch-to-buffer (marker-buffer beg))    (kill-buffer buffer)    (goto-char beg)    (org-delete-overlay ovl)    (delete-region beg end)    (insert code)    (goto-char beg)    (goto-line (1- (+ (org-current-line) line)))    (move-marker beg nil)    (move-marker end nil)))(defun org-edit-src-save ()  "Save parent buffer with current state source-code buffer."  (interactive)  (let ((p (point)) (m (mark)) msg)    (org-edit-src-exit)    (save-buffer)    (setq msg (current-message))    (org-edit-src-code)    (push-mark m 'nomessage)    (goto-char (min p (point-max)))    (message (or msg ""))))(provide 'org-src);; arch-tag: 6a1fc84f-dec7-47be-a416-64be56bea5d8;;; org-src.el ends here
 |