Mercurial > hgrepos > hgweb.cgi > yatex
view yatexsec.el @ 577:117a846879bc dev
merged
author | HIROSE Yuuji <yuuji@gentei.org> |
---|---|
date | Tue, 26 Nov 2019 08:26:49 +0900 |
parents | 5eb2b1d824f3 |
children |
line wrap: on
line source
;;; yatexsec.el --- YaTeX sectioning browser ;;; ;;; (c) 1994-2017 by HIROSE Yuuji [yuuji@yatex.org] ;;; Last modified Wed May 30 13:29:50 2018 on firestorm ;;; $Id$ ;;; Code: (defvar YaTeX-sectioning-level '(("part" . 0) ("chapter" . 1) ("section" . 2) ("subsection" . 3) ("subsubsection" . 4) ("paragraph" . 5) ("subparagraph" . 6)) "*Alist of LaTeX's sectioning command and its level. This value must be written in numerically ascending order and consecutive. Needn't define the level of `*' commands such as `section*'.") (defvar YaTeX-sectioning-max-level (cdr (nth (1- (length YaTeX-sectioning-level)) YaTeX-sectioning-level)) "*The heighest(numerically) level of sectioning command. This must be the heighest number in YaTeX-sectioning-level.") (defun YaTeX-sectioning-map-hide (map) (let ((ch ?0)) (while (<= ch ?9) (define-key map (char-to-string ch) 'YaTeX-sectioning-hide) (setq ch (1+ ch)))) ) (defvar YaTeX-sectioning-minibuffer-map nil "Key map used in minibuffer for sectioning.") (if YaTeX-sectioning-minibuffer-map nil (setq YaTeX-sectioning-minibuffer-map (copy-keymap minibuffer-local-completion-map)) (define-key YaTeX-sectioning-minibuffer-map "\C-p" 'YaTeX-sectioning-up) (define-key YaTeX-sectioning-minibuffer-map "\C-e" 'YaTeX-sectioning-up) (define-key YaTeX-sectioning-minibuffer-map "\C-i" 'YaTeX-minibuffer-complete) (define-key YaTeX-sectioning-minibuffer-map " " 'YaTeX-minibuffer-complete) (define-key YaTeX-sectioning-minibuffer-map "\C-n" 'YaTeX-sectioning-down) (define-key YaTeX-sectioning-minibuffer-map "\C-x" 'YaTeX-sectioning-down) (define-key YaTeX-sectioning-minibuffer-map "\C-v" 'YaTeX-sectioning-scroll-up) (define-key YaTeX-sectioning-minibuffer-map "\C-c" 'YaTeX-sectioning-scroll-up) (define-key YaTeX-sectioning-minibuffer-map "\M-v" 'YaTeX-sectioning-scroll-down) (define-key YaTeX-sectioning-minibuffer-map "\C-r" 'YaTeX-sectioning-scroll-down) (define-key YaTeX-sectioning-minibuffer-map "\C-w" (function (lambda () (interactive) (YaTeX-sectioning-scroll-down 1)))) (define-key YaTeX-sectioning-minibuffer-map "\C-z" (function (lambda () (interactive) (YaTeX-sectioning-scroll-up 1)))) (define-key YaTeX-sectioning-minibuffer-map "\C-l" 'YaTeX-sectioning-recenter) (define-key YaTeX-sectioning-minibuffer-map "?" 'YaTeX-sectioning-help) (YaTeX-sectioning-map-hide YaTeX-sectioning-minibuffer-map) ) (defvar YaTeX-sectioning-buffer-map nil "Key map used in YaTeX-sectioning-buffer.") (if YaTeX-sectioning-buffer-map nil (setq YaTeX-sectioning-buffer-map (make-sparse-keymap)) (define-key YaTeX-sectioning-buffer-map " " 'YaTeX-sectioning-buffer-jump) (define-key YaTeX-sectioning-buffer-map "." 'YaTeX-sectioning-buffer-show) (define-key YaTeX-sectioning-buffer-map (concat YaTeX-prefix "\C-c") 'YaTeX-sectioning-buffer-jump) (define-key YaTeX-sectioning-buffer-map "u" 'YaTeX-shift-section-up) (define-key YaTeX-sectioning-buffer-map "d" 'YaTeX-shift-section-down) (define-key YaTeX-sectioning-buffer-map "U" 'YaTeX-shift-section-up-region) (define-key YaTeX-sectioning-buffer-map "D" 'YaTeX-shift-section-down-region) (define-key YaTeX-sectioning-buffer-map "s" 'YaTeX-sync-section-buffer) (define-key YaTeX-sectioning-buffer-map "n" 'YaTeX-sectioning-buffer-next-line) (define-key YaTeX-sectioning-buffer-map "p" 'YaTeX-sectioning-buffer-prev-line) (define-key YaTeX-sectioning-buffer-map "h" 'describe-mode) (define-key YaTeX-sectioning-buffer-map "o" 'other-window) (define-key YaTeX-sectioning-buffer-map "-" 'shrink-window) (define-key YaTeX-sectioning-buffer-map "+" 'enlarge-window) (define-key YaTeX-sectioning-buffer-map "q" 'delete-window) (define-key YaTeX-sectioning-buffer-map "\C-_" 'YaTeX-shift-section-undo) (and YaTeX-emacs-19 (boundp 'window-system) (eq window-system 'x) (define-key YaTeX-sectioning-buffer-map [?\C-/] 'YaTeX-shift-section-undo)) (YaTeX-sectioning-map-hide YaTeX-sectioning-buffer-map) ) (defun YaTeX-sectioning-mode () "Mode for browsing document's sectioning structure. \\[YaTeX-shift-section-up] Shift up a sectioning command \\[YaTeX-shift-section-down] Shift down a sectioning command \\[YaTeX-shift-section-up-region] Shift up sectioning commands in region \\[YaTeX-shift-section-down-region] Shift down sectioning commands in region \\[YaTeX-shift-section-undo] Undo changes of shifting \\[YaTeX-sync-section-buffer] Synchronize sectioning buffer with source \\[YaTeX-sectioning-buffer-next-line] Next line \\[YaTeX-sectioning-buffer-prev-line] Previous line \\[YaTeX-sectioning-buffer-jump] Previous line \\[YaTeX-sectioning-buffer-show] Show curresponding source line " (interactive) (setq major-mode 'YaTeX-sectioning-mode mode-name "sectioning") (use-local-map YaTeX-sectioning-buffer-map) ) (defvar YaTeX-sectioning-buffer-parent nil) (defun YaTeX-sectioning-buffer-jump-internal (&optional keep) (let ((p (point)) ;save-excursion is NG because ptn ln) ;this function should switch buffer (beginning-of-line) (if (re-search-forward YaTeX-sectioning-regexp) (progn (save-restriction (narrow-to-region (point-beginning-of-line) (point-end-of-line)) (setq ptn (buffer-substring (1- (match-beginning 0)) (progn (skip-chars-forward "^}") (1+ (point)))) ln (buffer-substring (progn (search-forward "line:") (match-end 0)) (progn (skip-chars-forward "0-9") (point))))) (goto-char p) (YaTeX-showup-buffer YaTeX-sectioning-buffer-parent nil t) (or (and ln (string< "" ln) (progn (goto-char (point-min)) (forward-line (max 0 (- (YaTeX-str2int ln) 2))) (and (search-forward ptn nil t) (goto-char (match-beginning 0))))) (progn (goto-char (point-max)) (search-backward ptn))) (if keep (goto-buffer-window YaTeX-sectioning-buffer)) (current-buffer)) nil))) (defun YaTeX-sectioning-buffer-jump (&optional keep) "Goto corresponding sectioning unit with current line in the next window. If optional argument KEEP is non-nil, only shows the line." (interactive) (if (and YaTeX-sectioning-buffer-parent (get-buffer YaTeX-sectioning-buffer-parent)) (YaTeX-sectioning-buffer-jump-internal keep) (message "No line number expression.")) ) (defun YaTeX-sectioning-buffer-show () "Show corresponding sectioning unit with current line." (interactive) (YaTeX-sectioning-buffer-jump-internal t) ) (defun YaTeX-sectioning-hide-under (n) "Hide sectioning commands under level N." (let ((cw (selected-window))) (YaTeX-showup-buffer YaTeX-sectioning-buffer nil t) (if (>= n YaTeX-sectioning-max-level) (progn (set-selective-display nil) (message "Show all.")) (set-selective-display (1+ n)) (if (rassq n YaTeX-sectioning-level) (message "Hide lower than %s" (car (rassq n YaTeX-sectioning-level))) (message ""))) (if (numberp selective-display) (setq mode-name (format "level %d" (1- selective-display))) (setq mode-name (format "all"))) (select-window cw)) ) (defun YaTeX-sectioning-hide () "Call YaTeX-sectioning-hide-under with argument according to pressed key." (interactive) (YaTeX-sectioning-hide-under (- (YaTeX-last-key) ?0))) (defun YaTeX-sectioning-help () "Show help of sectioning." (interactive) (let ((cw (selected-window)) sb (hb (get-buffer-create "*Help*"))) (unwind-protect (progn (other-window 1) (setq sb (current-buffer)) (switch-to-buffer hb) (setq buffer-read-only nil) ;; Emacs26 (erase-buffer) (insert "===== View sectioning ===== C-p Up sectioning level. 0 Show only \\part, C-n Down sectioning level. 1 and \\chapter, C-v Scroll up *Sectioning line* buffer. 2 and \\section, M-v Scroll down *Sectioning line* buffer. 3 and \\subsection, C-z Scroll up by 1 line. 4 and \\subsubsection, C-w Scroll down by 1 line. 5 and \\paragraph. SPC Complete word. 6 Show all. TAB Complete word. C-l Recenter recent line. RET Select. ==== End of HELP ===== ") (set-buffer-modified-p nil) (goto-char (point-min)) (momentary-string-display "" (point-min))) (bury-buffer hb) (switch-to-buffer sb) (select-window cw))) ) (defun YaTeX-sectioning-up (n) "Up section level. Refers the YaTeX-read-section-in-minibuffer's local variable minibuffer-start." (interactive "p") (if (eq (selected-window) (minibuffer-window)) (let*((command (YaTeX-minibuffer-string)) (aster (and (string< "" command) (equal (substring command -1) "*"))) (command (if aster (substring command 0 -1) command)) (alist YaTeX-sectioning-level) (level 0)) (or (assoc command alist) (error "No such sectioning command.")) (while (not (string= (car (nth level alist)) command)) (setq level (1+ level))) ;I want to use `member'.... (setq level (- level n)) (if (or (< level 0) (>= level (length alist))) (ding) (YaTeX-minibuffer-erase) (insert (concat (car (nth level alist)) (if aster "*" "")))))) ) (defun YaTeX-sectioning-down (n) "Down section level." (interactive "p") (YaTeX-sectioning-up (- n)) ) (defun YaTeX-sectioning-scroll-up (n) (interactive "P") (let ((section-buffer YaTeX-sectioning-buffer) (cw (selected-window))) (YaTeX-showup-buffer section-buffer nil t) (unwind-protect (scroll-up (or n (- (window-height) 2))) (select-window cw))) ) (defun YaTeX-sectioning-scroll-down (n) (interactive "P") (let ((section-buffer YaTeX-sectioning-buffer) (cw (selected-window))) (YaTeX-showup-buffer section-buffer nil t) (unwind-protect (scroll-down (or n (- (window-height) 2))) (select-window cw))) ) (defun YaTeX-sectioning-recenter (arg) "Recenter `<<--' line" (interactive "P") (let ((cw (selected-window))) (unwind-protect (progn (YaTeX-showup-buffer YaTeX-sectioning-buffer nil t) (or (search-forward "<<--" nil t) (search-backward "<<--" nil)) (recenter (or arg (/ (window-height) 2)))) (select-window cw))) ) (defvar YaTeX-sectioning-minibuffer " *sectioning*" "Miniuffer used for sectioning") ;;;###autoload (defun YaTeX-read-section-in-minibuffer (prompt table &optional default delim) (interactive) (let ((minibuffer-completion-table table)) (read-from-minibuffer prompt default YaTeX-sectioning-minibuffer-map)) ) (defun YaTeX-get-sectioning-level () "Get section-level on the cursor." (cdr-safe (assoc (buffer-substring (point) (progn (skip-chars-forward "a-z") (point))) YaTeX-sectioning-level)) ) (defvar YaTeX-sectioning-buffer "*Sectioning lines*") (defvar YaTeX-sectioning-indent 1) (defun YaTeX-collect-sections () "Collect all the lines which contains sectioning command." (let ((cw (selected-window)) level indent begp (prevp 1) (prevl 1) (pattern (concat YaTeX-ec-regexp "\\(" YaTeX-sectioning-regexp "\\)\\*?{")) (cb (current-buffer))) (save-excursion (set-buffer (get-buffer-create YaTeX-sectioning-buffer)) (setq buffer-read-only nil) (erase-buffer) (set-buffer cb) (YaTeX-showup-buffer YaTeX-sectioning-buffer) ;show buffer (goto-char (point-min)) (let ((standard-output (get-buffer YaTeX-sectioning-buffer))) (while (re-search-forward pattern nil t) (goto-char (1+ (match-beginning 0))) (setq level (YaTeX-get-sectioning-level) begp (match-beginning 0)) ;;(beginning-of-line) ;;(skip-chars-forward " \t") (setq indent (format "%%%ds" (* level YaTeX-sectioning-indent))) (princ (format indent "")) (if (YaTeX-on-comment-p) (princ "%")) (princ (buffer-substring begp (progn (forward-list 1) (point)))) (setq prevl (+ prevl (count-lines prevp (point)) -1) prevp (point)) (princ (format " (line:%d)" prevl)) (princ "\n"))) (set-buffer YaTeX-sectioning-buffer) (make-local-variable 'YaTeX-sectioning-buffer-parent) (YaTeX-sectioning-mode) (use-local-map YaTeX-sectioning-buffer-map) (setq YaTeX-sectioning-buffer-parent cb) (if (numberp selective-display) (setq mode-name (format "level %d" (1- selective-display)))) YaTeX-sectioning-buffer)) ) (defvar YaTeX-pending-undo nil) (defun YaTeX-section-overview () "Show section overview. Return the nearest sectioning command." (interactive) (let ((cw (selected-window)) (ln (count-lines (point-min) (point))) (pattern "(line:\\([0-9]+\\))") secbuf (command "")) (save-excursion (setq secbuf (YaTeX-collect-sections)) (YaTeX-showup-buffer secbuf nil t) (set-buffer secbuf) (goto-char (point-max)) (while (re-search-backward pattern nil t) (if (< ln (YaTeX-str2int (YaTeX-match-string 1))) nil (beginning-of-line) (search-forward YaTeX-ec) (looking-at YaTeX-TeX-token-regexp) (setq command (YaTeX-match-string 0)) (end-of-line) (insert " <<--") (setq pattern (concat "HackyRegexp" "ForFailure")))) (set-buffer-modified-p nil) (setq buffer-read-only t buffer-undo-list nil) (make-local-variable 'YaTeX-pending-undo) (forward-line 1) (if (eobp) (recenter -1) (recenter -3)) (select-window cw) command)) ) ;;;###autoload (defun YaTeX-make-section-with-overview () "Input sectining command with previous overview." (interactive) (insert YaTeX-ec (YaTeX-read-section-in-minibuffer "Sectioning(Up=C-p, Down=C-n, Help=?): " YaTeX-sectioning-level (YaTeX-section-overview)) "{}") (forward-char -1) ) (defun YaTeX-shifted-section (sc n) "Get SC's N-shifted sectioning command." (let (lv) (setq lv (- (cdr (assoc sc YaTeX-sectioning-level)) n) lv (max (min YaTeX-sectioning-max-level lv) 0)) (car (nth lv YaTeX-sectioning-level))) ) (defun YaTeX-shift-section-up (n) "Shift sectioning command down by level N." (interactive "p") (let ((cb (current-buffer)) sc nsc lv) (if (and YaTeX-sectioning-buffer-parent (get-buffer YaTeX-sectioning-buffer-parent) (save-excursion (beginning-of-line) (skip-chars-forward "^\\\\" (point-end-of-line)) (YaTeX-on-section-command-p YaTeX-sectioning-regexp))) (save-excursion (or (buffer-name (get-buffer YaTeX-sectioning-buffer-parent)) (error "This buffer is obsolete.")) (setq nsc (YaTeX-shifted-section (YaTeX-match-string 1) n)) (YaTeX-sectioning-buffer-jump-internal) (undo-boundary) (goto-char (match-beginning 0)) (skip-chars-forward "\\\\") (delete-region (point) (progn (skip-chars-forward "^*{") (point))) (insert nsc) (undo-boundary) ;; Return to *Sectioning Lines* buffer (select-window (get-buffer-window cb)) (beginning-of-line) (let (buffer-read-only) (delete-region (point) (progn (skip-chars-forward " \t") (point))) (indent-to-column (* (cdr (assoc nsc YaTeX-sectioning-level)) YaTeX-sectioning-indent)) (skip-chars-forward "^\\\\") (delete-region (1+ (point)) (progn (skip-chars-forward "^*{") (point))) (insert nsc) (undo-boundary)) (set-buffer-modified-p nil) (setq YaTeX-pending-undo pending-undo-list) ))) ) (defun YaTeX-shift-section-down (n) "Shift sectioning command down by level N." (interactive "p") (YaTeX-shift-section-up (- n)) ) (defun YaTeX-shift-section-undo (arg) "Undo YaTeX-shift-section-up/down." (interactive "p") (and YaTeX-sectioning-buffer-parent (get-buffer YaTeX-sectioning-buffer-parent) (equal (current-buffer) (get-buffer YaTeX-sectioning-buffer)) (let ((cb (current-buffer)) (lc (if (eq last-command 'YaTeX-shift-section-undo) 'undo t))) (let ((pending-undo-list YaTeX-pending-undo) buffer-read-only (last-command lc)) (undo arg) (setq YaTeX-pending-undo pending-undo-list)) (YaTeX-showup-buffer YaTeX-sectioning-buffer-parent) (goto-buffer-window YaTeX-sectioning-buffer-parent) (undo-boundary) (let ((last-command lc) (pending-undo-list (if (eq lc 'undo) YaTeX-pending-undo pending-undo-list))) (undo arg) (setq YaTeX-pending-undo pending-undo-list)) (goto-buffer-window cb) (setq this-command 'YaTeX-shift-section-undo))) ) (defun YaTeX-sync-section-buffer () "Synchronize *Sectioning Lines* buffer with parent buffer." (interactive) (if (and YaTeX-sectioning-buffer-parent (get-buffer YaTeX-sectioning-buffer-parent)) (let ((cb (current-buffer)) (p (point))) (set-buffer (get-buffer YaTeX-sectioning-buffer-parent)) (YaTeX-section-overview) (switch-to-buffer cb) (goto-char p))) ) (defun YaTeX-shift-section-up-region (beg end n) "Shift sectioning commands in region down by level N." (interactive "r\np") (or YaTeX-sectioning-buffer-parent (get-buffer YaTeX-sectioning-buffer-parent) (error "Can't find corresponding LaTeX buffer")) (save-excursion (goto-char beg) (let ((cb (current-buffer)) nsc from to repllist (e (make-marker))) (set-marker e end) (while (progn (skip-chars-forward "^\\\\") (< (point) e)) (YaTeX-on-section-command-p YaTeX-sectioning-regexp) (setq from (YaTeX-match-string 0) nsc (YaTeX-shifted-section (YaTeX-match-string 1) n)) (goto-char (match-beginning 0)) (let (buffer-read-only) ;(delete-region (point) (progn (beginning-of-line) (point))) (delete-region (progn (beginning-of-line) (point)) (progn (skip-chars-forward " \t") (point))) (indent-to-column (cdr (assoc nsc YaTeX-sectioning-level))) (delete-region (progn (skip-chars-forward "%\\\\") (point)) (progn (skip-chars-forward "^*{") (point))) (insert nsc)) (YaTeX-on-section-command-p YaTeX-sectioning-regexp) (setq to (YaTeX-match-string 0) repllist (cons (cons from to) repllist)) (forward-line 1)) (YaTeX-showup-buffer YaTeX-sectioning-buffer-parent) (goto-buffer-window YaTeX-sectioning-buffer-parent) (save-excursion (goto-char (point-max)) (undo-boundary) (while repllist (if (search-backward (car (car repllist)) nil t) (progn (goto-char (match-beginning 0)) ;confirm (delete-region (point) (match-end 0)) (insert (cdr (car repllist))) (goto-char (match-beginning 0)))) (setq repllist (cdr repllist)))) (goto-buffer-window cb))) ) (defun YaTeX-shift-section-down-region (beg end n) "Shift sectioning commands in region down by level N." (interactive "r\np") (YaTeX-shift-section-up-region beg end (- n)) ) (defun YaTeX-sectioning-buffer-next-line (n) "Move to next line in *Sectioning Lines* buffer." (interactive "p") (forward-line n) (skip-chars-forward " \t%") ) (defun YaTeX-sectioning-buffer-prev-line (n) "Move to previous line in *Sectioning Lines* buffer." (interactive "p") (YaTeX-sectioning-buffer-next-line (- n)) ) (provide 'yatexsec)