From: Eshel Yaron Date: Fri, 13 Jun 2025 19:05:37 +0000 (+0200) Subject: Drop tex-mode, RefTeX, texinfo.el X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=74325864608c10e00f0691fdf63be266d6160b13;p=emacs.git Drop tex-mode, RefTeX, texinfo.el --- diff --git a/doc/emacs/text.texi b/doc/emacs/text.texi index 392d10cb4cb..b0689fd0c9c 100644 --- a/doc/emacs/text.texi +++ b/doc/emacs/text.texi @@ -1657,17 +1657,6 @@ used for keeping bibliographic references for @LaTeX{} documents. For more information, see the documentation string for the command @code{bibtex-mode}. -@item -The Ref@TeX{} package provides a minor mode which can be used with -@LaTeX{} mode to manage bibliographic references. -@ifinfo -@xref{Top,The Ref@TeX{} Manual,,reftex}. -@end ifinfo -@ifnotinfo -For more information, see the Ref@TeX{} Info manual, which is -distributed with Emacs. -@end ifnotinfo - @item The AUC@TeX{} package provides more advanced features for editing @TeX{} and its related formats, including the ability to preview diff --git a/doc/misc/Makefile.in b/doc/misc/Makefile.in index 7416eac18c1..0eff0269a73 100644 --- a/doc/misc/Makefile.in +++ b/doc/misc/Makefile.in @@ -70,7 +70,7 @@ INFO_COMMON = auth autotype calc ccmode cl dbus dired-x \ emacs-mime epa erc ert eshell eudc eww flymake forms gnus \ htmlfontify info.info mairix-el message \ modus-themes newsticker nxml-mode octave-mode org pcl-cvs pgg \ - rcirc reftex remember sasl sc ses sieve smtpmail \ + rcirc remember sasl sc ses sieve smtpmail \ speedbar todo-mode tramp transient url use-package \ vtable widget woman @@ -185,7 +185,7 @@ $(foreach ifile,$(filter-out info.info,$(INFO_TARGETS)),$(eval $(call info_templ ## FIXME Updating this list manually is unreliable. need_emacsver = calc cl dired-x efaq efaq-w32 erc forms \ - newsticker reftex remember use-package woman + newsticker remember use-package woman need_emacsver_prefix = $(addprefix ${buildinfodir}/,${need_emacsver}) $(need_emacsver_prefix:=.info) $(need_emacsver:=.dvi) $(need_emacsver:=.pdf) $(need_emacsver:=.html) : ${emacsdir}/emacsver.texi diff --git a/doc/misc/reftex.texi b/doc/misc/reftex.texi deleted file mode 100644 index 40ffbac737d..00000000000 --- a/doc/misc/reftex.texi +++ /dev/null @@ -1,6092 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@c %**start of header -@setfilename ../../info/reftex.info -@settitle RefTeX User Manual -@include docstyle.texi -@synindex ky cp -@syncodeindex vr cp -@syncodeindex fn cp - -@ifnottex -@macro RefTeX {} -Ref@TeX{} -@end macro -@macro AUCTeX {} -AUC@TeX{} -@end macro -@macro BibTeX {} -Bib@TeX{} -@end macro -@macro ConTeXt {} -Con@TeX{}t -@end macro -@end ifnottex -@tex -\gdef\RefTeX{Ref\TeX} -\gdef\AUCTeX{AUC\TeX} -\gdef\BibTeX{Bib\TeX} -\gdef\ConTeXt{Con\TeX t} -@end tex - -@include emacsver.texi - -@set VERSION @value{EMACSVER} -@set AUCTEXSITE @uref{https://www.gnu.org/software/auctex/,@AUCTeX{} web site} -@set MAINTAINERSITE @uref{https://www.gnu.org/software/auctex/reftex.html,@RefTeX{} web page} -@set MAINTAINERCONTACT @uref{mailto:auctex-devel@@gnu.org,contact the maintainers} -@set MAINTAINER the @AUCTeX{} project -@set SUPPORTADDRESS @AUCTeX{} user mailing list (@email{auctex@@gnu.org}) -@set DEVELADDRESS @AUCTeX{} developer mailing list (@email{auctex-devel@@gnu.org}) -@set BUGADDRESS @AUCTeX{} bug mailing list (@email{bug-auctex@@gnu.org}) -@c %**end of header - -@copying -This manual documents @RefTeX{} (version @value{VERSION}), a package -to do labels, references, citations and indices for LaTeX documents -with Emacs. - -Copyright @copyright{} 1997--2025 Free Software Foundation, Inc. - -@quotation -Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.3 or -any later version published by the Free Software Foundation; with no -Invariant Sections, with the Front-Cover Texts being ``A GNU Manual'', -and with the Back-Cover Texts as in (a) below. A copy of the license -is included in the section entitled ``GNU Free Documentation License''. - -(a) The FSF's Back-Cover Text is: ``You have the freedom to copy and -modify this GNU manual.'' -@end quotation -@end copying - -@dircategory Emacs misc features -@direntry -* RefTeX: (reftex). Emacs support for LaTeX cross-references - and citations. -@end direntry - -@finalout - -@c Macro definitions - -@c Subheadings inside a table. Need a difference between info and the rest. -@macro tablesubheading{text} -@ifinfo -@subsubheading \text\ -@end ifinfo -@ifnotinfo -@item @b{\text\} -@end ifnotinfo -@end macro - -@titlepage -@title @RefTeX{} User Manual -@subtitle Support for @LaTeX{} labels, references, citations and index entries with GNU Emacs -@subtitle Version @value{VERSION} - -@author by Carsten Dominik -@page -@vskip 0pt plus 1filll -@insertcopying -@end titlepage - -@summarycontents -@contents - -@ifnottex -@node Top -@top @RefTeX{} - -@insertcopying - -@RefTeX{} is a package for managing Labels, References, Citations and -index entries with GNU Emacs. - -This manual documents @RefTeX{} version @value{VERSION}. - -Don't be discouraged by the size of this manual, which covers @RefTeX{} -in great depth. All you need to know to use @RefTeX{} can be summarized -on two pages (@pxref{RefTeX in a Nutshell}). You can go back later to -other parts of this document when needed. - -@menu -* Introduction:: Quick-Start information. - -* Table of Contents:: A Tool to move around quickly. -* Labels and References:: Creating and referencing labels. -* Citations:: Creating Citations. -* Index Support:: Creating and Checking Index Entries. -* Viewing Cross-References:: Who references or cites what? - -* RefTeXs Menu:: The Ref menu in the menubar. -* Key Bindings:: The default key bindings. -* Faces:: Fontification of RefTeX's buffers. -* Multifile Documents:: Document spread over many files. -* Language Support:: How to support other languages. -* Finding Files:: Included @TeX{} files and @BibTeX{} .bib files. -* Optimizations:: When RefTeX is too slow. -* AUCTeX:: Cooperation with @AUCTeX{}. -* Problems and Work-Arounds:: First Aid. -* Imprint:: Author, Web-site, Thanks - -* Commands:: Which are the available commands. -* Options:: How to extend and configure RefTeX. -* Changes:: A List of recent changes to RefTeX. -* GNU Free Documentation License:: The license for this documentation. - -The Index - -* Index:: The full index. - -@detailmenu - --- The Detailed Node Listing --- - -Introduction - -* Installation:: How to install and activate RefTeX. -* RefTeX in a Nutshell:: A brief summary and quick guide. - -Labels and References - -* Creating Labels:: -* Referencing Labels:: -* Builtin Label Environments:: The environments RefTeX knows about. -* Defining Label Environments:: ... and environments it doesn't. -* Reference Info:: View the label corresponding to a \ref. -* Reference Styles:: Macros to be used instead of \ref. -* LaTeX xr Package:: References to external documents. - -Defining Label Environments - -* Theorem and Axiom:: Defined with @code{\newenvironment}. -* Quick Equation:: When a macro sets the label type. -* Figure Wrapper:: When a macro argument is a label. -* Adding Magic Words:: Other words for other languages. -* Using \eqref:: How to switch to this AMS-LaTeX macro. -* Non-Standard Environments:: Environments without \begin and \end -* Putting it Together:: How to combine many entries. - -Citations - -* Creating Citations:: How to create them. -* Citation Styles:: Natbib, Harvard, Chicago and Co. -* Citation Info:: View the corresponding database entry. -* Chapterbib and Bibunits:: Multiple bibliographies in a Document. -* Citations Outside LaTeX:: How to make citations in Emails etc. -* BibTeX Database Subsets:: Extract parts of a big database. - -Index Support - -* Creating Index Entries:: Macros and completion of entries. -* The Index Phrases File:: A special file for global indexing. -* Displaying and Editing the Index:: The index editor. -* Builtin Index Macros:: The index macros RefTeX knows about. -* Defining Index Macros:: ... and macros it doesn't. - -The Index Phrases File - -* Collecting Phrases:: Collecting from document or external. -* Consistency Checks:: Check for duplicates etc. -* Global Indexing:: The interactive indexing process. - -AUCTeX - -* AUCTeX-RefTeX Interface:: How both packages work together -* Style Files:: @AUCTeX{}'s style files can support RefTeX -* Bib-Cite:: Hypertext reading of a document - -Options, Keymaps, Hooks - -* Options - Table of Contents:: -* Options - Defining Label Environments:: -* Options - Creating Labels:: -* Options - Referencing Labels:: -* Options - Creating Citations:: -* Options - Index Support:: -* Options - Viewing Cross-References:: -* Options - Finding Files:: -* Options - Optimizations:: -* Options - Fontification:: -* Options - Misc:: - -@end detailmenu -@end menu - -@end ifnottex - -@node Introduction -@chapter Introduction -@cindex Introduction - -@RefTeX{} is a specialized package for support of labels, references, -citations, and the index in @LaTeX{}. @RefTeX{} wraps itself round four -@LaTeX{} macros: @code{\label}, @code{\ref}, @code{\cite}, and -@code{\index}. Using these macros usually requires looking up different -parts of the document and searching through @BibTeX{} database files. -@RefTeX{} automates these time-consuming tasks almost entirely. It also -provides functions to display the structure of a document and to move -around in this structure quickly. - -@iftex -Don't be discouraged by the size of this manual, which covers @RefTeX{} -in great depth. All you need to know to use @RefTeX{} can be -summarized on two pages (@pxref{RefTeX in a Nutshell}). You can go -back later to other parts of this document when needed. -@end iftex - -@xref{Imprint}, for information about who to contact for help, bug -reports or suggestions. - -@menu -* Installation:: How to install and activate RefTeX. -* RefTeX in a Nutshell:: A brief summary and quick guide. -@end menu - -@node Installation -@section Installation -@cindex Installation - -@RefTeX{} has been bundled and pre-installed with Emacs since -version 20.2. - -@findex turn-on-reftex -@findex reftex-mode -@findex use-package -@vindex LaTeX-mode-hook -@vindex latex-mode-hook -To turn @RefTeX{} Mode on and off in a particular buffer, use -@kbd{M-x reftex-mode @key{RET}}. To turn on @RefTeX{} Mode for all -LaTeX files, add the following lines to your @file{.emacs} file: - -@lisp -(add-hook 'LaTeX-mode-hook #'turn-on-reftex) ; with AUCTeX LaTeX mode -(add-hook 'latex-mode-hook #'turn-on-reftex) ; with Emacs latex mode -@end lisp - -@noindent -Users of the use-package library can achieve the same result with: - -@lisp -(use-package reftex ; with AUCTeX LaTeX mode - :hook (LaTeX-mode . turn-on-reftex)) -(use-package reftex ; with Emacs latex mode - :hook (latex-mode . turn-on-reftex)) -@end lisp - -That's all! - -To get started, read the documentation, in particular the -summary. (@pxref{RefTeX in a Nutshell}) - -In order to produce a printed version of the documentation, use -@code{make pdf} to produce a reftex.pdf file. Analogously you can use -the @code{dvi}, @code{ps}, or @code{html} targets to create DVI, -PostScript or HTML files. - -@subsection Environment -@cindex Finding files -@cindex BibTeX database files, not found -@cindex TeX files, not found -@cindex @code{TEXINPUTS}, environment variable -@cindex @code{BIBINPUTS}, environment variable - -@RefTeX{} needs to access all files which are part of a multifile -document, and the BibTeX database files requested by the -@code{\bibliography} command. To find these files, @RefTeX{} will -require a search path, i.e., a list of directories to check. Normally -this list is stored in the environment variables @code{TEXINPUTS} and -@code{BIBINPUTS} which are also used by @RefTeX{}. However, on some -systems these variables do not contain the full search path. If -@RefTeX{} does not work for you because it cannot find some files, -@xref{Finding Files}. - -@page -@node RefTeX in a Nutshell -@section @RefTeX{} in a Nutshell -@cindex Quick-Start -@cindex Getting Started -@cindex RefTeX in a Nutshell -@cindex Nutshell, RefTeX in a - -@enumerate -@item -@b{Table of Contents}@* Typing @kbd{C-c =} (@code{reftex-toc}) will show -a table of contents of the document. This buffer can display sections, -labels and index entries defined in the document. From the buffer, you -can jump quickly to every part of your document. Press @kbd{?} to get -help. - -@item -@b{Labels and References}@* @RefTeX{} helps to create unique labels -and to find the correct key for references quickly. It distinguishes -labels for different environments, knows about all standard -environments (and many others), and can be configured to recognize any -additional labeled environments you have defined yourself (variable -@code{reftex-label-alist}). - -@itemize @bullet -@item -@b{Creating Labels}@* -Type @kbd{C-c (} (@code{reftex-label}) to insert a label at point. -@RefTeX{} will either -@itemize @minus -@item -derive a label from context (default for section labels) -@item -prompt for a label string (default for figures and tables) or -@item -insert a simple label made of a prefix and a number (all other -environments) -@end itemize -@noindent -Which labels are created how is configurable with the variable -@code{reftex-insert-label-flags}. - -@item -@b{Referencing Labels}@* -To make a reference, type @kbd{C-c )} (@code{reftex-reference}). This -shows an outline of the document with all labels of a certain type -(figure, equation,...) and some label context. Selecting a label -inserts a @code{\ref@{@var{label}@}} macro into the original buffer. -@end itemize - -@item -@b{Citations}@* -Typing @kbd{C-c [} (@code{reftex-citation}) will let you specify a -regular expression to search in current @BibTeX{} database files (as -specified in the @code{\bibliography} command) and pull out a list of -matches for you to choose from. The list is @emph{formatted} and -sorted. The selected article is referenced as @samp{\cite@{@var{key}@}} -(see the variable @code{reftex-cite-format} if you want to insert -different macros). - -@item -@b{Index Support}@* -@RefTeX{} helps to enter index entries. It also compiles all entries -into an alphabetically sorted @file{*Index*} buffer which you can use to -check and edit the entries. @RefTeX{} knows about the standard index -macros and can be configured to recognize any additional macros you have -defined (@code{reftex-index-macros}). Multiple indices are supported. - -@itemize @bullet -@item -@b{Creating Index Entries}@* -To index the current selection or the word at point, type @kbd{C-c /} -(@code{reftex-index-selection-or-word}). The default macro -@code{reftex-index-default-macro} will be used. For a more complex entry -type @kbd{C-c <} (@code{reftex-index}), select any of the index macros -and enter the arguments with completion. - -@item -@b{The Index Phrases File (Delayed Indexing)}@* -Type @kbd{C-c \} (@code{reftex-index-phrase-selection-or-word}) to add -the current word or selection to a special @emph{index phrase file}. -@RefTeX{} can later search the document for occurrences of these -phrases and let you interactively index the matches. - -@item -@b{Displaying and Editing the Index}@* -To display the compiled index in a special buffer, type @kbd{C-c >} -(@code{reftex-display-index}). From that buffer you can check and edit -all entries. -@end itemize - -@page -@item -@b{Viewing Cross-References}@* -When point is on the @var{key} argument of a cross-referencing macro -(@code{\label}, @code{\ref}, @code{\cite}, @code{\bibitem}, -@code{\index}, and variations) or inside a @BibTeX{} database entry, you -can press @kbd{C-c &} (@code{reftex-view-crossref}) to display -corresponding locations in the document and associated @BibTeX{} database -files. @* -When the enclosing macro is @code{\cite} or @code{\ref} and no other -message occupies the echo area, information about the citation or label -will automatically be displayed in the echo area. - -@item -@b{Multifile Documents}@* -Multifile Documents are fully supported. The included files must have a -file variable @code{TeX-master} or @code{tex-main-file} pointing to the -master file. @RefTeX{} provides cross-referencing information from -all parts of the document, and across document borders -(@file{xr.sty}). - -@item -@b{Document Parsing}@* -@RefTeX{} needs to parse the document in order to find labels and other -information. It does it automatically once and updates its list -internally when @code{reftex-label} and @code{reftex-index} are used. -To enforce reparsing, call any of the commands described above with a -raw @kbd{C-u} prefix, or press the @kbd{r} key in the label selection -buffer, the table of contents buffer, or the index buffer. - -@item -@b{@AUCTeX{}}@* -If your major @LaTeX{} mode is @AUCTeX{}, @RefTeX{} can cooperate with -it (see variable @code{reftex-plug-into-AUCTeX}). @AUCTeX{} contains -style files which trigger appropriate settings in @RefTeX{}, so that for -many of the popular @LaTeX{} packages no additional customizations will -be necessary. - -@item -@b{Useful Settings}@* -To integrate RefTeX with @AUCTeX{}, use -@lisp -(setq reftex-plug-into-AUCTeX t) -@end lisp - -To make your own @LaTeX{} macro definitions known to @RefTeX{}, -customize the variables -@example -@code{reftex-label-alist} @r{(for label macros/environments)} -@code{reftex-section-levels} @r{(for sectioning commands)} -@code{reftex-cite-format} @r{(for @code{\cite}-like macros)} -@code{reftex-index-macros} @r{(for @code{\index}-like macros)} -@code{reftex-index-default-macro} @r{(to set the default macro)} -@end example -If you have a large number of macros defined, you may want to write -an @AUCTeX{} style file to support them with both @AUCTeX{} and -@RefTeX{}. - -@item -@b{Where Next?}@* -Go ahead and use @RefTeX{}. Use its menus until you have picked up the -key bindings. For an overview of what you can do in each of the -different special buffers, press @kbd{?}. Read the manual if you get -stuck, or if you are curious what else might be available. The first -part of the manual explains in a tutorial way how to use and customize -@RefTeX{}. The second part is a command and variable reference. -@end enumerate - -@node Table of Contents -@chapter Table of Contents -@cindex @file{*toc*} buffer -@cindex Structure editing -@cindex Table of contents buffer -@findex reftex-toc -@kindex C-c = - -Pressing the keys @kbd{C-c =} pops up a buffer showing the table of -contents of the document. By default, this @file{*toc*} buffer shows -only the sections of a document. Using the @kbd{l} and @kbd{i} keys you -can display all labels and index entries defined in the document as -well. - -With the cursor in any of the lines denoting a location in the -document, simple key strokes will display the corresponding part in -another window, jump to that location, or perform other actions. - -@kindex ? -Here is a list of special commands in the @file{*toc*} buffer. A -summary of this information is always available by pressing -@kbd{?}. - -@table @kbd - -@tablesubheading{General} -@item ? -Display a summary of commands. - -@item 0-9, - -Prefix argument. - -@tablesubheading{Moving around} -@item n -Goto next entry in the table of contents. - -@item p -Goto previous entry in the table of contents. - -@item C-c C-n -Goto next section heading. Useful when many labels and index entries -separate section headings. - -@item C-c C-p -Goto previous section heading. - -@item N z -Jump to section N, using the prefix arg. For example, @kbd{3 z} jumps -to section 3. - -@tablesubheading{Access to document locations} -@item @key{SPC} -Show the corresponding location in another window. This command does -@emph{not} select that other window. - -@item @key{TAB} -Goto the location in another window. - -@item @key{RET} -Go to the location and hide the @file{*toc*} buffer. This will restore -the window configuration before @code{reftex-toc} (@kbd{C-c =}) was -called. - -@item mouse-2 -@vindex reftex-highlight-selection -Clicking with mouse button 2 on a line has the same effect as @key{RET}. -See also variable @code{reftex-highlight-selection}, -@ref{Options - Fontification}. - -@item f -@vindex reftex-toc-follow-mode -@vindex reftex-revisit-to-follow -Toggle follow mode. When follow mode is active, the other window will -always show the location corresponding to the line at point in the -@file{*toc*} buffer. This is similar to pressing @key{SPC} after each -cursor motion. The default for this flag can be set with the variable -@code{reftex-toc-follow-mode}. Note that only context in files already -visited is shown. @RefTeX{} will not visit a file just for follow -mode. See, however, the variable -@code{reftex-revisit-to-follow}. - -@item . -Show calling point in another window. This is the point from where -@code{reftex-toc} was last called. - -@page -@tablesubheading{Promotion and Demotion} - -@item < -Promote the current section. This will convert @code{\section} to -@code{\chapter}, @code{\subsection} to @code{\section} etc. If there is -an active region, all sections in the region will be promoted, including -the one at point. To avoid mistakes, @RefTeX{} requires a fresh -document scan before executing this command; if necessary, it will -automatically do this scan and ask the user to repeat the promotion -command. - -@item > -Demote the current section. This is the opposite of promotion. It will -convert @code{\chapter} to @code{\section} etc. If there is an active -region, all sections in the region will be demoted, including the one at -point. - -@item M-% -Rename the label at point. While generally not recommended, this can be -useful when a package like @file{fancyref} is used where the label -prefix determines the wording of a reference. After a -promotion/demotion it may be necessary to change a few labels from -@samp{sec:xyz} to @samp{cha:xyz} or vice versa. This command can be -used to do this; it launches a query replace to rename the definition -and all references of a label. - -@tablesubheading{Exiting} -@item q -Hide the @file{*toc*} buffer, return to the position where -@code{reftex-toc} was last called. - -@item k -Kill the @file{*toc*} buffer, return to the position where -@code{reftex-toc} was last called. - -@item C-c > -Switch to the @file{*Index*} buffer of this document. With prefix -@samp{2}, restrict the index to the section at point in the @file{*toc*} -buffer. - -@tablesubheading{Controlling what gets displayed} - -@item t -@vindex reftex-toc-max-level -Change the maximum level of toc entries displayed in the @file{*toc*} -buffer. Without prefix arg, all levels will be included. With prefix -arg (e.g., @kbd{3 t}), ignore all toc entries with level greater than -@var{arg} (3 in this case). Chapters are level 1, sections are level 2. -The mode line @samp{T<>} indicator shows the current value. The default -depth can be configured with the variable -@code{reftex-toc-max-level}. - -@item F -@vindex reftex-toc-include-file-boundaries -Toggle the display of the file borders of a multifile document in the -@file{*toc*} buffer. The default for this flag can be set with the -variable @code{reftex-toc-include-file-boundaries}. - -@item l -@vindex reftex-toc-include-labels -Toggle the display of labels in the @file{*toc*} buffer. The default -for this flag can be set with the variable -@code{reftex-toc-include-labels}. When called with a prefix argument, -@RefTeX{} will prompt for a label type and include only labels of -the selected type in the @file{*toc*} buffer. The mode line @samp{L<>} -indicator shows which labels are included. - -@item i -@vindex reftex-toc-include-index-entries -Toggle the display of index entries in the @file{*toc*} buffer. The -default for this flag can be set with the variable -@code{reftex-toc-include-index-entries}. When called with a prefix -argument, @RefTeX{} will prompt for a specific index and include -only entries in the selected index in the @file{*toc*} buffer. The mode -line @samp{I<>} indicator shows which index is used. - -@item c -@vindex reftex-toc-include-context -Toggle the display of label and index context in the @file{*toc*} -buffer. The default for this flag can be set with the variable -@code{reftex-toc-include-context}. - -@tablesubheading{Updating the buffer} - -@item g -Rebuild the @file{*toc*} buffer. This does @emph{not} rescan the -document. - -@item r -@vindex reftex-enable-partial-scans -Reparse the @LaTeX{} document and rebuild the @file{*toc*} buffer. When -@code{reftex-enable-partial-scans} is non-@code{nil}, rescan only the file this -location is defined in, not the entire document. - -@item C-u r -Reparse the @emph{entire} @LaTeX{} document and rebuild the @file{*toc*} -buffer. - -@item x -Switch to the @file{*toc*} buffer of an external document. When the -current document is using the @code{xr} package (@pxref{LaTeX xr Package}), -@RefTeX{} will switch to one of the external documents. - - -@tablesubheading{Automatic recentering} - -@item d -Toggle the display of a dedicated frame displaying just the @file{*toc*} -buffer. Follow mode and visiting locations will not work that frame, -but automatic recentering will make this frame always show your current -editing location in the document (see below). - -@item a -Toggle the automatic recentering of the @file{*toc*} buffer. When this -option is on, moving around in the document will cause the @file{*toc*} -to always highlight the current section. By default, this option is -active while the dedicated @file{*TOC*} frame exists. See also the -variable @code{reftex-auto-recenter-toc}. - -@end table - -@vindex reftex-toc-mode-map -In order to define additional commands for the @file{*toc*} buffer, the -keymap @code{reftex-toc-mode-map} may be used. - -@findex reftex-toc-recenter -@vindex reftex-auto-recenter-toc -@vindex reftex-idle-time -@cindex @file{*toc*} buffer, recentering -@cindex Table of contents buffer, recentering -@kindex C-c - -If you call @code{reftex-toc} while the @file{*toc*} buffer already -exists, the cursor will immediately jump to the right place, i.e., the -section from which @code{reftex-toc} was called will be highlighted. -The command @kbd{C-c -} (@code{reftex-toc-recenter}) will only redisplay -the @file{*toc*} buffer and highlight the correct line without actually -selecting the @file{*toc*} window. This can be useful to quickly find -out where in the document you currently are. You can also automate this -by asking RefTeX to keep track of your current editing position in the -TOC@. The TOC window will then be updated whenever you stop typing for -more than @code{reftex-idle-time} seconds. By default this works only -with the dedicated @file{*TOC*} frame. But you can also force automatic -recentering of the TOC window on the current frame with -@lisp -(setq reftex-auto-recenter-toc t) -@end lisp - - -@cindex Sectioning commands -@cindex KOMA-Script, LaTeX classes -@cindex LaTeX classes, KOMA-Script -@cindex TOC entries for environments -@vindex reftex-section-levels -The section macros recognized by @RefTeX{} are all @LaTeX{} section -macros (from @code{\part} to @code{\subsubparagraph}) and the commands -@code{\addchap} and @code{\addsec} from the KOMA-Script classes. -Additional macros can be configured with the variable -@code{reftex-section-levels}. It is also possible to add certain @LaTeX{} -environments to the table of contents. This is probably only useful for -theorem-like environments. @xref{Defining Label Environments}, for an -example. - -@node Labels and References -@chapter Labels and References -@cindex Labels in LaTeX -@cindex References in LaTeX -@cindex Label category -@cindex Label environment -@cindex @code{\label} - -@LaTeX{} provides a powerful mechanism to deal with cross-references in a -document. When writing a document, any part of it can be marked with a -label, like @samp{\label@{mark@}}. @LaTeX{} records the current value of a -certain counter when a label is defined. Later references to this label -(like @samp{\ref@{mark@}}) will produce the recorded value of the -counter. - -Labels can be used to mark sections, figures, tables, equations, -footnotes, items in enumerate lists etc. @LaTeX{} is context sensitive in -doing this: A label defined in a figure environment automatically -records the figure counter, not the section counter. - -Several different environments can share a common counter and therefore -a common label category. For example labels in both @code{equation} and -@code{eqnarray} environments record the value of the same counter: the -equation counter. - -@menu -* Creating Labels:: -* Referencing Labels:: -* Builtin Label Environments:: The environments RefTeX knows about. -* Defining Label Environments:: ... and environments it doesn't. -* Reference Info:: View the label corresponding to a \ref. -* Reference Styles:: Macros to be used instead of \ref. -* LaTeX xr Package:: References to external documents. -@end menu - -@node Creating Labels -@section Creating Labels -@cindex Creating labels -@cindex Labels, creating -@cindex Labels, deriving from context -@kindex C-c ( -@findex reftex-label - -In order to create a label in a @LaTeX{} document, press @kbd{C-c (} -(@code{reftex-label}). Just like @LaTeX{}, @RefTeX{} is context sensitive -and will figure out the environment it currently is in and adapt the -label to that environment. A label usually consists of a short prefix -indicating the type of the label and a unique mark. @RefTeX{} has -three different modes to create this mark. - -@enumerate -@item -@vindex reftex-translate-to-ascii-function -@vindex reftex-derive-label-parameters -@vindex reftex-label-illegal-re -@vindex reftex-abbrev-parameters -A label can be derived from context. This means, @RefTeX{} takes -the context of the label definition and constructs a label from -that@footnote{Note that the context may contain constructs which are -invalid in labels. @RefTeX{} will therefore strip the accent from -accented Latin-1 characters and remove everything else which is not -valid in labels. This mechanism is safe, but may not be satisfactory -for non-western languages. Check the following variables if you need to -change things: @code{reftex-translate-to-ascii-function}, -@code{reftex-derive-label-parameters}, @code{reftex-label-illegal-re}, -@code{reftex-abbrev-parameters}.}. This works best for section labels, -where the section heading is used to construct a label. In fact, -@RefTeX{}'s default settings use this method only for section -labels. You will be asked to confirm the derived label, or edit -it. - -@item -We may also use a simple unique number to identify a label. This is -mostly useful for labels where it is difficult to come up with a very -good descriptive name. @RefTeX{}'s default settings use this method -for equations, enumerate items and footnotes. The author of @RefTeX{} -tends to write documents with many equations and finds it impossible -to come up with good names for each of them. These simple labels are -inserted without query, and are therefore very fast. Good descriptive -names are not really necessary as @RefTeX{} will provide context to -reference a label (@pxref{Referencing Labels}). - -@item -The third method is to ask the user for a label. This is most -useful for things which are easy to describe briefly and do not turn up -too frequently in a document. @RefTeX{} uses this for figures and -tables. Of course, one can enter the label directly by typing the full -@samp{\label@{mark@}}. The advantage of using @code{reftex-label} -anyway is that @RefTeX{} will know that a new label has been defined. -It will then not be necessary to rescan the document in order to access -this label later. -@end enumerate - -@vindex reftex-insert-label-flags -If you want to change the way certain labels are created, check out the -variable @code{reftex-insert-label-flags} (@pxref{Options - Creating -Labels}). - -If you are using @AUCTeX{} to write your @LaTeX{} documents, you can -set it up to delegate the creation of labels to -@RefTeX{}. @xref{AUCTeX}, for more information. - -@node Referencing Labels -@section Referencing Labels -@cindex Referencing labels -@cindex Labels, referencing -@cindex Selection buffer, labels -@cindex Selection process -@cindex @code{\ref} -@kindex C-c ) -@findex reftex-reference - -@vindex reftex-trust-label-prefix -@RefTeX{} scans the document in order to find all labels. To make -referencing labels easier, it assigns to each label a category, the -@emph{label type} (for example section, table, figure, equation, etc.). -In order to determine the label type, @RefTeX{} parses around each label -to see in what kind of environments it is located. You can speed up -the parsing by using type-specific prefixes for labels and configuring -the variable @code{reftex-trust-label-prefix}. - -Referencing Labels is really at the heart of @RefTeX{}. Press @kbd{C-c -)} in order to reference a label (@code{reftex-reference}). This will -start a selection process and finally insert the complete -@samp{\ref@{label@}} into the buffer. - -@vindex reftex-ref-macro-prompt -First, you can select which reference macro you want to use, -e.g., @samp{\ref} or @samp{\pageref}. Later in the process you have -another chance to make this selection and you can therefore disable this -step by customizing @code{reftex-ref-macro-prompt} if you find it too -intrusive. @xref{Reference Styles}. - -Then, @RefTeX{} will determine the label category which is required. -Often that can be figured out from context. For example, if you write -@samp{As shown in eq.} and then press @kbd{C-c )}, @RefTeX{} knows that -an equation label is going to be referenced. If it cannot figure out -what label category is needed, it will query for one. - -You will then be presented with a label selection menu. This is a -special buffer which contains an outline of the document along with all -labels of the given label category. In addition, next to the label -there will be one line of context of the label definition, which is some -text in the buffer near the label definition. Usually this is -sufficient to identify the label. If you are unsure about a certain -label, pressing @key{SPC} will show the label definition point in -another window. - -In order to reference a label, move the cursor to the correct label and -press @key{RET}. You can also reference several labels with a single -call to @code{reftex-reference} by marking entries with the @kbd{m} -key (see below). - -@kindex ? -Here is a list of special commands in the selection buffer. A summary -of this information is always available from the selection process by -pressing @kbd{?}. - - - -@table @kbd -@tablesubheading{General} -@item ? -Show a summary of available commands. - -@item 0-9,- -Prefix argument. - -@tablesubheading{Moving around} -@item n -Go to next label. - -@item p -Go to previous label. - -@item b -Jump back to the position where you last left the selection buffer. -Normally this should get you back to the last referenced label. - -@item C-c C-n -Goto next section heading. - -@item C-c C-p -Goto previous section heading. - -@item N z -Jump to section N, using the prefix arg. For example @kbd{3 z} jumps to -section 3. - -@tablesubheading{Displaying Context} -@item @key{SPC} -Show the surroundings of the definition of the current label in another -window. See also the @kbd{f} key. - -@item f -@vindex reftex-revisit-to-follow -Toggle follow mode. When follow mode is active, the other window will -always display the full context of the current label. This is similar -to pressing @key{SPC} after each cursor motion. Note that only context -in files already visited is shown. @RefTeX{} will not visit a file -just for follow mode. See, however, the variable -@code{reftex-revisit-to-follow}. - -@item . -Show insertion point in another window. This is the point from where you -called @code{reftex-reference}. - -@tablesubheading{Selecting a label and creating the reference} -@item @key{RET} -Insert a reference to the label at point into the buffer from which the -selection process was started. When entries have been marked, @key{RET} -references all marked labels. - -@item mouse-2 -@vindex reftex-highlight-selection -Clicking with mouse button 2 on a label will accept it like @key{RET} -would. See also variable @code{reftex-highlight-selection}, -@ref{Options - Misc}. - -@vindex reftex-multiref-punctuation -@item m - + , -Mark the current entry. When several entries have been marked, pressing -@kbd{RET} will accept all of them and place them into several -@code{\ref} macros. The special markers @samp{,-+} also store a -separator to be inserted before the corresponding reference. So marking -six entries with the keys @samp{m , , - , +} will give a reference list -like this (see the variable @code{reftex-multiref-punctuation}) -@example -In eqs. (1), (2), (3)--(4), (5) and (6) -@end example - -@item u -Unmark a marked entry. - -@c FIXME: Do we need 'A' as well for consistency? -@cindex LaTeX packages, @code{saferef} -@cindex @code{saferef}, LaTeX package -@item a -Accept the marked entries and put all labels as a comma-separated list -into one @emph{single} @code{\ref} macro. Some packages like -@file{saferef.sty} support multiple references in this way. - -@item l -Use the last referenced label(s) again. This is equivalent to moving to -that label and pressing @key{RET}. - -@item @key{TAB} -Enter a label with completion. This may also be a label which does not -yet exist in the document. - -@item v -Cycle forward through active reference macros. The selected macro is -displayed by the @samp{S<...>} indicator in the mode line of the -selection buffer. This mechanism comes in handy if you are using -@LaTeX{} packages like @code{varioref} or @code{fancyref} and want to -use the special referencing macros they provide (e.g., @code{\vref} or -@code{\fref}) instead of @code{\ref}. - -@item V -Cycle backward through active reference macros. - -@tablesubheading{Exiting} - -@item q -Exit the selection process without inserting any reference into the -buffer. - -@tablesubheading{Controlling what gets displayed} -@vindex reftex-label-menu-flags -The defaults for the following flags can be configured with the variable -@code{reftex-label-menu-flags} (@pxref{Options - Referencing Labels}). - -@item c -Toggle the display of the one-line label definition context in the -selection buffer. - -@item F -Toggle the display of the file borders of a multifile document in the -selection buffer. - -@item t -Toggle the display of the table of contents in the selection buffer. -With prefix @var{arg}, change the maximum level of toc entries displayed -to @var{arg}. Chapters are level 1, sections are level 2. - -@item # -Toggle the display of a label counter in the selection buffer. - -@item % -Toggle the display of labels hidden in comments in the selection -buffers. Sometimes, you may have commented out parts of your document. -If these parts contain label definitions, @RefTeX{} can still display -and reference these labels. - -@tablesubheading{Updating the buffer} -@item g -Update the menu. This will rebuilt the menu from the internal label -list, but not reparse the document (see @kbd{r}). - -@item r -@vindex reftex-enable-partial-scans -Reparse the document to update the information on all labels and rebuild -the menu. If the variable @code{reftex-enable-partial-scans} is -non-@code{nil} and your document is a multifile document, this will -reparse only a part of the document (the file in which the label at -point was defined). - -@item C-u r -Reparse the @emph{entire} document. - -@item s -Switch the label category. After prompting for another label category, -a menu for that category will be shown. - -@item x -Reference a label from an external document. With the @LaTeX{} package -@code{xr} it is possible to reference labels defined in another -document. This key will switch to the label menu of an external -document and let you select a label from there (@pxref{LaTeX xr Package,,xr}). - -@end table - -@vindex reftex-select-label-mode-map -In order to define additional commands for the selection process, the -keymap @code{reftex-select-label-mode-map} may be used. - -@node Builtin Label Environments -@section Builtin Label Environments -@cindex Builtin label environments -@cindex Label environments, builtin -@cindex Environments, builtin -@vindex reftex-label-alist -@vindex reftex-label-alist-builtin - -@RefTeX{} needs to be aware of the environments which can be referenced -with a label (i.e., which carry their own counters). By default, @RefTeX{} -recognizes all labeled environments and macros discussed in @cite{The -@LaTeX{} Companion by Goossens, Mittelbach & Samarin, Addison-Wesley -1994.}. These are: - -@itemize @minus -@item -@cindex @code{figure}, LaTeX environment -@cindex @code{figure*}, LaTeX environment -@cindex @code{table}, LaTeX environment -@cindex @code{table*}, LaTeX environment -@cindex @code{equation}, LaTeX environment -@cindex @code{eqnarray}, LaTeX environment -@cindex @code{enumerate}, LaTeX environment -@cindex @code{\footnote}, LaTeX macro -@cindex LaTeX macro @code{footnote} -@cindex LaTeX core -@code{figure}, @code{figure*}, @code{table}, @code{table*}, @code{equation}, -@code{eqnarray}, @code{enumerate}, the @code{\footnote} macro (this is -the @LaTeX{} core stuff) -@item -@cindex AMS-LaTeX -@cindex @code{amsmath}, LaTeX package -@cindex LaTeX packages, @code{amsmath} -@cindex @code{align}, AMS-LaTeX environment -@cindex @code{gather}, AMS-LaTeX environment -@cindex @code{multline}, AMS-LaTeX environment -@cindex @code{flalign}, AMS-LaTeX environment -@cindex @code{alignat}, AMS-LaTeX environment -@cindex @code{xalignat}, AMS-LaTeX environment -@cindex @code{xxalignat}, AMS-LaTeX environment -@cindex @code{subequations}, AMS-LaTeX environment -@code{align}, @code{gather}, @code{multline}, @code{flalign}, -@code{alignat}, @code{xalignat}, @code{xxalignat}, @code{subequations} -(from AMS-@LaTeX{}'s @file{amsmath.sty} package) -@item -@cindex @code{fancybox}, LaTeX package -@cindex LaTeX packages, @code{fancybox} -@cindex @code{Beqnarray}, LaTeX environment -@code{Beqnarray} (@file{fancybox.sty}) -@item -@cindex @code{ctable}, LaTeX package -@cindex LaTeX packages, @code{ctable} -@cindex @code{\ctable}, LaTeX macro -the @code{\ctable} macro (from @file{ctable.sty}) -@item -@cindex @code{endnote}, LaTeX package -@cindex LaTeX packages, @code{endnote} -@cindex @code{\endnote}, LaTeX macro -the @code{\endnote} macro (from @file{endnotes.sty}) -@item -@cindex @code{floatfig}, LaTeX package -@cindex LaTeX packages, @code{floatfig} -@cindex @code{floatingfig}, LaTeX environment -@code{floatingfig} (@file{floatfig.sty}) -@item -@cindex @code{minted}, LaTeX package -@cindex LaTeX packages, @code{minted} -@cindex @code{listing}, LaTeX environment -@code{listing} (@file{minted.sty}) -@item -@cindex @code{listings}, LaTeX package -@cindex LaTeX packages, @code{listings} -@cindex @code{lstlisting}, LaTeX environment -@code{lstlisting} (@file{listings.sty}) -@item -@cindex @code{longtable}, LaTeX package -@cindex LaTeX packages, @code{longtable} -@cindex @code{longtable}, LaTeX environment -@code{longtable} (@file{longtable.sty}) -@item -@cindex @code{picinpar}, LaTeX package -@cindex LaTeX packages, @code{picinpar} -@cindex @code{figwindow}, LaTeX environment -@cindex @code{tabwindow}, LaTeX environment -@code{figwindow}, @code{tabwindow} (@file{picinpar.sty}) -@item -@cindex @code{sidecap}, LaTeX package -@cindex LaTeX packages, @code{sidecap} -@cindex @code{SCfigure}, LaTeX environment -@cindex @code{SCtable}, LaTeX environment -@code{SCfigure}, @code{SCtable} (@file{sidecap.sty}) -@item -@cindex @code{rotating}, LaTeX package -@cindex LaTeX packages, @code{rotating} -@cindex @code{sidewaysfigure}, LaTeX environment -@cindex @code{sidewaystable}, LaTeX environment -@code{sidewaysfigure}, @code{sidewaystable} (@file{rotating.sty}) -@item -@cindex @code{subfig}, LaTeX package -@cindex LaTeX packages, @code{subfig} -@cindex @code{\subfigure}, LaTeX macro -@cindex @code{\subtable}, LaTeX macro -the @code{\subfigure} and @code{\subtable} macros (from -@file{subfig.sty}) -@item -@cindex @code{wrapfig}, LaTeX package -@cindex LaTeX packages, @code{wrapfig} -@cindex @code{wrapfigure}, LaTeX environment -@code{wrapfigure} (@file{wrapfig.sty}) -@end itemize - -If you want to use other labeled environments, defined with -@code{\newtheorem}, @RefTeX{} needs to be configured to recognize -them (@pxref{Defining Label Environments}). - -@node Defining Label Environments -@section Defining Label Environments -@cindex Label environments, defining - -@vindex reftex-label-alist -@RefTeX{} can be configured to recognize additional labeled -environments and macros. This is done with the variable -@code{reftex-label-alist} (@pxref{Options - Defining Label -Environments}). If you are not familiar with Lisp, you can use the -@code{custom} library to configure this rather complex variable. To do -this, use - -@example -@kbd{M-x customize-variable @key{RET} reftex-label-alist @key{RET}} -@end example - -@vindex reftex-label-alist-builtin -Here we will discuss a few examples, in order to make things clearer. -It can also be instructive to look at the constant -@code{reftex-label-alist-builtin} which contains the entries for -all the builtin environments and macros (@pxref{Builtin Label -Environments}). - -@menu -* Theorem and Axiom:: Defined with @code{\newenvironment}. -* Quick Equation:: When a macro sets the label type. -* Figure Wrapper:: When a macro argument is a label. -* Adding Magic Words:: Other words for other languages. -* Using \eqref:: How to switch to this AMS-@LaTeX{} macro. -* Non-Standard Environments:: Environments without \begin and \end -* Putting it Together:: How to combine many entries. -@end menu - -@node Theorem and Axiom -@subsection Theorem and Axiom Environments -@cindex @code{theorem}, newtheorem -@cindex @code{axiom}, newtheorem -@cindex @code{\newtheorem} - -Suppose you are using @code{\newtheorem} in @LaTeX{} in order to define two -new environments, @code{theorem} and @code{axiom} - -@example -\newtheorem@{axiom@}@{Axiom@} -\newtheorem@{theorem@}@{Theorem@} -@end example - -@noindent -to be used like this: - -@example -\begin@{axiom@} -\label@{ax:first@} - .... -\end@{axiom@} -@end example - -So we need to tell @RefTeX{} that @code{theorem} and @code{axiom} are new -labeled environments which define their own label categories. We can -either use Lisp to do this (e.g., in @file{.emacs}) or use the custom -library. With Lisp it would look like this - -@lisp -(setq reftex-label-alist - '(("axiom" ?a "ax:" "~\\ref@{%s@}" nil ("axiom" "ax.") -2) - ("theorem" ?h "thr:" "~\\ref@{%s@}" t ("theorem" "th.") -3))) -@end lisp - -The type indicator characters @code{?a} and @code{?h} are used for -prompts when @RefTeX{} queries for a label type. @code{?h} -was chosen for @code{theorem} since @code{?t} is already taken by -@code{table}. Note that also @code{?s}, @code{?f}, @code{?e}, -@code{?i}, @code{?n} are already used for standard environments. - -@noindent -The labels for Axioms and Theorems will have the prefixes @samp{ax:} and -@samp{thr:}, respectively. @xref{AUCTeX}, for information on how -@AUCTeX{} can use @RefTeX{} to automatically create labels when a new -environment is inserted into a buffer. Additionally, the following -needs to be added to one's .emacs file before @AUCTeX{} will -automatically create labels for the new environments. - -@lisp -(add-hook 'LaTeX-mode-hook - (lambda () - (LaTeX-add-environments - '("axiom" LaTeX-env-label) - '("theorem" LaTeX-env-label)))) -@end lisp - - -@noindent -The @samp{~\ref@{%s@}} is a format string indicating how to insert -references to these labels. - -@noindent -The next item indicates how to grab context of the label definition. -@itemize @minus -@item -@code{t} means to get it from a default location (from the beginning of -a @code{\macro} or after the @code{\begin} statement). @code{t} is -@emph{not} a good choice for eqnarray and similar environments. -@item -@code{nil} means to use the text right after the label definition. -@item -For more complex ways of getting context, see the variable -@code{reftex-label-alist} (@ref{Options - Defining Label Environments}). -@end itemize - -The following list of strings is used to guess the correct label type -from the word before point when creating a reference. For example if you -write: @samp{As we have shown in Theorem} and then press @kbd{C-c )}, -@RefTeX{} will know that you are looking for a theorem label and -restrict the menu to only these labels without even asking. - -The final item in each entry is the level at which the environment -should produce entries in the table of context buffer. If the number is -positive, the environment will produce numbered entries (like -@code{\section}), if it is negative the entries will be unnumbered (like -@code{\section*}). Use this only for environments which structure the -document similar to sectioning commands. For everything else, omit the -item. - -To do the same configuration with @code{customize}, you need to click on -the @code{[INS]} button twice to create two templates and fill them in -like this: - -@example -Reftex Label Alist: [Hide] -[INS] [DEL] Package or Detailed : [Value Menu] Detailed: - Environment or \macro : [Value Menu] String: axiom - Type specification : [Value Menu] Char : a - Label prefix string : [Value Menu] String: ax: - Label reference format: [Value Menu] String: ~\ref@{%s@} - Context method : [Value Menu] After label - Magic words: - [INS] [DEL] String: axiom - [INS] [DEL] String: ax. - [INS] - [X] Make TOC entry : [Value Menu] Level: -2 -[INS] [DEL] Package or Detailed : [Value Menu] Detailed: - Environment or \macro : [Value Menu] String: theorem - Type specification : [Value Menu] Char : h - Label prefix string : [Value Menu] String: thr: - Label reference format: [Value Menu] String: ~\ref@{%s@} - Context method : [Value Menu] Default position - Magic words: - [INS] [DEL] String: theorem - [INS] [DEL] String: theor. - [INS] [DEL] String: th. - [INS] - [X] Make TOC entry : [Value Menu] Level: -3 -@end example - -@vindex reftex-insert-label-flags -@vindex reftex-label-menu-flags -Depending on how you would like the label insertion and selection for -the new environments to work, you might want to add the letters @samp{a} -and @samp{h} to some of the flags in the variables -@code{reftex-insert-label-flags} (@pxref{Options - Creating Labels}) -and @code{reftex-label-menu-flags} (@pxref{Options - Referencing Labels}). - - -@node Quick Equation -@subsection Quick Equation Macro -@cindex Quick equation macro -@cindex Macros as environment wrappers - -Suppose you would like to have a macro for quick equations. It -could be defined like this: - -@example -\newcommand@{\quickeq@}[1]@{\begin@{equation@} #1 \end@{equation@}@} -@end example - -@noindent -and used like this: - -@example -Einstein's equation is \quickeq@{E=mc^2 \label@{eq:einstein@}@}. -@end example - -We need to tell @RefTeX{} that any label defined in the argument of the -@code{\quickeq} is an equation label. Here is how to do this with lisp: - -@lisp -(setq reftex-label-alist '(("\\quickeq@{@}" ?e nil nil 1 nil))) -@end lisp - -The first element in this list is now the macro with empty braces as an -@emph{image} of the macro arguments. @code{?e} indicates that this is -an equation label, the different @code{nil} elements indicate to use the -default values for equations. The @samp{1} as the fifth element -indicates that the context of the label definition should be the first -argument of the macro. - -Here is again how this would look in the customization buffer: - -@example -Reftex Label Alist: [Hide] -[INS] [DEL] Package or Detailed : [Value Menu] Detailed: - Environment or \macro : [Value Menu] String: \quickeq@{@} - Type specification : [Value Menu] Char : e - Label prefix string : [Value Menu] Default - Label reference format: [Value Menu] Default - Context method : [Value Menu] Macro arg nr: 1 - Magic words: - [INS] - [ ] Make TOC entry : [Value Menu] No entry -@end example - -@node Figure Wrapper -@subsection Figure Wrapping Macro -@cindex Macros as environment wrappers -@cindex Figure wrapping macro - -Suppose you want to make figures not directly with the figure -environment, but with a macro like - -@example -\newcommand@{\myfig@}[5][tbp]@{% - \begin@{figure@}[#1] - \epsimp[#5]@{#2@} - \caption@{#3@} - \label@{#4@} - \end@{figure@}@} -@end example - -@noindent -which would be called like - -@example -\myfig[htp]@{filename@}@{caption text@}@{label@}@{1@} -@end example - -Now we need to tell @RefTeX{} that the fourth argument of the -@code{\myfig} macro @emph{is itself} a figure label, and where to find -the context. - -@lisp -(setq reftex-label-alist - '(("\\myfig[]@{@}@{@}@{*@}@{@}" ?f nil nil 3))) -@end lisp - -The empty pairs of brackets indicate the different arguments of the -@code{\myfig} macro. The @samp{*} marks the label argument. @code{?f} -indicates that this is a figure label which will be listed together with -labels from normal figure environments. The @code{nil} entries for -prefix and reference format mean to use the defaults for figure labels. -The @samp{3} for the context method means to grab the third macro argument: -the caption. - -As a side effect of this configuration, @code{reftex-label} will now -insert the required naked label (without the @code{\label} macro) when -point is directly after the opening parenthesis of a @code{\myfig} macro -argument. - -Again, here the configuration in the customization buffer: - -@example -[INS] [DEL] Package or Detailed : [Value Menu] Detailed: - Environment or \macro : [Value Menu] String: \myfig[]@{@}@{@}@{*@}@{@} - Type specification : [Value Menu] Char : f - Label prefix string : [Value Menu] Default - Label reference format: [Value Menu] Default - Context method : [Value Menu] Macro arg nr: 3 - Magic words: - [INS] - [ ] Make TOC entry : [Value Menu] No entry -@end example - -@node Adding Magic Words -@subsection Adding Magic Words -@cindex Magic words -@cindex German magic words -@cindex Label category - -Sometimes you don't want to define a new label environment or macro, but -just change the information associated with a label category. Maybe you -want to add some magic words, for another language. Changing only the -information associated with a label category is done by giving -@code{nil} for the environment name and then specify the items you want -to define. Here is an example which adds German magic words to all -predefined label categories. - -@lisp -(setq reftex-label-alist - '((nil ?s nil nil nil ("Kapitel" "Kap." "Abschnitt" "Teil")) - (nil ?e nil nil nil ("Gleichung" "Gl.")) - (nil ?t nil nil nil ("Tabelle")) - (nil ?f nil nil nil ("Figur" "Abbildung" "Abb.")) - (nil ?n nil nil nil ("Anmerkung" "Anm.")) - (nil ?i nil nil nil ("Punkt")))) -@end lisp - -@node Using \eqref -@subsection Using @code{\eqref} -@cindex @code{\eqref}, AMS-LaTeX macro -@cindex AMS-LaTeX -@cindex Label category - -Another case where one only wants to change the information associated -with the label category is to change the macro which is used for -referencing the label. When working with the AMS-@LaTeX{}, you might -prefer @code{\eqref} for doing equation references. Here is how to -do this: - -@lisp -(setq reftex-label-alist '((nil ?e nil "~\\eqref@{%s@}" nil nil))) -@end lisp - -@RefTeX{} has also a predefined symbol for this special purpose. The -following is equivalent to the line above. - -@lisp -(setq reftex-label-alist '(AMSTeX)) -@end lisp - -Note that this is automatically done by the @file{amsmath.el} style file -of @AUCTeX{} (@pxref{Style Files}); so if you use @AUCTeX{}, -this configuration will not be necessary. - -@node Non-Standard Environments -@subsection Non-standard Environments -@cindex Non-standard environments -@cindex Environments without @code{\begin} -@cindex Special parser functions -@cindex Parser functions, for special environments - -Some @LaTeX{} packages define environment-like structures without using the -standard @samp{\begin..\end} structure. @RefTeX{} cannot parse -these directly, but you can write your own special-purpose parser and -use it instead of the name of an environment in an entry for -@code{reftex-label-alist}. The function should check if point is -currently in the special environment it was written to detect. If so, -it must return a buffer position indicating the start of this -environment. The return value must be @code{nil} on failure to detect -the environment. The function is called with one argument @var{bound}. -If non-@code{nil}, @var{bound} is a boundary for backwards searches -which should be observed. We will discuss two examples. - -@cindex LaTeX commands, abbreviated - -Some people define abbreviations for -environments, like @code{\be} for @code{\begin@{equation@}}, and -@code{\ee} for @code{\end@{equation@}}. The parser function would have -to search backward for these macros. When the first match is -@code{\ee}, point is not in this environment. When the first match is -@code{\be}, point is in this environment and the function must return -the beginning of the match. To avoid scanning too far, we can also look -for empty lines which cannot occur inside an equation environment. -Here is the setup: - -@lisp -;; Setup entry in reftex-label-alist, using all defaults for equations -(setq reftex-label-alist '((detect-be-ee ?e nil nil nil nil))) - -(defun detect-be-ee (bound) - ;; Search backward for the macros or an empty line - (if (re-search-backward - "\\(^[ \t]*\n\\|\\\\ee\\>\\)\\|\\(\\\\be\\>\\)" bound t) - (if (match-beginning 2) - (match-beginning 2) ; Return start of environment - nil) ; Return nil because env is closed - nil)) ; Return nil for not found -@end lisp - -@cindex @code{linguex}, LaTeX package -@cindex LaTeX packages, @code{linguex} -A more complex example is the @file{linguex.sty} package which defines -list macros @samp{\ex.}, @samp{\a.}, @samp{\b.} etc.@: for lists which are -terminated by @samp{\z.} or by an empty line. - -@example -\ex. \label@{ex:12@} Some text in an exotic language ... - \a. \label@{ex:13@} more stuff - \b. \label@{ex:14@} still more stuff - \a. List on a deeper level - \b. Another item - \b. and the third one - \z. - \b. Third item on this level. - -... text after the empty line terminating all lists -@end example - -The difficulty is that the @samp{\a.} lists can nest and that an empty -line terminates all list levels in one go. So we have to count nesting -levels between @samp{\a.} and @samp{\z.}. Here is the implementation -for @RefTeX{}. - -@lisp -(setq reftex-label-alist - '((detect-linguex ?x "ex:" "~\\ref@{%s@}" nil ("Example" "Ex.")))) - -(defun detect-linguex (bound) - (let ((cnt 0)) - (catch 'exit - (while - ;; Search backward for all possible delimiters - (re-search-backward - (concat "\\(^[ \t]*\n\\)\\|\\(\\\\z\\.\\)\\|" - "\\(\\ex[ig]?\\.\\)\\|\\(\\\\a\\.\\)") - nil t) - ;; Check which delimiter was matched. - (cond - ((match-beginning 1) - ;; empty line terminates all - return nil - (throw 'exit nil)) - ((match-beginning 2) - ;; \z. terminates one list level - decrease nesting count - (decf cnt)) - ((match-beginning 3) - ;; \ex. : return match unless there was a \z. on this level - (throw 'exit (if (>= cnt 0) (match-beginning 3) nil))) - ((match-beginning 4) - ;; \a. : return match when on level 0, otherwise - ;; increment nesting count - (if (>= cnt 0) - (throw 'exit (match-beginning 4)) - (incf cnt)))))))) -@end lisp - -@node Putting it Together -@subsection Putting it all together - -When you have to put several entries into @code{reftex-label-alist}, just -put them after each other in a list, or create that many templates in -the customization buffer. Here is a lisp example which uses several of -the entries described above: - -@lisp -(setq reftex-label-alist - '(("axiom" ?a "ax:" "~\\ref@{%s@}" nil ("axiom" "ax.") -2) - ("theorem" ?h "thr:" "~\\ref@{%s@}" t ("theorem" "theor." "th.") -3) - ("\\quickeq@{@}" ?e nil nil 1 nil) - AMSTeX - ("\\myfig[]@{@}@{@}@{*@}@{@}" ?f nil nil 3) - (detect-linguex ?x "ex:" "~\\ref@{%s@}" nil ("Example" "Ex.")))) -@end lisp - -@node Reference Info -@section Reference Info -@findex reftex-view-crossref -@findex reftex-mouse-view-crossref -@cindex Cross-references, displaying -@cindex Reference info -@cindex Displaying cross-references -@cindex Viewing cross-references -@kindex C-c & -@kindex S-mouse-2 - -When point is idle for more than @code{reftex-idle-time} seconds on the -argument of a @code{\ref} macro, the echo area will display some -information about the label referenced there. Note that the information -is only displayed if the echo area is not occupied by a different -message. - -@RefTeX{} can also display the label definition corresponding to a -@code{\ref} macro, or all reference locations corresponding to a -@code{\label} macro. @xref{Viewing Cross-References}, for more -information. - -@node Reference Styles -@section Reference Styles - -In case you defined your own macros for referencing or you are using -@LaTeX{} packages providing specialized macros to be used instead of -@code{\ref}, @RefTeX{} provides ways to select and insert them in a -convenient way. - -@RefTeX{} comes equipped with a set of so-called reference styles where -each relates to one or more reference macros. The standard macros -@samp{\ref}, @samp{\Ref}, @samp{\footref} and @samp{\pageref} are -provided by the ``Default'' style. The ``Varioref'' style offers macros -for the @samp{varioref} @LaTeX{} package (@samp{\vref}, @samp{\Vref}, -and @samp{\vpageref}), ``Fancyref'' for the @samp{fancyref} package -(@samp{\fref}, @samp{\Fref}), ``Hyperref'' for the @samp{hyperref} -package (@samp{\autoref}, @samp{\autopageref}), ``Cleveref'' for the -@samp{cleveref} package (@samp{\cref}, @samp{\Cref}, @samp{\cpageref} -and @samp{\Cpageref}) and ``AMSmath'' for the @samp{amsmath} package -(@samp{\eqref}). - -@vindex reftex-ref-style-default-list -A style can be toggled by selecting the respective entry in the -@samp{Reference Style} menu. Changes made through the menu will only -last for the Emacs session. In order to configure a preference -permanently, the variable @code{reftex-ref-style-default-list} should be -customized. This variable specifies the list of styles to be activated. -It can also be set as a file variable if the preference should be set -for a specific file. - -@vindex reftex-ref-style-alist -In case the built-in styles do not suffice, you can add additional -macros and styles to the variable @code{reftex-ref-style-alist}. Those -do not necessarily have to be related to a certain @LaTeX{} package but -can follow an arbitrary grouping rule. For example you could define a -style called ``Personal'' for your personal referencing macros. (When -changing the variable you should be aware that other Emacs packages, -like @AUCTeX{}, might rely on the entries from the default value to be -present.) - -Once a style is active the macros it relates to are available for -selection when you are about to insert a reference. In general this -process involves three steps: the selection of a reference macro, a -label type and a label. Reference macros can be chosen in the first and -last step. - -@vindex reftex-ref-macro-prompt -In the first step you will be presented with a list of macros from which -you can select one by typing a single key. If you dislike having an -extra step for reference macro selection, you can disable it by -customizing @code{reftex-ref-macro-prompt} and relying only on the -selection facilities provided in the last step. - -In the last step, i.e., the label selection, two key bindings are -provided to set the reference macro. Type @kbd{v} in order to cycle -forward through the list of available macros or @kbd{V} to cycle -backward. The mode line of the selection buffer shows the macro -currently selected. - -In case you are not satisfied with the order of macros when cycling -through them you should adapt the order of entries in the variable -@code{reftex-ref-style-alist} to fit your liking. - -For each entry in @code{reftex-ref-style-alist} a function with the name -@code{reftex--} (e.g., @code{reftex-varioref-vref}) will -be created automatically by @RefTeX{}. These functions can be used -instead of @kbd{C-c )} and provide an alternative way of having your -favorite referencing macro preselected and if cycling through the macros -seems inconvenient to you.@footnote{You could, e.g., bind -@code{reftex-varioref-vref} to @kbd{C-c v} and -@code{reftex-fancyref-fref} to @kbd{C-c f}.} - -@cindex @code{varioref}, LaTeX package -@cindex LaTeX packages, @code{varioref} -@cindex @code{fancyref}, LaTeX package -@cindex LaTeX packages, @code{fancyref} -@vindex reftex-vref-is-default @r{(deprecated)} -@vindex reftex-fref-is-default @r{(deprecated)} -In former versions of @RefTeX{} only support for @code{varioref} and -@code{fancyref} was included. @code{varioref} is a @LaTeX{} package to -create cross-references with page information. @code{fancyref} is a -package where a macro call like @code{\fref@{@var{fig:map-of-germany}@}} -creates not only the number of the referenced counter but also the -complete text around it, like @samp{Figure 3 on the preceding page}. In -order to make it work you need to use label prefixes like @samp{fig:} -consistently---something @RefTeX{} does automatically. For each of -these packages a variable could be configured to make its macros to take -precedence over @code{\ref}. Those were @code{reftex-vref-is-default} -and @code{reftex-fref-is-default} respectively. While still working, -these variables are deprecated now. Instead of setting them, the -variable @code{reftex-ref-style-default-list} should be adapted now. - -@node LaTeX xr Package -@section @code{xr}: Cross-Document References -@cindex @code{xr}, LaTeX package -@cindex LaTeX packages, @code{xr} -@cindex @code{\externaldocument} -@cindex External documents -@cindex References to external documents -@cindex Cross-document references - -The @LaTeX{} package @code{xr} makes it possible to create references to -labels defined in external documents. The preamble of a document using -@code{xr} will contain something like this: - -@example -\usepackage@{xr@} -\externaldocument[V1-]@{volume1@} -\externaldocument[V3-]@{volume3@} -@end example - -@noindent -and we can make references to any labels defined in these -external documents by using the prefixes @samp{V1-} and @samp{V3-}, -respectively. - -@RefTeX{} can be used to create such references as well. Start the -referencing process normally, by pressing @kbd{C-c )}. Select a label -type if necessary. When you see the label selection buffer, pressing -@kbd{x} will switch to the label selection buffer of one of the external -documents. You may then select a label as before and @RefTeX{} will -insert it along with the required prefix. - -For this kind of inter-document cross-references, saving of parsing -information and the use of multiple selection buffers can mean a large -speed-up (@pxref{Optimizations}). - -@node Citations -@chapter Citations -@cindex Citations -@cindex @code{\cite} - -Citations in @LaTeX{} are done with the @code{\cite} macro or variations of -it. The argument of the macro is a citation key which identifies an -article or book in either a @BibTeX{} database file or in an explicit -@code{thebibliography} environment in the document. @RefTeX{}'s -support for citations helps to select the correct key quickly. - -@menu -* Creating Citations:: How to create them. -* Citation Styles:: Natbib, Harvard, Chicago and Co. -* Citation Info:: View the corresponding database entry. -* Chapterbib and Bibunits:: Multiple bibliographies in a Document. -* Citations Outside LaTeX:: How to make citations in Emails etc. -* BibTeX Database Subsets:: Extract parts of a big database. -@end menu - -@node Creating Citations -@section Creating Citations -@cindex Creating citations -@cindex Citations, creating -@findex reftex-citation -@kindex C-c [ -@cindex Selection buffer, citations -@cindex Selection process - -In order to create a citation, press @kbd{C-c [}. @RefTeX{} then -prompts for a regular expression which will be used to search through -the database and present the list of matches to choose from in a -selection process similar to that for selecting labels -(@pxref{Referencing Labels}). - -The regular expression uses an extended syntax: @samp{&&} defines a -logic @code{and} for regular expressions. For example -@samp{Einstein&&Bose} will match all articles which mention -Bose-Einstein condensation, or which are co-authored by Bose and -Einstein. When entering the regular expression, you can complete on -known citation keys. @RefTeX{} also offers a default when prompting for -a regular expression. This default is the word before the cursor or the -word before the current @samp{\cite} command. Sometimes this may be a -good search key. - -@cindex @code{\bibliography} -@cindex @code{thebibliography}, LaTeX environment -@cindex @code{BIBINPUTS}, environment variable -@cindex @code{TEXBIB}, environment variable -@RefTeX{} prefers to use @BibTeX{} database files specified with a -@code{\bibliography} macro to collect its information. Just like -@BibTeX{}, it will search for the specified files in the current directory -and along the path given in the environment variable @code{BIBINPUTS}. -If you do not use @BibTeX{}, but the document contains an explicit -@code{thebibliography} environment, @RefTeX{} will collect its -information from there. Note that in this case the information -presented in the selection buffer will just be a copy of relevant -@code{\bibitem} entries, not the structured listing available with -@BibTeX{} database files. - -@kindex ? -In the selection buffer, the following keys provide special commands. A -summary of this information is always available from the selection -process by pressing @kbd{?}. - -@table @kbd -@tablesubheading{General} -@item ? -Show a summary of available commands. - -@item 0-9,- -Prefix argument. - -@tablesubheading{Moving around} -@item n -Go to next article. - -@item p -Go to previous article. - -@tablesubheading{Access to full database entries} -@item @key{SPC} -Show the database entry corresponding to the article at point, in -another window. See also the @kbd{f} key. - -@item f -Toggle follow mode. When follow mode is active, the other window will -always display the full database entry of the current article. This is -equivalent to pressing @key{SPC} after each cursor motion. With @BibTeX{} -entries, follow mode can be rather slow. - -@tablesubheading{Selecting entries and creating the citation} -@item @key{RET} -Insert a citation referencing the article at point into the buffer from -which the selection process was started. - -@item mouse-2 -@vindex reftex-highlight-selection -Clicking with mouse button 2 on a citation will accept it like @key{RET} -would. See also variable @code{reftex-highlight-selection}, -@ref{Options - Misc}. - -@item m -Mark the current entry. When one or several entries are marked, -pressing @kbd{a} or @kbd{A} accepts all marked entries. Also, -@key{RET} behaves like the @kbd{a} key. - -@item u -Unmark a marked entry. - -@item a -Accept all (marked) entries in the selection buffer and create a single -@code{\cite} macro referring to them. - -@item A -Accept all (marked) entries in the selection buffer and create a -separate @code{\cite} macro for each of it. - -@item e -Create a new @BibTeX{} database file which contains all @i{marked} entries -in the selection buffer. If no entries are marked, all entries are -selected. - -@item E -Create a new @BibTeX{} database file which contains all @i{unmarked} -entries in the selection buffer. If no entries are marked, all entries -are selected. - -@item @key{TAB} -Enter a citation key with completion. This may also be a key which does -not yet exist. - -@item . -Show insertion point in another window. This is the point from where you -called @code{reftex-citation}. - -@tablesubheading{Exiting} -@item q -Exit the selection process without inserting a citation into the -buffer. - -@tablesubheading{Updating the buffer} - -@item g -Start over with a new regular expression. The full database will be -rescanned with the new expression (see also @kbd{r}). - -@c FIXME: Should we use something else here? r is usually rescan! -@item r -Refine the current selection with another regular expression. This will -@emph{not} rescan the entire database, but just the already selected -entries. - -@end table - -@vindex reftex-select-bib-mode-map -In order to define additional commands for this selection process, the -keymap @code{reftex-select-bib-mode-map} may be used. - -Note that if you do not use Emacs to edit the @BibTeX{} database files, -@RefTeX{} will ask if the related buffers should be updated once it -detects that the files were changed externally. If you do not want to -be bothered by such queries, you can activate Auto Revert mode for these -buffers by adding the following expression to your init file: - -@lisp -(add-hook 'bibtex-mode-hook 'turn-on-auto-revert-mode) -@end lisp - - -@node Citation Styles -@section Citation Styles -@cindex Citation styles -@cindex Citation styles, @code{biblatex} -@cindex Citation styles, @code{natbib} -@cindex Citation styles, @code{harvard} -@cindex Citation styles, @code{chicago} -@cindex Citation styles, @code{jurabib} -@cindex Citation styles, @ConTeXt{} -@cindex @code{biblatex}, citation style -@cindex @code{natbib}, citation style -@cindex @code{harvard}, citation style -@cindex @code{chicago}, citation style -@cindex @code{jurabib}, citation style -@cindex @ConTeXt{}, citation style - -@vindex reftex-cite-format -The standard @LaTeX{} macro @code{\cite} works well with numeric or -simple key citations. To deal with the more complex task of author-year -citations as used in many natural sciences, a variety of packages has -been developed which define derived forms of the @code{\cite} macro. -@RefTeX{} can be configured to produce these citation macros as well by -setting the variable @code{reftex-cite-format}. For the most commonly -used @LaTeX{} packages (@code{biblatex}, @code{natbib}, @code{harvard}, -@code{chicago}, @code{jurabib}) and for @ConTeXt{} this may be done from -the menu, under @code{Ref->Citation Styles}. Since there are usually -several macros to create the citations, executing @code{reftex-citation} -(@kbd{C-c [}) starts by prompting for the correct macro. For the Natbib -style, this looks like this: - -@example -SELECT A CITATION FORMAT - -[^M] \cite@{%l@} -[t] \citet@{%l@} -[T] \citet*@{%l@} -[p] \citep@{%l@} -[P] \citep*@{%l@} -[e] \citep[e.g.][]@{%l@} -[s] \citep[see][]@{%l@} -[a] \citeauthor@{%l@} -[A] \citeauthor*@{%l@} -[y] \citeyear@{%l@} -@end example - -@noindent -And for the Biblatex style, it looks like this: - -@example -SELECT A CITATION FORMAT - -[^M] \cite[][]@{%l@} -[C] \cite*[][]@{%l@} -[t] \textcite[][]@{%l@} -[T] \textcite*[][]@{%l@} -[p] \parencite[][]@{%l@} -[P] \parencite*[][]@{%l@} -[f] \footcite[][]@{%l@} -[s] \smartcite[][]@{%l@} -[u] \autocite[][]@{%l@} -[U] \autocite*[][]@{%l@} -[a] \citeauthor@{%l@} -[A] \citeauthor*@{%l@} -[i] \citetitle@{%l@} -[I] \citetitle*@{%l@} -[y] \citeyear@{%l@} -[Y] \citeyear*@{%l@} -[n] \nocite@{%l@} -@end example - -@vindex reftex-cite-prompt-optional-args -If citation formats contain empty pairs of square brackets, @RefTeX{} -will prompt for values of these optional arguments if you call the -@code{reftex-citation} command with a @kbd{C-u} prefix. -Following the most generic of these packages, @code{natbib}, the builtin -citation packages always accept the @kbd{t} key for a @emph{textual} -citation (like: @code{Jones et al. (1997) have shown...}) as well as -the @kbd{p} key for a parenthetical citation (like: @code{As shown -earlier (Jones et al, 1997)}). - -To make one of these styles the default, customize the variable -@code{reftex-cite-format} or put into @file{.emacs}: - -@lisp -(setq reftex-cite-format 'natbib) -@end lisp - -@noindent -Or this if you prefer the biblatex package: - -@lisp -(setq reftex-cite-format 'biblatex) -@end lisp - -You can also use @AUCTeX{} style files to automatically set the -citation style based on the @code{usepackage} commands in a given -document. @xref{Style Files}, for information on how to set up the style -files correctly. - -@node Citation Info -@section Citation Info -@cindex Displaying citations -@cindex Citations, displaying -@cindex Citation info -@cindex Viewing citations -@kindex C-c & -@kindex S-mouse-2 -@findex reftex-view-crossref -@findex reftex-mouse-view-crossref - -When point is idle for more than @code{reftex-idle-time} seconds on the -argument of a @code{\cite} macro, the echo area will display some -information about the article cited there. Note that the information is -only displayed if the echo area is not occupied by a different message. - -@RefTeX{} can also display the @code{\bibitem} or @BibTeX{} database -entry corresponding to a @code{\cite} macro, or all citation locations -corresponding to a @code{\bibitem} or @BibTeX{} database entry. -@xref{Viewing Cross-References}. - -@node Chapterbib and Bibunits -@section Chapterbib and Bibunits -@cindex @code{chapterbib}, LaTeX package -@cindex @code{bibunits}, LaTeX package -@cindex Bibliographies, multiple - -@code{chapterbib} and @code{bibunits} are two @LaTeX{} packages which -produce multiple bibliographies in a document. This is no problem for -@RefTeX{} as long as all bibliographies use the same @BibTeX{} database -files. If they do not, it is best to have each document part in a -separate file (as it is required for @code{chapterbib} anyway). Then -@RefTeX{} will still scan the locally relevant databases correctly. If -you have multiple bibliographies within a @emph{single file}, this may -or may not be the case. - -@node Citations Outside LaTeX -@section Citations outside @LaTeX{} -@cindex Citations outside LaTeX -@vindex reftex-default-bibliography - -The command @code{reftex-citation} can also be executed outside a @LaTeX{} -buffer. This can be useful to reference articles in the mail buffer and -other documents. You should @emph{not} enter @code{reftex-mode} for -this, just execute the command. The list of @BibTeX{} files will in this -case be taken from the variable @code{reftex-default-bibliography}. -Setting the variable @code{reftex-cite-format} to the symbol -@code{locally} does a decent job of putting all relevant information -about a citation directly into the buffer. Here is the lisp code to add -the @kbd{C-c [} binding to the mail buffer. It also provides a local -binding for @code{reftex-cite-format}. - -@lisp -(add-hook 'mail-setup-hook - (lambda () (keymap-set mail-mode-map "C-c [" - (lambda () - (interactive) - (let ((reftex-cite-format 'locally)) - (reftex-citation)))))) -@end lisp - -@node BibTeX Database Subsets -@section Database Subsets -@cindex BibTeX database subsets -@findex reftex-create-bibtex-file - -@RefTeX{} offers two ways to create a new @BibTeX{} database file. - -The first option produces a file which contains only the entries -actually referenced in the current document. This can be useful if -the database is only meant for a single document and you want to clean -it of old and unused ballast. It can also be useful while writing a -document together with collaborators, in order to avoid sending around -the entire (possibly very large) database. To create the file, use -@kbd{M-x reftex-create-bibtex-file}, also available from the menu -under @code{Ref->Global Actions->Create Bibtex File}. The command will -prompt for a @BibTeX{} file name and write the extracted entries to that -file. - -The second option makes use of the selection process started by the -command @kbd{C-c [} (@pxref{Creating Citations}). This command uses a -regular expression to select entries, and lists them in a formatted -selection buffer. After pressing the @kbd{e} key (mnemonics: Export), -the command will prompt for the name of a new @BibTeX{} file and write -the selected entries to that file. You can also first mark some -entries in the selection buffer with the @kbd{m} key and then export -either the @i{marked} entries (with the @kbd{e} key) or the -@i{unmarked} entries (with the @kbd{E} key). - -@node Index Support -@chapter Index Support -@cindex Index Support -@cindex @code{\index} - -@LaTeX{} has builtin support for creating an Index. The @LaTeX{} core -supports two different indices, the standard index and a glossary. With -the help of special @LaTeX{} packages (@file{multind.sty} or -@file{index.sty}), any number of indices can be supported. - -Index entries are created with the @code{\index@{@var{entry}@}} macro. -All entries defined in a document are written out to the @file{.aux} -file. A separate tool must be used to convert this information into a -nicely formatted index. Tools used with @LaTeX{} include @code{MakeIndex} -and @code{xindy}. - -Indexing is a very difficult task. It must follow strict conventions to -make the index consistent and complete. There are basically two -approaches one can follow, and both have their merits. - -@enumerate -@item -Part of the indexing should already be done with the markup. The -document structure should be reflected in the index, so when starting -new sections, the basic topics of the section should be indexed. If the -document contains definitions, theorems or the like, these should all -correspond to appropriate index entries. This part of the index can -very well be developed along with the document. Often it is worthwhile -to define special purpose macros which define an item and at the same -time make an index entry, possibly with special formatting to make the -reference page in the index bold or underlined. To make @RefTeX{} -support for indexing possible, these special macros must be added to -@RefTeX{}'s configuration (@pxref{Defining Index Macros}). - -@item -The rest of the index is often just a collection of where in the -document certain words or phrases are being used. This part is -difficult to develop along with the document, because consistent entries -for each occurrence are needed and are best selected when the document -is ready. @RefTeX{} supports this with an @emph{index phrases file} -which collects phrases and helps indexing the phrases globally. -@end enumerate - -Before you start, you need to make sure that @RefTeX{} knows about -the index style being used in the current document. @RefTeX{} has -builtin support for the default @code{\index} and @code{\glossary} -macros. Other @LaTeX{} packages, like the @file{multind} or @file{index} -package, redefine the @code{\index} macro to have an additional -argument, and @RefTeX{} needs to be configured for those. A -sufficiently new version of @AUCTeX{} (9.10c or later) will do this -automatically. If you really don't use @AUCTeX{} (you should!), this -configuration needs to be done by hand with the menu (@code{Ref->Index -Style}), or globally for all your documents with - -@lisp -(setq reftex-index-macros '(multind)) @r{or} -(setq reftex-index-macros '(index)) -@end lisp - -@menu -* Creating Index Entries:: Macros and completion of entries. -* The Index Phrases File:: A special file for global indexing. -* Displaying and Editing the Index:: The index editor. -* Builtin Index Macros:: The index macros RefTeX knows about. -* Defining Index Macros:: ... and macros it doesn't. -@end menu - -@node Creating Index Entries -@section Creating Index Entries -@cindex Creating index entries -@cindex Index entries, creating -@kindex C-c < -@findex reftex-index -@kindex C-c / -@findex reftex-index-selection-or-word - -In order to index the current selection or the word at the cursor press -@kbd{C-c /} (@code{reftex-index-selection-or-word}). This causes the -selection or word @samp{@var{word}} to be replaced with -@samp{\index@{@var{word}@}@var{word}}. The macro which is used -(@code{\index} by default) can be configured with the variable -@code{reftex-index-default-macro}. When the command is called with a -prefix argument (@kbd{C-u C-c /}), you get a chance to edit the -generated index entry. Use this to change the case of the word or to -make the entry a subentry, for example by entering -@samp{main!sub!@var{word}}. When called with two raw @kbd{C-u} prefixes -(@kbd{C-u C-u C-c /}), you will be asked for the index macro as well. -When there is nothing selected and no word at point, this command will -just call @code{reftex-index}, described below. - -In order to create a general index entry, press @kbd{C-c <} -(@code{reftex-index}). @RefTeX{} will prompt for one of the -available index macros and for its arguments. Completion will be -available for the index entry and, if applicable, the index tag. The -index tag is a string identifying one of multiple indices. With the -@file{multind} and @file{index} packages, this tag is the first argument -to the redefined @code{\index} macro. - -@node The Index Phrases File -@section The Index Phrases File -@cindex Index phrase file -@cindex Phrase file -@kindex C-c | -@findex reftex-index-visit-phrases-buffer -@cindex Macro definition lines, in phrase buffer - -@RefTeX{} maintains a file in which phrases can be collected for -later indexing. The file is located in the same directory as the master -file of the document and has the extension @file{.rip} (@b{R}eftex -@b{I}ndex @b{P}hrases). You can create or visit the file with @kbd{C-c -|} (@code{reftex-index-visit-phrases-buffer}). If the file is empty it -is initialized by inserting a file header which contains the definition -of the available index macros. This list is initialized from -@code{reftex-index-macros} (@pxref{Defining Index Macros}). You can -edit the header as needed, but if you define new @LaTeX{} indexing macros, -don't forget to add them to @code{reftex-index-macros} as well. Here is -a phrase file header example: - -@example -% -*- mode: reftex-index-phrases -*- -% Key Macro Format Repeat -%---------------------------------------------------------- ->>>INDEX_MACRO_DEFINITION: i \index@{%s@} t ->>>INDEX_MACRO_DEFINITION: I \index*@{%s@} nil ->>>INDEX_MACRO_DEFINITION: g \glossary@{%s@} t ->>>INDEX_MACRO_DEFINITION: n \index*[name]@{%s@} nil -%---------------------------------------------------------- -@end example - -The macro definition lines consist of a unique letter identifying a -macro, a format string and the @var{repeat} flag, all separated by -@key{TAB}. The format string shows how the macro is to be applied, the -@samp{%s} will be replaced with the index entry. The repeat flag -indicates if @var{word} is indexed by the macro as -@samp{\index@{@var{word}@}} (@var{repeat} = @code{nil}) or as -@samp{\index@{@var{word}@}@var{word}} (@var{repeat} = @code{t}). In the -above example it is assumed that the macro @code{\index*@{@var{word}@}} -already typesets its argument in the text, so that it is unnecessary to -repeat @var{word} outside the macro. - -@menu -* Collecting Phrases:: Collecting from document or external. -* Consistency Checks:: Check for duplicates etc. -* Global Indexing:: The interactive indexing process. -@end menu - -@node Collecting Phrases -@subsection Collecting Phrases -@cindex Collecting index phrases -@cindex Index phrases, collection -@cindex Phrases, collecting - -Phrases for indexing can be collected while writing the document. The -command @kbd{C-c \} (@code{reftex-index-phrase-selection-or-word}) -copies the current selection (if active) or the word near point into the -phrases buffer. It then selects this buffer, so that the phrase line -can be edited. To return to the @LaTeX{} document, press @kbd{C-c C-c} -(@code{reftex-index-phrases-save-and-return}). - -You can also prepare the list of index phrases in a different way and -copy it into the phrases file. For example you might want to start from -a word list of the document and remove all words which should not be -indexed. - -The phrase lines in the phrase buffer must have a specific format. -@RefTeX{} will use font-lock to indicate if a line has the proper -format. A phrase line looks like this: - -@example -[@var{key}] @var{phrase} [ @var{arg}[&&@var{arg}]... [ || @var{arg}]...] -@end example - -@code{} stands for white space containing at least one @key{TAB}. -@var{key} must be at the start of the line and is the character -identifying one of the macros defined in the file header. It is -optional; when omitted, the first macro definition line in the file -will be used for this phrase. The @var{phrase} is the phrase to be -searched for when indexing. It may contain several words separated by -spaces. By default the search phrase is also the text entered as -argument of the index macro. If you want the index entry to be -different from the search phrase, enter another @key{TAB} and the index -argument @var{arg}. If you want to have each match produce several -index entries, separate the different index arguments with @samp{ && -}@footnote{@samp{&&} with optional spaces, see -@code{reftex-index-phrases-logical-and-regexp}.}. If you want to be -able to choose at each match between several different index arguments, -separate them with @samp{ || }@footnote{@samp{||} with optional spaces, -see @code{reftex-index-phrases-logical-or-regexp}.}. Here is an -example: - -@example -%-------------------------------------------------------------------- -I Sun -i Planet Planets -i Vega Stars!Vega - Jupiter Planets!Jupiter -i Mars Planets!Mars || Gods!Mars || Chocolate Bars!Mars -i Pluto Planets!Pluto && Kuiper Belt Objects!Pluto -@end example - - -So @samp{Sun} will be indexed directly as @samp{\index*@{Sun@}}, while -@samp{Planet} will be indexed as @samp{\index@{Planets@}Planet}. -@samp{Vega} will be indexed as a subitem of @samp{Stars}. The -@samp{Jupiter} line will also use the @samp{i} macro as it was the first -macro definition in the file header (see above example). At each -occurrence of @samp{Mars} you will be able choose between indexing it as -a subitem of @samp{Planets}, @samp{Gods} or @samp{Chocolate Bars}. -Finally, every occurrence of @samp{Pluto} will be indexed as -@samp{\index@{Planets!Pluto@}\index@{Kuiper Belt Objects!Pluto@}Pluto} -and will therefore create two different index entries. - -@node Consistency Checks -@subsection Consistency Checks -@cindex Index phrases, consistency checks -@cindex Phrases, consistency checks -@cindex Consistency check for index phrases - -@kindex C-c C-s -Before indexing the phrases in the phrases buffer, they should be -checked carefully for consistency. A first step is to sort the phrases -alphabetically; this is done with the command @kbd{C-c C-s} -(@code{reftex-index-sort-phrases}). It will sort all phrases in the -buffer alphabetically by search phrase. If you want to group certain -phrases and only sort within the groups, insert empty lines between the -groups. Sorting will only change the sequence of phrases within each -group (see the variable @code{reftex-index-phrases-sort-in-blocks}). - -@kindex C-c C-i -A useful command is @kbd{C-c C-i} (@code{reftex-index-phrases-info}) -which lists information about the phrase at point, including an example -of how the index entry will look like and the number of expected matches -in the document. - -@kindex C-c C-t -Another important check is to find out if there are double or -overlapping entries in the buffer. For example if you are first -searching and indexing @samp{Mars} and then @samp{Planet Mars}, the -second phrase will not match because of the index macro inserted before -@samp{Mars} earlier. The command @kbd{C-c C-t} -(@code{reftex-index-find-next-conflict-phrase}) finds the next phrase in -the buffer which is either duplicate or a subphrase of another phrase. -In order to check the whole buffer like this, start at the beginning and -execute this command repeatedly. - -@node Global Indexing -@subsection Global Indexing -@cindex Global indexing -@cindex Indexing, global -@cindex Indexing, from @file{phrases} buffer - -Once the index phrases have been collected and organized, you are set -for global indexing. I recommend to do this only on an otherwise -finished document. Global indexing starts from the phrases buffer. -There are several commands which start indexing: @kbd{C-c C-x} acts on -the current phrase line, @kbd{C-c C-r} on all lines in the current -region and @kbd{C-c C-a} on all phrase lines in the buffer. It is -probably good to do indexing in small chunks since your concentration -may not last long enough to do everything in one go. - -@RefTeX{} will start at the first phrase line and search the phrase -globally in the whole document. At each match it will stop, compute the -replacement string and offer you the following choices@footnote{Windows -users: Restrict yourself to the described keys during indexing. Pressing -@key{Help} at the indexing prompt can apparently hang Emacs.}: - -@table @kbd -@item y -Replace this match with the proposed string. -@item n -Skip this match. -@item ! -Replace this and all further matches in this file. -@item q -Skip this match, start with next file. -@item Q -Skip this match, start with next phrase. -@item o -Select a different indexing macro for this match. -@item 1-9 -Select one of multiple index keys (those separated with @samp{||}). -@item e -Edit the replacement text. -@item C-r -Recursive edit. Use @kbd{C-M-c} to return to the indexing process. -@item s -Save this buffer and ask again about the current match. -@item S -Save all document buffers and ask again about the current match. -@item C-g -Abort the indexing process. -@end table - -The @samp{Find and Index in Document} menu in the phrases buffer also -lists a few options for the indexing process. The options have -associated customization variables to set the defaults -(@pxref{Options - Index Support}). Here is a short explanation of -what the options do: - -@table @i -@item Match Whole Words -When searching for index phrases, make sure whole words are matched. -This should probably always be on. -@item Case Sensitive Search -Search case sensitively for phrases. I recommend to have this setting -off, in order to match the capitalized words at the beginning of a -sentence, and even typos. You can always say @emph{no} at a match you -do not like. -@item Wrap Long Lines -Inserting index macros increases the line length. Turn this option on -to allow @RefTeX{} to wrap long lines. -@item Skip Indexed Matches -When this is on, @RefTeX{} will at each match try to figure out if -this match is already indexed. A match is considered indexed if it is -either the argument of an index macro, or if an index macro is directly -(without whitespace separation) before or after the match. Index macros -are those configured in @code{reftex-index-macros}. Intended for -re-indexing a documents after changes have been made. -@end table - -Even though indexing should be the last thing you do to a document, you -are bound to make changes afterwards. Indexing then has to be applied -to the changed regions. The command -@code{reftex-index-phrases-apply-to-region} is designed for this -purpose. When called from a @LaTeX{} document with active region, it will -apply @code{reftex-index-all-phrases} to the current region. - -@node Displaying and Editing the Index -@section Displaying and Editing the Index -@cindex Displaying the Index -@cindex Editing the Index -@cindex Index entries, creating -@cindex Index, displaying -@cindex Index, editing -@kindex C-c > -@findex reftex-display-index - -In order to compile and display the index, press @kbd{C-c >}. If the -document uses multiple indices, @RefTeX{} will ask you to select -one. Then, all index entries will be sorted alphabetically and -displayed in a special buffer, the @file{*Index*} buffer. From that -buffer you can check and edit each entry. - -The index can be restricted to the current section or the region. Then -only entries in that part of the document will go into the compiled -index. To restrict to the current section, use a numeric prefix -@samp{2}, thus press @kbd{C-u 2 C-c >}. To restrict to the current -region, make the region active and use a numeric prefix @samp{3} (press -@kbd{C-u 3 C-c >}). From within the @file{*Index*} buffer the -restriction can be moved from one section to the next by pressing the -@kbd{<} and @kbd{>} keys. - -One caveat: @RefTeX{} finds the definition point of an index entry -by searching near the buffer position where it had found to macro during -scanning. If you have several identical index entries in the same -buffer and significant changes have shifted the entries around, you must -rescan the buffer to ensure the correspondence between the -@file{*Index*} buffer and the definition locations. It is therefore -advisable to rescan the document (with @kbd{r} or @kbd{C-u r}) -frequently while editing the index from the @file{*Index*} -buffer. - -@kindex ? -Here is a list of special commands available in the @file{*Index*} buffer. A -summary of this information is always available by pressing -@kbd{?}. - -@table @kbd -@tablesubheading{General} -@item ? -Display a summary of commands. - -@item 0-9, - -Prefix argument. - -@tablesubheading{Moving around} -@item ! A..Z -Pressing any capital letter will jump to the corresponding section in -the @file{*Index*} buffer. The exclamation mark is special and jumps to -the first entries alphabetically sorted below @samp{A}. These are -usually non-alphanumeric characters. -@item n -Go to next entry. -@item p -Go to previous entry. - -@tablesubheading{Access to document locations} -@item @key{SPC} -Show the place in the document where this index entry is defined. - -@item @key{TAB} -Go to the definition of the current index entry in another -window. - -@item @key{RET} -Go to the definition of the current index entry and hide the -@file{*Index*} buffer window. - -@item f -@vindex reftex-index-follow-mode -@vindex reftex-revisit-to-follow -Toggle follow mode. When follow mode is active, the other window will -always show the location corresponding to the line in the @file{*Index*} -buffer at point. This is similar to pressing @key{SPC} after each -cursor motion. The default for this flag can be set with the variable -@code{reftex-index-follow-mode}. Note that only context in files -already visited is shown. @RefTeX{} will not visit a file just for -follow mode. See, however, the variable -@code{reftex-revisit-to-follow}. - -@tablesubheading{Entry editing} -@item e -Edit the current index entry. In the minibuffer, you can edit the -index macro which defines this entry. - -@item C-k -Kill the index entry. Currently not implemented because I don't know -how to implement an @code{undo} function for this. - -@item * -Edit the @var{key} part of the entry. This is the initial part of the -entry which determines the location of the entry in the index. - -@item | -Edit the @var{attribute} part of the entry. This is the part after the -vertical bar. With @code{MakeIndex}, this part is an encapsulating -macro. With @code{xindy}, it is called @emph{attribute} and is a -property of the index entry that can lead to special formatting. When -called with @kbd{C-u} prefix, kill the entire @var{attribute} -part. - -@item @@ -Edit the @var{visual} part of the entry. This is the part after the -@samp{@@} which is used by @code{MakeIndex} to change the visual -appearance of the entry in the index. When called with @kbd{C-u} -prefix, kill the entire @var{visual} part. - -@item ( -Toggle the beginning of page range property @samp{|(} of the -entry. - -@item ) -Toggle the end of page range property @samp{|)} of the entry. - -@item _ -Make the current entry a subentry. This command will prompt for the -superordinate entry and insert it. - -@item ^ -Remove the highest superordinate entry. If the current entry is a -subitem (@samp{aaa!bbb!ccc}), this function moves it up the hierarchy -(@samp{bbb!ccc}). - -@tablesubheading{Exiting} -@item q -Hide the @file{*Index*} buffer. - -@item k -Kill the @file{*Index*} buffer. - -@item C-c = -Switch to the Table of Contents buffer of this document. - -@tablesubheading{Controlling what gets displayed} -@item c -@vindex reftex-index-include-context -Toggle the display of short context in the @file{*Index*} buffer. The -default for this flag can be set with the variable -@code{reftex-index-include-context}. - -@item @} -Restrict the index to a single document section. The corresponding -section number will be displayed in the @code{R<>} indicator in the -mode line and in the header of the @file{*Index*} buffer. - -@item @{ -Widen the index to contain all entries of the document. - -@item < -When the index is currently restricted, move the restriction to the -previous section. - -@item > -When the index is currently restricted, move the restriction to the -next section. - -@tablesubheading{Updating the buffer} -@item g -Rebuild the @file{*Index*} buffer. This does @emph{not} rescan the -document. However, it sorts the entries again, so that edited entries -will move to the correct position. - -@item r -@vindex reftex-enable-partial-scans -Reparse the @LaTeX{} document and rebuild the @file{*Index*} buffer. When -@code{reftex-enable-partial-scans} is non-@code{nil}, rescan only the file this -location is defined in, not the entire document. - -@item C-u r -Reparse the @emph{entire} @LaTeX{} document and rebuild the @file{*Index*} -buffer. - -@item s -Switch to a different index (for documents with multiple -indices). -@end table - - -@node Builtin Index Macros -@section Builtin Index Macros -@cindex Builtin index macros -@cindex Index macros, builtin -@vindex reftex-index-macros -@cindex @code{multind}, LaTeX package -@cindex @code{index}, LaTeX package -@cindex LaTeX packages, @code{multind} -@cindex LaTeX packages, @code{index} - -@RefTeX{} by default recognizes the @code{\index} and -@code{\glossary} macros which are defined in the @LaTeX{} core. It has -also builtin support for the re-implementations of @code{\index} -in the @file{multind} and @file{index} packages. However, since -the different definitions of the @code{\index} macro are incompatible, -you will have to explicitly specify the index style used. -@xref{Creating Index Entries}, for information on how to do that. - -@node Defining Index Macros -@section Defining Index Macros -@cindex Defining Index Macros -@cindex Index macros, defining -@vindex reftex-index-macros - -When writing a document with an index you will probably define -additional macros which make entries into the index. -Let's look at an example. - -@example -\newcommand@{\ix@}[1]@{#1\index@{#1@}@} -\newcommand@{\nindex@}[1]@{\textit@{#1@}\index[name]@{#1@}@} -\newcommand@{\astobj@}[1]@{\index@{Astronomical Objects!#1@}@} -@end example - -The first macro @code{\ix} typesets its argument in the text and places -it into the index. The second macro @code{\nindex} typesets its -argument in the text and places it into a separate index with the tag -@samp{name}@footnote{We are using the syntax of the @file{index} package -here.}. The last macro also places its argument into the index, but as -subitems under the main index entry @samp{Astronomical Objects}. Here -is how to make @RefTeX{} recognize and correctly interpret these -macros, first with Emacs Lisp. - -@lisp -(setq reftex-index-macros - '(("\\ix@{*@}" "idx" ?x "" nil nil) - ("\\nindex@{*@}" "name" ?n "" nil nil) - ("\\astobj@{*@}" "idx" ?o "Astronomical Objects!" nil t))) -@end lisp - -Note that the index tag is @samp{idx} for the main index, and -@samp{name} for the name index. @samp{idx} and @samp{glo} are reserved -for the default index and for the glossary. - -The character arguments @code{?x}, @code{?n}, and @code{?o} are for -quick identification of these macros when @RefTeX{} inserts new -index entries with @code{reftex-index}. These codes need to be -unique. @code{?i}, @code{?I}, and @code{?g} are reserved for the -@code{\index}, @code{\index*}, and @code{\glossary} macros, -respectively. - -The following string is empty unless your macro adds a superordinate -entry to the index key; this is the case for the @code{\astobj} macro. - -The next entry can be a hook function to exclude certain matches, it -almost always can be @code{nil}. - -The final element in the list indicates if the text being indexed needs -to be repeated outside the macro. For the normal index macros, this -should be @code{t}. Only if the macro typesets the entry in the text -(like @code{\ix} and @code{\nindex} in the example do), this should be -@code{nil}. - -To do the same thing with customize, you need to fill in the templates -like this: - -@example -Repeat: -[INS] [DEL] List: - Macro with args: \ix@{*@} - Index Tag : [Value Menu] String: idx - Access Key : x - Key Prefix : - Exclusion hook : nil - Repeat Outside : [Toggle] off (nil) -[INS] [DEL] List: - Macro with args: \nindex@{*@} - Index Tag : [Value Menu] String: name - Access Key : n - Key Prefix : - Exclusion hook : nil - Repeat Outside : [Toggle] off (nil) -[INS] [DEL] List: - Macro with args: \astobj@{*@} - Index Tag : [Value Menu] String: idx - Access Key : o - Key Prefix : Astronomical Objects! - Exclusion hook : nil - Repeat Outside : [Toggle] on (non-nil) -[INS] -@end example - -With the macro @code{\ix} defined, you may want to change the default -macro used for indexing a text phrase (@pxref{Creating Index Entries}). -This would be done like this - -@lisp -(setq reftex-index-default-macro '(?x "idx")) -@end lisp - -which specifies that the macro identified with the character @code{?x} (the -@code{\ix} macro) should be used for indexing phrases and words already -in the buffer with @kbd{C-c /} (@code{reftex-index-selection-or-word}). -The index tag is "idx". - -@node Viewing Cross-References -@chapter Viewing Cross-References -@findex reftex-view-crossref -@findex reftex-mouse-view-crossref -@kindex C-c & -@kindex S-mouse-2 - -@RefTeX{} can display cross-referencing information. This means, -if two document locations are linked, @RefTeX{} can display the -matching location(s) in another window. The @code{\label} and @code{\ref} -macros are one way of establishing such a link. Also, a @code{\cite} -macro is linked to the corresponding @code{\bibitem} macro or a @BibTeX{} -database entry. - -The feature is invoked by pressing @kbd{C-c &} -(@code{reftex-view-crossref}) while point is on the @var{key} argument -of a macro involved in cross-referencing. You can also click with -@kbd{S-mouse-2} on the macro argument. Here is what will happen for -individual classes of macros: - -@table @asis - -@item @code{\ref} -@cindex @code{\ref} -Display the corresponding label definition. All usual -variants@footnote{all macros that start with @samp{ref} or end with -@samp{ref} or @samp{refrange}} of the @code{\ref} macro are active for -cross-reference display. This works also for labels defined in an -external document when the current document refers to them through the -@code{xr} interface (@pxref{LaTeX xr Package}). - -@item @code{\label} -@cindex @code{\label} -@vindex reftex-label-alist -Display a document location which references this label. Pressing -@kbd{C-c &} several times moves through the entire document and finds -all locations. Not only the @code{\label} macro but also other macros -with label arguments (as configured with @code{reftex-label-alist}) are -active for cross-reference display. - -@item @code{\cite} -@cindex @code{\cite} -Display the corresponding @BibTeX{} database entry or @code{\bibitem}. -All usual variants@footnote{all macros that either start or end with -@samp{cite}} of the @code{\cite} macro are active for cross-reference -display. - -@item @code{\bibitem} -@cindex @code{\bibitem} -Display a document location which cites this article. Pressing -@kbd{C-c &} several times moves through the entire document and finds -all locations. - -@item @BibTeX{} -@cindex BibTeX buffer, viewing cite locations from -@cindex Viewing cite locations from BibTeX buffer -@kbd{C-c &} is also active in @BibTeX{} buffers. All locations in a -document where the database entry at point is cited will be displayed. -On first use, @RefTeX{} will prompt for a buffer which belongs to -the document you want to search. Subsequent calls will use the same -document, until you break this link with a prefix argument to @kbd{C-c -&}. - -@item @code{\index} -@cindex @code{\index} -Display other locations in the document which are marked by an index -macro with the same key argument. Along with the standard @code{\index} -and @code{\glossary} macros, all macros configured in -@code{reftex-index-macros} will be recognized. -@end table - -@vindex reftex-view-crossref-extra -While the display of cross referencing information for the above -mentioned macros is hard-coded, you can configure additional relations -in the variable @code{reftex-view-crossref-extra}. - -@iftex -@chapter All the Rest -@end iftex -@ifnottex -@raisesections -@end ifnottex - -@node RefTeXs Menu -@section @RefTeX{}'s Menu -@cindex RefTeXs Menu -@cindex Menu, in the menu bar - -@RefTeX{} installs a @code{Ref} menu in the menu bar on systems -which support this. From this menu you can access all of -@RefTeX{}'s commands and a few of its options. There is also a -@code{Customize} submenu which can be used to access @RefTeX{}'s -entire set of options. - -@node Key Bindings -@section Default Key Bindings -@cindex Key Bindings, summary - -Here is a summary of the available key bindings. - -@kindex C-c = -@kindex C-c - -@kindex C-c ( -@kindex C-c ) -@kindex C-c [ -@kindex C-c & -@kindex S-mouse-2 -@kindex C-c / -@kindex C-c \ -@kindex C-c | -@kindex C-c < -@kindex C-c > -@example -@kbd{C-c =} @code{reftex-toc} -@kbd{C-c -} @code{reftex-toc-recenter} -@kbd{C-c (} @code{reftex-label} -@kbd{C-c )} @code{reftex-reference} -@kbd{C-c [} @code{reftex-citation} -@kbd{C-c &} @code{reftex-view-crossref} -@kbd{S-mouse-2} @code{reftex-mouse-view-crossref} -@kbd{C-c /} @code{reftex-index-selection-or-word} -@kbd{C-c \} @code{reftex-index-phrase-selection-or-word} -@kbd{C-c |} @code{reftex-index-visit-phrases-buffer} -@kbd{C-c <} @code{reftex-index} -@kbd{C-c >} @code{reftex-display-index} -@end example - -Note that the @kbd{S-mouse-2} binding is only provided if this key is -not already used by some other package. @RefTeX{} will not override an -existing binding to @kbd{S-mouse-2}. - -Personally, I also bind some functions in the users @kbd{C-c} map for -easier access. - -@c FIXME: Do we need bindings for the Index macros here as well? -@c C-c i C-c I or so???? -@c How about key bindings for reftex-reset-mode and reftex-parse-document? -@kindex C-c t -@kindex C-c l -@kindex C-c r -@kindex C-c c -@kindex C-c v -@kindex C-c s -@kindex C-c g -@example -@kbd{C-c t} @code{reftex-toc} -@kbd{C-c l} @code{reftex-label} -@kbd{C-c r} @code{reftex-reference} -@kbd{C-c c} @code{reftex-citation} -@kbd{C-c v} @code{reftex-view-crossref} -@kbd{C-c s} @code{reftex-search-document} -@kbd{C-c g} @code{reftex-grep-document} -@end example - -@noindent These keys are reserved for the user, so I cannot bind them by -default. If you want to have these key bindings available, set in your -@file{.emacs} file: - -@vindex reftex-extra-bindings -@lisp -(setq reftex-extra-bindings t) -@end lisp - -Note that this variable has to be set before @RefTeX{} is loaded to -have an effect. - -Changing and adding to @RefTeX{}'s key bindings is best done using -@code{with-eval-after-load}. For information on the keymaps -which should be used to add keys, see @ref{Keymaps and Hooks}. - -@node Faces -@section Faces -@cindex Faces - -@RefTeX{} uses faces when available to structure the selection and -table of contents buffers. It does not create its own faces, but uses -the ones defined in @file{font-lock.el}. Therefore, @RefTeX{} will -use faces only when @code{font-lock} is loaded. This seems to be -reasonable because people who like faces will very likely have it -loaded. If you wish to turn off fontification or change the involved -faces, see @ref{Options - Fontification}. - -@node Multifile Documents -@section Multifile Documents -@cindex Multifile documents -@cindex Documents, spread over files - -The following is relevant when working with documents spread over many -files: - -@itemize @bullet -@item -@RefTeX{} has full support for multifile documents. You can edit parts of -several (multifile) documents at the same time without conflicts. -@RefTeX{} provides functions to run @code{grep}, @code{search} and -@code{query-replace} on all files which are part of a multifile -document. - -@item -@vindex tex-main-file -@vindex TeX-master -All files belonging to a multifile document should define a File -Variable (@code{TeX-master} for @AUCTeX{} or @code{tex-main-file} for the -standard Emacs @LaTeX{} mode) containing the name of the master file. For -example, to set the file variable @code{TeX-master}, include something -like the following at the end of each @TeX{} file: - -@example -%%% Local Variables: *** -%%% mode:latex *** -%%% TeX-master: "thesis.tex" *** -%%% End: *** -@end example - -@AUCTeX{} with the setting - -@lisp -(setq-default TeX-master nil) -@end lisp - -will actually ask you for each new file about the master file and insert -this comment automatically. For more details see the documentation of -the @AUCTeX{} (@pxref{Multifile,,,auctex, The AUCTeX User Manual}), the -documentation about the Emacs (La)TeX mode (@pxref{TeX Print,,,emacs, -The GNU Emacs Manual}) and the Emacs documentation on File Variables -(@pxref{File Variables,,,emacs, The GNU Emacs Manual}). - -@item -The context of a label definition must be found in the same file as the -label itself in order to be processed correctly by @RefTeX{}. The only -exception is that section labels referring to a section statement -outside the current file can still use that section title as -context. - -@item -@vindex reftex-include-file-commands -@RefTeX{} knows about the @code{\include} and @code{\input} macros. -In case you use different commands to include files in a multifile -document, customize the variable @code{reftex-include-file-commands}. -@end itemize - -@node Language Support -@section Language Support -@cindex Language support - -Some parts of @RefTeX{} are language dependent. The default -settings work well for English. If you are writing in a different -language, the following hints may be useful: - -@itemize @bullet -@vindex reftex-derive-label-parameters -@vindex reftex-abbrev-parameters -@item -The mechanism to derive a label from context includes the abbreviation -of words and omission of unimportant words. These mechanisms may have -to be changed for other languages. See the variables -@code{reftex-derive-label-parameters} and @code{reftex-abbrev-parameters}. - -@vindex reftex-translate-to-ascii-function -@vindex reftex-label-illegal-re -@item -Also, when a label is derived from context, @RefTeX{} clears the context -string from non-ASCII characters in order to make a label. Starting -with @LaTeX{} release 2019-10-01, non-ASCII characters are allowed in -@LaTeX{}'s @code{\label}/@code{\ref} mechanism. If you want to change -@RefTeX{}'s behavior and allow extended characters in labels, then take -a look at the variables @code{reftex-translate-to-ascii-function} and -@code{reftex-label-illegal-re}. The following example allows any -letters and digits (among other characters) in the label definition: -@lisp -(setq reftex-label-illegal-re "[^-[:alnum:]_+=:;,.]") -@end lisp - -@item -When a label is referenced, @RefTeX{} looks at the word before point -to guess which label type is required. These @emph{magic words} are -different in every language. For an example of how to add magic words, -see @ref{Adding Magic Words}. - -@vindex reftex-multiref-punctuation -@vindex reftex-cite-punctuation -@item -@RefTeX{} inserts ``punctuation'' for multiple references and -for the author list in citations. Some of this may be language -dependent. See the variables @code{reftex-multiref-punctuation} and -@code{reftex-cite-punctuation}. -@end itemize - -@node Finding Files -@section Finding Files -@cindex Finding files - -In order to find files included in a document via @code{\input} or -@code{\include}, @RefTeX{} searches all directories specified in the -environment variable @code{TEXINPUTS}. Similarly, it will search the -path specified in the variables @code{BIBINPUTS} and @code{TEXBIB} for -@BibTeX{} database files. - -When searching, @RefTeX{} will also expand recursive path -definitions (directories ending in @samp{//} or @samp{!!}). But it will -only search and expand directories @emph{explicitly} given in these -variables. This may cause problems under the following circumstances: - -@itemize @bullet -@item -Most @TeX{} system have a default search path for both @TeX{} files and @BibTeX{} -files which is defined in some setup file. Usually this default path is -for system files which @RefTeX{} does not need to see. But if your -document needs @TeX{} files or @BibTeX{} database files in a directory only -given in the default search path, @RefTeX{} will fail to find them. -@item -Some @TeX{} systems do not use environment variables at all in order to -specify the search path. Both default and user search path are then -defined in setup files. -@end itemize - -@noindent -There are three ways to solve this problem: - -@itemize @bullet -@item -Specify all relevant directories explicitly in the environment -variables. If for some reason you don't want to mess with the default -variables @code{TEXINPUTS} and @code{BIBINPUTS}, define your own -variables and configure @RefTeX{} to use them instead: - -@lisp -(setq reftex-texpath-environment-variables '("MYTEXINPUTS")) -(setq reftex-bibpath-environment-variables '("MYBIBINPUTS")) -@end lisp - -@item -Specify the full search path directly in @RefTeX{}'s variables. - -@lisp -(setq reftex-texpath-environment-variables - '("./inp:/home/cd/tex//:/usr/local/tex//")) -(setq reftex-bibpath-environment-variables - '("/home/cd/tex/lit/")) -@end lisp - -@item -Some @TeX{} systems provide stand-alone programs to do the file search just -like @TeX{} and @BibTeX{}. E.g., Thomas Esser's @code{teTeX} uses the -@code{kpathsearch} library which provides the command @code{kpsewhich} -to search for files. @RefTeX{} can be configured to use this -program. Note that the exact syntax of the @code{kpsewhich} -command depends upon the version of that program. - -@lisp -(setq reftex-use-external-file-finders t) -(setq reftex-external-file-finders - '(("tex" . "kpsewhich -format=.tex %f") - ("bib" . "kpsewhich -format=.bib %f"))) -@end lisp -@end itemize - -@cindex Noweb files -@vindex reftex-file-extensions -@vindex TeX-file-extensions -Some people like to use RefTeX with noweb files, which usually have the -extension @file{.nw}. In order to deal with such files, the new -extension must be added to the list of valid extensions in the variable -@code{reftex-file-extensions}. When working with @AUCTeX{} as major mode, -the new extension must also be known to @AUCTeX{} via the variable -@code{TeX-file-extension}. For example: - -@lisp -(setq reftex-file-extensions - '(("nw" "tex" ".tex" ".ltx") ("bib" ".bib"))) -(setq TeX-file-extensions - '("nw" "tex" "sty" "cls" "ltx" "texi" "texinfo")) -@end lisp - -@node Optimizations -@section Optimizations -@cindex Optimizations - -@b{Note added 2002. Computers have gotten a lot faster, so most of the -optimizations discussed below will not be necessary on new machines. I -am leaving this stuff in the manual for people who want to write thick -books, where some of it still might be useful.} - -Implementing the principle of least surprises, the default settings of -@RefTeX{} ensure a safe ride for beginners and casual users. However, -when using @RefTeX{} for a large project and/or on a small computer, -there are ways to improve speed or memory usage. - -@itemize @bullet -@item -@b{Removing Lookup Buffers}@* -@cindex Removing lookup buffers -@RefTeX{} will load other parts of a multifile document as well as @BibTeX{} -database files for lookup purposes. These buffers are kept, so that -subsequent use of the same files is fast. If you can't afford keeping -these buffers around, and if you can live with a speed penalty, try - -@vindex reftex-keep-temporary-buffers -@lisp -(setq reftex-keep-temporary-buffers nil) -@end lisp - -@item -@b{Partial Document Scans}@* -@cindex Partial documents scans -@cindex Document scanning, partial -A @kbd{C-u} prefix on the major @RefTeX{} commands @code{reftex-label} -(@kbd{C-u C-c (}), @code{reftex-reference} (@kbd{C-u C-c )}), -@code{reftex-citation} (@kbd{C-u C-c [}), @code{reftex-toc} (@kbd{C-u C-c -=}), and @code{reftex-view-crossref} (@kbd{C-u C-c &}) initiates -re-parsing of the entire document in order to update the parsing -information. For a large document this can be unnecessary, in -particular if only one file has changed. @RefTeX{} can be configured -to do partial scans instead of full ones. @kbd{C-u} re-parsing then -does apply only to the current buffer and files included from it. -Likewise, the @kbd{r} key in both the label selection buffer and the -table-of-contents buffer will only prompt scanning of the file in which -the label or section macro near the cursor was defined. Re-parsing of -the entire document is still available by using @kbd{C-u C-u} as a -prefix, or the capital @kbd{R} key in the menus. To use this feature, -try - -@vindex reftex-enable-partial-scans -@lisp -(setq reftex-enable-partial-scans t) -@end lisp - -@item -@b{Saving Parser Information}@* -@cindex Saving parser information -@cindex Parse information, saving to a file -@vindex reftex-parse-file-extension -Even with partial scans enabled, @RefTeX{} still has to make one full -scan, when you start working with a document. To avoid this, parsing -information can be stored in a file. The file @file{MASTER.rel} is used -for storing information about a document with master file -@file{MASTER.tex}. It is written automatically when you kill a buffer -in @code{reftex-mode} or when you exit Emacs. The information is -restored when you begin working with a document in a new editing -session. To use this feature, put into @file{.emacs}: - -@vindex reftex-save-parse-info -@lisp -(setq reftex-save-parse-info t) -@end lisp - -@item -@b{Identifying label types by prefix}@* -@cindex Parse information, saving to a file -@vindex reftex-trust-label-prefix -@RefTeX{} normally parses around each label to check in which -environment this label is located, in order to assign a label type to -the label. If your document contains thousands of labels, document -parsing will take considerable time. If you have been using label prefixes -like tab: and fn: consistently, you can tell @RefTeX{} to get the -label type directly from the prefix, without additional parsing. This -will be faster and also allow labels to end up in the correct category -if for some reason it is not possible to derive the correct type from -context. For example, to enable this feature for footnote and -equation labels, use - -@lisp -(setq reftex-trust-label-prefix '("fn:" "eq:")) -@end lisp - -@item -@b{Automatic Document Scans}@* -@cindex Automatic document scans -@cindex Document scanning, automatic -At rare occasions, @RefTeX{} will automatically rescan a part of the -document. If this gets into your way, it can be turned off with - -@vindex reftex-allow-automatic-rescan -@lisp -(setq reftex-allow-automatic-rescan nil) -@end lisp - -@RefTeX{} will then occasionally annotate new labels in the selection -buffer, saying that their position in the label list in uncertain. A -manual document scan will fix this. - -@item -@b{Multiple Selection Buffers}@* -@cindex Multiple selection buffers -@cindex Selection buffers, multiple -Normally, the selection buffer @file{*RefTeX Select*} is re-created for -every selection process. In documents with very many labels this can -take several seconds. @RefTeX{} provides an option to create a -separate selection buffer for each label type and to keep this buffer -from one selection to the next. These buffers are updated automatically -only when a new label has been added in the buffers category with -@code{reftex-label}. Updating the buffer takes as long as recreating it -- so the time saving is limited to cases where no new labels of that -category have been added. To turn on this feature, use - -@vindex reftex-use-multiple-selection-buffers -@lisp -(setq reftex-use-multiple-selection-buffers t) -@end lisp - -@noindent -@cindex Selection buffers, updating -You can also inhibit the automatic updating entirely. Then the -selection buffer will always pop up very fast, but may not contain the -most recently defined labels. You can always update the buffer by hand, -with the @kbd{g} key. To get this behavior, use instead - -@vindex reftex-auto-update-selection-buffers -@lisp -(setq reftex-use-multiple-selection-buffers t - reftex-auto-update-selection-buffers nil) -@end lisp -@end itemize - -@need 2000 -@noindent -@b{As a summary}, here are the settings I recommend for heavy use of -@RefTeX{} with large documents: - -@lisp -@group -(setq reftex-enable-partial-scans t - reftex-save-parse-info t - reftex-use-multiple-selection-buffers t) -@end group -@end lisp - -@node AUCTeX -@section @AUCTeX{} -@cindex @code{AUCTeX}, Emacs package -@cindex Emacs packages, @code{AUCTeX} - -@AUCTeX{} is without doubt the best major mode for editing @TeX{} and @LaTeX{} -files with Emacs (@pxref{Top,AUCTeX,,auctex, The AUCTeX User Manual}). -You can get it from its website at @value{AUCTEXSITE}, but since -it is available from GNU ELPA, you can simply install it from @kbd{M-x -list-packages}. - -@menu -* AUCTeX-RefTeX Interface:: How both packages work together -* Style Files:: @AUCTeX{}'s style files can support RefTeX -* Bib-Cite:: Hypertext reading of a document -@end menu - -@node AUCTeX-RefTeX Interface -@subsection The @AUCTeX{}-@RefTeX{} Interface - -@RefTeX{} contains code to interface with @AUCTeX{}. When this -interface is turned on, both packages will interact closely. Instead of -using @RefTeX{}'s commands directly, you can then also use them -indirectly as part of the @AUCTeX{} -environment@footnote{@RefTeX{} 4.0 and @AUCTeX{} 9.10c will be -needed for all of this to work. Parts of it work also with earlier -versions.}. The interface is turned on with - -@lisp -(setq reftex-plug-into-AUCTeX t) -@end lisp - -If you need finer control about which parts of the interface are used -and which not, read the docstring of the variable -@code{reftex-plug-into-AUCTeX} or customize it with @kbd{M-x -customize-variable @key{RET} reftex-plug-into-AUCTeX @key{RET}}. - -The following list describes the individual parts of the interface. - -@itemize @bullet -@item -@findex reftex-label -@vindex LaTeX-label-function@r{, AUCTeX} -@kindex C-c C-e -@kindex C-c C-s -@findex LaTeX-section@r{, AUCTeX} -@findex TeX-insert-macro@r{, AUCTeX} -@b{@AUCTeX{} calls @code{reftex-label} to insert labels}@* -When a new section is created with @kbd{C-c C-s}, or a new environment -is inserted with @kbd{C-c C-e}, @AUCTeX{} normally prompts for a label to -go with it. With the interface, @code{reftex-label} is called instead. -For example, if you type @kbd{C-c C-e equation @key{RET}}, @AUCTeX{} and -@RefTeX{} will insert - -@example -\begin@{equation@} -\label@{eq:1@} - -\end@{equation@} -@end example - -@noindent -without further prompts. - -Similarly, when you type @kbd{C-c C-s section @key{RET}}, @RefTeX{} -will offer its default label which is derived from the section title. - -@item -@b{@AUCTeX{} tells @RefTeX{} about new sections}@* -When creating a new section with @kbd{C-c C-s}, @RefTeX{} will not -have to rescan the buffer in order to see it. - -@item -@findex reftex-arg-label -@findex TeX-arg-label@r{, AUCTeX function} -@findex reftex-arg-ref -@findex TeX-arg-ref@r{, AUCTeX function} -@findex reftex-arg-cite -@findex TeX-arg-cite@r{, AUCTeX function} -@findex reftex-arg-index -@findex TeX-arg-index@r{, AUCTeX function} -@findex TeX-insert-macro@r{, AUCTeX function} -@kindex C-c RET -@b{@RefTeX{} supplies macro arguments}@* When you insert a macro -interactively with @kbd{C-c @key{RET}}, @AUCTeX{} normally prompts for -macro arguments. Internally, it uses the functions -@code{TeX-arg-label}, @code{TeX-arg-cite}, and @code{TeX-arg-index} to -prompt for arguments which are labels, citation keys and index entries. -The interface takes over these functions@footnote{@code{fset} is used to -do this, which is not reversible. However, @RefTeX{} implements the -old functionality when you later decide to turn off the interface.} and -supplies the macro arguments with @b{@RefTeX{}'s} mechanisms. For -example, when you type @kbd{C-c @key{RET} ref @key{RET}}, @RefTeX{} -will supply its label selection process (@pxref{Referencing -Labels}). - -@item -@b{@RefTeX{} tells @AUCTeX{} about new labels, citation and index keys}@* -@RefTeX{} will add all newly created labels to @AUCTeX{}'s completion list. -@end itemize - -@node Style Files -@subsection Style Files -@cindex Style files, AUCTeX -@findex TeX-add-style-hook@r{, AUCTeX} -Style files are Emacs Lisp files which are evaluated by @AUCTeX{} in -association with the @code{\documentclass} and @code{\usepackage} -commands of a document (@pxref{Style Files,,,auctex}). Support for -@RefTeX{} in such a style file is useful when the @LaTeX{} style defines -macros or environments connected with labels, citations, or the index. -Many style files (e.g., @file{amsmath.el}, @file{natbib.el} or -@file{biblatex.el}) distributed with @AUCTeX{} already support @RefTeX{} -in this way. - -Before calling a @RefTeX{} function, the style hook should always -test for the availability of the function, so that the style file will -also work for people who do not use @RefTeX{}. - -Additions made with style files in the way described below remain local -to the current document. For example, if one package uses AMSTeX, the -style file will make @RefTeX{} switch over to @code{\eqref}, but -this will not affect other documents. - -@findex reftex-add-label-environments -@findex reftex-add-to-label-alist -A style hook may contain calls to -@code{reftex-add-label-environments}@footnote{This used to be the -function @code{reftex-add-to-label-alist} which is still available as an -alias for compatibility.} which defines additions to -@code{reftex-label-alist}. The argument taken by this function must have -the same format as @code{reftex-label-alist}. The @file{amsmath.el} -style file of @AUCTeX{} for example contains the following: - -@lisp -@group -(TeX-add-style-hook "amsmath" - (lambda () - (if (fboundp 'reftex-add-label-environments) - (reftex-add-label-environments '(AMSTeX))))) -@end group -@end lisp - -@noindent -@findex LaTeX-add-environments@r{, AUCTeX} -while a package @code{myprop} defining a @code{proposition} environment -with @code{\newtheorem} might use - -@lisp -@group -(TeX-add-style-hook "myprop" - (lambda () - (LaTeX-add-environments '("proposition" LaTeX-env-label)) - (if (fboundp 'reftex-add-label-environments) - (reftex-add-label-environments - '(("proposition" ?p "prop:" "~\\ref@{%s@}" t - ("Proposition" "Prop.") -3)))))) -@end group -@end lisp - -@findex reftex-set-cite-format -Similarly, a style hook may contain a call to -@code{reftex-set-cite-format} to set the citation format. The style -file @file{natbib.el} for the Natbib citation style does switch -@RefTeX{}'s citation format like this: - -@lisp -(TeX-add-style-hook "natbib" - (lambda () - (if (fboundp 'reftex-set-cite-format) - (reftex-set-cite-format 'natbib)))) -@end lisp - -@findex reftex-add-index-macros -The hook may contain a call to @code{reftex-add-index-macros} to -define additional @code{\index}-like macros. The argument must have -the same format as @code{reftex-index-macros}. It may be a symbol, to -trigger support for one of the builtin index packages. For example, -the style @file{multind.el} contains - -@lisp -(TeX-add-style-hook "multind" - (lambda () - (and (fboundp 'reftex-add-index-macros) - (reftex-add-index-macros '(multind))))) -@end lisp - -If you have your own package @file{myindex} which defines the -following macros to be used with the @LaTeX{} @file{index.sty} file -@example -\newcommand@{\molec@}[1]@{#1\index@{Molecules!#1@}@} -\newcommand@{\aindex@}[1]@{#1\index[author]@{#1@} -@end example - -you could write this in the style file @file{myindex.el}: - -@lisp -(TeX-add-style-hook "myindex" - (lambda () - (TeX-add-symbols - '("molec" TeX-arg-index) - '("aindex" TeX-arg-index)) - (if (fboundp 'reftex-add-index-macros) - (reftex-add-index-macros - '(("molec@{*@}" "idx" ?m "Molecules!" nil nil) - ("aindex@{*@}" "author" ?a "" nil nil)))))) -@end lisp - -@findex reftex-add-section-levels -Finally the hook may contain a call to @code{reftex-add-section-levels} -to define additional section statements. For example, the FoilTeX class -has just two headers, @code{\foilhead} and @code{\rotatefoilhead}. Here -is a style file @file{foils.el} that will inform @RefTeX{} about these: - -@lisp -(TeX-add-style-hook "foils" - (lambda () - (if (fboundp 'reftex-add-section-levels) - (reftex-add-section-levels '(("foilhead" . 3) - ("rotatefoilhead" . 3)))))) -@end lisp - -@node Bib-Cite -@subsection Bib-Cite -@cindex @code{bib-cite}, Emacs package -@cindex Emacs packages, @code{bib-cite} - -Once you have written a document with labels, references and citations, -it can be nice to read it like a hypertext document. @RefTeX{} has -support for that: @code{reftex-view-crossref} (bound to @kbd{C-c -&}), @code{reftex-mouse-view-crossref} (bound to @kbd{S-mouse-2}), and -@code{reftex-search-document}. A somewhat fancier interface with mouse -highlighting is provided (among other things) by Peter S. Galbraith's -@file{bib-cite.el}. There is some overlap in the functionalities of -Bib-cite and @RefTeX{}. Bib-cite.el comes bundled with -@AUCTeX{}. - -Bib-cite version 3.06 and later can be configured so that bib-cite's -mouse functions use @RefTeX{} for displaying references and citations. -This can be useful in particular when working with the @LaTeX{} @code{xr} -package or with an explicit @code{thebibliography} environment (rather -than @BibTeX{}). Bib-cite cannot handle those, but @RefTeX{} does. To -make use of this feature, try - -@vindex bib-cite-use-reftex-view-crossref -@lisp -(setq bib-cite-use-reftex-view-crossref t) -@end lisp - -@page -@node Problems and Work-Arounds -@section Problems and Work-arounds -@cindex Problems and work-arounds - -@itemize @bullet -@item -@b{@LaTeX{} commands}@* -@cindex LaTeX commands, not found -@code{\input}, @code{\include}, and @code{\section} (etc.)@: statements -have to be first on a line (except for white space). - -@item -@b{Commented regions}@* -@cindex Labels, commented out -@RefTeX{} sees also labels in regions commented out and will refuse to -make duplicates of such labels. This is considered to be a feature. - -@item -@b{Wrong section numbers}@* -@cindex Section numbers, wrong -@vindex reftex-enable-partial-scans -When using partial scans (@code{reftex-enable-partial-scans}), the section -numbers in the table of contents may eventually become wrong. A full -scan will fix this. - -@item -@b{Local settings}@* -@cindex Settings, local -@findex reftex-add-label-environments -@findex reftex-set-cite-format -@findex reftex-add-section-levels -The label environment definitions in @code{reftex-label-alist} are -global and apply to all documents. If you need to make definitions -local to a document, because they would interfere with settings in other -documents, you should use @AUCTeX{} and set up style files with calls to -@code{reftex-add-label-environments}, @code{reftex-set-cite-format}, -@code{reftex-add-index-macros}, and @code{reftex-add-section-levels}. -Settings made with these functions remain local to the current -document. @xref{AUCTeX}. - -@item -@b{Funny display in selection buffer}@* -@cindex @code{x-symbol}, Emacs package -@cindex Emacs packages, @code{x-symbol} -@cindex @code{isotex}, Emacs package -@cindex Emacs packages, @code{isotex} -@cindex @code{iso-cvt}, Emacs package -@cindex Emacs packages, @code{iso-cvt} -When using packages which make the buffer representation of a file -different from its disk representation (e.g., x-symbol, isotex, -iso-cvt) you may find that @RefTeX{}'s parsing information sometimes -reflects the disk state of a file. This happens only in @emph{unvisited} -parts of a multifile document, because @RefTeX{} visits these files -literally for speed reasons. Then both short context and section -headings may look different from what you usually see on your screen. -In rare cases @code{reftex-toc} may have problems to jump to an affected -section heading. There are three possible ways to deal with -this: -@itemize @minus -@item -@vindex reftex-keep-temporary-buffers -@code{(setq reftex-keep-temporary-buffers t)}@* -This implies that @RefTeX{} will load all parts of a multifile -document into Emacs (i.e., there won't be any temporary buffers). -@item -@vindex reftex-initialize-temporary-buffers -@code{(setq reftex-initialize-temporary-buffers t)}@* -This means full initialization of temporary buffers. It involves -a penalty when the same unvisited file is used for lookup often. -@item -Set @code{reftex-initialize-temporary-buffers} to a list of hook -functions doing a minimal initialization. -@end itemize -@vindex reftex-refontify-context -See also the variable @code{reftex-refontify-context}. - -@item -@b{Labels as arguments to \begin}@* -@cindex @code{pf}, LaTeX package -@cindex LaTeX packages, @code{pf} -Some packages use an additional argument to a @code{\begin} macro -to specify a label. E.g., Lamport's @file{pf.sty} uses both -@example -\step@{@var{label}@}@{@var{claim}@} and \begin@{step+@}@{@var{label}@} - @var{claim} - \end@{step+@} -@end example - -@noindent -We need to trick @RefTeX{} into swallowing this: - -@lisp -@group -;; Configuration for Lamport's pf.sty -(setq reftex-label-alist - '(("\\step@{*@}@{@}" ?p "st:" "~\\stepref@{%s@}" 2 ("Step" "St.")) - ("\\begin@{step+@}@{*@}" ?p "st:" "~\\stepref@{%s@}" 1000))) -@end group -@end lisp - -@noindent -The first line is just a normal configuration for a macro. For the -@code{step+} environment we actually tell @RefTeX{} to look for the -@emph{macro} @samp{\begin@{step+@}} and interpret the @emph{first} -argument (which really is a second argument to the macro @code{\begin}) -as a label of type @code{?p}. Argument count for this macro starts only -after the @samp{@{step+@}}, also when specifying how to get -context. - -@end itemize - -@page -@node Imprint -@section Imprint -@cindex Imprint -@cindex Maintainer -@cindex Acknowledgments -@cindex Thanks -@cindex Bug reports -@cindex @code{http}, @RefTeX{} website -@cindex @code{ftp}, @RefTeX{} site - -@c dominik@@science.uva.nl -@RefTeX{} was written by @i{Carsten Dominik}, with contributions by @i{Stephen -Eglen}. @RefTeX{} is currently maintained by @value{MAINTAINER}, see -the @value{MAINTAINERSITE} for detailed information. - -If you have questions about @RefTeX{}, you can send email to the -@value{SUPPORTADDRESS}. If you want to contribute code or ideas, write -to the @value{DEVELADDRESS}. And in the rare case of finding a bug, -please use @kbd{M-x reftex-report-bug @key{RET}} which will prepare a -bug report with useful information about your setup. Remember to add -essential information like a recipe for reproducing the bug, what you -expected to happen, and what actually happened. Send the bug report to -the @value{BUGADDRESS}. - -There are also several Usenet groups which have competent readers who -might be able to help: @code{comp.emacs}, @code{gnu.emacs.help}, -and @code{comp.text.tex}. - -Thanks to the people on the Net who have used @RefTeX{} and helped -developing it with their reports. In particular thanks to @i{Ralf -Angeli, Fran Burstall, Alastair Burt, Lars Clausen, Soren Dayton, -Stephen Eglen, Karl Eichwalder, Erik Frisk, Peter Galbraith, Kai -Grossjohann, Frank Harrell, Till A. Heilmann, Peter Heslin, Stephan -Heuel, Alan Ho, Lute Kamstra, Dieter Kraft, David Kastrup, Adrian Lanz, -Juri Linkov, Wolfgang Mayer, Rory Molinari, Stefan Monnier, Laurent -Mugnier, Dan Nicolaescu, Sudeep Kumar Palat, Daniel Polani, Alan Shutko, -Robin Socha, Richard Stanton, Allan Strand, Jan Vroonhof, Christoph -Wedler, Alan Williams, Roland Winkler, Hans-Christoph Wirth, Eli -Zaretskii}. - -The @code{view-crossref} feature was inspired by @i{Peter Galbraith's} -@file{bib-cite.el}. - -Finally thanks to @i{Uwe Bolick} who first got me interested in -supporting @LaTeX{} labels and references with an editor (which was -MicroEmacs at the time). - -@c Turn off the raising that we turned on in ``All the rest''. -@ifnottex -@lowersections -@end ifnottex - -@node Commands -@chapter Commands -@cindex Commands, list of - -Here is a summary of @RefTeX{}'s commands which can be executed from -@LaTeX{} files. Command which are executed from the special buffers are -not described here. All commands are available from the @code{Ref} -menu. @xref{Key Bindings}. - -@deffn Command reftex-toc -Show the table of contents for the current document. When called with -one or two @kbd{C-u} prefixes, rescan the document first. -@end deffn - -@deffn Command reftex-label -Insert a unique label. With one or two @kbd{C-u} prefixes, enforce -document rescan first. -@end deffn - -@deffn Command reftex-reference -Start a selection process to select a label, and insert a reference to -it. With one or two @kbd{C-u} prefixes, enforce document rescan first. -@end deffn - -@deffn Command reftex-citation -Make a citation using @BibTeX{} database files. After prompting for a regular -expression, scans the buffers with @BibTeX{} entries (taken from the -@code{\bibliography} command or a @code{thebibliography} environment) -and offers the matching entries for selection. The selected entry is -formatted according to @code{reftex-cite-format} and inserted into the -buffer. @* -When called with a @kbd{C-u} prefix, prompt for optional arguments in -cite macros. When called with a numeric prefix, make that many citations. -When called with point inside the braces of a @code{\cite} command, it -will add another key, ignoring the value of -@code{reftex-cite-format}. @* -The regular expression uses an expanded syntax: @samp{&&} is interpreted -as @code{and}. Thus, @samp{aaaa&&bbb} matches entries which contain -both @samp{aaaa} and @samp{bbb}. While entering the regexp, completion -on knows citation keys is possible. @samp{=} is a good regular -expression to match all entries in all files. -@end deffn - -@deffn Command reftex-index -Query for an index macro and insert it along with its arguments. The -index macros available are those defined in @code{reftex-index-macro} or -by a call to @code{reftex-add-index-macros}, typically from an @AUCTeX{} -style file. @RefTeX{} provides completion for the index tag and the -index key, and will prompt for other arguments. -@end deffn - -@deffn Command reftex-index-selection-or-word -Put current selection or the word near point into the default index -macro. This uses the information in @code{reftex-index-default-macro} -to make an index entry. The phrase indexed is the current selection or -the word near point. When called with one @kbd{C-u} prefix, let the -user have a chance to edit the index entry. When called with 2 -@kbd{C-u} as prefix, also ask for the index macro and other stuff. When -called inside @TeX{} math mode as determined by the @file{texmathp.el} -library which is part of @AUCTeX{}, the string is first processed with the -@code{reftex-index-math-format}, which see. -@end deffn - -@deffn Command reftex-index-phrase-selection-or-word -Add current selection or the word at point to the phrases buffer. -When you are in transient-mark-mode and the region is active, the -selection will be used; otherwise the word at point. -You get a chance to edit the entry in the phrases buffer; to save the -buffer and return to the @LaTeX{} document, finish with @kbd{C-c C-c}. -@end deffn - -@deffn Command reftex-index-visit-phrases-buffer -Switch to the phrases buffer, initialize if empty. -@end deffn - -@deffn Command reftex-index-phrases-apply-to-region -Index all index phrases in the current region. -This works exactly like global indexing from the index phrases buffer, -but operation is restricted to the current region. -@end deffn - -@deffn Command reftex-display-index -Display a buffer with an index compiled from the current document. -When the document has multiple indices, first prompts for the correct one. -When index support is turned off, offer to turn it on. -With one or two @kbd{C-u} prefixes, rescan document first. -With prefix 2, restrict index to current document section. -With prefix 3, restrict index to active region. -@end deffn - -@deffn Command reftex-view-crossref -View cross reference of macro at point. Point must be on the @var{key} -argument. Works with the macros @code{\label}, @code{\ref}, -@code{\cite}, @code{\bibitem}, @code{\index} and many derivatives of -these. Where it makes sense, subsequent calls show additional -locations. See also the variable @code{reftex-view-crossref-extra} and -the command @code{reftex-view-crossref-from-bibtex}. With one or two -@kbd{C-u} prefixes, enforce rescanning of the document. With argument -2, select the window showing the cross reference. -@end deffn - -@deffn Command reftex-view-crossref-from-bibtex -View location in a @LaTeX{} document which cites the @BibTeX{} entry at point. -Since @BibTeX{} files can be used by many @LaTeX{} documents, this function -prompts upon first use for a buffer in @RefTeX{} mode. To reset this -link to a document, call the function with a prefix arg. Calling -this function several times find successive citation locations. -@end deffn - -@deffn Command reftex-create-tags-file -Create TAGS file by running @code{etags} on the current document. The -TAGS file is also immediately visited with -@code{visit-tags-table}. -@end deffn - -@deffn Command reftex-grep-document -Run grep query through all files related to this document. -With prefix arg, force to rescan document. -No active TAGS table is required. -@end deffn - -@deffn Command reftex-search-document -Regexp search through all files of the current document. -Starts always in the master file. Stops when a match is found. -No active TAGS table is required. -@end deffn - -@deffn Command reftex-query-replace-document -Run a query-replace-regexp of @var{from} with @var{to} over the entire -document. With prefix arg, replace only word-delimited matches. No -active TAGS table is required. -@end deffn - -@deffn Command reftex-isearch-minor-mode -Toggle a minor mode which enables incremental search to work globally -on the entire multifile document. Files will be searched in the -sequence they appear in the document. -@end deffn - -@deffn Command reftex-goto-label -Prompt for a label (with completion) and jump to the location of this -label. Optional prefix argument @var{other-window} goes to the label in -another window. -@end deffn - - -@deffn Command reftex-change-label -Query replace @var{from} with @var{to} in all @code{\label} and -@code{\ref} commands. Works on the entire multifile document. No -active TAGS table is required. -@end deffn - -@deffn Command reftex-renumber-simple-labels -Renumber all simple labels in the document to make them sequentially. -Simple labels are the ones created by RefTeX, consisting only of the -prefix and a number. After the command completes, all these labels will -have sequential numbers throughout the document. Any references to the -labels will be changed as well. For this, @RefTeX{} looks at the -arguments of any macros which either start or end with the string -@samp{ref}. This command should be used with care, in particular in -multifile documents. You should not use it if another document refers -to this one with the @code{xr} package. -@end deffn - -@deffn Command reftex-find-duplicate-labels -Produce a list of all duplicate labels in the document. -@end deffn - -@deffn Command reftex-create-bibtex-file -@vindex reftex-create-bibtex-header -@vindex reftex-create-bibtex-footer -Create a new @BibTeX{} database file with all entries referenced in -document. The command prompts for a filename and writes the collected -entries to that file. Only entries referenced in the current document -with any @code{\cite}-like macros are used. The sequence in the new -file is the same as it was in the old database. - -Entries referenced from other entries must appear after all referencing -entries. - -You can define strings to be used as header or footer for the created -files in the variables @code{reftex-create-bibtex-header} or -@code{reftex-create-bibtex-footer} respectively. -@end deffn - -@deffn Command reftex-customize -Run the customize browser on the @RefTeX{} group. -@end deffn -@deffn Command reftex-show-commentary -Show the commentary section from @file{reftex.el}. -@end deffn -@deffn Command reftex-info -Run info on the top @RefTeX{} node. -@end deffn -@deffn Command reftex-parse-document -Parse the entire document in order to update the parsing information. -@end deffn -@deffn Command reftex-reset-mode -Enforce rebuilding of several internal lists and variables. Also -removes the parse file associated with the current document. -@end deffn - -@node Options -@chapter Options, Keymaps, Hooks -@cindex Options, list of - -Here is a complete list of @RefTeX{}'s configuration variables. All -variables have customize support, so if you are not familiar with Emacs -Lisp (and even if you are) you might find it more comfortable to use -@code{customize} to look at and change these variables. @kbd{M-x -reftex-customize} will get you there. - -In case you don't use the @code{customize} interface, here's a caveat: -Changing (mostly parsing-related) options might require a call to -@code{reftex-compile-variables} in order to become effective. - -@menu -* Options - Table of Contents:: -* Options - Defining Label Environments:: -* Options - Creating Labels:: -* Options - Referencing Labels:: -* Options - Creating Citations:: -* Options - Index Support:: -* Options - Viewing Cross-References:: -* Options - Finding Files:: -* Options - Optimizations:: -* Options - Fontification:: -* Options - Misc:: -* Keymaps and Hooks:: -@end menu - -@node Options - Table of Contents -@section Table of Contents -@cindex Options, table of contents -@cindex Table of contents, options - -@defopt reftex-include-file-commands -List of @LaTeX{} commands which input another file. -The file name is expected after the command, either in braces or separated -by whitespace. -@end defopt - -@defopt reftex-max-section-depth -Maximum depth of section levels in document structure. -Standard @LaTeX{} needs 7, default is 12. -@end defopt - -@defopt reftex-section-levels -Commands and levels used for defining sections in the document. The -@code{car} of each cons cell is the name of the section macro. The -@code{cdr} is a number indicating its level. A negative level means the -same as the positive value, but the section will never get a number. -The @code{cdr} may also be a function which then has to return the -level. This list is also used for promotion and demotion of sectioning -commands. If you are using a document class which has several sets of -sectioning commands, promotion only works correctly if this list is -sorted first by set, then within each set by level. The promotion -commands always select the nearest entry with the correct new level. - -@end defopt - -@defopt reftex-toc-max-level -The maximum level of toc entries which will be included in the TOC@. -Section headings with a bigger level will be ignored. In RefTeX, -chapters are level 1, sections level 2 etc. This variable can be -changed from within the @file{*toc*} buffer with the @kbd{t} key. -@end defopt - -@defopt reftex-part-resets-chapter -Non-@code{nil} means, @code{\part} is like any other sectioning command. -This means, part numbers will be included in the numbering of chapters, and -chapter counters will be reset for each part. -When @code{nil} (the default), parts are special, do not reset the -chapter counter and also do not show up in chapter numbers. -@end defopt - -@defopt reftex-auto-recenter-toc -Non-@code{nil} means, turn automatic recentering of @file{*TOC*} window on. -When active, the @file{*TOC*} window will always show the section you -are currently working in. Recentering happens whenever Emacs is idle for -more than @code{reftex-idle-time} seconds. - -Value @code{t} means, turn on immediately when RefTeX gets started. Then, -recentering will work for any toc window created during the session. - -Value @code{frame} (the default) means, turn automatic recentering on -only while the dedicated TOC frame does exist, and do the recentering -only in that frame. So when creating that frame (with @kbd{d} key in an -ordinary TOC window), the automatic recentering is turned on. When the -frame gets destroyed, automatic recentering is turned off again. - -This feature can be turned on and off from the menu -(Ref->Options). -@end defopt - -@defopt reftex-toc-split-windows-horizontally -Non-@code{nil} means, create TOC window by splitting window -horizontally. The default is to split vertically. -@end defopt - -@defopt reftex-toc-split-windows-fraction -Fraction of the width or height of the frame to be used for TOC window. -@end defopt - -@defopt reftex-toc-keep-other-windows -Non-@code{nil} means, split the selected window to display the -@file{*toc*} buffer. This helps to keep the window configuration, but -makes the @file{*toc*} small. When @code{nil}, all other windows except -the selected one will be deleted, so that the @file{*toc*} window fills -half the frame. -@end defopt - -@defopt reftex-toc-include-file-boundaries -Non-@code{nil} means, include file boundaries in @file{*toc*} buffer. -This flag can be toggled from within the @file{*toc*} buffer with the -@kbd{i} key. -@end defopt - -@defopt reftex-toc-include-labels -Non-@code{nil} means, include labels in @file{*toc*} buffer. This flag -can be toggled from within the @file{*toc*} buffer with the @kbd{l} -key. -@end defopt - -@defopt reftex-toc-include-index-entries -Non-@code{nil} means, include index entries in @file{*toc*} buffer. -This flag can be toggled from within the @file{*toc*} buffer with the -@kbd{i} key. -@end defopt - -@defopt reftex-toc-include-context -Non-@code{nil} means, include context with labels in the @file{*toc*} -buffer. Context will only be shown if the labels are visible as well. -This flag can be toggled from within the @file{*toc*} buffer with the -@kbd{c} key. -@end defopt - -@defopt reftex-toc-follow-mode -Non-@code{nil} means, point in @file{*toc*} buffer (the -table-of-contents buffer) will cause other window to follow. The other -window will show the corresponding part of the document. This flag can -be toggled from within the @file{*toc*} buffer with the @kbd{f} -key. -@end defopt - -@deffn {Normal Hook} reftex-toc-mode-hook -Normal hook which is run when a @file{*toc*} buffer is -created. -@end deffn - -@deffn Keymap reftex-toc-mode-map -The keymap which is active in the @file{*toc*} buffer. -(@pxref{Table of Contents}). -@end deffn - -@node Options - Defining Label Environments -@section Defining Label Environments -@cindex Options, defining label environments -@cindex Defining label environments, options - -@defopt reftex-default-label-alist-entries -Default label alist specifications. It is a list of symbols with -associations in the constant @code{reftex-label-alist-builtin}. -@code{LaTeX} should always be the last entry. -@end defopt - -@defopt reftex-label-alist -Set this variable to define additions and changes to the defaults in -@code{reftex-default-label-alist-entries}. The only things you -@emph{must not} change is that @code{?s} is the type indicator for -section labels, and @key{SPC} for the @code{any} label type. These are -hard-coded at other places in the code. - -The value of the variable must be a list of items. Each item is a list -itself and has the following structure: - -@example - (@var{env-or-macro} @var{type-key} @var{label-prefix} @var{reference-format} - @var{context-method} (@var{magic-word} ... ) @var{toc-level}) -@end example - -Each list entry describes either an environment carrying a counter for -use with @code{\label} and @code{\ref}, or a @LaTeX{} macro defining a -label as (or inside) one of its arguments. The elements of each list -entry are: - -@table @asis -@item @var{env-or-macro} -Name of the environment (like @samp{table}) or macro (like -@samp{\myfig}). For macros, indicate the arguments, as in -@samp{\myfig[]@{@}@{@}@{*@}@{@}}. Use square brackets for optional -arguments, a star to mark the label argument, if any. The macro does -not have to have a label argument; you could also use -@samp{\label@{...@}} inside one of its arguments. - -Special names: @code{section} for section labels, @code{any} to define a -group which contains all labels. - -This may also be a function to do local parsing and identify point to be -in a non-standard label environment. The function must take an -argument @var{bound} and limit backward searches to this value. It -should return either @code{nil} or a cons cell @code{(@var{function} -. @var{position})} with the function symbol and the position where the -special environment starts. See the Info documentation for an -example. - -Finally this may also be @code{nil} if the entry is only meant to change -some settings associated with the type indicator character (see -below). - -@item @var{type-key} -Type indicator character, like @code{?t}, must be a printable ASCII -character. The type indicator is a single character which defines a -label type. Any label inside the environment or macro is assumed to -belong to this type. The same character may occur several times in this -list, to cover cases in which different environments carry the same -label type (like @code{equation} and @code{eqnarray}). If the type -indicator is @code{nil} and the macro has a label argument @samp{@{*@}}, -the macro defines neutral labels just like @code{\label}. In this case -the remainder of this entry is ignored. - -@item @var{label-prefix} -Label prefix string, like @samp{tab:}. The prefix is a short string -used as the start of a label. It may be the empty string. The prefix -may contain the following @samp{%} escapes: - -@example -%f Current file name, directory and extension stripped. -%F Current file name relative to master file directory. -%m Master file name, directory and extension stripped. -%M Directory name (without path) where master file is located. -%u User login name, on systems which support this. -%S A section prefix derived with variable @code{reftex-section-prefixes}. -@end example - -@noindent -Example: In a file @file{intro.tex}, @samp{eq:%f:} will become -@samp{eq:intro:}. - -@item @var{reference-format} -Format string for reference insertion in buffer. @samp{%s} will be -replaced by the label. When the format starts with @samp{~}, this -@samp{~} will only be inserted when the character before point is -@emph{not} a whitespace. - -@item @var{context-method} -Indication on how to find the short context. -@itemize @minus -@item -If @code{nil}, use the text following the @samp{\label@{...@}} macro. -@item -If @code{t}, use -@itemize @minus -@item -the section heading for section labels. -@item -text following the @samp{\begin@{...@}} statement of environments (not -a good choice for environments like eqnarray or enumerate, where one has -several labels in a single environment). -@item -text after the macro name (starting with the first arg) for -macros. -@end itemize -@item -If an integer, use the nth argument of the macro. As a special case, -1000 means to get text after the last macro argument. -@item -If a string, use as regexp to search @emph{backward} from the label. -Context is then the text following the end of the match. E.g., setting -this to @samp{\\caption[[@{]} will use the caption in a figure or table -environment. @samp{\\begin@{eqnarray@}\|\\\\} works for -eqnarrays. -@item -If any of @code{caption}, @code{item}, @code{eqnarray-like}, -@code{alignat-like}, this symbol will internally be translated into an -appropriate regexp (see also the variable -@code{reftex-default-context-regexps}). -@item -If a function, call this function with the name of the environment/macro -as argument. On call, point will be just after the @code{\label} macro. -The function is expected to return a suitable context string. It should -throw an exception (error) when failing to find context. As an example, -here is a function returning the 10 chars following the label macro as -context: - -@example -(defun my-context-function (env-or-mac) - (if (> (point-max) (+ 10 (point))) - (buffer-substring (point) (+ 10 (point))) - (error "Buffer too small"))) -@end example -@end itemize - -Label context is used in two ways by @RefTeX{}: For display in the label -menu, and to derive a label string. If you want to use a different -method for each of these, specify them as a dotted pair. -E.g., @code{(nil . t)} uses the text after the label (@code{nil}) for -display, and text from the default position (@code{t}) to derive a label -string. This is actually used for section labels. - -@item @var{magic-word-list} -List of magic words which identify a reference to be of this type. If -the word before point is equal to one of these words when calling -@code{reftex-reference}, the label list offered will be automatically -restricted to labels of the correct type. If the first element of this -word list is the symbol @code{regexp}, the strings are interpreted as regular -expressions. - -@item @var{toc-level} -The integer level at which this environment should be added to the table -of contents. See also @code{reftex-section-levels}. A positive value -will number the entries mixed with the sectioning commands of the same -level. A negative value will make unnumbered entries. Useful only for -theorem-like environments which structure the document. Will be ignored -for macros. When omitted or @code{nil}, no TOC entries will be -made. -@end table - -If the type indicator characters of two or more entries are the same, -@RefTeX{} will use -@itemize @minus -@item -the first non-@code{nil} format and prefix -@item -the magic words of all involved entries. -@end itemize - -Any list entry may also be a symbol. If that has an association in -@code{reftex-label-alist-builtin}, the @code{cddr} of that association is -spliced into the list. However, builtin defaults should normally be set -with the variable @code{reftex-default-label-alist-entries}. -@end defopt - -@defopt reftex-label-regexps -List of regular expressions matching @samp{\label} definitions. The -default value matches usual @samp{\label@{@dots{}@}} definitions and key -value style @samp{[@dots{}, label = @{@dots{}@}, @dots{}]} label -definitions. The regular expression for key value style explicitly -looks for environments provided by the packages @code{listings} -(@code{lstlisting}), @code{beamer} (@code{frame}), @code{breqn} -(@code{dmath}, @code{dseries}, @code{dgroup}, @code{darray}) and the -macro @code{\ctable} provided by the package of the same name. - -It is assumed that the regexp group 1 matches the label text, so you -have to define it using @samp{\(?1:...\)} when adding new regexps. - -When changed from Lisp, make sure to call -@code{reftex-compile-variables} afterwards to make the change effective. -@end defopt - -@defopt reftex-section-prefixes -Prefixes for section labels. When the label prefix given in an entry in -@code{reftex-label-alist} contains @samp{%S}, this list is used to -determine the correct prefix string depending on the current section -level. The list is an alist, with each entry of the form -@w{@code{(@var{key} . @var{prefix})}}. Possible keys are sectioning macro -names like @samp{chapter}, integer section levels (as given in -@code{reftex-section-levels}), and @code{t} for the default. -@end defopt - -@defopt reftex-default-context-regexps -Alist with default regular expressions for finding context. The emacs -lisp form @w{@code{(format regexp (regexp-quote environment))}} is used -to calculate the final regular expression, so @samp{%s} will be -replaced with the environment or macro. -@end defopt - -@defopt reftex-trust-label-prefix -Non-@code{nil} means, trust the label prefix when determining label type. -It is customary to use special label prefixes to distinguish different label -types. The label prefixes have no syntactic meaning in @LaTeX{} (unless -special packages like fancyref) are being used. RefTeX can and by -default does parse around each label to detect the correct label type, -but this process can be slow when a document contains thousands of -labels. If you use label prefixes consistently, you may speed up -document parsing by setting this variable to a non-@code{nil} value. RefTeX -will then compare the label prefix with the prefixes found in -@code{reftex-label-alist} and derive the correct label type in this way. -Possible values for this option are: - -@example -t @r{This means to trust any label prefixes found.} -regexp @r{If a regexp, only prefixes matched by the regexp are trusted.} -list @r{List of accepted prefixes, as strings. The colon is part of} - @r{the prefix, e.g., ("fn:" "eqn:" "item:").} -nil @r{Never trust a label prefix.} -@end example -The only disadvantage of using this feature is that the label context -displayed in the label selection buffer along with each label is -simply some text after the label definition. This is no problem if you -place labels keeping this in mind (e.g., @i{before} the equation, @i{at -the beginning} of a fig/tab caption ...). Anyway, it is probably best -to use the regexp or the list value types to fine-tune this feature. -For example, if your document contains thousands of footnotes with -labels fn:xxx, you may want to set this variable to the value "^fn:$" or -("fn:"). Then RefTeX will still do extensive parsing for any -non-footnote labels. -@end defopt - -@node Options - Creating Labels -@section Creating Labels -@cindex Options, creating labels -@cindex Creating labels, options - -@defopt reftex-insert-label-flags -Flags governing label insertion. The value has the form - -@example -(@var{derive} @var{prompt}) -@end example - -If @var{derive} is @code{t}, @RefTeX{} will try to derive a sensible -label from context. A section label for example will be derived from -the section heading. The conversion of the context to a valid label is -governed by the specifications given in -@code{reftex-derive-label-parameters}. If @var{derive} is @code{nil}, -the default label will consist of the prefix and a unique number, like -@samp{eq:23}. - -If @var{prompt} is @code{t}, the user will be prompted for a label -string. When @var{prompt} is @code{nil}, the default label will be -inserted without query. - -So the combination of @var{derive} and @var{prompt} controls label -insertion. Here is a table describing all four possibilities: - -@example -@group -@var{derive} @var{prompt} @var{action} ------------------------------------------------------------ -nil nil @r{Insert simple label, like @samp{eq:22} or @samp{sec:13}. No query.} -nil t @r{Prompt for label.} -t nil @r{Derive a label from context and insert. No query.} -t t @r{Derive a label from context, prompt for confirmation.} -@end group -@end example - -Each flag may be set to @code{t}, @code{nil}, or a string of label type -letters indicating the label types for which it should be true. Thus, -the combination may be set differently for each label type. The default -settings @samp{"s"} and @samp{"sft"} mean: Derive section labels from -headings (with confirmation). Prompt for figure and table labels. Use -simple labels without confirmation for everything else. - -The available label types are: @code{s} (section), @code{f} (figure), -@code{t} (table), @code{i} (item), @code{e} (equation), @code{n} -(footnote), @code{N} (endnote) plus any definitions in -@code{reftex-label-alist}. -@end defopt - -@deffn Hook reftex-format-label-function -If non-@code{nil}, should be a function which produces the string to -insert as a label definition. The function will be called with two -arguments, the @var{label} and the @var{default-format} (usually -@samp{\label@{%s@}}). It should return the string to insert into the -buffer. -@end deffn - -@deffn Hook reftex-string-to-label-function -Function to turn an arbitrary string into a valid label. -@RefTeX{}'s default function uses the variable -@code{reftex-derive-label-parameters}. -@end deffn - -@deffn Hook reftex-translate-to-ascii-function -Filter function which will process a context string before it is used to -derive a label from it. The intended application is to convert ISO or -Mule characters into something valid in labels. The default function -@code{reftex-latin1-to-ascii} removes the accents from Latin-1 -characters. X-Symbol (>=2.6) sets this variable to the much more -general @code{x-symbol-translate-to-ascii}. -@end deffn - -@defopt reftex-derive-label-parameters -Parameters for converting a string into a label. This variable is a -list of the following items: -@table @asis -@item @var{nwords} -Number of words to use. -@item @var{maxchar} -Maximum number of characters in a label string. -@item @var{invalid} -@code{nil}: Throw away any words containing characters invalid in labels.@* -@code{t}: Throw away only the invalid characters, not the whole word. -@item @var{abbrev} -@code{nil}: Never abbreviate words.@* -@code{t}: Always abbreviate words (see @code{reftex-abbrev-parameters}).@* -@code{1}: Abbreviate words if necessary to shorten label string. -@item @var{separator} -String separating different words in the label. -@item @var{ignorewords} -List of words which should not be part of labels. -@item @var{downcase} -@code{t}: Downcase words before putting them into the label.@* -@end table -@end defopt - -@defopt reftex-label-illegal-re -Regexp matching characters not valid in labels. -@end defopt - -@defopt reftex-abbrev-parameters -Parameters for abbreviation of words. A list of four parameters. -@table @asis -@item @var{min-chars} -Minimum number of characters remaining after abbreviation. -@item @var{min-kill} -Minimum number of characters to remove when abbreviating words. -@item @var{before} -Character class before abbrev point in word. -@item @var{after} -Character class after abbrev point in word. -@end table -@end defopt - -@node Options - Referencing Labels -@section Referencing Labels -@cindex Options, referencing labels -@cindex Referencing labels, options - -@defopt reftex-label-menu-flags -List of flags governing the label menu makeup. The flags are: -@table @asis -@item @var{table-of-contents} -Show the labels embedded in a table of context. -@item @var{section-numbers} -Include section numbers (like 4.1.3) in table of contents. -@item @var{counters} -Show counters. This just numbers the labels in the menu. -@item @var{no-context} -Non-@code{nil} means do @emph{not} show the short context. -@item @var{follow} -Follow full context in other window. -@item @var{show-commented} -Show labels from regions which are commented out. -@item @var{match-everywhere} -Obsolete flag. -@item @var{show-files} -Show begin and end of included files. -@end table - -Each of these flags can be set to @code{t} or @code{nil}, or to a string -of type letters indicating the label types for which it should be true. -These strings work like character classes in regular expressions. Thus, -setting one of the flags to @samp{"sf"} makes the flag true for section -and figure labels, @code{nil} for everything else. Setting it to -@samp{"^sf"} makes it the other way round. - -The available label types are: @code{s} (section), @code{f} (figure), -@code{t} (table), @code{i} (item), @code{e} (equation), @code{n} -(footnote), plus any definitions in @code{reftex-label-alist}. - -Most options can also be switched from the label menu itself, so if you -decide here to not have a table of contents in the label menu, you can -still get one interactively during selection from the label menu. -@end defopt - -@defopt reftex-multiref-punctuation -Punctuation strings for multiple references. When marking is used in -the selection buffer to select several references, this variable -associates the 3 marking characters @samp{,-+} with prefix strings to be -inserted into the buffer before the corresponding @code{\ref} macro. -This is used to string together whole reference sets, like -@samp{eqs. 1,2,3-5,6 and 7} in a single call to -@code{reftex-reference}. -@end defopt - -@defopt reftex-ref-style-alist -Alist of reference styles. Each element is a list of the style name, -the name of the @LaTeX{} package associated with the style or @code{t} -for any package, and an alist of macros where the first entry of each -item is the reference macro and the second a key for selecting the macro -when the macro type is being prompted for. (See also -@code{reftex-ref-macro-prompt}.) The keys, represented as characters, -have to be unique. -@end defopt - -@defopt reftex-ref-style-default-list -List of reference styles to be activated by default. The order is -significant and controls the order in which macros can be cycled in the -buffer for selecting a label. The entries in the list have to match the -respective reference style names used in the variable -@code{reftex-ref-style-alist}. -@end defopt - -@defopt reftex-ref-macro-prompt -Controls if @code{reftex-reference} prompts for the reference macro. -@end defopt - -@deffn Hook reftex-format-ref-function -If non-@code{nil}, should be a function which produces the string to -insert as a reference. Note that the insertion format can also be -changed with @code{reftex-label-alist}. This hook also is used by the -special commands to insert, e.g., @code{\vref} and @code{\fref} -references, so even if you set this, your setting will be ignored by the -special commands. The function will be called with three arguments, the -@var{label}, the @var{default format} which normally is -@samp{~\ref@{%s@}} and the @var{reference style}. The function should -return the string to insert into the buffer. -@end deffn - -@defopt reftex-level-indent -Number of spaces to be used for indentation per section level. -@end defopt - -@defopt reftex-guess-label-type -Non-@code{nil} means, @code{reftex-reference} will try to guess the -label type. To do that, @RefTeX{} will look at the word before the -cursor and compare it with the magic words given in -@code{reftex-label-alist}. When it finds a match, @RefTeX{} will -immediately offer the correct label menu; otherwise it will prompt you -for a label type. If you set this variable to @code{nil}, @RefTeX{} -will always prompt for a label type. -@end defopt - -@deffn {Normal Hook} reftex-display-copied-context-hook -Normal Hook which is run before context is displayed anywhere. Designed -for @w{@code{X-Symbol}}, but may have other uses as well. -@end deffn - -@deffn Hook reftex-pre-refontification-functions -@code{X-Symbol} specific hook. Probably not useful for other purposes. -The functions get two arguments, the buffer from where the command -started and a symbol indicating in what context the hook is -called. -@end deffn - -@deffn {Normal Hook} reftex-select-label-mode-hook -Normal hook which is run when a selection buffer enters -@code{reftex-select-label-mode}. -@end deffn - -@deffn Keymap reftex-select-label-mode-map -The keymap which is active in the labels selection process -(@pxref{Referencing Labels}). -@end deffn - -@node Options - Creating Citations -@section Creating Citations -@cindex Options, creating citations -@cindex Creating citations, options - -@defopt reftex-bibliography-commands -@LaTeX{} commands which specify the @BibTeX{} databases to use with the document. -@end defopt - -@defopt reftex-bibfile-ignore-regexps -List of regular expressions to exclude files in -@code{\\bibliography@{..@}}. File names matched by any of these regexps -will not be parsed. Intended for files which contain only -@code{@@string} macro definitions and the like, which are ignored by -@RefTeX{} anyway. -@end defopt - -@defopt reftex-default-bibliography -List of @BibTeX{} database files which should be used if none are specified. -When @code{reftex-citation} is called from a document with neither -a @samp{\bibliography@{...@}} statement nor a @code{thebibliography} -environment, @RefTeX{} will scan these files instead. Intended for -using @code{reftex-citation} in non-@LaTeX{} files. The files will be -searched along the BIBINPUTS or TEXBIB path. -@end defopt - -@defopt reftex-sort-bibtex-matches -Sorting of the entries found in @BibTeX{} databases by reftex-citation. -Possible values: -@example -nil @r{Do not sort entries.} -author @r{Sort entries by author name.} -year @r{Sort entries by increasing year.} -reverse-year @r{Sort entries by decreasing year.} -@end example -@end defopt - -@defopt reftex-cite-format -The format of citations to be inserted into the buffer. It can be a -string, an alist or a symbol. In the simplest case this is just the string -@samp{\cite@{%l@}}, which is also the default. See the definition of -@code{reftex-cite-format-builtin} for more complex examples. - -If @code{reftex-cite-format} is a string, it will be used as the format. -In the format, the following percent escapes will be expanded. - -@table @code -@item %l -The @BibTeX{} label of the citation. -@item %a -List of author names, see also @code{reftex-cite-punctuation}. -@item %2a -Like %a, but abbreviate more than 2 authors like Jones et al. -@item %A -First author name only. -@item %e -Works like @samp{%a}, but on list of editor names. (@samp{%2e} and -@samp{%E} work a well). -@end table - -It is also possible to access all other @BibTeX{} database fields: - -@example -%b booktitle %c chapter %d edition %h howpublished -%i institution %j journal %k key %m month -%n number %o organization %p pages %P first page -%r address %s school %u publisher %t title -%v volume %y year -%B booktitle, abbreviated %T title, abbreviated -@end example - -@noindent -Usually, only @samp{%l} is needed. The other stuff is mainly for the -echo area display, and for @code{(setq reftex-comment-citations t)}. - -@samp{%<} as a special operator kills punctuation and space around it -after the string has been formatted. - -A pair of square brackets indicates an optional argument, and RefTeX -will prompt for the values of these arguments. - -Beware that all this only works with @BibTeX{} database files. When -citations are made from the @code{\bibitems} in an explicit -@code{thebibliography} environment, only @samp{%l} is available. - -If @code{reftex-cite-format} is an alist of characters and strings, the -user will be prompted for a character to select one of the possible -format strings. - -In order to configure this variable, you can either set -@code{reftex-cite-format} directly yourself or set it to the -@emph{symbol} of one of the predefined styles. The predefined symbols -are those which have an association in the constant -@code{reftex-cite-format-builtin}, e.g.: @code{(setq reftex-cite-format -'natbib)}. -@end defopt - -@deffn Hook reftex-format-cite-function -If non-@code{nil}, should be a function which produces the string to -insert as a citation. Note that the citation format can also be changed -with the variable @code{reftex-cite-format}. The function will be -called with two arguments, the @var{citation-key} and the -@var{default-format} (taken from @code{reftex-cite-format}). It should -return the string to insert into the buffer. -@end deffn - -@defopt reftex-cite-prompt-optional-args -Non-@code{nil} means, prompt for empty optional arguments in cite macros. -When an entry in @code{reftex-cite-format} is given with square brackets to -indicate optional arguments (for example @samp{\\cite[][]@{%l@}}), RefTeX can -prompt for values. Possible values are: -@example -nil @r{Never prompt for optional arguments} -t @r{Always prompt} -maybe @r{Prompt only if @code{reftex-citation} was called with C-u prefix arg} -@end example -Unnecessary empty optional arguments are removed before insertion into -the buffer. See @code{reftex-cite-cleanup-optional-args}. -@end defopt - -@defopt reftex-cite-cleanup-optional-args -Non-@code{nil} means, remove empty optional arguments from cite macros -if possible. -@end defopt - -@defopt reftex-comment-citations -Non-@code{nil} means add a comment for each citation describing the full -entry. The comment is formatted according to -@code{reftex-cite-comment-format}. -@end defopt - -@defopt reftex-cite-comment-format -Citation format used for commented citations. Must @emph{not} contain -@samp{%l}. See the variable @code{reftex-cite-format} for possible -percent escapes. -@end defopt - -@defopt reftex-cite-punctuation -Punctuation for formatting of name lists in citations. This is a list -of 3 strings. -@enumerate -@item -normal names separator, like @samp{, } in Jones, Brown and Miller -@item -final names separator, like @samp{ and } in Jones, Brown and Miller -@item -The @samp{et al.} string, like @samp{ @{\it et al.@}} in -Jones @{\it et al.@} -@end enumerate -@end defopt - -@deffn {Normal Hook} reftex-select-bib-mode-hook -Normal hook which is run when a selection buffer enters -@code{reftex-select-bib-mode}. -@end deffn - -@deffn Keymap reftex-select-bib-mode-map -The keymap which is active in the citation-key selection process -(@pxref{Creating Citations}). -@end deffn - -@defopt reftex-cite-key-separator -String used to separate several keys in a single @samp{\\cite} macro. -Per default this is @samp{","} but if you often have to deal with a lot -of entries and need to break the macro across several lines you might -want to change it to @samp{", "}. -@end defopt - -@defopt reftex-create-bibtex-header -Header to insert in BibTeX files generated by -@code{reftex-create-bibtex-file}. -@end defopt - -@defopt reftex-create-bibtex-footer -Footer to insert in BibTeX files generated by -@code{reftex-create-bibtex-file}. -@end defopt - - -@node Options - Index Support -@section Index Support -@cindex Options, Index support -@cindex Index support, options - -@defopt reftex-support-index -Non-@code{nil} means, index entries are parsed as well. Index support -is resource intensive and the internal structure holding the parsed -information can become quite big. Therefore it can be turned off. When -this is @code{nil} and you execute a command which requires index -support, you will be asked for confirmation to turn it on and rescan the -document. -@end defopt - -@defopt reftex-index-special-chars -List of special characters in index entries, given as strings. These -correspond to the @code{MakeIndex} keywords -@code{(@var{level} @var{encap} @var{actual} @var{quote} @var{escape})}. -@end defopt - -@defopt reftex-index-macros -List of macros which define index entries. The structure of each entry -is -@lisp -(@var{macro} @var{index-tag} @var{key} @var{prefix} @var{exclude} @var{repeat}) -@end lisp - -@var{macro} is the macro. Arguments should be denoted by empty braces, -as for example in @samp{\index[]@{*@}}. Use square brackets to denote -optional arguments. The star marks where the index key is. - -@var{index-tag} is a short name of the index. @samp{idx} and @samp{glo} -are reserved for the default index and the glossary. Other indices can -be defined as well. If this is an integer, the Nth argument of the -macro holds the index tag. - -@var{key} is a character which is used to identify the macro for input -with @code{reftex-index}. @samp{?i}, @samp{?I}, and @samp{?g} are -reserved for default index and glossary. - -@var{prefix} can be a prefix which is added to the @var{key} part of the -index entry. If you have a macro -@code{\newcommand@{\molec@}[1]@{#1\index@{Molecules!#1@}}, this prefix -should be @samp{Molecules!}. - -@var{exclude} can be a function. If this function exists and returns a -non-@code{nil} value, the index entry at point is ignored. This was -implemented to support the (deprecated) @samp{^} and @samp{_} shortcuts -in the @LaTeX{}2e @code{index} package. - -@var{repeat}, if non-@code{nil}, means the index macro does not typeset -the entry in the text, so that the text has to be repeated outside the -index macro. Needed for @code{reftex-index-selection-or-word} and for -indexing from the phrase buffer. - -The final entry may also be a symbol. It must have an association in -the variable @code{reftex-index-macros-builtin} to specify the main -indexing package you are using. Valid values are currently -@example -default @r{The @LaTeX{} default; unnecessary to specify this one} -multind @r{The multind.sty package} -index @r{The index.sty package} -index-shortcut @r{The index.sty packages with the ^ and _ shortcuts.} - @r{Should not be used; only for old documents} -@end example -Note that @AUCTeX{} sets these things internally for @RefTeX{} as well, -so with a sufficiently new version of @AUCTeX{}, you should not set the -package here. -@end defopt - -@defopt reftex-index-default-macro -The default index macro for @code{reftex-index-selection-or-word}. -This is a list with @code{(@var{macro-key} @var{default-tag})}. - -@var{macro-key} is a character identifying an index macro; see -@code{reftex-index-macros}. - -@var{default-tag} is the tag to be used if the macro requires a -@var{tag} argument. When this is @code{nil} and a @var{tag} is needed, -@RefTeX{} will ask for it. When this is the empty string and the -TAG argument of the index macro is optional, the TAG argument will be -omitted. -@end defopt - -@defopt reftex-index-default-tag -Default index tag. When working with multiple indexes, RefTeX queries -for an index tag when creating index entries or displaying a specific -index. This variable controls the default offered for these queries. -The default can be selected with @key{RET} during selection or -completion. Valid values of this variable are: -@example -nil @r{Do not provide a default index} -"tag" @r{The default index tag given as a string, e.g., "idx"} -last @r{The last used index tag will be offered as default} -@end example -@end defopt - -@defopt reftex-index-math-format -Format of index entries when copied from inside math mode. When -@code{reftex-index-selection-or-word} is executed inside @TeX{} math mode, -the index key copied from the buffer is processed with this format -string through the @code{format} function. This can be used to add the -math delimiters (e.g., @samp{$}) to the string. Requires the -@file{texmathp.el} library which is part of @AUCTeX{}. -@end defopt - -@defopt reftex-index-phrase-file-extension -File extension for the index phrase file. This extension will be added -to the base name of the master file. -@end defopt - -@defopt reftex-index-phrases-logical-and-regexp -Regexp matching the @samp{and} operator for index arguments in phrases -file. When several index arguments in a phrase line are separated by -this operator, each part will generate an index macro. So each match of -the search phrase will produce @emph{several} different index entries. -Make sure this does no match things which are not separators. This -logical @samp{and} has higher priority than the logical @samp{or} -specified in @code{reftex-index-phrases-logical-or-regexp}. -@end defopt - -@defopt reftex-index-phrases-logical-or-regexp -Regexp matching the @samp{or} operator for index arguments in phrases -file. When several index arguments in a phrase line are separated by -this operator, the user will be asked to select one of them at each -match of the search phrase. The first index arg will be the default. A -number key @kbd{1}--@kbd{9} must be pressed to switch to another. Make -sure this does no match things which are not separators. The logical -@samp{and} specified in @code{reftex-index-phrases-logical-or-regexp} -has higher priority than this logical @samp{or}. -@end defopt - -@defopt reftex-index-phrases-search-whole-words -Non-@code{nil} means phrases search will look for whole words, not subwords. -This works by requiring word boundaries at the beginning and end of -the search string. When the search phrase already has a non-word-char -at one of these points, no word boundary is required there. -@end defopt - -@defopt reftex-index-phrases-case-fold-search -Non-@code{nil} means, searching for index phrases will ignore -case. -@end defopt - -@defopt reftex-index-verify-function -A function which is called at each match during global indexing. -If the function returns @code{nil}, the current match is skipped. -@end defopt - -@defopt reftex-index-phrases-skip-indexed-matches -Non-@code{nil} means, skip matches which appear to be indexed already. -When doing global indexing from the phrases buffer, searches for some -phrases may match at places where that phrase was already indexed. In -particular when indexing an already processed document again, this -will even be the norm. When this variable is non-@code{nil}, -@RefTeX{} checks if the match is an index macro argument, or if an -index macro is directly before or after the phrase. If that is the -case, that match will be ignored. -@end defopt - -@defopt reftex-index-phrases-wrap-long-lines -Non-@code{nil} means, when indexing from the phrases buffer, wrap lines. -Inserting indexing commands in a line makes the line longer, often -so long that it does not fit onto the screen. When this variable is -non-@code{nil}, newlines will be added as necessary before and/or after the -indexing command to keep lines short. However, the matched text -phrase and its index command will always end up on a single line. -@end defopt - -@defopt reftex-index-phrases-sort-prefers-entry -Non-@code{nil} means when sorting phrase lines, the explicit index entry -is used. Phrase lines in the phrases buffer contain a search phrase, and -sorting is normally based on these. Some phrase lines also have -an explicit index argument specified. When this variable is -non-@code{nil}, the index argument will be used for sorting. -@end defopt - -@defopt reftex-index-phrases-sort-in-blocks -Non-@code{nil} means, empty and comment lines separate phrase buffer -into blocks. Sorting will then preserve blocks, so that lines are -re-arranged only within blocks. -@end defopt - -@defopt reftex-index-phrases-mode-map -Keymap for the Index Phrases buffer. -@end defopt - -@defopt reftex-index-phrases-mode-hook -Normal hook which is run when a buffer is put into -@code{reftex-index-phrases-mode}. -@end defopt - -@defopt reftex-index-section-letters -The letters which denote sections in the index. Usually these are all -capital letters. Don't use any downcase letters. Order is not -significant, the index will be sorted by whatever the sort function -thinks is correct. In addition to these letters, @RefTeX{} will -create a group @samp{!} which contains all entries sorted below the -lowest specified letter. In the @file{*Index*} buffer, pressing any of -these capital letters or @kbd{!} will jump to that section. -@end defopt - -@defopt reftex-index-include-context -Non-@code{nil} means, display the index definition context in the -@file{*Index*} buffer. This flag may also be toggled from the -@file{*Index*} buffer with the @kbd{c} key. -@end defopt - -@defopt reftex-index-follow-mode -Non-@code{nil} means, point in @file{*Index*} buffer will cause other -window to follow. The other window will show the corresponding part of -the document. This flag can be toggled from within the @file{*Index*} -buffer with the @kbd{f} key. -@end defopt - -@deffn Keymap reftex-index-mode-map -The keymap which is active in the @file{*Index*} buffer -(@pxref{Index Support}). -@end deffn - -@node Options - Viewing Cross-References -@section Viewing Cross-References -@cindex Options, viewing cross-references -@cindex Viewing cross-references, options - -@defopt reftex-view-crossref-extra -Macros which can be used for the display of cross references. -This is used when @code{reftex-view-crossref} is called with point in an -argument of a macro. Note that crossref viewing for citations, -references (both ways) and index entries is hard-coded. This variable -is only to configure additional structures for which cross-reference -viewing can be useful. Each entry has the structure -@example -(@var{macro-re} @var{search-re} @var{highlight}). -@end example -@var{macro-re} is matched against the macro. @var{search-re} is the -regexp used to search for cross references. @samp{%s} in this regexp is -replaced with the macro argument at point. @var{highlight} is an -integer indicating which subgroup of the match should be highlighted. -@end defopt - -@defopt reftex-auto-view-crossref -Non-@code{nil} means, initially turn automatic viewing of crossref info -on. Automatic viewing of crossref info normally uses the echo area. -Whenever point is idle for more than @code{reftex-idle-time} seconds on -the argument of a @code{\ref} or @code{\cite} macro, and no other -message is being displayed, the echo area will display information about -that cross reference. You can also set the variable to the symbol -@code{window}. In this case a small temporary window is used for the -display. This feature can be turned on and off from the menu -(Ref->Options). -@end defopt - -@defopt reftex-idle-time -Time (secs) Emacs has to be idle before automatic crossref display -or toc recentering is done. -@end defopt - -@defopt reftex-cite-view-format -Citation format used to display citation info in the message area. See -the variable @code{reftex-cite-format} for possible percent -escapes. -@end defopt - -@defopt reftex-revisit-to-echo -Non-@code{nil} means, automatic citation display will revisit files if -necessary. When @code{nil}, citation display in echo area will only be active -for cached echo strings (see @code{reftex-cache-cite-echo}), or for -@BibTeX{} database files which are already visited by a live associated -buffers. -@end defopt - -@defopt reftex-cache-cite-echo -Non-@code{nil} means, the information displayed in the echo area for -cite macros (see variable @code{reftex-auto-view-crossref}) is cached and -saved along with the parsing information. The cache survives document -scans. In order to clear it, use @kbd{M-x reftex-reset-mode}. -@end defopt - -@node Options - Finding Files -@section Finding Files -@cindex Options, Finding Files -@cindex Finding files, options - -@defopt reftex-texpath-environment-variables -List of specifications how to retrieve the search path for @TeX{} files. -Several entries are possible. -@itemize @minus -@item -If an element is the name of an environment variable, its content is -used. -@item -If an element starts with an exclamation mark, it is used as a command -to retrieve the path. A typical command with the kpathsearch library -would be @w{@code{"!kpsewhich -show-path=.tex"}}. -@item -Otherwise the element itself is interpreted as a path. -@end itemize -Multiple directories can be separated by the system dependent -@code{path-separator}. Directories ending in @samp{//} or @samp{!!} will -be expanded recursively. See also @code{reftex-use-external-file-finders}. -@end defopt - -@defopt reftex-bibpath-environment-variables -List of specifications how to retrieve the search path for @BibTeX{} -files. Several entries are possible. -@itemize @minus -@item -If an element is the name of an environment variable, its content is -used. -@item -If an element starts with an exclamation mark, it is used as a command -to retrieve the path. A typical command with the kpathsearch library -would be @w{@code{"!kpsewhich -show-path=.bib"}}. -@item -Otherwise the element itself is interpreted as a path. -@end itemize -Multiple directories can be separated by the system dependent -@code{path-separator}. Directories ending in @samp{//} or @samp{!!} will -be expanded recursively. See also @code{reftex-use-external-file-finders}. -@end defopt - -@defopt reftex-file-extensions -Association list with file extensions for different file types. -This is a list of items, each item is like: -@code{(@var{type} . (@var{def-ext} @var{other-ext} ...))} -@example -@var{type}: @r{File type like @code{"bib"} or @code{"tex"}.} -@var{def-ext}: @r{The default extension for that file type, like @code{".tex"} or @code{".bib"}.} -@var{other-ext}: @r{Any number of other valid extensions for this file type.} -@end example -When a files is searched and it does not have any of the valid extensions, -we try the default extension first, and then the naked file name. -@end defopt - -@defopt reftex-search-unrecursed-path-first -Non-@code{nil} means, search all specified directories before trying -recursion. Thus, in a path @samp{.//:/tex/}, search first @samp{./}, -then @samp{/tex/}, and then all subdirectories of @samp{./}. If this -option is @code{nil}, the subdirectories of @samp{./} are searched -before @samp{/tex/}. This is mainly for speed; most of the time the -recursive path is for the system files and not for the user files. Set -this to @code{nil} if the default makes @RefTeX{} finding files with -equal names in wrong sequence. -@end defopt - -@defopt reftex-use-external-file-finders -Non-@code{nil} means, use external programs to find files. Normally, -@RefTeX{} searches the paths given in the environment variables -@code{TEXINPUTS} and @code{BIBINPUTS} to find @TeX{} files and @BibTeX{} -database files. With this option turned on, it calls an external -program specified in the option @code{reftex-external-file-finders} -instead. As a side effect, the variables -@code{reftex-texpath-environment-variables} and -@code{reftex-bibpath-environment-variables} will be ignored. -@end defopt - -@defopt reftex-external-file-finders -Association list with external programs to call for finding files. Each -entry is a cons cell @w{@code{(@var{type} . @var{program})}}. -@var{type} is either @code{"tex"} or @code{"bib"}. @var{program} is a -string containing the external program to use with any arguments. -@code{%f} will be replaced by the name of the file to be found. Note -that these commands will be executed directly, not via a shell. Only -relevant when @code{reftex-use-external-file-finders} is -non-@code{nil}. -@end defopt - -@page -@node Options - Optimizations -@section Optimizations -@cindex Options, optimizations -@cindex Optimizations, options - -@defopt reftex-keep-temporary-buffers -Non-@code{nil} means, keep buffers created for parsing and lookup. -@RefTeX{} sometimes needs to visit files related to the current -document. We distinguish files visited for -@table @asis -@item PARSING -Parts of a multifile document loaded when (re)-parsing the -document. -@item LOOKUP -@BibTeX{} database files and @TeX{} files loaded to find a reference, to -display label context, etc. -@end table -The created buffers can be kept for later use, or be thrown away -immediately after use, depending on the value of this variable: - -@table @code -@item nil -Throw away as much as possible. -@item t -Keep everything. -@item 1 -Throw away buffers created for parsing, but keep the ones created for -lookup. -@end table - -If a buffer is to be kept, the file is visited normally (which is -potentially slow but will happen only once). If a buffer is to be thrown -away, the initialization of the buffer depends upon the variable -@code{reftex-initialize-temporary-buffers}. -@end defopt - -@defopt reftex-initialize-temporary-buffers -Non-@code{nil} means do initializations even when visiting file -temporarily. When @code{nil}, @RefTeX{} may turn off find-file hooks and -other stuff to briefly visit a file. When @code{t}, the full default -initializations are done (@code{find-file-hook} etc.). Instead of -@code{t} or @code{nil}, this variable may also be a list of hook -functions to do a minimal initialization. -@end defopt - -@defopt reftex-no-include-regexps -List of regular expressions to exclude certain input files from parsing. -If the name of a file included via @code{\include} or @code{\input} is -matched by any of the regular expressions in this list, that file is not -parsed by @RefTeX{}. -@end defopt - -@defopt reftex-enable-partial-scans -Non-@code{nil} means, re-parse only 1 file when asked to re-parse. -Re-parsing is normally requested with a @kbd{C-u} prefix to many @RefTeX{} -commands, or with the @kbd{r} key in menus. When this option is -@code{t} in a multifile document, we will only parse the current buffer, -or the file associated with the label or section heading near point in a -menu. Requesting re-parsing of an entire multifile document then -requires a @kbd{C-u C-u} prefix or the capital @kbd{R} key in -menus. -@end defopt - -@defopt reftex-save-parse-info -Non-@code{nil} means, save information gathered with parsing in files. -The file @file{MASTER.rel} in the same directory as @file{MASTER.tex} is -used to save the information. When this variable is @code{t}, -@itemize @minus -@item -accessing the parsing information for the first time in an editing -session will read that file (if available) instead of parsing the -document. -@item -exiting Emacs or killing a buffer in reftex-mode will cause a new -version of the file to be written. -@end itemize -@end defopt - -@defopt reftex-parse-file-extension -File extension for the file in which parser information is stored. -This extension is added to the base name of the master file. -@end defopt - -@defopt reftex-allow-automatic-rescan -Non-@code{nil} means, @RefTeX{} may rescan the document when this seems -necessary. Applies (currently) only in rare cases, when a new label -cannot be placed with certainty into the internal label list. -@end defopt - -@defopt reftex-use-multiple-selection-buffers -Non-@code{nil} means use a separate selection buffer for each label -type. These buffers are kept from one selection to the next and need -not be created for each use, so the menu generally comes up faster. -The selection buffers will be erased (and therefore updated) -automatically when new labels in its category are added. See the -variable @code{reftex-auto-update-selection-buffers}. -@end defopt - -@defopt reftex-auto-update-selection-buffers -Non-@code{nil} means, selection buffers will be updated automatically. -When a new label is defined with @code{reftex-label}, all selection -buffers associated with that label category are emptied, in order to -force an update upon next use. When @code{nil}, the buffers are left -alone and have to be updated by hand, with the @kbd{g} key from the -label selection process. The value of this variable will only have any -effect when @code{reftex-use-multiple-selection-buffers} is -non-@code{nil}. -@end defopt - -@node Options - Fontification -@section Fontification -@cindex Options, fontification -@cindex Fontification, options - -@defopt reftex-use-fonts -Non-@code{nil} means, use fonts in label menu and on-the-fly help. -Font-lock must be loaded as well to actually get fontified -display. After changing this option, a rescan may be necessary to -activate it. -@end defopt - -@defopt reftex-refontify-context -Non-@code{nil} means, re-fontify the context in the label menu with -font-lock. This slightly slows down the creation of the label menu. It -is only necessary when you definitely want the context fontified. - -This option may have 3 different values: -@table @code -@item nil -Never refontify. -@item t -Always refontify. -@item 1 -Refontify when necessary, e.g., with old versions of the x-symbol -package. -@end table -The option is ignored when @code{reftex-use-fonts} is @code{nil}. -@end defopt - -@defopt reftex-highlight-selection -Non-@code{nil} means, highlight selected text in selection and -@file{*toc*} buffers. Normally, the text near the cursor is the -@emph{selected} text, and it is highlighted. This is the entry most -keys in the selection and @file{*toc*} buffers act on. However, if you -mainly use the mouse to select an item, you may find it nice to have -mouse-triggered highlighting @emph{instead} or @emph{as well}. The -variable may have one of these values: - -@example -nil @r{No highlighting.} -cursor @r{Highlighting is cursor driven.} -mouse @r{Highlighting is mouse driven.} -both @r{Both cursor and mouse trigger highlighting.} -@end example - -Changing this variable requires rebuilding the selection and *toc* -buffers to become effective (keys @kbd{g} or @kbd{r}). -@end defopt - -@defopt reftex-cursor-selected-face -Face name to highlight cursor selected item in toc and selection buffers. -See also the variable @code{reftex-highlight-selection}. -@end defopt -@defopt reftex-mouse-selected-face -Face name to highlight mouse selected item in toc and selection buffers. -See also the variable @code{reftex-highlight-selection}. -@end defopt -@defopt reftex-file-boundary-face -Face name for file boundaries in selection buffer. -@end defopt -@defopt reftex-label-face -Face name for labels in selection buffer. -@end defopt -@defopt reftex-section-heading-face -Face name for section headings in toc and selection buffers. -@end defopt -@defopt reftex-toc-header-face -Face name for the header of a toc buffer. -@end defopt -@defopt reftex-bib-author-face -Face name for author names in bib selection buffer. -@end defopt -@defopt reftex-bib-year-face -Face name for year in bib selection buffer. -@end defopt -@defopt reftex-bib-title-face -Face name for article title in bib selection buffer. -@end defopt -@defopt reftex-bib-extra-face -Face name for bibliographic information in bib selection buffer. -@end defopt -@defopt reftex-select-mark-face -Face name for marked entries in the selection buffers. -@end defopt -@defopt reftex-index-header-face -Face name for the header of an index buffer. -@end defopt -@defopt reftex-index-section-face -Face name for the start of a new letter section in the index. -@end defopt -@defopt reftex-index-tag-face -Face name for index names (for multiple indices). -@end defopt -@defopt reftex-index-face -Face name for index entries. -@end defopt - -@node Options - Misc -@section Miscellaneous -@cindex Options, misc - -@defopt reftex-extra-bindings -Non-@code{nil} means, make additional key bindings on startup. These -extra bindings are located in the users @samp{C-c letter} -map. @xref{Key Bindings}. -@end defopt - -@defopt reftex-plug-into-AUCTeX -Plug-in flags for @AUCTeX{} interface. This variable is a list of -5 boolean flags. When a flag is non-@code{nil}, @RefTeX{} -will - -@example -- supply labels in new sections and environments (flag 1) -- supply arguments for macros like @code{\label} (flag 2) -- supply arguments for macros like @code{\ref} (flag 3) -- supply arguments for macros like @code{\cite} (flag 4) -- supply arguments for macros like @code{\index} (flag 5) -@end example - -You may also set the variable itself to @code{t} or @code{nil} in -order to turn all options on or off, respectively.@* -Supplying labels in new sections and environments applies when creating -sections with @kbd{C-c C-s} and environments with @kbd{C-c C-e}.@* -Supplying macro arguments applies when you insert such a macro -interactively with @kbd{C-c @key{RET}}.@* -See the @AUCTeX{} documentation for more information. -@end defopt - -@defopt reftex-revisit-to-follow -Non-@code{nil} means, follow-mode will revisit files if necessary. -When @code{nil}, follow-mode will be suspended for stuff in unvisited files. -@end defopt - -@defopt reftex-allow-detached-macro-args -Non-@code{nil} means, allow arguments of macros to be detached by -whitespace. When this is @code{t}, the @samp{aaa} in @w{@samp{\bbb -[xxx] @{aaa@}}} will be considered an argument of @code{\bb}. Note that -this will be the case even if @code{\bb} is defined with zero or one -argument. -@end defopt - -@node Keymaps and Hooks -@section Keymaps and Hooks -@cindex Keymaps - -@RefTeX{} has the usual general keymap, load hook and mode hook. - -@deffn Keymap reftex-mode-map -The keymap for @RefTeX{} mode. -@end deffn - -@deffn {Normal Hook} reftex-mode-hook -Normal hook which is being run when turning on @RefTeX{} mode. -@end deffn - -Furthermore, the four modes used for referencing labels, creating -citations, the table of contents buffer and the phrases buffer have -their own keymaps and mode hooks. See the respective sections. There -are many more hooks which are described in the relevant sections about -options for a specific part of @RefTeX{}. - -@node Changes -@chapter Changes -@cindex Changes - -Here is a list of recent changes to @RefTeX{}. - -@noindent @b{Version 4.33} - -@itemize @bullet -@item -Update to GPLv3. -@item -Parse files are created in a way that does not interfere with recentf -mode. -@end itemize - -@noindent @b{Version 4.32} - -@itemize @bullet -@item -First release by @AUCTeX{} project. -@item -Installation routine rewritten after structure of source package -changed. -@item -Activation of @RefTeX{} changed, so make sure you read the installation -instructions and remove obsolete cruft related to @RefTeX{} from your -init file. -@item -Fixed bug where point would end up in the wrong buffer when jumping -between several @LaTeX{} and phrases buffers. -@item -Fixed bug where @BibTeX{} keys with hyphens were parsed incorrectly. -@item -Some performance improvements. -@item -The separator used between multiple citations in a \cite macro can now -be changed by customizing the variable @code{reftex-cite-key-separator}. -@end itemize - -@noindent @b{Version 4.28} -@itemize @bullet -@item Support for the Jurabib package. -@item Improvements when selecting several items in a selection buffer. -@end itemize - -@noindent @b{Version 4.26} -@itemize @bullet -@item -Support for global incremental search. -@item -Some improvements for XEmacs compatibility. -@end itemize - -@noindent @b{Version 4.25} -@itemize @bullet -@item -Fixed bug with @samp{%F} in a label prefix. Added new escapes -@samp{%m} and @samp{%M} for master file name and master directory. -@end itemize - -@noindent @b{Version 4.24} -@itemize @bullet -@item -Inserting citation commands now prompts for optional arguments -when called with a prefix argument. Related new options are -@code{reftex-cite-prompt-optional-args} and -@code{reftex-cite-cleanup-optional-args}. -@item -New option @code{reftex-trust-label-prefix}. Configure this variable -if you'd like RefTeX to base its classification of labels on prefixes. -This can speed-up document parsing, but may in some cases reduce the -quality of the context used by RefTeX to describe a label. -@item -Fixed bug in @code{reftex-create-bibtex-file} when -@code{reftex-comment-citations} is non-@code{nil}. -@item -Fixed bugs in indexing: Case-sensitive search, quotes before and/or -after words. Disabled indexing in comment lines. -@end itemize - -@noindent @b{Version 4.22} -@itemize @bullet -@item -New command @code{reftex-create-bibtex-file} to create a new database -with all entries referenced in the current document. -@item -New keys @kbd{e} and @kbd{E} allow you to produce a BibTeX database -file from entries marked in a citation selection buffer. -@end itemize - -@noindent @b{Version 4.21} -@itemize @bullet -@item -Renaming labels from the toc buffer with key @kbd{M-%}. -@end itemize - -@noindent @b{Version 4.20} -@itemize @bullet -@item -Structure editing capabilities. The command keys @kbd{<} and @kbd{>} in -the TOC buffer promote/demote the section at point or all sections in -the current region. -@item -New option @code{reftex-toc-split-windows-fraction} to set the size of -the window used by the TOC@. This makes the old variable -@code{reftex-toc-split-windows-horizontally-fraction} obsolete. -@item -A dedicated frame can show the TOC with the current section -always automatically highlighted. The frame is created and -deleted from the toc buffer with the @kbd{d} key. -@end itemize - -@noindent @b{Version 4.19} -@itemize @bullet -@item -New command @code{reftex-toc-recenter} (@kbd{C-c -}) which shows the current -section in the TOC buffer without selecting the TOC window. -@item -Recentering happens automatically in idle time when the option -@code{reftex-auto-recenter-toc} is turned on. -@item -Fixed several bugs related to automatic cursor positioning in the TOC -buffer. -@item -The highlight in the TOC buffer stays when the focus moves to a -different window. -@item -New command @code{reftex-goto-label}. -@item -Part numbers are no longer included in chapter numbers, and a new -part does not reset the chapter counter. See new option -@code{reftex-part-resets-chapter}. -@end itemize - -@noindent @b{Version 4.18} -@itemize @bullet -@item -@code{reftex-citation} uses the word before the cursor as a default -search string. -@item -Simplified several regular expressions for speed. -@item -Better support for chapterbib. -@end itemize - -@noindent @b{Version 4.17} -@itemize @bullet -@item -The toc window can be split off horizontally. See new options -@code{reftex-toc-split-windows-horizontally}, -@code{reftex-toc-split-windows-horizontally-fraction}. -@item -It is possible to specify a function which verifies an index match -during global indexing. See new option @code{reftex-index-verify-function}. -@item -The macros which input a file in LaTeX (like \input, \include) can -be configured. See new option @code{reftex-include-file-commands}. -@item -The macros which specify the bibliography file (like \bibliography) can -be configured. See new option @code{reftex-bibliography-commands}. -@item -The regular expression used to search for the \bibliography macro has -been relaxed to allow for @samp{@{\bibliography@{...@}@}} needed by -chapterbib. -@item -Small bug fixes. -@end itemize - -@noindent @b{Version 4.15} -@itemize @bullet -@item -Fixed bug with parsing of BibTeX files, when fields contain quotes or -unmatched parenthesis. -@item -Small bug fixes. -@item -Improved interaction with Emacs LaTeX mode. -@end itemize - -@noindent @b{Version 4.12} -@itemize @bullet -@item -Support for @file{bibentry} citation style. -@end itemize - -@noindent @b{Version 4.11} -@itemize @bullet -@item -Fixed bug which would parse @samp{\Section} just like @samp{\section}. -@end itemize - -@noindent @b{Version 4.10} -@itemize @bullet -@item -Renamed @file{reftex-vcr.el} to @file{reftex-dcr.el} because of conflict -with @file{reftex-vars.el} on DOS machines. -@item -New options @code{reftex-parse-file-extension} and -@code{reftex-index-phrase-file-extension}. -@end itemize - -@noindent [.....] -@ignore -@noindent @b{Version 4.09} -@itemize @bullet -@item -New option @code{reftex-toc-max-level} to limit the depth of the toc. -New key binding @kbd{t} in the @file{*toc*} buffer to change this -setting. -@item -RefTeX maintains an @file{Index Phrases} file in which phrases can be -collected. When the document is ready, RefTeX can search all -these phrases and assist indexing all matches. -@item -The variables @code{reftex-index-macros} and -@code{reftex-index-default-macro} have changed their syntax slightly. -The @var{repeat} parameter has move from the latter to the former. -Also calls to @code{reftex-add-index-macros} from AUCTeX style files -need to be adapted. -@item -The variable @code{reftex-section-levels} no longer contains the -default stuff which has been moved to a constant. -@item -Environments like theorems can be placed into the TOC by putting -entries for @samp{"begin@{theorem@}"} in -@code{reftex-section-levels}. -@end itemize - -@noindent @b{Version 4.06} -@itemize @bullet -@item -@code{reftex-section-levels} can contain a function to compute the level -of a sectioning command. -@item -Multiple @code{thebibliography} environments recognized. -@end itemize - -@noindent @b{Version 4.04} -@itemize @bullet -@item -New option @code{reftex-index-default-tag} implements a default for queries. -@end itemize - -@noindent @b{Version 4.02} -@itemize @bullet -@item -macros ending in @samp{refrange} are considered to contain references. -@item -Index entries made with @code{reftex-index-selection-or-word} in TeX -math mode automatically get enclosing @samp{$} to preserve math mode. See -new option @code{reftex-index-math-format}. Requires AUCTeX. -@end itemize - -@noindent @b{Version 4.01} -@itemize @bullet -@item -New command @code{reftex-index-globally} to index a word in many -places in the document. Also available from the index buffer with -@kbd{&}. -@item -The first item in a @code{reftex-label-alist} entry may now also be a parser -function to do non-standard parsing. -@item -@code{reftex-auto-view-crossref} no longer interferes with -@code{pop-up-frames} (patch from Stefan Monnier). -@end itemize - -@noindent @b{Version 4.00} -@itemize @bullet -@item -RefTeX has been split into several smaller files which are autoloaded on -demand. -@item -Index support, along with many new options. -@item -The selection of keys for @code{\ref} and @code{\cite} now allows you -to select multiple items by marking entries with the @kbd{m} key. -@item -Fancyref support. -@end itemize - -@noindent @b{Version 3.43} -@itemize @bullet -@item -Viewing cross-references generalized. Now works on @code{\label}, -@code{\ref}, @code{\cite}, @code{\bibitem}, @code{\index}, variations of -these, and from BibTeX buffers. -@item -New option @code{reftex-view-crossref-extra}. -@item -Support for the additional sectioning commands @code{\addchap} and -@code{\addsec} which are defined in the LaTeX KOMA-Script classes. -@item -Files in @code{reftex-default-bibliography} will be searched along -@code{BIBINPUTS} path. -@item -Reading a parse file now checks consistency. -@end itemize - -@noindent @b{Version 3.42} -@itemize @bullet -@item -File search further refined. New option @code{reftex-file-extensions}. -@item -@file{*toc*} buffer can show the file boundaries of a multifile -document, all labels and associated context. New keys @kbd{i}, @kbd{l}, -and @kbd{c}. New options @code{reftex-toc-include-labels}, -@code{reftex-toc-include-context}, -@code{reftex-toc-include-file-boundaries}. -@end itemize - -@noindent @b{Version 3.41} -@itemize @bullet -@item -New options @code{reftex-texpath-environment-variables}, -@code{reftex-use-external-file-finders}, -@code{reftex-external-file-finders}, -@code{reftex-search-unrecursed-path-first}. -@item -@emph{kpathsearch} support. See new options and -@code{reftex-bibpath-environment-variables}. -@end itemize - -@noindent @b{Version 3.38} -@itemize @bullet -@item -@code{reftex-view-crossref} no longer moves to find a macro. Point has -to be on the macro argument. -@end itemize - -@noindent @b{Version 3.36} -@itemize @bullet -@item -New value @code{window} for option @code{reftex-auto-view-crossref}. -@end itemize - -@noindent @b{Version 3.35} -@itemize @bullet -@item -ISO 8859 Latin-1 chars are converted to ASCII to derive better labels. -This takes back the related changes in 3.34 for safety reasons. -@end itemize - -@noindent @b{Version 3.34} -@itemize @bullet -@item -Additional flag in @code{reftex-derive-label-parameters} do make only -lowercase labels (default @code{t}). -@item -All @file{.rel} files have a final newline to avoid queries. -@item -Single byte representations of accented European letters (ISO-8859-1) -are now valid in labels. -@end itemize - -@noindent @b{Version 3.33} -@itemize @bullet -@item -Multiple selection buffers are now hidden buffers (they start with a -SPACE). -@item -Fixed bug with file search when TEXINPUTS environment variable is empty. -@end itemize - -@noindent @b{Version 3.30} -@itemize @bullet -@item -In @code{reftex-citation}, the regular expression used to scan BibTeX -files can be specified using completion on known citation keys. -@item -New keys @kbd{a} and @kbd{A} in BibTeX selection process to cite @emph{all} -entries. -@item -New command @code{reftex-renumber-simple-labels} to renumber simple -labels like @samp{eq:13} sequentially through a document. -@end itemize - -@noindent @b{Version 3.28} -@itemize @bullet -@item -Auto view crossref for XEmacs uses @code{post-command-hook} to restart the -timer, since itimer restart is not reliable. -@item -Option @code{reftex-bibfile-ignore-list} renamed to @code{-regexps}. -@item -Expansion of recursive tex and bib path rewritten. -@item -Fixed problem where @RefTeX{} did not scan unsaved buffers. -@item -Fixed bug with section numbering after *-red sections. -@end itemize - -@noindent @b{Version 3.27} -@itemize @bullet -@item -Macros can define @emph{neutral} labels, just like @code{\label} -itself. -@item -New option @code{reftex-allow-detached-macro-args}, default @code{nil}! -@end itemize - -@noindent @b{Version 3.26} -@itemize @bullet -@item -[X]Emacs 19 no longer supported. Use 3.22 for Emacs 19. -@item -New hooks @code{reftex-translate-to-ascii-function}, -@code{reftex-string-to-label-function}. -@item -Made sure automatic crossref display will not visit/scan files. -@end itemize - -@noindent @b{Version 3.25} -@itemize @bullet -@item -Echoing of citation info caches the info for displayed entries. -New option @code{reftex-cache-cite-echo}. -@item -@kbd{M-x reftex-reset-mode} now also removes the file with parsing -info. -@item -Default of @code{reftex-revisit-to-follow} changed to @code{nil}. -@end itemize - -@noindent @b{Version 3.24} -@itemize @bullet -@item -New option @code{reftex-revisit-to-echo}. -@item -Interface with X-Symbol (>=2.6) is now complete and stable. -@item -Adapted to new outline, which uses overlays. -@item -File names in @code{\bibliography} may now have the @code{.bib} -extension. -@item -Fixed Bug with parsing "single file" from master file buffer. -@end itemize - -@noindent @b{Version 3.23} -@itemize @bullet -@item -Parse files @file{MASTER.rel} made compatible between Emacs and XEmacs. -@item -@code{kill-emacs-hook} and @code{kill-buffer-hook} now write the parse -file. -@item -The cursor inside a @code{\ref} or @code{\cite} macro can now trigger -automatic display of crossref information in the echo area. See -variable @code{reftex-auto-view-crossref}. -@item -AUCTeX interface updates: -@itemize @minus -@item -AUCTeX 9.9c and later notifies @RefTeX{} about new sections. -@item -@RefTeX{} notifies AUCTeX about new labels. -@item -@code{TeX-arg-ref} no longer used (introduction was unnecessary). -@item -@code{reftex-arg-label} and @code{reftex-arg-cite} fixed up. -@item -Settings added to @RefTeX{} via style files remain local. -@end itemize -@item -Fixed bug with @code{reftex-citation} in non-latex buffers. -@item -Fixed bug with syntax table and context refontification. -@item -Safety-net for name change of @code{font-lock-reference-face}. -@end itemize - -@noindent @b{Version 3.22} -@itemize @bullet -@item -Fixed bug with empty context strings. -@item -@code{reftex-mouse-view-crossref} is now bound by default at -@kbd{S-mouse-2}. -@end itemize - -@noindent @b{Version 3.21} -@itemize @bullet -@item -New options for all faces used by @RefTeX{}. They're in the -customization group @code{reftex-fontification-configurations}. -@end itemize - -@noindent @b{Version 3.19} -@itemize @bullet -@item -Fixed bug with AUCTeX @code{TeX-master}. -@end itemize - -@noindent @b{Version 3.18} -@itemize @bullet -@item -The selection now uses a recursive edit, much like minibuffer input. -This removes all restrictions during selection. E.g., you can now -switch buffers at will, use the mouse etc. -@item -New option @code{reftex-highlight-selection}. -@item -@kbd{mouse-2} can be used to select in selection and @file{*toc*} -buffers. -@item -Fixed some problems regarding the interaction with VIPER mode. -@item -Follow-mode is now only used after point motion. -@item -@RefTeX{} now finally does not fontify temporary files anymore. -@end itemize - -@noindent @b{Version 3.17} -@itemize @bullet -@item -Additional bindings in selection and @file{*toc*} buffers. @kbd{g} -redefined. -@item -New command @code{reftex-save-all-document-buffers}. -@item -Magic word matching made more intelligent. -@item -Selection process can switch to completion (with @key{TAB}). -@item -@code{\appendix} is now recognized and influences section numbering. -@item -File commentary shortened considerably (use Info documentation). -@item -New option @code{reftex-no-include-regexps} to skip some include files. -@item -New option @code{reftex-revisit-to-follow}. -@end itemize - -@noindent @b{Version 3.16} -@itemize @bullet -@item -New hooks @code{reftex-format-label-function}, -@code{reftex-format-ref-function}, @code{reftex-format-cite-function}. -@item -TeXInfo documentation completed. -@item -Some restrictions in Label inserting and referencing removed. -@item -New variable @code{reftex-default-bibliography}. -@end itemize - -@noindent @b{Version 3.14} -@itemize @bullet -@item -Selection buffers can be kept between selections: this is faster. -See new variable @code{reftex-use-multiple-selection-buffers}. -@item -Prefix interpretation of reftex-view-crossref changed. -@item -Support for the @code{varioref} package (@kbd{v} key in selection -buffer). -@end itemize - -@noindent @b{Version 3.12} -@itemize @bullet -@item -There are 3 new keymaps for customization: @code{reftex-toc-mode-map}, -@code{reftex-select-label-mode-map}, @code{reftex-select-bib-mode-map}. -@item -Refontification uses more standard font-lock stuff. -@item -When no BibTeX database files are specified, citations can also use -@code{\bibitem} entries from a @code{thebibliography} environment. -@end itemize - -@noindent @b{Version 3.11} -@itemize @bullet -@item -Fixed bug which led to naked label in (e.g.)@: footnotes. -@item -Added scroll-other-window functions to RefTeX-Select. -@end itemize - -@noindent @b{Version 3.10} -@itemize @bullet -@item -Fixed a bug which made reftex 3.07 fail on [X]Emacs version 19. -@item -Removed unimportant code which caused OS/2 Emacs to crash. -@item -All customization variables now accessible from menu. -@end itemize - -@noindent @b{Version 3.07} -@itemize @bullet -@item -@code{Ref} menu improved. -@end itemize - -@noindent @b{Version 3.05} -@itemize @bullet -@item -Compatibility code now first checks for XEmacs feature. -@end itemize - -@noindent @b{Version 3.04} -@itemize @bullet -@item -Fixed BUG in the @emph{xr} support. -@end itemize - -@noindent @b{Version 3.03} -@itemize @bullet -@item -Support for the LaTeX package @code{xr}, for inter-document -references. -@item -A few (minor) Mule-related changes. -@item -Fixed bug which could cause @emph{huge} @file{.rel} files. -@item -Search for input and @file{.bib} files with recursive path definitions. -@end itemize - -@noindent @b{Version 3.00} -@itemize @bullet -@item -@RefTeX{} should work better for very large projects: -@item -The new parser works without creating a master buffer. -@item -Rescanning can be limited to a part of a multifile document. -@item -Information from the parser can be stored in a file. -@item -@RefTeX{} can deal with macros having a naked label as an argument. -@item -Macros may have white space and newlines between arguments. -@item -Multiple identical section headings no longer confuse -@code{reftex-toc}. -@item -@RefTeX{} should work correctly in combination with buffer-altering -packages like outline, folding, x-symbol, iso-cvt, isotex, etc. -@item -All labeled environments discussed in @emph{The LaTeX Companion} by -Goossens, Mittelbach & Samarin, Addison-Wesley 1994) are part of -@RefTeX{}'s defaults. -@end itemize - -@noindent @b{Version 2.17} -@itemize @bullet -@item -Label prefix expands % escapes with current file name and other stuff. -@item -Citation format now with % escapes. This is not backward -compatible! -@item -TEXINPUTS variable recognized when looking for input files. -@item -Context can be the nth argument of a macro. -@item -Searching in the select buffer is now possible (@kbd{C-s} and -@kbd{C-r}). -@item -Display and derive-label can use two different context methods. -@item -AMSmath @code{xalignat} and @code{xxalignat} added. -@end itemize - -@noindent @b{Version 2.14} -@itemize @bullet -@item -Variable @code{reftex-plug-into-AUCTeX} simplifies cooperation with -AUCTeX. -@end itemize - -@noindent @b{Version 2.11} -@itemize @bullet -@item -Submitted for inclusion to Emacs and XEmacs. -@end itemize - -@noindent @b{Version 2.07} -@itemize @bullet -@item -New functions @code{reftex-search-document}, -@code{reftex-query-replace-document}. -@end itemize - -@noindent @b{Version 2.05} -@itemize @bullet -@item -Support for @file{custom.el}. -@item -New function @code{reftex-grep-document} (thanks to Stephen Eglen). -@end itemize - -@noindent @b{Version 2.03} -@itemize @bullet -@item -@code{figure*}, @code{table*}, @code{sidewaysfigure/table} added to -default environments. -@item -@code{reftex-bibfile-ignore-list} introduced (thanks to Rory Molinari). -@item -New functions @code{reftex-arg-label}, @code{reftex-arg-ref}, -@code{reftex-arg-cite}. -@item -Emacs/XEmacs compatibility reworked. XEmacs 19.15 now is -required. -@item -@code{reftex-add-to-label-alist} (to be called from AUCTeX style -files). -@item -Finding context with a hook function. -@item -Sorting BibTeX entries (new variable: -@code{reftex-sort-bibtex-matches}). -@end itemize - -@noindent @b{Version 2.00} -@itemize @bullet -@item -Labels can be derived from context (default for sections). -@item -Configuration of label insertion and label referencing revised. -@item -Crossref fields in BibTeX database entries. -@item -@code{reftex-toc} introduced (thanks to Stephen Eglen). -@end itemize - -@noindent @b{Version 1.09} -@itemize @bullet -@item -Support for @code{tex-main-file}, an analogue for -@code{TeX-master}. -@item -MS-DOS support. -@end itemize - -@noindent @b{Version 1.07} -@itemize @bullet -@item -@RefTeX{} gets its own menu. -@end itemize - -@noindent @b{Version 1.05} -@itemize @bullet -@item -XEmacs port. -@end itemize - -@noindent @b{Version 1.04} -@itemize @bullet -@item -Macros as wrappers, AMSTeX support, delayed context parsing for -new labels. -@end itemize -@end ignore - -@noindent @b{Version 1.00} -@itemize @bullet -@item -released on 7 Jan 1997. -@end itemize - -@node GNU Free Documentation License -@appendix GNU Free Documentation License -@include doclicense.texi - -@node Index -@unnumbered Index -@printindex cp - -@bye diff --git a/lisp/align.el b/lisp/align.el index 2f1c932f9ba..1b62c950f36 100644 --- a/lisp/align.el +++ b/lisp/align.el @@ -186,11 +186,6 @@ If nil, then no messages will ever be printed to the minibuffer." "A list of modes whose syntax resembles Lisp." :type '(repeat symbol)) -(defcustom align-tex-modes - '(tex-mode plain-tex-mode latex-mode slitex-mode) - "A list of modes whose syntax resembles TeX (and family)." - :type '(repeat symbol)) - (defcustom align-text-modes '(text-mode outline-mode) "A list of modes whose content is plain text." :type '(repeat symbol)) @@ -509,33 +504,12 @@ The possible settings for `align-region-separate' are: (regexp . "\\(\\s-*\\)\\\\$") (modes . '(python-base-mode makefile-mode))) - (tex-record-separator - (regexp . ,(lambda (end reverse) - (align-match-tex-pattern "&" end reverse))) - (group . (1 2)) - (modes . align-tex-modes) - (repeat . t)) - - (tex-tabbing-separator - (regexp . ,(lambda (end reverse) - (align-match-tex-pattern "\\\\[=>]" end reverse))) - (group . (1 2)) - (modes . '(latex-mode)) - (repeat . t)) - - (tex-record-break - (regexp . "\\(\\s-*\\)\\\\\\\\") - (modes . align-tex-modes)) - - ;; Align space delimited text as columns. (text-column (regexp . "\\(^\\|\\S-\\)\\([ \t]+\\)\\(\\S-\\|$\\)") (group . 2) (modes . align-text-modes) (repeat . t) - (run-if . ,(lambda () - (and (not (eq '- current-prefix-arg)) - (not (derived-mode-p align-tex-modes)))))) + (run-if . ,(lambda () (not (eq '- current-prefix-arg))))) ;; With a negative prefix argument, lists of dollar figures will ;; be aligned. @@ -1017,28 +991,6 @@ indented." ;;; Internal Functions: -(defun align-match-tex-pattern (regexp end &optional reverse) - "Match REGEXP in TeX mode, counting backslashes appropriately. -END denotes the end of the region to be searched, while REVERSE, if -non-nil, indicates that the search should proceed backward from the -current position." - (let (result) - (while - (and (setq result - (funcall - (if reverse 're-search-backward - 're-search-forward) - (concat "\\(\\s-*\\)" regexp - "\\(\\s-*\\)") end t)) - (let ((pos (match-end 1)) - (count 0)) - (while (and (> pos (point-min)) - (eq (char-before pos) ?\\)) - (setq count (1+ count) pos (1- pos))) - (oddp count)) - (goto-char (match-beginning (if reverse 1 2))))) - result)) - (defun align-new-section-p (beg end separator) "Is there a section divider between BEG and END? SEPARATOR specifies how to look for the section divider. See the diff --git a/lisp/calendar/cal-tex.el b/lisp/calendar/cal-tex.el deleted file mode 100644 index f5bdfb970cc..00000000000 --- a/lisp/calendar/cal-tex.el +++ /dev/null @@ -1,1891 +0,0 @@ -;;; cal-tex.el --- calendar functions for printing calendars with LaTeX -*- lexical-binding: t; -*- - -;; Copyright (C) 1995, 2001-2025 Free Software Foundation, Inc. - -;; Author: Steve Fisk -;; Edward M. Reingold -;; Maintainer: emacs-devel@gnu.org -;; Keywords: calendar -;; Human-Keywords: Calendar, LaTeX -;; Package: calendar - -;; 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 . - -;;; Commentary: - -;; This collection of functions implements the creation of LaTeX calendars -;; based on the user's holiday choices and diary file. - -;; The user commands are: -;; cal-tex-cursor-year -;; cal-tex-cursor-year-landscape -;; cal-tex-cursor-filofax-year -;; cal-tex-cursor-month-landscape -;; cal-tex-cursor-month -;; cal-tex-cursor-week -;; cal-tex-cursor-week2 -;; cal-tex-cursor-week2-summary -;; cal-tex-cursor-week-iso -;; cal-tex-cursor-week-monday -;; cal-tex-cursor-filofax-2week -;; cal-tex-cursor-filofax-week -;; cal-tex-cursor-filofax-daily -;; cal-tex-cursor-day - -;; TO DO -;; -;; (*) Add holidays and diary entries to daily calendar. -;; -;; (*) Add diary entries to weekly calendar functions. -;; -;; (*) Make calendar styles for A4 paper. -;; -;; (*) Make monthly styles Filofax paper. - -;;; Code: - -(require 'calendar) - -;;; -;;; Customizable variables -;;; - -(defgroup calendar-tex nil - "Options for printing calendar with LaTeX." - :prefix "cal-tex-" - :group 'calendar) - -(defcustom cal-tex-which-days '(0 1 2 3 4 5 6) - "The days of the week that are displayed on the portrait monthly calendar. -Sunday is 0, Monday is 1, and so on. The default is to print from Sunday to -Saturday. For example, (1 3 5) prints only Monday, Wednesday, Friday." - :type '(repeat integer) - :group 'calendar-tex) - -(defcustom cal-tex-holidays t - "Non-nil means holidays are printed in the LaTeX calendars that support it. -Setting this to nil may speed up calendar generation." - :type 'boolean - :group 'calendar-tex) - -(defcustom cal-tex-diary nil - "Non-nil means diary entries are printed in LaTeX calendars that support it. -Setting this to nil may speed up calendar generation." - :type 'boolean - :group 'calendar-tex) - -(defcustom cal-tex-rules nil - "Non-nil means pages will be ruled in some LaTeX calendar styles. -At present, this only affects the daily filofax calendar." - :type 'boolean - :group 'calendar-tex) - -(defcustom cal-tex-daily-string - '(let* ((year (calendar-extract-year date)) - (day (calendar-day-number date)) - (days-remaining (- (calendar-day-number (list 12 31 year)) day))) - (format "%d/%d" day days-remaining)) - "Lisp expression giving the date format to use in the LaTeX calendars. -This should be an expression involving the variable `date'. When -this expression is called, `date' is a list of the form `(MONTH DAY YEAR)'. - -The string resulting from evaluating this expression is placed at -the bottom center of each date in monthly calendars, next to the -date in the weekly calendars, and in the top center of daily calendars. - -The default is ordinal day number of the year and the number of -days remaining. As an example, setting this to - - (calendar-hebrew-date-string date) - -will put the Hebrew date at the bottom of each day." - :type 'sexp - :group 'calendar-tex) - -(defcustom cal-tex-buffer "calendar.tex" - "The name for the output LaTeX calendar buffer." - :type 'string - :group 'calendar-tex) - -(defcustom cal-tex-24 nil - "Non-nil means use a 24 hour clock in the daily calendar." - :type 'boolean - :group 'calendar-tex) - -(defcustom cal-tex-daily-start 8 - "The first hour of the daily LaTeX calendar page. -At present, this only affects `cal-tex-cursor-day'." - :type 'integer - :group 'calendar-tex) - -(defcustom cal-tex-daily-end 20 - "The last hour of the daily LaTeX calendar page. -At present, this only affects `cal-tex-cursor-day'." - :type 'integer - :group 'calendar-tex) - -(defcustom cal-tex-preamble-extra nil - "A string giving extra LaTeX commands to insert in the calendar preamble. -For example, to include extra packages: -\"\\\\usepackage{foo}\\n\\\\usepackage{bar}\\n\"." - :type '(choice (const nil) - ;; An example to help people format things in custom. - (string :value "\\usepackage{foo}\n\\usepackage{bar}\n")) - :group 'calendar-tex - :version "22.1") - -(defcustom cal-tex-hook nil - "List of functions called after any LaTeX calendar buffer is generated. -You can use this to do post-processing on the buffer. For example, to change -characters with diacritical marks to their LaTeX equivalents, use - (add-hook \\='cal-tex-hook - (lambda () (iso-iso2tex (point-min) (point-max))))" - :type 'hook - :group 'calendar-tex) - -(defcustom cal-tex-year-hook nil - "List of functions called after a LaTeX year calendar buffer is generated." - :type 'hook - :group 'calendar-tex) - -(defcustom cal-tex-month-hook nil - "List of functions called after a LaTeX month calendar buffer is generated." - :type 'hook - :group 'calendar-tex) - -(defcustom cal-tex-week-hook nil - "List of functions called after a LaTeX week calendar buffer is generated." - :type 'hook - :group 'calendar-tex) - -(defcustom cal-tex-daily-hook nil - "List of functions called after a LaTeX daily calendar buffer is generated." - :type 'hook - :group 'calendar-tex) - -;;; -;;; Definitions for LaTeX code -;;; - -(defconst cal-tex-day-prefix "\\caldate{%s}{%s}" - "The initial LaTeX code for a day. -The holidays, diary entries, bottom string, and the text follow.") - -(defconst cal-tex-day-name-format "\\myday{%s}%%" - "The format for LaTeX code for a day name. -The names are taken from `calendar-day-name-array'.") - -(defconst cal-tex-cal-one-month - "\\def\\calmonth#1#2% -{\\begin{center}% -\\Huge\\bf\\uppercase{#1} #2 \\\\[1cm]% -\\end{center}}% -\\vspace*{-1.5cm}% -% -" - "LaTeX code for the month header, for a single month calendar.") - -(defconst cal-tex-cal-multi-month - "\\def\\calmonth#1#2#3#4% -{\\begin{center}% -\\Huge\\bf #1 #2---#3 #4\\\\[1cm]% -\\end{center}}% -\\vspace*{-1.5cm}% -% -" - "LaTeX code for the month header, for a multi-month calendar.") - -(defconst cal-tex-myday - "\\renewcommand{\\myday}[1]% -{\\makebox[\\cellwidth]{\\hfill\\large\\bf#1\\hfill}} -% -" - "LaTeX code for a day heading.") - -(defconst cal-tex-caldate -"\\fboxsep=0pt -\\long\\def\\caldate#1#2#3#4#5#6{% - \\fbox{\\hbox to\\cellwidth{% - \\vbox to\\cellheight{% - \\hbox to\\cellwidth{% - {\\hspace*{1mm}\\Large \\bf \\strut #2}\\hspace{.05\\cellwidth}% - \\raisebox{\\holidaymult\\cellheight}% - {\\parbox[t]{.75\\cellwidth}{\\tiny \\raggedright #4}}} - \\hbox to\\cellwidth{% - \\hspace*{1mm}\\parbox{.95\\cellwidth}{\\tiny \\raggedright #3}} - \\hspace*{1mm}% - \\hbox to\\cellwidth{#6}% - \\vfill% - \\hbox to\\cellwidth{\\hfill \\tiny #5 \\hfill}% - \\vskip 1.4pt}% - \\hskip -0.4pt}}} -" - "LaTeX code to insert one box with date info in calendar. -This definition is the heart of the calendar!") - -(defconst cal-tex-lefthead - "\\def\\lefthead#1{\\noindent {\\normalsize \\bf #1}\\hfill\\\\[-6pt]}\n" - "LaTeX code for left header.") - -(defconst cal-tex-righthead - "\\def\\righthead#1{\\hfill {\\normalsize \\bf #1}\\\\[-6pt]}\n" - "LaTeX code for right header.") - -(autoload 'holiday-in-range "holidays") - -(autoload 'diary-list-entries "diary-lib") - -(defvar diary-list-include-blanks) - -(defun cal-tex-list-diary-entries (d1 d2) - "Generate a list of all diary-entries from absolute date D1 to D2." - (let (diary-list-include-blanks) - (diary-list-entries (calendar-gregorian-from-absolute d1) - (1+ (- d2 d1)) t))) - -(defun cal-tex-preamble (&optional args) - "Insert the LaTeX calendar preamble into `cal-tex-buffer'. -Preamble includes initial definitions for various LaTeX commands. -Optional string ARGS are included as options for the article -document class with inclusion of default values \"12pt\" for -size, and \"a4paper\" for paper unless size or paper are already -specified in ARGS. When ARGS is omitted, by default the option -\"12pt,a4paper\" is passed. When ARGS has any other value, then -no option is passed to the class. - -Insert the \"\\usepackage{geometry}\" directive when ARGS -contains the \"landscape\" string." - (set-buffer (generate-new-buffer cal-tex-buffer)) - (save-match-data - (insert (format "\\documentclass%s{article}\n" - (cond - ((stringp args) - ;; set default size - (unless (string-match "\\(^\\|,\\) *[0-9]+pt *\\(,\\|$\\)" args) - (setq args (concat args ",12pt"))) - ;; set default paper - (unless (string-match "\\(^\\|,\\) *\\([ab][4-5]\\|le\\(tter\\|gal\\)\\|executive\\)paper *\\(,\\|$\\)" args) - (setq args (concat args ",a4paper"))) - (when (string= (substring args 0 1) ",") - (setq args (substring args 1))) - (if (string= args "") "" (format "[%s]" args))) - ((null args) "[12pt]") - (t "")))) - (if (and (stringp args) (string-match "\\" args)) - (insert "\\usepackage{geometry}\n"))) - (if (stringp cal-tex-preamble-extra) - (insert cal-tex-preamble-extra "\n")) - ;; FIXME boxwidth and boxheight unused? - (insert "\\hbadness 20000 -\\hfuzz=1000pt -\\vbadness 20000 -\\lineskip 0pt -\\marginparwidth 0pt -\\oddsidemargin -2cm -\\evensidemargin -2cm -\\marginparsep 0pt -\\topmargin 0pt -\\textwidth 7.5in -\\textheight 9.5in -\\newlength{\\cellwidth} -\\newlength{\\cellheight} -\\newlength{\\boxwidth} -\\newlength{\\boxheight} -\\newlength{\\cellsize} -\\newcommand{\\myday}[1]{} -\\newcommand{\\caldate}[6]{} -\\newcommand{\\nocaldate}[6]{} -\\newcommand{\\calsmall}[6]{} -% -")) - -;;; -;;; Yearly calendars -;;; - -;;;###cal-autoload -(defun cal-tex-cursor-year (&optional n event) - "Make a buffer with LaTeX commands for the year cursor is on. -Optional prefix argument N specifies number of years. -Optional EVENT indicates a buffer position to use instead of point." - (interactive (list (prefix-numeric-value current-prefix-arg) - last-nonmenu-event)) - (cal-tex-year (calendar-extract-year (calendar-cursor-to-date t event)) - (or n 1))) - -;;;###cal-autoload -(defun cal-tex-cursor-year-landscape (&optional n event) - "Make a buffer with LaTeX commands for the year cursor is on. -Optional prefix argument N specifies number of years. -Optional EVENT indicates a buffer position to use instead of point." - (interactive (list (prefix-numeric-value current-prefix-arg) - last-nonmenu-event)) - (cal-tex-year (calendar-extract-year (calendar-cursor-to-date t event)) - (or n 1) t)) - -(defun cal-tex-year (year n &optional landscape) - "Make a one page yearly calendar of YEAR; do this for N years. -There are four rows of three months each, unless optional -LANDSCAPE is non-nil, in which case the calendar is printed in -landscape mode with three rows of four months each." - (cal-tex-insert-preamble 1 (and landscape "landscape")) - (if landscape - (cal-tex-vspace "-.6cm") - (cal-tex-vspace "-3.1cm")) - (dotimes (j n) - (insert "\\vfill%\n") - (cal-tex-b-center) - (cal-tex-Huge (number-to-string year)) - (cal-tex-e-center) - (cal-tex-vspace "1cm") - (cal-tex-b-center) - (cal-tex-b-parbox "l" (if landscape "5.9in" "4.3in")) - (insert "\n") - (cal-tex-noindent) - (cal-tex-nl) - (dotimes (i 12) - (insert (cal-tex-mini-calendar (1+ i) year "month" "1.1in" "1in")) - (insert "\\month") - (cal-tex-hspace "0.5in") - (if (zerop (mod (1+ i) (if landscape 4 3))) - (cal-tex-nl "0.5in"))) - (cal-tex-e-parbox) - (cal-tex-e-center) - (insert "\\vfill%\n") - (setq year (1+ year)) - (if (= j (1- n)) - (cal-tex-end-document) - (cal-tex-newpage)) - (run-hooks 'cal-tex-year-hook)) - (run-hooks 'cal-tex-hook)) - - -(defun cal-tex-filofax-paper (&optional year) - "Insert some page size settings for filofax layouts." - (insert "\\textwidth 3.25in -\\textheight 6.5in -\\headheight -0.875in -\\topmargin 0pt -") - (insert - ;; Why is this one subtly different? Who knows... - (if year "\\oddsidemargin 1.675in -\\evensidemargin 1.675in -" - "\\oddsidemargin 1.75in -\\evensidemargin 1.5in -\\headsep 0.125in -\\footskip 0.125in -"))) - -(defun cal-tex-longday (funcname height) - "Insert LaTeX code for a long day function." - (insert "\\long\\def\\" funcname "#1#2#3#4#5{% - \\rule{\\textwidth}{0.3pt}\\\\% - \\hbox to \\textwidth{% - \\vbox to " height "{% - \\vspace*{2pt}% - \\hbox to \\textwidth{" - (if (string-equal funcname "leftday") - "\\noindent {\\normalsize \\bf #2} \\small #1 \\hfill #5}%\n" - "\\small #5 \\hfill #1 {\\normalsize \\bf #2}}%\n") - " \\hbox to \\textwidth{\\vbox {\\" - (if (string-equal funcname "leftday") "noindent" "raggedleft") - " \\footnotesize \\em #4}}% - \\hbox to \\textwidth{\\vbox to 0pt {\\noindent \\footnotesize #3}}}}\\\\}\n")) - -(defun cal-tex-shortday (funcname) - "Insert LaTeX code for a short day function." - (insert "\\long\\def\\" funcname "#1#2#3{% - \\rule{\\textwidth}{0.3pt}\\\\% - \\hbox to \\textwidth{% - \\vbox {% - \\vspace*{2pt}% - \\hbox to \\textwidth{\\hfill \\small #3 \\hfill}% - \\hbox to \\textwidth{\\vbox {\\" - (if (string-equal funcname "rightday") "raggedleft" "noindent") - " \\em #2}}% - \\hbox to \\textwidth{\\vbox {\\noindent \\footnotesize #1}}}}}\n")) - -;;;###cal-autoload -(defun cal-tex-cursor-filofax-year (&optional n event) - "Make a Filofax one page yearly calendar of year indicated by cursor. -Optional prefix argument N specifies number of years. -Optional EVENT indicates a buffer position to use instead of point." - (interactive (list (prefix-numeric-value current-prefix-arg) - last-nonmenu-event)) - (or n (setq n 1)) - (let ((year (calendar-extract-year (calendar-cursor-to-date t event)))) - (cal-tex-preamble "twoside") - (cal-tex-filofax-paper 'year) - (cal-tex-cmd "\\fboxsep 0.5mm") - (cal-tex-cmd "\\pagestyle" "empty") - (cal-tex-b-document) - (cal-tex-vspace "0.25in") - (dotimes (j n) - (insert (format "\\hfil \\textbf{\\Large %s} \\hfil\\\\\n" year)) - (cal-tex-b-center) - (cal-tex-b-parbox "l" "\\textwidth") - (insert "\n") - (cal-tex-noindent) - (cal-tex-nl) - (let ((month-names; don't use default in case user changed it - ;; These are only used to define the command names, not - ;; the names of the months they insert. - ["January" "February" "March" "April" "May" "June" - "July" "August" "September" "October" "November" "December"])) - (dotimes (i 12) - (insert (cal-tex-mini-calendar (1+ i) year (aref month-names i) - "1in" ".9in" "tiny" "0.6mm")))) - (insert - "\\noindent\\fbox{\\January}\\fbox{\\February}\\fbox{\\March}\\\\ -\\noindent\\fbox{\\April}\\fbox{\\May}\\fbox{\\June}\\\\ -\\noindent\\fbox{\\July}\\fbox{\\August}\\fbox{\\September}\\\\ -\\noindent\\fbox{\\October}\\fbox{\\November}\\fbox{\\December} -") - (cal-tex-e-parbox) - (cal-tex-e-center) - (setq year (1+ year)) - (if (= j (1- n)) - (cal-tex-end-document) - (cal-tex-newpage) - (cal-tex-vspace "0.25in")) - (run-hooks 'cal-tex-year-hook)) - (run-hooks 'cal-tex-hook))) - -;;; -;;; Monthly calendars -;;; - -;;;###cal-autoload -(defun cal-tex-cursor-month-landscape (&optional n event) - "Make a LaTeX calendar buffer for the month the cursor is on. -Optional prefix argument N specifies number of months to be -produced (default 1). The output is in landscape format, one -month to a page. It shows holiday and diary entries if -`cal-tex-holidays' and `cal-tex-diary', respectively, are non-nil. -Optional EVENT indicates a buffer position to use instead of point." - (interactive (list (prefix-numeric-value current-prefix-arg) - last-nonmenu-event)) - (or n (setq n 1)) - (let* ((date (calendar-cursor-to-date t event)) - (month (calendar-extract-month date)) - (year (calendar-extract-year date)) - (end-month month) - (end-year year) - (cal-tex-which-days '(0 1 2 3 4 5 6)) - (d1 (calendar-absolute-from-gregorian (list month 1 year))) - (d2 (progn - (calendar-increment-month end-month end-year (1- n)) - (calendar-absolute-from-gregorian - (list end-month - (calendar-last-day-of-month end-month end-year) - end-year)))) - (diary-list (if cal-tex-diary (cal-tex-list-diary-entries d1 d2))) - (holidays (if cal-tex-holidays (holiday-in-range d1 d2))) - other-month other-year small-months-at-start) - (cal-tex-insert-preamble (cal-tex-number-weeks month year 1) "landscape") - (cal-tex-cmd cal-tex-cal-one-month) - (dotimes (i n) - (setq other-month month - other-year year) - (calendar-increment-month other-month other-year -1) - (insert (cal-tex-mini-calendar other-month other-year "lastmonth" - "\\cellwidth" "\\cellheight")) - (calendar-increment-month other-month other-year 2) - (insert (cal-tex-mini-calendar other-month other-year "nextmonth" - "\\cellwidth" "\\cellheight")) - (cal-tex-insert-month-header 1 month year month year) - (cal-tex-insert-day-names) - (cal-tex-nl ".2cm") - (if (setq small-months-at-start - (< 1 (mod (- (calendar-day-of-week (list month 1 year)) - calendar-week-start-day) - 7))) - (insert "\\lastmonth\\nextmonth\\hspace*{-2\\cellwidth}")) - (cal-tex-insert-blank-days month year cal-tex-day-prefix) - (cal-tex-insert-days month year diary-list holidays - cal-tex-day-prefix) - (cal-tex-insert-blank-days-at-end month year cal-tex-day-prefix) - (if (and (not small-months-at-start) - (< 1 (mod (- (1- calendar-week-start-day) - (calendar-day-of-week - (list month - (calendar-last-day-of-month month year) - year))) - 7))) - (insert "\\vspace*{-\\cellwidth}\\hspace*{-2\\cellwidth}" - "\\lastmonth\\nextmonth% -")) - (unless (= i (1- n)) - (run-hooks 'cal-tex-month-hook) - (cal-tex-newpage) - (calendar-increment-month month year 1) - (cal-tex-vspace "-2cm") - (cal-tex-insert-preamble - (cal-tex-number-weeks month year 1) "landscape" t)))) - (cal-tex-end-document) - (run-hooks 'cal-tex-hook)) - -;;;###cal-autoload -(defun cal-tex-cursor-month (&optional n event) - "Make a LaTeX calendar buffer for the month the cursor is on. -Optional prefix argument N specifies number of months to be -produced (default 1). The calendar is condensed onto one page. -It shows holiday and diary entries if `cal-tex-holidays' and -`cal-tex-diary', respectively, are non-nil. Optional EVENT -indicates a buffer position to use instead of point." - (interactive (list (prefix-numeric-value current-prefix-arg) - last-nonmenu-event)) - (or n (setq n 1)) - (let* ((date (calendar-cursor-to-date t event)) - (month (calendar-extract-month date)) - (year (calendar-extract-year date)) - (end-month month) - (end-year year) - ;; FIXME -landscape sets cal-tex-which-days? - (d1 (calendar-absolute-from-gregorian (list month 1 year))) - (d2 (progn - (calendar-increment-month end-month end-year (1- n)) - (calendar-absolute-from-gregorian - (list end-month - (calendar-last-day-of-month end-month end-year) - end-year)))) - (diary-list (if cal-tex-diary (cal-tex-list-diary-entries d1 d2))) - (holidays (if cal-tex-holidays (holiday-in-range d1 d2)))) - (cal-tex-insert-preamble (cal-tex-number-weeks month year n)) - (if (> n 1) - (cal-tex-cmd cal-tex-cal-multi-month) - (cal-tex-cmd cal-tex-cal-one-month)) - (cal-tex-insert-month-header n month year end-month end-year) - (cal-tex-insert-day-names) - (cal-tex-nl ".2cm") - (cal-tex-insert-blank-days month year cal-tex-day-prefix) - (dotimes (_idummy n) - (cal-tex-insert-days month year diary-list holidays cal-tex-day-prefix) - (when (= (calendar-week-end-day) - (calendar-day-of-week - (list month - (calendar-last-day-of-month month year) - year))) ; last day of month was last day of week - (cal-tex-hfill) - (cal-tex-nl)) - (calendar-increment-month month year 1)) - (cal-tex-insert-blank-days-at-end end-month end-year cal-tex-day-prefix)) - (cal-tex-end-document) - (run-hooks 'cal-tex-hook)) - -(defun cal-tex-insert-days (month year diary-list holidays day-format) - "Insert LaTeX commands for a range of days in monthly calendars. -LaTeX commands are inserted for the days of the MONTH in YEAR. -Diary entries on DIARY-LIST are included. Holidays on HOLIDAYS -are included. Each day is formatted using format DAY-FORMAT." - (with-suppressed-warnings ((lexical date)) - (defvar date)) ;For `cal-tex-daily-string'. - (let ((blank-days ; at start of month - (mod - (- (calendar-day-of-week (list month 1 year)) - calendar-week-start-day) - 7)) - (last (calendar-last-day-of-month month year)) - date j) - (dotimes (i last) - (setq j (1+ i) ; 1-last, incl - date (list month j year)) - (when (memq (calendar-day-of-week date) cal-tex-which-days) - (insert (format day-format (cal-tex-month-name month) j)) - (cal-tex-arg (cal-tex-latexify-list diary-list date)) - (cal-tex-arg (cal-tex-latexify-list holidays date)) - (cal-tex-arg (eval cal-tex-daily-string t)) - (cal-tex-arg) - (cal-tex-comment)) - (when (and (zerop (mod (+ j blank-days) 7)) - (/= j last)) - (cal-tex-hfill) - (cal-tex-nl))))) - -(defun cal-tex-insert-day-names () - "Insert the names of the days at top of a monthly calendar." - (let (j) - (dotimes (i 7) - (if (memq (setq j (mod (+ calendar-week-start-day i) 7)) - cal-tex-which-days) - (insert (format cal-tex-day-name-format - (cal-tex-LaTeXify-string - (aref calendar-day-name-array j))))) - (cal-tex-comment)))) - -(defun cal-tex-insert-month-header (n month year end-month end-year) - "Create a title for a calendar. -A title is inserted for a calendar with N months starting with -MONTH YEAR and ending with END-MONTH END-YEAR." - (let ((month-name (cal-tex-month-name month)) - (end-month-name (cal-tex-month-name end-month))) - (if (= 1 n) - (insert (format "\\calmonth{%s}{%s}\n\\vspace*{-0.5cm}" - month-name year) ) - (insert (format "\\calmonth{%s}{%s}{%s}{%s}\n\\vspace*{-0.5cm}" - month-name year end-month-name end-year)))) - (cal-tex-comment)) - -(defun cal-tex-insert-blank-days (month year day-format) - "Insert code for initial days not in calendar. -Insert LaTeX code for the blank days at the beginning of the MONTH in -YEAR. The entry is formatted using DAY-FORMAT. If the entire week is -blank, no days are inserted." - (if (cal-tex-first-blank-p month year) - (let ((blank-days ; at start of month - (mod - (- (calendar-day-of-week (list month 1 year)) - calendar-week-start-day) - 7))) - (dotimes (i blank-days) - (if (memq (mod (+ calendar-week-start-day i) 7) cal-tex-which-days) - (insert (format day-format " " " ") "{}{}{}{}%\n")))))) - -(defun cal-tex-insert-blank-days-at-end (month year day-format) - "Insert code for final days not in calendar. -Insert LaTeX code for the blank days at the end of the MONTH in YEAR. -The entry is formatted using DAY-FORMAT." - (if (cal-tex-last-blank-p month year) - (let* ((last-day (calendar-last-day-of-month month year)) - (blank-days ; at end of month - (mod - (- (calendar-day-of-week (list month last-day year)) - calendar-week-start-day) - 7)) - (i blank-days)) - (while (<= (setq i (1+ i)) 6) - (if (memq (mod (+ calendar-week-start-day i) 7) cal-tex-which-days) - (insert (format day-format "" "") "{}{}{}{}%\n")))))) - -(defun cal-tex-first-blank-p (month year) - "Determine if any days of the first week will be printed. -Return t if there will there be any days of the first week printed -in the calendar starting in MONTH YEAR." - ;; Check days 1-7 of the month, until we find the last day of the week. - (catch 'found - (let (dow) - (dotimes (i 7) - (if (memq (setq dow (calendar-day-of-week (list month (1+ i) year))) - cal-tex-which-days) - (throw 'found t) - (if (= dow (calendar-week-end-day)) (throw 'found nil))))))) - -(defun cal-tex-last-blank-p (month year) - "Determine if any days of the last week will be printed. -Return t if there will there be any days of the last week printed -in the calendar starting in MONTH YEAR." - ;; Check backwards from the last day of the month, until we find the - ;; start of the last week in the month. - (catch 'found - (let ((last-day (calendar-last-day-of-month month year)) - dow) - (dotimes (i 7) - (if (memq (setq dow (calendar-day-of-week - (list month (- last-day i) year))) - cal-tex-which-days) - (throw 'found t) - (if (= dow calendar-week-start-day) (throw 'found nil))))))) - -(defun cal-tex-number-weeks (month year n) - "Determine the number of weeks in a range of dates. -Compute the number of weeks in the calendar starting with MONTH and YEAR, -and lasting N months, including only the days in WHICH-DAYS. As it stands, -this is only an upper bound." - (let ((d (list month 1 year))) - (calendar-increment-month month year (1- n)) - (/ (- (calendar-dayname-on-or-before - calendar-week-start-day - (+ 7 (calendar-absolute-from-gregorian - (list month (calendar-last-day-of-month month year) year)))) - (calendar-dayname-on-or-before - calendar-week-start-day - (calendar-absolute-from-gregorian d))) - 7))) - -;;; -;;; Weekly calendars -;;; - -(defconst cal-tex-LaTeX-hourbox - "\\newcommand{\\hourbox}[2]% -{\\makebox[2em]{\\rule{0cm}{#2ex}#1}\\rule{3in}{.15mm}}\n" - "One hour and a line on the right.") - -(defun cal-tex-weekly-paper (&optional nomargins) - "Insert some page size settings for weekly layouts." - (insert "\\textwidth 6.5in -\\textheight 10.5in -") - (or nomargins (insert "\\oddsidemargin 0in -\\evensidemargin 0in -"))) - -;; TODO cal-tex-diary-support. -;; TODO respect cal-tex-daily-start,end (see cal-tex-week-hours). -;;;###cal-autoload -(defun cal-tex-cursor-week (&optional n event) - "Make a one page LaTeX calendar for one week, showing hours of the day. -There are two columns; with 8-12am in the first and 1-5pm in the second. -It shows holidays if `cal-tex-holidays' is non-nil. -It does not show diary entries. - -The optional prefix argument N specifies a number of weeks (default 1). - -By default, the calendar is for the week at point; the optional -argument EVENT specifies a different buffer position." - (interactive (list (prefix-numeric-value current-prefix-arg) - last-nonmenu-event)) - (or n (setq n 1)) - (let* ((date (calendar-gregorian-from-absolute - (calendar-dayname-on-or-before - calendar-week-start-day - (calendar-absolute-from-gregorian - (calendar-cursor-to-date t event))))) - (month (calendar-extract-month date)) - (year (calendar-extract-year date)) - (d1 (calendar-absolute-from-gregorian date)) - (d2 (+ (* 7 n) d1)) - (holidays (if cal-tex-holidays - (holiday-in-range d1 d2)))) - (cal-tex-preamble "11pt") - (cal-tex-weekly-paper) - (insert cal-tex-LaTeX-hourbox) - (cal-tex-b-document) - (cal-tex-cmd "\\pagestyle" "empty") - (dotimes (i n) - (cal-tex-vspace "-1.5in") - (cal-tex-b-center) - (cal-tex-Huge-bf (format "\\uppercase{%s}" - (cal-tex-month-name month))) - (cal-tex-hspace "2em") - (cal-tex-Huge-bf (number-to-string year)) - (cal-tex-nl ".5cm") - (cal-tex-e-center) - (cal-tex-hspace "-.2in") - (cal-tex-b-parbox "l" "7in") - (dotimes (_jdummy 7) - (cal-tex-week-hours date holidays "3.1") - (setq date (cal-tex-incr-date date))) - (cal-tex-e-parbox) - (setq month (calendar-extract-month date) - year (calendar-extract-year date)) - (unless (= i (1- n)) - (run-hooks 'cal-tex-week-hook) - (cal-tex-newpage))) - (cal-tex-end-document) - (run-hooks 'cal-tex-hook))) - -;; TODO cal-tex-diary support. -;; TODO respect cal-tex-daily-start,end (see cal-tex-week-hours). -;;;###cal-autoload -(defun cal-tex-cursor-week2 (&optional n event) - "Make a two page LaTeX calendar for one week, showing hours of the day. -There are two columns; with 8-12am in the first and 1-5pm in the second. -It shows holidays if `cal-tex-holidays' is non-nil. -It does not show diary entries. - -The optional prefix argument N specifies a number of weeks (default 1). - -By default, the calendar is for the week at point; the optional -argument EVENT specifies a different buffer position." - (interactive (list (prefix-numeric-value current-prefix-arg) - last-nonmenu-event)) - (or n (setq n 1)) - (let* ((date (calendar-gregorian-from-absolute - (calendar-dayname-on-or-before - calendar-week-start-day - (calendar-absolute-from-gregorian - (calendar-cursor-to-date t event))))) - (month (calendar-extract-month date)) - (year (calendar-extract-year date)) - (d1 (calendar-absolute-from-gregorian date)) - (d2 (+ (* 7 n) d1)) - (holidays (if cal-tex-holidays - (holiday-in-range d1 d2)))) - (cal-tex-preamble "12pt") - (cal-tex-weekly-paper) - (insert cal-tex-LaTeX-hourbox) - (cal-tex-b-document) - (cal-tex-cmd "\\pagestyle" "empty") - (dotimes (i n) - (cal-tex-vspace "-1.5in") - (cal-tex-b-center) - (cal-tex-Huge-bf (format "\\uppercase{%s}" - (cal-tex-month-name month))) - (cal-tex-hspace "2em") - (cal-tex-Huge-bf (number-to-string year)) - (cal-tex-nl ".5cm") - (cal-tex-e-center) - (cal-tex-hspace "-.2in") - (cal-tex-b-parbox "l" "\\textwidth") - (dotimes (_jdummy 3) - (cal-tex-week-hours date holidays "5") - (setq date (cal-tex-incr-date date))) - (cal-tex-e-parbox) - (cal-tex-nl) - (insert (cal-tex-mini-calendar - (calendar-extract-month (cal-tex-previous-month date)) - (calendar-extract-year (cal-tex-previous-month date)) - "lastmonth" "1.1in" "1in")) - (insert (cal-tex-mini-calendar - (calendar-extract-month date) - (calendar-extract-year date) - "thismonth" "1.1in" "1in")) - (insert (cal-tex-mini-calendar - (calendar-extract-month (cal-tex-next-month date)) - (calendar-extract-year (cal-tex-next-month date)) - "nextmonth" "1.1in" "1in")) - (insert "\\hbox to \\textwidth{") - (cal-tex-hfill) - (insert "\\lastmonth") - (cal-tex-hfill) - (insert "\\thismonth") - (cal-tex-hfill) - (insert "\\nextmonth") - (cal-tex-hfill) - (insert "}") - (cal-tex-nl) - (cal-tex-b-parbox "l" "\\textwidth") - (dotimes (_jdummy 4) - (cal-tex-week-hours date holidays "5") - (setq date (cal-tex-incr-date date))) - (cal-tex-e-parbox) - (setq month (calendar-extract-month date) - year (calendar-extract-year date)) - (unless (= i (1- n)) - (run-hooks 'cal-tex-week-hook) - (cal-tex-newpage))) - (cal-tex-end-document) - (run-hooks 'cal-tex-hook))) - -(autoload 'calendar-iso-from-absolute "cal-iso") - -;;;###cal-autoload -(defun cal-tex-cursor-week-iso (&optional n event) - "Make a one page LaTeX calendar for one week, in the ISO-style. -It does not show hours of the day. -It shows holidays if `cal-tex-holidays' is non-nil. -It shows diary entries if `cal-tex-diary' is non-nil. - -The optional prefix argument N specifies a number of weeks (default 1). - -By default, the calendar is for the week at point; the optional -argument EVENT specifies a different buffer position." - (interactive (list (prefix-numeric-value current-prefix-arg) - last-nonmenu-event)) - (or n (setq n 1)) - (with-suppressed-warnings ((lexical date)) - (defvar date)) ;For `cal-tex-daily-string'. - (let* ((date (calendar-gregorian-from-absolute - (calendar-dayname-on-or-before - 1 - (calendar-absolute-from-gregorian - (calendar-cursor-to-date t event))))) - (month (calendar-extract-month date)) - ;; (year (calendar-extract-year date)) - (day (calendar-extract-day date)) - (d1 (calendar-absolute-from-gregorian date)) - (d2 (+ (* 7 n) d1)) - (holidays (if cal-tex-holidays - (holiday-in-range d1 d2))) - (diary-list (if cal-tex-diary - (cal-tex-list-diary-entries d1 d2))) - s) - (cal-tex-preamble "11pt") - (cal-tex-weekly-paper) - (cal-tex-b-document) - (cal-tex-cmd "\\pagestyle" "empty") - (dotimes (i n) - (cal-tex-vspace "-1.5in") - (cal-tex-b-center) - (cal-tex-Huge-bf - (let ((d (calendar-iso-from-absolute - (calendar-absolute-from-gregorian date)))) - (format "Week %d of %d" - (calendar-extract-month d) - (calendar-extract-year d)))) - (cal-tex-nl ".5cm") - (cal-tex-e-center) - (cal-tex-b-parbox "l" "\\textwidth") - (dotimes (_j 7) - (cal-tex-b-parbox "t" "\\textwidth") - (cal-tex-b-parbox "t" "\\textwidth") - (cal-tex-rule "0pt" "\\textwidth" ".2mm") - (cal-tex-nl) - (cal-tex-b-parbox "t" "\\textwidth") - (cal-tex-large-bf (cal-tex-LaTeXify-string (calendar-day-name date))) - (insert ", ") - (cal-tex-large-bf (cal-tex-month-name month)) - (insert "\\ ") - (cal-tex-large-bf (number-to-string day)) - (unless (string-equal "" (setq s (cal-tex-latexify-list - holidays date "; "))) - (insert ": ") - (cal-tex-large-bf s)) - (cal-tex-hfill) - (insert " " (eval cal-tex-daily-string t)) - (cal-tex-e-parbox) - (cal-tex-nl) - (cal-tex-noindent) - (cal-tex-b-parbox "t" "\\textwidth") - (unless (string-equal "" (setq s (cal-tex-latexify-list - diary-list date))) - (insert "\\vbox to 0pt{") - (cal-tex-large-bf s) - (insert "}")) - (cal-tex-e-parbox) - (cal-tex-nl) - (setq date (cal-tex-incr-date date) - month (calendar-extract-month date) - day (calendar-extract-day date)) - (cal-tex-e-parbox) - (cal-tex-e-parbox "2cm") - (cal-tex-nl) - (setq month (calendar-extract-month date) - ;; year (calendar-extract-year date) - )) - (cal-tex-e-parbox) - (unless (= i (1- n)) - (run-hooks 'cal-tex-week-hook) - (cal-tex-newpage))) - (cal-tex-end-document) - (run-hooks 'cal-tex-hook))) - -;; TODO respect cal-tex-daily-start,end? -;; Using different numbers of hours will probably break some layouts. -(defun cal-tex-week-hours (thedate holidays height) - "Insert hourly entries for THEDATE with HOLIDAYS, with line height HEIGHT. -Uses the 24-hour clock if `cal-tex-24' is non-nil. Note that the hours -shown are hard-coded to 8-12, 13-17." - (with-suppressed-warnings ((lexical date)) - (defvar date)) ;For `cal-tex-daily-string'. - (let* ((date thedate) - (month (calendar-extract-month date)) - (day (calendar-extract-day date)) - ;; (year (calendar-extract-year date)) - morning afternoon s) - (cal-tex-comment "begin cal-tex-week-hours") - (cal-tex-cmd "\\ \\\\[-.2cm]") - (cal-tex-cmd "\\noindent") - (cal-tex-b-parbox "l" "6.8in") - (cal-tex-large-bf (cal-tex-LaTeXify-string (calendar-day-name date))) - (insert ", ") - (cal-tex-large-bf (cal-tex-month-name month)) - (insert "\\ ") - (cal-tex-large-bf (number-to-string day)) - (unless (string-equal "" (setq s (cal-tex-latexify-list - holidays date "; "))) - (insert ": ") - (cal-tex-large-bf s)) - (cal-tex-hfill) - (insert " " (eval cal-tex-daily-string t)) - (cal-tex-e-parbox) - (cal-tex-nl "-.3cm") - (cal-tex-rule "0pt" "6.8in" ".2mm") - (cal-tex-nl "-.1cm") - (dotimes (i 5) - (setq morning (+ i 8) ; 8-12 incl - afternoon (if cal-tex-24 - (+ i 13) ; 13-17 incl - (1+ i))) ; 1-5 incl - (cal-tex-cmd "\\hourbox" (number-to-string morning)) - (cal-tex-arg height) - (cal-tex-hspace ".4cm") - (cal-tex-cmd "\\hourbox" (number-to-string afternoon)) - (cal-tex-arg height) - (cal-tex-nl)))) - -;; TODO cal-tex-diary support. -;; TODO respect cal-tex-daily-start,end (see cal-tex-weekly4-box). -;;;###cal-autoload -(defun cal-tex-cursor-week-monday (&optional n event) - "Make a one page LaTeX calendar for one week, showing hours of the day. -There are two columns; with M-W in the first and T-S in the second. -It shows the hours 8-12am and 1-5pm. -It shows holidays if `cal-tex-holidays' is non-nil. -It does not show diary entries. - -The optional prefix argument N specifies a number of weeks (default 1). - -By default, the calendar is for the week at point; the optional -argument EVENT specifies a different buffer position." - (interactive (list (prefix-numeric-value current-prefix-arg) - last-nonmenu-event)) - (or n (setq n 1)) - (let ((date (calendar-gregorian-from-absolute - (calendar-dayname-on-or-before - 0 - (calendar-absolute-from-gregorian - (calendar-cursor-to-date t event)))))) - (cal-tex-preamble "11pt") - (cal-tex-weekly-paper) - (cal-tex-b-document) - (dotimes (i n) - (cal-tex-vspace "-1cm") - (insert "\\noindent ") - (cal-tex-weekly4-box (cal-tex-incr-date date) nil) - (cal-tex-weekly4-box (cal-tex-incr-date date 4) nil) - (cal-tex-nl ".2cm") - (cal-tex-weekly4-box (cal-tex-incr-date date 2) nil) - (cal-tex-weekly4-box (cal-tex-incr-date date 5) nil) - (cal-tex-nl ".2cm") - (cal-tex-weekly4-box (cal-tex-incr-date date 3) nil) - (cal-tex-weekly4-box (cal-tex-incr-date date 6) t) - (unless (= i (1- n)) - (run-hooks 'cal-tex-week-hook) - (setq date (cal-tex-incr-date date 7)) - (cal-tex-newpage))) - (cal-tex-end-document) - (run-hooks 'cal-tex-hook))) - -;; TODO respect cal-tex-daily-start,end? -;; Using different numbers of hours will probably break some layouts. -(defun cal-tex-weekly4-box (date weekend) - "Make one box for DATE, different if WEEKEND. -Uses the 24-hour clock if `cal-tex-24' is non-nil. Note that the hours -shown are hard-coded to 8-12, 13-17." - (let* ((day (calendar-extract-day date)) - (month (calendar-extract-month date)) - (year (calendar-extract-year date)) - (dayname (cal-tex-LaTeXify-string (calendar-day-name date))) - (date1 (cal-tex-incr-date date)) - (day1 (calendar-extract-day date1)) - (month1 (calendar-extract-month date1)) - (year1 (calendar-extract-year date1)) - (dayname1 (cal-tex-LaTeXify-string (calendar-day-name date1)))) - (cal-tex-b-framebox "8cm" "l") - (cal-tex-b-parbox "b" "7.5cm") - (insert (format "\\textbf{\\Large %s,} %s/%s/%s\\\\\n" - dayname month day year)) - (cal-tex-rule "0pt" "7.5cm" ".5mm") - (cal-tex-nl) - (unless weekend - (dotimes (i 5) - (insert (format "\\textsf{\\large %d}\\\\\n" (+ i 8)))) - (dotimes (i 5) - (insert (format "\\textsf{\\large %d}\\\\\n" - (if cal-tex-24 - (+ i 13) ; 13-17 incl - (1+ i)))))) ; 1-5 incl - (cal-tex-nl ".5cm") - (when weekend - (cal-tex-vspace "1cm") - (insert "\\ \\vfill") - (insert (format "\\textbf{\\Large %s,} %s/%s/%s\\\\\n" - dayname1 month1 day1 year1)) - (cal-tex-rule "0pt" "7.5cm" ".5mm") - (cal-tex-nl "1.5cm") - (cal-tex-vspace "1cm")) - (cal-tex-e-parbox) - (cal-tex-e-framebox) - (cal-tex-hspace "1cm"))) - -(defun cal-tex-weekly-common (n event &optional filofax) - "Common code for weekly calendars." - (or n (setq n 1)) - (with-suppressed-warnings ((lexical date)) - (defvar date)) ;For `cal-tex-daily-string'. - (let* ((date (calendar-gregorian-from-absolute - (calendar-dayname-on-or-before - 1 - (calendar-absolute-from-gregorian - (calendar-cursor-to-date t event))))) - ;; (month (calendar-extract-month date)) - ;; (year (calendar-extract-year date)) - ;; (day (calendar-extract-day date)) - (d1 (calendar-absolute-from-gregorian date)) - (d2 (+ (* 7 n) d1)) - (holidays (if cal-tex-holidays - (holiday-in-range d1 d2))) - (diary-list (if cal-tex-diary - (cal-tex-list-diary-entries d1 d2)))) - (if filofax - (progn - (cal-tex-preamble "twoside") - (cal-tex-filofax-paper) - (insert cal-tex-righthead) - (cal-tex-longday "rightday" "1.85in") - (cal-tex-longday "weekend" "0.8in") - (insert cal-tex-lefthead) - (cal-tex-longday "leftday" "1.85in")) - (cal-tex-preamble "twoside,12pt") - (insert "\\textwidth 7in -\\textheight 10.5in -\\oddsidemargin 0in -\\evensidemargin 0in -\\topmargin 0pt -\\headheight -0.875in -\\headsep 0.125in -\\footskip .125in -") - (insert cal-tex-righthead) - (cal-tex-longday "rightday" "2.75in") - (cal-tex-longday "weekend" "1.8in") - (insert cal-tex-lefthead) - (cal-tex-longday "leftday" "2.75in")) - (cal-tex-b-document) - (cal-tex-cmd "\\pagestyle" "empty") - ;; Let's assume this is something to do with twopage documents. - ;; It has the downside that we start with a blank page. - ;; It doesn't make obvious sense when oddside and evenside margins - ;; are the same (non-filofax), but consider the left and right - ;; versions of various functions as applicable to even and odd pages. - (cal-tex-newpage) - (dotimes (i n) - (insert "\\lefthead") - (cal-tex-arg - (let ((d (cal-tex-incr-date date 2))) - (if (= (calendar-extract-month date) - (calendar-extract-month d)) - (format "%s %s" - (cal-tex-month-name (calendar-extract-month date)) - (calendar-extract-year date)) - (if (= (calendar-extract-year date) - (calendar-extract-year d)) - (format "%s---%s %s" - (cal-tex-month-name (calendar-extract-month date)) - (cal-tex-month-name (calendar-extract-month d)) - (calendar-extract-year date)) - (format "%s %s---%s %s" - (cal-tex-month-name (calendar-extract-month date)) - (calendar-extract-year date) - (cal-tex-month-name (calendar-extract-month d)) - (calendar-extract-year d)))))) - (insert "%\n") - (dotimes (_jdummy 3) - (insert "\\leftday") - (cal-tex-arg (cal-tex-LaTeXify-string (calendar-day-name date))) - (cal-tex-arg (number-to-string (calendar-extract-day date))) - (cal-tex-arg (cal-tex-latexify-list diary-list date)) - (cal-tex-arg (cal-tex-latexify-list holidays date)) - (cal-tex-arg (eval cal-tex-daily-string t)) - (insert "%\n") - (setq date (cal-tex-incr-date date))) - (insert "\\noindent\\rule{\\textwidth}{0.3pt}\\\\%\n") - (unless filofax - (cal-tex-nl) - (insert (cal-tex-mini-calendar - (calendar-extract-month (cal-tex-previous-month date)) - (calendar-extract-year (cal-tex-previous-month date)) - "lastmonth" "1.1in" "1in")) - (insert (cal-tex-mini-calendar - (calendar-extract-month date) - (calendar-extract-year date) - "thismonth" "1.1in" "1in")) - (insert (cal-tex-mini-calendar - (calendar-extract-month (cal-tex-next-month date)) - (calendar-extract-year (cal-tex-next-month date)) - "nextmonth" "1.1in" "1in")) - (insert "\\hbox to \\textwidth{") - (cal-tex-hfill) - (insert "\\lastmonth") - (cal-tex-hfill) - (insert "\\thismonth") - (cal-tex-hfill) - (insert "\\nextmonth") - (cal-tex-hfill) - (insert "}")) - (cal-tex-newpage) - (insert "\\righthead") - (cal-tex-arg - (let ((d (cal-tex-incr-date date 3))) - (if (= (calendar-extract-month date) - (calendar-extract-month d)) - (format "%s %s" - (cal-tex-month-name (calendar-extract-month date)) - (calendar-extract-year date)) - (if (= (calendar-extract-year date) - (calendar-extract-year d)) - (format "%s---%s %s" - (cal-tex-month-name (calendar-extract-month date)) - (cal-tex-month-name (calendar-extract-month d)) - (calendar-extract-year date)) - (format "%s %s---%s %s" - (cal-tex-month-name (calendar-extract-month date)) - (calendar-extract-year date) - (cal-tex-month-name (calendar-extract-month d)) - (calendar-extract-year d)))))) - (insert "%\n") - (dotimes (_jdummy 2) - (insert "\\rightday") - (cal-tex-arg (cal-tex-LaTeXify-string (calendar-day-name date))) - (cal-tex-arg (number-to-string (calendar-extract-day date))) - (cal-tex-arg (cal-tex-latexify-list diary-list date)) - (cal-tex-arg (cal-tex-latexify-list holidays date)) - (cal-tex-arg (eval cal-tex-daily-string)) - (insert "%\n") - (setq date (cal-tex-incr-date date))) - (dotimes (_jdummy 2) - (insert "\\weekend") - (cal-tex-arg (cal-tex-LaTeXify-string (calendar-day-name date))) - (cal-tex-arg (number-to-string (calendar-extract-day date))) - (cal-tex-arg (cal-tex-latexify-list diary-list date)) - (cal-tex-arg (cal-tex-latexify-list holidays date)) - (cal-tex-arg (eval cal-tex-daily-string)) - (insert "%\n") - (setq date (cal-tex-incr-date date))) - (unless (= i (1- n)) - (run-hooks 'cal-tex-week-hook) - (cal-tex-newpage))) - (cal-tex-end-document) - (run-hooks 'cal-tex-hook))) - -;;;###cal-autoload -(defun cal-tex-cursor-week2-summary (&optional n event) - "Make a two page LaTeX calendar for one week, with optional diary entries. -It does not show hours of the day. -It shows holidays if `cal-tex-holidays' is non-nil. -It shows diary entries if `cal-tex-diary' is non-nil. - -The optional prefix argument N specifies a number of weeks (default 1). - -By default, the calendar is for the week at point; the optional -argument EVENT specifies a different buffer position." - (interactive (list (prefix-numeric-value current-prefix-arg) - last-nonmenu-event)) - (cal-tex-weekly-common n event)) - -;;;###cal-autoload -(defun cal-tex-cursor-filofax-2week (&optional n event) - "Two-weeks-at-a-glance Filofax style calendar for week cursor is in. -Optional prefix argument N specifies number of weeks (default 1). -The calendar shows holiday and diary entries if -`cal-tex-holidays' and `cal-tex-diary', respectively, are non-nil. -Optional EVENT indicates a buffer position to use instead of point." - (interactive (list (prefix-numeric-value current-prefix-arg) - last-nonmenu-event)) - (or n (setq n 1)) - (with-suppressed-warnings ((lexical date)) - (defvar date)) ;For `cal-tex-daily-string'. - (let* ((date (calendar-gregorian-from-absolute - (calendar-dayname-on-or-before - calendar-week-start-day - (calendar-absolute-from-gregorian - (calendar-cursor-to-date t event))))) - ;; (month (calendar-extract-month date)) - ;; (year (calendar-extract-year date)) - ;; (day (calendar-extract-day date)) - (d1 (calendar-absolute-from-gregorian date)) - (d2 (+ (* 7 n) d1)) - (holidays (if cal-tex-holidays - (holiday-in-range d1 d2))) - (diary-list (if cal-tex-diary - (cal-tex-list-diary-entries d1 d2)))) - (cal-tex-preamble "twoside") - (cal-tex-filofax-paper) - (insert cal-tex-righthead) - (cal-tex-longday "rightday" "0.7in") - (insert cal-tex-lefthead) - (cal-tex-longday "leftday" "0.7in") - (cal-tex-b-document) - (cal-tex-cmd "\\pagestyle" "empty") - (dotimes (i n) - (if (evenp i) - (insert "\\righthead") - (insert "\\lefthead")) - (cal-tex-arg - (let ((d (cal-tex-incr-date date 6))) - (if (= (calendar-extract-month date) - (calendar-extract-month d)) - (format "%s %s" - (cal-tex-month-name (calendar-extract-month date)) - (calendar-extract-year date)) - (if (= (calendar-extract-year date) - (calendar-extract-year d)) - (format "%s---%s %s" - (cal-tex-month-name (calendar-extract-month date)) - (cal-tex-month-name (calendar-extract-month d)) - (calendar-extract-year date)) - (format "%s %s---%s %s" - (cal-tex-month-name (calendar-extract-month date)) - (calendar-extract-year date) - (cal-tex-month-name (calendar-extract-month d)) - (calendar-extract-year d)))))) - (insert "%\n") - (dotimes (_jdummy 7) - (if (evenp i) - (insert "\\rightday") - (insert "\\leftday")) - (cal-tex-arg (cal-tex-LaTeXify-string (calendar-day-name date))) - (cal-tex-arg (number-to-string (calendar-extract-day date))) - (cal-tex-arg (cal-tex-latexify-list diary-list date)) - (cal-tex-arg (cal-tex-latexify-list holidays date)) - (cal-tex-arg (eval cal-tex-daily-string t)) - (insert "%\n") - (setq date (cal-tex-incr-date date))) - (unless (= i (1- n)) - (run-hooks 'cal-tex-week-hook) - (cal-tex-newpage))) - (cal-tex-end-document) - (run-hooks 'cal-tex-hook))) - -;;;###cal-autoload -(defun cal-tex-cursor-filofax-week (&optional n event) - "One-week-at-a-glance Filofax style calendar for week indicated by cursor. -Optional prefix argument N specifies number of weeks (default 1), -starting on Mondays. The calendar shows holiday and diary entries -if `cal-tex-holidays' and `cal-tex-diary', respectively, are non-nil. -Optional EVENT indicates a buffer position to use instead of point." - (interactive (list (prefix-numeric-value current-prefix-arg) - last-nonmenu-event)) - (cal-tex-weekly-common n event t)) - -;;;###cal-autoload -(defun cal-tex-cursor-filofax-daily (&optional n event) - "Day-per-page Filofax style calendar for week indicated by cursor. -Optional prefix argument N specifies number of weeks (default 1), -starting on Mondays. The calendar shows holiday and diary -entries if `cal-tex-holidays' and `cal-tex-diary', respectively, -are non-nil. Pages are ruled if `cal-tex-rules' is non-nil. -Optional EVENT indicates a buffer position to use instead of point." - (interactive (list (prefix-numeric-value current-prefix-arg) - last-nonmenu-event)) - (or n (setq n 1)) - (with-suppressed-warnings ((lexical date)) - (defvar date)) ;For `cal-tex-daily-string'. - (let* ((date (calendar-gregorian-from-absolute - (calendar-dayname-on-or-before - 1 - (calendar-absolute-from-gregorian - (calendar-cursor-to-date t event))))) - ;; (month (calendar-extract-month date)) - ;; (year (calendar-extract-year date)) - ;; (day (calendar-extract-day date)) - (d1 (calendar-absolute-from-gregorian date)) - (d2 (+ (* 7 n) d1)) - (holidays (if cal-tex-holidays - (holiday-in-range d1 d2))) - (diary-list (if cal-tex-diary - (cal-tex-list-diary-entries d1 d2)))) - (cal-tex-preamble "twoside") - (cal-tex-filofax-paper) - (insert cal-tex-righthead) - (cal-tex-shortday "rightday") - (cal-tex-shortday "weekend") - (insert cal-tex-lefthead) - (cal-tex-shortday "leftday") - (insert "\\newbox\\LineBox -\\setbox\\LineBox=\\hbox to\\textwidth{% -\\vrule height.2in width0pt\\leaders\\hrule\\hfill} -\\def\\linesfill{\\par\\leaders\\copy\\LineBox\\vfill} -") - (cal-tex-b-document) - (cal-tex-cmd "\\pagestyle" "empty") - (dotimes (i n) - (dotimes (j 4) - (let ((even (evenp j))) - (insert (if even - "\\righthead" - "\\lefthead")) - (cal-tex-arg (calendar-date-string date)) - (insert "%\n") - (insert (if even - "\\rightday" - "\\leftday"))) - (cal-tex-arg (cal-tex-latexify-list diary-list date)) - (cal-tex-arg (cal-tex-latexify-list holidays date "\\\\" t)) - (cal-tex-arg (eval cal-tex-daily-string t)) - (insert "%\n") - (insert (if cal-tex-rules - "\\linesfill\n" - "\\vfill\\noindent\\rule{\\textwidth}{0.3pt}\\\\%\n")) - (cal-tex-newpage) - (setq date (cal-tex-incr-date date))) - (insert "%\n") - (dotimes (_jdummy 2) - (insert "\\lefthead") - (cal-tex-arg (calendar-date-string date)) - (insert "\\weekend") - (cal-tex-arg (cal-tex-latexify-list diary-list date)) - (cal-tex-arg (cal-tex-latexify-list holidays date "\\\\" t)) - (cal-tex-arg (eval cal-tex-daily-string t)) - (insert "%\n") - (insert (if cal-tex-rules - "\\linesfill\n" - "\\vfill")) - (setq date (cal-tex-incr-date date))) - (or cal-tex-rules - (insert "\\noindent\\rule{\\textwidth}{0.3pt}\\\\%\n")) - (unless (= i (1- n)) - (run-hooks 'cal-tex-week-hook) - (cal-tex-newpage))) - (cal-tex-end-document) - (run-hooks 'cal-tex-hook))) - - -;;; -;;; Daily calendars -;;; - -;;;###cal-autoload -(defun cal-tex-cursor-day (&optional n event) - "Make a buffer with LaTeX commands for the day cursor is on. -Optional prefix argument N specifies number of days. The calendar shows -the hours between `cal-tex-daily-start' and `cal-tex-daily-end', using -the 24-hour clock if `cal-tex-24' is non-nil. Optional EVENT indicates -a buffer position to use instead of point." - (interactive (list (prefix-numeric-value current-prefix-arg) - last-nonmenu-event)) - (or n (setq n 1)) - (let ((date (calendar-absolute-from-gregorian - (calendar-cursor-to-date t event)))) - (cal-tex-preamble "12pt") - (cal-tex-weekly-paper 'nomargins) - (cal-tex-b-document) - (cal-tex-cmd "\\pagestyle" "empty") - (dotimes (i n) - (cal-tex-vspace "-1.7in") - (cal-tex-daily-page (calendar-gregorian-from-absolute date)) - (setq date (1+ date)) - (unless (= i (1- n)) - (cal-tex-newpage) - (run-hooks 'cal-tex-daily-hook))) - (cal-tex-end-document) - (run-hooks 'cal-tex-hook))) - -(defun cal-tex-daily-page (thedate) - "Make a calendar page for Gregorian THEDATE on 8.5 by 11 paper. -Uses the 24-hour clock if `cal-tex-24' is non-nil. Produces -hourly sections for the period specified by `cal-tex-daily-start' -and `cal-tex-daily-end'." - (with-suppressed-warnings ((lexical date)) - (defvar date)) ;For `cal-tex-daily-string'. - (let* ((date thedate) - (month-name (cal-tex-month-name (calendar-extract-month date))) - (i (1- cal-tex-daily-start)) - hour) - (cal-tex-banner "cal-tex-daily-page") - (cal-tex-b-makebox "4cm" "l") - (cal-tex-b-parbox "b" "3.8cm") - (cal-tex-rule "0mm" "0mm" "2cm") - (cal-tex-Huge (number-to-string (calendar-extract-day date))) - (cal-tex-nl ".5cm") - (cal-tex-bf month-name ) - (cal-tex-e-parbox) - (cal-tex-hspace "1cm") - (cal-tex-scriptsize (eval cal-tex-daily-string t)) - (cal-tex-hspace "3.5cm") - (cal-tex-e-makebox) - (cal-tex-hfill) - (cal-tex-b-makebox "4cm" "r") - (cal-tex-bf (cal-tex-LaTeXify-string (calendar-day-name date))) - (cal-tex-e-makebox) - (cal-tex-nl) - (cal-tex-hspace ".4cm") - (cal-tex-rule "0mm" "16.1cm" "1mm") - (cal-tex-nl ".1cm") - (while (<= (setq i (1+ i)) cal-tex-daily-end) - (cal-tex-cmd "\\noindent") - (setq hour (if cal-tex-24 - i - (mod i 12))) - (if (zerop hour) (setq hour 12)) - (cal-tex-b-makebox "1cm" "c") - (cal-tex-arg (number-to-string hour)) - (cal-tex-e-makebox) - (cal-tex-rule "0mm" "15.5cm" ".2mm") - (cal-tex-nl ".2cm") - (cal-tex-b-makebox "1cm" "c") - (cal-tex-arg "$\\diamond$" ) - (cal-tex-e-makebox) - (cal-tex-rule "0mm" "15.5cm" ".2mm") - (cal-tex-nl ".2cm")) - (cal-tex-hfill) - (insert (cal-tex-mini-calendar - (calendar-extract-month (cal-tex-previous-month date)) - (calendar-extract-year (cal-tex-previous-month date)) - "lastmonth" "1.1in" "1in")) - (insert (cal-tex-mini-calendar - (calendar-extract-month date) - (calendar-extract-year date) - "thismonth" "1.1in" "1in")) - (insert (cal-tex-mini-calendar - (calendar-extract-month (cal-tex-next-month date)) - (calendar-extract-year (cal-tex-next-month date)) - "nextmonth" "1.1in" "1in")) - (insert "\\hbox to \\textwidth{") - (cal-tex-hfill) - (insert "\\lastmonth") - (cal-tex-hfill) - (insert "\\thismonth") - (cal-tex-hfill) - (insert "\\nextmonth") - (cal-tex-hfill) - (insert "}") - (cal-tex-banner "end of cal-tex-daily-page"))) - -;;; -;;; Mini calendars -;;; - -(defun cal-tex-mini-calendar (month year name width height &optional ptsize colsep) - "Produce mini-calendar for MONTH, YEAR in macro NAME with WIDTH and HEIGHT. -Optional string PTSIZE gives the point size (default \"scriptsize\"). -Optional string COLSEP gives the column separation (default \"1mm\")." - (or colsep (setq colsep "1mm")) - (or ptsize (setq ptsize "scriptsize")) - (let ((blank-days ; at start of month - (mod - (- (calendar-day-of-week (list month 1 year)) - calendar-week-start-day) - 7)) - (last( calendar-last-day-of-month month year)) - (str (concat "\\def\\" name "{\\hbox to" width "{%\n" - "\\vbox to" height "{%\n" - "\\vfil \\hbox to" width "{%\n" - "\\hfil\\" ptsize - "\\begin{tabular}" - "{@{\\hspace{0mm}}r@{\\hspace{" colsep - "}}r@{\\hspace{" colsep "}}r@{\\hspace{" colsep - "}}r@{\\hspace{" colsep "}}r@{\\hspace{" colsep - "}}r@{\\hspace{" colsep "}}r@{\\hspace{0mm}}}%\n" - "\\multicolumn{7}{c}{" - (cal-tex-month-name month) - " " - (number-to-string year) - "}\\\\[1mm]\n"))) - (dotimes (i 7) - (setq str - (concat str - (cal-tex-LaTeXify-string - (substring (aref calendar-day-name-array - (mod (+ calendar-week-start-day i) 7)) - - 0 2)) - (if (= i 6) - "\\\\[0.7mm]\n" - " & ")))) - (dotimes (_idummy blank-days) - (setq str (concat str " & "))) - (dotimes (i last) - (setq str (concat str (number-to-string (1+ i))) - str (concat str (if (zerop (mod (+ i 1 blank-days) 7)) - (if (= i (1- last)) - "" - "\\\\[0.5mm]\n") - " & ")))) - (setq str (concat str "\n\\end{tabular}\\hfil}\\vfil}}}%\n")) - str)) - -;;; -;;; Various calendar functions -;;; - -(defun cal-tex-incr-date (date &optional n) - "The date of the day following DATE. -If optional N is given, the date of N days after DATE." - (calendar-gregorian-from-absolute - (+ (or n 1) (calendar-absolute-from-gregorian date)))) - -(defun cal-tex-latexify-list (date-list date &optional separator final-separator) - "Return string with concatenated, LaTeX-ified entries in DATE-LIST for DATE. -Use double backslash as a separator unless optional SEPARATOR is given. -If resulting string is not empty, put separator at end if optional -FINAL-SEPARATOR is non-nil." - (or separator (setq separator "\\\\")) - (let (result) - (setq result - (mapconcat #'cal-tex-LaTeXify-string - (dolist (d date-list (reverse result)) - (and (car d) - (calendar-date-equal date (car d)) - (setq result (cons (cadr d) result)))) - separator)) - (if (and final-separator - (not (string-equal result ""))) - (concat result separator) - result))) - -(defun cal-tex-previous-month (date) - "Return the date of the first day in the month previous to DATE." - (let ((month (calendar-extract-month date)) - (year (calendar-extract-year date))) - (calendar-increment-month month year -1) - (list month 1 year))) - -(defun cal-tex-next-month (date) - "Return the date of the first day in the month following DATE." - (let ((month (calendar-extract-month date)) - (year (calendar-extract-year date))) - (calendar-increment-month month year 1) - (list month 1 year))) - -;;; -;;; LaTeX Code -;;; - -(defun cal-tex-end-document () - "Finish the LaTeX document. -Insert the trailer to LaTeX document, pop to LaTeX buffer, add -informative header, and run HOOK." - (cal-tex-e-document) - (or (and cal-tex-preamble-extra - (string-match "inputenc" cal-tex-preamble-extra)) - (when (re-search-backward "[^[:ascii:]]" nil 'move) - (goto-char (point-min)) - (when (search-forward "documentclass" nil t) - (forward-line 1) - ;; E.g., for some Bahá’í holidays. - ;; FIXME latin1 might not always be right. - (insert "\\usepackage[latin1]{inputenc}\n")))) - (latex-mode) - (pop-to-buffer (current-buffer)) - (goto-char (point-min)) - ;; FIXME auctex equivalents? - (cal-tex-comment - "\tThis buffer was produced by cal-tex.el. -\tTo print a calendar, type -\t\tM-x tex-buffer RET -\t\tM-x tex-print RET")) - -(defun cal-tex-insert-preamble (weeks &optional class-options append) - "Initialize the output LaTeX calendar buffer, `cal-tex-buffer'. -Select the output buffer, and insert the preamble for a calendar -of WEEKS weeks. Pass string CLASS-OPTIONS as options for the -article document class. If it contains \"landscape\", use the -geometry package to produce landscape format. Optional argument -APPEND, if non-nil, means add to end of buffer without erasing -current contents." - (let ((landscape (and class-options - (string-match "\\" class-options))) - (width "18cm") - (height "24cm")) - (when landscape - (let ((swap width)) - (setq width height height swap))) - (unless append - (cal-tex-preamble class-options) - (if (not landscape) - (progn - (cal-tex-cmd "\\oddsidemargin -1.75cm") - (cal-tex-cmd "\\def\\holidaymult" ".06")) - (cal-tex-cmd "\\textwidth 9.5in") - (cal-tex-cmd "\\textheight 7in") - (cal-tex-comment) - (cal-tex-cmd "\\def\\holidaymult" ".08")) - (cal-tex-cmd cal-tex-caldate) - (cal-tex-cmd cal-tex-myday) - (cal-tex-b-document) - (cal-tex-cmd "\\pagestyle" "empty")) - (cal-tex-cmd "\\setlength{\\cellwidth}" width) - (insert (format "\\setlength{\\cellwidth}{%f\\cellwidth}\n" - (/ 1.1 (length cal-tex-which-days)))) - (cal-tex-cmd "\\setlength{\\cellheight}" height) - (insert (format "\\setlength{\\cellheight}{%f\\cellheight}\n" - (/ 1.0 weeks))) - (cal-tex-cmd "\\ \\par") - (cal-tex-vspace "-3cm"))) - -(defconst cal-tex-LaTeX-subst-list - '(("\"". "``") - ("\"". "''") ; quote changes meaning when list is reversed - ;; Don't think this is necessary, and in any case, does not work: - ;; "LaTeX Error: \verb illegal in command argument". -;;; ("@" . "\\verb|@|") - ("&" . "\\&") - ("%" . "\\%") - ("$" . "\\$") - ("#" . "\\#") - ("_" . "\\_") - ("{" . "\\{") - ("}" . "\\}") - ("<" . "$<$") - (">" . "$>$") - ("\n" . "\\ \\\\")) ; \\ needed for e.g \begin{center}\n AA\end{center} - "Alist of symbols and their LaTeX replacements.") - -(defun cal-tex-LaTeXify-string (string) - "Protect special characters in STRING from LaTeX." - (if (not string) - "" - (let ((head "") - (tail string) - (list cal-tex-LaTeX-subst-list) - ch pair) - (while (not (string-equal tail "")) - (setq ch (substring-no-properties tail 0 1) - pair (assoc ch list)) - (if (and pair (string-equal ch "\"")) - (setq list (reverse list))) ; quote changes meaning each time - (setq tail (substring-no-properties tail 1) - head (concat head (if pair (cdr pair) ch)))) - head))) - -(defun cal-tex-month-name (month) - "The name of MONTH, LaTeX-ified." - (cal-tex-LaTeXify-string (calendar-month-name month))) - -(defun cal-tex-hfill () - "Insert hfill." - (insert "\\hfill")) - -(defun cal-tex-newpage () - "Insert newpage." - (insert "\\newpage%\n")) - -(defun cal-tex-noindent () - "Insert noindent." - (insert "\\noindent")) - -(defun cal-tex-vspace (space) - "Insert vspace command to move SPACE vertically." - (cal-tex-cmd "\\vspace*" space)) - -(defun cal-tex-hspace (space) - "Insert hspace command to move SPACE horizontally." - (cal-tex-cmd "\\hspace*" space)) - -(defun cal-tex-comment (&optional comment) - "Insert \"% \", followed by optional string COMMENT, followed by newline. -COMMENT may contain newlines, which are prefixed by \"% \" in the output." - (insert (format "%% %s\n" - (if comment - (string-replace "\n" "\n% " comment) - "")))) - -(defun cal-tex-banner (comment) - "Insert string COMMENT, separated by blank lines." - (cal-tex-comment (format "\n\n\n\t\t\t%s\n" comment))) - -(defun cal-tex-nl (&optional skip comment) - "End a line with \\. If SKIP, then add that much spacing. -Add trailing COMMENT if present." - (insert (format "\\\\%s" - (if skip - (format "[%s]" skip) - ""))) - (cal-tex-comment comment)) - -(defun cal-tex-arg (&optional text) - "Insert a brace {} pair containing the optional string TEXT." - (insert (format "{%s}" (or text "")))) - -(defun cal-tex-cmd (cmd &optional arg) - "Insert LaTeX CMD, with optional argument ARG, and end with %." - (insert cmd) - (cal-tex-arg arg) - (cal-tex-comment)) - -;;; -;;; Environments -;;; - -(defun cal-tex-b-document () - "Insert beginning of document." - (cal-tex-cmd "\\begin" "document")) - -(defun cal-tex-e-document () - "Insert end of document." - (cal-tex-cmd "\\end" "document")) - -(defun cal-tex-b-center () - "Insert beginning of centered block." - (cal-tex-cmd "\\begin" "center")) - -(defun cal-tex-e-center () - "Insert end of centered block." - (cal-tex-comment) - (cal-tex-cmd "\\end" "center")) - - -;;; -;;; Boxes -;;; - - -(defun cal-tex-b-parbox (position width) - "Insert parbox with parameters POSITION and WIDTH." - (insert "\\parbox[" position "]{" width "}{") - (cal-tex-comment)) - -(defun cal-tex-e-parbox (&optional height) - "Insert end of parbox. Optionally, force it to be a given HEIGHT." - (cal-tex-comment) - (if height - (cal-tex-rule "0mm" "0mm" height)) - (insert "}") - (cal-tex-comment "end parbox")) - -(defun cal-tex-b-framebox (width position) - "Insert framebox with parameters WIDTH and POSITION (clr)." - (insert "\\framebox[" width "][" position "]{" ) - (cal-tex-comment)) - -(defun cal-tex-e-framebox () - "Insert end of framebox." - (cal-tex-comment) - (insert "}") - (cal-tex-comment "end framebox")) - - -(defun cal-tex-b-makebox (width position) - "Insert makebox with parameters WIDTH and POSITION (clr)." - (insert "\\makebox[" width "][" position "]{" ) - (cal-tex-comment)) - -(defun cal-tex-e-makebox () - "Insert end of makebox." - (cal-tex-comment) - (insert "}") - (cal-tex-comment "end makebox")) - - -(defun cal-tex-rule (lower width height) - "Insert a rule with parameters LOWER WIDTH HEIGHT." - (insert "\\rule[" lower "]{" width "}{" height "}")) - -;;; -;;; Fonts -;;; - -(defun cal-tex-em (string) - "Insert STRING in italic font." - (cal-tex-cmd "\\textit" string)) - -(defun cal-tex-bf (string) - "Insert STRING in bf font." - (cal-tex-cmd "\\textbf" string)) - -(defun cal-tex-scriptsize (string) - "Insert STRING in scriptsize font." - (cal-tex-arg (concat "\\scriptsize " string))) - -(defun cal-tex-huge (string) - "Insert STRING in huge font." - (cal-tex-arg (concat "\\huge " string))) - -(defun cal-tex-Huge (string) - "Insert STRING in Huge font." - (cal-tex-arg (concat "\\Huge " string))) - -(defun cal-tex-Huge-bf (string) - "Insert STRING in Huge bf font." - (cal-tex-cmd "\\textbf" (concat "\\Huge " string))) - -(defun cal-tex-large (string) - "Insert STRING in large font." - (cal-tex-arg (concat "\\large " string))) - -(defun cal-tex-large-bf (string) - "Insert STRING in large bf font." - (cal-tex-cmd "\\textbf" (concat "\\large " string))) - - -(provide 'cal-tex) - -;;; cal-tex.el ends here diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index dce1b6f818b..15c55315af5 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -1889,7 +1889,7 @@ It is too wide if it has any lines longer than the largest of f "the function `%s' might not be defined at runtime." (car urf)) (byte-compile-warn-with-fix - '("Fix it" elisp-create-missing-defun) + `("Fix it" ,#'elisp-create-missing-defun) f "the function `%s' is not known to be defined." (car urf)))))))) nil) diff --git a/lisp/files.el b/lisp/files.el index 06893e91d67..d5b16a6f58d 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -2964,10 +2964,6 @@ since only a single case-insensitive search through the alist is made." ("\\.jpe?g\\'" . image-mode) ("\\.webp\\'" . image-mode) ("\\.te?xt\\'" . text-mode) - ("\\.[tT]e[xX]\\'" . tex-mode) - ("\\.ins\\'" . tex-mode) ;Installation files for TeX packages. - ("\\.ltx\\'" . latex-mode) - ("\\.dtx\\'" . doctex-mode) ("\\.org\\'" . org-mode) ;; .dir-locals.el is not really Elisp. Could use the ;; `dir-locals-file' constant if it weren't defined below. @@ -3005,8 +3001,6 @@ since only a single case-insensitive search through the alist is made." ("\\.am\\'" . makefile-automake-mode) ;; Less common extensions come here ;; so more common ones above are found faster. - ("\\.texinfo\\'" . texinfo-mode) - ("\\.te?xi\\'" . texinfo-mode) ("\\.[sS]\\'" . asm-mode) ("\\.asm\\'" . asm-mode) ("\\.css\\'" . css-mode) @@ -3037,9 +3031,6 @@ since only a single case-insensitive search through the alist is made." ("\\.m?spec\\'" . sh-mode) ("\\.m[mes]\\'" . nroff-mode) ("\\.man\\'" . nroff-mode) - ("\\.sty\\'" . latex-mode) - ("\\.cl[so]\\'" . latex-mode) ;LaTeX 2e class option - ("\\.bbl\\'" . latex-mode) ("\\.bib\\'" . bibtex-mode) ("\\.bst\\'" . bibtex-style-mode) ("\\.sql\\'" . sql-mode) diff --git a/lisp/info-look.el b/lisp/info-look.el index bc65d7daef1..c1e0ce8c164 100644 --- a/lisp/info-look.el +++ b/lisp/info-look.el @@ -1072,7 +1072,6 @@ Return nil if there is nothing appropriate in the buffer near point." ("octave" "(octave-mode)Variable Index" "(octave-mode)Lisp Function Index") ("org" "Variable Index" "Command and Function Index") ("rcirc" "Variable Index" "Index") - ("reftex" "Index") ("sasl" "Variable Index" "Function Index") ("sc" "Variable Index") ("ses" "Index") diff --git a/lisp/org/ol-info.el b/lisp/org/ol-info.el index 4ce1eb6e73c..37102420eb1 100644 --- a/lisp/org/ol-info.el +++ b/lisp/org/ol-info.el @@ -133,7 +133,7 @@ If LINK is not an info link then DESC is returned." "elisp" "emacs-gnutls" "emacs-mime" "emacs" "epa" "erc" "ert" "eshell" "eudc" "eww" "flymake" "forms" "gnus" "htmlfontify" "ido" "info" "mairix-el" "message" "modus-themes" "newsticker" "nxml-mode" "octave-mode" - "org" "pcl-cvs" "pgg" "rcirc" "reftex" "remember" "sasl" "sc" "semantic" + "org" "pcl-cvs" "pgg" "rcirc" "remember" "sasl" "sc" "semantic" "ses" "sieve" "smtpmail" "speedbar" "srecode" "todo-mode" "tramp" "transient" "url" "use-package" "vip" "vtable" "widget" "wisent" "woman") "List of Emacs documents available. diff --git a/lisp/org/org-keys.el b/lisp/org/org-keys.el index d00e3d33e56..1391a709490 100644 --- a/lisp/org/org-keys.el +++ b/lisp/org/org-keys.el @@ -164,7 +164,6 @@ (declare-function org-refile "org-refile" (&optional arg1 default-buffer rfloc msg)) (declare-function org-refile-copy "org-refile" ()) (declare-function org-refile-reverse "org-refile" (&optional arg default-buffer rfloc msg)) -(declare-function org-reftex-citation "org" ()) (declare-function org-reload "org" (&optional arg1)) (declare-function org-remove-file "org" (&optional file)) (declare-function org-resolve-clocks "org" (&optional only-dangling-p prompt-fn last-valid)) @@ -641,7 +640,6 @@ COMMANDS is a list of alternating OLDDEF NEWDEF command names." (org-defkey org-mode-map (kbd "C-c C-x g") #'org-feed-update-all) (org-defkey org-mode-map (kbd "C-c C-x G") #'org-feed-goto-inbox) (org-defkey org-mode-map (kbd "C-c C-x @") #'org-cite-insert) -(org-defkey org-mode-map (kbd "C-c C-x [") #'org-reftex-citation) (org-defkey org-mode-map (kbd "C-c C-x I") #'org-info-find-node) diff --git a/lisp/org/org.el b/lisp/org/org.el index 9902fc2d01b..5f9158fc9ad 100644 --- a/lisp/org/org.el +++ b/lisp/org/org.el @@ -18922,8 +18922,7 @@ an argument, unconditionally call `org-insert-heading'." ["Insert Environment" cdlatex-environment (fboundp 'cdlatex-environment)] ["Insert math symbol" cdlatex-math-symbol (fboundp 'cdlatex-math-symbol)] ["Modify math symbol" org-cdlatex-math-modify - (org-inside-LaTeX-fragment-p)] - ["Insert citation" org-reftex-citation t]) + (org-inside-LaTeX-fragment-p)]) "--" ("Documentation" ["Show Version" org-version t] @@ -21016,36 +21015,8 @@ When NEED-NAME is nil, the drop is complete." ;;; Other stuff -(defvar reftex-docstruct-symbol) (defvar org--rds) -(defun org-reftex-citation () - "Use `reftex-citation' to insert a citation into the buffer. -This looks for a line like - -#+BIBLIOGRAPHY: foo plain option:-d - -and derives from it that foo.bib is the bibliography file relevant -for this document. It then installs the necessary environment for RefTeX -to work in this buffer and calls `reftex-citation' to insert a citation -into the buffer. - -Export of such citations to both LaTeX and HTML is handled by the contributed -package ox-bibtex by Taru Karttunen." - (interactive) - (let ((reftex-docstruct-symbol 'org--rds) - org--rds bib) - (org-with-wide-buffer - (let ((case-fold-search t) - (re "^[ \t]*#\\+BIBLIOGRAPHY:[ \t]+\\([^ \t\n]+\\)")) - (if (not (save-excursion - (or (re-search-forward re nil t) - (re-search-backward re nil t)))) - (user-error "No bibliography defined in file") - (setq bib (concat (match-string 1) ".bib") - org--rds (list (list 'bib bib)))))) - (call-interactively 'reftex-citation))) - ;;;; Functions extending outline functionality (defun org-beginning-of-line (&optional n) diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el index 2bef0573bed..478ba738654 100644 --- a/lisp/textmodes/bibtex.el +++ b/lisp/textmodes/bibtex.el @@ -1656,9 +1656,7 @@ Set this variable before loading BibTeX mode." "--" ["Narrow to Entry" bibtex-narrow-to-entry t] ["Mark Entry" bibtex-mark-entry t] - "--" - ["View Cite Locations (RefTeX)" reftex-view-crossref-from-bibtex - (fboundp 'reftex-view-crossref-from-bibtex)]) + "--") ("Operating on Buffer or Region" ["Search Entries" bibtex-search-entries t] "--" diff --git a/lisp/textmodes/flyspell.el b/lisp/textmodes/flyspell.el index d2989916dd1..151454d67a7 100644 --- a/lisp/textmodes/flyspell.el +++ b/lisp/textmodes/flyspell.el @@ -359,21 +359,6 @@ property of the major mode name.") (forward-word-strictly -1) (not (looking-at "@")))) -;;*--- tex mode --------------------------------------------------------*/ -(put 'tex-mode 'flyspell-mode-predicate 'tex-mode-flyspell-verify) -(defun tex-mode-flyspell-verify () - "Function used for `flyspell-generic-check-word-predicate' in LaTeX mode." - (and - (not (save-excursion - (re-search-backward "^[ \t]*%%%[ \t]+Local" nil t))) - (not (save-excursion - (let ((this (point))) - (beginning-of-line) - (and (re-search-forward "\\\\\\(cite\\|label\\|ref\\){[^}]*}" - (line-end-position) t) - (>= this (match-beginning 0)) - (<= this (match-end 0)))))))) - ;;*--- sgml mode -------------------------------------------------------*/ (put 'sgml-mode 'flyspell-mode-predicate 'sgml-mode-flyspell-verify) (put 'html-mode 'flyspell-mode-predicate 'sgml-mode-flyspell-verify) diff --git a/lisp/textmodes/makeinfo.el b/lisp/textmodes/makeinfo.el deleted file mode 100644 index 9c1d0c5223a..00000000000 --- a/lisp/textmodes/makeinfo.el +++ /dev/null @@ -1,299 +0,0 @@ -;;; makeinfo.el --- run makeinfo conveniently -*- lexical-binding: t; -*- - -;; Copyright (C) 1991, 1993, 2001-2025 Free Software Foundation, Inc. - -;; Author: Robert J. Chassell -;; Maintainer: emacs-devel@gnu.org -;; Keywords: docs convenience - -;; 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 . - -;;; Commentary: - -;;; The Texinfo mode `makeinfo' related commands are: - -;; makeinfo-region to run makeinfo on the current region. -;; makeinfo-buffer to run makeinfo on the current buffer, or -;; with optional prefix arg, on current region -;; kill-compilation to kill currently running makeinfo job -;; makeinfo-recenter-makeinfo-buffer to redisplay *compilation* buffer - -;;; Keybindings (defined in `texinfo.el') - -;; makeinfo bindings -; (keymap-set texinfo-mode-map "C-c C-m C-r" 'makeinfo-region) -; (keymap-set texinfo-mode-map "C-c C-m C-b" 'makeinfo-buffer) -; (keymap-set texinfo-mode-map "C-c C-m C-k" 'kill-compilation) -; (keymap-set texinfo-mode-map "C-c C-m C-l" -; 'makeinfo-recenter-compilation-buffer) - -;;; Code: - -;;; Variables used by `makeinfo' - -(require 'compile) -(require 'info) - -(defvar tex-end-of-header) -(defvar tex-start-of-header) - - -(defgroup makeinfo nil - "Run makeinfo conveniently." - :group 'docs) - - -(defcustom makeinfo-run-command - (cond ((executable-find "makeinfo") "makeinfo") - ((executable-find "texi2any") "texi2any") - (t "makeinfo")) - "Command used to run `makeinfo' subjob. -The name of the file is appended to this string, separated by a space." - :type 'string - :version "31.1") - -(defcustom makeinfo-options "--fill-column=70" - "String containing options for running `makeinfo'. -Do not include `--footnote-style' or `--paragraph-indent'; -the proper way to specify those is with the Texinfo commands -`@footnotestyle' and `@paragraphindent'." - :type 'string) - -(require 'texinfo) - -(defvar makeinfo-compilation-process nil - "Process that runs `makeinfo'. Should start out nil.") - -(defvar makeinfo-temp-file nil - "Temporary file name used for text being sent as input to `makeinfo'.") - -(defvar makeinfo-output-file-name nil - "Info file name used for text output by `makeinfo'.") - -(defvar makeinfo-output-node-name nil - "Node name to visit in output file, for `makeinfo-buffer'.") - - -;;; The `makeinfo' function definitions - -;;;###autoload -(defun makeinfo-region (region-beginning region-end) - "Make Info file from region of current Texinfo file, and switch to it. - -This command does not offer the `next-error' feature since it would -apply to a temporary file, not the original; use the `makeinfo-buffer' -command to gain use of `next-error'." - - (interactive "r") - (let (;; filename-or-header - filename-or-header-beginning - filename-or-header-end) - ;; Cannot use `let' for makeinfo-temp-file or - ;; makeinfo-output-file-name since `makeinfo-compilation-sentinel' - ;; needs them. - - (setq makeinfo-temp-file - (concat - (make-temp-file - (substring (buffer-file-name) - 0 - (or (string-match "\\.tex" (buffer-file-name)) - (length (buffer-file-name))))) - ".texinfo")) - - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (let ((search-end (save-excursion (forward-line 100) (point)))) - ;; Find and record the Info filename, - ;; or else explain that a filename is needed. - (if (re-search-forward - "^@setfilename[ \t]+\\([^ \t\n]+\\)[ \t]*" - search-end t) - (setq makeinfo-output-file-name - (buffer-substring (match-beginning 1) (match-end 1))) - (error - "The texinfo file needs a line saying: @setfilename ")) - - ;; Find header and specify its beginning and end. - (goto-char (point-min)) - (if (and - (prog1 - (search-forward tex-start-of-header search-end t) - (beginning-of-line) - ;; Mark beginning of header. - (setq filename-or-header-beginning (point))) - (prog1 - (search-forward tex-end-of-header nil t) - (beginning-of-line) - ;; Mark end of header - (setq filename-or-header-end (point)))) - - ;; Insert the header into the temporary file. - (write-region - (min filename-or-header-beginning region-beginning) - filename-or-header-end - makeinfo-temp-file nil nil) - - ;; Else no header; insert @filename line into temporary file. - (goto-char (point-min)) - (search-forward "@setfilename" search-end t) - (beginning-of-line) - (setq filename-or-header-beginning (point)) - (forward-line 1) - (setq filename-or-header-end (point)) - (write-region - (min filename-or-header-beginning region-beginning) - filename-or-header-end - makeinfo-temp-file nil nil)) - - ;; Insert the region into the file. - (write-region - (max region-beginning filename-or-header-end) - region-end - makeinfo-temp-file t nil) - - ;; Run the `makeinfo-compile' command in the *compilation* buffer - (save-excursion - (makeinfo-compile - (concat makeinfo-run-command - " " - makeinfo-options - " " - makeinfo-temp-file) - t - 'makeinfo-compilation-sentinel-region))))))) - -(defun makeinfo-next-error (_arg _reset) - "This is used to disable `next-error' if the user has used `makeinfo-region'. -Since the compilation process is used on a temporary file in that -case, calling `next-error' would give nonsensical results." - (error "Use `makeinfo-buffer' to gain use of the `next-error' command")) - -;; Actually run makeinfo. COMMAND is the command to run. If -;; DISABLE-ERRORS is non-nil, disable `next-error' by setting -;; `next-error-function' to `makeinfo-next-error' in the compilation -;; buffer. -(defun makeinfo-compile (command disable-errors sentinel) - (let ((buffer (compilation-start command))) - (with-current-buffer buffer - (setq next-error-function - (if disable-errors - 'makeinfo-next-error - 'compilation-next-error-function))) - (set-process-sentinel (get-buffer-process buffer) sentinel))) - -;; Delete makeinfo-temp-file after processing is finished, -;; and visit Info file. -;; This function is called when the compilation process changes state. -;; Based on `compilation-sentinel' in compile.el -(defun makeinfo-compilation-sentinel-region (proc msg) - "Sentinel for `makeinfo-compile' run from `makeinfo-region'." - (compilation-sentinel proc msg) - (when (memq (process-status proc) '(signal exit)) - (if (file-exists-p makeinfo-temp-file) - (delete-file makeinfo-temp-file)) - ;; Always use the version on disk. - (let ((buffer (get-file-buffer makeinfo-output-file-name))) - (if buffer - (with-current-buffer buffer - (revert-buffer t t)) - (setq buffer (find-file-noselect makeinfo-output-file-name))) - (if (window-dedicated-p) - (switch-to-buffer-other-window buffer) - (switch-to-buffer buffer))) - (goto-char (point-min)))) - -(defun makeinfo-current-node () - "Return the name of the node containing point, in a texinfo file." - (save-excursion - (end-of-line) ; in case point is at the start of an @node line - (if (re-search-backward "^@node\\s-+\\([^,\n]+\\)" (point-min) t) - (match-string 1) - "Top"))) - -;;;###autoload -(defun makeinfo-buffer () - "Make Info file from current buffer. - -Use the \\[next-error] command to move to the next error -\(if there are errors)." - - (interactive) - (cond ((null buffer-file-name) - (error "Buffer not visiting any file")) - ((buffer-modified-p) - (if (y-or-n-p "Buffer modified; do you want to save it? ") - (save-buffer)))) - - ;; Find and record the Info filename, - ;; or else explain that a filename is needed. - (save-excursion - (goto-char (point-min)) - (let ((search-end (save-excursion (forward-line 100) (point)))) - (if (re-search-forward - "^@setfilename[ \t]+\\([^ \t\n]+\\)[ \t]*" - search-end t) - (setq makeinfo-output-file-name - (expand-file-name - (buffer-substring (match-beginning 1) (match-end 1)))) - (error - "The texinfo file needs a line saying: @setfilename ")))) - (setq makeinfo-output-node-name (makeinfo-current-node)) - - (save-excursion - (let ((default-directory (file-name-directory buffer-file-name))) - (makeinfo-compile - (concat makeinfo-run-command " " makeinfo-options - " " (file-name-nondirectory buffer-file-name)) - nil - 'makeinfo-compilation-sentinel-buffer)))) - -(defun makeinfo-compilation-sentinel-buffer (proc msg) - "Sentinel for `makeinfo-compile' run from `makeinfo-buffer'." - (compilation-sentinel proc msg) - (when (memq (process-status proc) '(signal exit)) - (when (file-exists-p makeinfo-output-file-name) - (Info-revert-find-node - makeinfo-output-file-name makeinfo-output-node-name)))) - -;;;###autoload -(defun makeinfo-recenter-compilation-buffer (linenum) - "Redisplay `*compilation*' buffer so most recent output can be seen. -The last line of the buffer is displayed on -line LINE of the window, or centered if LINE is nil." - (interactive "P") - (let ((makeinfo-buffer (get-buffer "*compilation*")) - (old-buffer (current-buffer))) - (if (null makeinfo-buffer) - (message "No *compilation* buffer") - (pop-to-buffer makeinfo-buffer) - (bury-buffer makeinfo-buffer) - (goto-char (point-max)) - (recenter (if linenum - (prefix-numeric-value linenum) - (/ (window-height) 2))) - (pop-to-buffer old-buffer) - ))) - -(provide 'makeinfo) - -;; Local Variables: -;; generated-autoload-file: "texinfo-loaddefs.el" -;; End: - -;;; makeinfo.el ends here diff --git a/lisp/textmodes/reftex-auc.el b/lisp/textmodes/reftex-auc.el deleted file mode 100644 index 88cf1b1a3cf..00000000000 --- a/lisp/textmodes/reftex-auc.el +++ /dev/null @@ -1,245 +0,0 @@ -;;; reftex-auc.el --- RefTeX's interface to AUCTeX -*- lexical-binding: t; -*- - -;; Copyright (C) 1997-2025 Free Software Foundation, Inc. - -;; Author: Carsten Dominik -;; Maintainer: auctex-devel@gnu.org - -;; 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 . - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl-lib)) - -(require 'reftex) - -(declare-function TeX-argument-prompt "ext:tex" - (optional prompt default &optional complete)) -(declare-function TeX-argument-insert "ext:tex" - (name optional &optional prefix)) -(declare-function LaTeX-add-labels "ext:latex" (&rest labels) t) -(declare-function LaTeX-add-index-entries "ext:latex" (&rest index-entries) t) -(declare-function LaTeX-add-bibitems "ext:latex" (&rest bibitems) t) -(declare-function LaTeX-bibitem-list "ext:latex" () t) -(declare-function LaTeX-index-entry-list "ext:latex" () t) -(declare-function LaTeX-label-list "ext:latex" () t) -(declare-function multi-prompt "ext:multi-prompt" - (separator unique prompt table &optional - mp-predicate require-match initial history)) - -(defun reftex-plug-flag (which) - ;; Tell if a certain flag is set in reftex-plug-into-AUCTeX - (or (eq t reftex-plug-into-AUCTeX) - (and (listp reftex-plug-into-AUCTeX) - (nth which reftex-plug-into-AUCTeX)))) - -;;;###autoload -(defun reftex-arg-label (optional &optional prompt definition) - "Use `reftex-label', `reftex-reference' or AUCTeX's code to insert label arg. -What is being used depends upon `reftex-plug-into-AUCTeX'." - (let (label) - (cond - ((and definition (reftex-plug-flag 1)) - ;; Create a new label, with a temporary brace for `reftex-what-macro' - (unwind-protect - (progn (insert "{") (setq label (or (reftex-label nil t) ""))) - (delete-char -1))) - ((and (not definition) (reftex-plug-flag 2)) - ;; Reference a label with RefTeX - (setq label (reftex-reference nil t))) - (t - ;; AUCTeX's default mechanism - (setq label (completing-read (TeX-argument-prompt optional prompt "Key") - (LaTeX-label-list))))) - (if (and definition (not (string-equal "" label))) - (LaTeX-add-labels label)) - (TeX-argument-insert label optional))) - -;;;###autoload -(defun reftex-arg-cite (optional &optional prompt definition) - "Use `reftex-citation' or AUCTeX's code to insert a cite-key macro argument. -What is being used depends upon `reftex-plug-into-AUCTeX'." - (let (items) - (cond - ((and (not definition) (reftex-plug-flag 3)) - (setq items (or (reftex-citation t) (list "")))) - (t - (setq prompt (concat (if optional "(Optional) " "") - (if prompt prompt "Add key") - " (default none): ")) - (setq items (multi-prompt "," t prompt (LaTeX-bibitem-list))))) - (apply #'LaTeX-add-bibitems items) - (TeX-argument-insert (mapconcat #'identity items reftex-cite-key-separator) - optional))) - -;;;###autoload -(defun reftex-arg-index-tag (optional &optional prompt &rest _args) - "Prompt for an index tag with completion. -This is the name of an index, not the entry." - (let (tag taglist) - (setq prompt (concat (if optional "(Optional) " "") - (if prompt prompt "Index tag") - " (default none): ")) - (if (and reftex-support-index (reftex-plug-flag 4)) - ;; Use RefTeX completion - (progn - (reftex-access-scan-info nil) - (setq taglist - (cdr (assoc 'index-tags - (symbol-value reftex-docstruct-symbol))) - tag (completing-read prompt (mapcar #'list taglist)))) - ;; Just ask like AUCTeX does. - (setq tag (read-string prompt))) - (TeX-argument-insert tag optional))) - -;;;###autoload -(defun reftex-arg-index (optional &optional prompt &rest _args) - "Prompt for an index entry completing with known entries. -Completion is specific for just one index, if the macro or a tag -argument identify one of multiple indices." - (let* (tag key) - (if (and reftex-support-index (reftex-plug-flag 4)) - (progn - (reftex-access-scan-info nil) - (setq tag (reftex-what-index-tag) - key (reftex-index-complete-key (or tag "idx")))) - (setq key (completing-read (TeX-argument-prompt optional prompt "Key") - (LaTeX-index-entry-list)))) - (unless (string-equal "" key) - (LaTeX-add-index-entries key)) - (TeX-argument-insert key optional))) - -(defun reftex-what-index-tag () - ;; Look backward to find out what index the macro at point belongs to - (let ((macro (save-excursion - (and (re-search-backward "\\\\[a-zA-Z*]+" nil t) - (match-string 0)))) - tag entry) - (when (and macro - (setq entry (assoc macro reftex-index-macro-alist))) - (setq tag (nth 1 entry)) - (cond - ((stringp tag) tag) - ((integerp tag) - (save-excursion - (goto-char (match-end 0)) - (or (reftex-nth-arg tag (nth 6 entry)) "idx"))) - (t "idx"))))) - -(defvar LaTeX-label-function) -;;;###autoload -(defun reftex-plug-into-AUCTeX () - ;; Replace AUCTeX functions with RefTeX functions. - ;; Which functions are replaced is controlled by the variable - ;; `reftex-plug-into-AUCTeX'. - - (if (reftex-plug-flag 0) - (if (bound-and-true-p LaTeX-label-function) - (add-function :override LaTeX-label-function #'reftex-label) - (setq LaTeX-label-function #'reftex-label)) - (if (eq #'reftex-label (bound-and-true-p LaTeX-label-function)) - (setq LaTeX-label-function nil) - (remove-function LaTeX-label-function #'reftex-label))) - - (if (or (reftex-plug-flag 1) (reftex-plug-flag 2)) - (advice-add 'TeX-arg-label :override #'reftex-arg-label) - (advice-remove 'TeX-arg-label #'reftex-arg-label)) - - (if (reftex-plug-flag 3) - (advice-add 'TeX-arg-cite :override #'reftex-arg-cite) - (advice-remove 'TeX-arg-cite #'reftex-arg-cite)) - - (if (reftex-plug-flag 4) - (advice-add 'TeX-arg-index-tag :override #'reftex-arg-index-tag) - (advice-remove 'TeX-arg-index-tag #'reftex-arg-index-tag)) - (if (reftex-plug-flag 4) - (advice-add 'TeX-arg-index :override #'reftex-arg-index) - (advice-remove 'TeX-arg-index #'reftex-arg-index))) - -;;;###autoload -(defun reftex-toggle-plug-into-AUCTeX () - "Toggle Interface between AUCTeX and RefTeX on and off." - (interactive) - (unless (and (featurep 'tex-site) (featurep 'latex)) - (error "AUCTeX's LaTeX mode does not seem to be loaded")) - (setq reftex-plug-into-AUCTeX (not reftex-plug-into-AUCTeX)) - (reftex-plug-into-AUCTeX) - (if reftex-plug-into-AUCTeX - (message "RefTeX has been plugged into AUCTeX.") - (message "RefTeX no longer interacts with AUCTeX."))) - -;;;###autoload -(defun reftex-add-label-environments (entry-list) - "Add label environment descriptions to `reftex-label-alist-style'. -The format of ENTRY-LIST is exactly like `reftex-label-alist'. See there -for details. -This function makes it possible to support RefTeX from AUCTeX style files. -The entries in ENTRY-LIST will be processed after the user settings in -`reftex-label-alist', and before the defaults (specified in -`reftex-default-label-alist-entries'). Any changes made to -`reftex-label-alist-style' will raise a flag to the effect that -the label information is recompiled on next use." - (unless reftex-docstruct-symbol - (reftex-tie-multifile-symbols)) - (when (and reftex-docstruct-symbol - (symbolp reftex-docstruct-symbol)) - (let ((list (get reftex-docstruct-symbol 'reftex-label-alist-style)) - entry changed) - (while entry-list - (setq entry (pop entry-list)) - (unless (member entry list) - (setq reftex-tables-dirty t - changed t) - (push entry list))) - (when changed - (put reftex-docstruct-symbol 'reftex-label-alist-style list))))) -;;;###autoload -(defalias 'reftex-add-to-label-alist #'reftex-add-label-environments) - -;;;###autoload -(defun reftex-add-section-levels (entry-list) - "Add entries to the value of `reftex-section-levels'. -The added values are kept local to the current document. The format -of ENTRY-LIST is a list of cons cells (\"MACRONAME\" . LEVEL). See -`reftex-section-levels' for an example." - (unless reftex-docstruct-symbol - (reftex-tie-multifile-symbols)) - (when (and reftex-docstruct-symbol - (symbolp reftex-docstruct-symbol)) - (let ((list (get reftex-docstruct-symbol 'reftex-section-levels)) - entry changed) - (while entry-list - (setq entry (pop entry-list)) - (unless (member entry list) - (setq reftex-tables-dirty t - changed t) - (push entry list))) - (when changed - (put reftex-docstruct-symbol 'reftex-section-levels list))))) - -;;;###autoload -(defun reftex-notice-new-section () - (reftex-notice-new 1 'force)) - -(provide 'reftex-auc) - -;;; reftex-auc.el ends here - -;; Local Variables: -;; generated-autoload-file: "reftex-loaddefs.el" -;; End: diff --git a/lisp/textmodes/reftex-cite.el b/lisp/textmodes/reftex-cite.el deleted file mode 100644 index 6c6d551063f..00000000000 --- a/lisp/textmodes/reftex-cite.el +++ /dev/null @@ -1,1349 +0,0 @@ -;;; reftex-cite.el --- creating citations with RefTeX -*- lexical-binding: t; -*- - -;; Copyright (C) 1997-2025 Free Software Foundation, Inc. - -;; Author: Carsten Dominik -;; Maintainer: auctex-devel@gnu.org - -;; 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 . - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl-lib)) - -(require 'reftex) - -;;; Variables and constants -(defvar reftex-cite-regexp-hist nil - "The history list of regular expressions used for citations.") - -(defconst reftex-citation-prompt - "Select: [n]ext [p]revious [r]estrict [ ]full_entry [q]uit RET [?]Help+more" - "Prompt and help string for citation selection.") - -(defconst reftex-citation-help - " n / p Go to next/previous entry (Cursor motion works as well). - g / r Start over with new regexp / Refine with additional regexp. - SPC Show full database entry in other window. - f Toggle follow mode: Other window will follow with full db entry. - . Show insertion point. - q Quit without inserting \\cite macro into buffer. - TAB Enter citation key with completion. - RET Accept current entry (also on mouse-2) and create \\cite macro. - m / u Mark/Unmark the entry. - e / E Create BibTeX file with all (marked/unmarked) entries - a / A Put all (marked) entries into one/many \\cite commands.") - -;;; Find bibtex files -(defmacro reftex-with-special-syntax-for-bib (&rest body) - `(let ((saved-syntax (syntax-table))) - (unwind-protect - (progn - (set-syntax-table reftex-syntax-table-for-bib) - ,@body) - (set-syntax-table saved-syntax)))) - -;;;###autoload -(defun reftex-default-bibliography () - "Return the expanded value of variable `reftex-default-bibliography'. -The expanded value is cached." - (unless (eq (get 'reftex-default-bibliography :reftex-raw) - reftex-default-bibliography) - (put 'reftex-default-bibliography :reftex-expanded - (reftex-locate-bibliography-files - default-directory reftex-default-bibliography)) - (put 'reftex-default-bibliography :reftex-raw - reftex-default-bibliography)) - (get 'reftex-default-bibliography :reftex-expanded)) - -;;;###autoload -(defun reftex-bib-or-thebib () - "Test if BibTeX or \\begin{thebibliography} should be used for the citation. -Find the bof of the current file." - (let* ((docstruct (symbol-value reftex-docstruct-symbol)) - (rest (or (member (list 'bof (reftex--get-buffer-identifier)) - docstruct) - docstruct)) - (bib (assq 'bib rest)) - (thebib (assq 'thebib rest)) - (bibmem (memq bib rest)) - (thebibmem (memq thebib rest))) - (when (not (or thebib bib)) - (setq bib (assq 'bib docstruct) - thebib (assq 'thebib docstruct) - bibmem (memq bib docstruct) - thebibmem (memq thebib docstruct))) - (if (> (length bibmem) (length thebibmem)) - (if bib 'bib nil) - (if thebib 'thebib nil)))) - -;;;###autoload -(defun reftex-get-bibfile-list () - "Return list of bibfiles for current document. -When using the chapterbib or bibunits package you should either -use the same database files everywhere, or separate parts using -different databases into different files (included into the master file). -Then this function will return the applicable database files." - - ;; Ensure access to scanning info - (reftex-access-scan-info) - (or - ;; Try inside this file (and its includes) - (cdr (reftex-last-assoc-before-elt - 'bib (list 'eof (reftex--get-buffer-identifier)) - (member (list 'bof (reftex--get-buffer-identifier)) - (symbol-value reftex-docstruct-symbol)))) - ;; Try after the beginning of this file - (cdr (assq 'bib (member (list 'bof (reftex--get-buffer-identifier)) - (symbol-value reftex-docstruct-symbol)))) - ;; Anywhere in the entire document - (cdr (assq 'bib (symbol-value reftex-docstruct-symbol))) - (error "\\bibliography statement missing or .bib files not found"))) - -;;; Find a certain reference in any of the BibTeX files. -;;;###autoload -(defun reftex-pop-to-bibtex-entry (key file-list &optional mark-to-kill - highlight item return) - "Find BibTeX KEY in any file in FILE-LIST in another window. -If MARK-TO-KILL is non-nil, mark new buffer to kill. -If HIGHLIGHT is non-nil, highlight the match. -If ITEM in non-nil, search for bibitem instead of database entry. -If RETURN is non-nil, just return the entry and restore point." - (let* ((re - (if item - (concat "\\\\bibitem[ \t]*\\(\\[[^]]*\\]\\)?[ \t]*{" - (regexp-quote key) "}") - (concat "@\\(?:\\w\\|\\s_\\)+[ \t\n\r]*[{(][ \t\n\r]*" - (regexp-quote key) "[, \t\r\n}]"))) - (buffer-conf (current-buffer)) - file buf pos oldpos) - - (catch 'exit - (while file-list - (setq file (car file-list) - file-list (cdr file-list)) - (unless (setq buf (reftex-get-file-buffer-force file mark-to-kill)) - (error "No such file %s" file)) - (set-buffer buf) - (setq oldpos (point)) - (widen) - (goto-char (point-min)) - (if (not (re-search-forward re nil t)) - (goto-char oldpos) ;; restore previous position of point - (goto-char (match-beginning 0)) - (setq pos (point)) - (when return - ;; Just return the relevant entry - (if item (goto-char (match-end 0))) - (setq return (buffer-substring - (point) (reftex-end-of-bib-entry item))) - (goto-char oldpos) ;; restore point. - (set-buffer buffer-conf) - (throw 'exit return)) - (switch-to-buffer-other-window buf) - (goto-char pos) - (recenter 0) - (if highlight - (reftex-highlight 0 (match-beginning 0) (match-end 0))) - (throw 'exit (selected-window)))) - (set-buffer buffer-conf) - (if item - (error "No \\bibitem with citation key %s" key) - (error "No BibTeX entry with citation key %s" key))))) - -;;;###autoload -(defun reftex-end-of-bib-entry (item) - (save-excursion - (condition-case nil - (if item - (progn (end-of-line) - (re-search-forward - "\\\\bibitem\\|\\\\end{thebibliography}") - (1- (match-beginning 0))) - (progn (forward-list 1) (point))) - (error (min (point-max) (+ 300 (point))))))) - -(defun reftex--query-search-regexps (default) - "Query for regexps for searching entries using DEFAULT as default. -Return a list of regular expressions." - (split-string - (completing-read - (concat - "Regex { && Regex...}: " - "[" default "]: ") - ;; Ensure default is always in the completion list. - (let ((def (when default (list default))) - (coll (if reftex-mode - (if (fboundp 'LaTeX-bibitem-list) - (LaTeX-bibitem-list) - (cdr (assoc 'bibview-cache - (symbol-value reftex-docstruct-symbol)))) - nil))) - (if (and def (member def coll)) - coll - (cons def coll))) - nil nil nil 'reftex-cite-regexp-hist) - "[ \t]*&&[ \t]*")) - -;;; Parse bibtex buffers -(defun reftex-extract-bib-entries (buffers) - "Extract bib entries which match regexps from BUFFERS. -BUFFERS is a list of buffers or file names. -Return list with entries." - (let* (re-list first-re rest-re - (buffer-list (if (listp buffers) buffers (list buffers))) - found-list entry buffer1 buffer alist - key-point start-point end-point default) - - ;; Read a regexp, completing on known citation keys. - (setq default (regexp-quote (reftex-get-bibkey-default))) - (setq re-list (reftex--query-search-regexps default)) - - (if (or (null re-list ) (equal re-list '(""))) - (setq re-list (list default))) - - (setq first-re (car re-list) ; We'll use the first re to find things, - rest-re (cdr re-list)) ; the others to narrow down. - (if (string-match "\\`[ \t]*\\'" (or first-re "")) - (user-error "Empty regular expression")) - (if (string-match first-re "") - (user-error "Regular expression matches the empty string")) - - (save-excursion - (save-window-excursion - - ;; Walk through all bibtex files - (while buffer-list - (setq buffer (car buffer-list) - buffer-list (cdr buffer-list)) - (if (and (bufferp buffer) - (buffer-live-p buffer)) - (setq buffer1 buffer) - (setq buffer1 (reftex-get-file-buffer-force - buffer (not reftex-keep-temporary-buffers)))) - (if (not buffer1) - (message "No such BibTeX file %s (ignored)" buffer) - (message "Scanning bibliography database %s" buffer1) - (unless (verify-visited-file-modtime buffer1) - (when (y-or-n-p - (format "File %s changed on disk. Reread from disk? " - (file-name-nondirectory - (buffer-file-name buffer1)))) - (with-current-buffer buffer1 (revert-buffer t t))))) - - (set-buffer buffer1) - (reftex-with-special-syntax-for-bib - (save-excursion - (goto-char (point-min)) - (while (re-search-forward first-re nil t) - (catch 'search-again - (setq key-point (point)) - (unless (re-search-backward "\\(\\`\\|[\n\r]\\)[ \t]*\ -@\\(\\(?:\\w\\|\\s_\\)+\\)[ \t\n\r]*[{(]" nil t) - (throw 'search-again nil)) - (setq start-point (point)) - (goto-char (match-end 0)) - (condition-case nil - (up-list 1) - (error (goto-char key-point) - (throw 'search-again nil))) - (setq end-point (point)) - - ;; Ignore @string, @comment and @c entries or things - ;; outside entries - (when (or (string= (downcase (match-string 2)) "string") - (string= (downcase (match-string 2)) "comment") - (string= (downcase (match-string 2)) "c") - (< (point) key-point)) ; this means match not in {} - (goto-char key-point) - (throw 'search-again nil)) - - ;; Well, we have got a match - ;;(setq entry (concat - ;; (buffer-substring start-point (point)) "\n")) - (setq entry (buffer-substring start-point (point))) - - ;; Check if other regexp match as well - (setq re-list rest-re) - (while re-list - (unless (string-match (car re-list) entry) - ;; nope - move on - (throw 'search-again nil)) - (pop re-list)) - - (setq alist (reftex-parse-bibtex-entry - nil start-point end-point)) - (push (cons "&entry" entry) alist) - - ;; check for crossref entries - (if (assoc "crossref" alist) - (setq alist - (append - alist (reftex-get-crossref-alist alist)))) - - ;; format the entry - (push (cons "&formatted" (reftex-format-bib-entry alist)) - alist) - - ;; make key the first element - (push (reftex-get-bib-field "&key" alist) alist) - - ;; add it to the list - (push alist found-list))))) - (reftex-kill-temporary-buffers)))) - (setq found-list (nreverse found-list)) - - ;; Sorting - (cond - ((eq 'author reftex-sort-bibtex-matches) - (sort found-list #'reftex-bib-sort-author)) - ((eq 'year reftex-sort-bibtex-matches) - (sort found-list #'reftex-bib-sort-year)) - ((eq 'reverse-year reftex-sort-bibtex-matches) - (sort found-list #'reftex-bib-sort-year-reverse)) - (t found-list)))) - -(defun reftex-bib-sort-author (e1 e2) - "Compare bib entries E1 and E2 by author. -The name of the first different author/editor is used." - (let ((al1 (reftex-get-bib-names "author" e1)) - (al2 (reftex-get-bib-names "author" e2))) - (while (and al1 al2 (string= (car al1) (car al2))) - (pop al1) - (pop al2)) - (if (and (stringp (car al1)) - (stringp (car al2))) - (string< (car al1) (car al2)) - (not (stringp (car al1)))))) - -(defun reftex-bib-sort-year (e1 e2) - "Compare bib entries E1 and E2 by year in ascending order." - (< (string-to-number (or (cdr (assoc "year" e1)) "0")) - (string-to-number (or (cdr (assoc "year" e2)) "0")))) - -(defun reftex-bib-sort-year-reverse (e1 e2) - "Compare bib entries E1 and E2 by year in descending order." - (> (string-to-number (or (cdr (assoc "year" e1)) "0")) - (string-to-number (or (cdr (assoc "year" e2)) "0")))) - -(defun reftex-get-crossref-alist (entry) - "Return the alist from a crossref ENTRY." - (let ((crkey (cdr (assoc "crossref" entry))) - start) - (save-excursion - (save-restriction - (widen) - (if (re-search-forward - (concat "@\\w+[{(][ \t\n\r]*" (regexp-quote crkey) - "[ \t\n\r]*,") nil t) - (progn - (setq start (match-beginning 0)) - (condition-case nil - (up-list 1) - (error nil)) - (reftex-parse-bibtex-entry nil start (point))) - nil))))) - -;; Parse the bibliography environment -(defun reftex-extract-bib-entries-from-thebibliography (files) - "Extract bib-entries from the \\begin{thebibliography} environment. -Parsing is not as good as for the BibTeX database stuff. -The environment should be located in FILES." - (let* (start end buf entries re re-list file default) - (unless files - (error "Need file name to find thebibliography environment")) - (while (setq file (pop files)) - (setq buf (reftex-get-file-buffer-force - file (not reftex-keep-temporary-buffers))) - (unless buf - (error "No such file %s" file)) - (message "Scanning thebibliography environment in %s" file) - - (with-current-buffer buf - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (while (re-search-forward - "\\(\\`\\|[\n\r]\\)[ \t]*\\\\begin{thebibliography}" nil t) - (beginning-of-line 2) - (setq start (point)) - (if (re-search-forward - "\\(\\`\\|[\n\r]\\)[ \t]*\\\\end{thebibliography}" nil t) - (progn - (beginning-of-line 1) - (setq end (point)))) - (when (and start end) - (setq entries - (append entries - (mapcar #'reftex-parse-bibitem - (delete "" - (split-string - (buffer-substring-no-properties - start end) - "[ \t\n\r]*\\\\bibitem[ \t]*\ -\\(\\[[^]]*]\\)*[ \t]*")))))) - (goto-char end)))))) - (unless entries - (error "No bibitems found")) - - ;; Read a regexp, completing on known citation keys. - (setq default (regexp-quote (reftex-get-bibkey-default))) - (setq re-list (reftex--query-search-regexps default)) - - (if (or (null re-list ) (equal re-list '(""))) - (setq re-list (list default))) - - (if (string-match "\\`[ \t]*\\'" (car re-list)) - (error "Empty regular expression")) - - (while (and (setq re (pop re-list)) entries) - (setq entries - (delq nil (mapcar - (lambda (x) - (if (string-match re (cdr (assoc "&entry" x))) - x nil)) - entries)))) - (setq entries - (mapcar - (lambda (x) - (push (cons "&formatted" (reftex-format-bibitem x)) x) - (push (reftex-get-bib-field "&key" x) x) - x) - entries)) - - entries)) - -(defun reftex-get-bibkey-default () - "Return the word before the cursor. -If the cursor is in a citation macro, return the word before the macro." - (let* ((macro (reftex-what-macro 1))) - (save-excursion - (if (and macro (string-match "cite" (car macro))) - (goto-char (cdr macro))) - (skip-chars-backward "^a-zA-Z0-9") - (reftex-this-word)))) - -;;; Parse and format individual entries -(defun reftex-get-bib-names (field entry) - "Return a list with the author or editor names in ENTRY. -If FIELD is empty try \"editor\" field." - (let ((names (reftex-get-bib-field field entry))) - (if (equal "" names) - (setq names (reftex-get-bib-field "editor" entry))) - (while (string-match "\\band\\b[ \t]*" names) - (setq names (replace-match "\n" nil t names))) - (while (string-match "[-.a-zA-Z]+\\.[ \t]*\\|,.*\\|[{}]+" names) - (setq names (replace-match "" nil t names))) - (while (string-match "^[ \t]+\\|[ \t]+$" names) - (setq names (replace-match "" nil t names))) - (while (string-match "[ \t][ \t]+" names) - (setq names (replace-match " " nil t names))) - (split-string names "\n"))) - -;;;###autoload -(defun reftex-parse-bibtex-entry (entry &optional from to raw) - "Parse BibTeX ENTRY. -If ENTRY is nil then parse the entry in current buffer between FROM and TO. -If RAW is non-nil, keep double quotes/curly braces delimiting fields." - (let (alist key start field) - (save-excursion - (save-restriction - (if entry - (progn - (set-buffer (get-buffer-create " *RefTeX-scratch*")) - (fundamental-mode) - (set-syntax-table reftex-syntax-table-for-bib) - (erase-buffer) - (insert entry)) - (widen) - (if (and from to) (narrow-to-region from to))) - (goto-char (point-min)) - - (if (re-search-forward "@\\(\\(?:\\w\\|\\s_\\)+\\)[ \t\n\r]*\ -[{(][ \t\n\r]*\\([^ \t\n\r,]+\\)" nil t) - (setq alist - (list - (cons "&type" (downcase (reftex-match-string 1))) - (cons "&key" (reftex-match-string 2))))) - (while (re-search-forward "\\(\\(?:\\w\\|-\\)+\\)[ \t\n\r]*=[ \t\n\r]*" - nil t) - (setq key (downcase (reftex-match-string 1))) - (cond - ((= (following-char) ?{) - (cond - (raw - (setq start (point)) - (forward-char 1)) - (t - (forward-char 1) - (setq start (point)) - (condition-case nil - (up-list 1) - (error nil))))) - ((= (following-char) ?\") - (cond - (raw - (setq start (point)) - (forward-char 1)) - (t - (forward-char 1) - (setq start (point)))) - (while (and (search-forward "\"" nil t) - (= ?\\ (char-after (- (point) 2)))))) - (t - (setq start (point)) - (re-search-forward "[ \t]*[\n\r,}]" nil 1))) - ;; extract field value, ignore trailing comma if in RAW mode - (let ((stop (if (and raw (not (= (char-after (1- (point))) ?,))) - (point) - (1- (point))) )) - (setq field (buffer-substring-no-properties start stop))) - ;; remove extra whitespace - (while (string-match "[\n\t\r]\\|[ \t][ \t]+" field) - (setq field (replace-match " " nil t field))) - (push (cons key field) alist)))) - alist)) - -(defun reftex-get-bib-field (fieldname entry &optional format) - "Extract the field FIELDNAME from ENTRY. -If FORMAT is non-nil `format' entry accordingly." - (let ((cell (assoc fieldname entry))) - (if cell - (if format - (format format (cdr cell)) - (cdr cell)) - ""))) - -(defun reftex-format-bib-entry (entry) - "Format a BibTeX ENTRY so that it is nice to look at." - (let* - ((auth-list (reftex-get-bib-names "author" entry)) - (authors (mapconcat #'identity auth-list ", ")) - (year (reftex-get-bib-field "year" entry)) - (title (reftex-get-bib-field "title" entry)) - (type (reftex-get-bib-field "&type" entry)) - (key (reftex-get-bib-field "&key" entry)) - (extra - (cond - ((equal type "article") - (concat (let ((jt (reftex-get-bib-field "journal" entry))) - ;; biblatex prefers the alternative journaltitle - ;; field, so check if that exists in case journal - ;; is empty. - (if (zerop (length jt)) - (reftex-get-bib-field "journaltitle" entry) - jt)) - " " - (reftex-get-bib-field "volume" entry) ", " - (reftex-get-bib-field "pages" entry))) - ((equal type "book") - (concat "book (" (reftex-get-bib-field "publisher" entry) ")")) - ((equal type "phdthesis") - (concat "PhD: " (reftex-get-bib-field "school" entry))) - ((equal type "mastersthesis") - (concat "Master: " (reftex-get-bib-field "school" entry))) - ((equal type "inbook") - (concat "Chap: " (reftex-get-bib-field "chapter" entry) - ", pp. " (reftex-get-bib-field "pages" entry))) - ((or (equal type "conference") - (equal type "incollection") - (equal type "inproceedings")) - (reftex-get-bib-field "booktitle" entry "in: %s")) - (t "")))) - (setq authors (reftex-truncate authors 30 t t)) - (when reftex-use-fonts - (put-text-property 0 (length key) 'face reftex-label-face - key) - (put-text-property 0 (length authors) 'face reftex-bib-author-face - authors) - (put-text-property 0 (length year) 'face reftex-bib-year-face - year) - (put-text-property 0 (length title) 'face reftex-bib-title-face - title) - (put-text-property 0 (length extra) 'face reftex-bib-extra-face - extra)) - (concat key "\n " authors " " year " " extra "\n " title "\n\n"))) - -(defun reftex-parse-bibitem (item) - "Parse a \\bibitem entry in ITEM." - (let ((key "") (text "")) - (when (string-match "\\`{\\([^}]+\\)}\\([^\000]*\\)" item) - (setq key (match-string 1 item) - text (match-string 2 item))) - ;; Clean up the text a little bit - (while (string-match "[\n\r\t]\\|[ \t][ \t]+" text) - (setq text (replace-match " " nil t text))) - (if (string-match "\\`[ \t]+" text) - (setq text (replace-match "" nil t text))) - (list - (cons "&key" key) - (cons "&text" text) - (cons "&entry" (concat key " " text))))) - -(defun reftex-format-bibitem (item) - "Format a \\bibitem entry in ITEM so that it is (relatively) nice to look at." - (let ((text (reftex-get-bib-field "&text" item)) - (key (reftex-get-bib-field "&key" item)) - (lines nil)) - - ;; Wrap the text into several lines. - (while (and (> (length text) 70) - (string-match " " (substring text 60))) - (push (substring text 0 (+ 60 (match-beginning 0))) lines) - (setq text (substring text (+ 61 (match-beginning 0))))) - (push text lines) - (setq text (mapconcat #'identity (nreverse lines) "\n ")) - - (when reftex-use-fonts - (put-text-property 0 (length text) 'face reftex-bib-author-face text)) - (concat key "\n " text "\n\n"))) - -;;; Make a citation - -;; NB this is a global autoload - see reftex.el. -;;;###autoload -(defun reftex-citation (&optional no-insert format-key) - "Make a citation using BibTeX database files. -After prompting for a regular expression, scans the buffers with -bibtex entries (taken from the \\bibliography command) and offers the -matching entries for selection. The selected entry is formatted according -to `reftex-cite-format' and inserted into the buffer. - -If NO-INSERT is non-nil, nothing is inserted, only the selected key returned. - -FORMAT-KEY can be used to pre-select a citation format. - -When called with a \\[universal-argument] prefix, prompt for optional arguments in -cite macros. When called with a numeric prefix, make that many -citations. When called with point inside the braces of a `\\cite' -command, it will add another key, ignoring the value of -`reftex-cite-format'. - -The regular expression uses an expanded syntax: && is interpreted as `and'. -Thus, `aaaa&&bbb' matches entries which contain both `aaaa' and `bbb'. -While entering the regexp, completion on known citation keys is possible. -`=' is a good regular expression to match all entries in all files." - (interactive) - - ;; check for recursive edit - (reftex-check-recursive-edit) - - ;; This function may also be called outside reftex-mode. - ;; Thus look for the scanning info only if in reftex-mode. - - (when reftex-mode - (reftex-access-scan-info nil)) - - ;; Call reftex-do-citation, but protected - (unwind-protect - (reftex-do-citation current-prefix-arg no-insert format-key) - (reftex-kill-temporary-buffers))) - -(defun reftex-do-citation (&optional arg no-insert format-key) - "This really does the work of `reftex-citation'." - (let* ((format (reftex-figure-out-cite-format arg no-insert format-key)) - (docstruct-symbol reftex-docstruct-symbol) - (selected-entries (reftex-offer-bib-menu)) - (insert-entries selected-entries) - entry string cite-view) - - (unless selected-entries (error "Quit")) - - (if (stringp selected-entries) - ;; Nonexistent entry - (setq insert-entries (list (list selected-entries - (cons "&key" selected-entries))) - selected-entries nil) - ;; It makes sense to compute the cite-view strings. - (setq cite-view t)) - - (when (eq (car selected-entries) 'concat) - ;; All keys go into a single command - we need to trick a little - ;; FIXME: Unfortunately, this means that commenting does not work right. - (pop selected-entries) - (let ((concat-keys (mapconcat #'car selected-entries - reftex-cite-key-separator))) - (setq insert-entries - (list (list concat-keys (cons "&key" concat-keys)))))) - - (unless no-insert - - ;; We shall insert this into the buffer... - (message "Formatting...") - - (while (setq entry (pop insert-entries)) - ;; Format the citation and insert it - (setq string (if reftex-format-cite-function - (funcall reftex-format-cite-function - (reftex-get-bib-field "&key" entry) - format) - (reftex-format-citation entry format))) - (when (or (eq reftex-cite-prompt-optional-args t) - (and reftex-cite-prompt-optional-args - (equal arg '(4)))) - (let ((start 0) (nth 0) value) - (while (setq start (string-match "\\[\\]" string start)) - (setq value (save-match-data - (read-string (format "Optional argument %d: " - (setq nth (1+ nth)))))) - (setq string (replace-match (concat "[" value "]") t t string)) - (setq start (1+ start))))) - ;; Should we cleanup empty optional arguments? - ;; if the first is empty, it can be removed. If the second is empty, - ;; it has to go. If there is only a single arg and empty, it can go - ;; as well. - (when reftex-cite-cleanup-optional-args - (cond - ((string-match "\\([a-zA-Z0-9]\\)\\[\\]{" string) - (setq string (replace-match "\\1{" nil nil string))) - ((string-match "\\[\\]\\(\\[[a-zA-Z0-9., ]+\\]\\)" string) - (setq string (replace-match "\\1" nil nil string))) - ((string-match "\\[\\]\\[\\]" string) - (setq string (replace-match "" t t string))))) - (insert string)) - - ;; Reposition cursor? - (when (string-search "?" string) - (search-backward "?") - (delete-char 1)) - - ;; Tell AUCTeX - (when (and reftex-mode - (fboundp 'LaTeX-add-bibitems) - reftex-plug-into-AUCTeX) - (apply #'LaTeX-add-bibitems (mapcar #'car selected-entries))) - - ;; Produce the cite-view strings - (when (and reftex-mode reftex-cache-cite-echo cite-view) - (mapc (lambda (entry) - (reftex-make-cite-echo-string entry docstruct-symbol)) - selected-entries)) - - (message "")) - - (set-marker reftex-select-return-marker nil) - (reftex-kill-buffer "*RefTeX Select*") - - ;; Check if the prefix arg was numeric, and call recursively - (when (integerp arg) - (if (> arg 1) - (progn - (skip-chars-backward "}") - (decf arg) - (reftex-do-citation arg)) - (forward-char 1))) - - ;; Return the citation key - (mapcar #'car selected-entries))) - -(defun reftex-figure-out-cite-format (arg &optional no-insert format-key) - "Check if there is already a cite command at point and change cite format -in order to only add another reference in the same cite command." - (let ((macro (car (reftex-what-macro 1))) - (cite-format-value (reftex-get-cite-format)) - key format) - (cond - (no-insert - ;; Format does not really matter because nothing will be inserted. - (setq format "%l")) - - ((and (stringp macro) - ;; Match also commands from biblatex ending with `s' - ;; (\parencites) or `*' (\parencite*) and `texts?' - ;; (\footcitetext and \footcitetexts). - (string-match "\\`\\\\cite\\|cite\\([s*]\\|texts?\\)?\\'" macro)) - ;; We are already inside a cite macro - (if (or (not arg) (not (listp arg))) - (setq format - (concat - (if (member (preceding-char) '(?\{ ?,)) - "" - reftex-cite-key-separator) - "%l" - (if (member (following-char) '(?\} ?,)) - "" - reftex-cite-key-separator))) - (setq format "%l"))) - (t - ;; Figure out the correct format - (setq format - (if (and (symbolp cite-format-value) - (assq cite-format-value reftex-cite-format-builtin)) - (nth 2 (assq cite-format-value reftex-cite-format-builtin)) - cite-format-value)) - (when (listp format) - (setq key - (or format-key - (reftex-select-with-char - "" (concat "SELECT A CITATION FORMAT\n\n" - (mapconcat - (lambda (x) - (format "[%c] %s %s" (car x) - (if (> (car x) 31) " " "") - (cdr x))) - format "\n"))))) - (if (assq key format) - (setq format (cdr (assq key format))) - (error "No citation format associated with key `%c'" key))))) - format)) - -;;;###autoload -(defun reftex-citep () - "Call `reftex-citation' with a format selector `?p'." - (interactive) - (reftex-citation nil ?p)) - -;;;###autoload -(defun reftex-citet () - "Call `reftex-citation' with a format selector `?t'." - (interactive) - (reftex-citation nil ?t)) - -(defvar reftex-select-bib-mode-map) -(defvar reftex--found-list) -(defun reftex-offer-bib-menu () - "Offer bib menu and return list of selected items." - (let ((bibtype (reftex-bib-or-thebib)) - reftex--found-list rtn key data selected-entries) - (while - (not - (catch 'done - ;; Scan bibtex files - (setq reftex--found-list - (cond - ((eq bibtype 'bib) -; ((assq 'bib (symbol-value reftex-docstruct-symbol)) - ;; using BibTeX database files. - (reftex-extract-bib-entries (reftex-get-bibfile-list))) - ((eq bibtype 'thebib) -; ((assq 'thebib (symbol-value reftex-docstruct-symbol)) - ;; using thebibliography environment. - (reftex-extract-bib-entries-from-thebibliography - (reftex-uniquify - (mapcar #'cdr - (reftex-all-assq - 'thebib (symbol-value reftex-docstruct-symbol)))))) - (reftex-default-bibliography - (message "Using default bibliography") - (reftex-extract-bib-entries (reftex-default-bibliography))) - (t (error "No valid bibliography in this document, and no default available")))) - - (unless reftex--found-list - (error "Sorry, no matches found")) - - ;; Remember where we came from - (setq reftex-call-back-to-this-buffer (current-buffer)) - (set-marker reftex-select-return-marker (point)) - - ;; Offer selection - (save-window-excursion - (delete-other-windows) - (reftex-kill-buffer "*RefTeX Select*") - (switch-to-buffer-other-window "*RefTeX Select*") - (unless (derived-mode-p 'reftex-select-bib-mode) - (reftex-select-bib-mode)) - (let ((inhibit-read-only t)) - (erase-buffer) - (reftex-insert-bib-matches reftex--found-list)) - (setq buffer-read-only t) - (if (= 0 (buffer-size)) - (error "No matches found")) - (setq truncate-lines t) - (goto-char 1) - (while t - (setq rtn - (reftex-select-item - reftex-citation-prompt - reftex-citation-help - reftex-select-bib-mode-map - nil - 'reftex-bibtex-selection-callback nil)) - (setq key (car rtn) - data (nth 1 rtn)) - (unless key (throw 'done t)) - (cond - ((eq key ?g) - ;; Start over - (throw 'done nil)) - ((eq key ?r) - ;; Restrict with new regular expression - (setq reftex--found-list - (reftex-restrict-bib-matches reftex--found-list)) - (let ((buffer-read-only nil)) - (erase-buffer) - (reftex-insert-bib-matches reftex--found-list)) - (goto-char 1)) - ((eq key ?A) - ;; Take all (marked) - (setq selected-entries - (if reftex-select-marked - (mapcar #'car (nreverse reftex-select-marked)) - reftex--found-list)) - (throw 'done t)) - ((eq key ?a) - ;; Take all (marked), and push the symbol 'concat - (setq selected-entries - (cons 'concat - (if reftex-select-marked - (mapcar #'car (nreverse reftex-select-marked)) - reftex--found-list))) - (throw 'done t)) - ((eq key ?e) - ;; Take all (marked), and push the symbol 'concat - (reftex-extract-bib-file reftex--found-list - reftex-select-marked) - (setq selected-entries "BibTeX database file created") - (throw 'done t)) - ((eq key ?E) - ;; Take all (marked), and push the symbol 'concat - (reftex-extract-bib-file reftex--found-list reftex-select-marked - 'complement) - (setq selected-entries "BibTeX database file created") - (throw 'done t)) - ((or (eq key ?\C-m) - (eq key 'return)) - ;; Take selected - (setq selected-entries - (if reftex-select-marked - (cons 'concat - (mapcar #'car (nreverse reftex-select-marked))) - (if data (list data) nil))) - (throw 'done t)) - ((stringp key) - ;; Got this one with completion - (setq selected-entries key) - (throw 'done t)) - (t - (ding)))))))) - selected-entries)) - -(defun reftex-restrict-bib-matches (found-list) - "Limit FOUND-LIST with more regular expressions." - (let ((re-list (split-string (read-string - "RegExp [ && RegExp...]: " - nil 'reftex-cite-regexp-hist) - "[ \t]*&&[ \t]*")) - (found-list-r found-list) - re) - (while (setq re (pop re-list)) - (setq found-list-r - (delq nil - (mapcar - (lambda (x) - (if (string-match - re (cdr (assoc "&entry" x))) - x - nil)) - found-list-r)))) - (if found-list-r - found-list-r - (ding) - found-list))) - -(defun reftex-extract-bib-file (all &optional marked complement) - "Limit FOUND-LIST with more regular expressions." - (let ((file (read-file-name "File to create: "))) - (find-file-other-window file) - (if (> (buffer-size) 0) - (unless (yes-or-no-p - (format "Overwrite non-empty file %s? " file)) - (error "Abort"))) - (erase-buffer) - (setq all (delq nil - (mapcar - (lambda (x) - (if marked - (if (or (and (assoc x marked) (not complement)) - (and (not (assoc x marked)) complement)) - (cdr (assoc "&entry" x)) - nil) - (cdr (assoc "&entry" x)))) - all))) - (insert (mapconcat #'identity all "\n\n")) - (save-buffer) - (goto-char (point-min)))) - -(defun reftex-insert-bib-matches (list) - "Insert the bib matches and number them correctly." - (let ((mouse-face - (if (memq reftex-highlight-selection '(mouse both)) - reftex-mouse-selected-face - nil)) - tmp len) - (mapc - (lambda (x) - (setq tmp (cdr (assoc "&formatted" x)) - len (length tmp)) - (put-text-property 0 len :data x tmp) - (put-text-property 0 (1- len) 'mouse-face mouse-face tmp) - (insert tmp)) - list)) - (run-hooks 'reftex-display-copied-context-hook)) - -(defun reftex-format-names (namelist n) - (let (last (len (length namelist))) - (if (= n 0) (setq n len)) - (cond - ((< len 1) "") - ((= 1 len) (car namelist)) - ((> len n) (concat (car namelist) (nth 2 reftex-cite-punctuation))) - (t - (setq n (min len n) - last (nth (1- n) namelist)) - (setcdr (nthcdr (- n 2) namelist) nil) - (concat - (mapconcat #'identity namelist (nth 0 reftex-cite-punctuation)) - (nth 1 reftex-cite-punctuation) - last))))) - -(defun reftex-format-citation (entry format) - "Format a citation from the info in the BibTeX ENTRY according to FORMAT." - (unless (stringp format) (setq format "\\cite{%l}")) - - (if (and reftex-comment-citations - (string-match "%l" reftex-cite-comment-format)) - (error "reftex-cite-comment-format contains invalid %%l")) - - (while (string-match - "\\(\\`\\|[^%]\\)\\(\\(%\\([0-9]*\\)\\([a-zA-Z]\\)\\)[.,;: ]*\\)" - format) - (let ((n (string-to-number (match-string 4 format))) - (l (string-to-char (match-string 5 format))) - rpl b e) - (save-match-data - (setq rpl - (cond - ((= l ?l) (concat - (reftex-get-bib-field "&key" entry) - (if reftex-comment-citations - reftex-cite-comment-format - ""))) - ((= l ?a) (reftex-format-names - (reftex-get-bib-names "author" entry) - (or n 2))) - ((= l ?A) (car (reftex-get-bib-names "author" entry))) - ((= l ?b) (reftex-get-bib-field "booktitle" entry "in: %s")) - ((= l ?B) (reftex-abbreviate-title - (reftex-get-bib-field "booktitle" entry "in: %s"))) - ((= l ?c) (reftex-get-bib-field "chapter" entry)) - ((= l ?d) (reftex-get-bib-field "edition" entry)) - ((= l ?e) (reftex-format-names - (reftex-get-bib-names "editor" entry) - (or n 2))) - ((= l ?E) (car (reftex-get-bib-names "editor" entry))) - ((= l ?h) (reftex-get-bib-field "howpublished" entry)) - ((= l ?i) (reftex-get-bib-field "institution" entry)) - ((= l ?j) (let ((jr (reftex-get-bib-field "journal" entry))) - (if (string-empty-p jr) - ;; Biblatex prefers the alternative - ;; journaltitle field, so check if that - ;; exists in case journal is empty - (reftex-get-bib-field "journaltitle" entry) - ;; Standard BibTeX - jr))) - ((= l ?k) (reftex-get-bib-field "key" entry)) - ((= l ?m) (reftex-get-bib-field "month" entry)) - ((= l ?n) (reftex-get-bib-field "number" entry)) - ((= l ?N) (reftex-get-bib-field "note" entry)) - ((= l ?o) (reftex-get-bib-field "organization" entry)) - ((= l ?p) (reftex-get-bib-field "pages" entry)) - ((= l ?P) (car (split-string - (reftex-get-bib-field "pages" entry) - "[- .]+"))) - ((= l ?s) (reftex-get-bib-field "school" entry)) - ((= l ?u) (reftex-get-bib-field "publisher" entry)) - ((= l ?U) (reftex-get-bib-field "url" entry)) - ((= l ?r) (reftex-get-bib-field "address" entry)) - ((= l ?t) (reftex-get-bib-field "title" entry)) - ((= l ?T) (reftex-abbreviate-title - (reftex-get-bib-field "title" entry))) - ((= l ?v) (reftex-get-bib-field "volume" entry)) - ((= l ?y) (reftex-get-bib-field "year" entry))))) - - (if (string= rpl "") - (setq b (match-beginning 2) e (match-end 2)) - (setq b (match-beginning 3) e (match-end 3))) - (setq format (concat (substring format 0 b) rpl (substring format e))))) - (while (string-match "%%" format) - (setq format (replace-match "%" t t format))) - (while (string-match "[ ,.;:]*%<" format) - (setq format (replace-match "" t t format))) - format) - -;;;###autoload -(defun reftex-make-cite-echo-string (entry docstruct-symbol) - "Format a bibtex ENTRY for the echo area and cache the result." - (let* ((key (reftex-get-bib-field "&key" entry)) - (string - (let* ((reftex-cite-punctuation '(" " " & " " etal."))) - (reftex-format-citation entry reftex-cite-view-format))) - (cache (assq 'bibview-cache (symbol-value docstruct-symbol))) - (cache-entry (assoc key (cdr cache)))) - (unless cache - ;; This docstruct has no cache - make one. - (set docstruct-symbol (cons (cons 'bibview-cache nil) - (symbol-value docstruct-symbol)))) - (when reftex-cache-cite-echo - (setq key (copy-sequence key)) - (set-text-properties 0 (length key) nil key) - (set-text-properties 0 (length string) nil string) - (if cache-entry - (unless (string= (cdr cache-entry) string) - (setcdr cache-entry string) - (put reftex-docstruct-symbol 'modified t)) - (push (cons key string) (cdr cache)) - (put reftex-docstruct-symbol 'modified t))) - string)) - -(defun reftex-bibtex-selection-callback (data _ignore no-revisit) - "Callback function to be called from the BibTeX selection, in -order to display context. This function is relatively slow and not -recommended for follow mode. It works OK for individual lookups." - (let ((win (selected-window)) - (key (reftex-get-bib-field "&key" data)) - bibfile-list item bibtype) - - (catch 'exit - (with-current-buffer reftex-call-back-to-this-buffer - (setq bibtype (reftex-bib-or-thebib)) - (cond - ((eq bibtype 'bib) - ;; ((assq 'bib (symbol-value reftex-docstruct-symbol)) - (setq bibfile-list (reftex-get-bibfile-list))) - ((eq bibtype 'thebib) - ;; ((assq 'thebib (symbol-value reftex-docstruct-symbol)) - (setq bibfile-list - (reftex-uniquify - (mapcar #'cdr - (reftex-all-assq - 'thebib (symbol-value reftex-docstruct-symbol)))) - item t)) - (reftex-default-bibliography - (setq bibfile-list (reftex-default-bibliography))) - (t (ding) (throw 'exit nil)))) - - (when no-revisit - (setq bibfile-list (reftex-visited-files bibfile-list))) - - (condition-case nil - (reftex-pop-to-bibtex-entry - key bibfile-list (not reftex-keep-temporary-buffers) t item) - (error (ding)))) - - (select-window win))) - -;;; Global BibTeX file -(defun reftex-all-used-citation-keys () - "Return a list of all citation keys used in document." - (reftex-access-scan-info) - (let ((files (reftex-all-document-files)) - (re (concat "\\\\" - "\\(?:" - ;; biblatex volcite macros take these args: - ;; \volcite[prenote]{volume}[pages]{key} - ;; so cater for the first 3 args: - (regexp-opt '("volcite" "Volcite" - "pvolcite" "Pvolcite" - "fvolcite" "ftvolcite" - "svolcite" "Svolcite" - "tvolcite" "Tvolcite" - "avolcite" "Avolcite")) - "\\(?:\\[[^]]*\\]\\)?" - "{[^}]*}" - "\\(?:\\[[^]]*\\]\\)?" - "\\|" - ;; Other cite macros usually go like: - ;; \cite[prenote][postnote]{key} - ;; so cater for the optional args: - "\\(?:bibentry\\|[a-zA-Z]*[Cc]ite[a-zA-Z*]*\\)" - "\\(?:\\[[^]]*\\]\\)\\{0,2\\}" - "\\)" - ;; Now match the key: - "{\\([^}]+\\)}")) - ;; Multicites: Match \MACRONAME(Global Pre)(Global Post) - (re2 (concat "\\\\" - (regexp-opt '("cites" "Cites" - "parencites" "Parencites" - "footcites" "footcitetexts" - "smartcites" "Smartcites" - "textcites" "Textcites" - "supercites" - "autocites" "Autocites" - "volcites" "Volcites" - "pvolcites" "Pvolcites" - "fvolcites" "Fvolcites" - "svolcites" "Svolcites" - "tvolcites" "Tvolcites" - "avolcites" "Avolcites")) - "\\(?:([^)]*)\\)\\{0,2\\}")) - ;; For each key in list [prenote][postnote]{key} - (re3 (concat "\\(?:\\[[^]]*\\]\\)\\{0,2\\}" - "{\\([^}]+\\)}")) - file keys kk k) - (save-current-buffer - (while (setq file (pop files)) - (set-buffer (reftex-get-file-buffer-force file 'mark)) - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (while (re-search-forward re nil t) - ;; Make sure we're not inside a comment: - (unless (save-match-data - (nth 4 (syntax-ppss))) - (setq kk (match-string-no-properties 1)) - (while (string-match "%.*\n?" kk) - (setq kk (replace-match "" t t kk))) - (setq kk (split-string kk "[, \t\r\n]+")) - (while (setq k (pop kk)) - (or (member k keys) - (setq keys (cons k keys)))))) - ;; And now search for citation lists: - (goto-char (point-min)) - (while (re-search-forward re2 nil t) - ;; Make sure we're not inside a comment: - (unless (save-match-data - (nth 4 (syntax-ppss))) - (while (progn - ;; Ignore the value of - ;; `reftex-allow-detached-macro-args' since we - ;; expect a bigger number of args and detaching - ;; them seems natural for line breaks: - (while (looking-at "[ \t\r\n]+\\|%.*\n") - (goto-char (match-end 0))) - (and (looking-at re3) - (goto-char (match-end 0)))) - (setq kk (match-string-no-properties 1)) - (while (string-match "%.*\n?" kk) - (setq kk (replace-match "" t t kk))) - (setq kk (split-string kk "[, \t\r\n]+")) - (while (setq k (pop kk)) - (or (member k keys) - (setq keys (cons k keys))))))))))) - (reftex-kill-temporary-buffers) - keys)) - -(defun reftex-get-string-refs (alist) - "Return a list of BibTeX @string references that appear as values in ALIST." - (reftex-remove-if (lambda (x) (string-match "^\\([\"{]\\|[0-9]+$\\)" x)) - ;; get list of values, discard keys - (mapcar #'cdr - ;; remove &key and &type entries - (reftex-remove-if (lambda (pair) - (string-match "^&" (car pair))) - alist)))) - -;;;###autoload -(defun reftex-create-bibtex-file (bibfile) - "Create a new BibTeX database BIBFILE with all entries referenced in document. -The command prompts for a filename and writes the collected -entries to that file. Only entries referenced in the current -document with any \\cite-like macros are used. The sequence in -the new file is the same as it was in the old database. - -Entries referenced from other entries must appear after all -referencing entries. - -You can define strings to be used as header or footer for the -created files in the variables `reftex-create-bibtex-header' or -`reftex-create-bibtex-footer' respectively." - (interactive "FNew BibTeX file: ") - (let ((keys (reftex-all-used-citation-keys)) - (files (reftex-get-bibfile-list)) - key entries beg end entry string-keys string-entries) - (save-current-buffer - (dolist (file files) - (set-buffer (reftex-get-file-buffer-force file 'mark)) - (reftex-with-special-syntax-for-bib - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (while (re-search-forward "^[ \t]*@\\(?:\\w\\|\\s_\\)+[ \t\n\r]*\ -[{(][ \t\n\r]*\\([^ \t\n\r,]+\\)" nil t) - (setq key (match-string 1) - beg (match-beginning 0) - end (progn - (goto-char (match-beginning 1)) - (condition-case nil - (up-list 1) - (error (goto-char (match-end 0)))) - (point))) - (when (member key keys) - (setq entry (buffer-substring beg end) - entries (cons entry entries) - keys (delete key keys)) - - ;; check for crossref entries - (let* ((attr-list (reftex-parse-bibtex-entry nil beg end)) - (xref-key (cdr (assoc "crossref" attr-list)))) - (if xref-key (cl-pushnew xref-key keys))) - ;; check for string references - (let* ((raw-fields (reftex-parse-bibtex-entry nil beg end t)) - (string-fields (reftex-get-string-refs raw-fields))) - (dolist (skey string-fields) - (unless (member skey string-keys) - (push skey string-keys))))))))))) - ;; second pass: grab @string references - (if string-keys - (save-current-buffer - (dolist (file files) - (set-buffer (reftex-get-file-buffer-force file 'mark)) - (reftex-with-special-syntax-for-bib - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (while (re-search-forward - "^[ \t]*@[Ss][Tt][Rr][Ii][Nn][Gg][ \t]*{[ \t]*\\([^ \t\r\n]+\\)" - nil t) - (setq key (match-string 1) - beg (match-beginning 0) - end (progn - (goto-char (match-beginning 1)) - (condition-case nil - (up-list 1) - (error (goto-char (match-end 0)))) - (point))) - (when (member key string-keys) - (setq entry (buffer-substring beg end) - string-entries (cons entry string-entries) - string-keys (delete key string-keys)))))))))) - (find-file-other-window bibfile) - (if (> (buffer-size) 0) - (unless (yes-or-no-p - (format "Overwrite non-empty file %s? " bibfile)) - (error "Abort"))) - (erase-buffer) - (if reftex-create-bibtex-header (insert reftex-create-bibtex-header "\n\n")) - (insert (mapconcat #'identity (reverse string-entries) "\n\n")) - (if string-entries (insert "\n\n\n")) - (insert (mapconcat #'identity (reverse entries) "\n\n")) - (if reftex-create-bibtex-footer (insert "\n\n" reftex-create-bibtex-footer)) - (goto-char (point-min)) - (save-buffer) - (message "%d entries extracted and copied to new database" - (length entries)))) - -(provide 'reftex-cite) -;;; reftex-cite.el ends here - -;; Local Variables: -;; generated-autoload-file: "reftex-loaddefs.el" -;; End: diff --git a/lisp/textmodes/reftex-dcr.el b/lisp/textmodes/reftex-dcr.el deleted file mode 100644 index 65d0670bc35..00000000000 --- a/lisp/textmodes/reftex-dcr.el +++ /dev/null @@ -1,483 +0,0 @@ -;;; reftex-dcr.el --- viewing cross references and citations with RefTeX -*- lexical-binding: t; -*- - -;; Copyright (C) 1997-2025 Free Software Foundation, Inc. - -;; Author: Carsten Dominik -;; Maintainer: auctex-devel@gnu.org - -;; 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 . - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl-lib)) - -(declare-function bibtex-beginning-of-entry "bibtex" ()) - -(require 'reftex) - -;;;###autoload -(defun reftex-view-crossref (&optional arg auto-how fail-quietly) - "View cross reference of macro at point. - -Point must be on the KEY argument. When at a `\\ref' macro, show -corresponding `\\label' definition, also in external -documents (`xr'). When on a label, show a locations where KEY is -referenced. Subsequent calls find additional locations. When on -a `\\cite', show the associated `\\bibitem' macro or the BibTeX -database entry. When on a `\\bibitem', show a `\\cite' macro -which uses this KEY. When on an `\\index', show other locations -marked by the same index entry. - -To define additional cross referencing items, use the option -`reftex-view-crossref-extra'. See also `reftex-view-crossref-from-bibtex'. -With one or two \\[universal-argument] prefixes, enforce rescanning of the document. -With argument 2, select the window showing the cross reference. -AUTO-HOW is only for the automatic crossref display and is handed through -to the functions `reftex-view-cr-cite' and `reftex-view-cr-ref'." - - (interactive "P") - ;; See where we are. - (let* ((macro (car (reftex-what-macro-safe 1))) - (key (reftex-this-word "^{}%\n\r, \t")) - dw) - - (if (or (null macro) (reftex-in-comment)) - (or fail-quietly - (error "Not on a crossref macro argument")) - - (setq reftex-call-back-to-this-buffer (current-buffer)) - - (cond - ((string-match "\\`\\\\cite\\|cite\\([s*]\\|texts?\\)?\\'\\|bibentry" macro) - ;; A citation macro: search for bibitems or BibTeX entries. - ;; Match also commands from biblatex ending with `s' - ;; (\parencites) or `*' (\parencite*) and `texts?' - ;; (\footcitetext and \footcitetexts). - (setq dw (reftex-view-cr-cite arg key auto-how))) - ((string-match "\\`\\\\ref\\|ref\\(range\\|s\\)?\\*?\\'" macro) - ;; A reference macro: search for labels. - ;; Match also commands from cleveref ending with `s' (\namecrefs). - (setq dw (reftex-view-cr-ref arg key auto-how))) - (auto-how nil) ;; No further action for automatic display (speed) - ((or (equal macro "\\label") - (member macro reftex-macros-with-labels)) - ;; A label macro: search for reference macros - (reftex-access-scan-info arg) - (setq dw (reftex-view-regexp-match - (format reftex-find-reference-format (regexp-quote key)) - 4 nil nil))) - ((equal macro "\\bibitem") - ;; A bibitem macro: search for citations - (reftex-access-scan-info arg) - (setq dw (reftex-view-regexp-match - (format reftex-find-citation-regexp-format (regexp-quote key)) - 4 nil nil))) - ((member macro reftex-macros-with-index) - (reftex-access-scan-info arg) - (setq dw (reftex-view-regexp-match - (format reftex-find-index-entry-regexp-format - (regexp-quote key)) - 3 nil nil))) - (t - (reftex-access-scan-info arg) - (catch 'exit - (let ((list reftex-view-crossref-extra) - entry mre action group) - (while (setq entry (pop list)) - (setq mre (car entry) - action (nth 1 entry) - group (nth 2 entry)) - (when (string-match mre macro) - (setq dw (reftex-view-regexp-match - (format action key) group nil nil)) - (throw 'exit t)))) - (error "Not on a crossref macro argument")))) - (if (and (eq arg 2) (windowp dw)) (select-window dw))))) - -(defun reftex-view-cr-cite (arg key how) - ;; View cross-reference of a ref cite. HOW can have the values - ;; nil: Show in another window. - ;; echo: Show one-line info in echo area. - ;; tmp-window: Show in small window and arrange for window to disappear. - - ;; Ensure access to scanning info - (reftex-access-scan-info (or arg current-prefix-arg)) - - (if (eq how 'tmp-window) - ;; Remember the window configuration - (put 'reftex-auto-view-crossref 'last-window-conf - (current-window-configuration))) - - (let (files size item (pos (point)) (win (selected-window)) pop-win - (bibtype (reftex-bib-or-thebib))) - ;; Find the citation mode and the file list - (cond -; ((assq 'bib (symbol-value reftex-docstruct-symbol)) - ((eq bibtype 'bib) - (setq item nil - files (reftex-get-bibfile-list))) -; ((assq 'thebib (symbol-value reftex-docstruct-symbol)) - ((eq bibtype 'thebib) - (setq item t - files (reftex-uniquify - (mapcar #'cdr - (reftex-all-assq - 'thebib (symbol-value reftex-docstruct-symbol)))))) - (reftex-default-bibliography - (setq item nil - files (reftex-default-bibliography))) - (how) ;; don't throw for special display - (t (error "Cannot display crossref"))) - - (if (eq how 'echo) - ;; Display in Echo area - (reftex-echo-cite key files item) - ;; Display in a window - (if (not (eq how 'tmp-window)) - ;; Normal display - (reftex-pop-to-bibtex-entry key files nil t item) - ;; A temporary window - (condition-case nil - (reftex-pop-to-bibtex-entry key files nil t item) - (error (goto-char pos) - (message "cite: no such citation key %s" key) - (error ""))) - ;; Resize the window - (setq size (max 1 (count-lines (point) - (reftex-end-of-bib-entry item)))) - (let ((window-min-height 2)) - (shrink-window (1- (- (window-height) size))) - (recenter 0)) - ;; Arrange restoration - (add-hook 'pre-command-hook #'reftex-restore-window-conf)) - - ;; Normal display in other window - (add-hook 'pre-command-hook #'reftex-highlight-shall-die) - (setq pop-win (selected-window)) - (select-window win) - (goto-char pos) - (when (equal arg 2) - (select-window pop-win))))) - -(defun reftex-view-cr-ref (arg label how) - ;; View cross-reference of a ref macro. HOW can have the values - ;; nil: Show in another window. - ;; echo: Show one-line info in echo area. - ;; tmp-window: Show in small window and arrange for window to disappear. - - ;; Ensure access to scanning info - (reftex-access-scan-info (or arg current-prefix-arg)) - - (if (eq how 'tmp-window) - ;; Remember the window configuration - (put 'reftex-auto-view-crossref 'last-window-conf - (current-window-configuration))) - - (let* ((xr-data (assoc 'xr (symbol-value reftex-docstruct-symbol))) - (xr-re (nth 2 xr-data)) - (entry (assoc label (symbol-value reftex-docstruct-symbol))) - (win (selected-window)) pop-win (pos (point))) - - (if (and (not entry) (stringp label) xr-re (string-match xr-re label)) - ;; Label is defined in external document - (save-excursion - (save-match-data - (set-buffer - (or (reftex-get-file-buffer-force - (cdr (assoc (match-string 1 label) (nth 1 - xr-data)))) - (error "Problem with external label %s" label)))) - (setq label (substring label (match-end 1))) - (reftex-access-scan-info) - (setq entry - (assoc label (symbol-value reftex-docstruct-symbol))))) - (if (eq how 'echo) - ;; Display in echo area - (reftex-echo-ref label entry (symbol-value reftex-docstruct-symbol)) - (let ((window-conf (current-window-configuration))) - (condition-case nil - (reftex-show-label-location entry t nil t t) - (error (set-window-configuration window-conf) - (message "ref: Label %s not found" label) - (error "ref: Label %s not found" label)))) ;; 2nd is line OK - (add-hook 'pre-command-hook #'reftex-highlight-shall-die) - - (when (eq how 'tmp-window) - ;; Resize window and arrange restoration - (shrink-window (1- (- (window-height) 9))) - (recenter '(4)) - (add-hook 'pre-command-hook #'reftex-restore-window-conf)) - (setq pop-win (selected-window)) - (select-window win) - (goto-char pos) - (when (equal arg 2) - (select-window pop-win))))) - -;;;###autoload -(defun reftex-mouse-view-crossref (ev) - "View cross reference of \\ref or \\cite macro where you click. -If the macro at point is a \\ref, show the corresponding label definition. -If it is a \\cite, show the BibTeX database entry. -If there is no such macro at point, search forward to find one. -With argument, actually select the window showing the cross reference." - (interactive "e") - ;; Make sure the referencing macro stays visible in the original window. - (mouse-set-point ev) - (reftex-view-crossref current-prefix-arg)) - -(defun reftex-view-crossref-when-idle () - "Display info about crossref at point in echo area or a window. -This function is designed to work with an idle timer and returns quickly -if the call is useless." - (and reftex-mode - ;; Make sure message area is free if we need it. - (or (eq reftex-auto-view-crossref 'window) (not (current-message))) - ;; Make sure we are not already displaying this one - (not (memq last-command '(reftex-view-crossref - reftex-mouse-view-crossref))) - ;; Quick precheck if this might be a relevant spot - ;; `reftex-view-crossref' will do a more thorough check. - (save-excursion - (search-backward "\\" nil t) - (looking-at "\\\\[a-zA-Z]*\\(cite\\|ref\\|bibentry\\)")) - ;; Also check if point is inside a mandatory argument where the - ;; cite/ref key usually resides: (bug#38258) - (save-excursion - (condition-case nil - (let ((forward-sexp-function nil)) - (up-list -1) - (= (following-char) ?\{)) - (error nil))) - ;; Finally, call `reftex-view-crossref': - (condition-case nil - (let ((current-prefix-arg nil)) - (cond - ((eq reftex-auto-view-crossref t) - (reftex-view-crossref -1 'echo 'quiet)) - ((eq reftex-auto-view-crossref 'window) - (reftex-view-crossref -1 'tmp-window 'quiet)) - (t nil))) - (error nil)))) - -(defun reftex-restore-window-conf () - (set-window-configuration (get 'reftex-auto-view-crossref 'last-window-conf)) - (put 'reftex-auto-view-crossref 'last-window-conf nil) - (remove-hook 'pre-command-hook #'reftex-restore-window-conf)) - -(defun reftex-echo-ref (label entry docstruct) - ;; Display crossref info in echo area. - (cond - ((null docstruct) - (message "%s" - (substitute-command-keys (format reftex-no-info-message "ref")))) - ((null entry) - (message "ref: unknown label: %s" label)) - (t - (when (stringp (nth 2 entry)) - (message "ref(%s): %s" (nth 1 entry) (nth 2 entry))) - (let ((buf (get-buffer " *Echo Area*"))) - (when buf - (with-current-buffer buf - (run-hooks 'reftex-display-copied-context-hook))))))) - -(defun reftex-echo-cite (key files item) - ;; Display citation info in echo area. - (let* ((cache (assq 'bibview-cache (symbol-value reftex-docstruct-symbol))) - (cache-entry (assoc key (cdr cache))) - entry string buf (all-files files)) - - (if (and reftex-cache-cite-echo cache-entry) - ;; We can just use the cache - (setq string (cdr cache-entry)) - - ;; Need to look in the database - (unless reftex-revisit-to-echo - (setq files (reftex-visited-files files))) - - (setq entry - (condition-case nil - (save-excursion - (reftex-pop-to-bibtex-entry key files nil nil item t)) - (error - (if (and files (= (length all-files) (length files))) - (message "cite: no such database entry: %s" key) - (message "%s" (substitute-command-keys - (format reftex-no-info-message "cite")))) - nil))) - (when entry - (if item - (setq string (reftex-nicify-text entry)) - (setq string (reftex-make-cite-echo-string - (reftex-parse-bibtex-entry entry) - reftex-docstruct-symbol))))) - (unless (or (null string) (equal string "")) - (message "cite: %s" string)) - (when (setq buf (get-buffer " *Echo Area*")) - (with-current-buffer buf - (run-hooks 'reftex-display-copied-context-hook))))) - -;;;###autoload -(defun reftex-toggle-auto-view-crossref () - "Toggle the automatic display of crossref information in the echo area. -When active, leaving point idle in the argument of a \\ref or \\cite macro -will display info in the echo area." - (interactive) - (if reftex-auto-view-crossref-timer - (progn - (cancel-timer reftex-auto-view-crossref-timer) - (setq reftex-auto-view-crossref-timer nil) - (message "Automatic display of crossref information was turned off")) - (setq reftex-auto-view-crossref-timer - (run-with-idle-timer - reftex-idle-time t #'reftex-view-crossref-when-idle)) - (unless reftex-auto-view-crossref - (setq reftex-auto-view-crossref t)) - (message "Automatic display of crossref information was turned on"))) - -;;;###autoload -(defun reftex-view-crossref-from-bibtex (&optional arg) - "View location in a LaTeX document which cites the BibTeX entry at point. -Since BibTeX files can be used by many LaTeX documents, this function -prompts upon first use for a buffer in RefTeX mode. To reset this -link to a document, call the function with a prefix arg. -Calling this function several times find successive citation locations." - (interactive "P") - (when arg - ;; Break connection to reference buffer - (put 'reftex-bibtex-view-cite-locations :ref-buffer nil)) - (let ((ref-buffer (get 'reftex-bibtex-view-cite-locations :ref-buffer))) - ;; Establish connection to reference buffer - (unless ref-buffer - (setq ref-buffer - (save-current-buffer - (completing-read - "Reference buffer: " - (delq nil - (mapcar - (lambda (b) - (set-buffer b) - (if reftex-mode (list (buffer-name b)) nil)) - (buffer-list))) - nil t))) - (put 'reftex-bibtex-view-cite-locations :ref-buffer ref-buffer)) - ;; Search for citations - (bibtex-beginning-of-entry) - (if (looking-at - "@[a-zA-Z]+[ \t\n\r]*[{(][ \t\n\r]*\\([^, \t\r\n}]+\\)") - (progn - (goto-char (match-beginning 1)) - (reftex-view-regexp-match - (format reftex-find-citation-regexp-format - (regexp-quote (match-string 1))) - 4 arg ref-buffer)) - (error "Cannot find citation key in BibTeX entry")))) - -(defun reftex-view-regexp-match (re &optional highlight-group new ref-buffer) - ;; Search for RE in current document or in the document of REF-BUFFER. - ;; Continue the search, if the same re was searched last. - ;; Highlight the group HIGHLIGHT-GROUP of the match. - ;; When NEW is non-nil, start a new search regardless. - ;; Match point is displayed in another window. - ;; Upon success, returns the window which displays the match. - - ;;; Decide if new search or continued search - (let* ((oldprop (get 'reftex-view-regexp-match :props)) - (newprop (list (current-buffer) re)) - (cont (and (not new) (equal oldprop newprop))) - (cnt (if cont (get 'reftex-view-regexp-match :cnt) 0)) - (current-window (selected-window)) - (window-conf (current-window-configuration)) - match pop-window) - (switch-to-buffer-other-window (or ref-buffer (current-buffer))) - ;; Search - (condition-case nil - (if cont - (setq match (reftex-global-search-continue)) - (reftex-access-scan-info) - (setq match (reftex-global-search re (reftex-all-document-files)))) - (error nil)) - ;; Evaluate the match. - (if match - (progn - (put 'reftex-view-regexp-match :props newprop) - (put 'reftex-view-regexp-match :cnt (incf cnt)) - (reftex-highlight 0 (match-beginning highlight-group) - (match-end highlight-group)) - (add-hook 'pre-command-hook #'reftex-highlight-shall-die) - (setq pop-window (selected-window))) - (put 'reftex-view-regexp-match :props nil) - (or cont (set-window-configuration window-conf))) - (select-window current-window) - (if match - (progn - (message "Match Nr. %s" cnt) - pop-window) - (if cont - (error "No further matches (total number of matches: %d)" cnt) - (error "No matches"))))) - -(defvar reftex-global-search-marker (make-marker)) -(defun reftex-global-search (regexp file-list) - ;; Start a search for REGEXP in all files of FILE-LIST - (put 'reftex-global-search :file-list file-list) - (put 'reftex-global-search :regexp regexp) - (move-marker reftex-global-search-marker nil) - (reftex-global-search-continue)) - -(defun reftex-global-search-continue () - ;; Continue a global search started with `reftex-global-search' - (unless (get 'reftex-global-search :file-list) - (error "No global search to continue")) - (let* ((file-list (get 'reftex-global-search :file-list)) - (regexp (get 'reftex-global-search :regexp)) - (buf (or (marker-buffer reftex-global-search-marker) - (reftex-get-file-buffer-force (car file-list)))) - (pos (or (marker-position reftex-global-search-marker) 1)) - file) - ;; Take up starting position - (unless buf (error "No such buffer %s" buf)) - (switch-to-buffer buf) - (widen) - (goto-char pos) - ;; Search and switch file if necessary - (if (catch 'exit - (while t - (when (re-search-forward regexp nil t) - (move-marker reftex-global-search-marker (point)) - (throw 'exit t)) - ;; No match - goto next file - (pop file-list) - (or file-list (throw 'exit nil)) - (setq file (car file-list) - buf (reftex-get-file-buffer-force file)) - (unless buf (error "Cannot access file %s" file)) - (put 'reftex-global-search :file-list file-list) - (switch-to-buffer buf) - (widen) - (goto-char 1))) - t - (move-marker reftex-global-search-marker nil) - (error "All files processed")))) - -(provide 'reftex-dcr) - -;;; reftex-dcr.el ends here - -;; Local Variables: -;; generated-autoload-file: "reftex-loaddefs.el" -;; End: diff --git a/lisp/textmodes/reftex-global.el b/lisp/textmodes/reftex-global.el deleted file mode 100644 index 2463b231904..00000000000 --- a/lisp/textmodes/reftex-global.el +++ /dev/null @@ -1,532 +0,0 @@ -;;; reftex-global.el --- operations on entire documents with RefTeX -*- lexical-binding: t; -*- - -;; Copyright (C) 1997-2025 Free Software Foundation, Inc. - -;; Author: Carsten Dominik -;; Maintainer: auctex-devel@gnu.org - -;; 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 . - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl-lib)) -(provide 'reftex-global) -(require 'reftex) - -(declare-function fileloop-continue "fileloop") -;;; - -;;;###autoload -(defun reftex-create-tags-file () - "Create TAGS file by running `etags' on the current document. -The TAGS file is also immediately visited with `visit-tags-table'." - (interactive) - (reftex-access-scan-info current-prefix-arg) - (let ((master (reftex-TeX-master-file))) - (if (bufferp master) - (user-error "Cannot create TAGS file for non-file buffers") - (let* ((files (reftex-all-document-files)) - (cmd (format "%s %s" - etags-program-name - (mapconcat #'shell-quote-argument - files " ")))) - (with-current-buffer (reftex-get-file-buffer-force master) - (message "Running etags to create TAGS file...") - (shell-command cmd) - (visit-tags-table "TAGS")))))) - -;; History of grep commands. -(defvar reftex-grep-history nil) -(defvar reftex-grep-command "grep -n " - "Last grep command used in \\[reftex-grep-document]; default for next grep.") - -;;;###autoload -(defun reftex-grep-document (grep-cmd) - "Run grep query through all files related to this document. -With prefix arg, force to rescan document. -No active TAGS table is required." - - (interactive - (list (read-from-minibuffer "Run grep on document (like this): " - reftex-grep-command nil nil - 'reftex-grep-history))) - (reftex-access-scan-info current-prefix-arg) - (let* ((files (reftex-all-document-files t)) - (cmd (format - "%s %s" grep-cmd - (mapconcat #'identity files " ")))) - (grep cmd))) - -;;;###autoload -(defun reftex-search-document (&optional regexp) - "Regexp search through all files of the current document. -Starts always in the master file. Stops when a match is found. -To continue searching for next match, use command \\[tags-loop-continue]. -No active TAGS table is required." - (interactive) - (let ((default (reftex-this-word))) - (unless regexp - (setq regexp (read-string (format "Search regexp in document [%s]: " - default)))) - (if (string= regexp "") (setq regexp (regexp-quote default))) - - (reftex-access-scan-info current-prefix-arg) - (tags-search regexp (list 'reftex-all-document-files)))) - -;;;###autoload -(defun reftex-query-replace-document (&optional from to delimited) - "Do `query-replace-regexp' of FROM with TO over the entire document. -Third arg DELIMITED (prefix arg) means replace only word-delimited matches. - -As each match is found, the user must type a character saying -what to do with it. Type SPC or `y' to replace the match, -DEL or `n' to skip and go to the next match. For more directions, -type \\[help-command] at that time. - -If you exit (\\[keyboard-quit], RET or q), you can resume the query replace -with the command \\[tags-loop-continue]. -No active TAGS table is required." - (interactive) - (let ((default (reftex-this-word))) - (unless from - (setq from (read-string (format "Replace regexp in document [%s]: " - default))) - (if (string= from "") (setq from (regexp-quote default)))) - (unless to - (setq to (read-string (format "Replace regexp %s with: " from)))) - (reftex-access-scan-info current-prefix-arg) - (fileloop-initialize-replace - from to (reftex-all-document-files) - (if (equal from (downcase from)) nil 'default) - (or delimited current-prefix-arg)) - (fileloop-continue))) - -(defvar TeX-master) -(defvar isearch-next-buffer-function) - -;;;###autoload -(defun reftex-find-duplicate-labels () - "Produce a list of all duplicate labels in the document." - - (interactive) - - ;; Rescan the document to make sure - (reftex-access-scan-info t) - - (let ((master (reftex-TeX-master-file)) - (cnt 0) - (dlist - (mapcar - (lambda (x) - (let (x1) - (cond - ((memq (car x) - '(toc bof eof bib thebib label-numbers xr xr-doc - master-dir file-error bibview-cache appendix - is-multi index)) - nil) - (t - (setq x1 (reftex-all-assoc-string - (car x) (symbol-value reftex-docstruct-symbol))) - (if (< 1 (length x1)) - (append (list (car x)) - (mapcar (lambda(x) - (reftex--abbreviate-name (nth 3 x))) - x1)) - (list nil)))))) - (reftex-uniquify-by-car (symbol-value reftex-docstruct-symbol))))) - - (setq dlist (reftex-uniquify-by-car dlist)) - (if (null dlist) (error "No duplicate labels in document")) - (switch-to-buffer-other-window "*Duplicate Labels*") - (setq-local TeX-master master) - (erase-buffer) - (insert " MULTIPLE LABELS IN CURRENT DOCUMENT:\n") - (insert - (substitute-command-keys - " Move point to label and type \\`r' to run a query-replace on the label\n") - (substitute-command-keys - " and its references. Type \\`q' to exit this buffer.\n\n")) - (insert " LABEL FILE\n") - (insert " -------------------------------------------------------------\n") - (use-local-map (make-sparse-keymap)) - (local-set-key [?q] (lambda () "Kill this buffer." (interactive) - (kill-buffer (current-buffer)) (delete-window))) - (local-set-key [?r] 'reftex-change-label) - (while dlist - (when (and (car (car dlist)) - (cdr (car dlist))) - (incf cnt) - (insert (mapconcat #'identity (car dlist) "\n ") "\n")) - (pop dlist)) - (goto-char (point-min)) - (when (= cnt 0) - (kill-buffer (current-buffer)) - (delete-window) - (message "Document does not contain duplicate labels.")))) - -;;;###autoload -(defun reftex-change-label (&optional from to) - "Run `query-replace-regexp' of FROM with TO in all macro arguments. -Works on the entire multifile document. -If you exit (\\[keyboard-quit], RET or q), you can resume the query replace -with the command \\[tags-loop-continue]. -No active TAGS table is required." - (interactive) - (let ((default (reftex-this-word "-a-zA-Z0-9_*.:"))) - (unless from - (setq from (read-string (format "Replace label globally [%s]: " - default)))) - (if (string= from "") (setq from default)) - (unless to - (setq to (read-string (format "Replace label %s with: " from) - nil nil from))) - (reftex-query-replace-document - (concat "{" (regexp-quote from) "}") - (format "{%s}" to)))) - -;;;###autoload -(defun reftex-renumber-simple-labels () - "Renumber all simple labels in the document to make them sequentially. -Simple labels are the ones created by RefTeX, consisting only of the -prefix and a number. After the command completes, all these labels will -have sequential numbers throughout the document. Any references to -the labels will be changed as well. For this, RefTeX looks at the -arguments of any macros which either start or end in the string `ref'. -This command should be used with care, in particular in multifile -documents. You should not use it if another document refers to this -one with the `xr' package." - (interactive) - ;; Rescan the entire document - (reftex-access-scan-info 1) - ;; Get some insurance - (if (and (reftex-is-multi) - (not (yes-or-no-p "Replacing all simple labels in multiple files is risky. Continue? "))) - (error "Abort")) - ;; Make the translation list - (let* ((re-core (concat "\\(" - (mapconcat #'cdr reftex-typekey-to-prefix-alist "\\|") - "\\)")) - (label-re (concat "\\`" re-core "\\([0-9]+\\)\\'")) - (search-re (concat "[{,]\\(" re-core "\\([0-9]+\\)\\)[,}]")) - (error-fmt "Undefined label or reference %s. Ignore and continue? ") - (label-numbers-alist (mapcar (lambda (x) (cons (cdr x) 0)) - reftex-typekey-to-prefix-alist)) - (files (reftex-all-document-files)) - (list (symbol-value reftex-docstruct-symbol)) - translate-alist n entry label new-label nr-cell changed-sequence) - - (while (setq entry (pop list)) - (when (and (stringp (car entry)) - (string-match label-re (car entry))) - (setq label (car entry) - nr-cell (assoc (match-string 1 (car entry)) - label-numbers-alist)) - (if (assoc label translate-alist) - (error "Duplicate label %s" label)) - (setq new-label (concat (match-string 1 (car entry)) - (int-to-string (incf (cdr nr-cell))))) - (push (cons label new-label) translate-alist) - (or (string= label new-label) (setq changed-sequence t)))) - - (unless changed-sequence - (error "Simple labels are already in correct sequence")) - - (reftex-ensure-write-access (reftex-all-document-files)) - - ;; Save all document buffers before this operation - (reftex-save-all-document-buffers) - - ;; First test to check for errors. - (setq n (reftex-translate - files search-re translate-alist error-fmt 'test)) - - ;; Now the real thing. - (if (yes-or-no-p - (format "Replace %d items at %d places in %d files? " - (length translate-alist) n (length files))) - (progn - (let ((inhibit-quit t)) ;; Do not disturb... - (reftex-translate - files search-re translate-alist error-fmt nil) - (setq quit-flag nil)) - (if (and (reftex-is-multi) - (yes-or-no-p "Save entire document? ")) - (reftex-save-all-document-buffers)) - ;; Rescan again... - (reftex-access-scan-info 1) - (message "Done replacing simple labels.")) - (message "No replacements done")))) - -(defun reftex-translate (files search-re translate-alist error-fmt test) - ;; In FILES, look for SEARCH-RE and replace match 1 of it with - ;; its association in TRANSLATE-ALIST. - ;; If we do not find an association and TEST is non-nil, query - ;; to ignore the problematic string. - ;; If TEST is nil, it is ignored without query. - ;; Return the number of replacements. - (let ((n 0) - (opt-re (concat "\\(?:{[^}{]*" - "\\(?:{[^}{]*" - "\\(?:{[^}{]*}[^}{]*\\)*" - "}[^}{]*\\)*" - "}[^][]*\\)*")) - (man-re (concat "\\(?:{[^}{]*" - "\\(?:{[^}{]*" - "\\(?:{[^}{]*}[^}{]*\\)*" - "}[^}{]*\\)*" - "}[^}{]*\\)*")) - file label match-data buf macro pos cell) - (while (setq file (pop files)) - (setq buf (reftex-get-file-buffer-force file)) - (unless buf - (error "No such file %s" file)) - (set-buffer buf) - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (while (re-search-forward search-re nil t) - (backward-char) - (save-excursion - (setq label (reftex-match-string 1) - cell (assoc label translate-alist) - match-data (match-data) - macro (reftex-what-macro 1) - pos (cdr macro)) - (goto-char (or pos (point))) - (when (and macro - (or (looking-at "\\\\ref") - (looking-at "\\\\[a-zA-Z]*ref\\(range\\)?[^a-zA-Z]") - (looking-at "\\\\ref[a-zA-Z]*[^a-zA-Z]") - (looking-at (format - reftex-find-label-regexp-format - (regexp-quote label))) - ;; In case the label-keyval is inside an - ;; optional argument to \begin{env} - (looking-at (concat - "\\\\begin[[:space:]]*{[^}]+}" - "[[:space:]]*" - "\\[[^][]*" - opt-re - (format - reftex-find-label-regexp-format - (regexp-quote label)) - "[^]]*\\]")) - ;; In case the label-keyval is inside the - ;; first mandatory argument to \begin{env} - (looking-at (concat - "\\\\begin[[:space:]]*{[^}]+}" - "[[:space:]]*" - "{[^}{]*" - man-re - (format - reftex-find-label-regexp-format - (regexp-quote label)) - "[^}]*}")))) - ;; OK, we should replace it. - (set-match-data match-data) - (cond - ((and test (not cell)) - ;; We've got a problem - (unwind-protect - (progn - (reftex-highlight 1 (match-beginning 0) (match-end 0)) - (ding) - (or (y-or-n-p (format error-fmt label)) - (error "Abort"))) - (reftex-unhighlight 1))) - ((and test cell) - (incf n)) - ((and (not test) cell) - ;; Replace - (goto-char (match-beginning 1)) - (delete-region (match-beginning 1) (match-end 1)) - (insert (cdr cell))) - (t nil)))))))) - n)) - -;;;###autoload -(defun reftex-save-all-document-buffers () - "Save all documents associated with the current document. -The function is useful after a global action like replacing or renumbering -labels." - (interactive) - (let ((files (reftex-all-document-files)) - file buffer) - (save-current-buffer - (while (setq file (pop files)) - (when (stringp file) ; Ignore non-file buffers. - (setq buffer (find-buffer-visiting file)) - (when buffer - (set-buffer buffer) - (save-buffer))))))) - -(defun reftex-ensure-write-access (files) - "Make sure we have write access to all files in FILES. -Also checks if buffers visiting the files are in read-only mode." - (let (file buf) - (while (setq file (pop files)) ; Ignore non-file buffers. - (when (stringp file) - (unless (file-exists-p file) - (ding) - (or (y-or-n-p (format "No such file %s. Continue?" file)) - (error "Abort"))) - (unless (file-writable-p file) - (ding) - (or (y-or-n-p (format "No write access to %s. Continue?" file)) - (error "Abort"))) - (when (and (setq buf (find-buffer-visiting file)) - (with-current-buffer buf - buffer-read-only)) - (ding) - (or (y-or-n-p (format "Buffer %s is read-only. Continue?" - (buffer-name buf))) - (error "Abort"))))))) - -;;; Multi-file RefTeX Isearch - -;; `reftex-isearch-wrap-function', `reftex-isearch-push-state-function', -;; `reftex-isearch-pop-state-function', `reftex-isearch-isearch-search' -;; functions remain here only for backward-compatibility with Emacs 22 -;; and are obsolete since Emacs 23 that supports a single function -;; variable `multi-isearch-next-buffer-function'. - -(defun reftex-isearch-wrap-function () - (switch-to-buffer - (funcall isearch-next-buffer-function (current-buffer) t)) - (goto-char (if isearch-forward (point-min) (point-max)))) - -(defun reftex-isearch-push-state-function () - (let ((buf (current-buffer))) - (lambda (cmd) (reftex-isearch-pop-state-function cmd buf)))) - -(defun reftex-isearch-pop-state-function (_cmd buffer) - (switch-to-buffer buffer)) - -(defun reftex-isearch-isearch-search (string bound noerror) - (let ((nxt-buff nil) - (search-fun (isearch-search-fun-default))) - (or - (funcall search-fun string bound noerror) - (unless bound - (condition-case nil - (when isearch-next-buffer-function - (while (not (funcall search-fun string bound noerror)) - (cond - (isearch-forward - (setq nxt-buff - (funcall isearch-next-buffer-function - (current-buffer))) - (if (not nxt-buff) - (progn - (error "Wrap forward")) - (switch-to-buffer nxt-buff) - (goto-char (point-min)))) - (t - (setq nxt-buff - (funcall isearch-next-buffer-function - (current-buffer))) - (if (not nxt-buff) - (progn - (error "Wrap backward")) - (switch-to-buffer nxt-buff) - (goto-char (point-max)))))) - (point)) - (error nil)))))) - -;; This function is called when isearch reaches the end of a -;; buffer. For reftex what we want to do is not wrap to the -;; beginning, but switch to the next buffer in the logical order of -;; the document. This function looks through list of files in the -;; document (reftex-all-document-files), searches for the current -;; buffer and switches to the next/previous one in the logical order -;; of the document. If WRAPP is true then wrap the search to the -;; beginning/end of the file list, depending of the search direction. -(defun reftex-isearch-switch-to-next-file (crt-buf &optional wrapp) - (reftex-access-scan-info) - (let ((cb (reftex--get-buffer-identifier crt-buf)) - (flist (reftex-all-document-files))) - (when flist - (if wrapp - (unless isearch-forward - (setq flist (last flist))) - (unless isearch-forward - (setq flist (reverse flist))) - (while (not (equal (car flist) cb)) - (setq flist (cdr flist))) - (setq flist (cdr flist))) - (when flist - (find-file-noselect (car flist)))))) - -;; NB this is a global autoload - see reftex.el. -;;;###autoload -(defun reftex-isearch-minor-mode (&optional arg) - "When on, isearch searches the whole document, not only the current file. -This minor mode allows isearch to search through all the files of -the current TeX document. - -With no argument, this command toggles -`reftex-isearch-minor-mode'. With a prefix argument ARG, turn -`reftex-isearch-minor-mode' on if ARG is positive, otherwise turn it off." - (interactive "P") - (let ((old-reftex-isearch-minor-mode reftex-isearch-minor-mode)) - (setq reftex-isearch-minor-mode - (not (or (and (null arg) reftex-isearch-minor-mode) - (<= (prefix-numeric-value arg) 0)))) - (unless (eq reftex-isearch-minor-mode old-reftex-isearch-minor-mode) - (if reftex-isearch-minor-mode - (progn - (dolist (crt-buf (buffer-list)) - (with-current-buffer crt-buf - (when reftex-mode - (if (boundp 'multi-isearch-next-buffer-function) - (setq-local multi-isearch-next-buffer-function - #'reftex-isearch-switch-to-next-file) - (setq-local isearch-wrap-function - #'reftex-isearch-wrap-function) - (setq-local isearch-search-fun-function - (lambda () #'reftex-isearch-isearch-search)) - (setq-local isearch-push-state-function - #'reftex-isearch-push-state-function) - (setq-local isearch-next-buffer-function - #'reftex-isearch-switch-to-next-file)) - (setq reftex-isearch-minor-mode t)))) - (add-hook 'reftex-mode-hook #'reftex-isearch-minor-mode)) - (dolist (crt-buf (buffer-list)) - (with-current-buffer crt-buf - (when reftex-mode - (if (boundp 'multi-isearch-next-buffer-function) - (kill-local-variable 'multi-isearch-next-buffer-function) - (kill-local-variable 'isearch-wrap-function) - (kill-local-variable 'isearch-search-fun-function) - (kill-local-variable 'isearch-push-state-function) - (kill-local-variable 'isearch-next-buffer-function)) - (setq reftex-isearch-minor-mode nil)))) - (remove-hook 'reftex-mode-hook #'reftex-isearch-minor-mode))) - ;; Force mode line redisplay. - (set-buffer-modified-p (buffer-modified-p)))) - -(add-minor-mode 'reftex-isearch-minor-mode "/I" nil nil - 'reftex-isearch-minor-mode) - -;;; reftex-global.el ends here - -;; Local Variables: -;; generated-autoload-file: "reftex-loaddefs.el" -;; End: diff --git a/lisp/textmodes/reftex-index.el b/lisp/textmodes/reftex-index.el deleted file mode 100644 index d4c00b0cea5..00000000000 --- a/lisp/textmodes/reftex-index.el +++ /dev/null @@ -1,2086 +0,0 @@ -;;; reftex-index.el --- index support with RefTeX -*- lexical-binding: t; -*- - -;; Copyright (C) 1997-2025 Free Software Foundation, Inc. - -;; Author: Carsten Dominik -;; Maintainer: auctex-devel@gnu.org - -;; 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 . - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl-lib)) -(declare-function texmathp "ext:texmathp" ()) - -(require 'reftex) - -(defvar TeX-master) - -;;;###autoload -(defun reftex-index-selection-or-word (&optional arg phrase) - "Put selection or the word near point into the default index macro. -This uses the information in `reftex-index-default-macro' to make an index -entry. The phrase indexed is the current selection or the word near point. -When called with one \\[universal-argument] prefix, let the user have a chance to edit the -index entry. When called with 2 \\[universal-argument] as prefix, also ask for the index -macro and other stuff. -When called inside TeX math mode as determined by the `texmathp.el' library -which is part of AUCTeX, the string is first processed with the -`reftex-index-math-format', which see." - (interactive "P") - (let* ((use-default (not (equal arg '(16)))) ; check for double prefix - ;; check if we have an active selection - (active (region-active-p)) - (beg (if active - (region-beginning) - (save-excursion - (skip-syntax-backward "w\\") (point)))) - (end (if active - (region-end) - (save-excursion - (skip-syntax-forward "w\\") (point)))) - (sel (buffer-substring beg end)) - (mathp (condition-case nil (texmathp) (error nil))) - (current-prefix-arg nil) ; we want to call reftex-index without prefix. - key def-char def-tag full-entry) - - (if phrase - (progn - (reftex-index-visit-phrases-buffer) - (reftex-index-new-phrase sel)) - - (if (equal sel "") - ;; Nothing selected, no word, so use full reftex-index command - (reftex-index) - ;; OK, we have something to index here. - ;; Add the dollars when necessary - (setq key (if mathp - (format reftex-index-math-format sel) - sel)) - ;; Get info from `reftex-index-default-macro' - (setq def-char (if use-default (car reftex-index-default-macro))) - (setq def-tag (if use-default (nth 1 reftex-index-default-macro))) - ;; Does the user want to edit the entry? - (setq full-entry (if arg - (reftex-index-complete-key - def-tag nil (cons key 0)) - key)) - ;; Delete what is in the buffer and make the index entry - (delete-region beg end) - (reftex-index def-char full-entry def-tag sel))))) - -;;;###autoload -(defun reftex-index (&optional char key tag sel _no-insert) - "Query for an index macro and insert it along with its arguments. -The index macros available are those defined in `reftex-index-macro' or -by a call to `reftex-add-index-macros', typically from an AUCTeX style file. -RefteX provides completion for the index tag and the index key, and -will prompt for other arguments." - - (interactive) - - ;; Ensure access to scanning info - (reftex-ensure-index-support t) - (reftex-access-scan-info current-prefix-arg) - - ;; Find out which macro we are going to use - (let* ((char (or char - (reftex-select-with-char reftex-query-index-macro-prompt - reftex-query-index-macro-help))) - (macro (nth 1 (assoc char reftex-key-to-index-macro-alist))) - (entry (or (assoc macro reftex-index-macro-alist) - (error "No index macro associated with %c" char))) - (ntag (nth 1 entry)) - (tag (or tag (nth 1 entry))) - (nargs (nth 4 entry)) - (nindex (nth 5 entry)) - (opt-args (nth 6 entry)) - (repeat (nth 7 entry)) - opt tag1 value) - - ;; Get the supported arguments - (if (stringp tag) - (setq tag1 tag) - (setq tag1 (or (reftex-index-complete-tag tag opt-args) ""))) - (setq key (or key - (reftex-index-complete-key - (if (string= tag1 "") "idx" tag1) - (member nindex opt-args)))) - - ;; Insert the macro and ask for any additional args - (insert macro) - (cl-loop for i from 1 to nargs do - (setq opt (member i opt-args) - value (cond ((= nindex i) key) - ((equal ntag i) tag1) - (t (read-string (concat "Macro arg nr. " - (int-to-string i) - (if opt " (optional)" "") - ": "))))) - (unless (and opt (string= value "")) - (insert (if opt "[" "{") value (if opt "]" "}")))) - (and repeat (stringp sel) (insert sel)) - (and key reftex-plug-into-AUCTeX (fboundp 'LaTeX-add-index-entries) - (LaTeX-add-index-entries key)) - (reftex-index-update-taglist tag1) - (reftex-notice-new))) - -(defun reftex-default-index () - (cond ((null reftex-index-default-tag) nil) - ((stringp reftex-index-default-tag) reftex-index-default-tag) - (t (or (get reftex-docstruct-symbol 'default-index-tag) - "idx")))) - -(defun reftex-update-default-index (tag &optional tag-list) - (if (and (not (equal tag "")) - (stringp tag) - (eq reftex-index-default-tag 'last) - (or (null tag-list) - (member tag tag-list))) - (put reftex-docstruct-symbol 'default-index-tag tag))) - -;;;###autoload -(defun reftex-index-complete-tag (&optional itag opt-args) - ;; Ask the user for a tag, completing on known tags. - ;; ITAG is the argument number which contains the tag. - ;; OPT-ARGS is a list of optional argument indices, as given by - ;; `reftex-parse-args'. - (let* ((opt (and (integerp itag) (member itag opt-args))) - (index-tags (cdr (assq 'index-tags - (symbol-value reftex-docstruct-symbol)))) - (default (reftex-default-index)) - (prompt (concat "Index tag" - (if (or opt default) - (format " (%s): " - (concat - (if opt "optional" "") - (if default - (concat (if opt ", " "") - (format "default %s" default)) - ""))) - ": "))) - (tag (completing-read prompt (mapcar #'list index-tags)))) - (if (and default (equal tag "")) (setq tag default)) - (reftex-update-default-index tag) - tag)) - -;;;###autoload -(defun reftex-index-select-tag () - ;; Have the user select an index tag. - ;; FIXME: should we cache tag-alist, prompt and help? - (let* ((index-tags (cdr (assoc 'index-tags - (symbol-value reftex-docstruct-symbol)))) - (default (reftex-default-index))) - (cond - ((null index-tags) - (error "No index tags available")) - - ((= (length index-tags) 1) - ;; Just one index, use it - (car index-tags)) - - ((> (length index-tags) 1) - ;; Several indices, ask. - (let* ((tags (copy-sequence index-tags)) - (cnt 0) - tag-alist i val len tag prompt help rpl) - ;; Move idx and glo up in the list to ensure ?i and ?g shortcuts - (if (member "glo" tags) - (setq tags (cons "glo" (delete "glo" tags)))) - (if (member "idx" tags) - (setq tags (cons "idx" (delete "idx" tags)))) - ;; Find unique shortcuts for each index. - (while (setq tag (pop tags)) - (setq len (length tag) - i -1 - val nil) - (catch 'exit - (while (and (< (incf i) len) (null val)) - (unless (assq (aref tag i) tag-alist) - (push (list (aref tag i) - tag - (concat (substring tag 0 i) - "[" (substring tag i (incf i)) "]" - (substring tag i))) - tag-alist) - (throw 'exit t))) - (push (list (+ ?0 (incf cnt)) tag - (concat "[" (int-to-string cnt) "]:" tag)) - tag-alist))) - (setq tag-alist (nreverse tag-alist)) - ;; Compute Prompt and Help strings - (setq prompt - (concat - (format "Select Index%s: " - (if default (format " (Default <%s>)" default) "")) - (mapconcat (lambda(x) (nth 2 x)) tag-alist " "))) - (setq help - (concat "Select an Index\n===============\n" - (if default - (format "[^M] %s (the default)\n" default) - "") - (mapconcat (lambda(x) - (apply #'format "[%c] %s" x)) - tag-alist "\n"))) - ;; Query the user for an index-tag - (setq rpl (reftex-select-with-char prompt help 3 t)) - (message "") - (if (and default (equal rpl ?\C-m)) - default - (if (assq rpl tag-alist) - (progn - (reftex-update-default-index (nth 1 (assq rpl tag-alist))) - (nth 1 (assq rpl tag-alist))) - (error "No index tag associated with %c" rpl))))) - (t (error "This should not happen (reftex-index-select-tag)"))))) - -;;;###autoload -(defun reftex-index-complete-key (&optional tag optional initial) - ;; Read an index key, with completion. - ;; Restrict completion table on index tag TAG. - ;; OPTIONAL indicates if the arg is optional. - (let* ((table (reftex-sublist-nth - (symbol-value reftex-docstruct-symbol) 6 - (lambda(x) (and (eq (car x) 'index) - (string= (nth 1 x) (or tag "")))) - t)) - (prompt (concat "Index key" (if optional " (optional)" "") ": ")) - (key (completing-read prompt table nil nil initial))) - key)) - -(defun reftex-index-update-taglist (newtag) - ;; add NEWTAG to the list of available index tags. - (let ((cell (assoc 'index-tags (symbol-value reftex-docstruct-symbol)))) - (and newtag (cdr cell) (not (member newtag (cdr cell))) - (push newtag (cdr cell))))) - -(defvar reftex-index-mode-map - (let ((map (make-sparse-keymap))) - ;; Index map - (define-key map [(mouse-2)] #'reftex-index-mouse-goto-line-and-hide) - (define-key map [follow-link] 'mouse-face) - - (define-key map [remap next-line] #'reftex-index-next) - (define-key map [remap previous-line] #'reftex-index-previous) - - (define-key map "n" #'reftex-index-next) - (define-key map "p" #'reftex-index-previous) - (define-key map "?" #'reftex-index-show-help) - (define-key map " " #'reftex-index-view-entry) - (define-key map "\C-m" #'reftex-index-goto-entry-and-hide) - (define-key map "\C-i" #'reftex-index-goto-entry) - (define-key map "\C-k" #'reftex-index-kill) - (define-key map "r" #'reftex-index-rescan) - (define-key map "R" #'reftex-index-Rescan) - (define-key map "g" #'revert-buffer) - (define-key map "q" #'reftex-index-quit) - (define-key map "k" #'reftex-index-quit-and-kill) - (define-key map "f" #'reftex-index-toggle-follow) - (define-key map "s" #'reftex-index-switch-index-tag) - (define-key map "e" #'reftex-index-edit) - (define-key map "^" #'reftex-index-level-up) - (define-key map "_" #'reftex-index-level-down) - (define-key map "}" #'reftex-index-restrict-to-section) - (define-key map "{" #'reftex-index-widen) - (define-key map ">" #'reftex-index-restriction-forward) - (define-key map "<" #'reftex-index-restriction-backward) - (define-key map "(" #'reftex-index-toggle-range-beginning) - (define-key map ")" #'reftex-index-toggle-range-end) - (define-key map "|" #'reftex-index-edit-attribute) - (define-key map "@" #'reftex-index-edit-visual) - (define-key map "*" #'reftex-index-edit-key) - (define-key map "\C-c=" #'reftex-index-goto-toc) - (define-key map "c" #'reftex-index-toggle-context) - - ;; The capital letters and the exclamation mark - (mapc (lambda (key) - (define-key map (vector (list key)) - (lambda () (interactive) - (reftex-index-goto-letter key)))) - (concat "!" reftex-index-section-letters)) - - (easy-menu-define reftex-index-menu map - "Menu for Index buffer" - '("Index" - ["Goto section A-Z" - (message "To go to a section, just press any of: !%s" - reftex-index-section-letters) - t] - ["Show Entry" reftex-index-view-entry t] - ["Go To Entry" reftex-index-goto-entry t] - ["Exit & Go To Entry" reftex-index-goto-entry-and-hide t] - ["Table of Contents" reftex-index-goto-toc t] - ["Quit" reftex-index-quit t] - "--" - ("Update" - ["Rebuilt *Index* Buffer" revert-buffer t] - "--" - ["Rescan One File" reftex-index-rescan reftex-enable-partial-scans] - ["Rescan Entire Document" reftex-index-Rescan t]) - ("Restrict" - ["Restrict to section" reftex-index-restrict-to-section t] - ["Widen" reftex-index-widen reftex-index-restriction-indicator] - ["Next Section" reftex-index-restriction-forward - reftex-index-restriction-indicator] - ["Previous Section" reftex-index-restriction-backward - reftex-index-restriction-indicator]) - ("Edit" - ["Edit Entry" reftex-index-edit t] - ["Edit Key" reftex-index-edit-key t] - ["Edit Attribute" reftex-index-edit-attribute t] - ["Edit Visual" reftex-index-edit-visual t] - "--" - ["Add Parentkey" reftex-index-level-down t] - ["Remove Parentkey " reftex-index-level-up t] - "--" - ["Make Start-of-Range" reftex-index-toggle-range-beginning t] - ["Make End-of-Range" reftex-index-toggle-range-end t] - "--" - ["Kill Entry" reftex-index-kill nil] - "--" - ["Undo" reftex-index-undo nil]) - ("Options" - ["Context" reftex-index-toggle-context :style toggle - :selected reftex-index-include-context] - "--" - ["Follow Mode" reftex-index-toggle-follow :style toggle - :selected reftex-index-follow-mode]) - "--" - ["Help" reftex-index-show-help t])) - - map) - "Keymap used for *Index* buffers.") - -(defvar reftex-index-menu) - -(defvar reftex-last-index-file nil - "Stores the file name from which `reftex-display-index' was called.") -(defvar reftex-index-tag nil - "Stores the tag of the index in an index buffer.") - -(defvar reftex-index-return-marker (make-marker) - "Marker which makes it possible to return from index to old position.") - -(defvar reftex-index-restriction-indicator nil) -(defvar reftex-index-restriction-data nil) - -(define-derived-mode reftex-index-mode special-mode "RefTeX Index" - "Major mode for managing Index buffers for LaTeX files. -This buffer was created with RefTeX. -Press `?' for a summary of important key bindings, or check the menu. - -Here are all local bindings. - -\\{reftex-index-mode-map}" - (setq-local revert-buffer-function #'reftex-index-revert) - (setq-local reftex-index-restriction-data nil) - (setq-local reftex-index-restriction-indicator nil) - (setq mode-line-format - (list "---- " 'mode-line-buffer-identification - " " 'global-mode-string - " R<" 'reftex-index-restriction-indicator ">" - " -%-")) - (setq truncate-lines t) - (make-local-variable 'reftex-last-follow-point) - (add-hook 'post-command-hook #'reftex-index-post-command-hook nil t) - (add-hook 'pre-command-hook #'reftex-index-pre-command-hook nil t)) - -(defconst reftex-index-help -" AVAILABLE KEYS IN INDEX BUFFER - ============================== -! A..Z Goto the section of entries starting with this letter. -n / p next-entry / previous-entry -SPC / TAB Show/Goto the corresponding entry in the LaTeX document. -RET Goto the entry and hide the *Index* window (also on mouse-2). -q / k Hide/Kill *Index* buffer. -C-c = Switch to the TOC buffer. -f / c Toggle follow mode / Toggle display of [c]ontext. -g Refresh *Index* buffer. -r / C-u r Reparse the LaTeX document / Reparse entire LaTeX document. -s Switch to a different index (for documents with multiple indices). -e / C-k Edit/Kill the entry. -* | @ Edit specific part of entry: [*]key [|]attribute [@]visual - With prefix: kill that part. -\( ) Toggle entry's beginning/end of page range property. -_ ^ Add/Remove parent key (to make this item a subitem). -} / { Restrict Index to a single document section / Widen. -< / > When restricted, move restriction to previous/next section.") - -;;;###autoload -(defun reftex-index-show-entry (data &optional no-revisit) - ;; Find an index entry associated with DATA and display it highlighted - ;; in another window. NO-REVISIT means we are not allowed to visit - ;; files for this. - ;; Note: This function just looks for the nearest match of the - ;; context string and may fail if the entry moved and an identical - ;; entry is close to the old position. Frequent rescans make this - ;; safer. - (let* ((file (nth 3 data)) - (literal (nth 2 data)) - (pos (nth 4 data)) - (re (regexp-quote literal)) - (match - (cond - ((or (not no-revisit) - (find-buffer-visiting file)) - (switch-to-buffer-other-window - (reftex-get-file-buffer-force file nil)) - (goto-char (or pos (point-min))) - (or (looking-at re) - (reftex-nearest-match re (length literal)))) - (t (message "%s" reftex-no-follow-message) nil)))) - (when match - (goto-char (match-beginning 0)) - (recenter '(4)) - (reftex-highlight 0 (match-beginning 0) (match-end 0) (current-buffer))) - match)) - -;;;###autoload -(defun reftex-display-index (&optional tag overriding-restriction redo - &rest locations) - "Display a buffer with an index compiled from the current document. -When the document has multiple indices, first prompts for the correct one. -When index support is turned off, offer to turn it on. -With one or two \\[universal-argument] prefixes, rescan document first. -With prefix 2, restrict index to current document section. -With prefix 3, restrict index to region." - - (interactive) - - ;; Ensure access to scanning info and rescan buffer if prefix arg is '(4). - (let ((current-prefix-arg current-prefix-arg)) - (reftex-ensure-index-support t) - (reftex-access-scan-info current-prefix-arg)) - - (set-marker reftex-index-return-marker (point)) - (setq reftex-last-follow-point 1) - - ;; Determine the correct index to process - (let* ((docstruct (symbol-value reftex-docstruct-symbol)) - (docstruct-symbol reftex-docstruct-symbol) - (index-tag (or tag (reftex-index-select-tag))) - (master (reftex-TeX-master-file)) - (calling-file (reftex--get-buffer-identifier)) - (restriction - (or overriding-restriction - (and (not redo) - (reftex-get-restriction current-prefix-arg docstruct)))) - (locations - ;; See if we are on an index macro as initial position - (or locations - (let* ((what-macro (reftex-what-macro-safe 1)) - (macro (car what-macro)) - (here-I-am (when (member macro reftex-macros-with-index) - (save-excursion - (goto-char (+ (cdr what-macro) - (length macro))) - (reftex-move-over-touching-args) - (reftex-where-am-I))))) - (if (eq (car (car here-I-am)) 'index) - (list (car here-I-am)))))) - buffer-name) - - (setq buffer-name (reftex-make-index-buffer-name index-tag)) - - ;; Goto the buffer and put it into the correct mode - - (when (or restriction current-prefix-arg) - (reftex-kill-buffer buffer-name)) - - (if (get-buffer-window buffer-name) - (select-window (get-buffer-window buffer-name)) - (switch-to-buffer buffer-name)) - - (or (eq major-mode 'reftex-index-mode) (reftex-index-mode)) - - ;; If the buffer is currently restricted, empty it to force update. - (when reftex-index-restriction-data - (reftex-erase-buffer)) - (setq-local reftex-last-index-file calling-file) - (setq-local reftex-index-tag index-tag) - (setq-local reftex-docstruct-symbol docstruct-symbol) - (if restriction - (setq reftex-index-restriction-indicator (car restriction) - reftex-index-restriction-data (cdr restriction)) - (if (not redo) - (setq reftex-index-restriction-indicator nil - reftex-index-restriction-data nil))) - (when (= (buffer-size) 0) - ;; buffer is empty - fill it - (message "Building %s buffer..." buffer-name) - - (setq buffer-read-only nil) - (insert (format - "INDEX <%s> on %s -Restriction: <%s> -SPC=view TAB=goto RET=goto+hide [e]dit [q]uit [r]escan [f]ollow [?]Help ------------------------------------------------------------------------------- -" - index-tag (reftex--abbreviate-name master) - (if (eq (car (car reftex-index-restriction-data)) 'toc) - (nth 2 (car reftex-index-restriction-data)) - reftex-index-restriction-indicator))) - - (if reftex-use-fonts - (put-text-property (point-min) (point) - 'face reftex-index-header-face)) - (cursor-intangible-mode 1) - (add-text-properties (point-min) (point) - '(cursor-intangible t - front-sticky (cursor-intangible) - rear-nonsticky (cursor-intangible))) - - (reftex-insert-index docstruct index-tag) - (goto-char (point-min)) - (run-hooks 'reftex-display-copied-context-hook) - (message "Building %s buffer...done." buffer-name) - (setq buffer-read-only t)) - (and locations (apply #'reftex-find-start-point (point) locations)) - (if reftex-index-restriction-indicator - (message "Index restricted: <%s>" reftex-index-restriction-indicator)))) - -(defun reftex-insert-index (docstruct tag &optional update-one remark) - ;; Insert an index into the current buffer. Entries are from the - ;; DOCSTRUCT. - ;; TAG is the subindex to process. - ;; UPDATE-ONE: When non-nil, delete the entry at point and replace - ;; it with whatever the DOCSTRUCT contains. - ;; REMARK can be a note to add to the entry. - (let* ((all docstruct) - (indent " ") - (context reftex-index-include-context) - (context-indent (concat indent " ")) - (section-chars (mapcar #'identity reftex-index-section-letters)) - (this-section-char 0) - (font reftex-use-fonts) - (bor (car reftex-index-restriction-data)) - (eor (nth 1 reftex-index-restriction-data)) - (mouse-face - (if (memq reftex-highlight-selection '(mouse both)) - reftex-mouse-selected-face - nil)) - (index-face reftex-label-face) - sublist cell from to first-char) - - ;; Make the sublist and sort it - (when bor - (setq all (or (memq bor all) all))) - - (while (setq cell (pop all)) - (if (eq cell eor) - (setq all nil) - (and (eq (car cell) 'index) - (equal (nth 1 cell) tag) - (push cell sublist)))) - (setq sublist (sort (nreverse sublist) - (lambda (a b) (string< (nth 8 a) (nth 8 b))))) - - (when update-one - ;; Delete the entry at place - (and (bolp) (forward-char 1)) - (delete-region (previous-single-property-change (1+ (point)) :data) - (or (next-single-property-change (point) :data) - (point-max)))) - - ;; Walk through the list and insert all entries - (while (setq cell (pop sublist)) - (unless update-one - (setq first-char (upcase (string-to-char (nth 6 cell)))) - (when (and (not (equal first-char this-section-char)) - (member first-char section-chars)) - ;; There is a new initial letter, so start a new section - (reftex-index-insert-new-letter first-char font) - (setq section-chars (delete first-char section-chars) - this-section-char first-char)) - (when (= this-section-char 0) - (setq this-section-char ?!) - (reftex-index-insert-new-letter this-section-char font))) - - (setq from (point)) - (insert indent (nth 7 cell)) - (when font - (setq to (point)) - (put-text-property - (- (point) (length (nth 7 cell))) to - 'face index-face) - (goto-char to)) - - (when (or remark (nth 9 cell)) - (and (< (current-column) 40) - ;; FIXME: maybe this is too slow? - (insert (make-string (max (- 40 (current-column)) 0) ?\ ))) - (and (nth 9 cell) (insert " " (substring (nth 5 cell) (nth 9 cell)))) - (and remark (insert " " remark))) - - (insert "\n") - (setq to (point)) - - (when context - (insert context-indent (nth 2 cell) "\n") - (setq to (point))) - (put-text-property from to :data cell) - (when mouse-face - (put-text-property from (1- to) - 'mouse-face mouse-face)) - (goto-char to)))) - - -(defun reftex-index-insert-new-letter (letter &optional font) - ;; Start a new section in the index - (let ((from (point))) - (insert "\n" letter letter letter - "-----------------------------------------------------------------") - (when font - (put-text-property from (point) 'face reftex-index-section-face)) - (insert "\n"))) - -(defun reftex-get-restriction (arg docstruct) - ;; Interpret the prefix ARG and derive index restriction specs. - (let* ((beg (min (point) (or (condition-case nil (mark) (error nil)) - (point-max)))) - (end (max (point) (or (condition-case nil (mark) (error nil)) - (point-min)))) - bor eor label here-I-am) - (cond - ((eq arg 2) - (setq here-I-am (car (reftex-where-am-I)) - bor (if (eq (car here-I-am) 'toc) - here-I-am - (reftex-last-assoc-before-elt - 'toc here-I-am docstruct)) - eor (car (memq (assq 'toc (cdr (memq bor docstruct))) docstruct)) - label (nth 6 bor))) - ((eq arg 3) - (save-excursion - (setq label "region") - (goto-char beg) - (setq bor (car (reftex-where-am-I))) - (setq bor (nth 1 (memq bor docstruct))) - (goto-char end) - (setq eor (nth 1 (memq (car (reftex-where-am-I)) docstruct))))) - (t nil)) - (if (and label (or bor eor)) - (list label bor eor) - nil))) - -(defun reftex-index-pre-command-hook () - ;; Used as pre command hook in *Index* buffer - (reftex-unhighlight 0) - (reftex-unhighlight 1)) - -(defun reftex-index-post-command-hook () - ;; Used in the post-command-hook for the *Index* buffer - ;; FIXME: Lots of redundancy with reftex-toc-post-command-hook! - (when (get-text-property (point) :data) - (and (> (point) 1) ;FIXME: Is this point-min or do we care about narrowing? - (not (get-text-property (point) 'cursor-intangible)) - (memq reftex-highlight-selection '(cursor both)) - (reftex-highlight 1 - (or (previous-single-property-change (1+ (point)) :data) - (point-min)) - (or (next-single-property-change (point) :data) - (point-max))))) - (if (integerp reftex-index-follow-mode) - ;; Remove delayed action - (setq reftex-index-follow-mode t) - (and reftex-index-follow-mode - (not (equal reftex-last-follow-point (point))) - ;; Show context in other window - (setq reftex-last-follow-point (point)) - (condition-case nil - (reftex-index-visit-location nil (not reftex-revisit-to-follow)) - (error t))))) - -(defun reftex-index-show-help () - "Show a summary of special key bindings." - (interactive) - (with-output-to-temp-buffer "*RefTeX Help*" - (princ reftex-index-help)) - (reftex-enlarge-to-fit "*RefTeX Help*" t) - ;; If follow mode is active, arrange to delay it one command - (if reftex-index-follow-mode - (setq reftex-index-follow-mode 1))) - -(defun reftex-index-next (&optional _arg) - "Move to next selectable item." - (interactive "^") - (setq reftex-callback-fwd t) - (or (eobp) (forward-char 1)) - (goto-char (or (next-single-property-change (point) :data) - (point))) - (unless (get-text-property (point) :data) - (goto-char (or (next-single-property-change (point) :data) - (point))))) -(defun reftex-index-previous (&optional _arg) - "Move to previous selectable item." - (interactive "^") - (setq reftex-callback-fwd nil) - (goto-char (or (previous-single-property-change (point) :data) - (point))) - (unless (get-text-property (point) :data) - (goto-char (or (previous-single-property-change (point) :data) - (point))))) -(defun reftex-index-toggle-follow () - "Toggle follow (other window follows with context)." - (interactive) - (setq reftex-last-follow-point -1) - (setq reftex-index-follow-mode (not reftex-index-follow-mode))) -(defun reftex-index-toggle-context () - "Toggle inclusion of label context in *Index* buffer. -Label context is only displayed when the labels are there as well." - (interactive) - (setq reftex-index-include-context (not reftex-index-include-context)) - (reftex-index-revert)) -(defun reftex-index-view-entry () - "View document location in other window." - (interactive) - (reftex-index-visit-location)) -(defun reftex-index-goto-entry-and-hide () - "Go to document location in other window. Hide the *Index* window." - (interactive) - (reftex-index-visit-location 'hide)) -(defun reftex-index-goto-entry () - "Go to document location in other window. *Index* window stays." - (interactive) - (reftex-index-visit-location t)) -(defun reftex-index-mouse-goto-line-and-hide (ev) - "Go to document location in other window. Hide the *Index* window." - (interactive "e") - (mouse-set-point ev) - (reftex-index-visit-location 'hide)) -(defun reftex-index-quit () - "Hide the *Index* window and do not move point." - (interactive) - (or (one-window-p) (delete-window)) - (switch-to-buffer (marker-buffer reftex-index-return-marker)) - (goto-char (or (marker-position reftex-index-return-marker) (point)))) -(defun reftex-index-quit-and-kill () - "Kill the *Index* buffer." - (interactive) - (kill-buffer (current-buffer)) - (or (one-window-p) (delete-window)) - (switch-to-buffer (marker-buffer reftex-index-return-marker)) - (goto-char (or (marker-position reftex-index-return-marker) (point)))) -(defun reftex-index-goto-toc (&rest _ignore) - "Switch to the table of contents of the current document. -The function will go to the section where the entry at point was defined." - (interactive) - (if (get-text-property (point) :data) - (reftex-index-goto-entry) - (switch-to-buffer (marker-buffer reftex-index-return-marker))) - (delete-other-windows) - (reftex-toc)) -(defun reftex-index-rescan (&rest _ignore) - "Regenerate the *Index* buffer after reparsing file of section at point." - (interactive) - (let ((index-tag reftex-index-tag)) - (if (and reftex-enable-partial-scans - (null current-prefix-arg)) - (let* ((data (get-text-property (point) :data)) - (file (nth 3 data)) - (line (+ (count-lines (point-min) (point)) (if (bolp) 1 0)))) - (if (not file) - (error "Don't know which file to rescan. Try `C-u r'") - (switch-to-buffer (reftex-get-file-buffer-force file)) - (setq current-prefix-arg '(4)) - (reftex-display-index index-tag nil 'redo line))) - (reftex-index-Rescan)) - (reftex-kill-temporary-buffers))) -(defun reftex-index-Rescan (&rest _ignore) - "Regenerate the *Index* buffer after reparsing the entire document." - (interactive) - (let ((index-tag reftex-index-tag) - (line (+ (count-lines (point-min) (point)) (if (bolp) 1 0)))) - (switch-to-buffer - (reftex-get-file-buffer-force reftex-last-index-file)) - (setq current-prefix-arg '(16)) - (reftex-display-index index-tag nil 'redo line))) -(defun reftex-index-revert (&rest _ignore) - "Regenerate the *Index* from the internal lists. No reparsing os done." - (interactive) - (let ((buf (current-buffer)) - (index-tag reftex-index-tag) - (data (get-text-property (point) :data)) - (line (+ (count-lines (point-min) (point)) (if (bolp) 1 0)))) - (switch-to-buffer - (reftex-get-file-buffer-force reftex-last-index-file)) - (reftex-erase-buffer buf) - (setq current-prefix-arg nil - reftex-last-follow-point 1) - (reftex-display-index index-tag nil 'redo data line))) -(defun reftex-index-switch-index-tag (&rest _ignore) - "Switch to a different index of the same document." - (interactive) - (switch-to-buffer - (reftex-get-file-buffer-force reftex-last-index-file)) - (setq current-prefix-arg nil) - (reftex-display-index nil nil 'redo)) - -(defun reftex-index-restrict-to-section (&optional force) - "Restrict index to entries defined in same document section as entry at point." - ;; Optional FORCE means, even if point is not on an index entry. - (interactive) - (let* ((data (get-text-property (point) :data)) - (docstruct (symbol-value reftex-docstruct-symbol)) - bor eor) - (if (and (not data) force) - (setq data (assq 'toc docstruct))) - (when data - (setq bor (reftex-last-assoc-before-elt 'toc data docstruct) - eor (car (memq (assq 'toc (cdr (memq bor docstruct))) - docstruct)) - reftex-index-restriction-data (list bor eor) - reftex-index-restriction-indicator (nth 6 bor) ))) - (reftex-index-revert)) - -(defun reftex-index-widen (&rest _ignore) - "Show the unrestricted index (all entries)." - (interactive) - (setq reftex-index-restriction-indicator nil - reftex-index-restriction-data nil) - (reftex-index-revert) - (message "Index widened")) -(defun reftex-index-restriction-forward (&rest _ignore) - "Restrict to previous section. -When index is currently unrestricted, restrict it to a section. -When index is restricted, select the next section as restriction criterion." - (interactive) - (let* ((docstruct (symbol-value reftex-docstruct-symbol)) - (bor (nth 1 reftex-index-restriction-data))) - (if (or (not bor) - (not (eq (car bor) 'toc))) - (reftex-index-restrict-to-section t) - (setq reftex-index-restriction-indicator (nth 6 bor) - reftex-index-restriction-data - (list bor - (car (memq (assq 'toc (cdr (memq bor docstruct))) - docstruct)))) - (reftex-index-revert)))) -(defun reftex-index-restriction-backward (&rest _ignore) - "Restrict to next section. -When index is currently unrestricted, restrict it to a section. -When index is restricted, select the previous section as restriction criterion." - (interactive) - (let* ((docstruct (symbol-value reftex-docstruct-symbol)) - (eor (car reftex-index-restriction-data)) - (bor (reftex-last-assoc-before-elt 'toc eor docstruct t))) - (if (or (not bor) - (not (eq (car bor) 'toc))) - (reftex-index-restrict-to-section t) - (setq reftex-index-restriction-indicator (nth 6 bor) - reftex-index-restriction-data - (list bor eor)) - (reftex-index-revert)))) - -(defun reftex-index-visit-location (&optional final no-revisit) - ;; Visit the tex file corresponding to the index entry on the current line. - ;; If FINAL is t, stay there - ;; If FINAL is 'hide, hide the *Index* window. - ;; Otherwise, move cursor back into *Index* window. - ;; NO-REVISIT means don't visit files, just use live buffers. - - (let* ((data (get-text-property (point) :data)) - (index-window (selected-window)) - show-window show-buffer match) - - (unless data (error "Don't know which index entry to visit")) - - (if (eq (car data) 'index) - (setq match (reftex-index-show-entry data no-revisit))) - - (setq show-window (selected-window) - show-buffer (current-buffer)) - - (unless match - (select-window index-window) - (error "Cannot find location")) - - (select-window index-window) - - ;; Use the `final' parameter to decide what to do next - (cond - ((eq final t) - (reftex-unhighlight 0) - (select-window show-window)) - ((eq final 'hide) - (reftex-unhighlight 0) - (or (one-window-p) (delete-window)) - (switch-to-buffer show-buffer)) - (t nil)))) - -(defun reftex-index-analyze-entry (data) - "Split index context so that key, attribute and visual -values are accessible individually." - (interactive) - (let* ((arg (nth 5 data)) - (context (nth 2 data)) - (sc reftex-index-special-chars) - (boa (if (string-match (regexp-quote (concat "{" arg "}")) context) - (1+ (match-beginning 0)) - (error "Something is wrong here"))) - (eoa (1- (match-end 0))) - (boactual (if (string-match (concat "[^" (nth 3 sc) "]" (nth 2 sc)) - context boa) - (1+ (match-beginning 0)) - eoa)) - (boattr (if (string-match (concat "[^" (nth 3 sc) "]" (nth 1 sc)) - context boa) - (1+ (match-beginning 0)) - boactual)) - (pre (substring context 0 boa)) - (key (substring context boa boattr)) - (attr (substring context boattr boactual)) - (actual (substring context boactual eoa)) - (post (substring context eoa))) - (list pre key attr actual post))) - -(defun reftex-index-edit () - "Edit the index entry at point." - (interactive) - (let* ((data (get-text-property (point) :data)) - old new) - (unless data (error "Don't know which index entry to edit")) - (reftex-index-view-entry) - (setq old (nth 2 data) new (read-string "Edit: " old)) - (reftex-index-change-entry new))) - -(defun reftex-index-toggle-range-beginning () - "Toggle the page range start attribute `|('." - (interactive) - (let* ((data (get-text-property (point) :data)) - (bor (concat (nth 1 reftex-index-special-chars) "(")) - new analyze attr) - (unless data (error "Don't know which index entry to edit")) - (setq analyze (reftex-index-analyze-entry data) - attr (nth 2 analyze)) - (setf (nth 2 analyze) (if (string= attr bor) "" bor)) - (setq new (apply #'concat analyze)) - (reftex-index-change-entry - new (if (string= (nth 2 analyze) bor) - "Entry is now START-OF-PAGE-RANGE" - "START-OF-PAGE-RANGE canceled")))) - -(defun reftex-index-toggle-range-end () - "Toggle the page-range-end attribute `|)'." - (interactive) - (let* ((data (get-text-property (point) :data)) - (eor (concat (nth 1 reftex-index-special-chars) ")")) - new analyze attr) - (unless data (error "Don't know which index entry to edit")) - (setq analyze (reftex-index-analyze-entry data) - attr (nth 2 analyze)) - (setf (nth 2 analyze) (if (string= attr eor) "" eor)) - (setq new (apply #'concat analyze)) - (reftex-index-change-entry - new (if (string= (nth 2 analyze) eor) - "Entry is now END-OF-PAGE-RANGE" - "END-OF-PAGE-RANGE canceled")))) - -(defun reftex-index-edit-key () - "Edit the KEY part of the index entry." - (interactive) - (reftex-index-edit-part nil 1 "" "Key: " t)) - -(defun reftex-index-edit-attribute (&optional arg) - "EDIT the ATTRIBUTE part of the entry. With arg: remove entire ATTRIBUTE." - (interactive "P") - (reftex-index-edit-part arg 2 (nth 1 reftex-index-special-chars) - "Attribute: ")) - -(defun reftex-index-edit-visual (&optional arg) - "EDIT the VISUAL part of the entry. With arg: remove entire VISUAL string." - (interactive "P") - (reftex-index-edit-part arg 3 (nth 2 reftex-index-special-chars) "Visual: ")) - -(defun reftex-index-edit-part (arg n initial prompt &optional dont-allow-empty) - ;; This function does the work for all partial editing commands - (let* ((data (get-text-property (point) :data)) - new analyze opart npart) - (unless data (error "Don't know which index entry to edit")) - ;; Analyze the whole context string - (setq analyze (reftex-index-analyze-entry data) - opart (nth n analyze)) - (and (> (length opart) 0) (setq opart (substring opart 1))) - ;; Have the user editing the part - (setq npart (if arg "" (read-string (concat prompt initial) opart))) - ;; Tests: - (cond ((string= npart opart) - (error "Not changed")) - ((string= npart "") - (if dont-allow-empty - (error "Invalid value") - (setf (nth n analyze) npart))) - (t (setf (nth n analyze) (concat initial npart)))) - (setq new (apply #'concat analyze)) - ;; Change the entry and insert the changed version into the index. - (reftex-index-change-entry - new (if (string= npart "") - (format "Deleted: %s" opart) - (format "New value is: %s" npart))))) - -(defun reftex-index-level-down () - "Make index entry a subitem of another entry." - (interactive) - (let* ((data (get-text-property (point) :data)) - (docstruct (symbol-value reftex-docstruct-symbol)) - old new prefix key) - (unless data (error "Don't know which index entry to change")) - (setq old (nth 2 data) - key (nth 6 data) - prefix (completing-read - "Prefix: " - (reftex-sublist-nth - docstruct 6 - (lambda (x) - (and (eq (car x) 'index) - (string= (nth 1 x) reftex-index-tag))) t))) - (unless (string-match - (concat (regexp-quote (car reftex-index-special-chars)) "\\'") - prefix) - (setq prefix (concat prefix (car reftex-index-special-chars)))) - (if (string-match (regexp-quote key) old) - (setq new (replace-match (concat prefix key) t t old)) - (error "Cannot construct new index key")) - (reftex-index-change-entry new (format "Added prefix: %s" prefix)))) - -(defun reftex-index-level-up () - "Remove the highest level of a hierarchical index entry." - (interactive) - (let* ((data (get-text-property (point) :data)) - old new prefix) - (unless data (error "Don't know which entry to change")) - (setq old (nth 2 data)) - (if (string-match (concat "{\\([^" (nth 0 reftex-index-special-chars) "]*" - "[^" (nth 3 reftex-index-special-chars) "]" - (regexp-quote (nth 0 reftex-index-special-chars)) - "\\)") - old) - (setq prefix (substring old (match-beginning 1) (match-end 1)) - new (concat (substring old 0 (match-beginning 1)) - (substring old (match-end 1)))) - (error "Entry is not a subitem")) - (reftex-index-change-entry new (format "Removed prefix: %s" prefix)))) - -(defun reftex-index-kill () - "FIXME: Not yet implemented." - (interactive) - (error "This function is currently not implemented")) - -(defun reftex-index-undo () - "FIXME: Not yet implemented." - (interactive) - (error "This function is currently not implemented")) - -(defun reftex-index-change-entry (new &optional message) - ;; Change the full context string of the index entry at point to - ;; NEW. This actually edits the buffer where the entry is defined. - - (let* ((data (get-text-property (point) :data)) - old beg end info) - (unless data (error "Cannot change entry")) - (reftex-index-view-entry) - (setq beg (match-beginning 0) end (match-end 0)) - (setq old (nth 2 data)) - (and (equal old new) (error "Entry unchanged")) - (with-current-buffer (get-file-buffer (nth 3 data)) - (goto-char beg) - (unless (looking-at (regexp-quote old)) - (error "This should not happen (reftex-index-change-entry)")) - (delete-region beg end) - (insert new) - (goto-char (1- beg)) - (when (and (re-search-forward (reftex-everything-regexp) nil t) - (match-end 10) - (< (abs (- (match-beginning 10) beg)) (length new)) - (setq info (reftex-index-info-safe - (reftex--get-buffer-identifier)))) - (setcdr data (cdr info)))) - (let ((buffer-read-only nil)) - (save-excursion - (reftex-insert-index (list data) reftex-index-tag t - "EDITED"))) - (setq reftex-last-follow-point 1) - (and message (message "%s" message)))) - -(defun reftex-index-goto-letter (char) - "Go to the CHAR section in the index." - (let ((pos (point)) - (case-fold-search nil)) - (goto-char (point-min)) - (forward-line 2) - (if (re-search-forward (concat "^" (char-to-string char)) nil t) - (progn - (beginning-of-line) - (recenter 0) - (reftex-index-next)) - (goto-char pos) - (if (eq char ?!) - (error "This <%s> index does not contain entries sorted before the letters" - reftex-index-tag) - (error "This <%s> index does not contain entries starting with `%c'" - reftex-index-tag char))))) - - -;;---------------------------------------------------------------------- -;; The Index Phrases File - -;; Some constants and variables -(defconst reftex-index-phrases-comment-regexp "^[ \t]*%.*" - "Regular expression to match comment lines in phrases buffer.") -(defconst reftex-index-phrases-macrodef-regexp - "^\\(>>>INDEX_MACRO_DEFINITION:\\)[ \t]+\\(\\S-\\)\\( *\t[ \t]*\\)\\([^\t]*[^ \t]\\)\\( *\t[ \t]*\\)\\(\\S-+\\)" - "Regular expression to match macro definition lines the phrases buffer.") -;(defconst reftex-index-phrases-macrodef-regexp -; "^\\(>>>INDEX_MACRO_DEFINITION:\\)[ \t]+\\(\\S-\\)\\([ \t]*\\)\\([^\t]*[^ \t]\\)\\([ \t]*\\)\\(nil\\|t\\)[ \t]*$" -; "Regular expression to match macro definition lines the phrases buffer. -;This version would allow just spaces as separators.") -(defconst reftex-index-phrases-phrase-regexp1 - "^\\(\\S-?\\)\\(\t\\)\\([^\t\n]*\\S-\\)\\([ \t]*\\)$" - "Regular expression matching phrases which have no separate index key.") -(defconst reftex-index-phrases-phrase-regexp2 - "^\\(\\S-?\\)\\(\t\\)\\([^\t]*\\S-\\)\\(\t[ \t]*\\)\\([^\n\t]*\\S-\\)[ \t]*$" - "Regular expression matching phrases which have a separate index key.") -(defconst reftex-index-phrases-phrase-regexp12 - "^\\(\\S-?\\)\\(\t\\)\\([^\n\t]*\\S-\\)\\(\\(\t[ \t]*\\)\\([^\n\t]*\\S-\\)\\)?[ \t]*$" - "Regular expression matching all types of phrase lines.") -(defvar reftex-index-phrases-macro-data nil - "Alist containing the information taken from the macro definition lines. -This gets refreshed in every phrases command.") -(defvar reftex-index-phrases-files nil - "List of document files relevant for the phrases file.") - -(defvar reftex-index-phrases-font-lock-keywords - (list - (cons reftex-index-phrases-comment-regexp 'font-lock-comment-face) - (list reftex-index-phrases-macrodef-regexp - '(1 font-lock-type-face) - '(2 font-lock-keyword-face) - '(3 'secondary-selection) - '(4 font-lock-function-name-face) - '(5 'secondary-selection) - '(6 font-lock-string-face)) - (list reftex-index-phrases-phrase-regexp1 - '(1 font-lock-keyword-face) - '(2 'secondary-selection) - '(3 font-lock-string-face) - '(4 'secondary-selection)) - (list reftex-index-phrases-phrase-regexp2 - '(1 font-lock-keyword-face) - '(2 'secondary-selection) - '(3 font-lock-string-face) - '(4 'secondary-selection) - '(5 font-lock-function-name-face)) - '("^\t$" . 'secondary-selection)) - "Font lock keywords for `reftex-index-phrases-mode'.") -(defvar reftex-index-phrases-font-lock-defaults - '((reftex-index-phrases-font-lock-keywords) - nil t nil beginning-of-line) - "Font lock defaults for `reftex-index-phrases-mode'.") -(defvar reftex-index-phrases-mode-map - (let ((map (make-sparse-keymap))) - ;; Keybindings and Menu for phrases buffer - (define-key map "\C-c\C-c" #'reftex-index-phrases-save-and-return) - (define-key map "\C-c\C-x" #'reftex-index-this-phrase) - (define-key map "\C-c\C-f" #'reftex-index-next-phrase) - (define-key map "\C-c\C-r" #'reftex-index-region-phrases) - (define-key map "\C-c\C-a" #'reftex-index-all-phrases) - (define-key map "\C-c\C-d" #'reftex-index-remaining-phrases) - (define-key map "\C-c\C-s" #'reftex-index-sort-phrases) - (define-key map "\C-c\C-n" #'reftex-index-new-phrase) - (define-key map "\C-c\C-m" #'reftex-index-phrases-set-macro-key) - (define-key map "\C-c\C-i" #'reftex-index-phrases-info) - (define-key map "\C-c\C-t" #'reftex-index-find-next-conflict-phrase) - (define-key map "\C-i" #'self-insert-command) - - (easy-menu-define reftex-index-phrases-menu map - "Menu for Phrases buffer" - '("Phrases" - ["New Phrase" reftex-index-new-phrase t] - ["Set Phrase Macro" reftex-index-phrases-set-macro-key t] - ["Recreate File Header" reftex-index-initialize-phrases-buffer t] - "--" - ("Sort Phrases" - ["Sort" reftex-index-sort-phrases t] - "--" - "Sort Options" - ["by Search Phrase" (setq reftex-index-phrases-sort-prefers-entry nil) - :style radio :selected (not reftex-index-phrases-sort-prefers-entry)] - ["by Index Entry" (setq reftex-index-phrases-sort-prefers-entry t) - :style radio :selected reftex-index-phrases-sort-prefers-entry] - ["in Blocks" (setq reftex-index-phrases-sort-in-blocks - (not reftex-index-phrases-sort-in-blocks)) - :style toggle :selected reftex-index-phrases-sort-in-blocks]) - ["Describe Phrase" reftex-index-phrases-info t] - ["Next Phrase Conflict" reftex-index-find-next-conflict-phrase t] - "--" - ("Find and Index in Document" - ["Current Phrase" reftex-index-this-phrase t] - ["Next Phrase" reftex-index-next-phrase t] - ["Current and Following" reftex-index-remaining-phrases t] - ["Region Phrases" reftex-index-region-phrases t] - ["All Phrases" reftex-index-all-phrases t] - "--" - "Options" - ["Match Whole Words" (setq reftex-index-phrases-search-whole-words - (not reftex-index-phrases-search-whole-words)) - :style toggle :selected reftex-index-phrases-search-whole-words] - ["Case Sensitive Search" (setq reftex-index-phrases-case-fold-search - (not reftex-index-phrases-case-fold-search)) - :style toggle :selected (not - reftex-index-phrases-case-fold-search)] - ["Wrap Long Lines" (setq reftex-index-phrases-wrap-long-lines - (not reftex-index-phrases-wrap-long-lines)) - :style toggle :selected reftex-index-phrases-wrap-long-lines] - ["Skip Indexed Matches" (setq reftex-index-phrases-skip-indexed-matches - (not reftex-index-phrases-skip-indexed-matches)) - :style toggle :selected reftex-index-phrases-skip-indexed-matches]) - "--" - ["Save and Return" reftex-index-phrases-save-and-return t])) - - map) - "Keymap used for index phrases buffer.") -(defvar reftex-index-phrases-syntax-table - (let ((table (make-syntax-table))) - (modify-syntax-entry ?\" "." table) - table) - "Syntax table for RefTeX Index Phrases mode.") - -;;;###autoload -(defun reftex-index-phrase-selection-or-word (arg) - "Add current selection or word at point to the phrases buffer. -\\ -When you are in `transient-mark-mode' and the region is active, the -selection will be used - otherwise the word at point. -You get a chance to edit the entry in the phrases buffer - finish with -\\[reftex-index-phrases-save-and-return]." - (interactive "P") - (set-marker reftex-index-return-marker (point)) - (reftex-index-selection-or-word arg 'phrase) - (if (eq major-mode 'reftex-index-phrases-mode) - (message "%s" - (substitute-command-keys - "Return to LaTeX with \\[reftex-index-phrases-save-and-return]")))) - -;;;###autoload -(defun reftex-index-visit-phrases-buffer () - "Switch to the phrases buffer, initialize if empty." - (interactive) - (reftex-access-scan-info) - (set-marker reftex-index-return-marker (point)) - (let ((master (reftex-TeX-master-file))) - (when (bufferp master) - (user-error "RefTeX phrases buffer requires a file buffer")) - (let ((name (concat (file-name-sans-extension master) - reftex-index-phrase-file-extension))) - (find-file name) - (unless (eq major-mode 'reftex-index-phrases-mode) - (reftex-index-phrases-mode)) - (if (= (buffer-size) 0) - (reftex-index-initialize-phrases-buffer master))))) - -(defun reftex-index-initialize-phrases-buffer (&optional master) - "Initialize the phrases buffer by creating the header. -If the buffer is non-empty, delete the old header first." - (interactive) - (let* ((case-fold-search t) - (default-key (car reftex-index-default-macro)) - (default-macro (nth 1 (assoc default-key - reftex-key-to-index-macro-alist))) - (macro-alist - (sort (copy-sequence reftex-index-macro-alist) - (lambda (a _b) (equal (car a) default-macro)))) - macro entry key repeat) - - (when master (setq-local TeX-master (file-name-nondirectory master))) - - (when (> (buffer-size) 0) - (goto-char 1) - (set-mark (point)) - (while (re-search-forward reftex-index-phrases-macrodef-regexp nil t) - (end-of-line)) - (beginning-of-line 2) - (if (looking-at reftex-index-phrases-comment-regexp) - (beginning-of-line 2)) - (while (looking-at "^[ \t]*$") - (beginning-of-line 2)) - (activate-mark) - (if (yes-or-no-p "Delete and rebuild header? ") - (delete-region (point-min) (point)))) - - ;; Insert the mode line - (insert - (format "%% -*- mode: reftex-index-phrases; TeX-master: \"%s\" -*-\n" - (file-name-nondirectory (reftex-index-phrase-tex-master)))) - ;; Insert the macro definitions - (insert "% Key Macro Format Repeat\n") - (insert "%---------------------------------------------------------------------\n") - (while (setq entry (pop macro-alist)) - (setq macro (car entry) - repeat (nth 7 entry) - key (car (delq nil (mapcar (lambda (x) (if (equal (nth 1 x) macro) - (car x) - nil)) - reftex-key-to-index-macro-alist)))) - (insert (format ">>>INDEX_MACRO_DEFINITION:\t%s\t%-20s\t%s\n" - (char-to-string key) (concat macro "{%s}") - (if repeat "t" "nil")))) - (insert "%---------------------------------------------------------------------\n\n\n"))) - -(defun reftex-index-phrase-tex-master (&optional dir) - "Return the name of the master file associated with a phrase buffer." - (if (and (boundp 'TeX-master) - (local-variable-p 'TeX-master (current-buffer)) - (stringp TeX-master)) - ;; We have a local variable which tells us which file to use - (expand-file-name TeX-master dir) - ;; have to guess - (concat (file-name-sans-extension (buffer-file-name)) ".tex"))) - -(defun reftex-index-phrases-save-and-return () - "Return to where the `reftex-index-phrase-selection-or-word' was called." - (interactive) - (save-buffer) - (switch-to-buffer (marker-buffer reftex-index-return-marker)) - (goto-char (or (marker-position reftex-index-return-marker) (point)))) - - -(defvar reftex-index-phrases-menu) -(defvar reftex-index-phrases-marker) -(defvar reftex-index-phrases-restrict-file nil) -;; NB this is a global autoload - see reftex.el. -;;;###autoload -(define-derived-mode reftex-index-phrases-mode fundamental-mode "Phrases" - "Major mode for managing the Index phrases of a LaTeX document. -This buffer was created with RefTeX. -\\ -To insert new phrases, use - - `C-c \\' in the LaTeX document to copy selection or word - - `\\[reftex-index-new-phrase]' in the phrases buffer. - -To index phrases use one of: - -\\[reftex-index-this-phrase] index current phrase -\\[reftex-index-next-phrase] index next phrase (or N with prefix arg) -\\[reftex-index-all-phrases] index all phrases -\\[reftex-index-remaining-phrases] index current and following phrases -\\[reftex-index-region-phrases] index the phrases in the region - -You can sort the phrases in this buffer with \\[reftex-index-sort-phrases]. -To display information about the phrase at point, use \\[reftex-index-phrases-info]. - -For more information see the RefTeX User Manual. - -Here are all local bindings. - -\\{reftex-index-phrases-mode-map}" - :syntax-table reftex-index-phrases-syntax-table - (setq-local font-lock-defaults - reftex-index-phrases-font-lock-defaults) - (setq-local reftex-index-phrases-marker (make-marker))) -;; (add-hook 'reftex-index-phrases-mode-hook #'turn-on-font-lock) - -(defun reftex-index-next-phrase (&optional arg) - "Index the next ARG phrases in the phrases buffer." - (interactive "p") - (reftex-index-phrases-parse-header t) - (while (> arg 0) - (decf arg) - (end-of-line) - (if (re-search-forward reftex-index-phrases-phrase-regexp12 nil t) - (progn - (goto-char (match-beginning 0)) - (reftex-index-this-phrase 'slave)) - (error "No more phrase lines after point")))) - -(defun reftex-index-this-phrase (&optional slave) - "Index the phrase in the current line. -Does a global search and replace in the entire document. At each -match, the user will be asked to confirm the replacement." - (interactive) - (if (not slave) (reftex-index-phrases-parse-header t)) - (save-excursion - (beginning-of-line) - (cond ((looking-at reftex-index-phrases-comment-regexp) - (if (not slave) (error "Comment line"))) - ((looking-at "^[ \t]*$") - (if (not slave) (error "Empty line"))) - ((looking-at reftex-index-phrases-macrodef-regexp) - (if (not slave) (error "Macro definition line"))) - ((looking-at reftex-index-phrases-phrase-regexp12) - ;; This is a phrase - (let* ((char (if (not (equal (match-string 1) "")) - (string-to-char (match-string 1)))) - (phrase (match-string 3)) - (index-key (match-string 6)) - (macro-data (cdr (if (null char) - (car reftex-index-phrases-macro-data) - (assoc char reftex-index-phrases-macro-data)))) - (macro-fmt (car macro-data)) - (repeat (nth 1 macro-data)) - (files - (cond ((and (stringp reftex-index-phrases-restrict-file) - (file-regular-p reftex-index-phrases-restrict-file)) - (list reftex-index-phrases-restrict-file)) - ((stringp reftex-index-phrases-restrict-file) - (error "Invalid restriction file %s" - reftex-index-phrases-restrict-file)) - (t reftex-index-phrases-files))) - (as-words reftex-index-phrases-search-whole-words)) - (unless macro-data - (error "No macro associated with key %c" char)) - (let ((overlay-arrow-string "=>") - (overlay-arrow-position - reftex-index-phrases-marker) - (replace-count 0)) - ;; Show the overlay arrow - (move-marker reftex-index-phrases-marker - (match-beginning 0) (current-buffer)) - ;; Start the query-replace - (reftex-query-index-phrase-globally - files phrase macro-fmt - index-key repeat as-words) - (message "%s replaced" - (reftex-number replace-count "occurrence"))))) - (t (error "Cannot parse this line"))))) - -(defun reftex-index-all-phrases () - "Index all phrases in the phrases buffer. -Calls `reftex-index-this-phrase' on each line in the buffer." - (interactive) - (reftex-index-region-phrases (point-min) (point-max))) - -(defun reftex-index-remaining-phrases () - "Index all phrases in the phrases buffer. -Calls `reftex-index-this-phrase' on each line ay and below point in -the buffer." - (interactive) - (beginning-of-line) - (reftex-index-region-phrases (point) (point-max))) - -(defun reftex-index-region-phrases (beg end) - "Index all phrases in the phrases buffer. -Calls `reftex-index-this-phrase' on each line in the region." - (interactive "r") - (reftex-index-phrases-parse-header t) - (goto-char beg) - (while (not (or (eobp) - (>= (point) end))) - (save-excursion (reftex-index-this-phrase 'slave)) - (beginning-of-line 2))) - -(defun reftex-index-phrases-parse-header (&optional get-files) - "Parse the header of a phrases file to extract the macro definitions. -The definitions get stored in `reftex-index-phrases-macro-data'. -Also switches to the LaTeX document to find out which files belong to -the document and stores the list in `reftex-index-phrases-files'." - (let* ((master (reftex-index-phrase-tex-master)) - buf) - (if get-files - ;; Get the file list - (save-excursion - (setq buf (reftex-get-file-buffer-force master)) - (unless buf (error "Master file %s not found" master)) - (set-buffer buf) - (reftex-access-scan-info) - (setq reftex-index-phrases-files - (reftex-all-document-files)))) - ;; Parse the files header for macro definitions - (setq reftex-index-phrases-macro-data nil) - (save-excursion - (goto-char (point-min)) - (while (re-search-forward reftex-index-phrases-macrodef-regexp nil t) - (push (list - (string-to-char (match-string 2)) - (match-string 4) - (equal (match-string 6) "t")) - reftex-index-phrases-macro-data)) - ;; Reverse the list, so that the first macro is first - (if (null reftex-index-phrases-macro-data) - (error "No valid MACRO DEFINITION line in %s file (make sure to use TAB separators)" reftex-index-phrase-file-extension)) - (setq reftex-index-phrases-macro-data - (nreverse reftex-index-phrases-macro-data)) - (goto-char (point-min))))) - -(defun reftex-index-phrases-apply-to-region (beg end) - "Index all index phrases in the current region. -This works exactly like global indexing from the index phrases buffer, -but operation is restricted to the current region. This is useful if -you need to add/change text in an already indexed document and want to -index the new part without having to go over the unchanged parts again." - (interactive "r") - (let ((win-conf (current-window-configuration)) - (reftex-index-phrases-restrict-file (buffer-file-name))) - (save-excursion - (save-restriction - (narrow-to-region beg end) - (unwind-protect - (progn - ;; Hide the region highlighting - (deactivate-mark) - (delete-other-windows) - (reftex-index-visit-phrases-buffer) - (reftex-index-all-phrases)) - (set-window-configuration win-conf)))))) - -(defun reftex-index-new-phrase (&optional text) - "Open a new line in the phrases buffer, insert TEXT." - (interactive) - (if (and text (stringp text)) - (progn - ;; Check if the phrase is already in the buffer - (setq text (reftex-index-simplify-phrase text)) - (goto-char (point-min)) - (if (re-search-forward - (concat "^\\(\\S-*\\)\t\\(" (regexp-quote text) - "\\) *[\t\n]") nil t) - (progn - (goto-char (match-end 2)) - (error "Phrase is already in phrases buffer"))))) - ;; Add the new phrase line after the last in the buffer - (goto-char (point-max)) - (if (re-search-backward reftex-index-phrases-phrase-regexp12 nil t) - (end-of-line)) - (if (not (bolp)) - (insert "\n")) - (insert "\t") - (if (and text (stringp text)) - (insert text))) - -(defun reftex-index-find-next-conflict-phrase (&optional _arg) - "Find the next a phrase which is has conflicts in the phrase buffer. -The command helps to find possible conflicts in the phrase indexing process. -It searches downward from point for a phrase which is repeated elsewhere -in the buffer, or which is a subphrase of another phrase. If such a -phrase is found, the phrase info is displayed. -To check the whole buffer, start at the beginning and continue by calling -this function repeatedly." - (interactive) - (if (catch 'exit - (while (re-search-forward reftex-index-phrases-phrase-regexp12 nil t) - (goto-char (match-beginning 3)) - (let* ((phrase (match-string 3)) - (case-fold-search reftex-index-phrases-case-fold-search) - (re (reftex-index-phrases-find-dup-re phrase t))) - (if (save-excursion - (goto-char (point-min)) - (and (re-search-forward re nil t) - (re-search-forward re nil t))) - (throw 'exit t))))) - (progn - (reftex-index-phrases-info) - (message "Phrase with match conflict discovered")) - (goto-char (point-max)) - (error "No further problematic phrases found"))) - -(defun reftex-index-phrases-info () - "Display information about the phrase at point." - (interactive) - (save-excursion - (beginning-of-line) - (unless (looking-at reftex-index-phrases-phrase-regexp12) - (error "Not a phrase line")) - (save-match-data (reftex-index-phrases-parse-header t)) - (let* ((char (if (not (equal (match-string 1) "")) - (string-to-char (match-string 1)))) - (phrase (match-string 3)) - (index-key (match-string 6)) - (index-keys (split-string - (or index-key phrase) - reftex-index-phrases-logical-or-regexp)) - (macro-data (cdr (if (null char) - (car reftex-index-phrases-macro-data) - (assoc char reftex-index-phrases-macro-data)))) - (macro-fmt (car macro-data)) - (repeat (nth 1 macro-data)) - (as-words reftex-index-phrases-search-whole-words) - (example (reftex-index-make-replace-string - macro-fmt (downcase phrase) (car index-keys) repeat)) - (re (reftex-index-make-phrase-regexp phrase as-words t)) - (re1 (reftex-index-phrases-find-dup-re phrase)) - (re2 (reftex-index-phrases-find-dup-re phrase 'sub)) - superphrases - (nmatches 0) - (ntimes1 0) - (ntimes2 0) - (case-fold-search reftex-index-phrases-case-fold-search) - file files buf) - (setq files reftex-index-phrases-files) - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (while (re-search-forward re1 nil t) - (incf ntimes1)) - (goto-char (point-min)) - (while (re-search-forward re2 nil t) - (push (cons (count-lines 1 (point)) (match-string 1)) superphrases) - (incf ntimes2)))) - (save-current-buffer - (while (setq file (pop files)) - (setq buf (reftex-get-file-buffer-force file)) - (when buf - (set-buffer buf) - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (let ((case-fold-search reftex-index-phrases-case-fold-search)) - (while (re-search-forward re nil t) - (or (reftex-in-comment) - (incf nmatches))))))))) - (with-output-to-temp-buffer "*Help*" - (princ (format " Phrase: %s\n" phrase)) - (princ (format " Macro key: %s\n" char)) - (princ (format " Macro format: %s\n" macro-fmt)) - (princ (format " Repeat: %s\n" repeat)) - (cond - (index-key - (let ((iks index-keys) (cnt 0) ik) - (while (setq ik (pop iks)) - (princ (format "Index entry %d: %s\n" (incf cnt) ik))))) - (repeat - (princ (format " Index entry: %s\n" phrase))) - (t - (princ " Index key: <>\n"))) - (princ (format " Example: %s\n" example)) - (terpri) - (princ (format "Total matches: %s in %s\n" - (reftex-number nmatches "match" "es") - (reftex-number (length reftex-index-phrases-files) - "LaTeX file"))) - (princ (format " Uniqueness: Phrase occurs %s in phrase buffer\n" - (reftex-number ntimes1 "time"))) - (if (> ntimes2 1) - (progn - (princ (format " Superphrases: Phrase matches the following %s in the phrase buffer:\n" - (reftex-number ntimes2 "line"))) - (mapcar (lambda(x) - (princ (format " Line %4d: %s\n" (car x) (cdr x)))) - (nreverse superphrases)))))))) - -(defun reftex-index-phrases-set-macro-key () - "Change the macro key for the current line. -Prompts for a macro key and insert is at the beginning of the line. -If you reply with \\`SPC', the macro key will be removed, so that the -default macro will be used. If you reply with \\`RET', just prints -information about the currently selected macro." - (interactive) - (reftex-index-phrases-parse-header) - (save-excursion - (beginning-of-line) - (unless (or (looking-at reftex-index-phrases-phrase-regexp12) - (looking-at "\t")) - (error "This is not a phrase line")) - (let* ((nc (reftex-index-select-phrases-macro 0)) - (macro-data (assoc nc reftex-index-phrases-macro-data)) - macro-fmt repeat) - (cond (macro-data) - ((equal nc ?\ ) - (setq nc "" - macro-data (car reftex-index-phrases-macro-data))) - ((equal nc ?\C-m) - (setq nc (char-after (point))) - (if (equal nc ?\t) - (setq nc "" - macro-data (car reftex-index-phrases-macro-data)) - (setq macro-data (assoc nc reftex-index-phrases-macro-data)))) - (t (error "No macro associated with %c" nc))) - - (setq macro-fmt (nth 1 macro-data) - repeat (nth 2 macro-data)) - (if macro-data - (progn - (if (looking-at "[^\t]") (delete-char 1)) - (insert nc) - (message "Line will use %s %s repeat" macro-fmt - (if repeat "with" "without"))) - (error "Abort"))))) - -(defvar reftex--chars-first) - -(defun reftex-index-sort-phrases (&optional chars-first) - "Sort the phrases lines in the buffer alphabetically. -Normally, this looks only at the phrases. With a prefix arg CHARS-FIRST, -it first compares the macro identifying chars and then the phrases." - (interactive "P") - ;; Remember the current line, so that we can return - (let ((line (buffer-substring (progn (beginning-of-line) (point)) - (progn (end-of-line) (point)))) - beg end) - (goto-char (point-min)) - ;; Find first and last phrase line in buffer - (setq beg - (and (re-search-forward reftex-index-phrases-phrase-regexp12 nil t) - (match-beginning 0))) - (goto-char (point-max)) - (setq end (re-search-backward reftex-index-phrases-phrase-regexp12 nil t)) - (if end (setq end (progn (goto-char end) (end-of-line) (point)))) - ;; Take the lines, sort them and re-insert. - (if (and beg end) - (let ((reftex--chars-first chars-first)) - (message "Sorting lines...") - (let* ((lines (split-string (buffer-substring beg end) "\n")) - (lines1 (sort lines #'reftex-compare-phrase-lines))) - (message "Sorting lines...done") - (let ((inhibit-quit t)) ;; make sure we do not lose lines - (delete-region beg end) - (insert (mapconcat #'identity lines1 "\n")))) - (goto-char (point-max)) - (re-search-backward (concat "^" (regexp-quote line) "$") nil t)) - (error "Cannot find phrases lines to sort")))) - -(defun reftex-compare-phrase-lines (a b) - "The comparison function used for sorting." - (let (ca cb pa pb c-p p-p) - (if (string-match reftex-index-phrases-phrase-regexp12 a) - (progn - ;; Extract macro char and phrase-or-key for a - (setq ca (match-string 1 a) - pa (downcase - (or (and reftex-index-phrases-sort-prefers-entry - (match-string 6 a)) - (match-string 3 a)))) - (if (string-match reftex-index-phrases-phrase-regexp12 b) - (progn - ;; Extract macro char and phrase-or-key for b - (setq cb (match-string 1 b) - pb (downcase - (or (and reftex-index-phrases-sort-prefers-entry - (match-string 6 b)) - (match-string 3 b)))) - (setq c-p (string< ca cb) - p-p (string< pa pb)) - ;; Do the right comparison, based on the value of `chars-first' - ;; `chars-first' is bound locally in the calling function - (if reftex--chars-first - (if (string= ca cb) p-p c-p) - (if (string= pa pb) c-p p-p))))) - ;; If line a does not match, the answer we return determines - ;; if non-matching lines are collected at the beginning. - ;; When we return t here, non-matching lines form - ;; block separators for searches. - (not reftex-index-phrases-sort-in-blocks)))) - -(defvar reftex-index-phrases-menu) -(defun reftex-index-make-phrase-regexp (phrase &optional - as-words allow-newline) - "Return a regexp matching PHRASE, even if distributed over lines. -With optional arg AS-WORDS, require word boundary at beginning and end. -With optional arg ALLOW-NEWLINE, allow single newline between words." - (let* ((words (split-string phrase)) - (space-re (if allow-newline - "\\([ \t]*\\(\n[ \t]*\\)?\\|[ \t]\\)" - "\\([ \t]+\\)"))) - (concat (if (and as-words (string-match "\\`\\w" (car words))) - "\\(\\<\\|[`']\\)" "") - (mapconcat (lambda (w) (regexp-quote - (if reftex-index-phrases-case-fold-search - (downcase w) - w))) - words space-re) - (if (and as-words - (string-match "\\w\\'" (nth (1- (length words)) words))) - "\\(\\>\\|'\\)" "")))) - -(defun reftex-index-simplify-phrase (phrase) - "Make phrase single spaces and single line." - (mapconcat #'identity (split-string phrase) " ")) - -(defun reftex-index-phrases-find-dup-re (phrase &optional sub) - "Return a regexp which matches variations of PHRASE (with additional space). -When SUB ins non-nil, the regexp will also match when PHRASE is a subphrase -of another phrase. The regexp works only in the phrase buffer." - (concat (if sub "^\\S-?\t\\([^\t\n]*" "^\\S-?\t") - (mapconcat #'regexp-quote (split-string phrase) " +") - (if sub "[^\t\n]*\\)\\([\t\n]\\|$\\)" " *\\([\t\n]\\|$\\)"))) - -(defun reftex-index-make-replace-string (macro-fmt match index-key - &optional repeat mathp) - "Return the string which can be used as replacement. -Treats the logical `and' for index phrases." - (let ((index-keys (split-string (or index-key match) - reftex-index-phrases-logical-and-regexp))) - (concat - (mapconcat (lambda (x) - (format macro-fmt - (format (if mathp reftex-index-math-format "%s") x))) - index-keys "") - (if repeat (reftex-index-simplify-phrase match) "")))) - -(defun reftex-query-index-phrase-globally (files &rest args) - "Call `reftex-query-index-phrase' for all files in FILES." - (let ((win-conf (current-window-configuration)) - (file)) - (unless files (error "No files")) - (unwind-protect - (progn - (switch-to-buffer-other-window (reftex-get-file-buffer-force - (car files))) - (catch 'no-more-files - (while (setq file (pop files)) - (switch-to-buffer (reftex-get-file-buffer-force file)) - (save-excursion - (save-restriction - (unless (stringp reftex-index-phrases-restrict-file) - (widen)) - (goto-char (point-min)) - (apply #'reftex-query-index-phrase args)))))) - (reftex-unhighlight 0) - (set-window-configuration win-conf)))) - -(defconst reftex-index-phrases-help - " Keys for query-index search - =========================== -y Replace this match -n Skip this match -! Replace this and all further matches in this file -q / Q Skip match, start next file / start next phrase -o Use a different indexing macro for this match -1 - 9 Select one of the multiple phrases -e Edit the replacement text -C-r Recursive edit. -s / S Save this buffer / Save all document buffers -C-g Abort" - "The help string for indexing phrases.") - -(defvar replace-count) -(defun reftex-query-index-phrase (phrase macro-fmt &optional - index-key repeat as-words) - "Search through buffer for PHRASE, and offer to replace it with an indexed -version. The index version is derived by applying `format' with MACRO-FMT -to INDEX-KEY or PHRASE. When REPEAT is non-nil, the PHRASE is inserted -again after the macro. -AS-WORDS means, the search for PHRASE should require word boundaries at -both ends." - (let* ((re (reftex-index-make-phrase-regexp phrase as-words 'allow-newline)) - (case-fold-search reftex-index-phrases-case-fold-search) - (index-keys (split-string - (or index-key phrase) - reftex-index-phrases-logical-or-regexp)) - (nkeys (length index-keys)) - (ckey (nth 0 index-keys)) - (all-yes nil) - match rpl char (beg (make-marker)) (end (make-marker)) mathp) - (move-marker beg 1) - (move-marker end 1) - (unwind-protect - (while (re-search-forward re nil t) - (catch 'next-match - (if (reftex-in-comment) - (throw 'next-match nil)) - (if (and (fboundp reftex-index-verify-function) - (not (funcall reftex-index-verify-function))) - (throw 'next-match nil)) - (setq match (match-string 0)) - (setq mathp - (save-match-data - (condition-case nil (texmathp) (error nil)))) - (setq beg (move-marker beg (match-beginning 0)) - end (move-marker end (match-end 0))) - (if (and reftex-index-phrases-skip-indexed-matches - (save-match-data - (reftex-index-phrase-match-is-indexed beg - end))) - (throw 'next-match nil)) - (reftex-highlight 0 (match-beginning 0) (match-end 0)) - (setq rpl - (save-match-data - (reftex-index-make-replace-string - macro-fmt (match-string 0) ckey repeat mathp))) - (while - (not - (catch 'loop - (message "REPLACE: %s? (yn!qoe%s?)" - rpl - (if (> nkeys 1) - (concat "1-" (int-to-string nkeys)) - "")) - (setq char (if all-yes ?y (read-char-exclusive))) - (cond ((member char '(?y ?Y ?\ )) - ;; Yes! - (replace-match rpl t t) - (incf replace-count) - ;; See if we should insert newlines to shorten lines - (and reftex-index-phrases-wrap-long-lines - (reftex-index-phrases-fixup-line beg end)) - (throw 'loop t)) - ((member char '(?n ?N ?\C-h ?\C-?));; FIXME: DEL - ;; No - (throw 'loop t)) - ((equal char ?!) - ;; Yes for all in this buffer - (setq all-yes t)) - ((equal char ?q) - ;; Stop this one in this file - (goto-char (point-max)) - (throw 'loop t)) - ((equal char ?Q) - ;; Stop this one - (throw 'no-more-files t)) - ((equal char ?s) - (save-buffer)) - ((equal char ?S) - (reftex-save-all-document-buffers)) - ((equal char ?\C-g) - (keyboard-quit)) - ((member char '(?o ?O)) - ;; Select a different macro - (let* ((nc (reftex-index-select-phrases-macro 2)) - (macro-data - (cdr (assoc nc reftex-index-phrases-macro-data))) - (macro-fmt (car macro-data)) - (repeat (nth 1 macro-data))) - (if macro-data - (setq rpl (save-match-data - (reftex-index-make-replace-string - macro-fmt match - ckey repeat mathp))) - (ding)))) - ((equal char ?\?) - ;; Help - (with-output-to-temp-buffer "*Help*" - (princ reftex-index-phrases-help))) - ((equal char ?\C-r) - ;; Recursive edit - (save-match-data - (save-excursion - (message "%s" - (substitute-command-keys - "Recursive edit. Resume with \\[exit-recursive-edit]")) - (recursive-edit)))) - ((equal char ?e) - (setq rpl (read-string "Edit: " rpl))) - ((equal char ?0) - (setq ckey (or index-key phrase) - rpl (save-match-data - (reftex-index-make-replace-string - macro-fmt match ckey repeat mathp)))) - ((and (> char ?0) - (<= char (+ ?0 nkeys))) - (setq ckey (nth (1- (- char ?0)) index-keys) - rpl (save-match-data - (reftex-index-make-replace-string - macro-fmt match ckey repeat mathp)))) - (t (ding))) - nil))))) - (message "") - (move-marker beg nil) - (move-marker end nil) - (setq all-yes nil) - (reftex-unhighlight 0)))) - -(defun reftex-index-phrase-match-is-indexed (beg end) - ;; Check if match is in an argument of an index macro, or if an - ;; index macro is directly attached to the match. - (save-excursion - (goto-char end) - (let* ((all-macros (reftex-what-macro t)) -; (this-macro (car (car all-macros))) - (before-macro - (and (> beg 2) - (goto-char (1- beg)) - (memq (char-after (point)) '(?\] ?\})) - (car (reftex-what-macro 1)))) - (after-macro - (and (goto-char end) - (looking-at "\\(\\\\[a-zA-Z]+\\*?\\)[[{]") - (match-string 1))) - macro) - (or (catch 'matched - (while (setq macro (pop all-macros)) - (if (member (car macro) reftex-macros-with-index) - (throw 'matched t))) - nil) - (and before-macro - (member before-macro reftex-macros-with-index)) - (and after-macro - (member after-macro reftex-macros-with-index)))))) - -(defun reftex-index-phrases-fixup-line (beg end) - "Insert newlines before BEG and/or after END to shorten line." - (let (bol eol space1 space2) - (save-excursion - ;; Find line boundaries and possible line breaks near BEG and END - (beginning-of-line) - (setq bol (point)) - (end-of-line) - (setq eol (point)) - (goto-char beg) - (skip-chars-backward "^ \n") - (if (and (equal (preceding-char) ?\ ) - (string-match "\\S-" (buffer-substring bol (point)))) - (setq space1 (1- (point)))) - (goto-char end) - (skip-chars-forward "^ \n") - (if (and (equal (following-char) ?\ ) - (string-match "\\S-" (buffer-substring (point) eol))) - (setq space2 (point))) - ;; Now check what we have and insert the newlines - (if (<= (- eol bol) fill-column) - ;; Line is already short - nil - (cond - ((and (not space1) (not space2))) ; No spaces available - ((not space2) ; Do space1 - (reftex-index-phrases-replace-space space1)) - ((not space1) ; Do space2 - (reftex-index-phrases-replace-space space2)) - (t ; We have both spaces - (let ((l1 (- space1 bol)) - (l2 (- space2 space1)) - (l3 (- eol space2))) - (if (> l2 fill-column) - ;; The central part alone is more than one line - (progn - (reftex-index-phrases-replace-space space1) - (reftex-index-phrases-replace-space space2)) - (if (> (+ l1 l2) fill-column) - ;; Need to split beginning - (reftex-index-phrases-replace-space space1)) - (if (> (+ l2 l3) fill-column) - ;; Need to split end - (reftex-index-phrases-replace-space space2)))))))))) - -(defun reftex-index-phrases-replace-space (pos) - "If there is a space at POS, replace it with a newline char. -Does not do a `save-excursion'." - (when (equal (char-after pos) ?\ ) - (goto-char pos) - (delete-char 1) - (insert "\n"))) - -(defun reftex-index-select-phrases-macro (&optional delay) - "Offer a list of possible index macros and have the user select one." - (let* ((prompt (concat "Select macro: [" - (mapconcat (compf char-to-string car) - reftex-index-phrases-macro-data "") - "] ")) - (help (concat "Select an indexing macro\n========================\n" - (mapconcat (lambda (x) - (format " [%c] %s" - (car x) (nth 1 x))) - reftex-index-phrases-macro-data "\n")))) - (reftex-select-with-char prompt help delay))) - -(provide 'reftex-index) - -;;; reftex-index.el ends here - -;; Local Variables: -;; generated-autoload-file: "reftex-loaddefs.el" -;; End: diff --git a/lisp/textmodes/reftex-parse.el b/lisp/textmodes/reftex-parse.el deleted file mode 100644 index a7ff07eff8e..00000000000 --- a/lisp/textmodes/reftex-parse.el +++ /dev/null @@ -1,1179 +0,0 @@ -;;; reftex-parse.el --- parser functions for RefTeX -*- lexical-binding: t; -*- - -;; Copyright (C) 1997-2025 Free Software Foundation, Inc. - -;; Author: Carsten Dominik -;; Maintainer: auctex-devel@gnu.org - -;; 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 . - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl-lib)) - -(require 'reftex) - -(defmacro reftex-with-special-syntax (&rest body) - "Evaluate BODY with syntax table set to `reftex-syntax-table'." - (declare (debug t)) - `(let ((saved-syntax (syntax-table))) - (unwind-protect - (progn - (set-syntax-table reftex-syntax-table) - (let ((case-fold-search nil)) - ,@body)) - (set-syntax-table saved-syntax)))) - -;;;###autoload -(defun reftex-parse-one () - "Re-parse this file." - (interactive) - (let ((reftex-enable-partial-scans t)) - (reftex-access-scan-info '(4)))) - -;;;###autoload -(defun reftex-parse-all () - "Re-parse entire document." - (interactive) - (reftex-access-scan-info '(16))) - -(defvar reftex--index-tags) - -;;;###autoload -(defun reftex-do-parse (rescan &optional file) - "Do a document rescan. -When allowed, do only a partial scan from FILE." - - ;; Normalize the rescan argument - (setq rescan (cond ((eq rescan t) t) - ((eq rescan 1) 1) - ((equal rescan '(4)) t) - ((equal rescan '(16)) 1) - (t 1))) - - ;; Partial scans only when allowed - (unless reftex-enable-partial-scans - (setq rescan 1)) - - ;; Do the scanning. - - (let* ((old-list (symbol-value reftex-docstruct-symbol)) - (master (reftex-TeX-master-file)) - (true-master (reftex--get-truename master)) - (master-dir (file-name-as-directory (reftex--get-directory master))) - (file (or file (reftex--get-buffer-identifier))) - (true-file (reftex--get-truename file)) - (bibview-cache (assq 'bibview-cache old-list)) - (reftex--index-tags (cdr (assq 'index-tags old-list))) - from-file appendix docstruct tmp) - - ;; Make sure replacement is really an option here - (when (and (eq rescan t) - (not (and (member (list 'bof file) old-list) - (member (list 'eof file) old-list)))) - ;; Scan whole document because no such file section exists - (setq rescan 1)) - (when (equal true-file true-master) - ;; Scan whole document because this file is the master - (setq rescan 1)) - - ;; From which file do we start? - (setq from-file - (cond ((eq rescan t) (or file master)) - ((eq rescan 1) master) - (t (error "This should not happen (reftex-do-parse)")))) - - ;; Reset index-tags if we scan everything - (if (equal rescan 1) (setq reftex--index-tags nil)) - - ;; Find active toc entry and initialize section-numbers - (setq reftex-active-toc (reftex-last-assoc-before-elt - 'toc (list 'bof from-file) old-list) - appendix (reftex-last-assoc-before-elt - 'appendix (list 'bof from-file) old-list)) - - (reftex-init-section-numbers reftex-active-toc appendix) - - (if (eq rescan 1) - (message "Scanning entire document...") - (message "Scanning document from %s..." from-file)) - - (reftex-with-special-syntax - (save-window-excursion - (save-excursion - (unwind-protect - (setq docstruct - (reftex-parse-from-file - from-file docstruct master-dir)) - (reftex-kill-temporary-buffers))))) - - (message "Scanning document... done") - - ;; Turn the list around. - (setq docstruct (nreverse docstruct)) - - ;; Set or insert - (setq docstruct (reftex-replace-label-list-segment - old-list docstruct (eq rescan 1))) - - ;; Add all missing information - (unless (assq 'label-numbers docstruct) - (push (cons 'label-numbers nil) docstruct)) - (unless (assq 'master-dir docstruct) - (push (cons 'master-dir master-dir) docstruct)) - (unless (assq 'bibview-cache docstruct) - (push (cons 'bibview-cache (cdr bibview-cache)) docstruct)) - (let* ((bof1 (memq (assq 'bof docstruct) docstruct)) - (bof2 (assq 'bof (cdr bof1))) - (is-multi (not (not (and bof1 bof2)))) - (entry (or (assq 'is-multi docstruct) - (car (push (list 'is-multi is-multi) docstruct))))) - (setcdr entry (cons is-multi nil))) - (and reftex--index-tags - (setq reftex--index-tags (sort reftex--index-tags #'string<))) - (let ((index-tag-cell (assq 'index-tags docstruct))) - (if index-tag-cell - (setcdr index-tag-cell reftex--index-tags) - (push (cons 'index-tags reftex--index-tags) docstruct))) - (unless (assq 'xr docstruct) - (let* ((allxr (reftex-all-assq 'xr-doc docstruct)) - (alist (mapcar - (lambda (x) - (if (setq tmp (reftex-locate-file (nth 2 x) "tex" - master-dir)) - (cons (nth 1 x) tmp) - (message "Can't find external document %s" - (nth 2 x)) - nil)) - allxr)) - (alist (delq nil alist)) - (allprefix (delq nil (mapcar #'car alist))) - (regexp (if allprefix - (concat "\\`\\(" - (mapconcat #'identity allprefix "\\|") - "\\)") - "\\\\\\\\\\\\"))) ; this will never match - (push (list 'xr alist regexp) docstruct))) - - (set reftex-docstruct-symbol docstruct) - (put reftex-docstruct-symbol 'modified t))) - -;;;###autoload -(defun reftex-everything-regexp () - (if reftex-support-index - reftex-everything-regexp - reftex-everything-regexp-no-index)) - -;; NB this is a global autoload - see reftex.el. -;;;###autoload -(defun reftex-all-document-files (&optional relative) - "Return a list of all files belonging to the current document. -When RELATIVE is non-nil, give file names relative to directory -of master file." - (let* ((all (symbol-value reftex-docstruct-symbol)) - (master-dir (reftex--get-directory (reftex-TeX-master-file))) - (re (concat "\\`" (regexp-quote master-dir))) - file-list tmp file) - (while (setq tmp (assoc 'bof all)) - (setq file (nth 1 tmp) - all (cdr (memq tmp all))) - (and relative - (stringp file) ; Ignore non-file buffers. - (string-match re file) - (setq file (substring file (match-end 0)))) - (push file file-list)) - (nreverse file-list))) - -;; Bound in the caller, reftex-do-parse. -(defun reftex-parse-from-file (file docstruct master-dir) - "Scan the buffer for labels and save them in a list." - (let ((regexp (reftex-everything-regexp)) - (bound 0) - file-found tmp include-file - (level 1) - (highest-level 100) - toc-entry index-entry next-buf buf) - - (catch 'exit - (setq file-found (reftex-locate-file file "tex" master-dir)) - (if (and (not file-found) - (setq buf (find-buffer-visiting file))) - (setq file-found (buffer-file-name buf))) - - (unless file-found - (push (list 'file-error file) docstruct) - (throw 'exit nil)) - - (save-excursion - - (message "Scanning file %s" file) - (set-buffer - (setq next-buf - (reftex-get-file-buffer-force - file-found - (not (eq t reftex-keep-temporary-buffers))))) - - ;; Begin of file mark - (setq file (reftex--get-buffer-identifier)) - (push (list 'bof file) docstruct) - - (reftex-with-special-syntax - (save-excursion - (save-restriction - (widen) - (goto-char 1) - - (while (re-search-forward regexp nil t) - - (cond - - ((match-end 1) - ;; It is a label - (when (or (null reftex-label-ignored-macros-and-environments) - ;; \label{} defs should always be honored, - ;; just no keyval style [label=foo] defs. - (string-equal "\\label{" (substring (reftex-match-string 0) 0 7)) - (if (and (fboundp 'TeX-current-macro) - (fboundp 'LaTeX-current-environment)) - (not (or (member (save-match-data (TeX-current-macro)) - reftex-label-ignored-macros-and-environments) - (member (save-match-data (LaTeX-current-environment)) - reftex-label-ignored-macros-and-environments))) - t)) - (push (reftex-label-info (reftex-match-string 1) file bound) - docstruct))) - - ((match-end 3) - ;; It is a section - - ;; Use the beginning as bound and not the end - ;; (i.e. (point)) because the section command might - ;; be the start of the current environment to be - ;; found by `reftex-label-info'. - (setq bound (match-beginning 0)) - ;; The section regexp matches a character at the end - ;; we are not interested in. Especially if it is the - ;; backslash of a following macro we want to find in - ;; the next parsing iteration. - (when (eq (char-before) ?\\) (backward-char)) - ;; Insert in List - (setq toc-entry (funcall reftex-section-info-function file)) - (when (and toc-entry - (eq ;; Either both are t or both are nil. - (= (char-after bound) ?%) - (and (stringp file) - (string-suffix-p ".dtx" file)))) - ;; It can happen that section info returns nil - (setq level (nth 5 toc-entry)) - (setq highest-level (min highest-level level)) - (if (= level highest-level) - (message - "Scanning %s %s ..." - (car (rassoc level reftex-section-levels-all)) - (nth 6 toc-entry))) - - (push toc-entry docstruct) - (setq reftex-active-toc toc-entry))) - - ((match-end 7) - ;; It's an include or input - (setq include-file (reftex-match-string 7)) - ;; Test if this file should be ignored - (unless (delq nil (mapcar - (lambda (x) (string-match x include-file)) - reftex-no-include-regexps)) - ;; Parse it - (setq docstruct - (reftex-parse-from-file - include-file - docstruct master-dir)))) - - ((match-end 9) - ;; Appendix starts here - (reftex-init-section-numbers nil t) - (push (cons 'appendix t) docstruct)) - - ((match-end 10) - ;; Index entry - (when reftex-support-index - (setq index-entry (reftex-index-info file)) - (when index-entry - (cl-pushnew (nth 1 index-entry) reftex--index-tags :test #'equal) - (push index-entry docstruct)))) - - ((match-end 11) - ;; A macro with label - (save-excursion - (let* ((mac (reftex-match-string 11)) - (label (progn (goto-char (match-end 11)) - (save-match-data - (reftex-no-props - (reftex-nth-arg-wrapper - mac))))) - (typekey (nth 1 (assoc mac reftex-env-or-mac-alist))) - (entry (progn (if typekey - ;; A typing macro - (goto-char (match-end 0)) - ;; A neutral macro - (goto-char (match-end 11)) - (reftex-move-over-touching-args)) - (reftex-label-info - label file bound nil nil)))) - (push entry docstruct)))) - (t (error "This should not happen (reftex-parse-from-file)"))) - ) - - ;; Find bibliography statement - (when (setq tmp (reftex-locate-bibliography-files master-dir)) - (push (cons 'bib tmp) docstruct)) - - (goto-char 1) - (when (re-search-forward - "\\(\\`\\|[\n\r]\\)[ \t]*\\\\begin{thebibliography}" nil t) - (push (cons 'thebib file) docstruct)) - - ;; Find external document specifications - (goto-char 1) - (while (re-search-forward - (concat "[\n\r][ \t]*" - ;; Support \externalcitedocument macro - "\\\\external\\(?:cite\\)?document" - ;; The optional prefix - "\\(\\[\\([^]]*\\)\\]\\)?" - ;; The 2nd opt. arg can only be nocite - "\\(?:\\[nocite\\]\\)?" - ;; Mandatory file argument - "{\\([^}]+\\)}") - nil t) - (push (list 'xr-doc (reftex-match-string 2) - (reftex-match-string 3)) - docstruct)) - - ;; End of file mark - (push (list 'eof file) docstruct))))) - - ;; Kill the scanned buffer - (reftex-kill-temporary-buffers next-buf)) - - ;; Return the list - docstruct)) - -(defun reftex-using-biblatex-p () - "Return non-nil if we are using biblatex or other specific cite package. -biblatex and other similar packages like multibib allow multiple macro -calls to load a bibliography file. This function should be able to -detect those packages." - (if (boundp 'TeX-active-styles) - ;; the sophisticated AUCTeX way - (or (member "biblatex" TeX-active-styles) - (member "multibib" TeX-active-styles)) - ;; poor-man's check... - (save-excursion - (re-search-forward - "^[^%\n]*?\\\\usepackage\\(\\[[^]]*\\]\\)?{biblatex\\|multibib}" nil t)))) - -;;;###autoload -(defun reftex-locate-bibliography-files (master-dir &optional files) - "Scan buffer for bibliography macros and return file list." - (unless files - (save-excursion - (goto-char (point-min)) - ;; when biblatex or multibib are used, multiple \bibliography or - ;; \addbibresource macros are allowed. With plain bibtex, only - ;; the first is used. - (let ((using-biblatex (reftex-using-biblatex-p)) - (again t)) - (while (and again - (re-search-forward - (concat - ;; "\\(\\`\\|[\n\r]\\)[^%]*\\\\\\(" - "\\(^\\)[^%\n\r]*\\\\\\(" - (mapconcat #'identity reftex-bibliography-commands "\\|") - "\\)\\(\\[.+?\\]\\)?{[ \t]*\\([^}]+\\)") - nil t)) - (setq files - (append files - (split-string (reftex-match-string 4) - "[ \t\n\r]*,[ \t\n\r]*"))) - (unless using-biblatex - (setq again nil)))))) - (when files - (setq files - (mapcar - (lambda (x) - (if (or (member x reftex-bibfile-ignore-list) - (delq nil (mapcar (lambda (re) (string-match re x)) - reftex-bibfile-ignore-regexps))) - ;; excluded file - nil - ;; find the file - (reftex-locate-file x "bib" master-dir))) - files)) - (delq nil (delete-dups files)))) - -(defun reftex-replace-label-list-segment (old insert &optional entirely) - "Replace the segment in OLD which corresponds to INSERT. -Works with side effects, directly changes old. -If ENTIRELY is t, just return INSERT. -This function also makes sure the old toc markers do not point anywhere." - - (cond - (entirely - (reftex-silence-toc-markers old (length old)) - insert) - (t (let* ((new old) - (file (nth 1 (car insert))) - (eof-list (member (list 'eof file) old)) - (bof-list (member (list 'bof file) old)) - n) - (if (not (and bof-list eof-list)) - (error "Cannot splice") - ;; Splice - (reftex-silence-toc-markers bof-list (- (length bof-list) - (length eof-list))) - (setq n (- (length old) (length bof-list))) - (setcdr (nthcdr n new) (cdr insert)) - (setcdr (nthcdr (1- (length new)) new) (cdr eof-list))) - new)))) - -;;;###autoload -(defun reftex-section-info (file) - "Return a section entry for the current match. -Careful: This function expects the `match-data' to still be in -place!" - (let* ((marker (set-marker (make-marker) (1- (match-beginning 3)))) - (macro (reftex-match-string 3)) - (prefix (save-match-data - (if (string-match "begin{\\([^}]+\\)}" macro) - (match-string 1 macro)))) - (level-exp (cdr (assoc macro reftex-section-levels-all))) - (level (if (symbolp level-exp) - (save-match-data (funcall level-exp)) - level-exp)) - (star (= ?* (char-after (match-end 3)))) - (unnumbered (or star (< level 0))) - (level (abs level)) - (section-number (reftex-section-number level unnumbered)) - (text1 (save-match-data - (save-excursion - (reftex-context-substring prefix)))) - (literal (buffer-substring-no-properties - (1- (match-beginning 3)) - (min (point-max) (+ (match-end 0) (length text1) 1)))) - ;; Literal can be too short since text1 too short. No big problem. - (text (reftex-nicify-text text1))) - - ;; Add section number and indentation - (setq text - (concat - (make-string (* reftex-level-indent level) ?\ ) - (if (nth 1 reftex-label-menu-flags) ; section number flag - (concat section-number " ")) - (if prefix (concat (capitalize prefix) ": ") "") - text)) - (list 'toc "toc" text file marker level section-number - literal (marker-position marker)))) - -;;;###autoload -(defun reftex-ensure-index-support (&optional abort) - "When index support is turned off, ask to turn it on and -set the current prefix argument so that `reftex-access-scan-info' -will rescan the entire document." - (cond - (reftex-support-index t) - ((y-or-n-p "Turn on index support and rescan entire document? ") - (setq reftex-support-index 'demanded - current-prefix-arg '(16))) - (t (if abort - (error "No index support") - (message "No index support") - (ding) - (sit-for 1))))) - -;;;###autoload -(defun reftex-index-info-safe (file) - (reftex-with-special-syntax - (reftex-index-info file))) - -(defvar test-dummy) -;;;###autoload -(defun reftex-index-info (file) - "Return an index entry for the current match. -Careful: This function expects the `match-data' to still be in -place!" - (catch 'exit - (let* ((macro (reftex-match-string 10)) - (bom (match-beginning 10)) - (boa (match-end 10)) - (entry (or (assoc macro reftex-index-macro-alist) - (throw 'exit nil))) - (exclude (nth 3 entry)) - ;; The following is a test if this match should be excluded - (test-dummy (and (fboundp exclude) - (funcall exclude) - (throw 'exit nil))) - (itag (nth 1 entry)) - (prefix (nth 2 entry)) - (index-tag - (cond ((stringp itag) itag) - ((integerp itag) - (progn (goto-char boa) - (or (reftex-nth-arg itag (nth 6 entry)) "idx"))) - (t "idx"))) - (arg (or (progn (goto-char boa) - (reftex-nth-arg (nth 5 entry) (nth 6 entry))) - "")) - (end-of-args (progn (goto-char boa) - (reftex-move-over-touching-args) - (point))) - (end-of-context (progn (skip-chars-forward "^ \t\n\r") (point))) - (begin-of-context - (progn (goto-char bom) - (skip-chars-backward "^ \t\r\n") - (point))) - (context (buffer-substring-no-properties - begin-of-context end-of-context)) - (key-end (if (string-match reftex-index-key-end-re arg) - (1+ (match-beginning 0)))) - (rawkey (substring arg 0 key-end)) - - (key (if prefix (concat prefix rawkey) rawkey)) - (sortkey (downcase key)) - (showkey (mapconcat #'identity - (split-string key reftex-index-level-re) - " ! "))) - (goto-char end-of-args) - ;; 0 1 2 3 4 5 6 7 8 9 - (list 'index index-tag context file bom arg key showkey sortkey key-end)))) - -;;;###autoload -(defun reftex-short-context (env parse &optional bound derive) - "Get about one line of useful context for the label definition at point." - - (if (consp parse) - (setq parse (if derive (cdr parse) (car parse)))) - - (reftex-nicify-text - - (cond - - ((null parse) - (save-excursion - (reftex-context-substring))) - - ((eq parse t) - (if (string= env "section") - ;; special treatment for section labels - (save-excursion - (if (and (re-search-backward reftex-section-or-include-regexp - (point-min) t) - (match-end 2)) - (progn - (goto-char (match-end 0)) - (reftex-context-substring)) - (if reftex-active-toc - (progn - (string-match "{\\([^}]*\\)" (nth 7 reftex-active-toc)) - (match-string 1 (nth 7 reftex-active-toc))) - "SECTION HEADING NOT FOUND"))) - (save-excursion - (goto-char reftex-default-context-position) - (unless (eq (string-to-char env) ?\\) - (reftex-move-over-touching-args)) - (reftex-context-substring)))) - - ((stringp parse) - (save-excursion - (if (re-search-backward parse bound t) - (progn - (goto-char (match-end 0)) - (reftex-context-substring)) - "NO MATCH FOR CONTEXT REGEXP"))) - - ((integerp parse) - (or (save-excursion - (goto-char reftex-default-context-position) - (reftex-nth-arg - parse - (nth 6 (assoc env reftex-env-or-mac-alist)))) - "")) - - ((fboundp parse) - ;; A hook function. Call it. - (save-excursion - (condition-case error-var - (funcall parse env) - (error (format "HOOK ERROR: %s" (cdr error-var)))))) - (t - "INVALID VALUE OF PARSE")))) - -;;;###autoload -(defun reftex-where-am-I () - "Return the docstruct entry above point. -Actually returns a cons cell in which the cdr is a flag indicating -if the information is exact (t) or approximate (nil)." - - (let ((docstruct (symbol-value reftex-docstruct-symbol)) - (cnt 0) rtn rtn-if-no-other - found) - (save-excursion - (while (not rtn) - (incf cnt) - (setq found (re-search-backward (reftex-everything-regexp) nil t)) - (setq rtn - (cond - ((not found) - ;; no match - (or - (car (member (list 'bof (reftex--get-buffer-identifier)) - docstruct)) - (not (setq cnt 2)) - (assq 'bof docstruct) ;; for safety reasons - 'corrupted)) - ((match-end 1) - ;; Label - (assoc (reftex-match-string 1) - (symbol-value reftex-docstruct-symbol))) - ((match-end 3) - ;; Section - (goto-char (1- (match-beginning 3))) - (let* ((buffile (reftex--get-buffer-identifier)) - (list (member (list 'bof buffile) - docstruct)) - (endelt (car (member (list 'eof buffile) - list))) - rtn1) - (while (and list (not (eq endelt (car list)))) - (if (and (eq (car (car list)) 'toc) - (equal buffile - (nth 3 (car list)))) - (cond - ((equal (point) - (or (and (markerp (nth 4 (car list))) - (marker-position (nth 4 (car list)))) - (nth 8 (car list)))) - ;; Fits with marker position or recorded position - (setq rtn1 (car list) list nil)) - ((looking-at (reftex-make-regexp-allow-for-ctrl-m - (nth 7 (car list)))) - ;; Same title: remember, but keep looking - (setq rtn-if-no-other (car list))))) - (pop list)) - rtn1)) - ((match-end 7) - ;; Input or include... - (car - (member (list 'eof (reftex-locate-file - (reftex-match-string 7) "tex" - (cdr (assq 'master-dir docstruct)))) - docstruct))) - ((match-end 9) - (assq 'appendix (symbol-value reftex-docstruct-symbol))) - ((match-end 10) - ;; Index entry - (when reftex-support-index - (let* ((index-info (save-excursion - (reftex-index-info-safe nil))) - (list (member - (list 'bof (reftex--get-buffer-identifier)) - docstruct)) - (endelt - (car (member - (list 'eof (reftex--get-buffer-identifier)) - list))) - dist last-dist last (n 0)) - ;; Check all index entries with equal text - (while (and list (not (eq endelt (car list)))) - (when (and (eq (car (car list)) 'index) - (string= (nth 2 index-info) - (nth 2 (car list)))) - (incf n) - (setq dist (abs (- (point) (nth 4 (car list))))) - (if (or (not last-dist) (< dist last-dist)) - (setq last-dist dist last (car list)))) - (setq list (cdr list))) - ;; We are sure if we have only one, or a zero distance - (cond ((or (= n 1) (equal dist 0)) last) - ((> n 1) (setq cnt 2) last) - (t nil))))) - ((match-end 11) - (save-excursion - (goto-char (match-end 11)) - (assoc (reftex-no-props - (reftex-nth-arg-wrapper - (reftex-match-string 11))) - (symbol-value reftex-docstruct-symbol)))) - (t - (error "This should not happen (reftex-where-am-I)")))))) - ;; Check if there was only a by-name match for the section. - (when (and (not rtn) rtn-if-no-other) - (setq rtn rtn-if-no-other - cnt 2)) - (cons rtn (eq cnt 1)))) - -;;;###autoload -(defun reftex-notice-new (&optional n force) - "Hook to handshake with RefTeX after something new has been inserted." - ;; Add a new entry to the docstruct list. If it is a section, renumber - ;; the following sections. - ;; FIXME: Put in a WHAT parameter and search backward until one is found. - ;; When N is given, go back that many matches of reftex-everything-regexp - ;; When FORCE is non-nil, also insert if `reftex-where-am-I' was uncertain. - (condition-case nil - (catch 'exit - (unless reftex-mode (throw 'exit nil)) - (reftex-access-scan-info) - (let* ((docstruct (symbol-value reftex-docstruct-symbol)) - here-I-am appendix tail entry star level - section-number context) - - (save-excursion - (when (re-search-backward (reftex-everything-regexp) nil t (or n 1)) - - ;; Find where we are - (setq here-I-am (reftex-where-am-I)) - (or here-I-am (throw 'exit nil)) - (unless (or force (cdr here-I-am)) (throw 'exit nil)) - (setq tail (memq (car here-I-am) docstruct)) - (or tail (throw 'exit nil)) - (setq reftex-active-toc (reftex-last-assoc-before-elt - 'toc (car here-I-am) docstruct) - appendix (reftex-last-assoc-before-elt - 'appendix (car here-I-am) docstruct)) - - ;; Initialize section numbers - (if (eq (car (car here-I-am)) 'appendix) - (reftex-init-section-numbers nil t) - (reftex-init-section-numbers reftex-active-toc appendix)) - - ;; Match the section command - (when (re-search-forward (reftex-everything-regexp) nil t) - (cond - ((match-end 1) - (push (reftex-label-info (reftex-match-string 1) - (reftex--get-buffer-identifier)) - (cdr tail))) - - ((match-end 3) - (setq star (= ?* (char-after (match-end 3))) - entry (reftex-section-info (reftex--get-buffer-identifier)) - level (nth 5 entry)) - ;; Insert the section info - (push entry (cdr tail)) - - ;; We are done unless we use section numbers - (unless (nth 1 reftex-label-menu-flags) (throw 'exit nil)) - - ;; Update the remaining toc items - (setq tail (cdr tail)) - (while (and (setq tail (memq (assq 'toc (cdr tail)) tail)) - (setq entry (car tail)) - (>= (nth 5 entry) level)) - (setq star (string-search "*" (nth 6 entry)) - context (nth 2 entry) - section-number - (reftex-section-number (nth 5 entry) star)) - (when (string-match "\\`\\([ \t]*\\)\\([.0-9A-Z]+\\)\\(.*\\)" - context) - (when (and (not appendix) - (>= (string-to-char (match-string 2)) ?A)) - ;; Just entered the appendix. Get out. - (throw 'exit nil)) - - ;; Change the section number. - (setf (nth 2 entry) - (concat (match-string 1 context) - section-number - (match-string 3 context)))))) - ((match-end 10) - ;; Index entry - (and reftex-support-index - (setq entry (reftex-index-info-safe - (reftex--get-buffer-identifier))) - ;; FIXME: (add-to-list 'reftex--index-tags (nth 1 index-entry)) - (push entry (cdr tail)))))))))) - - (error nil)) - ) - -(defsubst reftex-move-to-previous-arg (&optional bound) - "Move backward to the closing parenthesis of the previous argument. -This happens under the assumption that we are in front of a macro -argument. This function understands the splitting of macros over -several lines in TeX." - (cond - ;; Just to be quick: - ((memq (preceding-char) '(?\] ?\) ?\}))) - ;; Do a search - ((and reftex-allow-detached-macro-args - (re-search-backward - "[])}][ \t]*[\n\r]?\\([ \t]*%[^\n\r]*[\n\r]\\)*[ \t]*\\=" bound t)) - (goto-char (1+ (match-beginning 0))) - t) - (t nil))) - -;;;###autoload -(defun reftex-what-macro-safe (which &optional bound) - "Call `reftex-what-macro' with special syntax table." - (reftex-with-special-syntax - (reftex-what-macro which bound))) - -;;;###autoload -(defun reftex-what-macro (which &optional bound) - "Find out if point is within the arguments of any TeX-macro. -The return value is either (\"\\macro\" . (point)) or a list of them. - -If WHICH is nil, immediately return nil. -If WHICH is 1, return innermost enclosing macro. -If WHICH is t, return list of all macros enclosing point. -If WHICH is a list of macros, look only for those macros and return the - name of the first macro in this list found to enclose point. -If the optional BOUND is an integer, bound backwards directed - searches to this point. If it is nil, limit to nearest \\section - - like statement. - -This function is pretty stable, but can be fooled if the text contains -things like \\macro{aa}{bb} where \\macro is defined to take only one -argument. As RefTeX cannot know this, the string \"bb\" would still be -considered an argument of macro \\macro." - (unless reftex-section-regexp (reftex-compile-variables)) - (catch 'exit - (if (null which) (throw 'exit nil)) - (let ((bound (or bound (save-excursion (re-search-backward - reftex-section-regexp nil 1) - (point)))) - pos cmd-list cmd cnt cnt-opt entry) - (save-restriction - (save-excursion - (narrow-to-region (max (point-min) bound) (point-max)) - ;; move back out of the current parenthesis - (while (condition-case nil - (let ((forward-sexp-function nil)) - (up-list -1) t) - (error nil)) - (setq cnt 1 cnt-opt 0) - ;; move back over any touching sexps - (while (and (reftex-move-to-previous-arg bound) - (condition-case nil - (let ((forward-sexp-function nil)) - (if (eq (preceding-char) ?\)) - ;; '?\(' and '?\)' receive the - ;; punctuation syntax "." in - ;; `reftex-syntax-table', so we have - ;; to change it in order move back - ;; over the optional arg in - ;; parentheses correctly: - (let ((temp-table (make-syntax-table))) - (modify-syntax-entry ?\( "()" temp-table) - (modify-syntax-entry ?\) ")(" temp-table) - (with-syntax-table temp-table - (backward-sexp))) - (backward-sexp)) - t) - (error nil))) - (if (memq (following-char) '(?\( ?\[)) (incf cnt-opt)) - (incf cnt)) - (setq pos (point)) - (when (and (memq (following-char) '(?\[ ?\( ?\{)) - (re-search-backward "\\\\[*a-zA-Z]+\\=" nil t)) - (setq cmd (reftex-match-string 0)) - (when (looking-at "\\\\begin{[^}]*}") - (setq cmd (reftex-match-string 0) - cnt (1- cnt))) - ;; This does ignore optional arguments. Very hard to fix. - (when (setq entry (assoc cmd reftex-env-or-mac-alist)) - (if (> cnt (or (nth 4 entry) 100)) - (setq cmd nil))) - (cond - ((null cmd)) - ((eq t which) - (push (cons cmd (point)) cmd-list)) - ((or (eq 1 which) (member cmd which)) - (throw 'exit (cons cmd (point)))))) - (goto-char pos))) - (nreverse cmd-list))))) - -;;;###autoload -(defun reftex-what-environment (which &optional bound) - "Find out if point is inside a LaTeX environment. -The return value is (e.g.) either (\"equation\" . (point)) or a list of -them. - -If WHICH is nil, immediately return nil. -If WHICH is 1, return innermost enclosing environment. -If WHICH is t, return list of all environments enclosing point. -If WHICH is a list of environments, look only for those environments and - return the name of the first environment in this list found to enclose - point. - -If the optional BOUND is an integer, bound backwards directed searches to -this point. If it is nil, limit to nearest \\section - like statement." - (unless reftex-section-regexp (reftex-compile-variables)) - (catch 'exit - (save-excursion - (if (null which) (throw 'exit nil)) - (let ((bound (or bound (save-excursion (re-search-backward - reftex-section-regexp nil 1) - (point)))) - env-list end-list env) - (while (re-search-backward "\\\\\\(begin\\|end\\){\\([^}]+\\)}" - bound t) - (setq env (buffer-substring-no-properties - (match-beginning 2) (match-end 2))) - (cond - ((string= (match-string 1) "end") - (push env end-list)) - ((equal env (car end-list)) - (setq end-list (cdr end-list))) - ((eq t which) - (push (cons env (point)) env-list)) - ((or (eq 1 which) (member env which)) - (throw 'exit (cons env (point)))))) - (nreverse env-list))))) - -;;;###autoload -(defun reftex-what-special-env (which &optional bound) - "Run the special environment parsers and return the matches. - -The return value is (e.g.) either (\"my-parser-function\" . (point)) -or a list of them. - -If WHICH is nil, immediately return nil. -If WHICH is 1, return innermost enclosing environment. -If WHICH is t, return list of all environments enclosing point. -If WHICH is a list of environments, look only for those environments and - return the name of the first environment in this list found to enclose - point." - (unless reftex-section-regexp (reftex-compile-variables)) - (catch 'exit - (save-excursion - (if (null reftex-special-env-parsers) (throw 'exit nil)) - (if (null which) (throw 'exit nil)) - (let ((bound (or bound (save-excursion (re-search-backward - reftex-section-regexp nil 1) - (point)))) - (fun-list (if (listp which) - (mapcar (lambda (x) (if (memq x which) x nil)) - reftex-special-env-parsers) - reftex-special-env-parsers)) - specials rtn) - ;; Call all functions - (setq specials (mapcar - (lambda (fun) - (save-excursion - (setq rtn (and fun (funcall fun bound))) - (if rtn (cons (symbol-name fun) rtn) nil))) - fun-list)) - ;; Delete the non-matches - (setq specials (delq nil specials)) - ;; Sort - (setq specials (sort specials (lambda (a b) (> (cdr a) (cdr b))))) - (if (eq which t) - specials - (car specials)))))) - -(defsubst reftex-move-to-next-arg (&optional _ignore) - "Assuming that we are at the end of a macro name or a macro argument, -move forward to the opening parenthesis of the next argument. -This function understands the splitting of macros over several lines -in TeX." - (cond - ;; Just to be quick: - ((memq (following-char) '(?\[ ?\{))) - ;; Do a search - ((and reftex-allow-detached-macro-args - (looking-at "[ \t]*[\n\r]?\\([ \t]*%[^\n\r]*[\n\r]\\)*[ \t]*[[{]")) - (goto-char (1- (match-end 0))) - t) - (t nil))) - -(defun reftex-nth-arg-wrapper (key) - (let ((entry (assoc key reftex-env-or-mac-alist))) - (reftex-nth-arg (nth 5 entry) (nth 6 entry)))) - -;;;###autoload -(defun reftex-nth-arg (n &optional opt-args) - "Return the Nth following {} or [] parentheses content. -OPT-ARGS is a list of argument numbers which are optional." - - ;; If we are sitting at a macro start, skip to end of macro name. - (and (eq (following-char) ?\\) (skip-chars-forward "a-zA-Z*\\\\")) - - (if (= n 1000) - ;; Special case: Skip all touching arguments - (progn - (reftex-move-over-touching-args) - (reftex-context-substring)) - - ;; Do the real thing. - (let ((cnt 1)) - - (when (reftex-move-to-next-arg) - - (while (< cnt n) - (while (and (member cnt opt-args) - (eq (following-char) ?\{)) - (incf cnt)) - (when (< cnt n) - (unless (and (condition-case nil - (or (forward-list 1) t) - (error nil)) - (reftex-move-to-next-arg) - (incf cnt)) - (setq cnt 1000)))) - - (while (and (memq cnt opt-args) - (eq (following-char) ?\{)) - (incf cnt))) - (if (and (= n cnt) - (> (skip-chars-forward "{[") 0)) - (reftex-context-substring) - nil)))) - -;;;###autoload -(defun reftex-move-over-touching-args () - (condition-case nil - (while (memq (following-char) '(?\[ ?\{)) - (forward-list 1)) - (error nil))) - -(defun reftex-context-substring (&optional to-end) - "Return up to 150 chars from point. -When point is just after a { or [, limit string to matching parenthesis." - (cond - (to-end - ;; Environment - find next \end - (buffer-substring-no-properties - (point) - (min (+ (point) 150) - (save-match-data - ;; FIXME: This is not perfect - (if (re-search-forward "\\\\end{" nil t) - (match-beginning 0) - (point-max)))))) - ((memq (preceding-char) '(?\{ ?\[)) - ;; Inside a list - get only the list. - (buffer-substring-no-properties - (point) - (min (+ (point) 150) - (point-max) - (condition-case nil - (let ((forward-sexp-function nil)) ;Unneeded fanciness. - (up-list 1) - (1- (point))) - (error (point-max)))))) - (t - ;; no list - just grab 150 characters - (buffer-substring-no-properties (point) - (min (+ (point) 150) (point-max)))))) - -;; Variable holding the vector with section numbers -(defvar reftex-section-numbers (make-vector reftex-max-section-depth 0)) - -;;;###autoload -(defun reftex-init-section-numbers (&optional toc-entry appendix) - "Initialize section numbers with zeros or with what is found in the TOC-ENTRY." - (let* ((level (or (nth 5 toc-entry) -1)) - (numbers (nreverse (split-string (or (nth 6 toc-entry) "") "\\."))) - (depth (1- (length reftex-section-numbers))) - (i depth) number-string) - (while (>= i 0) - (if (> i level) - (aset reftex-section-numbers i 0) - (setq number-string (or (car numbers) "0")) - (if (string-match "\\`[A-Z]\\'" number-string) - (aset reftex-section-numbers i - (- (string-to-char number-string) ?A -1)) - (aset reftex-section-numbers i (string-to-number number-string))) - (pop numbers)) - (decf i))) - (put 'reftex-section-numbers 'appendix appendix)) - -;;;###autoload -(defun reftex-section-number (&optional level star) - "Return a string with the current section number. -When LEVEL is non-nil, increase section numbers on that level." - (let* ((depth (1- (length reftex-section-numbers))) idx n (string "") - (appendix (get 'reftex-section-numbers 'appendix)) - (partspecial (and (not reftex-part-resets-chapter) - (equal level 0)))) - ;; partspecial means, this is a part statement. - ;; Parts do not reset the chapter counter, and the part number is - ;; not included in the numbering of other sectioning levels. - (when level - (when (and (> level -1) (not star)) - (aset reftex-section-numbers - level (1+ (aref reftex-section-numbers level)))) - (setq idx (1+ level)) - (when (not star) - (while (<= idx depth) - (if (or (not partspecial) - (not (= idx 1))) - (aset reftex-section-numbers idx 0)) - (incf idx)))) - (if partspecial - (setq string (concat "Part " (reftex-roman-number - (aref reftex-section-numbers 0)))) - (setq idx (if reftex-part-resets-chapter 0 1)) - (while (<= idx depth) - (setq n (aref reftex-section-numbers idx)) - (if (not (and partspecial (not (equal string "")))) - (setq string (concat string (if (not (string= string "")) "." "") - (int-to-string n)))) - (incf idx)) - (save-match-data - (if (string-match "\\`\\([@0]\\.\\)+" string) - (setq string (replace-match "" nil nil string))) - (if (string-match "\\(\\.0\\)+\\'" string) - (setq string (replace-match "" nil nil string))) - (if (and appendix - (string-match "\\`[0-9]+" string)) - (setq string - (concat - (char-to-string - (1- (+ ?A (string-to-number (match-string 0 string))))) - (substring string (match-end 0)))))) - (if star - (concat (make-string (1- (length string)) ?\ ) "*") - string)))) - -(defun reftex-roman-number (n) - "Return as a string the roman number equal to N." - (let ((nrest n) - (string "") - (list '((1000 . "M") ( 900 . "CM") ( 500 . "D") ( 400 . "CD") - ( 100 . "C") ( 90 . "XC") ( 50 . "L") ( 40 . "XL") - ( 10 . "X") ( 9 . "IX") ( 5 . "V") ( 4 . "IV") - ( 1 . "I"))) - listel i s) - (while (>= nrest 1) - (setq listel (pop list) - i (car listel) - s (cdr listel)) - (while (>= nrest i) - (setq string (concat string s) - nrest (- nrest i)))) - string)) - -(provide 'reftex-parse) - -;;; reftex-parse.el ends here - -;; Local Variables: -;; generated-autoload-file: "reftex-loaddefs.el" -;; End: diff --git a/lisp/textmodes/reftex-ref.el b/lisp/textmodes/reftex-ref.el deleted file mode 100644 index 97b855006e7..00000000000 --- a/lisp/textmodes/reftex-ref.el +++ /dev/null @@ -1,892 +0,0 @@ -;;; reftex-ref.el --- code to create labels and references with RefTeX -*- lexical-binding: t; -*- - -;; Copyright (C) 1997-2025 Free Software Foundation, Inc. - -;; Author: Carsten Dominik -;; Maintainer: auctex-devel@gnu.org - -;; 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 . - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl-lib)) - -(require 'reftex) -(require 'reftex-parse) - -;;;###autoload -(defun reftex-label-location (&optional bound) - "Return the environment or macro which determines the label type at point. -If optional BOUND is an integer, limit backward searches to that point." - - (let* ((loc1 (reftex-what-macro reftex-label-mac-list bound)) - (loc2 (reftex-what-environment reftex-label-env-list bound)) - (loc3 (reftex-what-special-env 1 bound)) - (p1 (or (cdr loc1) 0)) - (p2 (or (cdr loc2) 0)) - (p3 (or (cdr loc3) 0)) - (pmax (max p1 p2 p3))) - - (setq reftex-location-start pmax) - (cond - ((= p1 pmax) - ;; A macro. Default context after macro name. - (setq reftex-default-context-position (+ p1 (length (car loc1)))) - (or (car loc1) "section")) - ((= p2 pmax) - ;; An environment. Default context after \begin{name}. - (setq reftex-default-context-position (+ p2 8 (length (car loc2)))) - (or (car loc2) "section")) - ((= p3 pmax) - ;; A special. Default context right there. - (setq reftex-default-context-position p3) - (setq loc3 (car loc3)) - (cond ((null loc3) "section") - ((symbolp loc3) (symbol-name loc3)) - ((stringp loc3) loc3) - (t "section"))) - (t ;; This should not happen, I think? - "section")))) - -;;;###autoload -(defun reftex-label-info-update (cell) - ;; Update information about just one label in a different file. - ;; CELL contains the old info list - (let* ((label (nth 0 cell)) - (typekey (nth 1 cell)) - ;; (text (nth 2 cell)) - (file (nth 3 cell)) - (comment (nth 4 cell)) - (note (nth 5 cell)) - (buf (if (bufferp file) - file - (reftex-get-file-buffer-force - file (not (eq t reftex-keep-temporary-buffers)))))) - (if (not buf) - (list label typekey "" file comment "LOST LABEL. RESCAN TO FIX.") - (with-current-buffer buf - (save-restriction - (widen) - (goto-char 1) - - (if (or (re-search-forward - (format reftex-find-label-regexp-format - (regexp-quote label)) - nil t) - (re-search-forward - (format reftex-find-label-regexp-format2 - (regexp-quote label)) - nil t)) - - (progn - (backward-char 1) - (append (reftex-label-info label file) (list note))) - (list label typekey "" file "LOST LABEL. RESCAN TO FIX."))))))) - -;;;###autoload -(defun reftex-label-info (label &optional file bound derive env-or-mac) - ;; Return info list on LABEL at point. - (let* ((prefix (if (string-match "^[a-zA-Z0-9]+:" label) - (match-string 0 label))) - (typekey (cdr (assoc prefix reftex-prefix-to-typekey-alist))) - (file (or file (reftex--get-buffer-identifier))) - (trust reftex-trust-label-prefix) - (in-comment (reftex-in-comment))) - (if (and typekey - (cond ((eq trust t) t) - ((null trust) nil) - ((stringp trust) (string-match trust typekey)) - ((listp trust) (member typekey trust)) - (t nil))) - (list label typekey - (reftex-nicify-text (reftex-context-substring)) - file in-comment) - (let* ((env-or-mac (or env-or-mac (reftex-label-location bound))) - (typekey (nth 1 (assoc env-or-mac reftex-env-or-mac-alist))) - (parse (nth 2 (assoc env-or-mac reftex-env-or-mac-alist))) - (text (reftex-short-context env-or-mac parse reftex-location-start - derive))) - (list label typekey text file in-comment))))) - -;;; Creating labels --------------------------------------------------------- - -;;;###autoload -(defun reftex-label (&optional environment no-insert) - "Insert a unique label. Return the label. -If ENVIRONMENT is given, don't bother to find out yourself. -If NO-INSERT is non-nil, do not insert label into buffer. -With prefix arg, force to rescan document first. -When you are prompted to enter or confirm a label, and you reply with -just the prefix or an empty string, no label at all will be inserted. -A new label is also recorded into the label list. -This function is controlled by the settings of reftex-insert-label-flags." - - (interactive) - - ;; Ensure access to scanning info and rescan buffer if prefix arg is '(4). - (reftex-access-scan-info current-prefix-arg) - - ;; Find out what kind of environment this is and abort if necessary. - (if (or (not environment) - (not (assoc environment reftex-env-or-mac-alist))) - (setq environment (reftex-label-location))) - (unless environment - (error "Can't figure out what kind of label should be inserted")) - - ;; Ok, go ahead. - (catch 'exit - (let* ((entry (assoc environment reftex-env-or-mac-alist)) - (typekey (nth 1 entry)) - (format (nth 3 entry)) - (macro-cell (reftex-what-macro 1)) - (entry1 (assoc (car macro-cell) reftex-env-or-mac-alist)) - label naked prefix valid default force-prompt rescan-is-useful) - (when (and (or (nth 5 entry) (nth 5 entry1)) - (memq (preceding-char) '(?\[ ?\{))) - ;; This is an argument of a label macro. Insert naked label. - (setq naked t format "%s")) - - (setq prefix (or (cdr (assoc typekey reftex-typekey-to-prefix-alist)) - (concat typekey "-"))) - ;; Replace any escapes in the prefix - (setq prefix (reftex-replace-prefix-escapes prefix)) - - ;; Make a default label. - (cond - - ((reftex-typekey-check typekey (nth 0 reftex-insert-label-flags)) - ;; Derive a label from context. - (setq reftex-active-toc (reftex-last-assoc-before-elt - 'toc (car (reftex-where-am-I)) - (symbol-value reftex-docstruct-symbol))) - (setq default (reftex-no-props - (nth 2 (reftex-label-info " " nil nil t)))) - ;; Catch the cases where the is actually no context available. - (if (or (string-match "NO MATCH FOR CONTEXT REGEXP" default) - (string-match "INVALID VALUE OF PARSE" default) - (string-match "SECTION HEADING NOT FOUND" default) - (string-match "HOOK ERROR" default) - (string-match "^[ \t]*$" default)) - (setq default prefix - force-prompt t) ; need to prompt - (setq default - (concat prefix - (funcall reftex-string-to-label-function default))) - - ;; Make it unique. - (setq default (reftex-uniquify-label default nil "-")))) - - ((reftex-typekey-check typekey (nth 1 reftex-insert-label-flags)) - ;; Minimal default: the user will be prompted. - (setq default prefix)) - - (t - ;; Make an automatic label. - (setq default (reftex-uniquify-label prefix t)))) - - ;; Should we ask the user? - (if (or (reftex-typekey-check typekey - (nth 1 reftex-insert-label-flags)) ; prompt - force-prompt) - - (while (not valid) - ;; iterate until we get a valid label - - (setq label (read-string - (if naked "Naked Label: " "Label: ") - default)) - - ;; Let's make sure that this is a valid label - (cond - - ((string-match (concat "\\`\\(" (regexp-quote prefix) - "\\)?[ \t]*\\'") - label) - ;; No label at all, please - (message "No label inserted.") - (throw 'exit nil)) - - ;; Test if label contains strange characters - ((string-match reftex-label-illegal-re label) - (message "Label \"%s\" contains invalid characters" label) - (ding) - (sit-for 2)) - - ;; Look it up in the label list - ((setq entry (assoc label - (symbol-value reftex-docstruct-symbol))) - (ding) - (if (y-or-n-p - (format-message "Label `%s' exists. Use anyway?" label)) - (setq valid t))) - - ;; Label is ok - (t - (setq valid t)))) - (setq label default)) - - ;; Insert the label into the label list - (let* ((here-I-am-info - (save-excursion - (if (and (or naked no-insert) - (integerp (cdr macro-cell))) - (goto-char (cdr macro-cell))) - (reftex-where-am-I))) - (here-I-am (car here-I-am-info)) - (note (if (cdr here-I-am-info) - "" - "POSITION UNCERTAIN. RESCAN TO FIX.")) - (file (reftex--get-buffer-identifier)) - ;; (text nil) - (tail (memq here-I-am (symbol-value reftex-docstruct-symbol)))) - - (or (cdr here-I-am-info) (setq rescan-is-useful t)) - - (when tail - (push (list label typekey nil file nil note) (cdr tail)) - (put reftex-docstruct-symbol 'modified t))) - - ;; Insert the label into the buffer - (unless no-insert - (insert - (if reftex-format-label-function - (funcall reftex-format-label-function label format) - (format format label))) - (if (and reftex-plug-into-AUCTeX - (fboundp 'LaTeX-add-labels)) - ;; Tell AUCTeX about this - (LaTeX-add-labels label))) - - ;; Delete the corresponding selection buffers to force update on next use. - (when reftex-auto-update-selection-buffers - (reftex-erase-buffer (reftex-make-selection-buffer-name typekey)) - (reftex-erase-buffer (reftex-make-selection-buffer-name " "))) - - (when (and rescan-is-useful reftex-allow-automatic-rescan) - (reftex-parse-one)) - - ;; return value of the function is the label - label))) - -(defun reftex-string-to-label (string) - "Convert a string (a sentence) to a label. -Uses `reftex-derive-label-parameters' and `reftex-label-illegal-re'. It -also applies `reftex-translate-to-ascii-function' to the string." - (when (and reftex-translate-to-ascii-function - (fboundp reftex-translate-to-ascii-function)) - (setq string (funcall reftex-translate-to-ascii-function string))) - (apply #'reftex-convert-string string - "[-~ \t\n\r,;]+" reftex-label-illegal-re nil nil - reftex-derive-label-parameters)) - -(defun reftex-latin1-to-ascii (string) - ;; Translate the upper 128 chars in the Latin-1 charset to ASCII equivalents - (let ((tab "@@@@@@@@@@@@@@@@@@'@@@@@@@@@@@@@ icLxY|S\"ca<--R-o|23'uq..1o>423?AAAAAAACEEEEIIIIDNOOOOOXOUUUUYP3aaaaaaaceeeeiiiidnooooo:ouuuuypy")) - (mapconcat - (lambda (c) - (cond ((and (> c 127) (< c 256)) ; 8 bit Latin-1 - (char-to-string (aref tab (- c 128)))) - ((and (> c 2175) (< c 2304)) ; Mule Latin-1 - (char-to-string (aref tab (- c 2176)))) - (t (char-to-string c)))) - string ""))) - -(defun reftex-replace-prefix-escapes (prefix) - ;; Replace %escapes in a label prefix - (save-match-data - (let (letter (num 0) replace) - (while (string-match "%\\([a-zA-Z]\\)" prefix num) - (setq letter (match-string 1 prefix)) - (setq replace - (save-match-data - (cond - ((equal letter "f") - (file-name-base (reftex--get-buffer-identifier))) - ((equal letter "F") - (let ((masterdir (reftex--get-directory - (reftex-TeX-master-file))) - (file (file-name-sans-extension - (reftex--get-buffer-identifier)))) - (if (string-match (concat "\\`" (regexp-quote masterdir)) - file) - (substring file (length masterdir)) - file))) - ((equal letter "m") - (reftex--get-basename (reftex-TeX-master-file))) - ((equal letter "M") - (file-name-nondirectory - (substring (reftex--get-directory (reftex-TeX-master-file)) - 0 -1))) - ((equal letter "u") - (or (user-login-name) "")) - ((equal letter "S") - (let* (macro level-exp level) - (save-excursion - (save-match-data - (when (re-search-backward reftex-section-regexp nil t) - (setq macro (reftex-match-string 2) - level-exp (cdr (assoc macro reftex-section-levels-all)) - level (if (symbolp level-exp) - (abs (save-match-data - (funcall level-exp))) - (abs level-exp)))) - (cdr (or (assoc macro reftex-section-prefixes) - (assoc level reftex-section-prefixes) - (assq t reftex-section-prefixes) - (list t "sec:"))))))) - (t "")))) - (setq num (1- (+ (match-beginning 1) (length replace))) - prefix (replace-match replace nil nil prefix))) - prefix))) - -(defun reftex-uniquify-label (label &optional force separator) - ;; Make label unique by appending a number. - ;; Optional FORCE means, force appending a number, even if label is unique. - ;; Optional SEPARATOR is a string to stick between label and number. - - ;; Ensure access to scanning info - (reftex-access-scan-info) - - (cond - ((and (not force) - (not (assoc label (symbol-value reftex-docstruct-symbol)))) - label) - (t - (let* ((label-numbers (assq 'label-numbers - (symbol-value reftex-docstruct-symbol))) - (label-numbers-alist (cdr label-numbers)) - (cell (or (assoc label label-numbers-alist) - (car (setcdr label-numbers - (cons (cons label 0) - label-numbers-alist))))) - (num (1+ (cdr cell))) - (sep (or separator ""))) - (while (assoc (concat label sep (int-to-string num)) - (symbol-value reftex-docstruct-symbol)) - (incf num)) - (setcdr cell num) - (concat label sep (int-to-string num)))))) - -;;; Referencing labels ------------------------------------------------------ - -;; Help string for the reference label menu -(defconst reftex-select-label-prompt - "Select: [n]ext [p]revious [r]escan [ ]context e[x]tern [q]uit RET [?]HELP+more") - -(defconst reftex-select-label-help - " n / p Go to next/previous label (Cursor motion works as well) - C-c C-n/p Go to next/previous section heading. - b / l Jump back to previous selection / Reuse last referenced label. - z Jump to a specific section, e.g. '3 z' jumps to section 3. - g / s Update menu / Switch label type. - r / C-u r Reparse document / Reparse entire document. - x Switch to label menu of external document (with LaTeX package `xr'). - F t c Toggle: [F]ile borders, [t]able of contents, [c]ontext - # % Toggle: [#] label counters, [%] labels in comments - SPC / f Show full context in other window / Toggle follow mode. - . Show insertion point in other window. - v / V Toggle \\ref <-> \\vref / Rotate \\ref <=> \\fref <=> \\Fref - TAB Enter a label with completion. - m , - + Mark entry. `,-+' also assign a separator. - a / A Put all marked entries into one/many \\ref commands. - q / RET Quit without referencing / Accept current label (also on mouse-2).") - -(defvar reftex-refstyle) - -;;;###autoload -(defun reftex-reference (&optional type no-insert cut) - "Make a LaTeX reference. Look only for labels of a certain TYPE. -With prefix arg, force to rescan buffer for labels. This should only be -necessary if you have recently entered labels yourself without using -reftex-label. Rescanning of the buffer can also be requested from the -label selection menu. -The function returns the selected label or nil. -If NO-INSERT is non-nil, do not insert \\ref command, just return label. -When called with 2 \\[universal-argument] prefix args, disable magic word recognition." - - (interactive) - - ;; Check for active recursive edits - (reftex-check-recursive-edit) - - ;; Ensure access to scanning info and rescan buffer if prefix is '(4) - (reftex-access-scan-info current-prefix-arg) - - (let ((reftex-refstyle (when (and (boundp 'reftex-refstyle) reftex-refstyle) - reftex-refstyle)) - (reftex-format-ref-function reftex-format-ref-function) - (form "\\ref{%s}") - label labels sep sep1 style-alist) - - (unless reftex-refstyle - (if reftex-ref-macro-prompt - (progn - ;; Build a temporary list which handles more easily. - (dolist (elt reftex-ref-style-alist) - (when (member (car elt) (reftex-ref-style-list)) - (mapc (lambda (x) - (add-to-list 'style-alist (cons (cadr x) (car x)) t)) - (nth 2 elt)))) - ;; Prompt the user for the macro. - (let ((key (reftex-select-with-char - "" (concat "SELECT A REFERENCE FORMAT\n\n" - (mapconcat - (lambda (x) - (format "[%c] %s %s" (car x) - (if (> (car x) 31) " " "") - (cdr x))) - style-alist "\n"))))) - (setq reftex-refstyle (cdr (assoc key style-alist))) - (unless reftex-refstyle - (error "No reference macro associated with key `%c'" key)))) - ;; Get the first macro from `reftex-ref-style-alist' which - ;; matches the first entry in the list of active styles. - (setq reftex-refstyle - (or (caar (nth 2 (assoc (car (reftex-ref-style-list)) - reftex-ref-style-alist))) - ;; Use the first entry in r-r-s-a as a last resort. - (caar (nth 2 (car reftex-ref-style-alist))))))) - - (unless type - ;; Guess type from context - (if (and reftex-guess-label-type - (setq type (reftex-guess-label-type))) - (setq cut (cdr type) - type (car type)) - (setq type (reftex-query-label-type)))) - - ;; Have the user select a label - (set-marker reftex-select-return-marker (point)) - (setq labels (save-excursion - (reftex-offer-label-menu type))) - (reftex-ensure-compiled-variables) - (set-marker reftex-select-return-marker nil) - ;; If the first entry is the symbol 'concat, concat all labels. - ;; We keep the cdr of the first label for typekey etc information. - (if (eq (car labels) 'concat) - (setq labels (list (list (mapconcat #'car (cdr labels) ",") - (cdr (nth 1 labels)))))) - (setq type (nth 1 (car labels)) - form (or (cdr (assoc type reftex-typekey-to-format-alist)) - form)) - - (cond - (no-insert - ;; Just return the first label - (car (car labels))) - ((null labels) - (message "Quit") - nil) - (t - (while labels - (setq label (car (car labels)) - sep (nth 2 (car labels)) - sep1 (cdr (assoc sep reftex-multiref-punctuation)) - labels (cdr labels)) - (when cut - (delete-char (- cut)) - (setq cut nil)) - - ;; remove ~ if we do already have a space - (when (and (= ?~ (string-to-char form)) - (member (preceding-char) '(?\ ?\t ?\n ?~))) - (setq form (substring form 1))) - ;; do we have a special format? - (unless (string= reftex-refstyle "\\ref") - (setq reftex-format-ref-function #'reftex-format-special)) - ;; ok, insert the reference - (if sep1 (insert sep1)) - (insert - (if reftex-format-ref-function - (funcall reftex-format-ref-function label form reftex-refstyle) - (format form label label))) - ;; take out the initial ~ for good - (and (= ?~ (string-to-char form)) - (setq form (substring form 1)))) - (message "") - label)))) - -(defun reftex-guess-label-type () - ;; Examine context to guess what a \ref might want to reference. - (let ((words reftex-words-to-typekey-alist) - (case-fold-search t) - (bound (max (point-min) (- (point) 35))) - matched cell) - (save-excursion - (while (and (setq cell (pop words)) - (not (setq matched - (re-search-backward (car cell) bound t)))))) - (if matched - (cons (cdr cell) (- (match-end 0) (match-end 1))) - nil))) - -(defvar reftex-select-label-mode-map) -(defun reftex-offer-label-menu (typekey) - ;; Offer a menu with the appropriate labels. - (let* ((buf (current-buffer)) - (xr-data (assq 'xr (symbol-value reftex-docstruct-symbol))) - (xr-alist (cons (cons "" (reftex--get-buffer-identifier)) - (nth 1 xr-data))) - (xr-index 0) - (here-I-am (car (reftex-where-am-I))) - (here-I-am1 here-I-am) - (toc (reftex-typekey-check typekey reftex-label-menu-flags 0)) - (files (reftex-typekey-check typekey reftex-label-menu-flags 7)) - (context (not (reftex-typekey-check - typekey reftex-label-menu-flags 3))) - (counter (reftex-typekey-check - typekey reftex-label-menu-flags 2)) - (follow (reftex-typekey-check - typekey reftex-label-menu-flags 4)) - (commented (nth 5 reftex-label-menu-flags)) - (prefix "") - selection-buffers - offset rtn key data last-data entries) - - (unwind-protect - (catch 'exit - (while t - (save-window-excursion - (delete-other-windows) - (setq reftex-call-back-to-this-buffer buf - reftex-latex-syntax-table (syntax-table)) - (if reftex-use-multiple-selection-buffers - (switch-to-buffer-other-window - (with-current-buffer buf - (reftex-make-selection-buffer-name typekey))) - (switch-to-buffer-other-window "*RefTeX Select*") - (reftex-erase-buffer)) - (unless (eq major-mode 'reftex-select-label-mode) - (reftex-select-label-mode)) - (cl-pushnew (current-buffer) selection-buffers) - (setq truncate-lines t) - (setq mode-line-format - (list "---- " 'mode-line-buffer-identification - " " 'global-mode-string " (" mode-name ")" - " S<" 'reftex-refstyle ">" - " -%-")) - (cond - ((= 0 (buffer-size)) - (let ((buffer-read-only nil)) - (message "Creating Selection Buffer...") - (setq offset (reftex-insert-docstruct - buf - toc - typekey - nil ; index - files - context - counter - commented - (or here-I-am offset) - prefix - nil ; no a toc buffer - )))) - (here-I-am - (setq offset (reftex-get-offset buf here-I-am typekey))) - (t (setq offset t))) - (setq buffer-read-only t) - (setq offset (or offset t)) - - (setq here-I-am nil) ; turn off determination of offset - (setq rtn - (reftex-select-item - reftex-select-label-prompt - reftex-select-label-help - reftex-select-label-mode-map - offset - 'reftex-show-label-location follow)) - (setq key (car rtn) - data (nth 1 rtn) - last-data (nth 2 rtn) - offset t) - (unless key (throw 'exit nil)) - (cond - ((eq key ?g) - ;; update buffer - (reftex-erase-buffer)) - ((or (eq key ?r) - (eq key ?R)) - ;; rescan buffer - (and current-prefix-arg (setq key ?R)) - (reftex-erase-buffer) - (reftex-reparse-document buf last-data key)) - ((eq key ?c) - ;; toggle context mode - (reftex-erase-buffer) - (setq context (not context))) - ((eq key ?s) - ;; switch type - (setq here-I-am here-I-am1) - (setq typekey (reftex-query-label-type))) - ((eq key ?t) - ;; toggle table of contents display, or change depth - (reftex-erase-buffer) - (if current-prefix-arg - (setq reftex-toc-max-level (prefix-numeric-value - current-prefix-arg)) - (setq toc (not toc)))) - ((eq key ?F) - ;; toggle display of included file borders - (reftex-erase-buffer) - (setq files (not files))) - ((eq key ?#) - ;; toggle counter display - (reftex-erase-buffer) - (setq counter (not counter))) - ((eq key ?%) - ;; toggle display of commented labels - (reftex-erase-buffer) - (setq commented (not commented))) - ((eq key ?l) - ;; reuse the last referenced label again - (setq entries reftex-last-used-reference) - (throw 'exit t)) - ((eq key ?x) - ;; select an external document - (setq xr-index (reftex-select-external-document - xr-alist xr-index)) - (setq buf (or (reftex-get-file-buffer-force - (cdr (nth xr-index xr-alist))) - (error "Cannot switch document")) - prefix (or (car (nth xr-index xr-alist)) "")) - (set-buffer buf) - (reftex-access-scan-info)) - ((stringp key) - (setq entries - (list - (list - (or (assoc key (symbol-value reftex-docstruct-symbol)) - (list key typekey))))) - (throw 'exit t)) - ((memq key '(?a ?A return)) - (cond - (reftex-select-marked - (setq entries (nreverse reftex-select-marked))) - (data - (setq entries (list (list data)))) - (t (setq entries nil))) - (when entries - (if (equal key ?a) (push 'concat entries)) - (setq reftex-last-used-reference entries)) - (set-buffer buf) - (throw 'exit t)) - (t (error "This should not happen (reftex-offer-label-menu)")))))) - (save-excursion - (while reftex-buffers-with-changed-invisibility - (set-buffer (car (car reftex-buffers-with-changed-invisibility))) - (setq buffer-invisibility-spec - (cdr (pop reftex-buffers-with-changed-invisibility))))) - (mapc (lambda (buf) (and (buffer-live-p buf) (bury-buffer buf))) - selection-buffers) - (reftex-kill-temporary-buffers)) - ;; Add the prefixes, put together the relevant information in the form - ;; (LABEL TYPEKEY SEPARATOR) and return a list of those. - (mapcar (lambda (x) - (if (listp x) - (list (concat prefix (car (car x))) - (nth 1 (car x)) - (nth 2 x)) - x)) - entries))) - -(defun reftex-reparse-document (&optional buffer data key) - ;; Rescan the document. - (save-window-excursion - (save-excursion - (if buffer - (if (not (bufferp buffer)) - (error "No such buffer %s" (buffer-name buffer)) - (set-buffer buffer))) - (let ((arg (if (eq key ?R) '(16) '(4))) - (file (nth 3 data))) - (reftex-access-scan-info arg file))))) - -;;;###autoload -(defun reftex-query-label-type () - ;; Ask for label type - (let ((key (reftex-select-with-char - reftex-type-query-prompt reftex-type-query-help 3))) - (unless (member (char-to-string key) reftex-typekey-list) - (error "No such label type: %s" (char-to-string key))) - (char-to-string key))) - -;;;###autoload -(defun reftex-show-label-location (data forward no-revisit - &optional stay error) - ;; View the definition site of a label in another window. - ;; DATA is an entry from the docstruct list. - ;; FORWARD indicates if the label is likely forward from current point. - ;; NO-REVISIT means do not load a file to show this label. - ;; STAY means leave the new window selected. - ;; ERROR means throw an error exception when the label cannot be found. - ;; If ERROR is nil, the return value of this function indicates success. - (let* ((this-window (selected-window)) - (errorf (if error 'error 'message)) - label file buffer re found) - - (catch 'exit - (setq label (nth 0 data) - file (nth 3 data)) - - (unless file - (funcall errorf "Unknown label - reparse might help") - (throw 'exit nil)) - - ;; Goto the file in another window - (setq buffer - (if no-revisit - (find-buffer-visiting file) - (reftex-get-file-buffer-force - file (not reftex-keep-temporary-buffers)))) - (if buffer - ;; good - the file is available - (switch-to-buffer-other-window buffer) - ;; we have got a problem here. The file does not exist. - ;; Let' get out of here.. - (funcall errorf "Label %s not found" label) - (throw 'exit nil)) - - ;; search for that label - (setq re (format reftex-find-label-regexp-format (regexp-quote label))) - (setq found - (if forward - (re-search-forward re nil t) - (re-search-backward re nil t))) - (unless found - (goto-char (point-min)) - (unless (setq found (re-search-forward re nil t)) - ;; Ooops. Must be in a macro with distributed args. - (setq found - (re-search-forward - (format reftex-find-label-regexp-format2 - (regexp-quote label)) nil t)))) - (if (match-end 3) - (progn - (reftex-highlight 0 (match-beginning 3) (match-end 3)) - (reftex-show-entry (match-beginning 3) (match-end 3)) - (recenter '(4)) - (unless stay (select-window this-window))) - (select-window this-window) - (funcall errorf "Label %s not found" label)) - found))) - -(defun reftex-show-entry (beg-hlt end-hlt) - ;; Show entry if point is hidden - (let* ((n (/ (window-height) 2)) - (beg (save-excursion - (re-search-backward "[\n\r]" nil 1 n) (point))) - (end (save-excursion - (re-search-forward "[\n\r]" nil 1 n) (point)))) - (cond - ((and (boundp 'buffer-invisibility-spec) buffer-invisibility-spec - (get-char-property (1+ beg-hlt) 'invisible)) - ;; Invisible with text properties. That is easy to change. - (push (cons (current-buffer) buffer-invisibility-spec) - reftex-buffers-with-changed-invisibility) - (setq buffer-invisibility-spec nil)) - ((string-search "\r" (buffer-substring beg end)) - ;; Invisible with selective display. We need to copy it. - (let ((string (buffer-substring-no-properties beg end))) - (switch-to-buffer "*RefTeX Context Copy*") - (setq buffer-read-only nil) - (erase-buffer) - (insert string) - (subst-char-in-region (point-min) (point-max) ?\r ?\n t) - (goto-char (- beg-hlt beg)) - (reftex-highlight 0 (1+ (- beg-hlt beg)) (1+ (- end-hlt beg))) - (if (reftex-refontify) - (when (or (not (eq major-mode 'latex-mode)) - (not font-lock-mode)) - (latex-mode) - (run-hook-with-args - 'reftex-pre-refontification-functions - reftex-call-back-to-this-buffer 'reftex-hidden) - (turn-on-font-lock)) - (when (or (not (eq major-mode 'fundamental-mode)) - font-lock-mode) - (fundamental-mode))) - (run-hooks 'reftex-display-copied-context-hook) - (setq buffer-read-only t)))))) - -;; Generate functions for direct insertion of specific referencing -;; macros. The functions are named `reftex--', -;; e.g. `reftex-varioref-vref'. -(dolist (elt reftex-ref-style-alist) - (when (stringp (nth 1 elt)) - (dolist (item (nth 2 elt)) - (let ((macro (car item)) - (package (nth 1 elt))) - (defalias (intern (format "reftex-%s-%s" package - (substring macro 1 (length macro)))) - (lambda () - (:documentation - (format "Insert a reference using the `%s' macro from the %s \ -package.\n\nThis is a generated function." - macro package)) - (interactive) - (let ((reftex-refstyle macro)) - (reftex-reference)))))))) - -(defun reftex-format-special (label fmt refstyle) - "Apply selected reference style to format FMT and add LABEL. -Replace any occurrences of \"\\ref\" with REFSTYLE." - ;; Replace instances of \ref in `fmt' with the special reference - ;; style selected by the user. - (cond - ((while (let ((case-fold-search nil)) - (string-match "\\(\\\\ref\\)[ \t]*{" fmt)) - (setq fmt (replace-match refstyle t t fmt 1)))) - ((string-match "\\(\\\\[[:alpha:]]+\\)[ \t]*{" fmt) - (setq fmt (replace-match refstyle t t fmt 1)))) - (format fmt label)) - -;;;###autoload -(defun reftex-goto-label (&optional other-window) - "Prompt for a label (with completion) and jump to the location of this label. -Optional prefix argument OTHER-WINDOW goes to the label in another window." - (interactive "P") - (reftex-access-scan-info) - (let* ((wcfg (current-window-configuration)) - (docstruct (symbol-value reftex-docstruct-symbol)) - ;; If point is inside a \ref{} or \pageref{}, use that as - ;; default value. - (default (when (looking-back "\\\\\\(?:page\\)?ref{[-a-zA-Z0-9_*.:]*" - (line-beginning-position)) - (reftex-this-word "-a-zA-Z0-9_*.:"))) - (label (completing-read (format-prompt "Label" default) - docstruct - (compf stringp car) t nil nil - default)) - (selection (assoc label docstruct)) - (where (progn - (reftex-show-label-location selection t nil 'stay) - (point-marker)))) - (unless other-window - (set-window-configuration wcfg) - (switch-to-buffer (marker-buffer where)) - (goto-char where)) - (reftex-unhighlight 0))) - -(provide 'reftex-ref) - -;;; reftex-ref.el ends here - -;; Local Variables: -;; generated-autoload-file: "reftex-loaddefs.el" -;; End: diff --git a/lisp/textmodes/reftex-sel.el b/lisp/textmodes/reftex-sel.el deleted file mode 100644 index 45087e69de8..00000000000 --- a/lisp/textmodes/reftex-sel.el +++ /dev/null @@ -1,726 +0,0 @@ -;;; reftex-sel.el --- the selection modes for RefTeX -*- lexical-binding: t; -*- - -;; Copyright (C) 1997-2025 Free Software Foundation, Inc. - -;; Author: Carsten Dominik -;; Maintainer: auctex-devel@gnu.org - -;; 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 . - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl-lib)) - -(require 'reftex) - -;; Common bindings in reftex-select-label-mode-map -;; and reftex-select-bib-mode-map. -(defvar reftex-select-shared-map - (let ((map (make-sparse-keymap))) - (set-keymap-parent map special-mode-map) - (define-key map [remap next-line] #'reftex-select-next) - (define-key map [remap previous-line] #'reftex-select-previous) - (define-key map [remap keyboard-quit] #'reftex-select-keyboard-quit) - (define-key map [remap newline] #'reftex-select-accept) - - (define-key map " " #'reftex-select-callback) - (define-key map "n" #'reftex-select-next) - (define-key map [(down)] #'reftex-select-next) - (define-key map "p" #'reftex-select-previous) - (define-key map [(up)] #'reftex-select-previous) - (define-key map "f" #'reftex-select-toggle-follow) - (define-key map "\C-m" #'reftex-select-accept) - (define-key map [(return)] #'reftex-select-accept) - (define-key map "q" #'reftex-select-quit) - (define-key map "." #'reftex-select-show-insertion-point) - (define-key map "?" #'reftex-select-help) - - ;; The mouse-2 binding - (define-key map [(mouse-2)] #'reftex-select-mouse-accept) - (define-key map [follow-link] 'mouse-face) - map)) - -(defvar reftex-select-label-mode-map - (let ((map (make-sparse-keymap))) - (set-keymap-parent map reftex-select-shared-map) - - (mapc (lambda (key) - (define-key map (vector (list key)) - (lambda () - "Press `?' during selection to find out about this key." - (interactive) (throw 'myexit key)))) - "aAcgFlrRstx#%") - - (define-key map "b" #'reftex-select-jump-to-previous) - (define-key map "z" #'reftex-select-jump) - (define-key map "v" #'reftex-select-cycle-ref-style-forward) - (define-key map "V" #'reftex-select-cycle-ref-style-backward) - (define-key map "m" #'reftex-select-mark) - (define-key map "u" #'reftex-select-unmark) - (define-key map "," #'reftex-select-mark-comma) - (define-key map "-" #'reftex-select-mark-to) - (define-key map "+" #'reftex-select-mark-and) - (define-key map [(tab)] #'reftex-select-read-label) - (define-key map "\C-i" #'reftex-select-read-label) - (define-key map "\C-c\C-n" #'reftex-select-next-heading) - (define-key map "\C-c\C-p" #'reftex-select-previous-heading) - - map) - "Keymap used for *RefTeX Select* buffer, when selecting a label. -This keymap can be used to configure the label selection process which is -started with the command \\[reftex-reference].") - -;;;###autoload -(define-derived-mode reftex-select-label-mode special-mode "LSelect" - "Major mode for selecting a label in a LaTeX document. -This buffer was created with RefTeX. -It only has a meaningful keymap when you are in the middle of a -selection process. -To select a label, move the cursor to it and press RET. -Press `?' for a summary of important key bindings. - -During a selection process, these are the local bindings. - -\\{reftex-select-label-mode-map}" - (setq-local reftex-select-marked nil) - (when (syntax-table-p reftex-latex-syntax-table) - (set-syntax-table reftex-latex-syntax-table)) - ;; We do not set a local map - reftex-select-item does this. - ) - -(defvar reftex-select-bib-mode-map - (let ((map (make-sparse-keymap))) - (set-keymap-parent map reftex-select-shared-map) - - (mapc (lambda (key) - (define-key map (vector (list key)) - (lambda () - "Press `?' during selection to find out about this key." - (interactive) (throw 'myexit key)))) - "grRaAeE") - - (define-key map "\C-i" #'reftex-select-read-cite) - (define-key map [(tab)] #'reftex-select-read-cite) - (define-key map "m" #'reftex-select-mark) - (define-key map "u" #'reftex-select-unmark) - - map) - "Keymap used for *RefTeX Select* buffer, when selecting a BibTeX entry. -This keymap can be used to configure the BibTeX selection process which is -started with the command \\[reftex-citation].") - -;;;###autoload -(define-derived-mode reftex-select-bib-mode special-mode "BSelect" - "Major mode for selecting a citation key in a LaTeX document. -This buffer was created with RefTeX. -It only has a meaningful keymap when you are in the middle of a -selection process. -In order to select a citation, move the cursor to it and press RET. -Press `?' for a summary of important key bindings. - -During a selection process, these are the local bindings. - -\\{reftex-select-label-mode-map}" - (setq-local reftex-select-marked nil) - ;; We do not set a local map - reftex-select-item does this. - ) - -;; (defun reftex-get-offset (buf here-am-I &optional typekey toc index file) -;; ;; Find the correct offset data, like insert-docstruct would, but faster. -;; ;; Buffer BUF knows the correct docstruct to use. -;; ;; Basically this finds the first docstruct entry after HERE-I-AM which -;; ;; is of allowed type. The optional arguments specify what is allowed. -;; (catch 'exit -;; (with-current-buffer buf -;; (reftex-access-scan-info) -;; (let* ((rest (memq here-am-I (symbol-value reftex-docstruct-symbol))) -;; entry) -;; (while (setq entry (pop rest)) -;; (if (or (and typekey -;; (stringp (car entry)) -;; (or (equal typekey " ") -;; (equal typekey (nth 1 entry)))) -;; (and toc (eq (car entry) 'toc)) -;; (and index (eq (car entry) 'index)) -;; (and file -;; (memq (car entry) '(bof eof file-error)))) -;; (throw 'exit entry))) -;; nil)))) - -;;;###autoload -(defun reftex-get-offset (buf here-am-I &optional typekey toc index file) - ;; Find the correct offset data, like insert-docstruct would, but faster. - ;; Buffer BUF knows the correct docstruct to use. - ;; Basically this finds the first docstruct entry before HERE-I-AM which - ;; is of allowed type. The optional arguments specify what is allowed. - (catch 'exit - (with-current-buffer buf - (reftex-access-scan-info) - (let* ((rest (symbol-value reftex-docstruct-symbol)) - lastentry entry) - (while (setq entry (pop rest)) - (if (or (and typekey - (stringp (car entry)) - (or (equal typekey " ") - (equal typekey (nth 1 entry)))) - (and toc (eq (car entry) 'toc)) - (and index (eq (car entry) 'index)) - (and file - (memq (car entry) '(bof eof file-error)))) - (setq lastentry entry)) - (if (eq entry here-am-I) - (throw 'exit (or lastentry entry)))) - nil)))) - -;;;###autoload -(defun reftex-insert-docstruct - (buf toc labels index-entries files context counter show-commented - here-I-am xr-prefix toc-buffer) - ;; Insert an excerpt of the docstruct list. - ;; Return the data property of the entry corresponding to HERE-I-AM. - ;; BUF is the buffer which has the correct docstruct-symbol. - ;; LABELS non-nil means to include labels into the list. - ;; When a string, indicates the label type to include - ;; FILES non-nil means to display file boundaries. - ;; CONTEXT non-nil means to include label context. - ;; COUNTER means to count the labels. - ;; SHOW-COMMENTED means to include also labels which are commented out. - ;; HERE-I-AM is a member of the docstruct list. The function will return - ;; a used member near to this one, as a possible starting point. - ;; XR-PREFIX is the prefix to put in front of labels. - ;; TOC-BUFFER means this is to fill the toc buffer. - (let* ((font reftex-use-fonts) - (cnt 0) - (index -1) - (toc-indent " ") - (label-indent - (concat "> " - (if toc (make-string (* 7 reftex-level-indent) ?\ ) ""))) - (context-indent - (concat ". " - (if toc (make-string (* 7 reftex-level-indent) ?\ ) ""))) - (mouse-face - (if (memq reftex-highlight-selection '(mouse both)) - reftex-mouse-selected-face - nil)) - (label-face reftex-label-face) - (index-face reftex-index-face) - all cell text label typekey note comment master-dir-re - prev-inserted offset from to index-tag docstruct-symbol) - - ;; Pop to buffer buf to get the correct buffer-local variables - (with-current-buffer buf - - ;; Ensure access to scanning info - (reftex-access-scan-info) - - (setq docstruct-symbol reftex-docstruct-symbol - all (symbol-value reftex-docstruct-symbol) - reftex-active-toc nil - master-dir-re - (concat "\\`" (regexp-quote - (reftex--get-directory (reftex-TeX-master-file)))))) - - (setq-local reftex-docstruct-symbol docstruct-symbol) - (setq-local reftex-prefix - (cdr (assoc labels reftex-typekey-to-prefix-alist))) - (if (equal reftex-prefix " ") (setq reftex-prefix nil)) - - ;; Walk the docstruct and insert the appropriate stuff - (while (setq cell (pop all)) - - (incf index) - (setq from (point)) - - (cond - - ((memq (car cell) '(bib thebib label-numbers appendix - master-dir bibview-cache is-multi xr xr-doc))) - ;; These are currently ignored - - ((memq (car cell) '(bof eof file-error)) - ;; Beginning or end of a file - (when files - (setq prev-inserted cell) -; (if (eq offset 'attention) (setq offset cell)) - (insert - " File " (if (string-match master-dir-re (nth 1 cell)) - (substring (nth 1 cell) (match-end 0)) - (nth 1 cell)) - (cond ((eq (car cell) 'bof) " starts here\n") - ((eq (car cell) 'eof) " ends here\n") - ((eq (car cell) 'file-error) " was not found\n"))) - (setq to (point)) - (when font - (put-text-property from to - 'font-lock-face reftex-file-boundary-face)) - (when toc-buffer - (if mouse-face - (put-text-property from (1- to) - 'mouse-face mouse-face)) - (put-text-property from to :data cell)))) - - ((eq (car cell) 'toc) - ;; a table of contents entry - (when (and toc - (<= (nth 5 cell) reftex-toc-max-level)) - (setq prev-inserted cell) -; (if (eq offset 'attention) (setq offset cell)) - (setq reftex-active-toc cell) - (insert (concat toc-indent (nth 2 cell) "\n")) - (setq to (point)) - (when font - (put-text-property from to - 'font-lock-face reftex-section-heading-face)) - (when toc-buffer - (if mouse-face - (put-text-property from (1- to) - 'mouse-face mouse-face)) - (put-text-property from to :data cell)) - (goto-char to))) - - ((stringp (car cell)) - ;; a label - (when (null (nth 2 cell)) - ;; No context yet. Quick update. - (setcdr cell (cdr (reftex-label-info-update cell))) - (put docstruct-symbol 'modified t)) - - (setq label (car cell) - typekey (nth 1 cell) - text (nth 2 cell) - comment (nth 4 cell) - note (nth 5 cell)) - - (when (and labels - (or (eq labels t) - (string= typekey labels) - (string= labels " ")) - (or show-commented (null comment))) - - ;; Yes we want this one - (incf cnt) - (setq prev-inserted cell) -; (if (eq offset 'attention) (setq offset cell)) - - (setq label (concat xr-prefix label)) - (when comment (setq label (concat "% " label))) - (insert label-indent label) - (when font - (setq to (point)) - (put-text-property - (- (point) (length label)) to - 'font-lock-face (if comment - 'font-lock-comment-face - label-face)) - (goto-char to)) - - (insert (if counter (format " (%d) " cnt) "") - (if comment " LABEL IS COMMENTED OUT " "") - (if (stringp note) (concat " " note) "") - "\n") - (setq to (point)) - - (when context - (insert context-indent text "\n") - (setq to (point))) - (put-text-property from to :data cell) - (when mouse-face - (put-text-property from (1- to) - 'mouse-face mouse-face)) - (goto-char to))) - - ((eq (car cell) 'index) - ;; index entry - (when (and index-entries - (or (eq t index-entries) - (string= index-entries (nth 1 cell)))) - (setq prev-inserted cell) -; (if (eq offset 'attention) (setq offset cell)) - (setq index-tag (format "<%s>" (nth 1 cell))) - (and font - (put-text-property 0 (length index-tag) - 'font-lock-face reftex-index-tag-face index-tag)) - (insert label-indent index-tag " " (nth 7 cell)) - - (when font - (setq to (point)) - (put-text-property - (- (point) (length (nth 7 cell))) to - 'font-lock-face index-face) - (goto-char to)) - (insert "\n") - (setq to (point)) - - (when context - (insert context-indent (nth 2 cell) "\n") - (setq to (point))) - (put-text-property from to :data cell) - (when mouse-face - (put-text-property from (1- to) - 'mouse-face mouse-face)) - (goto-char to)))) - - (if (eq cell here-I-am) - (setq offset 'attention)) - (if (and prev-inserted (eq offset 'attention)) - (setq offset prev-inserted)) - ) - - (when (reftex-refontify) - ;; we need to fontify the buffer - (reftex-fontify-select-label-buffer buf)) - (run-hooks 'reftex-display-copied-context-hook) - offset)) - -;;;###autoload -(defun reftex-find-start-point (fallback &rest locations) - ;; Set point to the first available LOCATION. When a LOCATION is a list, - ;; search for such a :data text property. When it is an integer, - ;; use is as line number. FALLBACK is a buffer position used if everything - ;; else fails. - (catch 'exit - (goto-char (point-min)) - (let (loc pos) - (while locations - (setq loc (pop locations)) - (cond - ((null loc)) - ((listp loc) - (setq pos (text-property-any (point-min) (point-max) :data loc)) - (when pos - (goto-char pos) - (throw 'exit t))) - ((integerp loc) - (when (<= loc (count-lines (point-min) (point-max))) - (goto-char (point-min)) - (forward-line (1- loc)) - (throw 'exit t))))) - (goto-char fallback)))) - -(defvar reftex-last-data nil) -(defvar reftex-last-line nil) -(defvar reftex-select-marked nil) -(defvar reftex-refstyle) - -;; The following variables are all bound dynamically in `reftex-select-item'. - -(defvar reftex-select-data) -(defvar reftex-select-prompt) -(defvar reftex--cb-flag) -(defvar reftex--last-data) -(defvar reftex--call-back) -(defvar reftex--help-string) - -;;;###autoload -(defun reftex-select-item ( prompt help-string keymap - &optional offset call-back cb-flag) - ;; Select an item, using PROMPT. - ;; The function returns a key indicating an exit status, along with a - ;; data structure indicating which item was selected. - ;; HELP-STRING contains help. KEYMAP is a keymap with the available - ;; selection commands. - ;; OFFSET can be a label list item which will be selected at start. - ;; When it is t, point will start out at the beginning of the buffer. - ;; Any other value will cause restart where last selection left off. - ;; When CALL-BACK is given, it is a function which is called with the index - ;; of the element. - ;; CB-FLAG is the initial value of that flag. - (let ((reftex-select-prompt prompt) - (reftex--help-string help-string) - (reftex--call-back call-back) - (reftex--cb-flag cb-flag) - ev reftex-select-data reftex--last-data - (selection-buffer (current-buffer))) - - (setq reftex-select-marked nil) - - (setq ev - (catch 'myexit - (save-window-excursion - (setq truncate-lines t) - - ;; Find a good starting point - (reftex-find-start-point - (point-min) offset reftex-last-data reftex-last-line) - (beginning-of-line 1) - (setq-local reftex-last-follow-point (point)) - - (unwind-protect - (progn - (use-local-map keymap) - (add-hook 'pre-command-hook #'reftex-select-pre-command-hook nil t) - (add-hook 'post-command-hook #'reftex-select-post-command-hook nil t) - (princ reftex-select-prompt) - (set-marker reftex-recursive-edit-marker (point)) - (recursive-edit)) - - (set-marker reftex-recursive-edit-marker nil) - (with-current-buffer selection-buffer - (use-local-map nil) - (remove-hook 'pre-command-hook #'reftex-select-pre-command-hook t) - (remove-hook 'post-command-hook - #'reftex-select-post-command-hook t)) - ;; Kill the mark overlays - (mapc (lambda (c) (delete-overlay (nth 1 c))) - reftex-select-marked))))) - - (setq-local reftex-last-line - (+ (count-lines (point-min) (point)) (if (bolp) 1 0))) - (setq-local reftex-last-data reftex--last-data) - (reftex-kill-buffer "*RefTeX Help*") - (setq reftex-callback-fwd (not reftex-callback-fwd)) ;; ;-))) - (message "") - (list ev reftex-select-data reftex--last-data))) - -;; The selection commands - -(defun reftex-select-pre-command-hook () - (reftex-unhighlight 1) - (reftex-unhighlight 0)) - -(defun reftex-select-post-command-hook () - (let (b e) - (setq reftex-select-data (get-text-property (point) :data)) - (setq reftex--last-data (or reftex-select-data reftex--last-data)) - - (when (and reftex-select-data reftex--cb-flag - (not (equal reftex-last-follow-point (point)))) - (setq reftex-last-follow-point (point)) - (funcall reftex--call-back reftex-select-data reftex-callback-fwd - (not reftex-revisit-to-follow))) - (if reftex-select-data - (setq b (or (previous-single-property-change - (1+ (point)) :data) - (point-min)) - e (or (next-single-property-change - (point) :data) - (point-max))) - (setq b (point) e (point))) - (and (memq reftex-highlight-selection '(cursor both)) - (reftex-highlight 1 b e)) - (if (or (not (pos-visible-in-window-p b)) - (not (pos-visible-in-window-p e))) - (recenter '(4))) - (unless (current-message) - (princ reftex-select-prompt)))) - -(defun reftex-select-next (&optional arg) - "Move to next selectable item." - (interactive "p") - (setq reftex-callback-fwd t) - (or (eobp) (forward-char 1)) - (re-search-forward "^[^. \t\n\r]" nil t arg) - (beginning-of-line 1)) -(defun reftex-select-previous (&optional arg) - "Move to previous selectable item." - (interactive "p") - (setq reftex-callback-fwd nil) - (re-search-backward "^[^. \t\n\r]" nil t arg)) -(defun reftex-select-jump (arg) - "Jump to a specific section. E.g. '3 z' jumps to section 3. -Useful for large TOC's." - (interactive "P") - (goto-char (point-min)) - (re-search-forward - (concat "^ *" (number-to-string (if (numberp arg) arg 1)) " ") - nil t) - (beginning-of-line)) -(defun reftex-select-next-heading (&optional arg) - "Move to next table of contents line." - (interactive "p") - (end-of-line) - (re-search-forward "^ " nil t arg) - (beginning-of-line)) -(defun reftex-select-previous-heading (&optional arg) - "Move to previous table of contents line." - (interactive "p") - (re-search-backward "^ " nil t arg)) -(defun reftex-select-quit () - "Abort selection process." - (interactive) - (throw 'myexit nil)) -(defun reftex-select-keyboard-quit () - "Abort selection process." - (interactive) - (throw 'exit t)) -(defun reftex-select-jump-to-previous () - "Jump back to where previous selection process left off." - (interactive) - (let (pos) - (cond - ((and (local-variable-p 'reftex-last-data (current-buffer)) - reftex-last-data - (setq pos (text-property-any (point-min) (point-max) - :data reftex-last-data))) - (goto-char pos)) - ((and (local-variable-p 'reftex-last-line (current-buffer)) - (integerp reftex-last-line)) - (goto-char (point-min)) - (forward-line (1- reftex-last-line))) - (t (ding))))) -(defun reftex-select-toggle-follow () - "Toggle follow mode: Other window follows with full context." - (interactive) - (setq reftex-last-follow-point -1) - (setq reftex--cb-flag (not reftex--cb-flag))) - -(defun reftex-select-cycle-ref-style-internal (&optional reverse) - "Cycle through macros used for referencing. -Cycle in reverse order if optional argument REVERSE is non-nil." - (let (list) - (dolist (style (reftex-ref-style-list)) - (mapc (lambda (x) (add-to-list 'list (car x) t)) - (nth 2 (assoc style reftex-ref-style-alist)))) - (when reverse - (setq list (reverse list))) - (setq reftex-refstyle (or (cadr (member reftex-refstyle list)) (car list)))) - (force-mode-line-update)) - -(defun reftex-select-cycle-ref-style-forward () - "Cycle forward through macros used for referencing." - (interactive) - (reftex-select-cycle-ref-style-internal)) - -(defun reftex-select-cycle-ref-style-backward () - "Cycle backward through macros used for referencing." - (interactive) - (reftex-select-cycle-ref-style-internal t)) - -(defun reftex-select-show-insertion-point () - "Show the point from where selection was started in another window." - (interactive) - (let ((this-window (selected-window))) - (unwind-protect - (progn - (switch-to-buffer-other-window - (marker-buffer reftex-select-return-marker)) - (goto-char (marker-position reftex-select-return-marker)) - (recenter '(4))) - (select-window this-window)))) -(defun reftex-select-callback () - "Show full context in another window." - (interactive) - (if reftex-select-data - (funcall reftex--call-back reftex-select-data reftex-callback-fwd nil) - (ding))) -(defun reftex-select-accept () - "Accept the currently selected item." - (interactive) - (throw 'myexit 'return)) -(defun reftex-select-mouse-accept (ev) - "Accept the item at the mouse click." - (interactive "e") - (mouse-set-point ev) - (setq reftex-select-data (get-text-property (point) :data)) - (setq reftex--last-data (or reftex-select-data reftex--last-data)) - (throw 'myexit 'return)) -(defun reftex-select-read-label () - "Use minibuffer to read a label to reference, with completion." - (interactive) - (let ((label (completing-read - "Label: " (symbol-value reftex-docstruct-symbol) - nil nil reftex-prefix))) - (unless (or (equal label "") (equal label reftex-prefix)) - (throw 'myexit label)))) - -(defvar reftex--found-list) - -(defun reftex-select-read-cite () - "Use minibuffer to read a citation key with completion." - (interactive) - (let* ((key (completing-read "Citation key: " reftex--found-list)) - (entry (assoc key reftex--found-list))) - (cond - ((or (null key) (equal key ""))) - (entry - (setq reftex-select-data entry) - (setq reftex--last-data reftex-select-data) - (throw 'myexit 'return)) - (t (throw 'myexit key))))) - -(defun reftex-select-mark (&optional separator) - "Mark the entry." - (interactive) - (let* ((data (get-text-property (point) :data)) - boe eoe ovl) - (or data (error "No entry to mark at point")) - (if (assq data reftex-select-marked) - (error "Entry is already marked")) - (setq boe (or (previous-single-property-change (1+ (point)) :data) - (point-min)) - eoe (or (next-single-property-change (point) :data) (point-max))) - (setq ovl (make-overlay boe eoe)) - (push (list data ovl separator) reftex-select-marked) - (overlay-put ovl 'font-lock-face reftex-select-mark-face) - (overlay-put ovl 'before-string - (if separator - (format "*%c%d* " separator - (length reftex-select-marked)) - (format "*%d* " (length reftex-select-marked)))) - (message "Entry has mark no. %d" (length reftex-select-marked)))) - -(defun reftex-select-mark-comma () - "Mark the entry and store the `comma' separator." - (interactive) - (reftex-select-mark ?,)) -(defun reftex-select-mark-to () - "Mark the entry and store the `to' separator." - (interactive) - (reftex-select-mark ?-)) -(defun reftex-select-mark-and () - "Mark the entry and store `and' to separator." - (interactive) - (reftex-select-mark ?+)) - -(defun reftex-select-unmark () - "Unmark the entry." - (interactive) - (let* ((data (get-text-property (point) :data)) - (cell (assq data reftex-select-marked)) - (ovl (nth 1 cell)) - (cnt 0) - sep) - (unless cell - (error "No marked entry at point")) - (and ovl (delete-overlay ovl)) - (setq reftex-select-marked (delq cell reftex-select-marked)) - (setq cnt (1+ (length reftex-select-marked))) - (mapc (lambda (c) - (setq sep (nth 2 c)) - (overlay-put (nth 1 c) 'before-string - (if sep - (format "*%c%d* " sep (decf cnt)) - (format "*%d* " (decf cnt))))) - reftex-select-marked) - (message "Entry no longer marked"))) - -(defun reftex-select-help () - "Display a summary of the special key bindings." - (interactive) - (with-output-to-temp-buffer "*RefTeX Help*" - (princ reftex--help-string)) - (reftex-enlarge-to-fit "*RefTeX Help*" t)) - -(provide 'reftex-sel) - -;;; reftex-sel.el ends here - -;; Local Variables: -;; generated-autoload-file: "reftex-loaddefs.el" -;; End: diff --git a/lisp/textmodes/reftex-toc.el b/lisp/textmodes/reftex-toc.el deleted file mode 100644 index 3c780bddd20..00000000000 --- a/lisp/textmodes/reftex-toc.el +++ /dev/null @@ -1,1076 +0,0 @@ -;;; reftex-toc.el --- RefTeX's table of contents mode -*- lexical-binding: t; -*- - -;; Copyright (C) 1997-2025 Free Software Foundation, Inc. - -;; Author: Carsten Dominik -;; Maintainer: auctex-devel@gnu.org - -;; 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 . - -;;; Commentary: - -;;; Code: - -(provide 'reftex-toc) -(require 'reftex) -;;; - -(defvar reftex-toc-mode-map - (let ((map (make-sparse-keymap))) - - (define-key map [(mouse-2)] #'reftex-toc-mouse-goto-line-and-hide) - (define-key map [follow-link] 'mouse-face) - - (define-key map [remap next-line] #'reftex-toc-next) - (define-key map [remap previous-line] #'reftex-toc-previous) - - (define-key map "n" #'reftex-toc-next) - (define-key map "p" #'reftex-toc-previous) - (define-key map "?" #'reftex-toc-show-help) - (define-key map " " #'reftex-toc-view-line) - (define-key map "\C-m" #'reftex-toc-goto-line-and-hide) - (define-key map "\C-i" #'reftex-toc-goto-line) - (define-key map "\C-c>" #'reftex-toc-display-index) - (define-key map "r" #'reftex-toc-rescan) - (define-key map "R" #'reftex-toc-Rescan) - (define-key map "q" #'reftex-toc-quit) ; - (define-key map "k" #'reftex-toc-quit-and-kill) - (define-key map "f" #'reftex-toc-toggle-follow) ; - (define-key map "a" #'reftex-toggle-auto-toc-recenter) - (define-key map "d" #'reftex-toc-toggle-dedicated-frame) - (define-key map "F" #'reftex-toc-toggle-file-boundary) - (define-key map "i" #'reftex-toc-toggle-index) - (define-key map "l" #'reftex-toc-toggle-labels) - (define-key map "t" #'reftex-toc-max-level) - (define-key map "c" #'reftex-toc-toggle-context) - ;; (define-key map "%" #'reftex-toc-toggle-commented) - (define-key map "\M-%" #'reftex-toc-rename-label) - (define-key map "x" #'reftex-toc-external) - (define-key map "z" #'reftex-toc-jump) - (define-key map "." #'reftex-toc-show-calling-point) - (define-key map "\C-c\C-n" #'reftex-toc-next-heading) - (define-key map "\C-c\C-p" #'reftex-toc-previous-heading) - (define-key map ">" #'reftex-toc-demote) - (define-key map "<" #'reftex-toc-promote) - - (easy-menu-define - reftex-toc-menu map - "Menu for Table of Contents buffer" - '("TOC" - ["Show Location" reftex-toc-view-line t] - ["Go To Location" reftex-toc-goto-line t] - ["Exit & Go To Location" reftex-toc-goto-line-and-hide t] - ["Show Calling Point" reftex-toc-show-calling-point t] - ["Quit" reftex-toc-quit t] - "--" - ("Edit" - ["Promote" reftex-toc-promote t] - ["Demote" reftex-toc-demote t] - ["Rename Label" reftex-toc-rename-label t]) - "--" - ["Index" reftex-toc-display-index t] - ["External Document TOC " reftex-toc-external t] - "--" - ("Update" - ["Rebuilt *toc* Buffer" revert-buffer t] - ["Rescan One File" reftex-toc-rescan reftex-enable-partial-scans] - ["Rescan Entire Document" reftex-toc-Rescan t]) - ("Options" - "TOC Items" - ["File Boundaries" reftex-toc-toggle-file-boundary :style toggle - :selected reftex-toc-include-file-boundaries] - ["Labels" reftex-toc-toggle-labels :style toggle - :selected reftex-toc-include-labels] - ["Index Entries" reftex-toc-toggle-index :style toggle - :selected reftex-toc-include-index-entries] - ["Context" reftex-toc-toggle-context :style toggle - :selected reftex-toc-include-context] - "--" - ["Follow Mode" reftex-toc-toggle-follow :style toggle - :selected reftex-toc-follow-mode] - ["Auto Recenter" reftex-toggle-auto-toc-recenter :style toggle - :selected reftex-toc-auto-recenter-timer] - ["Dedicated Frame" reftex-toc-toggle-dedicated-frame t]) - "--" - ["Help" reftex-toc-show-help t])) - - map) - "Keymap used for *toc* buffer.") - -(defvar reftex-toc-menu) -(defvar reftex-last-window-height nil) -(defvar reftex-last-window-width nil) -(defvar reftex-toc-include-labels-indicator nil) -(defvar reftex-toc-include-index-indicator nil) -(defvar reftex-toc-max-level-indicator nil) - -(define-derived-mode reftex-toc-mode special-mode "TOC" - "Major mode for managing Table of Contents for LaTeX files. -This buffer was created with RefTeX. -Press `?' for a summary of important key bindings. - -Here are all local bindings. - -\\{reftex-toc-mode-map}" - (setq-local transient-mark-mode t) - (setq-local revert-buffer-function #'reftex-toc-revert) - (setq-local reftex-toc-include-labels-indicator "") - (setq-local reftex-toc-max-level-indicator - (if (= reftex-toc-max-level 100) - "ALL" - (int-to-string reftex-toc-max-level))) - (setq mode-line-format - (list "---- " 'mode-line-buffer-identification - " " 'global-mode-string " (" mode-name ")" - " L<" 'reftex-toc-include-labels-indicator ">" - " I<" 'reftex-toc-include-index-indicator ">" - " T<" 'reftex-toc-max-level-indicator ">" - " -%-")) - (setq truncate-lines t) - (make-local-variable 'reftex-last-follow-point) - (add-hook 'post-command-hook #'reftex-toc-post-command-hook nil t) - (add-hook 'pre-command-hook #'reftex-toc-pre-command-hook nil t)) - -(defvar reftex-last-toc-file nil - "Stores the file name from which `reftex-toc' was called. For redo command.") - - -(defvar reftex-toc-return-marker (make-marker) - "Marker which makes it possible to return from TOC to old position.") - -(defconst reftex-toc-help -" AVAILABLE KEYS IN TOC BUFFER - ============================ -\\`n' / \\`p' `next-line' / `previous-line' -\\`SPC' Show the corresponding location of the LaTeX document. -\\`TAB' Goto the location and keep the TOC window. -\\`RET' Goto the location and hide the TOC window (also on `mouse-2'). -\\`<' / \\`>' Promote / Demote section, or all sections in region. -\\`C-c >' Display Index. With prefix arg, restrict index to current section. -\\`q' / \\`k' Hide/Kill *toc* buffer, return to position of reftex-toc command. -\\`l' \\`i' \\`c' \\`F' Toggle display of [l]abels, [i]ndex, [c]ontext, [F]ile borders. -\\`t' Change maximum toc depth (e.g., \\`3 t' hides levels greater than 3). -\\`f' / \\`g' Toggle follow mode / Refresh *toc* buffer. -\\`a' / \\`d' Toggle auto recenter / Toggle dedicated frame -\\`r' / \\`C-u r' Reparse the LaTeX document / Reparse entire LaTeX document. -\\`.' In other window, show position from where `reftex-toc' was called. -\\`M-%' Global search and replace to rename label at point. -\\`x' Switch to TOC of external document (with LaTeX package `xr'). -\\`z' Jump to a specific section (e.g., \\`3 z' goes to section 3).") - -(defvar reftex--rebuilding-toc nil) - -;;;###autoload -(defun reftex-toc (&optional _rebuild reuse) - ;; FIXME: Get rid of the `rebuild' argument. - "Show the table of contents for the current document. -When called with a raw \\[universal-argument] prefix, rescan the document first." - -;; The REUSE argument means, search all visible frames for a window -;; displaying the toc window. If yes, reuse this window. - - (interactive) - - (if (or (not (equal reftex-last-toc-master (reftex-TeX-master-file))) - ;; FIXME: use (interactive "P") to receive current-prefix-arg as - ;; an argument instead of using the var here, which forces us to set - ;; current-prefix-arg in the callers. - current-prefix-arg) - (reftex-erase-buffer "*toc*")) - - (setq reftex-last-toc-file (reftex--get-buffer-identifier)) - (setq reftex-last-toc-master (reftex-TeX-master-file)) - - (set-marker reftex-toc-return-marker (point)) - - ;; If follow mode is active, arrange to delay it one command - (if reftex-toc-follow-mode - (setq reftex-toc-follow-mode 1)) - - (and reftex-toc-include-index-entries - (reftex-ensure-index-support)) - (or reftex-support-index - (setq reftex-toc-include-index-entries nil)) - - ;; Ensure access to scanning info and rescan buffer if prefix arg is '(4) - (reftex-access-scan-info current-prefix-arg) - - (let* ((this-buf (current-buffer)) - (docstruct-symbol reftex-docstruct-symbol) - (xr-data (assq 'xr (symbol-value reftex-docstruct-symbol))) - (xr-alist (cons (cons "" (reftex--get-buffer-identifier)) - (nth 1 xr-data))) - (here-I-am (if reftex--rebuilding-toc - (get 'reftex-toc :reftex-data) - (car (reftex-where-am-I)))) - (unsplittable (frame-parameter nil 'unsplittable)) - offset toc-window) - - (if (setq toc-window (get-buffer-window - "*toc*" - (if reuse 'visible))) - (select-window toc-window) - (when (or (not reftex-toc-keep-other-windows) - (< (window-height) (* 2 window-min-height))) - (delete-other-windows)) - - (setq reftex-last-window-width (window-total-width) - reftex-last-window-height (window-height)) ; remember - - (unless unsplittable - (if reftex-toc-split-windows-horizontally - (split-window-right - (floor (* (window-total-width) - reftex-toc-split-windows-fraction))) - (split-window-below - (floor (* (window-height) - reftex-toc-split-windows-fraction))))) - - (switch-to-buffer "*toc*")) - - (or (eq major-mode 'reftex-toc-mode) (reftex-toc-mode)) - (setq-local reftex-docstruct-symbol docstruct-symbol) - (setq reftex-toc-include-labels-indicator - (if (eq reftex-toc-include-labels t) - "ALL" - reftex-toc-include-labels)) - (setq reftex-toc-include-index-indicator - (if (eq reftex-toc-include-index-entries t) - "ALL" - reftex-toc-include-index-entries)) - - (cond - ((= (buffer-size) 0) - ;; buffer is empty - fill it with the table of contents - (message "Building *toc* buffer...") - - (setq buffer-read-only nil) - (insert (format -"TABLE-OF-CONTENTS on %s -SPC=view TAB=goto RET=goto+hide [q]uit [r]escan [l]abels [f]ollow [x]r [?]Help ------------------------------------------------------------------------------- -" (reftex--abbreviate-name reftex-last-toc-master))) - - (if reftex-use-fonts - (put-text-property (point-min) (point) 'font-lock-face reftex-toc-header-face)) - (cursor-intangible-mode 1) - (add-text-properties (point-min) (point) - '(cursor-intangible t - front-sticky (cursor-intangible) - rear-nonsticky (cursor-intangible))) - (put-text-property (point-min) (1+ (point-min)) 'xr-alist xr-alist) - - (setq offset - (reftex-insert-docstruct - this-buf - t ; include TOC - reftex-toc-include-labels - reftex-toc-include-index-entries - reftex-toc-include-file-boundaries - reftex-toc-include-context - nil ; counter - nil ; commented - here-I-am - "" ; xr-prefix - t ; a TOC buffer - )) - - (run-hooks 'reftex-display-copied-context-hook) - (message "Building *toc* buffer...done.") - (setq buffer-read-only t)) - (t - ;; Only compute the offset - (setq offset - (or (reftex-get-offset this-buf here-I-am - (if reftex-toc-include-labels " " nil) - t - reftex-toc-include-index-entries - reftex-toc-include-file-boundaries) - (reftex-last-assoc-before-elt - 'toc here-I-am - (symbol-value reftex-docstruct-symbol)))) - (put 'reftex-toc :reftex-line 3) - (goto-char (point-min)) - (forward-line 2))) - - ;; Find the correct starting point - (reftex-find-start-point (point) offset (get 'reftex-toc :reftex-line)) - (setq reftex-last-follow-point (point)))) - -;;;###autoload -(defun reftex-toc-recenter (&optional arg) - "Display the TOC window and highlight line corresponding to current position." - (interactive "P") - (let ((buf (current-buffer)) - (frame (selected-frame))) - (reftex-toc arg t) - (if (= (count-lines 1 (point)) 2) - (let ((current-prefix-arg nil)) - (select-window (get-buffer-window buf frame)) - (reftex-toc nil t))) - (and (> (point) 1) ;FIXME: Is this point-min or do we care about narrowing? - (not (get-text-property (point) 'cursor-intangible)) - (memq reftex-highlight-selection '(cursor both)) - (reftex-highlight 2 - (or (previous-single-property-change - (min (point-max) (1+ (point))) :data) - (point-min)) - (or (next-single-property-change (point) :data) - (point-max)))) - (select-window (get-buffer-window buf frame)))) - -(defun reftex-toc-pre-command-hook () - ;; used as pre command hook in *toc* buffer - (reftex-unhighlight 0) - ) - -(defun reftex-toc-post-command-hook () - ;; used in the post-command-hook for the *toc* buffer - ;; FIXME: Lots of redundancy with reftex-index-post-command-hook! - (when (get-text-property (point) :data) - (put 'reftex-toc :reftex-data (get-text-property (point) :data)) - (and (> (point) 1) ;FIXME: Is this point-min or do we care about narrowing? - (not (get-text-property (point) 'cursor-intangible)) - (memq reftex-highlight-selection '(cursor both)) - (reftex-highlight 2 - (or (previous-single-property-change (1+ (point)) :data) - (point-min)) - (or (next-single-property-change (point) :data) - (point-max))))) - (if (integerp reftex-toc-follow-mode) - ;; remove delayed action - (setq reftex-toc-follow-mode t) - (and (not (reftex-toc-dframe-p)) - reftex-toc-follow-mode - (not (equal reftex-last-follow-point (point))) - ;; show context in other window - (setq reftex-last-follow-point (point)) - (condition-case nil - (reftex-toc-visit-location nil (not reftex-revisit-to-follow)) - (error t))))) - -(defun reftex-re-enlarge () - "Enlarge window to a remembered size." - ;; FIXME: reftex-last-window-width might be the width of another window on - ;; another frame, so the enlarge-window call might make no sense. - ;; We should just use `quit-window' instead nowadays. - (let ((count (if reftex-toc-split-windows-horizontally - (- (or reftex-last-window-width (window-total-width)) - (window-total-width)) - (- (or reftex-last-window-height (window-height)) - (window-height))))) - (when (> count 0) - (with-demoted-errors "Enlarge window error: %S" - (enlarge-window count reftex-toc-split-windows-horizontally))))) - -(defun reftex-toc-dframe-p (&optional frame error) - ;; Check if FRAME is the dedicated TOC frame. - ;; If yes, and ERROR is non-nil, throw an error. - (setq frame (or frame (selected-frame))) - (let ((res (equal (frame-parameter frame 'name) - "RefTeX TOC Frame"))) - (if (and res error) - (error (substitute-command-keys - "This frame is view-only. Use \\[reftex-toc] \ -to create TOC window for commands"))) - res)) - -(defun reftex-toc-show-help () - "Show a summary of special key bindings." - (interactive) - (reftex-toc-dframe-p nil 'error) - (with-output-to-temp-buffer "*RefTeX Help*" - (let ((help (substitute-command-keys reftex-toc-help))) - (with-current-buffer standard-output - (insert help)))) - (reftex-enlarge-to-fit "*RefTeX Help*" t) - ;; If follow mode is active, arrange to delay it one command - (if reftex-toc-follow-mode - (setq reftex-toc-follow-mode 1))) - -(defun reftex-toc-next (&optional _arg) - "Move to next selectable item." - (interactive) - (setq reftex-callback-fwd t) - (or (eobp) (forward-char 1)) - (goto-char (or (next-single-property-change (point) :data) - (point)))) -(defun reftex-toc-previous (&optional _arg) - "Move to previous selectable item." - (interactive) - (setq reftex-callback-fwd nil) - (goto-char (or (previous-single-property-change (point) :data) - (point)))) -(defun reftex-toc-next-heading (&optional arg) - "Move to next table of contents line." - (interactive "p") - (end-of-line) - (re-search-forward "^ " nil t arg) - (beginning-of-line)) -(defun reftex-toc-previous-heading (&optional arg) - "Move to previous table of contents line." - (interactive "p") - (re-search-backward "^ " nil t arg)) -(defun reftex-toc-toggle-follow () - "Toggle follow (other window follows with context)." - (interactive) - (setq reftex-last-follow-point -1) - (setq reftex-toc-follow-mode (not reftex-toc-follow-mode))) -(defun reftex-toc-toggle-file-boundary () - "Toggle inclusion of file boundaries in *toc* buffer." - (interactive) - (setq reftex-toc-include-file-boundaries - (not reftex-toc-include-file-boundaries)) - (reftex-toc-revert)) -(defun reftex-toc-toggle-labels (arg) - "Toggle inclusion of labels in *toc* buffer. -With prefix ARG, prompt for a label type and include only labels of -that specific type." - (interactive "P") - (setq reftex-toc-include-labels - (if arg (reftex-query-label-type) - (not reftex-toc-include-labels))) - (reftex-toc-revert)) -(defun reftex-toc-toggle-index (arg) - "Toggle inclusion of index in *toc* buffer. -With prefix arg, prompt for an index tag and include only entries of that -specific index." - (interactive "P") - (setq reftex-toc-include-index-entries - (if arg (reftex-index-select-tag) - (not reftex-toc-include-index-entries))) - (reftex-toc-revert)) -(defun reftex-toc-toggle-context () - "Toggle inclusion of label context in *toc* buffer. -Label context is only displayed when the labels are there as well." - (interactive) - (setq reftex-toc-include-context (not reftex-toc-include-context)) - (reftex-toc-revert)) -(defun reftex-toc-max-level (arg) - "Set the maximum level of TOC lines in this buffer to value of prefix ARG. -When no prefix is given, set the max level to a large number, so that all -levels are shown. For example, to set the level to 3, type `3 m'." - (interactive "P") - (setq reftex-toc-max-level (if arg - (prefix-numeric-value arg) - 100)) - (setq reftex-toc-max-level-indicator - (if arg (int-to-string reftex-toc-max-level) "ALL")) - (reftex-toc-revert)) -(defun reftex-toc-view-line () - "View document location in other window." - (interactive) - (reftex-toc-dframe-p nil 'error) - (reftex-toc-visit-location)) -(defun reftex-toc-goto-line-and-hide () - "Go to document location in other window. Hide the TOC window." - (interactive) - (reftex-toc-dframe-p nil 'error) - (reftex-toc-visit-location 'hide)) -(defun reftex-toc-goto-line () - "Go to document location in other window. TOC window stays." - (interactive) - (reftex-toc-dframe-p nil 'error) - (reftex-toc-visit-location t)) -(defun reftex-toc-mouse-goto-line-and-hide (ev) - "Go to document location in other window. Hide the TOC window." - (interactive "e") - (mouse-set-point ev) - (reftex-toc-dframe-p nil 'error) - (reftex-toc-visit-location 'hide)) -(defun reftex-toc-show-calling-point () - "Show point where `reftex-toc' was called from." - (interactive) - (reftex-toc-dframe-p nil 'error) - (let ((this-window (selected-window))) - (unwind-protect - (progn - (switch-to-buffer-other-window - (marker-buffer reftex-toc-return-marker)) - (goto-char (marker-position reftex-toc-return-marker)) - (recenter '(4))) - (select-window this-window)))) -(defun reftex-toc-quit () - "Hide the TOC window and do not move point. -If the TOC window is the only window on the dedicated TOC frame, the frame -is destroyed." - (interactive) - (if (and (one-window-p) - (reftex-toc-dframe-p) - (> (length (frame-list)) 1)) - (delete-frame) - (or (one-window-p) (delete-window)) - (switch-to-buffer (marker-buffer reftex-toc-return-marker)) - (reftex-re-enlarge) - (goto-char (or (marker-position reftex-toc-return-marker) (point))))) -(defun reftex-toc-quit-and-kill () - "Kill the *toc* buffer." - (interactive) - (kill-buffer "*toc*") - (or (one-window-p) (delete-window)) - (switch-to-buffer (marker-buffer reftex-toc-return-marker)) - (reftex-re-enlarge) - (goto-char (marker-position reftex-toc-return-marker))) -(defun reftex-toc-display-index (&optional arg) - "Display the index buffer for the current document. -This works just like `reftex-display-index' from a LaTeX buffer. -With prefix arg 1, restrict index to the section at point." - (interactive "P") - (reftex-toc-dframe-p nil 'error) - (let ((data (get-text-property (point) :data)) - (docstruct (symbol-value reftex-docstruct-symbol)) - bor eor restr) - (when (equal arg 2) - (setq bor (reftex-last-assoc-before-elt 'toc data docstruct) - eor (assoc 'toc (cdr (memq bor docstruct))) - restr (list (nth 6 bor) bor eor))) - (reftex-toc-goto-line) - (reftex-display-index (if restr nil arg) restr))) - -;; Rescanning the document and rebuilding the TOC buffer. -(defun reftex-toc-rescan (&rest _) - "Regenerate the *toc* buffer by reparsing file of section at point." - (interactive) - (if (and reftex-enable-partial-scans - (null current-prefix-arg)) - (let* ((data (get-text-property (point) :data)) - (what (car data)) - (file (cond ((eq what 'toc) (nth 3 data)) - ((memq what '(eof bof file-error)) (nth 1 data)) - ((stringp what) (nth 3 data)) - ((eq what 'index) (nth 3 data)))) - (line (+ (count-lines (point-min) (point)) (if (bolp) 1 0)))) - (if (not file) - (error "Don't know which file to rescan. Try `C-u r'") - (put 'reftex-toc :reftex-line line) - (switch-to-buffer-other-window - (reftex-get-file-buffer-force file)) - (setq current-prefix-arg '(4)) - (let ((reftex--rebuilding-toc t)) - (reftex-toc)))) - (reftex-toc-Rescan)) - (reftex-kill-temporary-buffers)) - -(defun reftex-toc-Rescan (&rest _) - "Regenerate the *toc* buffer by reparsing the entire document." - (interactive) - (let* ((line (+ (count-lines (point-min) (point)) (if (bolp) 1 0)))) - (put 'reftex-toc :reftex-line line)) - (switch-to-buffer-other-window - (reftex-get-file-buffer-force reftex-last-toc-file)) - (setq current-prefix-arg '(16)) - (let ((reftex--rebuilding-toc t)) - (reftex-toc))) - -(defun reftex-toc-revert (&rest _) - "Regenerate the TOC from the internal lists." - (interactive) - (let ((unsplittable (frame-parameter nil 'unsplittable)) - (reftex--rebuilding-toc t)) - (if unsplittable - (switch-to-buffer - (reftex-get-file-buffer-force reftex-last-toc-file)) - (switch-to-buffer-other-window - (reftex-get-file-buffer-force reftex-last-toc-file)))) - (reftex-erase-buffer "*toc*") - (setq current-prefix-arg nil) - (reftex-toc t t)) - -(defun reftex-toc-external (&rest _) - "Switch to table of contents of an external document." - (interactive) - (reftex-toc-dframe-p nil 'error) - (let* ((old-buf (current-buffer)) - (xr-alist (get-text-property 1 'xr-alist)) - (xr-index (reftex-select-external-document - xr-alist 0))) - (switch-to-buffer-other-window (or (reftex-get-file-buffer-force - (cdr (nth xr-index xr-alist))) - (error "Cannot switch document"))) - (reftex-toc) - (if (equal old-buf (current-buffer)) - (message "") - (message "Switched document")))) - -(defun reftex-toc-jump (arg) - "Jump to a specific section. E.g. '3 z' jumps to section 3. -Useful for large TOCs." - (interactive "P") - (goto-char (point-min)) - (re-search-forward - (concat "^ *" (number-to-string (if (numberp arg) arg 1)) " ") - nil t) - (beginning-of-line)) - -;; Promotion/Demotion stuff - -(defvar reftex--pro-or-de) -(defvar reftex--start-line) -(defvar reftex--mark-line) - -(defun reftex-toc-demote (&optional _arg) - "Demote section at point. If region is active, apply to all in region." - (interactive) - (reftex-toc-do-promote 1)) -(defun reftex-toc-promote (&optional _arg) - "Promote section at point. If region is active, apply to all in region." - (interactive) - (reftex-toc-do-promote -1)) -(defun reftex-toc-do-promote (delta) - "Workhorse for `reftex-toc-promote' and `reftex-toc-demote'. -Changes the level of sections in the current region, or just the section at -point." - ;; We should not do anything unless we are sure this is going to work for - ;; each section in the region. Therefore we first collect information and - ;; test. - (let* ((reftex--start-line (+ (count-lines (point-min) (point)) - (if (bolp) 1 0))) - (reftex--mark-line - (if (region-active-p) - (save-excursion (goto-char (mark)) - (+ (count-lines (point-min) (point)) - (if (bolp) 1 0))))) - (start-pos (point)) - (reftex--pro-or-de (if (> delta 0) "de" "pro")) - beg end entries data sections nsec msg) - (setq msg - (catch 'exit - (if (region-active-p) - ;; A region is dangerous, check if we have a brand new scan, - ;; to make sure we are not missing any section statements. - (if (not (reftex-toc-check-docstruct)) - (reftex-toc-load-all-files-for-promotion) ;; exits - (setq beg (min (point) (mark)) - end (max (point) (mark)))) - (setq beg (point) end (point))) - (goto-char beg) - (while (and (setq data (get-text-property (point) :data)) - (<= (point) end)) - (if (eq (car data) 'toc) (push (cons data (point)) entries)) - (goto-char (or (next-single-property-change (point) :data) - (point-max)))) - (setq entries (nreverse entries)) - ;; Get the relevant section numbers, for an informative message - (goto-char start-pos) - (setq sections (reftex-toc-extract-section-number (car entries))) - (if (> (setq nsec (length entries)) 1) - (setq sections - (concat sections "-" - (reftex-toc-extract-section-number - (nth (1- nsec) entries))))) - ;; Run through the list and prepare the changes. - (setq entries (mapcar - (lambda (e) (reftex-toc-promote-prepare e delta)) - entries)) - ;; Ask for permission - (if (or (not reftex-toc-confirm-promotion) ; never confirm - (and (integerp reftex-toc-confirm-promotion) ; confirm if many - (< nsec reftex-toc-confirm-promotion)) - (yes-or-no-p ; ask - (format "%s %d toc-entr%s (section%s %s)? " - (if (< delta 0) "Promote" "Demote") - nsec - (if (= 1 nsec) "y" "ies") - (if (= 1 nsec) "" "s") - sections))) - nil ; we have permission, do nothing - (error "Abort")) ; abort, we don't have permission - ;; Do the changes - (mapc #'reftex-toc-promote-action entries) - ;; Rescan the document and rebuilt the toc buffer - (save-window-excursion - (reftex-toc-Rescan)) - (reftex-toc-restore-region reftex--start-line reftex--mark-line) - (message "%d section%s %smoted" - nsec (if (= 1 nsec) "" "s") reftex--pro-or-de) - nil)) - (if msg (progn (ding) (message "%s" msg))))) - - -(defun reftex-toc-restore-region (point-line &optional mark-line) - (let ((mpos - (when mark-line - (goto-char (point-min)) - (forward-line (1- mark-line)) - (point)))) - (when point-line - (goto-char (point-min)) - (forward-line (1- point-line))) - (when mpos - (set-mark mpos) - (setq mark-active t - deactivate-mark nil)))) - -(defun reftex-toc-promote-prepare (x delta) - "Look at a TOC entry and see if we could pro/demote it. -This function prepares everything for the change, but does not do it. -The return value is a list with information needed when doing the -promotion/demotion later. DELTA is the level change." - (let* ((data (car x)) - (toc-point (cdr x)) - (marker (nth 4 data)) - (literal (nth 7 data)) - (load nil) - (name nil) - ;; Here follows some paranoid code to make very sure we are not - ;; going to break anything - (_ - (if (and (markerp marker) (marker-buffer marker)) - ;; Buffer is still live and we have the marker. - (progn - (with-current-buffer (marker-buffer marker) - ;; Goto the buffer and check of section is unchanged - (goto-char (marker-position marker)) - (if (looking-at (regexp-quote literal)) - ;; OK, get the makro name - (progn - (beginning-of-line 1) - (if (looking-at reftex-section-regexp) - (setq name (reftex-match-string 2)) - (error "Something is wrong! Contact maintainer!"))) - ;; Section has changed, request scan and loading - ;; We use a variable to delay until after the safe-exc. - ;; because otherwise we lose the region. - (setq load t))) - ;; Scan document and load all files, this exits command - (if load (reftex-toc-load-all-files-for-promotion))) ; exits - ;; We don't have a live marker: scan and load files. - (reftex-toc-load-all-files-for-promotion))) - (level (cdr (assoc name reftex-section-levels-all))) - (_ (if (not (integerp level)) - (progn - (goto-char toc-point) - (error "Cannot %smote special sections" reftex--pro-or-de)))) - (newlevel (if (>= level 0) (+ delta level) (- level delta))) - (_ (if (or (and (>= level 0) (= newlevel -1)) - (and (< level 0) (= newlevel 0))) - (error "Cannot %smote \\%s" reftex--pro-or-de name))) - (newname (reftex-toc-newhead-from-alist newlevel name - reftex-section-levels-all))) - (if (and name newname) - (list data name newname toc-point) - (goto-char toc-point) - (error "Cannot %smote \\%s" reftex--pro-or-de name)))) - -(defun reftex-toc-promote-action (x) - "Change the level of a TOC entry. -`reftex--pro-or-de' is assumed to be dynamically scoped into this function." - (let* ((data (car x)) - (name (nth 1 x)) - (newname (nth 2 x)) - (marker (nth 4 data))) - (with-current-buffer (marker-buffer marker) - (goto-char (marker-position marker)) - (if (looking-at (concat "\\([ \t]*" reftex-section-pre-regexp "\\)" (regexp-quote name))) - (replace-match (concat "\\1" newname)) - (error "Fatal error during %smotion" reftex--pro-or-de))))) - -(defun reftex-toc-extract-section-number (entry) - "Get the numbering of a TOC entry, for message purposes." - (if (string-match "\\s-*\\(\\S-+\\)" (nth 2 (car entry))) - (match-string 1 (nth 2 (car entry))) - "?")) - -(defun reftex-toc-newhead-from-alist (nlevel head alist) - "Get new heading with level NLEVEL from ALIST. -If there are no such entries, return nil. -If there are several different entries with same new level, choose the -one with the smallest distance to the association of HEAD in the alist. -This makes it possible for promotion to work several sets of headings, -if these sets are sorted blocks in the alist." - (let* ((al alist) - (ass (assoc head al)) - (pos (length (memq ass al))) - dist (mindist 1000) newhead) - (while al - (if (equal (cdar al) nlevel) - (progn - (setq dist (abs (- (length al) pos))) - (if (< dist mindist) - (setq newhead (car (car al)) - mindist dist)))) - (setq al (cdr al))) - newhead)) - -(defun reftex-toc-check-docstruct () - "Check if the current docstruct is fully up to date and all files visited." - ;; We do this by checking if all sections are on the right position - (let ((docstruct (symbol-value reftex-docstruct-symbol)) - entry marker empoint) - (catch 'exit - (while (setq entry (pop docstruct)) - (if (eq (car entry) 'toc) - (progn - (setq marker (nth 4 entry) - empoint (nth 8 entry)) - (if (not (and (markerp marker) - (marker-buffer marker) - (= (marker-position marker) empoint))) - (throw 'exit nil))))) - t))) - -(defun reftex-toc-load-all-files-for-promotion () - "Make sure all files of the document are being visited by buffers, -and that the scanning info is absolutely up to date. -We do this by rescanning with `reftex-keep-temporary-buffers' bound to t. -The variable `reftex--pro-or-de' is assumed to be dynamically -scoped into this function. -When finished, we exit with an error message." - (let ((reftex-keep-temporary-buffers t)) - (reftex-toc-Rescan) - (reftex-toc-restore-region reftex--start-line reftex--mark-line) - (throw 'exit - "TOC had to be updated first. Please check selection and repeat the command."))) - -(defun reftex-toc-rename-label () - "Rename the currently selected label in the *toc* buffer. -This launches a global search and replace in order to rename a label. -Renaming a label is hardly ever necessary - the only exception is after -promotion/demotion in connection with a package like fancyref, where the -label prefix determines the wording of a reference." - (interactive) - (let* ((toc (get-text-property (point) :data)) - (label (car toc)) newlabel) - (if (not (stringp label)) - (error "This is not a label entry")) - (setq newlabel (read-string (format "Rename label \"%s\" to: " label))) - (if (assoc newlabel (symbol-value reftex-docstruct-symbol)) - (if (not (y-or-n-p - (format-message "Label `%s' exists. Use anyway? " newlabel))) - (error "Abort"))) - (save-excursion - (save-window-excursion - (reftex-toc-visit-location t) - (condition-case nil - (reftex-query-replace-document - (concat "{" (regexp-quote label) "}") - (format "{%s}" newlabel)) - (error t)))) - (reftex-toc-rescan))) - - -(defun reftex-toc-visit-location (&optional final no-revisit) - ;; Visit the tex file corresponding to the TOC entry on the current line. - ;; If FINAL is t, stay there - ;; If FINAL is 'hide, hide the TOC window. - ;; Otherwise, move cursor back into TOC window. - ;; NO-REVISIT means don't visit files, just use live buffers. - ;; This function is pretty clever about finding back a section heading, - ;; even if the buffer is not live, or things like outline, x-symbol etc. - ;; have been active. - - (let* ((toc (get-text-property (point) :data)) - (toc-window (selected-window)) - match) - - (unless toc (error "Don't know which TOC line to visit")) - - (cond - - ((eq (car toc) 'toc) - ;; a toc entry - (setq match (reftex-toc-find-section toc no-revisit))) - - ((eq (car toc) 'index) - ;; an index entry - (setq match (reftex-index-show-entry toc no-revisit))) - - ((memq (car toc) '(bof eof)) - ;; A file entry - (setq match - (let ((where (car toc)) - (file (nth 1 toc))) - (if (or (not no-revisit) (find-buffer-visiting file)) - (progn - (switch-to-buffer-other-window - (reftex-get-file-buffer-force file nil)) - (goto-char (if (eq where 'bof) (point-min) (point-max)))) - (message "%s" reftex-no-follow-message) nil)))) - - ((stringp (car toc)) - ;; a label - (setq match (reftex-show-label-location toc reftex-callback-fwd - no-revisit t)))) - - (unless match - (select-window toc-window) - (error "Cannot find location")) - - ;; Use the `final' parameter to decide what to do next. - (cond - ((eq final t) - (with-selected-window toc-window - (reftex-unhighlight 0))) - ((eq final 'hide) - (let ((window (selected-window)) - (buffer (window-buffer))) - (unless (eq window toc-window) ;FIXME: Can this happen? - (with-selected-window toc-window - (reftex-unhighlight 0) - (or (one-window-p) (delete-window)))) - ;; If window is still live, buffer is already visible - ;; so let's not make it visible in yet-another-window. - (unless (window-live-p window) - ;; FIXME: How could window not be live? - (pop-to-buffer-same-window buffer)) - (reftex-re-enlarge))) - (t - (unless (eq (selected-frame) (window-frame toc-window)) - ;; Make sure `toc-window' is not just selected but has focus. - (select-frame-set-input-focus (window-frame toc-window))) - (select-window toc-window))))) - -(defun reftex-toc-find-section (toc &optional no-revisit) - (let* ((file (nth 3 toc)) - (marker (nth 4 toc)) - (level (nth 5 toc)) - (literal (nth 7 toc)) - (emergency-point (nth 8 toc)) - (match - (cond - ((and (markerp marker) (marker-buffer marker)) - ;; Buffer is still live and we have the marker. Should be easy. - (switch-to-buffer-other-window (marker-buffer marker)) - (push-mark nil) - (goto-char (marker-position marker)) - (or (looking-at (regexp-quote literal)) - (looking-at (reftex-make-regexp-allow-for-ctrl-m literal)) - (looking-at (reftex-make-desperate-section-regexp literal)) - (looking-at (concat "\\\\" - (regexp-quote - (car - (rassq level - reftex-section-levels-all))) - "[[{]?")))) - ((or (not no-revisit) - (find-buffer-visiting file)) - ;; Marker is lost. Use the backup method. - (switch-to-buffer-other-window - (reftex-get-file-buffer-force file nil)) - (goto-char (or emergency-point (point-min))) - (or (looking-at (regexp-quote literal)) - (let ((len (length literal))) - (or (reftex-nearest-match (regexp-quote literal) len) - (reftex-nearest-match - (reftex-make-regexp-allow-for-ctrl-m literal) len) - (reftex-nearest-match - (reftex-make-desperate-section-regexp literal) len))))) - (t (message "%s" reftex-no-follow-message) nil)))) - (when match - (goto-char (match-beginning 0)) - (if (not (= (point) (point-max))) (recenter 1)) - (reftex-highlight 0 (match-beginning 0) (match-end 0) (current-buffer))) - match)) - -(defun reftex-make-desperate-section-regexp (old) - ;; Return a regexp which will still match a section statement even if - ;; x-symbol or isotex or the like have been at work in the mean time. - (let* ((n (1+ (string-match "[[{]" old))) - (new (regexp-quote (substring old 0 (1+ (string-match "[[{]" old))))) - (old (substring old n))) - (while (string-match - "\\([\r\n]\\)\\|\\(\\`\\|[ \t\n\r]\\)\\([a-zA-Z0-9]+\\)\\([ \t\n\r]\\|}\\'\\)" - old) - (if (match-beginning 1) - (setq new (concat new "[^\n\r]*[\n\r]")) - (setq new (concat new "[^\n\r]*" (match-string 3 old)))) - (setq old (substring old (match-end 0)))) - new)) - -;; Auto recentering of TOC window - -(defun reftex-recenter-toc-when-idle () - (and (> (buffer-size) 5) - reftex-mode - (not (active-minibuffer-window)) - (fboundp 'reftex-toc-mode) - (get-buffer-window "*toc*" 'visible) - (equal reftex-last-toc-master (reftex-TeX-master-file)) - (let (current-prefix-arg) - (reftex-toc-recenter)))) - -;;;###autoload -(defun reftex-toggle-auto-toc-recenter () - "Toggle the automatic recentering of the TOC window. -When active, leaving point idle will make the TOC window jump to the correct -section." - (interactive) - (if reftex-toc-auto-recenter-timer - (progn - (cancel-timer reftex-toc-auto-recenter-timer) - (setq reftex-toc-auto-recenter-timer nil) - (message "Automatic recentering of TOC window was turned off")) - (setq reftex-toc-auto-recenter-timer - (run-with-idle-timer - reftex-idle-time t #'reftex-recenter-toc-when-idle)) - (message "Automatic recentering of TOC window was turned on"))) - -(defun reftex-toc-toggle-dedicated-frame () - "Toggle the display of a separate frame for the TOC. -This frame is not used by the `reftex-toc' commands, but it is useful to -always show the current section in connection with the option -`reftex-auto-recenter-toc'." - (interactive) - (catch 'exit - (let* ((frames (frame-list)) frame) - (while (setq frame (pop frames)) - (if (equal (frame-parameter frame 'name) - "RefTeX TOC Frame") - (progn - (delete-frame frame) - (throw 'exit nil)))) - (reftex-make-separate-toc-frame)))) - -(defun reftex-make-separate-toc-frame () - ;; Create a new fame showing only the TOC buffer. - (let ((current-frame (selected-frame)) - (current-window (selected-window)) - (current-toc-window (get-buffer-window "*toc*" 'visible)) - current-toc-frame) - (if (and current-toc-window - (not (equal (selected-frame) (window-frame current-toc-window)))) - nil - (setq current-toc-frame - (make-frame - '((name . "RefTeX TOC Frame") - (height . 20) (width . 60) - (unsplittable . t) - (minibuffer . nil) - (default-toolbar-visible-p . nil) - (menubar-visible-p . nil) - (horizontal-scrollbar-visible-p . nil)))) - (select-frame current-toc-frame) - (switch-to-buffer "*toc*") - (select-frame current-frame) - (cond ((fboundp 'x-focus-frame) - (x-focus-frame current-frame))) - (select-window current-window) - (when (eq reftex-auto-recenter-toc 'frame) - (unless reftex-toc-auto-recenter-timer - (reftex-toggle-auto-toc-recenter)) - (add-hook 'delete-frame-functions #'reftex-toc-delete-frame-hook))))) - -(defun reftex-toc-delete-frame-hook (frame) - (if (and reftex-toc-auto-recenter-timer - (reftex-toc-dframe-p frame)) - (progn - (reftex-toggle-auto-toc-recenter)))) - -;;; reftex-toc.el ends here - -;; Local Variables: -;; generated-autoload-file: "reftex-loaddefs.el" -;; End: diff --git a/lisp/textmodes/reftex-vars.el b/lisp/textmodes/reftex-vars.el deleted file mode 100644 index 6c852566df9..00000000000 --- a/lisp/textmodes/reftex-vars.el +++ /dev/null @@ -1,2121 +0,0 @@ -;;; reftex-vars.el --- configuration variables for RefTeX -*- lexical-binding: t; -*- - -;; Copyright (C) 1997-1999, 2001-2025 Free Software Foundation, Inc. - -;; Author: Carsten Dominik -;; Maintainer: auctex-devel@gnu.org - -;; 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 . - -;;; Commentary: - -;;; Code: -(defvar reftex-tables-dirty) -(eval-when-compile (require 'cl-lib)) -(eval-and-compile - (defun reftex-set-dirty (symbol value) - (setq reftex-tables-dirty t) - (set symbol value))) - -;; Define the two constants which are needed during compilation - -(eval-and-compile -(defconst reftex-label-alist-builtin - '( - ;; Some aliases, mostly for backward compatibility - (Sideways "Alias for -->rotating" (rotating)) - (AMSTeX "amsmath with eqref macro" - ((nil ?e nil "~\\eqref{%s}") - amsmath)) - - ;; Individual package defaults - (amsmath "AMS-LaTeX math environments" - (("align" ?e nil nil eqnarray-like) - ("gather" ?e nil nil eqnarray-like) - ("multline" ?e nil nil t) - ("flalign" ?e nil nil eqnarray-like) - ("alignat" ?e nil nil alignat-like) - ("xalignat" ?e nil nil alignat-like) - ("xxalignat" ?e nil nil alignat-like) - ("subequations" ?e nil nil t))) - - (endnotes "The \\endnote macro" - (("\\endnote[]{}" ?N "en:" "~\\ref{%s}" 2 - (regexp "endnotes?" "notes?" "Anmerkung\\(en\\)?" "Anm\\.")))) - - (fancybox "The Beqnarray environment" - (("Beqnarray" ?e nil nil eqnarray-like))) - - (floatfig "The floatingfigure environment" - (("floatingfigure" ?f nil nil caption))) - - (longtable "The longtable environment" - (("longtable" ?t nil nil caption))) - - (picinpar "The figwindow and tabwindow environments" - (("figwindow" ?f nil nil 1) - ("tabwindow" ?f nil nil 1))) - - (rotating "The sidewaysfigure and sidewaystable environments" - (("sidewaysfigure" ?f nil nil caption) - ("sidewaysfigure*" ?f nil nil caption) - ("sidewaystable" ?t nil nil caption) - ("sidewaystable*" ?t nil nil caption))) - - (sidecap "The SCfigure and SCtable environments" - (("SCfigure" ?f nil nil caption) - ("SCfigure*" ?f nil nil caption) - ("SCtable" ?t nil nil caption) - ("SCtable*" ?t nil nil caption))) - - (subfig "The \\subfigure and \\subtable macros" - ;; The main macro \subfloat is ambiguous, so we only support the - ;; compat macros for the old subfigure package. The context regexp - ;; must match combinations of - ;; \subfigure[list-capt.][sub-capt.]{body} - (("\\subfigure[][]{}" ?f "fig:" "~\\subref{%s}" - "\\\\subfigure\\(?:\\(?:\\[[^]]*\\]\\)?\\[\\|{\\)") - ("\\subtable[][]{}" ?t "tab:" "~\\subref{%s}" - "\\\\subtable\\(?:\\(?:\\[[^]]*\\]\\)?\\[\\|{\\)"))) - - (wrapfig "The wrapfigure and wraptable environments" - (("wrapfigure" ?f nil nil caption) - ("wraptable" ?t nil nil caption))) - - (ctable "The \\ctable macro" - (("\\ctable[]{}{}{}" ?t "tab:" "~\\ref{%s}" 1 ("table" "Tabelle")))) - - (listings "The lstlisting environment" - (("lstlisting" ?l "lst:" "~\\ref{%s}" nil (regexp "[Ll]isting")))) - - (minted "The listing environment" - (("listing" ?l "lst:" "~\\ref{%s}" nil (regexp "[Ll]isting")))) - - ;; The LaTeX core stuff - (LaTeX "LaTeX default macros and environments" - (("section" ?s "%S" "~\\ref{%s}" (nil . t) - (regexp "parts?" "chapters?" "chap\\." "sections?" "sect?\\." - "paragraphs?" "par\\." - "\\\\S" "\247" "Teile?" "Kapitel" "Kap\\." "Abschnitte?" - "appendi\\(x\\|ces\\)" "App\\." "Anh\"?ange?" "Anh\\.")) - - ("enumerate" ?i "item:" "~\\ref{%s}" item - (regexp "items?" "Punkte?")) - - ("equation" ?e "eq:" "~(\\ref{%s})" t - (regexp "equations?" "eqs?\\." "eqn\\." "Gleichung\\(en\\)?" "Gl\\.")) - ("eqnarray" ?e "eq:" nil eqnarray-like) - - ("figure" ?f "fig:" "~\\ref{%s}" caption - (regexp "figure?[sn]?" "figs?\\." "Abbildung\\(en\\)?" "Abb\\.")) - ("figure*" ?f nil nil caption) - - ("table" ?t "tab:" "~\\ref{%s}" caption - (regexp "tables?" "tab\\." "Tabellen?")) - ("table*" ?t nil nil caption) - - ("\\footnote[]{}" ?n "fn:" "~\\footref{%s}" 2 - (regexp "footnotes?" "Fussnoten?")) - - ("any" ?\ " " "~\\ref{%s}" nil) - - ;; The label macro is hard coded, but it *could* be defined like this: - ;;("\\label{*}" nil nil nil nil) - )) - - ;; Texinfo - (Texinfo "Texinfo default environments" nil)) - "The default label environment descriptions. -Lower-case symbols correspond to a style file of the same name in the LaTeX -distribution. Mixed-case symbols are convenience aliases.") - -(defconst reftex-cite-format-builtin - '((default "Default macro \\cite{%l}" - "\\cite[]{%l}") - (natbib "The Natbib package" - ((?\C-m . "\\cite[][]{%l}") - (?t . "\\citet[][]{%l}") - (?T . "\\citet*[][]{%l}") - (?p . "\\citep[][]{%l}") - (?P . "\\citep*[][]{%l}") - (?e . "\\citep[e.g.][]{%l}") - (?s . "\\citep[see][]{%l}") - (?a . "\\citeauthor{%l}") - (?A . "\\citeauthor*{%l}") - (?y . "\\citeyear{%l}") - (?n . "\\nocite{%l}"))) - (biblatex "The Biblatex package" - ((?\C-m . "\\cite[][]{%l}") - (?C . "\\cite*[][]{%l}") - (?t . "\\textcite[][]{%l}") - (?T . "\\textcite*[][]{%l}") - (?p . "\\parencite[][]{%l}") - (?P . "\\parencite*[][]{%l}") - (?f . "\\footcite[][]{%l}") - (?s . "\\smartcite[][]{%l}") - (?u . "\\autocite[][]{%l}") - (?U . "\\autocite*[][]{%l}") - (?a . "\\citeauthor{%l}") - (?A . "\\citeauthor*{%l}") - (?i . "\\citetitle{%l}") - (?I . "\\citetitle*{%l}") - (?y . "\\citeyear{%l}") - (?Y . "\\citeyear*{%l}") - (?n . "\\nocite{%l}"))) - (amsrefs "The AMSRefs package" - ((?\C-m . "\\cite{%l}") - (?p . "\\cite{%l}") - (?P . "\\cites{%l}") - (?t . "\\ocite{%l}") - (?T . "\\ocites{%l}") - (?y . "\\ycite{%l}") - (?Y . "\\ycites{%l}") - (?a . "\\citeauthor{%l}") - (?A . "\\citeauthory{%l}") - (?f . "\\fullcite{%l}") - (?F . "\\fullocite{%l}") - (?n . "\\nocite{%l}"))) - (jurabib "The Jurabib package" - ((?\C-m . "\\cite{%l}") - (?c . "\\cite[][]{%l}") - (?t . "\\citet{%l}") - (?p . "\\citep{%l}") - (?e . "\\citep[e.g.][]{%l}") - (?s . "\\citep[see][]{%l}") - (?u . "\\fullcite{%l}") - (?i . "\\citetitle{%l}") - (?a . "\\citeauthor{%l}") - (?e . "\\citefield{}{%l}") - (?y . "\\citeyear{%l}") - (?f . "\\footcite{%l}") - (?F . "\\footcite[][]{%l}") - (?l . "\\footfullcite{%l}"))) - (bibentry "The Bibentry package" - "\\bibentry{%l}") - (harvard "The Harvard package" - ((?\C-m . "\\cite[]{%l}") - (?p . "\\cite[]{%l}") - (?t . "\\citeasnoun[]{%l}") - (?n . "\\citeasnoun[]{%l}") - (?s . "\\possessivecite{%l}") - (?e . "\\citeaffixed{%l}{?}") - (?y . "\\citeyear{%l}") - (?a . "\\citename{%l}"))) - (chicago "The Chicago package" - ((?\C-m . "\\cite[]{%l}") - (?t . "\\citeN[]{%l}") - (?T . "\\shortciteN{%l}") - (?p . "\\cite[]{%l}") - (?P . "\\shortcite{%l}") - (?a . "\\citeA{%l}") - (?A . "\\shortciteA{%l}") - (?y . "\\citeyear{%l}"))) - (astron "The Astron package" - ((?\C-m . "\\cite[]{%l}") - (?p . "\\cite[]{%l}" ) - (?t . "%2a (\\cite{%l})"))) - (author-year "Do-it-yourself Author-year" - ((?\C-m . "\\cite{%l}") - (?t . "%2a (%y)\\nocite{%l}") - (?p . "(%2a %y\\nocite{%l})"))) - (locally "Full info in parenthesis" - "(%2a %y, %j %v, %P, %e: %b, %u, %s %<)") - (context - "ConTeXt bib module" - ((?\C-m . "\\cite[%l]") - (?s . "\\cite[][%l]") - (?n . "\\nocite[%l]")))) - "Builtin versions of the citation format. -The following conventions are valid for all alist entries: -`?\\C-m' should always point to a straight \\cite{%l} macro. -`?t' should point to a textual citation (citation as a noun). -`?p' should point to a parenthetical citation.") - -(defconst reftex-index-macros-builtin - '((default "Default \\index and \\glossary macros" - (("\\index{*}" "idx" ?i "" nil t) - ("\\glossary{*}" "glo" ?g "" nil t))) - (multind "The multind.sty package" - (("\\index{}{*}" 1 ?i "" nil t))) - (index "The index.sty package" - (("\\index[]{*}" 1 ?i "" nil t) - ("\\index*[]{*}" 1 ?I "" nil nil))) - (Index-Shortcut "index.sty with \\shortindexingon" - (("\\index[]{*}" 1 ?i "" nil t) - ("\\index*[]{*}" 1 ?I "" nil nil) - ("^[]{*}" 1 ?^ "" texmathp t) - ("_[]{*}" 1 ?_ "" texmathp nil)))) - "Builtin stuff for `reftex-index-macros'. -Lower-case symbols correspond to a style file of the same name in the LaTeX -distribution. Mixed-case symbols are convenience aliases.") -) - -;; Configuration Variables and User Options for RefTeX ------------------ - -(defgroup reftex nil - "LaTeX label and citation support." - :tag "RefTeX" - :link '(url-link :tag "Website" - "https://www.gnu.org/software/auctex/reftex.html") - :link '(emacs-commentary-link :tag "Commentary in reftex.el" "reftex.el") - :link '(custom-manual "(reftex)Top") - :prefix "reftex-" - :group 'tex) - - -;; Table of contents configuration -------------------------------------- - -(defgroup reftex-table-of-contents-browser nil - "A multifile table of contents browser." - :group 'reftex) - -(defcustom reftex-include-file-commands '("include" "input") - "LaTeX commands which input another file. -The file name is expected after the command, either in braces or separated -by whitespace." - :group 'reftex-table-of-contents-browser - :set #'reftex-set-dirty - :type '(repeat string)) - -(defcustom reftex-max-section-depth 12 - "Maximum depth of section levels in document structure. -The default in standard LaTeX is 7, but there are packages for -which this needs to be larger." - :group 'reftex-table-of-contents-browser - :type 'integer) - -;; LaTeX section commands and level numbers -(defcustom reftex-section-levels - '( - ("part" . 0) - ("chapter" . 1) - ("section" . 2) - ("subsection" . 3) - ("subsubsection" . 4) - ("paragraph" . 5) - ("subparagraph" . 6) - ("addchap" . -1) ; KOMA-Script - ("addsec" . -2) ; KOMA-Script -;;; ("minisec" . -7) ; KOMA-Script - ) - "Commands and levels used for defining sections in the document. -This is an alist with each element like (COMMAND-NAME . LEVEL). -The car of each cons cell is the name of the section macro (without -the backslash). The cdr is a number indicating its level. A negative -level means the same level as the positive value, but the section will -never get a number. The cdr may also be a function which will be called -to after the section-re matched to determine the level. -This list is also used for promotion and demotion of sectioning commands. -If you are using a document class which has several sets of sectioning -commands, promotion only works correctly if this list is sorted first -by set, then within each set by level. The promotion commands always -select the nearest entry with the correct new level." - :group 'reftex-table-of-contents-browser - :set #'reftex-set-dirty - :type '(repeat - (cons (string :tag "sectioning macro" "") - (choice - (number :tag "level " 0) - (symbol :tag "function " my-level-func))))) - -(defcustom reftex-toc-max-level 100 - "The maximum level of toc entries which will be included in the TOC. -Section headings with a bigger level will be ignored. In RefTeX, chapters -are level 1, sections are level 2 etc. -This variable can be changed from within the *toc* buffer with \ -\\\\[reftex-toc-max-level]." - :group 'reftex-table-of-contents-browser - :type 'integer) - -(defcustom reftex-part-resets-chapter nil - "Non-nil means, \\part is like any other sectioning command. -This means, part numbers will be included in the numbering of chapters, and -chapter counters will be reset for each part. -When nil (the default), parts are special, do not reset the chapter counter -and also do not show up in chapter numbers." - :group 'reftex-table-of-contents-browser - :type 'boolean) - - -(defcustom reftex-auto-recenter-toc 'frame - "Non-nil means, turn automatic recentering of *TOC* window on. -When active, the *TOC* window will always show the section you -are currently working in. Recentering happens whenever Emacs is idle for -more than `reftex-idle-time' seconds. - -Value t means, turn on immediately when RefTeX gets started. Then, -recentering will work for any TOC window created during the session. - -Value `frame' (the default) means, turn automatic recentering on only while the -dedicated TOC frame does exist, and do the recentering only in that frame. So -when creating that frame (with `d' key in an ordinary TOC window), the -automatic recentering is turned on. When the frame gets destroyed, automatic -recentering is turned off again. - -This feature can be turned on and off from the menu -\(Ref->Options)." - :group 'reftex-table-of-contents-browser - :type '(choice - (const :tag "never" nil) - (const :tag "always" t) - (const :tag "in dedicated frame only" frame))) - -(defcustom reftex-toc-split-windows-horizontally nil - "Non-nil means, create TOC window by splitting window horizontally." - :group 'reftex-table-of-contents-browser - :type 'boolean) - -(defcustom reftex-toc-split-windows-fraction .3 - "Fraction of the width or height of the frame to be used for TOC window. -See also `reftex-toc-split-windows-horizontally'." - :group 'reftex-table-of-contents-browser - :type 'number) - -(defcustom reftex-toc-keep-other-windows t - "Non-nil means, split the selected window to display the *toc* buffer. -This helps to keep the window configuration, but makes the *toc* small. -When nil, all other windows except the selected one will be deleted, so -that the *toc* window fills half the frame." - :group 'reftex-table-of-contents-browser - :type 'boolean) - -(defcustom reftex-toc-include-file-boundaries nil - "Non-nil means, include file boundaries in *toc* buffer. -This flag can be toggled from within the *toc* buffer with the \\`F' key." - :group 'reftex-table-of-contents-browser - :type 'boolean) - -(defcustom reftex-toc-include-labels nil - "Non-nil means, include labels in *toc* buffer. -This flag can be toggled from within the *toc* buffer with the \\`l' key." - :group 'reftex-table-of-contents-browser - :type 'boolean) - -(defcustom reftex-toc-include-index-entries nil - "Non-nil means, include index entries in *toc* buffer. -This flag can be toggled from within the *toc* buffer with the \\`i' key." - :group 'reftex-table-of-contents-browser - :type 'boolean) - -(defcustom reftex-toc-confirm-promotion 2 - "Non-nil means, promotion/demotion commands first prompt for confirmation. -If nil, the command is executed immediately. If this is an integer N, -ask for confirmation only if N or more section commands are going to be -changed." - :group 'reftex-table-of-contents-browser - :type '(choice - (const :tag "Never" nil) - (const :tag "Always" t) - (number :tag "When more than N sections" :value 2))) - -(defcustom reftex-toc-include-context nil - "Non-nil means, include context with labels in the *toc* buffer. -Context will only be shown when labels are visible as well. -This flag can be toggled from within the *toc* buffer with the \\`c' key." - :group 'reftex-table-of-contents-browser - :type 'boolean) - -(defcustom reftex-toc-follow-mode nil - "Non-nil means, point in *toc* buffer will cause other window to follow. -The other window will show the corresponding part of the document. -This flag can be toggled from within the *toc* buffer with the \\`f' key." - :group 'reftex-table-of-contents-browser - :type 'boolean) - -(defcustom reftex-revisit-to-follow nil - "Non-nil means, `follow-mode' will revisit files if necessary. -If nil, `follow-mode' will be suspended for stuff in unvisited files." - :group 'reftex-table-of-contents-browser - :group 'reftex-referencing-labels - :type 'boolean) - -(defcustom reftex-toc-mode-hook nil - "Mode hook for `reftex-toc-mode'." - :group 'reftex-table-of-contents-browser - :type 'hook) - -;; Label Support Configuration - -(defgroup reftex-label-support nil - "Support for creation, insertion and referencing of labels in LaTeX." - :group 'reftex) - -(defgroup reftex-defining-label-environments nil - "Definition of environments and macros to do with label." - :group 'reftex-label-support) - -(defcustom reftex-default-label-alist-entries - '( amsmath endnotes fancybox floatfig longtable picinpar - rotating sidecap subfig wrapfig - listings minted ctable LaTeX) - "Default label alist specifications. LaTeX should always be the last entry. -The value of this variable is a list of symbols with associations in the -constant `reftex-label-alist-builtin'. Check that constant for a full list -of options." - :group 'reftex-defining-label-environments - :set #'reftex-set-dirty - :type `(set - :indent 4 - :inline t - :greedy t - ,@(mapcar - (lambda (x) - (list 'const :tag (concat (symbol-name (nth 0 x)) - ": " (nth 1 x)) - (nth 0 x))) - reftex-label-alist-builtin)) - :version "31.1") - -(defcustom reftex-label-alist nil - "Alist with information on environments for \\label-\\ref use. - -This doc string is easier to understand after reading the configuration -examples in the manual. Looking at the builtin defaults in the constant -`reftex-label-alist-builtin' may also be instructive. - -Set this variable to define additions and changes to the default. The only -things you MUST NOT change is that `?s' is the type indicator for section -labels, and SPC for the `any' label type. These are hard-coded at other -places in the code. - -The value of the variable must be a list of items. Each item is a list -itself and has the following structure: - - (ENV-OR-MACRO TYPE-KEY LABEL-PREFIX REFERENCE-FORMAT CONTEXT-METHOD - (MAGIC-WORD ... ) TOC-LEVEL) - -Each list entry describes either an environment carrying a counter for use -with \\label and \\ref, or a LaTeX macro defining a label as (or inside) -one of its arguments. The elements of each list entry are: - -ENV-OR-MACRO - Name of the environment (like \"table\") or macro (like \"\\\\myfig\"). - For macros, indicate the macro arguments for best results, as in - \"\\\\myfig[]{}{}{*}{}\". Use square brackets for optional arguments, - a star to mark the label argument, if any. The macro does not have to - have a label argument - you could also use \\label{..} inside one of - its arguments. - Special names: `section' for section labels, `any' to define a group - which contains all labels. - - This may also be a function to do local parsing and identify point to - be in a non-standard label environment. The function must take an - argument BOUND and limit backward searches to this value. It should - return either nil or the position where the special environment starts. - See the Info documentation for an example. - - Finally this may also be nil if the entry is only meant to change - some settings associated with the type indicator character (see below). - -TYPE-KEY - Type indicator character, like `?t', must be a printable ASCII character. - The type indicator is a single character which defines a label type. - Any label inside the environment or macro is assumed to belong to this - type. The same character may occur several times in this list, to cover - cases in which different environments carry the same label type (like - `equation' and `eqnarray'). - If the type indicator is nil and the macro has a label argument {*}, - the macro defines neutral labels just like \\label. In this case - the remainder of this entry is ignored. - -LABEL-PREFIX - Label prefix string, like \"tab:\". - The prefix is a short string used as the start of a label. It may be the - empty string. The prefix may contain the following `%' escapes: - %f Current file name with directory and extension stripped. - %F Current file name relative to directory of master file. - %m Master file name, directory and extension stripped. - %M Directory name (without path) where master file is located. - %u User login name, on systems which support this. - %S A section prefix derived with variable `reftex-section-prefixes'. - - Example: In a file `intro.tex', \"eq:%f:\" will become \"eq:intro:\"). - -REFERENCE-FORMAT - Format string for reference insertion in buffer. `%s' will be replaced - by the label. - When the format starts with `~', the `~' will only be inserted if - there is not already a whitespace before point. - -CONTEXT-METHOD - Indication on how to find the short context. - - If nil, use the text following the \\label{...} macro. - - If t, use - - the section heading for section labels. - - text following the \\begin{...} statement of environments. - (not a good choice for environments like eqnarray or enumerate, - where one has several labels in a single environment). - - text after the macro name (starting with the first arg) for macros. - - If an integer, use the nth argument of the macro. As a special case, - 1000 means to get text after the last macro argument. - - If a string, use as regexp to search *backward* from the label. Context - is then the text following the end of the match. E.g. setting this to - \"\\\\\\\\caption[[{]\" will use the caption in a figure or table - environment. - \"\\\\\\\\begin{eqnarray}\\\\|\\\\\\\\\\\\\\\\\" works for eqnarrays. - - If any of `caption', `item', `eqnarray-like', `alignat-like', this - symbol will internally be translated into an appropriate regexp - (see also the variable `reftex-default-context-regexps'). - - If a function, call this function with the name of the environment/macro - as argument. On call, point will be just after the \\label macro. The - function is expected to return a suitable context string. It should - throw an exception (error) when failing to find context. - As an example, here is a function returning the 10 chars following - the label macro as context: - - (defun my-context-function (env-or-mac) - (if (> (point-max) (+ 10 (point))) - (buffer-substring (point) (+ 10 (point))) - (error \"Buffer too small\"))) - - Label context is used in two ways by RefTeX: For display in the label - menu, and to derive a label string. If you want to use a different - method for each of these, specify them as a dotted pair. - E.g. `(nil . t)' uses the text after the label (nil) for display, and - text from the default position (t) to derive a label string. This is - actually used for section labels. - -MAGIC-WORDS - List of magic words which identify a reference to be of this type. - If the word before point is equal to one of these words when calling - `reftex-reference', the label list offered will be automatically - restricted to labels of the correct type. - If the first element of this wordlist is the symbol `regexp', the - strings are interpreted as regular expressions. RefTeX will add - a \"\\\\W\" to the beginning and other stuff to the end of the regexp. - -TOC-LEVEL - The integer level at which this environment should be added to the - table of contents. See also `reftex-section-levels'. A positive - value will number the entries mixed with the sectioning commands of - the same level. A negative value will make unnumbered entries. - Useful only for theorem-like environments, will be ignored for macros. - When omitted or nil, no TOC entries will be made. - -If the type indicator characters of two or more entries are the same, RefTeX -will use - - the first non-nil format and prefix - - the magic words of all involved entries. - -Any list entry may also be a symbol. If that has an association in -`reftex-label-alist-builtin', the cddr of that association is spliced into the -list. However, builtin defaults should normally be set with the variable -`reftex-default-label-alist-entries'." - :group 'reftex-defining-label-environments - :set #'reftex-set-dirty - :type - `(repeat - (choice :tag "Package or Detailed " - :value ("" ?a nil nil nil nil) - (list :tag "Detailed Entry" - :value ("" ?a nil nil nil nil) - (choice :tag "Environment or \\macro " - (const :tag "Ignore, just use typekey" nil) - (string "") - (symbol :tag "Special parser" my-parser)) - (choice :tag "Type specification " - (const :tag "unspecified, like in \\label" nil) - (character :tag "Char " ?a)) - (choice :tag "Label prefix string " - (const :tag "Default" nil) - (string :tag "String" "lab:")) - (choice :tag "Label reference format" - (const :tag "Default" nil) - (string :tag "String" "~\\ref{%s}")) - (choice :tag "Context method " - (const :tag "Default position" t) - (const :tag "After label" nil) - (number :tag "Macro arg nr" 1) - (regexp :tag "Regexp" "") - (const :tag "Caption in float" caption) - (const :tag "Item in list" item) - (const :tag "Eqnarray-like" eqnarray-like) - (const :tag "Alignat-like" alignat-like) - (symbol :tag "Function" my-func)) - (repeat :tag "Magic words" :extra-offset 2 (string)) - (option (choice :tag "Make TOC entry " - (const :tag "No entry" nil) - (integer :tag "Level" :value -3)))) - (choice - :tag "Package" - :value AMSTeX - ,@(mapcar - (lambda (x) - (list 'const :tag (concat (symbol-name (nth 0 x))) - (nth 0 x))) - reftex-label-alist-builtin))))) - -(defcustom reftex-section-prefixes '((0 . "part:") (1 . "cha:") (t . "sec:")) - "Prefixes for section labels. -When the label prefix given in an entry in `reftex-label-alist' contains `%S', -this list is used to determine the correct prefix string depending on the -current section level. -The list is an alist, with each entry of the form (KEY . PREFIX) -Possible keys are sectioning macro names like `chapter', section levels -\(as given in `reftex-section-levels'), and t for the default." - :group 'reftex-defining-label-environments - :type '(repeat - (cons :value (0 . "") - (choice - (string :tag "macro name") - (integer :tag "section level") - (const :tag "default" t)) - (string :tag "Prefix")))) - -(defcustom reftex-default-context-regexps - '((caption . "\\\\\\(rot\\|bi\\)?\\(sub\\)?caption\\(box\\)?\\*?[[{]") - (item . "\\\\item\\(\\[[^]]*\\]\\)?") - (eqnarray-like . "\\\\begin{%s}\\|\\\\\\\\") - (alignat-like . "\\\\begin{%s}{[0-9]*}\\|\\\\\\\\")) -"Alist with default regular expressions for finding context. -The form (format regexp (regexp-quote environment)) is used to calculate -the final regular expression - so %s will be replaced with the environment -or macro." - :group 'reftex-defining-label-environments - :type '(repeat (cons (symbol) (regexp)))) - -(defcustom reftex-trust-label-prefix nil - "Non-nil means, trust the label prefix when determining label type. -It is customary to use special label prefixes to distinguish different label -types. The label prefixes have no syntactic meaning in LaTeX (unless -special packages like fancyref are being used). RefTeX can and by -default does parse around each label to detect the correct label type, -but this process can be slow when a document contains thousands of -labels. If you use label prefixes consistently, you may speed up -document parsing by setting this variable to a non-nil value. RefTeX -will then compare the label prefix with the prefixes found in -`reftex-label-alist' and derive the correct label type in this way. -Possible values for this option are: - -t This means to trust any label prefixes found. -regexp If a regexp, only prefixes matched by the regexp are trusted. -list List of accepted prefixes, as strings. The colon is part of - the prefix, e.g. (\"fn:\" \"eqn:\" \"item:\"). -nil Never trust a label prefix. - -The only disadvantage of using this feature is that the label context -displayed in the label selection buffer along with each label is -simply some text after the label definition. This is no problem if you -place labels keeping this in mind (e.g. *before* the equation, *at -the beginning* of a fig/tab caption ...). Anyway, it is probably best -to use the regexp or the list value types to fine-tune this feature. -For example, if your document contains thousands of footnotes with -labels fn:xxx, you may want to set this variable to the value \"^fn:$\" or -\(\"fn:\"). Then RefTeX will still do extensive parsing for any -non-footnote labels." - :group 'reftex-defining-label-environments - :type '(choice - (const :tag "Always" t) - (const :tag "Never" nil) - (regexp) - (repeat :tag "List" - (string :tag "prefix (with colon)")))) - -(defcustom reftex-special-environment-functions nil - "List of functions to be called when trying to figure out current environment. -These are special functions to detect \"environments\" which do not -start with \\begin and end with \\end. Some LaTeX packages seem to -use such non-standard ways to set up environment-like constructs. The -purpose of each function in this list is to detect if point is -currently inside such a special \"environment\". If the environment -carries a label, you must also set up an entry for it in -`reftex-label-alist'. - -The function should check if point is currently in the special -environment it was written to detect. If so, the function must return -a cons cell (NAME . POSITION). NAME is the name of the environment -detected and POSITION is the buffer position where the environment -starts. The function must return nil on failure to detect the -environment. - -The function must take an argument BOUND. If non-nil, BOUND is a -boundary for backwards searches which should be observed. - -Here is an example. The LaTeX package linguex.sty defines list macros -`\\ex.', `\\a.', etc for lists which are terminated by `\\z.' or an -empty line. - - \\ex. \\label{ex:12} Some text in an exotic language ... - \\a. \\label{ex:13} more stuff - \\b. \\label{ex:14} still more stuff - - ... more text after the empty line terminating all lists - -And here is the setup for RefTeX: - -1. Define a dummy environment for this in `reftex-label-alist'. Dummy means, - make up an environment name even though it is not used with \\begin and - \\end. Here we use \"linguex\" as this name. - - (setq reftex-label-alist - \\='((\"linguex\" ?x \"ex:\" \"~\\\\ref{%s}\" nil (\"Example\" \"Ex.\")))) - -2. Write a function to detect the list macros and the determinators as well. - - (defun my-detect-linguex-list (bound) - (let ((pos (point)) p1) - (save-excursion - ;; Search for any of the linguex item macros at the beginning of a line - (if (re-search-backward - (concat \"^[ \\t]*\\\\(\\\\\\\\\\\\(ex\\\\|a\\\\|\" - \"b\\\\|c\\\\|d\\\\|e\\\\|f\\\\)g?\\\\.\\\\)\") - bound t) - (progn - (setq p1 (match-beginning 1)) - ;; Make sure no empty line or \\z. is between us and item macro - (if (re-search-forward \"\\n[ \\t]*\\n\\\\|\\\\\\\\z\\\\.\" pos t) - ;; Return nil because list was already closed - nil - ;; OK, we got it - (cons \"linguex\" p1))) - ;; Return nil for not found - nil)))) - -3. Tell RefTeX to use this function - - (setq reftex-special-environment-functions \\='(my-detect-linguex-list))" - :group 'reftex-defining-label-environments - :type 'hook) - -;; Label insertion - -(defgroup reftex-making-and-inserting-labels nil - "Options on how to create new labels." - :group 'reftex-label-support) - -(defcustom reftex-insert-label-flags '("s" "sft") - "Flags governing label insertion. First flag DERIVE, second flag PROMPT. - -If DERIVE is t, RefTeX will try to derive a sensible label from context. -A section label for example will be derived from the section heading. -The conversion of the context to a valid label is governed by the -specifications given in `reftex-derive-label-parameters'. -If RefTeX fails to derive a label, it will prompt the user. -If DERIVE is nil, the label generated will consist of the prefix and a -unique number, like `eq:23'. - -If PROMPT is t, the user will be prompted for a label string. The prompt will -already contain the prefix, and (if DERIVE is t) a default label derived from -context. When PROMPT is nil, the default label will be inserted without -query. - -So the combination of DERIVE and PROMPT controls label insertion. Here is a -table describing all four possibilities: - -DERIVE PROMPT ACTION -------------------------------------------------------------------------- - nil nil Insert simple label, like eq:22 or sec:13. No query. - nil t Prompt for label. - t nil Derive a label from context and insert without query. - t t Derive a label from context and prompt for confirmation. - -Each flag may be set to t, nil, or a string of label type letters -indicating the label types for which it should be true. The strings work -like character classes. -Thus, the combination may be set differently for each label type. The -default settings \"s\" and \"sft\" mean: Derive section labels from headings -\(with confirmation). Prompt for figure and table labels. Use simple labels -without confirmation for everything else. -The available label types are: s (section), f (figure), t (table), i (item), -e (equation), n (footnote), N (endnote), plus any definitions in -`reftex-label-alist'." - :group 'reftex-making-and-inserting-labels - :type '(list (choice :tag "Derive label from context" - (const :tag "always" t) - (const :tag "never" nil) - (string :tag "selected label types" "")) - (choice :tag "Prompt for label string " - :entry-format " %b %v" - (const :tag "always" t) - (const :tag "never" nil) - (string :tag "selected label types" "")))) - -(defcustom reftex-string-to-label-function 'reftex-string-to-label - "Function to turn an arbitrary string into a valid label. -RefTeX's default function uses the variable `reftex-derive-label-parameters'." - :group 'reftex-making-and-inserting-labels - :type 'symbol) - -(defcustom reftex-translate-to-ascii-function 'reftex-latin1-to-ascii - "Filter function to convert a string to ASCII. -The function is used to process a context string before it is -used to derive a label from it. The intended application is to -convert ISO or Mule characters into something valid in labels. -The default function removes the accents from Latin-1 characters. -X-Symbol (>=2.6) sets this variable to the much more general -`x-symbol-translate-to-ascii'." - :group 'reftex-making-and-inserting-labels - :type 'symbol) - -(defcustom reftex-derive-label-parameters '(3 20 t 1 "-" - ("the" "on" "in" "off" "a" "for" "by" "of" "and" "is" "to") t) - "Parameters for converting a string into a label. -This variable is a list of the following items. - -NWORDS Number of words to use. -MAXCHAR Maximum number of characters in a label string. -INVALID nil: Throw away any words containing characters invalid in labels. - t: Throw away only the invalid characters, not the whole word. -ABBREV nil: Never abbreviate words. - t: Always abbreviate words (see `reftex-abbrev-parameters'). - not t and not nil: Abbreviate words if necessary to shorten - label string below MAXCHAR. -SEPARATOR String separating different words in the label. -IGNOREWORDS List of words which should not be part of labels. -DOWNCASE t: Downcase words before using them." - :group 'reftex-making-and-inserting-labels - :type '(list (integer :tag "Number of words " 3) - (integer :tag "Maximum label length " 20) - (choice :tag "Invalid characters in words" - (const :tag "throw away entire word" nil) - (const :tag "throw away single chars" t)) - (choice :tag "Abbreviate words " - (const :tag "never" nil) - (const :tag "always" t) - (const :tag "when label is too long" 1)) - (string :tag "Separator between words " "-") - (repeat :tag "Ignore words" - :entry-format " %i %d %v" - (string :tag "")) - (option (boolean :tag "Downcase words ")))) - -(defcustom reftex-label-regexps - `(;; Normal \\label{foo} labels - "\\\\label{\\(?1:[^}]*\\)}" - ;; keyvals [..., label = {foo}, ...] forms used by ctable, - ;; listings, breqn, ... - ,(concat - ;; Make sure we search only for optional arguments of - ;; environments/macros and don't match any other [. ctable - ;; provides a macro called \ctable, beamer/breqn/listings have - ;; environments. Start with a backslash and a group for names - "\\\\\\(?:" - ;; begin, optional spaces and opening brace - "begin[[:space:]]*{" - ;; Build a regexp for env names - (regexp-opt '("lstlisting" "dmath" "dseries" "dgroup" - "darray" "frame")) - ;; closing brace, optional spaces - "}[[:space:]]*" - ;; Now for macros - "\\|" - ;; Build a regexp for macro names; currently only \ctable - (regexp-opt '("ctable")) - ;; Close the group for names - "\\)" - ;; Match the opening [ and the following chars - "\\[[^][]*" - ;; Allow nested levels of chars enclosed in braces - "\\(?:{[^}{]*" - "\\(?:{[^}{]*" - "\\(?:{[^}{]*}[^}{]*\\)*" - "}[^}{]*\\)*" - "}[^][]*\\)*" - ;; Match the label key - "\\ \\cite{Jones} - \\cite[][Chapter 1]{Jones} -> \\cite[Chapter 1]{Jones} - \\cite[see][]{Jones} -> \\cite[see][]{Jones} - \\cite[see][Chapter 1]{Jones} -> \\cite[see][Chapter 1]{Jones} -It is possible that other packages have other conventions about which -optional argument is interpreted how - that is why this cleaning up -can be turned off." - :group 'reftex-citation-support - :type 'boolean) - -(defcustom reftex-comment-citations nil - "Non-nil means add a comment for each citation describing the full entry. -The comment is formatted according to `reftex-cite-comment-format'." - :group 'reftex-citation-support - :type 'boolean) - -(defcustom reftex-cite-comment-format - "%% %2a %y, %j %v, %P, %b, %e, %u, %s %<\n" - "Citation format used for commented citations. Must NOT contain %l. -See the variable `reftex-cite-format' for possible percent escapes." - :group 'reftex-citation-support - :type 'string) - -(defcustom reftex-cite-view-format "%2a %y, %T, %B, %j %v:%P, %s %<" - "Citation format used to display citation info in the message area. -Must NOT contain %l. See the variable `reftex-cite-format' for -possible percent escapes." - :group 'reftex-citation-support - :group 'reftex-viewing-cross-references - :type 'string) - -(defcustom reftex-cite-punctuation '(", " " \\& " " {\\it et al.}") - "Punctuation for formatting of name lists in citations. -This is a list of 3 strings. -1. Normal names separator, like \", \" in Jones, Brown and Miller -2. Final names separator, like \" and \" in Jones, Brown and Miller -3. The \"et al\" string, like \" {\\it et al.}\" in Jones {\\it et al.}" - :group 'reftex-citation-support - :type '(list - (string :tag "Separator for names ") - (string :tag "Separator for last name in list") - (string :tag "string used as et al. "))) - -(defcustom reftex-format-cite-function nil - "Function which produces the string to insert as a citation. -Normally should be nil, because the format to insert a reference can -already be specified in `reftex-cite-format'. -The function will be called with two arguments, the CITATION KEY and the -DEFAULT FORMAT, which is taken from `reftex-cite-format'. The function -should return the string to insert into the buffer." - :group 'reftex-citation-support - :type '(choice (const nil) function)) - -(defcustom reftex-select-bib-mode-hook nil - "Mode hook for `reftex-select-bib-mode'." - :group 'reftex-citation-support - :type 'hook) - -(defcustom reftex-cite-key-separator "," - "String to be used for separating several keys in a \\cite macro." - :group 'reftex-citation-support - :version "24.3" - :type 'string) - -(defcustom reftex-create-bibtex-header nil - "Header to insert in BibTeX files generated by RefTeX." - :group 'reftex-citation-support - :version "24.3" - :type '(choice (const :tag "No header" nil) string)) - -(defcustom reftex-create-bibtex-footer nil - "Footer to insert in BibTeX files generated by RefTeX." - :group 'reftex-citation-support - :version "24.3" - :type '(choice (const :tag "No footer" nil) string)) - -;; Index Support Configuration - -(defgroup reftex-index-support nil - "Support for viewing and editing the index." - :group 'reftex) - -(defcustom reftex-support-index t - "Non-nil means, index entries are parsed as well. -Index support is resource intensive and the internal structure holding the -parsed information can become quite big. Therefore it can be turned off. -When this is nil and you execute a command which requires index support, -you will be asked for confirmation to turn it on and rescan the document." - :group 'reftex-index-support - :type 'boolean) - -(defcustom reftex-index-special-chars '("!" "|" "@" "\"" "\\") - "Special characters in index entries. The value is a list of five strings. -These correspond to the makeindex keywords LEVEL ENCAP ACTUAL QUOTE ESCAPE." - :group 'reftex-index-support - :type '(list - (string :tag "LEVEL separator") - (string :tag "ENCAP char ") - (string :tag "ACTUAL char ") - (string :tag "QUOTE char ") - (string :tag "ESCAPE char "))) - -(defcustom reftex-index-macros nil - "Macros which define index entries. - -The structure is - -\(MACRO INDEX-TAG KEY PREFIX EXCLUDE REPEAT) - -MACRO is the macro. Arguments should be denoted by empty braces like -\\index[]{*}. Use square brackets to denote optional arguments. The star -marks where the index key is. - -INDEX-TAG is a short name of the index. \"idx\" and \"glo\" are -reserved for the default index and the glossary. Other indices can be -defined as well. If this is an integer, the Nth argument of the macro -holds the index tag. - -KEY is a character which is used to identify the macro for input with -\\[reftex-index]. ?i, ?I, and ?g are reserved for default index and glossary. - -PREFIX can be a prefix which is added to the KEY part of the index entry. -If you have a macro \\newcommand{\\molec}[1]{#1\\index{Molecules!#1}}, this -prefix should be \"Molecules!\". See the manual for details. - -EXCLUDE can be a function. If this function exists and returns a non-nil -value, the index entry at point is ignored. This was implemented to support -the (deprecated) `^' and `_' shortcuts in the LaTeX2e `index' package. - -REPEAT, if non-nil, means the index macro does not typeset the entry in -the text, so that the text has to be repeated outside the index macro. -Needed for `reftex-index-selection-or-word' and for indexing from the -phrase buffer. - -The final entry may also be a symbol if this entry has an association -in the variable `reftex-index-macros-builtin' to specify the main -indexing package you are using. Valid values are currently -default The LaTeX default - unnecessary to specify this one -multind The multind.sty package -index The index.sty package -index-shortcut The index.sty packages with the ^ and _ shortcuts. - Should not be used - only for old documents. -Note that AUCTeX sets these things internally for RefTeX as well, so -with a sufficiently new version of AUCTeX, you should not set the -package here." - :group 'reftex-index-support - :set #'reftex-set-dirty - :type `(list - (repeat - :inline t - (list :value ("" "idx" ?a "" nil) - (string :tag "Macro with args") - (choice :tag "Index Tag " - (string) - (integer :tag "Macro arg Nr" :value 1)) - (character :tag "Access Key ") - (string :tag "Key Prefix ") - (symbol :tag "Exclusion hook ") - (boolean :tag "Repeat Outside "))) - (option - :tag "Package:" - (choice :tag "Package" - :value index - ,@(mapcar - (lambda (x) - (list 'const :tag (concat (symbol-name (nth 0 x)) - ": " (nth 1 x)) - (nth 0 x))) - reftex-index-macros-builtin))))) - -(defcustom reftex-index-default-macro '(?i "idx") - "The default index macro for \\[reftex-index-selection-or-word]. -This is a list with (MACRO-KEY DEFAULT-TAG). - -MACRO-KEY: Character identifying an index macro - see `reftex-index-macros'. -DEFAULT-TAG: This is the tag to be used if the macro requires a TAG argument. - When this is nil and a TAG is needed, RefTeX will ask for it. - When this is the empty string and the TAG argument of the index - macro is optional, the TAG argument will be omitted." - :group 'reftex-index-support - :type '(list - (character :tag "Character identifying default macro") - (choice :tag "Default index tag " - (const nil) - (string)))) - -(defcustom reftex-index-default-tag "idx" - "Default index tag. -When working with multiple indexes, RefTeX queries for an index tag when -creating index entries or displaying a specific index. This variable controls -the default offered for these queries. The default can be selected with RET -during selection or completion. Valid values of this variable are: - -nil Do not provide a default index -\"tag\" The default index tag given as a string, e.g. \"idx\". -last The last used index tag will be offered as default." - :group 'reftex-index-support - :type '(choice - (const :tag "no default" nil) - (const :tag "last used " last) - (string :tag "index tag " "idx"))) - -(defcustom reftex-index-math-format "$%s$" - "Format of index entries when copied from inside math mode. -When `reftex-index-selection-or-word' is executed inside TeX math mode, -the index key copied from the buffer is processed with this format string -through the `format' function. This can be used to add the math delimiters -\(e.g. `$') to the string. -Requires the `texmathp.el' library which is part of AUCTeX." - :group 'reftex-index-support - :type 'string) - -(defcustom reftex-index-phrase-file-extension ".rip" - "File extension for the index phrase file. -This extension will be added to the base name of the master file." - :group 'reftex-index-support - :type 'string) - -(defcustom reftex-index-phrases-logical-and-regexp " *&& *" - "Regexp matching the `and' operator for index arguments in phrases file. -When several index arguments in a phrase line are separated by this -operator, each part will generate an index macro. So each match of -the search phrase will produce *several* different index entries. - -Note: make sure this does no match things which are not separators. -This logical `and' has higher priority than the logical `or' specified in -`reftex-index-phrases-logical-or-regexp'." - :group 'reftex-index-support - :type 'regexp) - -(defcustom reftex-index-phrases-logical-or-regexp " *|| *" - "Regexp matching the `or' operator for index arguments in phrases file. -When several index arguments in a phrase line are separated by this -operator, the user will be asked to select one of them at each match -of the search phrase. The first index arg will be the default - a -number key 1-9 must be pressed to switch to another. - -Note: make sure this does no match things which are not separators. -The logical `and' specified in `reftex-index-phrases-logical-or-regexp' -has higher priority than this logical `or'." - :group 'reftex-index-support - :type 'regexp) - -(defcustom reftex-index-phrases-search-whole-words t - "Non-nil means phrases search will look for whole words, not subwords. -This works by requiring word boundaries at the beginning and end of -the search string. When the search phrase already has a non-word-char -at one of these points, no word boundary is required there." - :group 'reftex-index-support - :type 'boolean) - -(defcustom reftex-index-phrases-case-fold-search t - "Non-nil means, searching for index phrases will ignore case." - :group 'reftex-index-support - :type 'boolean) - -(defcustom reftex-index-verify-function nil - "A function which is called at each match during global indexing. -If the function returns nil, the current match is skipped." - :group 'reftex-index-support - :type '(choice - (const :tag "No verification" nil) - (function))) - -(defcustom reftex-index-phrases-skip-indexed-matches nil - "Non-nil means, skip matches which appear to be indexed already. -When doing global indexing from the phrases buffer, searches for some -phrases may match at places where that phrase was already indexed. In -particular when indexing an already processed document again, this -will even be the norm. When this variable is non-nil, RefTeX checks if -the match is inside an index macro argument, or if an index macro is directly -before or after the phrase. If that is the case, that match will -be ignored." - :group 'reftex-index-support - :type 'boolean) - -(defcustom reftex-index-phrases-wrap-long-lines nil - "Non-nil means, when indexing from the phrases buffer, wrap lines. -Inserting indexing commands in a line makes the line longer - often -so long that it does not fit onto the screen. When this variable is -non-nil, newlines will be added as necessary before and/or after the -indexing command to keep lines short. However, the matched text -phrase and its index command will always end up on a single line." - :group 'reftex-index-support - :type 'boolean) - -(defcustom reftex-index-phrases-sort-prefers-entry nil - "Non-nil means when sorting phrase lines, the explicit index entry is used. -Phrase lines in the phrases buffer contain a search phrase, and -sorting is normally based on these. Some phrase lines also have -an explicit index argument specified. When this variable is non-nil, -the index argument will be used for sorting." - :group 'reftex-index-support - :type 'boolean) - -(defcustom reftex-index-phrases-sort-in-blocks t - "Non-nil means, empty and comment lines separate phrase buffer into blocks. -Sorting will then preserve blocks, so that lines are re-arranged only -within blocks." - :group 'reftex-index-support - :type 'boolean) - -(defcustom reftex-index-section-letters "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "The letters which denote sections in the index. -Usually these are all capital letters. Don't use any downcase letters. -Order is not significant, the index will be sorted by whatever the sort -function thinks is correct. -In addition to these letters, RefTeX will create a group `!' which -contains all entries sorted below the lowest specified letter. -In the index buffer, pressing any of these capital letters or `!' will jump -to that section." - :group 'reftex-index-support - :type '(string :tag "Capital letters")) - -(defcustom reftex-index-include-context nil - "Non-nil means, display the index definition context in the index buffer. -This flag may also be toggled from the index buffer with the \\`c' key." - :group 'reftex-index-support - :type 'boolean) - -(defcustom reftex-index-follow-mode nil - "Non-nil means, point in *Index* buffer will cause other window to follow. -The other window will show the corresponding part of the document. -This flag can be toggled from within the *Index* buffer with the \\`f' key." - :group 'reftex-table-of-contents-browser - :type 'boolean) - -;; Viewing Cross References - -(defgroup reftex-viewing-cross-references nil - "Displaying cross references and citations." - :group 'reftex) - -(defcustom reftex-view-crossref-extra nil - "Macros which can be used for the display of cross references. -This is used when `reftex-view-crossref' is called with point in an -argument of a macro. Note that crossref viewing for citations, -references (both ways) and index entries is hard-coded. This variable -is only to configure additional structures for which cross-reference -viewing can be useful. Each entry has the structure - -\(MACRO-RE SEARCH-RE HIGHLIGHT). - -MACRO-RE is matched against the macro. SEARCH-RE is the regexp used -to search for cross references. `%s' in this regexp is replaced with -the macro argument at point. HIGHLIGHT is an integer indicating -which subgroup of the match should be highlighted." - :group 'reftex-viewing-cross-references - :type '(repeat (group (regexp :tag "Macro Regexp ") - (string :tag "Search Regexp ") - (integer :tag "Highlight Group")))) - -(defcustom reftex-auto-view-crossref t - "Non-nil means, initially turn automatic viewing of crossref info on. -Automatic viewing of crossref info normally uses the echo area. -Whenever point is idle for more than `reftex-idle-time' seconds on the -argument of a \\ref or \\cite macro, and no other message is being -displayed, the echo area will display information about that cross -reference. You can also set the variable to the symbol `window'. In -this case a small temporary window is used for the display. -This feature can be turned on and off from the menu -\(Ref->Options)." - :group 'reftex-viewing-cross-references - :type '(choice (const :tag "off" nil) - (const :tag "in Echo Area" t) - (const :tag "in Other Window" window))) - -(defcustom reftex-idle-time 1.2 - "Time (secs) Emacs has to be idle before automatic crossref display is done. -Applies also to toc recentering." - :group 'reftex-viewing-cross-references - :type 'number) - -(defcustom reftex-revisit-to-echo nil - "Non-nil means, automatic citation display will revisit files if necessary. -When nil, citation display in echo area will only be active for cached -entries and for BibTeX database files with live associated buffers." - :group 'reftex-viewing-cross-references - :type 'boolean) - -(defcustom reftex-cache-cite-echo t - "Non-nil means, echoed information for cite macros is cached. -The information displayed in the echo area for cite macros is -cached and even saved along with the parsing information. The -cache survives document scans. In order to clear it, use -\\[reftex-reset-mode]." - :group 'reftex-viewing-cross-references - :type 'boolean) - -(defcustom reftex-display-copied-context-hook nil - "Normal hook which is run before context is displayed anywhere. -Designed for X-Symbol, but may have other uses as well." - :group 'reftex-viewing-cross-references - :group 'reftex-referencing-labels - :type 'hook) - -;; Finding Files -------------------------------------------------------- - -(defgroup reftex-finding-files nil - "Finding files on search paths." - :group 'reftex) - -(defcustom reftex-texpath-environment-variables '("TEXINPUTS") - "List of specifications how to retrieve the search path for TeX files. -Several entries are possible. -- If an element is the name of an environment variable, its content is used. -- If an element starts with an exclamation mark, it is used as a command - to retrieve the path. A typical command with the kpathsearch library would - be `!kpsewhich -show-path=.tex'. -- Otherwise the element itself is interpreted as a path. -Multiple directories can be separated by the system dependent `path-separator'. -Directories ending in `//' or `!!' will be expanded recursively. -See also `reftex-use-external-file-finders'." - :group 'reftex-finding-files - :set #'reftex-set-dirty - :type '(repeat (string :tag "Specification"))) - -(defcustom reftex-bibpath-environment-variables '("BIBINPUTS" "TEXBIB") - "List of specifications how to retrieve search path for .bib database files. -Several entries are possible. -- If an element is the name of an environment variable, its content is used. -- If an element starts with an exclamation mark, it is used as a command - to retrieve the path. A typical command with the kpathsearch library would - be `!kpsewhich -show-path=.bib'. -- Otherwise the element itself is interpreted as a path. -Multiple directories can be separated by the system dependent `path-separator'. -Directories ending in `//' or `!!' will be expanded recursively. -See also `reftex-use-external-file-finders'." - :group 'reftex-citation-support - :group 'reftex-finding-files - :set #'reftex-set-dirty - :type '(repeat (string :tag "Specification"))) - -(defcustom reftex-file-extensions '(("tex" . (".tex" ".ltx")) - ("bib" . (".bib"))) - "Association list with file extensions for different file types. -This is a list of items, each item is like: (TYPE . (DEF-EXT OTHER-EXT ...)) - -TYPE: File type like \"bib\" or \"tex\". -DEF-EXT: The default extension for that file type, like \".tex\" or \".bib\". -OTHER-EXT: Any number of other valid extensions for this file type. - -When a files is searched and it does not have any of the legal extensions, -we try the default extension first, and then the naked file name. - -If you are using AUCTeX, you also need to add new extensions to -TeX-file-extensions." - :group 'reftex-finding-files - :type '(repeat (cons (string :tag "File type") - (repeat (string :tag "Extension"))))) - -(defcustom reftex-try-all-extensions nil - "Non-nil means, try all extensions listed in `reftex-file-extensions'. -When searching for a file, LaTeX uses only the default extension. However, -if you are working with a noweb system that produces the .tex files from -some other file, and you want RefTeX to scan the web file instead of the -tex file, you need to set this option. You also need to make the noweb -extension the default extension, i.e. the first in the list in -`reftex-file-extensions'. -Note that if you are using external file finders, this option has no effect." - :group 'reftex-finding-files - :type 'boolean) - -(defcustom reftex-search-unrecursed-path-first t - "Non-nil means, search all specified directories before trying recursion. -Thus, in a path \".//:/tex/\", search first \"./\", then \"/tex/\" and then -all subdirectories of \"./\". If this option is nil, the subdirectories of -\"./\" are searched before \"/tex/\". This is mainly for speed - most of the -time the recursive path is for the system files and not for the user files. -Set this to nil if the default makes RefTeX finding files with equal names -in wrong sequence." - :group 'reftex-finding-files - :type 'boolean) - -(defcustom reftex-use-external-file-finders nil - "Non-nil means, use external programs to find files. -Normally, RefTeX searches the paths given in the environment variables -TEXINPUTS and BIBINPUTS to find TeX files and BibTeX database files. -With this option turned on, it calls an external program specified in the -option `reftex-external-file-finders' instead. As a side effect, -the variables `reftex-texpath-environment-variables' and -`reftex-bibpath-environment-variables' will be ignored." - :group 'reftex-finding-files - :type 'boolean) - -(defcustom reftex-external-file-finders '(("tex" . "kpsewhich -format=.tex %f") - ("bib" . "kpsewhich -format=.bib %f")) - "Association list with external programs to call for finding files. -Each entry is a cons cell (TYPE . PROGRAM). -TYPE is either \"tex\" or \"bib\". PROGRAM is the external program to use with -any arguments. %f will be replaced by the name of the file to be found. -Note that these commands will be executed directly, not via a shell. -Only relevant when `reftex-use-external-file-finders' is non-nil." - :group 'reftex-finding-files - :type '(repeat (cons (string :tag "File type") - (string :tag "Program ")))) - -;; Tuning the parser ---------------------------------------------------- - -(defgroup reftex-optimizations-for-large-documents nil - "Configuration of parser speed and memory usage." - :group 'reftex) - -(defcustom reftex-keep-temporary-buffers 1 - "Non-nil means, keep buffers created for parsing and lookup. -RefTeX sometimes needs to visit files related to the current document. -We distinguish files visited for -PARSING: Parts of a multifile document loaded when (re)-parsing the document. -LOOKUP: BibTeX database files and TeX files loaded to find a reference, - to display label context, etc. -The created buffers can be kept for later use, or be thrown away immediately -after use, depending on the value of this variable: - -nil Throw away as much as possible. -t Keep everything. -1 Throw away buffers created for parsing, but keep the ones created - for lookup. - -If a buffer is to be kept, the file is visited normally (which is potentially -slow but will happen only once). -If a buffer is to be thrown away, the initialization of the buffer depends -upon the variable `reftex-initialize-temporary-buffers'." - :group 'reftex-optimizations-for-large-documents - :type '(choice - (const :tag "Throw away everything" nil) - (const :tag "Keep everything" t) - (const :tag "Keep lookup buffers only" 1))) - -(defcustom reftex-initialize-temporary-buffers nil - "Non-nil means do initializations even when visiting file temporarily. -When nil, RefTeX may turn off `find-file' hooks and other stuff to briefly -visit a file. -When t, the full default initializations are done (find-file-hook etc.). -Instead of t or nil, this variable may also be a list of hook functions to -do a minimal initialization." - :group 'reftex-optimizations-for-large-documents - :type '(choice - (const :tag "Read files literally" nil) - (const :tag "Fully initialize buffers" t) - (repeat :tag "Hook functions" :value (nil) - (function-item)))) - -(defcustom reftex-no-include-regexps '("\\.pstex_t\\'") - "List of regular expressions to exclude certain input files from parsing. -If the name of a file included via \\include or \\input is matched by any -of the regular expressions in this list, that file is not parsed by RefTeX." - :group 'reftex-optimizations-for-large-documents - :type '(repeat (regexp))) - -(defcustom reftex-enable-partial-scans nil - "Non-nil means, re-parse only 1 file when asked to re-parse. -Re-parsing is normally requested with a \\[universal-argument] prefix to many RefTeX commands, -or with the \\`r' key in menus. When this option is t in a multifile document, -we will only parse the current buffer, or the file associated with the label -or section heading near point in a menu. Requesting re-parsing of an entire -multifile document then requires a \\[universal-argument] \ -\\[universal-argument] prefix or the capital \\`R' key -in menus." - :group 'reftex-optimizations-for-large-documents - :type 'boolean) - -(defcustom reftex-allow-automatic-rescan t - "Non-nil means, RefTeX may rescan the document when this seems necessary. -Currently this applies only to rescanning after label insertion, when -the new label cannot be inserted correctly into the internal label -list." - :group 'reftex-optimizations-for-large-documents - :type 'boolean) - -(defcustom reftex-save-parse-info nil - "Non-nil means, save information gathered with parsing in a file. -The file MASTER.rel in the same directory as MASTER.tex is used to save the -information. When this variable is t, -- accessing the parsing information for the first time in an editing session - will read that file (if available) instead of parsing the document. -- exiting Emacs or killing a buffer in `reftex-mode' will cause a new version - of the file to be written." - :group 'reftex-optimizations-for-large-documents - :type 'boolean) - -(defcustom reftex-parse-file-extension ".rel" - "File extension for the file in which parser information is stored. -This extension is added to the base name of the master file." - :group 'reftex-optimizations-for-large-documents - :type 'string) - -(defcustom reftex-use-multiple-selection-buffers nil - "Non-nil means use a separate selection buffer for each label type. -These buffers are kept from one selection to the next and need not to be -created for each use - so the menu generally comes up faster. The -selection buffers will be erased (and therefore updated) automatically -when new labels in its category are added. See the variable -`reftex-auto-update-selection-buffers'." - :group 'reftex-optimizations-for-large-documents - :group 'reftex-referencing-labels - :type 'boolean) - -(defcustom reftex-auto-update-selection-buffers t - "Non-nil means, selection buffers will be updated automatically. -When a new label is defined with `reftex-label', all selection buffers -associated with that label category are emptied, in order to force an -update upon next use. When nil, the buffers are left alone and have to be -updated by hand, with the \\`g' key from the label selection process. -The value of this variable will only have any effect when -`reftex-use-multiple-selection-buffers' is non-nil." - :group 'reftex-optimizations-for-large-documents - :group 'reftex-referencing-labels - :type 'boolean) - -;; Fontification and Faces ---------------------------------------------- - -(defgroup reftex-fontification-configurations nil - "Options concerning the faces used in RefTeX." - :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces) - :group 'reftex) - -(defcustom reftex-use-fonts t - "Non-nil means, use fonts in *toc* and selection buffers. -When changing this option, a rescan may be necessary to activate the change." - :group 'reftex-fontification-configurations - :type 'boolean) - -(defcustom reftex-refontify-context 1 - "Non-nil means, re-fontify the context in the label menu with font-lock. -This slightly slows down the creation of the label menu. It is only necessary -when you definitely want the context fontified. - -This option may have 3 different values: -nil Never refontify. -t Always refontify. -1 Refontify when absolutely necessary, e.g. when old versions of X-Symbol. -The option is ignored when `reftex-use-fonts' is nil." - :group 'reftex-fontification-configurations - :group 'reftex-referencing-labels - :type '(choice - (const :tag "Never" nil) - (const :tag "Always" t) - (const :tag "When necessary" 1))) - -(defcustom reftex-highlight-selection 'cursor - "Non-nil mean, highlight selected text in selection and *toc* buffers. -Normally, the text near the cursor is the selected text, and it is -highlighted. This is the entry most keys in the selection and *toc* -buffers act on. However, if you mainly use the mouse to select an -item, you may find it nice to have mouse-triggered highlighting -instead or as well. The variable may have one of these values: - - nil No highlighting. - cursor Highlighting is cursor driven. - mouse Highlighting is mouse driven. - both Both cursor and mouse trigger highlighting. - -Changing this variable requires rebuilding the selection and *toc* buffers -to become effective (keys \\`g' or \\`r')." - :group 'reftex-fontification-configurations - :type '(choice - (const :tag "Never" nil) - (const :tag "Cursor driven" cursor) - (const :tag "Mouse driven" mouse) - (const :tag "Mouse and Cursor driven." both))) - -(defcustom reftex-cursor-selected-face 'highlight - "Face name to highlight cursor selected item in toc and selection buffers. -See also the variable `reftex-highlight-selection'." - :group 'reftex-fontification-configurations - :type 'symbol) -(defcustom reftex-mouse-selected-face 'secondary-selection - "Face name to highlight mouse selected item in toc and selection buffers. -See also the variable `reftex-highlight-selection'." - :group 'reftex-fontification-configurations - :type 'symbol) -(defcustom reftex-file-boundary-face 'font-lock-comment-face - "Face name for file boundaries in selection buffer." - :group 'reftex-fontification-configurations - :type 'symbol) -(defcustom reftex-label-face 'font-lock-constant-face - "Face name for labels in selection buffer." - :group 'reftex-fontification-configurations - :type 'symbol) -(defcustom reftex-section-heading-face 'font-lock-function-name-face - "Face name for section headings in toc and selection buffers." - :group 'reftex-fontification-configurations - :type 'symbol) -(defcustom reftex-toc-header-face 'font-lock-comment-face - "Face name for the header of a toc buffer." - :group 'reftex-fontification-configurations - :type 'symbol) -(defcustom reftex-bib-author-face 'font-lock-keyword-face - "Face name for author names in bib selection buffer." - :group 'reftex-fontification-configurations - :type 'symbol) -(defcustom reftex-bib-year-face 'font-lock-comment-face - "Face name for year in bib selection buffer." - :group 'reftex-fontification-configurations - :type 'symbol) -(defcustom reftex-bib-title-face 'font-lock-function-name-face - "Face name for article title in bib selection buffer." - :group 'reftex-fontification-configurations - :type 'symbol) -(defcustom reftex-bib-extra-face 'font-lock-comment-face - "Face name for bibliographic information in bib selection buffer." - :group 'reftex-fontification-configurations - :type 'symbol) -(defcustom reftex-select-mark-face 'bold - "Face name for marked entries in the selection buffers." - :group 'reftex-fontification-configurations - :type 'symbol) -(defcustom reftex-index-header-face 'font-lock-comment-face - "Face name for the header of an index buffer." - :group 'reftex-fontification-configurations - :type 'symbol) -(defcustom reftex-index-section-face 'font-lock-function-name-face - "Face name for the start of a new letter section in the index." - :group 'reftex-fontification-configurations - :type 'symbol) -(defcustom reftex-index-tag-face 'font-lock-keyword-face - "Face name for index names (for multiple indices)." - :group 'reftex-fontification-configurations - :type 'symbol) -(defcustom reftex-index-face 'font-lock-constant-face - "Face name for index entries." - :group 'reftex-fontification-configurations - :type 'symbol) - -(defcustom reftex-pre-refontification-functions nil - "X-Symbol specific hook. -Functions get two arguments, the buffer from where the command started and a -symbol indicating in what context the hook is called." - :group 'reftex-fontification-configurations - :type 'hook) - -;; Miscellaneous configurations ----------------------------------------- - -(defgroup reftex-miscellaneous-configurations nil - "Collection of further configurations." - :group 'reftex) - -(defcustom reftex-extra-bindings nil - "Non-nil means, make additional key bindings on startup. -These extra bindings are located in the users `C-c letter' map. -Note that this variable needs to be set before reftex is loaded." - :group 'reftex-miscellaneous-configurations - :type 'boolean) - -(defcustom reftex-plug-into-AUCTeX nil - "Plug-in flags for AUCTeX interface. -This variable is a list of 5 boolean flags. When a flag is non-nil, -RefTeX will - - - supply labels in new sections and environments (flag 1) - - supply arguments for macros like `\\label'. (flag 2) - - supply arguments for macros like `\\ref'. (flag 3) - - supply arguments for macros like `\\cite'. (flag 4) - - supply arguments for macros like `\\index'. (flag 5) - -You may also set the variable itself to t or nil in order to turn all -plug-ins on or off, respectively. -\\Supplying labels in new sections and environments applies when creating -sections with \\[LaTeX-section] and environments with \\[LaTeX-environment]. -Supplying macro arguments applies when you insert such a macro interactively -with \\[TeX-insert-macro]. -See the AUCTeX documentation for more information. -RefTeX uses `fset' to take over the function calls. Changing the variable -may require a restart of Emacs in order to become effective." - :group 'reftex-miscellaneous-configurations - :group 'LaTeX - :type '(choice - (const :tag "No plug-ins" nil) - (const :tag "All possible plug-ins" t) - (list - :tag "Individual choice" - :value (t t t t t) - (boolean :tag "supply label in new sections and environments") - (boolean :tag "supply argument for macros like `\\label' ") - (boolean :tag "supply argument for macros like `\\ref' ") - (boolean :tag "supply argument for macros like `\\cite' ") - (boolean :tag "supply argument for macros like `\\index' ")))) - -(defcustom reftex-allow-detached-macro-args nil - "Non-nil means, allow arguments of macros to be detached by whitespace. -When this is t, `aaa' will be considered as argument of \\bbb in -the following construct: \\bbb [xxx] {aaa}." - :group 'reftex-miscellaneous-configurations - :type 'boolean) - - -(defcustom reftex-load-hook nil - "Hook which is being run when loading reftex.el." - :group 'reftex-miscellaneous-configurations - :type 'hook) -(make-obsolete-variable 'reftex-load-hook - "use `with-eval-after-load' instead." "28.1") - -(defcustom reftex-mode-hook nil - "Hook which is being run when turning on RefTeX mode." - :group 'reftex-miscellaneous-configurations - :type 'hook) - -(defvar reftex-toc-split-windows-horizontally-fraction 0.5) -(make-obsolete-variable 'reftex-toc-split-windows-horizontally-fraction - 'reftex-toc-split-windows-fraction "31.1") - -(provide 'reftex-vars) - -;;; reftex-vars.el ends here diff --git a/lisp/textmodes/reftex.el b/lisp/textmodes/reftex.el deleted file mode 100644 index 035b3fb82ee..00000000000 --- a/lisp/textmodes/reftex.el +++ /dev/null @@ -1,2399 +0,0 @@ -;;; reftex.el --- minor mode for doing \label, \ref, \cite, \index in LaTeX -*- lexical-binding: t; -*- - -;; Copyright (C) 1997-2025 Free Software Foundation, Inc. - -;; Author: Carsten Dominik -;; Maintainer: auctex-devel@gnu.org -;; Keywords: tex - -;; 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 . - -;;; Commentary: - -;; RefTeX is a minor mode with distinct support for \ref, \label, \cite, -;; and \index commands in (multi-file) LaTeX documents. -;; - A table of contents provides easy access to any part of a document. -;; - Labels are created semi-automatically. -;; - Definition context of labels is provided when creating a reference. -;; - Citations are simplified with efficient database lookup. -;; - Text phrases can be collected in a file, for later global indexing. -;; - The index preview buffer helps to check and edit index entries. -;; -;; There is an extensive Texinfo document describing RefTeX in detail. -;; One way to view this documentation is `M-x reftex-info RET'. -;; -;; The documentation in various formats is also available at -;; -;; https://www.gnu.org/software/auctex/manual/reftex.index.html -;; -;; RefTeX is bundled with Emacs. -;; If you need to install it yourself, you can find a distribution at -;; -;; https://www.gnu.org/software/auctex/reftex.html -;; -;; RefTeX was written by Carsten Dominik with -;; contributions from Stephen Eglen. It is currently maintained by -;; the AUCTeX project. - -;;; Code: - -(eval-when-compile (require 'cl-lib)) -(when (< emacs-major-version 28) ; preloaded in Emacs 28 - (require 'easymenu)) - -(defvar reftex-tables-dirty t - "Flag showing if tables need to be re-computed.") - -(eval-and-compile - (defun reftex-set-dirty (symbol value) - (setq reftex-tables-dirty t) - (set symbol value))) - - -;; Configuration variables -(require 'reftex-vars) - - -;;; Autoloads to ensure loading of support files when necessary -(require 'reftex-loaddefs) - -;; We autoload tons of functions from these files, but some have -;; a single function that needs to be globally autoloaded. -;; The alternative is to use a Makefile rule + distinct autoload -;; cookie (eg ;;;###reftex-autoload) for internal autoloads, -;; as eg calendar/ does. But that seemed like overkill for 4 functions. - -;;;###autoload(autoload 'reftex-citation "reftex-cite" nil t) -;;;###autoload(autoload 'reftex-all-document-files "reftex-parse") -;;;###autoload(autoload 'reftex-isearch-minor-mode "reftex-global" nil t) -;;;###autoload(autoload 'reftex-index-phrases-mode "reftex-index" nil t) - -;; Generated functions. -(autoload 'reftex-varioref-vref "reftex-ref" - "Make a varioref reference." t) -(autoload 'reftex-fancyref-fref "reftex-ref" - "Make a fancyref \\fref reference." t) -(autoload 'reftex-fancyref-Fref "reftex-ref" - "Make a fancyref \\Fref reference." t) - -;;; ========================================================================= -;;; -;;; Define the formal stuff for a minor mode named RefTeX. -;;; - -(defconst reftex-version emacs-version - "Version string for RefTeX.") - -(defvar reftex-mode-map - (let ((map (make-sparse-keymap))) - ;; The default bindings in the mode map. - (define-key map "\C-c=" #'reftex-toc) - (define-key map "\C-c-" #'reftex-toc-recenter) - (define-key map "\C-c(" #'reftex-label) - (define-key map "\C-c)" #'reftex-reference) - (define-key map "\C-c[" #'reftex-citation) - (define-key map "\C-c<" #'reftex-index) - (define-key map "\C-c>" #'reftex-display-index) - (define-key map "\C-c/" #'reftex-index-selection-or-word) - (define-key map "\C-c\\" #'reftex-index-phrase-selection-or-word) - (define-key map "\C-c|" #'reftex-index-visit-phrases-buffer) - (define-key map "\C-c&" #'reftex-view-crossref) - - ;; Bind `reftex-mouse-view-crossref' only when the key is still free - (unless (key-binding [(shift mouse-2)]) - (define-key map [(shift mouse-2)] #'reftex-mouse-view-crossref)) - - ;; For most of these commands there are already bindings in place. - ;; Setting `reftex-extra-bindings' really is only there to spare users - ;; the hassle of defining bindings in the user space themselves. This - ;; is why they violate the key binding recommendations. - (when reftex-extra-bindings - (define-key map "\C-ct" #'reftex-toc) - (define-key map "\C-cl" #'reftex-label) - (define-key map "\C-cr" #'reftex-reference) - (define-key map "\C-cc" #'reftex-citation) - (define-key map "\C-cv" #'reftex-view-crossref) - (define-key map "\C-cg" #'reftex-grep-document) - (define-key map "\C-cs" #'reftex-search-document)) - - map) - "Keymap for RefTeX mode.") - -(defvar reftex-mode-menu nil) -(defvar reftex-syntax-table - (let ((st (make-syntax-table))) - (modify-syntax-entry ?\( "." st) - (modify-syntax-entry ?\) "." st) - st)) - -(defvar reftex-syntax-table-for-bib - (let ((st (make-syntax-table))) - (modify-syntax-entry ?\' "." st) - (modify-syntax-entry ?\" "." st) - (modify-syntax-entry ?\[ "." st) - (modify-syntax-entry ?\] "." st) - (modify-syntax-entry ?\( "." st) - (modify-syntax-entry ?\) "." st) - st)) - -;; The following definitions are out of place, but I need them here -;; to make the compilation of reftex-mode not complain. -(defvar reftex-auto-view-crossref-timer nil - "The timer used for auto-view-crossref.") -(defvar reftex-toc-auto-recenter-timer nil - "The idle timer used to recenter the toc window.") - -;;;###autoload -(defun turn-on-reftex () - "Turn on RefTeX mode." - (reftex-mode t)) - -(put 'reftex-mode :included '(memq major-mode '(latex-mode tex-mode))) -(put 'reftex-mode :menu-tag "RefTeX Mode") -;;;###autoload -(define-minor-mode reftex-mode - "Minor mode with distinct support for \\label, \\ref and \\cite in LaTeX. - -\\A Table of Contents of the entire (multifile) document with browsing -capabilities is available with `\\[reftex-toc]'. - -Labels can be created with `\\[reftex-label]' and referenced with `\\[reftex-reference]'. -When referencing, you get a menu with all labels of a given type and -context of the label definition. The selected label is inserted as a -\\ref macro. - -Citations can be made with `\\[reftex-citation]' which will use a regular expression -to pull out a *formatted* list of articles from your BibTeX -database. The selected citation is inserted as a \\cite macro. - -Index entries can be made with `\\[reftex-index-selection-or-word]' which indexes the word at point -or the current selection. More general index entries are created with -`\\[reftex-index]'. `\\[reftex-display-index]' displays the compiled index. - -Most command have help available on the fly. This help is accessed by -pressing `?' to any prompt mentioning this feature. - -Extensive documentation about RefTeX is available in Info format. -You can view this information with `\\[reftex-info]'. - -\\{reftex-mode-map} -Under X, these and other functions will also be available as `Ref' menu -on the menu bar. - -------------------------------------------------------------------------------" - :lighter " Ref" :keymap reftex-mode-map - (if reftex-mode - (progn - ;; Mode was turned on - (and reftex-plug-into-AUCTeX - (reftex-plug-into-AUCTeX)) - (unless (get 'reftex-auto-view-crossref 'initialized) - (and reftex-auto-view-crossref - (reftex-toggle-auto-view-crossref)) - (put 'reftex-auto-view-crossref 'initialized t)) - (unless (get 'reftex-auto-recenter-toc 'initialized) - (and (eq reftex-auto-recenter-toc t) - (reftex-toggle-auto-toc-recenter)) - (put 'reftex-auto-recenter-toc 'initialized t)) - - (run-hooks 'reftex-mode-hook)))) - -(defvar reftex-docstruct-symbol) -(defun reftex-kill-buffer-hook () - "Save RefTeX's parse file for this buffer if the information has changed." - ;; Save the parsing information if it was modified. - ;; This function should be installed in `kill-buffer-hook'. - ;; We are careful to make sure nothing goes wrong in this function. - (when (and (boundp 'reftex-mode) reftex-mode - (boundp 'reftex-save-parse-info) reftex-save-parse-info - (boundp 'reftex-docstruct-symbol) reftex-docstruct-symbol - (symbol-value reftex-docstruct-symbol) - (get reftex-docstruct-symbol 'modified)) - ;; Write the file. - (condition-case nil - (reftex-access-parse-file 'write) - (error nil)))) - -(defun reftex-kill-emacs-hook () - "Call `reftex-kill-buffer-hook' on all buffers." - ;; This function should be installed in `kill-emacs-hook'. - (save-excursion - (mapcar (lambda (buf) - (set-buffer buf) - (reftex-kill-buffer-hook)) - (buffer-list)))) - -;;; ========================================================================= -;;; -;;; Silence warnings about variables in other packages. -(defvar TeX-master) -(defvar LaTeX-section-hook) -(defvar LaTeX-label-function) -(defvar tex-main-file) -(defvar outline-minor-mode) - -;;; ========================================================================= -;;; -;;; Helper functions for handling both file names and buffer objects. -;;; - -(defun reftex--get-buffer-identifier (&optional buffer) - "Return the base buffer's file name or buffer identifier. -For file buffers, returns the file name of the base buffer. -For non-file buffers, return the base buffer object itself. -When BUFFER is nil, use the current buffer." - (let* ((buffer (or (buffer-base-buffer buffer) buffer (current-buffer)))) - (or (buffer-local-value 'buffer-file-name buffer) - buffer))) - -(defun reftex--get-directory (file-or-buffer) - "Get the directory associated with FILE-OR-BUFFER. -FILE-OR-BUFFER can be a file name or a buffer object." - (if (bufferp file-or-buffer) - (buffer-local-value 'default-directory file-or-buffer) - (file-name-directory file-or-buffer))) - -(defun reftex--abbreviate-name (file-or-buffer) - "Get a nice display name for FILE-OR-BUFFER. -For files, returns the abbreviated file name. -For buffers, returns the buffer name." - (if (bufferp file-or-buffer) - (prin1-to-string file-or-buffer) - (abbreviate-file-name file-or-buffer))) - -(defun reftex--get-basename (file-or-buffer) - "Get the base name (without extension) for FILE-OR-BUFFER. -For file names, returns the file name without directory and extension. -For buffer objects, returns a sanitized version of the buffer name -suitable for use in LaTeX labels." - (if (bufferp file-or-buffer) - (file-name-base (buffer-name file-or-buffer)) - (file-name-base file-or-buffer))) - -(defun reftex--get-truename (file-or-buffer) - "Get the canonical form of FILE-OR-BUFFER's identity. -For files, returns the result of file-truename. -For buffer objects, returns the buffer object itself." - (if (bufferp file-or-buffer) - file-or-buffer - (file-truename file-or-buffer))) - -;;; ========================================================================= -;;; -;;; Multibuffer Variables -;;; -;; Technical notes: These work as follows: We keep just one list -;; of labels for each master file - this can save a lot of memory. -;; `reftex-master-index-list' is an alist which connects the true file name -;; of each master file with the symbols holding the information on that -;; document. Each buffer has local variables which point to these symbols. - -;; List of variables which handle the multifile stuff. -;; This list is used to tie, untie, and reset these symbols. -(defconst reftex-multifile-symbols - '(reftex-docstruct-symbol)) - -;; Alist connecting master file names with the corresponding lisp symbols. -(defvar reftex-master-index-list nil) - -;; Last index used for a master file. -(defvar reftex-multifile-index 0) - -;; Variable holding the symbol with the label list of the document. -(defvar-local reftex-docstruct-symbol nil) - -(defun reftex-next-multifile-index () - "Return the next free index for multifile symbols." - (incf reftex-multifile-index)) - -(defun reftex--remove-buffer-from-master-index () - "Remove current buffer from `reftex-master-index-list'." - (setq reftex-master-index-list - (assq-delete-all (current-buffer) reftex-master-index-list))) - -(defun reftex-tie-multifile-symbols () - "Tie the buffer-local symbols to globals connected with the master file. -If the symbols for the current master file do not exist, they are created." - (let* ((master (reftex-TeX-master-file)) - (master (reftex--get-truename master)) - (index (assoc master reftex-master-index-list)) - (symlist reftex-multifile-symbols) - symbol symname newflag) - ;; Find the correct index. - (if index - ;; Symbols do exist - (setq index (cdr index)) - ;; Get a new index and add info to the alist. - (setq index (reftex-next-multifile-index) - newflag t) - (push (cons master index) reftex-master-index-list) - (when (bufferp master) - (with-current-buffer master - (add-hook 'kill-buffer-hook - #'reftex--remove-buffer-from-master-index nil t)))) - - ;; Get/create symbols and tie them. - (while symlist - (setq symbol (car symlist) - symlist (cdr symlist) - symname (symbol-name symbol)) - (set symbol (intern (concat symname "-" (int-to-string index)))) - (put (symbol-value symbol) :master-index index) - ;; Initialize if new symbols. - (when newflag - (set (symbol-value symbol) nil) - (put (symbol-value symbol) 'reftex-index-macros-style '(default)) - (put (symbol-value symbol) 'reftex-ref-style-list - reftex-ref-style-default-list))) - - ;; Return t if the symbols did already exist, nil when we've made them. - (not newflag))) - -(defun reftex-untie-multifile-symbols () - "Remove ties from multifile symbols, so that next use makes new ones." - (let ((symlist reftex-multifile-symbols) - (symbol nil)) - (while symlist - (setq symbol (car symlist) - symlist (cdr symlist)) - (set symbol nil)))) - -(defun reftex-TeX-master-file () - "Return the name of the master file associated with the current buffer. -When AUCTeX is loaded, we will use it's more sophisticated method. -We also support the default TeX and LaTeX modes by checking for a -variable `tex-main-file'." - (with-current-buffer (or (buffer-base-buffer) (current-buffer)) - (let - ;; Set master to a file name (possibly non-existent), or nil: - ((master - (cond - ;; Test if we're in a subfile using the subfiles document - ;; class, e.g., \documentclass[main.tex]{subfiles}. It's - ;; argument is the main file, however it's not really the - ;; master file in `TeX-master-file' or `tex-main-file's - ;; sense. It should be used for references but not for - ;; compilation, thus subfiles use a setting of - ;; `TeX-master'/`tex-main-file' being themselves. - ((save-excursion - (goto-char (point-min)) - (re-search-forward - "^[[:space:]]*\\\\documentclass\\[\\([^]]+\\)\\]{subfiles}" - nil t)) - (match-string-no-properties 1)) - ;; AUCTeX is loaded. Use its mechanism. - ((fboundp 'TeX-master-file) - (condition-case nil - (TeX-master-file t) - (error (buffer-file-name)))) - ;; Emacs LaTeX mode - ((fboundp 'tex-main-file) - (condition-case nil - (tex-main-file) - (error (buffer-file-name)))) - ;; Check the `TeX-master' variable. - ((boundp 'TeX-master) - (cond - ((eq TeX-master t) - (buffer-file-name)) - ((or (stringp TeX-master) (bufferp TeX-master)) TeX-master) - (t - (setq TeX-master (read-file-name "Master file: " - nil nil t nil))))) - ;; Check the `tex-main-file' variable. - ((boundp 'tex-main-file) - ;; This is the variable from the default TeX modes. - (cond - ((stringp tex-main-file) - ;; ok, this must be it - tex-main-file) - (t - ;; In this case, the buffer is its own master. - (buffer-file-name)))) - ;; We know nothing about master file. Assume this is a - ;; master file. - (t - (buffer-file-name))))) - (cond - ((not (stringp master))) - ((or (file-exists-p (concat master ".tex")) - (find-buffer-visiting (concat master ".tex"))) - ;; Ahh, an extra .tex was missing... - (setq master (concat master ".tex"))) - ((or (file-exists-p master) - (find-buffer-visiting master)) - ;; We either see the file, or have a buffer on it. OK. - ) - (t - ;; Use buffer file name. - (setq master (buffer-file-name)))) - (if (stringp master) - (expand-file-name master) - (or master (current-buffer)))))) - -(defun reftex-is-multi () - "Tell if this is a multifile document. When not sure, say yes." - (let ((entry (assq 'is-multi (symbol-value reftex-docstruct-symbol)))) - (if entry - (nth 1 entry) - t))) - -(defun reftex-set-cite-format (value) - "Set the document-local VALUE of `reftex-cite-format'. -When such a value exists, it overwrites the setting given with -`reftex-cite-format'. See the documentation of `reftex-cite-format' -for possible values. This function should be used from AUCTeX style files." - (unless reftex-docstruct-symbol - (reftex-tie-multifile-symbols)) - (when (and reftex-docstruct-symbol - (symbolp reftex-docstruct-symbol)) - (put reftex-docstruct-symbol 'reftex-cite-format value))) - -(defun reftex-get-cite-format () - "Return the current citation format. -Either the document-local value in `reftex-cite-format-symbol', or the -global value in `reftex-cite-format'." - (if (and reftex-docstruct-symbol - (symbolp reftex-docstruct-symbol) - (get reftex-docstruct-symbol 'reftex-cite-format)) - (get reftex-docstruct-symbol 'reftex-cite-format) - reftex-cite-format)) - -(defun reftex-add-index-macros (entry-list) - "Add index macro descriptions to `reftex-index-macros-style'. -The format of ENTRY-LIST is exactly like `reftex-index-macros'. See there -for details. -This function makes it possible to support RefTeX from AUCTeX style files. -The entries in ENTRY-LIST will be processed after the user settings in -`reftex-index-entries', and before the defaults. Any changes made to -`reftex-index-macros-style' will raise a flag to the effect that -the label information is recompiled on next use." - (unless reftex-docstruct-symbol - (reftex-tie-multifile-symbols)) - (when (and reftex-docstruct-symbol - (symbolp reftex-docstruct-symbol)) - (let ((list (get reftex-docstruct-symbol 'reftex-index-macros-style)) - entry changed) - (while entry-list - (setq entry (pop entry-list)) - ;; When it is a symbol, remove all other symbols - (and (symbolp entry) - (not (memq entry list)) - (setq list (seq-remove #'symbolp list))) - ;; Add to list unless already member - (unless (member entry list) - (setq reftex-tables-dirty t - changed t) - (push entry list))) - (when changed - (put reftex-docstruct-symbol 'reftex-index-macros-style list))))) - -(defun reftex-ref-style-activate (style) - "Activate the referencing style STYLE." - (reftex-ref-style-toggle style 'activate)) - -(defun reftex-ref-style-toggle (style &optional action) - "Activate or deactivate the referencing style STYLE. -With the optional argument ACTION a certain action can be forced. -The symbol `activate' will activate the style and `deactivate' -will deactivate it." - (unless reftex-docstruct-symbol - (reftex-tie-multifile-symbols)) - (when (and reftex-docstruct-symbol - (symbolp reftex-docstruct-symbol)) - (let ((list (get reftex-docstruct-symbol 'reftex-ref-style-list)) - changed) - (cond ((eq action 'activate) - (unless (member style list) - (setq reftex-tables-dirty t - changed t) - (setq list (append list (list style))))) - ((eq action 'deactivate) - (when (member style list) - (setq reftex-tables-dirty t - changed t) - (setq list (delete style list)))) - (t - (setq list (if (member style list) - (delete style list) - (append list (list style)))) - (setq reftex-tables-dirty t - changed t))) - (when changed - (put reftex-docstruct-symbol 'reftex-ref-style-list list))))) - -(defun reftex-ref-style-list () - "Return the list of referencing styles to be active at the moment." - ;; Initialize the value of `reftex-ref-style-list' and tie it to the - ;; docstruct symbol if necessary. - (unless reftex-docstruct-symbol - (reftex-tie-multifile-symbols)) - (if (and reftex-docstruct-symbol - (symbolp reftex-docstruct-symbol) - (get reftex-docstruct-symbol 'reftex-ref-style-list)) - (get reftex-docstruct-symbol 'reftex-ref-style-list) - reftex-ref-style-default-list)) - -;;; ========================================================================= -;;; -;;; Functions to compile the tables, reset the mode etc. - -;; The following constants are derived from `reftex-label-alist'. - -;; Prompt used for label type queries directed to the user. -(defvar reftex-type-query-prompt nil) - -;; Help string for label type queries. -(defvar reftex-type-query-help nil) - -;; Alist relating label type to reference format. -(defvar reftex-typekey-to-format-alist nil) - -;; Alist relating label type to label prefix. -(defvar reftex-typekey-to-prefix-alist nil) - -;; Alist relating environments or macros to label type and context regexp. -(defvar reftex-env-or-mac-alist nil) - -;; List of special environment parser functions -(defvar reftex-special-env-parsers nil) - -;; List of macros carrying a label. -(defvar reftex-label-mac-list nil) - -;; List of environments carrying a label. -(defvar reftex-label-env-list nil) - -;; List of all typekey letters in use. -(defvar reftex-typekey-list nil) - -;; Alist relating magic words to a label type. -(defvar reftex-words-to-typekey-alist nil) -;; Alist relating label prefixes to a label type. -(defvar reftex-prefix-to-typekey-alist nil) - -;; The last list-of-labels entry used in a reference. -(defvar reftex-last-used-reference (list nil nil nil nil)) - -;; Alist relating index macros to other info. -(defvar reftex-key-to-index-macro-alist nil) -;; Prompt for index macro queries -(defvar reftex-query-index-macro-prompt nil) -;; Help string for index macro queries -(defvar reftex-query-index-macro-help nil) - -;; The message when follow-mode is suspended -(defvar reftex-no-follow-message - "No follow-mode into unvisited file. Press SPC to visit it.") -(defvar reftex-no-info-message - "%s: info not available, use `\\[reftex-view-crossref]' to get it.") - -;; Global variables used for communication between functions. -(defvar reftex-default-context-position nil) -(defvar reftex-location-start nil) -(defvar reftex-call-back-to-this-buffer nil) -(defvar reftex-select-return-marker (make-marker)) -(defvar reftex-active-toc nil) -(defvar reftex-tex-path nil) -(defvar reftex-bib-path nil) -(defvar reftex-select-marked nil) -(defvar reftex-last-follow-point nil) -(defvar reftex-latex-syntax-table nil) -(defvar reftex-prefix nil) -(defvar reftex-section-levels-all nil) -(defvar reftex-buffers-with-changed-invisibility nil) -(defvar reftex-callback-fwd t) -(defvar reftex-last-toc-master nil - "Stores the name of the tex file that `reftex-toc' was last run on.") -;; Marker for return point from recursive edit -(defvar reftex-recursive-edit-marker (make-marker)) - -;; List of buffers created temporarily for lookup, which should be killed. -(defvar reftex-buffers-to-kill nil) - -;; Regexp to find anything. -(defvar reftex-section-regexp nil) -(defvar reftex-section-or-include-regexp nil) -(defvar reftex-index-macro-regexp nil) -(defvar reftex-index-level-re nil) -(defvar reftex-index-key-end-re nil) -(defvar reftex-find-index-entry-regexp-format nil) -(defvar reftex-everything-regexp nil) -(defvar reftex-everything-regexp-no-index nil) -(defvar reftex-index-re nil) -(defvar reftex-find-citation-regexp-format - "\\\\\\([a-zA-Z]*cite[*a-zA-Z]*\\*?\\|bibentry\\)\\(\\[[^]]*\\]\\|{[^}]*}\\)*{\\([^}]*,\\)?\\(%s\\)[},]") -(defvar reftex-find-reference-format - "\\\\\\(ref[a-zA-Z]*\\|[a-zA-Z]*ref\\(range\\)?\\)\\*?\\(\\[[^]]*\\]\\|{[^}]*}\\)*{\\(%s\\)}") -(defvar reftex-macros-with-labels nil) -(defvar reftex-macros-with-index nil) -(defvar reftex-index-macro-alist nil) -(defvar reftex-find-label-regexp-format nil) -(defvar reftex-find-label-regexp-format2 nil) - -;; Constants for making RefTeX open to Texinfo hooking -(defvar reftex-section-pre-regexp "\\\\") -;; Including `\' as a character to be matched at the end of the regexp -;; will allow stuff like \begin{foo}\label{bar} to be matched. This -;; will make the parser to advance one char too much. Therefore -;; `reftex-parse-from-file' will step one char back if a section is -;; found. -(defvar reftex-section-post-regexp "\\*?\\(\\[[^]]*\\]\\)?[[{ \t\r\n\\]") -(defvar reftex-section-info-function 'reftex-section-info) - -(defvar reftex-memory nil - "Memorizes old variable values to indicate changes in these variables.") - -;; A list of all variables in the cache. -;; The cache is used to save the compiled versions of some variables. -(defconst reftex-cache-variables - '(reftex-memory ;; This MUST ALWAYS be the first! - - ;; Outline - reftex-section-levels-all - - ;; Labels - reftex-env-or-mac-alist - reftex-special-env-parsers - reftex-macros-with-labels - reftex-label-mac-list - reftex-label-env-list - reftex-typekey-list - reftex-typekey-to-format-alist - reftex-typekey-to-prefix-alist - reftex-words-to-typekey-alist - reftex-prefix-to-typekey-alist - reftex-type-query-prompt - reftex-type-query-help - - ;; Index - reftex-index-macro-alist - reftex-macros-with-index - reftex-query-index-macro-prompt - reftex-query-index-macro-help - reftex-key-to-index-macro-alist - - ;; Regular expressions - reftex-section-regexp - reftex-section-or-include-regexp - reftex-index-re - reftex-everything-regexp - reftex-everything-regexp-no-index - reftex-find-label-regexp-format - reftex-find-label-regexp-format2 - reftex-find-index-entry-regexp-format -)) - -(defun reftex-ensure-compiled-variables () - "Recompile the label alist when necessary." - (let* ((mem reftex-memory) - (cache (get reftex-docstruct-symbol 'reftex-cache)) - (cmem (car cache)) - (alist reftex-label-alist) - (levels (get reftex-docstruct-symbol 'reftex-section-levels)) - (style (get reftex-docstruct-symbol 'reftex-label-alist-style)) - (default reftex-default-label-alist-entries) - (index reftex-index-macros) - (istyle (get reftex-docstruct-symbol 'reftex-index-macros-style))) - (cond - (reftex-tables-dirty (reftex-compile-variables)) - ((and (eq alist (nth 0 mem)) - (eq levels (nth 1 mem)) - (eq style (nth 2 mem)) - (eq default (nth 3 mem)) - (eq index (nth 4 mem)) - (eq istyle (nth 5 mem)))) ;; everything is OK - ((and (eq alist (nth 0 cmem)) - (eq levels (nth 1 cmem)) - (eq style (nth 2 cmem)) - (eq default (nth 2 cmem)) - (eq index (nth 4 cmem)) - (eq istyle (nth 5 cmem))) - ;; restore the cache - (message "Restoring cache") - (mapcar (lambda (sym) (set sym (pop cache))) reftex-cache-variables)) - (t (reftex-compile-variables))))) - -(defun reftex-reset-mode () - "Reset RefTeX Mode. -This will re-compile the configuration information and remove all -current scanning information and the parse file to enforce a rescan -on next use." - (interactive) - - ;; Reset the file search path variables - (dolist (prop '(status master-dir recursive-path rec-type)) - (put 'reftex-tex-path prop nil) - (put 'reftex-bib-path prop nil)) - - ;; Kill temporary buffers associated with RefTeX - just in case they - ;; were not cleaned up properly - (save-excursion - (let ((buffer-list '("*RefTeX Help*" "*RefTeX Select*" - "*Duplicate Labels*" "*toc*" " *RefTeX-scratch*")) - buf) - (while (setq buf (pop buffer-list)) - (if (get-buffer buf) - (kill-buffer buf)))) - (reftex-erase-all-selection-and-index-buffers)) - - ;; Make sure the current document will be rescanned soon. - (reftex-reset-scanning-information) - - ;; Remove any parse info file - (reftex-access-parse-file 'kill) - - ;; Plug functions into AUCTeX if the user option says so. - (and reftex-plug-into-AUCTeX - (reftex-plug-into-AUCTeX)) - - (reftex-compile-variables)) - -;;;###autoload -(defun reftex-reset-scanning-information () - "Reset the symbols containing information from buffer scanning. -This enforces rescanning the buffer on next use." - (if (equal reftex-last-toc-master (reftex-TeX-master-file)) - (reftex-erase-buffer "*toc*")) - (let ((symlist reftex-multifile-symbols) - symbol) - (while symlist - (setq symbol (car symlist) - symlist (cdr symlist)) - (if (and (symbolp (symbol-value symbol)) - (not (null (symbol-value symbol)))) - (set (symbol-value symbol) nil))))) - -(defun reftex-erase-all-selection-and-index-buffers () - "Remove all selection buffers associated with current document." - (mapc - (lambda (type) - (reftex-erase-buffer (reftex-make-selection-buffer-name type))) - reftex-typekey-list) - ;; Kill all index buffers - (mapc - (lambda (tag) - (reftex-kill-buffer (reftex-make-index-buffer-name tag))) - (cdr (assoc 'index-tags (symbol-value reftex-docstruct-symbol))))) - -(defun reftex-compile-variables () - "Compile the information in reftex-label-alist & Co." - (message "Compiling label environment definitions...") - - ;; Update AUCTeX style information - (when (and (featurep 'tex-site) (fboundp 'TeX-update-style)) - (condition-case nil (TeX-update-style) (error nil))) - - ;; Record that we have done this, and what we have used. - (setq reftex-tables-dirty nil) - (setq reftex-memory - (list reftex-label-alist - (get reftex-docstruct-symbol 'reftex-section-levels) - (get reftex-docstruct-symbol 'reftex-label-alist-style) - reftex-default-label-alist-entries - reftex-index-macros - (get reftex-docstruct-symbol 'reftex-index-macros-style))) - - ;; Compile information in reftex-label-alist - (let ((all (reftex-uniquify-by-car - (reftex-splice-symbols-into-list - (append reftex-label-alist - (get reftex-docstruct-symbol - 'reftex-label-alist-style) - reftex-default-label-alist-entries) - reftex-label-alist-builtin) - '(nil))) - (all-index (reftex-uniquify-by-car - (reftex-splice-symbols-into-list - (append reftex-index-macros - (get reftex-docstruct-symbol - 'reftex-index-macros-style) - '(default)) - reftex-index-macros-builtin))) - entry env-or-mac typekeychar typekey prefix context word - fmt reffmt labelfmt wordlist qh-list macros-with-labels - nargs nlabel opt-args cell sum i - macro verify repeat nindex tag key toc-level toc-levels) - - (setq reftex-words-to-typekey-alist nil - reftex-prefix-to-typekey-alist - '(("sec:" . "s") ("cha:" . "s") ("chap:" . "s")) - reftex-typekey-list nil - reftex-typekey-to-format-alist nil - reftex-typekey-to-prefix-alist nil - reftex-env-or-mac-alist nil - reftex-label-env-list nil - reftex-label-mac-list nil) - (while all - (catch 'next-entry - (setq entry (car all) - env-or-mac (car entry) - entry (cdr entry) - all (cdr all)) - (if (null env-or-mac) - (setq env-or-mac "")) - (if (stringp (car entry)) - ;; This is before version 2.00 - convert entry to new format - ;; This is just to keep old users happy - (setq entry (cons (string-to-char (car entry)) - (cons (concat (car entry) ":") - (cdr entry))))) - (setq typekeychar (nth 0 entry) - typekey (if typekeychar (char-to-string typekeychar) nil) - prefix (nth 1 entry) - fmt (nth 2 entry) - context (nth 3 entry) - wordlist (nth 4 entry) - toc-level (nth 5 entry)) - (if (stringp wordlist) - ;; This is before version 2.04 - convert to new format - (setq wordlist (nthcdr 4 entry))) - - (if (and (stringp fmt) - (string-search "@" fmt)) - ;; Special syntax for specifying a label format - (setq fmt (split-string fmt "@+")) - (setq fmt (list "\\label{%s}" fmt))) - (setq labelfmt (car fmt) - reffmt (nth 1 fmt)) - ;; Note a new typekey - (if typekey - (cl-pushnew typekey reftex-typekey-list :test #'equal)) - (if (and typekey prefix - (not (assoc prefix reftex-prefix-to-typekey-alist))) - (cl-pushnew (cons prefix typekey) reftex-prefix-to-typekey-alist - :test #'equal)) - (if (and typekey prefix - (not (assoc typekey reftex-typekey-to-prefix-alist))) - (cl-pushnew (cons typekey prefix) reftex-typekey-to-prefix-alist - :test #'equal)) - ;; Check if this is a macro or environment - (cond - ((symbolp env-or-mac) - ;; A special parser function - (unless (fboundp env-or-mac) - (message "Warning: %s does not seem to be a valid function" - env-or-mac)) - (setq nargs nil nlabel nil opt-args nil) - (cl-pushnew env-or-mac reftex-special-env-parsers) - (setq env-or-mac (symbol-name env-or-mac))) - ((string-match "\\`\\\\" env-or-mac) - ;; It's a macro - (let ((result (reftex-parse-args env-or-mac))) - (setq env-or-mac (or (cl-first result) env-or-mac) - nargs (cl-second result) - nlabel (cl-third result) - opt-args (cl-fourth result)) - (if nlabel (cl-pushnew env-or-mac macros-with-labels :test #'equal))) - (if typekey (cl-pushnew env-or-mac reftex-label-mac-list :test #'equal))) - (t - ;; It's an environment - (setq nargs nil nlabel nil opt-args nil) - (cond ((string= env-or-mac "any")) - ((string= env-or-mac "")) - ((string= env-or-mac "section")) - (t - (cl-pushnew env-or-mac reftex-label-env-list :test #'equal) - (if toc-level - (let ((string (format "begin{%s}" env-or-mac))) - (or (assoc string toc-levels) - (push (cons string toc-level) toc-levels)))))))) - ;; Translate some special context cases - (when (assq context reftex-default-context-regexps) - (setq context - (format - (cdr (assq context reftex-default-context-regexps)) - (regexp-quote env-or-mac)))) - ;; See if this is the first format for this typekey - (and reffmt - (not (assoc typekey reftex-typekey-to-format-alist)) - (push (cons typekey reffmt) reftex-typekey-to-format-alist)) - ;; See if this is the first definition for this env-or-mac - (and (not (string= env-or-mac "any")) - (not (string= env-or-mac "")) - (not (assoc env-or-mac reftex-env-or-mac-alist)) - (push (list env-or-mac typekey context labelfmt - nargs nlabel opt-args) - reftex-env-or-mac-alist)) - ;; Are the magic words regular expressions? Quote normal words. - (if (eq (car wordlist) 'regexp) - (setq wordlist (cdr wordlist)) - (setq wordlist (mapcar #'regexp-quote wordlist))) - ;; Remember the first association of each word. - (while (stringp (setq word (pop wordlist))) - (or (assoc word reftex-words-to-typekey-alist) - (push (cons word typekey) reftex-words-to-typekey-alist))) - (cond - ((string= "" env-or-mac) nil) - ((setq cell (assoc typekey qh-list)) - (push env-or-mac (cdr cell))) - (typekey - (push (list typekey env-or-mac) qh-list))))) - - (setq reftex-typekey-to-prefix-alist - (nreverse reftex-typekey-to-prefix-alist)) - - ;; Prepare the typekey query prompt and help string. - (setq qh-list - (sort qh-list - (lambda (x1 x2) - (string< (downcase (car x1)) (downcase (car x2)))))) - (setq reftex-type-query-prompt - (concat "Label type: [" - (mapconcat (lambda(x) (format "%s" (car x))) - qh-list "") - "]")) - ;; In the help string, we need to wrap lines... - (setq reftex-type-query-help - (concat - "SELECT A LABEL TYPE:\n--------------------\n" - (mapconcat - (lambda(x) - (setq sum 0) - (format " [%s] %s" - (car x) - (mapconcat (lambda(env) - (setq sum (+ sum (length env))) - (if (< sum 60) - env - (setq sum 0) - (concat "\n " env))) - (cdr x) " "))) - qh-list "\n"))) - - ;; Convert magic words to regular expressions. We make regular expressions - ;; which allow for some chars from the ref format to be in the buffer. - ;; These characters will be seen and removed. - (setq reftex-words-to-typekey-alist - (mapcar - (lambda (x) - (setq word (car x) - typekey (cdr x) - fmt (cdr (assoc typekey reftex-typekey-to-format-alist))) - (setq word (concat "\\W\\(" word "[ \t\n\r]*\\)\\(")) - (setq i 0) - (while (and (< i 10) ; maximum number of format chars allowed - (< i (length fmt)) - (not (member (aref fmt i) '(?%)))) - (setq word (concat word "\\|" (regexp-quote - (substring fmt 0 (1+ i))))) - (incf i)) - (cons (concat word "\\)\\=") typekey)) - (nreverse reftex-words-to-typekey-alist))) - - ;; Parse the index macros - (setq reftex-index-macro-alist nil - reftex-key-to-index-macro-alist nil - reftex-macros-with-index nil) - (while all-index - (setq entry (car all-index) - macro (car entry) - tag (nth 1 entry) - key (nth 2 entry) - prefix (or (nth 3 entry) "") - verify (nth 4 entry) - ;; For repeat, we need to be compatible with older code - ;; This information used to be given only for the default macro, - ;; but later we required to have it for *every* index macro - repeat (cond ((> (length entry) 5) (nth 5 entry)) - ((and (eq key (car reftex-index-default-macro)) - (> (length reftex-index-default-macro) 2)) - ;; User has old setting - respect it - (nth 2 reftex-index-default-macro)) - (t t)) - all-index (cdr all-index)) - (let ((result (reftex-parse-args macro))) - (setq macro (or (cl-first result) macro) - nargs (cl-second result) - nindex (cl-third result) - opt-args (cl-fourth result)) - (unless (member macro reftex-macros-with-index) - ;; 0 1 2 3 4 5 6 7 - (push (list macro tag prefix verify nargs nindex opt-args repeat) - reftex-index-macro-alist) - (or (assoc key reftex-key-to-index-macro-alist) - (push (list key macro) reftex-key-to-index-macro-alist)) - (push macro reftex-macros-with-index)))) - ;; Make the prompt and help string for index macros query - (setq reftex-key-to-index-macro-alist - (sort reftex-key-to-index-macro-alist - (lambda (a b) (< (downcase (car a)) (downcase (car b)))))) - (setq reftex-query-index-macro-prompt - (concat "Index macro: [" - (mapconcat (compf char-to-string car) - reftex-key-to-index-macro-alist "") - "]")) - (setq i 0 - reftex-query-index-macro-help - (concat - "SELECT A MACRO:\n---------------\n" - (mapconcat - (lambda(x) - (format "[%c] %-20.20s%s" (car x) (nth 1 x) - (if (= 0 (mod (incf i) 3)) "\n" ""))) - reftex-key-to-index-macro-alist ""))) - - ;; Make the full list of section levels - (setq reftex-section-levels-all - (append toc-levels - (get reftex-docstruct-symbol 'reftex-section-levels) - reftex-section-levels)) - - ;; Calculate the regular expressions - (let* (;; (wbol "\\(\\`\\|[\n\r]\\)[ \t]*") - ;; Need to keep the empty group because match numbers are - ;; hard coded - (wbol (concat "\\(^\\)" - (when (string-suffix-p ".dtx" (buffer-file-name) t) - "%") - "[ \t]*")) - (label-re (concat "\\(?:" - (mapconcat #'identity reftex-label-regexps "\\|") - "\\)")) - (include-re (concat wbol - "\\\\\\(" - (mapconcat #'identity - reftex-include-file-commands "\\|") - "\\)[{ \t]+\\([^} \t\n\r]+\\)")) - (section-re - (concat wbol reftex-section-pre-regexp "\\(" - (mapconcat (compf regexp-quote car) - reftex-section-levels-all "\\|") - "\\)" reftex-section-post-regexp)) - (appendix-re (concat wbol "\\(\\\\appendix\\)")) - (macro-re - (if macros-with-labels - (concat "\\(" - (mapconcat #'regexp-quote macros-with-labels "\\|") - "\\)[[{]") - "")) - (index-re - (concat "\\(" - (mapconcat #'regexp-quote reftex-macros-with-index "\\|") - "\\)[[{]")) - (find-index-re-format - (concat "\\(" - (mapconcat #'regexp-quote reftex-macros-with-index "\\|") - "\\)\\([[{][^]}]*[]}]\\)*[[{]\\(%s\\)[]}]")) - (find-label-re-format - (concat "\\(" - "label[[:space:]]*=[[:space:]]*" - "\\|" - (mapconcat #'regexp-quote (append '("\\label") - macros-with-labels) - "\\|") - "\\)\\([[{][^]}]*[]}]\\)*[[{]\\(%s\\)[]}]")) - (index-level-re - (regexp-quote (nth 0 reftex-index-special-chars))) - (index-key-end-re ;; ^]- not allowed - (concat "[^" (nth 3 reftex-index-special-chars) "]" - "[" (nth 1 reftex-index-special-chars) - (nth 2 reftex-index-special-chars) "]")) - ) - (setq reftex-section-regexp section-re - reftex-section-or-include-regexp - (concat section-re "\\|" include-re) - reftex-everything-regexp - (concat label-re "\\|" section-re "\\|" include-re - "\\|" appendix-re - "\\|" index-re - (if macros-with-labels "\\|" "") macro-re) - reftex-everything-regexp-no-index - (concat label-re "\\|" section-re "\\|" include-re - "\\|" appendix-re - "\\|" "\\(\\\\6\\\\3\\\\1\\)" ; This is unlikely to match - (if macros-with-labels "\\|" "") macro-re) - reftex-index-re index-re - reftex-index-level-re index-level-re - reftex-index-key-end-re index-key-end-re - reftex-macros-with-labels macros-with-labels - reftex-find-index-entry-regexp-format find-index-re-format - reftex-find-label-regexp-format find-label-re-format - reftex-find-label-regexp-format2 - "\\([]} \t\n\r]\\)\\([[{]\\)\\(%s\\)[]}]") - (message "Compiling label environment definitions...done"))) - (put reftex-docstruct-symbol 'reftex-cache - (mapcar #'symbol-value reftex-cache-variables))) - -(defun reftex-parse-args (macro) - "Return a list of MACRO name, nargs, arg-nr. -arg-nr is label and a list of optional argument indices." - (if (string-match "[[{]\\*?[]}]" macro) - (progn - (let ((must-match (substring macro 0 (match-beginning 0))) - (args (substring macro (match-beginning 0))) - opt-list nlabel (cnt 0)) - (while (string-match "\\`[[{]\\(\\*\\)?[]}]" args) - (incf cnt) - (when (eq ?\[ (string-to-char args)) - (push cnt opt-list)) - (when (and (match-end 1) - (not nlabel)) - (setq nlabel cnt)) - (setq args (substring args (match-end 0)))) - (list must-match cnt nlabel opt-list))) - nil)) - -;;; ========================================================================= -;;; -;;; Accessing the parse information - -(defun reftex-access-scan-info (&optional rescan file) - "Ensure access to the scanning info for the current file. -When the multifile symbols are not yet tied, tie them. -When they are empty or RESCAN is non-nil, scan the document. -But, when RESCAN is -1, don't rescan even if docstruct is empty. -When FILE is non-nil, parse only from that file." - - ;; Make sure we have the symbols tied - (if (eq reftex-docstruct-symbol nil) - ;; Symbols are not yet tied: Tie them. - (reftex-tie-multifile-symbols)) - - (reftex-ensure-compiled-variables) - - (when (or (null (symbol-value reftex-docstruct-symbol)) - (member rescan '(t 1 (4) (16)))) - ;; The docstruct will change: Remove selection buffers. - (save-excursion - (reftex-erase-buffer "*toc*") - (reftex-erase-all-selection-and-index-buffers))) - - (if (and (null (symbol-value reftex-docstruct-symbol)) - (not (member rescan '(t 1 (4) (16)))) - reftex-save-parse-info) - ;; Try to read the stuff from a file - (reftex-access-parse-file 'read)) - - (cond - ((equal rescan -1)) ;; We are not allowed to scan. - ((not (symbol-value reftex-docstruct-symbol)) - ;; Scan the whole document - (reftex-do-parse 1 file)) - ((member rescan '(t 1 (4) (16))) - ;; Scan whatever was required by the caller. - (reftex-do-parse rescan file)))) - -(defun reftex-scanning-info-available-p () - "Is the scanning info about the current document available?" - (unless reftex-docstruct-symbol - (reftex-tie-multifile-symbols)) - (and (symbolp reftex-docstruct-symbol) - (symbol-value reftex-docstruct-symbol) - t)) - -(defun reftex-silence-toc-markers (list n) - "Set all toc markers in the first N entries in LIST to nil." - (while (and list (> (decf n) -1)) - (and (eq (car (car list)) 'toc) - (markerp (nth 4 (car list))) - (set-marker (nth 4 (car list)) nil)) - (pop list))) - -(defun reftex-access-parse-file (action) - "Perform ACTION on the parse file (the .rel file). -Valid actions are: readable, restore, read, kill, write. -For non-file buffers, persistence operations are skipped." - (let* ((list (symbol-value reftex-docstruct-symbol)) - (docstruct-symbol reftex-docstruct-symbol) - (master (reftex-TeX-master-file)) - (enable-local-variables nil) - (non-file (bufferp master)) - (file (if non-file - nil - (if (string-match "\\.[a-zA-Z]+\\'" master) - (concat (substring master 0 (match-beginning 0)) - reftex-parse-file-extension) - (concat master reftex-parse-file-extension))))) - (cond - ;; For non-file buffers, skip file operations but allow initialization. - (non-file (cond ((eq action 'readable) nil) - ((eq action 'read) nil) - ((eq action 'kill) t) - ((eq action 'restore) - (error "Cannot restore for non-file buffer")))) - ((eq action 'readable) - (file-readable-p file)) - ((eq action 'restore) - (put reftex-docstruct-symbol 'modified nil) - (if (eq reftex-docstruct-symbol nil) - ;; Symbols are not yet tied: Tie them. - (reftex-tie-multifile-symbols)) - (if (file-exists-p file) - ;; load the file and return t for success - (condition-case nil - (progn (load-file file) t) - (error (set reftex-docstruct-symbol nil) - (error "Error while loading file %s" file))) - ;; Throw an exception if the file does not exist - (error "No restore file %s" file))) - ((eq action 'read) - (put reftex-docstruct-symbol 'modified nil) - (if (file-exists-p file) - ;; load the file and return t for success - (condition-case nil - (progn - (load-file file) - (reftex-check-parse-consistency) - t) - (error (message "Error while restoring file %s" file) - (set reftex-docstruct-symbol nil) - nil)) - ;; return nil for failure, but no exception - nil)) - ((eq action 'kill) - ;; Remove the file - (when (and (file-exists-p file) (file-writable-p file)) - (message "Unlinking file %s" file) - (delete-file file))) - (t - (put docstruct-symbol 'modified nil) - (save-excursion - (if (file-writable-p file) - (with-temp-file file - (message "Writing parse file %s" (abbreviate-file-name file)) - (insert ";; RefTeX parse info file\n") - (insert (format ";; File: %s\n" master)) - (insert (format ";; User: %s (%s)\n\n" - (user-login-name) (user-full-name))) - (insert "(set reftex-docstruct-symbol '(\n\n") - (let ((standard-output (current-buffer))) - (mapc - (lambda (x) - (cond ((eq (car x) 'toc) - ;; A toc entry. Do not save the marker. - ;; Save the markers position at position 8 - (print (list 'toc "toc" (nth 2 x) (nth 3 x) - nil (nth 5 x) (nth 6 x) (nth 7 x) - (or (and (markerp (nth 4 x)) - (marker-position (nth 4 x))) - (nth 8 x))))) - ((and (not (eq t reftex-support-index)) - (eq (car x) 'index)) - ;; Don't save index entries - ) - (t (print x)))) - list)) - (insert "))\n\n")) - (error "Cannot write to file %s" file))) - t)))) - -(defun reftex-check-parse-consistency () - "Check if parse file is consistent, throw an error if not." - - ;; Check if the master is the same: when moving a document, this will see it. - (let* ((real-master (reftex-TeX-master-file)) - (parsed-master - (nth 1 (assq 'bof (symbol-value reftex-docstruct-symbol))))) - ;; Skip this check for buffer objects. - (unless (equal (reftex--get-truename real-master) - (reftex--get-truename parsed-master)) - (message "Master file name in load file is different: %s versus %s" - parsed-master real-master) - (error "Master file name error"))) - - ;; Check for the existence of all document files -;;; (let* ((all (symbol-value reftex-docstruct-symbol))) -;;; (while all -;;; (when (and (eq (car (car all)) 'bof) -;;; (not (file-regular-p (nth 1 (car all))))) -;;; (message "File %s in saved parse info not available" (cdr (car all))) -;;; (error "File not found")) -;;; (setq all (cdr all)))) - ) - -(defun reftex-select-external-document (xr-alist xr-index) - "Return index of an external document." - (let* ((len (length xr-alist)) (highest (1- (+ ?0 len))) - (prompt (format "[%c-%c] Select TAB: Read prefix with completion" - ?0 highest)) - key prefix) - (cond - ((= len 1) - (message "No external documents available") - (ding) (sit-for 1) 0) - ((= len 2) - (- 1 xr-index)) - (t - (save-excursion - (let* ((length (apply #'max (mapcar - (lambda(x) (length (car x))) xr-alist))) - (fmt (format " [%%c] %%-%ds %%s\n" length)) - (n (1- ?0))) - (setq key - (reftex-select-with-char - prompt - (concat - "SELECT EXTERNAL DOCUMENT\n------------------------\n" - (mapconcat - (lambda (x) - (format fmt (incf n) (or (car x) "") - (reftex--abbreviate-name (cdr x)))) - xr-alist "")) - nil t)) - (cond - ((and (>= key ?0) (<= key highest)) (- key ?0)) - ((= key ?\C-i) - (setq prefix (completing-read "Prefix: " xr-alist nil t)) - (- len (length (memq (assoc prefix xr-alist) xr-alist)))) - (t (error "Invalid document selection [%c]" key))))))))) - -;;; ========================================================================= -;;; -;;; Finding files - -(defun reftex-locate-file (file type master-dir &optional die) - "Find FILE of type TYPE in MASTER-DIR or on the path associated with TYPE. -If the file does not have any of the valid extensions for TYPE, -try first the default extension and only then the naked file name. -When DIE is non-nil, throw an error if file not found. -When FILE is a buffer object, return that buffer." - (if (bufferp file) - file - (let* ((rec-values (if reftex-search-unrecursed-path-first '(nil t) '(t))) - (extensions (cdr (assoc type reftex-file-extensions))) - (def-ext (car extensions)) - (ext-re (concat "\\(" - (mapconcat #'regexp-quote extensions "\\|") - "\\)\\'")) - (files (if (string-match ext-re file) - (cons file nil) - (if reftex-try-all-extensions - (append (mapcar (lambda (x) (concat file x)) - extensions) - (list file)) - (list (concat file def-ext) file)))) - path old-path file1 f fs) - (cond - ((file-name-absolute-p file) - (while (setq f (pop files)) - (if (file-regular-p f) - (setq file1 f files nil)))) - ((and reftex-use-external-file-finders - (assoc type reftex-external-file-finders)) - (setq file1 (reftex-find-file-externally file type master-dir))) - (t - (while (and (null file1) rec-values) - (setq path (reftex-access-search-path - type (pop rec-values) master-dir file)) - (setq fs files) - (while (and (null file1) (setq f (pop fs))) - (when (or (null old-path) - (not (eq old-path path))) - (setq old-path path - path (cons master-dir path)) - (setq file1 (reftex-find-file-on-path f path master-dir))))))) - (cond (file1 file1) - (die (error "No such file: %s" file)) - (t (message "No such file: %s (ignored)" file) nil))))) - -(defun reftex-find-file-externally (file type &optional master-dir) - "Use external program to find FILE. -The program is taken from `reftex-external-file-finders'. -Interpret relative path definitions starting from MASTER-DIR." - (let ((default-directory (or master-dir default-directory)) - (prg (cdr (assoc type reftex-external-file-finders))) - out) - (if (string-match "%f" prg) - (setq prg (replace-match file t t prg))) - (setq out (apply #'reftex-process-string (split-string prg))) - (if (string-match "[ \t\n]+\\'" out) ; chomp - (setq out (replace-match "" nil nil out))) - (cond ((equal out "") nil) - ((file-regular-p out) (expand-file-name out master-dir)) - (t nil)))) - -(defun reftex-process-string (program &rest args) - "Execute PROGRAM with arguments ARGS and return its STDOUT as a string." - (let ((calling-dir default-directory)) ; remember default directory - (with-output-to-string - (with-current-buffer standard-output - (let ((default-directory calling-dir)) ; set default directory - (apply #'call-process program nil '(t nil) nil args)))))) - -(defun reftex-access-search-path (type &optional recurse master-dir file) - "Access path from environment variables. TYPE is either \"tex\" or \"bib\". -When RECURSE is t, expand path elements ending in `//' recursively. -Relative path elements are left as they are. However, relative recursive -elements are expanded with MASTER-DIR as default directory. -The expanded path is cached for the next search. -FILE is just for the progress message. -Returns the derived path." - (let* ((pathvar (intern (concat "reftex-" type "-path")))) - (when (null (get pathvar 'status)) - ;; Get basic path - (set pathvar - (reftex-uniquify - (reftex-parse-colon-path - (mapconcat - (lambda(x) - (if (string-match "^!" x) - (apply #'reftex-process-string - (split-string (substring x 1))) - (or (getenv x) x))) - ;; For consistency, the next line should look like this: - ;; (cdr (assoc type reftex-path-environment)) - ;; However, historically we have separate options for the - ;; environment variables, so we have to do this: - (symbol-value (intern (concat "reftex-" type - "path-environment-variables"))) - path-separator)))) - (put pathvar 'status 'split) - ;; Check if we have recursive elements - (let ((path (symbol-value pathvar)) dir rec) - (while (setq dir (pop path)) - (when (string= (substring dir -2) "//") - (if (file-name-absolute-p dir) - (setq rec (or rec 'absolute)) - (setq rec 'relative)))) - (put pathvar 'rec-type rec))) - - (if recurse - ;; Return the recursive expansion of the path - (cond - ((not (get pathvar 'rec-type)) - ;; Path does not contain recursive elements - use simple path - (symbol-value pathvar)) - ((or (not (get pathvar 'recursive-path)) - (and (eq (get pathvar 'rec-type) 'relative) - (not (equal master-dir (get pathvar 'master-dir))))) - ;; Either: We don't have a recursive expansion yet. - ;; or: Relative recursive path elements need to be expanded - ;; relative to new default directory - (message "Expanding search path to find %s file: %s ..." type file) - (put pathvar 'recursive-path - (reftex-expand-path (symbol-value pathvar) master-dir)) - (put pathvar 'master-dir master-dir) - (get pathvar 'recursive-path)) - (t - ;; Recursive path computed earlier is still OK. - (get pathvar 'recursive-path))) - ;; The simple path was requested - (symbol-value pathvar)))) - -(defun reftex-find-file-on-path (file path &optional def-dir) - "Find FILE along the directory list PATH. -DEF-DIR is the default directory for expanding relative path elements." - (catch 'exit - (when (file-name-absolute-p file) - (if (file-regular-p file) - (throw 'exit file) - (throw 'exit nil))) - (let* ((thepath path) file1 dir) - (while (setq dir (pop thepath)) - (when (string= (substring dir -2) "//") - (setq dir (substring dir 0 -1))) - (setq file1 (expand-file-name file (expand-file-name dir def-dir))) - (if (file-regular-p file1) - (throw 'exit file1))) - ;; No such file - nil))) - -(defun reftex-parse-colon-path (path) - "Like parse-colon-parse, but // or /~ are left alone. -Trailing ! or !! will be converted into `//' (emTeX convention)" - (mapcar - (lambda (dir) - (if (string-match "\\(//+\\|/*!+\\)\\'" dir) - (setq dir (replace-match "//" t t dir))) - (file-name-as-directory dir)) - (delete "" (split-string path (concat path-separator "+"))))) - -(defun reftex-expand-path (path &optional default-dir) - "Expand parts of path ending in `//' recursively into directory list. -Relative recursive path elements are expanded relative to DEFAULT-DIR." - (let (path1 dir recursive) - (while (setq dir (pop path)) - (if (setq recursive (string= (substring dir -2) "//")) - (setq dir (substring dir 0 -1))) - (if (and recursive - (not (file-name-absolute-p dir))) - (setq dir (expand-file-name dir default-dir))) - (if recursive - ;; Expand recursively - (setq path1 (append (reftex-recursive-directory-list dir) path1)) - ;; Keep unchanged - (push dir path1))) - (nreverse path1))) - -(defun reftex-recursive-directory-list (dir) - "Return a list of all directories below DIR, including DIR itself." - (let ((path (list dir)) path1 file files) - (while (setq dir (pop path)) - (when (file-directory-p dir) - (setq files (nreverse (directory-files dir t "[^.]"))) - (while (setq file (pop files)) - (if (file-directory-p file) - (push (file-name-as-directory file) path))) - (push dir path1))) - path1)) - -;;; ========================================================================= -;;; -;;; Some generally useful functions - -(defun reftex-typekey-check (typekey conf-variable &optional n) - "Check if CONF-VARIABLE is true or contains TYPEKEY." - (and n (setq conf-variable (nth n conf-variable))) - (or (eq conf-variable t) - (and (stringp conf-variable) - (let ((case-fold-search nil)) - (string-match (concat "[" conf-variable "]") typekey))))) - -(defun reftex-check-recursive-edit () - "Check if we are already in a recursive edit. -Abort with helpful message if so." - (if (marker-position reftex-recursive-edit-marker) - (error - (substitute-command-keys - "In unfinished selection process. Finish, or abort with \\[abort-recursive-edit]")))) - -(defun reftex-in-comment () - "Return non-nil if point is in a comment." - (save-excursion - (save-match-data - (let ((pos (point))) - (beginning-of-line) - (re-search-forward - (or comment-start-skip - ;; The parser may open files in fundamental mode if - ;; `reftex-initialize-temporary-buffers' is nil, so here - ;; is a default suitable for plain TeX and LaTeX. - "\\(\\(^\\|[^\\\n]\\)\\(\\\\\\\\\\)*\\)\\(%+[ \t]*\\)") - pos t))))) - -(defun reftex-no-props (string) - "Return STRING with all text properties removed." - (and (stringp string) - (set-text-properties 0 (length string) nil string)) - string) - -(defun reftex-match-string (n) - "Match string without properties." - (when (match-beginning n) - (buffer-substring-no-properties (match-beginning n) (match-end n)))) - -(define-obsolete-function-alias 'reftex-region-active-p #'use-region-p "28.1") - -(defun reftex-kill-buffer (buffer) - "Kill BUFFER if it exists." - (and (setq buffer (get-buffer buffer)) - (kill-buffer buffer))) - -(defun reftex-erase-buffer (&optional buffer) - "Erase BUFFER if it exists. BUFFER defaults to current buffer. -This even erases read-only buffers." - (cond - ((null buffer) - ;; erase current buffer - (let ((buffer-read-only nil)) (erase-buffer))) - ((setq buffer (get-buffer buffer)) - ;; buffer exists - (with-current-buffer buffer - (let ((inhibit-read-only t)) (erase-buffer)))))) - -(defun reftex-this-word (&optional class) - "Grab the word around point." - (setq class (or class "-a-zA-Z0-9:_/.*;|")) - (save-excursion - (buffer-substring-no-properties - (progn (skip-chars-backward class) (point)) - (progn (skip-chars-forward class) (point))))) - -(defun reftex-number (n unit &optional ending) - (if (and (integerp n) (stringp unit)) - (format "%d %s%s" n unit (if (= n 1) "" (or ending "s"))) - "")) - -(defun reftex-all-assq (key list) - "Return a list of all associations of KEY in LIST. Comparison with eq." - (let (rtn) - (while (setq list (memq (assq key list) list)) - (push (car list) rtn) - (pop list)) - (nreverse rtn))) - -(defun reftex-all-assoc-string (key list) - "Return a list of all associations of KEY in LIST. Comparison with string=." - (let (rtn) - (while list - (if (string= (car (car list)) key) - (push (car list) rtn)) - (pop list)) - (nreverse rtn))) - -(defun reftex-last-assoc-before-elt (key elt list &optional exclusive) - "Find the last association of KEY in LIST before or at ELT. -ELT is found in LIST with equal, not eq. -Returns nil when either KEY or elt are not found in LIST. -When EXCLUSIVE is non-nil, ELT cannot be the return value. -On success, returns the association." - (let* ((elt (car (member elt list))) (ex (not exclusive)) ass last-ass) - (while (and (setq ass (assoc key list)) - (setq list (memq ass list)) - (or ex (not (eq elt (car list)))) - (memq elt list)) - (setq last-ass ass - list (cdr list))) - last-ass)) - -(defun reftex-sublist-nth (list nth predicate &optional completion) - "Make a list of the NTH elements of all members of LIST which fulfill PREDICATE. -When COMPLETION is non-nil, make all elements of the resulting -list also a list, so that the result can be used for completion." - (let (rtn) - (while list - (if (funcall predicate (car list)) - (push (if completion - (list (nth nth (car list))) - (nth nth (car list))) - rtn)) - (setq list (cdr list))) - (nreverse rtn))) - -(defun reftex-make-selection-buffer-name (type &optional index) - "Make unique name for a selection buffer." - (format " *RefTeX[%s][%d]*" - type (or index (get reftex-docstruct-symbol :master-index) 0))) - -(defun reftex-make-index-buffer-name (tag &optional cnt) - "Make unique name for an index buffer." - (format "*Index[%s][%d]*" - tag (or cnt (get reftex-docstruct-symbol :master-index) 0))) - -(defun reftex-truncate (string ncols &optional ellipses padding) - "Truncate STRING to NCOLS characters. -When PADDING is non-nil, and string is shorter than NCOLS, fill with -white space to NCOLS characters. When ELLIPSES is non-nil and the -string needs to be truncated, replace last 3 characters by dots." - (setq string - (if (<= (length string) ncols) - string - (if ellipses - (concat (substring string 0 (- ncols 3)) "...") - (substring string 0 ncols)))) - (if padding - (format (format "%%-%ds" ncols) string) - string)) - -(defun reftex-nearest-match (regexp &optional max-length) - "Find the nearest match of REGEXP. Set the match data. -If POS is given, calculate distances relative to it. -Return nil if there is no match." - (let ((pos (point)) - (dist (or max-length (length regexp))) - match1 match2 match) - (goto-char (min (+ pos dist) (point-max))) - (when (re-search-backward regexp nil t) - (setq match1 (match-data))) - (goto-char (max (- pos dist) (point-min))) - (when (re-search-forward regexp nil t) - (setq match2 (match-data))) - (goto-char pos) - (setq match - (cond - ((not match1) match2) - ((not match2) match1) - ((< (abs (- pos (car match1))) (abs (- pos (car match2)))) match1) - (t match2))) - (if match (progn (set-match-data match) t) nil))) - -(defun reftex-auto-mode-alist () - "Return an `auto-mode-alist' with only the .gz (etc) thingies. -Stolen from gnus nnheader." - (let ((alist auto-mode-alist) - out) - (while alist - (when (listp (cdr (car alist))) - (push (car alist) out)) - (pop alist)) - (nreverse out))) - -(defun reftex-enlarge-to-fit (buf2 &optional keep-current) - "Enlarge other window displaying buffer to show whole buffer if possible. -If KEEP-CURRENT in non-nil, current buffer must remain visible." - (let* ((win1 (selected-window)) - (buf1 (current-buffer)) - (win2 (get-buffer-window buf2))) ;; Only on current frame. - (when win2 - (select-window win2) - (unless (and (pos-visible-in-window-p (point-min)) - (pos-visible-in-window-p (point-max))) - (enlarge-window (1+ (- (count-lines (point-min) (point-max)) - (window-height)))))) - (cond - ((window-live-p win1) (select-window win1)) - (keep-current - ;; we must have the old buffer! - (switch-to-buffer-other-window buf1) - (shrink-window (- (window-height) window-min-height)))))) - -(defun reftex-select-with-char (prompt help-string &optional delay-time scroll) - "Offer to select something with PROMPT. -After DELAY-TIME seconds, also with HELP-STRING. When SCROLL is -non-nil, use \\`SPC' and \\`DEL' to scroll help window." - (let ((char ?\?)) - (save-window-excursion - (catch 'exit - (message "%s (?=Help)" prompt) - (when (or (sit-for (or delay-time 0)) - (= ?\? (setq char (read-char-exclusive)))) - (reftex-kill-buffer "*RefTeX Select*") - (switch-to-buffer-other-window "*RefTeX Select*") - (insert help-string) - (goto-char 1) - (unless (and (pos-visible-in-window-p (point-min)) - (pos-visible-in-window-p (point-max))) - (enlarge-window (1+ (- (count-lines (point-min) (point-max)) - (window-height))))) - (setq truncate-lines t)) - (if (and (pos-visible-in-window-p (point-min)) - (pos-visible-in-window-p (point-max))) - nil - (setq prompt (concat prompt (if scroll " (SPC/DEL=Scroll)" "")))) - (message "%s" prompt) - (and (equal char ?\?) (setq char (read-char-exclusive))) - (while t - (cond ((equal char ?\C-g) (keyboard-quit)) - ((equal char ?\?)) - ((and scroll (equal char ?\ )) - (condition-case nil (scroll-up) (error nil)) - (message "%s" prompt)) - ((and scroll (equal char ?\C-? )) - (condition-case nil (scroll-down) (error nil)) - (message "%s" prompt)) - (t (message "") - (reftex-kill-buffer "*RefTeX Select*") - (throw 'exit char))) - (setq char (read-char-exclusive))))))) - - -(defun reftex-make-regexp-allow-for-ctrl-m (string) - "Convert STRING into a regexp, allowing ^M for \\n and vice versa." - (let ((start -2)) - (setq string (regexp-quote string)) - (while (setq start (string-match "[\n\r]" string (+ 3 start))) - (setq string (replace-match "[\n\r]" nil t string))) - string)) - -(define-obsolete-function-alias 'reftex-get-buffer-visiting - #'find-buffer-visiting "28.1") - -(defun reftex-visited-files (list) - "Takes a list of filenames and returns the buffers of those already visited." - (delq nil (mapcar (lambda (x) (if (find-buffer-visiting x) x nil)) - list))) - -(defun reftex-get-file-buffer-force (file &optional mark-to-kill) - "Return a buffer visiting file. Make one, if necessary. -If neither such a buffer nor the file exist, return nil. -If MARK-TO-KILL is t and there is no live buffer, visit the file with -initializations according to `reftex-initialize-temporary-buffers', -and mark the buffer to be killed after use." - - (let ((buf (if (bufferp file) - file - (find-buffer-visiting file)))) - - (cond (buf - ;; We have it already as a buffer - just return it - buf) - - ((file-readable-p file) - ;; At least there is such a file and we can read it. - - (if (or (not mark-to-kill) - (eq t reftex-initialize-temporary-buffers)) - - ;; Visit the file with full magic - (setq buf (find-file-noselect file)) - - ;; Else: Visit the file just briefly, without or - ;; with limited Magic - - ;; The magic goes away - (cl-letf ((format-alist nil) - (auto-mode-alist (reftex-auto-mode-alist)) - ((default-value 'major-mode) 'fundamental-mode) - (enable-local-variables nil) - (after-insert-file-functions nil)) - (setq buf (find-file-noselect file))) - - ;; Is there a hook to run? - (when (listp reftex-initialize-temporary-buffers) - (with-current-buffer buf - (run-hooks 'reftex-initialize-temporary-buffers)))) - - ;; Let's see if we got a license to kill :-| - (and mark-to-kill - (cl-pushnew buf reftex-buffers-to-kill)) - - ;; Return the new buffer - buf) - - ;; If no such file exists, return nil - (t nil)))) - -(defun reftex-kill-temporary-buffers (&optional buffer) - "Kill all buffers in the list reftex-kill-temporary-buffers." - (cond - (buffer - (when (member buffer reftex-buffers-to-kill) - (kill-buffer buffer) - (setq reftex-buffers-to-kill - (delete buffer reftex-buffers-to-kill)))) - (t - (while (setq buffer (pop reftex-buffers-to-kill)) - (when (bufferp buffer) - (and (buffer-modified-p buffer) - (y-or-n-p (format "Save file %s? " - (buffer-file-name buffer))) - (with-current-buffer buffer - (save-buffer))) - (kill-buffer buffer)) - (pop reftex-buffers-to-kill))))) - -(defun reftex-splice-symbols-into-list (list alist) - "Splice the association in ALIST of any symbols in LIST into the list. -Return new list." - (let (rtn tmp) - (while list - (while (and (not (null (car list))) ;; keep list elements nil - (symbolp (car list))) - (setq tmp (car list)) - (cond - ((assoc tmp alist) - (setq list (append (nth 2 (assoc tmp alist)) (cdr list)))) - (t - (error "Cannot treat symbol %s in reftex-label-alist" - (symbol-name tmp))))) - (push (pop list) rtn)) - (nreverse rtn))) - -(defun reftex-uniquify (list &optional sort) - "Return a list of all strings in LIST, but each only once. -Keep order unless SORT is set (faster!)." - (setq list (copy-sequence list)) - (if sort - (progn - (setq list (sort list #'string<)) - (let ((p list)) - (while (cdr p) - (if (string= (car p) (car (cdr p))) - (setcdr p (cdr (cdr p))) - (setq p (cdr p))))) - list) - (let ((p list) lst elt) - ;; push all sublists into lst in reverse(!) order - (while p - (push p lst) - (setq p (cdr p))) - ;; sort all sublists - (setq lst (sort lst (lambda (x1 x2) (string< (car x1) (car x2))))) - (while (cdr lst) - (setq elt (car (car lst))) - ;; for equal elements in the sorted sublist, replace the - ;; last(!) original list member with nil - (when (string= elt (car (cadr lst))) - (setcar (pop lst) nil) - (while (and (cdr lst) (string= elt (car (cadr lst)))) - (setcar (pop lst) nil))) - (pop lst))) - ;; weed out all nils and return. - (delq nil list))) - -(defun reftex-uniquify-by-car (alist &optional keep-list sort) - "Return a list of all elements in ALIST, but each car only once. -Elements of KEEP-LIST are not removed even if duplicate. -The order is kept unless SORT is set (faster!)." - (setq keep-list (sort (copy-sequence keep-list) #'string<) - alist (copy-sequence alist)) - (if sort - (let (lst elt) - (setq alist (sort alist (lambda(a b) (string< (car a) (car b))))) - (setq lst alist) - (while (cdr lst) - (setq elt (car (car lst))) - (when (string= elt (car (cadr lst))) - (while (and keep-list (string< (car keep-list) elt)) - (pop keep-list)) - (if (and keep-list (string= elt (car keep-list))) - (progn - (pop lst) - (while (and (cdr lst) - (string= elt (car (cadr lst)))) - (pop lst))) - (setcdr lst (cdr (cdr lst))) - (while (and (cdr lst) - (string= elt (car (cadr lst)))) - (setcdr lst (cdr (cdr lst)))))) - (pop lst)) - alist) - (let ((p alist) lst elt) - (while p - (push p lst) - (setq p (cdr p))) - (setq lst (sort lst (lambda(a b) (string< (car (car a)) - (car (car b)))))) - (while (cdr lst) - (setq elt (car (car (car lst)))) - (when (string= elt (car (car (cadr lst)))) - (while (and keep-list (string< (car keep-list) elt)) - (pop keep-list)) - (if (and keep-list (string= elt (car keep-list))) - (progn - (pop lst) - (while (and (cdr lst) - (string= elt (car (car (cadr lst))))) - (pop lst))) - (setcar (pop lst) nil) - (while (and (cdr lst) - (string= elt (car (car (cadr lst))))) - (setcar (pop lst) nil)))) - (pop lst))) - (delq nil alist))) - -(defun reftex-remove-if (predicate list) - "Nondestructively remove all items from LIST which satisfy PREDICATE." - (let (result) - (dolist (elt list (nreverse result)) - (unless (funcall predicate elt) - (push elt result))))) - -(defun reftex-abbreviate-title (string) - (reftex-convert-string string "[-~ \t\n\r,;]" nil t t - 5 40 nil 1 " " (nth 5 reftex-derive-label-parameters))) - -(defun reftex-convert-string (string split-re invalid-re dot keep-fp - nwords maxchar invalid abbrev sep - ignore-words &optional downcase) - "Convert STRING (a sentence) to something shorter. -SPLIT-RE is the regular expression used to split the string into words. -INVALID-RE matches characters which are invalid in the final string. -DOT t means add dots to abbreviated words. -KEEP-FP t means to keep a final punctuation when applicable. -NWORDS Number of words to use. -MAXCHAR Maximum number of characters in the final string. -INVALID nil: Throw away any words containing stuff matched with INVALID-RE. - t: Throw away only the matched part, not the whole word. -ABBREV nil: Never abbreviate words. - t: Always abbreviate words (see `reftex-abbrev-parameters'). - not t and not nil: Abbreviate words if necessary to shorten - string below MAXCHAR. -SEP String separating different words in the output string. -IGNORE-WORDS List of words which should be removed from the string." - - (let* ((words0 (split-string string (or split-re "[ \t\n\r]"))) - (reftex-label-illegal-re (or invalid-re "\000")) - (abbrev-re (concat - "\\`\\(" - (make-string (nth 0 reftex-abbrev-parameters) ?.) - "[" (nth 2 reftex-abbrev-parameters) "]*" - "\\)" - "[" (nth 3 reftex-abbrev-parameters) "]" - (make-string (1- (nth 1 reftex-abbrev-parameters)) ?.))) - words word) - - ;; Remove words from the ignore list or with funny characters - (while (setq word (pop words0)) - (if downcase (setq word (downcase word))) - (cond - ((member (downcase word) ignore-words)) - ((string-match reftex-label-illegal-re word) - (when invalid - (while (string-match reftex-label-illegal-re word) - (setq word (replace-match "" nil nil word))) - (push word words))) - (t - (push word words)))) - (setq words (nreverse words)) - - ;; Restrict number of words - (if (> (length words) nwords) - (setcdr (nthcdr (1- nwords) words) nil)) - - ;; First, try to use all words - (setq string (mapconcat #'identity words sep)) - - ;; Abbreviate words if enforced by user settings or string length - (if (or (eq t abbrev) - (and abbrev - (> (length string) maxchar))) - (setq words - (mapcar - (lambda (w) (if (string-match abbrev-re w) - (if dot - (concat (match-string 1 w) ".") - (match-string 1 w)) - w)) - words) - string (mapconcat #'identity words sep))) - - ;; Shorten if still to long - (setq string - (if (> (length string) maxchar) - (substring string 0 maxchar) - string)) - - ;; Delete the final punctuation, if any - (if (and (not keep-fp) (string-match "\\s.+\\'" string)) - (setq string (replace-match "" nil nil string))) - string)) - -(defun reftex-nicify-text (text) - "Make TEXT nice for inclusion as context into label menu." - ;; 1. remove line breaks and extra white space - (while (string-match "[\n\r\t]\\|[ \t][ \t]+" text) - (setq text (replace-match " " nil t text))) - ;; 2. cut before the next `\end{' or `\item' or `\\' - (if (string-match "\\(\\\\end{\\|\\\\item\\|\\\\\\\\\\).*" text) - (setq text (replace-match "" nil t text))) - ;; 3. kill the embedded label - (if (string-match "\\\\label{[^}]*}" text) - (setq text (replace-match "" nil t text))) - ;; 4. remove leading garbage - (if (string-match "\\`[ }]+" text) - (setq text (replace-match "" nil t text))) - ;; 5. limit length - (cond - ((> (length text) 100) (substring text 0 100)) - ((= (length text) 0) (make-string 1 ?\ )) - (t text))) - - -;;; ========================================================================= -;;; -;;; Fontification and Highlighting - -(defun reftex-refontify () - "Return t if we need to refontify context." - (and reftex-use-fonts - (or (eq t reftex-refontify-context) - (and (eq 1 reftex-refontify-context) - ;; Test of we use the font-lock version of x-symbol - (and (featurep 'x-symbol-tex) (not (boundp 'x-symbol-mode))))))) - -(defun reftex-fontify-select-label-buffer (parent-buffer) - "Fontify the `*RefTeX Select*' buffer. -Buffer is temporarily renamed to start with none-SPC char, because -Font-Lock otherwise refuses operation." - (run-hook-with-args 'reftex-pre-refontification-functions - parent-buffer 'reftex-ref) - (let* ((oldname (buffer-name)) - (newname (concat "Fontify-me-" oldname))) - (unwind-protect - (progn - ;; Rename buffer temporarily to start without space (because - ;; of font-lock) - (rename-buffer newname t) - ;; Good: we have the indirection functions - (setq-local font-lock-fontify-region-function - #'reftex-select-font-lock-fontify-region) - (let ((major-mode 'latex-mode)) - (font-lock-mode 1))) - (rename-buffer oldname)))) - -(defun reftex-select-font-lock-fontify-region (beg end &optional _loudly) - "Fontify a region, but only lines starting with a dot." - (let ((func (if (fboundp 'font-lock-default-fontify-region) - 'font-lock-default-fontify-region - 'font-lock-fontify-region)) - beg1 end1) - (goto-char beg) - (while (re-search-forward "^\\." end t) - (setq beg1 (point) end1 (progn (skip-chars-forward "^\n") (point))) - (funcall func beg1 end1 nil) - (goto-char end1)))) - -(defun reftex-select-font-lock-unfontify (&rest _ignore) t) - -(defun reftex-verified-face (&rest faces) - "Return the first valid face in FACES, or nil if none is valid. -Also, when finding a nil element in FACES, return nil. This -function is just a safety net to catch name changes of builtin -fonts. Currently it is only used for reftex-label-face." - (let (face) - (catch 'exit - (while (setq face (pop faces)) - (if (facep face) (throw 'exit face)))))) - -(define-obsolete-function-alias 'reftex-make-overlay #'make-overlay "28.1") -(define-obsolete-function-alias 'reftex-overlay-put #'overlay-put "28.1") -(define-obsolete-function-alias 'reftex-move-overlay #'move-overlay "28.1") -(define-obsolete-function-alias 'reftex-delete-overlay #'delete-overlay "28.1") - -;; We keep a vector with several different overlays to do our highlighting. -(defvar reftex-highlight-overlays [nil nil nil]) - -;; Initialize the overlays -(aset reftex-highlight-overlays 0 (make-overlay 1 1)) -(overlay-put (aref reftex-highlight-overlays 0) - 'face 'highlight) -(aset reftex-highlight-overlays 1 (make-overlay 1 1)) -(overlay-put (aref reftex-highlight-overlays 1) - 'face reftex-cursor-selected-face) -(aset reftex-highlight-overlays 2 (make-overlay 1 1)) -(overlay-put (aref reftex-highlight-overlays 2) - 'face reftex-cursor-selected-face) - -;; Two functions for activating and deactivation highlight overlays -(defun reftex-highlight (index begin end &optional buffer) - "Highlight a region with overlay INDEX." - (move-overlay (aref reftex-highlight-overlays index) - begin end (or buffer (current-buffer)))) -(defun reftex-unhighlight (index) - "Detach overlay INDEX." - (delete-overlay (aref reftex-highlight-overlays index))) - -(defun reftex-highlight-shall-die () - "Function used in pre-command-hook to remove highlights." - (remove-hook 'pre-command-hook #'reftex-highlight-shall-die) - (reftex-unhighlight 0)) - -;;; ========================================================================= -;;; -;;; Keybindings - -(defvar bibtex-mode-map) - -;; Bind `reftex-view-crossref-from-bibtex' in BibTeX mode map -(eval-after-load - "bibtex" - '(define-key bibtex-mode-map "\C-c&" #'reftex-view-crossref-from-bibtex)) - -;;; ========================================================================= -;;; -;;; Menu - -;; Define a menu for the menu bar if Emacs is running under X - -(defvar-local reftex-isearch-minor-mode nil) - -(easy-menu-define reftex-mode-menu reftex-mode-map - "Menu used in RefTeX mode." - `("Ref" - ["Table of Contents" reftex-toc t] - ["Recenter TOC" reftex-toc-recenter t] - "--" - ["\\label" reftex-label t] - ["\\ref" reftex-reference t] - ["\\cite" reftex-citation t] - ("\\index" - ["\\index" reftex-index t] - ["\\index{THIS}" reftex-index-selection-or-word t] - "--" - ["Add THIS to Index Phrases" reftex-index-phrase-selection-or-word t] - ["Visit Phrase Buffer" reftex-index-visit-phrases-buffer t] - ["Apply Phrases to Region" reftex-index-phrases-apply-to-region t] - "--" - ["Display the Index" reftex-display-index t]) - "--" - ["View Crossref" reftex-view-crossref t] - "--" - ("Parse Document" - ["One File" reftex-parse-one reftex-enable-partial-scans] - ["Entire Document" reftex-parse-all t] - ["Save to File" (reftex-access-parse-file 'write) - (> (length (symbol-value reftex-docstruct-symbol)) 0)] - ["Restore from File" (reftex-access-parse-file 'restore) t]) - ("Global Actions" - ["Search Whole Document" reftex-search-document t] - ["Search Again" tags-loop-continue t] - ["Replace in Document" reftex-query-replace-document t] - ["Grep on Document" reftex-grep-document t] - "--" - ["Goto Label" reftex-goto-label t] - ["Find Duplicate Labels" reftex-find-duplicate-labels t] - ["Change Label and Refs" reftex-change-label t] - ["Renumber Simple Labels" reftex-renumber-simple-labels t] - "--" - ["Create BibTeX File" reftex-create-bibtex-file t] - "--" - ["Create TAGS File" reftex-create-tags-file t] - "--" - ["Save Document" reftex-save-all-document-buffers t]) - "--" - ("Options" - "PARSER" - ["Partial Scans" - (setq reftex-enable-partial-scans (not reftex-enable-partial-scans)) - :style toggle :selected reftex-enable-partial-scans] - ["Auto-Save Parse Info" - (setq reftex-save-parse-info (not reftex-save-parse-info)) - :style toggle :selected reftex-save-parse-info] - "--" - "TOC RECENTER" - ["Automatic Recenter" reftex-toggle-auto-toc-recenter - :style toggle :selected reftex-toc-auto-recenter-timer] - "--" - "CROSSREF INFO" - ["Automatic Info" reftex-toggle-auto-view-crossref - :style toggle :selected reftex-auto-view-crossref-timer] - ["...in Echo Area" (setq reftex-auto-view-crossref t) - :style radio :selected (eq reftex-auto-view-crossref t)] - ["...in Other Window" (setq reftex-auto-view-crossref 'window) - :style radio :selected (eq reftex-auto-view-crossref 'window)] - "--" - "MISC" - ["AUCTeX Interface" reftex-toggle-plug-into-AUCTeX - :style toggle :selected reftex-plug-into-AUCTeX] - ["isearch whole document" reftex-isearch-minor-mode - :style toggle :selected reftex-isearch-minor-mode]) - ("Reference Style" - ,@(let (list item) - (dolist (elt reftex-ref-style-alist) - (setq elt (car elt) - item (vector - elt - `(reftex-ref-style-toggle ,elt) - :style 'toggle - :selected `(member ,elt (reftex-ref-style-list)))) - (unless (member item list) - (setq list (append list (list item))))) - list)) - ("Citation Style" - ,@(mapcar - (lambda (x) - (vector - (capitalize (symbol-name (car x))) - (list 'reftex-set-cite-format (list 'quote (car x))) - :style 'radio :selected - (list 'eq (list 'reftex-get-cite-format) (list 'quote (car x))))) - reftex-cite-format-builtin) - "--" - "Sort Database Matches" - ["Not" (setq reftex-sort-bibtex-matches nil) - :style radio :selected (eq reftex-sort-bibtex-matches nil)] - ["by Author" (setq reftex-sort-bibtex-matches 'author) - :style radio :selected (eq reftex-sort-bibtex-matches 'author)] - ["by Year" (setq reftex-sort-bibtex-matches 'year) - :style radio :selected (eq reftex-sort-bibtex-matches 'year)] - ["by Year, reversed" (setq reftex-sort-bibtex-matches 'reverse-year) - :style radio :selected (eq reftex-sort-bibtex-matches 'reverse-year)]) - ("Index Style" - ,@(mapcar - (lambda (x) - (vector - (capitalize (symbol-name (car x))) - (list 'reftex-add-index-macros (list 'list (list 'quote (car x)))) - :style 'radio :selected - (list 'memq (list 'quote (car x)) - (list 'get 'reftex-docstruct-symbol - (list 'quote 'reftex-index-macros-style))))) - reftex-index-macros-builtin)) - "--" - ["Reset RefTeX Mode" reftex-reset-mode t] - "--" - ("Customize" - ["Browse RefTeX Group" reftex-customize t] - "--" - ["Build Full Customize Menu" reftex-create-customize-menu]) - ("Documentation" - ["Info" reftex-info t] - ["Commentary" reftex-show-commentary t]))) - -(defun reftex-customize () - "Call the customize function with reftex as argument." - (interactive) - (customize-browse 'reftex)) - -(defun reftex-create-customize-menu () - "Create a full customization menu for RefTeX, insert it into the menu." - (interactive) - (easy-menu-change - '("Ref") "Customize" - `(["Browse RefTeX group" reftex-customize t] - "--" - ,(customize-menu-create 'reftex) - ["Set" Custom-set t] - ["Save" Custom-save t] - ["Reset to Current" Custom-reset-current t] - ["Reset to Saved" Custom-reset-saved t] - ["Reset to Standard Settings" Custom-reset-standard t])) - (message "\"Ref\"-menu now contains full customization menu")) - - -;;; Misc - -(defun reftex-show-commentary () - "Use the finder to view the file documentation from `reftex.el'." - (interactive) - (describe-library "reftex")) - -(defun reftex-info (&optional node) - "Read documentation for RefTeX in the info system. -With optional NODE, go directly to that node." - (interactive) - (info (format "(reftex)%s" (or node "")))) - -(defun reftex-report-bug () - "Report a bug in RefTeX. - -Don't hesitate to report any problems or inaccurate documentation. - -If you don't have setup sending mail from (X)Emacs, please copy the -output buffer into your mail program, as it gives us important -information about your RefTeX version and configuration." - (interactive) - (require 'reporter) - (defvar reporter-prompt-for-summary-p) - (let ((reporter-prompt-for-summary-p "Bug report subject: ")) - (reporter-submit-bug-report - "bug-auctex@gnu.org, bug-gnu-emacs@gnu.org" - reftex-version - (list 'window-system - 'reftex-plug-into-AUCTeX) - nil nil - "Remember to cover the basics, that is, what you expected to happen and -what in fact did happen. - -Check if the bug is reproducible with an up-to-date version of -RefTeX available from https://www.gnu.org/software/auctex/. - -If the bug is triggered by a specific (La)TeX file, you should try -to produce a minimal sample file showing the problem and include it -in your report. - -Your bug report will be posted to the AUCTeX bug reporting list. -------------------------------------------------------------------------"))) - -;;; Install the kill-buffer and kill-emacs hooks ------------------------------ - -(add-hook 'kill-buffer-hook #'reftex-kill-buffer-hook) -(unless noninteractive - (add-hook 'kill-emacs-hook #'reftex-kill-emacs-hook)) - -;;; Run Hook ------------------------------------------------------------------ - -(run-hooks 'reftex-load-hook) - -;;; That's it! ---------------------------------------------------------------- - -(setq reftex-tables-dirty t) ; in case this file is evaluated by hand - -(define-obsolete-function-alias 'reftex-window-height #'window-height "30.1") - -(defun reftex-use-fonts () - (declare (obsolete "use variable `reftex-use-fonts' instead." "30.1")) - reftex-use-fonts) - -(defun reftex-remove-symbols-from-list (list) - (declare (obsolete seq-remove "30.1")) - (seq-remove #'symbolp list)) - -(provide 'reftex) - -;;; reftex.el ends here diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el deleted file mode 100644 index bb47ce31758..00000000000 --- a/lisp/textmodes/tex-mode.el +++ /dev/null @@ -1,4096 +0,0 @@ -;;; tex-mode.el --- TeX, LaTeX, and SliTeX mode commands -*- lexical-binding:t -*- - -;; Copyright (C) 1985-1986, 1989, 1992, 1994-1999, 2001-2025 Free -;; Software Foundation, Inc. - -;; Maintainer: emacs-devel@gnu.org -;; Keywords: tex - -;; Contributions over the years by William F. Schelter, Dick King, -;; Stephen Gildea, Michael Prange, Jacob Gore, and Edward M. Reingold. - -;; 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 . - -;;; Commentary: - -;;; Code: - -(eval-when-compile - (require 'cl-lib) - (require 'skeleton)) - -(require 'shell) -(require 'compile) - -(defgroup tex-file nil - "TeX files and directories." - :prefix "tex-" - :group 'tex) - -(defgroup tex-run nil - "Running external commands from TeX mode." - :prefix "tex-" - :group 'tex) - -(defgroup tex-view nil - "Viewing and printing TeX files." - :prefix "tex-" - :group 'tex) - -(defgroup tex-flymake nil - "Flymake backend for linting TeX files." - :prefix "tex-" - :group 'tex) - -;;;###autoload -(defcustom tex-shell-file-name nil - "If non-nil, the shell file name to run in the subshell used to run TeX." - :type '(choice (const :tag "None" nil) - string) - :group 'tex-run) - -;;;###autoload -(defcustom tex-directory "." - "Directory in which temporary files are written. -You can make this `/tmp' if your TEXINPUTS has no relative directories in it -and you don't try to apply \\[tex-region] or \\[tex-buffer] when there are -`\\input' commands with relative directories." - :type 'directory - :group 'tex-file) - -;;;###autoload -(defcustom tex-first-line-header-regexp nil - "Regexp for matching a first line which `tex-region' should include. -If this is non-nil, it should be a regular expression string; -if it matches the first line of the file, -`tex-region' always includes the first line in the TeX run." - :type '(choice (const :tag "None" nil) - regexp) - :group 'tex-file) - -;;;###autoload -(defcustom tex-main-file nil - "The main TeX source file which includes this buffer's file. -The command `tex-file' runs TeX on the file specified by `tex-main-file' -if the variable is non-nil." - :type '(choice (const :tag "None" nil) - file) - :group 'tex-file) - -;;;###autoload -(defcustom tex-offer-save t - "If non-nil, ask about saving modified buffers before \\[tex-file] is run." - :type 'boolean - :group 'tex-file) - -;;;###autoload -(defcustom tex-run-command "tex" - "Command used to run TeX subjob. -TeX Mode sets `tex-command' to this string. -See the documentation of that variable." - :type 'string - :group 'tex-run) - -;;;###autoload -(defcustom latex-run-command "latex" - "Command used to run LaTeX subjob. -LaTeX Mode sets `tex-command' to this string. -See the documentation of that variable." - :type 'string - :group 'tex-run) - -;;;###autoload -(defcustom slitex-run-command "slitex" - "Command used to run SliTeX subjob. -SliTeX Mode sets `tex-command' to this string. -See the documentation of that variable." - :type 'string - :group 'tex-run) - -;;;###autoload -(defcustom tex-start-options "" - "TeX options to use when starting TeX. -These immediately precede the commands in `tex-start-commands' -and the input file name, with no separating space and are not shell-quoted. -If nil, TeX runs with no options. See the documentation of `tex-command'." - :type 'string - :group 'tex-run - :version "22.1") - -;;;###autoload -(defcustom tex-start-commands "\\nonstopmode\\input" - "TeX commands to use when starting TeX. -They are shell-quoted and precede the input file name, with a separating space. -If nil, no commands are used. See the documentation of `tex-command'." - :type '(radio (const :tag "Interactive (nil)" nil) - (const :tag "Nonstop (\"\\nonstopmode\\input\")" - "\\nonstopmode\\input") - (string :tag "String at your choice")) - :group 'tex-run - :version "22.1") - -(defvar latex-standard-block-names - '("abstract" "array" "center" "description" - "displaymath" "document" "enumerate" "eqnarray" - "eqnarray*" "equation" "figure" "figure*" - "flushleft" "flushright" "itemize" "letter" - "list" "minipage" "picture" "quotation" - "quote" "slide" "sloppypar" "tabbing" - "table" "table*" "tabular" "tabular*" - "thebibliography" "theindex*" "titlepage" "trivlist" - "verbatim" "verbatim*" "verse" "math") - "Standard LaTeX block names.") - -;;;###autoload -(defcustom latex-block-names nil - "User defined LaTeX block names. -Combined with `latex-standard-block-names' for minibuffer completion." - :type '(repeat string) - :group 'tex-run) - -;;;###autoload -(defcustom tex-bibtex-command "bibtex" - "Command used by `tex-bibtex-file' to gather bibliographic data. -If this string contains an asterisk (`*'), that is replaced by the file name; -otherwise, the file name, preceded by blank, is added at the end." - :type 'string - :group 'tex-run) - -;;;###autoload -(defcustom tex-dvi-print-command "lpr -d" - "Command used by \\[tex-print] to print a .dvi file. -If this string contains an asterisk (`*'), that is replaced by the file name; -otherwise, the file name, preceded by blank, is added at the end." - :type 'string - :group 'tex-view) - -;;;###autoload -(defcustom tex-alt-dvi-print-command "lpr -d" - "Command used by \\[tex-print] with a prefix arg to print a .dvi file. -If this string contains an asterisk (`*'), that is replaced by the file name; -otherwise, the file name, preceded by blank, is added at the end. - -If two printers are not enough of a choice, you can set the variable -`tex-alt-dvi-print-command' to an expression that asks what you want; -for example, - - (setq tex-alt-dvi-print-command - \\='(format \"lpr -P%s\" (read-string \"Use printer: \"))) - -would tell \\[tex-print] with a prefix argument to ask you which printer to -use." - :type '(choice (string :tag "Command") - (sexp :tag "Expression")) - :group 'tex-view) - -;;;###autoload -(defcustom tex-dvi-view-command - (cond ((eq window-system 'x) "xdvi") - ((eq window-system 'w32) "yap") - (t "dvi2tty * | cat -s")) - "Command used by \\[tex-view] to display a `.dvi' file. -If this string contains an asterisk (`*'), that is replaced by the file name; -otherwise, the file name, preceded by a space, is added at the end. - -For backwards-compatibility, the value can also be a form, in which case -it is evaluated to get the command to use. This is now obsolete, and -will lead to a warning. Set it to a string instead." - :type '(choice (const nil) string) - :risky t - :group 'tex-view) - -;;;###autoload -(defcustom tex-show-queue-command "lpq" - "Command used by \\[tex-show-print-queue] to show the print queue. -Should show the queue(s) that \\[tex-print] puts jobs on." - :type 'string - :group 'tex-view) - -;;;###autoload -(defcustom tex-default-mode #'latex-mode - "Mode to enter for a new file that might be either TeX or LaTeX. -This variable is used when it can't be determined whether the file -is plain TeX or LaTeX or what because the file contains no commands. -Normally set to either `plain-tex-mode' or `latex-mode'." - :type 'function - :group 'tex) - -;;;###autoload -(defcustom tex-open-quote "``" - "String inserted by typing \\[tex-insert-quote] to open a quotation." - :type 'string - :options '("``" "\"<" "\"`" "<<" "«") - :group 'tex) - -;;;###autoload -(defcustom tex-close-quote "''" - "String inserted by typing \\[tex-insert-quote] to close a quotation." - :type 'string - :options '("''" "\">" "\"'" ">>" "»") - :group 'tex) - -(defcustom tex-fontify-script t - "If non-nil, fontify subscript and superscript strings." - :type 'boolean - :safe #'booleanp - :group 'tex - :version "23.1") - -(defcustom tex-font-script-display '(-0.2 0.2) - "How much to lower and raise subscript and superscript content. -This is a list of two floats. The first is negative and -specifies how much subscript is lowered, the second is positive -and specifies how much superscript is raised. Heights are -measured relative to that of the normal text." - :group 'tex - :type '(list (float :tag "Subscript") - (float :tag "Superscript")) - :version "23.1") - -(defcustom tex-chktex-program "chktex" - "ChkTeX executable to use for linting TeX files." - :version "26.1" - :type 'string - :link '(url-link "man:chktex(1)") - :group 'tex-flymake) - -(defcustom tex-chktex-extra-flags nil - "Extra command line flags for `tex-chktex-program'." - :version "26.1" - :type '(repeat string) - :group 'tex-flymake) - -(defvar tex-last-temp-file nil - "Latest temporary file generated by \\[tex-region] and \\[tex-buffer]. -Deleted when the \\[tex-region] or \\[tex-buffer] is next run, or when the -tex shell terminates.") - -(defvar tex-command "tex" - "Command to run TeX. -If this string contains an asterisk \(`*'), that is replaced by the file name; -otherwise the value of `tex-start-options', the \(shell-quoted) -value of `tex-start-commands', and the file name are added at the end -with blanks as separators. - -In TeX, LaTeX, and SliTeX Mode this variable becomes buffer local.") - -(defvar tex-trailer nil - "String appended after the end of a region sent to TeX by \\[tex-region].") - -(defvar tex-start-of-header nil - "Regular expression used by \\[tex-region] to find start of file's header.") - -(defvar tex-end-of-header nil - "Regular expression used by \\[tex-region] to find end of file's header.") - -(defvar tex-shell-cd-command "cd" - "Command to give to shell running TeX to change directory. -The value of `tex-directory' is appended to this, separated by a space.") - -(defvar tex-zap-file nil - "Temporary file name used for text being sent as input to TeX. -Should be a simple file name with no extension or directory specification.") - -(defvar tex-last-buffer-texed nil - "Buffer which was last TeXed.") - -(defvar tex-print-file nil - "File name that \\[tex-print] prints. -Set by \\[tex-region], \\[tex-buffer], \\[tex-file] and \\[tex-compile].") - -(defvar tex-mode-syntax-table - (let ((st (make-syntax-table))) - (modify-syntax-entry ?% "<" st) - (modify-syntax-entry ?\n ">" st) - (modify-syntax-entry ?\f ">" st) - (modify-syntax-entry ?\C-@ "w" st) - (modify-syntax-entry ?' "w" st) - (modify-syntax-entry ?@ "_" st) - (modify-syntax-entry ?* "_" st) - (modify-syntax-entry ?\t " " st) - ;; ~ is printed by TeX as a space, but it's semantics in the syntax - ;; of TeX is not `whitespace' (i.e. it's just like \hspace{foo}). - (modify-syntax-entry ?~ "." st) - (modify-syntax-entry ?$ "$$" st) - (modify-syntax-entry ?\\ "/" st) - (modify-syntax-entry ?\" "." st) - (modify-syntax-entry ?& "." st) - (modify-syntax-entry ?_ "." st) - (modify-syntax-entry ?^ "." st) - st) - "Syntax table used while in TeX mode.") - -;;;; -;;;; Imenu support -;;;; - -(defcustom latex-imenu-indent-string ". " - "String to add repeated in front of nested sectional units for Imenu. -An alternative value is \" . \", if you use a font with a narrow period." - :type 'string - :group 'tex) - -(defvar latex-section-alist - '(("part" . 0) ("chapter" . 1) - ("section" . 2) ("subsection" . 3) - ("subsubsection" . 4) - ("paragraph" . 5) ("subparagraph" . 6))) - -(defvar latex-metasection-list - '("documentstyle" "documentclass" - "begin{document}" "end{document}" - "appendix" "frontmatter" "mainmatter" "backmatter")) - -(defun latex-imenu-create-index () - "Generate an alist for imenu from a LaTeX buffer." - (let ((section-regexp - (concat "\\\\" (regexp-opt (mapcar #'car latex-section-alist) t) - "\\*?[ \t]*{")) - (metasection-regexp - (concat "\\\\" (regexp-opt latex-metasection-list t))) - i0 menu case-fold-search) - (save-excursion - ;; Find the top-most level in this file but don't allow it to be - ;; any deeper than "section" (which is top-level in an article). - (goto-char (point-min)) - (if (search-forward-regexp "\\\\part\\*?[ \t]*{" nil t) - (setq i0 0) - (if (search-forward-regexp "\\\\chapter\\*?[ \t]*{" nil t) - (setq i0 1) - (setq i0 2))) - - ;; Look for chapters and sections. - (goto-char (point-min)) - (while (search-forward-regexp section-regexp nil t) - (let ((start (match-beginning 0)) - (here (point)) - (i (cdr (assoc (buffer-substring-no-properties - (match-beginning 1) - (match-end 1)) - latex-section-alist)))) - (backward-char 1) - (condition-case nil - (progn - ;; Using sexps allows some use of matching {...} inside - ;; titles. - (forward-sexp 1) - (push (cons (concat (apply #'concat - (make-list - (max 0 (- i i0)) - latex-imenu-indent-string)) - (buffer-substring-no-properties - here (1- (point)))) - start) - menu)) - (error nil)))) - - ;; Look for included material. - (goto-char (point-min)) - (while (search-forward-regexp - "\\\\\\(include\\|input\\|verbatiminput\\|bibliography\\)\ -[ \t]*{\\([^}\n]+\\)}" - nil t) - (push (cons (concat "<<" (buffer-substring-no-properties - (match-beginning 2) - (match-end 2)) - (if (= (char-after (match-beginning 1)) ?b) - ".bbl" - ".tex")) - (match-beginning 0)) - menu)) - - ;; Look for \frontmatter, \mainmatter, \backmatter, and \appendix. - (goto-char (point-min)) - (while (search-forward-regexp metasection-regexp nil t) - (push (cons "--" (match-beginning 0)) menu)) - - ;; Sort in increasing buffer position order. - (sort menu (lambda (a b) (< (cdr a) (cdr b))))))) - -;;;; -;;;; Outline support -;;;; - -(defvar latex-outline-regexp - (concat "\\\\" - (regexp-opt (append latex-metasection-list - (mapcar #'car latex-section-alist)) - t))) - -(defun latex-outline-level () - (if (looking-at latex-outline-regexp) - (1+ (or (cdr (assoc (match-string 1) latex-section-alist)) -1)) - 1000)) - -(defun tex-current-defun-name () - "Return the name of the TeX section/paragraph/chapter at point, or nil." - (save-excursion - (when (re-search-backward - "\\\\\\(sub\\)*\\(section\\|paragraph\\|chapter\\)" - nil t) - (goto-char (match-beginning 0)) - (buffer-substring-no-properties - (1+ (point)) ; without initial backslash - (line-end-position))))) - -;;;; -;;;; Font-Lock support -;;;; - -;(defvar tex-font-lock-keywords -; ;; Regexps updated with help from Ulrik Dickow . -; '(("\\\\\\(begin\\|end\\|newcommand\\){\\([a-zA-Z0-9\\*]+\\)}" -; 2 font-lock-function-name-face) -; ("\\\\\\(cite\\|label\\|pageref\\|ref\\){\\([^} \t\n]+\\)}" -; 2 font-lock-constant-face) -; ;; It seems a bit dubious to use `bold' and `italic' faces since we might -; ;; not be able to display those fonts. -; ("{\\\\bf\\([^}]+\\)}" 1 'bold keep) -; ("{\\\\\\(em\\|it\\|sl\\)\\([^}]+\\)}" 2 'italic keep) -; ("\\\\\\([a-zA-Z@]+\\|.\\)" . font-lock-keyword-face) -; ("^[ \t\n]*\\\\def[\\@]\\(\\w+\\)" 1 font-lock-function-name-face keep)) -; ;; Rewritten and extended for LaTeX2e by Ulrik Dickow . -; '(("\\\\\\(begin\\|end\\|newcommand\\){\\([a-zA-Z0-9\\*]+\\)}" -; 2 font-lock-function-name-face) -; ("\\\\\\(cite\\|label\\|pageref\\|ref\\){\\([^} \t\n]+\\)}" -; 2 font-lock-constant-face) -; ("^[ \t]*\\\\def\\\\\\(\\(\\w\\|@\\)+\\)" 1 font-lock-function-name-face) -; "\\\\\\([a-zA-Z@]+\\|.\\)" -; ;; It seems a bit dubious to use `bold' and `italic' faces since we might -; ;; not be able to display those fonts. -; ;; LaTeX2e: \emph{This is emphasized}. -; ("\\\\emph{\\([^}]+\\)}" 1 'italic keep) -; ;; LaTeX2e: \textbf{This is bold}, \textit{...}, \textsl{...} -; ("\\\\text\\(\\(bf\\)\\|it\\|sl\\){\\([^}]+\\)}" -; 3 (if (match-beginning 2) 'bold 'italic) keep) -; ;; Old-style bf/em/it/sl. Stop at `\\' and un-escaped `&', for tables. -; ("\\\\\\(\\(bf\\)\\|em\\|it\\|sl\\)\\>\\(\\([^}&\\]\\|\\\\[^\\]\\)+\\)" -; 3 (if (match-beginning 2) 'bold 'italic) keep)) - -;; Rewritten with the help of Alexandra Bac . -(defconst tex-font-lock-keywords-1 - (eval-when-compile - (let* (;; Names of commands whose arg should be fontified as heading, etc. - (headings (regexp-opt - '("title" "begin" "end" "chapter" "part" - "section" "subsection" "subsubsection" - "paragraph" "subparagraph" "subsubparagraph" - "newcommand" "renewcommand" "providecommand" - "newenvironment" "renewenvironment" - "newtheorem" "renewtheorem") - t)) - (variables (regexp-opt - '("newcounter" "newcounter*" "setcounter" "addtocounter" - "setlength" "addtolength" "settowidth") - t)) - (includes (regexp-opt - '("input" "include" "includeonly" "bibliography" - "epsfig" "psfig" "epsf" "nofiles" "usepackage" - "documentstyle" "documentclass" "verbatiminput" - "includegraphics" "includegraphics*") - t)) - (verbish (regexp-opt '("url" "nolinkurl" "path" - "href" "ProvidesFile") - t)) - ;; Miscellany. - (slash "\\\\") - (opt " *\\(\\[[^]]*\\] *\\)*") - ;; This would allow highlighting \newcommand\CMD but requires - ;; adapting subgroup numbers below. - ;; (arg "\\(?:{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)\\|\\\\[a-z*]+\\)")) - (inbraces-re - (lambda (n) ;; Level of nesting of braces we should support. - (let ((re "[^}]")) - (dotimes (_ n) - (setq re - (concat "\\(?:[^{}\\]\\|\\\\.\\|{" re "*}\\)"))) - re))) - (arg (concat "{\\(" (funcall inbraces-re 2) "+\\)"))) - `(;; Verbatim-like args. - ;; Do it first, because we don't want to highlight them - ;; in comments (bug#68827), but we do want to highlight them - ;; in $math$. - (,(concat slash verbish opt arg) 3 'tex-verbatim keep) - ;; Highlight $$math$$ and $math$. - ;; This is done at the very beginning so as to interact with the other - ;; keywords in the same way as comments and strings. - (,(concat "\\$\\$?\\(?:[^$\\{}]\\|\\\\.\\|{" - (funcall inbraces-re 6) - "*}\\)+\\$?\\$") - (0 'tex-math keep)) - ;; Heading args. - (,(concat slash headings "\\*?" opt arg) - ;; If ARG ends up matching too much (if the {} don't match, e.g.) - ;; jit-lock will do funny things: when updating the buffer - ;; the re-highlighting is only done locally so it will just - ;; match the local line, but defer-contextually will - ;; match more lines at a time, so ARG will end up matching - ;; a lot more, which might suddenly include a comment - ;; so you get things highlighted bold when you type them - ;; but they get turned back to normal a little while later - ;; because "there's already a face there". - ;; Using `keep' works around this un-intuitive behavior as well - ;; as improves the behavior in the very rare case where you do - ;; have a comment in ARG. - 3 font-lock-function-name-face keep) - (,(concat slash "\\(?:provide\\|\\(?:re\\)?new\\)command\\** *\\(\\\\[A-Za-z@]+\\)") - 1 font-lock-function-name-face keep) - ;; Variable args. - (,(concat slash variables " *" arg) 2 font-lock-variable-name-face) - ;; Include args. - (,(concat slash includes opt arg) 3 font-lock-builtin-face) - ;; Definitions. I think. - ("^[ \t]*\\\\def *\\\\\\(\\(\\w\\|@\\)+\\)" - 1 font-lock-function-name-face)))) - "Subdued expressions to highlight in TeX modes.") - -(defun tex-font-lock-append-prop (prop) - (unless (memq (get-text-property (match-end 1) 'face) - '(font-lock-comment-face tex-verbatim)) - prop)) - -(defconst tex-font-lock-keywords-2 - (append tex-font-lock-keywords-1 - (eval-when-compile - (let* (;; - ;; Names of commands whose arg should be fontified with fonts. - (bold (regexp-opt '("textbf" "textsc" "textup" - "boldsymbol" "pmb") - t)) - (italic (regexp-opt '("textit" "textsl" "emph") t)) - ;; FIXME: unimplemented yet. - ;; (type (regexp-opt '("texttt" "textmd" "textrm" "textsf") t)) - ;; - ;; Names of commands whose arg should be fontified as a citation. - (citations (regexp-opt - '("label" "ref" "pageref" "vref" "eqref" - "cite" "nocite" "index" "glossary" "bibitem" - ;; natbib's two variants of \cite: - "citep" "citet" - ;; These are text, rather than citations. - ;; "caption" "footnote" "footnotemark" "footnotetext" - ) - t)) - ;; - ;; Names of commands that should be fontified. - (specials-1 (regexp-opt '("\\" "\\*") t)) ;; "-" - (specials-2 (regexp-opt - '("linebreak" "nolinebreak" "pagebreak" "nopagebreak" - "newline" "newpage" "clearpage" "cleardoublepage" - "displaybreak" "allowdisplaybreaks" - "enlargethispage") - t)) - (general "\\([a-zA-Z@]+\\**\\|[^ \t\n]\\)") - ;; - ;; Miscellany. - (slash "\\\\") - (opt " *\\(\\[[^]]*\\] *\\)*") - (args "\\(\\(?:[^${}&\\]+\\|\\\\.\\|{[^}]*}\\)+\\)") - (arg "{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)")) - (list - ;; - ;; Citation args. - (list (concat slash citations opt arg) 3 'font-lock-constant-face) - ;; - ;; Text between `` quotes ''. - (list (concat (regexp-opt '("``" "\"<" "\"`" "<<" "«") t) - "\\(\\(.\\|\n\\)+?\\)" - (regexp-opt `("''" "\">" "\"'" ">>" "»") t)) - '(1 'font-lock-keyword-face) - '(2 'font-lock-string-face) - '(4 'font-lock-keyword-face)) - ;; - ;; Command names, special and general. - (cons (concat slash specials-1) 'font-lock-warning-face) - (list (concat "\\(" slash specials-2 "\\)\\([^a-zA-Z@]\\|\\'\\)") - '(1 'font-lock-warning-face)) - (concat slash general) - ;; - ;; Font environments. It seems a bit dubious to use `bold' etc. faces - ;; since we might not be able to display those fonts. - (list (concat slash bold " *" arg) 2 - '(tex-font-lock-append-prop 'bold) 'append) - (list (concat slash italic " *" arg) 2 - '(tex-font-lock-append-prop 'italic) 'append) - ;; (list (concat slash type arg) 2 '(quote bold-italic) 'append) - ;; - ;; Old-style bf/em/it/sl. Stop at `\\' and un-escaped `&', for tables. - (list (concat "\\\\\\(em\\|it\\|sl\\)\\>" args) - 2 '(tex-font-lock-append-prop 'italic) 'append) - ;; This is separate from the previous one because of cases like - ;; {\em foo {\bf bar} bla} where both match. - (list (concat "\\\\\\(bf\\(series\\)?\\)\\>" args) - 3 '(tex-font-lock-append-prop 'bold) 'append))))) - "Gaudy expressions to highlight in TeX modes.") - -(defvar-local tex-expl-region-list nil - "List of region boundaries where expl3 syntax is active. -It will be nil in buffers visiting files which use expl3 syntax -throughout, for example, expl3 classes or packages.") - -(defvar-local tex-expl-buffer-p nil - "Non-nil in buffers using expl3 syntax throughout.") - -(defun tex-font-lock-suscript (pos) - (unless (or (memq (get-text-property pos 'face) - '(font-lock-constant-face font-lock-builtin-face - font-lock-comment-face tex-verbatim)) - ;; Check for backslash quoting - (let ((odd nil) - (pos pos)) - (while (eq (char-before pos) ?\\) - (setq pos (1- pos) odd (not odd))) - odd) - ;; Check if POS is in an expl3 syntax region or an expl3 buffer - (when (eq (char-after pos) ?_) - (or tex-expl-buffer-p - (and - tex-expl-region-list - (catch 'result - (dolist (range tex-expl-region-list) - (and (> pos (car range)) - (< pos (cdr range)) - (throw 'result t)))))))) - (if (eq (char-after pos) ?_) - `(face subscript display (raise ,(car tex-font-script-display))) - `(face superscript display (raise ,(cadr tex-font-script-display)))))) - -(defun tex-font-lock-match-suscript (limit) - "Match subscript and superscript patterns up to LIMIT." - (when (and tex-fontify-script - (re-search-forward "[_^] *\\([^\n\\{}]\\|\ -\\\\\\([a-zA-Z@]+\\|[^ \t\n]\\)\\|\\({\\)\\)" limit t)) - (when (match-end 3) - (let ((beg (match-beginning 3)) - (end (save-restriction - (narrow-to-region (point-min) limit) - (condition-case nil (scan-lists (point) 1 1) (error nil))))) - (store-match-data (if end - (list (match-beginning 0) end beg end) - (list beg beg beg beg))))) - t)) - -(defconst tex-font-lock-keywords-3 - (append tex-font-lock-keywords-2 - '((tex-font-lock-match-suscript - (1 (tex-font-lock-suscript (match-beginning 0)) append)))) - "Experimental expressions to highlight in TeX modes.") - -(defconst tex-font-lock-keywords tex-font-lock-keywords-1 - "Default expressions to highlight in TeX modes.") - -(defvar tex-verbatim-environments - '("verbatim" "verbatim*" - "Verbatim" ;; From "fancyvrb" - )) -(put 'tex-verbatim-environments 'safe-local-variable - (lambda (x) (not (memq nil (mapcar #'stringp x))))) - -(eval-when-compile - (defconst tex-syntax-propertize-rules - (syntax-propertize-precompile-rules - ("\\\\verb\\**\\([^a-z@*]\\)" - (1 (prog1 "\"" - (tex-font-lock-verb - (match-beginning 0) (char-after (match-beginning 1)))))))) - - (defconst latex-syntax-propertize-rules - (syntax-propertize-precompile-rules - tex-syntax-propertize-rules - ("\\\\\\(?:end\\|begin\\) *\\({[^\n{}]*}\\)" - (1 (ignore - (tex-env-mark (match-beginning 0) - (match-beginning 1) (match-end 1)))))))) - -(defun tex-env-mark (cmd start end) - (when (= cmd (line-beginning-position)) - (let ((arg (buffer-substring-no-properties (1+ start) (1- end)))) - (when (member arg tex-verbatim-environments) - (if (eq ?b (char-after (1+ cmd))) - ;; \begin - (put-text-property (line-end-position) - (line-beginning-position 2) - 'syntax-table (string-to-syntax "< c")) - ;; In the case of an empty verbatim env, the \n after the \begin is - ;; the same as the \n before the \end. Lucky for us, the "> c" - ;; property associated to the \end will be placed afterwards, so it - ;; will override the "< c". - (put-text-property (1- cmd) cmd - 'syntax-table (string-to-syntax "> c")) - ;; The text between \end{verbatim} and \n is ignored, so we'll treat - ;; it as a comment. - (put-text-property end (min (1+ end) (line-end-position)) - 'syntax-table (string-to-syntax "<"))))))) - -(defun tex-font-lock-unfontify-region (beg end) - (font-lock-default-unfontify-region beg end) - (while (< beg end) - (let ((next (next-single-property-change beg 'display nil end)) - (prop (get-text-property beg 'display))) - (if (and (eq (car-safe prop) 'raise) - (member (car-safe (cdr prop)) tex-font-script-display) - (null (cddr prop))) - (put-text-property beg next 'display nil)) - (setq beg next)))) - -(defcustom tex-suscript-height-ratio 0.8 - "Ratio of subscript/superscript height to that of the preceding text. -In nested subscript/superscript, this factor is applied repeatedly, -subject to the limit set by `tex-suscript-height-minimum'." - :type 'float - :group 'tex - :version "23.1") - -(defcustom tex-suscript-height-minimum 0.0 - "Integer or float limiting the minimum size of subscript/superscript text. -An integer is an absolute height in units of 1/10 point, a float -is a height relative to that of the default font. Zero means no minimum." - :type '(choice (integer :tag "Integer height in 1/10 point units") - (float :tag "Fraction of default font height")) - :group 'tex - :version "23.1") - -(defun tex-suscript-height (height) - "Return the integer height of subscript/superscript font in 1/10 points. -Not smaller than the value set by `tex-suscript-height-minimum'." - (ceiling (max (if (integerp tex-suscript-height-minimum) - tex-suscript-height-minimum - ;; For bootstrapping. - (condition-case nil - (* tex-suscript-height-minimum - (face-attribute 'default :height)) - (error 0))) - ;; NB assumes height is integer. - (* height tex-suscript-height-ratio)))) - -(defface superscript - '((t :height tex-suscript-height)) ;; :raise 0.2 - "Face used for superscripts." - :group 'tex) -(defface subscript - '((t :height tex-suscript-height)) ;; :raise -0.2 - "Face used for subscripts." - :group 'tex) - -(defface tex-math - '((t :inherit font-lock-string-face)) - "Face used to highlight TeX math expressions." - :group 'tex) - -(defface tex-verbatim - '((t :inherit fixed-pitch-serif)) - "Face used to highlight TeX verbatim environments." - :group 'tex) - -(defun tex-font-lock-verb (start delim) - "Place syntax table properties on the \\verb construct. -START is the position of the \\ and DELIM is the delimiter char." - ;; Do nothing if the \verb construct is itself inside a comment or - ;; verbatim env. - (unless (nth 8 (save-excursion (syntax-ppss start))) - ;; Let's find the end and mark it. - (let ((afterdelim (point))) - (skip-chars-forward (string ?^ delim) (line-end-position)) - (if (eolp) - ;; "LaTeX Error: \verb ended by end of line." - ;; Remove the syntax-table property we've just put on the - ;; start-delimiter, so it doesn't spill over subsequent lines. - (put-text-property (1- afterdelim) afterdelim - 'syntax-table nil) - (when (eq (char-syntax (preceding-char)) ?/) - (put-text-property (1- (point)) (point) - 'syntax-table (string-to-syntax "."))) - (put-text-property (point) (1+ (point)) - 'syntax-table (string-to-syntax "\"")))))) - -;; Use string syntax but math face for $...$. -(defun tex-font-lock-syntactic-face-function (state) - (let ((char (nth 3 state))) - (cond - ((not char) - (if (eq 2 (nth 7 state)) 'tex-verbatim 'font-lock-comment-face)) - ((eq char ?$) 'tex-math) - ;; A \verb element. - (t 'tex-verbatim)))) - - -(defun tex-define-common-keys (keymap) - "Define the keys that we want defined both in TeX mode and in the TeX shell." - (define-key keymap "\C-c\C-k" #'tex-kill-job) - (define-key keymap "\C-c\C-l" #'tex-recenter-output-buffer) - (define-key keymap "\C-c\C-q" #'tex-show-print-queue) - (define-key keymap "\C-c\C-p" #'tex-print) - (define-key keymap "\C-c\C-v" #'tex-view) - - (define-key keymap [menu-bar tex] (cons "TeX" (make-sparse-keymap "TeX"))) - - (define-key keymap [menu-bar tex tex-kill-job] - '(menu-item "Tex Kill" tex-kill-job :enable (tex-shell-running))) - (define-key keymap [menu-bar tex tex-recenter-output-buffer] - '(menu-item "Tex Recenter" tex-recenter-output-buffer - :enable (get-buffer "*tex-shell*"))) - (define-key keymap [menu-bar tex tex-show-print-queue] - '("Show Print Queue" . tex-show-print-queue)) - (define-key keymap [menu-bar tex tex-alt-print] - '(menu-item "Tex Print (alt printer)" tex-alt-print - :enable (stringp tex-print-file))) - (define-key keymap [menu-bar tex tex-print] - '(menu-item "Tex Print" tex-print :enable (stringp tex-print-file))) - (define-key keymap [menu-bar tex tex-view] - '(menu-item "Tex View" tex-view :enable (stringp tex-print-file)))) - -(defvar tex-mode-map - (let ((map (make-sparse-keymap))) - (set-keymap-parent map text-mode-map) - (tex-define-common-keys map) - (define-key map "\"" #'tex-insert-quote) - (define-key map "\n" #'tex-handle-newline) - (define-key map "\M-\r" #'latex-insert-item) - (define-key map "\C-c}" #'up-list) - (define-key map "\C-c{" #'tex-insert-braces) - (define-key map "\C-c\C-r" #'tex-region) - (define-key map "\C-c\C-b" #'tex-buffer) - (define-key map "\C-c\C-f" #'tex-file) - (define-key map "\C-c\C-c" #'tex-compile) - (define-key map "\C-c\C-i" #'tex-bibtex-file) - (define-key map "\C-c\C-o" #'latex-insert-block) - - ;; Redundant keybindings, for consistency with SGML mode. - (define-key map "\C-c\C-t" #'latex-insert-block) - (define-key map "\C-c]" #'latex-close-block) - (define-key map "\C-c/" #'latex-close-block) - - (define-key map "\C-c\C-e" #'latex-close-block) - (define-key map "\C-c\C-u" #'tex-goto-last-unclosed-latex-block) - (define-key map "\C-c\C-m" #'tex-feed-input) - (define-key map [(control return)] #'tex-feed-input) - (define-key map [menu-bar tex tex-bibtex-file] - '("BibTeX File" . tex-bibtex-file)) - (define-key map [menu-bar tex tex-validate-region] - '(menu-item "Validate Region" tex-validate-region :enable mark-active)) - (define-key map [menu-bar tex tex-validate-buffer] - '("Validate Buffer" . tex-validate-buffer)) - (define-key map [menu-bar tex tex-region] - '(menu-item "TeX Region" tex-region :enable mark-active)) - (define-key map [menu-bar tex tex-buffer] - '("TeX Buffer" . tex-buffer)) - (define-key map [menu-bar tex tex-file] '("TeX File" . tex-file)) - map) - "Keymap shared by TeX modes.") - -(defvar-keymap latex-mode-map - :doc "Keymap for `latex-mode'. See also `tex-mode-map'." - :parent tex-mode-map - "C-c C-s" #'latex-split-block) - -(defvar-keymap plain-tex-mode-map - :doc "Keymap for `plain-tex-mode'. See also `tex-mode-map'." - :parent tex-mode-map) - -(defvar tex-shell-map - (let ((m (make-sparse-keymap))) - (set-keymap-parent m shell-mode-map) - (tex-define-common-keys m) - m) - "Keymap for the TeX shell. -Inherits `shell-mode-map' with a few additions.") - -(defvar tex-face-alist - '((bold . "{\\bf ") - (italic . "{\\it ") - (bold-italic . "{\\bi ") ; hypothetical - (underline . "\\underline{") - (default . "{\\rm ")) - "Alist of face and TeX font name for facemenu.") - -(defvar tex-latex-face-alist - `((italic . "{\\em ") - ,@tex-face-alist) - "Alist of face and LaTeX font name for facemenu.") - -(defun tex-facemenu-add-face-function (face _end) - (or (cdr (assq face tex-face-alist)) - (or (and (consp face) - (consp (car face)) - (null (cdr face)) - (eq major-mode 'latex-mode) - ;; This actually requires the `color' LaTeX package. - (cond ((eq (caar face) :foreground) - (format "{\\color{%s} " (cadr (car face)))) - ((eq (caar face) :background) - (format "\\colorbox{%s}{" (cadr (car face)))))) - (error "Face %s not configured for %s mode" face mode-name)))) - -;; This would be a lot simpler if we just used a regexp search, -;; but then it would be too slow. -(defun tex--guess-mode () - (let ((mode tex-default-mode) slash comment) - (save-excursion - (goto-char (point-min)) - (while (and (setq slash (search-forward "\\" nil t)) - (setq comment (let ((search-end (point))) - (save-excursion - (beginning-of-line) - (search-forward "%" search-end t)))))) - (if (not (and slash (not comment))) - mode - (if (looking-at - (concat - (regexp-opt '("documentstyle" "documentclass" - "begin" "subsection" "section" - "part" "chapter" "newcommand" - "renewcommand" "RequirePackage") - 'words) - "\\|NeedsTeXFormat{LaTeX")) - (if (and (looking-at - "document\\(style\\|class\\)\\(\\[.*\\]\\)?{slides}") - ;; SliTeX is almost never used any more nowadays. - (tex-executable-exists-p slitex-run-command)) - #'slitex-mode - #'latex-mode) - #'plain-tex-mode))))) - -;; `tex-mode' plays two roles: it's the parent of several sub-modes -;; but it's also the function that chooses between those submodes. -;; To tell the difference between those two cases where the function -;; might be called, we check `delay-mode-hooks'. -;;;###autoload -(define-derived-mode tex-mode text-mode "generic-TeX" - "Major mode for editing files of input for TeX, LaTeX, or SliTeX. -This is the shared parent mode of several submodes. -Tries to determine (by looking at the beginning of the file) whether -this file is for plain TeX, LaTeX, or SliTeX and calls `plain-tex-mode', -`latex-mode', or `slitex-mode', accordingly. If it cannot be determined, -such as if there are no commands in the file, the value of `tex-default-mode' -says which mode to use." - (tex-common-initialization)) - -(advice-add 'tex-mode :around #'tex--redirect-to-submode - ;; Give it lower precedence than normal advice, so - ;; AUCTeX's advice takes precedence over it. - '((depth . 50))) -(defvar tex-mode--recursing nil) -(defun tex--redirect-to-submode (orig-fun) - "Redirect to one of the submodes when called directly." - ;; The file may have "mode: tex" in the local variable - ;; block, in which case we'll be called recursively - ;; infinitely. Inhibit that. - (let ((tex-mode--recursing tex-mode--recursing)) - (funcall (if (or delay-mode-hooks tex-mode--recursing) - ;; We're called from one of the children already. - orig-fun - (setq tex-mode--recursing t) - (let ((mode (tex--guess-mode))) - ;; `tex--guess-mode' really tries to guess the *type* of file, - ;; so we still need to consult `major-mode-remap-alist' - ;; to see which mode to use for that type. - (major-mode-remap mode)))))) - -;; Support files annotated with -*- LaTeX -*- (e.g. because they received -;; them from someone using AUCTeX). -;;;###autoload (add-to-list 'major-mode-remap-defaults '(TeX-mode . tex-mode)) -;;;###autoload (add-to-list 'major-mode-remap-defaults '(plain-TeX-mode . plain-tex-mode)) -;;;###autoload (add-to-list 'major-mode-remap-defaults '(LaTeX-mode . latex-mode)) - -;; FIXME: These aliases conflict with AUCTeX, but we still need them -;; because of packages out there which call these functions directly. -;; They should be patched to use `major-mode-remap'. -;; It would be nice to mark them obsolete somehow to encourage using -;; something else, but the obsolete declaration would become invalid -;; and confusing when AUCTeX *is* installed. -;;;###autoload (defalias 'TeX-mode #'tex-mode) -;;;###autoload (defalias 'plain-TeX-mode #'plain-tex-mode) -;;;###autoload (defalias 'LaTeX-mode #'latex-mode) - -;;;###autoload -(define-derived-mode plain-tex-mode tex-mode "TeX" - "Major mode for editing files of input for plain TeX. -Makes $ and } display the characters they match. -Makes \" insert \\=`\\=` when it seems to be the beginning of a quotation, -and \\='\\=' when it appears to be the end; it inserts \" only after a \\. - -Use \\[tex-region] to run TeX on the current region, plus a \"header\" -copied from the top of the file (containing macro definitions, etc.), -running TeX under a special subshell. \\[tex-buffer] does the whole buffer. -\\[tex-file] saves the buffer and then processes the file. -\\[tex-print] prints the .dvi file made by any of these. -\\[tex-view] previews the .dvi file made by any of these. -\\[tex-bibtex-file] runs bibtex on the file of the current buffer. - -Use \\[tex-validate-buffer] to check buffer for paragraphs containing -mismatched $'s or braces. - -Special commands: -\\{plain-tex-mode-map} - -Mode variables: -tex-run-command - Command string used by \\[tex-region] or \\[tex-buffer]. -tex-directory - Directory in which to create temporary files for TeX jobs - run by \\[tex-region] or \\[tex-buffer]. -tex-dvi-print-command - Command string used by \\[tex-print] to print a .dvi file. -tex-alt-dvi-print-command - Alternative command string used by \\[tex-print] (when given a prefix - argument) to print a .dvi file. -tex-dvi-view-command - Command string used by \\[tex-view] to preview a .dvi file. -tex-show-queue-command - Command string used by \\[tex-show-print-queue] to show the print - queue that \\[tex-print] put your job on. - -Entering Plain-tex mode runs the hook `text-mode-hook', then the hook -`tex-mode-hook', and finally the hook `plain-tex-mode-hook'. When the -special subshell is initiated, the hook `tex-shell-hook' is run." - (setq-local tex-command tex-run-command) - (setq-local tex-start-of-header "%\\*\\*start of header") - (setq-local tex-end-of-header "%\\*\\*end of header") - (setq-local tex-trailer "\\bye\n")) - -;;;###autoload -(define-derived-mode latex-mode tex-mode "LaTeX" - "Major mode for editing files of input for LaTeX. -Makes $ and } display the characters they match. -Makes \" insert \\=`\\=` when it seems to be the beginning of a quotation, -and \\='\\=' when it appears to be the end; it inserts \" only after a \\. - -Use \\[tex-region] to run LaTeX on the current region, plus the preamble -copied from the top of the file (containing \\documentstyle, etc.), -running LaTeX under a special subshell. \\[tex-buffer] does the whole buffer. -\\[tex-file] saves the buffer and then processes the file. -\\[tex-print] prints the .dvi file made by any of these. -\\[tex-view] previews the .dvi file made by any of these. -\\[tex-bibtex-file] runs bibtex on the file of the current buffer. - -Use \\[tex-validate-buffer] to check buffer for paragraphs containing -mismatched $'s or braces. - -Special commands: -\\{latex-mode-map} - -Mode variables: -latex-run-command - Command string used by \\[tex-region] or \\[tex-buffer]. -tex-directory - Directory in which to create temporary files for LaTeX jobs - run by \\[tex-region] or \\[tex-buffer]. -tex-dvi-print-command - Command string used by \\[tex-print] to print a .dvi file. -tex-alt-dvi-print-command - Alternative command string used by \\[tex-print] (when given a prefix - argument) to print a .dvi file. -tex-dvi-view-command - Command string used by \\[tex-view] to preview a .dvi file. -tex-show-queue-command - Command string used by \\[tex-show-print-queue] to show the print - queue that \\[tex-print] put your job on. - -Entering Latex mode runs the hook `text-mode-hook', then -`tex-mode-hook', and finally `latex-mode-hook'. When the special -subshell is initiated, `tex-shell-hook' is run." - (setq-local tex-command latex-run-command) - (setq-local tex-start-of-header "\\\\document\\(style\\|class\\)") - (setq-local tex-end-of-header "\\\\begin\\s-*{document}") - (setq-local tex-trailer "\\end{document}\n") - ;; A line containing just $$ is treated as a paragraph separator. - ;; A line starting with $$ starts a paragraph, - ;; but does not separate paragraphs if it has more stuff on it. - ;; For \pagebreak allow latex optional arg like \pagebreak[2] - (setq paragraph-start - (concat "[ \t]*\\(\\$\\$\\|" - "\\\\[][]\\|" - "\\\\" (regexp-opt (append - (mapcar #'car latex-section-alist) - '("begin" "label" "end" - "item" "bibitem" "newline" "noindent" - "newpage" "footnote" "marginpar" - "parbox" "caption")) - t) - "\\>\\|\\\\[a-z]*" (regexp-opt '("space" "skip" "page") t) - "\\>\\)")) - (setq paragraph-separate - (concat "\\([ \t]*%\\)\\|[\f]\\|[ \t]*\\($\\|" - "\\\\[][]\\|" - "\\\\" (regexp-opt (append - (mapcar #'car latex-section-alist) - '("begin" "label" "end" )) - t) - "\\>\\|\\\\\\(" (regexp-opt '("item" "bibitem" "newline" - "noindent" "newpage" "footnote" - "marginpar" "parbox" "caption")) - "\\|\\$\\$\\|[a-z]*\\(space\\|skip\\|page[a-z]*\\)" - "\\>\\)[][0-9 \t]*\\($\\|%\\)\\)")) - (setq-local imenu-create-index-function #'latex-imenu-create-index) - (setq-local tex-face-alist tex-latex-face-alist) - (add-hook 'fill-nobreak-predicate #'latex-fill-nobreak-predicate nil t) - (setq-local indent-line-function #'latex-indent) - (setq-local fill-indent-according-to-mode t) - (add-hook 'completion-at-point-functions - #'latex-complete-data nil 'local) - (add-hook 'flymake-diagnostic-functions #'tex-chktex nil t) - (setq-local outline-regexp latex-outline-regexp) - (setq-local outline-level #'latex-outline-level) - (setq-local forward-sexp-function #'latex-forward-sexp) - (setq-local skeleton-end-hook nil)) - -;;;###autoload -(define-derived-mode slitex-mode latex-mode "SliTeX" - "Major mode for editing files of input for SliTeX. -Makes $ and } display the characters they match. -Makes \" insert \\=`\\=` when it seems to be the beginning of a quotation, -and \\='\\=' when it appears to be the end; it inserts \" only after a \\. - -Use \\[tex-region] to run SliTeX on the current region, plus the preamble -copied from the top of the file (containing \\documentstyle, etc.), -running SliTeX under a special subshell. \\[tex-buffer] does the whole buffer. -\\[tex-file] saves the buffer and then processes the file. -\\[tex-print] prints the .dvi file made by any of these. -\\[tex-view] previews the .dvi file made by any of these. -\\[tex-bibtex-file] runs bibtex on the file of the current buffer. - -Use \\[tex-validate-buffer] to check buffer for paragraphs containing -mismatched $'s or braces. - -Special commands: -\\{slitex-mode-map} - -Mode variables: -slitex-run-command - Command string used by \\[tex-region] or \\[tex-buffer]. -tex-directory - Directory in which to create temporary files for SliTeX jobs - run by \\[tex-region] or \\[tex-buffer]. -tex-dvi-print-command - Command string used by \\[tex-print] to print a .dvi file. -tex-alt-dvi-print-command - Alternative command string used by \\[tex-print] (when given a prefix - argument) to print a .dvi file. -tex-dvi-view-command - Command string used by \\[tex-view] to preview a .dvi file. -tex-show-queue-command - Command string used by \\[tex-show-print-queue] to show the print - queue that \\[tex-print] put your job on. - -Entering SliTeX mode runs the hook `text-mode-hook', then the hook -`tex-mode-hook', then the hook `latex-mode-hook', and finally the hook -`slitex-mode-hook'. When the special subshell is initiated, the hook -`tex-shell-hook' is run." - (setq tex-command slitex-run-command) - (setq tex-start-of-header "\\\\documentstyle{slides}\\|\\\\documentclass{slides}")) - -(defvar tildify-space-string) -(defvar tildify-foreach-region-function) -(declare-function tildify-foreach-ignore-environments - "tildify" (pairs callback _beg end)) -(defvar tex--prettify-symbols-alist) - -(defun tex-common-initialization () - ;; Regexp isearch should accept newline and formfeed as whitespace. - (setq-local search-whitespace-regexp "[ \t\r\n\f]+") - ;; Use tilde as hard-space character in tildify package. - (setq-local tildify-space-string "~") - ;; FIXME: Use the fact that we're parsing the document already - ;; rather than using regex-based filtering. - (setq-local tildify-foreach-region-function - (apply-partially - #'tildify-foreach-ignore-environments - `(("\\\\\\\\" . "") ; do not remove this - (,(concat "\\\\begin{\\(" - (regexp-opt '("verbatim" "math" "displaymath" - "equation" "eqnarray" "eqnarray*")) - "\\)}") - . ("\\\\end{" 1 "}")) - ("\\\\verb\\*?\\(.\\)" . (1)) - ("\\$\\$?" . (0)) - ("\\\\(" . "\\\\)") - ("\\\\[[]" . "\\\\[]]") - ("\\\\[a-zA-Z]+\\( +\\|{}\\)[a-zA-Z]*" . "") - ("%" . "$")))) - ;; A line containing just $$ is treated as a paragraph separator. - (setq-local paragraph-start "[ \t]*$\\|[\f\\%]\\|[ \t]*\\$\\$") - ;; A line starting with $$ starts a paragraph, - ;; but does not separate paragraphs if it has more stuff on it. - (setq-local paragraph-separate "[ \t]*$\\|[\f\\%]\\|[ \t]*\\$\\$[ \t]*$") - (setq-local add-log-current-defun-function #'tex-current-defun-name) - (setq-local comment-start "%") - (setq-local comment-add 1) - (setq-local comment-start-skip - "\\(\\(^\\|[^\\\n]\\)\\(\\\\\\\\\\)*\\)\\(%+ *\\)") - (setq-local parse-sexp-ignore-comments t) - (setq-local facemenu-add-face-function #'tex-facemenu-add-face-function) - (setq-local facemenu-end-add-face "}") - (setq-local facemenu-remove-face-function t) - (setq-local font-lock-defaults - '(( tex-font-lock-keywords tex-font-lock-keywords-1 - tex-font-lock-keywords-2 tex-font-lock-keywords-3) - nil nil nil nil - ;; Who ever uses that anyway ??? - (font-lock-mark-block-function . mark-paragraph) - (font-lock-syntactic-face-function - . tex-font-lock-syntactic-face-function) - (font-lock-unfontify-region-function - . tex-font-lock-unfontify-region))) - (setq-local prettify-symbols-alist tex--prettify-symbols-alist) - (add-function :override (local 'prettify-symbols-compose-predicate) - #'tex--prettify-symbols-compose-p) - (setq-local syntax-propertize-function - (syntax-propertize-rules latex-syntax-propertize-rules)) - ;; Don't add extra processing to `syntax-propertize' in files where - ;; expl3 syntax is always active. - :after-hook (progn (tex-expl-buffer-parse) - (unless tex-expl-buffer-p - (add-hook 'syntax-propertize-extend-region-functions - #'tex-expl-region-set nil t))) - ;; TABs in verbatim environments don't do what you think. - (setq-local indent-tabs-mode nil) - ;; Set up xref backend in TeX buffers. - (add-hook 'xref-backend-functions #'tex--xref-backend nil t) - ;; Other vars that should be buffer-local. - (make-local-variable 'tex-command) - (make-local-variable 'tex-start-of-header) - (make-local-variable 'tex-end-of-header) - (make-local-variable 'tex-trailer)) - -(defun tex-insert-quote (arg) - "Insert the appropriate quote marks for TeX. -Inserts the value of `tex-open-quote' (normally \\=`\\=`) or `tex-close-quote' -\(normally \\='\\=') depending on the context. With prefix argument, always -inserts \" characters." - (interactive "*P") - ;; Discover if we'll be inserting normal double quotes. - ;; - (if (or arg (memq (char-syntax (preceding-char)) '(?/ ?\\)) - (eq (get-text-property (point) 'face) 'tex-verbatim) - (nth 4 (syntax-ppss)) ; non-nil if point is in a TeX comment - ;; Discover if a preceding occurrence of `tex-open-quote' - ;; should be morphed to a normal double quote. - ;; - (and (>= (point) (+ (point-min) (length tex-open-quote))) - (save-excursion - (backward-char (length tex-open-quote)) - (when (or (looking-at (regexp-quote tex-open-quote)) - (looking-at (regexp-quote tex-close-quote))) - (delete-char (length tex-open-quote)) - (when (looking-at (regexp-quote tex-close-quote)) - (delete-char (length tex-close-quote))) - t)))) - ;; Insert the normal quote (eventually letting - ;; `electric-pair-mode' do its thing). - ;; - (self-insert-command (prefix-numeric-value arg)) - ;; We'll be inserting fancy TeX quotes, but consider and imitate - ;; `electric-pair-mode''s two behaviors: pair-insertion and - ;; region wrapping. - ;; - (if (and electric-pair-mode (use-region-p)) - (let* ((saved (point-marker))) - (goto-char (mark)) - (insert (if (> saved (mark)) tex-open-quote tex-close-quote)) - (goto-char saved) - (insert (if (> saved (mark)) tex-close-quote tex-open-quote))) - (if (or (memq (char-syntax (preceding-char)) '(?\( ?> ?\s)) - (memq (preceding-char) '(?~ ?'))) - ;; We're in an "opening" context - ;; - (if electric-pair-mode - (if (looking-at (regexp-quote tex-close-quote)) - (forward-char (length tex-close-quote)) - (insert tex-open-quote) - (insert tex-close-quote) - (backward-char (length tex-close-quote))) - (insert tex-open-quote)) - ;; We're in a "closing" context. - ;; - (if (looking-at (regexp-quote tex-close-quote)) - (forward-char (length tex-close-quote)) - (insert tex-close-quote)))))) - -(defun tex-validate-buffer () - "Check current buffer for paragraphs containing mismatched braces or $s. -Their positions are recorded in the buffer `*Occur*'. -To find a particular invalidity from `*Occur*', switch to that buffer -and type C-c C-c or click with mouse-2 -on the line for the invalidity you want to see." - (interactive) - (let ((buffer (current-buffer)) - (prevpos (point-min)) - (linenum nil) - (num-matches 0)) - (with-output-to-temp-buffer "*Occur*" - (princ "Mismatches:\n") - (with-current-buffer standard-output - (occur-mode) - ;; This won't actually work...Really, this whole thing should - ;; be rewritten instead of being a hack on top of occur. - (setq occur-revert-arguments (list nil 0 (list buffer)))) - (save-excursion - (goto-char (point-max)) - ;; Do a little shimmy to place point at the end of the last - ;; "real" paragraph. Need to avoid validating across an \end, - ;; because that blows up latex-forward-sexp. - (backward-paragraph) - (forward-paragraph) - (while (not (bobp)) - ;; Scan the previous paragraph for invalidities. - (backward-paragraph) - (save-excursion - (or (tex-validate-region (point) (save-excursion - (forward-paragraph) - (point))) - (let ((end (line-beginning-position 2)) - start tem) - (beginning-of-line) - (setq start (point)) - ;; Keep track of line number as we scan, - ;; in a cumulative fashion. - (if linenum - (setq linenum (- linenum - (count-lines prevpos (point)))) - (setq linenum (1+ (count-lines 1 start)))) - (setq prevpos (point)) - ;; Mention this mismatch in *Occur*. - ;; Since we scan from end of buffer to beginning, - ;; add each mismatch at the beginning of *Occur*. - (save-excursion - (setq tem (point-marker)) - (set-buffer standard-output) - (goto-char (point-min)) - ;; Skip "Mismatches:" header line. - (forward-line 1) - (setq num-matches (1+ num-matches)) - (let ((inhibit-read-only t)) - (insert-buffer-substring buffer start end) - (let ((text-end (point-marker)) - text-beg) - (forward-char (- start end)) - (setq text-beg (point-marker)) - (insert (format "%3d: " linenum)) - (add-text-properties - text-beg (- text-end 1) - '(mouse-face highlight - help-echo - "mouse-2: go to this invalidity")) - (put-text-property (point) (- text-end 1) - 'occur-match t) - (put-text-property text-beg text-end - 'occur-target tem))))))))) - (with-current-buffer standard-output - (let ((no-matches (zerop num-matches)) - (inhibit-read-only t)) - (if no-matches - (insert "None!\n")) - (if (called-interactively-p 'interactive) - (message (cond (no-matches "No mismatches found") - ((= num-matches 1) "1 mismatch found") - (t "%d mismatches found")) - num-matches))))))) - -(defun tex-validate-region (start end) - "Check for mismatched braces or $'s in region. -Returns t if no mismatches. Returns nil and moves point to suspect -area if a mismatch is found." - (interactive "r") - (let ((failure-point nil) (max-possible-sexps (- end start))) - (save-excursion - (condition-case () - (save-restriction - (narrow-to-region start end) - ;; First check that the open and close parens balance in numbers. - (goto-char start) - (while (and (not (eobp)) - (<= 0 (setq max-possible-sexps - (1- max-possible-sexps)))) - (forward-sexp 1)) - ;; Now check that like matches like. - (goto-char start) - (while (re-search-forward "\\s(" nil t) - (save-excursion - (let ((pos (match-beginning 0))) - (goto-char pos) - (skip-chars-backward "\\\\") ; escaped parens - (forward-sexp 1) - (or (eq (preceding-char) (cdr (syntax-after pos))) - (eq (char-after pos) (cdr (syntax-after (1- (point))))) - (error "Mismatched parentheses")))))) - (error - (skip-syntax-forward " .>") - (setq failure-point (point))))) - (if failure-point (goto-char failure-point)) - (not failure-point))) - -(defun tex-handle-newline (inhibit-validation) - "Break a TeX paragraph with two newlines, or continue a comment. -If not in a comment, insert two newlines, breaking a paragraph for TeX, -and check for mismatched braces or $s in the paragraph being terminated -unless prefix arg INHIBIT-VALIDATION is non-nil to inhibit the checking. -Otherwise (in a comment), just insert a single continued comment line." - (interactive "*P") - (if (nth 4 (syntax-ppss)) ; non-nil if point is in a TeX comment - (comment-indent-new-line) - (tex-terminate-paragraph inhibit-validation))) - -(defun tex-terminate-paragraph (inhibit-validation) - "Insert two newlines, breaking a paragraph for TeX. -Check for mismatched braces or $s in paragraph being terminated. -A prefix arg inhibits the checking." - (interactive "*P") - (or inhibit-validation - (save-excursion - ;; For the purposes of this, a "paragraph" is a block of text - ;; wherein all the brackets etc are expected to be balanced. It - ;; may start after a blank line (ie a "proper" paragraph), or - ;; a begin{} or end{} block, etc. - (tex-validate-region - (save-excursion - (backward-paragraph) - (point)) - (point))) - (message "Paragraph being closed appears to contain a mismatch")) - (insert "\n\n")) - -(define-skeleton tex-insert-braces - "Make a pair of braces and be poised to type inside of them." - nil - ?\{ _ ?}) - -;; This function is used as the value of fill-nobreak-predicate -;; in LaTeX mode. Its job is to prevent line-breaking inside -;; of a \verb construct. -(defun latex-fill-nobreak-predicate () - (save-excursion - (skip-chars-backward " ") - ;; Don't break after \ since `\ ' has special meaning. - (or (and (not (bobp)) (memq (char-syntax (char-before)) '(?\\ ?/))) - (let ((opoint (point)) - inside) - (beginning-of-line) - (while (re-search-forward "\\\\verb\\(.\\)" opoint t) - (unless (re-search-forward (regexp-quote (match-string 1)) opoint t) - (setq inside t))) - inside)))) - -(defvar latex-block-default "enumerate") - -(defvar latex-block-args-alist - '(("array" nil ?\{ (skeleton-read "Format: ") ?\}) - ("tabular" nil ?\{ (skeleton-read "Format: ") ?\}) - ("minipage" nil ?\{ (skeleton-read "Size: ") ?\}) - ("picture" nil ?\( (skeleton-read "SizeX,SizeY: ") ?\)) - ;; FIXME: This is right for Prosper, but not for seminar. - ;; ("slide" nil ?\{ (skeleton-read "Title: ") ?\}) - ) - "Skeleton element to use for arguments to particular environments. -Every element of the list has the form (NAME . SKEL-ELEM) where NAME is -the name of the environment and SKEL-ELEM is an element to use in -a skeleton (see `skeleton-insert').") - -(defvar latex-block-body-alist - '(("enumerate" nil '(latex-insert-item) > _) - ("itemize" nil '(latex-insert-item) > _) - ("table" nil "\\caption{" > (skeleton-read "Caption: ") "}" > \n - '(if (and (boundp 'reftex-mode) reftex-mode) (reftex-label "table")) - \n _) - ("figure" nil > _ \n "\\caption{" > (skeleton-read "Caption: ") "}" > \n - '(if (and (boundp 'reftex-mode) reftex-mode) (reftex-label "figure")))) - "Skeleton element to use for the body of particular environments. -Every element of the list has the form (NAME . SKEL-ELEM) where NAME is -the name of the environment and SKEL-ELEM is an element to use in -a skeleton (see `skeleton-insert').") - -;; Like tex-insert-braces, but for LaTeX. -(defalias 'tex-latex-block #'latex-insert-block) -(define-skeleton latex-insert-block - "Create a matching pair of lines \\begin{NAME} and \\end{NAME} at point. -Puts point on a blank line between them." - (let ((choice (completing-read (format "LaTeX block name [%s]: " - latex-block-default) - (latex-complete-envnames) - nil nil nil nil latex-block-default))) - (setq latex-block-default choice) - (unless (or (member choice latex-standard-block-names) - (member choice latex-block-names)) - ;; Remember new block names for later completion. - (push choice latex-block-names)) - choice) - \n "\\begin{" str "}" - (cdr (assoc str latex-block-args-alist)) - > \n (or (cdr (assoc str latex-block-body-alist)) '(nil > _)) - (unless (bolp) '\n) - "\\end{" str "}" > \n) - -(define-skeleton latex-insert-item - "Insert an \\item macro." - nil - \n "\\item " >) - - -;;;; LaTeX completion. - -(defvar latex-complete-bibtex-cache nil) -(defvar bibtex-reference-key) -(declare-function reftex-get-bibfile-list "reftex-cite.el" ()) - -(defun latex-complete-bibtex-keys () - (when (bound-and-true-p reftex-mode) - (lambda (key pred action) - (let ((re (concat "^[ \t]*@\\([a-zA-Z]+\\)[ \t\n]*\\([{(][ \t\n]*\\)" - (regexp-quote key))) - (files (reftex-get-bibfile-list)) - keys) - (if (and (eq (car latex-complete-bibtex-cache) - (reftex-get-bibfile-list)) - (string-prefix-p (nth 1 latex-complete-bibtex-cache) - key)) - ;; Use the cache. - (setq keys (nth 2 latex-complete-bibtex-cache)) - (dolist (file files) - (with-current-buffer (find-file-noselect file) - (goto-char (point-min)) - (while (re-search-forward re nil t) - (goto-char (match-end 2)) - (when (and (not (member-ignore-case (match-string 1) - '("c" "comment" "string"))) - (looking-at bibtex-reference-key)) - (push (match-string-no-properties 0) keys))))) - ;; Fill the cache. - (setq-local latex-complete-bibtex-cache (list files key keys))) - (complete-with-action action keys key pred))))) - -(defun latex-complete-envnames () - (completion-table-in-turn - (append latex-block-names latex-standard-block-names) - (completion-table-dynamic - (lambda (str) - (with-current-buffer (if (and (minibufferp) (minibuffer-selected-window)) - (window-buffer (minibuffer-selected-window)) - (current-buffer)) - (save-excursion - (let ((comps '()) - (pos (point))) - (goto-char (point-min)) - (while (re-search-forward (concat "\\\\begin{\\(" str "[^}\n ]*\\)") - nil t) - (unless (and (<= (match-beginning 0) pos) - (>= (match-end 0) pos)) - (push (match-string 1) comps))) - comps))))))) - -(defun latex-complete-refkeys () - (when (boundp 'reftex-docstruct-symbol) - (symbol-value reftex-docstruct-symbol))) - -(defvar latex-complete-alist - `(("\\`\\\\\\(short\\)?cite\\'" . ,#'latex-complete-bibtex-keys) - ("\\`\\\\\\(begin\\|end\\)\\'" . ,#'latex-complete-envnames) - ("\\`\\\\[vf]?ref\\'" . ,#'latex-complete-refkeys))) - -(defun latex-complete-data () - "Get completion-data at point." - (save-excursion - (let ((pt (point))) - (skip-chars-backward "^ {}\n\t\\\\") - (pcase (char-before) - ((or 'nil ?\s ?\n ?\t ?\}) nil) - (?\\ - ;; TODO: Complete commands. - nil) - (?\{ - ;; Complete args to commands. - (let* ((cmd - (save-excursion - (forward-char -1) - (skip-chars-backward " \n") - (buffer-substring (point) - (progn - (skip-chars-backward "a-zA-Z@*") - (let ((n (skip-chars-backward "\\\\"))) - (forward-char (* 2 (/ n 2)))) - (point))))) - (start (point)) - (_ (progn (goto-char pt) (skip-chars-backward "^," start))) - (comp-beg (point)) - (_ (progn (goto-char pt) (skip-chars-forward "^, {}\n\t\\\\"))) - (comp-end (point)) - (table - (funcall - (let ((f (lambda () t))) - (dolist (comp latex-complete-alist) - (if (string-match (car comp) cmd) - (setq f (cdr comp)))) - f)))) - (if (eq table t) - ;; Unknown command. - nil - (list comp-beg comp-end table)))))))) - -;;;; -;;;; LaTeX syntax navigation -;;;; - -(defmacro tex-search-noncomment (&rest body) - "Execute BODY as long as it return non-nil and point is in a comment. -Return the value returned by the last execution of BODY." - (declare (debug t)) - (let ((res-sym (make-symbol "result"))) - `(let (,res-sym) - (while - (and (setq ,res-sym (progn ,@body)) - (save-excursion (skip-chars-backward "^\n%") (not (bolp))))) - ,res-sym))) - -(defun tex-last-unended-begin () - "Leave point at the beginning of the last `\\begin{...}' that is unended." - (condition-case nil - (while (and (tex-search-noncomment - (re-search-backward "\\\\\\(begin\\|end\\)\\s *{")) - (looking-at "\\\\end")) - (tex-last-unended-begin)) - (search-failed (error "Couldn't find unended \\begin")))) - -(defun tex-next-unmatched-end () - "Leave point at the end of the next `\\end' that is unmatched." - (while (and (tex-search-noncomment - (re-search-forward "\\\\\\(begin\\|end\\)\\s *{[^}]+}")) - (save-excursion (goto-char (match-beginning 0)) - (looking-at "\\\\begin"))) - (tex-next-unmatched-end))) - -(defun tex-next-unmatched-eparen (otype) - "Leave point after the next unmatched escaped closing parenthesis. -The string OTYPE is an opening parenthesis type: `(', `{', or `['." - (condition-case nil - (let ((ctype (char-to-string (cdr (aref (syntax-table) - (string-to-char otype)))))) - (while (and (tex-search-noncomment - (re-search-forward (format "\\\\[%s%s]" ctype otype))) - (save-excursion - (goto-char (match-beginning 0)) - (looking-at (format "\\\\%s" (regexp-quote otype))))) - (tex-next-unmatched-eparen otype))) - (wrong-type-argument (error "Unknown opening parenthesis type: %s" otype)) - (search-failed (error "Couldn't find closing escaped paren")))) - -(defun tex-last-unended-eparen (ctype) - "Leave point at the start of the last unended escaped opening parenthesis. -The string CTYPE is a closing parenthesis type: `)', `}', or `]'." - (condition-case nil - (let ((otype (char-to-string (cdr (aref (syntax-table) - (string-to-char ctype)))))) - (while (and (tex-search-noncomment - (re-search-backward (format "\\\\[%s%s]" ctype otype))) - (looking-at (format "\\\\%s" (regexp-quote ctype)))) - (tex-last-unended-eparen ctype))) - (wrong-type-argument (error "Unknown opening parenthesis type: %s" ctype)) - (search-failed (error "Couldn't find unended escaped paren")))) - -(defun tex-goto-last-unclosed-latex-block () - "Move point to the last unclosed \\begin{...}. -Mark is left at original location." - (interactive) - (let ((spot)) - (save-excursion - (tex-last-unended-begin) - (setq spot (point))) - (push-mark) - (goto-char spot))) - -(defvar latex-handle-escaped-parens t) - -;; Don't think this one actually _needs_ (for the purposes of -;; tex-mode) to handle escaped parens. -;; Does not handle escaped parens when latex-handle-escaped-parens is nil. -(defun latex-backward-sexp-1 () - "Like (backward-sexp 1) but aware of multi-char elements and escaped parens." - (let ((pos (point)) - (forward-sexp-function)) - (backward-sexp 1) - (cond ((looking-at - (if latex-handle-escaped-parens - "\\\\\\(begin\\>\\|[[({]\\)" - "\\\\begin\\>")) - (signal 'scan-error - (list "Containing expression ends prematurely" - (point) (prog1 (point) (goto-char pos))))) - ((and latex-handle-escaped-parens - (looking-at "\\\\\\([])}]\\)")) - (tex-last-unended-eparen (match-string 1))) - ((eq (char-after) ?{) - (let ((newpos (point))) - (when (ignore-errors (backward-sexp 1) t) - (if (or (looking-at "\\\\end\\>") - ;; In case the \\ ends a verbatim section. - (and (looking-at "end\\>") (eq (char-before) ?\\))) - (tex-last-unended-begin) - (goto-char newpos)))))))) - -;; Note this does not handle things like mismatched brackets inside -;; begin/end blocks. -;; Needs to handle escaped parens for tex-validate-*. -;; https://lists.gnu.org/r/bug-gnu-emacs/2007-09/msg00038.html -;; Does not handle escaped parens when latex-handle-escaped-parens is nil. -(defun latex-forward-sexp-1 () - "Like (forward-sexp 1) but aware of multi-char elements and escaped parens." - (let ((pos (point)) - (forward-sexp-function)) - (forward-sexp 1) - (let ((newpos (point))) - (skip-syntax-backward "/w") - (cond - ((looking-at "\\\\end\\>") - (signal 'scan-error - (list "Containing expression ends prematurely" - (point) - (prog1 - (progn (ignore-errors (forward-sexp 2)) (point)) - (goto-char pos))))) - ((looking-at "\\\\begin\\>") - (goto-char (match-end 0)) - (tex-next-unmatched-end)) - ;; A better way to handle this, \( .. \) etc, is probably to - ;; temporarily change the syntax of the \ in \( to punctuation. - ((and latex-handle-escaped-parens - (looking-back "\\\\[])}]" (- (point) 2))) - (signal 'scan-error - (list "Containing expression ends prematurely" - (- (point) 2) (prog1 (point) - (goto-char pos))))) - ((and latex-handle-escaped-parens - (looking-back "\\\\\\([({[]\\)" (- (point) 2))) - (tex-next-unmatched-eparen (match-string 1))) - (t (goto-char newpos)))))) - -(defun latex-forward-sexp (&optional arg) - "Like `forward-sexp' but aware of multi-char elements and escaped parens." - (interactive "P") - (unless arg (setq arg 1)) - (let ((pos (point)) - (opoint 0)) - (condition-case err - (while (and (/= (point) opoint) - (/= arg 0)) - (setq opoint (point)) - (setq arg - (if (> arg 0) - (progn (latex-forward-sexp-1) (1- arg)) - (progn (latex-backward-sexp-1) (1+ arg))))) - (scan-error - (goto-char pos) - (signal (car err) (cdr err)))))) - -(defun latex-syntax-after () - "Like (char-syntax (char-after)) but aware of multi-char elements." - (if (looking-at "\\\\end\\>") ?\) (char-syntax (following-char)))) - -(defun latex-skip-close-parens () - "Like (skip-syntax-forward \" )\") but aware of multi-char elements." - (let ((forward-sexp-function nil)) - (while (progn (skip-syntax-forward " )") - (looking-at "\\\\end\\>")) - (forward-sexp 2)))) - -(defun latex-down-list () - "Like (down-list 1) but aware of multi-char elements." - (forward-comment (point-max)) - (let ((forward-sexp-function nil)) - (if (not (looking-at "\\\\begin\\>")) - (down-list 1) - (forward-sexp 1) - ;; Skip arguments. - (while (looking-at "[ \t]*[[{(]") - (with-syntax-table tex-mode-syntax-table - (forward-sexp)))))) - -(defalias 'tex-close-latex-block #'latex-close-block) -(define-skeleton latex-close-block - "Create an \\end{...} to match the last unclosed \\begin{...}." - (save-excursion - (tex-last-unended-begin) - (if (not (looking-at "\\\\begin\\(\\s *{[^}\n]*}\\)")) '("{" _ "}") - (match-string 1))) - \n "\\end" str > \n) - -(define-skeleton latex-split-block - "Split the enclosing environment by inserting \\end{..}\\begin{..} at point." - (save-excursion - (tex-last-unended-begin) - (if (not (looking-at "\\\\begin\\(\\s *{[^}\n]*}\\)")) '("{" _ "}") - (prog1 (match-string 1) - (goto-char (match-end 1)) - (setq v1 (buffer-substring (point) - (progn - (while (looking-at "[ \t]*[[{]") - (forward-sexp 1)) - (point))))))) - \n "\\end" str > \n _ \n "\\begin" str v1 > \n) - -(defconst tex-discount-args-cmds - '("begin" "end" "input" "special" "cite" "ref" "include" "includeonly" - "documentclass" "usepackage" "label") - "TeX commands whose arguments should not be counted as text.") - -(defun tex-count-words (begin end) - "Count the number of words in the buffer." - (interactive - (if (and transient-mark-mode mark-active) - (list (region-beginning) (region-end)) - (list (point-min) (point-max)))) - ;; TODO: skip comments and math and maybe some environments. - (save-excursion - (goto-char begin) - (let ((count 0)) - (while (and (< (point) end) (re-search-forward "\\<" end t)) - (if (not (eq (char-syntax (preceding-char)) ?/)) - (progn - ;; Don't count single-char words. - (unless (looking-at ".\\>") (incf count)) - (forward-char 1)) - (let ((cmd - (buffer-substring-no-properties - (point) (progn (when (zerop (skip-chars-forward "a-zA-Z@")) - (forward-char 1)) - (point))))) - (when (member cmd tex-discount-args-cmds) - (skip-chars-forward "*") - (forward-comment (point-max)) - (when (looking-at "\\[") - (forward-sexp 1) - (forward-comment (point-max))) - (if (not (looking-at "{")) - (forward-char 1) - (forward-sexp 1)))))) - (message "%s words" count)))) - -(defun tex-expl-buffer-parse () - "Identify buffers using expl3 syntax throughout." - (save-excursion - (goto-char (point-min)) - (when (tex-search-noncomment - (re-search-forward - "\\\\\\(?:ExplFile\\|ProvidesExpl\\|__xparse_file\\)" - nil t)) - (setq tex-expl-buffer-p t)))) - -(defun tex-expl-region-set (_beg _end) - "Create a list of regions where expl3 syntax is active. -This function updates the list whenever `syntax-propertize' runs, and -stores it in the buffer-local variable `tex-expl-region-list'. The list -will always be nil when the buffer visits an expl3 file, for example, an -expl3 class or package, where the entire file uses expl3 syntax." - (unless syntax-ppss--updated-cache;; Stop forward search running twice. - (setq tex-expl-region-list nil) - ;; Leaving this test here allows users to set `tex-expl-buffer-p' - ;; independently of the mode's automatic detection of an expl3 file. - (unless tex-expl-buffer-p - (goto-char (point-min)) - (let ((case-fold-search nil)) - (while (tex-search-noncomment - (search-forward "\\ExplSyntaxOn" nil t)) - (let ((new-beg (point)) - (new-end (or (tex-search-noncomment - (search-forward "\\ExplSyntaxOff" nil t)) - (point-max)))) - (push (cons new-beg new-end) tex-expl-region-list))))))) - - -;;; Invoking TeX in an inferior shell. - -;; Why use a shell instead of running TeX directly? Because if TeX -;; gets stuck, the user can switch to the shell window and type at it. - -(defvar tex-error-parse-syntax-table - (let ((st (make-syntax-table))) - (modify-syntax-entry ?\( "()" st) - (modify-syntax-entry ?\) ")(" st) - (modify-syntax-entry ?\\ "\\" st) - (modify-syntax-entry ?\{ "_" st) - (modify-syntax-entry ?\} "_" st) - (modify-syntax-entry ?\[ "_" st) - (modify-syntax-entry ?\] "_" st) - ;; Single quotations may appear in errors - (modify-syntax-entry ?\" "_" st) - st) - "Syntax-table used while parsing TeX error messages.") - -(defun tex-old-error-file-name () - ;; This is unreliable, partly because we don't try very hard, and - ;; partly because TeX's output format is eminently ambiguous and unfriendly - ;; to automation. - (save-excursion - (save-match-data - (with-syntax-table tex-error-parse-syntax-table - (beginning-of-line) - (backward-up-list 1) - (skip-syntax-forward "(_") - (while (not (let ((try-filename (thing-at-point 'filename))) - (and try-filename - (not (string= "" try-filename)) - (file-readable-p try-filename)))) - (skip-syntax-backward "(_") - (backward-up-list 1) - (skip-syntax-forward "(_")) - (thing-at-point 'filename))))) - -(defconst tex-error-regexp-alist - ;; First alternative handles the newer --file-line-error style: - ;; ./test2.tex:14: Too many }'s. - '(gnu - ;; Second handles the old-style, which spans two lines but doesn't include - ;; any file info: - ;; ! Too many }'s. - ;; l.396 toto} - ("^l\\.\\([1-9][0-9]*\\) \\(?:\\.\\.\\.\\)?\\(.*\\)$" - tex-old-error-file-name 1 nil nil nil - ;; Since there's no filename to highlight, let's highlight the message. - (2 compilation-error-face)) - ;; A few common warning messages. - ("^\\(?:Und\\|Ov\\)erfull \\\\[hv]box .* at lines? \\(\\([1-9][0-9]*\\)\\(?:--\\([1-9][0-9]*\\)\\)?\\)$" - tex-old-error-file-name (2 . 3) nil 1 nil - (1 compilation-warning-face)) - ("^(Font) *\\([^ \n].* on input line \\([1-9][0-9]*\\)\\)\\.$" - tex-old-error-file-name 2 nil 1 1 - (2 compilation-warning-face)) - ;; Included files get output as ( ...). - ;; FIXME: there tend to be a boatload of them at the beginning of the - ;; output which aren't that interesting. Maybe we should filter out - ;; all the file name that start with /usr/share? - ;; ("(\\.?/\\([^() \n]+\\)" 1 nil nil 0) - )) - -;; The utility functions: - -(define-derived-mode tex-shell shell-mode "TeX-Shell" - (setq-local compilation-error-regexp-alist tex-error-regexp-alist) - (compilation-shell-minor-mode t)) - -;;;###autoload -(defun tex-start-shell () - (with-current-buffer - (make-comint - "tex-shell" - (or tex-shell-file-name (getenv "ESHELL") shell-file-name) - nil - ;; Specify an interactive shell, to make sure it prompts. - "-i") - (let ((proc (get-process "tex-shell"))) - (set-process-sentinel proc #'tex-shell-sentinel) - (set-process-query-on-exit-flag proc nil) - (tex-shell) - (while (zerop (buffer-size)) - (sleep-for 1))))) - -(defun tex-feed-input () - "Send input to the tex shell process. -In the tex buffer this can be used to continue an interactive tex run. -In the tex shell buffer this command behaves like `comint-send-input'." - (interactive) - (set-buffer (tex-shell-buf)) - (comint-send-input) - (tex-recenter-output-buffer nil)) - -(defun tex-display-shell () - "Make the TeX shell buffer visible in a window." - (display-buffer (tex-shell-buf) '(display-buffer-in-previous-window - (inhibit-same-window . t) - (category . tex-shell))) - (tex-recenter-output-buffer nil)) - -(defun tex-shell-sentinel (proc _msg) - (cond ((null (buffer-name (process-buffer proc))) - ;; buffer killed - (set-process-buffer proc nil) - (tex-delete-last-temp-files)) - ((memq (process-status proc) '(signal exit)) - (tex-delete-last-temp-files)))) - -(defun tex-set-buffer-directory (buffer directory) - "Set BUFFER's default directory to be DIRECTORY." - (setq directory (file-name-as-directory (expand-file-name directory))) - (if (not (file-directory-p directory)) - (error "%s is not a directory" directory) - (with-current-buffer buffer - (setq default-directory directory)))) - -(defvar-local tex-send-command-modified-tick 0) - -(defun tex-shell-proc () - (or (tex-shell-running) (error "No TeX subprocess"))) -(defun tex-shell-buf () - (process-buffer (tex-shell-proc))) -(defun tex-shell-buf-no-error () - (let ((proc (tex-shell-running))) - (and proc (process-buffer proc)))) - -(defun tex-send-command (command &optional file background) - "Send COMMAND to TeX shell process, substituting optional FILE for *. -Do this in background if optional BACKGROUND is t. If COMMAND has no *, -FILE will be appended, preceded by a blank, to COMMAND. If FILE is nil, no -substitution will be made in COMMAND. COMMAND can be any expression that -evaluates to a command string. - -Return the process in which TeX is running." - (save-excursion - (let* ((cmd (eval command t)) - (proc (tex-shell-proc)) - (buf (process-buffer proc)) - (star (string-search "*" cmd)) - (string - (concat - (if (null file) - cmd - (if (file-name-absolute-p file) - (setq file (convert-standard-filename file))) - (if star (concat (substring cmd 0 star) - (shell-quote-argument file) - (substring cmd (1+ star))) - (concat cmd " " (shell-quote-argument file)))) - (if background "&" "")))) - ;; Switch to buffer before checking for subproc output in it. - (set-buffer buf) - ;; If text is unchanged since previous tex-send-command, - ;; we haven't got any output. So wait for output now. - (if (= (buffer-modified-tick buf) tex-send-command-modified-tick) - (accept-process-output proc)) - (goto-char (process-mark proc)) - (insert string) - (comint-send-input) - (setq tex-send-command-modified-tick (buffer-modified-tick buf)) - proc))) - -(defun tex-delete-last-temp-files (&optional not-all) - "Delete any junk files from last temp file. -If NOT-ALL is non-nil, save the `.dvi' file." - (if tex-last-temp-file - (let* ((dir (file-name-directory tex-last-temp-file)) - (list (and (file-directory-p dir) - (file-name-all-completions - (file-name-base tex-last-temp-file) - dir)))) - (while list - (if not-all - (and - ;; If arg is non-nil, don't delete the .dvi file. - (not (string-match "\\.dvi$" (car list))) - (delete-file (concat dir (car list)))) - (delete-file (concat dir (car list)))) - (setq list (cdr list)))))) - -(add-hook 'kill-emacs-hook #'tex-delete-last-temp-files) - -;; -;; Machinery to guess the command that the user wants to execute. -;; - -(defvar tex-compile-history nil) - -(defvar tex-input-files-re - (concat "\\." (regexp-opt '("tex" "texi" "texinfo" - "bbl" "ind" "sty" "cls") t) - ;; Include files with no dots (for directories). - "\\'\\|\\`[^.]+\\'")) - -(defcustom tex-use-reftex t - "If non-nil, use RefTeX's list of files to determine what command to use." - :type 'boolean - :group 'tex) - -(defvar tex-compile-commands - `(,@(mapcar (lambda (prefix) - `((concat ,prefix tex-command - " " tex-start-options - " " (if (< 0 (length tex-start-commands)) - (shell-quote-argument tex-start-commands)) - " %f") - t "%r.pdf")) - '("pdf" "xe" "lua")) - ((concat tex-command - " " tex-start-options - " " (if (< 0 (length tex-start-commands)) - (shell-quote-argument tex-start-commands)) - " %f") - t "%r.dvi") - ("xdvi %r &" "%r.dvi") - ("\\doc-view \"%r.pdf\"" "%r.pdf") - ("evince %r.pdf &" "%r.pdf") - ("mupdf %r.pdf &" "%r.pdf") - ("xpdf %r.pdf &" "%r.pdf") - ("gv %r.ps &" "%r.ps") - ("yap %r &" "%r.dvi") - ("advi %r &" "%r.dvi") - ("gv %r.pdf &" "%r.pdf") - ("bibtex %r" "%r.aux" "%r.bbl") - ("makeindex %r" "%r.idx" "%r.ind") - ("texindex %r.??") - ("dvipdfm %r" "%r.dvi" "%r.pdf") - ("dvipdf %r" "%r.dvi" "%r.pdf") - ("dvips -o %r.ps %r" "%r.dvi" "%r.ps") - ("ps2pdf %r.ps" "%r.ps" "%r.pdf") - ("lpr %r.ps" "%r.ps")) - "List of commands for `tex-compile'. -Each element should be of the form (FORMAT IN OUT) where -FORMAT is an expression that evaluates to a string that can contain - - `%r' the main file name without extension. - - `%f' the main file name. -IN can be either a string (with the same % escapes in it) indicating - the name of the input file, or t to indicate that the input is all - the TeX files of the document, or nil if we don't know. -OUT describes the output file and is either a %-escaped string - or nil to indicate that there is no output file.") - -(defun tex-guess-main-file (&optional all) - "Find a likely `tex-main-file'. -Looks for hints in other buffers in the same directory or in -ALL other buffers. If ALL is `sub' only look at buffers in parent directories -of the current buffer." - (let ((dir default-directory) - (header-re tex-start-of-header)) - (catch 'found - ;; Look for a buffer with `tex-main-file' set. - (dolist (buf (if (consp all) all (buffer-list))) - (with-current-buffer buf - (when (and (cond - ((null all) (equal dir default-directory)) - ((eq all 'sub) (string-prefix-p default-directory dir)) - (t)) - (stringp tex-main-file)) - (throw 'found (expand-file-name tex-main-file))))) - ;; Look for a buffer containing the magic `tex-start-of-header'. - (dolist (buf (if (consp all) all (buffer-list))) - (with-current-buffer buf - (when (and (cond - ((null all) (equal dir default-directory)) - ((eq all 'sub) (string-prefix-p default-directory dir)) - (t)) - buffer-file-name - ;; (or (easy-mmode-derived-mode-p 'latex-mode) - ;; (easy-mmode-derived-mode-p 'plain-tex-mode)) - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (re-search-forward - header-re (+ (point) 10000) t)))) - (throw 'found (expand-file-name buffer-file-name)))))))) - -(defun tex-main-file () - "Return the relative name of the main file." - (let* ((file (or tex-main-file - ;; Compatibility with AUCTeX. - (with-no-warnings - (when (boundp 'TeX-master) - (cond ((stringp TeX-master) - (setq-local tex-main-file TeX-master)) - ((and (eq TeX-master t) buffer-file-name) - (file-relative-name buffer-file-name))))) - ;; Try to guess the main file. - (if (not buffer-file-name) - (error "Buffer is not associated with any file") - (file-relative-name - (if (save-excursion - (goto-char (point-min)) - (re-search-forward tex-start-of-header - (+ (point) 10000) t)) - ;; This is the main file. - buffer-file-name - ;; This isn't the main file, let's try to find better, - (or (tex-guess-main-file) - (tex-guess-main-file 'sub) - ;; (tex-guess-main-file t) - buffer-file-name))))))) - (if (or (file-exists-p file) (string-match "\\.tex\\'" file)) - file (concat file ".tex")))) - -(defun tex-summarize-command (cmd) - (if (not (stringp cmd)) "" - (mapconcat #'identity - (mapcar (compf car split-string) - (split-string cmd "\\s-*\\(?:;\\|&&\\)\\s-*")) - "&"))) - -(defun tex-uptodate-p (file) - "Return non-nil if FILE is not up-to-date w.r.t the document source files. -FILE is typically the output DVI or PDF file." - ;; We should check all the files included !!! - (and - ;; Clearly, the target must exist. - (file-exists-p file) - ;; And the last run must not have asked for a rerun. - ;; FIXME: this should check that the last run was done on the same file. - (let ((buf (condition-case nil (tex-shell-buf) (error nil)))) - (when buf - (with-current-buffer buf - (save-excursion - (goto-char (point-max)) - (and (re-search-backward - (concat "(see the transcript file for additional information)" - "\\|^Output written on .*" - (regexp-quote (file-name-nondirectory file)) - " (.*)\\.") - nil t) - (> (save-excursion - ;; Usually page numbers are output as [N], but - ;; I've already seen things like - ;; [N{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] - ;; as well as [N.N] (e.g. with 'acmart' style). - (or (re-search-backward - "\\[[0-9]+\\({[^}]*}\\|\\.[0-9]+\\)?\\]" - nil t) - (point-min))) - (save-excursion - (or (re-search-backward "Rerun" nil t) - (point-min))))))))) - ;; And the input files must not have been changed in the meantime. - (let ((files (if (and tex-use-reftex - (fboundp 'reftex-scanning-info-available-p) - (reftex-scanning-info-available-p)) - (reftex-all-document-files) - (list (file-name-directory (expand-file-name file))))) - (ignored-dirs-re - (concat - (regexp-opt - (delq nil (mapcar (lambda (s) (if (eq (aref s (1- (length s))) ?/) - (substring s 0 (1- (length s))))) - completion-ignored-extensions)) - t) "\\'")) - (uptodate t)) - (while (and files uptodate) - (let ((f (pop files))) - (if (and (file-directory-p f) - ;; Avoid infinite loops. - (not (file-symlink-p f))) - (unless (string-match ignored-dirs-re f) - (setq files (nconc - (ignore-errors ;Not readable or something. - (directory-files f t tex-input-files-re)) - files))) - (when (file-newer-than-file-p f file) - (setq uptodate nil))))) - uptodate))) - -(defvar tex-executable-cache nil) -(defun tex-executable-exists-p (name) - "Like `executable-find' but with a cache." - (let ((f (and (string-match "^\\\\\\([^ \t\n]+\\)" name) - (intern-soft (concat "tex-cmd-" (match-string 1 name)))))) - (if (fboundp f) - f - (let ((cache (assoc name tex-executable-cache))) - (if cache (cdr cache) - (let ((executable (executable-find name))) - (push (cons name executable) tex-executable-cache) - executable)))))) - -(defun tex-command-executable (cmd) - (let ((s (if (stringp cmd) cmd (eval (car cmd) t)))) - (substring s 0 (string-match "[ \t]\\|\\'" s)))) - -(defun tex-command-active-p (cmd fspec) - "Return non-nil if the CMD spec might need to be run." - (let ((in (nth 1 cmd)) - (out (nth 2 cmd))) - (if (stringp in) - (let ((file (format-spec in fspec))) - (when (file-exists-p file) - (or (not out) - (file-newer-than-file-p - file (format-spec out fspec))))) - (when (and (eq in t) (stringp out)) - (not (tex-uptodate-p (format-spec out fspec))))))) - -(defcustom tex-cmd-bibtex-args "--min-crossref=100" - "Extra args to pass to `bibtex' by default." - :type 'string - :version "23.1" - :group 'tex-run) - -(defun tex--quote-spec (fspec) - (cl-loop for (char . file) in fspec - collect (cons char (shell-quote-argument file)))) - -(defun tex-format-cmd (format fspec) - "Like `format-spec' but add user-specified args to the command. -Only applies the FSPEC to the args part of FORMAT." - (setq fspec (tex--quote-spec fspec)) - (if (not (string-match "\\([^ /\\]+\\) " format)) - (format-spec format fspec) - (let* ((prefix (substring format 0 (match-beginning 0))) - (cmd (match-string 1 format)) - (args (substring format (match-end 0))) - (sym (intern-soft (format "tex-cmd-%s-args" cmd))) - (extra-args (and sym (symbol-value sym)))) - (concat prefix cmd - (if extra-args (concat " " extra-args)) - " " (format-spec args fspec))))) - -(defun tex-compile-default (fspec) - "Guess a default command given the `format-spec' FSPEC." - ;; TODO: Learn to do latex+dvips! - (let ((cmds nil) - (unchanged-in nil)) - ;; Only consider active commands. - (dolist (cmd tex-compile-commands) - (when (tex-executable-exists-p (tex-command-executable cmd)) - (if (tex-command-active-p cmd fspec) - (push cmd cmds) - (push (nth 1 cmd) unchanged-in)))) - ;; If no command seems to be applicable, arbitrarily pick the first one. - (setq cmds (if cmds (nreverse cmds) (list (car tex-compile-commands)))) - ;; Remove those commands whose input was considered stable for - ;; some other command (typically if (t . "%.pdf") is inactive - ;; then we're using pdflatex and the fact that the dvi file - ;; is nonexistent doesn't matter). - (let ((tmp nil)) - (dolist (cmd cmds) - (unless (member (nth 1 cmd) unchanged-in) - (push cmd tmp))) - ;; Only remove if there's something left. - (if tmp (setq cmds (nreverse tmp)))) - ;; Remove commands whose input is not up-to-date either. - (let ((outs (delq nil (mapcar (lambda (x) (nth 2 x)) cmds))) - (tmp nil)) - (dolist (cmd cmds) - (unless (member (nth 1 cmd) outs) - (push cmd tmp))) - ;; Only remove if there's something left. - (if tmp (setq cmds (nreverse tmp)))) - ;; Select which file we're going to operate on (the latest). - (let ((latest (nth 1 (car cmds)))) - (dolist (cmd (prog1 (cdr cmds) (setq cmds (list (car cmds))))) - (if (equal latest (nth 1 cmd)) - (push cmd cmds) - (unless (eq latest t) ;Can't beat that! - (if (or (not (stringp latest)) - (eq (nth 1 cmd) t) - (and (stringp (nth 1 cmd)) - (file-newer-than-file-p - (format-spec (nth 1 cmd) fspec) - (format-spec latest fspec)))) - (setq latest (nth 1 cmd) cmds (list cmd))))))) - ;; Expand the command spec into the actual text. - (dolist (cmd (prog1 cmds (setq cmds nil))) - (push (cons (eval (car cmd) t) (cdr cmd)) cmds)) - ;; Select the favorite command from the history. - (let ((hist tex-compile-history) - re hist-cmd) - (while hist - (setq hist-cmd (pop hist)) - (setq re (concat "\\`" - (regexp-quote (tex-command-executable hist-cmd)) - "\\([ \t]\\|\\'\\)")) - (dolist (cmd cmds) - ;; If the hist entry uses the same command and applies to a file - ;; of the same type (e.g. `gv %r.pdf' vs `gv %r.ps'), select cmd. - (and (string-match re (car cmd)) - (or (not (string-match "%[fr]\\([-._[:alnum:]]+\\)" (car cmd))) - (string-match (regexp-quote (match-string 1 (car cmd))) - hist-cmd)) - (setq hist nil cmds (list cmd))))) - ;; Substitute and return. - (if (and hist-cmd - (string-match (concat "[' \t\"]" (format-spec "%r" fspec) - "\\([;&' \t\"]\\|\\'\\)") - hist-cmd)) - ;; The history command was already applied to the same file, - ;; so just reuse it. - hist-cmd - (if cmds (tex-format-cmd (caar cmds) fspec)))))) - -(defun tex-cmd-doc-view (file) - (pop-to-buffer (find-file-noselect file))) - -(defun tex-compile (dir cmd) - "Run a command CMD on current TeX buffer's file in DIR." - ;; FIXME: Use time-stamps on files to decide the next op. - (interactive - (let* ((file (tex-main-file)) - (default-directory - (prog1 (file-name-directory (expand-file-name file)) - (setq file (file-name-nondirectory file)))) - (root (file-name-sans-extension file)) - (fspec (list (cons ?r root) - (cons ?f file))) - (default (tex-compile-default fspec))) - (list default-directory - (completing-read - (format-prompt "Command" (tex-summarize-command default)) - (mapcar (lambda (x) - (list (tex-format-cmd (eval (car x) t) fspec))) - tex-compile-commands) - nil nil nil 'tex-compile-history default)))) - (save-some-buffers (not compilation-ask-about-save) nil) - (let ((f (and (string-match "^\\\\\\([^ \t\n]+\\)" cmd) - (intern-soft (concat "tex-cmd-" (match-string 1 cmd)))))) - (if (functionp f) - (condition-case nil - (let ((default-directory dir)) - (apply f (split-string-and-unquote - (substring cmd (match-end 0))))) - (wrong-number-of-arguments - (error "Wrong number of arguments to %s" - (substring (symbol-name f) 8)))) - (if (tex-shell-running) - (tex-kill-job) - (tex-start-shell)) - (setq tex-print-file (expand-file-name (tex-main-file))) - (tex-send-tex-command cmd dir)))) - -(defun tex-start-tex (command file &optional dir) - "Start a TeX run, using COMMAND on FILE." - (let* ((star (string-search "*" command)) - (compile-command - (if star - (concat (substring command 0 star) - (shell-quote-argument file) - (substring command (1+ star))) - (concat command " " - tex-start-options - (if (< 0 (length tex-start-commands)) - (concat - (shell-quote-argument tex-start-commands) " ")) - (shell-quote-argument file))))) - (tex-send-tex-command compile-command dir))) - -(defun tex-send-tex-command (cmd &optional dir) - (unless (or (equal dir (let ((buf (tex-shell-buf-no-error))) - (and buf (with-current-buffer buf - default-directory)))) - (not dir)) - (let (shell-dirtrack-verbose) - (tex-send-command tex-shell-cd-command dir))) - (with-current-buffer (process-buffer (tex-send-command cmd)) - (setq next-error-last-buffer (current-buffer)) - (compilation-forget-errors)) - (tex-display-shell) - (setq tex-last-buffer-texed (current-buffer))) - -;;; The commands: - -(defun tex-region (beg end) - "Run TeX on the current region, via a temporary file. -The file's name comes from the variable `tex-zap-file' and the -variable `tex-directory' says where to put it. - -If the buffer has a header, the header is given to TeX before the -region itself. The buffer's header is all lines between the strings -defined by `tex-start-of-header' and `tex-end-of-header' inclusive. -The header must start in the first 100 lines of the buffer. - -The value of `tex-trailer' is given to TeX as input after the region. - -The value of `tex-command' specifies the command to use to run TeX." - (interactive "r") - (if (tex-shell-running) - (tex-kill-job) - (tex-start-shell)) - (or tex-zap-file - (setq tex-zap-file (tex-generate-zap-file-name))) - ;; Temp file will be written and TeX will be run in zap-directory. - ;; If the TEXINPUTS file has relative directories or if the region has - ;; \input of files, this must be the same directory as the file for - ;; TeX to access the correct inputs. That's why it's safest if - ;; tex-directory is ".". - (let* ((zap-directory - (file-name-as-directory (expand-file-name tex-directory))) - (tex-out-file (expand-file-name (concat tex-zap-file ".tex") - zap-directory)) - ;; We may be running from an unsaved buffer, in which case - ;; there's no point in guessing for a main file name. - (main-file (and buffer-file-name - (expand-file-name (tex-main-file)))) - (ismain (string-equal main-file (buffer-file-name))) - already-output) - ;; Don't delete temp files if we do the same buffer twice in a row. - (or (eq (current-buffer) tex-last-buffer-texed) - (tex-delete-last-temp-files t)) - (let ((default-directory zap-directory)) ; why? - ;; We assume the header is fully contained in tex-main-file. - ;; We use f-f-ns so we get prompted about any changes on disk. - (if (not main-file) - (setq already-output 0) - (with-current-buffer (find-file-noselect main-file) - (setq already-output (tex-region-header tex-out-file - (and ismain beg))))) - ;; Write out the specified region (but don't repeat anything - ;; already written in the header). - (write-region (if ismain - (max beg already-output) - beg) - end tex-out-file (not (zerop already-output))) - ;; Write the trailer, if any. - ;; Precede it with a newline to make sure it - ;; is not hidden in a comment. - (if tex-trailer - (write-region (concat "\n" tex-trailer) nil - tex-out-file t))) - ;; Record the file name to be deleted afterward. - (setq tex-last-temp-file tex-out-file) - ;; Use a relative file name here because (1) the proper dir - ;; is already current, and (2) the abs file name is sometimes - ;; too long and can make tex crash. - (tex-start-tex tex-command (concat tex-zap-file ".tex") zap-directory) - (setq tex-print-file tex-out-file))) - -(defun tex-region-header (file &optional beg) - "If there is a TeX header in the current buffer, write it to FILE. -Return point at the end of the region so written, or zero. If -the optional buffer position BEG is specified, then the region -written out starts at BEG, if this lies before the start of the header. - -If the first line matches `tex-first-line-header-regexp', it is -also written out. The variables `tex-start-of-header' and -`tex-end-of-header' are used to locate the header. Note that the -start of the header is required to be within the first 100 lines." - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (let ((search-end (save-excursion - (forward-line 100) - (point))) - (already-output 0) - hbeg hend) - ;; Maybe copy first line, such as `\input texinfo', to temp file. - (and tex-first-line-header-regexp - (looking-at tex-first-line-header-regexp) - (write-region (point) - (progn (forward-line 1) - (setq already-output (point))) - file)) - ;; Write out the header, if there is one, and any of the - ;; specified region which extends before it. But don't repeat - ;; anything already written. - (and tex-start-of-header - (re-search-forward tex-start-of-header search-end t) - (progn - (beginning-of-line) - (setq hbeg (point)) ; mark beginning of header - (when (re-search-forward tex-end-of-header nil t) - (forward-line 1) - (setq hend (point)) ; mark end of header - (write-region - (max (if beg - (min hbeg beg) - hbeg) - already-output) - hend file (not (zerop already-output))) - (setq already-output hend)))) - already-output)))) - -(defun tex-buffer () - "Run TeX on current buffer. See \\[tex-region] for more information. -Does not save the buffer, so it's useful for trying experimental versions. -See \\[tex-file] for an alternative." - (interactive) - (tex-region (point-min) (point-max))) - -(defun tex-file () - "Prompt to save all buffers and run TeX (or LaTeX) on current buffer's file. -This function is more useful than \\[tex-buffer] when you need the -`.aux' file of LaTeX to have the correct name." - (interactive) - (when tex-offer-save - (save-some-buffers)) - (let* ((source-file (tex-main-file)) - (file-dir (file-name-directory (expand-file-name source-file)))) - (if (tex-shell-running) - (tex-kill-job) - (tex-start-shell)) - (tex-start-tex tex-command source-file file-dir) - (setq tex-print-file (expand-file-name source-file)))) - -(defun tex-generate-zap-file-name () - "Generate a unique name suitable for use as a file name." - ;; Include the shell process number and host name - ;; in case there are multiple shells (for same or different user). - ;; Dec 1998: There is a report that some versions of xdvi - ;; don't work with file names that start with #. - (format "_TZ_%d-%s" - (process-id (get-buffer-process "*tex-shell*")) - (subst-char-in-string ?. ?- (system-name)))) - -;; This will perhaps be useful for modifying TEXINPUTS. -;; Expand each file name, separated by colons, in the string S. -(defun tex-expand-files (s) - (let (elts (start 0)) - (while (string-match ":" s start) - (setq elts (cons (substring s start (match-beginning 0)) elts)) - (setq start (match-end 0))) - (or (= start 0) - (setq elts (cons (substring s start) elts))) - (mapconcat (lambda (elt) - (if (= (length elt) 0) elt (expand-file-name elt))) - (nreverse elts) ":"))) - -(defun tex-shell-running () - (let ((proc (get-process "tex-shell"))) - (when proc - (if (and (eq (process-status proc) 'run) - (buffer-live-p (process-buffer proc))) - ;; return the TeX process on success - proc - ;; get rid of the process permanently - ;; this should get rid of the annoying w32 problem with - ;; dead tex-shell buffer and live process - (delete-process proc))))) - -(defun tex-kill-job () - "Kill the currently running TeX job." - (interactive) - ;; `quit-process' leads to core dumps of the tex process (except if - ;; coredumpsize has limit 0kb as on many environments). One would - ;; like to use (kill-process proc 'lambda), however that construct - ;; does not work on some systems and kills the shell itself. - (let ((proc (get-process "tex-shell"))) - (when proc (quit-process proc t)))) - -(defun tex-recenter-output-buffer (linenum) - "Redisplay buffer of TeX job output so that most recent output can be seen. -The last line of the buffer is displayed on -line LINE of the window, or centered if LINE is nil." - (interactive "P") - (let ((tex-shell (get-buffer "*tex-shell*"))) - (if (null tex-shell) - (message "No TeX output buffer") - (when-let* ((window - (display-buffer tex-shell '(display-buffer-in-previous-window - (inhibit-same-window . t) - (category . tex-shell))))) - (with-selected-window window - (bury-buffer tex-shell) - (goto-char (point-max)) - (recenter (if linenum - (prefix-numeric-value linenum) - (/ (window-height) 2)))))))) - -(defcustom tex-print-file-extension ".dvi" - "The TeX-compiled file extension for viewing and printing. -If you use pdflatex instead of latex, set this to \".pdf\" and modify - `tex-dvi-view-command' and `tex-dvi-print-command' appropriately." - :type 'string - :group 'tex-view - :version "25.1") - -(defun tex-print (&optional alt) - "Print the .dvi file made by \\[tex-region], \\[tex-buffer] or \\[tex-file]. -Runs the shell command defined by `tex-dvi-print-command'. If prefix argument -is provided, use the alternative command, `tex-alt-dvi-print-command'." - (interactive "P") - (let ((print-file-name-dvi (tex-append tex-print-file - tex-print-file-extension)) - test-name) - (if (and (not (equal (current-buffer) tex-last-buffer-texed)) - (buffer-file-name) - ;; Check that this buffer's printed file is up to date. - (file-newer-than-file-p - (setq test-name (tex-append (buffer-file-name) - tex-print-file-extension)) - (buffer-file-name))) - (setq print-file-name-dvi test-name)) - (if (not (file-exists-p print-file-name-dvi)) - (error "No appropriate `.dvi' file could be found") - (if (tex-shell-running) - (tex-kill-job) - (tex-start-shell)) - (tex-send-command - (if alt tex-alt-dvi-print-command tex-dvi-print-command) - print-file-name-dvi - t)))) - -(defun tex-alt-print () - "Print the .dvi file made by \\[tex-region], \\[tex-buffer] or \\[tex-file]. -Runs the shell command defined by `tex-alt-dvi-print-command'." - (interactive) - (tex-print t)) - -(defvar tex-view--warned-once nil) -(defun tex-view () - "Preview the last `.dvi' file made by running TeX under Emacs. -This means, made using \\[tex-region], \\[tex-buffer] or \\[tex-file]. -The variable `tex-dvi-view-command' specifies the shell command for preview. -You must set that variable yourself before using this command, -because there is no standard value that would generally work." - (interactive) - (or tex-dvi-view-command - (error "You must set `tex-dvi-view-command'")) - ;; Restart the TeX shell if necessary. - (or (tex-shell-running) - (tex-start-shell)) - (let ((tex-dvi-print-command - (if (stringp tex-dvi-view-command) - tex-dvi-view-command - (unless tex-view--warned-once - (warn (concat "Setting `tex-dvi-view-command' to an S-expression" - " is obsolete since Emacs " "31.1")) - (setq tex-view--warned-once t)) - (eval tex-dvi-view-command t)))) - (tex-print))) - -(defun tex-append (file-name suffix) - "Append to FILENAME the suffix SUFFIX, using same algorithm TeX uses. -Pascal-based TeX scans for the first period, C TeX uses the last. -No period is retained immediately before SUFFIX, -so normally SUFFIX starts with one." - (if (stringp file-name) - (let ((file (file-name-nondirectory file-name)) - trial-name) - ;; Try splitting on last period. - ;; The first-period split can get fooled when two files - ;; named a.tex and a.b.tex are both tex'd; - ;; the last-period split must be right if it matches at all. - (setq trial-name - (concat (file-name-directory file-name) - (substring file 0 - (string-match "\\.[^.]*$" file)) - suffix)) - (if (or (file-exists-p trial-name) - (file-exists-p (concat trial-name ".aux"))) ;for BibTeX files - trial-name - ;; Not found, so split on first period. - (concat (file-name-directory file-name) - (substring file 0 - (string-search "." file)) - suffix))) - " ")) - -(defun tex-show-print-queue () - "Show the print queue that \\[tex-print] put your job on. -Runs the shell command defined by `tex-show-queue-command'." - (interactive) - (if (tex-shell-running) - (tex-kill-job) - (tex-start-shell)) - (tex-send-command tex-show-queue-command) - (tex-display-shell)) - -(defun tex-bibtex-file () - "Run BibTeX on the current buffer's file." - (interactive) - (if (tex-shell-running) - (tex-kill-job) - (tex-start-shell)) - (let* (shell-dirtrack-verbose - (source-file (expand-file-name (tex-main-file))) - (tex-out-file - (tex-append (file-name-nondirectory source-file) "")) - (file-dir (file-name-directory source-file))) - (tex-send-command tex-shell-cd-command file-dir) - (tex-send-command tex-bibtex-command tex-out-file)) - (tex-display-shell)) - -;;;; -;;;; LaTeX indentation -;;;; - -(defvar tex-indent-allhanging t) -(defvar tex-indent-arg 4) -(defvar tex-indent-basic 2) -(defvar tex-indent-item tex-indent-basic) -(defvar tex-indent-item-re "\\\\\\(bib\\)?item\\>") -(defcustom latex-noindent-environments '("document") - "Environments whose content is not indented by `tex-indent-basic'." - :type '(repeat string) - :safe (lambda (x) (not (memq nil (mapcar #'stringp x)))) - :group 'tex-file - :version "27.1") - -(defcustom latex-noindent-commands '("emph" "footnote") - "Commands for which `tex-indent-basic' should not be used." - :type '(repeat string) - :safe (lambda (x) (not (memq nil (mapcar #'stringp x)))) - :group 'tex-file - :version "27.1") - -(defvar tex-latex-indent-syntax-table - (let ((st (make-syntax-table tex-mode-syntax-table))) - (modify-syntax-entry ?$ "." st) - (modify-syntax-entry ?\( "." st) - (modify-syntax-entry ?\) "." st) - st) - "Syntax table used while computing indentation.") - -(defun latex-indent (&optional _arg) - (if (and (eq (get-text-property (if (and (eobp) (bolp)) - (max (point-min) (1- (point))) - (line-beginning-position)) - 'face) - 'tex-verbatim)) - 'noindent - (with-syntax-table tex-latex-indent-syntax-table - ;; TODO: Rather than ignore $, we should try to be more clever about it. - (let ((indent - (save-excursion - (beginning-of-line) - (latex-find-indent)))) - (if (< indent 0) (setq indent 0)) - (if (<= (current-column) (current-indentation)) - (indent-line-to indent) - (save-excursion (indent-line-to indent))))))) - -(defcustom latex-indent-within-escaped-parens nil - "Non-nil means add extra indent to text within escaped parens. -When this is non-nil, text within matching pairs of escaped -parens is indented at the column following the open paren. The -default value does not add any extra indent thus providing the -behavior of Emacs 22 and earlier." - :type 'boolean - :group 'tex - :version "23.1") - -(defun latex-find-indent (&optional virtual) - "Find the proper indentation of text after point. -VIRTUAL if non-nil indicates that we're only trying to find the indentation - in order to determine the indentation of something else. -There might be text before point." - (let ((latex-handle-escaped-parens latex-indent-within-escaped-parens)) - (save-excursion - (skip-chars-forward " \t") - (or - ;; Stick the first line at column 0. - (and (= (point-min) (line-beginning-position)) 0) - ;; Trust the current indentation, if such info is applicable. - (and virtual (save-excursion (skip-chars-backward " \t&") (bolp)) - (current-column)) - ;; Stick verbatim environments to the left margin. - (and (looking-at "\\\\\\(begin\\|end\\) *{\\([^\n}]+\\)") - (member (match-string 2) tex-verbatim-environments) - 0) - ;; Put leading close-paren where the matching open paren would be. - (let (escaped) - (and (or (eq (latex-syntax-after) ?\)) - ;; Try to handle escaped close parens but keep - ;; original position if it doesn't work out. - (and latex-handle-escaped-parens - (setq escaped (looking-at "\\\\\\([])}]\\)")))) - (ignore-errors - (save-excursion - (when escaped - (goto-char (match-beginning 1))) - (latex-skip-close-parens) - (latex-backward-sexp-1) - (latex-find-indent 'virtual))))) - ;; Default (maybe an argument) - (let ((pos (point)) - ;; Outdent \item if necessary. - (indent (if (looking-at tex-indent-item-re) (- tex-indent-item) 0)) - up-list-pos) - ;; Find the previous point which determines our current indentation. - (condition-case err - (progn - (latex-backward-sexp-1) - (while (> (current-column) (current-indentation)) - (latex-backward-sexp-1))) - (scan-error - (setq up-list-pos (nth 2 err)))) - (cond - ((= (point-min) pos) 0) ; We're really just indenting the first line. - ((integerp up-list-pos) - ;; Have to indent relative to the open-paren. - (goto-char up-list-pos) - (if (and (not tex-indent-allhanging) - (save-excursion - ;; Make sure we're an argument to a macro and - ;; that the macro is at the beginning of a line. - (condition-case nil - (progn - (while (eq (char-syntax (char-after)) ?\() - (forward-sexp -1)) - (and (eq (char-syntax (char-after)) ?/) - (progn (skip-chars-backward " \t&") - (bolp)))) - (scan-error nil))) - (> pos (progn (latex-down-list) - (forward-comment (point-max)) - (point)))) - ;; Align with the first element after the open-paren. - (current-column) - ;; We're the first element after a hanging brace. - (goto-char up-list-pos) - (+ (if (if (eq (char-after) ?\{) - (save-excursion - (skip-chars-backward " \t") - (let ((end (point))) - (skip-chars-backward "a-zA-Z") - (and (eq (char-before) ?\\) - (member (buffer-substring (point) end) - latex-noindent-commands)))) - (and (looking-at "\\\\begin *{\\([^\n}]+\\)") - (member (match-string 1) - latex-noindent-environments))) - 0 tex-indent-basic) - indent (latex-find-indent 'virtual)))) - ;; We're now at the "beginning" of a line. - ((not (and (not virtual) (eq (char-after) ?\\))) - ;; Nothing particular here: just keep the same indentation. - (+ indent (current-column))) - ;; We're now looking at a macro call. - ((looking-at tex-indent-item-re) - ;; Indenting relative to an item, have to re-add the outdenting. - (+ indent (current-column) tex-indent-item)) - (t - (let ((col (current-column))) - (if (or (not (eq (char-syntax (or (char-after pos) ?\s)) ?\()) - ;; Can't be an arg if there's an empty line in between. - (save-excursion (re-search-forward "^[ \t]*$" pos t))) - ;; If the first char was not an open-paren, there's - ;; a risk that this is really not an argument to the - ;; macro at all. - (+ indent col) - (forward-sexp 1) - (if (< (line-end-position) - (save-excursion (forward-comment (point-max)) - (point))) - ;; we're indenting the first argument. - (min (current-column) (+ tex-indent-arg col)) - (skip-syntax-forward " ") - (current-column))))))))))) -;;; DocTeX support - -(defun doctex-font-lock-^^A () - (if (eq (char-after (line-beginning-position)) ?\%) - (progn - (put-text-property - (1- (match-beginning 1)) (match-beginning 1) - 'syntax-table - (string-to-syntax ">")) - (let ((end (line-end-position))) - (if (< end (point-max)) - (put-text-property - end (1+ end) - 'syntax-table - (string-to-syntax "> b")))) - (string-to-syntax "< b")))) - -(defun doctex-font-lock-syntactic-face-function (state) - ;; Mark DocTeX documentation, which is parsed as a style A comment - ;; starting in column 0. - (if (or (nth 3 state) (nth 7 state) - (not (memq (char-before (nth 8 state)) - '(?\n nil)))) - ;; Anything else is just as for LaTeX. - (tex-font-lock-syntactic-face-function state) - 'font-lock-doc-face)) - -(eval-when-compile - (defconst doctex-syntax-propertize-rules - (syntax-propertize-precompile-rules - latex-syntax-propertize-rules - ;; For DocTeX comment-in-doc (DocTeX ≥3 also allows ^^X). - ;; We make the comment start on the second char because of bug#35140. - ("\\^\\(\\^\\)[AX]" (1 (doctex-font-lock-^^A)))))) - -(defvar doctex-font-lock-keywords - (append tex-font-lock-keywords - '(("^%<[^>]*>" (0 font-lock-preprocessor-face t))))) - -;;;###autoload -(define-derived-mode doctex-mode latex-mode "DocTeX" - "Major mode to edit DocTeX files." - (setq font-lock-defaults - (cons (append (car font-lock-defaults) '(doctex-font-lock-keywords)) - (mapcar - (lambda (x) - (pcase (car-safe x) - ('font-lock-syntactic-face-function - (cons (car x) #'doctex-font-lock-syntactic-face-function)) - (_ x))) - (cdr font-lock-defaults)))) - (setq-local syntax-propertize-function - (syntax-propertize-rules doctex-syntax-propertize-rules))) - -;;; Prettify Symbols Support - -(defvar tex--prettify-symbols-alist - '( ;; Lowercase Greek letters. - ("\\alpha" . ?α) - ("\\beta" . ?β) - ("\\gamma" . ?γ) - ("\\delta" . ?δ) - ("\\epsilon" . ?ϵ) - ("\\zeta" . ?ζ) - ("\\eta" . ?η) - ("\\theta" . ?θ) - ("\\iota" . ?ι) - ("\\kappa" . ?κ) - ("\\lambda" . ?λ) - ("\\mu" . ?μ) - ("\\nu" . ?ν) - ("\\xi" . ?ξ) - ;; There is no \omicron because it looks like a latin o. - ("\\pi" . ?π) - ("\\rho" . ?ρ) - ("\\sigma" . ?σ) - ("\\tau" . ?τ) - ("\\upsilon" . ?υ) - ("\\phi" . ?ϕ) - ("\\chi" . ?χ) - ("\\psi" . ?ψ) - ("\\omega" . ?ω) - ;; Uppercase Greek letters. - ("\\Gamma" . ?Γ) - ("\\Delta" . ?Δ) - ("\\Lambda" . ?Λ) - ("\\Phi" . ?Φ) - ("\\Pi" . ?Π) - ("\\Psi" . ?Ψ) - ("\\Sigma" . ?Σ) - ("\\Theta" . ?Θ) - ("\\Upsilon" . ?Υ) - ("\\Xi" . ?Ξ) - ("\\Omega" . ?Ω) - - ;; Other math symbols (taken from leim/quail/latin-ltx.el). - ("\\Box" . ?□) - ("\\Bumpeq" . ?≎) - ("\\Cap" . ?⋒) - ("\\Cup" . ?⋓) - ("\\Diamond" . ?◇) - ("\\Downarrow" . ?⇓) - ("\\H{o}" . ?ő) - ("\\Im" . ?ℑ) - ("\\Join" . ?⋈) - ("\\Leftarrow" . ?⇐) - ("\\Leftrightarrow" . ?⇔) - ("\\Ll" . ?⋘) - ("\\Lleftarrow" . ?⇚) - ("\\Longleftarrow" . ?⇐) - ("\\Longleftrightarrow" . ?⇔) - ("\\Longrightarrow" . ?⇒) - ("\\Lsh" . ?↰) - ("\\Re" . ?ℜ) - ("\\Rightarrow" . ?⇒) - ("\\Rrightarrow" . ?⇛) - ("\\Rsh" . ?↱) - ("\\Subset" . ?⋐) - ("\\Supset" . ?⋑) - ("\\Uparrow" . ?⇑) - ("\\Updownarrow" . ?⇕) - ("\\Vdash" . ?⊩) - ("\\Vert" . ?‖) - ("\\Vvdash" . ?⊪) - ("\\aleph" . ?ℵ) - ("\\amalg" . ?∐) - ("\\angle" . ?∠) - ("\\approx" . ?≈) - ("\\approxeq" . ?≊) - ("\\ast" . ?∗) - ("\\asymp" . ?≍) - ("\\backcong" . ?≌) - ("\\backepsilon" . ?∍) - ("\\backprime" . ?‵) - ("\\backsim" . ?∽) - ("\\backsimeq" . ?⋍) - ("\\backslash" . ?\\) - ("\\barwedge" . ?⊼) - ("\\because" . ?∵) - ("\\beth" . ?ℶ) - ("\\between" . ?≬) - ("\\bigcap" . ?⋂) - ("\\bigcirc" . ?◯) - ("\\bigcup" . ?⋃) - ("\\bigodot" . ?⨀) - ("\\bigoplus" . ?⨁) - ("\\bigotimes" . ?⨂) - ("\\bigsqcup" . ?⨆) - ("\\bigstar" . ?★) - ("\\bigtriangledown" . ?▽) - ("\\bigtriangleup" . ?△) - ("\\biguplus" . ?⨄) - ("\\bigvee" . ?⋁) - ("\\bigwedge" . ?⋀) - ("\\blacklozenge" . ?✦) - ("\\blacksquare" . ?▪) - ("\\blacktriangle" . ?▴) - ("\\blacktriangledown" . ?▾) - ("\\blacktriangleleft" . ?◂) - ("\\blacktriangleright" . ?▸) - ("\\bot" . ?⊥) - ("\\bowtie" . ?⋈) - ("\\boxminus" . ?⊟) - ("\\boxplus" . ?⊞) - ("\\boxtimes" . ?⊠) - ("\\bullet" . ?•) - ("\\bumpeq" . ?≏) - ("\\cap" . ?∩) - ("\\cdot" . ?⋅) - ("\\cdots" . ?⋯) - ("\\centerdot" . ?·) - ("\\checkmark" . ?✓) - ("\\chi" . ?χ) - ("\\circ" . ?∘) - ("\\circeq" . ?≗) - ("\\circlearrowleft" . ?↺) - ("\\circlearrowright" . ?↻) - ("\\circledR" . ?®) - ("\\circledS" . ?Ⓢ) - ("\\circledast" . ?⊛) - ("\\circledcirc" . ?⊚) - ("\\circleddash" . ?⊝) - ("\\clubsuit" . ?♣) - ("\\coloneq" . ?≔) - ("\\complement" . ?∁) - ("\\cong" . ?≅) - ("\\coprod" . ?∐) - ("\\cup" . ?∪) - ("\\curlyeqprec" . ?⋞) - ("\\curlyeqsucc" . ?⋟) - ("\\curlypreceq" . ?≼) - ("\\curlyvee" . ?⋎) - ("\\curlywedge" . ?⋏) - ("\\curvearrowleft" . ?↶) - ("\\curvearrowright" . ?↷) - ("\\dag" . ?†) - ("\\dagger" . ?†) - ("\\daleth" . ?ℸ) - ("\\dashv" . ?⊣) - ("\\ddag" . ?‡) - ("\\ddagger" . ?‡) - ("\\ddots" . ?⋱) - ("\\diamond" . ?⋄) - ("\\diamondsuit" . ?♢) - ("\\divideontimes" . ?⋇) - ("\\doteq" . ?≐) - ("\\doteqdot" . ?≑) - ("\\dotplus" . ?∔) - ("\\dotsquare" . ?⊡) - ("\\downarrow" . ?↓) - ("\\downdownarrows" . ?⇊) - ("\\downleftharpoon" . ?⇃) - ("\\downrightharpoon" . ?⇂) - ("\\ell" . ?ℓ) - ("\\emptyset" . ?∅) - ("\\eqcirc" . ?≖) - ("\\eqcolon" . ?≕) - ("\\eqslantgtr" . ?⋝) - ("\\eqslantless" . ?⋜) - ("\\equiv" . ?≡) - ("\\exists" . ?∃) - ("\\fallingdotseq" . ?≒) - ("\\flat" . ?♭) - ("\\forall" . ?∀) - ("\\frown" . ?⌢) - ("\\ge" . ?≥) - ("\\geq" . ?≥) - ("\\geqq" . ?≧) - ("\\geqslant" . ?≥) - ("\\gets" . ?←) - ("\\gg" . ?≫) - ("\\ggg" . ?⋙) - ("\\gimel" . ?ℷ) - ("\\gnapprox" . ?⋧) - ("\\gneq" . ?≩) - ("\\gneqq" . ?≩) - ("\\gnsim" . ?⋧) - ("\\gtrapprox" . ?≳) - ("\\gtrdot" . ?⋗) - ("\\gtreqless" . ?⋛) - ("\\gtreqqless" . ?⋛) - ("\\gtrless" . ?≷) - ("\\gtrsim" . ?≳) - ("\\gvertneqq" . ?≩) - ("\\hbar" . ?ℏ) - ("\\heartsuit" . ?♥) - ("\\hookleftarrow" . ?↩) - ("\\hookrightarrow" . ?↪) - ("\\iff" . ?⇔) - ("\\iiiint" . ?⨌) - ("\\iiint" . ?∭) - ("\\iint" . ?∬) - ("\\imath" . ?ı) - ("\\in" . ?∈) - ("\\infty" . ?∞) - ("\\int" . ?∫) - ("\\intercal" . ?⊺) - ("\\jmath" . ?ȷ) - ("\\langle" . 10216) ; Literal ?⟨ breaks indentation. - ("\\lbrace" . ?{) - ("\\lbrack" . ?\[) - ("\\lceil" . ?⌈) - ("\\ldots" . ?…) - ("\\le" . ?≤) - ("\\leadsto" . ?↝) - ("\\leftarrow" . ?←) - ("\\leftarrowtail" . ?↢) - ("\\leftharpoondown" . ?↽) - ("\\leftharpoonup" . ?↼) - ("\\leftleftarrows" . ?⇇) - ;; ("\\leftparengtr" ?〈), see bug#12948. - ("\\leftrightarrow" . ?↔) - ("\\leftrightarrows" . ?⇆) - ("\\leftrightharpoons" . ?⇋) - ("\\leftrightsquigarrow" . ?↭) - ("\\leftthreetimes" . ?⋋) - ("\\leq" . ?≤) - ("\\leqq" . ?≦) - ("\\leqslant" . ?≤) - ("\\lessapprox" . ?≲) - ("\\lessdot" . ?⋖) - ("\\lesseqgtr" . ?⋚) - ("\\lesseqqgtr" . ?⋚) - ("\\lessgtr" . ?≶) - ("\\lesssim" . ?≲) - ("\\lfloor" . ?⌊) - ("\\lhd" . ?◁) - ("\\rhd" . ?▷) - ("\\ll" . ?≪) - ("\\llcorner" . ?⌞) - ("\\lll" . ?⋘) - ("\\lnapprox" . ?⋦) - ("\\lneq" . ?≨) - ("\\lneqq" . ?≨) - ("\\lnsim" . ?⋦) - ("\\longleftarrow" . ?←) - ("\\longleftrightarrow" . ?↔) - ("\\longmapsto" . ?↦) - ("\\longrightarrow" . ?→) - ("\\looparrowleft" . ?↫) - ("\\looparrowright" . ?↬) - ("\\lozenge" . ?✧) - ("\\lq" . ?‘) - ("\\lrcorner" . ?⌟) - ("\\ltimes" . ?⋉) - ("\\lvertneqq" . ?≨) - ("\\maltese" . ?✠) - ("\\mapsto" . ?↦) - ("\\measuredangle" . ?∡) - ("\\mho" . ?℧) - ("\\mid" . ?∣) - ("\\models" . ?⊧) - ("\\mp" . ?∓) - ("\\multimap" . ?⊸) - ("\\nLeftarrow" . ?⇍) - ("\\nLeftrightarrow" . ?⇎) - ("\\nRightarrow" . ?⇏) - ("\\nVDash" . ?⊯) - ("\\nVdash" . ?⊮) - ("\\nabla" . ?∇) - ("\\napprox" . ?≉) - ("\\natural" . ?♮) - ("\\ncong" . ?≇) - ("\\ne" . ?≠) - ("\\nearrow" . ?↗) - ("\\neg" . ?¬) - ("\\neq" . ?≠) - ("\\nequiv" . ?≢) - ("\\newline" . ?
) - ("\\nexists" . ?∄) - ("\\ngeq" . ?≱) - ("\\ngeqq" . ?≱) - ("\\ngeqslant" . ?≱) - ("\\ngtr" . ?≯) - ("\\ni" . ?∋) - ("\\nleftarrow" . ?↚) - ("\\nleftrightarrow" . ?↮) - ("\\nleq" . ?≰) - ("\\nleqq" . ?≰) - ("\\nleqslant" . ?≰) - ("\\nless" . ?≮) - ("\\nmid" . ?∤) - ;; ("\\not" ?̸) ;FIXME: conflict with "NOT SIGN" ¬. - ("\\notin" . ?∉) - ("\\nparallel" . ?∦) - ("\\nprec" . ?⊀) - ("\\npreceq" . ?⋠) - ("\\nrightarrow" . ?↛) - ("\\nshortmid" . ?∤) - ("\\nshortparallel" . ?∦) - ("\\nsim" . ?≁) - ("\\nsimeq" . ?≄) - ("\\nsubset" . ?⊄) - ("\\nsubseteq" . ?⊈) - ("\\nsubseteqq" . ?⊈) - ("\\nsucc" . ?⊁) - ("\\nsucceq" . ?⋡) - ("\\nsupset" . ?⊅) - ("\\nsupseteq" . ?⊉) - ("\\nsupseteqq" . ?⊉) - ("\\ntriangleleft" . ?⋪) - ("\\ntrianglelefteq" . ?⋬) - ("\\ntriangleright" . ?⋫) - ("\\ntrianglerighteq" . ?⋭) - ("\\nvDash" . ?⊭) - ("\\nvdash" . ?⊬) - ("\\nwarrow" . ?↖) - ("\\odot" . ?⊙) - ("\\oiiint" . ?∰) - ("\\oiint" . ?∯) - ("\\oint" . ?∮) - ("\\ominus" . ?⊖) - ("\\oplus" . ?⊕) - ("\\oslash" . ?⊘) - ("\\otimes" . ?⊗) - ("\\parallel" . ?∥) - ("\\partial" . ?∂) - ("\\perp" . ?⊥) - ("\\pitchfork" . ?⋔) - ("\\prec" . ?≺) - ("\\precapprox" . ?≾) - ("\\preceq" . ?≼) - ("\\precnapprox" . ?⋨) - ("\\precnsim" . ?⋨) - ("\\precsim" . ?≾) - ("\\prime" . ?′) - ("\\prod" . ?∏) - ("\\propto" . ?∝) - ("\\qed" . ?∎) - ("\\qquad" . ?⧢) - ("\\quad" . ?␣) - ("\\rangle" . 10217) ; Literal ?⟩ breaks indentation. - ("\\rbrace" . ?}) - ("\\rbrack" . ?\]) - ("\\rceil" . ?⌉) - ("\\rfloor" . ?⌋) - ("\\rightarrow" . ?→) - ("\\rightarrowtail" . ?↣) - ("\\rightharpoondown" . ?⇁) - ("\\rightharpoonup" . ?⇀) - ("\\rightleftarrows" . ?⇄) - ("\\rightleftharpoons" . ?⇌) - ;; ("\\rightparengtr" ?⦔) ;; Was ?〉, see bug#12948. - ("\\rightrightarrows" . ?⇉) - ("\\rightthreetimes" . ?⋌) - ("\\risingdotseq" . ?≓) - ("\\rtimes" . ?⋊) - ("\\times" . ?×) - ("\\sbs" . ?﹨) - ("\\searrow" . ?↘) - ("\\setminus" . ?∖) - ("\\sharp" . ?♯) - ("\\shortmid" . ?∣) - ("\\shortparallel" . ?∥) - ("\\sim" . ?∼) - ("\\simeq" . ?≃) - ("\\smallamalg" . ?∐) - ("\\smallsetminus" . ?∖) - ("\\smallsmile" . ?⌣) - ("\\smile" . ?⌣) - ("\\spadesuit" . ?♠) - ("\\sphericalangle" . ?∢) - ("\\sqcap" . ?⊓) - ("\\sqcup" . ?⊔) - ("\\sqsubset" . ?⊏) - ("\\sqsubseteq" . ?⊑) - ("\\sqsupset" . ?⊐) - ("\\sqsupseteq" . ?⊒) - ("\\square" . ?□) - ("\\squigarrowright" . ?⇝) - ("\\star" . ?⋆) - ("\\straightphi" . ?φ) - ("\\subset" . ?⊂) - ("\\subseteq" . ?⊆) - ("\\subseteqq" . ?⊆) - ("\\subsetneq" . ?⊊) - ("\\subsetneqq" . ?⊊) - ("\\succ" . ?≻) - ("\\succapprox" . ?≿) - ("\\succcurlyeq" . ?≽) - ("\\succeq" . ?≽) - ("\\succnapprox" . ?⋩) - ("\\succnsim" . ?⋩) - ("\\succsim" . ?≿) - ("\\sum" . ?∑) - ("\\supset" . ?⊃) - ("\\supseteq" . ?⊇) - ("\\supseteqq" . ?⊇) - ("\\supsetneq" . ?⊋) - ("\\supsetneqq" . ?⊋) - ("\\surd" . ?√) - ("\\swarrow" . ?↙) - ("\\therefore" . ?∴) - ("\\thickapprox" . ?≈) - ("\\thicksim" . ?∼) - ("\\to" . ?→) - ("\\top" . ?⊤) - ("\\triangle" . ?▵) - ("\\triangledown" . ?▿) - ("\\triangleleft" . ?◃) - ("\\trianglelefteq" . ?⊴) - ("\\triangleq" . ?≜) - ("\\triangleright" . ?▹) - ("\\trianglerighteq" . ?⊵) - ("\\twoheadleftarrow" . ?↞) - ("\\twoheadrightarrow" . ?↠) - ("\\ulcorner" . ?⌜) - ("\\uparrow" . ?↑) - ("\\updownarrow" . ?↕) - ("\\upleftharpoon" . ?↿) - ("\\uplus" . ?⊎) - ("\\uprightharpoon" . ?↾) - ("\\upuparrows" . ?⇈) - ("\\urcorner" . ?⌝) - ("\\u{i}" . ?ĭ) - ("\\vDash" . ?⊨) - ("\\varepsilon" . ?ε) - ("\\varphi" . ?φ) - ("\\varpi" . ?ϖ) - ("\\varprime" . ?′) - ("\\varpropto" . ?∝) - ("\\varrho" . ?ϱ) - ("\\varsigma" . ?ς) - ("\\vartheta" . ?ϑ) - ("\\vartriangleleft" . ?⊲) - ("\\vartriangleright" . ?⊳) - ("\\vdash" . ?⊢) - ("\\vdots" . ?⋮) - ("\\vee" . ?∨) - ("\\veebar" . ?⊻) - ("\\vert" . ?|) - ("\\wedge" . ?∧) - ("\\wp" . ?℘) - ("\\wr" . ?≀) - ("\\Bbb{A}" . ?𝔸) ; AMS commands for blackboard bold - ("\\Bbb{B}" . ?𝔹) ; Also sometimes \mathbb. - ("\\Bbb{C}" . ?ℂ) - ("\\Bbb{D}" . ?𝔻) - ("\\Bbb{E}" . ?𝔼) - ("\\Bbb{F}" . ?𝔽) - ("\\Bbb{G}" . ?𝔾) - ("\\Bbb{H}" . ?ℍ) - ("\\Bbb{I}" . ?𝕀) - ("\\Bbb{J}" . ?𝕁) - ("\\Bbb{K}" . ?𝕂) - ("\\Bbb{L}" . ?𝕃) - ("\\Bbb{M}" . ?𝕄) - ("\\Bbb{N}" . ?ℕ) - ("\\Bbb{O}" . ?𝕆) - ("\\Bbb{P}" . ?ℙ) - ("\\Bbb{Q}" . ?ℚ) - ("\\Bbb{R}" . ?ℝ) - ("\\Bbb{S}" . ?𝕊) - ("\\Bbb{T}" . ?𝕋) - ("\\Bbb{U}" . ?𝕌) - ("\\Bbb{V}" . ?𝕍) - ("\\Bbb{W}" . ?𝕎) - ("\\Bbb{X}" . ?𝕏) - ("\\Bbb{Y}" . ?𝕐) - ("\\Bbb{Z}" . ?ℤ) - ("\\mathbb{A}" . ?𝔸) ; AMS commands for blackboard bold - ("\\mathbb{B}" . ?𝔹) ; Also sometimes \mathbb. - ("\\mathbb{C}" . ?ℂ) - ("\\mathbb{D}" . ?𝔻) - ("\\mathbb{E}" . ?𝔼) - ("\\mathbb{F}" . ?𝔽) - ("\\mathbb{G}" . ?𝔾) - ("\\mathbb{H}" . ?ℍ) - ("\\mathbb{I}" . ?𝕀) - ("\\mathbb{J}" . ?𝕁) - ("\\mathbb{K}" . ?𝕂) - ("\\mathbb{L}" . ?𝕃) - ("\\mathbb{M}" . ?𝕄) - ("\\mathbb{N}" . ?ℕ) - ("\\mathbb{O}" . ?𝕆) - ("\\mathbb{P}" . ?ℙ) - ("\\mathbb{Q}" . ?ℚ) - ("\\mathbb{R}" . ?ℝ) - ("\\mathbb{S}" . ?𝕊) - ("\\mathbb{T}" . ?𝕋) - ("\\mathbb{U}" . ?𝕌) - ("\\mathbb{V}" . ?𝕍) - ("\\mathbb{W}" . ?𝕎) - ("\\mathbb{X}" . ?𝕏) - ("\\mathbb{Y}" . ?𝕐) - ("\\mathbb{Z}" . ?ℤ) - ("\\pm" . ?±) - ("\\pounds" . ?£) - ("\\|" . ?‖) - ("\\varkappa" . ?ϰ) - ;; caligraphic - ("\\mathcal{A}" . ?𝒜) - ("\\mathcal{B}" . ?ℬ) - ("\\mathcal{C}" . ?𝒞) - ("\\mathcal{D}" . ?𝒟) - ("\\mathcal{E}" . ?ℰ) - ("\\mathcal{F}" . ?ℱ) - ("\\mathcal{G}" . ?𝒢) - ("\\mathcal{H}" . ?ℋ) - ("\\mathcal{I}" . ?ℐ) - ("\\mathcal{J}" . ?𝒥) - ("\\mathcal{K}" . ?𝒦) - ("\\mathcal{L}" . ?ℒ) - ("\\mathcal{M}" . ?ℳ) - ("\\mathcal{N}" . ?𝒩) - ("\\mathcal{O}" . ?𝒪) - ("\\mathcal{P}" . ?𝒫) - ("\\mathcal{Q}" . ?𝒬) - ("\\mathcal{R}" . ?ℛ) - ("\\mathcal{S}" . ?𝒮) - ("\\mathcal{T}" . ?𝒯) - ("\\mathcal{U}" . ?𝒰) - ("\\mathcal{V}" . ?𝒱) - ("\\mathcal{W}" . ?𝒲) - ("\\mathcal{X}" . ?𝒳) - ("\\mathcal{Y}" . ?𝒴) - ("\\mathcal{Z}" . ?𝒵) - ;; fractur - ("\\mathfrak{A}" . ?𝔄) - ("\\mathfrak{B}" . ?𝔅) - ("\\mathfrak{C}" . ?ℭ) - ("\\mathfrak{D}" . ?𝔇) - ("\\mathfrak{E}" . ?𝔈) - ("\\mathfrak{F}" . ?𝔉) - ("\\mathfrak{G}" . ?𝔊) - ("\\mathfrak{H}" . ?ℌ) - ("\\mathfrak{I}" . ?ℑ) - ("\\mathfrak{J}" . ?𝔍) - ("\\mathfrak{K}" . ?𝔎) - ("\\mathfrak{L}" . ?𝔏) - ("\\mathfrak{M}" . ?𝔐) - ("\\mathfrak{N}" . ?𝔑) - ("\\mathfrak{O}" . ?𝔒) - ("\\mathfrak{P}" . ?𝔓) - ("\\mathfrak{Q}" . ?𝔔) - ("\\mathfrak{R}" . ?ℜ) - ("\\mathfrak{S}" . ?𝔖) - ("\\mathfrak{T}" . ?𝔗) - ("\\mathfrak{U}" . ?𝔘) - ("\\mathfrak{V}" . ?𝔙) - ("\\mathfrak{W}" . ?𝔚) - ("\\mathfrak{X}" . ?𝔛) - ("\\mathfrak{Y}" . ?𝔜) - ("\\mathfrak{Z}" . ?ℨ) - ("\\mathfrak{a}" . ?𝔞) - ("\\mathfrak{b}" . ?𝔟) - ("\\mathfrak{c}" . ?𝔠) - ("\\mathfrak{d}" . ?𝔡) - ("\\mathfrak{e}" . ?𝔢) - ("\\mathfrak{f}" . ?𝔣) - ("\\mathfrak{g}" . ?𝔤) - ("\\mathfrak{h}" . ?𝔥) - ("\\mathfrak{i}" . ?𝔦) - ("\\mathfrak{j}" . ?𝔧) - ("\\mathfrak{k}" . ?𝔨) - ("\\mathfrak{l}" . ?𝔩) - ("\\mathfrak{m}" . ?𝔪) - ("\\mathfrak{n}" . ?𝔫) - ("\\mathfrak{o}" . ?𝔬) - ("\\mathfrak{p}" . ?𝔭) - ("\\mathfrak{q}" . ?𝔮) - ("\\mathfrak{r}" . ?𝔯) - ("\\mathfrak{s}" . ?𝔰) - ("\\mathfrak{t}" . ?𝔱) - ("\\mathfrak{u}" . ?𝔲) - ("\\mathfrak{v}" . ?𝔳) - ("\\mathfrak{w}" . ?𝔴) - ("\\mathfrak{x}" . ?𝔵) - ("\\mathfrak{y}" . ?𝔶) - ("\\mathfrak{z}" . ?𝔷) - ("--" . ?–) - ("---" . ?—) - ("\\ordfeminine" . ?ª) - ("\\ordmasculine" . ?º) - ("\\lambdabar" . ?ƛ) - ("\\celsius" . ?℃) - ;; Text symbols formerly part of textcomp package: - ("\\textdollar" . ?$) - ("\\textborn" . ?*) - ("\\textless" . ?<) - ("\\textgreater" . ?>) - ("\\textbackslash" . ?\\) - ("\\textasciicircum" . ?^) - ("\\textunderscore" . ?_) - ("\\textbraceleft" . ?\{) - ("\\textbar" . ?|) - ("\\textbraceright" . ?\}) - ("\\textasciitilde" . ?~) - ("\\textexclamdown" . ?¡) - ("\\textcent" . ?¢) - ("\\textsterling" . ?£) - ("\\textcurrency" . ?¤) - ("\\textyen" . ?¥) - ("\\textbrokenbar" . ?¦) - ("\\textsection" . ?§) - ("\\textasciidieresis" . ?¨) - ("\\textcopyright" . ?©) - ("\\textordfeminine" . ?ª) - ("\\guillemetleft" . ?«) - ("\\guillemotleft" . ?«) - ("\\textlnot" . ?¬) - ("\\textregistered" . ?®) - ("\\textasciimacron" . ?¯) - ("\\textdegree" . ?°) - ("\\textpm" . ?±) - ("\\texttwosuperior" . ?²) - ("\\textthreesuperior" . ?³) - ("\\textasciiacute" . ?´) - ("\\textmu" . ?µ) - ("\\textparagraph" . ?¶) - ("\\textpilcrow" . ?¶) - ("\\textperiodcentered" . ?·) - ("\\textonesuperior" . ?¹) - ("\\textordmasculine" . ?º) - ("\\guillemetright" . ?») - ("\\guillemotright" . ?») - ("\\textonequarter" . ?¼) - ("\\textonehalf" . ?½) - ("\\textthreequarters" . ?¾) - ("\\textquestiondown" . ?¿) - ("\\texttimes" . ?×) - ("\\textdiv" . ?÷) - ("\\textflorin" . ?ƒ) - ("\\textasciicaron" . ?ˇ) - ("\\textasciibreve" . ?˘) - ("\\textacutedbl" . ?˝) - ("\\textgravedbl" . 757) - ("\\texttildelow" . 759) - ("\\textbaht" . ?฿) - ("\\textendash" . ?–) - ("\\textemdash" . ?—) - ("\\textbardbl" . ?‖) - ("\\textquoteleft" . 8216) - ("\\textquoteright" . 8217) - ("\\quotesinglbase" . 8218) - ("\\textquotedblleft" . 8220) - ("\\textquotedblright" . 8221) - ("\\quotedblbase" . 8222) - ;; \textdagger and \textdied are replaced with DAGGER (#x2020) and - ;; not with LATIN CROSS (#x271d) - ("\\textdagger" . ?†) - ("\\textdied" . ?†) - ("\\textdaggerdbl" . ?‡) - ("\\textbullet" . ?•) - ("\\textellipsis" . ?…) - ("\\textperthousand" . ?‰) - ("\\textpertenthousand" . ?‱) - ("\\guilsinglleft" . ?‹) - ("\\guilsinglright" . ?›) - ("\\textreferencemark" . ?※) - ("\\textinterrobang" . ?‽) - ("\\textfractionsolidus" . ?⁄) - ("\\textlquill" . 8261) ; Literal ?⁅ breaks indentation - ("\\textrquill" . 8262) ; Literal ?⁆ breaks indentation - ("\\textdiscount" . ?⁒) - ("\\textcolonmonetary" . ?₡) - ("\\textlira" . ?₤) - ("\\textnaira" . ?₦) - ("\\textwon" . ?₩) - ("\\textdong" . ?₫) - ("\\texteuro" . ?€) - ("\\textpeso" . ?₱) - ("\\textguarani" . ?₲) - ("\\textcelsius" . ?℃) - ("\\textnumero" . ?№) - ("\\textcircledP" . ?℗) - ("\\textrecipe" . ?℞) - ("\\textservicemark" . ?℠) - ("\\texttrademark" . ?™) - ("\\textohm" . ?Ω) - ("\\textmho" . ?℧) - ("\\textestimated" . ?℮) - ("\\textleftarrow" . ?←) - ("\\textuparrow" . ?↑) - ("\\textrightarrow" . ?→) - ("\\textdownarrow" . ?↓) - ("\\textminus" . ?−) - ("\\textsurd" . ?√) - ("\\textlangle" . 9001) ; Literal ?〈 breaks indentation - ("\\textrangle" . 9002) ; Literal ?〉 breaks indentation - ("\\textblank" . ?␢) - ("\\textvisiblespace" . ?␣) - ("\\textopenbullet" . ?◦) - ;; \textbigcircle is replaced with LARGE CIRCLE (#x25ef) and not - ;; with COMBINING ENCLOSING CIRCLE (#x20dd) - ("\\textbigcircle" . ?◯) - ("\\textmusicalnote" . ?♪) - ("\\textmarried" . ?⚭) - ("\\textdivorced" . ?⚮) - ("\\textlbrackdbl" . 10214) ; Literal ?⟦ breaks indentation - ("\\textrbrackdbl" . 10215) ; Literal ?⟧ breaks indentation - ("\\textinterrobangdown" . ?⸘) - - ;; TeX quotes - ("``" . ?“) - ("''" . ?”) - - ;; Unicode Fractions - ("\\frac{1}{2}" . "½") - ("\\frac{1}{3}" . "⅓") - ("\\frac{2}{3}" . "⅔") - ("\\frac{1}{4}" . "¼") - ("\\frac{3}{4}" . "¾") - ("\\frac{1}{5}" . "⅕") - ("\\frac{2}{5}" . "⅖") - ("\\frac{3}{5}" . "⅗") - ("\\frac{4}{5}" . "⅘") - ("\\frac{1}{6}" . "⅙") - ("\\frac{5}{6}" . "⅚") - ("\\frac{1}{7}" . "⅐") - ("\\frac{1}{8}" . "⅛") - ("\\frac{3}{8}" . "⅜") - ("\\frac{5}{8}" . "⅝") - ("\\frac{7}{8}" . "⅞") - ("\\frac{1}{9}" . "⅑") - ("\\frac{1}{10}" . "⅒") - ("\\tfrac{1}{2}" . "½") - ("\\tfrac{1}{3}" . "⅓") - ("\\tfrac{2}{3}" . "⅔") - ("\\tfrac{1}{4}" . "¼") - ("\\tfrac{3}{4}" . "¾") - ("\\tfrac{1}{5}" . "⅕") - ("\\tfrac{2}{5}" . "⅖") - ("\\tfrac{3}{5}" . "⅗") - ("\\tfrac{4}{5}" . "⅘") - ("\\tfrac{1}{6}" . "⅙") - ("\\tfrac{5}{6}" . "⅚") - ("\\tfrac{1}{7}" . "⅐") - ("\\tfrac{1}{8}" . "⅛") - ("\\tfrac{3}{8}" . "⅜") - ("\\tfrac{5}{8}" . "⅝") - ("\\tfrac{7}{8}" . "⅞") - ("\\tfrac{1}{9}" . "⅑") - ("\\tfrac{1}{10}" . "⅒") - - ;; Other symbols - ("\\S" . ?§) - ("\\Finv" . ?Ⅎ) - ("\\Game" . ?⅁) - ("\\ " . 9141) ; Literal ?⎵ breaks indentation - ("\\lvert" . ?|) - ("\\rvert" . ?|) - ("\\lVert" . ?‖) - ("\\rVert" . ?‖)) - "A `prettify-symbols-alist' usable for (La)TeX modes.") - -(defun tex--prettify-symbols-compose-p (_start end _match) - (or - ;; If the matched symbol doesn't end in a word character, then we - ;; simply allow composition. The symbol is probably something like - ;; \|, \(, etc. - (not (eq ?w (char-syntax (char-before end)))) - ;; Else we look at what follows the match in order to decide. - (let* ((after-char (char-after end)) - (after-syntax (char-syntax after-char))) - (not (or - ;; Don't compose \alpha@foo. - (eq after-char ?@) - ;; The \alpha in \alpha2 or \alpha-\beta may be composed but - ;; of course \alphax may not. - (and (eq after-syntax ?w) - (not (memq after-char - '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?+ ?- ?' ?\")))) - ;; Don't compose inside verbatim blocks. - (eq 2 (nth 7 (syntax-ppss)))))))) - - -;;; Flymake support - -(defvar-local tex-chktex--process nil) - -(defun tex-chktex-command () - "Return a list of command arguments for invoking ChkTeX." - `(,tex-chktex-program ,@tex-chktex-extra-flags - "--quiet" "--verbosity=0" "--inputfiles")) - -(defun tex-chktex (report-fn &rest _args) - "Flymake backend for linting TeX buffers with ChkTeX." - (unless (executable-find tex-chktex-program) - (error "Cannot find a suitable TeX checker")) - (when (process-live-p tex-chktex--process) - (kill-process tex-chktex--process)) - (let ((source (current-buffer)) - (re "^stdin:\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\):\\(.*\\)$")) - (save-restriction - (widen) - (setq tex-chktex--process - (make-process - :name "tex-chktex" - :buffer (generate-new-buffer "*tex-chktex*") - :command (tex-chktex-command) - :noquery t :connection-type 'pipe - :sentinel - (lambda (process _event) - (when (eq (process-status process) 'exit) - (unwind-protect - (when (eq process - (with-current-buffer source tex-chktex--process)) - (with-current-buffer (process-buffer process) - (goto-char (point-min)) - (cl-loop - while (search-forward-regexp re nil t) - for msg = (match-string 4) - for line = (string-to-number (match-string 1)) - for col = (string-to-number (match-string 2)) - for (beg . end) = (flymake-diag-region source line col) - collect (flymake-make-diagnostic source beg end :warning msg) - into diags - finally (funcall report-fn diags)))) - (kill-buffer (process-buffer process))))))) - (process-send-region tex-chktex--process (point-min) (point-max)) - (process-send-eof tex-chktex--process)))) - - -;;; Xref backend - -;; Here we lightly adapt the default etags backend for xref so that -;; the main xref user commands (including `xref-find-definitions', -;; `xref-find-apropos', and `xref-find-references' [on M-., C-M-., and -;; M-?, respectively]) work in TeX buffers. The only methods we -;; actually modify are `xref-backend-identifier-at-point' and -;; `xref-backend-references'. Many of the complications here, and in -;; `etags' itself, are due to the necessity of parsing both the old -;; TeX syntax and the new expl3 syntax, which will continue to appear -;; together in documents for the foreseeable future. Synchronizing -;; Emacs and `etags' this way aims to improve the user experience "out -;; of the box." - -(with-eval-after-load 'grep - (defvar grep-filepattern-alist) - (push '(latex-mode "*.[tT]e[xX]" "*.ltx" "*.sty" "*.cl[so]" - "*.bbl" "*.drv" "*.hva") - grep-filepattern-alist) - (push '(plain-tex-mode "*.[tT]e[xX]" "*.ins") - grep-filepattern-alist) - (push '(doctex-mode "*.dtx") grep-filepattern-alist)) - -(defun tex--xref-backend () 'tex-etags) - -(cl-defmethod xref-backend-identifier-at-point ((_backend (eql 'tex-etags))) - (require 'etags) - (tex--thing-at-point)) - -;; The detection of `_' and `:' is a primitive method for determining -;; whether point is on an expl3 construct. It may fail in some -;; instances. -(defun tex--thing-at-point () - "Demarcate `thing-at-point' for the TeX `xref' backend." - (let ((bounds (tex--bounds-of-symbol-at-point))) - (when bounds - (let ((texsym (buffer-substring-no-properties (car bounds) (cdr bounds)))) - (if (and (not (string-match-p "reference" (symbol-name this-command))) - (seq-contains-p texsym ?_) - (seq-contains-p texsym ?:)) - (seq-take texsym (seq-position texsym ?:)) - texsym))))) - -(defun tex-thingatpt--beginning-of-symbol () - (and - (re-search-backward "[][\\{}\"*`'#=&()%,|$[:cntrl:][:blank:]]" nil t) - (forward-char))) - -(defun tex-thingatpt--end-of-symbol () - (and - (re-search-forward "[][\\{}\"*`'#=&()%,|$[:cntrl:][:blank:]]" nil t) - (backward-char))) - -(defun tex--bounds-of-symbol-at-point () - "Simplify `bounds-of-thing-at-point' for TeX `xref' backend." - (let ((orig (point))) - (ignore-errors - (save-excursion - (tex-thingatpt--end-of-symbol) - (tex-thingatpt--beginning-of-symbol) - (let ((beg (point))) - (if (<= beg orig) - (let ((real-end - (progn - (tex-thingatpt--end-of-symbol) - (point)))) - (cond ((and (<= orig real-end) (< beg real-end)) - (cons beg real-end)) - ((and (= orig real-end) (= beg real-end)) - (cons beg (1+ beg)))))))))));; For 1-char TeX commands. - -(cl-defmethod xref-backend-identifier-completion-table ((_backend - (eql 'tex-etags))) - (xref-backend-identifier-completion-table 'etags)) - -(cl-defmethod xref-backend-identifier-completion-ignore-case ((_backend - (eql - 'tex-etags))) - (xref-backend-identifier-completion-ignore-case 'etags)) - -(cl-defmethod xref-backend-definitions ((_backend (eql 'tex-etags)) symbol) - (xref-backend-definitions 'etags symbol)) - -(cl-defmethod xref-backend-apropos ((_backend (eql 'tex-etags)) pattern) - (xref-backend-apropos 'etags pattern)) - -;; The `xref-backend-references' method requires more code than the -;; others for at least two main reasons: TeX authors have typically been -;; free in their invention of new file types with new suffixes, and they -;; have also tended sometimes to include non-symbol characters in -;; command names. When combined with the default Semantic Symbol -;; Reference API, these two characteristics of TeX code mean that a -;; command like `xref-find-references' would often fail to find any hits -;; for a symbol at point, including the one under point in the current -;; buffer, or it would find only some instances and skip others. - -(defun tex-find-references-syntax-table () - (let ((st (if (boundp 'TeX-mode-syntax-table) - (make-syntax-table TeX-mode-syntax-table) - (make-syntax-table tex-mode-syntax-table)))) - st)) - -(defvar tex--xref-syntax-fun nil) - -(defun tex-xref-syntax-function (str beg end) - "Provide a bespoke `syntax-propertize-function' for \\[xref-find-references]." - (let* (grpb tempstr - (shrtstr (if end - (progn - (setq tempstr (seq-take str (1- (length str)))) - (if beg - (setq tempstr (seq-drop tempstr 1)) - tempstr)) - (seq-drop str 1))) - (grpa (if (and beg end) - (prog1 - (list 1 "_") - (setq grpb (list 2 "_"))) - (list 1 "_"))) - (re (concat beg (regexp-quote shrtstr) end)) - (temp-rule (if grpb - (list re grpa grpb) - (list re grpa)))) - ;; Simple benchmarks suggested that the speed-up from compiling this - ;; function was nearly nil, so `eval' and its non-byte-compiled - ;; function remain. - (setq tex--xref-syntax-fun (eval - `(syntax-propertize-rules ,temp-rule))))) - -(defun tex--collect-file-extensions () - "Gather TeX file extensions from `auto-mode-alist'." - (let* ((mlist (when (rassq major-mode auto-mode-alist) - (seq-filter - (lambda (elt) - (eq (cdr elt) major-mode)) - auto-mode-alist))) - (lcsym (intern-soft (downcase (symbol-name major-mode)))) - (lclist (and lcsym - (not (eq lcsym major-mode)) - (rassq lcsym auto-mode-alist) - (seq-filter - (lambda (elt) - (eq (cdr elt) lcsym)) - auto-mode-alist))) - (shortsym (when (stringp mode-name) - (intern-soft (concat (string-trim-right mode-name "/.*") - "-mode")))) - (lcshortsym (when (stringp mode-name) - (intern-soft (downcase - (concat - (string-trim-right mode-name "/.*") - "-mode"))))) - (shlist (and shortsym - (not (eq shortsym major-mode)) - (not (eq shortsym lcsym)) - (rassq shortsym auto-mode-alist) - (seq-filter - (lambda (elt) - (eq (cdr elt) shortsym)) - auto-mode-alist))) - (lcshlist (and lcshortsym - (not (eq lcshortsym major-mode)) - (not (eq lcshortsym lcsym)) - (rassq lcshortsym auto-mode-alist) - (seq-filter - (lambda (elt) - (eq (cdr elt) lcshortsym)) - auto-mode-alist))) - (exts (when (or mlist lclist shlist lcshlist) - (seq-union (seq-map #'car lclist) - (seq-union (seq-map #'car mlist) - (seq-union (seq-map #'car lcshlist) - (seq-map #'car shlist)))))) - (ed-exts (when exts - (seq-map - (lambda (elt) - (concat "*" (string-trim elt "\\\\" "\\\\'"))) - exts)))) - ed-exts)) - -(defvar tex--buffers-list nil) -(defvar-local tex--old-syntax-function nil) - -(cl-defmethod xref-backend-references ((_backend (eql 'tex-etags)) identifier) - "Find references of IDENTIFIER in TeX buffers and files." - (require 'grep) - (defvar grep-filepattern-alist) - (let (bufs texbufs - (mode major-mode)) - (dolist (buf (buffer-list)) - (if (eq (buffer-local-value 'major-mode buf) mode) - (push buf bufs) - (when (string-match-p ".*\\.[tT]e[xX]" (buffer-name buf)) - (push buf texbufs)))) - (unless (seq-set-equal-p tex--buffers-list bufs) - (let* ((amalist (tex--collect-file-extensions)) - (extlist (alist-get mode grep-filepattern-alist)) - (extlist-new (seq-uniq - (seq-union amalist extlist #'string-match-p)))) - (setq tex--buffers-list bufs) - (dolist (buf bufs) - (when-let* ((fbuf (buffer-file-name buf)) - (ext (file-name-extension fbuf)) - (finext (concat "*." ext)) - ((not (seq-find (lambda (elt) (string-match-p elt finext)) - extlist-new)))) - (push finext extlist-new))) - (unless (seq-set-equal-p extlist-new extlist) - (alist-set mode grep-filepattern-alist extlist-new)))) - (let* (setsyntax - (punct (with-syntax-table (tex-find-references-syntax-table) - (seq-positions identifier (list ?w ?_) - (lambda (elt sycode) - (not (memq (char-syntax elt) sycode)))))) - (end (and punct - (memq (1- (length identifier)) punct) - (> (length identifier) 1) - (concat "\\(" - (regexp-quote - (string (elt identifier - (1- (length identifier))))) - "\\)"))) - (beg (and punct - (memq 0 punct) - (concat "\\(" - (regexp-quote (string (elt identifier 0))) - "\\)"))) - (text-mode-hook - (if (or end beg) - (progn - (tex-xref-syntax-function identifier beg end) - (setq setsyntax (lambda () - (setq-local syntax-propertize-function - tex--xref-syntax-fun) - (setq-local TeX-style-hook-applied-p t))) - (cons setsyntax text-mode-hook)) - text-mode-hook))) - (unless (memq 'doctex-mode (derived-mode-all-parents mode)) - (setq bufs (append texbufs bufs))) - (when (or end beg) - (dolist (buf bufs) - (with-current-buffer buf - (unless (local-variable-p 'tex--old-syntax-function) - (setq tex--old-syntax-function syntax-propertize-function)) - (setq-local syntax-propertize-function - tex--xref-syntax-fun) - (syntax-ppss-flush-cache (point-min))))) - (unwind-protect - (xref-backend-references nil identifier) - (when (or end beg) - (dolist (buf bufs) - (with-current-buffer buf - (when buffer-file-truename - (setq-local syntax-propertize-function - tex--old-syntax-function) - (syntax-ppss-flush-cache (point-min)))))))))) - -(make-obsolete-variable 'tex-mode-load-hook - "use `with-eval-after-load' instead." "28.1") -(run-hooks 'tex-mode-load-hook) - -(provide 'tex-mode) - -;;; tex-mode.el ends here diff --git a/lisp/textmodes/texinfmt.el b/lisp/textmodes/texinfmt.el deleted file mode 100644 index 1f32755b64f..00000000000 --- a/lisp/textmodes/texinfmt.el +++ /dev/null @@ -1,4317 +0,0 @@ -;;; texinfmt.el --- format Texinfo files into Info files -*- lexical-binding: t; -*- - -;; Copyright (C) 1985-1986, 1988, 1990-1998, 2000-2025 Free Software -;; Foundation, Inc. - -;; Maintainer: emacs-devel@gnu.org -;; Keywords: maint, tex, docs - -;; 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 . - -;;; Commentary: - -;;; Emacs Lisp functions to convert Texinfo files to Info files. - -;;; Code: - -(defvar texinfmt-version "2.42 of 7 Jul 2006") -(make-obsolete-variable 'texinfmt-version 'emacs-version "28.1") - -(defun texinfmt-version (&optional here) - "Show the version of texinfmt.el in the minibuffer. -If optional argument HERE is non-nil, insert info at point." - (declare (obsolete emacs-version "28.1")) - (interactive "P") - (let ((version-string - (format-message "Version of `texinfmt.el': %s" texinfmt-version))) - (if here - (insert version-string) - (if (called-interactively-p 'interactive) - (message "%s" version-string) - version-string)))) - - -;;; Variable definitions - -(require 'texinfo) ; So `texinfo-footnote-style' is defined. -(require 'texnfo-upd) ; So `texinfo-section-types-regexp' is defined. - -(defvar texinfo-vindex) -(defvar texinfo-findex) -(defvar texinfo-cindex) -(defvar texinfo-pindex) -(defvar texinfo-tindex) -(defvar texinfo-kindex) -(defvar texinfo-last-node) -(defvar texinfo-node-names) -(defvar texinfo-enclosure-list) -(defvar texinfo-alias-list) -(defvar texinfo-fold-nodename-case nil) - -(defvar texinfo-command-start) -(defvar texinfo-command-end) -(defvar texinfo-command-name) -(defvar texinfo-defun-type) -(defvar texinfo-last-node-pos) -(defvar texinfo-stack) -(defvar texinfo-short-index-cmds-alist) -(defvar texinfo-short-index-format-cmds-alist) -(defvar texinfo-format-filename) -(defvar texinfo-footnote-number) - -(defvar texinfo-raisesections-alist - '((@chapter . @chapter) ; Cannot go higher - (@unnumbered . @unnumbered) - (@centerchap . @unnumbered) - - (@majorheading . @majorheading) - (@chapheading . @chapheading) - (@appendix . @appendix) - - (@section . @chapter) - (@unnumberedsec . @unnumbered) - (@heading . @chapheading) - (@appendixsec . @appendix) - - (@subsection . @section) - (@unnumberedsubsec . @unnumberedsec) - (@subheading . @heading) - (@appendixsubsec . @appendixsec) - - (@subsubsection . @subsection) - (@unnumberedsubsubsec . @unnumberedsubsec) - (@subsubheading . @subheading) - (@appendixsubsubsec . @appendixsubsec)) - "An alist of next higher levels for chapters, sections, etc... -For example, section to chapter, subsection to section. -Used by `texinfo-raise-lower-sections'. -The keys specify types of section; the values correspond to the next -higher types.") - -(defvar texinfo-lowersections-alist - '((@chapter . @section) - (@unnumbered . @unnumberedsec) - (@centerchap . @unnumberedsec) - (@majorheading . @heading) - (@chapheading . @heading) - (@appendix . @appendixsec) - - (@section . @subsection) - (@unnumberedsec . @unnumberedsubsec) - (@heading . @subheading) - (@appendixsec . @appendixsubsec) - - (@subsection . @subsubsection) - (@unnumberedsubsec . @unnumberedsubsubsec) - (@subheading . @subsubheading) - (@appendixsubsec . @appendixsubsubsec) - - (@subsubsection . @subsubsection) ; Cannot go lower. - (@unnumberedsubsubsec . @unnumberedsubsubsec) - (@subsubheading . @subsubheading) - (@appendixsubsubsec . @appendixsubsubsec)) - "An alist of next lower levels for chapters, sections, etc... -For example, chapter to section, section to subsection. -Used by `texinfo-raise-lower-sections'. -The keys specify types of section; the values correspond to the next -lower types.") - -;;; Syntax table - -(defvar texinfo-format-syntax-table - (let ((st (make-syntax-table))) - (modify-syntax-entry ?\" " " st) - (modify-syntax-entry ?\\ " " st) - (modify-syntax-entry ?@ "\\" st) - (modify-syntax-entry ?\^q "\\" st) - (modify-syntax-entry ?\[ "." st) - (modify-syntax-entry ?\] "." st) - (modify-syntax-entry ?\( "." st) - (modify-syntax-entry ?\) "." st) - (modify-syntax-entry ?{ "(}" st) - (modify-syntax-entry ?} "){" st) - (modify-syntax-entry ?\' "." st) - st)) - - -;;; Top level buffer and region formatting functions - -;;;###autoload -(defun texinfo-format-buffer (&optional nosplit) - "Process the current buffer as texinfo code, into an Info file. -The Info file output is generated in a buffer visiting the Info file -name specified in the @setfilename command. - -Non-nil argument (prefix, if interactive) means don't make tag table -and don't split the file if large. You can use `Info-tagify' and -`Info-split' to do these manually." - (interactive "P") - (let ((lastmessage "Formatting Info file...") - (coding-system-for-write buffer-file-coding-system)) - (message lastmessage) - (widen) - (texinfo-format-buffer-1) - (Info-tagify) - (if nosplit - nil - (if (> (buffer-size) (+ 50000 Info-split-threshold)) - (progn - (message (setq lastmessage "Splitting Info file...")) - (Info-split)))) - (message (concat lastmessage - (if (called-interactively-p 'interactive) - "done. Now save it." "done."))))) - -(defvar texinfo-region-buffer-name "*Info Region*" - "Name of the temporary buffer used by \\[texinfo-format-region].") - -(defvar texinfo-pre-format-hook nil - "Hook called before the conversion of the Texinfo file to Info format. -The functions on this hook are called with argument BUFFER, the buffer -containing the Texinfo file.") - -;; These come from tex-mode.el. -(defvar tex-start-of-header) -(defvar tex-end-of-header) -(defvar texinfo-example-start) - -;;;###autoload -(defun texinfo-format-region (region-beginning region-end) - "Convert the current region of the Texinfo file to Info format. -This lets you see what that part of the file will look like in Info. -The command is bound to \\[texinfo-format-region]. The text that is -converted to Info is stored in a temporary buffer." - (interactive "r") - (message "Converting region to Info format...") - (let (texinfo-command-start - texinfo-command-end - texinfo-command-name - texinfo-vindex - texinfo-findex - texinfo-cindex - texinfo-pindex - texinfo-tindex - texinfo-kindex - texinfo-stack - (texinfo-format-filename "") - texinfo-example-start - texinfo-last-node-pos - texinfo-last-node - texinfo-node-names - (texinfo-footnote-number 0) - ;; last-input-buffer - (fill-column-for-info fill-column) - (input-buffer (current-buffer)) - (input-directory default-directory) - (header-text "") - (header-beginning 1) - (header-end 1)) - -;;; Copy lines between beginning and end of header lines, -;;; if any, or else copy the `@setfilename' line, if any. - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (let ((search-end (line-beginning-position 101))) - (if (or - ;; Either copy header text. - (and - (prog1 - (search-forward tex-start-of-header search-end t) - (forward-line 1) - ;; Mark beginning of header. - (setq header-beginning (point))) - (prog1 - (search-forward tex-end-of-header nil t) - (beginning-of-line) - ;; Mark end of header - (setq header-end (point)))) - ;; Or copy @filename line. - (prog2 - (goto-char (point-min)) - (search-forward "@setfilename" search-end t) - (beginning-of-line) - (setq header-beginning (point)) - (forward-line 1) - (setq header-end (point)))) - - ;; Copy header - (setq header-text - (buffer-substring-no-properties - (min header-beginning region-beginning) - header-end)))))) - -;;; Find a buffer to use. - (switch-to-buffer (get-buffer-create texinfo-region-buffer-name)) - (setq buffer-read-only t) - (let ((inhibit-read-only t)) - (erase-buffer) - ;; Insert the header into the buffer. - (insert header-text) - ;; Insert the region into the buffer. - (insert-buffer-substring - input-buffer - (max region-beginning header-end) - region-end) - (run-hook-with-args 'texinfo-pre-format-hook input-buffer) - ;; Make sure region ends in a newline. - (or (= (preceding-char) ?\n) - (insert "\n")) - - (goto-char (point-min)) - (texinfo-mode) - (message "Converting region to Info format...") - (setq fill-column fill-column-for-info) - ;; Install a syntax table useful for scanning command operands. - (set-syntax-table texinfo-format-syntax-table) - - ;; Insert @include files so `texinfo-raise-lower-sections' can - ;; work on them without losing track of multiple - ;; @raise/@lowersections commands. - (while (re-search-forward "^@include" nil t) - (setq texinfo-command-end (point)) - (let ((filename (concat input-directory - (texinfo-parse-line-arg)))) - (re-search-backward "^@include") - (delete-region (point) (line-beginning-position 2)) - (message "Reading included file: %s" filename) - (save-excursion - (save-restriction - (narrow-to-region - (point) - (+ (point) (car (cdr (insert-file-contents filename))))) - (goto-char (point-min)) - ;; Remove `@setfilename' line from included file, if any, - ;; so @setfilename command not duplicated. - (if (re-search-forward "^@setfilename" (line-end-position 100) t) - (delete-region (line-beginning-position 1) - (line-beginning-position 2))))))) - - ;; Raise or lower level of each section, if necessary. - (goto-char (point-min)) - (texinfo-raise-lower-sections) - ;; Append @refill to appropriate paragraphs for filling. - (goto-char (point-min)) - (texinfo-append-refill) - ;; If the region includes the effective end of the data, - ;; discard everything after that. - (goto-char (point-max)) - (if (re-search-backward "^@bye" nil t) - (delete-region (point) (point-max))) - ;; Make sure buffer ends in a newline. - (or (= (preceding-char) ?\n) - (insert "\n")) - ;; Don't use a previous value of texinfo-enclosure-list. - (setq texinfo-enclosure-list nil) - (setq texinfo-alias-list nil) - - (goto-char (point-min)) - (if (looking-at "\\\\input[ \t]+texinfo") - (delete-region (point) (line-beginning-position 2))) - - ;; Insert Info region title text. - (goto-char (point-min)) - (if (search-forward "@setfilename" (line-beginning-position 101) t) - (progn - (setq texinfo-command-end (point)) - (beginning-of-line) - (setq texinfo-command-start (point)) - (let ((arg (texinfo-parse-arg-discard))) - (insert " " - texinfo-region-buffer-name - (format-message " buffer for: `")) - (insert (file-name-nondirectory (expand-file-name arg))) - (insert (format-message "', -*-Text-*-\n")))) - ;; Else no `@setfilename' line - (insert " " - texinfo-region-buffer-name - " buffer -*-Text-*-\n")) - (insert (format-message "produced by `texinfo-format-region'\n") - "from a region in: " - (if (buffer-file-name input-buffer) - (format-message "`%s'" - (file-name-sans-versions - (file-name-nondirectory - (buffer-file-name input-buffer)))) - (format-message "buffer `%s'" (buffer-name input-buffer))) - (format-message "\nusing `texinfmt.el' on Emacs version ") - emacs-version - ".\n\n") - - ;; Now convert for real. - (goto-char (point-min)) - (texinfo-format-scan) - (goto-char (point-min)) - (Info-tagify input-buffer) - (goto-char (point-min)) - (message "Done.")))) - -;;;###autoload -(defun texi2info (&optional nosplit) - "Convert the current buffer (written in Texinfo code) into an Info file. -The Info file output is generated in a buffer visiting the Info file -names specified in the @setfilename command. - -This function automatically updates all node pointers and menus, and -creates a master menu. This work is done on a temporary buffer that -is automatically removed when the Info file is created. The original -Texinfo source buffer is not changed. - -Non-nil argument (prefix, if interactive) means don't split the file -if large. You can use `Info-split' to do this manually." - (interactive "P") - (let ((temp-buffer (concat "*--" (buffer-name) "--temporary-buffer*" ))) - (message "First updating nodes and menus, then creating Info file.") - ;; (sit-for 2) - (copy-to-buffer temp-buffer (point-min) (point-max)) - (switch-to-buffer temp-buffer) - (texinfo-master-menu t) - (message "Now creating Info file.") - (sit-for 2) - (texinfo-format-buffer nosplit) - (save-buffer) - (kill-buffer temp-buffer))) - - -;;; Primary internal formatting function for the whole buffer. - -(defun texinfo-format-buffer-1 () - (let (texinfo-format-filename - texinfo-example-start - texinfo-command-start - texinfo-command-end - texinfo-command-name - texinfo-last-node - texinfo-last-node-pos - texinfo-vindex - texinfo-findex - texinfo-cindex - texinfo-pindex - texinfo-tindex - texinfo-kindex - texinfo-stack - texinfo-node-names - (texinfo-footnote-number 0) - ;; last-input-buffer - outfile - (fill-column-for-info fill-column) - (input-buffer (current-buffer)) - (input-directory default-directory)) - (setq texinfo-enclosure-list nil) - (setq texinfo-alias-list nil) - (save-excursion - (goto-char (point-min)) - (or (search-forward "@setfilename" nil t) - (error "Texinfo file needs an `@setfilename FILENAME' line")) - (setq texinfo-command-end (point)) - (setq outfile (texinfo-parse-line-arg))) - - (find-file outfile) - (texinfo-mode) - (erase-buffer) - (buffer-disable-undo) - - (message "Formatting Info file: %s" outfile) - (setq texinfo-format-filename - (file-name-nondirectory (expand-file-name outfile))) - - (setq fill-column fill-column-for-info) - (set-syntax-table texinfo-format-syntax-table) - - (insert-buffer-substring input-buffer) - (run-hook-with-args 'texinfo-pre-format-hook input-buffer) - (message "Converting %s to Info format..." (buffer-name input-buffer)) - - ;; Insert @include files so `texinfo-raise-lower-sections' can - ;; work on them without losing track of multiple - ;; @raise/@lowersections commands. - (goto-char (point-min)) - (while (re-search-forward "^@include" nil t) - (setq texinfo-command-end (point)) - (let ((filename (concat input-directory - (texinfo-parse-line-arg)))) - (re-search-backward "^@include") - (delete-region (point) (line-beginning-position 2)) - (message "Reading included file: %s" filename) - (save-excursion - (save-restriction - (narrow-to-region - (point) - (+ (point) (car (cdr (insert-file-contents filename))))) - (goto-char (point-min)) - ;; Remove `@setfilename' line from included file, if any, - ;; so @setfilename command not duplicated. - (if (re-search-forward "^@setfilename" (line-end-position 100) t) - (delete-region (line-beginning-position 1) - (line-beginning-position 2))))))) - ;; Raise or lower level of each section, if necessary. - (goto-char (point-min)) - (texinfo-raise-lower-sections) - ;; Append @refill to appropriate paragraphs - (goto-char (point-min)) - (texinfo-append-refill) - (goto-char (point-min)) - (search-forward "@setfilename") - (beginning-of-line) - (delete-region (point-min) (point)) - ;; Remove @bye at end of file, if it is there. - (goto-char (point-max)) - (if (search-backward "@bye" nil t) - (delete-region (point) (point-max))) - ;; Make sure buffer ends in a newline. - (or (= (preceding-char) ?\n) - (insert "\n")) - ;; Scan the whole buffer, converting to Info format. - (texinfo-format-scan) - (goto-char (point-min)) - ;; Insert info about how this file was made. - (insert "Info file: " - texinfo-format-filename ", -*-Text-*-\n" - (format-message "produced by `texinfo-format-buffer'\n") - ;; Date string removed so that regression testing is easier. - ;; "on " - ;; (insert (format-time-string "%e %b %Y")) " " - "from file" - (if (buffer-file-name input-buffer) - (format-message " `%s'" - (file-name-sans-versions - (file-name-nondirectory - (buffer-file-name input-buffer)))) - (format-message "buffer `%s'" (buffer-name input-buffer))) - (format-message "\nusing `texinfmt.el' on Emacs version ") - emacs-version - ".\n\n") - ;; Return data for indices. - (list outfile - texinfo-vindex texinfo-findex texinfo-cindex - texinfo-pindex texinfo-tindex texinfo-kindex))) - - -;;; Perform non-@-command file conversions: quotes and hyphens - -(defun texinfo-format-convert (min max) - ;; Convert left and right quotes to typewriter font quotes. - (goto-char min) - (while (search-forward "``" max t) - (replace-match "\"")) - (goto-char min) - (while (search-forward "''" max t) - (replace-match "\"")) - ;; Convert three hyphens in a row to two. - (goto-char min) - (while (re-search-forward "\\( \\|\\w\\)\\(---\\)\\( \\|\\w\\)" max t) - (delete-region (1+ (match-beginning 2)) (+ 2 (match-beginning 2))))) - - -;;; Handle paragraph filling - -;; Keep as concatenated lists for ease of maintenance - -(defvar texinfo-no-refill-regexp - (concat - "^@" - "\\(" - ;; add "itemize\\|" (from experiment of 2001 Nov 28) - ;; because of a problem with @end itemize@refill - ;; I don't know if this causes other problems. - ;; I suspect itemized lists don't get filled properly and a - ;; more precise fix is required. Bob - ;; commented out on 2005 Feb 28 by Bob - ;; "itemize\\|" - "direntry\\|" - "lisp\\|" - "smalllisp\\|" - "example\\|" - "smallexample\\|" - "display\\|" - "smalldisplay\\|" - "format\\|" - "smallformat\\|" - "flushleft\\|" - "flushright\\|" - "menu\\|" - "multitable\\|" - "titlepage\\|" - "iftex\\|" - "ifhtml\\|" - "tex\\|" - "html" - "\\)") - "Regexp specifying environments in which paragraphs are not filled.") - -(defvar texinfo-accent-commands - (concat - "@[\"',=^`~]\\|" - "@OE{\\|" - "@oe{\\|" - "@AA{\\|" - "@aa{\\|" - "@AE{\\|" - "@ae{\\|" - "@ss{\\|" - "@questiondown{\\|" - "@exclamdown{\\|" - "@L{\\|" - "@l{\\|" - "@O{\\|" - "@o{\\|" - "@dotaccent{\\|" - "@ubaraccent{\\|" - "@d{\\|" - "@H{\\|" - "@ringaccent{\\|" - "@tieaccent{\\|" - "@u{\\|" - "@v{\\|" - "@dotless{" - )) - -(defvar texinfo-part-of-para-regexp - (concat - "^@" - "\\(" - "b{\\|" - "bullet{\\|" - "cite{\\|" - "code{\\|" - "email{\\|" - "emph{\\|" - "equiv{\\|" - "error{\\|" - "expansion{\\|" - "file{\\|" - "i{\\|" - "inforef{\\|" - "kbd{\\|" - "key{\\|" - "lisp{\\|" - "minus{\\|" - "point{\\|" - "print{\\|" - "pxref{\\|" - "r{\\|" - "ref{\\|" - "result{\\|" - "samp{\\|" - "sc{\\|" - "t{\\|" - "TeX{\\|" - "today{\\|" - "url{\\|" - "var{\\|" - "w{\\|" - "xref{\\|" - "@-\\|" ; @- is a discretionary hyphen (not an accent) (a noop). - texinfo-accent-commands - "\\)" - ) - "Regexp specifying @-commands found within paragraphs.") - -(defun texinfo-append-refill () - "Append @refill at end of each paragraph that should be filled. -Do not append @refill to paragraphs within @example and similar environments. -Do not append @refill to paragraphs containing @w{TEXT} or @*." - - ;; It is necessary to append @refill before other processing because - ;; the other processing removes information that tells Texinfo - ;; whether the text should or should not be filled. - - (while (< (point) (point-max)) - (let ((refill-blank-lines "^[ \t\n]*$") - (case-fold-search nil)) ; Don't confuse @TeX and @tex.... - (beginning-of-line) - ;; 1. Skip over blank lines; - ;; skip over lines beginning with @-commands, - ;; but do not skip over lines - ;; that are no-refill environments such as @example or - ;; that begin with within-paragraph @-commands such as @code. - (while (and (looking-at (concat "^@\\|^\\\\\\|" refill-blank-lines)) - (not (looking-at - (concat - "\\(" - texinfo-no-refill-regexp - "\\|" - texinfo-part-of-para-regexp - "\\)"))) - (< (point) (point-max))) - (forward-line 1)) - ;; 2. Skip over @example and similar no-refill environments. - (if (looking-at texinfo-no-refill-regexp) - (let ((environment (match-string-no-properties 1))) - (progn (re-search-forward (concat "^@end " environment) nil t) - (forward-line 1))) - ;; Else - ;; 3. Do not refill a paragraph containing @w or @*, or ending - ;; with @ followed by a newline. - (if (or (>= (point) (point-max)) - (re-search-forward - "@w{\\|@\\*\\|@\n\n" - (save-excursion (forward-paragraph) - (line-beginning-position 2)) - t)) - ;; Go to end of paragraph and do nothing. - (forward-paragraph) - ;; 4. Else go to end of paragraph and insert @refill - (forward-paragraph) - (forward-line -1) - (let ((line-beg (point))) - (end-of-line) - (delete-region - (point) - (save-excursion (skip-chars-backward " \t") (point))) - (forward-char 1) - (unless (re-search-backward "@c[ \t\n]\\|@comment[ \t\n]" line-beg t) - (forward-char -1)) - (unless (re-search-backward "@refill\\|^[ \t]*@" line-beg t) - (insert "@refill"))) - (forward-line 1)))))) - - -;;; Handle `@raisesections' and `@lowersections' commands - -;; These commands change the hierarchical level of chapter structuring -;; commands. -;; -;; @raisesections changes @subsection to @section, -;; @section to @chapter, -;; etc. -;; -;; @lowersections changes @chapter to @section -;; @subsection to @subsubsection, -;; etc. -;; -;; An @raisesections/@lowersections command changes only those -;; structuring commands that follow the @raisesections/@lowersections -;; command. -;; -;; Repeated @raisesections/@lowersections continue to raise or lower -;; the heading level. -;; -;; An @lowersections command cancels an @raisesections command, and -;; vice versa. -;; -;; You cannot raise or lower "beyond" chapters or subsubsections, but -;; trying to do so does not elicit an error---you just get more -;; headings that mean the same thing as you keep raising or lowering -;; (for example, after a single @raisesections, both @chapter and -;; @section produce chapter headings). - -(defun texinfo-raise-lower-sections () - "Raise or lower the hierarchical level of chapters, sections, etc. - -This function acts according to `@raisesections' and `@lowersections' -commands in the Texinfo file. - -For example, an `@lowersections' command is useful if you wish to -include what is written as an outer or standalone Texinfo file in -another Texinfo file as an inner, included file. The `@lowersections' -command changes chapters to sections, sections to subsections and so -on. - -@raisesections changes @subsection to @section, - @section to @chapter, - @heading to @chapheading, - etc. - -@lowersections changes @chapter to @section, - @subsection to @subsubsection, - @heading to @subheading, - etc. - -An `@raisesections' or `@lowersections' command changes only those -structuring commands that follow the `@raisesections' or -`@lowersections' command. - -An `@lowersections' command cancels an `@raisesections' command, and -vice versa. - -Repeated use of the commands continue to raise or lower the hierarchical -level a step at a time. - -An attempt to raise above `chapters' reproduces chapter commands; an -attempt to lower below subsubsections reproduces subsubsection -commands." - - ;; `texinfo-section-types-regexp' is defined in `texnfo-upd.el'; - ;; it is a regexp matching chapter, section, other headings - ;; (but not the top node). - - (let (type (level 0)) - (while - (re-search-forward - (concat - "\\(\\(^@\\(raise\\|lower\\)sections\\)\\|\\(" - texinfo-section-types-regexp - "\\)\\)") - nil t) - (beginning-of-line) - (save-excursion (setq type (read (current-buffer)))) - (cond - - ;; 1. Increment level - ((eq type '@raisesections) - (setq level (1+ level)) - (delete-region - (point) (line-beginning-position 2))) - - ;; 2. Decrement level - ((eq type '@lowersections) - (setq level (1- level)) - (delete-region - (point) (line-beginning-position 2))) - - ;; Now handle structuring commands - ((cond - - ;; 3. Raise level when positive - ((> level 0) - (let ((count level) - (new-level type)) - (while (> count 0) - (setq new-level - (cdr (assq new-level texinfo-raisesections-alist))) - (setq count (1- count))) - (kill-word 1) - (insert (symbol-name new-level)))) - - ;; 4. Do nothing except move point when level is zero - ((= level 0) (forward-line 1)) - - ;; 5. Lower level when positive - ((< level 0) - (let ((count level) - (new-level type)) - (while (< count 0) - (setq new-level - (cdr (assq new-level texinfo-lowersections-alist))) - (setq count (1+ count))) - (kill-word 1) - (insert (symbol-name new-level)))))))))) - -;;; Perform those texinfo-to-info conversions that apply to the whole input -;;; uniformly. - -(defun texinfo-format-scan () - (texinfo-format-convert (point-min) (point-max)) - ;; Search for @copying, which has to be first since the - ;; @insertcopying command then inserts the text elsewhere. - (goto-char (point-min)) - (when (search-forward "@copying" nil t) - (texinfo-copying)) - (while (search-forward "@insertcopying" nil t) - (delete-region (match-beginning 0) (match-end 0)) - - (texinfo-insertcopying)) - ;; Scan for other @-commands. - (goto-char (point-min)) - (while (search-forward "@" nil t) - ;; - ;; These are the single-character accent commands: @^ @` @' @" @= @~ - ;; In Info, they are simply quoted and the @ deleted. - ;; Other single-character commands: - ;; @* forces a line break, - ;; @- is a discretionary hyphenation point; does nothing in Info. - ;; @, @, @ each produce a single space, - ;; unless followed by a newline. - ;; - ;; Old version 2.34 expression: (looking-at "[@{}^'` *\"?!]") - (if (looking-at "[@{}^'`\"=~ \t\n*?!-]") - ;; @*, causes a line break. - (cond - ;; @*, a line break - ((= (following-char) ?*) - ;; remove command - (delete-region (1- (point)) (1+ (point))) - ;; insert return if not at end of line; - ;; else line is already broken. - (if (not (= (following-char) ?\n)) - (insert ?\n))) - ;; @-, deleted - ((= (following-char) ?-) - (delete-region (1- (point)) (1+ (point)))) - ;; @, @, @: produce a single space, - ;; unless followed by a newline. - ((= (following-char) ? ) - (delete-region (1- (point)) (1+ (point))) - ;; insert single space if not at end of line; - ;; else line is already broken. - (if (not (= (following-char) ?\n)) - (insert ? ))) - ((= (following-char) ?\t) - (delete-region (1- (point)) (1+ (point))) - ;; insert single space if not at end of line; - ;; else line is already broken. - (if (not (= (following-char) ?\n)) - (insert ? ))) - ;; following char is a carriage return - ((= (following-char) ?\n) - ;; remove command - (delete-region (1- (point)) (1+ (point))) - ;; insert single space if not at end of line; - ;; else line is already broken. - (if (not (= (following-char) ?\n)) - (insert ? ))) - ;; Otherwise: the other characters are simply quoted. Delete the @. - (t - (delete-char -1) - ;; Be compatible with makeinfo: if @' and its ilk are - ;; followed by a @ without a brace, barf. - (if (looking-at "[\"'^`~=]") - (progn - (if (= (char-after (1+ (point))) ?@) - (error "Use braces to give a command as an argument to @%c" - (following-char))) - (forward-char 1) - ;; @' etc. can optionally accept their argument in - ;; braces (makeinfo supports that). - (when (looking-at "{") - (let ((start (point))) - (forward-list 1) - (delete-char -1) - (goto-char start) - (delete-char 1)))) - (forward-char 1)))) - ;; @ is followed by a command-word; find the end of the word. - (setq texinfo-command-start (1- (point))) - (if (= (char-syntax (following-char)) ?w) - (forward-word-strictly 1) - (forward-char 1)) - (setq texinfo-command-end (point)) - ;; Detect the case of two @-commands in a row; - ;; process just the first one. - (goto-char (1+ texinfo-command-start)) - (skip-chars-forward "^@" texinfo-command-end) - (setq texinfo-command-end (point)) - ;; Handle let aliasing - (setq texinfo-command-name - (let (trial - (cmdname - (buffer-substring-no-properties - (1+ texinfo-command-start) texinfo-command-end))) - (while (setq trial (assoc cmdname texinfo-alias-list)) - (setq cmdname (cdr trial))) - (intern cmdname))) - ;; Call the handler for this command. - (let ((enclosure-type - (assoc - (symbol-name texinfo-command-name) - texinfo-enclosure-list))) - (if enclosure-type - (progn - (insert - (car (car (cdr enclosure-type))) - (texinfo-parse-arg-discard) - (car (cdr (car (cdr enclosure-type))))) - (goto-char texinfo-command-start)) - (let ((cmd (get texinfo-command-name 'texinfo-format))) - (if cmd (funcall cmd) (texinfo-unsupported))))))) - - (cond (texinfo-stack - (goto-char (nth 2 (car texinfo-stack))) - (error "Unterminated @%s" (car (car texinfo-stack))))) - - ;; Remove excess whitespace - (dlet ((whitespace-silent t)) - (whitespace-cleanup))) - -(defvar texinfo-copying-text "" - "Text of the copyright notice and copying permissions.") - -(defun texinfo-copying () - "Copy the copyright notice and copying permissions from Texinfo file. -This is indicated by the \"@copying ... @end copying\" command; -insert the text with the \"@insertcopying\" command." - (let ((beg (progn (beginning-of-line) (point))) - (end (progn (re-search-forward "^@end copying[ \t]*\n") (point)))) - (setq texinfo-copying-text - (buffer-substring-no-properties - (save-excursion (goto-char beg) (line-beginning-position 2)) - (save-excursion (goto-char end) (line-beginning-position 0)))) - (delete-region beg end))) - -(defun texinfo-insertcopying () - "Insert the copyright notice and copying permissions from Texinfo file. -This is indicated by the \"@copying ... @end copying\" command." - (insert (concat "\n" texinfo-copying-text))) - -(put 'begin 'texinfo-format 'texinfo-format-begin) -(defun texinfo-format-begin () - (texinfo-format-begin-end 'texinfo-format)) - -(put 'end 'texinfo-format 'texinfo-format-end) -(defun texinfo-format-end () - (texinfo-format-begin-end 'texinfo-end)) - -(defun texinfo-format-begin-end (prop) - (setq texinfo-command-name (intern (texinfo-parse-line-arg))) - (let ((cmd (get texinfo-command-name prop))) - (if cmd (funcall cmd) - (texinfo-unsupported)))) - -;;; Parsing functions - -(defun texinfo-parse-line-arg () - "Return argument of @-command as string. -Argument is separated from command either by a space or by a brace. -If a space, return rest of line, with beginning and ending white -space removed. If a brace, return string between braces. -Leave point after argument." - (goto-char texinfo-command-end) - (let ((start (point))) - (cond ((looking-at " ") - (skip-chars-forward " ") - (setq start (point)) - (end-of-line) - (skip-chars-backward " ") - (delete-region (point) (progn (end-of-line) (point))) - (setq texinfo-command-end (1+ (point)))) - ((looking-at "{") - (setq start (1+ (point))) - (forward-list 1) - (setq texinfo-command-end (point)) - (forward-char -1)) - (t - (error "Invalid texinfo command arg format"))) - (prog1 (buffer-substring-no-properties start (point)) - (if (eolp) (forward-char 1))))) - -(defun texinfo-parse-expanded-arg () - (goto-char texinfo-command-end) - (let ((start (point)) - marker) - (cond ((looking-at " ") - (skip-chars-forward " ") - (setq start (point)) - (end-of-line) - (setq texinfo-command-end (1+ (point)))) - ((looking-at "{") - (setq start (1+ (point))) - (forward-list 1) - (setq texinfo-command-end (point)) - (forward-char -1)) - (t - (error "Invalid texinfo command arg format"))) - (setq marker (move-marker (make-marker) texinfo-command-end)) - (texinfo-format-expand-region start (point)) - (setq texinfo-command-end (marker-position marker)) - (move-marker marker nil) - (prog1 (buffer-substring-no-properties start (point)) - (if (eolp) (forward-char 1))))) - -(defun texinfo-format-expand-region (start end) - (save-restriction - (narrow-to-region start end) - (let (texinfo-command-start - texinfo-command-end - texinfo-command-name - texinfo-stack) - (texinfo-format-scan)) - (goto-char (point-max)))) - -(defun texinfo-parse-arg-discard () - "Delete command and argument; return argument of command." - (prog1 (texinfo-parse-line-arg) - (texinfo-discard-command))) - -(defun texinfo-discard-command () - (delete-region texinfo-command-start texinfo-command-end)) - -(defun texinfo-optional-braces-discard () - "Discard braces following command, if any." - (goto-char texinfo-command-end) - ;; (let ((start (point))) - (cond ((looking-at "[ \t]*\n")) ; do nothing - ((looking-at "{") ; remove braces, if any - (forward-list 1) - (setq texinfo-command-end (point))) - (t - (error - "Invalid `texinfo-optional-braces-discard' format (need braces?)"))) - (delete-region texinfo-command-start texinfo-command-end)) ;;) - -(defun texinfo-format-parse-line-args () - (let (;; (start (1- (point))) - next beg end - args) - (skip-chars-forward " ") - (while (not (eolp)) - (setq beg (point)) - (re-search-forward "[\n,]") - (setq next (point)) - (if (bolp) (setq next (1- next))) - (forward-char -1) - (skip-chars-backward " ") - (setq end (point)) - (push (if (> end beg) (buffer-substring-no-properties beg end)) - args) - (goto-char next) - (skip-chars-forward " ")) - (if (eolp) (forward-char 1)) - (setq texinfo-command-end (point)) - (nreverse args))) - -(defun texinfo-format-parse-args () - (let (;; (start (1- (point))) - next beg end - args) - (search-forward "{") - (save-excursion - (texinfo-format-expand-region - (point) - (save-excursion (up-list 1) (1- (point))))) - ;; The following does not handle cross references of the form: - ;; `@xref{bullet, , @code{@@bullet}@{@}}.' because the - ;; re-search-forward finds the first right brace after the second - ;; comma. - (while (/= (preceding-char) ?\}) - (skip-chars-forward " \t\n") - (setq beg (point)) - (re-search-forward "[},]") - (setq next (point)) - (forward-char -1) - (skip-chars-backward " \t\n") - (setq end (point)) - (cond ((< beg end) - (goto-char beg) - (while (search-forward "\n" end t) - (replace-match " ")))) - (push (if (> end beg) (buffer-substring-no-properties beg end)) - args) - (goto-char next)) - ;;(if (eolp) (forward-char 1)) - (setq texinfo-command-end (point)) - (nreverse args))) - -(defun texinfo-format-parse-defun-args () - (goto-char texinfo-command-end) - (let ((start (point))) - (end-of-line) - (setq texinfo-command-end (1+ (point))) - (let ((marker (move-marker (make-marker) texinfo-command-end))) - (texinfo-format-expand-region start (point)) - (setq texinfo-command-end (marker-position marker)) - (move-marker marker nil)) - (goto-char start) - (let ((args '()) - beg end) - (skip-chars-forward " ") - (while (not (eolp)) - (cond ((looking-at "{") - (setq beg (1+ (point))) - (forward-list 1) - (setq end (1- (point)))) - (t - (setq beg (point)) - (re-search-forward "[\n ]") - (forward-char -1) - (setq end (point)))) - (push (buffer-substring-no-properties beg end) args) - (skip-chars-forward " ")) - (forward-char 1) - (nreverse args)))) - -(defun texinfo-discard-line () - (goto-char texinfo-command-end) - (skip-chars-forward " \t") - (or (eolp) - (error "Extraneous text at end of command line")) - (goto-char texinfo-command-start) - (or (bolp) - (error "Extraneous text at beginning of command line")) - (delete-region (point) (progn (forward-line 1) (point)))) - -(defun texinfo-discard-line-with-args () - (goto-char texinfo-command-start) - (delete-region (point) (progn (forward-line 1) (point)))) - - -;;; @setfilename - -;; Only `texinfo-format-buffer' handles @setfilename with this -;; definition; `texinfo-format-region' handles @setfilename, if any, -;; specially. -(put 'setfilename 'texinfo-format 'texinfo-format-setfilename) -(defun texinfo-format-setfilename () - (texinfo-parse-arg-discard)) - -;;; @node, @menu, @detailmenu - -(put 'node 'texinfo-format 'texinfo-format-node) -(put 'nwnode 'texinfo-format 'texinfo-format-node) -(defun texinfo-format-node () - (let* ((args (texinfo-format-parse-line-args)) - (name (nth 0 args)) - (next (nth 1 args)) - (prev (nth 2 args)) - (up (nth 3 args))) - (texinfo-discard-command) - (setq texinfo-last-node name) - (let ((tem (if texinfo-fold-nodename-case (downcase name) name))) - (if (assoc tem texinfo-node-names) - (error "Duplicate node name: %s" name) - (push (list tem) texinfo-node-names))) - (setq texinfo-footnote-number 0) - ;; insert "\n\^_" unconditionally since this is what info is looking for - (insert "\n\^_\nFile: " texinfo-format-filename - ", Node: " name) - (if next - (insert ", Next: " next)) - (if prev - (insert ", Prev: " prev)) - (if up - (insert ", Up: " up)) - (insert ?\n) - (setq texinfo-last-node-pos (point)))) - -(put 'anchor 'texinfo-format 'texinfo-anchor) -(defun texinfo-anchor () - (let (anchor-string - (here (- (point) 7)) ; save location of beginning of `@anchor' - (arg (texinfo-parse-arg-discard))) - (if (looking-at " ") ; since a space may be left after -discard - (delete-char 1)) - (forward-paragraph) - (let ((end (point))) - (if (save-excursion - (backward-word-strictly 1) - (search-forward "@refill" end t)) - (setq anchor-string "@anchor-yes-refill") - (setq anchor-string "@anchor-no-refill"))) - (goto-char here) - (insert anchor-string "{" arg "}"))) - -(put 'menu 'texinfo-format 'texinfo-format-menu) -(defun texinfo-format-menu () - (texinfo-discard-line) - (insert "* Menu:\n\n")) - -(put 'menu 'texinfo-end 'texinfo-discard-command) - -;; The @detailmenu should be removed eventually. - -;; According to Karl Berry, 31 August 1996: -;; -;; You don't like, I don't like it. I agree, it would be better just to -;; fix the bug [in `makeinfo']. .. At this point, since inserting those -;; two commands in the Elisp fn is trivial, I don't especially want to -;; expend more effort... -;; -;; I added a couple sentences of documentation to the manual (putting the -;; blame on makeinfo where it belongs :-(). - -(put 'detailmenu 'texinfo-format 'texinfo-discard-line) -(put 'detailmenu 'texinfo-end 'texinfo-discard-command) - -;; (Also see `texnfo-upd.el') - - -;;; Cross references - -;; @xref {NODE, FNAME, NAME, FILE, DOCUMENT} -;; -> *Note FNAME: (FILE)NODE -;; If FILE is missing, -;; *Note FNAME: NODE -;; If FNAME is empty and NAME is present -;; *Note NAME: Node -;; If both NAME and FNAME are missing -;; *Note NODE:: -;; texinfo ignores the DOCUMENT argument. -;; -> See section [NAME, else NODE], page -;; If FILE is specified, (FILE)NODE is used for xrefs. -;; If fifth argument DOCUMENT is specified, produces -;; See section [NAME, else NODE], page -;; of DOCUMENT - -;; @ref a reference that does not put `See' or `see' in -;; the hardcopy and is the same as @xref in Info -(put 'ref 'texinfo-format 'texinfo-format-xref) - -(put 'xref 'texinfo-format 'texinfo-format-xref) -(defun texinfo-format-xref () - (let ((args (texinfo-format-parse-args))) - (texinfo-discard-command) - (insert "*Note ") - (let ((fname (or (nth 1 args) (nth 2 args)))) - (if (null (or fname (nth 3 args))) - (insert (car args) "::") - (insert (or fname (car args)) ": ") - (if (nth 3 args) - (insert "(" (nth 3 args) ")")) - (and (car args) (insert (car args))))))) - -(put 'pxref 'texinfo-format 'texinfo-format-pxref) -(defun texinfo-format-pxref () - (texinfo-format-xref) - (or (save-excursion - (forward-char -2) - (looking-at "::")) - (insert "."))) - -;; @inforef{NODE, FNAME, FILE} -;; Like @xref{NODE, FNAME,,FILE} in texinfo. -;; In Tex, generates "See Info file FILE, node NODE" -(put 'inforef 'texinfo-format 'texinfo-format-inforef) -(defun texinfo-format-inforef () - (let ((args (texinfo-format-parse-args))) - (texinfo-discard-command) - (if (nth 1 args) - (insert "*Note " (nth 1 args) ": (" (nth 2 args) ")" (car args)) - (insert "*Note " "(" (nth 2 args) ")" (car args) "::")))) - - -;;; URL Reference: @uref - -;; @uref produces a reference to a uniform resource locator (URL). -;; It takes one mandatory argument, the URL, and one optional argument, -;; the text to display (the default is the URL itself). - -(put 'uref 'texinfo-format 'texinfo-format-uref) -(defun texinfo-format-uref () - "Format URL and optional URL-TITLE. -Insert \\=` ... \\=' around URL if no URL-TITLE argument; -otherwise, insert URL-TITLE followed by URL in parentheses." - (let ((args (texinfo-format-parse-args))) - (texinfo-discard-command) - ;; if url-title - (if (nth 1 args) - (insert (nth 1 args) " (" (nth 0 args) ")") - (insert "`" (nth 0 args) "'")))) - - -;;; Section headings - -(put 'majorheading 'texinfo-format 'texinfo-format-chapter) -(put 'chapheading 'texinfo-format 'texinfo-format-chapter) -(put 'ichapter 'texinfo-format 'texinfo-format-chapter) -(put 'chapter 'texinfo-format 'texinfo-format-chapter) -(put 'iappendix 'texinfo-format 'texinfo-format-chapter) -(put 'appendix 'texinfo-format 'texinfo-format-chapter) -(put 'iunnumbered 'texinfo-format 'texinfo-format-chapter) -(put 'top 'texinfo-format 'texinfo-format-chapter) -(put 'unnumbered 'texinfo-format 'texinfo-format-chapter) -(put 'centerchap 'texinfo-format 'texinfo-format-chapter) -(defun texinfo-format-chapter () - (texinfo-format-chapter-1 ?*)) - -(put 'heading 'texinfo-format 'texinfo-format-section) -(put 'isection 'texinfo-format 'texinfo-format-section) -(put 'section 'texinfo-format 'texinfo-format-section) -(put 'iappendixsection 'texinfo-format 'texinfo-format-section) -(put 'appendixsection 'texinfo-format 'texinfo-format-section) -(put 'iappendixsec 'texinfo-format 'texinfo-format-section) -(put 'appendixsec 'texinfo-format 'texinfo-format-section) -(put 'iunnumberedsec 'texinfo-format 'texinfo-format-section) -(put 'unnumberedsec 'texinfo-format 'texinfo-format-section) -(defun texinfo-format-section () - (texinfo-format-chapter-1 ?=)) - -(put 'subheading 'texinfo-format 'texinfo-format-subsection) -(put 'isubsection 'texinfo-format 'texinfo-format-subsection) -(put 'subsection 'texinfo-format 'texinfo-format-subsection) -(put 'iappendixsubsec 'texinfo-format 'texinfo-format-subsection) -(put 'appendixsubsec 'texinfo-format 'texinfo-format-subsection) -(put 'iunnumberedsubsec 'texinfo-format 'texinfo-format-subsection) -(put 'unnumberedsubsec 'texinfo-format 'texinfo-format-subsection) -(defun texinfo-format-subsection () - (texinfo-format-chapter-1 ?-)) - -(put 'subsubheading 'texinfo-format 'texinfo-format-subsubsection) -(put 'isubsubsection 'texinfo-format 'texinfo-format-subsubsection) -(put 'subsubsection 'texinfo-format 'texinfo-format-subsubsection) -(put 'iappendixsubsubsec 'texinfo-format 'texinfo-format-subsubsection) -(put 'appendixsubsubsec 'texinfo-format 'texinfo-format-subsubsection) -(put 'iunnumberedsubsubsec 'texinfo-format 'texinfo-format-subsubsection) -(put 'unnumberedsubsubsec 'texinfo-format 'texinfo-format-subsubsection) -(defun texinfo-format-subsubsection () - (texinfo-format-chapter-1 ?.)) - -(defun texinfo-format-chapter-1 (belowchar) - (let ((arg (texinfo-parse-arg-discard))) - (message "Formatting: %s ... " arg) ; So we can see where we are. - (insert ?\n arg ?\n "@SectionPAD " belowchar ?\n) - (forward-line -2))) - -(put 'SectionPAD 'texinfo-format 'texinfo-format-sectionpad) -(defun texinfo-format-sectionpad () - (let ((str (texinfo-parse-arg-discard))) - (forward-char -1) - (let ((column (current-column))) - (forward-char 1) - (while (> column 0) - (insert str) - (setq column (1- column)))) - (insert ?\n))) - - -;;; Space controlling commands: @. and @:, and the soft hyphen. - -(put '\. 'texinfo-format 'texinfo-format-\.) -(defun texinfo-format-\. () - (texinfo-discard-command) - (insert ".")) - -(put '\: 'texinfo-format 'texinfo-format-\:) -(defun texinfo-format-\: () - (texinfo-discard-command)) - -(put '\- 'texinfo-format 'texinfo-format-soft-hyphen) -(defun texinfo-format-soft-hyphen () - (texinfo-discard-command)) - - -;;; @kbdinputstyle, @vskip, headings & footings -;; These commands for not for Info and should never -;; appear in an Info environment; but if they do, -;; this causes them to be discarded. - -;; @kbdinputstyle -(put 'kbdinputstyle 'texinfo-format 'texinfo-discard-line-with-args) - -;; @vskip -(put 'vskip 'texinfo-format 'texinfo-discard-line-with-args) - -;; headings & footings -(put 'evenfooting 'texinfo-format 'texinfo-discard-line-with-args) -(put 'evenheading 'texinfo-format 'texinfo-discard-line-with-args) -(put 'oddfooting 'texinfo-format 'texinfo-discard-line-with-args) -(put 'oddheading 'texinfo-format 'texinfo-discard-line-with-args) -(put 'everyfooting 'texinfo-format 'texinfo-discard-line-with-args) -(put 'everyheading 'texinfo-format 'texinfo-discard-line-with-args) - - -;;; @documentdescription ... @end documentdescription -;; This command is for HTML output and should never -;; appear in an Info environment; but if it does, -;; this causes it to be discarded. - -(put 'documentdescription 'texinfo-format 'texinfo-format-documentdescription) -(defun texinfo-format-documentdescription () - (delete-region texinfo-command-start - (progn (re-search-forward "^@end documentdescription[ \t]*\n") - (point)))) - - - -;;; @center, @sp, and @br - -(put 'center 'texinfo-format 'texinfo-format-center) -(defun texinfo-format-center () - (let ((arg (texinfo-parse-expanded-arg))) - (texinfo-discard-command) - (insert arg) - (insert ?\n) - (save-restriction - (goto-char (1- (point))) - (let ((indent-tabs-mode nil)) - (center-line))))) - -(put 'sp 'texinfo-format 'texinfo-format-sp) -(defun texinfo-format-sp () - (let* ((arg (texinfo-parse-arg-discard)) - (num (read arg))) - (insert-char ?\n num))) - -(put 'br 'texinfo-format 'texinfo-format-paragraph-break) -(defun texinfo-format-paragraph-break () - "Force a paragraph break. -If used within a line, follow `@br' with braces." - (texinfo-optional-braces-discard) - ;; insert one return if at end of line; - ;; else insert two returns, to generate a blank line. - (if (= (following-char) ?\n) - (insert ?\n) - (insert-char ?\n 2))) - - -;;; @footnote and @footnotestyle - -;; In Texinfo, footnotes are created with the `@footnote' command. -;; This command is followed immediately by a left brace, then by the text of -;; the footnote, and then by a terminating right brace. The -;; template for a footnote is: -;; -;; @footnote{TEXT} -;; -;; Info has two footnote styles: -;; -;; * In the End of node style, all the footnotes for a single node -;; are placed at the end of that node. The footnotes are -;; separated from the rest of the node by a line of dashes with -;; the word `Footnotes' within it. -;; -;; * In the Separate node style, all the footnotes for a single node -;; are placed in an automatically constructed node of their own. - -;; Footnote style is specified by the @footnotestyle command, either -;; @footnotestyle separate -;; or -;; @footnotestyle end -;; -;; The default is separate - -(defvar texinfo-footnote-style "separate" - "Footnote style, either separate or end.") - -(put 'footnotestyle 'texinfo-format 'texinfo-footnotestyle) -(defun texinfo-footnotestyle () - "Specify whether footnotes are at end of node or in separate nodes. -Argument is either end or separate." - (setq texinfo-footnote-style (texinfo-parse-arg-discard))) - -(put 'footnote 'texinfo-format 'texinfo-format-footnote) -(defun texinfo-format-footnote () - "Format a footnote in either end of node or separate node style. -The texinfo-footnote-style variable controls which style is used." - (setq texinfo-footnote-number (1+ texinfo-footnote-number)) - (cond ((string= texinfo-footnote-style "end") - (texinfo-format-end-node)) - ((string= texinfo-footnote-style "separate") - (texinfo-format-separate-node)))) - -(defun texinfo-format-separate-node () - "Format footnote in Separate node style, with notes in own node. -The node is constructed automatically." - (let* (start - (arg (texinfo-parse-line-arg)) - (node-name-beginning - (save-excursion - (re-search-backward - "^File: \\w+\\(\\w\\|\\s_\\|\\.\\|,\\)*[ \t]+Node:") - (match-end 0))) - (node-name - (save-excursion - (buffer-substring-no-properties - (progn (goto-char node-name-beginning) ; skip over node command - (skip-chars-forward " \t") ; and over spaces - (point)) - (if (search-forward "," (line-end-position) t) ; bound search - (1- (point)) - (end-of-line) (point)))))) - (texinfo-discard-command) ; remove or insert whitespace, as needed - (delete-region (save-excursion (skip-chars-backward " \t\n") (point)) - (point)) - (insert (format " (%d) (*Note %s-Footnotes::)" - texinfo-footnote-number node-name)) - (fill-paragraph nil) - (save-excursion - (if (re-search-forward "^@node" nil 'move) - (forward-line -1)) - - ;; two cases: for the first footnote, we must insert a node header; - ;; for the second and subsequent footnotes, we need only insert - ;; the text of the footnote. - - (if (save-excursion - (search-backward - (concat node-name "-Footnotes, Up: ") - node-name-beginning - t)) - (progn ; already at least one footnote - (setq start (point)) - (insert (format "\n(%d) %s\n" texinfo-footnote-number arg)) - (fill-region start (point))) - ;; else not yet a footnote - (insert "\n\^_\nFile: " texinfo-format-filename - " Node: " node-name "-Footnotes, Up: " node-name "\n") - (setq start (point)) - (insert (format "\n(%d) %s\n" texinfo-footnote-number arg)) - (narrow-to-region (save-excursion (goto-char start) (point)) (point)) - (fill-region (point-min) (point-max)) - (widen))))) - -(defun texinfo-format-end-node () - "Format footnote in the End of node style, with notes at end of node." - (let (start - (arg (texinfo-parse-line-arg))) - (texinfo-discard-command) ; remove or insert whitespace, as needed - (delete-region (save-excursion (skip-chars-backward " \t\n") (point)) - (point)) - (insert (format " (%d) " texinfo-footnote-number)) - (fill-paragraph nil) - (save-excursion - (if (search-forward "\n--------- Footnotes ---------\n" nil t) - (progn ; already have footnote, put new one before end of node - (if (re-search-forward "^@node" nil 'move) - (forward-line -1)) - (setq start (point)) - (insert (format "\n(%d) %s\n" texinfo-footnote-number arg)) - (fill-region start (point))) - ;; else no prior footnote - (if (re-search-forward "^@node" nil 'move) - (forward-line -1)) - (insert "\n--------- Footnotes ---------\n") - (setq start (point)) - (insert (format "\n(%d) %s\n" texinfo-footnote-number arg)))))) - - -;;; @itemize, @enumerate, and similar commands - -;; @itemize pushes (itemize "COMMANDS" STARTPOS) on texinfo-stack. -;; @enumerate pushes (enumerate 0 STARTPOS). -;; @item dispatches to the texinfo-item prop of the first elt of the list. -;; For itemize, this puts in and rescans the COMMANDS. -;; For enumerate, this increments the number and puts it in. -;; In either case, it puts a Backspace at the front of the line -;; which marks it not to be indented later. -;; All other lines get indented by 5 when the @end is reached. - -(defvar texinfo-stack-depth 0 - "Count of number of unpopped texinfo-push-stack calls. -Used by @refill indenting command to avoid indenting within lists, etc.") - -(defun texinfo-push-stack (check arg) - (setq texinfo-stack-depth (1+ texinfo-stack-depth)) - (push (list check arg texinfo-command-start) - texinfo-stack)) - -(defun texinfo-pop-stack (check) - (setq texinfo-stack-depth (1- texinfo-stack-depth)) - (if (null texinfo-stack) - (error "Unmatched @end %s" check)) - (if (not (eq (car (car texinfo-stack)) check)) - (error "@end %s matches @%s" - check (car (car texinfo-stack)))) - (prog1 (cdr (car texinfo-stack)) - (setq texinfo-stack (cdr texinfo-stack)))) - -(put 'itemize 'texinfo-format 'texinfo-itemize) -(defun texinfo-itemize () - (texinfo-push-stack - 'itemize - (progn (skip-chars-forward " \t") - (if (eolp) - "@bullet" - (texinfo-parse-line-arg)))) - (texinfo-discard-line-with-args) - (setq fill-column (- fill-column 5))) - -(put 'itemize 'texinfo-end 'texinfo-end-itemize) -(defun texinfo-end-itemize () - (setq fill-column (+ fill-column 5)) - (texinfo-discard-command) - (let ((stacktop - (texinfo-pop-stack 'itemize))) - (texinfo-do-itemize (nth 1 stacktop)))) - -(put 'enumerate 'texinfo-format 'texinfo-enumerate) -(defun texinfo-enumerate () - (texinfo-push-stack - 'enumerate - (progn (skip-chars-forward " \t") - (if (eolp) - 1 - (read (current-buffer))))) - (if (and (symbolp (car (cdr (car texinfo-stack)))) - (> 1 (length (symbol-name (car (cdr (car texinfo-stack))))))) - (error - "@enumerate: Use a number or letter, eg: 1, A, a, 3, B, or d")) - (texinfo-discard-line-with-args) - (setq fill-column (- fill-column 5))) - -(put 'enumerate 'texinfo-end 'texinfo-end-enumerate) -(defun texinfo-end-enumerate () - (setq fill-column (+ fill-column 5)) - (texinfo-discard-command) - (let ((stacktop - (texinfo-pop-stack 'enumerate))) - (texinfo-do-itemize (nth 1 stacktop)))) - -;; @alphaenumerate never became a standard part of Texinfo -(put 'alphaenumerate 'texinfo-format 'texinfo-alphaenumerate) -(defun texinfo-alphaenumerate () - (texinfo-push-stack 'alphaenumerate (1- ?a)) - (setq fill-column (- fill-column 5)) - (texinfo-discard-line)) - -(put 'alphaenumerate 'texinfo-end 'texinfo-end-alphaenumerate) -(defun texinfo-end-alphaenumerate () - (setq fill-column (+ fill-column 5)) - (texinfo-discard-command) - (let ((stacktop - (texinfo-pop-stack 'alphaenumerate))) - (texinfo-do-itemize (nth 1 stacktop)))) - -;; @capsenumerate never became a standard part of Texinfo -(put 'capsenumerate 'texinfo-format 'texinfo-capsenumerate) -(defun texinfo-capsenumerate () - (texinfo-push-stack 'capsenumerate (1- ?A)) - (setq fill-column (- fill-column 5)) - (texinfo-discard-line)) - -(put 'capsenumerate 'texinfo-end 'texinfo-end-capsenumerate) -(defun texinfo-end-capsenumerate () - (setq fill-column (+ fill-column 5)) - (texinfo-discard-command) - (let ((stacktop - (texinfo-pop-stack 'capsenumerate))) - (texinfo-do-itemize (nth 1 stacktop)))) - -;; At the @end, indent all the lines within the construct -;; except those marked with backspace. FROM says where -;; construct started. -(defun texinfo-do-itemize (from) - (save-excursion - (while (progn (forward-line -1) - (>= (point) from)) - (if (= (following-char) ?\b) - (save-excursion - (delete-char 1) - (end-of-line) - (delete-char 6)) - (if (not (looking-at "[ \t]*$")) - (save-excursion (insert " "))))))) - -(put 'item 'texinfo-format 'texinfo-item) -(put 'itemx 'texinfo-format 'texinfo-item) -(defun texinfo-item () - (funcall (get (car (car texinfo-stack)) 'texinfo-item))) - -(put 'itemize 'texinfo-item 'texinfo-itemize-item) -(defun texinfo-itemize-item () - ;; (texinfo-discard-line) ; Did not handle text on same line as @item. - (delete-region (1+ (point)) (line-beginning-position)) - (if (looking-at "[ \t]*[^ \t\n]+") - ;; Text on same line as @item command. - (insert "\b " (nth 1 (car texinfo-stack)) " \n") - ;; Else text on next line. - (insert "\b " (nth 1 (car texinfo-stack)) " ")) - (forward-line -1)) - -(put 'enumerate 'texinfo-item 'texinfo-enumerate-item) -(defun texinfo-enumerate-item () - (texinfo-discard-line) - (let (enumerating-symbol) - (cond ((integerp (car (cdr (car texinfo-stack)))) - (setq enumerating-symbol (car (cdr (car texinfo-stack)))) - (insert ?\b (format "%3d. " enumerating-symbol) ?\n) - (setcar (cdr (car texinfo-stack)) (1+ enumerating-symbol))) - ((symbolp (car (cdr (car texinfo-stack)))) - (setq enumerating-symbol - (symbol-name (car (cdr (car texinfo-stack))))) - (if (or (equal ?\[ (string-to-char enumerating-symbol)) - (equal ?\{ (string-to-char enumerating-symbol))) - (error - "Too many items in enumerated list; alphabet ends at Z")) - (insert ?\b (format "%3s. " enumerating-symbol) ?\n) - (setcar (cdr (car texinfo-stack)) - (make-symbol - (char-to-string - (1+ - (string-to-char enumerating-symbol)))))) - (t - (error - "@enumerate: Use a number or letter, eg: 1, A, a, 3, B or d"))) - (forward-line -1))) - -(put 'alphaenumerate 'texinfo-item 'texinfo-alphaenumerate-item) -(defun texinfo-alphaenumerate-item () - (texinfo-discard-line) - (let ((next (1+ (car (cdr (car texinfo-stack)))))) - (if (> next ?z) - (error "More than 26 items in @alphaenumerate; get a bigger alphabet")) - (setcar (cdr (car texinfo-stack)) next) - (insert "\b " next ". \n")) - (forward-line -1)) - -(put 'capsenumerate 'texinfo-item 'texinfo-capsenumerate-item) -(defun texinfo-capsenumerate-item () - (texinfo-discard-line) - (let ((next (1+ (car (cdr (car texinfo-stack)))))) - (if (> next ?Z) - (error "More than 26 items in @capsenumerate; get a bigger alphabet")) - (setcar (cdr (car texinfo-stack)) next) - (insert "\b " next ". \n")) - (forward-line -1)) - - -;;; @table - -;; The `@table' command produces two-column tables. - -(put 'table 'texinfo-format 'texinfo-table) -(defun texinfo-table () - (texinfo-push-stack - 'table - (progn (skip-chars-forward " \t") - (if (eolp) - "@asis" - (texinfo-parse-line-arg)))) - (texinfo-discard-line-with-args) - (setq fill-column (- fill-column 5))) - -(put 'table 'texinfo-item 'texinfo-table-item) -(defun texinfo-table-item () - (let ((arg (texinfo-parse-arg-discard)) - (itemfont (car (cdr (car texinfo-stack))))) - (insert ?\b itemfont ?\{ arg "}\n \n")) - (forward-line -2)) - -(put 'table 'texinfo-end 'texinfo-end-table) -(defun texinfo-end-table () - (setq fill-column (+ fill-column 5)) - (texinfo-discard-command) - (let ((stacktop - (texinfo-pop-stack 'table))) - (texinfo-do-itemize (nth 1 stacktop)))) - -;; @description appears to be an undocumented variant on @table that -;; does not require an arg. It fails in texinfo.tex 2.58 and is not -;; part of makeinfo.c The command appears to be a relic of the past. -(put 'description 'texinfo-end 'texinfo-end-table) -(put 'description 'texinfo-format 'texinfo-description) -(defun texinfo-description () - (texinfo-push-stack 'table "@asis") - (setq fill-column (- fill-column 5)) - (texinfo-discard-line)) - - -;;; @ftable, @vtable - -;; The `@ftable' and `@vtable' commands are like the `@table' command -;; but they also insert each entry in the first column of the table -;; into the function or variable index. - -;; Handle the @ftable and @vtable commands: - -(put 'ftable 'texinfo-format 'texinfo-ftable) -(put 'vtable 'texinfo-format 'texinfo-vtable) - -(defun texinfo-ftable () (texinfo-indextable 'ftable)) -(defun texinfo-vtable () (texinfo-indextable 'vtable)) - -(defun texinfo-indextable (table-type) - (texinfo-push-stack table-type (texinfo-parse-arg-discard)) - (setq fill-column (- fill-column 5))) - -;; Handle the @item commands within ftable and vtable: - -(put 'ftable 'texinfo-item 'texinfo-ftable-item) -(put 'vtable 'texinfo-item 'texinfo-vtable-item) - -(defun texinfo-ftable-item () (texinfo-indextable-item 'texinfo-findex)) -(defun texinfo-vtable-item () (texinfo-indextable-item 'texinfo-vindex)) - -(defun texinfo-indextable-item (index-type) - (let ((item (texinfo-parse-arg-discard)) - (itemfont (car (cdr (car texinfo-stack)))) - (indexvar index-type)) - (insert ?\b itemfont ?\{ item "}\n \n") - (set indexvar - (cons - (list item texinfo-last-node) - (symbol-value indexvar))) - (forward-line -2))) - -;; Handle @end ftable, @end vtable - -(put 'ftable 'texinfo-end 'texinfo-end-ftable) -(put 'vtable 'texinfo-end 'texinfo-end-vtable) - -(defun texinfo-end-ftable () (texinfo-end-indextable 'ftable)) -(defun texinfo-end-vtable () (texinfo-end-indextable 'vtable)) - -(defun texinfo-end-indextable (table-type) - (setq fill-column (+ fill-column 5)) - (texinfo-discard-command) - (let ((stacktop - (texinfo-pop-stack table-type))) - (texinfo-do-itemize (nth 1 stacktop)))) - - -;;; @multitable ... @end multitable - -;; Produce a multi-column table, with as many columns as desired. -;; -;; A multi-column table has this template: -;; -;; @multitable {A1} {A2} {A3} -;; @item A1 @tab A2 @tab A3 -;; @item B1 @tab B2 @tab B3 -;; @item C1 @tab C2 @tab C3 -;; @end multitable -;; -;; where the width of the text in brackets specifies the width of the -;; respective column. -;; -;; Or else: -;; -;; @multitable @columnfractions .25 .3 .45 -;; @item A1 @tab A2 @tab A3 -;; @item B1 @tab B2 @tab B3 -;; @end multitable -;; -;; where the fractions specify the width of each column as a percent -;; of the current width of the text (i.e., of the fill-column). -;; -;; Long lines of text are filled within columns. -;; -;; Using the Emacs Lisp formatter, texinfmt.el, -;; the whitespace between columns can be increased by setting -;; `texinfo-extra-inter-column-width' to a value greater than 0. By default, -;; there is at least one blank space between columns. -;; -;; The Emacs Lisp formatter, texinfmt.el, ignores the following four -;; commands that are defined in texinfo.tex for printed output. -;; -;; @multitableparskip, -;; @multitableparindent, -;; @multitablecolmargin, -;; @multitablelinespace. - -;; How @multitable works. -;; ===================== -;; -;; `texinfo-multitable' reads the @multitable line and determines from it -;; how wide each column should be. -;; -;; Also, it pushes this information, along with an identifying symbol, -;; onto the `texinfo-stack'. At the @end multitable command, the stack -;; is checked for its matching @multitable command, and then popped, or -;; else an error is signaled. Also, this command pushes the location of -;; the start of the table onto the stack. -;; -;; `texinfo-end-multitable' checks the `texinfo-stack' that the @end -;; multitable truly is ending a corresponding beginning, and if it is, -;; pops the stack. -;; -;; `texinfo-multitable-widths' is called by `texinfo-multitable'. -;; The function returns a list of the widths of each column in a -;; multi-column table, based on the information supplied by the arguments -;; to the @multitable command (by arguments, I mean the text on the rest -;; of the @multitable line, not the remainder of the multi-column table -;; environment). -;; -;; `texinfo-multitable-item' formats a row within a multicolumn table. -;; This command is executed when texinfmt sees @item inside @multitable. -;; Cells in row are separated by `@tab's. Widths of cells are specified -;; by the arguments in the @multitable line. Cells are filled. All cells -;; are made to be the same height by padding their bottoms, as needed, -;; with blanks. -;; -;; `texinfo-multitable-extract-row' is called by `texinfo-multitable-item'. -;; This function returns the text in a multitable row, as a string. -;; The start of a row is marked by an @item and the end of row is the -;; beginning of next @item or beginning of the @end multitable line. -;; Cells within a row are separated by @tab. -;; -;; Note that @tab, the cell separators, are not treated as independent -;; Texinfo commands. - -(defvar texinfo-extra-inter-column-width 0 - "Number of extra spaces between entries (columns) in @multitable.") - -(defvar texinfo-multitable-buffer-name "*multitable-temporary-buffer*") -(defvar texinfo-multitable-rectangle-name "texinfo-multitable-temp-") - -;; These commands are defined in texinfo.tex for printed output. -(put 'multitableparskip 'texinfo-format 'texinfo-discard-line-with-args) -(put 'multitableparindent 'texinfo-format 'texinfo-discard-line-with-args) -(put 'multitablecolmargin 'texinfo-format 'texinfo-discard-line-with-args) -(put 'multitablelinespace 'texinfo-format 'texinfo-discard-line-with-args) - -(put 'multitable 'texinfo-format 'texinfo-multitable) - -(defun texinfo-multitable () - "Produce multi-column tables. - -A multi-column table has this template: - - @multitable {A1} {A2} {A3} - @item A1 @tab A2 @tab A3 - @item B1 @tab B2 @tab B3 - @item C1 @tab C2 @tab C3 - @end multitable - -where the width of the text in brackets specifies the width of the -respective column. - -Or else: - - @multitable @columnfractions .25 .3 .45 - @item A1 @tab A2 @tab A3 - @item B1 @tab B2 @tab B3 - @end multitable - -where the fractions specify the width of each column as a percent -of the current width of the text (i.e., of the `fill-column'). - -Long lines of text are filled within columns. - -Using the Emacs Lisp formatter, texinfmt.el, -the whitespace between columns can be increased by setting -`texinfo-extra-inter-column-width' to a value greater than 0. By default, -there is at least one blank space between columns. - -The Emacs Lisp formatter, texinfmt.el, ignores the following four -commands that are defined in texinfo.tex for printed output. - - @multitableparskip, - @multitableparindent, - @multitablecolmargin, - @multitablelinespace." - -;; This function pushes information onto the `texinfo-stack'. -;; A stack element consists of: -;; - type-of-command, i.e., multitable -;; - the information about column widths, and -;; - the position of texinfo-command-start. -;; e.g., ('multitable (1 2 3 4) 123) -;; The command line is then deleted. - (texinfo-push-stack - 'multitable - ;; push width information on stack - (texinfo-multitable-widths)) - (texinfo-discard-line-with-args)) - -(put 'multitable 'texinfo-end 'texinfo-end-multitable) -(defun texinfo-end-multitable () - "Discard the @end multitable line and pop the stack of multitable." - (texinfo-discard-command) - (texinfo-pop-stack 'multitable)) - -(defun texinfo-multitable-widths () - "Return list of widths of each column in a multi-column table." - (let (texinfo-multitable-width-list) - ;; Fractions format: - ;; @multitable @columnfractions .25 .3 .45 - ;; - ;; Template format: - ;; @multitable {Column 1 template} {Column 2} {Column 3 example} - ;; Place point before first argument - (skip-chars-forward " \t") - (cond - ;; Check for common misspelling - ((looking-at "@columnfraction ") - (error "In @multitable, @columnfractions misspelled")) - ;; Case 1: @columnfractions .25 .3 .45 - ((looking-at "@columnfractions") - (forward-word-strictly 1) - (while (not (eolp)) - (push (truncate - (1- - (* fill-column (read (get-buffer (current-buffer)))))) - texinfo-multitable-width-list))) - ;; - ;; Case 2: {Column 1 template} {Column 2} {Column 3 example} - ((looking-at "{") - ;; (let ((start-of-templates (point))) - (while (not (eolp)) - (skip-chars-forward " \t") - (let* ((start-of-template (1+ (point))) - (end-of-template - ;; forward-sexp works with braces in Texinfo mode - (progn (forward-sexp 1) (1- (point))))) - (push (- end-of-template start-of-template) - texinfo-multitable-width-list) - ;; Remove carriage return from within a template, if any. - ;; This helps those who want to use more than - ;; one line's worth of words in @multitable line. - (narrow-to-region start-of-template end-of-template) - (goto-char (point-min)) - (while (search-forward " -" nil t) - (delete-char -1)) - (goto-char (point-max)) - (widen) - (forward-char 1)))) ;; ) - ;; - ;; Case 3: Trouble - (t - (error - "You probably need to specify column widths for @multitable correctly"))) - ;; Check whether columns fit on page. - (let ((desired-columns - (+ - ;; between column spaces - (length texinfo-multitable-width-list) - ;; additional between column spaces, if any - texinfo-extra-inter-column-width - ;; sum of spaces for each entry - (apply #'+ texinfo-multitable-width-list)))) - (if (> desired-columns fill-column) - (error - "Multi-column table width, %d chars, is greater than page width, %d chars" - desired-columns fill-column))) - texinfo-multitable-width-list)) - -;; @item A1 @tab A2 @tab A3 -(defun texinfo-multitable-extract-row () - "Return multitable row, as a string. -End of row is beginning of next @item or beginning of @end. -Cells within rows are separated by @tab." - (skip-chars-forward " \t") - (let* ((start (point)) - (end (progn - (re-search-forward "@item\\|@end") - (match-beginning 0))) - (row (progn (goto-char end) - (skip-chars-backward " ") - ;; remove whitespace at end of argument - (delete-region (point) end) - (buffer-substring-no-properties start (point))))) - (delete-region texinfo-command-start end) - row)) - -(put 'multitable 'texinfo-item 'texinfo-multitable-item) -(defun texinfo-multitable-item () - "Format a row within a multicolumn table. -Cells in row are separated by @tab. -Widths of cells are specified by the arguments in the @multitable line. -All cells are made to be the same height. -This command is executed when texinfmt sees @item inside @multitable." - (let ((original-buffer (current-buffer)) - (table-widths (reverse (car (cdr (car texinfo-stack))))) - (existing-fill-column fill-column) - start - end - (table-column 0) - (table-entry-height 0) - ;; unformatted row looks like: A1 @tab A2 @tab A3 - ;; extract-row command deletes the source line in the table. - (unformatted-row (texinfo-multitable-extract-row))) - ;; Use a temporary buffer - (set-buffer (get-buffer-create texinfo-multitable-buffer-name)) - (delete-region (point-min) (point-max)) - (insert unformatted-row) - (goto-char (point-min)) -;; 1. Check for correct number of @tab in line. - (let ((tab-number 1)) ; one @tab between two columns - (while (search-forward "@tab" nil t) - (setq tab-number (1+ tab-number))) - (let ((needed-tabs (- (length table-widths) tab-number))) - (when (> needed-tabs 0) - (goto-char (point-min)) - (end-of-line) - (while (> needed-tabs 0) - (insert "@w{ }\n@tab") - (setq needed-tabs (1- needed-tabs)) - (message - "Added @tabs and empty spaces to a @multitable row"))))) - (goto-char (point-min)) -;; 2. Format each cell, and copy to a rectangle - ;; buffer looks like this: A1 @tab A2 @tab A3 - ;; Cell #1: format up to @tab - ;; Cell #2: format up to @tab - ;; Cell #3: format up to eob - (while (not (eobp)) - (setq start (point)) - (setq end (save-excursion - (if (search-forward "@tab" nil 'move) - ;; Delete the @tab command, including the @-sign - (delete-region - (point) - (progn (forward-word-strictly -1) (1- (point))))) - (point))) - ;; Set fill-column *wider* than needed to produce inter-column space - (setq fill-column (+ 1 - texinfo-extra-inter-column-width - (nth table-column table-widths))) - (narrow-to-region start end) - ;; Remove whitespace before and after entry. - (skip-chars-forward " ") - (delete-region (point) (line-beginning-position)) - (goto-char (point-max)) - (skip-chars-backward " ") - (delete-region (point) (line-end-position)) - ;; Temporarily set texinfo-stack to nil so texinfo-format-scan - ;; does not see an unterminated @multitable. - (let (texinfo-stack) ; nil - (texinfo-format-scan)) - (let (fill-prefix) ; no fill prefix - (fill-region (point-min) (point-max))) - (setq table-entry-height - (max table-entry-height (count-lines (point-min) (point-max)))) -;; 3. Move point to end of bottom line, and pad that line to fill column. - (goto-char (point-min)) - (forward-line (1- table-entry-height)) - (let* ((beg (point)) ; beginning of line - ;; add one more space for inter-column spacing - (needed-whitespace - (1+ - (- fill-column - (- - (progn (end-of-line) (point)) ; end of existing line - beg))))) - (insert (make-string - (if (> needed-whitespace 0) needed-whitespace 1) - ? ))) - ;; now, put formatted cell into a rectangle - (set (intern (concat texinfo-multitable-rectangle-name - (int-to-string table-column))) - (extract-rectangle (point-min) (point))) - (delete-region (point-min) (point)) - (goto-char (point-max)) - (setq table-column (1+ table-column)) - (widen)) -;; 4. Add extra lines to rectangles so all are of same height - (let ((total-number-of-columns table-column) - (column-number 0) - here) - (while (> table-column 0) - (let ((this-rectangle (int-to-string table-column))) - (while (< (length this-rectangle) table-entry-height) - (setq this-rectangle (append this-rectangle '(""))))) - (setq table-column (1- table-column))) -;; 5. Insert formatted rectangles in original buffer - (switch-to-buffer original-buffer) - (open-line table-entry-height) - (while (< column-number total-number-of-columns) - (setq here (point)) - (insert-rectangle - (symbol-value (intern - (concat texinfo-multitable-rectangle-name - (int-to-string column-number))))) - (goto-char here) - (end-of-line) - (setq column-number (1+ column-number)))) - (kill-buffer texinfo-multitable-buffer-name) - (setq fill-column existing-fill-column))) - - -;;; @image -;; Use only the FILENAME argument to the command. -;; In Info, ignore the other arguments. - -(put 'image 'texinfo-format 'texinfo-format-image) -(defun texinfo-format-image () - "Insert an image from a file ending in .txt. -Use only the FILENAME arg; for Info, ignore the other arguments to @image." - (let ((args (texinfo-format-parse-args)) - filename) - (when (null (nth 0 args)) - (error "Invalid image command")) - (texinfo-discard-command) - ;; makeinfo uses FILENAME.txt - (setq filename (format "%s.txt" (nth 0 args))) - (message "Reading included file: %s" filename) - ;; verbatim for Info output - (goto-char (+ (point) (cadr (insert-file-contents filename)))) - (message "Reading included file: %s...done" filename))) - - -;;; @ifinfo, @iftex, @tex, @ifhtml, @html, @ifplaintext, @ifxml, @xml -;; @ifnottex, @ifnotinfo, @ifnothtml, @ifnotplaintext, @ifnotxml - -(put 'ifinfo 'texinfo-format 'texinfo-discard-line) -(put 'ifinfo 'texinfo-end 'texinfo-discard-command) - -(put 'iftex 'texinfo-format 'texinfo-format-iftex) -(defun texinfo-format-iftex () - (delete-region texinfo-command-start - (re-search-forward "@end iftex[ \t]*\n"))) - -(put 'ifhtml 'texinfo-format 'texinfo-format-ifhtml) -(defun texinfo-format-ifhtml () - (delete-region texinfo-command-start - (re-search-forward "@end ifhtml[ \t]*\n"))) - -(put 'ifplaintext 'texinfo-format 'texinfo-format-ifplaintext) -(defun texinfo-format-ifplaintext () - (delete-region texinfo-command-start - (re-search-forward "@end ifplaintext[ \t]*\n"))) - -(put 'ifxml 'texinfo-format 'texinfo-format-ifxml) -(defun texinfo-format-ifxml () - (delete-region texinfo-command-start - (progn (re-search-forward "^@end ifxml[ \t]*\n") - (point)))) - -(put 'tex 'texinfo-format 'texinfo-format-tex) -(defun texinfo-format-tex () - (delete-region texinfo-command-start - (re-search-forward "@end tex[ \t]*\n"))) - -(put 'html 'texinfo-format 'texinfo-format-html) -(defun texinfo-format-html () - (delete-region texinfo-command-start - (re-search-forward "@end html[ \t]*\n"))) - -(put 'xml 'texinfo-format 'texinfo-format-xml) -(defun texinfo-format-xml () - (delete-region texinfo-command-start - (progn (re-search-forward "^@end xml[ \t]*\n") - (point)))) - -(put 'ifnotinfo 'texinfo-format 'texinfo-format-ifnotinfo) -(defun texinfo-format-ifnotinfo () - (delete-region texinfo-command-start - (re-search-forward "@end ifnotinfo[ \t]*\n"))) - -(put 'ifnotplaintext 'texinfo-format 'texinfo-discard-line) -(put 'ifnotplaintext 'texinfo-end 'texinfo-discard-command) - -(put 'ifnottex 'texinfo-format 'texinfo-discard-line) -(put 'ifnottex 'texinfo-end 'texinfo-discard-command) - -(put 'ifnothtml 'texinfo-format 'texinfo-discard-line) -(put 'ifnothtml 'texinfo-end 'texinfo-discard-command) - -(put 'ifnotxml 'texinfo-format 'texinfo-discard-line) -(put 'ifnotxml 'texinfo-end 'texinfo-discard-command) - - -;;; @titlepage - -(put 'titlepage 'texinfo-format 'texinfo-format-titlepage) -(defun texinfo-format-titlepage () - (delete-region texinfo-command-start - (re-search-forward "@end titlepage[ \t]*\n"))) - -(put 'endtitlepage 'texinfo-format 'texinfo-discard-line) - -;; @titlespec an alternative titling command; ignored by Info - -(put 'titlespec 'texinfo-format 'texinfo-format-titlespec) -(defun texinfo-format-titlespec () - (delete-region texinfo-command-start - (re-search-forward "@end titlespec[ \t]*\n"))) - -(put 'endtitlespec 'texinfo-format 'texinfo-discard-line) - - -;;; @today - -(put 'today 'texinfo-format 'texinfo-format-today) - -;; Produces Day Month Year style of output. eg `1 Jan 1900' -;; The `@today{}' command requires a pair of braces, like `@dots{}'. -(defun texinfo-format-today () - (texinfo-parse-arg-discard) - (insert (format-time-string "%e %b %Y"))) - - -;;; @timestamp{} -;; Produce `Day Month Year Hour:Min' style of output. -;; eg `1 Jan 1900 13:52' - -(put 'timestamp 'texinfo-format 'texinfo-format-timestamp) - -;; The `@timestamp{}' command requires a pair of braces, like `@dots{}'. -(defun texinfo-format-timestamp () - "Insert the current local time and date." - (texinfo-parse-arg-discard) - ;; For seconds and time zone, replace format string with "%e %b %Y %T %Z" - (insert (format-time-string "%e %b %Y %R"))) - - -;;; @ignore - -(put 'ignore 'texinfo-format 'texinfo-format-ignore) -(defun texinfo-format-ignore () - (delete-region texinfo-command-start - (re-search-forward "@end ignore[ \t]*\n"))) - -(put 'endignore 'texinfo-format 'texinfo-discard-line) - - -;;; Define the Info enclosure command: @definfoenclose - -;; A `@definfoenclose' command may be used to define a highlighting -;; command for Info, but not for TeX. A command defined using -;; `@definfoenclose' marks text by enclosing it in strings that precede -;; and follow the text. -;; -;; Presumably, if you define a command with `@definfoenclose` for Info, -;; you will also define the same command in the TeX definitions file, -;; `texinfo.tex' in a manner appropriate for typesetting. -;; -;; Write a `@definfoenclose' command on a line and follow it with three -;; arguments separated by commas (commas are used as separators in an -;; `@node' line in the same way). The first argument to -;; `@definfoenclose' is the @-command name (without the `@'); the -;; second argument is the Info start delimiter string; and the third -;; argument is the Info end delimiter string. The latter two arguments -;; enclose the highlighted text in the Info file. A delimiter string -;; may contain spaces. Neither the start nor end delimiter is -;; required. However, if you do not provide a start delimiter, you -;; must follow the command name with two commas in a row; otherwise, -;; the Info formatting commands will misinterpret the end delimiter -;; string as a start delimiter string. -;; -;; If you do a @definfoenclose{} on the name of a pre-defined macro (such -;; as @emph{}, @strong{}, @tt{}, or @i{}) the enclosure definition will -;; override the built-in definition. -;; -;; An enclosure command defined this way takes one argument in braces. -;; -;; For example, you can write: -;; -;; @ifinfo -;; @definfoenclose phoo, //, \\ -;; @end ifinfo -;; -;; near the beginning of a Texinfo file at the beginning of the lines -;; to define `@phoo' as an Info formatting command that inserts `//' -;; before and `\\' after the argument to `@phoo'. You can then write -;; `@phoo{bar}' wherever you want `//bar\\' highlighted in Info. -;; -;; Also, for TeX formatting, you could write -;; -;; @iftex -;; @global@let@phoo=@i -;; @end iftex -;; -;; to define `@phoo' as a command that causes TeX to typeset -;; the argument to `@phoo' in italics. -;; -;; Note that each definition applies to its own formatter: one for TeX, -;; the other for texinfo-format-buffer or texinfo-format-region. -;; -;; Here is another example: write -;; -;; @definfoenclose headword, , : -;; -;; near the beginning of the file, to define `@headword' as an Info -;; formatting command that inserts nothing before and a colon after the -;; argument to `@headword'. - -(put 'definfoenclose 'texinfo-format 'texinfo-define-info-enclosure) -(defun texinfo-define-info-enclosure () - (let* ((args (texinfo-format-parse-line-args)) - (command-name (nth 0 args)) - (beginning-delimiter (or (nth 1 args) "")) - (end-delimiter (or (nth 2 args) ""))) - (texinfo-discard-command) - (push (list command-name - (list - beginning-delimiter - end-delimiter)) - texinfo-enclosure-list))) - - -;;; @alias - -(put 'alias 'texinfo-format 'texinfo-alias) -(defun texinfo-alias () - (let (;; (start (1- (point)) - ) ;; args - (skip-chars-forward " ") - (setq texinfo-command-end (line-end-position)) - (if (not (looking-at "\\([^=]+\\)=\\(.*\\)")) - (error "Invalid alias command") - (push (cons - (match-string-no-properties 1) - (match-string-no-properties 2)) - texinfo-alias-list) - (texinfo-discard-command)))) - - -;;; @var, @code and the like - -(put 'var 'texinfo-format 'texinfo-format-var) -;; @sc a small caps font for TeX; formatted as `var' in Info -(put 'sc 'texinfo-format 'texinfo-format-var) -;; @acronym for abbreviations in all caps, such as `NASA'. -;; Convert all letters to uppercase if they are not already. -(put 'acronym 'texinfo-format 'texinfo-format-var) -(defun texinfo-format-var () - (let ((arg (texinfo-parse-expanded-arg))) - (texinfo-discard-command) - (insert (upcase arg)))) - -(put 'cite 'texinfo-format 'texinfo-format-code) -(put 'code 'texinfo-format 'texinfo-format-code) -;; @command (for command names) -(put 'command 'texinfo-format 'texinfo-format-code) -;; @env (for environment variables) -(put 'env 'texinfo-format 'texinfo-format-code) -(put 'file 'texinfo-format 'texinfo-format-code) -(put 'samp 'texinfo-format 'texinfo-format-code) -(put 'url 'texinfo-format 'texinfo-format-code) -(defun texinfo-format-code () - (insert "`" (texinfo-parse-arg-discard) "'") - (goto-char texinfo-command-start)) - -;; @option (for command-line options) must be different from @code -;; because of its special formatting in @table; namely that it does -;; not lead to inserted ` ... ' in a table, but does elsewhere. -(put 'option 'texinfo-format 'texinfo-format-option) -(defun texinfo-format-option () - "Insert \\=` ... \\=' around arg unless inside a table; in that case, no quotes." - ;; `looking-at-backward' not available in v. 18.57, 20.2 - (if (not (search-backward "\^H" - (line-beginning-position) - t)) - (insert "`" (texinfo-parse-arg-discard) "'") - (insert (texinfo-parse-arg-discard))) - (goto-char texinfo-command-start)) - -(put 'emph 'texinfo-format 'texinfo-format-emph) -(put 'strong 'texinfo-format 'texinfo-format-emph) -(defun texinfo-format-emph () - (insert "*" (texinfo-parse-arg-discard) "*") - (goto-char texinfo-command-start)) - -(put 'dfn 'texinfo-format 'texinfo-format-defn) -(put 'defn 'texinfo-format 'texinfo-format-defn) -(defun texinfo-format-defn () - (insert "\"" (texinfo-parse-arg-discard) "\"") - (goto-char texinfo-command-start)) - -(put 'email 'texinfo-format 'texinfo-format-email) -(defun texinfo-format-email () - "Format email address and optional following full name. -Insert full name, if present, followed by email address -surrounded by in angle brackets." - (let ((args (texinfo-format-parse-args))) - (texinfo-discard-command) - ;; if full-name - (if (nth 1 args) - (insert (nth 1 args) " ")) - (insert "<" (nth 0 args) ">"))) - -(put 'key 'texinfo-format 'texinfo-format-key) -;; I've decided not want to have angle brackets around these -- rms. -(defun texinfo-format-key () - (insert (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @verb{TEXT} (in `makeinfo' 4.1 and later) -(put 'verb 'texinfo-format 'texinfo-format-verb) -(defun texinfo-format-verb () - "Format text between non-quoted unique delimiter characters verbatim. -Enclose the verbatim text, including the delimiters, in braces. Print -text exactly as written (but not the delimiters) in a fixed-width. - -For example, @verb{|@|} results in @ and -@verb{+@\\='e?\\=`!\\=`+} results in @\\='e?\\=`!\\=`." - - (let ((delimiter (buffer-substring-no-properties - (1+ texinfo-command-end) (+ 2 texinfo-command-end)))) - (unless (looking-at "{") - (error "Not found: @verb start brace")) - (delete-region texinfo-command-start (+ 2 texinfo-command-end)) - (search-forward delimiter)) - (delete-char -1) - (unless (looking-at "}") - (error "Not found: @verb end brace")) - (delete-char 1)) - -;; as of 2002 Dec 10 -;; see (texinfo)Block Enclosing Commands -;; need: @verbatim - -;; as of 2002 Dec 10 -;; see (texinfo)verbatiminclude -;; need: @verbatiminclude FILENAME - -(put 'bullet 'texinfo-format 'texinfo-format-bullet) -(defun texinfo-format-bullet () - "Insert an asterisk. -If used within a line, follow `@bullet' with braces." - (texinfo-optional-braces-discard) - (insert "*")) - - -;;; @kbd - -;; Inside of @example ... @end example and similar environments, -;; @kbd does nothing; but outside of such environments, it places -;; single quotation marks around its argument. - -(defvar texinfo-format-kbd-regexp - (concat - "^@" - "\\(" - "display\\|" - "example\\|" - "smallexample\\|" - "lisp\\|" - "smalllisp" - "\\)") - "Regexp matching environments in which @kbd does not put `...' around arg.") - -(defvar texinfo-format-kbd-end-regexp - (concat - "^@end " - "\\(" - "display\\|" - "example\\|" - "smallexample\\|" - "lisp\\|" - "smalllisp" - "\\)") - "Regexp specifying end of environments in which @kbd does not put `...' -around argument. - -See `texinfo-format-kbd-regexp'.") - -(put 'kbd 'texinfo-format 'texinfo-format-kbd) -(defun texinfo-format-kbd () - "Place single quote marks around arg, except in @example and similar." - ;; Search forward for @end example closer than an @example. - ;; Can stop search at nearest @node or texinfo-section-types-regexp - (let* ((stop - (save-excursion - (re-search-forward - (concat "^@node\\|\\(" texinfo-section-types-regexp "\\)") - nil - 'move-to-end) ; if necessary, return point at end of buffer - (point))) - (example-location - (save-excursion - (re-search-forward texinfo-format-kbd-regexp stop 'move-to-end) - (point))) - (end-example-location - (save-excursion - (re-search-forward texinfo-format-kbd-end-regexp stop 'move-to-end) - (point)))) - ;; If inside @example, @end example will be closer than @example - ;; or end of search i.e., end-example-location less than example-location - (if (>= end-example-location example-location) - ;; outside an @example or equivalent - (insert "`" (texinfo-parse-arg-discard) "'") - ;; else, in @example; do not surround with `...' - (insert (texinfo-parse-arg-discard))) - (goto-char texinfo-command-start))) - - -;;; @example, @lisp, @quotation, @display, @smalllisp, @smallexample, -;; @smalldisplay - -(put 'display 'texinfo-format 'texinfo-format-example) -(put 'smalldisplay 'texinfo-format 'texinfo-format-example) -(put 'example 'texinfo-format 'texinfo-format-example) -(put 'lisp 'texinfo-format 'texinfo-format-example) -(put 'quotation 'texinfo-format 'texinfo-format-example) -(put 'smallexample 'texinfo-format 'texinfo-format-example) -(put 'smalllisp 'texinfo-format 'texinfo-format-example) -(defun texinfo-format-example () - (texinfo-push-stack 'example nil) - (setq fill-column (- fill-column 5)) - (texinfo-discard-line)) - -(put 'example 'texinfo-end 'texinfo-end-example) -(put 'display 'texinfo-end 'texinfo-end-example) -(put 'smalldisplay 'texinfo-end 'texinfo-end-example) -(put 'lisp 'texinfo-end 'texinfo-end-example) -(put 'quotation 'texinfo-end 'texinfo-end-example) -(put 'smallexample 'texinfo-end 'texinfo-end-example) -(put 'smalllisp 'texinfo-end 'texinfo-end-example) -(defun texinfo-end-example () - (setq fill-column (+ fill-column 5)) - (texinfo-discard-command) - (let ((stacktop - (texinfo-pop-stack 'example))) - (texinfo-do-itemize (nth 1 stacktop)))) - -(put 'exdent 'texinfo-format 'texinfo-format-exdent) -(defun texinfo-format-exdent () - (texinfo-discard-command) - (delete-region (point) - (progn - (skip-chars-forward " ") - (point))) - (insert ?\b) - ;; Cancel out the deletion that texinfo-do-itemize - ;; is going to do at the end of this line. - (save-excursion - (end-of-line) - (insert "\n "))) - - -;; @direntry and @dircategory - -(put 'direntry 'texinfo-format 'texinfo-format-direntry) -(defun texinfo-format-direntry () - (texinfo-push-stack 'direntry nil) - (texinfo-discard-line) - (insert "START-INFO-DIR-ENTRY\n")) - -(put 'direntry 'texinfo-end 'texinfo-end-direntry) -(defun texinfo-end-direntry () - (texinfo-discard-command) - (insert "END-INFO-DIR-ENTRY\n\n") - (texinfo-pop-stack 'direntry)) - -(put 'dircategory 'texinfo-format 'texinfo-format-dircategory) -(defun texinfo-format-dircategory () - (let ((str (texinfo-parse-arg-discard))) - (delete-region (point) - (progn - (skip-chars-forward " ") - (point))) - (insert "INFO-DIR-SECTION " str "\n"))) - -;;; @cartouche - -;; The @cartouche command is a noop in Info; in a printed manual, -;; it makes a box with rounded corners. - -(put 'cartouche 'texinfo-format 'texinfo-discard-line) -(put 'cartouche 'texinfo-end 'texinfo-discard-command) - - -;;; @flushleft and @format - -;; The @flushleft command left justifies every line but leaves the -;; right end ragged. As far as Info is concerned, @flushleft is a -;; `do-nothing' command - -;; The @format command is similar to @example except that it does not -;; indent; this means that in Info, @format is similar to @flushleft. - -(put 'format 'texinfo-format 'texinfo-format-flushleft) -(put 'smallformat 'texinfo-format 'texinfo-format-flushleft) -(put 'flushleft 'texinfo-format 'texinfo-format-flushleft) -(defun texinfo-format-flushleft () - (texinfo-discard-line)) - -(put 'format 'texinfo-end 'texinfo-end-flushleft) -(put 'smallformat 'texinfo-end 'texinfo-end-flushleft) -(put 'flushleft 'texinfo-end 'texinfo-end-flushleft) -(defun texinfo-end-flushleft () - (texinfo-discard-command)) - - -;;; @flushright - -;; The @flushright command right justifies every line but leaves the -;; left end ragged. Spaces and tabs at the right ends of lines are -;; removed so that visible text lines up on the right side. - -(put 'flushright 'texinfo-format 'texinfo-format-flushright) -(defun texinfo-format-flushright () - (texinfo-push-stack 'flushright nil) - (texinfo-discard-line)) - -(put 'flushright 'texinfo-end 'texinfo-end-flushright) -(defun texinfo-end-flushright () - (texinfo-discard-command) - - (let ((stacktop - (texinfo-pop-stack 'flushright))) - - (texinfo-do-flushright (nth 1 stacktop)))) - -(defun texinfo-do-flushright (from) - (save-excursion - (while (progn (forward-line -1) - (>= (point) from)) - - (beginning-of-line) - (insert - (make-string - (- fill-column - (save-excursion - (end-of-line) - (skip-chars-backward " \t") - (delete-region (point) (progn (end-of-line) (point))) - (current-column))) - ? ))))) - - -;;; @ctrl, @TeX, @copyright, @minus, @dots, @enddots, @pounds - -(put 'ctrl 'texinfo-format 'texinfo-format-ctrl) -(defun texinfo-format-ctrl () - (let ((str (texinfo-parse-arg-discard))) - (insert (logand 31 (aref str 0))))) - -(put 'TeX 'texinfo-format 'texinfo-format-TeX) -(defun texinfo-format-TeX () - (texinfo-parse-arg-discard) - (insert "TeX")) - -(put 'copyright 'texinfo-format 'texinfo-format-copyright) -(defun texinfo-format-copyright () - (texinfo-parse-arg-discard) - (insert "(C)")) - -(put 'minus 'texinfo-format 'texinfo-format-minus) -(defun texinfo-format-minus () - "Insert a minus sign. -If used within a line, follow `@minus' with braces." - (texinfo-optional-braces-discard) - (insert "-")) - -(put 'dots 'texinfo-format 'texinfo-format-dots) -(defun texinfo-format-dots () - (texinfo-parse-arg-discard) - (insert "...")) - -(put 'enddots 'texinfo-format 'texinfo-format-enddots) -(defun texinfo-format-enddots () - (texinfo-parse-arg-discard) - (insert "....")) - -(put 'pounds 'texinfo-format 'texinfo-format-pounds) -(defun texinfo-format-pounds () - (texinfo-parse-arg-discard) - (insert "#")) - - -;;; Refilling and indenting: @refill, @paragraphindent, @noindent - -;; Indent only those paragraphs that are refilled as a result of an -;; @refill command. - -;; * If the value is `asis', do not change the existing indentation at -;; the starts of paragraphs. - -;; * If the value zero, delete any existing indentation. - -;; * If the value is greater than zero, indent each paragraph by that -;; number of spaces. - -;; But do not refill paragraphs with an @refill command that are -;; preceded by @noindent or are part of a table, list, or deffn. - -(defvar texinfo-paragraph-indent "asis" - "Number of spaces for @refill to indent a paragraph; else to leave as is.") - -(put 'paragraphindent 'texinfo-format 'texinfo-paragraphindent) - -(defun texinfo-paragraphindent () - "Specify the number of spaces for @refill to indent a paragraph. -Default is to leave the number of spaces as is." - (let ((arg (texinfo-parse-arg-discard))) - (if (string= "asis" arg) - (setq texinfo-paragraph-indent "asis") - (setq texinfo-paragraph-indent (string-to-number arg))))) - -(put 'refill 'texinfo-format 'texinfo-format-refill) -(defun texinfo-format-refill () - "Refill paragraph. Also, indent first line as set by @paragraphindent. -Default is to leave paragraph indentation as is." - (texinfo-discard-command) - (let ((position (point-marker))) - (forward-paragraph -1) - (if (looking-at "[ \t\n]*$") (forward-line 1)) - ;; Do not indent if an entry in a list, table, or deffn, - ;; or if paragraph is preceded by @noindent. - ;; Otherwise, indent - (cond - ;; delete a @noindent line and do not indent paragraph - ((save-excursion (forward-line -1) - (looking-at "^@noindent")) - (forward-line -1) - (delete-region (point) (progn (forward-line 1) (point)))) - ;; do nothing if "asis" - ((equal texinfo-paragraph-indent "asis")) - ;; do no indenting in list, etc. - ((> texinfo-stack-depth 0)) - ;; otherwise delete existing whitespace and indent - (t - (delete-region (point) (progn (skip-chars-forward " \t") (point))) - (insert (make-string texinfo-paragraph-indent ? )))) - (forward-paragraph 1) - (forward-line -1) - (end-of-line) - ;; Do not fill a section title line with asterisks, hyphens, etc. that - ;; are used to underline it. This could occur if the line following - ;; the underlining is not an index entry and has text within it. - (let* ((previous-paragraph-separate paragraph-separate) - (paragraph-separate - (concat paragraph-separate "\\|[-=.]+\\|\\*\\*+")) - (previous-paragraph-start paragraph-start) - (paragraph-start - (concat paragraph-start "\\|[-=.]+\\|\\*\\*+"))) - (unwind-protect - (fill-paragraph nil) - (setq paragraph-separate previous-paragraph-separate) - (setq paragraph-start previous-paragraph-start))) - (goto-char position))) - -(put 'noindent 'texinfo-format 'texinfo-noindent) -(defun texinfo-noindent () - (save-excursion - (forward-paragraph 1) - (if (search-backward "@refill" (line-beginning-position 0) t) - () ; leave @noindent command so @refill command knows not to indent - ;; else - (texinfo-discard-line)))) - - -;;; Index generation - -(put 'vindex 'texinfo-format 'texinfo-format-vindex) -(defun texinfo-format-vindex () - (texinfo-index 'texinfo-vindex)) - -(put 'cindex 'texinfo-format 'texinfo-format-cindex) -(defun texinfo-format-cindex () - (texinfo-index 'texinfo-cindex)) - -(put 'findex 'texinfo-format 'texinfo-format-findex) -(defun texinfo-format-findex () - (texinfo-index 'texinfo-findex)) - -(put 'pindex 'texinfo-format 'texinfo-format-pindex) -(defun texinfo-format-pindex () - (texinfo-index 'texinfo-pindex)) - -(put 'tindex 'texinfo-format 'texinfo-format-tindex) -(defun texinfo-format-tindex () - (texinfo-index 'texinfo-tindex)) - -(put 'kindex 'texinfo-format 'texinfo-format-kindex) -(defun texinfo-format-kindex () - (texinfo-index 'texinfo-kindex)) - -(defun texinfo-index (indexvar) - (let ((arg (texinfo-parse-expanded-arg))) - (texinfo-discard-command) - (set indexvar - (cons (list arg - texinfo-last-node - ;; Region formatting may not provide last node position. - (if texinfo-last-node-pos - (1+ (count-lines texinfo-last-node-pos (point))) - 1)) - (symbol-value indexvar))))) - -(defvar texinfo-indexvar-alist - '(("cp" . texinfo-cindex) - ("fn" . texinfo-findex) - ("vr" . texinfo-vindex) - ("tp" . texinfo-tindex) - ("pg" . texinfo-pindex) - ("ky" . texinfo-kindex))) - - -;;; @defindex @defcodeindex -(put 'defindex 'texinfo-format 'texinfo-format-defindex) -(put 'defcodeindex 'texinfo-format 'texinfo-format-defindex) - -(defun texinfo-format-defindex () - (let* ((index-name (texinfo-parse-arg-discard)) ; eg: `aa' - (indexing-command (intern (concat index-name "index"))) - (index-formatting-command ; eg: `texinfo-format-aaindex' - (intern (concat "texinfo-format-" index-name "index"))) - (index-alist-name ; eg: `texinfo-aaindex' - (intern (concat "texinfo-" index-name "index")))) - - (set index-alist-name nil) - - (put indexing-command ; eg, aaindex - 'texinfo-format - index-formatting-command) ; eg, texinfo-format-aaindex - - ;; eg: "aa" . texinfo-aaindex - (or (assoc index-name texinfo-indexvar-alist) - (push (cons index-name - index-alist-name) - texinfo-indexvar-alist)) - - (fset index-formatting-command - (list 'lambda 'nil - (list 'texinfo-index - (list 'quote index-alist-name)))))) - - -;;; @synindex @syncodeindex - -(put 'synindex 'texinfo-format 'texinfo-format-synindex) -(put 'syncodeindex 'texinfo-format 'texinfo-format-synindex) - -(defun texinfo-format-synindex () - (let* ((args (texinfo-parse-arg-discard)) - (second (cdr (read-from-string args))) - (joiner (symbol-name (car (read-from-string args)))) - (joined (symbol-name (car (read-from-string args second))))) - - (if (assoc joiner texinfo-short-index-cmds-alist) - (put - (cdr (assoc joiner texinfo-short-index-cmds-alist)) - 'texinfo-format - (or (cdr (assoc joined texinfo-short-index-format-cmds-alist)) - (intern (concat "texinfo-format-" joined "index")))) - (put - (intern (concat joiner "index")) - 'texinfo-format - (or (cdr(assoc joined texinfo-short-index-format-cmds-alist)) - (intern (concat "texinfo-format-" joined "index"))))))) - -(defconst texinfo-short-index-cmds-alist - '(("cp" . cindex) - ("fn" . findex) - ("vr" . vindex) - ("tp" . tindex) - ("pg" . pindex) - ("ky" . kindex))) - -(defconst texinfo-short-index-format-cmds-alist - '(("cp" . texinfo-format-cindex) - ("fn" . texinfo-format-findex) - ("vr" . texinfo-format-vindex) - ("tp" . texinfo-format-tindex) - ("pg" . texinfo-format-pindex) - ("ky" . texinfo-format-kindex))) - - -;;; Sort and index - -;; Sort an index which is in the current buffer between START and END. -(defun texinfo-sort-region (start end) - (require 'sort) - (save-restriction - (narrow-to-region start end) - (goto-char (point-min)) - (sort-subr nil 'forward-line 'end-of-line 'texinfo-sort-startkeyfun))) - -;; Subroutine for sorting an index. -;; At start of a line, return a string to sort the line under. -(defun texinfo-sort-startkeyfun () - (let ((line (buffer-substring-no-properties (point) (line-end-position)))) - ;; Canonicalize whitespace and eliminate funny chars. - (while (string-match "[ \t][ \t]+\\|[^a-z0-9 ]+" line) - (setq line (concat (substring line 0 (match-beginning 0)) - " " - (substring line (match-end 0))))) - line)) - - -;;; @printindex - -(put 'printindex 'texinfo-format 'texinfo-format-printindex) - -(defun texinfo-format-printindex () - (let* ((arg (texinfo-parse-arg-discard)) - (fmt (cdr (assoc arg texinfo-short-index-format-cmds-alist))) - (index-list (delq nil (mapcar (lambda (e) - (and (eq fmt (get (cdr e) 'texinfo-format)) - (cdr (assoc (car e) texinfo-indexvar-alist)))) - texinfo-short-index-cmds-alist))) - (indexelts (apply #'append nil (mapcar #'symbol-value index-list))) - opoint) - (insert "\n* Menu:\n\n") - (setq opoint (point)) - (texinfo-print-index nil indexelts) - (texinfo-sort-region opoint (point)))) - -(defun texinfo-print-index (file indexelts) - (while indexelts - (if (stringp (car (car indexelts))) - (progn - (insert "* " (car (car indexelts)) ": " ) - (indent-to 32) - (insert - (if file (concat "(" file ")") "") - (nth 1 (car indexelts)) ".") - (indent-to 54) - (insert - (if (nth 2 (car indexelts)) - (format " (line %3d)" (1+ (nth 2 (car indexelts)))) - "") - "\n")) - ;; index entries from @include'd file - (texinfo-print-index (nth 1 (car indexelts)) - (nth 2 (car indexelts)))) - (setq indexelts (cdr indexelts)))) - - -;;; Glyphs: @equiv, @error, etc - -;; @equiv to show that two expressions are equivalent -;; @error to show an error message -;; @expansion to show what a macro expands to -;; @point to show the location of point in an example -;; @print to show what an evaluated expression prints -;; @result to indicate the value returned by an expression - -(put 'equiv 'texinfo-format 'texinfo-format-equiv) -(defun texinfo-format-equiv () - (texinfo-parse-arg-discard) - (insert "==")) - -(put 'error 'texinfo-format 'texinfo-format-error) -(defun texinfo-format-error () - (texinfo-parse-arg-discard) - (insert "error-->")) - -(put 'expansion 'texinfo-format 'texinfo-format-expansion) -(defun texinfo-format-expansion () - (texinfo-parse-arg-discard) - (insert "==>")) - -(put 'point 'texinfo-format 'texinfo-format-point) -(defun texinfo-format-point () - (texinfo-parse-arg-discard) - (insert "-!-")) - -(put 'print 'texinfo-format 'texinfo-format-print) -(defun texinfo-format-print () - (texinfo-parse-arg-discard) - (insert "-|")) - -(put 'result 'texinfo-format 'texinfo-format-result) -(defun texinfo-format-result () - (texinfo-parse-arg-discard) - (insert "=>")) - - -;;; Accent commands - -;; Info presumes a plain ASCII output, so the accented characters do -;; not look as they would if typeset, or output with a different -;; character set. - -;; See the `texinfo-accent-commands' variable -;; in the section for `texinfo-append-refill'. -;; Also, see the defun for `texinfo-format-scan' -;; for single-character accent commands. - -;; Command Info output Name - -;; These do not have braces: -;; @^ ==> ^ circumflex accent -;; @` ==> ` grave accent -;; @' ==> ' acute accent -;; @" ==> " umlaut accent -;; @= ==> = overbar accent -;; @~ ==> ~ tilde accent - -;; These have braces, but take no argument: -;; @OE{} ==> OE French-OE-ligature -;; @oe{} ==> oe -;; @AA{} ==> AA Scandinavian-A-with-circle -;; @aa{} ==> aa -;; @AE{} ==> AE Latin-Scandinavian-AE -;; @ae{} ==> ae -;; @ss{} ==> ss German-sharp-S - -;; @questiondown{} ==> ? upside-down-question-mark -;; @exclamdown{} ==> ! upside-down-exclamation-mark -;; @L{} ==> L/ Polish suppressed-L (Lslash) -;; @l{} ==> l/ Polish suppressed-L (Lslash) (lower case) -;; @O{} ==> O/ Scandinavian O-with-slash -;; @o{} ==> o/ Scandinavian O-with-slash (lower case) - -;; These have braces, and take an argument: -;; @,{c} ==> c, cedilla accent -;; @dotaccent{o} ==> .o overdot-accent -;; @ubaraccent{o} ==> _o underbar-accent -;; @udotaccent{o} ==> o-. underdot-accent -;; @H{o} ==> ""o long Hungarian umlaut -;; @ringaccent{o} ==> *o ring accent -;; @tieaccent{oo} ==> [oo tie after accent -;; @u{o} ==> (o breve accent -;; @v{o} ==> i dotless i and dotless j - -;; ========== - -;; Note: The defun texinfo-format-scan -;; looks at "[@{}^'`\",=~ *?!-]" -;; In the case of @*, a line break is inserted; -;; in the other cases, the characters are simply quoted and the @ is deleted. -;; Thus, `texinfo-format-scan' handles the following -;; single-character accent commands: @^ @` @' @" @, @- @= @~ - -;; @^ ==> ^ circumflex accent -;; (put '^ 'texinfo-format 'texinfo-format-circumflex-accent) -;; (defun texinfo-format-circumflex-accent () -;; (texinfo-discard-command) -;; (insert "^")) -;; -;; @` ==> ` grave accent -;; (put '\` 'texinfo-format 'texinfo-format-grave-accent) -;; (defun texinfo-format-grave-accent () -;; (texinfo-discard-command) -;; (insert "`")) -;; -;; @' ==> ' acute accent -;; (put '\' 'texinfo-format 'texinfo-format-acute-accent) -;; (defun texinfo-format-acute-accent () -;; (texinfo-discard-command) -;; (insert "'")) -;; -;; @" ==> " umlaut accent -;; (put '\" 'texinfo-format 'texinfo-format-umlaut-accent) -;; (defun texinfo-format-umlaut-accent () -;; (texinfo-discard-command) -;; (insert "\"")) -;; -;; @= ==> = overbar accent -;; (put '= 'texinfo-format 'texinfo-format-overbar-accent) -;; (defun texinfo-format-overbar-accent () -;; (texinfo-discard-command) -;; (insert "=")) -;; -;; @~ ==> ~ tilde accent -;; (put '~ 'texinfo-format 'texinfo-format-tilde-accent) -;; (defun texinfo-format-tilde-accent () -;; (texinfo-discard-command) -;; (insert "~")) - -;; @OE{} ==> OE French-OE-ligature -(put 'OE 'texinfo-format 'texinfo-format-French-OE-ligature) -(defun texinfo-format-French-OE-ligature () - (insert "OE" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @oe{} ==> oe -(put 'oe 'texinfo-format 'texinfo-format-French-oe-ligature) -(defun texinfo-format-French-oe-ligature () ; lower case - (insert "oe" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @AA{} ==> AA Scandinavian-A-with-circle -(put 'AA 'texinfo-format 'texinfo-format-Scandinavian-A-with-circle) -(defun texinfo-format-Scandinavian-A-with-circle () - (insert "AA" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @aa{} ==> aa -(put 'aa 'texinfo-format 'texinfo-format-Scandinavian-a-with-circle) -(defun texinfo-format-Scandinavian-a-with-circle () ; lower case - (insert "aa" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @AE{} ==> AE Latin-Scandinavian-AE -(put 'AE 'texinfo-format 'texinfo-format-Latin-Scandinavian-AE) -(defun texinfo-format-Latin-Scandinavian-AE () - (insert "AE" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @ae{} ==> ae -(put 'ae 'texinfo-format 'texinfo-format-Latin-Scandinavian-ae) -(defun texinfo-format-Latin-Scandinavian-ae () ; lower case - (insert "ae" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @ss{} ==> ss German-sharp-S -(put 'ss 'texinfo-format 'texinfo-format-German-sharp-S) -(defun texinfo-format-German-sharp-S () - (insert "ss" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @questiondown{} ==> ? upside-down-question-mark -(put 'questiondown 'texinfo-format 'texinfo-format-upside-down-question-mark) -(defun texinfo-format-upside-down-question-mark () - (insert "?" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @exclamdown{} ==> ! upside-down-exclamation-mark -(put 'exclamdown 'texinfo-format 'texinfo-format-upside-down-exclamation-mark) -(defun texinfo-format-upside-down-exclamation-mark () - (insert "!" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @L{} ==> L/ Polish suppressed-L (Lslash) -(put 'L 'texinfo-format 'texinfo-format-Polish-suppressed-L) -(defun texinfo-format-Polish-suppressed-L () - (insert (texinfo-parse-arg-discard) "/L") - (goto-char texinfo-command-start)) - -;; @l{} ==> l/ Polish suppressed-L (Lslash) (lower case) -(put 'l 'texinfo-format 'texinfo-format-Polish-suppressed-l-lower-case) -(defun texinfo-format-Polish-suppressed-l-lower-case () - (insert (texinfo-parse-arg-discard) "/l") - (goto-char texinfo-command-start)) - - -;; @O{} ==> O/ Scandinavian O-with-slash -(put 'O 'texinfo-format 'texinfo-format-Scandinavian-O-with-slash) -(defun texinfo-format-Scandinavian-O-with-slash () - (insert (texinfo-parse-arg-discard) "O/") - (goto-char texinfo-command-start)) - -;; @o{} ==> o/ Scandinavian O-with-slash (lower case) -(put 'o 'texinfo-format 'texinfo-format-Scandinavian-o-with-slash-lower-case) -(defun texinfo-format-Scandinavian-o-with-slash-lower-case () - (insert (texinfo-parse-arg-discard) "o/") - (goto-char texinfo-command-start)) - -;; Take arguments - -;; @,{c} ==> c, cedilla accent -(put '\, 'texinfo-format 'texinfo-format-cedilla-accent) -(defun texinfo-format-cedilla-accent () - (insert (texinfo-parse-arg-discard) ",") - (goto-char texinfo-command-start)) - - -;; @dotaccent{o} ==> .o overdot-accent -(put 'dotaccent 'texinfo-format 'texinfo-format-overdot-accent) -(defun texinfo-format-overdot-accent () - (insert "." (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @ubaraccent{o} ==> _o underbar-accent -(put 'ubaraccent 'texinfo-format 'texinfo-format-underbar-accent) -(defun texinfo-format-underbar-accent () - (insert "_" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @udotaccent{o} ==> o-. underdot-accent -(put 'udotaccent 'texinfo-format 'texinfo-format-underdot-accent) -(defun texinfo-format-underdot-accent () - (insert (texinfo-parse-arg-discard) "-.") - (goto-char texinfo-command-start)) - -;; @H{o} ==> ""o long Hungarian umlaut -(put 'H 'texinfo-format 'texinfo-format-long-Hungarian-umlaut) -(defun texinfo-format-long-Hungarian-umlaut () - (insert "\"\"" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @ringaccent{o} ==> *o ring accent -(put 'ringaccent 'texinfo-format 'texinfo-format-ring-accent) -(defun texinfo-format-ring-accent () - (insert "*" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @tieaccent{oo} ==> [oo tie after accent -(put 'tieaccent 'texinfo-format 'texinfo-format-tie-after-accent) -(defun texinfo-format-tie-after-accent () - (insert "[" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - - -;; @u{o} ==> (o breve accent -(put 'u 'texinfo-format 'texinfo-format-breve-accent) -(defun texinfo-format-breve-accent () - (insert "(" (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @v{o} ==> i dotless i and dotless j -(put 'dotless 'texinfo-format 'texinfo-format-dotless) -(defun texinfo-format-dotless () - (insert (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - - -;;; Definition formatting: @deffn, @defun, etc - -;; What definition formatting produces: -;; -;; @deffn category name args... -;; In Info, `Category: name ARGS' -;; In index: name: node. line#. -;; -;; @defvr category name -;; In Info, `Category: name' -;; In index: name: node. line#. -;; -;; @deftp category name attributes... -;; `category name attributes...' Note: @deftp args in lower case. -;; In index: name: node. line#. -;; -;; Specialized function-like or variable-like entity: -;; -;; @defun, @defmac, @defspec, @defvar, @defopt -;; -;; @defun name args In Info, `Function: name ARGS' -;; @defmac name args In Info, `Macro: name ARGS' -;; @defvar name In Info, `Variable: name' -;; etc. -;; In index: name: node. line#. -;; -;; Generalized typed-function-like or typed-variable-like entity: -;; @deftypefn category data-type name args... -;; In Info, `Category: data-type name args...' -;; @deftypevr category data-type name -;; In Info, `Category: data-type name' -;; In index: name: node. line#. -;; -;; Specialized typed-function-like or typed-variable-like entity: -;; @deftypefun data-type name args... -;; In Info, `Function: data-type name ARGS' -;; In index: name: node. line#. -;; -;; @deftypevar data-type name -;; In Info, `Variable: data-type name' -;; In index: name: node. line#. but include args after name!? -;; -;; Generalized object oriented entity: -;; @defop category class name args... -;; In Info, `Category on class: name ARG' -;; In index: name on class: node. line#. -;; -;; @defcv category class name -;; In Info, `Category of class: name' -;; In index: name of class: node. line#. -;; -;; Specialized object oriented entity: -;; @defmethod class name args... -;; In Info, `Method on class: name ARGS' -;; In index: name on class: node. line#. -;; -;; @defivar class name -;; In Info, `Instance variable of class: name' -;; In index: name of class: node. line#. - - -;;; The definition formatting functions - -(defun texinfo-format-defun () - (texinfo-push-stack 'defun nil) - (setq fill-column (- fill-column 5)) - (texinfo-format-defun-1 t)) - -(defun texinfo-end-defun () - (setq fill-column (+ fill-column 5)) - (texinfo-discard-command) - (let ((start (nth 1 (texinfo-pop-stack 'defun)))) - (texinfo-do-itemize start) - ;; Delete extra newline inserted after header. - (save-excursion - (goto-char start) - (delete-char -1)))) - -(defun texinfo-format-defunx () - (texinfo-format-defun-1 nil)) - -(defun texinfo-format-defun-1 (first-p) - (let ((parse-args (texinfo-format-parse-defun-args)) - (texinfo-defun-type (get texinfo-command-name 'texinfo-defun-type))) - (texinfo-discard-command) - ;; Delete extra newline inserted after previous header line. - (if (not first-p) - (delete-char -1)) - (funcall - (get texinfo-command-name 'texinfo-deffn-formatting-property) parse-args) - ;; Insert extra newline so that paragraph filling does not mess - ;; with header line. - (insert "\n\n") - (rplaca (cdr (cdr (car texinfo-stack))) (point)) - (funcall - (get texinfo-command-name 'texinfo-defun-indexing-property) parse-args))) - -;;; Formatting the first line of a definition - -;; @deffn, @defvr, @deftp -(put 'deffn 'texinfo-deffn-formatting-property 'texinfo-format-deffn) -(put 'deffnx 'texinfo-deffn-formatting-property 'texinfo-format-deffn) -(put 'defvr 'texinfo-deffn-formatting-property 'texinfo-format-deffn) -(put 'defvrx 'texinfo-deffn-formatting-property 'texinfo-format-deffn) -(put 'deftp 'texinfo-deffn-formatting-property 'texinfo-format-deffn) -(put 'deftpx 'texinfo-deffn-formatting-property 'texinfo-format-deffn) -(defun texinfo-format-deffn (parsed-args) - ;; Generalized function-like, variable-like, or generic data-type entity: - ;; @deffn category name args... - ;; In Info, `Category: name ARGS' - ;; @deftp category name attributes... - ;; `category name attributes...' Note: @deftp args in lower case. - (let ((category (car parsed-args)) - (name (car (cdr parsed-args))) - (args (cdr (cdr parsed-args)))) - (insert " -- " category ": " name) - (while args - (insert " " - (if (or (= ?& (aref (car args) 0)) - (eq (car texinfo-defun-type) 'deftp-type)) - (car args) - (upcase (car args)))) - (setq args (cdr args))))) - -;; @defun, @defmac, @defspec, @defvar, @defopt: Specialized, simple -(put 'defun 'texinfo-deffn-formatting-property - 'texinfo-format-specialized-defun) -(put 'defunx 'texinfo-deffn-formatting-property - 'texinfo-format-specialized-defun) -(put 'defmac 'texinfo-deffn-formatting-property - 'texinfo-format-specialized-defun) -(put 'defmacx 'texinfo-deffn-formatting-property - 'texinfo-format-specialized-defun) -(put 'defspec 'texinfo-deffn-formatting-property - 'texinfo-format-specialized-defun) -(put 'defspecx 'texinfo-deffn-formatting-property - 'texinfo-format-specialized-defun) -(put 'defvar 'texinfo-deffn-formatting-property - 'texinfo-format-specialized-defun) -(put 'defvarx 'texinfo-deffn-formatting-property - 'texinfo-format-specialized-defun) -(put 'defopt 'texinfo-deffn-formatting-property - 'texinfo-format-specialized-defun) -(put 'defoptx 'texinfo-deffn-formatting-property - 'texinfo-format-specialized-defun) -(defun texinfo-format-specialized-defun (parsed-args) - ;; Specialized function-like or variable-like entity: - ;; @defun name args In Info, `Function: Name ARGS' - ;; @defmac name args In Info, `Macro: Name ARGS' - ;; @defvar name In Info, `Variable: Name' - ;; Use cdr of texinfo-defun-type to determine category: - (let ((category (car (cdr texinfo-defun-type))) - (name (car parsed-args)) - (args (cdr parsed-args))) - (insert " -- " category ": " name) - (while args - (insert " " - (if (= ?& (aref (car args) 0)) - (car args) - (upcase (car args)))) - (setq args (cdr args))))) - -;; @deftypefn, @deftypevr: Generalized typed -(put 'deftypefn 'texinfo-deffn-formatting-property 'texinfo-format-deftypefn) -(put 'deftypefnx 'texinfo-deffn-formatting-property 'texinfo-format-deftypefn) -(put 'deftypevr 'texinfo-deffn-formatting-property 'texinfo-format-deftypefn) -(put 'deftypevrx 'texinfo-deffn-formatting-property 'texinfo-format-deftypefn) -(defun texinfo-format-deftypefn (parsed-args) - ;; Generalized typed-function-like or typed-variable-like entity: - ;; @deftypefn category data-type name args... - ;; In Info, `Category: data-type name args...' - ;; @deftypevr category data-type name - ;; In Info, `Category: data-type name' - ;; Note: args in lower case, unless modified in command line. - (let ((category (car parsed-args)) - (data-type (car (cdr parsed-args))) - (name (car (cdr (cdr parsed-args)))) - (args (cdr (cdr (cdr parsed-args))))) - (insert " -- " category ": " data-type " " name) - (while args - (insert " " (car args)) - (setq args (cdr args))))) - -;; @deftypefun, @deftypevar: Specialized typed -(put 'deftypefun 'texinfo-deffn-formatting-property 'texinfo-format-deftypefun) -(put 'deftypefunx 'texinfo-deffn-formatting-property - 'texinfo-format-deftypefun) -(put 'deftypevar 'texinfo-deffn-formatting-property 'texinfo-format-deftypefun) -(put 'deftypevarx 'texinfo-deffn-formatting-property - 'texinfo-format-deftypefun) -(defun texinfo-format-deftypefun (parsed-args) - ;; Specialized typed-function-like or typed-variable-like entity: - ;; @deftypefun data-type name args... - ;; In Info, `Function: data-type name ARGS' - ;; @deftypevar data-type name - ;; In Info, `Variable: data-type name' - ;; Note: args in lower case, unless modified in command line. - ;; Use cdr of texinfo-defun-type to determine category: - (let ((category (car (cdr texinfo-defun-type))) - (data-type (car parsed-args)) - (name (car (cdr parsed-args))) - (args (cdr (cdr parsed-args)))) - (insert " -- " category ": " data-type " " name) - (while args - (insert " " (car args)) - (setq args (cdr args))))) - -;; @defop: Generalized object-oriented -(put 'defop 'texinfo-deffn-formatting-property 'texinfo-format-defop) -(put 'defopx 'texinfo-deffn-formatting-property 'texinfo-format-defop) -(defun texinfo-format-defop (parsed-args) - ;; Generalized object oriented entity: - ;; @defop category class name args... - ;; In Info, `Category on class: name ARG' - ;; Note: args in upper case; use of `on' - (let ((category (car parsed-args)) - (class (car (cdr parsed-args))) - (name (car (cdr (cdr parsed-args)))) - (args (cdr (cdr (cdr parsed-args))))) - (insert " -- " category " on " class ": " name) - (while args - (insert " " (upcase (car args))) - (setq args (cdr args))))) - -;; @defcv: Generalized object-oriented -(put 'defcv 'texinfo-deffn-formatting-property 'texinfo-format-defcv) -(put 'defcvx 'texinfo-deffn-formatting-property 'texinfo-format-defcv) -(defun texinfo-format-defcv (parsed-args) - ;; Generalized object oriented entity: - ;; @defcv category class name - ;; In Info, `Category of class: name' - ;; Note: args in upper case; use of `of' - (let ((category (car parsed-args)) - (class (car (cdr parsed-args))) - (name (car (cdr (cdr parsed-args)))) - (args (cdr (cdr (cdr parsed-args))))) - (insert " -- " category " of " class ": " name) - (while args - (insert " " (upcase (car args))) - (setq args (cdr args))))) - -;; @defmethod: Specialized object-oriented -(put 'defmethod 'texinfo-deffn-formatting-property 'texinfo-format-defmethod) -(put 'defmethodx 'texinfo-deffn-formatting-property 'texinfo-format-defmethod) -(defun texinfo-format-defmethod (parsed-args) - ;; Specialized object oriented entity: - ;; @defmethod class name args... - ;; In Info, `Method on class: name ARGS' - ;; Note: args in upper case; use of `on' - ;; Use cdr of texinfo-defun-type to determine category: - (let ((category (car (cdr texinfo-defun-type))) - (class (car parsed-args)) - (name (car (cdr parsed-args))) - (args (cdr (cdr parsed-args)))) - (insert " -- " category " on " class ": " name) - (while args - (insert " " (upcase (car args))) - (setq args (cdr args))))) - -;; @defivar: Specialized object-oriented -(put 'defivar 'texinfo-deffn-formatting-property 'texinfo-format-defivar) -(put 'defivarx 'texinfo-deffn-formatting-property 'texinfo-format-defivar) -(defun texinfo-format-defivar (parsed-args) - ;; Specialized object oriented entity: - ;; @defivar class name - ;; In Info, `Instance variable of class: name' - ;; Note: args in upper case; use of `of' - ;; Use cdr of texinfo-defun-type to determine category: - (let ((category (car (cdr texinfo-defun-type))) - (class (car parsed-args)) - (name (car (cdr parsed-args))) - (args (cdr (cdr parsed-args)))) - (insert " -- " category " of " class ": " name) - (while args - (insert " " (upcase (car args))) - (setq args (cdr args))))) - - -;;; Indexing for definitions - -;; An index entry has three parts: the `entry proper', the node name, and the -;; line number. Depending on the which command is used, the entry is -;; formatted differently: -;; -;; @defun, -;; @defmac, -;; @defspec, -;; @defvar, -;; @defopt all use their 1st argument as the entry-proper -;; -;; @deffn, -;; @defvr, -;; @deftp -;; @deftypefun -;; @deftypevar all use their 2nd argument as the entry-proper -;; -;; @deftypefn, -;; @deftypevr both use their 3rd argument as the entry-proper -;; -;; @defmethod uses its 2nd and 1st arguments as an entry-proper -;; formatted: NAME on CLASS - -;; @defop uses its 3rd and 2nd arguments as an entry-proper -;; formatted: NAME on CLASS -;; -;; @defivar uses its 2nd and 1st arguments as an entry-proper -;; formatted: NAME of CLASS -;; -;; @defcv uses its 3rd and 2nd argument as an entry-proper -;; formatted: NAME of CLASS - -(put 'defun 'texinfo-defun-indexing-property 'texinfo-index-defun) -(put 'defunx 'texinfo-defun-indexing-property 'texinfo-index-defun) -(put 'defmac 'texinfo-defun-indexing-property 'texinfo-index-defun) -(put 'defmacx 'texinfo-defun-indexing-property 'texinfo-index-defun) -(put 'defspec 'texinfo-defun-indexing-property 'texinfo-index-defun) -(put 'defspecx 'texinfo-defun-indexing-property 'texinfo-index-defun) -(put 'defvar 'texinfo-defun-indexing-property 'texinfo-index-defun) -(put 'defvarx 'texinfo-defun-indexing-property 'texinfo-index-defun) -(put 'defopt 'texinfo-defun-indexing-property 'texinfo-index-defun) -(put 'defoptx 'texinfo-defun-indexing-property 'texinfo-index-defun) -(defun texinfo-index-defun (parsed-args) - ;; use 1st parsed-arg as entry-proper - ;; `index-list' will be texinfo-findex or the like - (let ((index-list (get texinfo-command-name 'texinfo-defun-index))) - (set index-list - (cons - ;; Three elements: entry-proper, node-name, line-number - (list - (car parsed-args) - texinfo-last-node - ;; Region formatting may not provide last node position. - (if texinfo-last-node-pos - (1+ (count-lines texinfo-last-node-pos (point))) - 1)) - (symbol-value index-list))))) - -(put 'deffn 'texinfo-defun-indexing-property 'texinfo-index-deffn) -(put 'deffnx 'texinfo-defun-indexing-property 'texinfo-index-deffn) -(put 'defvr 'texinfo-defun-indexing-property 'texinfo-index-deffn) -(put 'defvrx 'texinfo-defun-indexing-property 'texinfo-index-deffn) -(put 'deftp 'texinfo-defun-indexing-property 'texinfo-index-deffn) -(put 'deftpx 'texinfo-defun-indexing-property 'texinfo-index-deffn) -(put 'deftypefun 'texinfo-defun-indexing-property 'texinfo-index-deffn) -(put 'deftypefunx 'texinfo-defun-indexing-property 'texinfo-index-deffn) -(put 'deftypevar 'texinfo-defun-indexing-property 'texinfo-index-deffn) -(put 'deftypevarx 'texinfo-defun-indexing-property 'texinfo-index-deffn) -(defun texinfo-index-deffn (parsed-args) - ;; use 2nd parsed-arg as entry-proper - ;; `index-list' will be texinfo-findex or the like - (let ((index-list (get texinfo-command-name 'texinfo-defun-index))) - (set index-list - (cons - ;; Three elements: entry-proper, node-name, line-number - (list - (car (cdr parsed-args)) - texinfo-last-node - ;; Region formatting may not provide last node position. - (if texinfo-last-node-pos - (1+ (count-lines texinfo-last-node-pos (point))) - 1)) - (symbol-value index-list))))) - -(put 'deftypefn 'texinfo-defun-indexing-property 'texinfo-index-deftypefn) -(put 'deftypefnx 'texinfo-defun-indexing-property 'texinfo-index-deftypefn) -(put 'deftypevr 'texinfo-defun-indexing-property 'texinfo-index-deftypefn) -(put 'deftypevrx 'texinfo-defun-indexing-property 'texinfo-index-deftypefn) -(defun texinfo-index-deftypefn (parsed-args) - ;; use 3rd parsed-arg as entry-proper - ;; `index-list' will be texinfo-findex or the like - (let ((index-list (get texinfo-command-name 'texinfo-defun-index))) - (set index-list - (cons - ;; Three elements: entry-proper, node-name, line-number - (list - (car (cdr (cdr parsed-args))) - texinfo-last-node - ;; Region formatting may not provide last node position. - (if texinfo-last-node-pos - (1+ (count-lines texinfo-last-node-pos (point))) - 1)) - (symbol-value index-list))))) - -(put 'defmethod 'texinfo-defun-indexing-property 'texinfo-index-defmethod) -(put 'defmethodx 'texinfo-defun-indexing-property 'texinfo-index-defmethod) -(defun texinfo-index-defmethod (parsed-args) - ;; use 2nd on 1st parsed-arg as entry-proper - ;; `index-list' will be texinfo-findex or the like - (let ((index-list (get texinfo-command-name 'texinfo-defun-index))) - (set index-list - (cons - ;; Three elements: entry-proper, node-name, line-number - (list - (format "%s on %s" - (car (cdr parsed-args)) - (car parsed-args)) - texinfo-last-node - ;; Region formatting may not provide last node position. - (if texinfo-last-node-pos - (1+ (count-lines texinfo-last-node-pos (point))) - 1)) - (symbol-value index-list))))) - -(put 'defop 'texinfo-defun-indexing-property 'texinfo-index-defop) -(put 'defopx 'texinfo-defun-indexing-property 'texinfo-index-defop) -(defun texinfo-index-defop (parsed-args) - ;; use 3rd on 2nd parsed-arg as entry-proper - ;; `index-list' will be texinfo-findex or the like - (let ((index-list (get texinfo-command-name 'texinfo-defun-index))) - (set index-list - (cons - ;; Three elements: entry-proper, node-name, line-number - (list - (format "%s on %s" - (car (cdr (cdr parsed-args))) - (car (cdr parsed-args))) - texinfo-last-node - ;; Region formatting may not provide last node position. - (if texinfo-last-node-pos - (1+ (count-lines texinfo-last-node-pos (point))) - 1)) - (symbol-value index-list))))) - -(put 'defivar 'texinfo-defun-indexing-property 'texinfo-index-defivar) -(put 'defivarx 'texinfo-defun-indexing-property 'texinfo-index-defivar) -(defun texinfo-index-defivar (parsed-args) - ;; use 2nd of 1st parsed-arg as entry-proper - ;; `index-list' will be texinfo-findex or the like - (let ((index-list (get texinfo-command-name 'texinfo-defun-index))) - (set index-list - (cons - ;; Three elements: entry-proper, node-name, line-number - (list - (format "%s of %s" - (car (cdr parsed-args)) - (car parsed-args)) - texinfo-last-node - ;; Region formatting may not provide last node position. - (if texinfo-last-node-pos - (1+ (count-lines texinfo-last-node-pos (point))) - 1)) - (symbol-value index-list))))) - -(put 'defcv 'texinfo-defun-indexing-property 'texinfo-index-defcv) -(put 'defcvx 'texinfo-defun-indexing-property 'texinfo-index-defcv) -(defun texinfo-index-defcv (parsed-args) - ;; use 3rd of 2nd parsed-arg as entry-proper - ;; `index-list' will be texinfo-findex or the like - (let ((index-list (get texinfo-command-name 'texinfo-defun-index))) - (set index-list - (cons - ;; Three elements: entry-proper, node-name, line-number - (list - (format "%s of %s" - (car (cdr (cdr parsed-args))) - (car (cdr parsed-args))) - texinfo-last-node - ;; Region formatting may not provide last node position. - (if texinfo-last-node-pos - (1+ (count-lines texinfo-last-node-pos (point))) - 1)) - (symbol-value index-list))))) - - -;;; Properties for definitions - -;; Each definition command has six properties: -;; -;; 1. texinfo-deffn-formatting-property to format definition line -;; 2. texinfo-defun-indexing-property to create index entry -;; 3. texinfo-format formatting command -;; 4. texinfo-end end formatting command -;; 5. texinfo-defun-type type of deffn to format -;; 6. texinfo-defun-index type of index to use -;; -;; The `x' forms of each definition command are used for the second -;; and subsequent header lines. - -;; The texinfo-deffn-formatting-property and texinfo-defun-indexing-property -;; are listed just before the appropriate formatting and indexing commands. - -(put 'deffn 'texinfo-format 'texinfo-format-defun) -(put 'deffnx 'texinfo-format 'texinfo-format-defunx) -(put 'deffn 'texinfo-end 'texinfo-end-defun) -(put 'deffn 'texinfo-defun-type '(deffn-type nil)) -(put 'deffnx 'texinfo-defun-type '(deffn-type nil)) -(put 'deffn 'texinfo-defun-index 'texinfo-findex) -(put 'deffnx 'texinfo-defun-index 'texinfo-findex) - -(put 'defun 'texinfo-format 'texinfo-format-defun) -(put 'defunx 'texinfo-format 'texinfo-format-defunx) -(put 'defun 'texinfo-end 'texinfo-end-defun) -(put 'defun 'texinfo-defun-type '(defun-type "Function")) -(put 'defunx 'texinfo-defun-type '(defun-type "Function")) -(put 'defun 'texinfo-defun-index 'texinfo-findex) -(put 'defunx 'texinfo-defun-index 'texinfo-findex) - -(put 'defmac 'texinfo-format 'texinfo-format-defun) -(put 'defmacx 'texinfo-format 'texinfo-format-defunx) -(put 'defmac 'texinfo-end 'texinfo-end-defun) -(put 'defmac 'texinfo-defun-type '(defun-type "Macro")) -(put 'defmacx 'texinfo-defun-type '(defun-type "Macro")) -(put 'defmac 'texinfo-defun-index 'texinfo-findex) -(put 'defmacx 'texinfo-defun-index 'texinfo-findex) - -(put 'defspec 'texinfo-format 'texinfo-format-defun) -(put 'defspecx 'texinfo-format 'texinfo-format-defunx) -(put 'defspec 'texinfo-end 'texinfo-end-defun) -(put 'defspec 'texinfo-defun-type '(defun-type "Special form")) -(put 'defspecx 'texinfo-defun-type '(defun-type "Special form")) -(put 'defspec 'texinfo-defun-index 'texinfo-findex) -(put 'defspecx 'texinfo-defun-index 'texinfo-findex) - -(put 'defvr 'texinfo-format 'texinfo-format-defun) -(put 'defvrx 'texinfo-format 'texinfo-format-defunx) -(put 'defvr 'texinfo-end 'texinfo-end-defun) -(put 'defvr 'texinfo-defun-type '(deffn-type nil)) -(put 'defvrx 'texinfo-defun-type '(deffn-type nil)) -(put 'defvr 'texinfo-defun-index 'texinfo-vindex) -(put 'defvrx 'texinfo-defun-index 'texinfo-vindex) - -(put 'defvar 'texinfo-format 'texinfo-format-defun) -(put 'defvarx 'texinfo-format 'texinfo-format-defunx) -(put 'defvar 'texinfo-end 'texinfo-end-defun) -(put 'defvar 'texinfo-defun-type '(defun-type "Variable")) -(put 'defvarx 'texinfo-defun-type '(defun-type "Variable")) -(put 'defvar 'texinfo-defun-index 'texinfo-vindex) -(put 'defvarx 'texinfo-defun-index 'texinfo-vindex) - -(put 'defconst 'texinfo-format 'texinfo-format-defun) -(put 'defconstx 'texinfo-format 'texinfo-format-defunx) -(put 'defconst 'texinfo-end 'texinfo-end-defun) -(put 'defconst 'texinfo-defun-type '(defun-type "Constant")) -(put 'defconstx 'texinfo-defun-type '(defun-type "Constant")) -(put 'defconst 'texinfo-defun-index 'texinfo-vindex) -(put 'defconstx 'texinfo-defun-index 'texinfo-vindex) - -(put 'defcmd 'texinfo-format 'texinfo-format-defun) -(put 'defcmdx 'texinfo-format 'texinfo-format-defunx) -(put 'defcmd 'texinfo-end 'texinfo-end-defun) -(put 'defcmd 'texinfo-defun-type '(defun-type "Command")) -(put 'defcmdx 'texinfo-defun-type '(defun-type "Command")) -(put 'defcmd 'texinfo-defun-index 'texinfo-findex) -(put 'defcmdx 'texinfo-defun-index 'texinfo-findex) - -(put 'defopt 'texinfo-format 'texinfo-format-defun) -(put 'defoptx 'texinfo-format 'texinfo-format-defunx) -(put 'defopt 'texinfo-end 'texinfo-end-defun) -(put 'defopt 'texinfo-defun-type '(defun-type "User Option")) -(put 'defoptx 'texinfo-defun-type '(defun-type "User Option")) -(put 'defopt 'texinfo-defun-index 'texinfo-vindex) -(put 'defoptx 'texinfo-defun-index 'texinfo-vindex) - -(put 'deftp 'texinfo-format 'texinfo-format-defun) -(put 'deftpx 'texinfo-format 'texinfo-format-defunx) -(put 'deftp 'texinfo-end 'texinfo-end-defun) -(put 'deftp 'texinfo-defun-type '(deftp-type nil)) -(put 'deftpx 'texinfo-defun-type '(deftp-type nil)) -(put 'deftp 'texinfo-defun-index 'texinfo-tindex) -(put 'deftpx 'texinfo-defun-index 'texinfo-tindex) - -;;; Object-oriented stuff is a little hairier. - -(put 'defop 'texinfo-format 'texinfo-format-defun) -(put 'defopx 'texinfo-format 'texinfo-format-defunx) -(put 'defop 'texinfo-end 'texinfo-end-defun) -(put 'defop 'texinfo-defun-type '(defop-type nil)) -(put 'defopx 'texinfo-defun-type '(defop-type nil)) -(put 'defop 'texinfo-defun-index 'texinfo-findex) -(put 'defopx 'texinfo-defun-index 'texinfo-findex) - -(put 'defmethod 'texinfo-format 'texinfo-format-defun) -(put 'defmethodx 'texinfo-format 'texinfo-format-defunx) -(put 'defmethod 'texinfo-end 'texinfo-end-defun) -(put 'defmethod 'texinfo-defun-type '(defmethod-type "Method")) -(put 'defmethodx 'texinfo-defun-type '(defmethod-type "Method")) -(put 'defmethod 'texinfo-defun-index 'texinfo-findex) -(put 'defmethodx 'texinfo-defun-index 'texinfo-findex) - -(put 'defcv 'texinfo-format 'texinfo-format-defun) -(put 'defcvx 'texinfo-format 'texinfo-format-defunx) -(put 'defcv 'texinfo-end 'texinfo-end-defun) -(put 'defcv 'texinfo-defun-type '(defop-type nil)) -(put 'defcvx 'texinfo-defun-type '(defop-type nil)) -(put 'defcv 'texinfo-defun-index 'texinfo-vindex) -(put 'defcvx 'texinfo-defun-index 'texinfo-vindex) - -(put 'defivar 'texinfo-format 'texinfo-format-defun) -(put 'defivarx 'texinfo-format 'texinfo-format-defunx) -(put 'defivar 'texinfo-end 'texinfo-end-defun) -(put 'defivar 'texinfo-defun-type '(defmethod-type "Instance variable")) -(put 'defivarx 'texinfo-defun-type '(defmethod-type "Instance variable")) -(put 'defivar 'texinfo-defun-index 'texinfo-vindex) -(put 'defivarx 'texinfo-defun-index 'texinfo-vindex) - -;;; Typed functions and variables - -(put 'deftypefn 'texinfo-format 'texinfo-format-defun) -(put 'deftypefnx 'texinfo-format 'texinfo-format-defunx) -(put 'deftypefn 'texinfo-end 'texinfo-end-defun) -(put 'deftypefn 'texinfo-defun-type '(deftypefn-type nil)) -(put 'deftypefnx 'texinfo-defun-type '(deftypefn-type nil)) -(put 'deftypefn 'texinfo-defun-index 'texinfo-findex) -(put 'deftypefnx 'texinfo-defun-index 'texinfo-findex) - -(put 'deftypefun 'texinfo-format 'texinfo-format-defun) -(put 'deftypefunx 'texinfo-format 'texinfo-format-defunx) -(put 'deftypefun 'texinfo-end 'texinfo-end-defun) -(put 'deftypefun 'texinfo-defun-type '(deftypefun-type "Function")) -(put 'deftypefunx 'texinfo-defun-type '(deftypefun-type "Function")) -(put 'deftypefun 'texinfo-defun-index 'texinfo-findex) -(put 'deftypefunx 'texinfo-defun-index 'texinfo-findex) - -(put 'deftypevr 'texinfo-format 'texinfo-format-defun) -(put 'deftypevrx 'texinfo-format 'texinfo-format-defunx) -(put 'deftypevr 'texinfo-end 'texinfo-end-defun) -(put 'deftypevr 'texinfo-defun-type '(deftypefn-type nil)) -(put 'deftypevrx 'texinfo-defun-type '(deftypefn-type nil)) -(put 'deftypevr 'texinfo-defun-index 'texinfo-vindex) -(put 'deftypevrx 'texinfo-defun-index 'texinfo-vindex) - -(put 'deftypevar 'texinfo-format 'texinfo-format-defun) -(put 'deftypevarx 'texinfo-format 'texinfo-format-defunx) -(put 'deftypevar 'texinfo-end 'texinfo-end-defun) -(put 'deftypevar 'texinfo-defun-type '(deftypevar-type "Variable")) -(put 'deftypevarx 'texinfo-defun-type '(deftypevar-type "Variable")) -(put 'deftypevar 'texinfo-defun-index 'texinfo-vindex) -(put 'deftypevarx 'texinfo-defun-index 'texinfo-vindex) - - -;;; @set, @clear, @ifset, @ifclear - -;; If a flag is set with @set FLAG, then text between @ifset and @end -;; ifset is formatted normally, but if the flag is cleared with -;; @clear FLAG, then the text is not formatted; it is ignored. - -;; If a flag is cleared with @clear FLAG, then text between @ifclear -;; and @end ifclear is formatted normally, but if the flag is set with -;; @set FLAG, then the text is not formatted; it is ignored. @ifclear -;; is the opposite of @ifset. - -;; If a flag is set to a string with @set FLAG, -;; replace @value{FLAG} with the string. -;; If a flag with a value is cleared, -;; @value{FLAG} is invalid, -;; as if there had never been any @set FLAG previously. - -(put 'clear 'texinfo-format 'texinfo-clear) -(defun texinfo-clear () - "Clear the value of the flag." - (let* ((arg (texinfo-parse-arg-discard)) - (flag (car (read-from-string arg))) - ;; (value (substring arg (cdr (read-from-string arg)))) - ) - (put flag 'texinfo-whether-setp 'flag-cleared) - (put flag 'texinfo-set-value ""))) - -(put 'set 'texinfo-format 'texinfo-set) -(defun texinfo-set () - "Set the value of the flag, optionally to a string. -The command `@set foo This is a string.' -sets flag foo to the value: `This is a string.' -The command `@value{foo}' expands to the value." - (let* ((arg (texinfo-parse-arg-discard)) - (flag (car (read-from-string arg))) - (value (substring arg (cdr (read-from-string arg))))) - (if (string-match "^[ \t]+" value) - (setq value (substring value (match-end 0)))) - (put flag 'texinfo-whether-setp 'flag-set) - (put flag 'texinfo-set-value value))) - -(put 'value 'texinfo-format 'texinfo-value) -(defun texinfo-value () - "Insert the string to which the flag is set. -The command `@set foo This is a string.' -sets flag foo to the value: `This is a string.' -The command `@value{foo}' expands to the value." - (let ((arg (texinfo-parse-arg-discard))) - (cond ((and - (eq (get (car (read-from-string arg)) 'texinfo-whether-setp) - 'flag-set) - (get (car (read-from-string arg)) 'texinfo-set-value)) - (insert (get (car (read-from-string arg)) 'texinfo-set-value))) - ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp) - 'flag-cleared) - (insert (format "{No value for \"%s\"}" arg))) - ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp) nil) - (insert (format "{No value for \"%s\"}" arg)))))) - -(put 'ifset 'texinfo-end 'texinfo-discard-command) -(put 'ifset 'texinfo-format 'texinfo-if-set) -(defun texinfo-if-set () - "If set, continue formatting; else do not format region up to @end ifset." - (let ((arg (texinfo-parse-arg-discard))) - (cond - ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp) - 'flag-set) - ;; Format the text (i.e., do not remove it); do nothing here. - ()) - ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp) - 'flag-cleared) - ;; Clear region (i.e., cause the text to be ignored). - (delete-region texinfo-command-start - (re-search-forward "@end ifset[ \t]*\n"))) - ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp) - nil) - ;; In this case flag is neither set nor cleared. - ;; Act as if set, i.e. do nothing. - ())))) - -(put 'ifclear 'texinfo-end 'texinfo-discard-command) -(put 'ifclear 'texinfo-format 'texinfo-if-clear) -(defun texinfo-if-clear () - "If clear, continue formatting; if set, do not format up to @end ifset." - (let ((arg (texinfo-parse-arg-discard))) - (cond - ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp) - 'flag-set) - ;; Clear region (i.e., cause the text to be ignored). - (delete-region texinfo-command-start - (re-search-forward "@end ifclear[ \t]*\n"))) - ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp) - 'flag-cleared) - ;; Format the text (i.e., do not remove it); do nothing here. - ()) - ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp) - nil) - ;; In this case flag is neither set nor cleared. - ;; Act as if clear, i.e. do nothing. - ())))) - -;;; @ifeq - -(put 'ifeq 'texinfo-format 'texinfo-format-ifeq) -(defun texinfo-format-ifeq () - "If ARG1 and ARG2 caselessly string compare to same string, perform COMMAND. -Otherwise produces no output. - -Thus: - @ifeq{ arg1 , arg1 , @code{foo}} bar - - ==> `foo' bar. -but - @ifeq{ arg1 , arg2 , @code{foo}} bar - - ==> bar - -Note that the Texinfo command and its arguments must be arguments to -the @ifeq command." - ;; compare-buffer-substrings does not exist in version 18; don't use - (goto-char texinfo-command-end) - (let* ((case-fold-search t) - (stop (save-excursion (forward-sexp 1) (point))) - start ;; end - ;; @ifeq{arg1, arg2, @command{optional-args}} - (arg1 - (progn - (forward-char 1) - (skip-chars-forward " ") - (setq start (point)) - (search-forward "," stop t) - (skip-chars-backward ", ") - (buffer-substring-no-properties start (point)))) - (arg2 - (progn - (search-forward "," stop t) - (skip-chars-forward " ") - (setq start (point)) - (search-forward "," stop t) - (skip-chars-backward ", ") - (buffer-substring-no-properties start (point)))) - (texinfo-command - (progn - (search-forward "," stop t) - (skip-chars-forward " ") - (setq start (point)) - (goto-char (1- stop)) - (skip-chars-backward " ") - (buffer-substring-no-properties start (point))))) - (delete-region texinfo-command-start stop) - (if (equal arg1 arg2) - (insert texinfo-command)) - (goto-char texinfo-command-start))) - - -;;; Process included files: `@include' command - -;; Updated 19 October 1990 -;; In the original version, include files were ignored by Info but -;; incorporated in to the printed manual. To make references to the -;; included file, the Texinfo source file has to refer to the included -;; files using the `(filename)nodename' format for referring to other -;; Info files. Also, the included files had to be formatted on their -;; own. It was just like they were another file. - -;; Currently, include files are inserted into the buffer that is -;; formatted for Info. If large, the resulting info file is split and -;; tagified. For current include files to work, the master menu must -;; refer to all the nodes, and the highest level nodes in the include -;; files must have the correct next, prev, and up pointers. - -;; The included file may have an @setfilename and even an @settitle, -;; but not an `\input texinfo' line. - -;; Updated 24 March 1993 -;; In order for @raisesections and @lowersections to work, included -;; files must be inserted into the buffer holding the outer file -;; before other Info formatting takes place. So @include is no longer -;; is treated like other @-commands. -(put 'include 'texinfo-format 'texinfo-format-noop) - -;; Original definition: -;; (defun texinfo-format-include () -;; (let ((filename (texinfo-parse-arg-discard)) -;; (default-directory input-directory) -;; subindex) -;; (setq subindex -;; (save-excursion -;; (progn (find-file -;; (cond ((file-readable-p (concat filename ".texinfo")) -;; (concat filename ".texinfo")) -;; ((file-readable-p (concat filename ".texi")) -;; (concat filename ".texi")) -;; ((file-readable-p (concat filename ".tex")) -;; (concat filename ".tex")) -;; ((file-readable-p filename) -;; filename) -;; (t (error "@include'd file %s not found" -;; filename)))) -;; (texinfo-format-buffer-1)))) -;; (texinfo-subindex 'texinfo-vindex (car subindex) (nth 1 subindex)) -;; (texinfo-subindex 'texinfo-findex (car subindex) (nth 2 subindex)) -;; (texinfo-subindex 'texinfo-cindex (car subindex) (nth 3 subindex)) -;; (texinfo-subindex 'texinfo-pindex (car subindex) (nth 4 subindex)) -;; (texinfo-subindex 'texinfo-tindex (car subindex) (nth 5 subindex)) -;; (texinfo-subindex 'texinfo-kindex (car subindex) (nth 6 subindex)))) -;; -;;(defun texinfo-subindex (indexvar file content) -;; (set indexvar (cons (list 'recurse file content) -;; (symbol-value indexvar)))) - -;; Second definition: -;; (put 'include 'texinfo-format 'texinfo-format-include) -;; (defun texinfo-format-include () -;; (let ((filename (concat input-directory -;; (texinfo-parse-arg-discard))) -;; (default-directory input-directory)) -;; (message "Reading: %s" filename) -;; (save-excursion -;; (save-restriction -;; (narrow-to-region -;; (point) -;; (+ (point) (car (cdr (insert-file-contents filename))))) -;; (goto-char (point-min)) -;; (texinfo-append-refill) -;; (texinfo-format-convert (point-min) (point-max)))) -;; (setq last-input-buffer input-buffer) ; to bypass setfilename -;; )) - - -;;; Numerous commands do nothing in Info -;; These commands are defined in texinfo.tex for printed output. - - -;;; various noops, such as @b{foo}, that take arguments in braces - -(put 'b 'texinfo-format 'texinfo-format-noop) -(put 'i 'texinfo-format 'texinfo-format-noop) -(put 'r 'texinfo-format 'texinfo-format-noop) -(put 't 'texinfo-format 'texinfo-format-noop) -(put 'w 'texinfo-format 'texinfo-format-noop) -(put 'asis 'texinfo-format 'texinfo-format-noop) -(put 'dmn 'texinfo-format 'texinfo-format-noop) -(put 'math 'texinfo-format 'texinfo-format-noop) -(put 'titlefont 'texinfo-format 'texinfo-format-noop) -(defun texinfo-format-noop () - (insert (texinfo-parse-arg-discard)) - (goto-char texinfo-command-start)) - -;; @hyphenation command discards an argument within braces -(put 'hyphenation 'texinfo-format 'texinfo-discard-command-and-arg) -(defun texinfo-discard-command-and-arg () - "Discard both @-command and its argument in braces." - (goto-char texinfo-command-end) - (forward-list 1) - (setq texinfo-command-end (point)) - (delete-region texinfo-command-start texinfo-command-end)) - - -;;; Do nothing commands, such as @smallbook, that have no args and no braces -;; These must appear on a line of their own - -(put 'bye 'texinfo-format 'texinfo-discard-line) -(put 'smallbook 'texinfo-format 'texinfo-discard-line) -(put 'finalout 'texinfo-format 'texinfo-discard-line) -(put 'overfullrule 'texinfo-format 'texinfo-discard-line) -(put 'smallbreak 'texinfo-format 'texinfo-discard-line) -(put 'medbreak 'texinfo-format 'texinfo-discard-line) -(put 'bigbreak 'texinfo-format 'texinfo-discard-line) -(put 'afourpaper 'texinfo-format 'texinfo-discard-line) -(put 'afivepaper 'texinfo-format 'texinfo-discard-line) -(put 'afourlatex 'texinfo-format 'texinfo-discard-line) -(put 'afourwide 'texinfo-format 'texinfo-discard-line) - - -;;; These noop commands discard the rest of the line. - -(put 'c 'texinfo-format 'texinfo-discard-line-with-args) -(put 'comment 'texinfo-format 'texinfo-discard-line-with-args) -(put 'contents 'texinfo-format 'texinfo-discard-line-with-args) -(put 'group 'texinfo-end 'texinfo-discard-line-with-args) -(put 'group 'texinfo-format 'texinfo-discard-line-with-args) -(put 'headings 'texinfo-format 'texinfo-discard-line-with-args) -(put 'setchapterstyle 'texinfo-format 'texinfo-discard-line-with-args) -(put 'hsize 'texinfo-format 'texinfo-discard-line-with-args) -(put 'itemindent 'texinfo-format 'texinfo-discard-line-with-args) -(put 'lispnarrowing 'texinfo-format 'texinfo-discard-line-with-args) -(put 'need 'texinfo-format 'texinfo-discard-line-with-args) -(put 'nopara 'texinfo-format 'texinfo-discard-line-with-args) - -;; @novalidate suppresses cross-reference checking and auxiliary file -;; creation with TeX. The Info-validate command checks that every -;; node pointer points to an existing node. Since this Info command -;; is not invoked automatically, the @novalidate command is irrelevant -;; and not supported by texinfmt.el -(put 'novalidate 'texinfo-format 'texinfo-discard-line-with-args) - -(put 'page 'texinfo-format 'texinfo-discard-line-with-args) -(put 'pagesizes 'texinfo-format 'texinfo-discard-line-with-args) -(put 'parindent 'texinfo-format 'texinfo-discard-line-with-args) -(put 'setchapternewpage 'texinfo-format 'texinfo-discard-line-with-args) -(put 'setq 'texinfo-format 'texinfo-discard-line-with-args) - -(put 'setcontentsaftertitlepage - 'texinfo-format 'texinfo-discard-line-with-args) -(put 'setshortcontentsaftertitlepage - 'texinfo-format 'texinfo-discard-line-with-args) - -(put 'settitle 'texinfo-format 'texinfo-discard-line-with-args) -(put 'setx 'texinfo-format 'texinfo-discard-line-with-args) -(put 'shortcontents 'texinfo-format 'texinfo-discard-line-with-args) -(put 'shorttitlepage 'texinfo-format 'texinfo-discard-line-with-args) -(put 'summarycontents 'texinfo-format 'texinfo-discard-line-with-args) -(put 'input 'texinfo-format 'texinfo-discard-line-with-args) - -(put 'documentlanguage 'texinfo-format 'texinfo-discard-line-with-args) -(put 'documentencoding 'texinfo-format 'texinfo-discard-line-with-args) - - - -;;; Some commands cannot be handled - -(defun texinfo-unsupported () - (error "%s is not handled by texinfo" - (buffer-substring-no-properties texinfo-command-start texinfo-command-end))) - -;;; Batch formatting - -(defun batch-texinfo-format () - "Run `texinfo-format-buffer' on the files remaining on the command line. -Must be used only with -batch, and kills Emacs on completion. -Each file will be processed even if an error occurred previously. -For example, invoke - \"emacs -batch -l texinfmt -f batch-texinfo-format $docs/ ~/*.texinfo\"." - (if (not noninteractive) - (error "batch-texinfo-format may only be used -batch")) - (let ((version-control t) - (auto-save-default nil) - (find-file-run-dired nil) - (kept-old-versions 259259) - (kept-new-versions 259259)) - (let ((error 0) - file - (files ())) - (while command-line-args-left - (setq file (expand-file-name (car command-line-args-left))) - (cond ((not (file-exists-p file)) - (message ">> %s does not exist!" file) - (setq error 1 - command-line-args-left (cdr command-line-args-left))) - ((file-directory-p file) - (setq command-line-args-left - (nconc (directory-files file) - (cdr command-line-args-left)))) - (t - (push file files) - (setq command-line-args-left (cdr command-line-args-left))))) - (while files - (setq file (car files) - files (cdr files)) - (condition-case err - (progn - (if buffer-file-name (kill-buffer (current-buffer))) - (find-file file) - (buffer-disable-undo (current-buffer)) - (set-buffer-modified-p nil) - (texinfo-mode) - (message "texinfo formatting %s..." file) - (texinfo-format-buffer nil) - (if (buffer-modified-p) - (progn (message "Saving modified %s" (buffer-file-name)) - (save-buffer)))) - (error - (message ">> Error: %s" (prin1-to-string err)) - (message ">> point at") - (let ((s (buffer-substring-no-properties (point) - (min (+ (point) 100) - (point-max)))) - (tem 0)) - (while (setq tem (string-match "\n+" s tem)) - (setq s (concat (substring s 0 (match-beginning 0)) - "\n>> " - (substring s (match-end 0))) - tem (1+ tem))) - (message ">> %s" s)) - (setq error 1)))) - (kill-emacs error)))) - -(provide 'texinfmt) - -;;; texinfmt.el ends here diff --git a/lisp/textmodes/texinfo.el b/lisp/textmodes/texinfo.el deleted file mode 100644 index c15b06009a5..00000000000 --- a/lisp/textmodes/texinfo.el +++ /dev/null @@ -1,1069 +0,0 @@ -;;; texinfo.el --- major mode for editing Texinfo files -*- lexical-binding: t; -*- - -;; Copyright (C) 1985, 1988-1993, 1996-1997, 2000-2025 Free Software -;; Foundation, Inc. - -;; Author: Robert J. Chassell -;; Maintainer: emacs-devel@gnu.org -;; Keywords: maint, tex, docs - -;; 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 . - -;;; Todo: - -;; - facemenu support. -;; - command completion. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl-lib) - (require 'flymake) - (require 'rx)) -(declare-function flymake-diag-region "flymake" - (buffer line &optional col)) -(declare-function flymake-make-diagnostic "flymake" - ( locus beg end type text - &optional data overlay-properties)) -(declare-function flymake--log-1 "flymake" (level sublog msg &rest args)) - -(eval-when-compile (require 'tex-mode)) -(declare-function tex-buffer "tex-mode" ()) -(declare-function tex-region "tex-mode" (beg end)) -(declare-function tex-send-command "tex-mode") -(declare-function tex-recenter-output-buffer "tex-mode" (linenum)) -(declare-function tex-print "tex-mode" (&optional alt)) -(declare-function tex-view "tex-mode" ()) -(declare-function tex-shell-running "tex-mode" ()) -(declare-function tex-kill-job "tex-mode" ()) - -(defvar outline-heading-alist) - -(defvar skeleton-end-newline) - -(defgroup texinfo nil - "Texinfo Mode." - :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces) - :group 'docs) - -;;;###autoload -(defcustom texinfo-open-quote "``" - "String inserted by typing \\[texinfo-insert-quote] to open a quotation." - :type 'string) - -;;;###autoload -(defcustom texinfo-close-quote "''" - "String inserted by typing \\[texinfo-insert-quote] to close a quotation." - :type 'string) - -(defcustom texinfo-mode-hook nil - "Normal hook run when entering Texinfo mode." - :type 'hook - :options '(turn-on-auto-fill flyspell-mode)) - - -;;; Autoloads: - -(autoload 'kill-compilation - "compile" - "Kill the process made by the \\[compile] command." - t nil) - -(require 'texinfo-loaddefs) - - -;;; Code: - -;;; Don't you dare insert any `require' calls at top level in this file--rms. - -(defvar texinfo-section-list - '(("top" 1) - ("chapter" 2) - ("section" 3) - ("subsection" 4) - ("subsubsection" 5) - ("unnumbered" 2) - ("unnumberedsec" 3) - ("unnumberedsubsec" 4) - ("unnumberedsubsubsec" 5) - ("appendix" 2) - ("appendixsec" 3) - ("appendixsection" 3) - ("appendixsubsec" 4) - ("appendixsubsubsec" 5) - ("majorheading" 2) - ("chapheading" 2) - ("heading" 3) - ("subheading" 4) - ("subsubheading" 5)) - "Alist of sectioning commands and their relative level.") - -;;; Syntax table - -(defvar texinfo-mode-syntax-table - (let ((st (make-syntax-table))) - (modify-syntax-entry ?\" "." st) - (modify-syntax-entry ?\\ "." st) - (modify-syntax-entry ?@ "\\" st) - (modify-syntax-entry ?\^q "\\" st) - (modify-syntax-entry ?\[ "(]" st) - (modify-syntax-entry ?\] ")[" st) - (modify-syntax-entry ?{ "(}" st) - (modify-syntax-entry ?} "){" st) - (modify-syntax-entry ?\n ">" st) - (modify-syntax-entry ?\' "w" st) - st)) - -;; Written by Wolfgang Bangerth -;; To override this example, set either `imenu-generic-expression' -;; or `imenu-create-index-function'. -(defvar texinfo-imenu-generic-expression - '((nil "^@\\(node\\|anchor\\)[ \t]+\\([^,\n]*\\)" 2) - ("Chapters" "^@chapter[ \t]+\\(.*\\)$" 1)) - "Imenu generic expression for Texinfo mode. See `imenu-generic-expression'.") - -(defconst texinfo-syntax-propertize-function - (syntax-propertize-rules - ("\\(@\\)c\\(omment\\)?\\>" (1 "<")) - ("^\\(@\\)ignore\\>" (1 "< b")) - ("^@end ignore\\(\n\\)" (1 "> b"))) - "Syntactic keywords to catch comment delimiters in `texinfo-mode'.") - -(defconst texinfo-environments - '("cartouche" "copying" "defcv" "deffn" "defivar" "defmac" - "defmethod" "defop" "defopt" "defspec" "deftp" "deftypecv" - "deftypefn" "deftypefun" "deftypeivar" "deftypemethod" - "deftypeop" "deftypevar" "deftypevr" "defun" "defvar" - "defvr" "description" "detailmenu" "direntry" "display" - "documentdescription" "enumerate" "example" "flushleft" - "flushright" "format" "ftable" "group" "html" "ifclear" "ifset" - "ifhtml" "ifinfo" "ifnothtml" "ifnotinfo" "ifnotplaintext" - "ifnottex" "ifplaintext" "iftex" "ignore" "itemize" "lisp" - "macro" "menu" "multitable" "quotation" "smalldisplay" - "smallexample" "smallformat" "smalllisp" "table" "tex" - "titlepage" "verbatim" "vtable") - "List of Texinfo environments.") - -(defconst texinfo-environment-regexp - (concat "^@" (regexp-opt (cons "end" texinfo-environments) t) "\\>") - "Regexp for environment-like Texinfo list commands. -Subexpression 1 is what goes into the corresponding `@end' statement.") - -(defface texinfo-heading - '((t (:inherit font-lock-function-name-face))) - "Face used for section headings in `texinfo-mode'.") - -(defvar texinfo-font-lock-keywords - `(;; All but the first had an OVERRIDE of t. - ;; It didn't seem to be any better, and it's slower--simon. - ;; Robert J. Chassell says remove this line. - ;;("\\$\\([^$]*\\)\\$" 1 font-lock-string-face t) - ("@\\([a-zA-Z]+\\|[^ \t\n]\\)" 1 font-lock-keyword-face) ;commands - ("^\\*\\([^\n:]*\\)" 1 font-lock-function-name-face t) ;menu items - ("@\\(emph\\|i\\|sc\\){\\([^}]+\\)" 2 'italic) - ("@\\(strong\\|b\\){\\([^}]+\\)" 2 'bold) - ("@\\(kbd\\|key\\|url\\|uref\\){\\([^}]+\\)" 2 font-lock-string-face) - ;; The following two groups have an OVERRIDE of `keep' because - ;; their arguments frequently include a @@, and we don't want that - ;; to overwrite the normal fontification of the argument. - ("@\\(file\\|email\\){\\([^}]+\\)" 2 font-lock-string-face keep) - ("@\\(samp\\|code\\|var\\|env\\|command\\|option\\){\\([^}]+\\)" - 2 font-lock-variable-name-face keep) - ;; @math allows nested braces like @math{2^{12}} - ("@math{\\([^{}]*{?[^{}]*}?[^{}]*\\)}" 1 font-lock-variable-name-face) - ("@\\(cite\\|x?ref\\|pxref\\|dfn\\|inforef\\){\\([^}]+\\)" - 2 font-lock-constant-face) - ("@\\(anchor\\){\\([^}]+\\)" 2 font-lock-type-face) - ("@\\(dmn\\|acronym\\|value\\){\\([^}]+\\)" 2 font-lock-builtin-face) - ("@\\(end\\|itemx?\\) +\\(.+\\)" 2 font-lock-keyword-face keep) - (,(concat "^@" (regexp-opt (mapcar #'car texinfo-section-list) t) - ".*\n") - 0 'texinfo-heading t)) - "Additional expressions to highlight in Texinfo mode.") - - -;;; Keybindings - -;;; Keys common both to Texinfo mode and to TeX shell. - -(declare-function tex-show-print-queue "tex-mode" ()) - -(defun texinfo-define-common-keys (keymap) - "Define the keys both in Texinfo mode and in the texinfo-tex-shell." - (define-key keymap "\C-c\C-t\C-k" #'tex-kill-job) - (define-key keymap "\C-c\C-t\C-x" #'texinfo-quit-job) - (define-key keymap "\C-c\C-t\C-l" #'tex-recenter-output-buffer) - (define-key keymap "\C-c\C-t\C-d" #'texinfo-delete-from-print-queue) - (define-key keymap "\C-c\C-t\C-q" #'tex-show-print-queue) - (define-key keymap "\C-c\C-t\C-p" #'texinfo-tex-print) - (define-key keymap "\C-c\C-t\C-v" #'texinfo-tex-view) - (define-key keymap "\C-c\C-t\C-i" #'texinfo-texindex) - - (define-key keymap "\C-c\C-t\C-r" #'texinfo-tex-region) - (define-key keymap "\C-c\C-t\C-b" #'texinfo-tex-buffer)) - -(defvar texinfo-mode-map - (let ((map (make-sparse-keymap))) - - ;; bindings for `texnfo-tex.el' - (texinfo-define-common-keys map) - - (define-key map "\"" #'texinfo-insert-quote) - - ;; bindings for `makeinfo.el' - (define-key map "\C-c\C-m\C-k" #'kill-compilation) - (define-key map "\C-c\C-m\C-l" - #'makeinfo-recenter-compilation-buffer) - (define-key map "\C-c\C-m\C-r" #'makeinfo-region) - (define-key map "\C-c\C-m\C-b" #'makeinfo-buffer) - - ;; bindings for `texinfmt.el' - (define-key map "\C-c\C-e\C-r" #'texinfo-format-region) - (define-key map "\C-c\C-e\C-b" #'texinfo-format-buffer) - - ;; AUCTeX-like bindings - (define-key map "\e\r" #'texinfo-insert-@item) - - ;; bindings for updating nodes and menus - - (define-key map "\C-c\C-um" #'texinfo-master-menu) - - (define-key map "\C-c\C-u\C-m" #'texinfo-make-menu) - (define-key map "\C-c\C-u\C-n" #'texinfo-update-node) - (define-key map "\C-c\C-u\C-e" #'texinfo-every-node-update) - (define-key map "\C-c\C-u\C-a" #'texinfo-all-menus-update) - - (define-key map "\C-c\C-s" #'texinfo-show-structure) - - (define-key map "\C-c}" #'up-list) - ;; FIXME: This is often used for "close block" aka texinfo-insert-@end. - (define-key map "\C-c]" #'up-list) - (define-key map "\C-c/" #'texinfo-insert-@end) - (define-key map "\C-c{" #'texinfo-insert-braces) - - ;; bindings for inserting strings - (define-key map "\C-c\C-o" #'texinfo-insert-block) - (define-key map "\C-c\C-c\C-d" #'texinfo-start-menu-description) - (define-key map "\C-c\C-c\C-s" #'texinfo-insert-@strong) - (define-key map "\C-c\C-c\C-e" #'texinfo-insert-@emph) - - (define-key map "\C-c\C-cv" #'texinfo-insert-@var) - (define-key map "\C-c\C-cu" #'texinfo-insert-@uref) - (define-key map "\C-c\C-ct" #'texinfo-insert-@table) - (define-key map "\C-c\C-cs" #'texinfo-insert-@samp) - (define-key map "\C-c\C-cr" #'texinfo-insert-dwim-@ref) - (define-key map "\C-c\C-cq" #'texinfo-insert-@quotation) - (define-key map "\C-c\C-co" #'texinfo-insert-@noindent) - (define-key map "\C-c\C-cn" #'texinfo-insert-@node) - (define-key map "\C-c\C-cm" #'texinfo-insert-@email) - (define-key map "\C-c\C-ck" #'texinfo-insert-@kbd) - (define-key map "\C-c\C-ci" #'texinfo-insert-@item) - (define-key map "\C-c\C-cf" #'texinfo-insert-@file) - (define-key map "\C-c\C-cx" #'texinfo-insert-@example) - (define-key map "\C-c\C-ce" #'texinfo-insert-@end) - (define-key map "\C-c\C-cd" #'texinfo-insert-@dfn) - (define-key map "\C-c\C-cc" #'texinfo-insert-@code) - - ;; bindings for environment movement - (define-key map "\C-c." #'texinfo-to-environment-bounds) - (define-key map "\C-c\C-c\C-f" #'texinfo-next-environment-end) - (define-key map "\C-c\C-c\C-b" #'texinfo-previous-environment-end) - (define-key map "\C-c\C-c\C-n" #'texinfo-next-environment-start) - (define-key map "\C-c\C-c\C-p" #'texinfo-previous-environment-start) - map)) - -(easy-menu-define texinfo-mode-menu - texinfo-mode-map - "Menu used for `texinfo-mode'." - '("Texinfo" - ["Insert block" texinfo-insert-block t] - ;; ["Insert node" texinfo-insert-@node t] - "----" - ["Update All" (lambda () (interactive) (texinfo-master-menu t)) - :keys "\\[universal-argument] \\[texinfo-master-menu]"] - ["Update every node" texinfo-every-node-update t] - ["Update node" texinfo-update-node t] - ["Make Master menu" texinfo-master-menu t] - ["Make menu" texinfo-make-menu t] - ["Update all menus" texinfo-all-menus-update t] - "----" - ["Show structure" texinfo-show-structure t] - ["Format region" texinfo-format-region t] - ["Format buffer" texinfo-format-buffer t] - ["Makeinfo region" makeinfo-region t] - ["Makeinfo buffer" makeinfo-buffer t])) - - -(defun texinfo-filter (section list) - (let (res) - (dolist (x list) (if (eq section (cadr x)) (push (car x) res))) - res)) - -(defvar texinfo-chapter-level-regexp - (regexp-opt (texinfo-filter 2 texinfo-section-list)) - "Regular expression matching just the Texinfo chapter level headings.") - -(defun texinfo-current-defun-name () - "Return the name of the Texinfo node at point, or nil." - (save-excursion - (if (re-search-backward "^@node[ \t]+\\([^,\n]+\\)" nil t) - (match-string-no-properties 1)))) - -;;; Flymake support -(defvar-local texinfo--flymake-proc nil) -(defun texinfo-flymake (report-fn &rest _) - "Texinfo checking for Flymake. - -It uses either \"makeinfo\" or \"texi2any\", in that order. - -REPORT-FN is the callback function." - (let ((executable (or (executable-find "makeinfo") - (executable-find "texi2any"))) - (source (current-buffer))) - - (unless executable - (error "Flymake for Texinfo requires `makeinfo' or `texi2any'")) - - (when (process-live-p texinfo--flymake-proc) - (kill-process texinfo--flymake-proc)) - - (save-restriction - (widen) - (setq texinfo--flymake-proc - (make-process - :name "texinfo-flymake" - :noquery t - :connection-type 'pipe - :buffer (generate-new-buffer " *texinfo-flymake*") - :command `(,executable "-o" ,null-device "-") - :sentinel - (lambda (proc _event) - (when (memq (process-status proc) '(exit signal)) - (unwind-protect - (if (eq (buffer-local-value 'texinfo--flymake-proc - source) - proc) - (with-current-buffer (process-buffer proc) - (goto-char (point-min)) - (cl-loop - while (search-forward-regexp - (rx line-start - "-:" - (group-n 1 (0+ digit)) ; Line - (optional ":" (group-n 2 (0+ digit))) ; col - ": " - (optional (group-n 3 "warning: ")) ; warn - (group-n 4 (0+ nonl)) ; Message - line-end) - nil t) - for msg = (match-string 4) - for (beg . end) = (flymake-diag-region - source - (string-to-number (match-string 1))) - for type = (if (match-string 3) - :warning - :error) - collect (flymake-make-diagnostic - source beg end type msg) - into diags - finally (funcall report-fn diags)))) - (kill-buffer (process-buffer proc))))))) - (process-send-region texinfo--flymake-proc (point-min) (point-max)) - (process-send-eof texinfo--flymake-proc)))) - - -;;; Texinfo mode - -(defvar fill-paragraph-separate nil) - -;;;###autoload -(define-derived-mode texinfo-mode text-mode "Texinfo" - "Major mode for editing Texinfo files. - - It has these extra commands: -\\{texinfo-mode-map} - - These are files that are used as input for TeX to make printed manuals -and also to be turned into Info files with \\[makeinfo-buffer] or -the `makeinfo' program. These files must be written in a very restricted and -modified version of TeX input format. - - Editing commands are like `text-mode' except that the syntax table is -set up so expression commands skip Texinfo bracket groups. To see -what the Info version of a region of the Texinfo file will look like, -use \\[makeinfo-region], which runs `makeinfo' on the current region. - - You can show the structure of a Texinfo file with \\[texinfo-show-structure]. -This command shows the structure of a Texinfo file by listing the -lines with the @-sign commands for @chapter, @section, and the like. -These lines are displayed in another window called the *Occur* window. -In that window, you can position the cursor over one of the lines and -use \\[occur-mode-goto-occurrence], to jump to the corresponding spot -in the Texinfo file. - - In addition, Texinfo mode provides commands that insert various -frequently used @-sign commands into the buffer. You can use these -commands to save keystrokes. And you can insert balanced braces with -\\[texinfo-insert-braces] and later use the command \\[up-list] to -move forward past the closing brace. - -Also, Texinfo mode provides functions for automatically creating or -updating menus and node pointers. These functions - - * insert the `Next', `Previous' and `Up' pointers of a node, - * insert or update the menu for a section, and - * create a master menu for a Texinfo source file. - -Here are the functions: - - `texinfo-update-node' \\[texinfo-update-node] - `texinfo-every-node-update' \\[texinfo-every-node-update] - `texinfo-sequential-node-update' - - `texinfo-make-menu' \\[texinfo-make-menu] - `texinfo-all-menus-update' \\[texinfo-all-menus-update] - `texinfo-master-menu' - - `texinfo-indent-menu-description' (column &optional region-p) - -The `texinfo-column-for-description' variable specifies the column to -which menu descriptions are indented. - -Passed an argument (a prefix argument, if interactive), the -`texinfo-update-node' and `texinfo-make-menu' functions do their jobs -in the region. - -To use the updating commands, you must structure your Texinfo file -hierarchically, such that each `@node' line, with the exception of the -Top node, is accompanied by some kind of section line, such as an -`@chapter' or `@section' line. - -If the file has a `top' node, it must be called `top' or `Top' and -be the first node in the file. - -Entering Texinfo mode calls the value of `text-mode-hook', and then the -value of `texinfo-mode-hook'." - (setq-local page-delimiter - (concat "^@node [ \t]*[Tt]op\\|^@\\(" - texinfo-chapter-level-regexp - "\\)\\>")) - (setq-local require-final-newline mode-require-final-newline) - (setq-local indent-tabs-mode nil) - ;; This is used in 'texinfo--fill-paragraph'. - (setq-local fill-paragraph-separate (default-value 'paragraph-separate)) - (setq-local paragraph-separate - (concat "@[a-zA-Z]*[ \n]\\|" paragraph-separate)) - (setq-local paragraph-start (concat "@[a-zA-Z]*[ \n]\\|" - paragraph-start)) - (setq-local fill-paragraph-function 'texinfo--fill-paragraph) - (setq-local sentence-end-base "\\(@\\(end\\)?dots{}\\|[.?!]\\)[]\"'”)}]*") - (setq-local fill-column 70) - (setq-local beginning-of-defun-function #'texinfo--beginning-of-defun) - (setq-local end-of-defun-function #'texinfo--end-of-defun) - (setq-local comment-start "@c ") - (setq-local comment-start-skip "@c +\\|@comment +") - (setq-local words-include-escapes t) - (setq-local imenu-generic-expression texinfo-imenu-generic-expression) - (setq imenu-case-fold-search nil) - (setq font-lock-defaults - '(texinfo-font-lock-keywords nil nil nil backward-paragraph)) - (setq-local syntax-propertize-function texinfo-syntax-propertize-function) - (setq-local add-log-current-defun-function #'texinfo-current-defun-name) - - ;; Outline settings. - (setq-local outline-heading-alist - ;; We should merge `outline-heading-alist' and - ;; `texinfo-section-list'. But in the mean time, let's - ;; just generate one from the other. - (mapcar (lambda (x) (cons (concat "@" (car x)) (cadr x))) - texinfo-section-list)) - (setq-local outline-regexp - (concat (regexp-opt (mapcar #'car outline-heading-alist) t) - "\\>")) - - (setq-local tex-start-of-header "%\\*\\*start") - (setq-local tex-end-of-header "%\\*\\*end") - (setq-local tex-first-line-header-regexp "^\\\\input") - (setq-local tex-trailer "@bye\n") - - ;; Prevent skeleton.el from adding a newline to each inserted - ;; skeleton. Those which do want a newline do that explicitly in - ;; their define-skeleton form. - (setq-local skeleton-end-newline nil) - - ;; Prevent filling certain lines, in addition to ones specified by - ;; the user. - (setq-local auto-fill-inhibit-regexp - (let ((prevent-filling "^@\\(def\\|multitable\\)")) - (if (null auto-fill-inhibit-regexp) - prevent-filling - (concat auto-fill-inhibit-regexp "\\|" prevent-filling)))) - - ;; Set up Flymake support. - (add-hook 'flymake-diagnostic-functions #'texinfo-flymake nil t)) - -(defvar texinfo-fillable-commands '("@noindent") - "A list of commands that can be filled.") - -(defun texinfo--fill-paragraph (justify) - "Function to fill a paragraph in `texinfo-mode'." - (let ((command-re "\\(@[a-zA-Z]+\\)[ \t\n]") - ;; Kludge alert: we override paragraph-separate here because - ;; that is needed for filling @noindent and similar lines. - ;; The default Texinfo-specific paragraph-separate value, - ;; OTOH, is needed for auto-fill-mode, which doesn't call - ;; mode-specific functions. - (paragraph-separate fill-paragraph-separate)) - (catch 'no-fill - (save-restriction - ;; First check whether we're on a command line that can be - ;; filled by itself. - (or - (save-excursion - (beginning-of-line) - (when (looking-at command-re) - (let ((command (match-string 1))) - (if (member command texinfo-fillable-commands) - (progn - (narrow-to-region (point) (progn (forward-line 1) (point))) - t) - (throw 'no-fill nil))))) - ;; We're not on such a line, so fill the region. - (save-excursion - (let ((regexp (concat command-re "\\|^[ \t]*$\\|\f"))) - (narrow-to-region - (if (re-search-backward regexp nil t) - (progn - (forward-line 1) - (point)) - (point-min)) - (if (re-search-forward regexp nil t) - (match-beginning 0) - (point-max))) - (goto-char (point-min))))) - ;; We've now narrowed to the region we want to fill. - (let ((fill-paragraph-function nil) - (adaptive-fill-mode nil)) - (fill-paragraph justify)))) - t)) - -(defun texinfo--beginning-of-defun (&optional arg) - "Go to the previous @node line." - (while (and (> arg 0) - (re-search-backward "^@node " nil t)) - (setq arg (1- arg)))) - -(defun texinfo--end-of-defun () - "Go to the start of the next @node line." - (when (looking-at-p "@node") - (forward-line)) - (if (re-search-forward "^@node " nil t) - (goto-char (match-beginning 0)) - (goto-char (point-max)))) - - -;;; Insert string commands - -(defvar texinfo-block-default "example") - -(define-skeleton texinfo-insert-block - "Create a matching pair @ .. @end at point. -Puts point on a blank line between them." - (setq texinfo-block-default - (completing-read (format "Block name [%s]: " texinfo-block-default) - texinfo-environments - nil nil nil nil texinfo-block-default)) - \n "@" str - ;; Blocks that take parameters: all the def* blocks take parameters, - ;; plus a few others. - (if (or (string-match "\\`def" str) - (member str '("table" "ftable" "vtable"))) - '(nil " " -)) - \n _ \n "@end " str \n \n) - -(defun texinfo-inside-macro-p (macro &optional bound) - "Non-nil if inside a macro matching the regexp MACRO." - (condition-case nil - (save-excursion - (save-restriction - (narrow-to-region bound (point)) - (while (progn - (up-list -1) - (not (condition-case nil - (save-excursion - (backward-sexp 1) - (looking-at macro)) - (scan-error nil))))) - t)) - (scan-error nil))) - -(defun texinfo-inside-env-p (env &optional bound) - "Non-nil if inside an environment matching the regexp @ENV." - (save-excursion - (and (re-search-backward (concat "@\\(end\\s +\\)?" env) bound t) - (not (match-end 1))))) - -(defvar texinfo-enable-quote-macros "@\\(code\\|samp\\|kbd\\)\\>") -(defvar texinfo-enable-quote-envs - '("example\\>" "smallexample\\>" "lisp\\>")) -(defun texinfo-insert-quote (&optional arg) - "Insert the appropriate quote mark for Texinfo. -Usually inserts the value of `texinfo-open-quote' (normally \\=`\\=`) or -`texinfo-close-quote' (normally \\='\\='), depending on the context. -With prefix argument or inside @code or @example, inserts a plain \"." - (interactive "*P") - (let ((top (or (save-excursion (re-search-backward "@node\\>" nil t)) - (point-min)))) - (if (or arg - (= (preceding-char) ?\\) - (save-excursion - ;; Might be near the start of a (narrowed) buffer. - (ignore-errors (backward-char (length texinfo-open-quote))) - (when (or (looking-at texinfo-open-quote) - (looking-at texinfo-close-quote)) - (delete-char (length texinfo-open-quote)) - t)) - (texinfo-inside-macro-p texinfo-enable-quote-macros top) - (let ((in-env nil)) - (dolist (env texinfo-enable-quote-envs in-env) - (if (texinfo-inside-env-p env top) - (setq in-env t))))) - (self-insert-command (prefix-numeric-value arg)) - (insert - (if (or (bobp) - (memq (char-syntax (preceding-char)) '(?\( ?> ?\s))) - texinfo-open-quote - texinfo-close-quote))))) - -;; The following texinfo-insert-@end command not only inserts a SPC -;; after the @end, but tries to find out what belongs there. It is -;; not very smart: it does not understand nested lists. - -(defun texinfo-last-unended-begin () - (while (and (re-search-backward texinfo-environment-regexp) - (looking-at "@end")) - (texinfo-last-unended-begin))) - -(defun texinfo-next-unmatched-end () - (while (and (re-search-forward texinfo-environment-regexp) - (save-excursion - (goto-char (match-beginning 0)) - (not (looking-at "@end")))) - (texinfo-next-unmatched-end))) - -(define-skeleton texinfo-insert-@end - "Insert the matching `@end' for the last Texinfo command that needs one." - (ignore-errors - (save-excursion - (backward-word-strictly 1) - (texinfo-last-unended-begin) - (or (match-string 1) '-))) - \n "@end " str \n \n) - -(define-skeleton texinfo-insert-braces - "Make a pair of braces and be poised to type inside of them. -Use \\[up-list] to move forward out of the braces." - nil - "{" _ "}") - -(define-skeleton texinfo-insert-@code - "Insert a `@code{...}' command in a Texinfo buffer. -A numeric argument says how many words the braces should surround. -The default is not to surround any existing words with the braces." - nil - "@code{" _ "}") - -(define-skeleton texinfo-insert-@dfn - "Insert a `@dfn{...}' command in a Texinfo buffer. -A numeric argument says how many words the braces should surround. -The default is not to surround any existing words with the braces." - nil - "@dfn{" _ "}") - -(define-skeleton texinfo-insert-@email - "Insert a `@email{...}' command in a Texinfo buffer. -A numeric argument says how many words the braces should surround. -The default is not to surround any existing words with the braces." - nil - "@email{" _ "}") - -(define-skeleton texinfo-insert-@emph - "Insert a `@emph{...}' command in a Texinfo buffer. -A numeric argument says how many words the braces should surround. -The default is not to surround any existing words with the braces." - nil - "@emph{" _ "}") - -(define-skeleton texinfo-insert-@example - "Insert the string `@example' in a Texinfo buffer." - nil - \n "@example" \n \n) - -(define-skeleton texinfo-insert-@file - "Insert a `@file{...}' command in a Texinfo buffer. -A numeric argument says how many words the braces should surround. -The default is not to surround any existing words with the braces." - nil - "@file{" _ "}") - -(define-skeleton texinfo-insert-@item - "Insert the string `@item' in a Texinfo buffer. -If in a table defined by @table, follow said string with a space. -Otherwise, follow with a newline." - nil - \n "@item" - (if (equal (ignore-errors - (save-excursion - (texinfo-last-unended-begin) - (match-string 1))) - "table") - " " '\n) - _ \n) - -(define-skeleton texinfo-insert-@kbd - "Insert a `@kbd{...}' command in a Texinfo buffer. -A numeric argument says how many words the braces should surround. -The default is not to surround any existing words with the braces." - nil - "@kbd{" _ "}") - -(define-skeleton texinfo-insert-@node - "Insert the string `@node' in a Texinfo buffer. -Insert a comment on the following line indicating the order of -arguments to @node. Insert a carriage return after the comment line. -Leave point after `@node'." - nil - \n "@node " _ \n) - -(define-skeleton texinfo-insert-@noindent - "Insert the string `@noindent' in a Texinfo buffer." - nil - \n "@noindent" \n) - -(define-skeleton texinfo-insert-@quotation - "Insert the string `@quotation' in a Texinfo buffer." - \n "@quotation" \n _ \n) - -(define-skeleton texinfo-insert-dwim-@ref - "Insert appropriate `@pxref{...}', `@xref{}', or `@ref{}' command. - -Looks at text around point to decide what to insert; an unclosed -preceding open parenthesis results in '@pxref{}', point at the -beginning of a sentence or at (point-min) yields '@xref{}', any -other location (including inside a word), will result in '@ref{}' -at the nearest previous whitespace or beginning-of-line. A -numeric argument says how many words the braces should surround. -The default is not to surround any existing words with the -braces." - nil - (cond - ;; parenthesis - ((looking-back "([^)]*" (line-beginning-position 0)) - "@pxref{") - ;; beginning of sentence or buffer - ((or (looking-back (sentence-end) (line-beginning-position 0)) - (= (point) (point-min))) - "@xref{") - ;; bol or eol - ((looking-at "^\\|$") - "@ref{") - ;; inside word - ((not (eq (char-syntax (char-after)) ? )) - (skip-syntax-backward "^ " (line-beginning-position)) - "@ref{") - ;; everything else - (t - "@ref{")) - _ "}") - -(define-skeleton texinfo-insert-@samp - "Insert a `@samp{...}' command in a Texinfo buffer. -A numeric argument says how many words the braces should surround. -The default is not to surround any existing words with the braces." - nil - "@samp{" _ "}") - -(define-skeleton texinfo-insert-@strong - "Insert a `@strong{...}' command in a Texinfo buffer. -A numeric argument says how many words the braces should surround. -The default is not to surround any existing words with the braces." - nil - "@strong{" _ "}") - -(define-skeleton texinfo-insert-@table - "Insert the string `@table' in a Texinfo buffer." - nil - \n "@table " _ \n) - -(define-skeleton texinfo-insert-@var - "Insert a `@var{}' command in a Texinfo buffer. -A numeric argument says how many words the braces should surround. -The default is not to surround any existing words with the braces." - nil - "@var{" _ "}") - -(define-skeleton texinfo-insert-@uref - "Insert a `@uref{}' command in a Texinfo buffer. -A numeric argument says how many words the braces should surround. -The default is not to surround any existing words with the braces." - nil - "@uref{" _ "}") -(defalias 'texinfo-insert-@url #'texinfo-insert-@uref) - -;;; Texinfo file structure - -(defun texinfo-show-structure (&optional nodes-too) - "Show the structure of a Texinfo file. -List the lines in the file that begin with the @-sign commands for -@chapter, @section, and the like. - -With optional argument (prefix if interactive), list both the lines -with @-sign commands for @chapter, @section, and the like, and list -@node lines. - -Lines with structuring commands beginning in them are displayed in -another buffer named `*Occur*'. In that buffer, you can move point to -one of those lines and then use -\\\\[occur-mode-goto-occurrence], -to jump to the corresponding spot in the Texinfo source file." - - (interactive "P") - ;; First, remember current location - (let (current-location) - (save-excursion - (end-of-line) ; so as to find section on current line - (if (re-search-backward - ;; do not require `texinfo-section-types-regexp' in texnfo-upd.el - "^@\\(chapter \\|sect\\|subs\\|subh\\|unnum\\|major\\|chapheading \\|heading \\|appendix\\)" - nil t) - (setq current-location - (progn - (beginning-of-line) - (buffer-substring (point) (progn (end-of-line) (point))))) - ;; else point is located before any section command. - (setq current-location "tex"))) - ;; Second, create and format an *Occur* buffer - (save-excursion - (goto-char (point-min)) - (occur (concat "^\\(?:" (if nodes-too "@node\\>\\|") - outline-regexp "\\)"))) - (pop-to-buffer "*Occur*") - (goto-char (point-min)) - (let ((inhibit-read-only t)) - (flush-lines "-----") - ;; Now format the "*Occur*" buffer to show the structure. - ;; Thanks to ceder@signum.se (Per Cederqvist) - (goto-char (point-max)) - (let (level) - (while (re-search-backward "^ *[0-9]*:@\\(\\sw+\\)" nil 0) - (goto-char (1- (match-beginning 1))) - (setq level - (or (cadr (assoc (match-string 1) texinfo-section-list)) 2)) - (indent-to-column (+ (current-column) (* 4 (- level 2)))) - (beginning-of-line)))) - ;; Third, go to line corresponding to location in source file - ;; potential bug: two exactly similar `current-location' lines ... - (goto-char (point-min)) - (re-search-forward current-location nil t) - (beginning-of-line) - )) - - -;;; The tex and print function definitions: - -(defcustom texinfo-texi2dvi-command "texi2dvi" - "Command used by `texinfo-tex-buffer' to run TeX and texindex on a buffer." - :type 'string) - -(defcustom texinfo-texi2dvi-options "" - "Command line options for `texinfo-texi2dvi-command'." - :type 'string - :version "28.1") - -(defcustom texinfo-tex-command "tex" - "Command used by `texinfo-tex-region' to run TeX on a region." - :type 'string) - -(defcustom texinfo-texindex-command "texindex" - "Command used by `texinfo-texindex' to sort unsorted index files." - :type 'string) - -(defcustom texinfo-delete-from-print-queue-command "lprm" - "Command string used to delete a job from the line printer queue. -Command is used by \\[texinfo-delete-from-print-queue] based on -number provided by a previous \\[tex-show-print-queue] -command." - :type 'string) - -(defvar texinfo-tex-trailer "@bye" - "String appended after a region sent to TeX by `texinfo-tex-region'.") - -(defun texinfo-tex-region (beg end) - "Run TeX on the current region. -This works by writing a temporary file (`tex-zap-file') in the directory -that is the value of `tex-directory', then running TeX on that file. - -The first line of the buffer is copied to the -temporary file; and if the buffer has a header, it is written to the -temporary file before the region itself. The buffer's header is all lines -between the strings defined by `tex-start-of-header' and `tex-end-of-header' -inclusive. The header must start in the first 100 lines. - -The value of `texinfo-tex-trailer' is appended to the temporary -file after the region." - (interactive "r") - (require 'tex-mode) - (let ((tex-command texinfo-tex-command) - (tex-trailer texinfo-tex-trailer)) - (tex-region beg end))) - -(defun texinfo-tex-buffer () - "Run TeX on visited file, once or twice, to make a correct `.dvi' file." - (interactive) - (require 'tex-mode) - (let ((tex-command texinfo-texi2dvi-command) - (tex-start-options texinfo-texi2dvi-options) - ;; Disable tex-start-commands. texi2dvi would not understand - ;; anything specified here. - (tex-start-commands "")) - (tex-buffer))) - -(defun texinfo-texindex () - "Run `texindex' on unsorted index files. -The index files are made by \\[texinfo-tex-region] or \\[texinfo-tex-buffer]. -This runs the shell command defined by `texinfo-texindex-command'." - (interactive) - (require 'tex-mode) - (tex-send-command texinfo-texindex-command (concat tex-zap-file ".??")) - ;; alternatively - ;; (send-string "tex-shell" - ;; (concat texinfo-texindex-command - ;; " " tex-zap-file ".??" "\n")) - (tex-recenter-output-buffer nil)) - -(defun texinfo-tex-print () - "Print `.dvi' file made by \\[texinfo-tex-region] or \\[texinfo-tex-buffer]. -This runs the shell command defined by `tex-dvi-print-command'." - (interactive) - (require 'tex-mode) - (tex-print)) - -(defun texinfo-tex-view () - "View `.dvi' file made by \\[texinfo-tex-region] or \\[texinfo-tex-buffer]. -This runs the shell command defined by `tex-dvi-view-command'." - (interactive) - (require 'tex-mode) - (tex-view)) - -(defun texinfo-quit-job () - "Quit currently running TeX job, by sending an `x' to it." - (interactive) - (if (not (get-process "tex-shell")) - (error "No TeX shell running")) - (tex-send-command "x")) -;; alternatively: -;; save-excursion -;; (set-buffer (get-buffer "*tex-shell*")) -;; (goto-char (point-max)) -;; (insert "x") -;; (comint-send-input) - -(defun texinfo-delete-from-print-queue (job-number) - "Delete job from the line printer spooling queue. -You are prompted for the job number (use a number shown by a previous -\\[tex-show-print-queue] command)." - (interactive "nPrinter job number for deletion: ") - (require 'tex-mode) - (if (tex-shell-running) - (tex-kill-job) - (tex-start-shell)) - (tex-send-command texinfo-delete-from-print-queue-command job-number) - ;; alternatively - ;; (send-string "tex-shell" - ;; (concat - ;; texinfo-delete-from-print-queue-command - ;; " " - ;; job-number"\n")) - (tex-recenter-output-buffer nil)) - -(defun texinfo-to-environment-bounds () - "Move point alternately to the start and end of a Texinfo environment. -Do nothing when outside of an environment. This command does not -handle nested environments." - (interactive) - (cond ((save-excursion - (forward-line 0) - (looking-at texinfo-environment-regexp)) - (if (save-excursion - (forward-line 0) - (looking-at "^@end")) - (texinfo-previous-environment-start) - (texinfo-next-environment-end))) - ((save-excursion - (and (re-search-backward texinfo-environment-regexp nil t) - (not (looking-at "^@end")))) - (texinfo-previous-environment-start)) - ;; Otherwise, point is outside of an environment, so do nothing. - )) - -(defun texinfo-next-environment-start () - "Move forward to the beginning of a Texinfo environment." - (interactive) - (if (looking-at texinfo-environment-regexp) - (forward-line 1)) - (while (and (re-search-forward texinfo-environment-regexp nil t) - (save-excursion - (goto-char (match-beginning 0)) - (looking-at "@end")))) - (if (save-excursion - (forward-line 0) - (looking-at texinfo-environment-regexp)) - (forward-line 0))) - -(defun texinfo-previous-environment-start () - "Move back to the beginning of the previous Texinfo environment." - (interactive) - (while (and (re-search-backward texinfo-environment-regexp nil t) - (save-excursion - (goto-char (match-beginning 0)) - (looking-at "@end"))))) - -(defun texinfo-next-environment-end () - "Move forward to the beginning of the next @end line of an environment." - (interactive) - (if (looking-at "^@end") - (forward-line 1)) - (while (and (re-search-forward texinfo-environment-regexp nil t) - (save-excursion - (goto-char (match-beginning 0)) - (not (looking-at "^@end"))))) - (if (save-excursion - (forward-line 0) - (looking-at "^@end")) - (forward-line 0))) - -(defun texinfo-previous-environment-end () - "Move backward to the beginning of the next @end line of an environment." - (interactive) - (while (and (re-search-backward texinfo-environment-regexp nil t) - (save-excursion - (goto-char (match-beginning 0)) - (not (looking-at "@end")))))) - -(provide 'texinfo) - -;;; texinfo.el ends here diff --git a/lisp/textmodes/texnfo-upd.el b/lisp/textmodes/texnfo-upd.el deleted file mode 100644 index 51505faa03d..00000000000 --- a/lisp/textmodes/texnfo-upd.el +++ /dev/null @@ -1,2131 +0,0 @@ -;;; texnfo-upd.el --- utilities for updating nodes and menus in Texinfo files -*- lexical-binding: t; -*- - -;; Copyright (C) 1989-1992, 2001-2025 Free Software Foundation, Inc. - -;; Author: Robert J. Chassell -;; Maintainer: emacs-devel@gnu.org -;; Keywords: maint, tex, docs - -;; 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 . - -;;; Commentary: - -;; Known bug: update commands fail to ignore @ignore, and fail to DTRT -;; with the @if... directives (so expect trouble when the manual uses -;; different @node lines or @menu items in @iftex and in @ifnottex). - -;; Summary: how to use the updating commands - -;; The node and menu updating functions automatically - -;; * insert missing `@node' lines, -;; * insert the `Next', `Previous' and `Up' pointers of a node, -;; * insert or update the menu for a section, -;; * create a master menu for a Texinfo source file. -;; -;; With a prefix argument, the `texinfo-update-node' and -;; `texinfo-make-menu' functions do their jobs in the region. -;; -;; Important note: We do NOT recommend use of these commands to update -;; the `Next', `Previous' and `Up' pointers on @node lines. Most -;; manuals, including those whose Texinfo files adhere to the structure -;; described below, don't need these pointers, because makeinfo will -;; generate them automatically (see the node "makeinfo Pointer -;; Creation" in the Texinfo manual). By contrast, due to known bugs -;; described above, texinfo-update-node etc. could produce incorrect -;; pointers, and thus make a perfectly valid Texinfo file into an -;; invalid one. You _have_ been warned! -;; -;; In brief, the functions for creating or updating nodes and menus, are: -;; -;; texinfo-update-node (&optional beginning end) -;; texinfo-every-node-update () -;; texinfo-sequential-node-update (&optional region-p) -;; -;; texinfo-make-menu (&optional beginning end) -;; texinfo-all-menus-update () -;; texinfo-master-menu () -;; -;; texinfo-insert-node-lines (&optional title-p) -;; -;; texinfo-indent-menu-description (column &optional region-p) - -;; The `texinfo-column-for-description' variable specifies the column to -;; which menu descriptions are indented. - -;; Texinfo file structure -;; ---------------------- - -;; To use the updating commands, you must structure your Texinfo file -;; hierarchically. Each `@node' line, with the exception of the top -;; node, must be accompanied by some kind of section line, such as an -;; `@chapter' or `@section' line. Each node-line/section-line -;; combination must look like this: - -;; @node Lists and Tables, Cross References, Structuring, Top -;; @comment node-name, next, previous, up -;; @chapter Making Lists and Tables - -;; or like this (without the `@comment' line): - -;; @node Lists and Tables, Cross References, Structuring, Top -;; @chapter Making Lists and Tables - -;; If the file has a `top' node, it must be called `top' or `Top' and -;; be the first node in the file. - - -;;; The update node functions described in detail - -;; The `texinfo-update-node' command with no prefix argument inserts -;; the correct next, previous and up pointers for the node in which -;; point is located (i.e., for the node preceding point). - -;; With prefix argument, the `texinfo-update-node' function inserts the -;; correct next, previous and up pointers for the nodes inside the -;; region. - -;; It does not matter whether the `@node' line has pre-existing -;; `Next', `Previous', or `Up' pointers in it. They are removed. - -;; Warning: Since the pre-existing pointers are replaced with the ones -;; computed by `texinfo-update-node', and since this function has -;; known bugs with the more advanced Texinfo features (see above), it -;; could produce an invalid Texinfo file. You are well advised not to -;; use this function, except if you know what you are doing and -;; exercise extreme caution. Keep in mind that most manuals do not -;; need the `Next', `Previous', and `Up' pointers to be present on the -;; @node lines; makeinfo will automatically generate them when it -;; produces the Info or HTML versions of the manual. - -;; The `texinfo-every-node-update' function runs `texinfo-update-node' -;; on the whole buffer. - -;; The `texinfo-sequential-node-update' function inserts the -;; immediately following and preceding node into the `Next' or -;; `Previous' pointers regardless of their hierarchical level. This is -;; only useful for certain kinds of text, like a novel, which you go -;; through sequentially. - - -;;; The menu making functions described in detail - -;; The `texinfo-make-menu' function without an argument creates or -;; updates a menu for the section encompassing the node that follows -;; point. With an argument, it makes or updates menus for the nodes -;; within or part of the marked region. - -;; Whenever an existing menu is updated, the descriptions from -;; that menu are incorporated into the new menu. This is done by copying -;; descriptions from the existing menu to the entries in the new menu -;; that have the same node names. If the node names are different, the -;; descriptions are not copied to the new menu. - -;; Menu entries that refer to other Info files are removed since they -;; are not a node within current buffer. This is a deficiency. - -;; The `texinfo-all-menus-update' function runs `texinfo-make-menu' -;; on the whole buffer. - -;; The `texinfo-master-menu' function creates an extended menu located -;; after the top node. (The file must have a top node.) This -;; function works only on Texinfo files all of whose menus are -;; present in a single file; use `texinfo-multiple-files-update' for -;; multi-file manuals. The function constructs a master menu that -;; includes every entry from every other menu. Use this command to -;; create or update the @detailmenu menu after you've created or -;; updated all the menus in the file, including the menu in the Top -;; node, using the `texinfo-make-menu' or the `texinfo-all-menus-update' -;; command. - -;; The `texinfo-indent-menu-description' function indents every -;; description in the menu following point, to the specified column. -;; Non-nil argument (prefix, if interactive) means indent every -;; description in every menu in the region. This function does not -;; indent second and subsequent lines of a multi-line description. - -;; The `texinfo-insert-node-lines' function inserts `@node' before the -;; `@chapter', `@section', and such like lines of a region in a Texinfo -;; file where the `@node' lines are missing. -;; -;; With a non-nil argument (prefix, if interactive), the function not -;; only inserts `@node' lines but also inserts the chapter or section -;; titles as the names of the corresponding nodes; and inserts titles -;; as node names in pre-existing `@node' lines that lack names. -;; -;; Since node names should be more concise than section or chapter -;; titles, you will usually want to manually edit node names so inserted. - - -;;; Code: - -(require 'texinfo) - - -(defvar texinfo-master-menu-header - " --- The Detailed Node Listing ---\n" - "String inserted before lower level entries in Texinfo master menu. -It comes after the chapter-level menu entries.") - -;; We used to look for just sub, but that found @subtitle. -(defvar texinfo-section-types-regexp - "^@\\(chapter \\|sect\\|subs\\|subh\\|unnum\\|major\\|chapheading \\|heading \\|appendix\\)" - "Regexp matching chapter, section, other headings (but not the top node).") - -(defvar texinfo-section-level-regexp - (regexp-opt (texinfo-filter 3 texinfo-section-list)) - "Regular expression matching just the Texinfo section level headings.") - -(defvar texinfo-subsection-level-regexp - (regexp-opt (texinfo-filter 4 texinfo-section-list)) - "Regular expression matching just the Texinfo subsection level headings.") - -(defvar texinfo-subsubsection-level-regexp - (regexp-opt (texinfo-filter 5 texinfo-section-list)) - "Regular expression matching just the Texinfo subsubsection level headings.") - -(defvar texinfo-update-menu-same-level-regexps - '((1 . "top[ \t]+") - (2 . (concat "\\(^@\\)\\(" texinfo-chapter-level-regexp "\\)\\>[ \t]*")) - (3 . (concat "\\(^@\\)\\(" texinfo-section-level-regexp "\\)\\>[ \t]*")) - (4 . (concat "\\(^@\\)\\(" texinfo-subsection-level-regexp "\\)\\>[ \t]+")) - (5 . (concat "\\(^@\\)\\(" texinfo-subsubsection-level-regexp "\\)\\>[ \t]+"))) - "Regexps for searching for same level sections in a Texinfo file. -The keys are strings specifying the general hierarchical level in the -document; the values are regular expressions.") - -(defvar texinfo-update-menu-higher-regexps - '((1 . "^@node [ \t]*DIR") - (2 . "^@node [ \t]*top[ \t]*\\(,\\|$\\)") - (3 . - (concat - "\\(^@\\(" - texinfo-chapter-level-regexp - "\\)\\>[ \t]*\\)")) - (4 . - (concat - "\\(^@\\(" - texinfo-section-level-regexp - "\\|" - texinfo-chapter-level-regexp - "\\)\\>[ \t]*\\)")) - (5 . - (concat - "\\(^@\\(" - texinfo-subsection-level-regexp - "\\|" - texinfo-section-level-regexp - "\\|" - texinfo-chapter-level-regexp - "\\)\\>[ \t]*\\)"))) - "Regexps for searching for higher level sections in a Texinfo file. -The keys are strings specifying the general hierarchical level in the -document; the values are regular expressions.") - -(defvar texinfo-update-menu-lower-regexps - '((1 . - (concat - "\\(^@\\(" - texinfo-chapter-level-regexp - "\\|" - texinfo-section-level-regexp - "\\|" - texinfo-subsection-level-regexp - "\\|" - texinfo-subsubsection-level-regexp - "\\)\\>[ \t]*\\)")) - (2 . - (concat - "\\(^@\\(" - texinfo-section-level-regexp - "\\|" - texinfo-subsection-level-regexp - "\\|" - texinfo-subsubsection-level-regexp - "\\)\\>[ \t]*\\)")) - (3 . - (concat - "\\(^@\\(" - texinfo-subsection-level-regexp - "\\|" - texinfo-subsubsection-level-regexp - "\\)\\>[ \t]+\\)")) - (4 . - (concat - "\\(^@\\(" - texinfo-subsubsection-level-regexp - "\\)\\>[ \t]+\\)")) - ;; There's nothing below 5, use a bogus regexp that can't match. - (5 . "a\\(^\\)")) - "Regexps for searching for lower level sections in a Texinfo file. -The keys are strings specifying the general hierarchical level in the -document; the values are regular expressions.") - - -;;;###autoload -(defun texinfo-make-menu (&optional beginning end) - "Without any prefix argument, make or update a menu. -Make the menu for the section enclosing the node found following point. - -A prefix argument means make or update menus -for nodes within or part of the marked region. - -Whenever a menu exists, and is being updated, the descriptions that -are associated with node names in the pre-existing menu are -incorporated into the new menu. - -Leaves trailing whitespace in a menu that lacks descriptions, so -descriptions will format well. In general, a menu should contain -descriptions, because node names and section titles are often too -short to explain a node well." - - (interactive - (if prefix-arg - (list (point) (mark)))) - (if (null beginning) - (let ((level (texinfo-hierarchic-level))) - (texinfo-make-one-menu level) - (message "Menu updated")) - ;; else - (message "Making or updating menus in %s... " (buffer-name)) - (save-excursion - (goto-char (min beginning end)) - ;; find section type following point - (let ((level (texinfo-hierarchic-level)) - (region-end-marker (make-marker))) - (set-marker region-end-marker (max beginning end)) - (save-restriction - (widen) - - (while (texinfo-find-lower-level-node - level (marker-position region-end-marker)) - (setq level (texinfo-hierarchic-level)) ; new, lower level - (texinfo-make-one-menu level)) - - (while (and (< (point) (marker-position region-end-marker)) - (texinfo-find-higher-level-node - level (marker-position region-end-marker))) - (setq level (texinfo-hierarchic-level)) - ;; Don't allow texinfo-find-higher-level-node - ;; to find the same node again. - (forward-line 1) - (while (texinfo-find-lower-level-node - level (marker-position region-end-marker)) - (setq level (texinfo-hierarchic-level)) ; new, lower level - (texinfo-make-one-menu level)))))) - (message "Making or updating menus in %s...done" (buffer-name)))) - -(defun texinfo-make-one-menu (level) - "Make a menu of all the appropriate nodes in this section. -`Appropriate nodes' are those associated with sections that are -at the level specified by LEVEL. Point is left at the end of menu." - (let* - ((case-fold-search t) - (beginning - (save-excursion - (goto-char (texinfo-update-menu-region-beginning level)) - (end-of-line) - (point))) - (end (texinfo-update-menu-region-end level)) - (first (texinfo-menu-first-node beginning end)) - (node-name (progn - (goto-char beginning) - (beginning-of-line) - (texinfo-copy-node-name))) - (new-menu-list (texinfo-make-menu-list beginning end level))) - (when (texinfo-old-menu-p beginning first) - (texinfo-incorporate-descriptions new-menu-list) - (texinfo-incorporate-menu-entry-names new-menu-list) - (texinfo-delete-old-menu beginning first)) - (texinfo-insert-menu new-menu-list node-name))) - -;;;###autoload -(defun texinfo-all-menus-update (&optional update-all-nodes-p) - "Update every regular menu in a Texinfo file. -Update pre-existing master menu, if there is one. - -Only single-file manuals are supported by this function. For -multi-file manuals, use `texinfo-multiple-files-update'. - -If called with a non-nil argument, this function first updates all the -nodes in the buffer before updating the menus. Do NOT invoke this -command with an argument if your Texinfo file uses @node lines without -the `Next', `Previous', and `Up' pointers! - -Indents the first line of descriptions, and leaves trailing whitespace -in a menu that lacks descriptions, so descriptions will format well. -In general, a menu should contain descriptions, because node names and -section titles are often too short to explain a node well." - (interactive "P") - (let ((case-fold-search t) - master-menu-p) - (save-excursion - (push-mark (point-max) t) - (goto-char (point-min)) - (message "Checking for a master menu in %s ... "(buffer-name)) - (save-excursion - (when (search-forward texinfo-master-menu-header nil t) - ;; Check if @detailmenu kludge is used; - ;; if so, leave point before @detailmenu. - (search-backward "\n@detailmenu" (line-beginning-position -2) t) - ;; Remove detailed master menu listing - (setq master-menu-p t) - (goto-char (match-beginning 0)) - (let ((end-of-detailed-menu-descriptions - (save-excursion ; beginning of end menu line - (goto-char (texinfo-menu-end)) - (beginning-of-line) (forward-char -1) - (point)))) - (delete-region (point) end-of-detailed-menu-descriptions)))) - - (when update-all-nodes-p - (message "Updating all nodes in %s ... " (buffer-name)) - (texinfo-update-node (point-min) (point-max))) - - (message "Updating all menus in %s ... " (buffer-name)) - (texinfo-make-menu (point-max) (point-min)) - - (when master-menu-p - (message "Updating the master menu in %s... " (buffer-name)) - (texinfo-master-menu nil))) - - (message "Done...updated all the menus. You may save the buffer."))) - -(defun texinfo-find-lower-level-node (level region-end) - "Search forward from point for node at any level lower than LEVEL. -Search is limited to the end of the marked region, REGION-END, -and to the end of the menu region for the level. - -Return t if the node is found, else nil. Leave point at the beginning -of the node if one is found; else do not move point." - (let ((case-fold-search t)) - (when (and (< (point) region-end) - (re-search-forward - (concat - "\\(^@node\\).*\n" ; match node line - "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any - "\\|" ; or - "\\(^@ifinfo[ ]*\n\\)" ; ifinfo line, if any - "\\|" ; or - "\\(^@ifnottex[ ]*\n\\)" ; ifnottex line, if any - "\\)?" ; end of expression - (eval (cdr (assoc level texinfo-update-menu-lower-regexps)) t)) - ;; the next higher level node marks the end of this - ;; section, and no lower level node will be found beyond - ;; this position even if region-end is farther off - (texinfo-update-menu-region-end level) - t)) - (goto-char (match-beginning 1)) - t))) - -(defun texinfo-find-higher-level-node (level region-end) - "Search forward from point for node at any higher level than argument LEVEL. -Search is limited to the end of the marked region, REGION-END. - -Return t if the node is found, else nil. Leave point at the beginning -of the node if one is found; else do not move point. - -A `@node' line starting at point does count as a match; -if the match is found there, the value is t and point does not move." - - (let ((case-fold-search t)) - (cond - ((< level 3) - (if (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" region-end t) - (progn (beginning-of-line) t))) - (t - (when (re-search-forward - (concat - "\\(^@node\\).*\n" ; match node line - "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any - "\\|" ; or - "\\(^@ifinfo[ ]*\n\\)" ; ifinfo line, if any - "\\|" ; or - "\\(^@ifnottex[ ]*\n\\)" ; ifnottex line, if any - "\\)?" ; end of expression - (eval (cdr (assoc level texinfo-update-menu-higher-regexps)) t)) - region-end t) - (beginning-of-line) t))))) - - -;;; Making the list of new menu entries - -(defun texinfo-make-menu-list (beginning end level) - "Make a list of node names and their descriptions. -Point is left at the end of the menu region, but the menu is not inserted. - -First argument is position from which to start making menu list; -second argument is end of region in which to try to locate entries; -third argument is the level of the nodes that are the entries. - -Node names and descriptions are dotted pairs of strings. Each pair is -an element of the list. If the description does not exist, the -element consists only of the node name." - (goto-char beginning) - (let (new-menu-list) - (while (texinfo-menu-locate-entry-p level end) - (push (cons - (texinfo-copy-node-name) - (prog1 "" (forward-line 1))) - ;; Use following to insert section titles automatically. - ;; (texinfo-copy-section-title)) - new-menu-list)) - (nreverse new-menu-list))) - -(defun texinfo-menu-locate-entry-p (level search-end) - "Find a node that will be part of menu for this section. -First argument is a string such as \"section\" specifying the general -hierarchical level of the menu; second argument is a position -specifying the end of the search. - -The function returns t if the node is found, else nil. It searches -forward from point, and leaves point at the beginning of the node. - -The function finds entries of the same type. Thus `subsections' and -`unnumberedsubsecs' will appear in the same menu." - (let ((case-fold-search t)) - (if (re-search-forward - (concat - "\\(^@node\\).*\n" ; match node line - "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any - "\\|" ; or - "\\(^@ifinfo[ ]*\n\\)" ; ifinfo line, if any - "\\|" ; or - "\\(^@ifnottex[ ]*\n\\)" ; ifnottex line, if any - "\\)?" ; end of expression - (eval - (cdr (assoc level texinfo-update-menu-same-level-regexps)) t)) - search-end - t) - (goto-char (match-beginning 1))))) - -(defun texinfo-copy-node-name () - "Return the node name as a string. - -Start with point at the beginning of the node line; copy the text -after the node command up to the first comma on the line, if any, and -return the text as a string. Leaves point at the beginning of the -line. If there is no node name, returns an empty string." - - (save-excursion - (buffer-substring - (progn (forward-word-strictly 1) ; skip over node command - (skip-chars-forward " \t") ; and over spaces - (point)) - (if (search-forward "," (line-end-position) t) ; bound search - (1- (point)) - (end-of-line) (point))))) - -(defun texinfo-copy-section-title () - "Return the title of the section as a string. -The title is used as a description line in the menu when one does not -already exist. - -Move point to the beginning of the appropriate section line by going -to the start of the text matched by last regexp searched for, which -must have been done by `texinfo-menu-locate-entry-p'." - - ;; could use the same re-search as in `texinfo-menu-locate-entry-p' - ;; instead of using `match-beginning'; such a variation would be - ;; more general, but would waste information already collected - - (goto-char (match-beginning 7)) ; match section name - - (buffer-substring - (progn (forward-word-strictly 1) ; skip over section type - (skip-chars-forward " \t") ; and over spaces - (point)) - (progn (end-of-line) (point)))) - - -;;; Handling the old menu - -(defun texinfo-old-menu-p (beginning first) - "Move point to the beginning of the menu for this section, if any. -Otherwise move point to the end of the first node of this section. -Return t if a menu is found, nil otherwise. - -First argument is the position of the beginning of the section in which -the menu will be located; second argument is the position of the first -node within the section. - -If no menu is found, the function inserts two newlines just before the -end of the section, and leaves point there where a menu ought to be." - (goto-char beginning) - (if (re-search-forward "^@menu" first 'goto-end) - t - (insert "\n\n") (forward-line -2) nil)) - -(defun texinfo-incorporate-descriptions (new-menu-list) - "Copy the old menu line descriptions that exist to the new menu. - -Point must be at beginning of old menu. - -If the node-name of the new menu is found in the old menu, insert the -old description into the new entry. - -For this function, the new menu is a list made up of lists of dotted -pairs in which the first element of the pair is the node name and the -second element the description. The new menu is changed destructively. -The old menu is the menu as it appears in the Texinfo file." - - (let ((end-of-menu (texinfo-menu-end))) - (dolist (new-menu new-menu-list new-menu-list) - (save-excursion ; keep point at beginning of menu - (when (re-search-forward - ;; Existing nodes can have the form - ;; * NODE NAME:: DESCRIPTION - ;; or - ;; * MENU ITEM: NODE NAME. DESCRIPTION. - ;; - ;; Recognize both when looking for the description. - (concat "\\* \\(" ; so only menu entries are found - (regexp-quote (car new-menu)) "::" - "\\|" - ".*: " (regexp-quote (car new-menu)) "[.,\t\n]" - "\\)" - ) ; so only complete entries are found - end-of-menu - t) - (setcdr new-menu (texinfo-menu-copy-old-description end-of-menu))))))) - -(defun texinfo-incorporate-menu-entry-names (new-menu-list) - "Copy any old menu entry names to the new menu. - -Point must be at beginning of old menu. - -If the node-name of the new menu entry cannot be found in the old -menu, do nothing. - -For this function, the new menu is a list made up of lists of dotted -pairs in which the first element of the pair is the node name and the -second element is the description (or nil). - -If we find an existing menu entry name, we change the first element of -the pair to be another dotted pair in which the car is the menu entry -name and the cdr is the node name. - -NEW-MENU-LIST is changed destructively. The old menu is the menu as it -appears in the texinfo file." - - (let ((end-of-menu (texinfo-menu-end))) - (dolist (new-menu new-menu-list new-menu-list) - (save-excursion ; keep point at beginning of menu - (if (re-search-forward - ;; Existing nodes can have the form - ;; * NODE NAME:: DESCRIPTION - ;; or - ;; * MENU ITEM: NODE NAME. DESCRIPTION. - ;; - ;; We're interested in the second case. - (concat "\\* " ; so only menu entries are found - "\\(.*\\): " (regexp-quote (car new-menu)) - "[.,\t\n]") - end-of-menu - t) - (setcar - new-menu ; replace the node name - (cons (buffer-substring (match-beginning 1) (match-end 1)) - (car new-menu)))))))) - -(defun texinfo-menu-copy-old-description (end-of-menu) - "Return description field of old menu line as string. -Point must be located just after the node name. Point left before description. -Single argument, END-OF-MENU, is position limiting search." - (skip-chars-forward ":.,\t\n ") - ;; don't copy a carriage return at line beginning with asterisk! - ;; don't copy @detailmenu or @end menu or @ignore as descriptions! - ;; do copy a description that begins with an `@'! - ;; !! Known bug: does not copy descriptions starting with ^|\{?* etc. - (if (and (looking-at "\\(\\w+\\|@\\)") - (not (looking-at - "\\(^\\* \\|^@detailmenu\\|^@end menu\\|^@ignore\\)"))) - (buffer-substring - (point) - (save-excursion - (re-search-forward "\\(^\\* \\|^@ignore\\|^@end menu\\)" end-of-menu t) - (line-end-position 0))) ; end of last description line - "")) - -(defun texinfo-menu-end () - "Return position of end of menu, but don't move point. -Signal an error if not end of menu." - (save-excursion - (if (re-search-forward "^@end menu" nil t) - (point) - (error "Menu does not have an end")))) - -(defun texinfo-delete-old-menu (beginning first) - "Delete the old menu. Point must be in or after menu. -First argument is position of the beginning of the section in which -the menu will be located; second argument is the position of the first -node within the section." - ;; No third arg to search, so error if search fails. - (re-search-backward "^@menu" beginning) - (delete-region (point) - (save-excursion - (re-search-forward "^@end menu" first) - (point)))) - - -;;; Inserting new menu - -;; try 32, but perhaps 24 is better -(defvar texinfo-column-for-description 32 - "Column at which descriptions start in a Texinfo menu.") - -(defun texinfo-insert-menu (menu-list node-name) - "Insert formatted menu at point. -Indents the first line of descriptions, if any, to the value of -texinfo-column-for-description. Indenting leaves trailing whitespace -in a menu that lacks descriptions, so descriptions will format well. -In general, a menu should contain descriptions, because node names and -section titles are often too short to explain a node well. - -MENU-LIST has form: - - ((\"node-name1\" . \"description\") - (\"node-name2\" . \"description\") ... ) - -However, the description field might be nil. - -Also, the node-name field might itself be a dotted pair (call it P) of -strings instead of just a string. In that case, the car of P -is the menu entry name, and the cdr of P is the node name." - - (insert "@menu\n") - (dolist (menu menu-list) - ;; Every menu entry starts with a star and a space. - (insert "* ") - - ;; Insert the node name (and menu entry name, if present). - (let ((node-part (car menu))) - (if (stringp node-part) - ;; "Double colon" entry line; menu entry and node name are the same, - (insert (format "%s::" node-part)) - ;; "Single colon" entry line; menu entry and node name are different. - (insert (format "%s: %s." (car node-part) (cdr node-part))))) - - ;; Insert the description, if present. - (when (> (length (cdr menu)) 0) - ;; Move to right place. - (indent-to texinfo-column-for-description 2) - ;; Insert description. - (insert (format "%s" (cdr menu)))) - - (insert "\n")) ; end this menu entry - (insert "@end menu") - (let ((level (texinfo-hierarchic-level))) - (message - "Updated level \"%s\" menu following node: %s ... " level node-name))) - - -;;; Starting menu descriptions by inserting titles - -;;;###autoload -(defun texinfo-start-menu-description () - "In this menu entry, insert the node's section title as a description. -Position point at beginning of description ready for editing. -Do not insert a title if the line contains an existing description. - -You will need to edit the inserted text since a useful description -complements the node name rather than repeats it as a title does." - - (interactive) - (let (beginning node-name title) ;; end - (save-excursion - (beginning-of-line) - (if (search-forward "* " (line-end-position) t) - (progn (skip-chars-forward " \t") - (setq beginning (point))) - (error "This is not a line in a menu")) - - (cond - ;; "Double colon" entry line; menu entry and node name are the same, - ((search-forward "::" (line-end-position) t) - (if (looking-at "[ \t]*[^ \t\n]+") - (error "Descriptive text already exists")) - (skip-chars-backward ": \t") - (setq node-name (buffer-substring beginning (point)))) - - ;; "Single colon" entry line; menu entry and node name are different. - ((search-forward ":" (line-end-position) t) - (skip-chars-forward " \t") - (setq beginning (point)) - ;; Menu entry line ends in a period, comma, or tab. - (if (re-search-forward "[.,\t]" (line-beginning-position 2) t) - (progn - (if (looking-at "[ \t]*[^ \t\n]+") - (error "Descriptive text already exists")) - (skip-chars-backward "., \t") - (setq node-name (buffer-substring beginning (point)))) - ;; Menu entry line ends in a return. - (re-search-forward ".*\n" (line-beginning-position 2) t) - (skip-chars-backward " \t\n") - (setq node-name (buffer-substring beginning (point))) - (if (= 0 (length node-name)) - (error "No node name on this line") - (insert ".")))) - (t (error "No node name on this line"))) - ;; Search for node that matches node name, and copy the section title. - (if (re-search-forward - (concat - "^@node[ \t]+" - (regexp-quote node-name) - ".*\n" ; match node line - "\\(" - "\\(\\(^@c \\|^@comment\\).*\n\\)" ; match comment line, if any - "\\|" ; or - "\\(^@ifinfo[ ]*\n\\)" ; ifinfo line, if any - "\\|" ; or - "\\(^@ifnottex[ ]*\n\\)" ; ifnottex line, if any - "\\)?" ; end of expression - ) - nil t) - (setq title - (buffer-substring - ;; skip over section type - (progn (forward-word-strictly 1) - ;; and over spaces - (skip-chars-forward " \t") - (point)) - (progn (end-of-line) - (skip-chars-backward " \t") - (point)))) - (error "Cannot find node to match node name in menu entry"))) - ;; Return point to the menu and insert the title. - (end-of-line) - (delete-region - (point) - (save-excursion (skip-chars-backward " \t") (point))) - (indent-to texinfo-column-for-description 2) - (save-excursion (insert title)))) - - -;;; Handling description indentation - -;; Since the make-menu functions indent descriptions, these functions -;; are useful primarily for indenting a single menu specially. - -;;;###autoload -(defun texinfo-indent-menu-description (column &optional region-p) - "Indent every description in menu following point to COLUMN. -Non-nil argument (prefix, if interactive) means indent every -description in every menu in the region. Does not indent second and -subsequent lines of a multi-line description." - - (interactive - "nIndent menu descriptions to (column number): \nP") - (save-excursion - (save-restriction - (widen) - (if (not region-p) - (progn - (re-search-forward "^@menu") - (texinfo-menu-indent-description column) - (message - "Indented descriptions in menu. You may save the buffer.")) - ;;else - (message "Indenting every menu description in region... ") - (goto-char (region-beginning)) - (while (and (< (point) (region-end)) - (texinfo-locate-menu-p)) - (forward-line 1) - (texinfo-menu-indent-description column)) - (message "Indenting done. You may save the buffer."))))) - -(defun texinfo-menu-indent-description (to-column-number) - "Indent the Texinfo file menu description to TO-COLUMN-NUMBER. -Start with point just after the word `menu' in the `@menu' line and -leave point on the line before the `@end menu' line. Does not indent -second and subsequent lines of a multi-line description." - (let* ((beginning-of-next-line (point))) - (while (< beginning-of-next-line - (save-excursion ; beginning of end menu line - (goto-char (texinfo-menu-end)) - (beginning-of-line) - (point))) - - (when (re-search-forward "\\* \\(.*::\\|.*: [^.,\t\n]+[.,\t]\\)" - (texinfo-menu-end) - t) - (let ((beginning-white-space (point))) - (skip-chars-forward " \t") ; skip over spaces - (if (looking-at "\\(@\\|\\w\\)+") ; if there is text - (progn - ;; remove pre-existing indentation - (delete-region beginning-white-space (point)) - (indent-to-column to-column-number))))) - ;; position point at beginning of next line - (forward-line 1) - (setq beginning-of-next-line (point))))) - - -;;; Making the master menu - -;;;###autoload -(defun texinfo-master-menu (update-all-nodes-menus-p) - "Make a master menu for a whole Texinfo file. -Remove pre-existing master menu, if there is one. - -This function supports only single-file manuals. For multi-file -manuals, use `texinfo-multiple-files-update'. - -This function creates or updates the @detailmenu section of a -master menu that follows the Top node. It replaces any existing -detailed menu that follows the top node. The detailed menu -includes every entry from all the other menus. By default, the -existing menus, including the menu in the Top node, are not -updated according to the buffer contents, so all the menus should -be updated first using `texinfo-make-menu' or -`texinfo-all-menus-update', which see. Alternatively, invoke -this function with a prefix argument, see below. - -Non-nil, non-numeric argument (\\[universal-argument] prefix, if interactive) means -first update all existing menus in the buffer (incorporating -descriptions from pre-existing menus) before it constructs the -master menu. If the argument is numeric (e.g., \"\\[universal-argument] 2\"), -update all existing nodes as well, by calling -`texinfo-update-node' on the entire file. Warning: do NOT -invoke with a numeric argument if your Texinfo file uses @node -lines without the `Next', `Previous', `Up' pointers, as the -result could be an invalid Texinfo file! - -The function removes and recreates the detailed part of an already -existing master menu. This action assumes that the pre-existing -master menu uses the standard `texinfo-master-menu-header' for the -detailed menu. - -The master menu has the following format, which is adapted from the -recommendation in the Texinfo Manual: - - * The first part contains the major nodes in the Texinfo file: the - nodes for the chapters, chapter-like sections, and the major - appendices. This includes the indices, so long as they are in - chapter-like sections, such as unnumbered sections. - - * The second and subsequent parts contain a listing of the other, - lower level menus, in order. This way, an inquirer can go - directly to a particular node if he or she is searching for - specific information. - -Each of the menus in the detailed node listing is introduced by the -title of the section containing the menu. - -Indents the first line of descriptions, and leaves trailing whitespace -in a menu that lacks descriptions, so descriptions will format well. -In general, a menu should contain descriptions, because node names and -section titles are often too short to explain a node well." - - (interactive "P") - (let ((case-fold-search t)) - (widen) - (goto-char (point-min)) - - ;; Move point to location after `top'. - (if (not (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t)) - (error "This buffer needs a Top node")) - - (let ((first-chapter - (save-excursion - (or (re-search-forward "^@node" nil t) - (error "Too few nodes for a master menu")) - (point)))) - (if (search-forward texinfo-master-menu-header first-chapter t) - (progn - ;; Check if @detailmenu kludge is used; - ;; if so, leave point before @detailmenu. - (search-backward "\n@detailmenu" (line-beginning-position -2) t) - ;; Remove detailed master menu listing - (goto-char (match-beginning 0)) - (let ((end-of-detailed-menu-descriptions - (save-excursion ; beginning of end menu line - (goto-char (texinfo-menu-end)) - (beginning-of-line) (forward-char -1) - (point)))) - (delete-region (point) end-of-detailed-menu-descriptions))))) - - (if update-all-nodes-menus-p - (progn - (when (numberp update-all-nodes-menus-p) - (message - "Making a master menu in %s ...first updating all nodes... " - (buffer-name)) - (texinfo-update-node (point-min) (point-max))) - (message "Updating all menus in %s ... " (buffer-name)) - (texinfo-make-menu (point-min) (point-max)))) - - (message "Now making the master menu in %s... " (buffer-name)) - (goto-char (point-min)) - (texinfo-insert-master-menu-list - (texinfo-master-menu-list)) - - ;; Remove extra newlines that texinfo-insert-master-menu-list - ;; may have inserted. - - (save-excursion - (goto-char (point-min)) - - (if (search-forward texinfo-master-menu-header nil t) - (progn - (goto-char (match-beginning 0)) - ;; Check if @detailmenu kludge is used; - ;; if so, leave point before @detailmenu. - (search-backward "\n@detailmenu" (line-beginning-position -2) t) - (insert "\n") - (delete-blank-lines) - (goto-char (point-min)))) - - (re-search-forward "^@menu") - (forward-line -1) - (delete-blank-lines) - - (re-search-forward "^@end menu") - (forward-line 1) - (delete-blank-lines)) - - (message - "Done...completed making master menu. You may save the buffer."))) - -(defun texinfo-master-menu-list () - "Return a list of menu entries and header lines for the master menu. - -Start with the menu for chapters and indices and then find each -following menu and the title of the node preceding that menu. - -The master menu list has this form: - - (((... \"entry-1-2\" \"entry-1\") \"title-1\") - ((... \"entry-2-2\" \"entry-2-1\") \"title-2\") - ...) - -However, there does not need to be a title field." - - (let (master-menu-list) - (while (texinfo-locate-menu-p) - (push (list (texinfo-copy-menu) (texinfo-copy-menu-title)) - master-menu-list)) - (nreverse master-menu-list))) - -(defun texinfo-insert-master-menu-list (master-menu-list) - "Format and insert the master menu in the current buffer." - (goto-char (point-min)) - ;; Insert a master menu only after `Top' node and before next node - ;; (or include file if there is no next node). - (unless (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t) - (error "This buffer needs a Top node")) - (let ((first-chapter - (save-excursion (re-search-forward "^@node\\|^@include") (point)))) - (unless (re-search-forward "^@menu" first-chapter t) - (error "Buffer lacks a menu in its first node; create it, then run me again"))) - (beginning-of-line) - (delete-region ; buffer must have ordinary top menu - (point) - (save-excursion (re-search-forward "^@end menu") (point))) - - (save-excursion - ;; `master-menu-inserted-p' is a kludge to tell - ;; whether to insert @end detailmenu (see below) - (let (master-menu-inserted-p) - ;; Handle top of menu - (insert "\n@menu\n") - ;; Insert chapter menu entries. Tell user what is going on. - (message "Inserting chapter menu entry: %s ... " - (car (car master-menu-list))) - (dolist (entry (reverse (car (car master-menu-list)))) - (insert "* " entry "\n")) - - (setq master-menu-list (cdr master-menu-list)) - - ;; Only insert detailed master menu if there is one.... - (if (car (car master-menu-list)) - (progn (setq master-menu-inserted-p t) - (insert (concat "\n@detailmenu\n" - texinfo-master-menu-header)))) - - ;; @detailmenu added 5 Sept 1996 to `texinfo-master-menu-header' - ;; at Karl Berry's request to avert a bug in `makeinfo'; - ;; all agree this is a bad kludge and should eventually be removed. - ;; @detailmenu ... @end detailmenu is a noop in `texinfmt.el'. - ;; See @end detailmenu below; - ;; also see `texinfo-all-menus-update' above, `texinfo-master-menu', - ;; `texinfo-multiple-files-update'. - - ;; Now, insert all the other menus - - ;; The menu master-menu-list has a form like this: - ;; ((("beta" "alpha") "title-A") - ;; (("delta" "gamma") "title-B")) - - (dolist (menu master-menu-list) - - (message "Inserting menu for %s .... " (cadr menu)) - ;; insert title of menu section - (insert "\n" (cadr menu) "\n\n") - - ;; insert each menu entry - (dolist (entry (reverse (car menu))) - (insert "* " entry "\n"))) - - ;; Finish menu - - ;; @detailmenu (see note above) - ;; Only insert @end detailmenu if a master menu was inserted. - (if master-menu-inserted-p - (insert "\n@end detailmenu")) - (insert "\n@end menu\n\n")))) - -(defun texinfo-locate-menu-p () - "Find the next menu in the texinfo file. -If found, leave point after word `menu' on the `@menu' line, and return t. -If a menu is not found, do not move point and return nil." - (re-search-forward "\\(^@menu\\)" nil t)) - -(defun texinfo-copy-menu-title () - "Return the title of the section preceding the menu as a string. -If such a title cannot be found, return an empty string. Do not move -point." - (let ((case-fold-search t)) - (save-excursion - (if (re-search-backward - (concat - "\\(^@top" - "\\|" ; or - texinfo-section-types-regexp ; all other section types - "\\)") - nil - t) - (progn - (beginning-of-line) - (forward-word-strictly 1) ; skip over section type - (skip-chars-forward " \t") ; and over spaces - (buffer-substring - (point) - (progn (end-of-line) (point)))) - "")))) - -(defun texinfo-copy-menu () - "Return the entries of an existing menu as a list. -Start with point just after the word `menu' in the `@menu' line -and leave point on the line before the `@end menu' line." - (let* (this-menu-list - (end-of-menu (texinfo-menu-end)) ; position of end of `@end menu' - (last-entry (save-excursion ; position of beginning of - ; last `* ' entry - (goto-char end-of-menu) - ;; handle multi-line description - (if (not (re-search-backward "^\\* " nil t)) - (error "No entries in menu")) - (point)))) - (while (< (point) last-entry) - (if (re-search-forward "^\\* " end-of-menu t) - (push (buffer-substring - (point) - ;; copy multi-line descriptions - (save-excursion - (re-search-forward "\\(^\\* \\|^@e\\)" nil t) - (- (point) 3))) - this-menu-list))) - this-menu-list)) - - -;;; Determining the hierarchical level in the texinfo file - -(defun texinfo-specific-section-type () - "Return the specific type of next section, as a string. -For example, \"unnumberedsubsec\". Return \"top\" for top node. - -Searches forward for a section. Hence, point must be before the -section whose type will be found. Does not move point. Signal an -error if the node is not the top node and a section is not found." - (let* ((case-fold-search t) - ;; The Texinfo manual has a second Top node inside @verbatim - ;; near the end, which dupes us into thinking we are at top - ;; level, no matter where we are when invoked. We don't - ;; really grok @verbatim, so we cheat: only consider us to be - ;; at top level if the position of the Top node we found is - ;; before any other sectioning command. - (top-pos (save-excursion - (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" - ;; Following search limit causes a bug - ;;(line-end-position) - nil - t))) - (sec-pos (save-excursion - (re-search-forward texinfo-section-types-regexp nil t))) - sec-name) - (if sec-pos - (save-excursion - (goto-char sec-pos) - (setq sec-name (buffer-substring-no-properties - (progn (beginning-of-line) ; copy its name - (1+ (point))) - (progn (forward-word-strictly 1) - (point)))))) - (cond - ((or sec-pos top-pos) - (if (and top-pos sec-pos) - (if (< top-pos sec-pos) - "top" - sec-name) - (or sec-name "top"))) - (t - (error - "texinfo-specific-section-type: Chapter or section not found"))))) - -(defun texinfo-hierarchic-level () - "Return the general hierarchical level of the next node in a texinfo file. -Thus, a subheading or appendixsubsec is of type subsection." - (let ((case-fold-search t)) - (cadr (assoc - (texinfo-specific-section-type) - texinfo-section-list)))) - - -;;; Locating the major positions - -(defun texinfo-update-menu-region-beginning (level) - "Locate beginning of higher level section this section is within. -Return position of the beginning of the node line; do not move point. -Thus, if this level is subsection, searches backwards for section node. -Only argument is a string of the general type of section." - (let ((case-fold-search t)) - ;; !! Known bug: if section immediately follows top node, this - ;; returns the beginning of the buffer as the beginning of the - ;; higher level section. - (cond - ((< level 3) - (save-excursion - (goto-char (point-min)) - (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t) - (line-beginning-position))) - (t - (save-excursion - (re-search-backward - (concat - "\\(^@node\\).*\n" ; match node line - "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any - "\\|" ; or - "\\(^@ifinfo[ ]*\n\\)" ; ifinfo line, if any - "\\|" ; or - "\\(^@ifnottex[ ]*\n\\)" ; ifnottex line, if any - "\\)?" ; end of expression - (eval - (cdr (assoc level texinfo-update-menu-higher-regexps)) t)) - nil - 'goto-beginning) - (point)))))) - -(defun texinfo-update-menu-region-end (level) - "Locate end of higher level section this section is within. -Return position; do not move point. Thus, if this level is a -subsection, find the node for the section this subsection is within. -If level is top or chapter, returns end of file. Only argument is a -string of the general type of section." - (let ((case-fold-search t)) - (save-excursion - (if (re-search-forward - (concat - "\\(^@node\\).*\n" ; match node line - "\\(\\(\\(^@c\\).*\n\\)" ; match comment line, if any - "\\|" ; or - "\\(^@ifinfo[ ]*\n\\)" ; ifinfo line, if any - "\\|" ; or - "\\(^@ifnottex[ ]*\n\\)" ; ifnottex line, if any - "\\)?" ; end of expression - (eval - ;; Never finds end of level above chapter so goes to end. - (cdr (assoc level texinfo-update-menu-higher-regexps)) t)) - nil - 'goto-end) - (match-beginning 1) - (point-max))))) - -(defun texinfo-menu-first-node (beginning end) - "Locate first node of the section the menu will be placed in. -Return position; do not move point. -The menu will be located just before this position. - -First argument is the position of the beginning of the section in -which the menu will be located; second argument is the position of the -end of that region; it limits the search." - (save-excursion - (goto-char beginning) - (forward-line 1) - (re-search-forward "^@node" end t) - (line-beginning-position))) - - -;;; Updating a node - -;;;###autoload -(defun texinfo-update-node (&optional beginning end) - "Without any prefix argument, update the node in which point is located. -Interactively, a prefix argument means to operate on the region. - -Warning: do NOT use this function if your Texinfo file uses @node -lines without the `Next', `Previous', `Up' pointers, because the -result could be an invalid Texinfo file due to known deficiencies -in this command: it does not support @ignore and @if* directives. - -The functions for creating or updating nodes and menus, and their -keybindings, are: - - texinfo-update-node (&optional beginning end) \\[texinfo-update-node] - texinfo-every-node-update () \\[texinfo-every-node-update] - texinfo-sequential-node-update (&optional region-p) - - texinfo-make-menu (&optional region-p) \\[texinfo-make-menu] - texinfo-all-menus-update () \\[texinfo-all-menus-update] - texinfo-master-menu () - - texinfo-indent-menu-description (column &optional region-p) - -The `texinfo-column-for-description' variable specifies the column to -which menu descriptions are indented. Its default value is 32." - - (interactive - (if prefix-arg - (list (point) (mark)))) - (if (null beginning) - ;; Update a single node. - (let ((auto-fill-function nil)) - (if (not (re-search-backward "^@node" (point-min) t)) - (error "Node line not found before this position")) - (texinfo-update-the-node) - (message "Done...updated the node. You may save the buffer.")) - ;; else - (let ((auto-fill-function nil)) - (save-excursion - (save-restriction - (narrow-to-region beginning end) - (goto-char (point-min)) - (while (re-search-forward "^@node" (point-max) t) - (beginning-of-line) - (texinfo-update-the-node)) - (goto-char (point-max)) - (message "Done...nodes updated in region. You may save the buffer.")))))) - -;;;###autoload -(defun texinfo-every-node-update () - "Update every node in a Texinfo file. - -Warning: do NOT use this function if your Texinfo file uses @node -lines without the `Next', `Previous', `Up' pointers, because the -result could be an invalid Texinfo file due to known deficiencies -in this command: it does not support @ignore and @if* directives." - (interactive) - (save-excursion - (texinfo-update-node (point-min) (point-max)) - (message "Done...updated every node. You may save the buffer."))) - -(defun texinfo-update-the-node () - "Update one node. Point must be at the beginning of node line. -Leave point at the end of the node line." - (texinfo-check-for-node-name) - (texinfo-delete-existing-pointers) - (message "Updating node: %s ... " (texinfo-copy-node-name)) - (save-restriction - (widen) - (let* - ((case-fold-search t) - (level (texinfo-hierarchic-level)) - (beginning (texinfo-update-menu-region-beginning level)) - (end (texinfo-update-menu-region-end level))) - (if (eq level 1) - (texinfo-top-pointer-case) - ;; else - (texinfo-insert-pointer beginning end level 'next) - (texinfo-insert-pointer beginning end level 'previous) - (texinfo-insert-pointer beginning end level 'up) - (texinfo-clean-up-node-line))))) - -(defun texinfo-top-pointer-case () - "Insert pointers in the Top node. This is a special case. - -The `Next' pointer is a pointer to a chapter or section at a lower -hierarchical level in the file. The `Previous' and `Up' pointers are -to `(dir)'. Point must be at the beginning of the node line, and is -left at the end of the node line." - - (texinfo-clean-up-node-line) - (insert ", " - (save-excursion - ;; There may be an @chapter or other such command between - ;; the top node line and the next node line, as a title - ;; for an `ifinfo' section. This @chapter command must - ;; be skipped. So the procedure is to search for - ;; the next `@node' line, and then copy its name. - (if (re-search-forward "^@node" nil t) - (progn - (beginning-of-line) - (texinfo-copy-node-name)) - " ")) - ", (dir), (dir)")) - -(defun texinfo-check-for-node-name () - "Determine whether the node has a node name. Prompt for one if not. -Point must be at beginning of node line. Does not move point." - (save-excursion - (let ((initial (texinfo-copy-next-section-title))) - ;; This is not clean. Use `interactive' to read the arg. - (forward-word-strictly 1) ; skip over node command - (skip-chars-forward " \t") ; and over spaces - (if (not (looking-at "[^,\t\n ]+")) ; regexp based on what Info looks for - ; alternatively, use "[a-zA-Z]+" - (let ((node-name - (read-from-minibuffer - "Node name (use no @, commas, colons, or apostrophes): " - initial))) - (insert " " node-name)))))) - -(defun texinfo-delete-existing-pointers () - "Delete `Next', `Previous', and `Up' pointers. -Starts from the current position of the cursor, and searches forward -on the line for a comma and if one is found, deletes the rest of the -line, including the comma. Leaves point at beginning of line." - (let ((eol-point (line-end-position))) - (if (search-forward "," eol-point t) - (delete-region (1- (point)) eol-point))) - (beginning-of-line)) - -(defun texinfo-find-pointer (beginning end level direction) - "Move point to section associated with next, previous, or up pointer. -Return type of pointer (either `normal' or `no-pointer'). - -The first and second arguments bound the search for a pointer to the -beginning and end, respectively, of the enclosing higher level -section. The third argument is a string specifying the general kind -of section such as \"chapter\" or \"section\". When looking for the -`Next' pointer, the section found will be at the same hierarchical -level in the Texinfo file; when looking for the `Previous' pointer, -the section found will be at the same or higher hierarchical level in -the Texinfo file; when looking for the `Up' pointer, the section found -will be at some level higher in the Texinfo file. The fourth argument -\(one of `next', `previous', or `up') specifies whether to find the -`Next', `Previous', or `Up' pointer." - (let ((case-fold-search t)) - (cond ((eq direction 'next) - (forward-line 3) ; skip over current node - ;; Search for section commands accompanied by node lines; - ;; ignore section commands in the middle of nodes. - (if (re-search-forward - ;; A `Top' node is never a next pointer, so won't find it. - (concat - ;; Match node line. - "\\(^@node\\).*\n" - ;; Match comment, ifinfo, ifnottex line, if any - (concat - "\\(\\(" - "\\(^@c\\).*\n\\)" - "\\|" - "\\(^@ifinfo[ ]*\n\\)" - "\\|" - "\\(^@ifnottex[ ]*\n\\)" - "\\)?") - (eval - (cdr (assoc level texinfo-update-menu-same-level-regexps)) t)) - end - t) - 'normal - 'no-pointer)) - ((eq direction 'previous) - (if (re-search-backward - (concat - "\\(" - ;; Match node line. - "\\(^@node\\).*\n" - ;; Match comment, ifinfo, ifnottex line, if any - (concat - "\\(\\(" - "\\(^@c\\).*\n\\)" - "\\|" - "\\(^@ifinfo[ ]*\n\\)" - "\\|" - "\\(^@ifnottex[ ]*\n\\)" - "\\)?") - (eval - (cdr (assoc level texinfo-update-menu-same-level-regexps)) t) - "\\|" - ;; Match node line. - "\\(^@node\\).*\n" - ;; Match comment, ifinfo, ifnottex line, if any - (concat - "\\(\\(" - "\\(^@c\\).*\n\\)" - "\\|" - "\\(^@ifinfo[ ]*\n\\)" - "\\|" - "\\(^@ifnottex[ ]*\n\\)" - "\\)?") - (eval - (cdr (assoc level texinfo-update-menu-higher-regexps)) t) - "\\|" - ;; Handle `Top' node specially. - "^@node [ \t]*top[ \t]*\\(,\\|$\\)" - "\\)") - beginning - t) - 'normal - 'no-pointer)) - ((eq direction 'up) - (if (re-search-backward - (concat - "\\(" - ;; Match node line. - "\\(^@node\\).*\n" - ;; Match comment, ifinfo, ifnottex line, if any - (concat - "\\(\\(" - "\\(^@c\\).*\n\\)" - "\\|" - "\\(^@ifinfo[ ]*\n\\)" - "\\|" - "\\(^@ifnottex[ ]*\n\\)" - "\\)?") - (eval (cdr (assoc level texinfo-update-menu-higher-regexps)) t) - "\\|" - ;; Handle `Top' node specially. - "^@node [ \t]*top[ \t]*\\(,\\|$\\)" - "\\)") - (save-excursion - (goto-char beginning) - (line-beginning-position)) - t) - 'normal - 'no-pointer)) - (t - (error "texinfo-find-pointer: Lack proper arguments"))))) - -(defun texinfo-pointer-name (kind) - "Return the node name preceding the section command. -The argument is the kind of section, either `normal' or `no-pointer'." - (let (name) - (cond ((eq kind 'normal) - (end-of-line) ; this handles prev node top case - (re-search-backward ; when point is already - "^@node" ; at the beginning of @node line - (line-beginning-position -2) - t) - (setq name (texinfo-copy-node-name))) - ((eq kind 'no-pointer) - ;; Don't need to put a blank in the pointer slot, - ;; since insert "' " always has a space - (setq name " "))) ; put a blank in the pointer slot - name)) - -(defun texinfo-insert-pointer (beginning end level direction) - "Insert the `Next', `Previous' or `Up' node name at point. -Move point forward. - -The first and second arguments bound the search for a pointer to the -beginning and end, respectively, of the enclosing higher level -section. The third argument is the hierarchical level of the Texinfo -file, a string such as \"section\". The fourth argument is direction -towards which the pointer is directed, one of `next', `previous', or `up'." - - (end-of-line) - (insert - ", " - (save-excursion - (texinfo-pointer-name - (texinfo-find-pointer beginning end level direction))))) - -(defun texinfo-clean-up-node-line () - "Remove extra commas, if any, at end of node line." - (end-of-line) - (skip-chars-backward ", ") - (delete-region (point) (line-end-position))) - - -;;; Updating nodes sequentially -;; These sequential update functions insert `Next' or `Previous' -;; pointers that point to the following or preceding nodes even if they -;; are at higher or lower hierarchical levels. This means that if a -;; section contains one or more subsections, the section's `Next' -;; pointer will point to the subsection and not the following section. -;; (The subsection to which `Next' points will most likely be the first -;; item on the section's menu.) - -;;;###autoload -(defun texinfo-sequential-node-update (&optional region-p) - "Update one node (or many) in a Texinfo file with sequential pointers. - -This function causes the `Next' or `Previous' pointer to point to the -immediately preceding or following node, even if it is at a higher or -lower hierarchical level in the document. Continually pressing `n' or -`p' takes you straight through the file. - -Without any prefix argument, update the node in which point is located. -Non-nil argument (prefix, if interactive) means update the nodes in the -marked region. - -This command makes it awkward to navigate among sections and -subsections; it should be used only for those documents that are meant -to be read like a novel rather than a reference, and for which the -Info `g*' command is inadequate." - - (interactive "P") - (if (not region-p) - ;; update a single node - (let ((auto-fill-function nil)) - (if (not (re-search-backward "^@node" (point-min) t)) - (error "Node line not found before this position")) - (texinfo-sequentially-update-the-node) - (message - "Done...sequentially updated the node . You may save the buffer.")) - ;; else - (let ((auto-fill-function nil) - (beginning (region-beginning)) - (end (region-end))) - (if (= end beginning) - (error "Please mark a region")) - (save-restriction - (narrow-to-region beginning end) - (goto-char beginning) - (push-mark (point) t) - (while (re-search-forward "^@node" (point-max) t) - (beginning-of-line) - (texinfo-sequentially-update-the-node)) - (message - "Done...updated the nodes in sequence. You may save the buffer."))))) - -(defun texinfo-sequentially-update-the-node () - "Update one node such that the pointers are sequential. -A `Next' or `Previous' pointer points to any preceding or following node, -regardless of its hierarchical level." - - (texinfo-check-for-node-name) - (texinfo-delete-existing-pointers) - (message - "Sequentially updating node: %s ... " (texinfo-copy-node-name)) - (save-restriction - (widen) - (let* ((case-fold-search t) - (level (texinfo-hierarchic-level))) - (if (eq level 1) - (texinfo-top-pointer-case) - ;; else - (texinfo-sequentially-insert-pointer level 'next) - (texinfo-sequentially-insert-pointer level 'previous) - (texinfo-sequentially-insert-pointer level 'up) - (texinfo-clean-up-node-line))))) - -(defun texinfo-sequentially-insert-pointer (level direction) - "Insert the `Next', `Previous' or `Up' node name at point. -Move point forward. - -The first argument is the hierarchical level of the Texinfo file, a -string such as \"section\". The second argument is direction, one of -`next', `previous', or `up'." - - (end-of-line) - (insert - ", " - (save-excursion - (texinfo-pointer-name - (texinfo-sequentially-find-pointer level direction))))) - -(defun texinfo-sequentially-find-pointer (level direction) - "Find next or previous pointer sequentially in Texinfo file, or up pointer. -Move point to section associated with the pointer. Find point even if -it is in a different section. - -Return type of pointer (either `normal' or `no-pointer'). - -The first argument is a string specifying the general kind of section -such as \"chapter\" or \"section\". The section found will be at the -same hierarchical level in the Texinfo file, or, in the case of the up -pointer, some level higher. The second argument (one of `next', -`previous', or `up') specifies whether to find the `Next', `Previous', -or `Up' pointer." - (let ((case-fold-search t)) - (cond ((eq direction 'next) - (forward-line 3) ; skip over current node - (if (re-search-forward - texinfo-section-types-regexp - (point-max) - t) - 'normal - 'no-pointer)) - ((eq direction 'previous) - (if (re-search-backward - texinfo-section-types-regexp - (point-min) - t) - 'normal - 'no-pointer)) - ((eq direction 'up) - (if (re-search-backward - (eval (cdr (assoc level texinfo-update-menu-higher-regexps)) t) - (point-min) - t) - 'normal - 'no-pointer)) - (t - (error "texinfo-sequential-find-pointer: Lack proper arguments"))))) - - -;;; Inserting `@node' lines -;; The `texinfo-insert-node-lines' function inserts `@node' lines as needed -;; before the `@chapter', `@section', and such like lines of a region -;; in a Texinfo file. - -;;;###autoload -(defun texinfo-insert-node-lines (beginning end &optional title-p) - "Insert missing `@node' lines in region of Texinfo file. -Non-nil argument (prefix, if interactive) means also to insert the -section titles as node names; and also to insert the section titles as -node names in pre-existing `@node' lines that lack names." - (interactive "r\nP") - - ;; Use marker; after inserting node lines, leave point at end of - ;; region and mark at beginning. - - (let (end-marker title last-section-position) ;; beginning-marker - - ;; Save current position on mark ring and set mark to end. - (push-mark end t) - (setq end-marker (mark-marker)) - - (goto-char beginning) - (while (re-search-forward - texinfo-section-types-regexp - end-marker - 'end) - ;; Copy title if desired. - (if title-p - (progn - (beginning-of-line) - (forward-word-strictly 1) - (skip-chars-forward " \t") - (setq title (buffer-substring - (point) - (line-end-position))))) - ;; Insert node line if necessary. - (if (re-search-backward - "^@node" - ;; Avoid finding previous node line if node lines are close. - (or last-section-position - (line-beginning-position -1)) - t) - ;; @node is present, and point at beginning of that line - (forward-word-strictly 1) ; Leave point just after @node. - ;; Else @node missing; insert one. - (beginning-of-line) ; Beginning of `@section' line. - (insert "@node\n") - (backward-char 1)) ; Leave point just after `@node'. - ;; Insert title if desired. - (if title-p - (progn - (skip-chars-forward " \t") - ;; Use regexp based on what info looks for - ;; (alternatively, use "[a-zA-Z]+"); - ;; this means we only insert a title if none exists. - (if (not (looking-at "[^,\t\n ]+")) - (progn - (beginning-of-line) - (forward-word-strictly 1) - (insert " " title) - (message "Inserted title %s ... " title))))) - ;; Go forward beyond current section title. - (re-search-forward texinfo-section-types-regexp - (line-beginning-position 4) t) - (setq last-section-position (point)) - (forward-line 1)) - - ;; Leave point at end of region, mark at beginning. - (set-mark beginning) - - (if title-p - (message - "Done inserting node lines and titles. You may save the buffer.") - (message "Done inserting node lines. You may save the buffer.")))) - - -;;; Update and create menus for multi-file Texinfo sources - -;; 1. M-x texinfo-multiple-files-update -;; -;; Read the include file list of an outer Texinfo file and -;; update all highest level nodes in the files listed and insert a -;; main menu in the outer file after its top node. - -;; 2. C-u M-x texinfo-multiple-files-update -;; -;; Same as 1, but insert a master menu. (Saves reupdating lower -;; level menus and nodes.) This command simply reads every menu, -;; so if the menus are wrong, the master menu will be wrong. -;; Similarly, if the lower level node pointers are wrong, they -;; will stay wrong. - -;; 3. C-u 2 M-x texinfo-multiple-files-update -;; -;; Read the include file list of an outer Texinfo file and -;; update all nodes and menus in the files listed and insert a -;; master menu in the outer file after its top node. - -;;; Note: these functions: -;;; -;;; * Do not save or delete any buffers. You may fill up your memory. -;;; * Do not handle any pre-existing nodes in outer file. -;;; Hence, you may need a file for indices. - - -;;; Auxiliary functions for multiple file updating - -(defun texinfo-multi-file-included-list (outer-file) - "Return a list of the included files in OUTER-FILE." - (let ((included-file-list (list outer-file)) - start) - (with-current-buffer (find-file-noselect outer-file) - (widen) - (goto-char (point-min)) - (while (re-search-forward "^@include" nil t) - (skip-chars-forward " \t") - (setq start (point)) - (end-of-line) - (skip-chars-backward " \t") - (setq included-file-list - (cons (buffer-substring start (point)) - included-file-list))) - (nreverse included-file-list)))) - -(defun texinfo-copy-next-section-title () - "Return the name of the immediately following section as a string. - -Start with point at the beginning of the node line. Leave point at the -same place. If there is no title, returns an empty string." - - (save-excursion - (end-of-line) - (let ((node-end (or - (save-excursion - (if (re-search-forward "\\(^@node\\)" nil t) - (match-beginning 0))) - (point-max)))) - (if (re-search-forward texinfo-section-types-regexp node-end t) - (progn - (beginning-of-line) - ;; copy title - (let ((title - (buffer-substring - (progn (forward-word-strictly 1) ; skip over section type - (skip-chars-forward " \t") ; and over spaces - (point)) - (progn (end-of-line) (point))))) - title)) - "")))) - -(defun texinfo-multi-file-update (files &optional update-everything) - "Update first node pointers in each file in FILES. -Return a list of the node names. - -The first file in the list is an outer file; the remaining are -files included in the outer file with `@include' commands. - -If optional arg UPDATE-EVERYTHING non-nil, update every menu and -pointer in each of the included files. - -Also update the `Top' level node pointers of the outer file. - -Requirements: - - * the first file in the FILES list must be the outer file, - * each of the included files must contain exactly one highest - hierarchical level node, - * this node must be the first node in the included file, - * each highest hierarchical level node must be of the same type. - -Thus, normally, each included file contains one, and only one, chapter. - -However, when an included file does not have any node lines in -it, this command does not try to create a menu entry for it. -Consequently, you can include any file, such as a version or an -update file without node lines, not just files that are -chapters." - -;; The menu-list has the form: -;; -;; ((\"node-name1\" . \"title1\") -;; (\"node-name2\" . \"title2\") ... ) -;; -;; However, there does not need to be a title field and this function -;; does not fill it; however a comment tells you how to do so. -;; You would use the title field if you wanted to insert titles in the -;; description slot of a menu as a description. - - (let ((case-fold-search t) - menu-list next-node-name previous-node-name files-with-node-lines) - - ;; Create a new list of included files that only have node lines - (while files - (set-buffer (find-file-noselect (car files))) - (widen) - (goto-char (point-min)) - (when (re-search-forward "^@node" nil t) - (setq files-with-node-lines (cons (car files) files-with-node-lines))) - (setq files (cdr files))) - (setq files-with-node-lines (nreverse files-with-node-lines)) - - ;; Find the name of the first node in a subsequent file - ;; and copy it into the variable next-node-name - (set-buffer (find-file-noselect (car (cdr files-with-node-lines)))) - (widen) - (goto-char (point-min)) - ;; The following search _must_ succeed, since we verified above - ;; that this file does have a @node line. - (re-search-forward "^@node" nil t) - (beginning-of-line) - (texinfo-check-for-node-name) - (setq next-node-name (texinfo-copy-node-name)) - (push (cons next-node-name (prog1 "" (forward-line 1))) - ;; Use following to insert section titles automatically. - ;; (texinfo-copy-next-section-title) - menu-list) - - ;; Go to outer file - ;; `pop' is analogous to (prog1 (car PLACE) (setf PLACE (cdr PLACE))) - (set-buffer (find-file-noselect (pop files-with-node-lines))) - (goto-char (point-min)) - (if (not (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t)) - (error "This buffer needs a Top node")) - (beginning-of-line) - (texinfo-delete-existing-pointers) - (end-of-line) - (insert ", " next-node-name ", (dir), (dir)") - (beginning-of-line) - (setq previous-node-name "Top") - - (while files-with-node-lines - - (if (not (cdr files-with-node-lines)) - ;; No next file - (setq next-node-name "") - ;; Else, - ;; find the name of the first node in the next file. - (set-buffer (find-file-noselect (car (cdr files-with-node-lines)))) - (widen) - (goto-char (point-min)) - ;; The following search _must_ succeed, since we verified - ;; above that files in files-with-node-lines do have a @node - ;; line. - (re-search-forward "^@node" nil t) - (beginning-of-line) - (texinfo-check-for-node-name) - (setq next-node-name (texinfo-copy-node-name)) - (push (cons next-node-name (prog1 "" (forward-line 1))) - ;; Use following to insert section titles automatically. - ;; (texinfo-copy-next-section-title) - menu-list)) - - ;; Go to node to be updated. - (set-buffer (find-file-noselect (car files-with-node-lines))) - (goto-char (point-min)) - (beginning-of-line) - - ;; Update other menus and nodes if requested. - (if update-everything (texinfo-all-menus-update t)) - - (beginning-of-line) - (texinfo-delete-existing-pointers) - (end-of-line) - (insert ", " next-node-name ", " previous-node-name ", Top") - - (beginning-of-line) - (setq previous-node-name (texinfo-copy-node-name)) - - (setq files-with-node-lines (cdr files-with-node-lines))) - (nreverse menu-list))) - -(defun texinfo-multi-files-insert-main-menu (menu-list) - "Insert formatted main menu at point. -Indents the first line of the description, if any, to the value of -`texinfo-column-for-description'." - - (insert "@menu\n") - (dolist (entry menu-list) - ;; Every menu entry starts with a star and a space. - (insert "* ") - - ;; Insert the node name (and menu entry name, if present). - (let ((node-part (car entry))) - (if (stringp node-part) - ;; "Double colon" entry line; menu entry and node name are the same, - (insert (format "%s::" node-part)) - ;; "Single colon" entry line; menu entry and node name are different. - (insert (format "%s: %s." (car node-part) (cdr node-part))))) - - ;; Insert the description, if present. - (when (cdr entry) - ;; Move to right place. - (indent-to texinfo-column-for-description 2) - ;; Insert description. - (insert (format "%s" (cdr entry)))) - - (insert "\n")) ; end this menu entry - (insert "@end menu")) - -(defun texinfo-multi-file-master-menu-list (files-list) - "Return master menu list from files in FILES-LIST. -Menu entries in each file collected using `texinfo-master-menu-list'. - -The first file in FILES-LIST must be the outer file; the others must -be the files included within it. A main menu must already exist." - (save-excursion - (let (master-menu-list) - (dolist (file files-list) - (set-buffer (find-file-noselect file)) - (message "Working on: %s " (current-buffer)) - (goto-char (point-min)) - (setq master-menu-list - (append master-menu-list (texinfo-master-menu-list)))) - master-menu-list))) - - -;;; The multiple-file update function - -;;;###autoload -(defun texinfo-multiple-files-update - (outer-file &optional make-master-menu update-everything) - "Update first node pointers in each file included in OUTER-FILE; -create or update the `Top' level node pointers and the main menu in -the outer file that refers to such nodes. This does not create or -update menus or pointers within the included files. - -With optional MAKE-MASTER-MENU argument (prefix arg, if interactive), -insert a master menu in OUTER-FILE in addition to creating or updating -pointers in the first @node line in each included file and creating or -updating the `Top' level node pointers of the outer file. This does -not create or update other menus and pointers within the included -files. - -With optional UPDATE-EVERYTHING argument (numeric prefix arg, if -interactive), update all the menus and all the `Next', `Previous', and -`Up' pointers of all the files included in OUTER-FILE before inserting -a master menu in OUTER-FILE. Also, update the `Top' level node -pointers of OUTER-FILE. Do NOT invoke this command with a numeric prefix -arg, if your files use @node lines without the `Next', `Previous', `Up' -pointers, because this could produce invalid Texinfo files due to known -deficiencies in `texinfo-update-node': it does not support the @ignore -and @if... directives. - -Notes: - - * this command does NOT save any files--you must save the - outer file and any modified, included files. - - * except for the `Top' node, this command does NOT handle any - pre-existing nodes in the outer file; hence, indices must be - enclosed in an included file. - -Requirements: - - * each of the included files must contain exactly one highest - hierarchical level node, - * this highest node must be the first node in the included file, - * each highest hierarchical level node must be of the same type. - -Thus, normally, each included file contains one, and only one, -chapter." - - (interactive (cons - (read-string - "Name of outer `include' file: " - (buffer-file-name)) - (cond - ((not current-prefix-arg) '(nil nil)) - ((listp current-prefix-arg) '(t nil)) ; make-master-menu - ((numberp current-prefix-arg) '(t t))))) ; update-everything - - (let* ((included-file-list (texinfo-multi-file-included-list outer-file)) - (files included-file-list) - ;; next-node-name - ;; previous-node-name - ;; Update the pointers and collect the names of the nodes and titles - (main-menu-list (texinfo-multi-file-update files update-everything))) - - ;; Insert main menu - - ;; Go to outer file - (set-buffer (find-file-noselect (car included-file-list))) - (if (texinfo-old-menu-p - (point-min) - (save-excursion - (re-search-forward "^@include") - (line-beginning-position))) - ;; If found, leave point after word `menu' on the `@menu' line. - (progn - (texinfo-incorporate-descriptions main-menu-list) - ;; Delete existing menu. - (beginning-of-line) - (delete-region - (point) - (save-excursion (re-search-forward "^@end menu") (point))) - ;; Insert main menu - (texinfo-multi-files-insert-main-menu main-menu-list)) - - ;; Else no current menu; insert it before `@include' - (texinfo-multi-files-insert-main-menu main-menu-list)) - - ;; Insert master menu - - (if make-master-menu - (progn - ;; First, removing detailed part of any pre-existing master menu - (goto-char (point-min)) - (if (search-forward texinfo-master-menu-header nil t) - (progn - (goto-char (match-beginning 0)) - ;; Check if @detailmenu kludge is used; - ;; if so, leave point before @detailmenu. - (search-backward "\n@detailmenu" (line-beginning-position -2) t) - ;; Remove detailed master menu listing - (let ((end-of-detailed-menu-descriptions - (save-excursion ; beginning of end menu line - (goto-char (texinfo-menu-end)) - (beginning-of-line) (forward-char -1) - (point)))) - (delete-region (point) end-of-detailed-menu-descriptions)))) - - ;; Create a master menu and insert it - (texinfo-insert-master-menu-list - (texinfo-multi-file-master-menu-list - included-file-list))))) - - ;; Remove unwanted extra lines. - (save-excursion - (goto-char (point-min)) - - (re-search-forward "^@menu") - (forward-line -1) - (insert "\n") ; Ensure at least one blank line. - (delete-blank-lines) - - (re-search-forward "^@end menu") - (forward-line 1) - (insert "\n") ; Ensure at least one blank line. - (delete-blank-lines)) - - (message "Multiple files updated.")) - -(provide 'texnfo-upd) - -;; Local Variables: -;; generated-autoload-file: "texinfo-loaddefs.el" -;; End: - -;;; texnfo-upd.el ends here diff --git a/test/lisp/align-tests.el b/test/lisp/align-tests.el index 2475a2f3369..50b5717f772 100644 --- a/test/lisp/align-tests.el +++ b/test/lisp/align-tests.el @@ -45,10 +45,6 @@ (ert-test-erts-file (ert-resource-file "java-mode.erts") (test-align-transform-fun #'java-mode))) -(ert-deftest align-latex () - (ert-test-erts-file (ert-resource-file "latex-mode.erts") - (test-align-transform-fun #'latex-mode))) - (autoload 'treesit-ready-p "treesit") (ert-deftest align-ts-lua () diff --git a/test/lisp/electric-tests.el b/test/lisp/electric-tests.el index 1d258a5ffcb..f72993d430f 100644 --- a/test/lisp/electric-tests.el +++ b/test/lisp/electric-tests.el @@ -626,16 +626,6 @@ baz\"\"" (skip-chars-backward "\"") (mark-sexp -1))) -(define-electric-pair-test autowrapping-7 - "foo" "\"" :expected-string "``foo''" :expected-point 8 - :modes '(tex-mode) - :test-in-comments nil - :fixture-fn (lambda () - (electric-pair-mode 1) - (goto-char (point-max)) - (skip-chars-backward "\"") - (mark-sexp -1))) - (define-electric-pair-test autowrapping-multi-1 "foo" "(" :expected-string "(((((foo)))))" :expected-point 6 :bindings '((current-prefix-arg . 5)) diff --git a/test/lisp/simple-tests.el b/test/lisp/simple-tests.el index f037f84ad52..bcb1dbd39f4 100644 --- a/test/lisp/simple-tests.el +++ b/test/lisp/simple-tests.el @@ -737,27 +737,6 @@ See bug#35036." ,@body) (switch-to-buffer ,before-buffer))))) -;; This tests for a regression in emacs 25.0 see bug #23632 -(ert-deftest simple-test-undo-extra-boundary-in-tex () - (should - (string= - "" - (simple-test-undo-with-switched-buffer - "temp.tex" - (latex-mode) - ;; This macro calls `latex-insert-block' - (execute-kbd-macro - (read-kbd-macro - " -C-c C-o ;; latex-insert-block -RET ;; newline -C-/ ;; undo -" - )) - (buffer-substring-no-properties - (point-min) - (point-max)))))) - (ert-deftest missing-record-point-in-undo () "Check point is being restored correctly. diff --git a/test/lisp/textmodes/reftex-tests.el b/test/lisp/textmodes/reftex-tests.el deleted file mode 100644 index 3a4d9b1f2e5..00000000000 --- a/test/lisp/textmodes/reftex-tests.el +++ /dev/null @@ -1,889 +0,0 @@ -;;; reftex-tests.el --- Test suite for reftex. -*- lexical-binding: t -*- - -;; Copyright (C) 2013-2025 Free Software Foundation, Inc. - -;; Author: Rüdiger Sonderfeld -;; Keywords: internal -;; Human-Keywords: internal - -;; 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 . - -;;; Code: - -(require 'ert) -(require 'ert-x) - -;;; reftex -(require 'reftex) - -;;; reftex-parse -(require 'reftex-parse) - -(ert-deftest reftex-locate-bibliography-files () - "Test `reftex-locate-bibliography-files'." - (ert-with-temp-directory temp-dir - (let ((files '("ref1.bib" "ref2.bib")) - (test '(("\\addbibresource{ref1.bib}\n" . ("ref1.bib")) - ("\\\\addbibresource[label=x]{ref2.bib}\\n" . ("ref2.bib")) - ("\\begin{document}\n\\bibliographystyle{plain}\n -\\bibliography{ref1,ref2}\n\\end{document}" . ("ref1.bib" "ref2.bib")))) - (reftex-bibliography-commands - ;; Default value: See reftex-vars.el `reftex-bibliography-commands' - '("bibliography" "nobibliography" "setupbibtex\\[.*?database=" - "addbibresource"))) - (with-temp-buffer - (insert "test\n") - (mapc - (lambda (file) - (write-region (point-min) (point-max) (expand-file-name file - temp-dir))) - files)) - (mapc - (lambda (data) - (with-temp-buffer - (insert (car data)) - (let ((res (mapcar #'file-name-nondirectory - (reftex-locate-bibliography-files temp-dir)))) - (should (equal res (cdr data)))))) - test)))) - -(ert-deftest reftex-what-environment-test () - "Test `reftex-what-environment'." - (with-temp-buffer - (insert "\\begin{equation}\n x=y^2\n") - (let ((pt (point)) - pt2) - (insert "\\end{equation}\n") - (goto-char pt) - - (should (equal (reftex-what-environment 1) '("equation" . 1))) - (should (equal (reftex-what-environment t) '(("equation" . 1)))) - - (insert "\\begin{something}\nxxx") - (setq pt2 (point)) - (insert "\\end{something}") - (goto-char pt2) - (should (equal (reftex-what-environment 1) `("something" . ,pt))) - (should (equal (reftex-what-environment t) `(("something" . ,pt) - ("equation" . 1)))) - (should (equal (reftex-what-environment t pt) `(("something" . ,pt)))) - (should (equal (reftex-what-environment '("equation")) - '("equation" . 1)))))) - -(ert-deftest reftex-roman-number-test () - "Test `reftex-roman-number'." - (let ((hindu-arabic '(1 2 4 9 14 1050)) - (roman '("I" "II" "IV" "IX" "XIV" "ML"))) - (while (and hindu-arabic roman) - (should (string= (reftex-roman-number (car hindu-arabic)) - (car roman))) - (pop roman) - (pop hindu-arabic)))) - -(ert-deftest reftex-parse-from-file-test () - "Test `reftex-parse-from-file'." - ;; Use file-truename to convert 8+3 aliases in $TEMP value on - ;; MS-Windows into their long file-name equivalents, which is - ;; necessary for the 'equal' and 'string=' comparisons below. This - ;; also resolves any symlinks, which cannot be bad for the same - ;; reason. (An alternative solution would be to use file-equal-p, - ;; but I'm too lazy to do that, as one of the tests compares a - ;; list.) - (ert-with-temp-directory temp-dir - (let* ((tex-file (expand-file-name "test.tex" temp-dir)) - (bib-file (expand-file-name "ref.bib" temp-dir))) - (with-temp-buffer - (insert - "\\begin{document} -\\section{test}\\label{sec:test} -\\subsection{subtest} - -\\begin{align*}\\label{eq:foo} - x &= y^2 -\\end{align*} - -\\bibliographystyle{plain} -\\bibliography{ref} -\\end{document}") - (write-region (point-min) (point-max) tex-file)) - (with-temp-buffer - (insert "test\n") - (write-region (point-min) (point-max) bib-file)) - (reftex-ensure-compiled-variables) - (let ((parsed (reftex-parse-from-file tex-file nil temp-dir))) - (should (equal (car parsed) `(eof ,tex-file))) - (pop parsed) - (while parsed - (let ((entry (pop parsed))) - (cond - ((eq (car entry) 'bib) - (should (string= (cadr entry) bib-file))) - ((eq (car entry) 'toc)) ;; ... - ((string= (car entry) "eq:foo")) - ((string= (car entry) "sec:test")) - ((eq (car entry) 'bof) - (should (string= (cadr entry) tex-file)) - (should (null parsed))) - (t (should-not t))))))))) - -;;; reftex-cite -(require 'reftex-cite) - -(ert-deftest reftex-parse-bibtex-entry-test () - "Test `reftex-parse-bibtex-entry'." - (let ((entry "@Book{Stallman12, - author = {Richard Stallman\net al.}, - title = {The Emacs Editor}, - publisher = {GNU Press}, - year = 2012, - edition = {17th}, - note = {Updated for Emacs Version 24.2} -}") - (check (lambda (parsed) - (should (string= (reftex-get-bib-field "&key" parsed) - "Stallman12")) - (should (string= (reftex-get-bib-field "&type" parsed) - "book")) - (should (string= (reftex-get-bib-field "author" parsed) - "Richard Stallman et al.")) - (should (string= (reftex-get-bib-field "title" parsed) - "The Emacs Editor")) - (should (string= (reftex-get-bib-field "publisher" parsed) - "GNU Press")) - (should (string= (reftex-get-bib-field "year" parsed) - "2012")) - (should (string= (reftex-get-bib-field "edition" parsed) - "17th")) - (should (string= (reftex-get-bib-field "note" parsed) - "Updated for Emacs Version 24.2"))))) - (funcall check (reftex-parse-bibtex-entry entry)) - (with-temp-buffer - (insert entry) - (funcall check (reftex-parse-bibtex-entry nil (point-min) - (point-max)))))) - -(ert-deftest reftex-get-bib-names-test () - "Test `reftex-get-bib-names'." - (let ((entry (reftex-parse-bibtex-entry "@article{Foo123, - author = {Jane Roe and\tJohn Doe and W. Public}, -}"))) - (should (equal (reftex-get-bib-names "author" entry) - '("Jane Roe" "John Doe" "Public")))) - (let ((entry (reftex-parse-bibtex-entry "@article{Foo123, - editor = {Jane Roe and\tJohn Doe and W. Public}, -}"))) - (should (equal (reftex-get-bib-names "author" entry) - '("Jane Roe" "John Doe" "Public"))))) - -(ert-deftest reftex-format-citation-test () - "Test `reftex-format-citation'." - (let ((entry (reftex-parse-bibtex-entry "\ -@article{Foo13, - author = {Jane Roe and John Doe and Jane Q. Taxpayer}, - title = {Some Article}, - journal = {Some Journal}, - year = 2013, - pages = {1--333} -}")) - (entry2 (reftex-parse-bibtex-entry "\ -@article{Abels:slice, -author = {Abels, H.}, -title = {Parallelizability of proper actions, global - {$K$}-slices and maximal compact subgroups}, -journaltitle = {Math. Ann.}, -year = 1974, -volume = 212, -pages = {1--19} -}"))) - (should (string= (reftex-format-citation entry nil) "\\cite{Foo13}")) - (should (string= (reftex-format-citation entry "%l:%A:%y:%t %j %P %a") - "Foo13:Jane Roe:2013:Some Article Some Journal 1 Jane Roe, John Doe \\& Jane Taxpayer")) - ;; Test for biblatex field journaltitle (bug#38762): - (should (string= - (reftex-format-citation entry2 - "[%4a, \\textit{%t}, \ -%b %e, %u, %r %h %j \\textbf{%v} (%y), %p %<]") - "[Abels, \\textit{Parallelizability of proper actions, \ -global {$K$}-slices and maximal compact subgroups}, \ -Math. Ann. \\textbf{212} (1974), 1--19]")))) - -(ert-deftest reftex-all-used-citation-keys () - "Test `reftex-all-used-citation-keys'. -Take the cite macros provided by biblatex package as reference." - (ert-with-temp-directory temp-dir - (let ((tex-file (expand-file-name "keys.tex" temp-dir)) - keys) - (with-temp-buffer - (insert "\ -\\documentclass{article} -\\usepackage{biblatex} -\\begin{document} - -Standard commands: -\\cite[pre][pos]{cite:2022} -\\Cite[pos]{Cite:2022} -\\parencite{parencite:2022} -\\Parencite[pre][]{Parencite:2022} -\\footcite[][]{footcite:2022} -\\footcitetext[pre][pos]{footcitetext:2022} - -Style specific commands: -\\textcite{textcite:2022} -\\Textcite[pos]{Textcite:2022} -\\smartcite[pre][pos]{smartcite:2022} -\\Smartcite[pre][]{Smartcite:2022} -\\cite*[pre][pos]{cite*:2022} -\\parencite*[][]{parencite*:2022} - -Style independent commands: -\\autocite[pre][pos]{autocite:2022} -\\autocite*[pos]{autocite*:2022} -\\Autocite[pre][]{Autocite:2022} -\\Autocite*{Autocite*:2022} - -Text commands: -\\citeauthor[pre][pos]{citeauthor:2022} -\\citeauthor*[pre][]{citeauthor*:2022} -\\Citeauthor[pos]{Citeauthor:2022} -\\Citeauthor*{Citeauthor*:2022} -\\citetitle[][]{citetitle:2022} -\\citetitle*[pre][pos]{citetitle*:2022} -\\citeyear[pre][pos]{citeyear:2022} -\\citeyear*[pre][pos]{citeyear*:2022} -\\citedate[pre][pos]{citedate:2022} -\\citedate*[pre][pos]{citedate*:2022} -\\citeurl[pre][pos]{citeurl:2022} - -Special commands: -\\nocite{nocite:2022} -\\fullcite[pos]{fullcite:2022} -\\footfullcite[][]{fullfootcite:2022} -``volcite'' macros have different number of args. -\\volcite{2}{volcite:2022} -\\Volcite[pre]{1}{Volcite:2022} -\\pvolcite{1}[pg]{pvolcite:2022} -\\Pvolcite[pre]{2}[pg]{Pvolcite:2022} -\\fvolcite[pre]{3}[pg]{fvolcite:2022} -\\ftvolcite[pre]{3}[pg]{ftvolcite:2022} -\\svolcite[pre]{2}[pg]{svolcite:2022} -\\Svolcite[pre]{4}[pg]{Svolcite:2022} -\\tvolcite[pre]{5}[pg]{tvolcite:2022} -\\Tvolcite[pre]{2}[pg]{Tvolcite:2022} -\\avolcite[pre]{3}[pg]{avolcite:2022} -\\Avolcite[pre]{1}[pg]{Avolcite:2022} -\\Notecite[pre]{Notecite:2022} -\\pnotecite[pre]{pnotecite:2022} -\\Pnotecite[pre]{Pnotecite:2022} -\\fnotecite[pre]{fnotecite:2022} - -Natbib compatibility commands: -\\citet{citet:2022} -\\citet*[pre][pos]{citet*:2022} -\\citep[pre][pos]{citep:2022} -\\citep*[pos]{citep*:2022} -\\citealt[pre][]{citealt:2022} -\\citealt*[][]{citealt*:2022} -\\citealp[pre][pos]{citealp:2022} -\\citealp*{citealp*:2022} -\\Citet[pre][pos]{Citet:2022} -\\Citet*[pre][pos]{Citet*:2022} -\\Citep[pre][pos]{Citep:2022} -\\Citep*[pre][pos]{Citep*:2022} - -Qualified Citation Lists: -\\cites(Global Prenote)(Global Postnote)[pre][post]{cites:1}[pre][post]{cites:2} -\\Cites(Global Prenote)(Global Postnote)[pre][post]{Cites:1}[pre][post]{Cites:2} -\\parencites(Global Prenote)(Global Postnote)[pre][post]{parencites:1} - [pre][post]{parencites:2} -\\Parencites(Global Prenote)(Global Postnote)[pre][post]{Parencites:1}{Parencites:2} -\\footcites[pre][post]{footcites:1}[pre][post]{footcites:2} -\\footcitetexts{footcitetexts:1}{footcitetexts:2} -\\smartcites{smartcites:1} -% This is comment about \\smartcites{smartcites:2} -[pre][post]{smartcites:2} -% And this should be ignored \\smartcites{smartcites:3}{smartcites:4} - - -Test for bug#56655: -There was a few \\% of increase in budget \\Citep*{bug:56655}. - -And this should be % \\cite{ignored}. -\\end{document}") - (write-region (point-min) (point-max) tex-file)) - (find-file tex-file) - (setq keys (reftex-all-used-citation-keys)) - (should (equal (sort keys #'string<) - (sort (list - ;; Standard commands: - "cite:2022" "Cite:2022" - "parencite:2022" "Parencite:2022" - "footcite:2022" "footcitetext:2022" - ;; Style specific commands: - "textcite:2022" "Textcite:2022" - "smartcite:2022" "Smartcite:2022" - "cite*:2022" "parencite*:2022" - ;; Style independent commands: - "autocite:2022" "autocite*:2022" - "Autocite:2022" "Autocite*:2022" - ;; Text commands - "citeauthor:2022" "citeauthor*:2022" - "Citeauthor:2022" "Citeauthor*:2022" - "citetitle:2022" "citetitle*:2022" - "citeyear:2022" "citeyear*:2022" - "citedate:2022" "citedate*:2022" - "citeurl:2022" - ;; Special commands: - "nocite:2022" "fullcite:2022" - "fullfootcite:2022" - "volcite:2022" "Volcite:2022" - "pvolcite:2022" "Pvolcite:2022" - "fvolcite:2022" "ftvolcite:2022" - "svolcite:2022" "Svolcite:2022" - "tvolcite:2022" "Tvolcite:2022" - "avolcite:2022" "Avolcite:2022" - "Notecite:2022" "pnotecite:2022" - "Pnotecite:2022" "fnotecite:2022" - ;; Natbib compatibility commands: - "citet:2022" "citet*:2022" - "citep:2022" "citep*:2022" - "citealt:2022" "citealt*:2022" - "citealp:2022" "citealp*:2022" - "Citet:2022" "Citet*:2022" - "Citep:2022" "Citep*:2022" - ;; Qualified Citation Lists - "cites:1" "cites:2" - "Cites:1" "Cites:2" - "parencites:1" "parencites:2" - "Parencites:1" "Parencites:2" - "footcites:1" "footcites:2" - "footcitetexts:1" "footcitetexts:2" - "smartcites:1" "smartcites:2" - "bug:56655") - #'string<))) - (kill-buffer (file-name-nondirectory tex-file))))) - -(ert-deftest reftex-renumber-simple-labels () - "Test `reftex-renumber-simple-labels'. -The function must recognize labels defined with macros like -\\label and the ones as key=value option in optional or mandatory -argument of other macros or environments." - (ert-with-temp-directory temp-dir - (let ((tex-file (expand-file-name "renumber.tex" temp-dir))) - (with-temp-buffer - (insert "\ -\\documentclass{article} -\\usepackage{tcolorbox} -\\tcbuselibrary{theorems} -\\usepackage{fancyvrb} -\\usepackage{listings} - -\\begin{document} - -This is with tcolorbox package: -\\begin{problem}[% - colback = white , - colframe = red!50!black , - fonttitle = \\bfseries , - description delimiters = {\\flqq}{\\frqq} , - label = {problem:2}]{Prove RH2}{} - Problem -\\end{problem} - -This is with vanilla \\LaTeX: -\\begin{equation} - \\label{eq:2} - 2 -\\end{equation} -By \\eqref{eq:2} and \\ref{problem:2} - -This is with tcolorbox package: -\\begin{problem}[% - colback=white, - colframe=red!50!black, - fonttitle=\\bfseries, - theorem label supplement={hypertarget={XYZ-##1}}, - theorem full label supplement={code={\\marginnote{##1}}}, - label={problem:1}]{Prove RH1}{} - Problem -\\end{problem} - -This is with vanilla \\LaTeX: -\\begin{equation} - \\label{eq:1} - 1 -\\end{equation} - -\\Cref{problem:1} and \\pageref{eq:1}. - -\\begin{problem}[label={problem:6}]{Some Problem}{} - Problem -\\end{problem} - -\\Ref{problem:6}. - -This is with fancyvrb package: -\\begin{Verbatim}[reflabel={lst:6}] -Some Verb Content -\\end{Verbatim} - -\\pageref{lst:6} - -This is with listings package: -\\begin{lstlisting}[language=elisp,caption=Some Caption,label={lst:3}] -(car (cons 1 '(2))) -\\end{lstlisting} - -\\ref{lst:3} - -\\end{document}") - (write-region (point-min) (point-max) tex-file)) - ;; The label prefix must be known to RefTeX: - (add-to-list 'reftex-label-alist - '("problem" ?p "problem:" "~\\ref{%s}" - nil nil nil) - t) - (add-to-list 'reftex-label-alist - '("Verbatim" ?l "lst:" "~\\ref{%s}" - nil nil nil) - t) - ;; The environments must be known to RefTeX otherwise the labels - ;; aren't parsed correctly: - (add-to-list 'reftex-label-regexps - (concat "\\\\begin{\\(?:problem\\|Verbatim\\)}" - "\\[[^][]*" - "\\(?:{[^}{]*" - "\\(?:{[^}{]*" - "\\(?:{[^}{]*}[^}{]*\\)*" - "}[^}{]*\\)*" - "}[^][]*\\)*" - "\\<\\(?:ref\\)?label[[:space:]]*=[[:space:]]*" - "{?\\(?1:[^] ,}\r\n\t%]+\\)" - "[^]]*\\]") - t) - ;; Always run this after changing `reftex-label-regexps': - (reftex-compile-variables) - (find-file tex-file) - ;; Silence the user query: - (cl-letf (((symbol-function 'yes-or-no-p) #'always)) - (reftex-renumber-simple-labels)) - (should (string= (buffer-string) - "\ -\\documentclass{article} -\\usepackage{tcolorbox} -\\tcbuselibrary{theorems} -\\usepackage{fancyvrb} -\\usepackage{listings} - -\\begin{document} - -This is with tcolorbox package: -\\begin{problem}[% - colback = white , - colframe = red!50!black , - fonttitle = \\bfseries , - description delimiters = {\\flqq}{\\frqq} , - label = {problem:1}]{Prove RH2}{} - Problem -\\end{problem} - -This is with vanilla \\LaTeX: -\\begin{equation} - \\label{eq:1} - 2 -\\end{equation} -By \\eqref{eq:1} and \\ref{problem:1} - -This is with tcolorbox package: -\\begin{problem}[% - colback=white, - colframe=red!50!black, - fonttitle=\\bfseries, - theorem label supplement={hypertarget={XYZ-##1}}, - theorem full label supplement={code={\\marginnote{##1}}}, - label={problem:2}]{Prove RH1}{} - Problem -\\end{problem} - -This is with vanilla \\LaTeX: -\\begin{equation} - \\label{eq:2} - 1 -\\end{equation} - -\\Cref{problem:2} and \\pageref{eq:2}. - -\\begin{problem}[label={problem:3}]{Some Problem}{} - Problem -\\end{problem} - -\\Ref{problem:3}. - -This is with fancyvrb package: -\\begin{Verbatim}[reflabel={lst:1}] -Some Verb Content -\\end{Verbatim} - -\\pageref{lst:1} - -This is with listings package: -\\begin{lstlisting}[language=elisp,caption=Some Caption,label={lst:2}] -(car (cons 1 '(2))) -\\end{lstlisting} - -\\ref{lst:2} - -\\end{document}")) - (kill-buffer (file-name-nondirectory tex-file))))) - -;;; non-file buffers - -(ert-deftest reftex-all-used-citation-keys-buffer () - "Test `reftex-all-used-citation-keys' on a buffer without a file." - (with-temp-buffer - (insert "\ -\\documentclass{article} -\\usepackage{biblatex} -\\begin{document} - -Standard commands: -\\cite[pre][pos]{cite:2022} -\\Cite[pos]{Cite:2022} -\\parencite{parencite:2022} -\\Parencite[pre][]{Parencite:2022} -\\footcite[][]{footcite:2022} -\\footcitetext[pre][pos]{footcitetext:2022} - -Style specific commands: -\\textcite{textcite:2022} -\\Textcite[pos]{Textcite:2022} -\\smartcite[pre][pos]{smartcite:2022} -\\Smartcite[pre][]{Smartcite:2022} -\\cite*[pre][pos]{cite*:2022} -\\parencite*[][]{parencite*:2022} - -Style independent commands: -\\autocite[pre][pos]{autocite:2022} -\\autocite*[pos]{autocite*:2022} -\\Autocite[pre][]{Autocite:2022} -\\Autocite*{Autocite*:2022} - -Text commands: -\\citeauthor[pre][pos]{citeauthor:2022} -\\citeauthor*[pre][]{citeauthor*:2022} -\\Citeauthor[pos]{Citeauthor:2022} -\\Citeauthor*{Citeauthor*:2022} -\\citetitle[][]{citetitle:2022} -\\citetitle*[pre][pos]{citetitle*:2022} -\\citeyear[pre][pos]{citeyear:2022} -\\citeyear*[pre][pos]{citeyear*:2022} -\\citedate[pre][pos]{citedate:2022} -\\citedate*[pre][pos]{citedate*:2022} -\\citeurl[pre][pos]{citeurl:2022} - -Special commands: -\\nocite{nocite:2022} -\\fullcite[pos]{fullcite:2022} -\\footfullcite[][]{fullfootcite:2022} -``volcite'' macros have different number of args. -\\volcite{2}{volcite:2022} -\\Volcite[pre]{1}{Volcite:2022} -\\pvolcite{1}[pg]{pvolcite:2022} -\\Pvolcite[pre]{2}[pg]{Pvolcite:2022} -\\fvolcite[pre]{3}[pg]{fvolcite:2022} -\\ftvolcite[pre]{3}[pg]{ftvolcite:2022} -\\svolcite[pre]{2}[pg]{svolcite:2022} -\\Svolcite[pre]{4}[pg]{Svolcite:2022} -\\tvolcite[pre]{5}[pg]{tvolcite:2022} -\\Tvolcite[pre]{2}[pg]{Tvolcite:2022} -\\avolcite[pre]{3}[pg]{avolcite:2022} -\\Avolcite[pre]{1}[pg]{Avolcite:2022} -\\Notecite[pre]{Notecite:2022} -\\pnotecite[pre]{pnotecite:2022} -\\Pnotecite[pre]{Pnotecite:2022} -\\fnotecite[pre]{fnotecite:2022} - -Natbib compatibility commands: -\\citet{citet:2022} -\\citet*[pre][pos]{citet*:2022} -\\citep[pre][pos]{citep:2022} -\\citep*[pos]{citep*:2022} -\\citealt[pre][]{citealt:2022} -\\citealt*[][]{citealt*:2022} -\\citealp[pre][pos]{citealp:2022} -\\citealp*{citealp*:2022} -\\Citet[pre][pos]{Citet:2022} -\\Citet*[pre][pos]{Citet*:2022} -\\Citep[pre][pos]{Citep:2022} -\\Citep*[pre][pos]{Citep*:2022} - -Qualified Citation Lists: -\\cites(Global Prenote)(Global Postnote)[pre][post]{cites:1}[pre][post]{cites:2} -\\Cites(Global Prenote)(Global Postnote)[pre][post]{Cites:1}[pre][post]{Cites:2} -\\parencites(Global Prenote)(Global Postnote)[pre][post]{parencites:1} - [pre][post]{parencites:2} -\\Parencites(Global Prenote)(Global Postnote)[pre][post]{Parencites:1}{Parencites:2} -\\footcites[pre][post]{footcites:1}[pre][post]{footcites:2} -\\footcitetexts{footcitetexts:1}{footcitetexts:2} -\\smartcites{smartcites:1} -% This is comment about \\smartcites{smartcites:2} -[pre][post]{smartcites:2} -% And this should be ignored \\smartcites{smartcites:3}{smartcites:4} - - -Test for bug#56655: -There was a few \\% of increase in budget \\Citep*{bug:56655}. - -And this should be % \\cite{ignored}. -\\end{document}") - (tex-mode) - (let ((keys (reftex-all-used-citation-keys))) - (should (equal (sort keys #'string<) - (sort (list - ;; Standard commands: - "cite:2022" "Cite:2022" - "parencite:2022" "Parencite:2022" - "footcite:2022" "footcitetext:2022" - ;; Style specific commands: - "textcite:2022" "Textcite:2022" - "smartcite:2022" "Smartcite:2022" - "cite*:2022" "parencite*:2022" - ;; Style independent commands: - "autocite:2022" "autocite*:2022" - "Autocite:2022" "Autocite*:2022" - ;; Text commands - "citeauthor:2022" "citeauthor*:2022" - "Citeauthor:2022" "Citeauthor*:2022" - "citetitle:2022" "citetitle*:2022" - "citeyear:2022" "citeyear*:2022" - "citedate:2022" "citedate*:2022" - "citeurl:2022" - ;; Special commands: - "nocite:2022" "fullcite:2022" - "fullfootcite:2022" - "volcite:2022" "Volcite:2022" - "pvolcite:2022" "Pvolcite:2022" - "fvolcite:2022" "ftvolcite:2022" - "svolcite:2022" "Svolcite:2022" - "tvolcite:2022" "Tvolcite:2022" - "avolcite:2022" "Avolcite:2022" - "Notecite:2022" "pnotecite:2022" - "Pnotecite:2022" "fnotecite:2022" - ;; Natbib compatibility commands: - "citet:2022" "citet*:2022" - "citep:2022" "citep*:2022" - "citealt:2022" "citealt*:2022" - "citealp:2022" "citealp*:2022" - "Citet:2022" "Citet*:2022" - "Citep:2022" "Citep*:2022" - ;; Qualified Citation Lists - "cites:1" "cites:2" - "Cites:1" "Cites:2" - "parencites:1" "parencites:2" - "Parencites:1" "Parencites:2" - "footcites:1" "footcites:2" - "footcitetexts:1" "footcitetexts:2" - "smartcites:1" "smartcites:2" - "bug:56655") - #'string<)))))) - -(ert-deftest reftex-renumber-simple-labels-buffer () - "Test `reftex-renumber-simple-labels' on a buffer without a file." - (let ((temp-buffer (generate-new-buffer " *temp*"))) - (unwind-protect - (with-current-buffer temp-buffer - (insert "\ -\\documentclass{article} -\\usepackage{tcolorbox} -\\tcbuselibrary{theorems} -\\usepackage{fancyvrb} -\\usepackage{listings} - -\\begin{document} - -This is with tcolorbox package: -\\begin{problem}[% - colback = white , - colframe = red!50!black , - fonttitle = \\bfseries , - description delimiters = {\\flqq}{\\frqq} , - label = {problem:2}]{Prove RH2}{} - Problem -\\end{problem} - -This is with vanilla \\LaTeX: -\\begin{equation} - \\label{eq:2} - 2 -\\end{equation} -By \\eqref{eq:2} and \\ref{problem:2} - -This is with tcolorbox package: -\\begin{problem}[% - colback=white, - colframe=red!50!black, - fonttitle=\\bfseries, - theorem label supplement={hypertarget={XYZ-##1}}, - theorem full label supplement={code={\\marginnote{##1}}}, - label={problem:1}]{Prove RH1}{} - Problem -\\end{problem} - -This is with vanilla \\LaTeX: -\\begin{equation} - \\label{eq:1} - 1 -\\end{equation} - -\\Cref{problem:1} and \\pageref{eq:1}. - -\\begin{problem}[label={problem:6}]{Some Problem}{} - Problem -\\end{problem} - -\\Ref{problem:6}. - -This is with fancyvrb package: -\\begin{Verbatim}[reflabel={lst:6}] -Some Verb Content -\\end{Verbatim} - -\\pageref{lst:6} - -This is with listings package: -\\begin{lstlisting}[language=elisp,caption=Some Caption,label={lst:3}] -(car (cons 1 '(2))) -\\end{lstlisting} - -\\ref{lst:3} - -\\end{document}") - - ;; The label prefix must be known to RefTeX: - (add-to-list 'reftex-label-alist - '("problem" ?p "problem:" "~\\ref{%s}" - nil nil nil) - t) - (add-to-list 'reftex-label-alist - '("Verbatim" ?l "lst:" "~\\ref{%s}" - nil nil nil) - t) - ;; The environments must be known to RefTeX otherwise the labels - ;; aren't parsed correctly: - (add-to-list 'reftex-label-regexps - (concat "\\\\begin{\\(?:problem\\|Verbatim\\)}" - "\\[[^][]*" - "\\(?:{[^}{]*" - "\\(?:{[^}{]*" - "\\(?:{[^}{]*}[^}{]*\\)*" - "}[^}{]*\\)*" - "}[^][]*\\)*" - "\\<\\(?:ref\\)?label[[:space:]]*=[[:space:]]*" - "{?\\(?1:[^] ,}\r\n\t%]+\\)" - "[^]]*\\]") - t) - ;; Always run this after changing `reftex-label-regexps': - (reftex-compile-variables) - - ;; Silence the user query: - (cl-letf (((symbol-function 'yes-or-no-p) #'always)) - (reftex-renumber-simple-labels)) - - (should (string= (buffer-string) - "\ -\\documentclass{article} -\\usepackage{tcolorbox} -\\tcbuselibrary{theorems} -\\usepackage{fancyvrb} -\\usepackage{listings} - -\\begin{document} - -This is with tcolorbox package: -\\begin{problem}[% - colback = white , - colframe = red!50!black , - fonttitle = \\bfseries , - description delimiters = {\\flqq}{\\frqq} , - label = {problem:1}]{Prove RH2}{} - Problem -\\end{problem} - -This is with vanilla \\LaTeX: -\\begin{equation} - \\label{eq:1} - 2 -\\end{equation} -By \\eqref{eq:1} and \\ref{problem:1} - -This is with tcolorbox package: -\\begin{problem}[% - colback=white, - colframe=red!50!black, - fonttitle=\\bfseries, - theorem label supplement={hypertarget={XYZ-##1}}, - theorem full label supplement={code={\\marginnote{##1}}}, - label={problem:2}]{Prove RH1}{} - Problem -\\end{problem} - -This is with vanilla \\LaTeX: -\\begin{equation} - \\label{eq:2} - 1 -\\end{equation} - -\\Cref{problem:2} and \\pageref{eq:2}. - -\\begin{problem}[label={problem:3}]{Some Problem}{} - Problem -\\end{problem} - -\\Ref{problem:3}. - -This is with fancyvrb package: -\\begin{Verbatim}[reflabel={lst:1}] -Some Verb Content -\\end{Verbatim} - -\\pageref{lst:1} - -This is with listings package: -\\begin{lstlisting}[language=elisp,caption=Some Caption,label={lst:2}] -(car (cons 1 '(2))) -\\end{lstlisting} - -\\ref{lst:2} - -\\end{document}"))) - (kill-buffer temp-buffer)))) - - -;;; Autoload tests - -;; Test to check whether reftex autoloading mechanisms are working -;; correctly. -(ert-deftest reftex-autoload-auc () - "Tests to see whether reftex-auc has been autoloaded" - (should - (fboundp 'reftex-arg-label)) - (should - (autoloadp - (symbol-function - 'reftex-arg-label)))) - - -(provide 'reftex-tests) -;;; reftex-tests.el ends here. diff --git a/test/lisp/textmodes/tildify-tests.el b/test/lisp/textmodes/tildify-tests.el index 4087ddcd883..e494370b0b5 100644 --- a/test/lisp/textmodes/tildify-tests.el +++ b/test/lisp/textmodes/tildify-tests.el @@ -103,15 +103,6 @@ latter is missing, SENTENCE will be used in all placeholder positions." "\\v A % " sentence "\n" with-nbsp "\n"))) -(ert-deftest tildify-test-tex () - "Tests tildification in a (La)TeX document" - (let* ((sentence (tildify-test--example-sentence " ")) - (with-nbsp (tildify-test--example-sentence "~"))) - (tildify-test--test '(tex-mode latex-mode plain-tex-mode) - (tildify-test--example-tex sentence sentence) - (tildify-test--example-tex sentence with-nbsp)))) - - (ert-deftest tildify-test-find-env-end-re-bug () "Tests generation of end-regex using mix of indexes and strings" (with-temp-buffer @@ -219,12 +210,6 @@ The function must terminate as soon as callback returns nil." "Tests auto-tildification in an XML document" (tildify-space-test--test '(nxml-mode) " " "