branch: main commit 14de1605acdfaedda60568b0f4e06e48b4a17d41 Author: Paul Nelson <ultr...@gmail.com> Commit: Arash Esbati <ar...@gnu.org>
Add folding support for \begin and \end macros * NEWS.org (Added): Announce the addition. * auctex.texi (Folding Macros and Environments): Document the new user option. * tex-fold.el (TeX-fold-macro-spec-list): Add begin and end entries. (TeX-fold-begin-display, TeX-fold-end-display): New functions, added above as entries. (TeX-fold--helper-display): New helper function. (TeX-fold-begin-end-spec-list): New user option, used by the above functions. (TeX-fold-format-titled-block, TeX-fold-format-titled-alertblock, TeX-fold-format-theorem-environment): New functions used in the default value of the new user option. (bug#73724) --- NEWS.org | 4 ++ doc/auctex.texi | 75 ++++++++++++++++++++++++++ tex-fold.el | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 239 insertions(+) diff --git a/NEWS.org b/NEWS.org index 6eddeb2f..6960e062 100644 --- a/NEWS.org +++ b/NEWS.org @@ -11,6 +11,10 @@ ** Added +- Add support for folding of =\begin{env}= and =\end{env}= macros. The + replacement specifiers are controlled by the custom option + ~TeX-fold-begin-end-spec-list~. + - Add new custom option ~TeX-fold-alert-color~ which determines the color used when folding the ~\alert~ macro, defaults to ~red~. diff --git a/doc/auctex.texi b/doc/auctex.texi index d8e92e80..0356b96d 100644 --- a/doc/auctex.texi +++ b/doc/auctex.texi @@ -2880,6 +2880,81 @@ replacement specifier given by the default value of @code{TeX-fold-macro-spec-list}). @end defopt +@defopt TeX-fold-begin-end-spec-list +List of replacement specifiers for @samp{\begin@{@var{env}@}} and +@samp{\end@{@var{env}@}} macros. This option is used only when the +replacement specifiers for @samp{begin} and @samp{end} macros in +@code{TeX-fold-macro-spec-list} are set to their default values: +@code{TeX-fold-begin-display} and @code{TeX-fold-end-display}, +respectively. + +Each item in the list consists of two elements. The first element is a +cons cell @code{(@var{BEGIN} . @var{END})}, where @var{BEGIN} and +@var{END} are the display specifications for @samp{\begin@{...@}} and +@samp{\end@{...@}} macros, respectively. Each specification can be +either: + +@itemize @bullet +@item +A string, which will be used directly as the fold display string. + +@item +A function symbol, which will be called with two arguments: the +(unabbreviated) environment name and a list of the remaining mandatory +macro arguments. The function should return a string to be used as the +fold display. +@end itemize + +The second element is a list of environment types. Each type can be: + +@itemize @bullet +@item +A string representing the environment name (e.g., @code{"remark"}). + +@item +A list with the first element being the environment name and the remaining +elements being any abbreviated forms of that name (e.g., @code{("remark" +"rem" "rmk")}). +@end itemize + +For example: + +@lisp +(((">" . "<") ("itemize" "enumerate" "description" "frame")) + ((TeX-fold-format-theorem-environment . "*") + ("note" ("theorem" "thm")))) +@end lisp + +In this example: + +@itemize @bullet +@item +@samp{\begin@{itemize@}}, @samp{\begin@{enumerate@}}, +@samp{\begin@{description@}} and @samp{\begin@{frame@}} will fold to +@samp{>}, while their corresponding @samp{\end@{...@}} macros will fold to +@samp{<}. + +@item +@samp{\begin@{note@}} will fold to @samp{Note}. + +@item +@samp{\begin@{theorem@}} and @samp{\begin@{thm@}} will fold to @samp{Theorem}. + +@item +If an optional argument is provided, e.g., @samp{\begin@{theorem@}[Foo]}, +it will fold to @samp{Theorem (Foo)}. + +@item +All corresponding @samp{\end@{...@}} macros for @samp{note}, +@samp{theorem}, and @samp{thm} will fold to @samp{*}. +@end itemize + +To disable folding for @samp{\begin@{...@}} and @samp{\end@{...@}} macros, +you can either set this variable to @code{nil}, or remove the display +specifications for @samp{begin} and @samp{end} from +@code{TeX-fold-macro-spec-list}. +@end defopt + @node Outline @section Outlining the Document @cindex Outlining diff --git a/tex-fold.el b/tex-fold.el index c83b970d..dc7ac340 100644 --- a/tex-fold.el +++ b/tex-fold.el @@ -83,6 +83,8 @@ macros, `math' for math macros and `comment' for comments." ("TM" ("texttrademark")) (TeX-fold-alert-display ("alert")) (TeX-fold-textcolor-display ("textcolor")) + (TeX-fold-begin-display ("begin")) + (TeX-fold-end-display ("end")) (1 ("part" "chapter" "section" "subsection" "subsubsection" "paragraph" "subparagraph" "part*" "chapter*" "section*" "subsection*" "subsubsection*" @@ -616,6 +618,8 @@ Return non-nil if a comment was found and folded, nil otherwise." ;;; Display functions +;;;; textcolor + (defun TeX-fold-textcolor-display (color text &rest _args) "Fold display for a \\textcolor{COLOR}{TEXT} macro." (with-temp-buffer @@ -625,6 +629,8 @@ Return non-nil if a comment was found and folded, nil otherwise." (current-buffer)) (buffer-string))) +;;;; alert + (defcustom TeX-fold-alert-color "red" "Color for alert text." :type 'color @@ -639,6 +645,160 @@ Return non-nil if a comment was found and folded, nil otherwise." (current-buffer)) (buffer-string))) +;;;; begin/end + +(defcustom TeX-fold-begin-end-spec-list + '((("↴" . "↲") + ("itemize" "enumerate" "description" "frame")) + ((TeX-fold-format-titled-block . "◼") + ("block")) + ((TeX-fold-format-titled-alertblock . "◼") + ("alertblock")) + ((TeX-fold-format-theorem-environment . "□") + ("proof")) + ((TeX-fold-format-theorem-environment . "◼") + ("abstract" + "acknowledgment" + "algorithm" + "assumptions" + "claim" + "commentary" + "fact" + "note" + "questions" + ("answer" "ans") + ("conclusion" "conc") + ("condition" "cond") + ("conjecture" "conj") + ("corollary" "cor") + ("criterion" "crit") + ("definition" "def" "defn") + ("example" "ex") + ("exercise" "exer") + ("lemma" "lem") + ("notation" "not") + ("problem" "prob") + ("proposition" "prop") + ("question" "ques") + ("remark" "rem" "rmk") + ("summary" "sum") + ("terminology" "term") + ("theorem" "thm")))) + "Replacement specifier list for \\begin{env} and \\end{env} macros. + +This option is relevant only if the replacement specifiers in +`TeX-fold-macro-spec-list' for \"begin\" and \"end\" macros are the +defaults, namely `TeX-fold-begin-display' and `TeX-fold-end-display'. + +Each item is a list consisting of two elements: + +The first element is a cons cell, with car and cdr the display +specifications for \\begin{...} and \\end{...} macros, respectively. +Each specification is either + + - a string, used as the fold display string, or + + - a function, called with the (unabbreviated) environment name and a + list consisting of the remaining mandatory macro arguments, that + returns a string. + +The second element is a list of environment types, which are either + +- the environment name, e.g., \"remark\", or + +- a list with first element an environment name and remaining elements + any abbreviated environment names, e.g., (\"remark\" \"rem\" \"rmk\")." + :type '(repeat + (group + (cons (choice (string :tag "Display String for \\begin{...}") + (function :tag "Function to execute for \\begin{...}")) + (choice (string :tag "Display String for \\end{...}") + (function :tag "Function to execute for \\end{...}"))) + (repeat :tag "Environment Types" + (choice (string :tag "Environment") + (cons :tag "Environment and Abbreviations" + (string :tag "Environment") + (repeat :tag "Abbreviations" + (string :tag "Abbreviation"))))))) + :package-version '(auctex . "14.0.8")) + + +(defun TeX-fold-begin-display (env &rest args) + "Fold display for a \\begin{ENV}. +Intended for use in `TeX-fold-begin-end-spec-list'. ARGS is a list +consisting of the remaining mandatory macro arguments." + (TeX-fold--helper-display env args #'car)) + +(defun TeX-fold-end-display (env &rest args) + "Fold display for a \\end{ENV} macro. +Intended for use in `TeX-fold-begin-end-spec-list'. ARGS is a list +consisting of the remaining mandatory macro arguments." + (TeX-fold--helper-display env args #'cdr)) + +(defun TeX-fold--helper-display (env args spec-retriever) + "Generate fold display string for \\begin{ENV} or \\end{ENV} macro. +ARGS are the remaining mandatory macro arguments. Returns the string or +function determined by `TeX-fold-begin-end-spec-list' if ENV is found +there, otherwise `abort'. SPEC-RETRIEVER, which should be either `car' +or `cdr', retrieves the appropriate part of the display specification." + (catch 'result + (dolist (item TeX-fold-begin-end-spec-list) + (let* ((spec (funcall spec-retriever (car item))) + (types (cadr item))) + (dolist (type types) + (when-let ((name (cond ((stringp type) + (when (string= env type) + env)) + ((consp type) + (when (member env type) + (car type)))))) + (throw 'result + (if (functionp spec) + (funcall spec name args) + spec)))))) + 'abort)) + +;;;;; block environments + +(defun TeX-fold-format-titled-block (_env args) + "Format fold display for beamer block environments. +Intended for use in `TeX-fold-begin-end-spec-list'. ENV is ignored. +ARGS is a list whose car will be the block title. + +Example: \"\\begin{block}{Theorem 1}\" folds to \"Theorem 1\"." + (car args)) + +(defun TeX-fold-format-titled-alertblock (_env args) + "Format fold display for beamer alertblock environments. +Intended for use in `TeX-fold-begin-end-spec-list'. The arguments +ENV/ARGS and the behavior are as in `TeX-fold-format-titled-block', but +the folded text is colored using `TeX-fold-alert-color'." + (let ((caption (car args))) + (add-face-text-property 0 (length caption) + `(:foreground ,TeX-fold-alert-color) nil caption) + (format "%s" caption))) + +;;;;; theorem-like environments + +(defun TeX-fold-format-theorem-environment (env _args) + "Format fold display for theorem-like LaTeX environments. +Intended for use in `TeX-fold-begin-end-spec-list'. ENV is the +environment name, ARGS are ignored. Returns a string of the form +\"Environment \" or \"Environment (Description) \"" + (let* ((env (with-temp-buffer + (insert env) + (goto-char (point-min)) + (capitalize-word 1) + (buffer-string))) + (description + (car (TeX-fold-macro-nth-arg 1 (point) + (TeX-fold-item-end (point) 'macro) + '(?\[ . ?\]))))) + (concat + (format "%s " env) + (when description + (format "(%s) " description))))) + ;;; Utilities (defun TeX-fold-make-overlay (ov-start ov-end type display-string-spec)