--- /dev/null
+(1
+ (auctex .
+ [(11 86)
+ nil "integrated environment for *TeX*" tar])
+ (company .
+ [(0 5)
+ nil "Flexible inline text and code completion" tar])
+ (muse .
+ [(3 20)
+ nil "Authoring and publishing tool" tar])
+ (org .
+ [(20101118)
+ nil "Outline-based notes management and organizer" tar])
+ (js2-mode .
+ [(20090814)
+ nil "Improved JavaScript editing mode" single])
+ (rainbow-mode .
+ [(0 1)
+ nil "Colorize color names in buffers." single]))
+
--- /dev/null
+This is the README file for the AUCTeX distribution.
+
+ Copyright (C) 2008 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without
+ modification, are permitted in any medium without royalty provided
+ the copyright notice and this notice are preserved.
+
+Introduction to AUCTeX
+**********************
+
+This file gives a brief overview of what AUCTeX is. It is *not* an
+attempt to document AUCTeX. Real documentation for AUCTeX is available
+in the manual, which should be available as an info file after
+installation.
+
+AUCTeX is a comprehensive customizable integrated environment for
+writing input files for TeX, LaTeX, ConTeXt, Texinfo, and docTeX using
+Emacs or XEmacs.
+
+It supports you in the insertion of macros, environments, and sectioning
+commands by providing completion alternatives and prompting for
+parameters. It automatically indents your text as you type it and lets
+you format a whole file at once. The outlining and folding facilities
+provide you with a focused and clean view of your text.
+
+AUCTeX lets you process your source files by running TeX and related
+tools (such as output filters, post processors for generating indices
+and bibliographies, and viewers) from inside Emacs. AUCTeX lets you
+browse through the errors TeX reported, while it moves the cursor
+directly to the reported error, and displays some documentation for
+that particular error. This will even work when the document is spread
+over several files.
+
+One component of AUCTeX that LaTeX users will find attractive is
+preview-latex, a combination of folding and in-source previewing that
+provides true "What You See Is What You Get" experience in your
+sourcebuffer, while letting you retain full control. For more
+information, see further below.
+
+More detailed information about the features and usage of AUCTeX can be
+found in the AUCTeX manual. You can access it from within Emacs by
+typing `C-h i d m auctex <RET>'. If you prefer the standalone info
+reader, issue the command `info auctex' in a terminal.
+
+AUCTeX is written entirely in Emacs Lisp, and hence you can easily add
+new features for your own needs. It is a GNU project and distributed
+under the `GNU General Public License Version 3'.
+
+The most recent version is always available at
+`http://ftp.gnu.org/pub/gnu/auctex/'.
+
+WWW users may want to check out the AUCTeX page at
+`http://www.gnu.org/software/auctex/'.
+
+For comprehensive information about how to install AUCTeX read the file
+`INSTALL' or `INSTALL.windows', respectively.
+
+If you are considering upgrading AUCTeX, the recent changes are
+described in the `CHANGES' file.
+
+If you want to discuss AUCTeX with other users or its developers, there
+are several mailing lists you can use.
+
+Send a mail with the subject "subscribe" to <auctex-request@gnu.org> in
+order to join the general discussion list for AUCTeX. Articles should
+be sent to <auctex@gnu.org>. In a similar way, you can subscribe to
+the <info-auctex@gnu.org> list for just getting important announcements
+about AUCTeX. The list <bug-auctex@gnu.org> is for bug reports which
+you should usually file with the `M-x TeX-submit-bug-report <RET>'
+command. If you want to address the developers of AUCTeX themselves
+with technical issues, they can be found on the discussion list
+<auctex-devel@gnu.org>.
+
+preview-latex in a nutshell
+***************************
+
+Does your neck hurt from turning between previewer windows and the
+source too often? This AUCTeX component will render your displayed
+LaTeX equations right into the editing window where they belong.
+
+The purpose of preview-latex is to embed LaTeX environments such as
+display math or figures into the source buffers and switch conveniently
+between source and image representation.
+
+1 What use is it?
+*****************
+
+WYSIWYG (what you see is what you get) sometimes is considered all the
+rage, sometimes frowned upon. Do we really want it? Wrong question.
+The right question is _what_ we want from it. Except when finetuning
+the layout, we don't want to use printer fonts for on-screen text
+editing. The low resolution and contrast of a computer screen render
+all but the coarsest printer fonts (those for low-quality newsprint)
+unappealing, and the margins and pagination of the print are not wanted
+on the screen, either. On the other hand, more complex visual
+compositions like math formulas and tables can't easily be taken in
+when seen only in the source. preview-latex strikes a balance: it only
+uses graphic renditions of the output for certain, configurable
+constructs, does this only when told, and then right in the source code.
+Switching back and forth between the source and preview is easy and
+natural and can be done for each image independently. Behind the scenes
+of preview-latex, a sophisticated framework of other programs like
+`dvipng', Dvips and Ghostscript are employed together with a special
+LaTeX style file for extracting the material of interest in the
+background and providing fast interactive response.
+
+2 Activating preview-latex
+**************************
+
+After installation, the package may need to be activated (and remember
+to activate AUCTeX too). In XEmacs, and in any prepackaged versions
+worth their salt, activation should be automatic upon installation. If
+this seems not the case, complain to your installation provider.
+
+The usual activation (if it is not done automatically) would be
+
+ (load "preview-latex.el" nil t t)
+
+If you still don't get a "Preview" menu in LaTeX mode in spite of
+AUCTeX showing its "Command", your installation is broken. One
+possible cause are duplicate Lisp files that might be detectable with
+`<M-x> list-load-path-shadows <RET>'.
+
+3 Getting started
+*****************
+
+Once activated, preview-latex and its documentation will be accessible
+via its menus (note that preview-latex requires AUCTeX to be loaded).
+When you have loaded a LaTeX document (a sample document `circ.tex' is
+included in the distribution, but most documents including math and/or
+figures should do), you can use its menu or `C-c C-p C-d' (for
+`Preview/Document'). Previews will now be generated for various
+objects in your document. You can use the time to take a short look at
+the other menu entries and key bindings in the `Preview' menu. You'll
+see the previewed objects change into a roadworks sign when
+preview-latex has determined just what it is going to preview. Note
+that you can freely navigate the buffer while this is going on. When
+the process is finished you will see the objects typeset in your buffer.
+
+It is a bad idea, however, to edit the buffer before the roadworks signs
+appear, since that is the moment when the correlation between the
+original text and the buffer locations gets established. If the buffer
+changes before that point of time, the previews will not be placed where
+they belong. If you do want to change some obvious error you just
+spotted, we recommend you stop the background process by pressing `C-c
+C-k'.
+
+To see/edit the LaTeX code for a specific object, put the point (the
+cursor) on it and press `C-c C-p C-p' (for `Preview/at point'). It
+will also do to click with the middle mouse button on the preview. Now
+you can edit the code, and generate a new preview by again pressing
+`C-c C-p C-p' (or by clicking with the middle mouse button on the icon
+before the edited text).
+
+If you are using the `desktop' package, previews will remain from one
+session to the next as long as you don't kill your buffer. If you are
+using XEmacs, you will probably need to upgrade the package to the
+newest one; things are being fixed just as I am writing this.
+
+4 Basic modes of operation
+**************************
+
+preview-latex has a number of methods for generating its graphics. Its
+default operation is equivalent to using the `LaTeX' command from
+AUCTeX. If this happens to be a call of PDFLaTeX generating PDF output
+(you need at least AUCTeX 11.51 for this), then Ghostscript will be
+called directly on the resulting PDF file. If a DVI file gets
+produced, first Dvips and then Ghostscript get called by default.
+
+The image type to be generated by Ghostscript can be configured with
+
+ M-x customize-variable RET preview-image-type RET
+
+The default is `png' (the most efficient image type). A special
+setting is `dvipng' in case you have the `dvipng' program installed.
+In this case, `dvipng' will be used for converting DVI files and
+Ghostscript (with a `PNG' device) for converting PDF files. `dvipng'
+is much faster than the combination of Dvips and Ghostscript. You can
+get downloads, access to its CVS archive and further information from
+its project site (http://savannah.nongnu.org/projects/dvipng).
+
+5 More documentation
+********************
+
+After the installation, documentation in the form of an info manual
+will be available. You can access it with the standalone info reader
+with
+
+ info preview-latex
+
+or by pressing `C-h i d m preview-latex <RET>' in Emacs. Once
+preview-latex is activated, you can instead use `C-c C-p <TAB>' (or the
+menu entry `Preview/Read documentation').
+
+Depending on your installation, a printable manual may also be
+available in the form of `preview-latex.dvi' or `preview-latex.ps'.
+
+Detailed documentation for the LaTeX style used for extracting the
+preview images is placed in `preview.dvi' in a suitable directory
+during installation; on typical teTeX-based systems,
+
+ texdoc preview
+
+will display it.
+
+6 Availability
+**************
+
+The preview-latex project is now part of AUCTeX and accessible as part
+of the AUCTeX project page (http://savannah.gnu.org/projects/auctex).
+You can get its files from the AUCTeX download area
+(ftp://ftp.gnu.org/pub/gnu/auctex). As of AUCTeX 11.81, preview-latex
+should already be integrated into AUCTeX, so no separate download will
+be necessary.
+
+You will also find `.rpm' files there for Fedora and possibly SuSE.
+Anonymous CVS is available as well.
+
+7 Contacts
+**********
+
+Bug reports should be sent by using `M-x preview-report-bug <RET>', as
+this will fill in a lot of information interesting to us. If the
+installation fails (but this should be a rare event), report bugs to
+<bug-auctex@gnu.org>.
+
+There is a general discussion list for AUCTeX which also covers
+preview-latex, look at `http://lists.gnu.org/mailman/listinfo/auctex'.
+For more information on the mailing list, send a message with just the
+word "help" as subject or body to <auctex-request@gnu.org>. For the
+developers, there is the <auctex-devel@gnu.org> list; it would probably
+make sense to direct feature requests and questions about internal
+details there. There is a low-volume read-only announcement list
+available to which you can subscribe by sending a mail with "subscribe"
+in the subject to <info-auctex-request@gnu.org>.
+
+Offers to support further development will be appreciated. If you want
+to show your appreciation with a donation to the main developer, you can
+do so via PayPal to <dak@gnu.org>, and of course you can arrange for
+service contracts or for added functionality. Take a look at the
+`TODO' list for suggestions in that area.
+
--- /dev/null
+(define-package "auctex" "11.86" "integrated environment for *TeX*")
--- /dev/null
+This is auctex.info, produced by makeinfo version 4.13 from auctex.texi.
+
+This manual is for AUCTeX (version 11.86 from 2010-02-21), a
+sophisticated TeX environment for Emacs.
+
+ Copyright (C) 1992, 1993, 1994, 1995, 2001, 2002, 2004, 2005, 2006,
+2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ 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, no Front-Cover Texts and
+ no Back-Cover Texts. A copy of the license is included in the
+ section entitled "GNU Free Documentation License."
+
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* AUCTeX: (auctex). A sophisticated TeX environment for Emacs.
+END-INFO-DIR-ENTRY
+INFO-DIR-SECTION TeX
+START-INFO-DIR-ENTRY
+* AUCTeX: (auctex). A sophisticated TeX environment for Emacs.
+END-INFO-DIR-ENTRY
+
+\1f
+Indirect:
+auctex.info-1: 961
+auctex.info-2: 291546
+\1f
+Tag Table:
+(Indirect)
+Node: Top\7f961
+Node: Copying\7f6965
+Node: Introduction\7f8921
+Node: Summary\7f9191
+Node: Installation\7f11935
+Node: Prerequisites\7f12901
+Node: Configure\7f15930
+Node: Build/install\7f21352
+Node: Loading the package\7f21843
+Node: Advice for package providers\7f23650
+Node: Advice for non-privileged users\7f27598
+Node: Installation under MS Windows\7f31555
+Node: Customizing\7f46789
+Node: Quick Start\7f48372
+Ref: Quick Start-Footnote-1\7f50165
+Node: Editing Facilities\7f50312
+Node: Processing Facilities\7f55108
+Node: Editing\7f59002
+Node: Quotes\7f60237
+Node: Font Specifiers\7f63978
+Node: Sectioning\7f65804
+Node: Environments\7f70118
+Node: Equations\7f72484
+Node: Floats\7f73075
+Node: Itemize-like\7f74614
+Node: Tabular-like\7f75156
+Node: Customizing Environments\7f75785
+Node: Mathematics\7f76025
+Node: Completion\7f78952
+Node: Commenting\7f83017
+Node: Indenting\7f84345
+Node: Filling\7f90138
+Node: Display\7f95459
+Node: Font Locking\7f96772
+Node: Fontification of macros\7f98847
+Node: Fontification of quotes\7f108294
+Node: Fontification of math\7f109789
+Node: Verbatim content\7f111509
+Node: Faces\7f112283
+Node: Known problems\7f112772
+Node: Folding\7f113700
+Node: Outline\7f124133
+Node: Processing\7f125387
+Node: Commands\7f126550
+Node: Starting a Command\7f127106
+Node: Selecting a Command\7f130849
+Node: Processor Options\7f133731
+Node: Viewing\7f139415
+Node: Starting Viewers\7f139789
+Node: I/O Correlation\7f145957
+Node: Debugging\7f148330
+Node: Checking\7f149844
+Node: Control\7f151148
+Node: Cleaning\7f151877
+Node: Documentation\7f153090
+Node: Customization\7f153870
+Node: Modes and Hooks\7f154363
+Node: Multifile\7f155571
+Node: Parsing Files\7f160282
+Node: Internationalization\7f164687
+Node: European\7f165868
+Node: Japanese\7f172689
+Node: Automatic\7f174386
+Node: Automatic Global\7f176910
+Node: Automatic Private\7f178071
+Node: Automatic Local\7f179384
+Node: Style Files\7f180471
+Node: Simple Style\7f181264
+Node: Adding Macros\7f182355
+Node: Adding Environments\7f187859
+Node: Adding Other\7f192128
+Node: Hacking the Parser\7f192715
+Node: Appendices\7f196588
+Node: Copying this Manual\7f196839
+Node: GNU Free Documentation License\7f197762
+Node: Changes\7f222900
+Node: Development\7f246154
+Node: Mid-term Goals\7f246800
+Node: Wishlist\7f248362
+Node: Bugs\7f255300
+Node: FAQ\7f256695
+Node: Indices\7f262843
+Node: Key Index\7f263006
+Node: Function Index\7f268016
+Node: Variable Index\7f275687
+Node: Concept Index\7f291546
+\1f
+End Tag Table
--- /dev/null
+This is auctex.info, produced by makeinfo version 4.13 from auctex.texi.
+
+This manual is for AUCTeX (version 11.86 from 2010-02-21), a
+sophisticated TeX environment for Emacs.
+
+ Copyright (C) 1992, 1993, 1994, 1995, 2001, 2002, 2004, 2005, 2006,
+2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ 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, no Front-Cover Texts and
+ no Back-Cover Texts. A copy of the license is included in the
+ section entitled "GNU Free Documentation License."
+
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* AUCTeX: (auctex). A sophisticated TeX environment for Emacs.
+END-INFO-DIR-ENTRY
+INFO-DIR-SECTION TeX
+START-INFO-DIR-ENTRY
+* AUCTeX: (auctex). A sophisticated TeX environment for Emacs.
+END-INFO-DIR-ENTRY
+
+\1f
+File: auctex.info, Node: Top, Next: Copying, Up: (dir)
+
+AUCTeX
+******
+
+This manual may be copied under the conditions spelled out in *note
+Copying this Manual::.
+
+ AUCTeX is an integrated environment for editing LaTeX, ConTeXt,
+docTeX, Texinfo, and TeX files.
+
+ Although AUCTeX contains a large number of features, there are no
+reasons to despair. You can continue to write TeX and LaTeX documents
+the way you are used to, and only start using the multiple features in
+small steps. AUCTeX is not monolithic, each feature described in this
+manual is useful by itself, but together they provide an environment
+where you will make very few LaTeX errors, and makes it easy to find
+the errors that may slip through anyway.
+
+ It is a good idea to make a printout of AUCTeX's reference card
+`tex-ref.tex' or one of its typeset versions.
+
+ If you want to make AUCTeX aware of style files and multi-file
+documents right away, insert the following in your `.emacs' file.
+
+ (setq TeX-auto-save t)
+ (setq TeX-parse-self t)
+ (setq-default TeX-master nil)
+
+ Another thing you should enable is RefTeX, a comprehensive solution
+for managing cross references, bibliographies, indices, document
+navigation and a few other things. (*note Installation:
+(reftex)Installation.)
+
+ For detailed information about the preview-latex subsystem of
+AUCTeX, see *note Introduction: (preview-latex)Top.
+
+ There is a mailing list for general discussion about AUCTeX: write a
+mail with "subscribe" in the subject to <auctex-request@gnu.org> to
+join it. Send contributions to <auctex@gnu.org>.
+
+ Bug reports should go to <bug-auctex@gnu.org>, suggestions for new
+features, and pleas for help should go to either <auctex-devel@gnu.org>
+(the AUCTeX developers), or to <auctex@gnu.org> if they might have
+general interest. Please use the command `M-x TeX-submit-bug-report
+RET' to report bugs if possible. You can subscribe to a low-volume
+announcement list by sending "subscribe" in the subject of a mail to
+<info-auctex-request@gnu.org>.
+
+* Menu:
+
+* Copying:: Copying
+* Introduction:: Introduction to AUCTeX
+* Editing:: Editing the Document Source
+* Display:: Controlling Screen Display
+* Processing:: Starting Processors, Viewers and Other Programs
+* Customization:: Customization and Extension
+* Appendices:: Copying, Changes, Development, FAQ
+* Indices:: Indices
+
+ --- The Detailed Node Listing ---
+
+Introduction
+
+* Summary:: Overview of AUCTeX
+* Installation:: Installing AUCTeX
+* Quick Start:: Quick Start
+
+Editing the Document Source
+
+* Quotes:: Inserting double quotes
+* Font Specifiers:: Inserting Font Specifiers
+* Sectioning:: Inserting chapters, sections, etc.
+* Environments:: Inserting Environment Templates
+* Mathematics:: Entering Mathematics
+* Completion:: Completion of macros
+* Commenting:: Commenting text
+* Indenting:: Reflecting syntactic constructs with whitespace
+* Filling:: Automatic and manual line breaking
+
+Inserting Environment Templates
+
+* Equations:: Equations
+* Floats:: Floats
+* Itemize-like:: Itemize-like Environments
+* Tabular-like:: Tabular-like Environments
+* Customizing Environments:: Customizing Environments
+
+Controlling Screen Display
+
+* Font Locking:: Font Locking
+* Folding:: Folding Macros and Environments
+* Outline:: Outlining the Document
+
+Font Locking
+
+* Fontification of macros:: Fontification of macros
+* Fontification of quotes:: Fontification of quotes
+* Fontification of math:: Fontification of math constructs
+* Verbatim content:: Verbatim macros and environments
+* Faces:: Faces used by font-latex
+
+Starting Processors, Viewers and Other Programs
+
+* Commands:: Invoking external commands.
+* Viewing:: Invoking external viewers.
+* Debugging:: Debugging TeX and LaTeX output.
+* Checking:: Checking the document.
+* Control:: Controlling the processes.
+* Cleaning:: Cleaning intermediate and output files.
+* Documentation:: Documentation about macros and packages.
+
+Viewing the Formatted Output
+
+* Starting Viewers:: Starting viewers
+* I/O Correlation:: Forward and inverse search
+
+Customization and Extension
+
+* Multifile:: Multifile Documents
+* Parsing Files:: Automatic Parsing of TeX Files
+* Internationalization:: Language Support
+* Automatic:: Automatic Customization
+* Style Files:: Writing Your Own Style Support
+
+Language Support
+
+* European:: Using AUCTeX with European Languages
+* Japanese:: Using AUCTeX with Japanese
+
+Automatic Customization
+
+* Automatic Global:: Automatic Customization for the Site
+* Automatic Private:: Automatic Customization for a User
+* Automatic Local:: Automatic Customization for a Directory
+
+Writing Your Own Style Support
+
+* Simple Style:: A Simple Style File
+* Adding Macros:: Adding Support for Macros
+* Adding Environments:: Adding Support for Environments
+* Adding Other:: Adding Other Information
+* Hacking the Parser:: Automatic Extraction of New Things
+
+Copying, Changes, Development, FAQ
+
+* Copying this Manual::
+* Changes::
+* Development::
+* FAQ::
+
+Copying this Manual
+
+* GNU Free Documentation License:: License for copying this manual.
+
+Indices
+
+* Key Index::
+* Function Index::
+* Variable Index::
+* Concept Index::
+
+\1f
+File: auctex.info, Node: Copying, Next: Introduction, Prev: Top, Up: Top
+
+Copying
+*******
+
+AUCTeX primarily consists of Lisp files for Emacs (and XEmacs), but
+there are also installation scripts and files and TeX support files.
+All of those are "free"; this means that everyone is free to use them
+and free to redistribute them on a free basis. The files of AUCTeX are
+not in the public domain; they are copyrighted and there are
+restrictions on their distribution, but these restrictions are designed
+to permit everything that a good cooperating citizen would want to do.
+What is not allowed is to try to prevent others from further sharing
+any version of these programs that they might get from you.
+
+ Specifically, we want to make sure that you have the right to give
+away copies of the files that constitute AUCTeX, that you receive source
+code or else can get it if you want it, that you can change these files
+or use pieces of them in new free programs, and that you know you can do
+these things.
+
+ To make sure that everyone has such rights, we have to forbid you to
+deprive anyone else of these rights. For example, if you distribute
+copies of parts of AUCTeX, you must give the recipients all the rights
+that you have. You must make sure that they, too, receive or can get
+the source code. And you must tell them their rights.
+
+ Also, for our own protection, we must make certain that everyone
+finds out that there is no warranty for AUCTeX. If any parts are
+modified by someone else and passed on, we want their recipients to
+know that what they have is not what we distributed, so that any
+problems introduced by others will not reflect on our reputation.
+
+ The precise conditions of the licenses for the files currently being
+distributed as part of AUCTeX are found in the General Public Licenses
+that accompany them. This manual specifically is covered by the GNU
+Free Documentation License (*note Copying this Manual::).
+
+\1f
+File: auctex.info, Node: Introduction, Next: Editing, Prev: Copying, Up: Top
+
+1 Introduction
+**************
+
+* Menu:
+
+* Summary:: Overview of AUCTeX
+* Installation:: Installing AUCTeX
+* Quick Start:: Quick Start
+
+\1f
+File: auctex.info, Node: Summary, Next: Installation, Up: Introduction
+
+1.1 Overview of AUCTeX
+======================
+
+ AUCTeX is a comprehensive customizable integrated environment for
+writing input files for TeX, LaTeX, ConTeXt, Texinfo, and docTeX using
+Emacs or XEmacs.
+
+ It supports you in the insertion of macros, environments, and
+sectioning commands by providing completion alternatives and prompting
+for parameters. It automatically indents your text as you type it and
+lets you format a whole file at once. The outlining and folding
+facilities provide you with a focused and clean view of your text.
+
+ AUCTeX lets you process your source files by running TeX and related
+tools (such as output filters, post processors for generating indices
+and bibliographies, and viewers) from inside Emacs. AUCTeX lets you
+browse through the errors TeX reported, while it moves the cursor
+directly to the reported error, and displays some documentation for
+that particular error. This will even work when the document is spread
+over several files.
+
+ One component of AUCTeX that LaTeX users will find attractive is
+preview-latex, a combination of folding and in-source previewing that
+provides true "What You See Is What You Get" experience in your
+sourcebuffer, while letting you retain full control.
+
+ More detailed information about the features and usage of AUCTeX can
+be found in the remainder of this manual.
+
+ AUCTeX is written entirely in Emacs Lisp, and hence you can easily
+add new features for your own needs. It is a GNU project and
+distributed under the `GNU General Public License Version 3'.
+
+ The most recent version is always available at
+`http://ftp.gnu.org/pub/gnu/auctex/'.
+
+ WWW users may want to check out the AUCTeX page at
+`http://www.gnu.org/software/auctex/'.
+
+ For comprehensive information about how to install AUCTeX *Note
+Installation::, or *note Installation under MS Windows::, respectively.
+
+ If you are considering upgrading AUCTeX, the recent changes are
+described in *note Changes::.
+
+ If you want to discuss AUCTeX with other users or its developers,
+there are several mailing lists you can use.
+
+ Send a mail with the subject "subscribe" to <auctex-request@gnu.org>
+in order to join the general discussion list for AUCTeX. Articles
+should be sent to <auctex@gnu.org>. In a similar way, you can
+subscribe to the <info-auctex@gnu.org> list for just getting important
+announcements about AUCTeX. The list <bug-auctex@gnu.org> is for bug
+reports which you should usually file with the `M-x
+TeX-submit-bug-report <RET>' command. If you want to address the
+developers of AUCTeX themselves with technical issues, they can be
+found on the discussion list <auctex-devel@gnu.org>.
+
+\1f
+File: auctex.info, Node: Installation, Next: Quick Start, Prev: Summary, Up: Introduction
+
+1.2 Installing AUCTeX
+=====================
+
+ Installing AUCTeX should be simple: merely `./configure', `make',
+and `make install' for a standard site-wide installation (most other
+installations can be done by specifying a `--prefix=...' option).
+
+ On many systems, this will already activate the package, making its
+modes the default instead of the built-in modes of Emacs. If this is
+not the case, consult *note Loading the package::. Please read through
+this document fully before installing anything. The installation
+procedure has changed as compared to earlier versions. Users of
+MS Windows are asked to consult *Note Installation under MS Windows::.
+
+* Menu:
+
+* Prerequisites::
+* Configure::
+* Build/install::
+* Loading the package::
+* Advice for package providers::
+* Advice for non-privileged users::
+* Installation under MS Windows::
+* Customizing::
+
+\1f
+File: auctex.info, Node: Prerequisites, Next: Configure, Up: Installation
+
+1.2.1 Prerequisites
+-------------------
+
+ * A recent version of Emacs, alternatively XEmacs
+
+ Emacs 20 is no longer supported, and neither is XEmacs with a
+ version of `xemacs-base' older than 1.84 (released in sumo from
+ 02/02/2004). Using preview-latex requires a version of Emacs
+ compiled with image support. While the X11 version of Emacs 21
+ will likely work, Emacs 22 and later is the preferred platform.
+
+ Windows
+ Precompiled versions are available from
+ `ftp://ftp.gnu.org/gnu/emacs/windows/'.
+
+ Mac OS X
+ For an overview of precompiled versions of Emacs for Mac OS X
+ see for example
+ `http://www.emacswiki.org/cgi-bin/wiki/EmacsForMacOS'.
+
+ GNU/Linux
+ Most GNU/Linux distributions nowadays provide a variant of
+ Emacs 22 or later via their package repositories.
+
+ Self-compiled
+ Compiling Emacs yourself requires a C compiler and a number
+ of tools and development libraries. Details are beyond the
+ scope of this manual. Instructions for checking out the
+ source code can be found at
+ `https://savannah.gnu.org/bzr/?group=emacs'.
+
+ If you really need to use Emacs 21 on platforms where this implies
+ missing image support, you should disable the installation of
+ preview-latex (see below).
+
+ While XEmacs (version 21.4.15, 21.4.17 or later) is supported,
+ doing this in a satisfactory manner has proven to be difficult.
+ This is mostly due to technical shortcomings and differing API's
+ which are hard to come by. If AUCTeX is your main application for
+ XEmacs, you are likely to get better results and support by
+ switching to Emacs. Of course, you can improve support for your
+ favorite editor by giving feedback in case you encounter bugs.
+
+ * A working TeX installation
+
+ Well, AUCTeX would be pointless without that. Processing
+ documentation requires TeX, LaTeX and Texinfo during installation.
+ preview-latex requires Dvips for its operation in DVI mode. The
+ default configuration of AUCTeX is tailored for teTeX or
+ TeXlive-based distributions, but can be adapted easily.
+
+ * A recent Ghostscript
+
+ This is needed for operation of preview-latex in both DVI and PDF
+ mode. Most versions of Ghostscript nowadays in use should work
+ fine (version 7.0 and newer). If you encounter problems, check
+ *note Problems with Ghostscript: (preview-latex)Problems with
+ Ghostscript.
+
+ * The `texinfo' package
+
+ Strictly speaking, you can get away without it if you are building
+ from the distribution tarball, have not modified any files and
+ don't need a printed version of the manual: the pregenerated info
+ file is included in the tarball. At least version 4.0 is required.
+
+
+ For some known issues with various software, see *note Known
+problems: (preview-latex)Known problems.
+
+\1f
+File: auctex.info, Node: Configure, Next: Build/install, Prev: Prerequisites, Up: Installation
+
+1.2.2 Configure
+---------------
+
+The first step is to configure the source code, telling it where
+various files will be. To do so, run
+
+ ./configure OPTIONS
+
+ (Note: if you have fetched AUCTeX from CVS rather than a regular
+release, you will have to first follow the instructions in
+`README.CVS').
+
+ On many machines, you will not need to specify any options, but if
+`configure' cannot determine something on its own, you'll need to help
+it out with one of these options:
+
+`--prefix=`/usr/local''
+ All automatic placements for package components will be chosen from
+ sensible existing hierarchies below this: directories like `man',
+ `share' and `bin' are supposed to be directly below PREFIX.
+
+ Only if no workable placement can be found there, in some cases an
+ alternative search will be made in a prefix deduced from a suitable
+ binary.
+
+ `/usr/local' is the default PREFIX, intended to be suitable for a
+ site-wide installation. If you are packaging this as an operating
+ system component for distribution, the setting `/usr' will
+ probably be the right choice. If you are planning to install the
+ package as a single non-priviledged user, you will typically set
+ PREFIX to your home directory.
+
+`--with-emacs[=/PATH/TO/EMACS]'
+ If you are using a pretest which isn't in your `$PATH', or
+ `configure' is not finding the right Emacs executable, you can
+ specify it with this option.
+
+`--with-xemacs[=/PATH/TO/XEMACS]'
+ Configure for generation under XEmacs (Emacs is the default).
+ Again, the name of the right XEmacs executable can be specified,
+ complete with path if necessary.
+
+`--with-packagedir=/DIR'
+ This XEmacs-only option configures the directory for XEmacs
+ packages. A typical user-local setting would be
+ `~/.xemacs/xemacs-packages'. If this directory exists and is
+ below PREFIX, it should be detected automatically. This will
+ install and activate the package.
+
+`--without-packagedir'
+ This XEmacs-only option switches the detection of a package
+ directory and corresponding installation off. Consequently, the
+ Emacs installation scheme will be used. This might be appropriate
+ if you are using a different package system/installer than the
+ XEmacs one and want to avoid conflicts.
+
+ The Emacs installation scheme has the following options:
+
+`--with-lispdir=/DIR'
+ This Emacs-only option specifies the location of the `site-lisp'
+ directory within `load-path' under which the files will get
+ installed (the bulk will get installed in a subdirectory).
+ `./configure' should figure this out by itself.
+
+`--with-auctexstartfile=`auctex.el''
+`--with-previewstartfile=`preview-latex.el''
+ This is the name of the respective startup files. If LISPDIR
+ contains a subdirectory `site-start.d', the start files are placed
+ there, and `site-start.el' should load them automatically. Please
+ be aware that you must not move the start files after installation
+ since other files are found _relative_ to them.
+
+`--with-packagelispdir=`auctex''
+ This is the directory where the bulk of the package gets located.
+ The startfile adds this into LOAD-PATH.
+
+`--with-auto-dir=/DIR'
+ You can use this option to specify the directory containing
+ automatically generated information. It is not necessary for most
+ TeX installs, but may be used if you don't like the directory that
+ configure is suggesting.
+
+`--help'
+ This is not an option specific to AUCTeX. A number of standard
+ options to `configure' exist, and we do not have the room to
+ describe them here; a short description of each is available, using
+ `--help'. If you use `--help=recursive', then also
+ preview-latex-specific options will get listed.
+
+`--disable-preview'
+ This disables configuration and installation of preview-latex.
+ This option is not actually recommended. If your Emacs does not
+ support images, you should really upgrade to a newer version.
+ Distributors should, if possible, refrain from distributing AUCTeX
+ and preview-latex separately in order to avoid confusion and
+ upgrade hassles if users install partial packages on their own.
+
+`--with-texmf-dir=/DIR
+ --without-texmf-dir'
+ This option is used for specifying a TDS-compliant directory
+ hierarchy. Using `--with-texmf-dir=/DIR' you can specify where
+ the TeX TDS directory hierarchy resides, and the TeX files will
+ get installed in `/DIR/tex/latex/preview/'.
+
+ If you use the `--without-texmf-dir' option, the TeX-related files
+ will be kept in the Emacs Lisp tree, and at runtime the
+ `TEXINPUTS' environment variable will be made to point there. You
+ can install those files into your own TeX tree at some later time
+ with `M-x preview-install-styles RET'.
+
+`--with-tex-dir=/DIR'
+ If you want to specify an exact directory for the preview TeX
+ files, use `--with-tex-dir=/DIR'. In this case, the files will be
+ placed in `/DIR', and you'll also need the following option:
+
+`--with-doc-dir=/DIR'
+ This option may be used to specify where the TeX documentation
+ goes. It is to be used when you are using `--with-tex-dir=/DIR',
+ but is normally not necessary otherwise.
+
+\1f
+File: auctex.info, Node: Build/install, Next: Loading the package, Prev: Configure, Up: Installation
+
+1.2.3 Build/install
+-------------------
+
+Once `configure' has been run, simply enter
+
+ make
+
+at the prompt to byte-compile the lisp files, extract the TeX files and
+build the documentation files. To install the files into the locations
+chosen earlier, type
+
+ make install
+
+ You may need special privileges to install, e.g., if you are
+installing into system directories.
+
+\1f
+File: auctex.info, Node: Loading the package, Next: Advice for package providers, Prev: Build/install, Up: Installation
+
+1.2.4 Loading the package
+-------------------------
+
+You can detect the successful activation of AUCTeX and preview-latex in
+the menus after loading a LaTeX file like `preview/circ.tex': AUCTeX
+then gives you a `Command' menu, and preview-latex gives you a
+`Preview' menu.
+
+ For XEmacs, if the installation occured into a valid package
+directory (which is the default), then this should work out of the box.
+
+ With Emacs (or if you explicitly disabled use of the package system),
+the startup files `auctex.el' and `preview-latex.el' may already be in
+a directory of the `site-start.d/' variety if your Emacs installation
+provides it. In that case they should be automatically loaded on
+startup and nothing else needs to be done. If not, they should at
+least have been placed somewhere in your `load-path'. You can then
+load them by placing the lines
+
+ (load "auctex.el" nil t t)
+ (load "preview-latex.el" nil t t)
+
+ into your init file.
+
+ If you explicitly used `--with-lispdir', you may need to add the
+specified directory into Emacs' `load-path' variable by adding
+something like
+
+ (add-to-list 'load-path "~/elisp")
+
+ before the above lines into your Emacs startup file.
+
+ For site-wide activation in GNU Emacs, see *Note Advice for package
+providers::.
+
+ Once activated, the modes provided by AUCTeX are used per default for
+all supported file types. If you want to change the modes for which it
+is operative instead of the default, use
+ M-x customize-variable <RET> TeX-modes <RET>
+
+ If you want to remove a preinstalled AUCTeX completely before any of
+its modes have been used,
+ (unload-feature 'tex-site)
+ should accomplish that.
+
+\1f
+File: auctex.info, Node: Advice for package providers, Next: Advice for non-privileged users, Prev: Loading the package, Up: Installation
+
+1.2.5 Providing AUCTeX as a package
+-----------------------------------
+
+As a package provider, you should make sure that your users will be
+served best according to their intentions, and keep in mind that a
+system might be used by more than one user, with different preferences.
+
+ There are people that prefer the built-in Emacs modes for editing
+TeX files, in particular plain TeX users. There are various ways to
+tell AUCTeX even after auto-activation that it should not get used, and
+they are described in *note Introduction to AUCTeX: Introduction.
+
+ So if you have users that don't want to use the preinstalled AUCTeX,
+they can easily get rid of it. Activating AUCTeX by default is
+therefore a good choice.
+
+ If the installation procedure did not achieve this already by placing
+`auctex.el' and `preview-latex.el' into a possibly existing
+`site-start.d' directory, you can do this by placing
+
+ (load "auctex.el" nil t t)
+ (load "preview-latex.el" nil t t)
+
+in the system-wide `site-start.el'.
+
+ If your package is intended as an XEmacs package or to accompany a
+precompiled version of Emacs, you might not know which TeX system will
+be available when preview-latex gets used. In this case you should
+build using the `--without-texmf-dir' option described previously.
+This can also be convenient for systems that are intended to support
+more than a single TeX distribution. Since more often than not TeX
+packages for operating system distributions are either much more
+outdated or much less complete than separately provided systems like
+TeX Live, this method may be generally preferable when providing
+packages.
+
+ The following package structure would be adequate for a typical fully
+supported Unix-like installation:
+
+`preview-tetex'
+ Style files and documentation for `preview.sty', placed into a TeX
+ tree where it is accessible from the teTeX executables usually
+ delivered with a system. If there are other commonly used TeX
+ system packages, it might be appropriate to provide separate
+ packages for those.
+
+`auctex-emacs-tetex'
+ This package will require the installation of `preview-tetex' and
+ will record in `TeX-macro-global' where to find the TeX tree. It
+ is also a good idea to run
+ emacs -batch -f TeX-auto-generate-global
+ when either AUCTeX or teTeX get installed or upgraded. If your
+ users might want to work with a different TeX distribution
+ (nowadays pretty common), instead consider the following:
+
+`auctex-emacs'
+ This package will be compiled with `--without-texmf-dir' and will
+ consequently contain the `preview' style files in its private
+ directory. It will probably not be possible to initialize
+ `TeX-macro-global' to a sensible value, so running
+ `TeX-auto-generate-global' does not appear useful. This package
+ would neither conflict with nor provide `preview-tetex'.
+
+`auctex-xemacs-tetex'
+`auctex-xemacs'
+ Those are the obvious XEmacs equivalents. For XEmacs, there is the
+ additional problem that the XEmacs sumo package tree already
+ possibly provides its own version of AUCTeX, and the user might
+ even have used the XEmacs package manager to updating this
+ package, or even installing a private AUCTeX version. So you
+ should make sure that such a package will not conflict with
+ existing XEmacs packages and will be at an appropriate place in
+ the load order (after site-wide and user-specific locations, but
+ before a distribution-specific sumo package tree). Using the
+ `--without-packagedir' option might be one idea to avoid
+ conflicts. Another might be to refrain from providing an XEmacs
+ package and just rely on the user or system administrator to
+ instead use the XEmacs package system.
+
+\1f
+File: auctex.info, Node: Advice for non-privileged users, Next: Installation under MS Windows, Prev: Advice for package providers, Up: Installation
+
+1.2.6 Installation for non-privileged users
+-------------------------------------------
+
+Often people without system administration privileges want to install
+software for their private use. In that case you need to pass more
+options to the `configure' script. For XEmacs users, this is fairly
+easy, because the XEmacs package system has been designed to make this
+sort of thing practical: but GNU Emacs users (and XEmacs users for whom
+the package system is for some reason misbehaving) may need to do a
+little more work.
+
+ The main expedient is using the `--prefix' option to the `configure'
+script, and let it point to the personal home directory. In that way,
+resulting binaries will be installed under the `bin' subdirectory of
+your home directory, manual pages under `man' and so on. It is
+reasonably easy to maintain a bunch of personal software, since the
+prefix argument is supported by most `configure' scripts.
+
+ You'll have to add something like
+`/home/myself/share/emacs/site-lisp' to your `load-path' variable, if
+it isn't there already.
+
+ XEmacs users can achieve the same end by pointing `configure' at an
+appropriate package directory (normally
+`--with-packagedir=~/.xemacs/xemacs-packages' will serve). The package
+directory stands a good chance at being detected automatically as long
+as it is in a subtree of the specified PREFIX.
+
+ Now here is another thing to ponder: perhaps you want to make it easy
+for other users to share parts of your personal Emacs configuration. In
+general, you can do this by writing `~myself/' anywhere where you
+specify paths to something installed in your personal subdirectories,
+not merely `~/', since the latter, when used by other users, will point
+to non-existent files.
+
+ For yourself, it will do to manipulate environment variables in your
+`.profile' resp. `.login' files. But if people will be copying just
+Elisp files, their copies will not work. While it would in general be
+preferable if the added components where available from a shell level,
+too (like when you call the standalone info reader, or try using
+`preview.sty' for functionality besides of Emacs previews), it will be
+a big help already if things work from inside of Emacs.
+
+ Here is how to do the various parts:
+
+Making the Elisp available
+..........................
+
+In GNU Emacs, it should be sufficient if people just do
+
+ (load "~myself/share/emacs/site-lisp/auctex.el" nil t t)
+ (load "~myself/share/emacs/site-lisp/preview-latex.el" nil t t)
+
+ where the path points to your personal installation. The rest of the
+package should be found relative from there without further ado.
+
+ In XEmacs, you should ask the other users to add symbolic links in
+the subdirectories `lisp', `info' and `etc' of their
+`~/.xemacs/xemacs-packages/' directory. (Alas, there is presently no
+easy programmatic way to do this, except to have a script do the
+symlinking for them.)
+
+Making the Info files available
+...............................
+
+For making the info files accessible from within Elisp, something like
+the following might be convenient to add into your or other people's
+startup files:
+
+ (eval-after-load 'info
+ '(add-to-list 'Info-directory-list "~myself/info"))
+
+ In XEmacs, as long as XEmacs can see the package, there should be no
+need to do anything at all; the info files should be immediately
+visible. However, you might want to set `INFOPATH' anyway, for the
+sake of standalone readers outside of XEmacs. (The info files in XEmacs
+are normally in `~/.xemacs/xemacs-packages/info'.)
+
+Making the LaTeX style available
+................................
+
+If you want others to be able to share your installation, you should
+configure it using `--without-texmf-dir', in which case things should
+work as well for them as for you.
+
+\1f
+File: auctex.info, Node: Installation under MS Windows, Next: Customizing, Prev: Advice for non-privileged users, Up: Installation
+
+1.2.7 Installation under MS Windows
+-----------------------------------
+
+In a Nutshell
+.............
+
+The following are brief installation instructions for the impatient. In
+case you don't understand some of this, run into trouble of some sort,
+or need more elaborate information, refer to the detailed instructions
+further below.
+
+ 1. Install the prerequisites, i.e. Emacs or XEmacs, MSYS or Cygwin, a
+ TeX system, and Ghostscript.
+
+ 2. Open the MSYS shell or a Cygwin shell and change to the directory
+ containing the unzipped file contents.
+
+ 3. Configure AUCTeX:
+
+ For Emacs: Many people like to install AUCTeX into the pseudo file
+ system hierarchy set up by the Emacs installation. Assuming Emacs
+ is installed in `C:/Program Files/Emacs' and the directory for
+ local additions of your TeX system, e.g. MiKTeX, is
+ `C:/localtexmf', you can do this by typing the following statement
+ at the shell prompt:
+
+ ./configure --prefix='C:/Program Files/Emacs' \
+ --infodir='C:/Program Files/Emacs/info' \
+ --with-texmf-dir='C:/localtexmf'
+
+ For XEmacs: You can install AUCTeX as an XEmacs package. Assuming
+ XEmacs is installed in `C:/Program Files/XEmacs' and the directory
+ for local additions of your TeX system, e.g. MiKTeX, is
+ `C:/localtexmf', you can do this by typing the following command at
+ the shell prompt:
+
+ ./configure --with-xemacs='C:/Program Files/XEmacs/bin/xemacs' \
+ --with-texmf-dir='C:/localtexmf'
+
+ The commands above are examples for common usage. More on
+ configuration options can be found in the detailed installation
+ instructions below.
+
+ If the configuration script failed to find all required programs,
+ make sure that these programs are in your system path and add
+ directories containing the programs to the `PATH' environment
+ variable if necessary. Here is how to do that in W2000/XP:
+
+ 1. On the desktop, right click "My Computer" and select
+ properties.
+
+ 2. Click on "Advanced" in the "System Properties" window.
+
+ 3. Select "Environment Variables".
+
+ 4. Select "path" in "System Variables" and click "edit". Move
+ to the front in the line (this might require scrolling) and
+ add the missing path including drive letter, ended with a
+ semicolon.
+
+ 4. If there were no further error messages, type
+
+ make
+
+ In case there were, please refer to the detailed description below.
+
+ 5. Finish the installation by typing
+
+ make install
+
+Detailed Installation Instructions
+..................................
+
+Installation of AUCTeX under Windows is in itself not more complicated
+than on other platforms. However, meeting the prerequisites might
+require more work than on some other platforms, and feel less natural.
+
+ If you are experiencing any problems, even if you think they are of
+your own making, be sure to report them to <auctex-devel@gnu.org> so
+that we can explain things better in future.
+
+ Windows is a problematic platform for installation scripts. The main
+problem is that the installation procedure requires consistent file
+names in order to find its way in the directory hierarchy, and Windows
+path names are a mess.
+
+ The installation procedure tries finding stuff in system search paths
+and in Emacs paths. For that to succeed, you have to use the same
+syntax and spelling and case of paths everywhere: in your system search
+paths, in Emacs' `load-path' variable, as argument to the scripts. If
+your path names contain spaces or other `shell-unfriendly' characters,
+most notably backslashes for directory separators, place the whole path
+in `"double quote marks"' whenever you specify it on a command line.
+
+ Avoid `helpful' magic file names like `/cygdrive/c' and
+`C:\PROGRA~1\' like the plague. It is quite unlikely that the scripts
+will be able to identify the actual file names involved. Use the full
+paths, making use of normal Windows drive letters like ` 'C:/Program
+Files/Emacs' ' where required, and using the same combination of upper-
+and lowercase letters as in the actual files. File names containing
+shell-special characters like spaces or backslashes (if you prefer that
+syntax) need to get properly quoted to the shell: the above example
+used single quotes for that.
+
+ Ok, now here are the steps to perform:
+
+ 1. You need to unpack the AUCTeX distribution (which you seemingly
+ have done since you are reading this). It must be unpacked in a
+ separate installation directory outside of your Emacs file
+ hierarchy: the installation will later copy all necessary files to
+ their final destination, and you can ultimately remove the
+ directory where you unpacked the files.
+
+ Line endings are a problem under Windows. The distribution
+ contains only text files, and theoretically most of the involved
+ tools should get along with that. However, the files are
+ processed by various utilities, and it is conceivable that not all
+ of them will use the same line ending conventions. If you
+ encounter problems, it might help if you try unpacking (or
+ checking out) the files in binary mode, if your tools allow that.
+
+ If you don't have a suitable unpacking tool, skip to the next
+ step: this should provide you with a working `unzip' command.
+
+ 2. The installation of AUCTeX will require the MSYS tool set from
+ `http://www.mingw.org/' or the Cygwin tool set from
+ `http://cygwin.com/'. The latter is slower and larger (the
+ download size of the base system is about 15 MB) but comes with a
+ package manager that allows for updating the tool set and
+ installing additional packages like, for example, the spell
+ checker aspell.
+
+ If Cygwin specific paths like `/cygdrive/c' crop up in the course
+ of the installation, using a non-Cygwin Emacs could conceivably
+ cause trouble. Using Cygwin either for everything or nothing
+ might save headaches, _if_ things don't work out.
+
+ 3. Install a current version of XEmacs from `http://www.xemacs.org/'
+ or Emacs from `ftp://ftp.gnu.org/gnu/emacs/windows/'. Emacs is
+ the recommended choice because it is currently the primary
+ platform for AUCTeX development.
+
+ 4. You need a working TeX installation. One popular installation
+ under Windows is MiKTeX (http://www.miktex.org). Another much more
+ extensive system is TeX Live (http://www.tug.org/texlive) which is
+ rather close to its Unix cousins.
+
+ 5. A working copy of Ghostscript (http://www.cs.wisc.edu/~ghost/) is
+ required for preview-latex operation. Examining the output from
+ gswin32c -h
+ on a Windows command line should tell you whether your Ghostscript
+ supports the `png16m' device needed for PNG support. MiKTeX
+ apparently comes with its own Ghostscript called `mgs.exe'.
+
+ 6. Perl (http://www.perl.org) is needed for rebuilding the
+ documentation if you are working with a copy from CVS or have
+ touched documentation source files in the preview-latex part. If
+ the line endings of the file `preview/latex/preview.dtx' don't
+ correspond with what Perl calls `\n' when reading text files,
+ you'll run into trouble.
+
+ 7. Now the fun stuff starts. If you have not yet done so, unpack the
+ AUCTeX distribution into a separate directory after rereading the
+ instructions for unpacking above.
+
+ 8. Ready for takeoff. Start some shell (typically `bash') capable of
+ running `configure', change into the installation directory and
+ call `./configure' with appropriate options.
+
+ Typical options you'll want to specify will be
+ `--prefix=DRIVE:/PATH/TO/EMACS-HIERARCHY'
+ which tells `configure' where to perform the installation. It
+ may also make `configure' find Emacs or XEmacs automatically;
+ if this doesn't happen, try one of `--with-emacs' or
+ `--with-xemacs' as described below. All automatic detection
+ of files and directories restricts itself to directories
+ below the PREFIX or in the same hierarchy as the program
+ accessing the files. Usually, directories like `man',
+ `share' and `bin' will be situated right under PREFIX.
+
+ This option also affects the defaults for placing the Texinfo
+ documentation files (see also `--infodir' below) and
+ automatically generated style hooks.
+
+ If you have a central directory hierarchy (not untypical with
+ Cygwin) for such stuff, you might want to specify its root
+ here. You stand a good chance that this will be the only
+ option you need to supply, as long as your TeX-related
+ executables are in your system path, which they better be for
+ AUCTeX's operation, anyway.
+
+ `--with-emacs'
+ if you are installing for a version of Emacs. You can use
+ `--with-emacs=DRIVE:/PATH/TO/EMACS' to specify the name of the
+ installed Emacs executable, complete with its path if
+ necessary (if Emacs is not within a directory specified in
+ your `PATH' environment setting).
+
+ `--with-xemacs'
+ if you are installing for a version of XEmacs. Again, you
+ can use `--with-xemacs=DRIVE:/PATH/TO/XEMACS' to specify the
+ name of the installed XEmacs executable complete with its
+ path if necessary. It may also be necessary to specify this
+ option if a copy of Emacs is found in your `PATH' environment
+ setting, but you still would like to install a copy of AUCTeX
+ for XEmacs.
+
+ `--with-packagedir=DRIVE:/DIR'
+ is an XEmacs-only option giving the location of the package
+ directory. This will install and activate the package.
+ Emacs uses a different installation scheme:
+
+ `--with-lispdir=DRIVE:/PATH/TO/SITE-LISP'
+ This Emacs-only option tells a place in `load-path' below
+ which the files are situated. The startup files `auctex.el'
+ and `preview-latex.el' will get installed here unless a
+ subdirectory `site-start.d' exists which will then be used
+ instead. The other files from AUCTeX will be installed in a
+ subdirectory called `auctex'.
+
+ If you think that you need a different setup, please refer to
+ the full installation instructions in *note Configure::.
+
+ `--infodir=DRIVE:/PATH/TO/INFO/DIRECTORY'
+ If you are installing into an Emacs directory, info files
+ have to be put into the `info' folder below that directory.
+ The configuration script will usually try to install into the
+ folder `share/info', so you have to override this by
+ specifying something like `--infodir='C:/Program Files/info''
+ for the configure call.
+
+ `--with-auto-dir=DRIVE:/DIR'
+ Directory containing automatically generated information.
+ You should not normally need to set this, as `--prefix'
+ should take care of this.
+
+ `--disable-preview'
+ Use this option if your Emacs version is unable to support
+ image display. This will be the case if you are using a
+ native variant of Emacs 21.
+
+ `--with-texmf-dir=DRIVE:/DIR'
+ This will specify the directory where your TeX installation
+ sits. If your TeX installation does not conform to the TDS
+ (TeX directory standard), you may need to specify more
+ options to get everything in place.
+
+ For more information about any of the above and additional
+ options, see *note Configure::.
+
+ Calling `./configure --help=recursive' will tell about other
+ options, but those are almost never required.
+
+ Some executables might not be found in your path. That is not a
+ good idea, but you can get around by specifying environment
+ variables to `configure':
+ GS="DRIVE:/PATH/TO/GSWIN32C.EXE" ./configure ...
+ should work for this purpose. `gswin32c.exe' is the usual name for
+ the required _command line_ executable under Windows; in contrast,
+ `gswin32.exe' is likely to fail.
+
+ As an alternative to specifying variables for the `configure' call
+ you can add directories containing the required executables to the
+ `PATH' variable of your Windows system. This is especially a good
+ idea if Emacs has trouble finding the respective programs later
+ during normal operation.
+
+ 9. Run `make' in the installation directory.
+
+ 10. Run `make install' in the installation directory.
+
+ 11. With XEmacs, AUCTeX and preview-latex should now be active by
+ default. With Emacs, activation depends on a working
+ `site-start.d' directory or similar setup, since then the startup
+ files `auctex.el' and `preview-latex.el' will have been placed
+ there. If this has not been done, you should be able to load the
+ startup files manually with
+ (load "auctex.el" nil t t)
+ (load "preview-latex.el" nil t t)
+ in either a site-wide `site-start.el' or your personal startup file
+ (usually accessible as `~/.emacs' from within Emacs and
+ `~/.xemacs/init.el' from within XEmacs).
+
+ The default configuration of AUCTeX is probably not the best fit
+ for Windows systems. You might want to add
+ (require 'tex-mik)
+ or
+ (require 'tex-fptex)
+ in order to get more appropriate values for MiKTeX and fpTeX,
+ respectively after loading `auctex.el' and `preview-latex.el'.
+
+ You can always use
+
+ M-x customize-group RET AUCTeX RET
+
+ in order to customize more stuff, or use the `Customize' menu.
+
+ 12. Load `preview/circ.tex' into Emacs or XEmacs and see if you get the
+ `Command' menu. Try using it to LaTeX the file.
+
+ 13. Check whether the `Preview' menu is available in this file. Use it
+ to generate previews for the document.
+
+ If this barfs and tells you that image type `png' is not supported,
+ you can either add PNG support to your Emacs installation or
+ choose another image format to be used by preview-latex.
+
+ Adding support for an image format usually involves the
+ installation of a library, e.g. from `http://gnuwin32.sf.net/'.
+ If you got your Emacs from `gnu.org' you might want to check its
+ README file (ftp://ftp.gnu.org/gnu/emacs/windows/README) for
+ details.
+
+ A different image format can be chosen by setting the variable
+ `preview-image-type'. While it is recommended to keep the
+ `dvipng' or `png' setting, you can temporarily select a different
+ format like `pnm' to check if the lack of PNG support is the only
+ problem with your Emacs installation.
+
+ Try adding the line
+
+ (setq preview-image-type 'pnm)
+
+ to your init file for a quick test. You should remove the line
+ after the test again, because PNM files take away *vast* amounts
+ of disk space, and thus also of load/save time.
+
+ Well, that about is all. Have fun!
+
+\1f
+File: auctex.info, Node: Customizing, Prev: Installation under MS Windows, Up: Installation
+
+1.2.8 Customizing
+-----------------
+
+Most of the site-specific customization should already have happened
+during configuration of AUCTeX. Any further customization can be done
+with customization buffers directly in Emacs. Just type `M-x
+customize-group RET AUCTeX RET' to open the customization group for
+AUCTeX or use the menu entries provided in the mode menus. Editing the
+file `tex-site.el' as suggested in former versions of AUCTeX should not
+be done anymore because the installation routine will overwrite those
+changes.
+
+ You might check some variables with a special significance. They are
+accessible directly by typing `M-x customize-variable RET <variable>
+RET'.
+
+ -- User Option: TeX-macro-global
+ Directories containing the site's TeX style files.
+
+ Normally, AUCTeX will only allow you to complete macros and
+environments which are built-in, specified in AUCTeX style files or
+defined by yourself. If you issue the `M-x TeX-auto-generate-global'
+command after loading AUCTeX, you will be able to complete on all
+macros available in the standard style files used by your document. To
+do this, you must set this variable to a list of directories where the
+standard style files are located. The directories will be searched
+recursively, so there is no reason to list subdirectories explicitly.
+Automatic configuration will already have set the variable for you if
+it could use the program `kpsewhich'. In this case you normally don't
+have to alter anything.
+
+\1f
+File: auctex.info, Node: Quick Start, Prev: Installation, Up: Introduction
+
+1.3 Quick Start
+===============
+
+AUCTeX is a powerful program offering many features and configuration
+options. If you are new to AUCTeX this might be deterrent.
+Fortunately you do not have to learn everything at once. This Quick
+Start Guide will give you the knowledge of the most important commands
+and enable you to prepare your first LaTeX document with AUCTeX after
+only a few minutes of reading.
+
+ In this introduction, we assume that AUCTeX is already installed on
+your system. If this is not the case, you should read the file
+`INSTALL' in the base directory of the unpacked distribution tarball.
+These installation instructions are available in this manual as well,
+*note Installation::. We also assume that you are familiar with the
+way keystrokes are written in Emacs manuals. If not, have a look at
+the Emacs Tutorial in the Help menu.
+
+ If AUCTeX is installed, you might still need to activate it, by
+inserting
+
+ (load "auctex.el" nil t t)
+
+ in your user init file.(1) In order to get support for many of the
+LaTeX packages you will use in your documents, you should enable
+document parsing as well, which can be achieved by putting
+
+ (setq TeX-auto-save t)
+ (setq TeX-parse-self t)
+
+ into your init file. Finally, if you often use `\include' or
+`\input', you should make AUCTeX aware of the multi-file document
+structure. You can do this by inserting
+
+ (setq-default TeX-master nil)
+
+ into your init file. Each time you open a new file, AUCTeX will then
+ask you for a master file.
+
+* Menu:
+
+* Editing Facilities:: Functions for editing TeX files
+* Processing Facilities:: Creating and viewing output, debugging
+
+ ---------- Footnotes ----------
+
+ (1) This usually is a file in your home directory called `.emacs' if
+you are utilizing GNU Emacs or `.xemacs/init.el' if you are using
+XEmacs.
+
+\1f
+File: auctex.info, Node: Editing Facilities, Next: Processing Facilities, Up: Quick Start
+
+1.3.1 Functions for editing TeX files
+-------------------------------------
+
+1.3.1.1 Making your TeX code more readable
+..........................................
+
+AUCTeX can do syntax highlighting of your source code, that means
+commands will get special colors or fonts. You can enable it locally by
+typing `M-x font-lock-mode RET'. If you want to have font locking
+activated generally, enable `global-font-lock-mode', e.g. with `M-x
+customize-variable RET global-font-lock-mode RET'.
+
+ AUCTeX will indent new lines to indicate their syntactical
+relationship to the surrounding text. For example, the text of a
+`\footnote' or text inside of an environment will be indented relative
+to the text around it. If the indenting has gotten wrong after adding
+or deleting some characters, use <TAB> to reindent the line, `M-q' for
+the whole paragraph, or `M-x LaTeX-fill-buffer RET' for the whole
+buffer.
+
+1.3.1.2 Entering sectioning commands
+....................................
+
+Insertion of sectioning macros, that is `\chapter', `\section',
+`\subsection', etc. and accompanying `\label' commands may be eased by
+using `C-c C-s'. You will be asked for the section level. As nearly
+everywhere in AUCTeX, you can use the <TAB> or <SPC> key to get a list
+of available level names, and to auto-complete what you started typing.
+Next, you will be asked for the printed title of the section, and last
+you will be asked for a label to be associated with the section.
+
+1.3.1.3 Inserting environments
+..............................
+
+Similarly, you can insert environments, that is `\begin{}'-`\end{}'
+pairs: Type `C-c C-e', and select an environment type. Again, you can
+use <TAB> or <SPC> to get a list, and to complete what you type.
+Actually, the list will not only provide standard LaTeX environments,
+but also take your `\documentclass' and `\usepackage' commands into
+account if you have parsing enabled by setting `TeX-parse-self' to `t'.
+If you use a couple of environments frequently, you can use the up and
+down arrow keys (or `M-p' and `M-n') in the minibuffer to get back to
+the previously inserted commands.
+
+ Some environments need additional arguments. Often, AUCTeX knows
+about this and asks you to enter a value.
+
+1.3.1.4 Inserting macros
+........................
+
+`C-c C-m', or simply `C-c RET' will give you a prompt that asks you for
+a LaTeX macro. You can use <TAB> for completion, or the up/down arrow
+keys (or `M-p' and `M-n') to browse the command history. In many
+cases, AUCTeX knows which arguments a macro needs and will ask you for
+that. It even can differentiate between mandatory and optional
+arguments--for details, see *note Completion::.
+
+ An additional help for inserting macros is provided by the
+possibility to complete macros right in the buffer. With point at the
+end of a partially written macro, you can complete it by typing `M-TAB'.
+
+1.3.1.5 Changing the font
+.........................
+
+AUCTeX provides convenient keyboard shortcuts for inserting macros
+which specify the font to be used for typesetting certain parts of the
+text. They start with `C-c C-f', and the last `C-' combination tells
+AUCTeX which font you want:
+
+`C-c C-f C-b'
+ Insert bold face `\textbf{-!-}' text.
+
+`C-c C-f C-i'
+ Insert italics `\textit{-!-}' text.
+
+`C-c C-f C-e'
+ Insert emphasized `\emph{-!-}' text.
+
+`C-c C-f C-s'
+ Insert slanted `\textsl{-!-}' text.
+
+`C-c C-f C-r'
+ Insert roman \textrm{-!-} text.
+
+`C-c C-f C-f'
+ Insert sans serif `\textsf{-!-}' text.
+
+`C-c C-f C-t'
+ Insert typewriter `\texttt{-!-}' text.
+
+`C-c C-f C-c'
+ Insert SMALL CAPS `\textsc{-!-}' text.
+
+`C-c C-f C-d'
+ Delete the innermost font specification containing point.
+
+
+ If you want to change font attributes of existing text, mark it as a
+region, and then invoke the commands. If no region is selected, the
+command will be inserted with empty braces, and you can start typing the
+changed text.
+
+ Most of those commands will also work in math mode, but then macros
+like `\mathbf' will be inserted.
+
+1.3.1.6 Other useful features
+.............................
+
+AUCTeX also tries to help you when inserting the right "quote" signs
+for your language, dollar signs to typeset math, or pairs of braces.
+It offers shortcuts for commenting out text (`C-c ;' for the current
+region or `C-c %' for the paragraph you are in). The same keystrokes
+will remove the % signs, if the region or paragraph is commented out
+yet. With `TeX-fold-mode', you can hide certain parts (like footnotes,
+references etc.) that you do not edit currently. Support for Emacs'
+outline mode is provided as well. And there's more, but this is beyond
+the scope of this Quick Start Guide.
+
+\1f
+File: auctex.info, Node: Processing Facilities, Prev: Editing Facilities, Up: Quick Start
+
+1.3.2 Creating and viewing output, debugging
+--------------------------------------------
+
+1.3.2.1 One Command for LaTeX, helpers, viewers, and printing
+.............................................................
+
+If you have typed some text and want to run LaTeX (or TeX, or other
+programs--see below) on it, type `C-c C-c'. If applicable, you will be
+asked whether you want to save changes, and which program you want to
+invoke. In many cases, the choice that AUCTeX suggests will be just
+what you want: first `latex', then a viewer. If a `latex' run produces
+or changes input files for `makeindex', the next suggestion will be to
+run that program, and AUCTeX knows that you need to run `latex' again
+afterwards--the same holds for BibTeX.
+
+ When no processor invocation is necessary anymore, AUCTeX will
+suggest to run a viewer, or you can chose to create a PostScript file
+using `dvips', or to directly print it.
+
+ At this place, a warning needs to be given: First, although AUCTeX is
+really good in detecting the standard situations when an additional
+`latex' run is necessary, it cannot detect it always. Second, the
+creation of PostScript files or direct printing currently only works
+when your output file is a DVI file, not a PDF file.
+
+ Ah, you didn't know you can do both? That brings us to the next
+topic.
+
+1.3.2.2 Choosing an output format
+.................................
+
+From a LaTeX file, you can produce DVI output, or a PDF file directly
+via `pdflatex'. You can switch on source specials for easier
+navigation in the output file, or tell `latex' to stop after an error
+(usually `\noninteractive' is used, to allow you to detect all errors
+in a single run).
+
+ These options are controlled by toggles, the keystrokes should be
+easy to memorize:
+
+`C-c C-t C-p'
+ This command toggles between DVI and PDF output
+
+`C-c C-t C-i'
+ toggles interactive mode
+
+`C-c C-t C-s'
+ toggles source specials support
+
+`C-c C-t C-o'
+ toggles usage of Omega/lambda.
+
+
+1.3.2.3 Debugging LaTeX
+.......................
+
+When AUCTeX runs a program, it creates an output buffer in which it
+displays the output of the command. If there is a syntactical error in
+your file, `latex' will not complete successfully. AUCTeX will tell you
+that, and you can get to the place where the first error occured by
+pressing `C-c `' (the last character is a backtick). The view will be
+split in two windows, the output will be displayed in the lower buffer,
+and both buffers will be centered around the place where the error
+ocurred. You can then try to fix it in the document buffer, and use
+the same keystrokes to get to the next error. This procedure may be
+repeated until all errors have been dealt with. By pressing `C-c C-w'
+(`TeX-toggle-debug-boxes') you can toggle whether AUCTeX should notify
+you of overfull and underfull boxes in addition to regular errors.
+
+ If a command got stuck in a seemingly infinite loop, or you want to
+stop execution for other reasons, you can use `C-c C-k' (for "kill").
+Similar to `C-l', which centers the buffer you are in around your
+current position, `C-c C-l' centers the output buffer so that the last
+lines added at the bottom become visible.
+
+1.3.2.4 Running LaTeX on parts of your document
+...............................................
+
+If you want to check how some part of your text looks like, and do not
+want to wait until the whole document has been typeset, then mark it as
+a region and use `C-c C-r'. It behaves just like `C-c C-c', but it
+only uses the document preamble and the region you marked.
+
+ If you are using `\include' or `\input' to structure your document,
+try `C-c C-b' while you are editing one of the included files. It will
+run `latex' only on the current buffer, using the preamble from the
+master file.
+
+\1f
+File: auctex.info, Node: Editing, Next: Display, Prev: Introduction, Up: Top
+
+2 Editing the Document Source
+*****************************
+
+The most commonly used commands/macros of AUCTeX are those which simply
+insert templates for often used TeX, LaTeX, or ConTeXt constructs, like
+font changes, handling of environments, etc. These features are very
+simple, and easy to learn, and help you avoid mistakes like mismatched
+braces, or `\begin{}'-`\end{}' pairs.
+
+ Apart from that this chapter contains a description of some features
+for entering more specialized sorts of text, for formatting the source
+by indenting and filling and for navigating through the document.
+
+* Menu:
+
+* Quotes:: Inserting double quotes
+* Font Specifiers:: Inserting Font Specifiers
+* Sectioning:: Inserting chapters, sections, etc.
+* Environments:: Inserting Environment Templates
+* Mathematics:: Entering Mathematics
+* Completion:: Completion of macros
+* Commenting:: Commenting text
+* Indenting:: Reflecting syntactic constructs with whitespace
+* Filling:: Automatic and manual line breaking
+
+\1f
+File: auctex.info, Node: Quotes, Next: Font Specifiers, Up: Editing
+
+2.1 Insertion of Quotes, Dollars, and Braces
+============================================
+
+Quotation Marks
+---------------
+
+In TeX, literal double quotes `"like this"' are seldom used, instead
+two single quotes are used ```like this'''. To help you insert these
+efficiently, AUCTeX allows you to continue to press `"' to insert two
+single quotes. To get a literal double quote, press `"' twice.
+
+ -- Command: TeX-insert-quote COUNT
+ (`"') 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.
+
+ -- User Option: TeX-open-quote
+ String inserted by typing `"' to open a quotation. (*Note
+ European::, for language-specific quotation mark insertion.)
+
+ -- User Option: TeX-close-quote
+ String inserted by typing `"' to close a quotation. (*Note
+ European::, for language-specific quotation mark insertion.)
+
+ -- User Option: TeX-quote-after-quote
+ Determines the behavior of `"'. If it is non-nil, typing `"' will
+ insert a literal double quote. The respective values of
+ `TeX-open-quote' and `TeX-close-quote' will be inserted after
+ typing `"' once again.
+
+ The `babel' package provides special support for the requirements of
+typesetting quotation marks in many different languages. If you use
+this package, either directly or by loading a language-specific style
+file, you should also use the special commands for quote insertion
+instead of the standard quotes shown above. AUCTeX is able to
+recognize several of these languages and will change quote insertion
+accordingly. *Note European::, for details about this feature and how
+to control it.
+
+ In case you are using the `csquotes' package, you should customize
+`LaTeX-csquotes-open-quote', `LaTeX-csquotes-close-quote' and
+`LaTeX-csquotes-quote-after-quote'. The quotation characters will only
+be used if both variables--`LaTeX-csquotes-open-quote' and
+`LaTeX-csquotes-close-quote'--are non-empty strings. But then the
+`csquotes'-related values will take precedence over the
+language-specific ones.
+
+Dollar Signs
+------------
+
+In AUCTeX, dollar signs should match like they do in TeX. This has
+been partially implemented, we assume dollar signs always match within
+a paragraph. The first `$' you insert in a paragraph will do nothing
+special. The second `$' will match the first. This will be indicated
+by moving the cursor temporarily over the first dollar sign.
+
+ -- Command: TeX-insert-dollar ARG
+ (`$') Insert dollar sign.
+
+ Show matching dollar sign if this dollar sign end the TeX math
+ mode. Ensure double dollar signs match up correctly by inserting
+ extra dollar signs when needed if `TeX-math-close-double-dollar'
+ is non-nil.
+
+ With optional ARG, insert that many dollar signs.
+
+ -- User Option: TeX-math-close-double-dollar
+ Control the insertion of double dollar signs for delimiting display
+ math. (Note that you should not use double dollar signs in LaTeX
+ because this practice can lead to wrong spacing in typeset
+ documents.) If the variable is non-nil and you enter a dollar
+ sign that matches a double dollar sign `$$' AUCTeX will
+ automatically insert two dollar signs.
+
+Braces
+------
+
+To avoid unbalanced braces, it is useful to insert them pairwise. You
+can do this by typing `C-c {'.
+
+ -- Command: TeX-insert-braces
+ (`C-c {') Make a pair of braces and position the cursor to type
+ inside of them. If there is an active region, put braces around
+ it and leave point after the closing brace.
+
+\1f
+File: auctex.info, Node: Font Specifiers, Next: Sectioning, Prev: Quotes, Up: Editing
+
+2.2 Inserting Font Specifiers
+=============================
+
+Perhaps the most used keyboard commands of AUCTeX are the short-cuts
+available for easy insertion of font changing macros.
+
+ If you give an argument (that is, type `C-u') to the font command,
+the innermost font will be replaced, i.e. the font in the TeX group
+around point will be changed. The following table shows the available
+commands, with `-!-' indicating the position where the text will be
+inserted.
+
+`C-c C-f C-b'
+ Insert bold face `\textbf{-!-}' text.
+
+`C-c C-f C-i'
+ Insert italics `\textit{-!-}' text.
+
+`C-c C-f C-e'
+ Insert emphasized `\emph{-!-}' text.
+
+`C-c C-f C-s'
+ Insert slanted `\textsl{-!-}' text.
+
+`C-c C-f C-r'
+ Insert roman \textrm{-!-} text.
+
+`C-c C-f C-f'
+ Insert sans serif `\textsf{-!-}' text.
+
+`C-c C-f C-t'
+ Insert typewriter `\texttt{-!-}' text.
+
+`C-c C-f C-c'
+ Insert SMALL CAPS `\textsc{-!-}' text.
+
+`C-c C-f C-d'
+ Delete the innermost font specification containing point.
+
+
+ -- Command: TeX-font replace what
+ (`C-c C-f') Insert template for font change command.
+
+ If REPLACE is not nil, replace current font. WHAT determines the
+ font to use, as specified by `TeX-font-list'.
+
+ -- User Option: TeX-font-list
+ List of fonts used by `TeX-font'.
+
+ Each entry is a list with three elements. The first element is the
+ key to activate the font. The second element is the string to
+ insert before point, and the third element is the string to insert
+ after point. An optional fourth element means always replace if
+ not nil.
+
+ -- User Option: LaTeX-font-list
+ List of fonts used by `TeX-font' in LaTeX mode. It has the same
+ structure as `TeX-font-list'.
+
+\1f
+File: auctex.info, Node: Sectioning, Next: Environments, Prev: Font Specifiers, Up: Editing
+
+2.3 Inserting chapters, sections, etc.
+======================================
+
+Insertion of sectioning macros, that is `\chapter', `\section',
+`\subsection', etc. and accompanying `\label''s may be eased by using
+`C-c C-s'. This command is highly customizable, the following
+describes the default behavior.
+
+ When invoking you will be asked for a section macro to insert. An
+appropriate default is automatically selected by AUCTeX, that is
+either: at the top of the document; the top level sectioning for that
+document style, and any other place: The same as the last occurring
+sectioning command.
+
+ Next, you will be asked for the actual name of that section, and
+last you will be asked for a label to be associated with that section.
+The label will be prefixed by the value specified in
+`LaTeX-section-hook'.
+
+ -- Command: LaTeX-section ARG
+ (`C-c C-s') Insert a sectioning command.
+
+ Determine the type of section to be inserted, by the argument ARG.
+
+ * If ARG is nil or missing, use the current level.
+
+ * If ARG is a list (selected by C-u), go downward one level.
+
+ * If ARG is negative, go up that many levels.
+
+ * If ARG is positive or zero, use absolute level:
+ + 0 : part
+
+ + 1 : chapter
+
+ + 2 : section
+
+ + 3 : subsection
+
+ + 4 : subsubsection
+
+ + 5 : paragraph
+
+ + 6 : subparagraph
+
+ The following variables can be set to customize the function.
+
+ `LaTeX-section-hook'
+ Hooks to be run when inserting a section.
+
+ `LaTeX-section-label'
+ Prefix to all section references.
+
+
+ The precise behavior of `LaTeX-section' is defined by the contents
+of `LaTeX-section-hook'.
+
+ -- User Option: LaTeX-section-hook
+ List of hooks to run when a new section is inserted.
+
+ The following variables are set before the hooks are run
+
+ LEVEL
+ Numeric section level, default set by prefix arg to
+ `LaTeX-section'.
+
+ NAME
+ Name of the sectioning command, derived from LEVEL.
+
+ TITLE
+ The title of the section, default to an empty string.
+
+ TOC
+ Entry for the table of contents list, default nil.
+
+ DONE-MARK
+ Position of point afterwards, default nil meaning after the
+ inserted text.
+
+ A number of hooks are already defined. Most likely, you will be
+ able to get the desired functionality by choosing from these hooks.
+
+ `LaTeX-section-heading'
+ Query the user about the name of the sectioning command.
+ Modifies LEVEL and NAME.
+
+ `LaTeX-section-title'
+ Query the user about the title of the section. Modifies TITLE.
+
+ `LaTeX-section-toc'
+ Query the user for the toc entry. Modifies TOC.
+
+ `LaTeX-section-section'
+ Insert LaTeX section command according to NAME, TITLE, and
+ TOC. If TOC is nil, no toc entry is inserted. If TOC or
+ TITLE are empty strings, DONE-MARK will be placed at the
+ point they should be inserted.
+
+ `LaTeX-section-label'
+ Insert a label after the section command. Controlled by the
+ variable `LaTeX-section-label'.
+
+ To get a full featured `LaTeX-section' command, insert
+
+ (setq LaTeX-section-hook
+ '(LaTeX-section-heading
+ LaTeX-section-title
+ LaTeX-section-toc
+ LaTeX-section-section
+ LaTeX-section-label))
+
+ in your `.emacs' file.
+
+ The behavior of `LaTeX-section-label' is determined by the variable
+`LaTeX-section-label'.
+
+ -- User Option: LaTeX-section-label
+ Default prefix when asking for a label.
+
+ If it is a string, it is used unchanged for all kinds of sections.
+ If it is nil, no label is inserted. If it is a list, the list is
+ searched for a member whose car is equal to the name of the
+ sectioning command being inserted. The cdr is then used as the
+ prefix. If the name is not found, or if the cdr is nil, no label
+ is inserted.
+
+ By default, chapters have a prefix of `cha:' while sections and
+ subsections have a prefix of `sec:'. Labels are not automatically
+ inserted for other types of sections.
+
+\1f
+File: auctex.info, Node: Environments, Next: Mathematics, Prev: Sectioning, Up: Editing
+
+2.4 Inserting Environment Templates
+===================================
+
+A large apparatus is available that supports insertions of environments,
+that is `\begin{}' -- `\end{}' pairs.
+
+ AUCTeX is aware of most of the actual environments available in a
+specific document. This is achieved by examining your `\documentclass'
+command, and consulting a precompiled list of environments available in
+a large number of styles.
+
+ You insert an environment with `C-c C-e', and select an environment
+type. Depending on the environment, AUCTeX may ask more questions
+about the optional parts of the selected environment type. With `C-u
+C-c C-e' you will change the current environment.
+
+ -- Command: LaTeX-environment ARG
+ (`C-c C-e') AUCTeX will prompt you for an environment to insert.
+ At this prompt, you may press <TAB> or <SPC> to complete a
+ partially written name, and/or to get a list of available
+ environments. After selection of a specific environment AUCTeX may
+ prompt you for further specifications.
+
+ If the optional argument ARG is not-nil (i.e. you have given a
+ prefix argument), the current environment is modified and no new
+ environment is inserted.
+
+ As a default selection, AUCTeX will suggest the environment last
+inserted or, as the first choice the value of the variable
+`LaTeX-default-environment'.
+
+ -- User Option: LaTeX-default-environment
+ Default environment to insert when invoking `LaTeX-environment'
+ first time.
+
+ If the document is empty, or the cursor is placed at the top of the
+document, AUCTeX will default to insert a `document' environment.
+
+ Most of these are described further in the following sections, and
+you may easily specify more. *Note Customizing Environments::.
+
+* Menu:
+
+* Equations:: Equations
+* Floats:: Floats
+* Itemize-like:: Itemize-like Environments
+* Tabular-like:: Tabular-like Environments
+* Customizing Environments:: Customizing Environments
+
+ You can close the current environment with `C-c ]', but we suggest
+that you use `C-c C-e' to insert complete environments instead.
+
+ -- Command: LaTeX-close-environment
+ (`C-c ]') Insert an `\end' that matches the current environment.
+
+\1f
+File: auctex.info, Node: Equations, Next: Floats, Up: Environments
+
+2.4.1 Equations
+---------------
+
+When inserting equation-like environments, the `\label' will have a
+default prefix, which is controlled by the following variables:
+
+ -- User Option: LaTeX-equation-label
+ Prefix to use for `equation' labels.
+
+ -- User Option: LaTeX-eqnarray-label
+ Prefix to use for `eqnarray' labels.
+
+ -- User Option: LaTeX-amsmath-label
+ Prefix to use for amsmath equation labels. Amsmath equations
+ include `align', `alignat', `xalignat', `aligned', `flalign' and
+ `gather'.
+
+\1f
+File: auctex.info, Node: Floats, Next: Itemize-like, Prev: Equations, Up: Environments
+
+2.4.2 Floats
+------------
+
+Figures and tables (i.e., floats) may also be inserted using AUCTeX.
+After choosing either `figure' or `table' in the environment list
+described above, you will be prompted for a number of additional things.
+
+FLOAT POSITION
+ This is the optional argument of float environments that controls
+ how they are placed in the final document. In LaTeX this is a
+ sequence of the letters `htbp' as described in the LaTeX manual.
+ The value will default to the value of `LaTeX-float'.
+
+CAPTION
+ This is the caption of the float. The default is to insert the
+ caption at the bottom of the float. You can specify floats where
+ the caption should be placed at the top with
+ `LaTeX-top-caption-list'.
+
+LABEL
+ The label of this float. The label will have a default prefix,
+ which is controlled by the variables `LaTeX-figure-label' and
+ `LaTeX-table-label'.
+
+ Moreover, you will be asked if you want the contents of the float
+environment to be horizontally centered. Upon a positive answer a
+`\centering' macro will be inserted at the beginning of the float
+environment.
+
+ -- User Option: LaTeX-float
+ Default placement for floats.
+
+ -- User Option: LaTeX-figure-label
+ Prefix to use for figure labels.
+
+ -- User Option: LaTeX-table-label
+ Prefix to use for table labels.
+
+ -- User Option: LaTeX-top-caption-list
+ List of float environments with top caption.
+
+\1f
+File: auctex.info, Node: Itemize-like, Next: Tabular-like, Prev: Floats, Up: Environments
+
+2.4.3 Itemize-like Environments
+-------------------------------
+
+In an itemize-like environment, nodes (i.e., `\item's) may be inserted
+using `C-c <LFD>'.
+
+ -- Command: LaTeX-insert-item
+ (`C-c <LFD>') Close the current item, move to the next line and
+ insert an appropriate `\item' for the current environment. That is,
+ `itemize' and `enumerate' will have `\item ' inserted, while
+ `description' will have `\item[]' inserted.
+
+\1f
+File: auctex.info, Node: Tabular-like, Next: Customizing Environments, Prev: Itemize-like, Up: Environments
+
+2.4.4 Tabular-like Environments
+-------------------------------
+
+When inserting Tabular-like environments, that is, `tabular' `array'
+etc., you will be prompted for a template for that environment.
+Related variables:
+
+ -- User Option: LaTeX-default-format
+ Default format string for array and tabular environments.
+
+ -- User Option: LaTeX-default-position
+ Default position string for array and tabular environments. If
+ nil, act like the empty string is given, but don't prompt for a
+ position.
+
+\1f
+File: auctex.info, Node: Customizing Environments, Prev: Tabular-like, Up: Environments
+
+2.4.5 Customizing Environments
+------------------------------
+
+*Note Adding Environments::, for how to customize the list of known
+environments.
+
+\1f
+File: auctex.info, Node: Mathematics, Next: Completion, Prev: Environments, Up: Editing
+
+2.5 Entering Mathematics
+========================
+
+TeX is written by a mathematician, and has always contained good
+support for formatting mathematical text. AUCTeX supports this
+tradition, by offering a special minor mode for entering text with many
+mathematical symbols. You can enter this mode by typing `C-c ~'.
+
+ -- Command: LaTeX-math-mode
+ (`C-c ~') Toggle LaTeX Math mode. This is a minor mode rebinding
+ the key `LaTeX-math-abbrev-prefix' to allow easy typing of
+ mathematical symbols. ``' will read a character from the keyboard,
+ and insert the symbol as specified in `LaTeX-math-default' and
+ `LaTeX-math-list'. If given a prefix argument, the symbol will be
+ surrounded by dollar signs.
+
+ You can use another prefix key (instead of ``') by setting the
+variable `LaTeX-math-abbrev-prefix'.
+
+ To enable LaTeX Math mode by default, add the following in your
+`.emacs' file:
+ (add-hook 'LaTeX-mode-hook 'LaTeX-math-mode)
+
+ -- User Option: LaTeX-math-abbrev-prefix
+ A string containing the prefix of `LaTeX-math-mode' commands; This
+ value defaults to ``'.
+
+ The string has to be a key or key sequence in a format understood
+ by the `kbd' macro. This corresponds to the syntax usually used
+ in the manuals for Emacs Emacs Lisp.
+
+ The variable `LaTeX-math-list' allows you to add your own mappings.
+
+ -- User Option: LaTeX-math-list
+ A list containing user-defined keys and commands to be used in
+ LaTeX Math mode. Each entry should be a list of two to four
+ elements.
+
+ First, the key to be used after `LaTeX-math-abbrev-prefix' for
+ macro insertion. If it is nil, the symbol has no associated
+ keystroke (it is available in the menu, though).
+
+ Second, a string representing the name of the macro (without a
+ leading backslash.)
+
+ Third, a string representing the name of a submenu the command
+ should be added to. Use a list of strings in case of nested menus.
+
+ Fourth, the position of a Unicode character to be displayed in the
+ menu alongside the macro name. This is an integer value.
+
+ -- User Option: LaTeX-math-menu-unicode
+ Whether the LaTeX menu should try using Unicode for effect. Your
+ Emacs built must be able to display include Unicode characters in
+ menus for this feature.
+
+ AUCTeX's reference card `tex-ref.tex' includes a list of all math
+mode commands.
+
+ AUCTeX can help you write subscripts and superscripts in math
+constructs by automatically inserting a pair of braces after typing <_>
+or <^> respectively and putting point between the braces. In order to
+enable this feature, set the variable
+`TeX-electric-sub-and-superscript' to a non-nil value.
+
+ -- User Option: TeX-electric-sub-and-superscript
+ If non-nil, insert braces after typing <^> and <_> in math mode.
+
+\1f
+File: auctex.info, Node: Completion, Next: Commenting, Prev: Mathematics, Up: Editing
+
+2.6 Completion
+==============
+
+Emacs lisp programmers probably know the `lisp-complete-symbol'
+command, usually bound to `M-<TAB>'. Users of the wonderful ispell
+mode know and love the `ispell-complete-word' command from that
+package. Similarly, AUCTeX has a `TeX-complete-symbol' command, by
+default bound to `M-<TAB>' which is equivalent to `M-C-i'. Using
+`TeX-complete-symbol' makes it easier to type and remember the names of
+long LaTeX macros.
+
+ In order to use `TeX-complete-symbol', you should write a backslash
+and the start of the macro. Typing `M-<TAB>' will now complete as much
+of the macro, as it unambiguously can. For example, if you type
+``\renewc'' and then `M-<TAB>', it will expand to ``\renewcommand''.
+
+ -- Command: TeX-complete-symbol
+ (`M-<TAB>') Complete TeX symbol before point.
+
+ A more direct way to insert a macro is with `TeX-insert-macro',
+bound to `C-c C-m' which is equivalent to `C-c <RET>'. It has the
+advantage over completion that it knows about the argument of most
+standard LaTeX macros, and will prompt for them. It also knows about
+the type of the arguments, so it will for example give completion for
+the argument to `\include'. Some examples are listed below.
+
+ -- Command: TeX-insert-macro
+ (`C-c C-m' or `C-c <RET>') Prompt (with completion) for the name
+ of a TeX macro, and if AUCTeX knows the macro, prompt for each
+ argument.
+
+ As a default selection, AUCTeX will suggest the macro last inserted
+or, as the first choice the value of the variable `TeX-default-macro'.
+
+ -- User Option: TeX-insert-macro-default-style
+ Specifies whether `TeX-insert-macro' will ask for all optional
+ arguments.
+
+ If set to the symbol `show-optional-args', `TeX-insert-macro' asks
+ for optional arguments of TeX macros. If set to
+ `mandatory-args-only', `TeX-insert-macro' asks only for mandatory
+ arguments. When `TeX-insert-macro' is called with prefix argument
+ (`C-u'), it's the other way round.
+
+ Note that for some macros, there are special mechanisms, e.g.
+ `LaTeX-includegraphics-options-alist'.
+
+
+ -- User Option: TeX-default-macro
+ Default macro to insert when invoking `TeX-insert-macro' first
+ time.
+
+ A faster alternative is to bind the function `TeX-electric-macro' to
+`\'. This can be done by setting the variable `TeX-electric-escape'
+
+ -- User Option: TeX-electric-escape
+ If this is non-nil when AUCTeX is loaded, the TeX escape character
+ `\' will be bound to `TeX-electric-macro'
+
+ The difference between `TeX-insert-macro' and `TeX-electric-macro'
+is that space will complete and exit from the minibuffer in
+`TeX-electric-macro'. Use <TAB> if you merely want to complete.
+
+ -- Command: TeX-electric-macro
+ Prompt (with completion) for the name of a TeX macro, and if
+ AUCTeX knows the macro, prompt for each argument. Space will
+ complete and exit.
+
+ By default AUCTeX will put an empty set braces `{}' after a macro
+with no arguments to stop it from eating the next whitespace. This can
+be stopped by entering `LaTeX-math-mode', *note Mathematics::, or by
+setting `TeX-insert-braces' to nil.
+
+ -- User Option: TeX-insert-braces
+ If non-nil, append a empty pair of braces after inserting a macro.
+
+ Completions work because AUCTeX can analyze TeX files, and store
+symbols in Emacs Lisp files for later retrieval. *Note Automatic::, for
+more information.
+
+ AUCTeX will also make completion for many macro arguments, for
+example existing labels when you enter a `\ref' macro with
+`TeX-insert-macro' or `TeX-electric-macro', and BibTeX entries when you
+enter a `\cite' macro. For this kind of completion to work, parsing
+must be enabled as described in *note Parsing Files::. For `\cite' you
+must also make sure that the BibTeX files have been saved at least once
+after you enabled automatic parsing on save, and that the basename of
+the BibTeX file does not conflict with the basename of one of TeX files.
+
+\1f
+File: auctex.info, Node: Commenting, Next: Indenting, Prev: Completion, Up: Editing
+
+2.7 Commenting
+==============
+
+It is often necessary to comment out temporarily a region of TeX or
+LaTeX code. This can be done with the commands `C-c ;' and `C-c %'.
+`C-c ;' will comment out all lines in the current region, while `C-c %'
+will comment out the current paragraph. Type `C-c ;' again to
+uncomment all lines of a commented region, or `C-c %' again to
+uncomment all comment lines around point. These commands will insert
+or remove a single `%' respectively.
+
+ -- Command: TeX-comment-or-uncomment-region
+ (`C-c ;') Add or remove `%' from the beginning of each line in the
+ current region. Uncommenting works only if the region encloses
+ solely commented lines. If AUCTeX should not try to guess if the
+ region should be commented or uncommented the commands
+ `TeX-comment-region' and `TeX-uncomment-region' can be used to
+ explicitly comment or uncomment the region in concern.
+
+ -- Command: TeX-comment-or-uncomment-paragraph
+ (`C-c %') Add or remove `%' from the beginning of each line in the
+ current paragraph. When removing `%' characters the paragraph is
+ considered to consist of all preceding and succeeding lines
+ starting with a `%', until the first non-comment line.
+
+\1f
+File: auctex.info, Node: Indenting, Next: Filling, Prev: Commenting, Up: Editing
+
+2.8 Indenting
+=============
+
+Indentation means the addition of whitespace at the beginning of lines
+to reflect special syntactical constructs. This makes it easier to see
+the structure of the document, and to catch errors such as a missing
+closing brace. Thus, the indentation is done for precisely the same
+reasons that you would indent ordinary computer programs.
+
+ Indentation is done by LaTeX environments and by TeX groups, that is
+the body of an environment is indented by the value of
+`LaTeX-indent-level' (default 2). Also, items of an `itemize-like'
+environment are indented by the value of `LaTeX-item-indent', default
+-2. (Items are identified with the help of `LaTeX-item-regexp'.) If
+more environments are nested, they are indented `accumulated' just like
+most programming languages usually are seen indented in nested
+constructs.
+
+ You can explicitely indent single lines, usually by pressing <TAB>,
+or marked regions by calling `indent-region' on it. If you have
+`auto-fill-mode' enabled and a line is broken while you type it, Emacs
+automatically cares about the indentation in the following line. If
+you want to have a similar behavior upon typing <RET>, you can
+customize the variable `TeX-newline-function' and change the default of
+`newline' which does no indentation to `newline-and-indent' which
+indents the new line or `reindent-then-newline-and-indent' which
+indents both the current and the new line.
+
+ There are certain LaTeX environments which should be indented in a
+special way, like `tabular' or `verbatim'. Those environments may be
+specified in the variable `LaTeX-indent-environment-list' together with
+their special indentation functions. Taking the `verbatim' environment
+as an example you can see that `current-indentation' is used as the
+indentation function. This will stop AUCTeX from doing any indentation
+in the environment if you hit <TAB> for example.
+
+ There are environments in `LaTeX-indent-environment-list' which do
+not bring a special indentation function with them. This is due to the
+fact that first the respective functions are not implemented yet and
+second that filling will be disabled for the specified environments.
+This shall prevent the source code from being messed up by accidently
+filling those environments with the standard filling routine. If you
+think that providing special filling routines for such environments
+would be an appropriate and challenging task for you, you are invited to
+contribute. (*Note Filling::, for further information about the filling
+functionality)
+
+ The check for the indentation function may be enabled or disabled by
+customizing the variable `LaTeX-indent-environment-check'.
+
+ As a side note with regard to formatting special environments: Newer
+Emacsen include `align.el' and therefore provide some support for
+formatting `tabular' and `tabbing' environments with the function
+`align-current' which will nicely align columns in the source code.
+
+ AUCTeX is able to format commented parts of your code just as any
+other part. This means LaTeX environments and TeX groups in comments
+will be indented syntactically correct if the variable
+`LaTeX-syntactic-comments' is set to t. If you disable it, comments
+will be filled like normal text and no syntactic indentation will be
+done.
+
+ Following you will find a list of most commands and variables related
+to indenting with a small summary in each case:
+
+`<TAB>'
+ `LaTeX-indent-line' will indent the current line.
+
+`<LFD>'
+ `newline-and-indent' inserts a new line (much like <RET>) and
+ moves the cursor to an appropriate position by the left margin.
+
+ Most keyboards nowadays lack a linefeed key and `C-j' may be
+ tedious to type. Therefore you can customize AUCTeX to perform
+ indentation upon typing <RET> as well. The respective option is
+ called `TeX-newline-function'.
+
+`C-j'
+ Alias for <LFD>
+
+ -- User Option: LaTeX-indent-environment-list
+ List of environments with special indentation. The second element
+ in each entry is the function to calculate the indentation level in
+ columns.
+
+ The filling code currently cannot handle tabular-like environments
+ which will be completely messed-up if you try to format them.
+ This is why most of these environments are included in this
+ customization option without a special indentation function. This
+ will prevent that they get filled.
+
+ -- User Option: LaTeX-indent-level
+ Number of spaces to add to the indentation for each `\begin' not
+ matched by a `\end'.
+
+ -- User Option: LaTeX-item-indent
+ Number of spaces to add to the indentation for `\item''s in list
+ environments.
+
+ -- User Option: TeX-brace-indent-level
+ Number of spaces to add to the indentation for each `{' not
+ matched by a `}'.
+
+ -- User Option: LaTeX-syntactic-comments
+ If non-nil comments will be filled and indented according to LaTeX
+ syntax. Otherwise they will be filled like normal text.
+
+ -- User Option: TeX-newline-function
+ Used to specify the function which is called when <RET> is pressed.
+ This will normally be `newline' which simply inserts a new line.
+ In case you want to have AUCTeX do indentation as well when you
+ press <RET>, use the built-in functions `newline-and-indent' or
+ `reindent-then-newline-and-indent'. The former inserts a new line
+ and indents the following line, i.e. it moves the cursor to the
+ right position and therefore acts as if you pressed <LFD>. The
+ latter function additionally indents the current line. If you
+ choose `Other', you can specify your own fancy function to be
+ called when <RET> is pressed.
+
+\1f
+File: auctex.info, Node: Filling, Prev: Indenting, Up: Editing
+
+2.9 Filling
+===========
+
+Filling deals with the insertion of line breaks to prevent lines from
+becoming wider than what is specified in `fill-column'. The linebreaks
+will be inserted automatically if `auto-fill-mode' is enabled. In this
+case the source is not only filled but also indented automatically as
+you write it.
+
+ `auto-fill-mode' can be enabled for AUCTeX by calling
+`turn-on-auto-fill' in one of the hooks AUCTeX is running. *Note Modes
+and Hooks::. As an example, if you want to enable `auto-fill-mode' in
+`LaTeX-mode', put the following into your init file:
+
+ (add-hook 'LaTeX-mode-hook 'turn-on-auto-fill)
+
+ You can manually fill explicitely marked regions, paragraphs,
+environments, complete sections, or the whole buffer. (Note that manual
+filling in AUCTeX will indent the start of the region to be filled in
+contrast to many other Emacs modes.)
+
+ There are some syntactical constructs which are handled specially
+with regard to filling. These are so-called code comments and paragraph
+commands.
+
+ Code comments are comments preceded by code or text in the same line.
+Upon filling a region, code comments themselves will not get filled.
+Filling is done from the start of the region to the line with the code
+comment and continues after it. In order to prevent overfull lines in
+the source code, a linebreak will be inserted before the last
+non-comment word by default. This can be changed by customizing
+`LaTeX-fill-break-before-code-comments'. If you have overfull lines
+with code comments you can fill those explicitely by calling
+`LaTeX-fill-paragraph' or pressing `M-q' with the cursor positioned on
+them. This will add linebreaks in the comment and indent subsequent
+comment lines to the column of the comment in the first line of the
+code comment. In this special case `M-q' only acts on the current line
+and not on the whole paragraph.
+
+ Lines with `\par' are treated similarly to code comments, i.e.
+`\par' will be treated as paragraph boundary which should not be
+followed by other code or text. But it is not treated as a real
+paragraph boundary like an empty line where filling a paragraph would
+stop.
+
+ Paragraph commands like `\section' or `\noindent' (the list of
+commands is defined by `LaTeX-paragraph-commands') are often to be
+placed in their own line(s). This means they should not be consecuted
+with any preceding or following adjacent lines of text. AUCTeX will
+prevent this from happening if you do not put any text except another
+macro after the end of the last brace of the respective macro. If
+there is other text after the macro, AUCTeX regards this as a sign that
+the macro is part of the following paragraph.
+
+ Here are some examples:
+
+ \begin{quote}
+ text text text text
+
+ \begin{quote}\label{foo}
+ text text text text
+
+ If you press `M-q' on the first line in both examples, nothing will
+change. But if you write
+
+ \begin{quote} text
+ text text text text
+
+ and press `M-q', you will get
+
+ \begin{quote} text text text text text
+
+ Besides code comments and paragraph commands, another speciality of
+filling in AUCTeX involves commented lines. You should be aware that
+these comments are treated as islands in the rest of the LaTeX code if
+syntactic filling is enabled. This means, for example, if you try to
+fill an environment with `LaTeX-fill-environment' and have the cursor
+placed on a commented line which does not have a surrounding
+environment inside the comment, AUCTeX will report an error.
+
+ The relevant commands and variables with regard to filling are:
+
+`C-c C-q C-p'
+ `LaTeX-fill-paragraph' will fill and indent the current paragraph.
+
+`M-q'
+ Alias for `C-c C-q C-p'
+
+`C-c C-q C-e'
+ `LaTeX-fill-environment' will fill and indent the current
+ environment. This may e.g. be the `document' environment, in
+ which case the entire document will be formatted.
+
+`C-c C-q C-s'
+ `LaTeX-fill-section' will fill and indent the current logical
+ sectional unit.
+
+`C-c C-q C-r'
+ `LaTeX-fill-region' will fill and indent the current region.
+
+ -- User Option: LaTeX-fill-break-at-separators
+ List of separators before or after which respectively linebreaks
+ will be inserted if they do not fit into one line. The separators
+ can be curly braces, brackets, switches for inline math (`$', `\(',
+ `\)') and switches for display math (`\[', `\]'). Such formatting
+ can be useful to make macros and math more visible or to prevent
+ overfull lines in the LaTeX source in case a package for
+ displaying formatted TeX output inside the Emacs buffer, like
+ preview-latex, is used.
+
+ -- User Option: LaTeX-fill-break-before-code-comments
+ Code comments are comments preceded by some other text in the same
+ line. When a paragraph containing such a comment is to be filled,
+ the comment start will be seen as a border after which no line
+ breaks will be inserted in the same line. If the option
+ `LaTeX-fill-break-before-code-comments' is enabled (which is the
+ default) and the comment does not fit into the line, a line break
+ will be inserted before the last non-comment word to minimize the
+ chance that the line becomes overfull.
+
+\1f
+File: auctex.info, Node: Display, Next: Processing, Prev: Editing, Up: Top
+
+3 Controlling Screen Display
+****************************
+
+It is often desirable to get visual help of what markup code in a text
+actually does whithout having to decipher it explicitely. For this
+purpose Emacs and AUCTeX provide font locking (also known as syntax
+highlighting) which visually sets off markup code like macros or
+environments by using different colors or fonts. For example text to be
+typeset in italics can be displayed with an italic font in the editor as
+well, or labels and references get their own distinct color.
+
+ While font locking helps you grasp the purpose of markup code and
+separate markup from content, the markup code can still be distracting.
+AUCTeX lets you hide those parts and show them again at request with
+its built-in support for hiding macros and environments which we call
+folding here.
+
+ Besides folding of macros and environments, AUCTeX provides support
+for Emacs' outline mode which lets you narrow the buffer content to
+certain sections of your text by hiding the parts not belonging to these
+sections.
+
+* Menu:
+
+* Font Locking:: Font Locking
+* Folding:: Folding Macros and Environments
+* Outline:: Outlining the Document
+
+\1f
+File: auctex.info, Node: Font Locking, Next: Folding, Up: Display
+
+3.1 Font Locking
+================
+
+Font locking is supposed to improve readability of the source code by
+highlighting certain keywords with different colors or fonts. It
+thereby lets you recognize the function of markup code to a certain
+extent without having to read the markup command. For general
+information on controlling font locking with Emacs' Font Lock mode, see
+*note Font Lock Mode: (emacs)Font Lock.
+
+ -- User Option: TeX-install-font-lock
+ Once font locking is enabled globally or for the major modes
+ provided by AUCTeX, the font locking patterns and functionality of
+ font-latex are activated by default. You can switch to a
+ different font locking scheme or disable font locking in AUCTeX by
+ customizing the variable `TeX-install-font-lock'.
+
+ Besides font-latex AUCTeX ships with a scheme which is derived
+ from Emacs' default LaTeX mode and activated by choosing
+ `tex-font-setup'. Be aware that this scheme is not coupled with
+ AUCTeX's style system and not the focus of development. Therefore
+ and due to font-latex being much more feature-rich the following
+ explanations will only cover font-latex.
+
+ In case you want to hook in your own fontification scheme, you can
+ choose `other' and insert the name of the function which sets up
+ your font locking patterns. If you want to disable fontification
+ in AUCTeX completely, choose `ignore'.
+
+ font-latex provides many options for customization which are
+accessible with `M-x customize-group RET font-latex RET'. For this
+description the various options are explained in conceptional groups.
+
+* Menu:
+
+* Fontification of macros:: Fontification of macros
+* Fontification of quotes:: Fontification of quotes
+* Fontification of math:: Fontification of math constructs
+* Verbatim content:: Verbatim macros and environments
+* Faces:: Faces used by font-latex
+* Known problems:: Known fontification problems
+
+\1f
+File: auctex.info, Node: Fontification of macros, Next: Fontification of quotes, Up: Font Locking
+
+3.1.1 Fontification of macros
+-----------------------------
+
+Highlighting of macros can be customized by adapting keyword lists which
+can be found in the customization group `font-latex-keywords'.
+
+ Three types of macros can be handled differently with respect to
+fontification:
+
+ 1. Commands of the form `\foo[bar]{baz}' which consist of the macro
+ itself, optional arguments in square brackets and mandatory
+ arguments in curly braces. For the command itself the face
+ `font-lock-keyword-face' will be used and for the optional
+ arguments the face `font-lock-variable-name-face'. The face
+ applied to the mandatory argument depends on the macro class
+ represented by the respective built-in variables.
+
+ 2. Declaration macros of the form `{\foo text}' which consist of the
+ macro which may be enclosed in a TeX group together with text to be
+ affected by the macro. In case a TeX group is present, the macro
+ will get the face `font-lock-keyword-face' and the text will get
+ the face configured for the respective macro class. If no TeX
+ group is present, the latter face will be applied to the macro
+ itself.
+
+ 3. Simple macros of the form `\foo' which do not have any arguments or
+ groupings. The respective face will be applied to the macro
+ itself.
+
+ Customization variables for `\foo[bar]{baz}' type macros allow both
+the macro name and the sequence of arguments to be specified. The
+latter is done with a string which can contain the characters
+`*'
+ indicating the existence of a starred variant for the macro,
+
+`['
+ for optional arguments in brackets,
+
+`{'
+ for mandatory arguments in braces,
+
+`\'
+ for mandatory arguments consisting of a single macro and
+
+`|'
+ as a prefix indicating that two alternatives are following.
+ For example the specifier for `\documentclass' would be `[{' because
+the macro has one optional followed by one mandatory argument. The
+specifier for `\newcommand' would be `*|{\[[{' because there is a
+starred variant, the mandatory argument following the macro name can be
+a macro or a TeX group which can be followed by two optional arguments
+and the last token is a mandatory argument in braces.
+
+ Customization variables for the `{\foo text}' and `\foo' types are
+simple lists of strings where each entry is a macro name (without the
+leading backslash).
+
+General macro classes
+---------------------
+
+font-latex provides keyword lists for different macro classes which are
+described in the following table:
+
+`font-latex-match-function-keywords'
+ Keywords for macros defining or related to functions, like
+ `\newcommand'.
+ Type: `\macro[...]{...}'
+ Face: `font-lock-function-name-face'
+
+`font-latex-match-reference-keywords'
+ Keywords for macros defining or related to references, like `\ref'.
+ Type: `\macro[...]{...}'
+ Face: `font-lock-constant-face'
+
+`font-latex-match-textual-keywords'
+ Keywords for macros specifying textual content, like `\caption'.
+ Type: `\macro[...]{...}'
+ Face: `font-lock-type-face'
+
+`font-latex-match-variable-keywords'
+ Keywords for macros defining or related to variables, like
+ `\setlength'.
+ Type: `\macro[...]{...}'
+ Face: `font-lock-variable-name-face'
+
+`font-latex-match-warning-keywords'
+ Keywords for important macros, e.g. affecting line or page break,
+ like `\clearpage'.
+ Type: `\macro'
+ Face: `font-latex-warning-face'
+
+Sectioning commands
+-------------------
+
+Sectioning commands are macros like `\chapter' or `\section'. For
+these commands there are two fontification schemes which may be
+selected by customizing the variable `font-latex-fontify-sectioning'.
+
+ -- User Option: font-latex-fontify-sectioning
+ Per default sectioning commands will be shown in a larger,
+ proportional font, which corresponds to a number for this
+ variable. The font size varies with the sectioning level, e.g.
+ `\part' (`font-latex-sectioning-0-face') has a larger font than
+ `\paragraph' (`font-latex-sectioning-5-face'). Typically, values
+ from 1.05 to 1.3 for `font-latex-fontify-sectioning' give best
+ results, depending on your font setup. If you rather like to use
+ the base font and a different color, set the variable to the symbol
+ `color'. In this case the face `font-lock-type-face' will be used
+ to fontify the argument of the sectioning commands.
+
+ You can make font-latex aware of your own sectioning commands be
+adding them to the keyword lists:
+`font-latex-match-sectioning-0-keywords'
+(`font-latex-sectioning-0-face') ...
+`font-latex-match-sectioning-5-keywords'
+(`font-latex-sectioning-5-face').
+
+ Related to sectioning there is special support for slide titles which
+may be fontified with the face `font-latex-slide-title-face'. You can
+add macros which should appear in this face by customizing the variable
+`font-latex-match-slide-title-keywords'.
+
+Commands for changing fonts
+---------------------------
+
+LaTeX provides various macros for changing fonts or font attributes.
+For example, you can select an italic font with `\textit{...}' or bold
+with `\textbf{...}'. An alternative way to specify these fonts is to
+use special macros in TeX groups, like `{\itshape ...}' for italics and
+`{\bfseries ...}' for bold. As mentioned above, we call the former
+variants commands and the latter declarations.
+
+ Besides the macros for changing fonts provided by LaTeX there is an
+infinite number of other macros--either defined by yourself for logical
+markup or defined by macro packages--which affect the font in the
+typeset text. While LaTeX's built-in macros and macros of packages
+known by AUCTeX are already handled by font-latex, different keyword
+lists per type style and macro type are provided for entering your own
+macros which are listed in the table below.
+
+`font-latex-match-bold-command-keywords'
+ Keywords for commands specifying a bold type style.
+ Face: `font-latex-bold-face'
+
+`font-latex-match-italic-command-keywords'
+ Keywords for commands specifying an italic font.
+ Face: `font-latex-italic-face'
+
+`font-latex-match-math-command-keywords'
+ Keywords for commands specifying a math font.
+ Face: `font-latex-math-face'
+
+`font-latex-match-type-command-keywords'
+ Keywords for commands specifying a typewriter font.
+ Face: `font-lock-type-face'
+
+`font-latex-match-bold-declaration-keywords'
+ Keywords for declarations specifying a bold type style.
+ Face: `font-latex-bold-face'
+
+`font-latex-match-italic-declaration-keywords'
+ Keywords for declarations specifying an italic font.
+ Face: `font-latex-italic-face'
+
+`font-latex-match-type-declaration-keywords'
+ Keywords for declarations specifying a typewriter font.
+ Face: `font-latex-type-face'
+
+Deactivating defaults of built-in keyword classes
+-------------------------------------------------
+
+font-latex ships with predefined lists of keywords for the classes
+described above. You can disable these defaults per class by
+customizing the variable `font-latex-deactivated-keyword-classes'.
+This is a list of strings for keyword classes to be deactivated. Valid
+entries are "warning", "variable", "reference", "function" ,
+"sectioning-0", "sectioning-1", "sectioning-2", "sectioning-3",
+"sectioning-4", "sectioning-5", "textual", "bold-command",
+"italic-command", "math-command", "type-command", "bold-declaration",
+"italic-declaration", "type-declaration".
+
+ You can also get rid of certain keywords only. For example if you
+want to remove highlighting of footnotes as references you can put the
+following stanza into your init file:
+
+ (eval-after-load "font-latex"
+ '(setq-default
+ font-latex-match-reference-keywords-local
+ (remove "footnote" font-latex-match-reference-keywords-local)))
+
+ But note that this means fiddling with font-latex's internals and is
+not guaranteed to work in future versions of font-latex.
+
+User-defined keyword classes
+----------------------------
+
+In case the customization options explained above do not suffice for
+your needs, you can specify your own keyword classes by customizing the
+variable `font-latex-user-keyword-classes'.
+
+ -- User Option: font-latex-user-keyword-classes
+ Every keyword class consists of four parts, a name, a list of
+ keywords, a face and a specifier for the type of macros to be
+ highlighted.
+
+ When adding new entries, you have to use unique values for the
+ class names, i.e. they must not clash with names of the built-in
+ keyword classes or other names given by you. Additionally the
+ names must not contain spaces.
+
+ The list of keywords defines which commands and declarations
+ should be covered by the keyword class. A keyword can either be a
+ simple command name omitting the leading backslash or a list
+ consisting of the command name and a string specifying the
+ sequence of arguments for the command.
+
+ The face argument can either be an existing face or font
+ specifications made by you. (The latter option is not available
+ on XEmacs.)
+
+ There are three alternatives for the type of keywords--"Command
+ with arguments", "Declaration inside TeX group" and "Command
+ without arguments"--which correspond with the macro types
+ explained above.
+
+\1f
+File: auctex.info, Node: Fontification of quotes, Next: Fontification of math, Prev: Fontification of macros, Up: Font Locking
+
+3.1.2 Fontification of quotes
+-----------------------------
+
+Text in quotation marks is displayed with the face
+`font-latex-string-face'. Besides the various forms of opening and
+closing double and single quotation marks, so-called guillemets (<<, >>)
+can be used for quoting. Because there are two styles of using
+them--French style: << text >>; German style: >>text<<--you can
+customize the variable `font-latex-quotes' to tell font-latex which
+type you are using if the correct value cannot be derived from document
+properties.
+
+ -- User Option: font-latex-quotes
+ The default value of `font-latex-quotes' is `auto' which means
+ that font-latex will try to derive the correct type of quotation
+ mark matching from document properties like the language option
+ supplied to the babel LaTeX package.
+
+ If the automatic detection fails for you and you mostly use one
+ specific style you can set it to a specific language-dependent
+ value as well. Set the value to `german' if you are using
+ >>German quotes<< and to `french' if you are using << French
+ quotes >>. font-latex will recognize the different ways these
+ quotes can be given in your source code, i.e. (`"<', `">'), (`<<',
+ `>>') and the respective 8-bit variants.
+
+ If you set `font-latex-quotes' to nil, quoted content will not be
+ fontified.
+
+\1f
+File: auctex.info, Node: Fontification of math, Next: Verbatim content, Prev: Fontification of quotes, Up: Font Locking
+
+3.1.3 Fontification of mathematical constructs
+----------------------------------------------
+
+In LaTeX mathematics can be indicated by a variety of different
+methods: toggles (like dollar signs), macros and environments. Math
+constructs known by font-latex are displayed with the face
+`font-latex-math-face'. Support for dollar signs and shorthands like
+`\(...\)' or `\[...\]' is built-in and not customizable. Support for
+other math macros and environments can be adapted by customizing the
+variables `font-latex-match-math-command-keywords' and
+`font-latex-math-environments' respectively.
+
+ In order to make math constructs more readable, font-latex displays
+subscript and superscript parts in a smaller font and raised or lowered
+respectively. This fontification feature can be controlled with the
+variables `font-latex-fontify-script' and `font-latex-script-display'.
+
+ -- User Option: font-latex-fontify-script
+ If non-nil, fontify subscript and superscript strings.
+
+ Note that this feature is not available on XEmacs, for which it is
+ disabled per default. In GNU Emacs raising and lowering is not
+ enabled for versions 21.3 and before due to it working not
+ properly.
+
+ -- User Option: font-latex-script-display
+ Display specification for subscript and superscript content. The
+ car is used for subscript, the cdr is used for superscript. The
+ feature is implemented using so-called display properties. For
+ information on what exactly to specify for the values, see *note
+ Other Display Specifications: (elisp)Other Display Specs.
+
+\1f
+File: auctex.info, Node: Verbatim content, Next: Faces, Prev: Fontification of math, Up: Font Locking
+
+3.1.4 Verbatim macros and environments
+--------------------------------------
+
+Usually it is not desirable to have content to be typeset verbatim
+highlighted according to LaTeX syntax. Therefore this content will be
+fontified uniformly with the face `font-latex-verbatim-face'.
+
+ font-latex differentiates three different types of verbatim
+constructs for fontification. Macros with special characters like | as
+delimiters, macros with braces, and environments. Which macros and
+environments are recognized is controlled by the variables
+`LaTeX-verbatim-macros-with-delims',
+`LaTeX-verbatim-macros-with-braces', and `LaTeX-verbatim-environments'
+respectively.
+
+\1f
+File: auctex.info, Node: Faces, Next: Known problems, Prev: Verbatim content, Up: Font Locking
+
+3.1.5 Faces used by font-latex
+------------------------------
+
+In case you want to change the colors and fonts used by font-latex
+please refer to the faces mentioned in the explanations above and use
+`M-x customize-face RET <face> RET'. All faces defined by font-latex
+are accessible through a customization group by typing `M-x
+customize-group RET font-latex-highlighting-faces RET'.
+
+\1f
+File: auctex.info, Node: Known problems, Prev: Faces, Up: Font Locking
+
+3.1.6 Known fontification problems
+----------------------------------
+
+In certain cases the fontification machinery fails to interpret buffer
+contents correctly. This can lead to color bleed, i.e. large parts of a
+buffer get fontified with an inappropriate face. A typical situation
+for this to happen is the use of a dollar sign (`$') in a verbatim
+macro or environment. If font-latex is not aware of the verbatim
+construct, it assumes the dollar sign to be a toggle for mathematics and
+fontifies the following buffer content with the respective face until it
+finds a closing dollar sign or till the end of the buffer.
+
+ As a remedy you can make the verbatim construct known to font-latex,
+*note Verbatim content::. If this is not possible, you can insert a
+commented dollar sign (`%$') at the next suitable end of line as a
+quick workaround.
+
+\1f
+File: auctex.info, Node: Folding, Next: Outline, Prev: Font Locking, Up: Display
+
+3.2 Folding Macros and Environments
+===================================
+
+A popular complaint about markup languages like TeX and LaTeX is that
+there is too much clutter in the source text and that one cannot focus
+well on the content. There are macros where you are only interested in
+the content they are enclosing, like font specifiers where the content
+might already be fontified in a special way by font locking. Or macros
+the content of which you only want to see when actually editing it,
+like footnotes or citations. Similarly you might find certain
+environments or comments distracting when trying to concentrate on the
+body of your document.
+
+ With AUCTeX's folding functionality you can collapse those items and
+replace them by a fixed string, the content of one of their arguments,
+or a mixture of both. If you want to make the original text visible
+again in order to view or edit it, move point sideways onto the
+placeholder (also called display string) or left-click with the mouse
+pointer on it. (The latter is currently only supported on Emacs.) The
+macro or environment will unfold automatically, stay open as long as
+point is inside of it and collapse again once you move point out of it.
+(Note that folding of environments currently does not work in every
+AUCTeX mode.)
+
+ In order to use this feature, you have to activate `TeX-fold-mode'
+which will activate the auto-reveal feature and the necessary commands
+to hide and show macros and environments. You can activate the mode in
+a certain buffer by typing the command `M-x TeX-fold-mode RET' or using
+the keyboard shortcut `C-c C-o C-f'. If you want to use it every time
+you edit a LaTeX document, add it to a hook:
+
+ (add-hook 'LaTeX-mode-hook (lambda ()
+ (TeX-fold-mode 1)))
+
+ If it should be activated in all AUCTeX modes, use `TeX-mode-hook'
+instead of `LaTeX-mode-hook'.
+
+ Once the mode is active there are several commands available to hide
+and show macros, environments and comments:
+
+ -- Command: TeX-fold-buffer
+ (`C-c C-o C-b') Hide all foldable items in the current buffer
+ according to the setting of `TeX-fold-type-list'.
+
+ If you want to have this done automatically every time you open a
+ file, add it to a hook and make sure the function is called after
+ font locking is set up for the buffer. The following code should
+ accomplish this:
+
+ (add-hook 'find-file-hook 'TeX-fold-buffer t)
+
+ The command can be used any time to refresh the whole buffer and
+ fold any new macros and environments which were inserted after the
+ last invocation of the command.
+
+ -- User Option: TeX-fold-type-list
+ List of symbols determining the item classes to consider for
+ folding. This can be macros, environments and comments. Per
+ default only macros and environments are folded.
+
+ -- User Option: TeX-fold-force-fontify
+ In order for all folded content to get the right faces, the whole
+ buffer has to be fontified before folding is carried out.
+ `TeX-fold-buffer' therefore will force fontification of unfontified
+ regions. As this will prolong the time folding takes, you can
+ prevent forced fontification by customizing the variable
+ `TeX-fold-force-fontify'.
+
+ -- User Option: TeX-fold-preserve-comments
+ By default items found in comments will be folded. If your
+ comments often contain unfinished code this might lead to
+ problems. Give this variable a non-nil value and foldable items
+ in your comments will be left alone.
+
+ -- Command: TeX-fold-region
+ (`C-c C-o C-r') Hide all configured macros in the marked region.
+
+ -- Command: TeX-fold-paragraph
+ (`C-c C-o C-p') Hide all configured macros in the paragraph
+ containing point.
+
+ -- Command: TeX-fold-macro
+ (`C-c C-o C-m') Hide the macro on which point currently is located.
+ If the name of the macro is found in `TeX-fold-macro-spec-list',
+ the respective display string will be shown instead. If it is not
+ found, the name of the macro in sqare brackets or the default
+ string for unspecified macros
+ (`TeX-fold-unspec-macro-display-string') will be shown, depending
+ on the value of the variable `TeX-fold-unspec-use-name'.
+
+ -- Command: TeX-fold-env
+ (`C-c C-o C-e') Hide the environment on which point currently is
+ located. The behavior regarding the display string is analogous to
+ `TeX-fold-macro' and determined by the variables
+ `TeX-fold-env-spec-list' and `TeX-fold-unspec-env-display-string'
+ respectively.
+
+ -- Command: TeX-fold-math
+ Hide the math macro on which point currently is located. If the
+ name of the macro is found in `TeX-fold-math-spec-list', the
+ respective display string will be shown instead. If it is not
+ found, the name of the macro in sqare brackets or the default
+ string for unspecified macros
+ (`TeX-fold-unspec-macro-display-string') will be shown, depending
+ on the value of the variable `TeX-fold-unspec-use-name'.
+
+ -- Command: TeX-fold-comment
+ (`C-c C-o C-c') Hide the comment point is located on.
+
+ -- Command: TeX-fold-clearout-buffer
+ (`C-c C-o b') Permanently unfold all macros and environments in the
+ current buffer.
+
+ -- Command: TeX-fold-clearout-region
+ (`C-c C-o r') Permanently unfold all macros and environments in the
+ marked region.
+
+ -- Command: TeX-fold-clearout-paragraph
+ (`C-c C-o p') Permanently unfold all macros and environments in the
+ paragraph containing point.
+
+ -- Command: TeX-fold-clearout-item
+ (`C-c C-o i') Permanently show the macro or environment on which
+ point currently is located. In contrast to temporarily opening the
+ macro when point is moved sideways onto it, the macro will be
+ permanently unfolded and will not collapse again once point is
+ leaving it.
+
+ -- Command: TeX-fold-dwim
+ (`C-c C-o C-o') Hide or show items according to the current
+ context. If there is folded content, unfold it. If there is a
+ marked region, fold all configured content in this region. If
+ there is no folded content but a macro or environment, fold it.
+
+ In case you want to use a different prefix than `C-c C-o' for these
+commands you can customize the variable `TeX-fold-command-prefix'.
+(Note that this will not change the key binding for activating the
+mode.)
+
+ The commands above will only take macros or environments into
+consideration which are specified in the variables
+`TeX-fold-macro-spec-list' or `TeX-fold-env-spec-list' respectively.
+
+ -- User Option: TeX-fold-macro-spec-list
+ List of replacement specifiers and macros to fold. The specifier
+ can be a string, an integer or a function symbol.
+
+ If you specify a string, it will be used as a display replacement
+ for the whole macro. Numbers in braces, brackets, parens or angle
+ brackets will be replaced by the respective macro argument. For
+ example `{1}' will be replaced by the first mandatory argument of
+ the macro. One can also define alternatives within the specifier
+ which are used if an argument is not found. Alternatives are
+ separated by `||'. They are most useful with optional arguments.
+ As an example, the default specifier for `\item' is `[1]:||*' which
+ means that if there is an optional argument, its value is shown
+ followed by a colon. If there is no optional argument, only an
+ asterisk is used as the display string.
+
+ If you specify a number as the first element, the content of the
+ respective mandatory argument of a LaTeX macro will be used as the
+ placeholder.
+
+ If the first element is a function symbol, the function will be
+ called with all mandatory arguments of the macro and the result of
+ the function call will be used as a replacement for the macro.
+
+ The placeholder is made by copying the text from the buffer
+ together with its properties, i.e. its face as well. If
+ fontification has not happened when this is done (e.g. because of
+ lazy font locking) the intended fontification will not show up.
+ As a workaround you can leave Emacs idle a few seconds and wait
+ for stealth font locking to finish before you fold the buffer. Or
+ you just re-fold the buffer with `TeX-fold-buffer' when you notice
+ a wrong fontification.
+
+ -- User Option: TeX-fold-env-spec-list
+ List of display strings or argument numbers and environments to
+ fold. Argument numbers refer to the `\begin' statement. That
+ means if you have e.g. `\begin{tabularx}{\linewidth}{XXX} ...
+ \end{tabularx}' and specify 3 as the argument number, the resulting
+ display string will be "XXX".
+
+ -- User Option: TeX-fold-math-spec-list
+ List of display strings and math macros to fold.
+
+ The variables `TeX-fold-macro-spec-list', `TeX-fold-env-spec-list',
+and `TeX-fold-math-spec-list' apply to any AUCTeX mode. If you want to
+make settings which are only applied to LaTeX mode, you can use the
+mode-specific variables `LaTeX-fold-macro-spec-list',
+`LaTeX-fold-env-spec-list', and `LaTeX-fold-math-spec-list'
+
+ -- User Option: TeX-fold-unspec-macro-display-string
+ Default display string for macros which are not specified in
+ `TeX-fold-macro-spec-list'.
+
+ -- User Option: TeX-fold-unspec-env-display-string
+ Default display string for environments which are not specified in
+ `TeX-fold-env-spec-list'.
+
+ -- User Option: TeX-fold-unspec-use-name
+ If non-nil the name of the macro or environment surrounded by
+ square brackets is used as display string, otherwise the defaults
+ specified in `TeX-fold-unspec-macro-display-string' or
+ `TeX-fold-unspec-env-display-string' respectively.
+
+ When you hover with the mouse pointer over folded content, its
+original text will be shown in a tooltip or the echo area depending on
+Tooltip mode being activate. In order to avoid exorbitantly big
+tooltips and to cater for the limited space in the echo area the
+content will be cropped after a certain amount of characters defined by
+the variable `TeX-fold-help-echo-max-length'.
+
+ -- User Option: TeX-fold-help-echo-max-length
+ Maximum length of original text displayed in a tooltip or the echo
+ area for folded content. Set it to zero in order to disable this
+ feature.
+
+\1f
+File: auctex.info, Node: Outline, Prev: Folding, Up: Display
+
+3.3 Outlining the Document
+==========================
+
+AUCTeX supports the standard outline minor mode using LaTeX/ConTeXt
+sectioning commands as header lines. *Note Outline Mode:
+(emacs)Outline Mode.
+
+ You can add your own headings by setting the variable
+`TeX-outline-extra'.
+
+ -- Variable: TeX-outline-extra
+ List of extra TeX outline levels.
+
+ Each element is a list with two entries. The first entry is the
+ regular expression matching a header, and the second is the level
+ of the header. A `^' is automatically prepended to the regular
+ expressions in the list, so they must match text at the beginning
+ of the line.
+
+ See `LaTeX-section-list' or `ConTeXt-INTERFACE-section-list' for
+ existing header levels.
+
+ The following example add `\item' and `\bibliography' headers, with
+`\bibliography' at the same outline level as `\section', and `\item'
+being below `\subparagraph'.
+
+ (setq TeX-outline-extra
+ '(("[ \t]*\\\\\\(bib\\)?item\\b" 7)
+ ("\\\\bibliography\\b" 2)))
+
+ You may want to check out the unbundled `out-xtra' package for even
+better outline support. It is available from your favorite emacs lisp
+archive.
+
+\1f
+File: auctex.info, Node: Processing, Next: Customization, Prev: Display, Up: Top
+
+4 Starting Processors, Viewers and Other Programs
+*************************************************
+
+The most powerful features of AUCTeX may be those allowing you to run
+TeX, LaTeX, ConTeXt and other external commands like BibTeX and
+`makeindex' from within Emacs, viewing and printing the results, and
+moreover allowing you to _debug_ your documents.
+
+ AUCTeX comes with a special tool bar for TeX and LaTeX which
+provides buttons for the most important commands. You can enable or
+disable it by customizing the options `plain-TeX-enable-toolbar' and
+`LaTeX-enable-toolbar' in the `TeX-tool-bar' customization group.
+
+* Menu:
+
+* Commands:: Invoking external commands.
+* Viewing:: Invoking external viewers.
+* Debugging:: Debugging TeX and LaTeX output.
+* Checking:: Checking the document.
+* Control:: Controlling the processes.
+* Cleaning:: Cleaning intermediate and output files.
+* Documentation:: Documentation about macros and packages.
+
+\1f
+File: auctex.info, Node: Commands, Next: Viewing, Up: Processing
+
+4.1 Executing Commands
+======================
+
+Formatting the document with TeX, LaTeX or ConTeXt, viewing with a
+previewer, printing the document, running BibTeX, making an index, or
+checking the document with `lacheck' or `chktex' all require running an
+external command.
+
+* Menu:
+
+* Starting a Command:: Starting a Command on a Document or Region
+* Selecting a Command:: Selecting and Executing a Command
+* Processor Options:: Options for TeX Processors
+
+\1f
+File: auctex.info, Node: Starting a Command, Next: Selecting a Command, Up: Commands
+
+4.1.1 Starting a Command on a Document or Region
+------------------------------------------------
+
+There are two ways to run an external command, you can either run it on
+the current document with `TeX-command-master', or on the current
+region with `TeX-command-region'. A special case of running TeX on a
+region is `TeX-command-buffer' which differs from `TeX-command-master'
+if the current buffer is not its own master file.
+
+ -- Command: TeX-command-master
+ (`C-c C-c') Query the user for a command, and run it on the master
+ file associated with the current buffer. The name of the master
+ file is controlled by the variable `TeX-master'. The available
+ commands are controlled by the variable `TeX-command-list'.
+
+ -- Command: TeX-command-region
+ (`C-c C-r') Query the user for a command, and run it on the
+ contents of the selected region. The region contents are written
+ into the region file, after extracting the header and trailer from
+ the master file. If mark is inactive (which can happen with
+ Transient Mark mode), use the old region. See also the command
+ `TeX-pin-region' about how to fix a region.
+
+ The name of the region file is controlled by the variable
+ `TeX-region'. The name of the master file is controlled by the
+ variable `TeX-master'. The header is all text up to the line
+ matching the regular expression `TeX-header-end'. The trailer is
+ all text from the line matching the regular expression
+ `TeX-trailer-start'. The available commands are controlled by the
+ variable `TeX-command-list'.
+
+ -- Command: TeX-command-buffer
+ (`C-c C-b') Query the user for a command, and apply it to the
+ contents of the current buffer. The buffer contents are written
+ into the region file, after extracting the header and trailer from
+ the master file. The command is then actually run on the region
+ file. See above for details.
+
+ -- User Option: TeX-region
+ The name of the file for temporarily storing the text when
+ formatting the current region.
+
+ -- User Option: TeX-header-end
+ A regular expression matching the end of the header. By default,
+ this is `\begin{document}' in LaTeX mode and `%**end of header' in
+ TeX mode.
+
+ -- User Option: TeX-trailer-start
+ A regular expression matching the start of the trailer. By
+ default, this is `\end{document}' in LaTeX mode and `\bye' in TeX
+ mode.
+
+ If you want to change the values of `TeX-header-end' and
+`TeX-trailer-start' you can do this for all files by setting the
+variables in a mode hook or per file by specifying them as file
+variables (*note File Variables: (emacs)File Variables.).
+
+ -- Command: TeX-pin-region
+ (`C-c C-t C-r') If you don't have a mode like Transient Mark mode
+ active, where marks get disabled automatically, the region would
+ need to get properly set before each call to `TeX-command-region'.
+ If you fix the current region with `C-c C-t C-r', then it will get
+ used for more commands even though mark and point may change. An
+ explicitly activated mark, however, will always define a new
+ region when calling `TeX-command-region'.
+
+ AUCTeX will allow one process for each document, plus one process
+for the region file to be active at the same time. Thus, if you are
+editing N different documents, you can have N plus one processes
+running at the same time. If the last process you started was on the
+region, the commands described in *note Debugging:: and *note Control::
+will work on that process, otherwise they will work on the process
+associated with the current document.
+
+\1f
+File: auctex.info, Node: Selecting a Command, Next: Processor Options, Prev: Starting a Command, Up: Commands
+
+4.1.2 Selecting and Executing a Command
+---------------------------------------
+
+Once you started the command selection with `C-c C-c', `C-c C-s' or
+`C-c C-b' you will be prompted for the type of command. AUCTeX will
+try to guess which command is appropriate in the given situation and
+propose it as default. Usually this is a processor like `TeX' or
+`LaTeX' if the document was changed or a viewer if the document was
+just typeset. Other commands can be selected in the minibuffer with
+completion support by typing <TAB>.
+
+ The available commands are defined by the variable
+`TeX-command-list'. Per default it includes commands for typesetting
+the document (e.g. `LaTeX'), for viewing the output (`View'), for
+printing (`Print'), for generating an index (`Index') or for spell
+checking (`Spell') to name but a few. You can also add your own
+commands by adding entries to `TeX-command-list'. Refer to its doc
+string for information about its syntax. You might also want to look
+at `TeX-expand-list' to learn about the expanders you can use in
+`TeX-command-list'.
+
+ Note that the default of the variable occasionally changes.
+Therefore it is advisable to add to the list rather than overwriting
+it. You can do this with a call to `add-to-list' in your init file.
+For example, if you wanted to add a command for running a program called
+`foo' on the master or region file, you could do this with the
+following form.
+
+ (eval-after-load "tex"
+ '(add-to-list 'TeX-command-list
+ '("Foo" "foo %s" TeX-run-command t t :help "Run foo") t))
+
+ As mentioned before, AUCTeX will try to guess what command you want
+to invoke. If you want to use another command than `TeX', `LaTeX' or
+whatever processor AUCTeX thinks is appropriate for the current mode,
+set the variable `TeX-command-default'. You can do this for all files
+by setting it in a mode hook or per file by specifying it as a file
+variable (*note File Variables: (emacs)File Variables.).
+
+ -- User Option: TeX-command-default
+ The default command to run in this buffer. Must be an entry in
+ `TeX-command-list'.
+
+ After confirming a command to execute, AUCTeX will try to save any
+buffers related to the document, and check if the document needs to be
+reformatted. If the variable `TeX-save-query' is non-nil, AUCTeX will
+query before saving each file. By default AUCTeX will check emacs
+buffers associated with files in the current directory, in one of the
+`TeX-macro-private' directories, and in the `TeX-macro-global'
+directories. You can change this by setting the variable
+`TeX-check-path'.
+
+ -- User Option: TeX-check-path
+ Directory path to search for dependencies.
+
+ If nil, just check the current file. Used when checking if any
+ files have changed.
+
+\1f
+File: auctex.info, Node: Processor Options, Prev: Selecting a Command, Up: Commands
+
+4.1.3 Options for TeX Processors
+--------------------------------
+
+There are some options you can customize affecting which processors are
+invoked or the way this is done and which output they produce as a
+result. These options control if DVI or PDF output should be produced,
+if TeX should be started in interactive or nonstop mode, if source
+specials or a SyncTeX file should be produced for making inverse and
+forward search possible or which TeX engine should be used instead of
+regular TeX, like PDFTeX, Omega or XeTeX.
+
+ -- Command: TeX-PDF-mode
+ (`C-c C-t C-p') This command toggles the PDF mode of AUCTeX, a
+ buffer-local minor mode. You can customize `TeX-PDF-mode' to give
+ it a different default. The default is used when AUCTeX does not
+ have additional clue about what a document might want. This
+ option usually results in calling either PDFTeX or ordinary TeX.
+
+ -- User Option: TeX-DVI-via-PDFTeX
+ If this is set, DVI will also be produced by calling PDFTeX,
+ setting `\pdfoutput=0'. This makes it possible to use PDFTeX
+ features like character protrusion even when producing DVI files.
+ Contemporary TeX distributions do this anyway, so that you need
+ not enable the option within AUCTeX.
+
+ -- Command: TeX-interactive-mode
+ (`C-c C-t C-i') This command toggles the interactive mode of
+ AUCTeX, a global minor mode. You can customize
+ `TeX-interactive-mode' to give it a different default. In
+ interactive mode, TeX will pause with an error prompt when errors
+ are encountered and wait for the user to type something.
+
+ -- Command: TeX-source-correlate-mode
+ (`C-c C-t C-s') Toggles support for forward and inverse search.
+ Forward search refers to jumping to the place in the previewed
+ document corresponding to where point is located in the document
+ source and inverse search to the other way round. *Note I/O
+ Correlation::.
+
+ You can permanently activate `TeX-source-correlate-mode' by
+ customizing the variable `TeX-source-correlate-mode'. There is a
+ bunch of customization options for the mode, use `M-x
+ customize-group <RET> TeX-view <RET>' to find out more.
+
+ AUCTeX is aware of three different means to do I/O correlation:
+ source specials (only DVI output), the pdfsync LaTeX package (only
+ PDF output) and SyncTeX. The choice between source specials and
+ SyncTeX can be controlled with the variable
+ `TeX-source-correlate-method'.
+
+ Should you use source specials it has to be stressed _very_
+ strongly however, that source specials can cause differences in
+ page breaks and spacing, can seriously interfere with various
+ packages and should thus _never_ be used for the final version of
+ a document. In particular, fine-tuning the page breaks should be
+ done with source specials switched off.
+
+ AUCTeX also allows you to easily select different TeX engines for
+processing, either by using the entries in the `TeXing Options' submenu
+below the `Command' menu or by calling the function `TeX-engine-set'.
+These eventually set the variable `TeX-engine' which you can also
+modify directly.
+
+ -- User Option: TeX-engine
+ This variable allows you to choose which TeX engine should be used
+ for typesetting the document, i.e. the executables which will be
+ used when you invoke the `TeX' or `LaTeX' commands. The value
+ should be one of the symbols defined in `TeX-engine-alist-builtin'
+ or `TeX-engine-alist'. The symbols `default', `xetex', `luatex'
+ and `omega' are available from the built-in list.
+
+ Note that `TeX-engine' is buffer-local, so setting the variable
+directly or via the above mentioned menu or function will not take
+effect in other buffers. If you want to activate an engine for all
+AUCTeX modes, set `TeX-engine' in your init file, e.g. by using `M-x
+customize-variable <RET>'. If you want to activate it for a certain
+AUCTeX mode only, set the variable in the respective mode hook. If you
+want to activate it for certain files, set it through file variables
+(*note File Variables: (emacs)File Variables.).
+
+ Should you need to change the executable names related to the
+different engine settings, there are some variables you can tweak.
+Those are `TeX-command', `LaTeX-command', `TeX-Omega-command',
+`LaTeX-Omega-command', `ConTeXt-engine' and `ConTeXt-Omega-engine'.
+The rest of the executables is defined directly in
+`TeX-engine-alist-builtin'. If you want to override an entry from
+that, add an entry to `TeX-engine-alist' that starts with the same
+symbol as that the entry in the built-in list and specify the
+executables you want to use instead. You can also add entries to
+`TeX-engine-alist' in order to add support for engines not covered per
+default.
+
+ -- User Option: TeX-engine-alist
+ Alist of TeX engines and associated commands. Each entry is a
+ list with a maximum of five elements. The first element is a
+ symbol used to identify the engine. The second is a string
+ describing the engine. The third is the command to be used for
+ plain TeX. The fourth is the command to be used for LaTeX. The
+ fifth is the command to be used for the `--engine' parameter of
+ ConTeXt's `texexec' program. Each command can either be a
+ variable or a string. An empty string or nil means there is no
+ command available.
+
+ You can customize AUCTeX to show the processor output as it is
+produced.
+
+ -- User Option: TeX-show-compilation
+ If non-nil, the output of TeX compilation is shown in another
+ window.
+
+\1f
+File: auctex.info, Node: Viewing, Next: Debugging, Prev: Commands, Up: Processing
+
+4.2 Viewing the Formatted Output
+================================
+
+AUCTeX allows you to start external programs for previewing the
+formatted output of your document.
+
+* Menu:
+
+* Starting Viewers:: Starting viewers
+* I/O Correlation:: Forward and inverse search
+
+\1f
+File: auctex.info, Node: Starting Viewers, Next: I/O Correlation, Up: Viewing
+
+4.2.1 Starting Viewers
+----------------------
+
+Viewers are normally invoked by pressing `C-c C-c' once the document is
+formatted, which will propose the View command, or by activating the
+respective entry in the Command menu. Alternatively you can type `C-c
+C-v' which calls the function `TeX-view'.
+
+ -- Command: TeX-view
+ (`C-c C-v') Start a viewer without confirmation. The viewer is
+ started either on a region or the master file, depending on the
+ last command issued. This is especially useful for jumping to the
+ location corresponding to point in the viewer when using
+ `TeX-source-correlate-mode'.
+
+ AUCTeX will try to guess which type of viewer (DVI, PostScript or
+PDF) has to be used and what options are to be passed over to it. This
+decision is based on the output files present in the working directory
+as well as the class and style options used in the document. For
+example, if there is a DVI file in your working directory, a DVI viewer
+will be invoked. In case of a PDF file it will be a PDF viewer. If
+you specified a special paper format like `a5paper' or use the
+`landscape' option, this will be passed to the viewer by the
+appropriate options. Especially some DVI viewers depend on this kind
+of information in order to display your document correctly. In case
+you are using `pstricks' or `psfrag' in your document, a DVI viewer
+cannot display the contents correctly and a PostScript viewer will be
+invoked instead.
+
+ The association between the tests for the conditions mentioned above
+and the viewers is made in the variable `TeX-view-program-selection'.
+Therefore this variable is the starting point for customization if you
+want to use other viewers than the ones suggested by default.
+
+ -- User Option: TeX-view-program-selection
+ This is a list of predicates and viewers which is evaluated from
+ front to back in order to find out which viewer to call under the
+ given conditions. In the first element of each list item you can
+ reference one or more predicates defined in
+ `TeX-view-predicate-list' or `TeX-view-predicate-list-builtin'.
+ In the second element you can reference a viewer defined in
+ `TeX-view-program-list' or `TeX-view-program-list-builtin'. The
+ viewer of the first item with a positively evaluated predicate is
+ selected.
+
+ So `TeX-view-program-selection' only contains references to the
+actual implementations of predicates and viewer commands respectively
+which can be found elsewhere. AUCTeX comes with a set of preconfigured
+predicates and viewer commands which are stored in the variables
+`TeX-view-predicate-list-builtin' and `TeX-view-program-list-builtin'
+respectively. If you are not satisfied with those and want to
+overwrite one of them or add your own definitions, you can do so via
+the variables `TeX-view-predicate-list' and `TeX-view-program-list'.
+
+ -- User Option: TeX-view-predicate-list
+ This is a list of predicates for viewer selection and invocation.
+ The first element of each list item is a symbol and the second
+ element a Lisp form to be evaluated. The form should return nil
+ if the predicate is not fulfilled.
+
+ A built-in predicate from `TeX-view-predicate-list-builtin' can be
+ overwritten by defining a new predicate with the same symbol.
+
+ -- User Option: TeX-view-program-list
+ This is a list of viewer specifications each consisting of a
+ symbolic name and either a command line or a function to be
+ invoked when the viewer is called. If a command line is used,
+ parts of it can be conditionalized by prefixing them with
+ predicates from `TeX-view-predicate-list' or
+ `TeX-view-predicate-list-builtin'. (See the doc string for the
+ exact format to use.) The command line can also contain
+ placeholders as defined in `TeX-expand-list' which are expanded
+ before the viewer is called.
+
+ A built-in viewer spec from `TeX-view-program-list-builtin' can be
+ overwritten by defining a new viewer spec with the same name.
+
+ Note that the viewer selection and invocation as described above will
+only work if certain default settings in AUCTeX are intact. For one,
+the whole viewer selection machinery will only be triggered if the `%V'
+expander in `TeX-expand-list' is unchanged. So if you have trouble
+with the viewer invocation you might check if there is an older
+customization of the variable in place. In addition, the use of a
+function in `TeX-view-program-list' only works if the View command in
+`TeX-command-list' makes use of the hook `TeX-run-discard-or-function'.
+
+ Note also that the implementation described above replaces an older
+one which was less flexible. This old implementation works with the
+variables `TeX-output-view-style' and `TeX-view-style' which are used
+to associate file types and style options with viewers. If desired you
+can reactivate it by using the placeholder `%vv' for the View command
+in `TeX-command-list'. Note however, that it is bound to be removed
+from AUCTeX once the new implementation proved to be satisfactory. For
+the time being, find a short description of the mentioned customization
+options below.
+
+ -- User Option: TeX-output-view-style
+ List of output file extensions, style options and view options.
+ Each item of the list consists of three elements. If the first
+ element (a regular expression) matches the output file extension,
+ and the second element (a regular expression) matches the name of
+ one of the style options, any occurrence of the string `%V' in a
+ command in `TeX-command-list' will be replaced with the third
+ element.
+
+ -- User Option: TeX-view-style
+ List of style options and view options. This is the predecessor of
+ `TeX-output-view-style' which does not provide the possibility to
+ specify output file extensions. It is used as a fallback in case
+ none of the alternatives specified in `TeX-output-view-style'
+ match. In case none of the entries in `TeX-view-style' match
+ either, no suggestion for a viewer is made.
+
+\1f
+File: auctex.info, Node: I/O Correlation, Prev: Starting Viewers, Up: Viewing
+
+4.2.2 Forward and Inverse Search
+--------------------------------
+
+Forward and inverse search refer to the correlation between the document
+source in the editor and the typeset document in the viewer. Forward
+search allows you to jump to the place in the previewed document
+corresponding to a certain line in the document source and inverse
+search vice versa.
+
+ AUCTeX supports three methods for forward and inverse search: source
+specials (only DVI output), the pdfsync LaTeX package (only PDF output)
+and SyncTeX (any type of output). If you want to make use of forward
+and inverse searching with source specials or SyncTeX, switch on
+`TeX-source-correlate-mode'. *Note Processor Options::, on how to do
+that. The use of the pdfsync package is detected automatically if
+document parsing is enabled.
+
+ Forward search happens automatically upon calling the viewer, e.g. by
+typing `C-c C-v' (`TeX-view'). This will open the viewer or bring it
+to front and display the output page corresponding to the position of
+point in the source file. AUCTeX will automatically pass the necessary
+command line options to the viewer for this to happen.
+
+ Upon opening the viewer you will be asked if you want to start a
+server process (Gnuserv or Emacs server) which is necessary for inverse
+search. This happens only if there is no server running already. You
+can customize the variable `TeX-source-correlate-start-server' to
+inhibit the question and always or never start the server respectively.
+
+ -- User Option: TeX-source-correlate-start-server
+ If `TeX-source-correlate-mode' is active and a viewer is invoked,
+ the default behavior is to ask if a server process should be
+ started. Set this variable to `t' if the question should be
+ inhibited and the server should always be started. Set it to
+ `nil' if the server should never be started. Inverse search will
+ not be available in the latter case.
+
+ Inverse search, i.e. jumping to the part of your document source in
+Emacs corresponding to a certain position in the viewer, is triggered
+from the viewer, typically by a mouse click. Refer to the documentation
+of your viewer to find out how it has to be configured and what you have
+to do exactly. In xdvi you normally have to use `C-down-mouse-1'.
+
+\1f
+File: auctex.info, Node: Debugging, Next: Checking, Prev: Viewing, Up: Processing
+
+4.3 Catching the errors
+=======================
+
+Once you've formatted your document you may `debug' it, i.e. browse
+through the errors (La)TeX reported.
+
+ -- Command: TeX-next-error
+ (`C-c `') Go to the next error reported by TeX. The view will be
+ split in two, with the cursor placed as close as possible to the
+ error in the top view. In the bottom view, the error message will
+ be displayed along with some explanatory text.
+
+ Normally AUCTeX will only report real errors, but you may as well
+ask it to report `bad boxes' and warnings as well.
+
+ -- Command: TeX-toggle-debug-bad-boxes
+ (`C-c C-t C-b') Toggle whether AUCTeX should stop at bad boxes
+ (i.e. overfull and underfull boxes) as well as normal errors.
+
+ -- Command: TeX-toggle-debug-warnings
+ (`C-c C-t C-w') Toggle whether AUCTeX should stop at warnings as
+ well as normal errors.
+
+ As default, AUCTeX will display a special help buffer containing the
+error reported by TeX along with the documentation. There is however
+an `expert' option, which allows you to display the real TeX output.
+
+ -- User Option: TeX-display-help
+ If t AUCTeX will automatically display a help text whenever an
+ error is encountered using `TeX-next-error' (`C-c `'). If nil a
+ terse information about the error is displayed in the echo area.
+ If `expert' AUCTeX will display the output buffer with the raw TeX
+ output.
+
+\1f
+File: auctex.info, Node: Checking, Next: Control, Prev: Debugging, Up: Processing
+
+4.4 Checking for problems
+=========================
+
+Running TeX or LaTeX will only find regular errors in the document, not
+examples of bad style. Furthermore, description of the errors may
+often be confusing. The utility `lacheck' can be used to find style
+errors, such as forgetting to escape the space after an abbreviation or
+using `...' instead of `\ldots' and many other problems like that. You
+start `lacheck' with `C-c C-c Check <RET>'. The result will be a list
+of errors in the `*compilation*' buffer. You can go through the errors
+with `C-x `' (`next-error', *note Compilation: (emacs)Compilation.),
+which will move point to the location of the next error.
+
+ Another newer program which can be used to find errors is `chktex'.
+It is much more configurable than `lacheck', but doesn't find all the
+problems `lacheck' does, at least in its default configuration. You
+must install the programs before using them, and for `chktex' you may
+also need modify `TeX-command-list' unless you use its `lacheck'
+compatibility wrapper. You can get `lacheck' from
+`<URL:ftp://ftp.ctan.org/tex-archive/support/lacheck/>' or
+alternatively `chktex' from
+`<URL:ftp://ftp.ctan.org/tex-archive/support/chktex/>'.
+
+\1f
+File: auctex.info, Node: Control, Next: Cleaning, Prev: Checking, Up: Processing
+
+4.5 Controlling the output
+==========================
+
+A number of commands are available for controlling the output of an
+application running under AUCTeX
+
+ -- Command: TeX-kill-job
+ (`C-c C-k') Kill currently running external application. This
+ may be either of TeX, LaTeX, previewer, BibTeX, etc.
+
+ -- Command: TeX-recenter-output-buffer
+ (`C-c C-l') Recenter the output buffer so that the bottom line is
+ visible.
+
+ -- Command: TeX-home-buffer
+ (`C-c ^') Go to the `master' file in the document associated with
+ the current buffer, or if already there, to the file where the
+ current process was started.
+
+\1f
+File: auctex.info, Node: Cleaning, Next: Documentation, Prev: Control, Up: Processing
+
+4.6 Cleaning intermediate and output files
+==========================================
+
+ -- Command: TeX-clean
+ Remove generated intermediate files. In case a prefix argument is
+ given, remove output files as well.
+
+ Canonical access to the function is provided by the `Clean' and
+ `Clean All' entries in `TeX-command-list', invokable with `C-c
+ C-c' or the Command menu.
+
+ The patterns governing which files to remove can be adapted
+ separately for each AUCTeX mode by means of the variables
+ `plain-TeX-clean-intermediate-suffixes',
+ `plain-TeX-clean-output-suffixes',
+ `LaTeX-clean-intermediate-suffixes', `LaTeX-clean-output-suffixes',
+ `docTeX-clean-intermediate-suffixes',
+ `docTeX-clean-output-suffixes',
+ `Texinfo-clean-intermediate-suffixes',
+ `Texinfo-clean-output-suffixes',
+ `ConTeXt-clean-intermediate-suffixes' and
+ `ConTeXt-clean-output-suffixes'.
+
+ -- User Option: TeX-clean-confirm
+ Control if deletion of intermediate and output files has to be
+ confirmed before it is actually done. If non-nil, ask before
+ deleting files.
+
+\1f
+File: auctex.info, Node: Documentation, Prev: Cleaning, Up: Processing
+
+4.7 Documentation about macros and packages
+===========================================
+
+ -- Command: TeX-doc
+ (`C-c ?') Get documentation about macros, packages or TeX & Co.
+ in general. The function will prompt for the name of a command or
+ manual, providing a list of available keywords for completion. If
+ point is on a command or word with available documentation, this
+ will be suggested as default.
+
+ In case no documentation could be found, a prompt for querying the
+ `texdoc' program is shown, should the latter be available.
+
+ The command can be invoked by the key binding mentioned above as
+ well as the `Find Documentation...' entry in the mode menu.
+
+\1f
+File: auctex.info, Node: Customization, Next: Appendices, Prev: Processing, Up: Top
+
+5 Customization and Extension
+*****************************
+
+* Menu:
+
+* Modes and Hooks:: Modes and Hooks
+* Multifile:: Multifile Documents
+* Parsing Files:: Automatic Parsing of TeX Files
+* Internationalization:: Language Support
+* Automatic:: Automatic Customization
+* Style Files:: Writing Your Own Style Support
+
+\1f
+File: auctex.info, Node: Modes and Hooks, Next: Multifile, Up: Customization
+
+5.1 Modes and Hooks
+===================
+
+AUCTeX supports a wide variety of derivatives and extensions of TeX.
+Besides plain TeX those are LaTeX, AMS-TeX, ConTeXt, Texinfo and
+docTeX. For each of them there is a separate major mode in AUCTeX and
+each major mode runs `text-mode-hook', `TeX-mode-hook' as well as a
+hook special to the mode in this order. The following table provides
+an overview of the respective mode functions and hooks.
+
+Type Mode function Hook
+-------------------------------------------------------
+Plain TeX `plain-TeX-mode' `plain-TeX-mode-hook'
+LaTeX `LaTeX-mode' `LaTeX-mode-hook'
+AMS-TeX `ams-tex-mode' `AmS-TeX-mode-hook'
+ConTeXt `ConTeXt-mode' `ConTeXt-mode-hook'
+Texinfo `Texinfo-mode' `Texinfo-mode-hook'
+DocTeX `docTeX-mode' `docTeX-mode-hook'
+
+ If you need to make a customization via a hook which is only relevant
+for one of the modes listed above, put it into the respective mode hook,
+if it is relevant for any AUCTeX mode, add it to `TeX-mode-hook' and if
+it is relevant for all text modes, append it to `text-mode-hook'.
+
+\1f
+File: auctex.info, Node: Multifile, Next: Parsing Files, Prev: Modes and Hooks, Up: Customization
+
+5.2 Multifile Documents
+=======================
+
+You may wish to spread a document over many files (as you are likely to
+do if there are multiple authors, or if you have not yet discovered the
+power of the outline commands (*note Outline::)). This can be done by
+having a "master" file in which you include the various files with the
+TeX macro `\input' or the LaTeX macro `\include'. These files may also
+include other files themselves. However, to format the document you
+must run the commands on the top level master file.
+
+ When you, for example, ask AUCTeX to run a command on the master
+file, it has no way of knowing the name of the master file. By default,
+it will assume that the current file is the master file. If you insert
+the following in your `.emacs' file AUCTeX will use a more advanced
+algorithm.
+
+ (setq-default TeX-master nil) ; Query for master file.
+
+ If AUCTeX finds the line indicating the end of the header in a master
+file (`TeX-header-end'), it can figure out for itself that this is a
+master file. Otherwise, it will ask for the name of the master file
+associated with the buffer. To avoid asking you again, AUCTeX will
+automatically insert the name of the master file as a file variable
+(*note File Variables: (emacs)File Variables.). You can also insert
+the file variable yourself, by putting the following text at the end of
+your files.
+
+ %%% Local Variables:
+ %%% TeX-master: "master"
+ %%% End:
+
+ You should always set this variable to the name of the top level
+document. If you always use the same name for your top level
+documents, you can set `TeX-master' in your `.emacs' file.
+
+ (setq-default TeX-master "master") ; All master files called "master".
+
+ -- User Option: TeX-master
+ The master file associated with the current buffer. If the file
+ being edited is actually included from another file, then you can
+ tell AUCTeX the name of the master file by setting this variable.
+ If there are multiple levels of nesting, specify the top level
+ file.
+
+ If this variable is `nil', AUCTeX will query you for the name.
+
+ If the variable is `t', then AUCTeX will assume the file is a
+ master file itself.
+
+ If the variable is `shared', then AUCTeX will query for the name,
+ but will not change the file.
+
+ -- User Option: TeX-one-master
+ Regular expression matching ordinary TeX files.
+
+ You should set this variable to match the name of all files, for
+ which it is a good idea to append a `TeX-master' file variable
+ entry automatically. When AUCTeX adds the name of the master file
+ as a file variable, it does not need to ask next time you edit the
+ file.
+
+ If you dislike AUCTeX automatically modifying your files, you can
+ set this variable to `"<none>"'. By default, AUCTeX will modify
+ any file with an extension of `.tex'.
+
+ -- Command: TeX-master-file-ask
+ (`C-c _') Query for the name of a master file and add the
+ respective File Variables (*note File Variables: (emacs)File
+ Variables.) to the file for setting this variable permanently.
+
+ AUCTeX will not ask for a master file when it encounters existing
+ files. This function shall give you the possibility to insert the
+ variable manually.
+
+ AUCTeX keeps track of macros, environments, labels, and style files
+that are used in a given document. For this to work with multifile
+documents, AUCTeX has to have a place to put the information about the
+files in the document. This is done by having an `auto' subdirectory
+placed in the directory where your document is located. Each time you
+save a file, AUCTeX will write information about the file into the
+`auto' directory. When you load a file, AUCTeX will read the
+information in the `auto' directory about the file you loaded _and the
+master file specified by `TeX-master'_. Since the master file (perhaps
+indirectly) includes all other files in the document, AUCTeX will get
+information from all files in the document. This means that you will
+get from each file, for example, completion for all labels defined
+anywhere in the document.
+
+ AUCTeX will create the `auto' directory automatically if
+`TeX-auto-save' is non-nil. Without it, the files in the document will
+not know anything about each other, except for the name of the master
+file. *Note Automatic Local::.
+
+ -- Command: TeX-save-document
+ (`C-c C-d') Save all buffers known to belong to the current
+ document.
+
+ -- User Option: TeX-save-query
+ If non-nil, then query the user before saving each file with
+ `TeX-save-document'.
+
+\1f
+File: auctex.info, Node: Parsing Files, Next: Internationalization, Prev: Multifile, Up: Customization
+
+5.3 Automatic Parsing of TeX Files
+==================================
+
+AUCTeX depends heavily on being able to extract information from the
+buffers by parsing them. Since parsing the buffer can be somewhat slow,
+the parsing is initially disabled. You are encouraged to enable them by
+adding the following lines to your `.emacs' file.
+
+ (setq TeX-parse-self t) ; Enable parse on load.
+ (setq TeX-auto-save t) ; Enable parse on save.
+
+ The latter command will make AUCTeX store the parsed information in
+an `auto' subdirectory in the directory each time the TeX files are
+stored, *note Automatic Local::. If AUCTeX finds the pre-parsed
+information when loading a file, it will not need to reparse the buffer.
+The information in the `auto' directory is also useful for multifile
+documents, *note Multifile::, since it allows each file to access the
+parsed information from all the other files in the document. This is
+done by first reading the information from the master file, and then
+recursively the information from each file stored in the master file.
+
+ The variables can also be done on a per file basis, by changing the
+file local variables.
+
+ %%% Local Variables:
+ %%% TeX-parse-self: t
+ %%% TeX-auto-save: t
+ %%% End:
+
+ Even when you have disabled the automatic parsing, you can force the
+generation of style information by pressing `C-c C-n'. This is often
+the best choice, as you will be able to decide when it is necessary to
+reparse the file.
+
+ -- User Option: TeX-parse-self
+ Parse file after loading it if no style hook is found for it.
+
+ -- User Option: TeX-auto-save
+ Automatically save style information when saving the buffer.
+
+ -- Command: TeX-normal-mode ARG
+ (`C-c C-n') Remove all information about this buffer, and apply the
+ style hooks again. Save buffer first including style information.
+ With optional argument, also reload the style hooks.
+
+ When AUCTeX saves your buffer, it can optionally convert all tabs in
+your buffer into spaces. Tabs confuse AUCTeX's error message parsing
+and so should generally be avoided. However, tabs are significant in
+some environments, and so by default AUCTeX does not remove them. To
+convert tabs to spaces when saving a buffer, insert the following in
+your `.emacs' file:
+
+ (setq TeX-auto-untabify t)
+
+ -- User Option: TeX-auto-untabify
+ Automatically remove all tabs from a file before saving it.
+
+ Instead of disabling the parsing entirely, you can also speed it
+significantly up by limiting the information it will search for (and
+store) when parsing the buffer. You can do this by setting the default
+values for the buffer local variables `TeX-auto-regexp-list' and
+`TeX-auto-parse-length' in your `.emacs' file.
+
+ ;; Only parse LaTeX class and package information.
+ (setq-default TeX-auto-regexp-list 'LaTeX-auto-minimal-regexp-list)
+ ;; The class and package information is usually near the beginning.
+ (setq-default TeX-auto-parse-length 2000)
+
+ This example will speed the parsing up significantly, but AUCTeX
+will no longer be able to provide completion for labels, macros,
+environments, or bibitems specified in the document, nor will it know
+what files belong to the document.
+
+ These variables can also be specified on a per file basis, by
+changing the file local variables.
+
+ %%% Local Variables:
+ %%% TeX-auto-regexp-list: TeX-auto-full-regexp-list
+ %%% TeX-auto-parse-length: 999999
+ %%% End:
+
+ -- User Option: TeX-auto-regexp-list
+ List of regular expressions used for parsing the current file.
+
+ -- User Option: TeX-auto-parse-length
+ Maximal length of TeX file that will be parsed.
+
+ The pre-specified lists of regexps are defined below. You can use
+these before loading AUCTeX by quoting them, as in the example above.
+
+ -- Constant: TeX-auto-empty-regexp-list
+ Parse nothing
+
+ -- Constant: LaTeX-auto-minimal-regexp-list
+ Only parse LaTeX class and packages.
+
+ -- Constant: LaTeX-auto-label-regexp-list
+ Only parse LaTeX labels.
+
+ -- Constant: LaTeX-auto-regexp-list
+ Parse common LaTeX commands.
+
+ -- Constant: plain-TeX-auto-regexp-list
+ Parse common plain TeX commands.
+
+ -- Constant: TeX-auto-full-regexp-list
+ Parse all TeX and LaTeX commands that AUCTeX can use.
+
+\1f
+File: auctex.info, Node: Internationalization, Next: Automatic, Prev: Parsing Files, Up: Customization
+
+5.4 Language Support
+====================
+
+TeX and Emacs are usable for European (Latin, Cyrillic, Greek) based
+languages. Some LaTeX and EmacsLisp packages are available for easy
+typesetting and editing documents in European languages.
+
+ For CJK (Chinese, Japanese, and Korean) languages, Emacs or XEmacs
+with MULE (MULtilingual Enhancement to GNU Emacs) support is required.
+MULE is part of Emacs by default since Emacs 20. XEmacs has to be
+configured with the `--with-mule' option. Special versions of TeX are
+needed for CJK languages: CTeX and ChinaTeX for Chinese, ASCII pTeX and
+NTT jTeX for Japanese, HLaTeX and kTeX for Korean. The CJK-LaTeX
+package is required for supporting multiple CJK scripts within a single
+document.
+
+ Note that Unicode is not fully supported in Emacs 21 and XEmacs 21.
+CJK characters are not usable. Please use the MULE-UCS EmacsLisp
+package or Emacs 22 (not released yet) if you need CJK.
+
+* Menu:
+
+* European:: Using AUCTeX with European Languages
+* Japanese:: Using AUCTeX with Japanese
+
+\1f
+File: auctex.info, Node: European, Next: Japanese, Up: Internationalization
+
+5.4.1 Using AUCTeX with European Languages
+------------------------------------------
+
+5.4.1.1 Typing and Displaying Non-ASCII Characters
+..................................................
+
+First you will need a way to write non-ASCII characters. You can either
+use macros, or teach TeX about the ISO character sets. I prefer the
+latter, it has the advantage that the usual standard emacs word
+movement and case change commands will work.
+
+ With LaTeX2e, just add `\usepackage[latin1]{inputenc}'. Other
+languages than Western European ones will probably have other encoding
+needs.
+
+ To be able to display non-ASCII characters you will need an
+appropriate font and a version of GNU Emacs capable of displaying 8-bit
+characters (e.g. Emacs 21). The manner in which this is supported
+differs between Emacsen, so you need to take a look at your respective
+documentation.
+
+ A compromise is to use an European character set when editing the
+file, and convert to TeX macros when reading and writing the files.
+
+`iso-cvt.el'
+ Much like `iso-tex.el' but is bundled with Emacs 19.23 and later.
+
+`x-compose.el'
+ Similar package bundled with new versions of XEmacs.
+
+`X-Symbol'
+ a much more complete package for both Emacs and XEmacs that can
+ also handle a lot of mathematical characters and input methods.
+
+5.4.1.2 Style Files for Different Languages
+...........................................
+
+AUCTeX supports style files for several languages. Each style file may
+modify AUCTeX to better support the language, and will run a language
+specific hook that will allow you to for example change ispell
+dictionary, or run code to change the keyboard remapping. The
+following will for example choose a Danish dictionary for documents
+including `\usepackage[danish]{babel}'. This requires parsing to be
+enabled, *note Parsing Files::.
+
+ (add-hook 'TeX-language-dk-hook
+ (lambda () (ispell-change-dictionary "danish")))
+
+ The following style files are recognized:
+
+`bulgarian'
+ Runs style hook `TeX-language-bg-hook'. Gives `"' word syntax,
+ makes the <"> key insert a literal `"'. Typing <"> twice will
+ insert insert `"`' or `"'' depending on context. Typing <-> twice
+ will insert `"=', three times `--'.
+
+`czech'
+ Runs style hook `TeX-language-cz-hook'. Pressing <"> will insert
+ `\uv{' and `}' depending on context.
+
+`danish'
+ Runs style hook `TeX-language-dk-hook'. Pressing <"> will insert
+ `"`' and `"'' depending on context. Typing <-> twice will insert
+ `"=', i.e. a hyphen string allowing hyphenation in the composing
+ words.
+
+`dutch'
+ Runs style hook `TeX-language-nl-hook'.
+
+`german'
+`ngerman'
+ Runs style hook `TeX-language-de-hook'. Gives `"' word syntax,
+ makes the <"> key insert a literal `"'. Pressing the key twice
+ will give you opening or closing German quotes (`"`' or `"'').
+ Typing <-> twice will insert `"=', three times `--'.
+
+`frenchb'
+`francais'
+ Runs style hook `TeX-language-fr-hook'. Pressing <"> will insert
+ `\\og' and `\\fg' depending on context. Note that the language
+ name for customizing `TeX-quote-language-alist' is `french'.
+
+`icelandic'
+ Runs style hook `TeX-language-is-hook'. Gives `"' word syntax,
+ makes the <"> key insert a literal `"'. Typing <"> twice will
+ insert insert `"`' or `"'' depending on context. Typing <-> twice
+ will insert `"=', three times `--'.
+
+`italian'
+ Runs style hook `TeX-language-it-hook'. Pressing <"> will insert
+ `"<' and `">' depending on context.
+
+`polish'
+ Runs style hook `TeX-language-pl-hook'. Gives `"' word syntax and
+ makes the <"> key insert a literal `"'. Pressing <"> twice will
+ insert `"`' or `"'' depending on context.
+
+`polski'
+ Runs style hook `TeX-language-pl-hook'. Makes the <"> key insert
+ a literal `"'. Pressing <"> twice will insert `,,' or `'''
+ depending on context.
+
+`slovak'
+ Runs style hook `TeX-language-sk-hook'. Pressing <"> will insert
+ `\uv{' and `}' depending on context.
+
+`swedish'
+ Runs style hook `TeX-language-sv-hook'. Pressing <"> will insert
+ `'''. Typing <-> twice will insert `"=', three times `--'.
+
+ Replacement of language-specific hyphen strings like `"=' with
+dashes does not require to type <-> three times in a row. You can put
+point after the hypen string anytime and trigger the replacement by
+typing <->.
+
+ In case you are not satisfied with the suggested behavior of quote
+and hyphen insertion you can change it by customizing the variables
+`TeX-quote-language-alist' and `LaTeX-babel-hyphen-language-alist'
+respectively.
+
+ -- User Option: TeX-quote-language-alist
+ Used for overriding the default language-specific quote insertion
+ behavior. This is an alist where each element is a list
+ consisting of four items. The first item is the name of the
+ language in concern as a string. See the list of supported
+ languages above. The second item is the opening quotation mark.
+ The third item is the closing quotation mark. Opening and closing
+ quotation marks can be specified directly as strings or as
+ functions returning a string. The fourth item is a boolean
+ controlling quote insertion. It should be non-nil if if the
+ special quotes should only be used after inserting a literal `"'
+ character first, i.e. on second key press.
+
+ -- User Option: LaTeX-babel-hyphen-language-alist
+ Used for overriding the behavior of hyphen insertion for specific
+ languages. Every element in this alist is a list of three items.
+ The first item should specify the affected language as a string.
+ The second item denotes the hyphen string to be used as a string.
+ The third item, a boolean, controls the behavior of hyphen
+ insertion and should be non-nil if the special hyphen should be
+ inserted after inserting a literal `-' character, i.e. on second
+ key press.
+
+ The defaults of hyphen insertion are defined by the variables
+`LaTeX-babel-hyphen' and `LaTeX-babel-hyphen-after-hyphen' respectively.
+
+ -- User Option: LaTeX-babel-hyphen
+ String to be used when typing <->. This usually is a hyphen
+ alternative or hyphenation aid provided by `babel' and the related
+ language style files, like `"=', `"~' or `"-'.
+
+ Set it to an empty string or nil in order to disable
+ language-specific hyphen insertion.
+
+ -- User Option: LaTeX-babel-hyphen-after-hyphen
+ Control insertion of hyphen strings. If non-nil insert normal
+ hyphen on first key press and swap it with the language-specific
+ hyphen string specified in the variable `LaTeX-babel-hyphen' on
+ second key press. If nil do it the other way round.
+
+\1f
+File: auctex.info, Node: Japanese, Prev: European, Up: Internationalization
+
+5.4.2 Using AUCTeX with Japanese TeX
+------------------------------------
+
+To write Japanese text with AUCTeX, you need to have versions of TeX
+and Emacs that support Japanese. There exist at least two variants of
+TeX for Japanese text (NTT jTeX and ASCII pTeX). AUCTeX can be used
+with MULE (MULtilingual Enhancement to GNU Emacs) supported Emacsen.
+
+ To use the Japanese TeX variants, simply activate
+`japanese-plain-tex-mode' or `japanese-latex-mode' and everything
+should work. If not, send mail to Masayuki Ataka
+`<ataka@milk.freemail.ne.jp>', who kindly donated the code for
+supporting Japanese in AUCTeX. None of the primary AUCTeX maintainers
+understand Japanese, so they cannot help you.
+
+ If you usually use AUCTeX in Japanese, setting the following
+variables is useful.
+
+ -- User Option: TeX-default-mode
+ Mode to enter for a new file when it cannott be determined whether
+ the file is plain TeX or LaTeX or what.
+
+ If you want to enter Japanese LaTeX mode whenever this may happen,
+ set the variable like this:
+ (setq TeX-default-mode 'japanese-latex-mode)
+
+ -- User Option: japanese-TeX-command-default
+ The default command for `TeX-command' in Japanese TeX mode.
+
+ The default value is `"pTeX"'.
+
+ -- User Option: japanese-LaTeX-command-default
+ The default command for `TeX-command' in Japanese LaTeX mode.
+
+ The default value is `"LaTeX"'.
+
+ -- User Option: japanese-LaTeX-default-style
+ The default style/class when creating a new Japanese LaTeX
+ document.
+
+ The default value is `"jarticle"'.
+
+ See `tex-jp.el' for more information.
+
+\1f
+File: auctex.info, Node: Automatic, Next: Style Files, Prev: Internationalization, Up: Customization
+
+5.5 Automatic Customization
+===========================
+
+Since AUCTeX is so highly customizable, it makes sense that it is able
+to customize itself. The automatic customization consists of scanning
+TeX files and extracting symbols, environments, and things like that.
+
+ The automatic customization is done on three different levels. The
+global level is the level shared by all users at your site, and consists
+of scanning the standard TeX style files, and any extra styles added
+locally for all users on the site. The private level deals with those
+style files you have written for your own use, and use in different
+documents. You may have a `~/lib/TeX/' directory where you store
+useful style files for your own use. The local level is for a specific
+directory, and deals with writing customization for the files for your
+normal TeX documents.
+
+ If compared with the environment variable `TEXINPUTS', the global
+level corresponds to the directories built into TeX. The private level
+corresponds to the directories you add yourself, except for `.', which
+is the local level.
+
+* Menu:
+
+* Automatic Global:: Automatic Customization for the Site
+* Automatic Private:: Automatic Customization for a User
+* Automatic Local:: Automatic Customization for a Directory
+
+ By default AUCTeX will search for customization files in all the
+global, private, and local style directories, but you can also set the
+path directly. This is useful if you for example want to add another
+person's style hooks to your path. Please note that all matching files
+found in `TeX-style-path' are loaded, and all hooks defined in the
+files will be executed.
+
+ -- User Option: TeX-style-path
+ List of directories to search for AUCTeX style files. Each must
+ end with a slash.
+
+ By default, when AUCTeX searches a directory for files, it will
+recursively search through subdirectories.
+
+ -- User Option: TeX-file-recurse
+ Whether to search TeX directories recursively: nil means do not
+ recurse, a positive integer means go that far deep in the directory
+ hierarchy, t means recurse indefinitely.
+
+ By default, AUCTeX will ignore files name `.', `..', `SCCS', `RCS',
+and `CVS'.
+
+ -- User Option: TeX-ignore-file
+ Regular expression matching file names to ignore.
+
+ These files or directories will not be considered when searching
+ for TeX files in a directory.
+
+\1f
+File: auctex.info, Node: Automatic Global, Next: Automatic Private, Up: Automatic
+
+5.5.1 Automatic Customization for the Site
+------------------------------------------
+
+Assuming that the automatic customization at the global level was done
+when AUCTeX was installed, your choice is now: will you use it? If you
+use it, you will benefit by having access to all the symbols and
+environments available for completion purposes. The drawback is slower
+load time when you edit a new file and perhaps too many confusing
+symbols when you try to do a completion.
+
+ You can disable the automatic generated global style hooks by setting
+the variable `TeX-auto-global' to nil.
+
+ -- User Option: TeX-macro-global
+ Directories containing the site's TeX style files.
+
+ -- User Option: TeX-style-global
+ Directory containing hand generated TeX information. Must end
+ with a slash.
+
+ These correspond to TeX macros shared by all users of a site.
+
+ -- User Option: TeX-auto-global
+ Directory containing automatically generated information.
+
+ For storing automatic extracted information about the TeX macros
+ shared by all users of a site.
+
+\1f
+File: auctex.info, Node: Automatic Private, Next: Automatic Local, Prev: Automatic Global, Up: Automatic
+
+5.5.2 Automatic Customization for a User
+----------------------------------------
+
+You should specify where you store your private TeX macros, so AUCTeX
+can extract their information. The extracted information will go to
+the directories listed in `TeX-auto-private'
+
+ Use `M-x TeX-auto-generate <RET>' to extract the information.
+
+ -- User Option: TeX-macro-private
+ Directories where you store your personal TeX macros. The value
+ defaults to the directories listed in the `TEXINPUTS' and
+ `BIBINPUTS' environment variables or to the respective directories
+ in `$TEXMFHOME' if no results can be obtained from the environment
+ variables.
+
+ -- User Option: TeX-auto-private
+ List of directories containing automatically generated AUCTeX style
+ files. These correspond to the personal TeX macros.
+
+ -- Command: TeX-auto-generate TEX AUTO
+ (`M-x TeX-auto-generate <RET>') Generate style hook for TEX and
+ store it in AUTO. If TEX is a directory, generate style hooks for
+ all files in the directory.
+
+ -- User Option: TeX-style-private
+ List of directories containing hand generated AUCTeX style files.
+ These correspond to the personal TeX macros.
+
+\1f
+File: auctex.info, Node: Automatic Local, Prev: Automatic Private, Up: Automatic
+
+5.5.3 Automatic Customization for a Directory
+---------------------------------------------
+
+AUCTeX can update the style information about a file each time you save
+it, and it will do this if the directory `TeX-auto-local' exist.
+`TeX-auto-local' is by default set to `"auto"', so simply creating an
+`auto' directory will enable automatic saving of style information.
+
+ The advantage of doing this is that macros, labels, etc. defined in
+any file in a multifile document will be known in all the files in the
+document. The disadvantage is that saving will be slower. To disable,
+set `TeX-auto-local' to nil.
+
+ -- User Option: TeX-style-local
+ Directory containing hand generated TeX information. Must end
+ with a slash.
+
+ These correspond to TeX macros found in the current directory.
+
+ -- User Option: TeX-auto-local
+ Directory containing automatically generated TeX information.
+ Must end with a slash.
+
+ These correspond to TeX macros found in the current directory.
+
+\1f
+File: auctex.info, Node: Style Files, Prev: Automatic, Up: Customization
+
+5.6 Writing Your Own Style Support
+==================================
+
+*Note Automatic::, for a discussion about automatically generated
+global, private, and local style files. The hand generated style files
+are equivalent, except that they by default are found in `style'
+directories instead of `auto' directories.
+
+* Menu:
+
+* Simple Style:: A Simple Style File
+* Adding Macros:: Adding Support for Macros
+* Adding Environments:: Adding Support for Environments
+* Adding Other:: Adding Other Information
+* Hacking the Parser:: Automatic Extraction of New Things
+
+ If you write some useful support for a public TeX style file, please
+send it to us.
+
+\1f
+File: auctex.info, Node: Simple Style, Next: Adding Macros, Up: Style Files
+
+5.6.1 A Simple Style File
+-------------------------
+
+Here is a simple example of a style file.
+
+ ;;; book.el - Special code for book style.
+
+ (TeX-add-style-hook
+ "book"
+ (lambda ()
+ (LaTeX-largest-level-set "chapter")))
+
+ This file specifies that the largest kind of section in a LaTeX
+document using the book document style is chapter. The interesting
+thing to notice is that the style file defines an (anonymous) function,
+and adds it to the list of loaded style hooks by calling
+`TeX-add-style-hook'.
+
+ The first time the user indirectly tries to access some style
+specific information, such as the largest sectioning command available,
+the style hooks for all files directly or indirectly read by the
+current document is executed. The actual files will only be evaluated
+once, but the hooks will be called for each buffer using the style file.
+
+ -- Function: TeX-add-style-hook STYLE HOOK
+ Add HOOK to the list of functions to run when we use the TeX file
+ STYLE.
+
+\1f
+File: auctex.info, Node: Adding Macros, Next: Adding Environments, Prev: Simple Style, Up: Style Files
+
+5.6.2 Adding Support for Macros
+-------------------------------
+
+The most common thing to define in a style hook is new symbols (TeX
+macros). Most likely along with a description of the arguments to the
+function, since the symbol itself can be defined automatically.
+
+ Here are a few examples from `latex.el'.
+
+ (TeX-add-style-hook
+ "latex"
+ (lambda ()
+ (TeX-add-symbols
+ '("arabic" TeX-arg-counter)
+ '("label" TeX-arg-define-label)
+ '("ref" TeX-arg-label)
+ '("newcommand" TeX-arg-define-macro [ "Number of arguments" ] t)
+ '("newtheorem" TeX-arg-define-environment
+ [ TeX-arg-environment "Numbered like" ]
+ t [ TeX-arg-counter "Within counter" ]))))
+
+ -- Function: TeX-add-symbols SYMBOL ...
+ Add each SYMBOL to the list of known symbols.
+
+ Each argument to `TeX-add-symbols' is a list describing one symbol.
+The head of the list is the name of the symbol, the remaining elements
+describe each argument.
+
+ If there are no additional elements, the symbol will be inserted with
+point inside braces. Otherwise, each argument of this function should
+match an argument of the TeX macro. What is done depends on the
+argument type.
+
+ If a macro is defined multiple times, AUCTeX will chose the one with
+the longest definition (i.e. the one with the most arguments).
+
+ Thus, to overwrite
+ '("tref" 1) ; one argument
+ you can specify
+ '("tref" TeX-arg-label ignore) ; two arguments
+
+ `ignore' is a function that does not do anything, so when you insert
+a `tref' you will be prompted for a label and no more.
+
+ You can use the following types of specifiers for arguments:
+
+`string'
+ Use the string as a prompt to prompt for the argument.
+
+`number'
+ Insert that many braces, leave point inside the first.
+
+`nil'
+ Insert empty braces.
+
+`t'
+ Insert empty braces, leave point between the braces.
+
+`other symbols'
+ Call the symbol as a function. You can define your own hook, or
+ use one of the predefined argument hooks.
+
+`list'
+ If the car is a string, insert it as a prompt and the next element
+ as initial input. Otherwise, call the car of the list with the
+ remaining elements as arguments.
+
+`vector'
+ Optional argument. If it has more than one element, parse it as a
+ list, otherwise parse the only element as above. Use square
+ brackets instead of curly braces, and is not inserted on empty user
+ input.
+
+ A lot of argument hooks have already been defined. The first
+argument to all hooks is a flag indicating if it is an optional
+argument. It is up to the hook to determine what to do with the
+remaining arguments, if any. Typically the next argument is used to
+overwrite the default prompt.
+
+`TeX-arg-conditional'
+ Implements if EXPR THEN ELSE. If EXPR evaluates to true, parse
+ THEN as an argument list, else parse ELSE as an argument list.
+
+`TeX-arg-literal'
+ Insert its arguments into the buffer. Used for specifying extra
+ syntax for a macro.
+
+`TeX-arg-free'
+ Parse its arguments but use no braces when they are inserted.
+
+`TeX-arg-eval'
+ Evaluate arguments and insert the result in the buffer.
+
+`TeX-arg-label'
+ Prompt for a label completing with known labels.
+
+`TeX-arg-macro'
+ Prompt for a TeX macro with completion.
+
+`TeX-arg-environment'
+ Prompt for a LaTeX environment with completion.
+
+`TeX-arg-cite'
+ Prompt for a BibTeX citation.
+
+`TeX-arg-counter'
+ Prompt for a LaTeX counter.
+
+`TeX-arg-savebox'
+ Prompt for a LaTeX savebox.
+
+`TeX-arg-file'
+ Prompt for a filename in the current directory, and use it without
+ the extension.
+
+`TeX-arg-input-file'
+ Prompt for the name of an input file in TeX's search path, and use
+ it without the extension. Run the style hooks for the file.
+
+`TeX-arg-define-label'
+ Prompt for a label completing with known labels. Add label to
+ list of defined labels.
+
+`TeX-arg-define-macro'
+ Prompt for a TeX macro with completion. Add macro to list of
+ defined macros.
+
+`TeX-arg-define-environment'
+ Prompt for a LaTeX environment with completion. Add environment to
+ list of defined environments.
+
+`TeX-arg-define-cite'
+ Prompt for a BibTeX citation.
+
+`TeX-arg-define-counter'
+ Prompt for a LaTeX counter.
+
+`TeX-arg-define-savebox'
+ Prompt for a LaTeX savebox.
+
+`TeX-arg-corner'
+ Prompt for a LaTeX side or corner position with completion.
+
+`TeX-arg-lr'
+ Prompt for a LaTeX side with completion.
+
+`TeX-arg-tb'
+ Prompt for a LaTeX side with completion.
+
+`TeX-arg-pagestyle'
+ Prompt for a LaTeX pagestyle with completion.
+
+`TeX-arg-verb'
+ Prompt for delimiter and text.
+
+`TeX-arg-pair'
+ Insert a pair of numbers, use arguments for prompt. The numbers are
+ surrounded by parentheses and separated with a comma.
+
+`TeX-arg-size'
+ Insert width and height as a pair. No arguments.
+
+`TeX-arg-coordinate'
+ Insert x and y coordinates as a pair. No arguments.
+
+ If you add new hooks, you can assume that point is placed directly
+after the previous argument, or after the macro name if this is the
+first argument. Please leave point located after the argument you are
+inserting. If you want point to be located somewhere else after all
+hooks have been processed, set the value of `exit-mark'. It will point
+nowhere, until the argument hook sets it.
+
+\1f
+File: auctex.info, Node: Adding Environments, Next: Adding Other, Prev: Adding Macros, Up: Style Files
+
+5.6.3 Adding Support for Environments
+-------------------------------------
+
+Adding support for environments is very much like adding support for
+TeX macros, except that each environment normally only takes one
+argument, an environment hook. The example is again a short version of
+`latex.el'.
+
+ (TeX-add-style-hook
+ "latex"
+ (lambda ()
+ (LaTeX-add-environments
+ '("document" LaTeX-env-document)
+ '("enumerate" LaTeX-env-item)
+ '("itemize" LaTeX-env-item)
+ '("list" LaTeX-env-list))))
+
+ It is completely up to the environment hook to insert the
+environment, but the function `LaTeX-insert-environment' may be of some
+help. The hook will be called with the name of the environment as its
+first argument, and extra arguments can be provided by adding them to a
+list after the hook.
+
+ For simple environments with arguments, for example defined with
+`\newenvironment', you can make AUCTeX prompt for the arguments by
+giving the prompt strings in the call to `LaTeX-add-environments'. The
+fact that an argument is optional can be indicated by wrapping the
+prompt string in a vector.
+
+ For example, if you have defined a `loop' environment with the three
+arguments FROM, TO, and STEP, you can add support for them in a style
+file.
+
+ %% loop.sty
+
+ \newenvironment{loop}[3]{...}{...}
+
+ ;; loop.el
+
+ (TeX-add-style-hook
+ "loop"
+ (lambda ()
+ (LaTeX-add-environments
+ '("loop" "From" "To" "Step"))))
+
+ If an environment is defined multiple times, AUCTeX will choose the
+one with the longest definition. Thus, if you have an enumerate style
+file, and want it to replace the standard LaTeX enumerate hook above,
+you could define an `enumerate.el' file as follows, and place it in the
+appropriate style directory.
+
+ (TeX-add-style-hook
+ "latex"
+ (lambda ()
+ (LaTeX-add-environments
+ '("enumerate" LaTeX-env-enumerate foo))))
+
+ (defun LaTeX-env-enumerate (environment &optional ignore) ...)
+
+ The symbol `foo' will be passed to `LaTeX-env-enumerate' as the
+second argument, but since we only added it to overwrite the definition
+in `latex.el' it is just ignored.
+
+ -- Function: LaTeX-add-environments ENV ...
+ Add each ENV to list of loaded environments.
+
+ -- Function: LaTeX-insert-environment ENV [ EXTRA ]
+ Insert environment of type ENV, with optional argument EXTRA.
+
+ Following is a list of available hooks for `LaTeX-add-environments':
+
+`LaTeX-env-item'
+ Insert the given environment and the first item.
+
+`LaTeX-env-figure'
+ Insert the given figure-like environment with a caption and a
+ label.
+
+`LaTeX-env-array'
+ Insert the given array-like environment with position and column
+ specifications.
+
+`LaTeX-env-label'
+ Insert the given environment with a label.
+
+`LaTeX-env-list'
+ Insert the given list-like environment, a specifier for the label
+ and the first item.
+
+`LaTeX-env-minipage'
+ Insert the given minipage-like environment with position and width
+ specifications.
+
+`LaTeX-env-tabular*'
+ Insert the given tabular*-like environment with width, position and
+ column specifications.
+
+`LaTeX-env-picture'
+ Insert the given environment with width and height specifications.
+
+`LaTeX-env-bib'
+ Insert the given environment with a label for a bibitem.
+
+`LaTeX-env-contents'
+ Insert the given environment with a filename as its argument.
+
+`LaTeX-env-args'
+ Insert the given environment with arguments. You can use this as
+ a hook in case you want to specify multiple complex arguments just
+ like in elements of `TeX-add-symbols'. This is most useful if the
+ specification of arguments to be prompted for with strings and
+ strings wrapped in a vector as described above is too limited.
+
+ Here is an example from `listings.el' which calls a function with
+ one argument in order to prompt for a key=value list to be
+ inserted as an optional argument of the `lstlisting' environment:
+
+ (LaTeX-add-environments
+ `("lstlisting" LaTeX-env-args
+ [TeX-arg-key-val ,LaTeX-listings-key-val-options]))
+
+\1f
+File: auctex.info, Node: Adding Other, Next: Hacking the Parser, Prev: Adding Environments, Up: Style Files
+
+5.6.4 Adding Other Information
+------------------------------
+
+You can also specify bibliographical databases and labels in the style
+file. This is probably of little use, since this information will
+usually be automatically generated from the TeX file anyway.
+
+ -- Function: LaTeX-add-bibliographies BIBLIOGRAPHY ...
+ Add each BIBLIOGRAPHY to list of loaded bibliographies.
+
+ -- Function: LaTeX-add-labels LABEL ...
+ Add each LABEL to the list of known labels.
+
+\1f
+File: auctex.info, Node: Hacking the Parser, Prev: Adding Other, Up: Style Files
+
+5.6.5 Automatic Extraction of New Things
+----------------------------------------
+
+The automatic TeX information extractor works by searching for regular
+expressions in the TeX files, and storing the matched information. You
+can add support for new constructs to the parser, something that is
+needed when you add new commands to define symbols.
+
+ For example, in the file `macro.tex' I define the following macro.
+
+ \newcommand{\newmacro}[5]{%
+ \def#1{#3\index{#4@#5~cite{#4}}\nocite{#4}}%
+ \def#2{#5\index{#4@#5~cite{#4}}\nocite{#4}}%
+ }
+
+ AUCTeX will automatically figure out that `newmacro' is a macro that
+takes five arguments. However, it is not smart enough to automatically
+see that each time we use the macro, two new macros are defined. We
+can specify this information in a style hook file.
+
+ ;;; macro.el --- Special code for my own macro file.
+
+ ;;; Code:
+
+ (defvar TeX-newmacro-regexp
+ '("\\\\newmacro{\\\\\\([a-zA-Z]+\\)}{\\\\\\([a-zA-Z]+\\)}"
+ (1 2) TeX-auto-multi)
+ "Matches \newmacro definitions.")
+
+ (defvar TeX-auto-multi nil
+ "Temporary for parsing \\newmacro definitions.")
+
+ (defun TeX-macro-cleanup ()
+ "Move symbols from `TeX-auto-multi' to `TeX-auto-symbol'."
+ (mapcar (lambda (list)
+ (mapcar (lambda (symbol)
+ (setq TeX-auto-symbol
+ (cons symbol TeX-auto-symbol)))
+ list))
+ TeX-auto-multi))
+
+ (defun TeX-macro-prepare ()
+ "Clear `Tex-auto-multi' before use."
+ (setq TeX-auto-multi nil))
+
+ (add-hook 'TeX-auto-prepare-hook 'TeX-macro-prepare)
+ (add-hook 'TeX-auto-cleanup-hook 'TeX-macro-cleanup)
+
+ (TeX-add-style-hook
+ "macro"
+ (lambda ()
+ (TeX-auto-add-regexp TeX-newmacro-regexp)
+ (TeX-add-symbols '("newmacro"
+ TeX-arg-macro
+ (TeX-arg-macro "Capitalized macro: \\")
+ t
+ "BibTeX entry: "
+ nil))))
+
+ ;;; macro.el ends here
+
+ When this file is first loaded, it adds a new entry to
+`TeX-newmacro-regexp', and defines a function to be called before the
+parsing starts, and one to be called after the parsing is done. It
+also declares a variable to contain the data collected during parsing.
+Finally, it adds a style hook which describes the `newmacro' macro, as
+we have seen it before.
+
+ So the general strategy is: Add a new entry to `TeX-newmacro-regexp'.
+Declare a variable to contain intermediate data during parsing. Add
+hook to be called before and after parsing. In this case, the hook
+before parsing just initializes the variable, and the hook after parsing
+collects the data from the variable, and adds them to the list of
+symbols found.
+
+ -- Variable: TeX-auto-regexp-list
+ List of regular expressions matching TeX macro definitions.
+
+ The list has the following format ((REGEXP MATCH TABLE) ...), that
+ is, each entry is a list with three elements.
+
+ REGEXP. Regular expression matching the macro we want to parse.
+
+ MATCH. A number or list of numbers, each representing one
+ parenthesized subexpression matched by REGEXP.
+
+ TABLE. The symbol table to store the data. This can be a
+ function, in which case the function is called with the argument
+ MATCH. Use `TeX-match-buffer' to get match data. If it is not a
+ function, it is presumed to be the name of a variable containing a
+ list of match data. The matched data (a string if MATCH is a
+ number, a list of strings if MATCH is a list of numbers) is put in
+ front of the table.
+
+ -- Variable: TeX-auto-prepare-hook nil
+ List of functions to be called before parsing a TeX file.
+
+ -- Variable: TeX-auto-cleanup-hook nil
+ List of functions to be called after parsing a TeX file.
+
+\1f
+File: auctex.info, Node: Appendices, Next: Indices, Prev: Customization, Up: Top
+
+Appendix A Copying, Changes, Development, FAQ
+*********************************************
+
+* Menu:
+
+* Copying this Manual::
+* Changes::
+* Development::
+* FAQ::
+
+\1f
+File: auctex.info, Node: Copying this Manual, Next: Changes, Up: Appendices
+
+A.1 Copying this Manual
+=======================
+
+The copyright notice for this manual is:
+
+ This manual is for AUCTeX (version 11.86 from 2010-02-21), a
+sophisticated TeX environment for Emacs.
+
+ Copyright (C) 1992, 1993, 1994, 1995, 2001, 2002, 2004, 2005, 2006,
+2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ 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, no Front-Cover Texts and
+ no Back-Cover Texts. A copy of the license is included in the
+ section entitled "GNU Free Documentation License."
+
+The full license text can be read here:
+
+* Menu:
+
+* GNU Free Documentation License:: License for copying this manual.
+
+\1f
+File: auctex.info, Node: GNU Free Documentation License, Up: Copying this Manual
+
+A.1.1 GNU Free Documentation License
+------------------------------------
+
+ Version 1.3, 3 November 2008
+
+ Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software
+ Foundation, Inc. `http://fsf.org/'
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ 0. PREAMBLE
+
+ The purpose of this License is to make a manual, textbook, or other
+ functional and useful document "free" in the sense of freedom: to
+ assure everyone the effective freedom to copy and redistribute it,
+ with or without modifying it, either commercially or
+ noncommercially. Secondarily, this License preserves for the
+ author and publisher a way to get credit for their work, while not
+ being considered responsible for modifications made by others.
+
+ This License is a kind of "copyleft", which means that derivative
+ works of the document must themselves be free in the same sense.
+ It complements the GNU General Public License, which is a copyleft
+ license designed for free software.
+
+ We have designed this License in order to use it for manuals for
+ free software, because free software needs free documentation: a
+ free program should come with manuals providing the same freedoms
+ that the software does. But this License is not limited to
+ software manuals; it can be used for any textual work, regardless
+ of subject matter or whether it is published as a printed book.
+ We recommend this License principally for works whose purpose is
+ instruction or reference.
+
+ 1. APPLICABILITY AND DEFINITIONS
+
+ This License applies to any manual or other work, in any medium,
+ that contains a notice placed by the copyright holder saying it
+ can be distributed under the terms of this License. Such a notice
+ grants a world-wide, royalty-free license, unlimited in duration,
+ to use that work under the conditions stated herein. The
+ "Document", below, refers to any such manual or work. Any member
+ of the public is a licensee, and is addressed as "you". You
+ accept the license if you copy, modify or distribute the work in a
+ way requiring permission under copyright law.
+
+ A "Modified Version" of the Document means any work containing the
+ Document or a portion of it, either copied verbatim, or with
+ modifications and/or translated into another language.
+
+ A "Secondary Section" is a named appendix or a front-matter section
+ of the Document that deals exclusively with the relationship of the
+ publishers or authors of the Document to the Document's overall
+ subject (or to related matters) and contains nothing that could
+ fall directly within that overall subject. (Thus, if the Document
+ is in part a textbook of mathematics, a Secondary Section may not
+ explain any mathematics.) The relationship could be a matter of
+ historical connection with the subject or with related matters, or
+ of legal, commercial, philosophical, ethical or political position
+ regarding them.
+
+ The "Invariant Sections" are certain Secondary Sections whose
+ titles are designated, as being those of Invariant Sections, in
+ the notice that says that the Document is released under this
+ License. If a section does not fit the above definition of
+ Secondary then it is not allowed to be designated as Invariant.
+ The Document may contain zero Invariant Sections. If the Document
+ does not identify any Invariant Sections then there are none.
+
+ The "Cover Texts" are certain short passages of text that are
+ listed, as Front-Cover Texts or Back-Cover Texts, in the notice
+ that says that the Document is released under this License. A
+ Front-Cover Text may be at most 5 words, and a Back-Cover Text may
+ be at most 25 words.
+
+ A "Transparent" copy of the Document means a machine-readable copy,
+ represented in a format whose specification is available to the
+ general public, that is suitable for revising the document
+ straightforwardly with generic text editors or (for images
+ composed of pixels) generic paint programs or (for drawings) some
+ widely available drawing editor, and that is suitable for input to
+ text formatters or for automatic translation to a variety of
+ formats suitable for input to text formatters. A copy made in an
+ otherwise Transparent file format whose markup, or absence of
+ markup, has been arranged to thwart or discourage subsequent
+ modification by readers is not Transparent. An image format is
+ not Transparent if used for any substantial amount of text. A
+ copy that is not "Transparent" is called "Opaque".
+
+ Examples of suitable formats for Transparent copies include plain
+ ASCII without markup, Texinfo input format, LaTeX input format,
+ SGML or XML using a publicly available DTD, and
+ standard-conforming simple HTML, PostScript or PDF designed for
+ human modification. Examples of transparent image formats include
+ PNG, XCF and JPG. Opaque formats include proprietary formats that
+ can be read and edited only by proprietary word processors, SGML or
+ XML for which the DTD and/or processing tools are not generally
+ available, and the machine-generated HTML, PostScript or PDF
+ produced by some word processors for output purposes only.
+
+ The "Title Page" means, for a printed book, the title page itself,
+ plus such following pages as are needed to hold, legibly, the
+ material this License requires to appear in the title page. For
+ works in formats which do not have any title page as such, "Title
+ Page" means the text near the most prominent appearance of the
+ work's title, preceding the beginning of the body of the text.
+
+ The "publisher" means any person or entity that distributes copies
+ of the Document to the public.
+
+ A section "Entitled XYZ" means a named subunit of the Document
+ whose title either is precisely XYZ or contains XYZ in parentheses
+ following text that translates XYZ in another language. (Here XYZ
+ stands for a specific section name mentioned below, such as
+ "Acknowledgements", "Dedications", "Endorsements", or "History".)
+ To "Preserve the Title" of such a section when you modify the
+ Document means that it remains a section "Entitled XYZ" according
+ to this definition.
+
+ The Document may include Warranty Disclaimers next to the notice
+ which states that this License applies to the Document. These
+ Warranty Disclaimers are considered to be included by reference in
+ this License, but only as regards disclaiming warranties: any other
+ implication that these Warranty Disclaimers may have is void and
+ has no effect on the meaning of this License.
+
+ 2. VERBATIM COPYING
+
+ You may copy and distribute the Document in any medium, either
+ commercially or noncommercially, provided that this License, the
+ copyright notices, and the license notice saying this License
+ applies to the Document are reproduced in all copies, and that you
+ add no other conditions whatsoever to those of this License. You
+ may not use technical measures to obstruct or control the reading
+ or further copying of the copies you make or distribute. However,
+ you may accept compensation in exchange for copies. If you
+ distribute a large enough number of copies you must also follow
+ the conditions in section 3.
+
+ You may also lend copies, under the same conditions stated above,
+ and you may publicly display copies.
+
+ 3. COPYING IN QUANTITY
+
+ If you publish printed copies (or copies in media that commonly
+ have printed covers) of the Document, numbering more than 100, and
+ the Document's license notice requires Cover Texts, you must
+ enclose the copies in covers that carry, clearly and legibly, all
+ these Cover Texts: Front-Cover Texts on the front cover, and
+ Back-Cover Texts on the back cover. Both covers must also clearly
+ and legibly identify you as the publisher of these copies. The
+ front cover must present the full title with all words of the
+ title equally prominent and visible. You may add other material
+ on the covers in addition. Copying with changes limited to the
+ covers, as long as they preserve the title of the Document and
+ satisfy these conditions, can be treated as verbatim copying in
+ other respects.
+
+ If the required texts for either cover are too voluminous to fit
+ legibly, you should put the first ones listed (as many as fit
+ reasonably) on the actual cover, and continue the rest onto
+ adjacent pages.
+
+ If you publish or distribute Opaque copies of the Document
+ numbering more than 100, you must either include a
+ machine-readable Transparent copy along with each Opaque copy, or
+ state in or with each Opaque copy a computer-network location from
+ which the general network-using public has access to download
+ using public-standard network protocols a complete Transparent
+ copy of the Document, free of added material. If you use the
+ latter option, you must take reasonably prudent steps, when you
+ begin distribution of Opaque copies in quantity, to ensure that
+ this Transparent copy will remain thus accessible at the stated
+ location until at least one year after the last time you
+ distribute an Opaque copy (directly or through your agents or
+ retailers) of that edition to the public.
+
+ It is requested, but not required, that you contact the authors of
+ the Document well before redistributing any large number of
+ copies, to give them a chance to provide you with an updated
+ version of the Document.
+
+ 4. MODIFICATIONS
+
+ You may copy and distribute a Modified Version of the Document
+ under the conditions of sections 2 and 3 above, provided that you
+ release the Modified Version under precisely this License, with
+ the Modified Version filling the role of the Document, thus
+ licensing distribution and modification of the Modified Version to
+ whoever possesses a copy of it. In addition, you must do these
+ things in the Modified Version:
+
+ A. Use in the Title Page (and on the covers, if any) a title
+ distinct from that of the Document, and from those of
+ previous versions (which should, if there were any, be listed
+ in the History section of the Document). You may use the
+ same title as a previous version if the original publisher of
+ that version gives permission.
+
+ B. List on the Title Page, as authors, one or more persons or
+ entities responsible for authorship of the modifications in
+ the Modified Version, together with at least five of the
+ principal authors of the Document (all of its principal
+ authors, if it has fewer than five), unless they release you
+ from this requirement.
+
+ C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+
+ D. Preserve all the copyright notices of the Document.
+
+ E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+
+ F. Include, immediately after the copyright notices, a license
+ notice giving the public permission to use the Modified
+ Version under the terms of this License, in the form shown in
+ the Addendum below.
+
+ G. Preserve in that license notice the full lists of Invariant
+ Sections and required Cover Texts given in the Document's
+ license notice.
+
+ H. Include an unaltered copy of this License.
+
+ I. Preserve the section Entitled "History", Preserve its Title,
+ and add to it an item stating at least the title, year, new
+ authors, and publisher of the Modified Version as given on
+ the Title Page. If there is no section Entitled "History" in
+ the Document, create one stating the title, year, authors,
+ and publisher of the Document as given on its Title Page,
+ then add an item describing the Modified Version as stated in
+ the previous sentence.
+
+ J. Preserve the network location, if any, given in the Document
+ for public access to a Transparent copy of the Document, and
+ likewise the network locations given in the Document for
+ previous versions it was based on. These may be placed in
+ the "History" section. You may omit a network location for a
+ work that was published at least four years before the
+ Document itself, or if the original publisher of the version
+ it refers to gives permission.
+
+ K. For any section Entitled "Acknowledgements" or "Dedications",
+ Preserve the Title of the section, and preserve in the
+ section all the substance and tone of each of the contributor
+ acknowledgements and/or dedications given therein.
+
+ L. Preserve all the Invariant Sections of the Document,
+ unaltered in their text and in their titles. Section numbers
+ or the equivalent are not considered part of the section
+ titles.
+
+ M. Delete any section Entitled "Endorsements". Such a section
+ may not be included in the Modified Version.
+
+ N. Do not retitle any existing section to be Entitled
+ "Endorsements" or to conflict in title with any Invariant
+ Section.
+
+ O. Preserve any Warranty Disclaimers.
+
+ If the Modified Version includes new front-matter sections or
+ appendices that qualify as Secondary Sections and contain no
+ material copied from the Document, you may at your option
+ designate some or all of these sections as invariant. To do this,
+ add their titles to the list of Invariant Sections in the Modified
+ Version's license notice. These titles must be distinct from any
+ other section titles.
+
+ You may add a section Entitled "Endorsements", provided it contains
+ nothing but endorsements of your Modified Version by various
+ parties--for example, statements of peer review or that the text
+ has been approved by an organization as the authoritative
+ definition of a standard.
+
+ You may add a passage of up to five words as a Front-Cover Text,
+ and a passage of up to 25 words as a Back-Cover Text, to the end
+ of the list of Cover Texts in the Modified Version. Only one
+ passage of Front-Cover Text and one of Back-Cover Text may be
+ added by (or through arrangements made by) any one entity. If the
+ Document already includes a cover text for the same cover,
+ previously added by you or by arrangement made by the same entity
+ you are acting on behalf of, you may not add another; but you may
+ replace the old one, on explicit permission from the previous
+ publisher that added the old one.
+
+ The author(s) and publisher(s) of the Document do not by this
+ License give permission to use their names for publicity for or to
+ assert or imply endorsement of any Modified Version.
+
+ 5. COMBINING DOCUMENTS
+
+ You may combine the Document with other documents released under
+ this License, under the terms defined in section 4 above for
+ modified versions, provided that you include in the combination
+ all of the Invariant Sections of all of the original documents,
+ unmodified, and list them all as Invariant Sections of your
+ combined work in its license notice, and that you preserve all
+ their Warranty Disclaimers.
+
+ The combined work need only contain one copy of this License, and
+ multiple identical Invariant Sections may be replaced with a single
+ copy. If there are multiple Invariant Sections with the same name
+ but different contents, make the title of each such section unique
+ by adding at the end of it, in parentheses, the name of the
+ original author or publisher of that section if known, or else a
+ unique number. Make the same adjustment to the section titles in
+ the list of Invariant Sections in the license notice of the
+ combined work.
+
+ In the combination, you must combine any sections Entitled
+ "History" in the various original documents, forming one section
+ Entitled "History"; likewise combine any sections Entitled
+ "Acknowledgements", and any sections Entitled "Dedications". You
+ must delete all sections Entitled "Endorsements."
+
+ 6. COLLECTIONS OF DOCUMENTS
+
+ You may make a collection consisting of the Document and other
+ documents released under this License, and replace the individual
+ copies of this License in the various documents with a single copy
+ that is included in the collection, provided that you follow the
+ rules of this License for verbatim copying of each of the
+ documents in all other respects.
+
+ You may extract a single document from such a collection, and
+ distribute it individually under this License, provided you insert
+ a copy of this License into the extracted document, and follow
+ this License in all other respects regarding verbatim copying of
+ that document.
+
+ 7. AGGREGATION WITH INDEPENDENT WORKS
+
+ A compilation of the Document or its derivatives with other
+ separate and independent documents or works, in or on a volume of
+ a storage or distribution medium, is called an "aggregate" if the
+ copyright resulting from the compilation is not used to limit the
+ legal rights of the compilation's users beyond what the individual
+ works permit. When the Document is included in an aggregate, this
+ License does not apply to the other works in the aggregate which
+ are not themselves derivative works of the Document.
+
+ If the Cover Text requirement of section 3 is applicable to these
+ copies of the Document, then if the Document is less than one half
+ of the entire aggregate, the Document's Cover Texts may be placed
+ on covers that bracket the Document within the aggregate, or the
+ electronic equivalent of covers if the Document is in electronic
+ form. Otherwise they must appear on printed covers that bracket
+ the whole aggregate.
+
+ 8. TRANSLATION
+
+ Translation is considered a kind of modification, so you may
+ distribute translations of the Document under the terms of section
+ 4. Replacing Invariant Sections with translations requires special
+ permission from their copyright holders, but you may include
+ translations of some or all Invariant Sections in addition to the
+ original versions of these Invariant Sections. You may include a
+ translation of this License, and all the license notices in the
+ Document, and any Warranty Disclaimers, provided that you also
+ include the original English version of this License and the
+ original versions of those notices and disclaimers. In case of a
+ disagreement between the translation and the original version of
+ this License or a notice or disclaimer, the original version will
+ prevail.
+
+ If a section in the Document is Entitled "Acknowledgements",
+ "Dedications", or "History", the requirement (section 4) to
+ Preserve its Title (section 1) will typically require changing the
+ actual title.
+
+ 9. TERMINATION
+
+ You may not copy, modify, sublicense, or distribute the Document
+ except as expressly provided under this License. Any attempt
+ otherwise to copy, modify, sublicense, or distribute it is void,
+ and will automatically terminate your rights under this License.
+
+ However, if you cease all violation of this License, then your
+ license from a particular copyright holder is reinstated (a)
+ provisionally, unless and until the copyright holder explicitly
+ and finally terminates your license, and (b) permanently, if the
+ copyright holder fails to notify you of the violation by some
+ reasonable means prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+ reinstated permanently if the copyright holder notifies you of the
+ violation by some reasonable means, this is the first time you have
+ received notice of violation of this License (for any work) from
+ that copyright holder, and you cure the violation prior to 30 days
+ after your receipt of the notice.
+
+ Termination of your rights under this section does not terminate
+ the licenses of parties who have received copies or rights from
+ you under this License. If your rights have been terminated and
+ not permanently reinstated, receipt of a copy of some or all of
+ the same material does not give you any rights to use it.
+
+ 10. FUTURE REVISIONS OF THIS LICENSE
+
+ The Free Software Foundation may publish new, revised versions of
+ the GNU Free Documentation License from time to time. Such new
+ versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns. See
+ `http://www.gnu.org/copyleft/'.
+
+ Each version of the License is given a distinguishing version
+ number. If the Document specifies that a particular numbered
+ version of this License "or any later version" applies to it, you
+ have the option of following the terms and conditions either of
+ that specified version or of any later version that has been
+ published (not as a draft) by the Free Software Foundation. If
+ the Document does not specify a version number of this License,
+ you may choose any version ever published (not as a draft) by the
+ Free Software Foundation. If the Document specifies that a proxy
+ can decide which future versions of this License can be used, that
+ proxy's public statement of acceptance of a version permanently
+ authorizes you to choose that version for the Document.
+
+ 11. RELICENSING
+
+ "Massive Multiauthor Collaboration Site" (or "MMC Site") means any
+ World Wide Web server that publishes copyrightable works and also
+ provides prominent facilities for anybody to edit those works. A
+ public wiki that anybody can edit is an example of such a server.
+ A "Massive Multiauthor Collaboration" (or "MMC") contained in the
+ site means any set of copyrightable works thus published on the MMC
+ site.
+
+ "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
+ license published by Creative Commons Corporation, a not-for-profit
+ corporation with a principal place of business in San Francisco,
+ California, as well as future copyleft versions of that license
+ published by that same organization.
+
+ "Incorporate" means to publish or republish a Document, in whole or
+ in part, as part of another Document.
+
+ An MMC is "eligible for relicensing" if it is licensed under this
+ License, and if all works that were first published under this
+ License somewhere other than this MMC, and subsequently
+ incorporated in whole or in part into the MMC, (1) had no cover
+ texts or invariant sections, and (2) were thus incorporated prior
+ to November 1, 2008.
+
+ The operator of an MMC Site may republish an MMC contained in the
+ site under CC-BY-SA on the same site at any time before August 1,
+ 2009, provided the MMC is eligible for relicensing.
+
+
+ADDENDUM: How to use this License for your documents
+----------------------------------------------------
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and license
+notices just after the title page:
+
+ Copyright (C) YEAR YOUR NAME.
+ 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, no Front-Cover Texts, and no Back-Cover
+ Texts. A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+
+ If you have Invariant Sections, Front-Cover Texts and Back-Cover
+Texts, replace the "with...Texts." line with this:
+
+ with the Invariant Sections being LIST THEIR TITLES, with
+ the Front-Cover Texts being LIST, and with the Back-Cover Texts
+ being LIST.
+
+ If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+ If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License, to
+permit their use in free software.
+
+\1f
+File: auctex.info, Node: Changes, Next: Development, Prev: Copying this Manual, Up: Appendices
+
+A.2 Changes and New Features
+============================
+
+News in 11.86
+-------------
+
+ * Parsing of LaTeX output was improved. It is now less likely that
+ AUCTeX opens a non-existent file upon calling `TeX-next-error'; a
+ problem for example encountered when using MiKTeX 2.8. In addition
+ quoted file names as emitted by MiKTeX are now supported.
+
+ * A new framework for the definition and selection of viewers was
+ implemented. If you have customizations regarding viewers you
+ will have to redo them in this new framework or reenable the old
+ one. *Note Starting Viewers::, for details.
+
+ * Comprehensive editing support for PSTricks was added.
+
+ * Support for various LaTeX packages was added, e.g. `tabularx',
+ `CJK', and `hyperref'.
+
+ * An easy way to switch between TeX engines (PDFTeX, LuaTeX, XeTeX,
+ Omega) was added.
+
+ * Support for SyncTeX was added. This involves the command line
+ options for LaTeX and the viewer.
+
+ * Folding can now be customized to use macro arguments as replacement
+ text.
+
+ * `preview.sty' now works with XeTeX.
+
+ * A lot of smaller and larger bugs have been squashed.
+
+News in 11.85
+-------------
+
+ * Font locking has been improved significantly. It is now less
+ prone to color bleeding which could lead to high resource usage.
+ In addition it now includes information about LaTeX macro syntax
+ and can indicate syntactically incorrect macros in LaTeX mode.
+
+ * The license was updated to GPLv3.
+
+ * Support for the nomencl, flashcards and comment LaTeX packages as
+ well as the Icelandic language option of babel were added.
+
+ * Support for folding of math macros was added.
+
+ * Lots of minor bugs in features and documentation fixed.
+
+News in 11.84
+-------------
+
+ * There have been problems with the `-without-texmf-dir' option to
+ `configure' when the value of `-with-kpathsea-sep' was set or
+ determined for an installation system with a default different
+ from that of the runtime system. `with-kpathsea-sep' has been
+ removed; the setting is now usually determined at runtime.
+
+ Due to this and other problems, preview-latex in the released
+ XEmacs package failed under Windows or with anything except recent
+ 21.5 XEmacsen.
+
+ * AUCTeX and preview-latex have been changed in order to accommodate
+ file names containing spaces. preview-latex now tolerates bad
+ PostScript code polluting the stack (like some Omega fonts).
+
+ * `preview.sty' had in some cases failed to emit PostScript header
+ specials.
+
+ * Support for folding of comments was added.
+
+ * The `polish' language option of the babel LaTeX package as well as
+ the polski LaTeX package are now supported. Most notably this
+ means that AUCTeX will help to insert quotation marks as defined
+ by polish.sty (`"`..."'') and polski.sty (`,,...''').
+
+ * The TeX tool bar is now available and enabled by default in plain
+ TeX mode. *Note Processing Facilities::.
+
+ * Bug fix in the display of math subscripts and superscripts.
+
+ * Bug fix `TeX-doc' for Emacs 21.
+
+ * There has been quite a number of other bug fixes to various
+ features and documentation across the board.
+
+
+News in 11.83
+-------------
+
+ * The new function `TeX-doc' provides easy access to documentation
+ about commands and packages or information related to TeX and
+ friends in general. *Note Documentation::.
+
+ * You can now get rid of generated intermediate and output files by
+ means of the new `Clean' and `Clean All' entries in
+ `TeX-command-list' accessible with `C-c C-c' or the Command menu.
+ *Note Cleaning::.
+
+ * Support for forward search with PDF files was added. That means
+ you can jump to a place in the output file corresponding to the
+ position in the source file. *Note Viewing::.
+
+ Adding support for this feature required the default value of the
+ variable `TeX-output-view-style' to be changed. Please make sure
+ you either remove any customizations overriding the new default or
+ incorporate the changes into your customizations if you want to
+ use this feature.
+
+ * TeX error messages of the `-file-line-error' kind are now
+ understood in AUCTeX and preview-latex (parsers are still
+ separate).
+
+ * Bug fix in XyMTeX support.
+
+ * The LaTeX tool bar is now enabled by default. *Note Processing
+ Facilities::.
+
+
+News in 11.82
+-------------
+
+ * Support for the MinionPro LaTeX package was added.
+
+ * Warnings and underfull/overfull boxes are now being indicated in
+ the echo area after a LaTeX run, if the respective debugging
+ options are activated with `TeX-toggle-debug-warnings' (`C-c C-t
+ C-w') or `TeX-toggle-debug-bad-boxes' (`C-c C-t C-b'). In this
+ case `TeX-next-error' will find these warnings in addition to
+ normal errors.
+
+ The key binding `C-c C-w' for `TeX-toggle-debug-bad-boxes' (which
+ was renamed from `TeX-toggle-debug-boxes') now is deprecated.
+
+ * AUCTeX now can automatically insert a pair of braces after typing
+ <_> or <^> in math constructs if the new variable
+ `TeX-electric-sub-and-superscript' is set to a non-nil value.
+
+ * Some language-specific support for French was added. There now is
+ completion support for the commands provided by the `frenchb' (and
+ `francais') options of the babel LaTeX package and easier input of
+ French quotation marks (`\\og ...\\fg') which can now be inserted
+ by typing <">.
+
+ * Completion support for options of some LaTeX packages was added.
+
+ * Already in version 11.81 the way to activate AUCTeX changed
+ substantially. This should now be done with `(load "auctex.el" nil
+ t t)' instead of the former `(require 'tex-site)'. Related to this
+ change `tex-mik.el' does not load `tex-site.el' anymore. That
+ means if you used only `(require 'tex-mik)' in order to activate
+ AUCTeX, you have to add `(load "auctex.el" nil t t)' before the
+ latter statement. *Note Loading the package::.
+
+ * Handling of verbatim constructs was consolidated across AUCTeX.
+ This resulted in the font-latex-specific variables
+ `font-latex-verb-like-commands', `font-latex-verbatim-macros', and
+ `font-latex-verbatim-environments' being removed and the more
+ general variables `LaTeX-verbatim-macros-with-delims',
+ `LaTeX-verbatim-macros-with-braces', and
+ `LaTeX-verbatim-environments' being added.
+
+ * The output of a BibTeX run is now checked for warnings and errors,
+ which are reported in the echo area.
+
+ * The aliases for `font-latex-title-fontify' were removed. Use
+ `font-latex-fontify-sectioning' instead.
+
+ * The problem that Japanese macros where broken across lines was
+ fixed.
+
+ * Various bug fixes.
+
+News in 11.81
+-------------
+
+ * `LaTeX-mark-section' now marks subsections of a given section as
+ well. The former behavior is available via the prefix argument.
+
+ * preview-latex which was previously available separately became a
+ subsystem of AUCTeX. There is no documented provision for building
+ or installing preview-latex separately. It is still possible to
+ use and install AUCTeX without preview-latex, however.
+
+ * The installation procedures have been overhauled and now also
+ install startup files as part of the process (those had to be
+ copied manually previously). You are advised to remove previous
+ installations of AUCTeX and preview-latex before starting the
+ installation procedure. A standard installation from an
+ unmodified tarball no longer requires Makeinfo or Perl.
+
+ Also note that the way AUCTeX is supposed to be activated changed.
+ Instead of `(require 'tex-site)' you should now use `(load
+ "auctex.el" nil t t)'. While the former method may still work,
+ the new method has the advantage that you can deactivate a
+ preactivated AUCTeX with the statement `(unload-feature
+ 'tex-site)' before any of its modes have been used. This may be
+ important especially for site-wide installations.
+
+ * Support for the babel LaTeX package was added.
+
+ * Folding a buffer now ensures that the whole buffer is fontified
+ before the actual folding is carried out. If this results in
+ unbearably long execution times, you can fall back to the old
+ behavior of relying on stealth font locking to do this job in the
+ background by customizing the variable `TeX-fold-force-fontify'.
+
+ * Folded content now reveals part of its original text in a tooltip
+ or the echo area when hovering with the mouse pointer over it.
+
+ * The language-specific insertion of quotation marks was
+ generalized. The variables `LaTeX-german-open-quote',
+ `LaTeX-german-close-quote', `LaTeX-german-quote-after-quote',
+ `LaTeX-italian-open-quote', `LaTeX-italian-close-quote', and
+ `LaTeX-italian-quote-after-quote' are now obsolete. If you are not
+ satisfied with the default settings, you should customize
+ `TeX-quote-language-alist' instead.
+
+ * Similar to language-specific quote insertion, AUCTeX now helps you
+ with hyphens in different languages as well. *Note European::,
+ for details.
+
+ * Fill problems in Japanese text introduced in AUCTeX 11.55 were
+ fixed. AUCTeX tries not to break lines between 1-byte and 2-byte
+ chars. These features will work in Chinese text, too.
+
+ * The scaling factor of the fontification of sectioning commands can
+ now be customized using the variable
+ `font-latex-fontify-sectioning'. This variable was previously
+ called `font-latex-title-fontify'; In this release we provide an
+ alias but this will disappear in one of the the next releases.
+ The faces for the sectioning commands are now called
+ `font-latex-sectioning-N-face' (N=0...5) instead of
+ `font-latex-title-N-face' (N=1...4). Analogously the names of the
+ variables holding the related keyword lists were changed from
+ `font-latex-title-N-keywords' to
+ `font-latex-sectioning-N-keywords'. *Note Font Locking::, for
+ details. Make sure to adjust your customizations.
+
+ * Titles in beamer slides marked by the "\frametitle" command are
+ know displayed with the new face `font-latex-slide-title-face'.
+ You can add macros to be highlighted with this face to
+ `font-latex-match-slide-title-keywords'.
+
+ * Of course a lot of bugs have been fixed.
+
+News in 11.55
+-------------
+
+ * A bug was fixed which lead to the insertion of trailing whitespace
+ during filling. In particular extra spaces were added to sentence
+ endings at the end of lines. You can make this whitespace visible
+ by setting the variable `show-trailing-whitespace' to `t'. If you
+ want to delete all trailing whitespace in a buffer, type `M-x
+ delete-trailing-whitespace RET'.
+
+ * A bug was fixed which lead to a `*Compile-Log*' buffer popping up
+ when the first LaTeX file was loaded in an Emacs session.
+
+ * On some systems the presence of an outdated Emacspeak package lead
+ to the error message `File mode specification error: (error
+ "Variable binding depth exceeds max-specpdl-size")'. Precautions
+ were added which prevent this error from happening. But
+ nevertheless, it is advised to upgrade or uninstall the outdated
+ Emacspeak package.
+
+ * The value of `TeX-macro-global' is not determined during
+ configuration anymore but at load time of AUCTeX. Consequently the
+ associated configuration option `--with-tex-input-dirs' was
+ removed.
+
+ * Support for the LaTeX Japanese classes `jsarticle' and `jsbook'
+ was added.
+
+News in 11.54
+-------------
+
+ * The parser (used e.g. for `TeX-auto-generate-global') was extended
+ to recognize keywords common in LaTeX packages and classes, like
+ "\DeclareRobustCommand" or "\RequirePackage". Additionally a bug
+ was fixed which led to duplicate entries in AUCTeX style files.
+
+ * Folding can now be done for paragraphs and regions besides single
+ constructs and the whole buffer. With the new `TeX-fold-dwim'
+ command content can both be hidden and shown with a single key
+ binding. In course of these changes new key bindings for
+ unfolding commands where introduced. The old bindings are still
+ present but will be phased out in future releases.
+
+ * Info files of the manual now have a .info extension.
+
+ * There is an experimental tool bar support now. It is not
+ activated by default. If you want to use it, add
+ (add-hook 'LaTeX-mode-hook 'LaTeX-install-toolbar)
+ to your init file.
+
+ * The manual now contains a new chapter "Quick Start". It explains
+ the main features and how to use them, and should be enough for a
+ new user to start using AUCTeX.
+
+ * A new section "Font Locking" was added to the manual which explains
+ syntax highlighting in AUCTeX and its customization. Together with
+ the sections related to folding and outlining, the section is part
+ of the new chapter "Display".
+
+ * Keywords for syntax highlighting of LaTeX constructs to be typeset
+ in bold, italic or typewriter fonts may now be customized.
+ Besides the built-in classes, new keyword classes may be added by
+ customizing the variable `font-latex-user-keyword-classes'. The
+ customization options can be found in the customization group
+ `font-latex-keywords'.
+
+ * Verbatim content is now displayed with the `fixed-pitch' face. (GNU
+ Emacs only)
+
+ * Syntax highlighting should not spill out of verbatim content
+ anymore. (GNU Emacs only)
+
+ * Verbatim commands like `\verb|...|' will not be broken anymore
+ during filling.
+
+ * You can customize the completion for graphic files with
+ `LaTeX-includegraphics-read-file'.
+
+ * Support for the LaTeX packages `url', `listings', `jurabib' and
+ `csquotes' was added with regard to command completion and syntax
+ highlighting.
+
+ * Performance of fontification and filling was improved.
+
+ * Insertion of nodes in Texinfo mode now supports completion of
+ existing node names.
+
+ * Setting the variable `LaTeX-float' to `nil' now means that you
+ will not be prompted for the float position of figures and tables.
+ You can get the old behaviour of `nil' by setting the variable to
+ `""', i.e. an empty string. See also *note Floats::.
+
+ * The XEmacs-specific bug concerning `overlays-at' was fixed.
+
+ * Lots of bug fixes.
+
+News in 11.53
+-------------
+
+ * The LaTeX math menu can include Unicode characters if your Emacs
+ built supports it. See the variable `LaTeX-math-menu-unicode',
+ *note Mathematics::.
+
+ * Bug fixes for XEmacs.
+
+ * Completion for graphic files in the TeX search path has been added.
+
+ * `start' is used for the viewer for MiKTeX and fpTeX.
+
+ * The variable `TeX-fold-preserve-comments' can now be customized to
+ deactivate folding in comments.
+
+News in 11.52
+-------------
+
+ * Installation and menus under XEmacs work again (maybe for the first
+ time).
+
+ * Fontification of subscripts and superscripts is now disabled when
+ the fontification engine is not able to support it properly.
+
+ * Bug fixes in the build process.
+
+News in 11.51
+-------------
+
+ * PDFTeX and Source Special support did not work with ConTeXt, this
+ has been fixed. Similar for Source Special support under Windows.
+
+ * Omega support has been added.
+
+ * Bug fixes in the build process.
+
+ * `TeX-fold' now supports folding of environments in Texinfo mode.
+
+News in 11.50
+-------------
+
+ * The use of source specials when processing or viewing the document
+ can now be controlled with the new `TeX-source-specials' minor mode
+ which can be toggled via an entry in the Command menu or the key
+ binding `C-c C-t C-s'. If you have customized the variable
+ `TeX-command-list', you have to re-initialize it for this to work.
+ This means to open a customization buffer for the variable by
+ typing `M-x customize-variable RET TeX-command-list RET', selecting
+ "Erase Customization" and do your customization again with the new
+ default.
+
+ * The content of the command menu now depends on the mode (plain TeX,
+ LaTeX, ConTeXt etc.). Any former customization of the variable
+ `TeX-command-list' has to be erased. Otherwise the command menu
+ and the customization will not work correctly.
+
+ * Support for hiding and auto-revealing macros, e.g. footnotes or
+ citations, and environments in a buffer was added, *note Folding::.
+
+ * You can now control if indentation is done upon typing <RET> by
+ customizing the variable `TeX-newline-function', *note Indenting::.
+
+ * Limited support for `doc.sty' and `ltxdoc.cls' (`dtx' files) was
+ added. The new docTeX mode provides functionality for editing
+ documentation parts. This includes formatting (indenting and
+ filling), adding and completion of macros and environments while
+ staying in comments as well as syntax highlighting. (Please note
+ that the mode is not finished yet. For example syntax
+ highlighting does not work yet in XEmacs.)
+
+ * For macro completion in docTeX mode the AUCTeX style files
+ `doc.el', `ltxdoc.el' and `ltx-base.el' were included. The latter
+ provides general support for low-level LaTeX macros and may be
+ used with LaTeX class and style files as well. It is currently
+ not loaded automatically for those files.
+
+ * Support for ConTeXt with a separate ConTeXt mode is now included.
+ Macro definitions for completion are available in Dutch and
+ English.
+
+ * The filling and indentation code was overhauled and is now able to
+ format commented parts of the source syntactically correct. Newly
+ available functionality and customization options are explained in
+ the manual.
+
+ * Filling and indentation in XEmacs with preview-latex and activated
+ previews lead to the insertion of whitespace before multi-line
+ previews. AUCTeX now contains facilities to prevent this problem.
+
+ * If `TeX-master' is set to `t', AUCTeX will now query for a master
+ file only when a new file is opened. Existing files will be left
+ alone. The new function `TeX-master-file-ask' (bound to `C-c _'
+ is provided for adding the variable manually.
+
+ * Sectioning commands are now shown in a larger font on display
+ devices which support such fontification. The variable
+ `font-latex-title-fontify' can be customized to restore the old
+ appearance, i.e. the usage of a different color instead of a
+ change in size.
+
+ * Support for `alphanum.sty', `beamer.cls', `booktabs.sty',
+ `captcont.sty', `emp.sty', `paralist.sty', `subfigure.sty' and
+ `units.sty'/`nicefrac.sty' was added. Credits go to the authors
+ mentioned in the respective AUCTeX style files.
+
+ * Inserting graphics with `C-c RET \includegraphics RET' was
+ improved. See the variable `LaTeX-includegraphics-options-alist'.
+
+ * If `LaTeX-default-position' is `nil', don't prompt for position
+ arguments in Tabular-like environments, see *note Tabular-like::.
+
+ * Completion for available packages when using `C-c RET \usepackage
+ RET' was improved on systems using the kpathsea library.
+
+ * The commenting functionality was fixed. The separate functions for
+ commenting and uncommenting were unified in one function for
+ paragraphs and regions respectively which do both.
+
+ * Syntax highlighting can be customized to fontify quotes delimited
+ by either >>German<< or <<French>> quotation marks by changing the
+ variable `font-latex-quotes'.
+
+ * Certain TeX/LaTeX keywords for functions, references, variables
+ and warnings will now be fontified specially. You may add your own
+ keywords by customizing the variables
+ `font-latex-match-function-keywords',
+ `font-latex-match-reference-keywords',
+ `font-latex-match-variable-keywords' and
+ `font-latex-match-warning-keywords'.
+
+ * If you include the style files `german' or `ngerman' in a document
+ (directly or via the `babel' package), you should now customize
+ `LaTeX-german-open-quote', `LaTeX-german-close-quote' and
+ `LaTeX-german-quote-after-quote' instead of `TeX-open-quote',
+ `TeX-close-quote' and `TeX-quote-after-quote' if you want to
+ influence the type of quote insertion.
+
+ * Upon viewing an output file, the right viewer and command line
+ options for it are now determined automatically by looking at the
+ extension of the output file and certain options used in the
+ source file. The behavior can be adapted or extended respectively
+ by customizing the variable `TeX-output-view-style'.
+
+ * You can control whether `TeX-insert-macro' (`C-c RET') ask for all
+ optional arguments by customizing the variable
+ `TeX-insert-macro-default-style', *note Completion::.
+
+ * `TeX-run-discard' is now able to completely detach a process that
+ it started.
+
+ * The build process was enhanced and is now based on `autoconf'
+ making installing AUCTeX a mostly automatic process. See *note
+ Installation:: and *note Installation under MS Windows:: for
+ details.
+
+News in 11.14
+-------------
+
+ * Many more LaTeX and LaTeX2e commands are supported. Done by
+ Masayuki Ataka <ataka@milk.freemail.ne.jp>
+
+News in 11.12
+-------------
+
+ * Support for the KOMA-Script classes. Contributed by Mark Trettin
+ <Mark.Trettin@gmx.de>.
+
+News in 11.11
+-------------
+
+ * Support for `prosper.sty', see `http://prosper.sourceforge.net/'.
+ Contributed by Phillip Lord <p.lord@russet.org.uk>.
+
+News in 11.10
+-------------
+
+ * `comment-region' now inserts %% by default. Suggested by "Davide
+ G. M. Salvetti" <salve@debian.org>.
+
+News in 11.06
+-------------
+
+ * You can now switch between using the `font-latex' (all emacsen),
+ the `tex-font' (Emacs 21 only) or no special package for font
+ locking. Customize `TeX-install-font-lock' for this.
+
+News in 11.04
+-------------
+
+ * Now use -t landscape by default when landscape option appears.
+ Suggested by Erik Frisk <frisk@isy.liu.se>.
+
+News in 11.03
+-------------
+
+ * Use `tex-fptex.el' for fpTeX support. Contributed by Fabrice
+ Popineau <Fabrice.Popineau@supelec.fr>.
+
+News in 11.02
+-------------
+
+ * New user option `LaTeX-top-caption-list' specifies environments
+ where the caption should go at top. Contributed by
+ ataka@milk.freemail.ne.jp (Masayuki Ataka).
+
+ * Allow explicit dimensions in `graphicx.sty'. Contributed by
+ ataka@milk.freemail.ne.jp (Masayuki Ataka).
+
+ * Limited support for `verbatim.sty'. Contributed by
+ ataka@milk.freemail.ne.jp (Masayuki Ataka).
+
+ * Better support for asmmath items. Patch by
+ ataka@milk.freemail.ne.jp (Masayuki Ataka).
+
+ * More accurate error parsing. Added by David Kastrup
+ <David.Kastrup@t-online.de>.
+
+News in 11.01
+-------------
+
+ * Bug fixes.
+
+Older versions
+--------------
+
+See the file `history.texi' for older changes.
+
+\1f
+File: auctex.info, Node: Development, Next: FAQ, Prev: Changes, Up: Appendices
+
+A.3 Future Development
+======================
+
+The following sections describe future development of AUCTeX. Besides
+mid-term goals, bug reports and requests we cannot fix or honor right
+away are being gathered here. If you have some time for Emacs Lisp
+hacking, you are encouraged to try to provide a solution to one of the
+following problems. If you don't know Lisp, you may help us to improve
+the documentation. It might be a good idea to discuss proposed changes
+on the mailing list of AUCTeX first.
+
+* Menu:
+
+* Mid-term Goals::
+* Wishlist::
+* Bugs::
+
+\1f
+File: auctex.info, Node: Mid-term Goals, Next: Wishlist, Up: Development
+
+A.3.1 Mid-term Goals
+--------------------
+
+ * Integration of preview-latex into AUCTeX
+
+ As of AUCTeX 11.81 preview-latex is a part of AUCTeX in the sense
+ that the installation routines were merged and preview-latex is
+ being packaged with AUCTeX.
+
+ Further integration will happen at the backend. This involves
+ folding of error parsing and task management of both packages
+ which will ease development efforts and avoid redundant work.
+
+ * More flexible option and command handling
+
+ The current state of command handling with `TeX-command-list' is
+ not very flexible because there is no distinction between
+ executables and command line options to be passed to them.
+
+ Customization of `TeX-command-list' by the user will interfere with
+ updates of AUCTeX.
+
+ * Error help catalogs
+
+ Currently, the help for errors is more or less hardwired into
+ `tex.el'. For supporting error help in other languages, it would
+ be sensible to instead arrange error messages in language-specific
+ files, make a common info file from all such catalogs in a given
+ language and look the error texts up in an appropriate index. The
+ user would then specify a preference list of languages, and the
+ errors would be looked up in the catalogs in sequence until they
+ were identified.
+
+ * Combining `docTeX' with RefTeX
+
+ Macro cross references should also be usable for document
+ navigation using RefTeX.
+
+
+\1f
+File: auctex.info, Node: Wishlist, Next: Bugs, Prev: Mid-term Goals, Up: Development
+
+A.3.2 Wishlist
+--------------
+
+ * Documentation lookup for macros
+
+ A parser could gather information about which macros are defined in
+ which LaTeX packages and store the information in a hashtable which
+ can be used in a backend for `TeX-doc' in order to open the
+ matching documentation for a given macro. The information could
+ also be used to insert an appropriate `\usepackage' statement if
+ the user tries to insert a macro for which the respective package
+ has not been requested yet.
+
+ * Spell checking of macros
+
+ A special ispell dictionary for macros could be nice to have.
+
+ * Quick error overviews
+
+ An error overview window (extract from the log file with just the
+ error lines, clickable like a "grep" buffer) and/or fringe
+ indicators for errors in the main text would be nice.
+
+ * A math entry grid
+
+ A separate frame with a table of math character graphics to click
+ on in order to insert the respective sequence into the buffer (cf.
+ the "grid" of x-symbol).
+
+ * Crossreferencing support
+
+ It would be nice if you could index process your favorite
+ collection of `.dtx' files (such as the LaTeX source), just call a
+ command on arbitrary control sequence, and get either the DVI
+ viewer opened right at the definition of that macro (using Source
+ Specials), or the source code of the `.dtx' file.
+
+ * Better plain TeX support
+
+ For starters, `LaTeX-math-mode' is not very LaTeX-specific in the
+ first place, and similar holds for indentation and formatting.
+
+ * Poor man's Source Specials In particular in PDF mode (and where
+ Source Specials cause problems), alternatives would be desirable.
+ One could implement inverse search by something like Heiko
+ Oberdiek's `vpe.sty', and forward search by using the `.aux' file
+ info to correlate labels in the text (possibly in cooperation with
+ RefTeX) with previewer pages.
+
+ In AUCTeX 11.83, support for forward search with PDF files was
+ added. Currently this only works if you use the pdfsync LaTeX
+ package and xpdf as your PDF viewer. *Note Viewing::.
+
+ * Page count when compiling should (optionally) go to modeline of the
+ window where the compilation command was invoked, instead of the
+ output window. Suggested by Karsten Tinnefeld
+ <tinnefeld@irb.informatik.uni-dortmund.de>.
+
+ * Command to insert a macrodefinition in the preamble, without moving
+ point from the current location. Suggested by "Jeffrey C. Ely"
+ <ely@nwu.edu>.
+
+ * A database of all commands defined in all stylefiles. When a
+ command or environment gets entered that is provided in one of the
+ styles, insert the appropriate `\usepackage' in the preamble.
+
+ * A way to add and overwrite math mode entries in style files, and to
+ decide where they should be. Suggested by Remo Badii
+ <Remo.Badii@psi.ch>.
+
+ * Create template for (first) line of tabular environment.
+
+ * I think prompting for the master is the intended behaviour. It
+ corresponds to a `shared' value for TeX-master.
+
+ There should probably be a `none' value which wouldn't query for
+ the master, but instead disable all features that relies on
+ TeX-master.
+
+ This default value for TeX-master could then be controled with
+ mapping based on the extension.
+
+ * Multiple argument completion for `\bibliography'. In general, I
+ ought to make `,' special for these kind of completions.
+
+ * Suggest `makeindex' when appropriate.
+
+ * Use index files (when available) to speed up `C-c C-m include
+ <RET>'.
+
+ * Option not to calculate very slow completions like for `C-c C-m
+ include <RET>'.
+
+ * Font menu should be created from `TeX-font-list'.
+
+ * Installation procedure written purely in emacs lisp.
+
+ * Included PostScript files should also be counted as part of the
+ document.
+
+ * A nice hierarchical by-topic organization of all officially
+ documented LaTeX macros, available from the menu bar.
+
+ * `TeX-command-default' should be set from the master file, if not
+ set locally. Suggested by Peter Whaite `<peta@cim.mcgill.ca>'.
+
+ * Make AUCTeX work with `crypt++'. Suggested by Chris Moore
+ `<Chris.Moore@src.bae.co.uk>'.
+
+ * Make AUCTeX work with `longlines'. This would also apply to
+ preview-latex, though it might make sense to unify error processing
+ before attempting this.
+
+ * The `Spell' command should apply to all files in a document. Maybe
+ it could try to restrict to files that have been modified since
+ last spell check? Suggested by Ravinder Bhumbla
+ `<rbhumbla@ucsd.edu>'.
+
+ * Make <.> check for abbreviations and sentences ending with capital
+ letters.
+
+ * Use Emacs 19 minibuffer history to choose between previewers, and
+ other stuff. Suggested by John Interrante
+ `<interran@uluru.Stanford.EDU>'.
+
+ * Make features.
+
+ A new command `TeX-update' (`C-c C-u') could be used to create an
+ up-to-date dvi file by repeatedly running BibTeX, MakeIndex and
+ (La)TeX, until an error occurs or we are done.
+
+ An alternative is to have an `Update' command that ensures the
+ `dvi' file is up to date. This could be called before printing and
+ previewing.
+
+ * Documentation of variables that can be set in a style hook.
+
+ We need a list of what can safely be done in an ordinary style
+ hook. You can not set a variable that AUCTeX depends on, unless
+ AUCTeX knows that it has to run the style hooks first.
+
+ Here is the start of such a list.
+ `LaTeX-add-environments'
+
+ `TeX-add-symbols'
+
+ `LaTeX-add-labels'
+
+ `LaTeX-add-bibliographies'
+
+ `LaTeX-largest-level'
+
+ * Completion for counters and sboxes.
+
+ * Outline should be (better) supported in TeX mode.
+
+ At least, support headers, trailers, as well as TeX-outline-extra.
+
+ * `TeX-header-start' and `TeX-trailer-end'.
+
+ We might want these, just for fun (and outlines)
+
+ * Plain TeX and LaTeX specific header and trailer expressions.
+
+ We should have a way to globally specify the default value of the
+ header and trailer regexps.
+
+ * Get closer to original `TeX-mode' keybindings.
+
+ A third initialization file (`tex-mode.el') containing an emulator
+ of the standard `TeX-mode' would help convince some people to
+ change to AUCTeX.
+
+ * Make `TeX-next-error' parse ahead and store the results in a list,
+ using markers to remember buffer positions in order to be more
+ robust with regard to line numbers and changed files. This is what
+ `next-error' does. (Or did, until Emacs 19).
+
+ * Finish the Texinfo mode. For one thing, many Texinfo mode
+ commands do not accept braces around their arguments.
+
+ * Hook up the letter environment with `bbdb.el'.
+
+
+\1f
+File: auctex.info, Node: Bugs, Prev: Wishlist, Up: Development
+
+A.3.3 Bugs
+----------
+
+ * The parsed files and style hooks for `example.dtx', `example.sty',
+ `example.drv' and `example.bib' all clash. Bad.
+
+ * `C-c `' should always stay in the current window, also when it
+ finds a new file.
+
+ * Do not overwrite emacs warnings about existing auto-save files when
+ loading a new file.
+
+ * Maybe the regexp for matching a TeX symbol during parsing should be
+ `"\\\\\\([a-zA-Z]+\\|.\\)"' --
+ `<thiemann@informatik.uni-tuebingen.de>' Peter Thiemann.
+
+ * AUCTeX should not parse verbatim environments.
+
+ * Make ``' check for math context in `LaTeX-math-mode'. and simply
+ self insert if not in a math context.
+
+ * Make `TeX-insert-dollar' more robust. Currently it can be fooled
+ by `\mbox''es and escaped double dollar for example.
+
+ * Correct indentation for tabular, tabbing, table, math, and array
+ environments.
+
+ * No syntactic font locking of verbatim macros and environments.
+ (XEmacs only)
+
+ * Font locking inside of verbatim macros and environments is not
+ inhibited. This may result in syntax highlighting of unbalanced
+ dollar signs and the like spilling out of the verbatim content.
+ (XEmacs only)
+
+ * Folding of LaTeX constructs spanning more than one line may result
+ in overfull lines. (XEmacs only)
+
+\1f
+File: auctex.info, Node: FAQ, Prev: Development, Up: Appendices
+
+A.4 Frequently Asked Questions
+==============================
+
+ 1. Something is not working correctly. What should I do?
+
+ Well, you might have guessed it, the first place to look is in the
+ available documentation packaged with AUCTeX. This could be the
+ release notes (in the `RELEASE' file) or the news section of the
+ manual in case you are experiencing problems after an upgrade, the
+ `INSTALL' file in case you are having problems with the
+ installation, the section about bugs in the manual in case you
+ encountered a bug or the relevant sections in the manual for other
+ related problems.
+
+ If this did not help, you can send a bug report to the AUCTeX bug
+ reporting list by using the command `M-x TeX-submit-bug-report
+ RET'. But before you do this, you can try to get more information
+ about the problem at hand which might also help you locate the
+ cause of the error yourself.
+
+ First, you can try to generate a so-called backtrace which shows
+ functions involved in a program error. In order to do this, start
+ Emacs with the command line `emacs --debug-init' and/or put the
+ line
+
+ (setq debug-on-error t)
+
+ as the first line into your init file. XEmacs users might want to
+ add `(setq stack-trace-on-error t)' as well. After Emacs has
+ started, you can load a file which triggers the error and a new
+ window should pop up showing the backtrace. If you get such a
+ backtrace, please include it in the bug report.
+
+ Second, you can try to figure out if something in your personal or
+ site configuration triggers the error by starting Emacs without
+ such customizations. You can do this by invoking Emacs with the
+ command line `emacs -q -no-site-file'. Once Emacs is running,
+ copy the line
+
+ (load "auctex.el" nil t t)
+
+ into the `*scratch*' buffer and type `M-x eval-buffer RET'. This
+ makes sure that AUCTeX will be used for the file types it
+ supports. After you have done so, you can load the file
+ triggering the error. If everything is working now, you know that
+ you have to search either in the site configuration file or your
+ personal init file for statements related to the problem.
+
+ 2. What versions of Emacs and XEmacs are supported?
+
+ AUCTeX was tested with Emacs 21 and XEmacs 21.4.15. Older
+ versions may work but are unsupported. Older versions of XEmacs
+ might possibly made to work by updating the `xemacs-base' package
+ through the XEmacs package system. If you are looking for a
+ recommendation, it would appear that the smoothest working
+ platform on all operating systems at the current point of time
+ would be Emacs 22.1. At the time of this writing, however, it has
+ not been released and is still under development. The quality of
+ the development version is quite solid, so we recommend giving it
+ a try. With a developer version, of course, you have to be
+ prepared to update in case you managed to get your snapshot at a
+ bad time. The second best choice would be the latest released
+ Emacs 21.4. However, Unicode support is less good, there is no
+ version for the popular GTK toolkit, and the native versions for
+ Windows and MacOS don't offer toolbar and preview-latex support.
+
+ Our success with XEmacs has been less than convincing. Under the
+ Windows operating system, nominally the only option for a released,
+ stable Emacs variant supporting toolbars and preview-latex would be
+ XEmacs 21.4. However, code for core functionality like formatting
+ and syntax highlighting tends to be different and often older than
+ even Emacs 21.4, and Unicode support as delivered is problematic
+ at best, missing on Windows. Both AUCTeX and XEmacs developers
+ don't hear much from active users of the combination. Partly for
+ that reason, problems tend to go unnoticed for long amounts of
+ time and are often found, if at all, after releases. No
+ experiences or recommendations can be given for beta or developer
+ versions of XEmacs.
+
+ 3. What should I do when `./configure' does not find programs like
+ latex?
+
+ This is problem often encountered on Windows. Make sure that the
+ `PATH' environment variable includes the directories containing the
+ relevant programs, as described in *note Installation under MS
+ Windows: (auctex)Installation under MS Windows.
+
+ 4. Why doesn't the completion, style file, or multi-file stuff work?
+
+ It must be enabled first, insert this in your init file:
+
+ (setq-default TeX-master nil)
+ (setq TeX-parse-self t)
+ (setq TeX-auto-save t)
+
+ Read also the chapters about parsing and multifile documents in the
+ manual.
+
+ 5. Why doesn't `TeX-save-document' work?
+
+ `TeX-check-path' has to contain "./" somewhere.
+
+ 6. Why is the information in `foo.tex' forgotten when I save
+ `foo.bib'?
+
+ For various reasons, AUCTeX ignores the extension when it stores
+ information about a file, so you should use unique base names for
+ your files. E.g. rename `foo.bib' to `foob.bib'.
+
+ 7. Why doesn't AUCTeX signal when processing a document is done?
+
+ If the message in the minibuffer stays "Type `C-c C-l' to display
+ results of compilation.", you probably have a misconfiguration in
+ your init file (`.emacs', `init.el' or similar). To track this
+ down either search in the `*Messages*' buffer for an error message
+ or put `(setq debug-on-error t)' as the first line into your init
+ file, restart Emacs and open a LaTeX file. Emacs will complain
+ loudly by opening a debugging buffer as soon as an error occurs.
+ The information in the debugging buffer can help you find the
+ cause of the error in your init file.
+
+ 8. What does AUC stand for?
+
+ AUCTeX came into being at Aalborg University in Denmark. Back then
+ the Danish name of the university was Aalborg Universitetscenter;
+ AUC for short.
+
+
+\1f
+File: auctex.info, Node: Indices, Prev: Appendices, Up: Top
+
+Indices
+*******
+
+* Menu:
+
+* Key Index::
+* Function Index::
+* Variable Index::
+* Concept Index::
+
+\1f
+File: auctex.info, Node: Key Index, Next: Function Index, Up: Indices
+
+Key Index
+=========
+
+\0\b[index\0\b]
+* Menu:
+
+* ": Quotes. (line 15)
+* $: Quotes. (line 62)
+* <LFD>: Indenting. (line 72)
+* <TAB>: Indenting. (line 69)
+* C-c %: Commenting. (line 23)
+* C-c ;: Commenting. (line 15)
+* C-c <LFD>: Itemize-like. (line 10)
+* C-c ?: Documentation. (line 7)
+* C-c ]: Environments. (line 56)
+* C-c ^: Control. (line 18)
+* C-c _: Multifile. (line 70)
+* C-c `: Debugging. (line 10)
+* C-c C-b: Starting a Command. (line 35)
+* C-c C-c: Starting a Command. (line 13)
+* C-c C-d: Multifile. (line 98)
+* C-c C-e: Environments. (line 20)
+* C-c C-f: Font Specifiers. (line 44)
+* C-c C-f C-b <1>: Font Specifiers. (line 16)
+* C-c C-f C-b: Editing Facilities. (line 73)
+* C-c C-f C-c <1>: Font Specifiers. (line 37)
+* C-c C-f C-c: Editing Facilities. (line 94)
+* C-c C-f C-e <1>: Font Specifiers. (line 22)
+* C-c C-f C-e: Editing Facilities. (line 79)
+* C-c C-f C-f <1>: Font Specifiers. (line 31)
+* C-c C-f C-f: Editing Facilities. (line 88)
+* C-c C-f C-i <1>: Font Specifiers. (line 19)
+* C-c C-f C-i: Editing Facilities. (line 76)
+* C-c C-f C-r <1>: Font Specifiers. (line 28)
+* C-c C-f C-r: Editing Facilities. (line 85)
+* C-c C-f C-s <1>: Font Specifiers. (line 25)
+* C-c C-f C-s: Editing Facilities. (line 82)
+* C-c C-f C-t <1>: Font Specifiers. (line 34)
+* C-c C-f C-t: Editing Facilities. (line 91)
+* C-c C-k: Control. (line 10)
+* C-c C-l: Control. (line 14)
+* C-c C-m: Completion. (line 30)
+* C-c C-n: Parsing Files. (line 44)
+* C-c C-o b: Folding. (line 113)
+* C-c C-o C-b: Folding. (line 44)
+* C-c C-o C-c: Folding. (line 110)
+* C-c C-o C-e: Folding. (line 94)
+* C-c C-o C-f: Folding. (line 32)
+* C-c C-o C-m: Folding. (line 85)
+* C-c C-o C-o: Folding. (line 132)
+* C-c C-o C-p: Folding. (line 81)
+* C-c C-o C-r: Folding. (line 78)
+* C-c C-o i: Folding. (line 125)
+* C-c C-o p: Folding. (line 121)
+* C-c C-o r: Folding. (line 117)
+* C-c C-q C-e: Filling. (line 92)
+* C-c C-q C-p: Filling. (line 86)
+* C-c C-q C-r: Filling. (line 101)
+* C-c C-q C-s: Filling. (line 97)
+* C-c C-r: Starting a Command. (line 19)
+* C-c C-s: Sectioning. (line 23)
+* C-c C-t C-b: Debugging. (line 19)
+* C-c C-t C-i: Processor Options. (line 29)
+* C-c C-t C-p: Processor Options. (line 15)
+* C-c C-t C-r: Starting a Command. (line 61)
+* C-c C-t C-s: Processor Options. (line 36)
+* C-c C-t C-w: Debugging. (line 23)
+* C-c C-v: Starting Viewers. (line 12)
+* C-c {: Quotes. (line 86)
+* C-c ~: Mathematics. (line 12)
+* C-j: Indenting. (line 81)
+* M-<TAB>: Completion. (line 20)
+* M-q: Filling. (line 89)
+
+\1f
+File: auctex.info, Node: Function Index, Next: Variable Index, Prev: Key Index, Up: Indices
+
+Function Index
+==============
+
+\0\b[index\0\b]
+* Menu:
+
+* LaTeX-add-bibliographies: Adding Other. (line 11)
+* LaTeX-add-environments: Adding Environments. (line 67)
+* LaTeX-add-labels: Adding Other. (line 14)
+* LaTeX-close-environment: Environments. (line 56)
+* LaTeX-env-args: Adding Environments. (line 109)
+* LaTeX-env-array: Adding Environments. (line 81)
+* LaTeX-env-bib: Adding Environments. (line 103)
+* LaTeX-env-contents: Adding Environments. (line 106)
+* LaTeX-env-figure: Adding Environments. (line 77)
+* LaTeX-env-item: Adding Environments. (line 74)
+* LaTeX-env-label: Adding Environments. (line 85)
+* LaTeX-env-list: Adding Environments. (line 88)
+* LaTeX-env-minipage: Adding Environments. (line 92)
+* LaTeX-env-picture: Adding Environments. (line 100)
+* LaTeX-env-tabular*: Adding Environments. (line 96)
+* LaTeX-environment: Environments. (line 20)
+* LaTeX-fill-environment: Filling. (line 81)
+* LaTeX-fill-paragraph: Filling. (line 86)
+* LaTeX-fill-region: Filling. (line 101)
+* LaTeX-fill-section: Filling. (line 97)
+* LaTeX-indent-line: Indenting. (line 69)
+* LaTeX-insert-environment: Adding Environments. (line 70)
+* LaTeX-insert-item: Itemize-like. (line 10)
+* LaTeX-math-mode: Mathematics. (line 12)
+* LaTeX-section: Sectioning. (line 23)
+* LaTeX-section-heading: Sectioning. (line 85)
+* LaTeX-section-label: Sectioning. (line 101)
+* LaTeX-section-section: Sectioning. (line 95)
+* LaTeX-section-title: Sectioning. (line 89)
+* LaTeX-section-toc: Sectioning. (line 92)
+* TeX-add-style-hook: Simple Style. (line 28)
+* TeX-add-symbols: Adding Macros. (line 25)
+* TeX-arg-cite: Adding Macros. (line 105)
+* TeX-arg-conditional: Adding Macros. (line 82)
+* TeX-arg-coordinate: Adding Macros. (line 165)
+* TeX-arg-corner: Adding Macros. (line 143)
+* TeX-arg-counter: Adding Macros. (line 108)
+* TeX-arg-define-cite: Adding Macros. (line 134)
+* TeX-arg-define-counter: Adding Macros. (line 137)
+* TeX-arg-define-environment: Adding Macros. (line 130)
+* TeX-arg-define-label: Adding Macros. (line 122)
+* TeX-arg-define-macro: Adding Macros. (line 126)
+* TeX-arg-define-savebox: Adding Macros. (line 140)
+* TeX-arg-environment: Adding Macros. (line 102)
+* TeX-arg-eval: Adding Macros. (line 93)
+* TeX-arg-file: Adding Macros. (line 114)
+* TeX-arg-free: Adding Macros. (line 90)
+* TeX-arg-input-file: Adding Macros. (line 118)
+* TeX-arg-label: Adding Macros. (line 96)
+* TeX-arg-literal: Adding Macros. (line 86)
+* TeX-arg-lr: Adding Macros. (line 146)
+* TeX-arg-macro: Adding Macros. (line 99)
+* TeX-arg-pagestyle: Adding Macros. (line 152)
+* TeX-arg-pair: Adding Macros. (line 158)
+* TeX-arg-savebox: Adding Macros. (line 111)
+* TeX-arg-size: Adding Macros. (line 162)
+* TeX-arg-tb: Adding Macros. (line 149)
+* TeX-arg-verb: Adding Macros. (line 155)
+* TeX-auto-generate: Automatic Private. (line 24)
+* TeX-clean: Cleaning. (line 7)
+* TeX-command-buffer: Starting a Command. (line 35)
+* TeX-command-master: Starting a Command. (line 13)
+* TeX-command-region: Starting a Command. (line 19)
+* TeX-comment-or-uncomment-paragraph: Commenting. (line 23)
+* TeX-comment-or-uncomment-region: Commenting. (line 15)
+* TeX-complete-symbol: Completion. (line 20)
+* TeX-doc: Documentation. (line 7)
+* TeX-electric-macro: Completion. (line 67)
+* TeX-fold-buffer: Folding. (line 44)
+* TeX-fold-clearout-buffer: Folding. (line 113)
+* TeX-fold-clearout-item: Folding. (line 125)
+* TeX-fold-clearout-paragraph: Folding. (line 121)
+* TeX-fold-clearout-region: Folding. (line 117)
+* TeX-fold-comment: Folding. (line 110)
+* TeX-fold-dwim: Folding. (line 132)
+* TeX-fold-env: Folding. (line 94)
+* TeX-fold-macro: Folding. (line 85)
+* TeX-fold-math: Folding. (line 101)
+* TeX-fold-mode: Folding. (line 32)
+* TeX-fold-paragraph: Folding. (line 81)
+* TeX-fold-region: Folding. (line 78)
+* TeX-font: Font Specifiers. (line 44)
+* TeX-header-end: Multifile. (line 29)
+* TeX-home-buffer: Control. (line 18)
+* TeX-insert-braces: Quotes. (line 86)
+* TeX-insert-dollar: Quotes. (line 62)
+* TeX-insert-macro: Completion. (line 30)
+* TeX-insert-quote: Quotes. (line 15)
+* TeX-interactive-mode: Processor Options. (line 29)
+* TeX-kill-job: Control. (line 10)
+* TeX-master-file-ask: Multifile. (line 70)
+* TeX-next-error: Debugging. (line 10)
+* TeX-normal-mode: Parsing Files. (line 44)
+* TeX-PDF-mode: Processor Options. (line 15)
+* TeX-pin-region: Starting a Command. (line 61)
+* TeX-recenter-output-buffer: Control. (line 14)
+* TeX-save-document: Multifile. (line 98)
+* TeX-source-correlate-mode <1>: I/O Correlation. (line 12)
+* TeX-source-correlate-mode: Processor Options. (line 36)
+* TeX-toggle-debug-bad-boxes: Debugging. (line 19)
+* TeX-toggle-debug-warnings: Debugging. (line 23)
+* TeX-view <1>: I/O Correlation. (line 20)
+* TeX-view: Starting Viewers. (line 12)
+
+\1f
+File: auctex.info, Node: Variable Index, Next: Concept Index, Prev: Function Index, Up: Indices
+
+Variable Index
+==============
+
+\0\b[index\0\b]
+* Menu:
+
+* ConTeXt-clean-intermediate-suffixes: Cleaning. (line 7)
+* ConTeXt-clean-output-suffixes: Cleaning. (line 7)
+* ConTeXt-engine: Processor Options. (line 83)
+* ConTeXt-Omega-engine: Processor Options. (line 83)
+* docTeX-clean-intermediate-suffixes: Cleaning. (line 7)
+* docTeX-clean-output-suffixes: Cleaning. (line 7)
+* font-latex-deactivated-keyword-classes: Fontification of macros.
+ (line 174)
+* font-latex-fontify-script: Fontification of math.
+ (line 21)
+* font-latex-fontify-sectioning: Fontification of macros.
+ (line 102)
+* font-latex-match-bold-command-keywords: Fontification of macros.
+ (line 143)
+* font-latex-match-bold-declaration-keywords: Fontification of macros.
+ (line 143)
+* font-latex-match-function-keywords: Fontification of macros.
+ (line 66)
+* font-latex-match-italic-command-keywords: Fontification of macros.
+ (line 143)
+* font-latex-match-italic-declaration-keywords: Fontification of macros.
+ (line 143)
+* font-latex-match-math-command-keywords <1>: Fontification of math.
+ (line 6)
+* font-latex-match-math-command-keywords: Fontification of macros.
+ (line 143)
+* font-latex-match-reference-keywords: Fontification of macros.
+ (line 66)
+* font-latex-match-sectioning-0-keywords: Fontification of macros.
+ (line 113)
+* font-latex-match-sectioning-1-keywords: Fontification of macros.
+ (line 113)
+* font-latex-match-sectioning-2-keywords: Fontification of macros.
+ (line 113)
+* font-latex-match-sectioning-3-keywords: Fontification of macros.
+ (line 113)
+* font-latex-match-sectioning-4-keywords: Fontification of macros.
+ (line 113)
+* font-latex-match-sectioning-5-keywords: Fontification of macros.
+ (line 113)
+* font-latex-match-slide-title-keywords: Fontification of macros.
+ (line 120)
+* font-latex-match-textual-keywords: Fontification of macros.
+ (line 66)
+* font-latex-match-type-command-keywords: Fontification of macros.
+ (line 143)
+* font-latex-match-type-declaration-keywords: Fontification of macros.
+ (line 143)
+* font-latex-match-variable-keywords: Fontification of macros.
+ (line 66)
+* font-latex-match-warning-keywords: Fontification of macros.
+ (line 66)
+* font-latex-math-environments: Fontification of math.
+ (line 6)
+* font-latex-quotes: Fontification of quotes.
+ (line 16)
+* font-latex-script-display: Fontification of math.
+ (line 29)
+* font-latex-sectioning-0-face: Fontification of macros.
+ (line 102)
+* font-latex-sectioning-1-face: Fontification of macros.
+ (line 102)
+* font-latex-sectioning-2-face: Fontification of macros.
+ (line 102)
+* font-latex-sectioning-3-face: Fontification of macros.
+ (line 102)
+* font-latex-sectioning-4-face: Fontification of macros.
+ (line 102)
+* font-latex-sectioning-5-face: Fontification of macros.
+ (line 102)
+* font-latex-slide-title-face: Fontification of macros.
+ (line 120)
+* font-latex-user-keyword-classes: Fontification of macros.
+ (line 204)
+* japanese-LaTeX-command-default: Japanese. (line 6)
+* japanese-LaTeX-default-style: Japanese. (line 6)
+* japanese-TeX-command-default: Japanese. (line 6)
+* LaTeX-amsmath-label: Equations. (line 16)
+* LaTeX-auto-label-regexp-list: Parsing Files. (line 100)
+* LaTeX-auto-minimal-regexp-list: Parsing Files. (line 97)
+* LaTeX-auto-regexp-list: Parsing Files. (line 103)
+* LaTeX-babel-hyphen: European. (line 150)
+* LaTeX-babel-hyphen-after-hyphen: European. (line 158)
+* LaTeX-babel-hyphen-language-alist: European. (line 137)
+* LaTeX-clean-intermediate-suffixes: Cleaning. (line 7)
+* LaTeX-clean-output-suffixes: Cleaning. (line 7)
+* LaTeX-command: Processor Options. (line 83)
+* LaTeX-csquotes-close-quote: Quotes. (line 44)
+* LaTeX-csquotes-open-quote: Quotes. (line 44)
+* LaTeX-csquotes-quote-after-quote: Quotes. (line 44)
+* LaTeX-default-environment: Environments. (line 35)
+* LaTeX-default-format: Tabular-like. (line 11)
+* LaTeX-default-position: Tabular-like. (line 14)
+* LaTeX-enable-toolbar: Processing. (line 11)
+* LaTeX-eqnarray-label: Equations. (line 13)
+* LaTeX-equation-label: Equations. (line 10)
+* LaTeX-figure-label: Floats. (line 25)
+* LaTeX-fill-break-at-separators: Filling. (line 104)
+* LaTeX-fill-break-before-code-comments: Filling. (line 114)
+* LaTeX-float: Floats. (line 14)
+* LaTeX-fold-env-spec-list: Folding. (line 189)
+* LaTeX-fold-macro-spec-list: Folding. (line 189)
+* LaTeX-fold-math-spec-list: Folding. (line 189)
+* LaTeX-font-list: Font Specifiers. (line 59)
+* LaTeX-indent-environment-check: Indenting. (line 51)
+* LaTeX-indent-environment-list: Indenting. (line 37)
+* LaTeX-indent-level: Indenting. (line 19)
+* LaTeX-item-indent: Indenting. (line 19)
+* LaTeX-item-regexp: Indenting. (line 19)
+* LaTeX-math-abbrev-prefix: Mathematics. (line 27)
+* LaTeX-math-list: Mathematics. (line 37)
+* LaTeX-math-menu-unicode: Mathematics. (line 55)
+* LaTeX-Omega-command: Processor Options. (line 83)
+* LaTeX-paragraph-commands: Filling. (line 55)
+* LaTeX-section-hook: Sectioning. (line 50)
+* LaTeX-section-label: Sectioning. (line 53)
+* LaTeX-syntactic-comments: Indenting. (line 63)
+* LaTeX-table-label: Floats. (line 25)
+* LaTeX-top-caption-list: Floats. (line 20)
+* LaTeX-verbatim-environments: Verbatim content. (line 10)
+* LaTeX-verbatim-macros-with-braces: Verbatim content. (line 10)
+* LaTeX-verbatim-macros-with-delims: Verbatim content. (line 10)
+* plain-TeX-auto-regexp-list: Parsing Files. (line 106)
+* plain-TeX-clean-intermediate-suffixes: Cleaning. (line 7)
+* plain-TeX-clean-output-suffixes: Cleaning. (line 7)
+* plain-TeX-enable-toolbar: Processing. (line 11)
+* TeX-auto-cleanup-hook: Hacking the Parser. (line 101)
+* TeX-auto-empty-regexp-list: Parsing Files. (line 94)
+* TeX-auto-full-regexp-list: Parsing Files. (line 109)
+* TeX-auto-global: Automatic Global. (line 26)
+* TeX-auto-local: Automatic Local. (line 23)
+* TeX-auto-parse-length: Parsing Files. (line 88)
+* TeX-auto-prepare-hook: Hacking the Parser. (line 98)
+* TeX-auto-private: Automatic Private. (line 20)
+* TeX-auto-regexp-list <1>: Hacking the Parser. (line 79)
+* TeX-auto-regexp-list: Parsing Files. (line 85)
+* TeX-auto-save: Parsing Files. (line 41)
+* TeX-auto-untabify: Parsing Files. (line 58)
+* TeX-brace-indent-level: Indenting. (line 103)
+* TeX-check-path: Selecting a Command. (line 56)
+* TeX-clean-confirm: Cleaning. (line 27)
+* TeX-close-quote: Quotes. (line 26)
+* TeX-command: Processor Options. (line 83)
+* TeX-command-default: Selecting a Command. (line 43)
+* TeX-command-list <1>: Selecting a Command. (line 14)
+* TeX-command-list: Starting a Command. (line 16)
+* TeX-default-macro: Completion. (line 52)
+* TeX-default-mode: Japanese. (line 6)
+* TeX-display-help: Debugging. (line 31)
+* TeX-DVI-via-PDFTeX: Processor Options. (line 22)
+* TeX-electric-escape: Completion. (line 59)
+* TeX-electric-sub-and-superscript: Mathematics. (line 69)
+* TeX-engine: Processor Options. (line 67)
+* TeX-engine-alist: Processor Options. (line 83)
+* TeX-engine-alist-builtin: Processor Options. (line 83)
+* TeX-expand-list: Selecting a Command. (line 14)
+* TeX-file-recurse: Automatic. (line 46)
+* TeX-fold-command-prefix: Folding. (line 137)
+* TeX-fold-env-spec-list: Folding. (line 180)
+* TeX-fold-force-fontify: Folding. (line 64)
+* TeX-fold-help-echo-max-length: Folding. (line 217)
+* TeX-fold-macro-spec-list: Folding. (line 147)
+* TeX-fold-math-spec-list: Folding. (line 187)
+* TeX-fold-preserve-comments: Folding. (line 72)
+* TeX-fold-type-list: Folding. (line 59)
+* TeX-fold-unspec-env-display-string: Folding. (line 200)
+* TeX-fold-unspec-macro-display-string: Folding. (line 196)
+* TeX-fold-unspec-use-name: Folding. (line 204)
+* TeX-font-list: Font Specifiers. (line 50)
+* TeX-header-end: Starting a Command. (line 32)
+* TeX-ignore-file: Automatic. (line 54)
+* TeX-insert-braces: Completion. (line 77)
+* TeX-insert-macro-default-style: Completion. (line 38)
+* TeX-install-font-lock: Font Locking. (line 14)
+* TeX-interactive-mode: Processor Options. (line 29)
+* TeX-language-bg-hook: European. (line 53)
+* TeX-language-cz-hook: European. (line 53)
+* TeX-language-de-hook: European. (line 53)
+* TeX-language-dk-hook: European. (line 53)
+* TeX-language-is-hook: European. (line 53)
+* TeX-language-it-hook: European. (line 53)
+* TeX-language-nl-hook: European. (line 53)
+* TeX-language-pl-hook: European. (line 53)
+* TeX-language-sk-hook: European. (line 53)
+* TeX-language-sv-hook: European. (line 53)
+* TeX-macro-global <1>: Automatic Global. (line 17)
+* TeX-macro-global: Customizing. (line 20)
+* TeX-macro-private: Automatic Private. (line 13)
+* TeX-master <1>: Multifile. (line 42)
+* TeX-master: Starting a Command. (line 16)
+* TeX-math-close-double-dollar: Quotes. (line 72)
+* TeX-newline-function: Indenting. (line 29)
+* TeX-Omega-command: Processor Options. (line 83)
+* TeX-one-master: Multifile. (line 57)
+* TeX-open-quote: Quotes. (line 22)
+* TeX-outline-extra: Outline. (line 14)
+* TeX-output-view-style: Starting Viewers. (line 100)
+* TeX-parse-self: Parsing Files. (line 38)
+* TeX-PDF-mode: Processor Options. (line 15)
+* TeX-quote-after-quote: Quotes. (line 30)
+* TeX-quote-language-alist: European. (line 124)
+* TeX-region: Starting a Command. (line 32)
+* TeX-save-query: Multifile. (line 102)
+* TeX-show-compilation: Processor Options. (line 110)
+* TeX-source-correlate-method: Processor Options. (line 47)
+* TeX-source-correlate-mode: Processor Options. (line 36)
+* TeX-source-correlate-start-server: I/O Correlation. (line 26)
+* TeX-style-global: Automatic Global. (line 20)
+* TeX-style-local: Automatic Local. (line 17)
+* TeX-style-path: Automatic. (line 39)
+* TeX-style-private: Automatic Private. (line 29)
+* TeX-trailer-start: Starting a Command. (line 32)
+* TeX-view-predicate-list: Starting Viewers. (line 58)
+* TeX-view-program-list: Starting Viewers. (line 67)
+* TeX-view-program-selection: Starting Viewers. (line 38)
+* TeX-view-style: Starting Viewers. (line 109)
+* Texinfo-clean-intermediate-suffixes: Cleaning. (line 7)
+* Texinfo-clean-output-suffixes: Cleaning. (line 7)
+
--- /dev/null
+;;; bib-cite.el --- test
+;; bib-cite.el - Display \cite, \ref or \label / Extract refs from BiBTeX file.
+
+;; Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2003, 2004, 2005
+;; Free Software Foundation
+
+;; Author: Peter S. Galbraith <psg@debian.org>
+;; Created: 06 July 1994
+;; Version: 3.28 (Feb 23 2005)
+;; Keywords: bibtex, cite, auctex, emacs, xemacs
+
+;;; This file is not part of GNU Emacs.
+
+;; This package 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, or (at your option)
+;; any later version.
+
+;; This package 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; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;; LCD Archive Entry:
+;; bib-cite|Peter Galbraith|GalbraithP@dfo-mpo.gc.ca|
+;; Display \cite, \ref or \label / Extract refs from BiBTeX file.|
+;; 21-May-1997|3.01|~/misc/bib-cite.el.gz|
+
+;; ----------------------------------------------------------------------------
+;;; Commentary:
+;; This minor-mode is used in various TeX modes to display or edit references
+;; associated with \cite commands, or matching \ref and \label commands.
+
+;; New versions of this package (if they exist) may be found at:
+;; http://people.debian.org/~psg/elisp/bib-cite.el
+;; and in AUCTeX's CVS archive at
+;; http://savannah.gnu.org/cgi-bin/viewcvs/auctex/auctex/
+
+;; Operating Systems:
+;; Works in unix, DOS and OS/2. Developped under Linux.
+
+;; AUCTeX users:
+;; AUCTeX is a super-charged LaTeX mode for emacs. Get it at:
+;;
+;; ftp://ftp.gnu.org/pub/gnu/auctex/
+;;
+;; WWW users may want to check out the AUCTeX page at
+;; http://www.gnu.org/software/auctex/
+;;
+;; bib-cite.el is included in the AUCTeX distribution. Therefore, if
+;; you use AUCTeX and didn't obtained bib-cite.el separately, make sure
+;; that you are actually using the more recent version.
+
+;; RefTeX users:
+;; RefTeX is a package with similar functions to bib-cite.
+;; http://www.astro.uva.nl/~dominik/Tools/reftex/
+;; RefTeX is bundled and preinstalled with Emacs since version 20.2.
+;; It was also bundled with XEmacs 19.16--20.x.
+;;
+;; I suggest that you use RefTeX to help you type-in text as it's functions
+;; are better suited to this task than bib-cite, and use bib-cite's features
+;; when you proof-read the text.
+;; If you wish bib-cite to use RefTeX's reftex-view-crossref command to
+;; display and find \label's and \cite bibliography entries, set the variable
+;; bib-cite-use-reftex-view-crossref to t.
+
+;; MS-DOS users:
+;; Multifile documents are supported by bib-cite by using etags (TAGS files)
+;; which contains a bug for MSDOS (at least for emacs 19.27 it does).
+;; Get the file
+;; http://people.debian.org/~psg/elisp/bib-cite.etags-bug-report
+;; to see what patches to make to etags.c to fix it.
+
+;; Description:
+;; ~~~~~~~~~~~
+;; This package is used in various TeX modes to display or edit references
+;; associated with \cite commands, or matching \eqref, \ref and \label
+;; commands (so I actually overstep BiBTeX bounds here...).
+;;
+;; These are the functions:
+;;
+;; bib-display bib-display-mouse
+;; - Display citation, \ref or \label under point
+;; bib-find bib-find-mouse
+;; - Edit citation, \ref or \label under point
+;; bib-find-next - Find next occurrence of a \ref or \eqref
+;; bib-make-bibliography - Make BiBTeX file containing only cite keys used.
+;; bib-apropos - Search BiBTeX source files for keywords.
+;; bib-etags - Refreshes (or builds) the TAGS files for
+;; multi-file documents.
+;; bib-create-auto-file - Used in bibtex-mode to create cite key
+;; completion .el file for AUCTeX.
+;; bib-highlight-mouse - Highlight \cite, \ref and \label commands in
+;; green when the mouse is over them.
+
+;; About Cite Commands and related functions:
+;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;; Various flavors of \cite commands are allowed (as long as they contain
+;; the word `cite') and they may optionally have bracketed [] options.
+;; Bibtex Cross-references are displayed, and @string abbreviations are
+;; substituted or included.
+;;
+;; The \cite text is found (by emacs) in the bibtex source files listed in the
+;; \bibliography command. The BiBTeX files can be located in a search path
+;; defined by an environment variable (typically BIBINPUTS, but you can change
+;; this).
+;;
+;; All citations used in a buffer can also be listed in a new bibtex buffer by
+;; using bib-make-bibliography. This is useful to make a bibtex file for a
+;; document from a large bibtex database. In this case, cross-references are
+;; included, as well as the @string commands used. The @string abbreviations
+;; are not substituted.
+;;
+;; The bibtex files can also be searched for entries matching a regular
+;; expression using bib-apropos.
+
+;; Usage instructions:
+;; ~~~~~~~~~~~~~~~~~~
+;; bib-display Bound to Mouse-3 when specially highlighted.
+;; In Hyperbole, bound to the Assist key.
+;; Bound to `\C-c b d'
+;;
+;; bib-display will show the bibtex entry or the corresponding label or
+;; ref commands from anywhere within a document.
+;; With cursor on the \cite command itslef
+;; -> display all citations of the cite command from the BiBTeX source.
+;; With cursor on a particular cite key within the brackets
+;; -> display that citation's text from the BiBTeX source file(s).
+;;
+;; Example:
+;;
+;; \cite{Wadhams81,Bourke.et.al87,SchneiderBudeus94}
+;; ^Cursor -> Display-all-citations ^Cursor -> Display-this-citation
+;;
+;; With cursor on a \label command
+;; -> Display first matching \ref command in the document
+;; With cursor on a \ref command
+;; -> Display environment associated with the matching \label command.
+;;
+;; Finding a ref or label within a multi-file document requires a TAGS file,
+;; which is automatically generated for you. This enables you to then use
+;; any tags related emacs features.
+;;
+;; bib-find Bound to Mouse-2 when specially highlighted.
+;; In Hyperbole, bound to the Action key.
+;; Bound to `\C-c b f'
+;;
+;; bib-find will select the buffer and move point to the BiBTeX source file
+;; at the proper citation for a cite command, or move point to anywhere
+;; within a document for a label or ref command. The ref chosen is the
+;; first occurrance within a document (using a TAGS file). If point is
+;; moved within the same buffer, mark is set before the move and a message
+;; stating so is given. If point is moved to another file, this is done in
+;; a new window using tag functions.
+;;
+;; The next occurrence of a \ref or \eqref command may be found by invoking
+;; bib-find-next, usually bound to `C-c b n'.
+;;
+;; For multi-file documents, you must be using AUCTeX (so that bib-cite can
+;; find the master file) and all \input and \include commands must be first
+;; on a line (not preceeded by any non-white text).
+;;
+;; bib-make-bibliography: Bound to `\C-c b m'
+;;
+;; Extract citations used in the current document from the \bibliography{}
+;; file(s). Put them into a new suitably-named buffer. In a AUCTeX
+;; multi-file document, the .aux files are used to find the cite keys (for
+;; speed). You will be warned if these are out of date.
+;;
+;; This buffer is not saved to a file. It is your job to save it to whatever
+;; name you wish. Note that AUCTeX has a unique name space for LaTeX and
+;; BiBTeX files, so you should *not* name the bib file associated with
+;; example.tex as example.bib! Rather, name it something like
+;; example-bib.bib.
+;;
+;; bib-apropos: Bound to `\C-c b a'
+;;
+;; Searches the \bibliography{} file(s) for entries containing a keyword and
+;; display them in the *help* buffer. You can trim down your search by using
+;; bib-apropos in the *Help* buffer after the first invocation. the current
+;; buffer is also searched for keyword matches if it is in bibtex-mode.
+;;
+;; It doesn't display cross-references nor does it substitute or display
+;; @string commands used. It could easily be added, but it's faster this
+;; way. Drop me a line if this would be a useful addition.
+;;
+;; If you find yourself entering a cite command and have forgotten which key
+;; you want, but have entered a few initial characters as in `\cite{Gal',
+;; then invoke bib-apropos. It will take that string (in this case `Gal') as
+;; an initial response to the apropos prompt. You are free to edit it, or
+;; simply press carriage return.
+;;
+;; bib-etags: Bound to `\C-c b e'
+;;
+;; Creates a TAGS file for AUCTeX's multi-file document (or refreshes it).
+;; This is used by bib-find when editing multi-file documents. The TAGS file
+;; is created automatically, but it isn't refreshed automatically. So if
+;; bib-find can't find something, try running bib-etags again.
+;;
+;; bib-create-auto-file:
+;;
+;; Use this when editing a BiBTeX buffer to generate the AUCTeX .el file
+;; which tell emacs about all its cite keys. I've added this command to
+;; bibtex-mode pull-down menu.
+;;
+;; bib-highlight-mouse: Bound to `\C-c b h'
+;;
+;; Highlights \cite, \ref and \label commands in green when the mouse is over
+;; them. By default, a call to this function is added to LaTeX-mode-hook
+;; (via bib-cite-initialize) if you set bib-highlight-mouse-t to true. But
+;; you may want to run this command to refresh the highlighting for newly
+;; edited text.
+
+;; Installation instructions:
+;; ~~~~~~~~~~~~~~~~~~~~~~~~~
+;; bib-cite is a minor-mode, so you could invoke it in a LaTeX-mode hook.
+;; e.g. If you are using AUCTeX (http://www.gnu.org/software/auctex/), you
+;; could use:
+;;
+;; (autoload 'turn-on-bib-cite "bib-cite")
+;; (add-hook 'LaTeX-mode-hook 'turn-on-bib-cite)
+;;
+;; If you are using Emacs' regular LaTeX-mode, use instead:
+;;
+;; (autoload 'turn-on-bib-cite "bib-cite")
+;; (add-hook 'latex-mode-hook 'turn-on-bib-cite)
+;;
+;; bib-cite can be used with AUCTeX, or stand-alone. If used with AUCTeX on a
+;; multi-file document (and AUCTeX's parsing is used), then all \bibliography
+;; commands in the document will be found and used.
+;; ---
+;; The following variable can be unset (like shown) to tell bib-cite to
+;; not give advice messages about which commands to use to find the next
+;; occurrence of a search:
+;;
+;; (setq bib-novice nil)
+;; ---
+;; If you wish bib-cite to use RefTeX's reftex-view-crossref command to
+;; display and find \label's and \cite bibliography entries, set the variable
+;; bib-cite-use-reftex-view-crossref to t:
+;;
+;; (setq bib-cite-use-reftex-view-crossref t)
+;; ---
+;; The following variable determines whether we will attempt to highlight
+;; citation, ref and label commands in green when they are under the
+;; mouse. When highlighted, the mouse keys work to call bib-display
+;; (bound to [mouse-3]) and bib-find (bound to [mouse-2]). If you use a
+;; mode other than LaTeX-mode, you'll want to call bib-highlight-mouse with
+;; a hook (See how we do this at the end of this file with the add-hook
+;; command).
+;;
+;; (setq bib-highlight-mouse-t nil)
+;; ---
+;; The variable bib-switch-to-buffer-function sets the function used to
+;; select buffers (if they differ from the original) in bib-cite commands
+;; bib-make-bibliography, bib-display, bib-find
+;; You may use `switch-to-buffer' `switch-to-buffer-other-window' or
+;; `switch-to-buffer-other-frame'.
+;; ---
+;; If you use DOS or OS/2, you may have to set the following variable:
+;;
+;; (setq bib-dos-or-os2-variable t)
+;;
+;; if bib-cite.el fails to determine that you are using DOS or OS/2.
+;; Try `C-h v bib-dos-or-os2-variable' to see if it needs to be set manually.
+;; ---
+;; bib-cite needs to call the etags program with its output file option
+;; and also with the append option (usually -a).
+;; I figured that DOS and OS/2 would use "etags /o=" instead of the unix
+;; variant "etags -o ", but users have reported differently. So while the
+;; unix notation is used here, you can reset it if you need to like so:
+;;
+;; (setq bib-etags-command "etags /r='/.*\\\(eq\|page\|[fvF]\)ref.*/' /o=")
+;; (setq bib-etags-append-command
+;; "etags /r='/.*\\\(eq\|page\|[fvF]\)ref.*/' /a /o=")
+;; ---
+;; For multi-file documents, a TAGS file is generated by etags.
+;; By default, its name is TAGS. You can change this like so:
+;;
+;; (setq bib-etags-filename "TAGSLaTeX")
+;; ---
+;; If your environment variable to find BiBTeX files is not BIBINPUTS, then
+;; reset it with the following variable (here, assuming it's TEXBIB instead):
+;;
+;; (setq bib-bibtex-env-variable "TEXBIB")
+;;
+;; Note that any directory ending in a double slash will cause bib-cite to
+;; search recursively through subdirectories for your .bib files. This can
+;; be slow, so use this judiciously.
+;; e.g. setenv BIBINPUTS .:/home/psg/LaTeX/bibinputs//
+;; -> all directories below /home/psg/LaTeX/bibinputs/ will be
+;; searched.
+;;
+;; If your bibtex setup works but Emacs can't see the environment variable
+;; correctly (Check `C-h v process-environment'), then customize the
+;; variable `bib-cite-inputs' (e.g. `M-x customize-variable bib-cite-imputs')
+;;
+;; ---
+;; If you do not wish bib-display to substitute @string abbreviations,
+;; then set the following variable like so:
+;;
+;; (setq bib-substitute-string-in-display nil)
+;; ---
+;; Warnings are given when @string abbreviations are not defined in your bib
+;; files. The exception is for months, usually defined in style files. If you
+;; use other definitions in styles file (e.g. journals), then you may add them
+;; to the `bib-substitute-string-in-display' list variable.
+
+;; If you find circumstances in which this package fails, please let me know.
+
+;; Things for me to do in later versions:
+;; - treat @Strings correctly, not just in isolation.
+;; - use `kpsewhich -expand-path='$BIBINPUTS'` instead of BIBINPUTS.
+;; - jmv@di.uminho.pt (Jose Manuel Valenca) wants:
+;; - prompt for \cite as well as \label and \ref
+;; (and use AUCTeX's completion list)
+;; - implement string concatenation, with #[ \t\n]*STRING_NAME
+;; - Create new command to substitute @string text in any bibtex buffer.
+;; ----------------------------------------------------------------------------
+;;; Change log:
+;; V3.28 Feb 23 2005 - Ralf Angeli
+;; - Some doc fixes in the commentary section.
+;; V3.27 Feb 09 2005 - PSG
+;; - Patch from Peter Heslin. TeX-master can now have symbol values.
+;; V3.26 Aug 06 2004 - Reiner Steib
+;; - Changed URL of AUCTeX. Use "AUCTeX", not "auc-tex" (skipped Change log).
+;; V3.25 Feb 15 2004 - PSG
+;; - Check existence of font-lock-unset-defaults; no longer defined in CVS
+;; Emacs. Thanks to Adrian Lanz for reporting the problem.
+;; V3.24 Oct 28 2003 - PSG
+;; - bib-cite-file-directory-p: new function to replace ff-paths code.
+;; V3.23 Oct 09 2003 - PSG
+;; - some checkdoc cleanup; not yet complete.
+;; V3.22 Sep 17 2003 - PSG
+;; - bib-cite-aux-inputs: new defcustom.
+;; - minor cleanup for `match-string'.
+;; V3.21 Sep 08 2003 - PSG
+;; - Ripping out off-topic imenu code.
+;; V3.20 Aug 14 2003 - PSG
+;; - psg-checkfor-file-list: Allow for relative directoties as entries in
+;; BIBINPUTS.
+;; - bib-cite-inputs: new defcustom equivalent to BIBINPUTS.
+;; - bib-label-help-echo-format: fixed defcustom.
+;; - psg-list-env: code cleanup.
+;; - trailing whitespace cleanup.
+;; V3.19 Apr 06 2003 - PSG
+;; Remove code that ran when defcustom not present.
+;; Remove hilit19 obsolete code.
+;; V3.18 Mar 27 2003 - Bruce Ravel <ravel@phys.washington.edu>
+;; Play well with the varioref and fancyref latex styles (vref, fref, Fref).
+;; V3.17 May 01 2001 - (RCS V1.38)
+;; - XEmacs has imenu after all.
+;; V3.16 Dec 20 99 - (RCS V1.37)
+;; - Added customize support.
+;; V3.15 Dec 20 99 - (RCS V1.36)
+;; - Removed stupid debugging code that I had left in.
+;; V3.14 Dec 20 99 -
+;; - New variable bib-ref-regexp for \ref regexp to match \label constructs
+;; and added \pageref. (RCS V1.34)
+;; - Edited bib-etags-command snd bib-etags-append-command to match.
+;; V3.13 Dec 20 99 - (RCS V1.32)
+;; - License changed to GPL.
+;; - Kai Engelhardt <ke@socs.uts.edu.au> bib-master-file takes .ltx extension
+;; - imenu--create-LaTeX-index-for-document and bib-document-TeX-files
+;; edited to accept .ltx extension.
+;; - Michael Steiner <steiner@cs.uni-sb.de> added journals to @string
+;; abbrevs and contributed `member-cis' to complaces @strings in a
+;; case-insensitive manner.
+;; V3.12 Dec 10 98 - Bruce Ravel <bruce.ravel@nist.gov> (RCS V1.30)
+;; Fixed bib-label-help.
+;; V3.11 Oct 06 98 - PSG (RCS V1.29)
+;; Quote \ character fot replace-match;
+;; Applies to: @String{JGR = "J. Geophys.\ Res."}
+;; V3.10 Sep 21 98 - Matt Hodges <mph1002@cam.ac.uk> (RCS V1.28)
+;; Removed instance of expand-file-name due to new behaviour in Emacs-20.3.
+;; V3.09 Sep 09 98 - PSG (RCS V1.27)
+;; Added support for \eqref; Added bib-find-next.
+;; V3.08 Aug 20 98 - PSG (RCS V1.26)
+;; Fixed imenu bug (prev-pos (point-max))
+;; V3.07 Nov 20 97 - Christoph Wedler <wedler@fmi.uni-passau.de> (RCS V1.24)
+;; bib-ext-list variable made permanent-local, otherwise VC registration
+;; would use two extents for each reference etc. This was not a visible bug.
+;; V3.06 Nov 12 97 - PSG (RCS V1.23)
+;; Support use of reftex's reftex-view-crossref command.
+;; V3.05 Nov 12 97 - Vladimir Alexiev <vladimir@cs.ualberta.ca> (RCS V1.22)
+;; regexp-quote the bibliography keys so a key like galbraith+kelley97 works
+;; V3.04 Aug 25 97 - Christoph Wedler <wedler@fmi.uni-passau.de> (RCS V1.20)
+;; (bib-highlight-mouse): Would bug out on detached extents,
+;; e.g. when killing a whole citation.
+;; V3.03 Jul 16 97 - Christoph Wedler <wedler@fmi.uni-passau.de> (RCS V1.18)
+;; turn-on-bib-cite back to non-interactive.
+;; V3.02 Jul 11 97 - Christoph Wedler <wedler@fmi.uni-passau.de> (RCS V1.17)
+;; * auctex/bib-cite.el (turn-on-bib-cite): Make interactive.
+;; Argument to `bib-cite-minor-mode' is 1.
+;; (bib-label-help-echo-format): New variable.
+;; (bib-label-help-echo): New function.
+;; (bib-label-help): Addition argument format.
+;; (bib-highlight-mouse): Set extent property `help-echo' for XEmacs.
+;; V3.01 May 22 97 - Diego Calvanese <calvanes@dis.uniroma1.it> (RCS V1.16)
+;; bib-make-bibliography handles commas separated citations in aux files.
+;; V3.00 May 16 97 - Peter Galbraith (RCS V1.15)
+;; bib-cite is now a minor mode.
+;; V2.32 Apr 30 97 - Anders Stenman <stenman@isy.liu.se> (RCS V1.14)
+;; - Support for balloon-help.
+;; V2.31 Mar 20 97 - Christoph Wedler <wedler@fmi.uni-passau.de> (RCS V1.12)
+;; - Better fontification of help buffer as bibtex or latex for XEmacs.
+;; V2.30 Feb 10 97 - Peter Galbraith (RCS V1.11)
+;; - Better fontification of help buffer as bibtex or latex.
+;; V2.29 Jan 29 97 - Peter Galbraith (RCS V1.10)
+;; - imenu looks for `\label{stuff}' instead of `\label'
+;; V2.28 Jan 22 97 - Peter Galbraith (RCS V1.9)
+;; - Bug in bib-create-auto-file.
+;; V2.27 Dec 31 96 - Peter Galbraith (RCS V1.8)
+;; - allow spaces between cite keys.
+;; - Vladimir Alexiev <vladimir@cs.ualberta.ca>
+;; Allow () delimiters as well as {}.
+;; Better check on bibtex-menu
+;; Erase *bibtex-bibliography* buffer.
+;; V2.26 Sep 24 96 - Peter Galbraith (RCS V1.7)
+;; imenu bug fix.
+;; V2.25 Sep 23 96 - Anders Stenman <stenman@isy.liu.se> (RCS V1.6)
+;; XEmacs bib-cite-fontify-help-as-latex bug fix.
+;; V2.24 Aug 19 96 - Peter Galbraith (RCS V1.3)
+;; XEmacs bug fix, minor defvars - Vladimir Alexiev <vladimir@cs.ualberta.ca>
+;; V2.23 Aug 13 96 - Peter Galbraith (RCS V1.2)
+;; XEmacs - Add bib-cite entries to bibtex-mode popup menu.
+;; V2.22 July 22 96 - Peter Galbraith (RCS V1.1)
+;; local-map has `m' for bib-make-bibliography instead of `b'
+;; set-buffer-menubar in XEmacs so that menu disappears after use.
+;; V2.21 July 12 96 - Peter Galbraith
+;; Define `\C-c b' keymap for both plain tex and auctex, in XEmacs and emacs.
+;; Separate menu-bar menu in gnu emacs.
+;; font-lock support for bib-display'ed citations (bibtex fontification)
+;; and for matching \ref{} and \labels (latex fontification).
+;; buffer-substring-no-properties in bib-apropos
+;; (bug in completing-read with mouse faces)
+;; imenu-sort-function made local and nil.
+;; imenu--LaTeX-name-and-position fixed for section name containing "\"
+;; Various other things... (whitespace within label strings, etc...)
+;; V2.20 June 25 96 - Peter Galbraith
+;; imenu fixed for emacs-19.31.
+;; V2.19 May 13 96
+;; PSG:
+;; - @string substitution fixed; bib-edit-citation fixed when buffer exists;
+;; Christoph Wedler <wedler@fmi.uni-passau.de>:
+;; - Added bib-switch-to-buffer-function
+;; - (setq tags-always-exact nil) for xemacs
+;; - removed eval-after-load foe xemacs
+;; V2.18 May 06 96 - PSG
+;; New eval-after-load from Fred Devernay <Frederic.Devernay@sophia.inria.fr>
+;; V2.17 May 03 96 - PSG
+;; Fixed bug introduced in V2.16, reported by Dennis Dams <wsindd@win.tue.nl>
+;; V2.16 May 02 96 - Vladimir Alexiev <vladimir@cs.ualberta.ca>
+;; - somewhat compatible with Hyperbole by binding bib-find and bib-display to
+;; the Action and Assist keys inside the bib-highlight-mouse-keymap.
+;; - makes more liberal provisions for users with a tty.
+;; V2.15 Apr 09 96 -
+;; - fix "Buffer read-only" error caused by mouse-face text properties
+;; patch by Piet van Oostrum <piet@cs.ruu.nl>
+;; - Use tmm non-X menu, patch by Vladimir Alexiev <vladimir@cs.ualberta.ca>
+;; - input{file.txt} would not work.
+;; bug report: David Kastrup <dak@pool.informatik.rwth-aachen.de>
+;; V2.14 Feb 26 96 - PSG - define eval-after-load for xemacs
+;; Frederic Devernay's <Frederic.Devernay@sophia.inria.fr> suggestion.
+;; V2.13 Feb 08 96 - Peter Galbraith - Fixed recursive use of bib-apropos.
+;; V2.12 Jan 19 96 - Peter Galbraith
+;; emacs-19.30's [down-mouse-1] is defined (rather than [mouse-1]), so
+;; bib-highlight-mouse-keymap now has [down-mouse-1] defined to override it.
+;; V2.11 Nov 21 95 - Peter Galbraith
+;; - Fixed bib-create-auto-file when bib file loaded before LaTeX file.
+;; - Michal Mnuk's better imenu labels menu <Michal.Mnuk@risc.uni-linz.ac.at>
+;; - [mouse-1] and [mouse-2] key defs for highlighted regions.
+;; - Improve X menus.
+;; - Skip over style files in bib-document-TeX-files.
+;; - Add menus and mouse highlighting for xemacs
+;; Anders Stenman <stenman@isy.liu.se> Dima Barsky <D.Barsky@ee.surrey.ac.uk>
+;; - Check bib-use-imenu before calling LaTeX-hook-setq-imenu.
+;; From: Kurt Hornik <hornik@ci.tuwien.ac.at>
+;; - Remove mouse face properties before inserting new ones.
+;; From: Peter Whaite <peta@Whippet.McRCIM.McGill.EDU>
+;; V2.10 Aug 17 95 - Peter Galbraith - fatal bugs in bib-make-bibliography.
+;; V2.09 Jul 19 95 - Peter Galbraith
+;; - Had introduced bug in search-directory-tree. synced with ff-paths.el.
+;; V2.08 Jul 13 95 - Peter Galbraith
+;; Fred Douglis <douglis@research.att.com> says etags should be required
+;; V2.07 Jul 04 95 - Peter Galbraith
+;; - Minor changes with filename manipulations (careful with DOS...)
+;; - Problem if auc-tex not already loaded -> LaTeX-mode-map
+;; V2.06 Jul 03 95 - Peter Galbraith - Added recursion through BIBINPUTS path.
+;; V2.05 Jun 22 95 - Peter Galbraith Bug: Hanno Wirth <wirth@jake.igd.fhg.de>
+;; bib-get-citations would truncate @String{KEY ="J. {\"u} Res."}
+;; V2.04 Jun 19 95 - Peter Galbraith -
+;; - use bibtex-mode syntax table in bib buffer, else bib-apropos truncates
+;; an article if it contains an unbalanced closing parenthesis.
+;; - bib-highlight-mouse would mark a buffer modified
+;; V2.03 May 16 95 - Peter Galbraith -
+;; auc-tec menu compatible with old "AUC TeX" pull-down name
+;; V2.02 May 10 95 - Peter Galbraith -
+;; bug report by Bodo Huckestein <bh@thp.Uni-Koeln.DE> (getenv env) under DOS
+;; V2.01 Mar 27 95 - Peter Galbraith - No imenu on xemacs; check BIBINPUT also
+;; V2.00 Mar 27 95 - Peter Galbraith
+;; - bib-find and bib-display replace bib-edit-citation and
+;; bib-display-citation
+;; - bib-apropos now take initial guess from start of cite argument at point.
+;; - Multi-file support for bib-make-bibliography using .aux files.
+;; - \label and \ref functionality for bib-find and bib-display:
+;; - \label may appear within an \begin\end or to label a (sub-)section.
+;; - Cursor on \label, goto first \ref, set next i-search to pattern.
+;; - Cursor on \ref, goto \label or display it's environment or section.
+;; - Works on hidden code!
+;; V1.08 Jan 16 95 - Peter Galbraith
+;; bib-apropos can be used within *Help* buffer to trim a search.
+;; V1.07 Dec 13 94 - Peter Galbraith
+;; - Fixed: multi-line @string commands in non-inserted display.
+;; - Fixed: quoted \ character in @string commands.
+;; - BiBTeX comments should not affect bib-cite
+;; - Fixed bib-apropos (from Christoph Wedler <wedler@fmi.uni-passau.de>)
+;; Faster now, and avoids infinite loops.
+;; - Added bib-edit-citation to edit a bibtex files about current citation.
+;; - Allow space and newlines between citations: \cite{ entry1, entry2}
+;; - Added bib-substitute-string-in-display, bib-string-ignored-warning
+;; and bib-string-regexp.
+;; - bib-display-citation (from Markus Stricker <stricki@vision.ee.ethz.ch>)
+;; Could not find entry with trailing spaces
+;; V1.06 Nov 20 94 - Peter Galbraith
+;; - Fixed bib-apropos for:
+;; hilighting without invoking bibtex mode.
+;; display message when no matches found.
+;; would search only last bib file listed (forgot to `goto-char 1')
+;; - Fixed bib-make-bibliography that would only see first citation in a
+;; multi-key \cite command (found by Michail Rozman <roz@physik.uni-ulm.de>
+;; - bib-make-bibliography didn't see \cite[A-Z]* commands.
+;; Found by Richard Stanton <stanton@haas.berkeley.edu>
+;; **************************************************
+;; - * Completely rewritten code to support crossrefs *
+;; **************************************************
+;; - autodetection of OS/2 and DOS for bib-dos-or-os2-variable
+;; - Created bib-display-citation-mouse
+;; - bib-apropos works in bibtex-mode on the current buffer
+;; - bibtex entry may have comma on next line (!)
+;; @ARTICLE{Kiryati-91
+;; , YEAR = {1991 }
+;; ...
+;; V1.05 Nov 02 94 - Peter Galbraith
+;; - bug fix by rossmann@TI.Uni-Trier.DE (Jan Rossmann)
+;; for (boundp 'TeX-check-path) instead of fboundp. Thanks!
+;; - Translate environment variable set by bib-bibtex-env-variable.
+;; (suggested by Richard Stanton <stanton@haas.berkeley.edu>)
+;; - add bib-dos-or-os2-variable to set environment variable path separator
+;; - Add key-defs for any tex-mode and auc-tex menu-bar entries.
+;; [in auc-tec TeX-mode-map is common to both TeX and LaTeX at startup
+;; (but TeX-mode-map is only copied to LaTeX-mode-map at initilisation)
+;; in plain emacs, use tex-mode-map for both TeX and LaTeX.]
+;; - Add key def for bibtex-mode to create auc-tex's parsing file.
+;; - Fix bugs found by <thompson@loon.econ.wisc.edu>
+;; - fix bib-get-citation for options
+;; - fix bib-get-citation for commas preceeded citation command
+;; - better regexp for citations and their keys.
+;; - Added @string support for any entry (not just journal entries).
+;; (I had to disallow numbers in @string keys because of years.
+;; Is that ok?)
+;; - added bib-apropos
+;; V1.04 Oct 24 94 - Peter Galbraith
+;; - Don't require dired-aux, rather define the function we need from it.
+;; - Regexp-quote the re-search for keys.
+;; - Name the bib-make-bibliography buffer diffently than LaTeX buffer
+;; because auc-tex's parsing gets confused if same name base is used.
+;; V1.03 Oct 24 94 - Peter Galbraith - require dired-aux for dired-split
+;; V1.02 Oct 19 94 - Peter Galbraith
+;; - If using auc-tex with parsing activated, use auc-tex's functions
+;; to find all \bibliography files in a multi-file document.
+;; - Find bib files in pwd, BIBINPUTS environment variable path and
+;; TeX-check-path elisp variable path.
+;; - Have the parser ignore \bibliography that is on a commented `%' line.
+;; (patched by Karl Eichwalder <karl@pertron.central.de>)
+;; - Allow for spaces between entry type and key in bib files:
+;; (e.g @Article{ key} )
+;; (suggested by Nathan E. Doss <doss@ERC.MsState.Edu>)
+;; - Allows options in \cite command (e.g. agu++ package \cite[e.g.][]{key})
+;; - Includes @String{} abbreviations for `journal' entries
+;; V1.01 July 07 94 - Peter Galbraith - \bibliography command may have list of
+;; BibTeX files. All must be readable.
+;; V1.00 July 06 94 - Peter Galbraith - Created
+;; ----------------------------------------------------------------------------
+;;; Code:
+
+(eval-when-compile (require 'cl))
+
+(defgroup bib-cite nil
+ "bib-cite, LaTeX minor-mode to display \\cite, \\ref and \\label commands."
+ :group 'tex)
+
+(defcustom bib-cite-use-reftex-view-crossref nil
+ "*Non-nil means, RefTeX will be used to find cross references.
+When this variable is non-nil, both `bib-find' and `bib-display' will
+call a function in RefTeX to find or display the cross reference of a
+\\ref or \\cite macro at point."
+ :group 'bib-cite
+ :type 'boolean)
+
+(defcustom bib-novice t
+ "*Give advice to novice users about what commands to use next."
+ :group 'bib-cite
+ :type 'boolean)
+
+(defcustom bib-switch-to-buffer-function 'switch-to-buffer
+ "*Function used to select buffers if they differ from the original.
+You may use `switch-to-buffer' `switch-to-buffer-other-window' or
+`switch-to-buffer-other-frame'."
+ :group 'bib-cite
+ :type '(choice (function-item switch-to-buffer)
+ (function-item switch-to-buffer-other-window)
+ (function-item switch-to-buffer-other-frame)))
+
+(defcustom bib-highlight-mouse-t t
+ "*Call bib-highlight-mouse from `LaTeX-mode-hook' to add green highlight."
+ :group 'bib-cite
+ :type 'boolean)
+
+(defcustom bib-label-help-echo-format "button2 finds %s, button3 displays %s"
+ "*Format string for info if the mouse is over LaTeX commands.
+If nil, do not display info."
+ :group 'bib-cite
+ :type '(radio (const :tag "Don't display info" nil)
+ string))
+
+(defcustom bib-bibtex-env-variable "BIBINPUTS"
+ "*Environment variable setting the path where BiBTeX input files are found.
+BiBTeX 0.99b manual says this should be TEXBIB.
+Another version says it should BSTINPUTS. I don't know anymore!
+
+The colon character (:) is the default path separator in unix, but you may
+use semi-colon (;) for DOS or OS/2 if you set bib-dos-or-os2-variable to t."
+ :group 'bib-cite
+ :type 'string)
+
+(defcustom bib-cite-inputs nil
+ "*List of directories to search for .bib files.
+This is in addition to those listed in the environment variable specified by
+`bib-bibtex-env-variable'."
+ :group 'bib-cite
+ :type '(repeat (file :format "%v")))
+
+(defcustom bib-cite-aux-inputs nil
+ "*List of directories to search for .aux files.
+MiKTeX has the LaTeX option -aux-directory to store .aux files in an alternate
+directory. You may set this variable to let bib-cite find these .aux files."
+ :group 'bib-cite
+ :type '(repeat (file :format "%v")))
+
+(defcustom bib-dos-or-os2-variable (or (equal 'emx system-type)
+ (equal 'ms-dos system-type))
+ ;; Under OS/2 system-type equals emx
+ ;; Under DOS system-type equals ms-dos
+ "*Whether you use DOS or OS/2 for bib-make-bibliography/bib-display.
+
+It tells bib-make-bibliography and bib-display to translate
+the BIBINPUTS environment variable using the \";\" character as
+a path separator and to translate DOS' backslash to slash.
+
+e.g. Use a path like \"c:\\emtex\\bibinput;c:\\latex\\bibinput\"
+
+\(You can change the environment variable which is searched by setting the elisp variable bib-bibtex-env-variable)"
+ :group 'bib-cite
+ :type 'boolean)
+
+(defcustom bib-etags-command "etags -r '/.*\\\\\\(eq\\|page\\|[fvF]\\)ref.*/' -o "
+ "*Variable for the etags command and its output option.
+In unix, this is usually \"etags -r '/.*\\\(eq\|page\|[fvF]\)ref.*/' -o \"
+\(we use the -r option to tell etags to list AMS-LaTeX's \\eqref command.)
+In DOS and OS/2, this *may* be different, e.g. using slashes like \"etags /o=\"
+If so, set it this variable."
+ :group 'bib-cite
+ :type 'string)
+
+(defcustom bib-etags-append-command "etags -r '/.*\\\\\\(eq\\|page\\|[fvF]\\)ref.*/' -a -o "
+ "*Variable for the etags command and its append and output option.
+In unix, this is usually \"etags -r '/.*\\\(eq\|page\|[fvF]\)ref.*/' -a -o \"
+In DOS and OS/2, this *may* be \"etags /a /o=\" If so, set it this variable."
+ :group 'bib-cite
+ :type 'string)
+
+(defcustom bib-etags-filename "TAGS"
+ "*Variable for the filename generated by etags, by defaults this TAGS.
+but you may want to change this to something like TAGSLaTeX such that it can
+coexist with some other tags file in your master file directory."
+ :group 'bib-cite
+ :type 'string)
+
+(defcustom bib-ref-regexp "\\\\\\(eq\\|page\\|[fvF]\\)?ref"
+ "*Regular expression for \\ref LaTeX commands that have a matching \\label.
+without the curly bracket.
+
+If you change this variable and you use multi-file documents, make sure you
+also edit the variables bib-etags-command and bib-etags-append-command."
+ :group 'bib-cite
+ :type 'regexp)
+
+(defcustom bib-substitute-string-in-display t
+ "*Determines if bib-display will substitute @string definitions.
+If t, then the @string text is substituted.
+If nil, the text is not substituted but the @string entry is included."
+ :group 'bib-cite
+ :type 'boolean)
+
+(defcustom bib-string-ignored-warning
+ '("jan" "feb" "mar" "apr" "may" "jun" "jul" "aug" "sep" "sept" "oct" "nov"
+ "dec" "acmcs" "acta" "cacm" "ibmjrd" "ibmjs" "ieeese" "ieeetcad"
+ "ieeetc" "ipl" "jacm" "jcss" "scp" "sicomp" "tcs" "tocs" "tods" "tog"
+ "toms" "toois" "toplas" )
+ "*@string abbreviations for which a warning is not given if not defined.
+These are usually month abbreviations (or journals) defined in a style file."
+ :group 'bib-cite
+ :type '(repeat (string :tag "Entry")))
+
+;;<<<<<<User-Modifiable variables end here.
+
+(defvar bib-ref-regexpc (concat bib-ref-regexp "{")
+ "*Regular expression for \\ref LaTeX commands that have a matching \\label.
+A opening curly bracket is appended to the regexp.")
+
+(defvar bib-cite-is-XEmacs
+ (not (null (save-match-data (string-match "XEmacs\\|Lucid" emacs-version)))))
+
+(defvar bib-cite-minor-mode nil)
+
+(defvar bib-highlight-mouse-keymap (make-sparse-keymap)
+ "Keymap for mouse bindings in highlighted texts in bicite.")
+
+(defvar bib-ext-list nil
+ "Xemacs buffer-local list of bib-cite extents.")
+(make-variable-buffer-local 'bib-ext-list)
+(put 'bib-ext-list 'permanent-local t)
+
+(defvar bib-cite-minor-mode-menu nil)
+
+;;;###autoload
+(defun bib-cite-minor-mode (arg)
+ "Toggle bib-cite mode.
+When bib-cite mode is enabled, citations, labels and refs are highlighted
+when the mouse is over them. Clicking on these highlights with [mouse-2]
+runs bib-find, and [mouse-3] runs bib-display."
+ (interactive "P")
+ (set (make-local-variable 'bib-cite-minor-mode)
+ (if arg
+ (> (prefix-numeric-value arg) 0)
+ (not bib-cite-minor-mode)))
+ (cond
+ (bib-cite-minor-mode ;Setup the minor-mode
+ ;; Christoph Wedler's <wedler@fmi.uni-passau.de> suggestion for xemacs
+ ;; Added for version 2.19
+ (if (boundp 'tags-always-exact)
+ (progn
+ (make-local-variable 'tags-always-exact)
+ (setq tags-always-exact nil)))
+ ;; mouse overlay
+ (if bib-highlight-mouse-t
+ (progn
+ (bib-cite-setup-highlight-mouse-keymap)
+ (bib-highlight-mouse)
+ (make-local-hook 'after-change-functions)
+ (add-hook 'after-change-functions
+ 'bib-cite-setup-mouse-function nil t)))
+ (if bib-cite-is-XEmacs
+ (progn
+ (or (local-variable-p 'current-menubar (current-buffer))
+ (set-buffer-menubar current-menubar))
+ (add-submenu nil bib-cite-minor-mode-menu))))
+ (t
+ ;;;Undo the minor-mode
+ ;; mouse overlay
+ (cond
+ (bib-cite-is-XEmacs
+ (while bib-ext-list
+ (delete-extent (car bib-ext-list))
+ (setq bib-ext-list (cdr bib-ext-list))))
+ (t
+ (remove-hook 'after-change-functions 'bib-cite-setup-mouse-function t)
+ (let ((before-change-functions) (after-change-functions))
+ ;; FIXME This detroys all mouse-faces and local-maps!
+ ;; FIXME Hope no other package is using them in this buffer!
+ (remove-text-properties (point-min) (point-max)
+ '(mouse-face t local-map t)))))
+ (if bib-cite-is-XEmacs
+ (delete-menu-item '("BCite"))))))
+
+;;This must be eval'ed when the LaTeX mode is in use.
+;; bib-highlight-mouse-keymap is a local variable so each buffer can have it's
+;; own.
+(defun bib-cite-setup-highlight-mouse-keymap ()
+ "Set up the bib-cite text in the current buffer to be clickable."
+ (make-local-variable 'bib-highlight-mouse-keymap)
+ (setq bib-highlight-mouse-keymap
+ ;;; First, copy the local keymap so we don't have `disappearing' menus
+ ;;; when the mouse is moved over a \ref, \label or \cite command.
+
+ ;;; FIXME: Check out (mouse-major-mode-menu) to see how it grabs the local
+ ;;; menus to display. Maybe on `highlighted' commands we could only
+ ;;; display the bib-cite stuff (or a subset of it).
+ (let ((m (copy-keymap (current-local-map))))
+ (cond
+ (bib-cite-is-XEmacs
+ (set-keymap-name m 'bib-highlight-mouse-keymap)
+ (cond
+ ;;action-key stuff from Vladimir Alexiev <vladimir@cs.ualberta.ca>
+ ((commandp 'action-key)
+ ;; for hyperbole. The Right Way is to define implicit buttons
+ ;; (defib) bib-cite and label-ref instead of overriding
+ ;; action-key and assist key, so that eg smart key help can
+ ;; be obtained, but I'm lazy.
+ (substitute-key-definition 'action-key 'bib-find m global-map)
+ (substitute-key-definition 'assist-key 'bib-display m global-map)
+ (substitute-key-definition 'action-key-depress
+ 'bib-find-mouse m global-map)
+ (substitute-key-definition 'assist-key-depress
+ 'bib-display-mouse m global-map)
+ (substitute-key-definition 'action-mouse-key nil m global-map)
+ (substitute-key-definition 'assist-mouse-key nil m global-map))
+ (t ; xemacs, not hyperbole
+ (define-key m "\e\r" 'bib-find-mouse) ; bug Fixed in V2.17
+ (define-key m "\e\n" 'bib-display-mouse) ;bug Fixed in V2.17
+ ;;(define-key m [(shift button1)] 'bib-display-mouse)
+ (define-key m [button3] 'bib-display-mouse)
+ (define-key m [button2] 'bib-find-mouse))))
+ (t ; emacs 19
+ (cond
+ ((commandp 'action-key)
+ (substitute-key-definition 'action-key 'bib-find m global-map)
+ (substitute-key-definition 'assist-key 'bib-display m global-map)
+ (substitute-key-definition 'action-mouse-key-emacs19
+ 'bib-find-mouse m global-map)
+ (substitute-key-definition 'assist-mouse-key-emacs19
+ 'bib-display-mouse m global-map)
+ (substitute-key-definition 'action-key-depress-emacs19
+ nil m global-map)
+ (substitute-key-definition 'assist-key-depress-emacs19
+ nil m global-map))
+ (t ; emacs 19, not hyperbole
+ (define-key m [down-mouse-3] 'bib-display-mouse)
+ (define-key m [mouse-2] 'bib-find-mouse)))))
+ m)))
+
+;;;###autoload
+(defun turn-on-bib-cite ()
+ "Unconditionally turn on Bib Cite mode."
+ (bib-cite-minor-mode 1))
+
+(defun bib-cite-setup-mouse-function (beg end old-len)
+ (save-excursion
+ (save-match-data
+ (save-restriction
+ (narrow-to-region
+ (progn (goto-char beg) (beginning-of-line) (point))
+ (progn (goto-char end) (forward-line 1) (point)))
+ (bib-highlight-mouse)))))
+
+(defvar bib-cite-minor-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "\C-cba" 'bib-apropos)
+ (define-key map "\C-cbb" 'bib-make-bibliography)
+ (define-key map "\C-cbd" 'bib-display)
+ (define-key map "\C-cbe" 'bib-etags)
+ (define-key map "\C-cbf" 'bib-find)
+ (define-key map "\C-cbn" 'bib-find-next)
+ (define-key map "\C-cbh" 'bib-highlight-mouse)
+ map)
+ "Bib-cite minor-mode keymap.")
+
+(easy-menu-define
+ bib-cite-minor-mode-menu bib-cite-minor-mode-map "Menu keymap for bib-cite."
+ '("BCite"
+ ["Make BibTeX bibliography buffer" bib-make-bibliography t]
+ ["Display citation or matching \\ref or \\label" bib-display t]
+ ["Find BibTeX citation or matching \\ref or \\label" bib-find t]
+ ["Search apropos BibTeX files" bib-apropos t]
+ ["Build TAGS file for multi-file document" bib-etags (bib-master-file)]
+ ["Refresh \\cite, \\ref and \\label mouse highlight"
+ bib-highlight-mouse t]))
+
+;; Install ourselves:
+(or (assq 'bib-cite-minor-mode minor-mode-alist)
+ (setq minor-mode-alist
+ (cons '(bib-cite-minor-mode " BCite") minor-mode-alist)))
+(or (assq 'bib-cite-minor-mode minor-mode-map-alist)
+ (setq minor-mode-map-alist
+ (cons (cons 'bib-cite-minor-mode bib-cite-minor-mode-map)
+ minor-mode-map-alist)))
+
+
+;;; Add a menu entry to bibtex.el (Perhaps I should not do this).
+(cond
+ ((and (string-match "XEmacs\\|Lucid" emacs-version)
+ (or window-system
+ (fboundp 'smart-menu))) ;text menus by Bob Weiner
+ ;;
+ ;; xemacs under X with AUCTeX
+ ;;
+
+ ;; Add to bibtex.el's popup menu
+ (defvar bib-cite-xemacs-bibtex-mode-menu
+ '("---"
+ "Bib-Cite"
+ "---"
+ ["Search apropos BibTeX files" bib-apropos t]
+ ["Create AUCTeX auto parsing file" bib-create-auto-file t])
+ "Submenu of bibtex-mode menu, used by bib-cite.")
+
+ (if (boundp 'bibtex-menu)
+ ;; Add menu now
+ (setq bibtex-menu
+ (append
+ bibtex-menu
+ bib-cite-xemacs-bibtex-mode-menu))
+ ;; Setup to add menu later
+ (defun bib-cite-bibtex-mode-hook ()
+ (if (boundp 'bibtex-menu)
+ (progn
+ (setq bibtex-menu
+ (append
+ bibtex-menu
+ bib-cite-xemacs-bibtex-mode-menu))
+ (remove-hook 'bibtex-mode-hook 'bib-cite-bibtex-mode-hook))))
+ (add-hook 'bibtex-mode-hook 'bib-cite-bibtex-mode-hook))
+ )
+
+ ((and (not (string-match "XEmacs\\|Lucid" emacs-version))
+ (string-equal "19" (substring emacs-version 0 2))
+ (or window-system
+ (fboundp 'tmm-menubar))) ; 19.30 - Will autoload if necessary
+ ;;
+ ;; emacs-19 under X-windows (or non-X with tmm)
+ ;;
+
+ ;; This *almost* makes me want to switch over to XEmacs...
+
+ ;; to AUCTeX auto file for a bibtex buffer
+ (eval-after-load
+ "bibtex"
+ '(progn
+ (cond
+ ((lookup-key bibtex-mode-map [menu-bar move/edit])
+ (define-key-after
+ (lookup-key bibtex-mode-map [menu-bar move/edit])
+ [bib-nil] '("---" . nil) '"--")
+ (define-key-after
+ (lookup-key bibtex-mode-map [menu-bar move/edit])
+ [bib-apropos] '("Search Apropos" . bib-apropos) 'bib-nil)
+ (define-key-after
+ (lookup-key bibtex-mode-map [menu-bar move/edit])
+ [auc-tex-parse]
+ '("Create AUCTeX auto parsing file" . bib-create-auto-file)
+ 'bib-apropos))
+ ((lookup-key bibtex-mode-map [menu-bar bibtex-edit])
+ (define-key-after
+ (lookup-key bibtex-mode-map [menu-bar bibtex-edit])
+ [bib-nil] '("---" . nil) '"--")
+ (define-key-after
+ (lookup-key bibtex-mode-map [menu-bar bibtex-edit])
+ [bib-apropos] '("Search Apropos" . bib-apropos) 'bib-nil)
+ (define-key-after
+ (lookup-key bibtex-mode-map [menu-bar bibtex-edit])
+ [auc-tex-parse]
+ '("Create AUCTeX auto parsing file" . bib-create-auto-file)
+ 'bib-apropos)))))))
+
+;; Following from bibtex.el
+(defvar
+ bib-cite-bibtex-font-lock-keywords
+ '(("^\\( \\|\t\\)*\\(@[A-Za-z]+\\)[ \t]*[({]\\([][A-Za-z0-9.:;?!`'()/*@_+=|<>-]+\\)?"
+ (2 font-lock-function-name-face)
+ (3 font-lock-reference-face nil t))
+ ;; reference type and reference label
+ ("^[ \t]*\\(OPT[^\"#%'(),={} \t\n0-9][^\"#%'(),={} \t\n]*\\)[ \t]*="
+ 1 font-lock-comment-face)
+ ;; optional field names (treated as comments)
+ ("^[ \t]*\\([^\"#%'(),={} \t\n0-9][^\"#%'(),={} \t\n]*\\)[ \t]*="
+ 1 font-lock-variable-name-face)
+ ;; field names
+ "Default expressions to fontify in BibTeX mode."))
+
+(defvar bib-cite-bibtex-mode-syntax-table
+ (let ((st (make-syntax-table)))
+ ;; [alarson:19920214.1004CST] make double quote a string quote
+ (modify-syntax-entry ?\" "\"" st)
+ (modify-syntax-entry ?$ "$$ " st)
+ (modify-syntax-entry ?% "< " st)
+ (modify-syntax-entry ?' "w " st)
+ (modify-syntax-entry ?@ "w " st)
+ (modify-syntax-entry ?\\ "\\" st)
+ (modify-syntax-entry ?\f "> " st)
+ (modify-syntax-entry ?\n "> " st)
+ (modify-syntax-entry ?~ " " st)
+ st))
+;; Code from bibtex.el ends
+
+;; @string starts with a letter and does not contain any of ""#%'(),={}
+;; Here we do not check that the field contains only one string field and
+;; nothing else.
+(defvar bib-string-regexp
+ "^[, \t]*[a-zA-Z]+[ \t]*=[ \t]*\\([a-zA-Z][^#%'(),={}\" \t\n]*\\)"
+ "Regular expression for field containing a @string.")
+
+(defun bib-display ()
+ "Display BibTeX citation or matching \\ref or \\label command under point.
+
+If text under cursor is a \\cite command, then display its BibTeX info from
+\\bibliography input file.
+ Example with cursor located over cite command or arguments:
+ \cite{Wadhams81,Bourke.et.al87,SchneiderBudeus94}
+ ^Display-all-citations ^Display-this-citation
+
+If text under cursor is a \\ref command, then display environment associated
+with its matching \\label command.
+
+If text under cursor is a \\label command, then display the text around
+the first matching \\ref command.
+
+The user is prompted for a \\label or \\ref is nothing suitable is found under
+the cursor. The first prompt is for a label. If you answer with an empty
+string, a second prompt for a ref will be given.
+
+A TAGS file is created and used for multi-file documents under auctex."
+ (interactive)
+ (let ((cite)(ref)(label))
+ (save-excursion
+ (if (not (looking-at "\\\\"))
+ (search-backward "\\" nil t))
+ (if (looking-at bib-ref-regexpc)
+ (setq ref t)
+ (if (looking-at "\\\\label{")
+ (setq label t)
+ (setq cite t))))
+ (cond
+ ;; reftex doesn't handle label->ref
+ ((and bib-cite-use-reftex-view-crossref
+ (or ref cite))
+ ;;;FIXME: reftex doesn't want point on \ref or \cite part, but on keyword
+ (require 'reftex)
+ (reftex-view-crossref nil))
+ (cite
+ (bib-display-citation))
+ (t
+ (bib-display-label)))))
+
+(defun bib-find ()
+ "Edit BibTeX citation or find matching \\ref or \\label command under point.
+
+For multi-entry cite commands, the cursor should be on the actual cite key
+desired (otherwise a random entry will be selected).
+e.g.: \cite{Wadhams81,Bourke.et.al87,SchneiderBudeus94}
+ ^Display-this-citation
+
+If text under cursor is a \\ref command, then point is moved to its matching
+\\label command.
+
+If text under cursor is a \\label command, then point is moved to the first
+matching \\ref command.
+
+The user is prompted for a \\label or \\ref is nothing suitable is found under
+the cursor. The first prompt is for a label. If you answer with an empty
+string, a second prompt for a ref will be given.
+
+A TAGS file is created and used for multi-file documents under auctex."
+ (interactive)
+ (let ((cite)(ref)(label))
+ (save-excursion
+ (if (not (looking-at "\\\\"))
+ (search-backward "\\" nil t))
+ (if (looking-at bib-ref-regexpc)
+ (setq ref t)
+ (if (looking-at "\\\\label{")
+ (setq label t)
+ (setq cite t))))
+ (cond
+ ;; reftex doesn't handle label->ref
+ ((and bib-cite-use-reftex-view-crossref
+ (or ref cite))
+ (require 'reftex)
+ (reftex-view-crossref t))
+ (cite
+ (bib-edit-citation))
+ (t
+ (bib-find-label)))))
+
+(defvar bib-cite-search-ring nil
+ "Bib-cite intenal variable to hold last \\ref or \\eqref find.")
+
+(defun bib-find-next (&optional prev-p)
+ "Find next occurrence of a \ref or \eqref.
+This is made necessary because we now use a regexp to find tags in multi-file
+documents, and the Emacs command `find-tag' doesn't allow to interactively
+find the next occurrence of a regexp."
+ (interactive "P")
+ (if (bib-master-file) ;Multi-file document
+ (if prev-p
+ (find-tag t '- t)
+ (find-tag t t t))
+ (if bib-cite-search-ring
+ ;;FIXME: Should first make sure I move off initial \ref{}.
+ (let ((regexp (concat bib-ref-regexpc bib-cite-search-ring "}")))
+ (if prev-p
+ (if (not (re-search-backward regexp nil t))
+ (message "No previous occurrence of reference %s"
+ bib-cite-search-ring))
+ (if (not (re-search-forward regexp nil t))
+ (message "No next occurrence of reference %s"
+ bib-cite-search-ring))))
+ (message "Sorry, no previous reference to find. Use bib-find?"))))
+
+(defun bib-display-mouse (EVENT)
+ "Display BibTeX citation or matching \\ref or \\label under mouse EVENT.
+See bib-display."
+ (interactive "e")
+ (mouse-set-point EVENT)
+ (bib-display))
+
+(defun bib-find-mouse (EVENT)
+ "Edit BibTeX citation or find matching \\ref or \\label under mouse EVENT.
+See bib-find."
+ (interactive "e")
+ (mouse-set-point EVENT)
+ (bib-find))
+
+(defun bib-apropos ()
+ "Display BibTeX entries containing a keyword from bibliography file.
+The files specified in the \\bibliography command are searched unless
+the current buffer is in `bibtex-mode' or is the Help buffer. In those
+cases, *it* is searched. This allows you to trim down a search further
+by using bib-apropos sequentially."
+ ;;(interactive "sBibTeX apropos: ")
+ (interactive)
+ (let* ((keylist (and (boundp 'TeX-auto-update) ;Avoid error in FRAMEPOP
+ (fboundp 'LaTeX-bibitem-list) ;Use this if using auctex
+ (LaTeX-bibitem-list)))
+ (keyword (bib-apropos-keyword-at-point))
+ (keyword (completing-read "BiBTeX apropos: " keylist nil nil keyword))
+ (the-text)(key-point)(start-point)
+ (new-buffer-f (and (not (string-match "^bib" mode-name))
+ (not (string-equal "*Help*" (buffer-name)))))
+ (bib-buffer (or (and new-buffer-f (bib-get-bibliography nil))
+ (current-buffer))))
+ (save-excursion
+ (set-buffer bib-buffer)
+ (goto-char (point-min))
+ (while (and (re-search-forward "^[ \t]*@" nil t)
+ (re-search-forward keyword nil t))
+ (setq key-point (point)) ;To make sure this is within entry
+ (re-search-backward "^[ \t]*@" nil t)
+ (setq start-point (point))
+ (forward-list 1)
+ (if (< (point) key-point) ;And this is that test...
+ (goto-char key-point) ;Not within entry, skip it.
+ (setq the-text
+ (cons (concat (buffer-substring start-point (point)) "\n")
+ the-text))))
+ (if (not the-text)
+ (message "Sorry, no matches found.")
+ (with-output-to-temp-buffer "*Help*"
+ (mapcar 'princ (nreverse the-text)))
+ (bib-cite-fontify-help-as-bibtex)
+ (if bib-novice
+ (message
+ (substitute-command-keys
+ (concat "Use \\[bib-apropos] again in the *help* buffer"
+ " to trim the search")))))
+ (if new-buffer-f
+ (kill-buffer bib-buffer)))))
+
+(defvar bib-document-citekeys-obarray-warnings nil
+ "Bib-cite internal variable.")
+
+(defun bib-make-bibliography ()
+ "Extract citations used in the current document from \bibliography{} file(s).
+Put them into a buffer named after the current buffer, with extension .bib.
+
+In an AUCTeX multi-file document, parsing must be on and the citation keys
+are extracted from the .aux files.
+
+In a plain LaTeX buffer (not multi-file), the cite keys are extracted from
+the text itself. Therefore the text need not have been previously processed
+by LaTeX.
+
+This function is useful when you want to share a LaTeX file, and therefore want
+to create a bibtex file containing only the references used in the document."
+ (interactive)
+ (let* ((the-keys-obarray (or (bib-document-citekeys-obarray)
+ (bib-buffer-citekeys-obarray)))
+ ;1st in case of error
+ (new-buffer
+ (create-file-buffer
+ (concat (substring (buffer-name) 0
+ (or (string-match "\\." (buffer-name))
+ (length (buffer-name))))
+ "-bib.bib")))
+ (bib-buffer (bib-get-bibliography nil))
+ (the-warnings (bib-get-citations the-keys-obarray
+ bib-buffer
+ new-buffer
+ nil)))
+ (kill-buffer bib-buffer)
+;;; (switch-to-buffer new-buffer)
+ (funcall bib-switch-to-buffer-function new-buffer)
+ (bibtex-mode)
+ (if (or bib-document-citekeys-obarray-warnings
+ the-warnings)
+ (progn
+ (cond
+ ((and bib-document-citekeys-obarray-warnings the-warnings)
+ (with-output-to-temp-buffer "*Help*"
+ (princ bib-document-citekeys-obarray-warnings the-warnings)))
+ (bib-document-citekeys-obarray-warnings
+ (with-output-to-temp-buffer "*Help*"
+ (princ bib-document-citekeys-obarray-warnings)))
+ (the-warnings
+ (with-output-to-temp-buffer "*Help*" (princ the-warnings))))
+ (setq bib-document-citekeys-obarray-warnings nil) ;Reset
+ (bib-cite-fontify-red)))
+ (if bib-novice
+ (message
+ (substitute-command-keys
+ "Use \\[save-buffer] to save this buffer to a file.")))))
+
+(defun bib-cite-fontify-red (&optional limit)
+ "Fontify *Help* buffer in red-bold up to optional LIMIT."
+ (if (and window-system ;Not exactly correct for XEmacs
+ (not (facep 'red-bold)))
+ (progn
+ (copy-face 'bold 'red-bold)
+ (set-face-foreground 'red-bold "red")))
+ (save-excursion
+ (set-buffer "*Help*")
+ (let ((before-change-functions) (after-change-functions))
+ (put-text-property (point-min)(or limit (point-max))
+ 'face 'red-bold))))
+
+(defun bib-cite-fontify-help-xemacs (defaults)
+ (if (fboundp 'font-lock-set-defaults-1) ; >= XEmcas 19.14
+ (progn
+ (set-buffer "*Help*")
+ (setq font-lock-defaults-computed nil
+ font-lock-keywords nil)
+ (font-lock-set-defaults-1
+ (and defaults (font-lock-find-font-lock-defaults defaults)))
+ (font-lock-fontify-buffer)
+ (setq font-lock-defaults-computed nil
+ font-lock-keywords nil)
+ (font-lock-set-defaults-1))))
+
+(defun bib-cite-fontify-help-as-bibtex ()
+ (save-excursion
+ (cond
+ ((not (featurep 'font-lock))
+ nil) ;No font-lock! Stop here.
+ ;; font-lock under Emacs and XEmacs
+ ((string-match "XEmacs\\|Lucid" emacs-version)
+ ;; XEmacs
+ (bib-cite-fontify-help-xemacs 'bibtex-mode))
+ (t
+ ;; Emacs
+ (set-buffer "*Help*")
+ (let ((font-lock-defaults
+ '(bib-cite-bibtex-font-lock-keywords
+ nil t ((?$ . "\"")(?\" . ".")))))
+ (if font-lock-mode
+ (font-lock-mode)
+ (if (fboundp 'font-lock-unset-defaults) (font-lock-unset-defaults))
+ (font-lock-unfontify-buffer))
+ (font-lock-fontify-buffer))))))
+
+(defun bib-cite-fontify-help-as-latex ()
+ (save-excursion
+ (cond
+ ((not (featurep 'font-lock))
+ nil) ;No font-lock! Stop here.
+ ;; font-lock under Emacs and XEmacs
+ ((string-match "XEmacs\\|Lucid" emacs-version)
+ ;; XEmacs, not necessary to do s.th. special for font-latex, we do *not*
+ ;; want the buffer-local faces!
+ (bib-cite-fontify-help-xemacs 'latex-mode))
+ (t
+ ;; Emacs
+ (set-buffer "*Help*")
+ ;; Actually, don't want to `permanently' affect *Help* buffer...
+ ;;(if (featurep 'font-latex)
+ ;; (font-latex-setup)
+ ;; Rather I should deal with this in the `let' form:
+ ;; (make-local-variable 'font-lock-string-face)
+ ;; (setq font-lock-string-face font-latex-math-face
+ ;; font-latex-string-face (default-value 'font-lock-string-face))
+ (let ((font-lock-defaults
+ (if (featurep 'font-latex)
+ '((font-latex-keywords font-latex-keywords-1
+ font-latex-keywords-2)
+ nil nil ((?\( . ".") (?\) . ".") (?$ . "\"")) nil
+ (font-lock-comment-start-regexp . "%")
+ (font-lock-mark-block-function . mark-paragraph))
+ '(tex-font-lock-keywords nil nil ((?$ . "\""))))))
+ (if font-lock-mode
+ (font-lock-mode)
+ (if (fboundp 'font-lock-unset-defaults) (font-lock-unset-defaults))
+ (font-lock-unfontify-buffer))
+ (font-lock-fontify-buffer))))))
+
+(defvar bib-document-TeX-files-warnings nil
+ "Bib-cite internal variable.")
+
+(defun bib-etags (&optional masterdir)
+ "Invoke etags on all tex files of the document in directory MASTERDIR.
+Store the TAGS file in the master-directory.
+Expect errors if you use this outside of auctex or within a plain
+single-file document. Also makes sure that the TAGS buffer is updated.
+See variables bib-etags-command and bib-etags-filename"
+ (interactive)
+ (require 'etags)
+ (let* ((the-file-list (bib-document-TeX-files))
+ (the-file (car the-file-list))
+ (dir (or masterdir (bib-master-directory)))
+ (the-tags-file (expand-file-name bib-etags-filename dir))
+ (the-tags-buffer (get-file-buffer the-tags-file)))
+ ;; Create TAGS file with first TeX file (master file)
+ (shell-command (concat bib-etags-command the-tags-file " " the-file))
+ (setq the-file-list (cdr the-file-list))
+ ;; Append to TAGS file for all other TeX files.
+ (while the-file-list
+ (setq the-file (car the-file-list))
+ (shell-command
+ (concat bib-etags-append-command the-tags-file " " the-file))
+ (setq the-file-list (cdr the-file-list)))
+ (if the-tags-buffer ;buffer existed; we must refresh it.
+ (save-excursion
+ (set-buffer the-tags-buffer)
+ (revert-buffer t t)))
+
+ ;; Check value of tags-file-name against the-tags-file
+ (or (equal the-tags-file tags-file-name) ;make sure it's current
+ (visit-tags-table the-tags-file))
+
+ ;(set (make-local-variable 'tags-file-name) the-tags-file))
+ ;; above should not be needed
+
+ ;; Weird Bug:
+ ;; (visit-tags-table-buffer) seems to get called twice when called by
+ ;; find-tag on an undefined tag. The second time, it's in the TAGS
+ ;; buffer and returns an error because TAGS buffer does have
+ ;; tags-file-name set.
+ ;; To get around this. I'm setting this variable in the TAGS buffer.
+ ;; Skip this in XEmacs (Changed by Anders Stenman)
+ (if (and (not (string-match "XEmacs\\|Lucid" emacs-version))
+ (get-file-buffer the-tags-file))
+ (save-excursion
+ (set-buffer (get-file-buffer the-tags-file))
+ (set (make-local-variable 'tags-file-name) the-tags-file))))
+
+
+ (if bib-document-TeX-files-warnings ;free variable loose in emacs!
+ (progn
+ (with-output-to-temp-buffer "*Help*"
+ (princ bib-document-TeX-files-warnings))
+ (setq bib-document-TeX-files-warnings nil) ;Reset
+ (bib-cite-fontify-red))))
+
+(defun bib-Is-hidden ()
+ "Return true is current point is hidden."
+ (if (not selective-display)
+ nil ;Not hidden if not using this...
+ (save-excursion
+ (if (not (re-search-backward "[\n\^M]" nil t))
+ nil ;Play safe
+ (if (string-equal (match-string 0) "\n")
+ nil
+ t)))))
+
+(defun bib-highlight-mouse ()
+ "Make that nice green highlight when the mouse is over LaTeX commands."
+ (interactive)
+;;;Comment this out. User should be able to use bib-highlight-mouse
+;;;to try it out regardless of bib-highlight-mouse-t.
+;;;Check bib-highlight-mouse-t only in automated cases.
+;;;
+;;; (if (and bib-highlight-mouse-t
+;;; ;;window-system) ;Do nothing unless under X
+;;; )
+;;; *all of code was here*
+;;; )
+ (save-excursion
+ (let ((s)(e)(extent)(local-extent-list bib-ext-list)
+ (inhibit-read-only t)
+ (modified (buffer-modified-p))) ;put-text-property changing this?
+ ;; * peta Wed Nov 8 16:27:29 1995 -- better remove the mouse face
+ ;; properties first.
+ (setq bib-ext-list nil) ;Reconstructed below...
+ (if (string-match "XEmacs\\|Lucid" emacs-version)
+ (while local-extent-list
+ (setq extent (car local-extent-list))
+ (if (or (extent-detached-p extent)
+ (and (<= (point-min)(extent-start-position extent))
+ (>= (point-max)(extent-end-position extent))))
+ (delete-extent extent)
+ (setq bib-ext-list (cons extent bib-ext-list)))
+ (setq local-extent-list (cdr local-extent-list)))
+ ;; Remove properties for regular emacs
+ ;; FIXME This detroys all mouse-faces and local-maps!
+ ;; FIXME Hope no other package is using them in this buffer!
+ (let ((before-change-functions) (after-change-functions))
+ (remove-text-properties (point-min) (point-max)
+ '(mouse-face t local-map t))))
+ (goto-char (point-min))
+ (while
+ (re-search-forward
+ (concat
+ "\\\\\\(" (substring bib-ref-regexp 2)
+ "\\|label\\|[A-Za-z]*cite[A-Za-z]*\\(\\[.*\\]\\)?\\){[^}]*}")
+ nil t)
+ (setq s (match-beginning 0))
+ (setq e (match-end 0))
+ (cond
+ ((string-match "XEmacs\\|Lucid" emacs-version)
+ (setq extent (make-extent s e))
+ (setq bib-ext-list (cons extent bib-ext-list))
+ (set-extent-property extent 'highlight t)
+ (set-extent-property extent 'start-open t)
+ (set-extent-property extent 'balloon-help 'bib-label-help)
+ (set-extent-property extent 'help-echo 'bib-label-help-echo)
+ (set-extent-property extent 'keymap bib-highlight-mouse-keymap))
+ (t
+ (let ((before-change-functions) (after-change-functions)
+ ;;(this-overlay (make-overlay s e))
+ )
+;;; Even using overlays doens't help here. If bib-highlight-mouse-keymap
+;;; does not include the AucTeX menus, then these disappear when we click
+;;; onto a \cite command. Perhaps using bib-cite as a minor mode will fix
+;;; this? For now, bib-cite must be loaded after these menus are built.
+;;; It must therefore be loaded in a mode-hook.
+ (put-text-property s e 'local-map bib-highlight-mouse-keymap)
+ (put-text-property s e 'mouse-face 'highlight)
+ ;;(overlay-put this-overlay 'local-map bib-highlight-mouse-keymap)
+ ;;(overlay-put this-overlay 'mouse-face 'highlight)
+ ))))
+ (set-buffer-modified-p modified))))
+
+(defun bib-toggle-highlight ()
+ "Toggle the enabling of bib-cite entries as clickable things."
+;; FIXME: do something about after-change stuff?
+ (interactive)
+ (if (setq bib-highlight-mouse-t (not bib-highlight-mouse-t))
+ (bib-highlight-mouse)
+ (let ((modified (buffer-modified-p))
+ (inhibit-read-only t))
+ (cond
+ ((string-match "XEmacs\\|Lucid" emacs-version)
+ (while bib-ext-list
+ (delete-extent (car bib-ext-list))
+ (setq bib-ext-list (cdr bib-ext-list))))
+ (t
+ (let ((before-change-functions) (after-change-functions))
+ (remove-text-properties (point-min) (point-max)
+ '(mouse-face local-map)))))
+ (set-buffer-modified-p modified))))
+
+(defun bib-label-help-echo (object)
+ (if bib-label-help-echo-format
+ (bib-label-help object bib-label-help-echo-format)))
+
+;;; Balloon-help callback. Anders Stenman <stenman@isy.liu.se>
+;;; Patched by Bruce Ravel <bruce.ravel@nist.gov>
+(defun bib-label-help (object &optional format)
+ (or format (setq format "Use mouse button 2 to find the %s.
+Use mouse button 3 to display the %s."))
+ (save-match-data
+ (let* ((string (extent-string object))
+ (type (cond ((string-match "^\\\\[A-Za-z]*cite[A-Za-z]*" string) "citation")
+ ((string-match
+ (concat "^" bib-ref-regexp) string) "\\label{}")
+ ((string-match "^\\\\label" string) "\\ref{}")
+ (t "this (unknown) reference"))))
+ (format format type type))))
+
+;;----------------------------------------------------------------------------
+;; Routines to display or edit a citation's bibliography
+
+(defun bib-display-citation ()
+ "Do the displaying of cite info. Return t if found cite key, nil otherwise.
+Example with cursor located over cite command or arguments:
+\cite{Wadhams81,Bourke.et.al87,SchneiderBudeus94}
+ ^Display-all-citations ^Display-this-citation"
+ (save-excursion
+ (let* ((the-keys-obarray (bib-get-citekeys-obarray)) ;1st in case of error
+ (work-buffer (get-buffer-create "*bibtex-work*"))
+ (bib-buffer (bib-get-bibliography nil))
+ (the-warnings (bib-get-citations
+ the-keys-obarray
+ bib-buffer
+ work-buffer
+ bib-substitute-string-in-display))
+ (the-warn-point))
+ (if the-warnings
+ (progn
+ (set-buffer work-buffer)
+ (goto-char 1)
+ (insert the-warnings)
+ (setq the-warn-point (point))))
+ (with-output-to-temp-buffer
+ "*Help*"
+ (set-buffer work-buffer)
+ (princ (buffer-substring 1 (point-max))))
+ (bib-cite-fontify-help-as-bibtex)
+ (if the-warn-point
+ (bib-cite-fontify-red the-warn-point))
+ (kill-buffer bib-buffer)
+ (kill-buffer work-buffer))))
+
+(defun bib-edit-citation ()
+ "Do the edit of cite info. Return t if found cite key, nil otherwise.
+Find and and put edit point in bib file associated with a BibTeX citation
+under cursor from \bibliography input file.
+In a multi-entry cite command, the cursor should be on the actual cite key
+desired (otherwise a random entry will be selected).
+e.g.: \cite{Wadhams81,Bourke.et.al87,SchneiderBudeus94}
+ ^Display-this-citation"
+ (let ((the-keys-obarray (bib-get-citekeys-obarray)) ;1st in case of error
+ (bib-buffer (bib-get-bibliography t))
+ (the-key)(the-file))
+ (save-excursion
+ (mapatoms ;Do this for each cite-key found...
+ (lambda (cite-key)
+ (setq the-key (symbol-name cite-key)))
+ the-keys-obarray)
+ (set-buffer bib-buffer)
+ (goto-char (point-min))
+ (if (not (re-search-forward
+ (concat "@[^{(]+[{(][\t ]*" (regexp-quote the-key) "[ ,\n]")
+ nil t))
+ (progn
+ (kill-buffer bib-buffer)
+ (error "Sorry, could not find bib entry for %s" the-key))
+ (re-search-backward "%%%Filename: \\([^\n]*\\)" nil t)
+ (setq the-file (match-string 1))
+ (kill-buffer bib-buffer)))
+;;; (find-file the-file)
+ (funcall bib-switch-to-buffer-function (find-file-noselect the-file))
+ (goto-char (point-min)) ;V2.19 fix
+ (re-search-forward (concat "@[^{(]+[{(][\t ]*"
+ (regexp-quote the-key)
+ "[ ,\n]") nil t)))
+
+;;--------------------------------------------------------------------------
+;; Function for bib-apropos
+
+(defun bib-apropos-keyword-at-point ()
+ "Return the keyword under point for initial input to bib-apropos prompt."
+ (save-excursion
+ (let ((here (point)))
+ (cond
+ ((and (re-search-backward "[\n{, ]" nil t)
+ (string-equal "{" (buffer-substring (match-beginning 0)
+ (match-end 0))))
+ (if (fboundp 'buffer-substring-no-properties)
+ (buffer-substring-no-properties (1+ (point)) here)
+ (buffer-substring (1+ (point)) here)))))))
+
+;;--------------------------------------------------------------------------
+;; Functions for Displaying or moving to matching \ref or \label command
+
+(defun bib-display-label ()
+"Display environment or first ref associated with a label.
+The label or ref name is extracted from the text under the cursor, or the
+user is prompted is nothing suitable is found. The first prompt is for a
+label. If you answer with an empty string, a second prompt for a ref will
+be given."
+ (let ((the-regexp (bib-guess-or-prompt-for-label)))
+ (if (not the-regexp)
+ (message "No name given")
+ (bib-display-or-find-label the-regexp t))))
+
+(defun bib-find-label ()
+ "Move to a label, or the first occurance of a ref.
+The label or ref name is extracted from the text under the cursor.
+If nothing suitable is found, the user is prompted. The first prompt is for a
+label. If you answer with an empty string, a second prompt for a ref will be
+given.
+
+If within a single file document:
+ You can move back with C-xC-x as the mark is set before moving.
+ You can search for next occurrances of a ref command with C-sC-s.
+
+If within a multi-file document (in auctex only)
+ You can move back with C-xC-x if within the same buffer. If not, just
+ select your previous buffer.
+ You can search for next occurrances of a ref command with tag commands:
+ C-u M-. Find next alternate definition of last tag specified.
+ C-u - M-. Go back to previous tag found."
+ (let ((the-regexp (bib-guess-or-prompt-for-label)))
+ (if (not the-regexp)
+ (message "No name given")
+ (bib-display-or-find-label the-regexp nil))))
+
+;;--------------------------------------------------------------------------
+;; Functions for Displaying or moving to matching \ref or \label command
+
+(defun bib-display-or-find-label (the-regexp displayf)
+;; work horse for bib-find-label and bib-display-label
+ (let* ((masterfile (bib-master-file))
+ (masterdir (and masterfile
+ (file-name-directory masterfile)))
+ (new-point)(new-buffer))
+ (save-excursion
+ ;; Now we are either in a simple file, or with a multi-file document
+ (cond
+ (masterfile ;Multi-file document
+ (cond
+ (displayf ;Display only
+ (set-buffer (bib-etags-find-noselect the-regexp masterdir))
+ (re-search-forward the-regexp nil t)
+ ;; ...because tags puts point on beginning of line
+ (if (string-match "^\\\\\\\\label" the-regexp)
+ (bib-display-this-environment) ;display the label's environment
+ (bib-display-this-ref))) ; display the ref's context
+ (t ;Move to it
+ (setq new-buffer (bib-etags-find-noselect the-regexp masterdir))
+ (if bib-novice
+ (message
+ (substitute-command-keys
+ (concat "Use \\[bib-find-next] to find the next occurrence "
+ "and C-u \\[bib-find-next] to find previous."))))
+ (if (equal new-buffer (current-buffer))
+ (setq new-point (point)))))) ;Moving with the same buffer
+ (t ;Single-file document
+ (goto-char (point-min))
+ (cond
+ ((re-search-forward the-regexp nil t)
+ (if displayf
+ (if (string-match "^\\\\label" the-regexp)
+ (bib-display-this-environment) ;Display the environment
+ (bib-display-this-ref)) ; display the ref's context
+ (setq new-point (match-beginning 0)) ;or move there
+ (if (string-match "{\\(.*\\)}" the-regexp)
+ (setq bib-cite-search-ring (match-string 1 the-regexp)))
+ (if bib-novice
+ (message
+ (substitute-command-keys
+ (concat "Use \\[bib-find-next] to find the next occurrence "
+ "and C-u \\[bib-find-next] to find previous."))))))
+ (t
+ (message "Sorry, cannot find it (%s)" the-regexp))))))
+ (if new-point
+ (progn
+ (push-mark (point) t nil) ;We've moving there... push mark
+ (goto-char new-point))
+ (if new-buffer ;We've changing buffer
+ ;;(switch-to-buffer new-buffer)
+ (funcall bib-switch-to-buffer-function new-buffer)))
+ (if (bib-Is-hidden)
+ (save-excursion
+ (beginning-of-line)
+ (show-entry)))))
+
+(defvar bib-label-prompt-map nil)
+(if bib-label-prompt-map
+ ()
+ (setq bib-label-prompt-map (copy-keymap minibuffer-local-completion-map))
+ (define-key bib-label-prompt-map " " 'self-insert-command))
+
+(defun bib-guess-or-prompt-for-label ()
+ "Guess from context, or prompt the user for a label command."
+ (save-excursion
+ (if (not (looking-at "\\\\")) ;If not on beginning of a command
+ (re-search-backward "[\\]"
+ (save-excursion (beginning-of-line)(point))
+ t))
+ (cond
+ ((looking-at bib-ref-regexpc) ;On \ref, looking for matching \label
+ (let ((b (progn (search-forward "{" nil t)(forward-char -1)(point)))
+ (e (progn (forward-sexp 1)(point))))
+ (concat "\\\\label" (regexp-quote (buffer-substring b e)))))
+ ((looking-at "\\\\label{") ;On \label, looking for matching \ref
+ (let ((b (progn (search-forward "{" nil t)(forward-char -1)(point)))
+ (e (progn (forward-sexp 1)(point))))
+ (concat bib-ref-regexp (regexp-quote (buffer-substring b e)))))
+ (t ;Prompt the user
+ (let* ((minibuffer-local-completion-map bib-label-prompt-map)
+ (the-alist (create-alist-from-list
+ (cdr (reverse LaTeX-label-list))))
+ ;;; LaTeX-label-list example:
+ ;;; '(("label3" "label4")("label1" "label2") nil)
+ ;; so let's get rid of that nil part in embedded list.
+ (the-name
+ (if (string-equal "18" (substring emacs-version 0 2))
+ (completing-read "Label: " the-alist nil nil nil)
+ (completing-read "Label: " the-alist nil nil nil
+ 'LaTeX-find-label-hist-alist))))
+ (if (not (equal the-name ""))
+ (concat "\\\\label{" (regexp-quote the-name) "}")
+ ;; else try to get a \ref
+ (if (string-equal "18" (substring emacs-version 0 2))
+ (setq the-name (completing-read "Ref: " the-alist nil nil nil))
+ (setq the-name (completing-read "Ref: " the-alist nil nil nil
+ 'LaTeX-find-label-hist-alist)))
+ (if (not (equal the-name ""))
+ (concat bib-ref-regexpc (regexp-quote the-name) "}")
+ nil)))))))
+
+(defun bib-display-this-ref ()
+ "Display a few lines around current point."
+ (cond
+ ((bib-Is-hidden)
+ (with-output-to-temp-buffer "*BiBTemp*"
+ (princ
+ (buffer-substring
+ (save-excursion
+ (let ((i 3))
+ (while (and (> i 0)
+ (re-search-backward "[\n\^M]" nil t)
+ (setq i (1- i)))))
+ (point))
+ (save-excursion
+ (let ((i 3))
+ (while (and (> i 0)
+ (re-search-forward "[\n\^M]" nil t)
+ (setq i (1- i)))))
+ (point)))))
+ (set-buffer "*BiBTemp*")
+ (while (search-forward "\^M" nil t)
+ (replace-match "\n" nil t))
+ (goto-char 1)
+ (if (looking-at "\n") ;Remove first empty line...
+ (delete-char 1))
+ (with-output-to-temp-buffer "*Help*"
+ (princ (buffer-substring 1 (point-max))))
+ (bib-cite-fontify-help-as-latex)
+ (kill-buffer "*BiBTemp*"))
+ (t
+ (with-output-to-temp-buffer ; display the ref's context
+ "*Help*"
+ (princ
+ (buffer-substring (save-excursion (forward-line -2)(point))
+ (save-excursion (forward-line 3)(point)))))
+ (bib-cite-fontify-help-as-latex))))
+
+(defun bib-display-this-environment ()
+ "Display the environment associated with a label, or its section name.
+Assumes point is already on the label.
+Does not save excursion."
+;; Bugs: The method used here to detect the environment is *not* foolproof.
+;; It will get confused, for example, between two figure environments,
+;; picking out both instead of the section label above them. But since
+;; users typically puts their labels next to the section declaration,
+;; I'm satisfied with this... for now.
+;; I could have used the following AUCTeX functions:
+;; LaTeX-current-environment
+;; Function: Return the name (a string) of the enclosing LaTeX environment.
+;; LaTeX-current-section
+;; Function: Return the level of the section that contain point.
+;; but then this code would only work as part of AUCTeX...
+ (let ((the-point (point))
+ (end-point (point))
+ (the-environment)(foundf))
+ (while (and (not foundf)
+ (goto-char end-point) ;Past end of last search
+ (re-search-forward "\\(^\\|\^M\\)[ \t]*\\\\end{\\([^}]*\\)}"
+ nil t))
+ (setq end-point (point))
+ (setq the-environment (match-string 2))
+ (and (not (string-match "document" the-environment))
+ (re-search-backward (concat "\\(^\\|\^M\\)[ \t]*\\\\begin{"
+ (regexp-quote the-environment) "}"))
+ (<= (point) the-point)
+ (setq foundf t)))
+ (if foundf ;A good environment
+ (progn
+ (cond ((bib-Is-hidden) ;Better way is: replace-within-string
+ (with-output-to-temp-buffer "*BiBTemp*"
+ (princ (buffer-substring (point) end-point)))
+ (set-buffer "*BiBTemp*")
+ (while (search-forward "\^M" nil t)
+ (replace-match "\n" nil t))
+ (goto-char 1)
+ (if (looking-at "\n") ;Remove first empty line...
+ (delete-char 1))
+ (with-output-to-temp-buffer "*Help*"
+ (princ (buffer-substring 1 (point-max))))
+ (kill-buffer "*BiBTemp*"))
+ (t
+ (with-output-to-temp-buffer "*Help*"
+ (princ (buffer-substring (point) end-point)))))
+ (bib-cite-fontify-help-as-latex))
+ ;; Just find the section declaration
+ (goto-char the-point)
+ (if (re-search-backward
+;;; "\\(^\\|\^M\\)[ \t]*\\\\\\(sub\\)*section{\\([^}]*\\)}" nil t)
+;;; Michael Steiner <steiner@cs.uni-sb.de> patch
+ "\\(^\\|\^M\\)[ \t]*\\\\\\(\\(sub\\)*section\\|chapter\\|part\\)\\*?\
+{\\([^}]*\\)}"
+ nil t)
+ (message (match-string 0))
+ (error
+ "Sorry, could not find an environment or section declaration")))))
+
+(defvar LaTeX-find-label-hist-alist nil "History list for LaTeX-find-label.")
+(defvar LaTeX-label-list nil "Used by AUCTeX to store label names.")
+
+
+(defun create-alist-from-list (the-list)
+ "Return a single list from a THE-LIST that may contain either items or lists.
+e.g. turns
+'((\"label3\" \"label4\")(\"label1\" \"label2\") \"label\")
+into
+'((\"label3\") (\"label4\") (\"label1\") (\"label2\") (\"label\"))"
+ (mapcar 'list (bib-cite-mh-list-to-string the-list)))
+
+;;;
+;;; Following two functions from mh-utils.el (part of GNU emacs)
+;;; I have changed the names in case these functions change what they do.
+;;;
+
+(defun bib-cite-mh-list-to-string (l)
+ "Flattens the list L and make every element of the new list into a string."
+ (nreverse (bib-cite-mh-list-to-string-1 l)))
+
+(defun bib-cite-mh-list-to-string-1 (l)
+ (let ((new-list nil))
+ (while l
+ (cond ((null (car l)))
+ ((symbolp (car l))
+ (setq new-list (cons (symbol-name (car l)) new-list)))
+ ((numberp (car l))
+ (setq new-list (cons (int-to-string (car l)) new-list)))
+ ((equal (car l) ""))
+ ((stringp (car l)) (setq new-list (cons (car l) new-list)))
+ ((listp (car l))
+ (setq new-list (nconc (bib-cite-mh-list-to-string-1 (car l))
+ new-list)))
+ (t (error "Bad element in mh-list-to-string: %s" (car l))))
+ (setq l (cdr l)))
+ new-list))
+
+;; -------------------------------------------------------------------------
+;; Routines to extract cite keys from text
+
+;; ... is truly remarkable, as shown in \citeN{Thomson77,Test56}. Every
+;; \cite[{\it e.g.}]{Thomson77,Test56}
+
+(defun bib-get-citations (keys-obarray bib-buffer new-buffer substitute)
+ "Put citations of KEYS-OBARRAY from BIB-BUFFER into NEW-BUFFER.
+Substitute strings if SUBSTITUTE is t
+Return the-warnings as text."
+ (let ((the-warnings) ;The only variable to remember...
+ (case-fold-search t)) ;All other results go into new-buffer
+ ;; bibtex is not case-sensitive for keys.
+ (save-excursion
+ (let ((the-text))
+ (set-buffer bib-buffer)
+ (mapatoms ;Do this for each cite-key found...
+ (lambda (cite-key)
+ (goto-char (point-min))
+ (if (re-search-forward
+ (concat "@[^{(]+[{(][\t ]*"
+ (regexp-quote (symbol-name cite-key))
+ "\\([, ]\\\|$\\)")
+ ;; ^^ ^ comma, space or end-of-line
+ nil t)
+ (setq the-text (concat the-text
+ (buffer-substring
+ (progn (beginning-of-line)(point))
+ (progn (forward-sexp 2)(point)))
+ "\n\n"))
+ (setq the-warnings (concat the-warnings
+ "Cannot find entry for: "
+ (symbol-name cite-key) "\n"))))
+ keys-obarray)
+ (if (not the-text)
+ (error "Sorry, could not find any of the references"))
+ ;; Insert the citations in the new buffer
+ (set-buffer new-buffer)
+ (insert the-text)
+ (goto-char 1))
+
+ ;; We are at beginning of new-buffer.
+ ;; Now handle crossrefs
+ (let ((crossref-obarray (make-vector 201 0)))
+ (while (re-search-forward
+ "[, \t]*crossref[ \t]*=[ \t]*\\(\"\\|\{\\)" nil t)
+ ;;handle {text} or "text" cases
+ (if (string-equal "{" (match-string 1))
+ (re-search-forward "[^\}]+" nil t)
+ (re-search-forward "[^\"]+" nil t))
+ (intern (match-string 0) crossref-obarray))
+ ;; Now find the corresponding keys,
+ ;; but add them only if not already in `keys-obarray'
+ (set-buffer bib-buffer)
+ (goto-char 1)
+ (let ((the-text))
+ (mapatoms ;Do this for each crossref key found...
+ (lambda (crossref-key)
+ (if (not (intern-soft (symbol-name crossref-key) keys-obarray))
+ (progn
+ ;; Not in keys-obarray, so not yet displayed.
+ (goto-char (point-min))
+ (if (re-search-forward
+ (concat "@[^{(]+[{(][\t ]*"
+ (regexp-quote (symbol-name crossref-key))
+ "\\(,\\|$\\)")
+ nil t)
+ (setq the-text
+ (concat the-text
+ (buffer-substring
+ (progn (beginning-of-line)(point))
+ (progn (forward-sexp 2)(point)))
+ "\n\n"))
+ (setq the-warnings
+ (concat the-warnings
+ "Cannot find crossref entry for: "
+ (symbol-name crossref-key) "\n"))))))
+ crossref-obarray)
+ ;; Insert the citations in the new buffer
+ (set-buffer new-buffer)
+ (goto-char (point-max))
+ (if the-text
+ (insert the-text)))
+ (goto-char 1))
+
+ ;; Now we have all citations in new-buffer, collect all used @String keys
+ ;; Ex: journal = JPO,
+ (let ((strings-obarray (make-vector 201 0)))
+ (while (re-search-forward bib-string-regexp nil t)
+ (intern (match-string 1) strings-obarray))
+ ;; Now find the corresponding @String commands
+ ;; Collect either the @string commands, or the string to substitute
+ (set-buffer bib-buffer)
+ (goto-char 1)
+ (let ((string-alist)
+ (the-text))
+ (mapatoms ;Do this for each string-key found...
+ (lambda (string-key)
+ (goto-char (point-min))
+ ;; search for @string{ key = {text}} or @string{ key = "text"}
+ (if (re-search-forward
+ (concat "^[ \t]*@string[{(]"
+ (regexp-quote (symbol-name string-key))
+ "[\t ]*=[\t ]*\\(\"\\|\{\\)")
+ nil t)
+ (let ((the-string-start (1- (match-end 1))) ;catch bracket
+ ;;handle {text} or "text" cases
+ (the-string-end
+ (cond
+ ((string-equal "\"" (match-string 1))
+ (re-search-forward "[^\\]\"" nil t)
+ (point))
+ (t
+ (forward-char -1)
+ (forward-list 1)
+ (point)))))
+ (if substitute ;Collect substitutions
+ (setq string-alist
+ (append
+ string-alist
+ (list
+ (cons (symbol-name string-key)
+ ;(regexp-quote
+ (buffer-substring the-string-start
+ the-string-end)))));)
+ ;;Collect the strings command themseves
+ (setq the-text
+ (concat the-text
+ (buffer-substring
+ (progn (forward-char 1)(point))
+ (re-search-backward "^[ \t]*@string[{(]"
+ nil t))
+ "\n"))))
+ ;; @string entry not found
+ (if (not (member-cis (symbol-name string-key)
+ bib-string-ignored-warning))
+ (setq the-warnings
+ (concat the-warnings
+ "Cannot find @String entry for: "
+ (symbol-name string-key) "\n")))))
+ strings-obarray)
+ ;; Now we have `the-text' of @string commands,
+ ;; or the `string-alist' to substitute.
+ (set-buffer new-buffer)
+ (if substitute
+ (while string-alist
+ (goto-char 1)
+ (let* ((the-key (car (car string-alist)))
+ (the-string (cdr (car string-alist)))
+ (slashed-string ; "J. of Geo.\" -> "J. of Geo.\\\\"
+ (dired-replace-in-string
+ "\\\\" "\\\\" the-string)))
+
+ (while (re-search-forward
+ (concat "\\(^[, \t]*[a-zA-Z]+[ \t]*=[ \t]*\\)"
+ (regexp-quote the-key)
+ "\\([, \t\n]\\)")
+ nil t)
+ (replace-match (concat "\\1" slashed-string "\\2") t nil)))
+ (setq string-alist (cdr string-alist)))
+ ;; substitute is nil; Simply insert text of @string commands
+ (goto-char 1)
+ (if the-text
+ (insert the-text "\n")))
+ (goto-char 1))))
+
+ ;; We are done!
+ ;; Return the warnings...
+ the-warnings))
+
+;;; Following contributed by Michael Steiner <steiner@cs.uni-sb.de> The
+;; @string abbreviation are not case-sensitive, so we replaced the `member'
+;; test above with `member-cis' defined here:
+(defun member-cis (ELT LIST)
+ "Return non-nil if ELT is an element of LIST.
+All elements should be strings.
+Comparison is case-insensitive."
+ ;; If list is exhausted,
+ (if (null LIST)
+ nil ;; if null then we haven't found the element ...
+ ;; else split list and ...
+ (let((listelt (car LIST))(listrest (cdr LIST)))
+ ;; see if car is equal to ELT
+ (if (string-equal (downcase ELT) (downcase listelt))
+ t ;; if so return true
+ ;; else recurse for rest of list
+ (member-cis ELT listrest)))))
+
+(defun bib-get-citekeys-obarray ()
+ "Return obarray of citation key (within curly brackets) under cursor."
+ (save-excursion
+ ;; First find *only* a key *within a cite command
+ (let ((the-point (point))
+ (keys-obarray (make-vector 201 0)))
+ ;; First try to match a cite command
+ (if (and (skip-chars-backward "a-zA-Z") ;Stops on \ or {
+ (looking-at "[a-zA-Z]*cite[a-zA-Z]*"))
+ (progn
+ ;;skip over any optional arguments to \cite[][]{key} command
+ (skip-chars-forward "a-zA-Z")
+ (while (looking-at "\\[")
+ (forward-list 1))
+ (re-search-forward "{[ \n]*\\([^,} \n]+\\)" nil t)
+ (intern (match-string 1) keys-obarray)
+ (while (and (skip-chars-forward " \n") ;no effect on while
+ (looking-at ","))
+ (forward-char 1)
+ ;;The following re-search skips over leading spaces
+ (re-search-forward "\\([^,} \n]+\\)" nil t)
+ (intern (match-string 1) keys-obarray)))
+ ;; Assume we are on the keyword
+ (goto-char the-point)
+ (let ((the-start (re-search-backward "[\n{, ]" nil t))
+ (the-end (progn (goto-char the-point)
+ (re-search-forward "[\n}, ]" nil t))))
+ (if (and the-start the-end)
+ (intern (buffer-substring (1+ the-start) (1- the-end))
+ keys-obarray)
+ ;; Neither...
+ (error "Sorry, can't find a reference here"))))
+ keys-obarray)))
+
+(defun bib-buffer-citekeys-obarray ()
+ "Extract citations keys used in the current buffer."
+ (let ((keys-obarray (make-vector 201 0)))
+ (save-excursion
+ (goto-char (point-min))
+ ;; Following must allow for \cite[e.g.][]{key} !!!
+ ;; regexp for \cite{key1,key2} was "\\\\[a-Z]*cite[a-Z]*{\\([^,}]+\\)"
+ (while (re-search-forward "\\\\[a-zA-Z]*cite[a-zA-Z]*\\(\\[\\|{\\)"
+ nil t)
+ (backward-char 1)
+ (while (looking-at "\\[") ; ...so skip all bracketted options
+ (forward-sexp 1))
+ ;; then lookup first key
+ (if (looking-at "{[ \n]*\\([^,} \n]+\\)")
+ (progn
+ (intern (match-string 1) keys-obarray)
+ (goto-char (match-end 1))
+ (while (and (skip-chars-forward " \n")
+ (looking-at ","))
+ (forward-char 1)
+ (re-search-forward "\\([^,} \n]+\\)" nil t)
+ (intern (match-string 1) keys-obarray)))))
+ (if keys-obarray
+ keys-obarray
+ (error "Sorry, could not find any citation keys in this buffer")))))
+
+;;---------------------------------------------------------------------------
+;; Multi-file document programming requirements:
+;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;; bib-make-bibliography
+;; bib-document-citekeys-obarray needs the master .aux file to extract
+;; citation keys.
+;; Included .aux files (corresponding to \include'd LaTeX files) are
+;; then specified relative to the master-file-directory.
+;;
+;; bib-get-bibliography (used by interactive commands to extract bib sources)
+;;
+;; bibtex source filenames are returned from (LaTeX-bibliography-list)
+;; unformatted. Since only a single \bibliogragrphy command is allowed
+;; by BiBTeX in a document, it is safe to assume that their path is
+;; relative to the master file's directory (since the path is relative
+;; to where the BiBTeX program is actually ran).
+;;
+
+;; (See TeX-check-files, used in TeX-save-document. All documents related
+;; files are returned by (TeX-style-list) and stored in TeX-active-styles.
+;; Original idea was to search TeX-check-path for files listed in
+;; TeX-active-styles (with possible relative or full paths) that end in .tex.)
+
+(defun bib-master-directory ()
+ "Return the directory associated with the master file.
+If no master file, then return current default."
+ (let ((masterfile (bib-master-file)))
+ (if masterfile
+ (file-name-directory (expand-file-name (TeX-master-file)))
+ default-directory)))
+
+(defun bib-master-file ()
+ "Return master file full path, or nil if not a multi-file document."
+;; I wish there were a better way to tell about non multi-file documents...
+ (let ((master
+ (cond
+ ((not (boundp 'TeX-master))
+ ;; This buffer doesn't know what a master file is, so return now.
+ nil)
+ ((and TeX-master ;Set, but not to t
+ (not (symbolp TeX-master))) ; then we have an actual name
+ (expand-file-name TeX-master))
+ ((and (eq TeX-master 't) ;Test if master file itself
+ (progn ;But also require at least one \include
+ (save-excursion
+ (goto-char 1) ;Too bad I have to do this search...
+ ;; Require that user uses \input{file}
+ ;; rather than \input file
+ (re-search-forward "^[ \t]*\\\\\\(include\\|input\\){"
+ nil t))))
+ (buffer-file-name))
+ (t
+ nil))))
+ (cond
+ ((not master)
+ nil)
+ ((string-match ".\\(tex\\|ltx\\)$" master)
+ master)
+ ((file-readable-p (concat master ".ltx"))
+ (concat master ".ltx"))
+ (t
+ (concat master ".tex")))))
+
+;; I don't use this one because files are not returned in order...
+;; (defun bib-document-TeX-files ()
+;; ;; Return all tex input files associated with a known multi-file document.
+;; (let ((master-directory (bib-master-directory))
+;; (the-list (cons (file-name-nondirectory (TeX-master-file))
+;; (TeX-style-list)))
+;; ;; TeX-style-list returns "../master" for the main file if TeX-master
+;; ;; was set like that. "../master" would not be found relative
+;; ;; to the master-directory! So let's add it to the list w/o directory.
+;; (the-result)
+;; (the-file))
+;; (while the-list
+;; (setq the-file (expand-file-name (car the-list) master-directory))
+;; (setq the-list (cdr the-list))
+;; (and (not (string-match ".tex$" the-file))
+;; (setq the-file (concat the-file ".tex")))
+;; (and (file-readable-p the-file)
+;; (not (member the-file the-result)) ;listed already?
+;; (setq the-result (cons the-file the-result))))
+;; the-result))
+
+(defun bib-document-TeX-files ()
+ "Return all tex input files associated with a *known* multi-file document.
+For a multi-file document in auctex only.
+No checking is done that this is a real multi-file document.
+Sets global variable bib-document-TeX-files-warnings."
+ (setq bib-document-TeX-files-warnings nil)
+ (let* ((masterfile (bib-master-file))
+ (dir (and masterfile (file-name-directory masterfile)))
+ (tex-buffer (get-buffer-create "*tex-document*"))
+ (the-list (list masterfile))
+ (the-file))
+ (if (not masterfile)
+ (progn
+ (kill-buffer tex-buffer)
+ (error
+ "Sorry, but this is not a multi-file document (Try C-u C-c C-n if using auctex)")))
+ (save-excursion
+ (set-buffer tex-buffer)
+ ;; set its directory so relative includes work without expanding
+ (setq default-directory dir)
+ (insert-file-contents masterfile)
+ (goto-char (point-min))
+ (while (re-search-forward "^[ \t]*\\\\\\(input\\|include\\){\\(.*\\)}"
+ nil t)
+ (let ((the-file (match-string 2)))
+ (if (string-match ".sty$" the-file) ;Skip over style files!
+ nil
+ (if (and (not (file-readable-p (expand-file-name the-file dir)))
+ (not (string-match ".ltx$" the-file))
+ (file-readable-p
+ (expand-file-name (concat the-file ".ltx") dir)))
+ (setq the-file (concat the-file ".ltx")))
+ (if (and (not (file-readable-p (expand-file-name the-file dir)))
+ (not (string-match ".tex$" the-file)))
+ (setq the-file (concat the-file ".tex")))
+ (setq the-file (expand-file-name the-file dir))
+ (if (not (file-readable-p the-file))
+ (setq bib-document-TeX-files-warnings
+ (concat
+ bib-document-TeX-files-warnings
+ (format "Warning: File not found: %s" the-file)))
+ (setq the-list (cons (expand-file-name the-file dir) the-list))
+ (end-of-line)(insert "\n")
+ (insert-file-contents the-file))))))
+ (kill-buffer tex-buffer)
+ (nreverse the-list)))
+
+(defun bib-document-citekeys-obarray ()
+ "Return cite keys obarray for multi-file document.
+Return nil if not a multi-file document.
+This is a AUCTeX supported feature only.
+Also, see bib-buffer-citekeys-obarray.
+Sets global variable bib-document-citekeys-obarray-warnings."
+ (setq bib-document-citekeys-obarray-warnings nil)
+ (let ((master-tex (bib-master-file))
+ (master-aux))
+ (if (not master-tex)
+ nil ;Not a multifile document. No need...
+ (setq master-aux (bib-return-aux-file-from-tex master-tex "aux"))
+ (or (file-readable-p master-aux)
+ (error "Sorry, cannot read file %s" master-aux))
+ (and (file-newer-than-file-p master-tex master-aux)
+ (setq bib-document-citekeys-obarray-warnings
+ (format "Warning: %s is out of date relative to %s.\n"
+ master-aux master-tex)))
+ (let ((work-buffer (get-buffer-create "*bib-cite-work*"))
+ (keys-obarray (make-vector 201 0)))
+ (save-excursion
+ (set-buffer work-buffer)
+ (insert-file-contents master-aux)
+ ;; Because we will be looking for \input statements, we need to set
+ ;; the default directory to that of the master file.
+ (setq default-directory (file-name-directory master-tex))
+ ;; bib-make-bibliography will need this also to find .bib files
+ ;; look for \@input{chap1/part1.aux}
+ (while (re-search-forward "^\\\\@input{\\(.*\\)}$" nil t)
+ (let* ((auxfile (match-string 1))
+ (texfile (bib-return-aux-file-from-tex auxfile "tex")))
+ (if (not (file-readable-p auxfile))
+ (setq bib-document-citekeys-obarray-warnings
+ (concat
+ bib-document-citekeys-obarray-warnings
+ (format "Warning: %s is not found or readable.\n"
+ auxfile)))
+ (if (file-newer-than-file-p texfile auxfile)
+ (setq bib-document-citekeys-obarray-warnings
+ (concat
+ bib-document-citekeys-obarray-warnings
+ (format
+ "Warning: %s is out of date relative to %s.\n"
+ auxfile texfile))))
+ (end-of-line)(insert "\n")
+ (insert-file-contents auxfile))))
+ (goto-char 1)
+
+;;; Patched by calvanes@dis.uniroma1.it (Diego Calvanese)
+;;; ;; look for \citation{gertsenshtein59}
+;;; (while (re-search-forward "^\\\\citation{\\(.*\\)}$" nil t)
+;;; (intern (buffer-substring (match-beginning 1)(match-end 1))
+;;; keys-obarray))
+ ;; look for \citation{gertsenshtein59,vardi88,...,ullmann90}
+ ;; comma-separation generated by certain LaTeX styles.
+ (while (re-search-forward "^\\\\citation{\\(.*\\)}$" nil t)
+ (let ((string (match-string 1))
+ (start 0))
+ (while (string-match "\\([^,\n]+\\)" string start)
+ (intern (substring string (match-beginning 1) (match-end 1))
+ keys-obarray)
+ (setq start (match-end 0))))))
+ (kill-buffer work-buffer)
+ keys-obarray))))
+
+(defun bib-return-aux-file-from-tex (texname ext)
+ "Given name.name.XXX in TEXNAME return name.name.EXT."
+;; FIXME: Check if in ./, else search
+ (let* ((filename (if (string-match "\\(.*\\)\\.[^\\.]+" texname)
+ (concat (match-string 1 texname) "." ext)
+ (concat texname "." ext)))
+ (sansdir (file-name-nondirectory filename)))
+ (if (file-exists-p filename)
+ filename
+ ;; Search bib-cite-aux-inputs path
+ (let ((filename (psg-checkfor-file-list sansdir bib-cite-aux-inputs)))
+ (if (and filename (file-exists-p filename))
+ filename
+ (error "Could not find file %s" sansdir))))))
+
+(defun bib-etags-find-noselect (tag &optional masterdir)
+ "Returns a buffer with point on TAG.
+Buffer is not selected.
+Makes sure TAGS file exists, etc."
+ (require 'etags)
+ (let* ((master (or masterdir (bib-master-directory)))
+ (the-buffer (current-buffer))
+ (new-buffer)
+ (the-tags-file-name (expand-file-name bib-etags-filename master)))
+ (or (file-exists-p the-tags-file-name) ;make sure TAGS exists
+ (bib-etags master))
+ (or (equal the-tags-file-name tags-file-name) ;make sure it's current
+ (visit-tags-table the-tags-file-name))
+ ;; find-tag-noselect should set the TAGS file for the new buffer
+ ;; that's what C-h f visit-tags-table says...
+ (cond
+ ((string-match "XEmacs\\|Lucid" emacs-version)
+ (find-tag tag)
+ (setq new-buffer (current-buffer))
+ (set-buffer the-buffer))
+ (t
+ (setq new-buffer (find-tag-noselect tag nil t))
+ ; -> Seems to set buffer to TAGS
+ (set-buffer the-buffer)))
+ new-buffer))
+
+;; --------------------------------------------------------------------------
+;; The following routines make a temporary bibliography buffer
+;; holding all bibtex files found.
+
+(defun bib-get-bibliography (include-filenames-f)
+ "Returns a new bibliography buffer holding all bibtex files in the document.
+
+If using AUCTeX, and either TeX-parse-self is set or C-c C-n is used to
+parse the document, then the entire multifile document will be searched
+for \bibliography commands.
+
+If this fails, the current buffer is searched for the first \bibliography
+command.
+
+If include-filenames-f is true, include as a special header the filename
+of each bib file.
+
+Puts the buffer in text-mode such that forward-sexp works with german \"
+accents embeded in bibtex entries."
+ (let ((bib-list (or (and (fboundp 'LaTeX-bibliography-list)
+ (boundp 'TeX-auto-update)
+ (LaTeX-bibliography-list))
+;; LaTeX-bibliography-list (if bound) returns an unformatted list of
+;; bib files used in the document, but only if parsing is turned on
+;; or C-c C-n was used.
+ (bib-bibliography-list)))
+ (bib-buffer (get-buffer-create "*bibtex-bibliography*"))
+ ;; Path is relative to the master directory
+ (default-directory (bib-master-directory))
+ (the-name)(the-warnings)(the-file))
+ (save-excursion
+ ;; such that forward-sexp works with embeeded \" in german,
+ ;; and unbalanced ()
+ (set-buffer bib-buffer)
+ (erase-buffer)
+ (set-syntax-table text-mode-syntax-table)
+;; (if (boundp 'bibtex-mode-syntax-table)
+;; (set-syntax-table bibtex-mode-syntax-table)
+;; (text-mode))
+ )
+ ;;We have a list of bib files
+ ;;Search for them, include them, list those not readable
+ (while bib-list
+ (setq the-name (car (car bib-list))) ;Extract the string only
+ (setq bib-list (cdr bib-list))
+ (setq the-name
+ (substring the-name
+ (string-match "[^ ]+" the-name) ;remove leading spaces
+ (string-match "[ ]+$" the-name))) ;remove trailing space
+ (if (not (string-match "\\.bib$" the-name))
+ (setq the-name (concat the-name ".bib")))
+ (setq the-file
+ (or (and (file-readable-p the-name) the-name)
+ (psg-checkfor-file-list
+ the-name (psg-list-env bib-bibtex-env-variable))
+ ;; Check for BIBINPUT env variable as well (by popular demand!)
+ (psg-checkfor-file-list the-name (psg-list-env "BIBINPUT"))
+ (and bib-cite-inputs
+ (psg-checkfor-file-list the-name bib-cite-inputs))
+ (and (boundp 'TeX-check-path)
+ (psg-checkfor-file-list the-name TeX-check-path))))
+ (if the-file
+ (progn
+ (save-excursion
+ (set-buffer bib-buffer)
+ (goto-char (point-max))
+ (if include-filenames-f
+ (insert "%%%Filename: " the-file "\n"))
+ (insert-file-contents the-file nil)
+ (goto-char 1)))
+ (setq the-warnings
+ (concat the-warnings "Could not read file: " the-name "\n"))))
+ (if the-warnings
+ (progn
+ (with-output-to-temp-buffer "*Help*"
+ (princ the-warnings))
+ (kill-buffer bib-buffer)
+ (error
+ "Sorry, can't find all bibtex files in \\bibliography command"))
+ bib-buffer)))
+
+(defun bib-bibliography-list ()
+ "Return list of bib files listed in first \\bibliography command in buffer.
+Similar output to AUCTeX's LaTeX-bibliography-list
+The first element may contain trailing whitespace (if there was any in input)
+although BiBTeX doesn't allow it!"
+ (save-excursion
+ (goto-char 1)
+ (if (not (re-search-forward "^[ \t]*\\\\bibliography{[ \t]*\\([^},]+\\)"
+ nil t))
+ (error "Sorry, can't find \\bibliography command anywhere")
+ (let ((the-list (list (match-string 1)))
+ (doNext t))
+ (while doNext
+ (if (looking-at ",")
+ (setq the-list
+ (append the-list
+ (list (buffer-substring
+ (progn (skip-chars-forward ", ")(point))
+ (progn (re-search-forward "[,}]" nil t)
+ (backward-char 1)
+ (skip-chars-backward ", ")
+ (point))))))
+ (setq doNext nil)))
+ (mapcar 'list the-list)))))
+
+;; BibTeX-mode key def to create AUCTeX's parsing file.
+(defun bib-create-auto-file ()
+ "Force the creation of the AUCTeX auto file for a bibtex buffer."
+ (interactive)
+ (if (not (require 'latex))
+ (error "Sorry, This is only useful if you have AUCTeX"))
+ (let ((TeX-auto-save t)
+ (TeX-auto-update t)
+ (TeX-auto-regexp-list BibTeX-auto-regexp-list))
+ ;; TeX-auto-write
+ ;; -> calls TeX-auto-store
+ ;; -> calls TeX-auto-parse
+ ;; clears LaTeX-auto-bibtem (temporary holding space for bibitems)
+ ;; searches buffer using regexp in TeX-auto-regexp-list
+ ;; -> if LaTeX-auto-bibtem (the temporary holding space for bibitems)
+ ;; holds stuffs like
+ ;; ("Zimmermann:1991" "Anger_et_al:1993")
+ ;; as determined by
+ ;; (member nil (mapcar 'TeX-auto-entry-clear-p TeX-auto-parser))
+ ;; then it creates the auto file.
+
+ ;; TeX-auto-write may call TeX-master-file which may fail if
+ ;; TeX-header-end is unset (by LaTeX-common-initialization in latex-mode)
+ (if (not TeX-header-end)
+ (setq TeX-header-end LaTeX-header-end))
+
+ (TeX-auto-write)))
+
+;; --------------------------------------------------------------------------
+;; The following routines are also defined in other packages...
+
+(defun psg-checkfor-file-list (filename list)
+ "Check for presence of FILENAME in directory LIST. Return 1st found path."
+ ;;USAGE: (psg-checkfor-file-list "gri" (psg-list-env "PATH"))
+ ;;USAGE: (psg-checkfor-file-list "gri-mode.el" load-path)
+ ;;USAGE: (psg-checkfor-file-list "gri.cmd" (psg-translate-ff-list "gri.tmp"))
+ (let ((the-list list)
+ (filespec))
+ (while the-list
+ (if (not (car the-list)) ; it is nil
+ (setq filespec (expand-file-name filename))
+ (setq filespec
+ (concat
+ (expand-file-name (file-name-as-directory (car the-list)))
+ filename)))
+ (if (file-exists-p filespec)
+ (setq the-list nil)
+ (setq filespec nil)
+ (setq the-list (cdr the-list))))
+ (if filespec
+ filespec
+ ;; If I have not found a file yet, then check if some directories
+ ;; ended in // and recurse through them.
+ (let ((the-list list))
+ (while the-list
+ (if (not (string-match "//$" (car the-list))) nil
+ (setq filespec (car
+ (search-directory-tree
+ (substring (car the-list) 0 (match-beginning 0))
+ (concat "^" filename "$")
+ t
+ t)))
+ (if filespec ;Success!
+ (setq the-list nil)))
+ (setq the-list (cdr the-list)))
+ filespec))))
+
+
+(defun search-directory-tree (directories extension-regexp recurse first-file)
+ "Return a list of all reachable files in DIRECTORIES ending with EXTENSION.
+DIRECTORIES is a list or a single-directory string
+EXTENSION-REGEXP is actually (any) regexp, usually \\\\.bib$
+If RECURSE is t, then we will recurse into the directory tree,
+ nil, we will only search the list given.
+If FIRST-FILE is t, stop after first file is found."
+ (or (listp directories)
+ (setq directories (list directories)))
+
+ (let (match)
+ (while directories
+ (let* ((directory (file-name-as-directory (car directories)))
+ (content (and directory
+ (file-readable-p directory)
+ (file-directory-p directory)
+ (directory-files directory))))
+ (setq directories (cdr directories))
+ (while content
+ (let ((file (expand-file-name (car content) directory)))
+ (cond ((string-match "[.]+$" (car content))) ;This or parent dir
+ ((not (file-readable-p file)))
+ ((and recurse
+ (file-directory-p file))
+ (setq directories
+ (cons (file-name-as-directory file) directories)))
+ ((string-match extension-regexp
+ (file-name-nondirectory file))
+ (and first-file
+ (setq content nil
+ directories nil))
+ (setq match (cons file match)))))
+ (setq content (cdr content)))))
+
+ match))
+
+;;; (defun psg-checkfor-file-list (filename list)
+;;; (let ((the-list list)
+;;; (filespec))
+;;; (while the-list
+;;; (if (not (car the-list)) ; it is nil
+;;; (setq filespec (concat "~/" filename))
+;;; (setq filespec
+;;; (concat (file-name-as-directory (car the-list)) filename)))
+;;; (if (file-exists-p filespec)
+;;; (setq the-list nil)
+;;; (setq filespec nil)
+;;; (setq the-list (cdr the-list))))
+;;; filespec))
+
+(or (fboundp 'dired-replace-in-string)
+ ;; This code is part of GNU emacs
+ (defun dired-replace-in-string (regexp newtext string)
+ ;; Replace REGEXP with NEWTEXT everywhere in STRING and return result.
+ ;; NEWTEXT is taken literally---no \\DIGIT escapes will be recognized.
+ (let ((result "") (start 0) mb me)
+ (while (string-match regexp string start)
+ (setq mb (match-beginning 0)
+ me (match-end 0)
+ result (concat result (substring string start mb) newtext)
+ start me))
+ (concat result (substring string start)))))
+
+
+;; Could use fset here to equal TeX-split-string to dired-split if only
+;; dired-split is defined. That would eliminate a check in psg-list-env.
+(and (not (fboundp 'TeX-split-string))
+ (not (fboundp 'dired-split))
+ ;; This code is part of AUCTeX
+ (defun TeX-split-string (char string)
+ "Returns a list of strings. given REGEXP the STRING is split into
+sections which in string was seperated by REGEXP.
+
+Examples:
+
+ (TeX-split-string \"\:\" \"abc:def:ghi\")
+ -> (\"abc\" \"def\" \"ghi\")
+
+ (TeX-split-string \" *\" \"dvips -Plw -p3 -c4 testfile.dvi\")
+
+ -> (\"dvips\" \"-Plw\" \"-p3\" \"-c4\" \"testfile.dvi\")
+
+If CHAR is nil, or \"\", an error will occur."
+
+ (let ((regexp char)
+ (start 0)
+ (result '()))
+ (while (string-match regexp string start)
+ (let ((match (string-match regexp string start)))
+ (setq result (cons (substring string start match) result))
+ (setq start (match-end 0))))
+ (setq result (cons (substring string start nil) result))
+ (nreverse result))))
+
+(defun bib-cite-file-directory-p (file)
+ "Like default `file-directory-p' but allow FILE to end in // for ms-windows."
+ (save-match-data
+ (if (string-match "\\(.*\\)//$" file)
+ (file-directory-p (match-string 1 file))
+ (file-directory-p file))))
+
+(defun psg-list-env (env)
+ "Return a list of directory elements in ENV variable (w/o leading $)
+argument may consist of environment variable plus a trailing directory, e.g.
+HOME or HOME/bin (trailing directory not supported in dos or OS/2).
+
+bib-dos-or-os2-variable affects:
+ path separator used (: or ;)
+ whether backslashes are converted to slashes"
+ (if (not (getenv env))
+ nil ;Because dired-replace-in-string fails
+ (let* ((value (if bib-dos-or-os2-variable
+ (dired-replace-in-string "\\\\" "/" (getenv env))
+ (getenv env)))
+ (sep-char (or (and bib-dos-or-os2-variable ";") ":"))
+ (entries (and value
+ (or (and (fboundp 'TeX-split-string)
+ (TeX-split-string sep-char value))
+ (dired-split sep-char value)))))
+ (loop for x in entries if (bib-cite-file-directory-p x) collect x))))
+
+(provide 'bib-cite)
+;;; bib-cite.el ends here
--- /dev/null
+;;; context-en.el --- Support for the ConTeXt english interface.
+
+;; Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+;; Maintainer: Berend de Boer <berend@pobox.com>
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file is loaded by context.el when required.
+
+;;; Code:
+
+;; Build upon ConTeXt
+(require 'context)
+
+;;; ConText macro names
+
+;;; Code:
+(defvar ConTeXt-environment-list-en
+ '("alignment" "appendices"
+ "background" "backmatter" "bodymatter" "bodypart" "buffer"
+ "code" "color" "columns" "combination"
+ "encoding" "extroductions"
+ "fact" "formula" "framedcode" "framedtext" "frontmatter"
+ "helptext" "hiding"
+ "itemize"
+ "legend" "line" "linecorrection" "linenumbering" "lines"
+ "localenvironment" "localfootnotes"
+ "makeup" "mapping" "marginblock" "marginedge" "marginrule" "mode"
+ "narrower" "notmode"
+ "opposite"
+ "packed" "pagecomment" "pagefigure" "positioning" "postponing"
+ "quotation"
+ "raster" "register"
+ "standardmakeup"
+ "table" "tabulate" "TEXpage" "text" "textbackground" "typing"
+ "unpacked"
+ ;; project structure
+ "component" "environment" "product" "project"
+ ;; flowcharts, if you have loaded this module
+ "FLOWcell" "FLOWchart"
+ ;; typesetting computer languages
+ "EIFFEL" "JAVA" "JAVASCRIPT" "MP" "PASCAL" "PERL" "SQL" "TEX" "XML"
+ ;; some metapost environments
+ "MPpositiongraphic" "useMPgraphic" "MPcode" "reusableMPgraphic"
+ "uniqueMPgraphic")
+ "List of the ConTeXt en interface start/stop pairs.")
+
+(defvar ConTeXt-define-list-en
+ '("accent"
+ "background" "blank" "block" "blocks" "bodyfont" "bodyfontenvironment"
+ "buffer"
+ "casemap" "character" "color" "colorgroup" "combinedlist" "command"
+ "description" "enumeration"
+ "float" "font" "fontsynonym" "framedtext" "head"
+ "indenting" "label"
+ "logo" "overlay"
+ "palet" "program" "startstop" "type" "typing")
+ "List of the names of ConTeXt en interface macro's that define things.")
+
+(defvar ConTeXt-setup-list-en
+ '("align" "arranging" "background" "backgrounds" "blackrules"
+ "blank" "block" "bodyfont" "bodyfontenvironment" "bottom"
+ "bottomtexts" "buffer" "capitals" "caption" "captions" "color"
+ "colors" "columns" "combinations" "combinedlist" "descriptions"
+ "enumerations" "externalfigures" "fillinlines" "fillinrules" "float"
+ "floats" "footer" "footertexts" "footnodedefinition" "footnotes"
+ "framed" "framedtexts" "head" "header" "headertexts" "headnumber"
+ "heads" "headtext" "hyphenmark" "indentations" "indenting" "inmargin"
+ "interlinespace" "itemize" "items" "labeltext" "language" "layout"
+ "linenumbering" "lines" "list" "makeup" "marginblocks"
+ "marginrules" "marking" "narrower" "oppositeplacing"
+ "pagecomment" "pagenumber" "pagenumbering" "palet" "papersize" "paragraphs"
+ "quote" "referencing" "register"
+ "screens" "section" "sectionblock" "sorting" "spacing"
+ "subpagenumber" "synonyms" "text" "textrules" "texttexts" "thinrules"
+ "tolerance" "top" "toptexts" "type" "typing" "underbar" "whitespace")
+ "List of the names of ConTeXt en interface macro's that setup things.")
+
+;; referencing in ConTeXt
+(defvar ConTeXt-referencing-list-en
+ '("in" "at" "about" "pagereference" "textreference" "reference")
+ "List of ConTeXt en macro's that are used for referencing."
+)
+
+;; lists some place macro's as well, should perhaps be under separate menu
+(defvar ConTeXt-other-macro-list-en
+ '("abbreviation" "adaptlayout" "at" "combinepages" "copypages"
+ "externalfigure" "framed" "from" "input" "insertpages" "filterpages"
+ "getbuffer" "goto"
+ "hideblocks" "keepblocks"
+ "leftaligned" "midaligned"
+ "obeyspaces"
+ "page"
+ "placecontent" "placeexternalfigure" "placefigure" "placelogos" "placetable"
+ "processblocks" "protect"
+ "raggedcenter" "rightaligned" "rotate"
+ "scale" "selectblocks" "showexternalfigures" "slicepages"
+ "useexternalfigure" "unprotect" "url" "useblocks" "usemodule" "useURL"
+ "version")
+ "List of ConTeXt en interface macro's that are not an environment nor a setup.")
+
+(defun ConTeXt-define-command-en (what)
+ "The ConTeXt en interface way of creating a define command."
+ (concat "define" what))
+
+(defun ConTeXt-setup-command-en (what)
+ "The ConTeXt en interface way of creating a setup command."
+ (concat "setup" what))
+
+(defvar ConTeXt-project-structure-list-en
+ '("project" "environment" "product" "component")
+ "List of the names of ConTeXt project structure elements for its en interface. List should be in logical order.")
+
+(defvar ConTeXt-section-block-list-en
+ '("frontmatter" "bodymatter" "appendices" "backmatter")
+ "List of the names of ConTeXt section blocks for its en interface. List should be in logical order.")
+
+
+;; TODO:
+;; ConTeXt has alternative sections like title and subject. Currently
+;; the level is used to find the section name, so the alternative
+;; names are never found. Have to start using the section name instead
+;; of the number.
+(defvar ConTeXt-section-list-en
+ '(("part" 0)
+ ("chapter" 1)
+ ("section" 2)
+ ("subsection" 3)
+ ("subsubsection" 4))
+ ;; ("title" 1)
+ ;; ("subject" 2)
+ ;; ("subsubject" 3)
+ ;; ("subsubsubject" 4)
+ "List of the names of ConTeXt sections for its en interface.")
+
+(defvar ConTeXt-text-en "text"
+ "The ConTeXt en interface body text group.")
+
+(defvar ConTeXt-item-list-en
+ '("item" "its" "mar" "ran" "sub" "sym")
+ "The ConTeXt macro's that are variants of item.")
+
+(defcustom ConTeXt-default-environment-en "itemize"
+ "*The default environment when creating new ones with `ConTeXt-environment'."
+ :group 'ConTeXt-en-environment
+ :type 'string)
+
+
+;; Emacs en menu names and labels should go here
+;; to be done
+
+
+;;; Mode
+
+(defun ConTeXt-en-mode-initialization ()
+ "ConTeXt english interface specific initialization."
+ (mapc 'ConTeXt-add-environments (reverse ConTeXt-environment-list-en))
+
+ (TeX-add-symbols
+ '("but" ConTeXt-arg-define-ref (TeX-arg-literal " "))
+ '("item" ConTeXt-arg-define-ref (TeX-arg-literal " "))
+ '("items" [ConTeXt-arg-setup] (TeX-arg-string "Comma separated list"))
+ '("its" ConTeXt-arg-define-ref (TeX-arg-literal " "))
+ '("nop" (TeX-arg-literal " "))
+ '("ran" TeX-arg-string (TeX-arg-literal " "))
+ '("sub" ConTeXt-arg-define-ref (TeX-arg-literal " "))
+ '("sym" (TeX-arg-string "Symbol") (TeX-arg-literal " "))))
+
+;;;###autoload
+(defun context-en-mode ()
+ "Major mode for editing files for ConTeXt using its english interface.
+
+Special commands:
+\\{ConTeXt-mode-map}
+
+Entering `context-mode' calls the value of `text-mode-hook',
+then the value of TeX-mode-hook, and then the value
+of context-mode-hook."
+ (interactive)
+ ;; set the ConTeXt interface
+ (setq ConTeXt-current-interface "en")
+
+ ;; initialization
+ (ConTeXt-mode-common-initialization)
+ (ConTeXt-en-mode-initialization)
+
+ ;; set mode line
+ (setq TeX-base-mode-name "ConTeXt-en")
+ (TeX-set-mode-name))
+
+(provide 'context-en)
+
+;;; context-en.el ends here
--- /dev/null
+;;; context-nl.el --- Support for the ConTeXt dutch interface.
+
+;; Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+;; Maintainer: Berend de Boer <berend@pobox.com>
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file is loaded by context.el when required.
+
+;;; Code:
+
+;; Build upon ConTeXt
+(require 'context)
+
+;;; ConText macro names
+
+(defvar ConTeXt-environment-list-nl
+ '("achtergrond" "alinea" "bloktekst" "buffer" "citaat" "combinatie"
+ "commentaar" "deelomgeving" "document" "doordefinitie"
+ "doornummering" "figuur" "formule" "gegeven" "interactiemenu"
+ "kadertekst" "kantlijn" "kleur" "kolommen" "legenda" "lokaal"
+ "lokalevoetnoten" "margeblok" "naamopmaak" "naast"
+ "opelkaar" "opmaak" "opsomming" "overlay" "overzicht"
+ "paginafiguur" "positioneren" "profiel"
+ "regel" "regelcorrectie" "regelnummeren" "regels"
+ "smaller" "symboolset" "synchronisatie"
+ "tabel" "tabellen" "tabulatie" "tekstlijn" "typen"
+ "uitlijnen" "uitstellen" "vanelkaar" "verbergen" "versie"
+ ;; project structure
+ "omgeving" "onderdeel" "produkt" "project"
+ ;; flowcharts, if you have loaded this module
+ "FLOWcell" "FLOWchart"
+ ;; typesetting computer languages
+ "EIFFEL" "JAVA" "JAVASCRIPT" "MP" "PASCAL" "PERL" "SQL" "TEX" "XML"
+ ;; some metapost environments
+ "MPpositiongraphic" "useMPgraphic" "MPcode" "reusableMPgraphic"
+ "uniqueMPgraphic")
+ "List of the ConTeXt nl interface start/stop pairs.")
+
+(defvar ConTeXt-define-list-nl
+ '("achtergrond" "startstop" "typen")
+ "List of ConTeXt nl interface macro's that define things.")
+
+(defvar ConTeXt-setup-list-nl
+ '("achtergronden" "achtergrond" "alineas" "arrangeren" "blanko"
+ "blok" "blokjes" "blokkopje" "blokkopjes" "boven" "boventeksten"
+ "brieven" "buffer" "buttons" "citeren" "clip" "combinaties"
+ "commentaar" "doordefinieren" "doornummeren" "doorspringen"
+ "dunnelijnen" "externefiguren" "formules" "formulieren"
+ "hoofd" "hoofdteksten" "inmarge" "inspringen" "interactiebalk"
+ "interactie" "interactiemenu" "interactiescherm" "interlinie"
+ "invullijnen" "invulregels" "items" "kaderteksten" "kantlijn"
+ "kapitalen" "kleuren" "kleur" "kolommen" "kop" "kopnummer"
+ "koppelteken" "koppen" "koptekst" "korps" "korpsomgeving"
+ "labeltekst" "layout" "legenda" "lijndikte" "lijn" "lijst"
+ "margeblokken" "markering" "naastplaatsen" "nummeren" "omlijnd"
+ "onder" "onderstrepen" "onderteksten" "opmaak" "opsomming"
+ "paginanummer" "paginanummering" "paginaovergangen" "palet"
+ "papierformaat" "papier" "paragraafnummeren" "plaatsblok"
+ "plaatsblokken" "plaatsblokkensplitsen" "positioneren" "profielen"
+ "programmas" "publicaties" "rasters" "referentielijst" "refereren"
+ "regelnummeren" "regels" "register" "roteren" "samengesteldelijst"
+ "sectieblok" "sectie" "sheets" "smaller" "sorteren" "spatiering"
+ "stickers" "strut" "strut" "subpaginanummer" "symboolset"
+ "synchronisatiebalk" "synchronisatie" "synoniemen" "systeem"
+ "taal" "tabellen" "tab" "tabulatie" "tekst" "tekstlijnen"
+ "tekstpositie" "tekstteksten" "tekstvariabele" "tolerantie" "type"
+ "typen" "uitlijnen" "uitvoer" "url" "velden" "veld" "versies"
+ "voet" "voetnootdefinitie" "voetnoten" "voetteksten" "witruimte")
+ "List of the names of ConTeXt nl interface macro's that setup things.")
+
+(defvar ConTeXt-other-macro-list-nl
+ '("regellinks" "regelmidden" "regelrechts" "toonexternefiguren")
+ "List of ConTeXt nl interface macro's that are not an environment nor a setup.")
+
+(defun ConTeXt-define-command-nl (what)
+ "The ConTeXt nl interface way of creating a define command."
+ (concat "definieer" what))
+
+(defun ConTeXt-setup-command-nl (what)
+ "The ConTeXt nl interface way of creating a setup command."
+ (concat "stel" what "in"))
+
+(defvar ConTeXt-project-structure-list-nl
+ '("project" "omgeving" "produkt" "onderdeel")
+ "List of the names of ConTeXt project structure elements for its nl interface. List should be in logical order.")
+
+(defvar ConTeXt-section-block-list-nl
+ '("inleidingen" "hoofdteksten" "bijlagen" "uitleidingen")
+ "List of the names of ConTeXt section blocks for its nl interface. List should be in logical order.")
+
+
+;; TODO:
+;; ConTeXt has alternative sections like title and subject. Currently
+;; the level is used to find the section name, so the alternative
+;; names are never found. Have to start using the section name instead
+;; of the number.
+(defvar ConTeXt-section-list-nl
+ '(("deel" 0)
+ ("hoofdstuk" 1)
+ ("paragraaf" 2)
+ ("subparagraaf" 3)
+ ("subsubparagraaf" 4))
+ ;; ("title" 1)
+ ;; ("subject" 2)
+ ;; ("subsubject" 3)
+ ;; ("subsubsubject" 4)
+ "List of the names of ConTeXt sections for its nl interface.")
+
+(defvar ConTeXt-text-nl "tekst"
+ "The ConTeXt nl interface body text group.")
+
+(defvar ConTeXt-item-list-nl
+ '("som" "its" "mar" "ran" "sub" "sym")
+ "The ConTeXt macro's that are variants of item.")
+
+(defcustom ConTeXt-default-environment-nl "opsomming"
+ "*The default environment when creating new ones with `ConTeXt-environment'."
+ :group 'ConTeXt-nl-environment
+ :type 'string)
+
+
+;; Emacs en menu names and labels should go here
+;; to be done
+
+
+;;; Mode
+
+(defun ConTeXt-nl-mode-initialization ()
+ "ConTeXt dutch interface specific initialization."
+ (mapc 'ConTeXt-add-environments (reverse ConTeXt-environment-list-nl))
+
+ (TeX-add-symbols
+ '("but" ConTeXt-arg-define-ref (TeX-arg-literal " "))
+ '("som" ConTeXt-arg-define-ref (TeX-arg-literal " "))
+ '("items" [ConTeXt-arg-setup] (TeX-arg-string "Comma separated list"))
+ '("its" ConTeXt-arg-define-ref (TeX-arg-literal " "))
+ '("nop" (TeX-arg-literal " "))
+ '("ran" TeX-arg-string (TeX-arg-literal " "))
+ '("sub" ConTeXt-arg-define-ref (TeX-arg-literal " "))
+ '("sym" (TeX-arg-string "Symbol") (TeX-arg-literal " "))))
+
+;;;###autoload
+(defun context-nl-mode ()
+ "Major mode for editing files for ConTeXt using its dutch interface.
+
+Special commands:
+\\{ConTeXt-mode-map}
+
+Entering `context-mode' calls the value of `text-mode-hook',
+then the value of TeX-mode-hook, and then the value
+of context-mode-hook."
+ (interactive)
+
+ ;; set the ConTeXt interface
+ (setq ConTeXt-current-interface "nl")
+
+ ;; initialization
+ (ConTeXt-mode-common-initialization)
+ (ConTeXt-nl-mode-initialization)
+
+ ;; set mode line
+ (setq TeX-base-mode-name "ConTeXt-nl")
+ (TeX-set-mode-name))
+
+(provide 'context-nl)
+
+;;; context-nl.el ends here
--- /dev/null
+;;; context.el --- Support for ConTeXt documents.
+
+;; Copyright (C) 2003, 2004, 2005, 2006, 2008 Free Software Foundation, Inc.
+
+;; Maintainer: Berend de Boer <berend@pobox.com>
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This is in progress ConTeXt support for AUCTeX. Please report
+;; anomalies or things you believe should be added.
+
+;; AUCTeX is closely interwoven with LaTeX. We have to split up
+;; things without breaking 'em.
+
+;; some parts are stolen from latex.el and adapted to ConTeXt.
+
+;; TODO
+;; 1. indentation still bad.
+;; 2. paragraph refilling doesn't work 100%, and is very slow.
+;; 4. Remove dependency on LaTeX by moving LaTeX commands to TeX.
+;; 5. Most ConTeXt macro's don't currently have lisp code to query for
+;; arguments. As ConTeXt arguments are quite complex, the LaTeX way
+;; of querying for arguments just doesn't cut it.
+;; 6. Check auto-parsing: does it detect % interface=nl for example?
+;; 7. Complete adding ConTeXt macro's. Perhaps parse cont-en.xml and
+;; generate the interfaces?
+;; 8. Add to menu: make TeX hash (mktexlsr), context format and metapost format.
+
+;; TODO Documentation
+;; 1. multifile done differently with ConTeXt
+
+;;; Code:
+
+(require 'tex-buf)
+(require 'tex)
+;; need functions like TeX-look-at and LaTeX-split-long-menu
+(require 'latex)
+
+(defgroup ConTeXt-macro nil
+ "Special support for ConTeXt macros in AUCTeX."
+ :prefix "TeX-"
+ :group 'ConTeXt
+ :group 'TeX-macro)
+
+
+;;; variables
+
+;; globals used in certain macro's.
+(defvar done-mark nil
+ "Position of point afterwards, default nil (meaning end).")
+
+(defvar reference nil
+ "Set by `ConTeXt-section-ref', used by `ConTeXt-section-section'.")
+
+(defvar title nil
+ "Set by `ConTeXt-section-title', used by `ConTeXt-section-section'.")
+
+
+;; others
+
+(defvar ConTeXt-known-interfaces '("cz" "de" "en" "it" "nl" "ro" "uk"))
+
+(defcustom ConTeXt-default-interface "en"
+ "Default interface to be used when running ConTeXt."
+ :group 'ConTeXt
+ :type 'string)
+
+(defvar ConTeXt-current-interface "en"
+ "Interface to be used for inserting macros and ConTeXt run.")
+(make-variable-buffer-local 'ConTeXt-current-interface)
+
+(defvar ConTeXt-menu-changed nil)
+;; Need to update ConTeXt menu.
+(make-variable-buffer-local 'ConTeXt-menu-changed)
+
+(defvar ConTeXt-largest-level nil
+ "Largest sectioning level within current document.")
+(make-variable-buffer-local 'ConTeXt-largest-level)
+
+(defun ConTeXt-largest-level ()
+ (TeX-update-style)
+ ConTeXt-largest-level)
+
+
+;;; Syntax
+
+(defvar ConTeXt-optop "["
+ "The ConTeXt optional argument opening character.")
+
+(defvar ConTeXt-optcl "]"
+ "The ConTeXt optional argument closing character.")
+
+
+;; Define a ConTeXt macro
+
+(defvar ConTeXt-define-list ()
+ "Calls ConTeXt-XX-define-list where XX is the current interface.")
+
+(defun ConTeXt-define-command (what)
+ "The ConTeXt macro to define WHAT."
+ (funcall
+ (intern (concat "ConTeXt-define-command-" ConTeXt-current-interface)) what))
+
+(defun ConTeXt-insert-define (define)
+ "Insert the ConTeXt define macro DEFINE."
+ (insert TeX-esc (ConTeXt-define-command define))
+ (newline)
+ (indent-according-to-mode)
+ (ConTeXt-arg-setup nil))
+
+
+;; Setup a ConTeXt macro
+
+(defvar ConTeXt-setup-list ()
+ "Calls ConTeXt-XX-setup-list where XX is the current interface.")
+
+(defun ConTeXt-setup-command (what)
+ "The ConTeXt macro to setup WHAT."
+ (funcall
+ (intern (concat "ConTeXt-setup-command-" ConTeXt-current-interface)) what))
+
+(defun ConTeXt-insert-setup (setup)
+ "Insert the ConTeXt setup macro SETUP."
+ (insert TeX-esc (ConTeXt-setup-command setup))
+ (newline)
+ (indent-according-to-mode)
+ (ConTeXt-arg-setup nil))
+
+
+;; Referencing ConTeXt macro's
+
+(defvar ConTeXt-referencing-list ()
+ "Calls ConTeXt-XX-other-macro-list where XX is the current interface.")
+
+(defun ConTeXt-referencing-command (what)
+ "The ConTeXt macro to call WHAT is itself, no interface specific calls."
+ what)
+
+(defun ConTeXt-insert-referencing (what)
+ "Insert the ConTeXt referencing SETUP."
+ (insert TeX-esc (ConTeXt-referencing-command what))
+ (newline)
+ (indent-according-to-mode)
+ (ConTeXt-arg-setup nil))
+
+
+;; Other ConTeXt macro's
+
+(defvar ConTeXt-other-macro-list ()
+ "Calls ConTeXt-XX-other-macro-list where XX is the current interface.")
+
+(defun ConTeXt-other-macro-command (what)
+ "The ConTeXt macro to call WHAT is itself, no interface specific calls."
+ what)
+
+(defun ConTeXt-insert-other-macro (other-macro)
+ "Insert the ConTeXt other macro's macro SETUP."
+ (insert TeX-esc (ConTeXt-other-macro-command other-macro))
+ (newline)
+ (indent-according-to-mode)
+ (ConTeXt-arg-setup nil))
+
+
+;;; Project structure
+
+(defvar ConTeXt-project-structure-list ()
+ "Calls ConTeXt-XX-project-structure where XX is the current interface.")
+
+(defun ConTeXt-project-structure (N)
+ "Insert a ConTeXt project structure where N is in index into `ConTeXt-project-structure-list'."
+ (funcall (intern(concat
+ "ConTeXt-project-"
+ (nth N ConTeXt-project-structure-list)
+ "-insert"))))
+
+(defun ConTeXt-project-project-insert ()
+ "Insert a basic template for a new ConTeXt project."
+ (save-excursion
+ (insert "% The following names are examples only\n")
+ (insert TeX-esc (ConTeXt-environment-start-name) (nth 0 ConTeXt-project-structure-list) " myproject")
+ (newline 2)
+ (insert TeX-esc (nth 1 ConTeXt-project-structure-list) " myenvironment")
+ (newline 2)
+ (insert TeX-esc (nth 2 ConTeXt-project-structure-list) " myproduct1")
+ (newline 2)
+ (insert TeX-esc (nth 2 ConTeXt-project-structure-list) " myproduct2")
+ (newline 2)
+ (insert TeX-esc (ConTeXt-environment-stop-name) (nth 0 ConTeXt-project-structure-list))))
+
+(defun ConTeXt-project-environment-insert ()
+ "Insert a basic template for the environment of a ConTeXt project."
+ (save-excursion
+ (insert "% The name 'myenvironment' is an example only.\n"
+ "% It must match the name in your project file.\n")
+ (insert TeX-esc (ConTeXt-environment-start-name)
+ (nth 1 ConTeXt-project-structure-list) " myenvironment\n\n")
+ (insert "% Put environment charateristics that must be defined at the "
+ "highest level here\n\n")
+ (insert TeX-esc (ConTeXt-environment-stop-name)
+ (nth 1 ConTeXt-project-structure-list))))
+
+(defun ConTeXt-project-product-insert ()
+ "Insert a basic template for a product of a ConTeXt project."
+ (save-excursion
+ (insert "% The following names are examples only\n")
+ (insert TeX-esc (ConTeXt-environment-start-name)
+ (nth 2 ConTeXt-project-structure-list) " myproduct1")
+ (newline 2)
+ (insert TeX-esc (nth 0 ConTeXt-project-structure-list) " myproject")
+ (newline 2)
+ (insert "% Components are optional. "
+ "You can also just start your document here.\n")
+ (insert TeX-esc (nth 3 ConTeXt-project-structure-list) " mycomponent1")
+ (newline 2)
+ (insert TeX-esc (nth 3 ConTeXt-project-structure-list) " mycomponent2")
+ (newline 2)
+ (insert TeX-esc (ConTeXt-environment-stop-name)
+ (nth 2 ConTeXt-project-structure-list))))
+
+(defun ConTeXt-project-component-insert ()
+ "Insert a basic template for a component of a ConTeXt project."
+ (save-excursion
+ (insert "% The following names are examples only\n")
+ (insert TeX-esc (ConTeXt-environment-start-name)
+ (nth 3 ConTeXt-project-structure-list) " mycomponent1")
+ (newline 2)
+ (insert TeX-esc (nth 0 ConTeXt-project-structure-list) " myproject\n")
+ (insert TeX-esc (nth 2 ConTeXt-project-structure-list) " myproduct1")
+ (newline 2)
+ (insert "% ... text here ...")
+ (newline 2)
+ (insert TeX-esc (ConTeXt-environment-stop-name)
+ (nth 3 ConTeXt-project-structure-list))))
+
+
+;;; Section blocks
+
+(defvar ConTeXt-section-block-list ()
+ "Calls ConTeXt-XX-section-list where XX is the current interface.")
+
+(defun ConTeXt-section-block (section-block)
+ "Insert the ConTeXt section block SECTION-BLOCK."
+ (ConTeXt-environment-menu section-block))
+
+
+;;; Sections
+
+(defun ConTeXt-section (arg)
+ "Insert a template for a ConTeXt section.
+Determinate the type of section to be inserted, by the argument ARG.
+
+If ARG is nil or missing, use the current level.
+If ARG is a list (selected by \\[universal-argument]), go downward one level.
+If ARG is negative, go up that many levels.
+If ARG is positive or zero, use absolute level:
+
+ 0 : part
+ 1 : chapter
+ 2 : section
+ 3 : subsection
+ 4 : subsubsection
+ 5 : subsubsubsection
+
+Or:
+
+ 0 : title
+ 1 : subject
+ 2 : subsubject
+ 3 : subsubsubject
+
+The following variables can be set to customize:
+
+`ConTeXt-section-hook' Hooks to run when inserting a section.
+`ConTeXt-section-ref' Prefix to all section references."
+
+ (interactive "*P")
+ (let* ((val (prefix-numeric-value arg))
+ (level (cond ((null arg)
+ (ConTeXt-current-section))
+ ((listp arg)
+ (ConTeXt-down-section))
+ ((< val 0)
+ (ConTeXt-up-section (- val)))
+ (t val)))
+ (name (ConTeXt-section-name level))
+ (toc nil)
+ (title "")
+ (done-mark (make-marker)))
+ (newline)
+ (run-hooks 'ConTeXt-section-hook)
+ (newline)
+ (if (marker-position done-mark)
+ (goto-char (marker-position done-mark)))
+ (set-marker done-mark nil)))
+
+;; LaTeX has a max function here, which makes no sense.
+;; I think you want to insert a section that is max ConTeXt-largest-level
+(defun ConTeXt-current-section ()
+ "Return the level of the section that contain point.
+See also `ConTeXt-section' for description of levels."
+ (save-excursion
+ (min (ConTeXt-largest-level)
+ (if (re-search-backward outline-regexp nil t)
+ (+ 1 (- (ConTeXt-outline-level) (ConTeXt-outline-offset)))
+ (ConTeXt-largest-level)))))
+
+(defun ConTeXt-down-section ()
+ "Return the value of a section one level under the current.
+Tries to find what kind of section that have been used earlier in the
+text, if this fail, it will just return one less than the current
+section."
+ (save-excursion
+ (let ((current (ConTeXt-current-section))
+ (next nil)
+ (regexp outline-regexp))
+ (if (not (re-search-backward regexp nil t))
+ (1+ current)
+ (while (not next)
+ (cond
+ ((eq (ConTeXt-current-section) current)
+ (if (re-search-forward regexp nil t)
+ (if (<= (setq next (ConTeXt-current-section)) current) ;Wow!
+ (setq next (1+ current)))
+ (setq next (1+ current))))
+ ((not (re-search-backward regexp nil t))
+ (setq next (1+ current)))))
+ next))))
+
+(defun ConTeXt-up-section (arg)
+ "Return the value of the section ARG levels above this one."
+ (save-excursion
+ (if (zerop arg)
+ (ConTeXt-current-section)
+ (let ((current (ConTeXt-current-section)))
+ (while (and (>= (ConTeXt-current-section) current)
+ (re-search-backward outline-regexp
+ nil t)))
+ (ConTeXt-up-section (1- arg))))))
+
+(defvar ConTeXt-section-list ()
+ "ConTeXt-XX-section-list where XX is the current interface.")
+
+(defun ConTeXt-section-name (level)
+ "Return the name of the section corresponding to LEVEL."
+ (let ((entry (TeX-member level ConTeXt-section-list
+ (function (lambda (a b) (equal a (nth 1 b)))))))
+ (if entry
+ (nth 0 entry)
+ nil)))
+
+(defun ConTeXt-section-level (name)
+ "Return the level of the section NAME."
+ (let ((entry (TeX-member name ConTeXt-section-list
+ (function (lambda (a b) (equal a (nth 0 b)))))))
+
+ (if entry
+ (nth 1 entry)
+ nil)))
+
+
+;;; Section Hooks.
+
+(defcustom ConTeXt-section-hook
+ '(ConTeXt-section-heading
+ ConTeXt-section-title
+ ConTeXt-section-ref
+ ConTeXt-section-section)
+ "List of hooks to run when a new section is inserted.
+
+The following variables are set before the hooks are run
+
+level - numeric section level, see the documentation of `ConTeXt-section'.
+name - name of the sectioning command, derived from `level'.
+title - The title of the section, default to an empty string.
+`done-mark' - Position of point afterwards, default nil (meaning end).
+
+The following standard hook exist -
+
+ConTeXt-section-heading: Query the user about the name of the
+sectioning command. Modifies `level' and `name'.
+
+ConTeXt-section-title: Query the user about the title of the
+section. Modifies `title'.
+
+ConTeXt-section-section: Insert ConTeXt section command according to
+`name', `title', and `reference'. If `title' is an empty string,
+`done-mark' will be placed at the point they should be inserted.
+
+ConTeXt-section-ref: Insert a reference for this section command.
+
+To get a full featured `ConTeXt-section' command, insert
+
+ (setq ConTeXt-section-hook
+ '(ConTeXt-section-heading
+ ConTeXt-section-title
+ ConTeXt-section-section
+ ConTeXt-section-ref))
+
+in your .emacs file."
+ :group 'ConTeXt-macro
+ :type 'hook
+ :options
+ '(ConTeXt-section-heading
+ ConTeXt-section-title
+ ConTeXt-section-ref
+ ConTeXt-section-section))
+
+(defun ConTeXt-section-heading ()
+ "Hook to prompt for ConTeXt section name.
+Insert this hook into `ConTeXt-section-hook' to allow the user to change
+the name of the sectioning command inserted with `\\[ConTeXt-section]'."
+ (let ((string (completing-read
+ (concat "Select level: (default " name ") ")
+ ConTeXt-section-list
+ nil nil nil)))
+ ;; Update name
+ (if (not (zerop (length string)))
+ (setq name string))))
+
+(defun ConTeXt-section-title ()
+ "Hook to prompt for ConTeXt section title.
+Insert this hook into `ConTeXt-section-hook' to allow the user to change
+the title of the section inserted with `\\[ConTeXt-section]."
+ (setq title (read-string "What title: ")))
+
+(defun ConTeXt-section-section ()
+ "Hook to insert ConTeXt section command into the file.
+Insert this hook into `ConTeXt-section-hook' after those hooks which sets
+the `name', `title', and `reference' variables, but before those hooks which
+assumes the section already is inserted."
+ (insert TeX-esc name)
+ (cond ((null reference))
+ ((zerop (length reference))
+ (insert ConTeXt-optop)
+ (set-marker done-mark (point))
+ (insert ConTeXt-optcl))
+ (t
+ (insert ConTeXt-optop reference ConTeXt-optcl)))
+ (insert TeX-grop)
+ (if (zerop (length title))
+ (set-marker done-mark (point)))
+ (insert title TeX-grcl)
+ (newline)
+ ;; If RefTeX is available, tell it that we've just made a new section
+ (and (fboundp 'reftex-notice-new-section)
+ (funcall (symbol-function 'reftex-notice-new-section))))
+
+(defun ConTeXt-section-ref ()
+ "Hook to insert a reference after the sectioning command.
+Insert this hook into `ConTeXt-section-hook' to prompt for a label to be
+inserted after the sectioning command."
+
+ (setq reference (completing-read
+ (TeX-argument-prompt t nil
+ "Comma separated list of references")
+ (LaTeX-label-list) nil nil))
+ ;; No reference or empty string entered?
+ (if (string-equal "" reference)
+ (setq reference nil)))
+
+
+;; Various
+(defun TeX-ConTeXt-sentinel (process name)
+ "Cleanup TeX output buffer after running ConTeXt."
+ (cond ((TeX-TeX-sentinel-check process name))
+ ((save-excursion
+ ;; in a full ConTeXt run there will multiple texutil
+ ;; outputs. Just looking for "another run needed" would
+ ;; find the first occurence
+ (goto-char (point-max))
+ (re-search-backward "TeXUtil " nil t)
+ (re-search-forward "another run needed" nil t))
+ (message (concat "You should run ConTeXt again "
+ "to get references right, "
+ (TeX-current-pages)))
+ (setq TeX-command-next TeX-command-default))
+ ((re-search-forward "removed files :" nil t)
+ (message "sucessfully cleaned up"))
+ ((re-search-forward "^ ?TeX\\(Exec\\|Util\\)" nil t) ;; strange regexp --pg
+ (message (concat name ": successfully formatted "
+ (TeX-current-pages)))
+ (setq TeX-command-next TeX-command-Show))
+ (t
+ (message (concat name ": problems after "
+ (TeX-current-pages)))
+ (setq TeX-command-next TeX-command-default))))
+
+
+;;; Environments
+
+(defgroup ConTeXt-environment nil
+ "Environments in AUCTeX."
+ :group 'ConTeXt-macro)
+
+;; TODO: interface awareness
+(defcustom ConTeXt-default-environment "itemize"
+ "*The default environment when creating new ones with `ConTeXt-environment'."
+ :group 'ConTeXt-environment
+ :type 'string)
+(make-variable-buffer-local 'ConTeXt-default-environment)
+
+(TeX-auto-add-type "environment" "ConTeXt")
+
+(fset 'ConTeXt-add-environments-auto
+ (symbol-function 'ConTeXt-add-environments))
+(defun ConTeXt-add-environments (&rest environments)
+ "Add ENVIRONMENTS to the list of known environments."
+ (apply 'ConTeXt-add-environments-auto environments)
+ (setq ConTeXt-menu-changed t))
+
+;; (defvar ConTeXt-environment-list ()
+;; "ConTeXt-environment-list-XX where XX is the current interface.")
+
+(defvar ConTeXt-environment-history nil)
+
+(defun ConTeXt-environment-start-name ()
+ "Return the \\start translated to the language in current interface."
+ ;; it is "inizia", others are "start"
+ (cond ((equal ConTeXt-current-interface "it")
+ "inizia")
+ ((member ConTeXt-current-interface ConTeXt-known-interfaces)
+ "start")
+ (t
+ ;; this should not happen
+ (error "Unknown interface: %s" ConTeXt-current-interface))))
+
+(defun ConTeXt-environment-stop-name ()
+ "Return the \\stop translated to the language in current interface."
+ ;; it is "termina", others are "stop"
+ (cond ((equal ConTeXt-current-interface "it")
+ "termina")
+ ((member ConTeXt-current-interface ConTeXt-known-interfaces)
+ "stop")
+ (t
+ ;; this should not happen
+ (error "Unknown interface: %s" ConTeXt-current-interface))))
+
+
+(defun ConTeXt-environment (arg)
+ "Make ConTeXt environment (\\start...-\\stop... pair).
+With optional ARG, modify current environment."
+ (interactive "*P")
+ (let ((environment (
+ completing-read (concat "Environment type: (default "
+ (if (TeX-near-bobp)
+ "text"
+ ConTeXt-default-environment)
+ ") ")
+ ConTeXt-environment-list
+ nil nil nil
+ 'ConTeXt-environment-history)
+ ))
+ ;; Get default
+ (cond ((and (zerop (length environment))
+ (TeX-near-bobp))
+ (setq environment "text"))
+ ((zerop (length environment))
+ (setq environment ConTeXt-default-environment))
+ (t
+ (setq ConTeXt-default-environment environment)))
+
+ (let ((entry (assoc environment ConTeXt-environment-list)))
+ (when (null entry)
+ (ConTeXt-add-environments (list environment)))
+ (if arg
+ (ConTeXt-modify-environment environment)
+ (ConTeXt-environment-menu environment)))))
+
+(defun ConTeXt-modify-environment (environment)
+ "Modify current environment."
+ (save-excursion
+ (ConTeXt-find-matching-stop)
+ (re-search-backward (concat (regexp-quote TeX-esc)
+ (ConTeXt-environment-stop-name)
+ " *\\([a-zA-Z]*\\)")
+ (save-excursion (beginning-of-line 1) (point)))
+ (replace-match
+ (concat TeX-esc (ConTeXt-environment-stop-name) environment) t t)
+ (beginning-of-line 1)
+ (ConTeXt-find-matching-start)
+ (re-search-forward (concat (regexp-quote TeX-esc)
+ (ConTeXt-environment-start-name)
+ " *\\([a-zA-Z]*\\)")
+ (save-excursion (end-of-line 1) (point)))
+ (replace-match
+ (concat TeX-esc (ConTeXt-environment-start-name) environment) t t)))
+
+
+(defun ConTeXt-environment-menu (environment)
+ "Insert ENVIRONMENT around point or region."
+ (let ((entry (assoc environment ConTeXt-environment-list)))
+ (cond ((not (and entry (nth 1 entry)))
+ (ConTeXt-insert-environment environment))
+ ((numberp (nth 1 entry))
+ (let ((count (nth 1 entry))
+ (args ""))
+ (while (> count 0)
+ (setq args (concat args TeX-grop TeX-grcl))
+ (setq count (- count 1)))
+ (ConTeXt-insert-environment environment args)))
+ ((stringp (nth 1 entry))
+ (let ((prompts (cdr entry))
+ (args ""))
+ (while prompts
+ (setq args (concat args
+ TeX-grop
+ (read-from-minibuffer
+ (concat (car prompts) ": "))
+ TeX-grcl))
+ (setq prompts (cdr prompts)))
+ (ConTeXt-insert-environment environment args)))
+ (t
+ (apply (nth 1 entry) environment (nthcdr 2 entry))))))
+
+(defun ConTeXt-close-environment ()
+ "Insert \\stop... to match the current environment."
+ (interactive "*")
+ (beginning-of-line)
+ (let ((empty-line (looking-at "[ \t]*$")))
+ (end-of-line)
+ (if (not empty-line)
+ (newline)))
+ (insert TeX-esc (ConTeXt-environment-stop-name)
+ (ConTeXt-current-environment))
+ ;; indent broken, so don't do it.
+ ;;(indent-according-to-mode)
+ (end-of-line)
+ (newline))
+
+(defun ConTeXt-insert-environment (environment &optional extra)
+ "Insert ENVIRONMENT, with optional argument EXTRA."
+ (if (and (TeX-active-mark)
+ (not (eq (mark) (point))))
+ (save-excursion
+ (if (< (mark) (point))
+ (exchange-point-and-mark))
+ (insert TeX-esc (ConTeXt-environment-start-name) environment)
+ (newline)
+ (forward-line -1)
+ (indent-according-to-mode)
+ (if extra (insert extra))
+ (goto-char (mark))
+ (or (TeX-looking-at-backward "^[ \t]*")
+ (newline))
+ (insert TeX-esc (ConTeXt-environment-stop-name) environment)
+ (newline)
+ (forward-line -1)
+ (indent-according-to-mode)
+ ;;(goto-char (point))
+ )
+ (or (TeX-looking-at-backward "^[ \t]*")
+ (newline))
+ (insert TeX-esc (ConTeXt-environment-start-name) environment)
+ (indent-according-to-mode)
+ (if extra (insert extra))
+ (end-of-line)
+ (newline-and-indent)
+ (newline)
+ (insert TeX-esc (ConTeXt-environment-stop-name) environment)
+ (or (looking-at "[ \t]*$")
+ (save-excursion (newline-and-indent)))
+ (indent-according-to-mode)
+ (end-of-line 0)))
+
+\f
+;; with the following we can call a function on an environment. Say
+;; you have metapost stuff within your TeX file, go to the environment
+;; and run ConTeXt-work-on-environment (suggested Key: C-c !). AUCTeX
+;; sees that you are inside e.g. \startMPpage....\stopMPpage and
+;; looks in ConTeXt-environment-helper for a function to be called.
+
+;; % so pressing C-c ! inside the following ...
+;;\startuseMPgraphic{Logo}{Scale}
+;; % Top rectangle
+;; filldraw (0,0)--(2cm,0)--(2cm,1cm)--(0,1cm)--cycle withcolor blue ;
+;; % Bottom black rectangle
+;; drawfill (0,0)--(2cm,0)--(2cm,-1cm)--(0,-1cm)--cycle withcolor black;
+;; % White Text
+;; draw btex \bf AB etex withcolor white ;
+;; % resize to size
+;; currentpicture := currentpicture scaled \MPvar{Scale} ;
+;; \stopuseMPgraphic
+
+;; % ...should give you a "new buffer" (currently narrowed to region
+;; % and switched to metapost-mode and recursive-edit)
+
+;; % Top rectangle
+;; filldraw (0,0)--(2cm,0)--(2cm,1cm)--(0,1cm)--cycle withcolor blue ;
+;; % Bottom black rectangle
+;; drawfill (0,0)--(2cm,0)--(2cm,-1cm)--(0,-1cm)--cycle withcolor black;
+;; % White Text
+;; draw btex \bf AB etex withcolor white ;
+;; % resize to size
+;; currentpicture := currentpicture scaled \MPvar{Scale} ;
+
+
+(defvar ConTeXt-environment-helper
+ '(("useMPgraphic" . ConTeXt-mp-region)
+ ("MPpage" . ConTeXt-mp-region))
+ "Alist that holds functions to call for working on regions.
+An entry looks like: (\"environment\" . function)")
+
+(defun ConTeXt-mp-region ()
+ "Edit region in `metapost-mode'."
+ (ConTeXt-mark-environment t)
+ (narrow-to-region (mark) (point))
+ (metapost-mode)
+ (message "Type `M-x exit-recursive-edit' to get back")
+ (recursive-edit)
+ (context-mode)
+ (widen))
+
+;; find smarter name. Suggestions welcome
+(defun ConTeXt-work-on-environment ()
+ "Takes current environment and does something on it (todo: documentation)."
+ (interactive)
+ (let ((fun (cdr (assoc (ConTeXt-current-environment)
+ ConTeXt-environment-helper))))
+ (when (functionp fun)
+ (funcall fun))))
+
+(defun ConTeXt-current-environment ()
+ "Return the name of the current environment."
+ ;; don't make this interactive.
+ (let ((beg))
+ (save-excursion
+ (ConTeXt-last-unended-start)
+ (setq beg (+ (point) (length (ConTeXt-environment-start-name)) 1))
+ (goto-char (match-end 0))
+ (skip-chars-forward "a-zA-Z")
+ (buffer-substring beg (point)))))
+
+(defun ConTeXt-last-unended-start ()
+ "Leave point at the beginning of the last `\\start...' that is unstopped looking from the current cursor."
+ (while (and (re-search-backward "\\\\start[a-zA-Z]*\\|\\\\stop[a-zA-Z]*")
+ (looking-at "\\\\stop[a-zA-Z]*"))
+ (ConTeXt-last-unended-start)))
+
+(defun ConTeXt-mark-environment (&optional inner)
+ "Set mark to end of current environment (\\start...-\\stop...) and
+point to the matching begin.
+If optional INNER is not nil, include \\start... and \\stop, otherwise only
+the contents."
+ (interactive)
+ (let ((cur (point)))
+ (ConTeXt-find-matching-stop inner)
+ (set-mark (point))
+ (goto-char cur)
+ (ConTeXt-find-matching-start inner)
+ (TeX-activate-region)))
+
+(defun ConTeXt-find-matching-stop (&optional inner)
+ "Find end of current \\start...\\stop-Pair.
+If INNER is non-nil, go to the point just past before
+\\stop... macro. Otherwise goto the point just past \\stop..."
+ (interactive)
+ (let ((regexp (concat (regexp-quote TeX-esc)
+ "\\("
+ (ConTeXt-environment-start-name)
+ "\\|"
+ (ConTeXt-environment-stop-name)
+ "\\)"
+ ))
+ (level 1)
+ (pos))
+ ;;jump over the \start... when at the beginning of it.
+ (when (looking-at (concat (regexp-quote TeX-esc)
+ (ConTeXt-environment-start-name)))
+ (re-search-forward regexp nil t))
+ (while (and (> level 0)
+ (re-search-forward regexp nil t)
+ (goto-char (1- (match-beginning 1)))
+ (cond ((looking-at (concat (regexp-quote TeX-esc)
+ (ConTeXt-environment-start-name)))
+ (re-search-forward regexp nil t)
+ (setq level (1+ level)))
+ ((looking-at (concat (regexp-quote TeX-esc)
+ (ConTeXt-environment-stop-name)))
+ (re-search-forward regexp nil t)
+ (setq level (1- level))))))
+ ;; now we have to look if we want to start behind the \start... macro
+ (if inner
+ (beginning-of-line)
+ (skip-chars-forward "a-zA-Z"))))
+
+(defun ConTeXt-find-matching-start (&optional inner)
+ "Find beginning of current \\start...\\stop-Pair.
+If INNER is non-nil, go to the point just past the \\start... macro."
+ (interactive)
+ (let ((regexp (concat (regexp-quote TeX-esc)
+ "\\("
+ (ConTeXt-environment-start-name)
+ "\\|"
+ (ConTeXt-environment-stop-name)
+ "\\)"
+ ))
+ (level 1)
+ (pos))
+ (while (and (> level 0)
+ (re-search-backward regexp nil t)
+ (cond ((looking-at (concat (regexp-quote TeX-esc)
+ (ConTeXt-environment-stop-name)))
+ (setq level (1+ level)))
+ ((looking-at (concat (regexp-quote TeX-esc)
+ (ConTeXt-environment-start-name)))
+ (setq level (1- level))))))
+ ;; now we have to look if we want to start behind the \start... macro
+ (when inner
+ ;; \startfoo can have 0 or more {} and [] pairs. I assume that
+ ;; skipping all those parens will be smart enough. It fails when
+ ;; the first part in the \start-\stop-environment is { or [, like
+ ;; in \startquotation {\em important} \stopquotation. There is
+ ;; yet another pitfall: \startsetups SomeSetup foo bar
+ ;; \stopsetups will use SomeSetup as the argument and the
+ ;; environment
+ (skip-chars-forward "\\\\a-zA-Z")
+ (save-excursion
+ (while (progn
+ (skip-chars-forward "\t\n ")
+ (forward-comment 1)
+ (skip-chars-forward "\t\n ")
+ (looking-at "\\s\("))
+ (forward-list 1)
+ (setq pos (point))))
+ (when pos
+ (goto-char pos))
+ (unless (bolp)
+ (forward-line)))))
+
+;;; items
+
+(defun ConTeXt-insert-item ()
+ "Insert a new item."
+ (interactive "*")
+ (or (TeX-looking-at-backward "^[ \t]*")
+ (newline))
+ (TeX-insert-macro "item")
+ (indent-according-to-mode))
+
+
+;;; Macro Argument Hooks
+
+(defun ConTeXt-optional-argument-insert (arg &optional prefix)
+ "Insert ARG surrounded by square brackets."
+ (insert ConTeXt-optop)
+ (insert arg)
+ (insert ConTeXt-optcl))
+
+(defun ConTeXt-required-argument-insert (arg &optional prefix)
+ "Insert ARG surrounded by curly braces."
+ (insert TeX-grop)
+ (insert arg)
+ (insert TeX-grcl))
+
+(defun ConTeXt-argument-insert (arg optional &optional prefix)
+ "Insert ARG surrounded by curly braces.
+
+If OPTIONAL, only insert it if not empty, and then use square brackets."
+ (if optional
+ (if
+ (not (string-equal arg ""))
+ (ConTeXt-optional-argument-insert arg prefix))
+ (ConTeXt-required-argument-insert arg prefix)))
+
+(defun ConTeXt-arg-ref (optional &optional prompt definition)
+ "Prompt for a reference completing with known references."
+ (let ((ref (completing-read (TeX-argument-prompt optional prompt "ref")
+ (LaTeX-label-list))))
+ (if (and definition (not (string-equal "" ref)))
+ (LaTeX-add-labels ref))
+ (ConTeXt-argument-insert ref optional)))
+
+(defun ConTeXt-arg-define-ref (&optional prompt)
+ "Prompt for an optional reference completing with known references."
+ (ConTeXt-arg-ref t prompt t))
+
+(defun ConTeXt-arg-setup (optional &optional prompt)
+ "Prompt for setup arguments."
+ (let ((setup (read-from-minibuffer
+ (TeX-argument-prompt optional prompt "Setup"))))
+ (ConTeXt-argument-insert setup t)))
+
+
+;; paragraph (re)-formatting
+
+(defvar ConTeXt-item-list ()
+ "List of macro's considered items.")
+
+(defvar ConTeXt-extra-paragraph-commands
+ '("crlf" "par")
+ "List of ConTeXt macros that should have their own line besides the section(-block) commands.")
+
+(defun ConTeXt-paragraph-commands-regexp ()
+ "Return a regexp matching macros that should have their own line."
+ (concat
+ (regexp-quote TeX-esc) "\\("
+ "[][]\\|" ; display math delimitors (is this applicable to ConTeXt??)
+ (ConTeXt-environment-start-name) "\\|"
+ (ConTeXt-environment-stop-name) "\\|"
+ (mapconcat 'car ConTeXt-section-list "\\b\\|") "\\b\\|"
+ (mapconcat 'identity ConTeXt-extra-paragraph-commands "\\b\\|")
+ "\\b\\|"
+ (mapconcat 'identity ConTeXt-item-list "\\b\\|") "\\b\\)"))
+
+
+;; Outline support
+
+(defun ConTeXt-environment-full-start-name (environment)
+ "Return the ConTeXt macro name that starts ENVIRONMENT.
+It is interface aware"
+ (concat (ConTeXt-environment-start-name) environment))
+
+(defun ConTeXt-outline-regexp (&optional anywhere)
+ "Return regexp for ConTeXt section blocks and sections.
+
+If optional argument ANYWHERE is not nil, do not require that the
+header is at the start of a line."
+ (concat
+ (if anywhere "" "^")
+ "[ \t]*"
+ (regexp-quote TeX-esc)
+ "\\("
+ (mapconcat 'ConTeXt-environment-full-start-name ConTeXt-section-block-list "\\|") "\\|"
+ (mapconcat 'car ConTeXt-section-list "\\|")
+ "\\)\\b"
+ (if TeX-outline-extra
+ "\\|"
+ "")
+ (mapconcat 'car TeX-outline-extra "\\|")
+ "\\|" (ConTeXt-header-end) "\\b"
+ "\\|" (ConTeXt-trailer-start) "\\b"))
+
+(defvar ConTeXt-text "Name of ConTeXt macro that begins the text body.")
+
+(defun ConTeXt-header-end ()
+ "Default end of header marker for ConTeXt documents."
+ (concat
+ (regexp-quote TeX-esc)
+ (ConTeXt-environment-start-name)
+ ConTeXt-text))
+
+(defun ConTeXt-trailer-start ()
+ "Default start of trailer marker for ConTeXt documents."
+ (concat
+ (regexp-quote TeX-esc)
+ (ConTeXt-environment-stop-name)
+ ConTeXt-text))
+
+(defun ConTeXt-outline-offset ()
+ "Offset to add to `ConTeXt-section-list' levels to get outline level."
+ (- 4 (ConTeXt-largest-level)))
+
+(defun ConTeXt-start-environment-regexp (list)
+ "Regular expression that matches a start of all environments mentioned in LIST."
+ (concat
+ "start\\("
+ (mapconcat 'identity list "\\|")
+ "\\)\\b"))
+
+;; The top headings are \starttext, \startfrontmatter, \startbodymatter etc.
+;; \part, \chapter etc. are children of that.
+(defun ConTeXt-outline-level ()
+ "Find the level of current outline heading in an ConTeXt document."
+ (cond ((looking-at (concat (ConTeXt-header-end) "\\b")) 1)
+ ((looking-at (concat (ConTeXt-trailer-start) "\\b")) 1)
+ ((TeX-look-at TeX-outline-extra)
+ (max 1 (+ (TeX-look-at TeX-outline-extra)
+ (ConTeXt-outline-offset))))
+ (t
+ (save-excursion
+ (skip-chars-forward " \t")
+ (forward-char 1)
+ (cond ((looking-at (ConTeXt-start-environment-regexp
+ ConTeXt-section-block-list)) 1)
+ ((TeX-look-at ConTeXt-section-list)
+ (max 1 (+ (TeX-look-at ConTeXt-section-list)
+ (ConTeXt-outline-offset))))
+ (t
+ (error "Unrecognized header")))))))
+
+
+;;; Fonts
+
+(defcustom ConTeXt-font-list '((?\C-b "{\\bf " "}")
+ (?\C-c "{\\sc " "}")
+ (?\C-e "{\\em " "}")
+ (?\C-i "{\\it " "}")
+ (?\C-r "{\\rm " "}")
+ (?\C-s "{\\sl " "}")
+ (?\C-t "{\\tt " "}")
+ (?\C-d "" "" t))
+ "List of fonts used by `TeX-font'.
+
+Each entry is a list.
+The first element is the key to activate the font.
+The second element is the string to insert before point, and the third
+element is the string to insert after point.
+If the fourth and fifth element are strings, they specify the prefix and
+suffix to be used in math mode.
+An optional fourth (or sixth) element means always replace if t."
+ :group 'TeX-macro
+ :type '(repeat
+ (group
+ :value (?\C-a "" "")
+ (character :tag "Key")
+ (string :tag "Prefix")
+ (string :tag "Suffix")
+ (option (group
+ :inline t
+ (string :tag "Math Prefix")
+ (string :tag "Math Suffix")))
+ (option (sexp :format "Replace\n" :value t)))))
+
+
+;; Imenu support
+
+(defun ConTeXt-outline-name ()
+ "Guess a name for the current header line."
+ (save-excursion
+ (if (re-search-forward "{\\([^\}]*\\)}" (point-at-eol) t)
+ (match-string 1)
+ (buffer-substring-no-properties (point) (point-at-eol)))))
+
+;; This imenu also includes commented out chapters. Perhaps a feature
+;; for LaTeX, not sure we want or need that for ConTeXt.
+
+(defun ConTeXt-imenu-create-index-function ()
+ "Imenu support function for ConTeXt."
+ (TeX-update-style)
+ (let (entries level (regexp (ConTeXt-outline-regexp)))
+ (goto-char (point-max))
+ (while (re-search-backward regexp nil t)
+ (let* ((name (ConTeXt-outline-name))
+ (level (make-string (1- (ConTeXt-outline-level)) ?\ ))
+ (label (concat level level name))
+ (mark (make-marker)))
+ (set-marker mark (point))
+ (set-text-properties 0 (length label) nil label)
+ (setq entries (cons (cons label mark) entries))))
+ entries))
+
+
+;; Indentation, copied from Berend's context mode.
+;; TODO: doesn't work great.
+
+(defvar ConTeXt-indent-allhanging t)
+(defvar ConTeXt-indent-arg 2)
+(defvar ConTeXt-indent-basic 2)
+(defvar ConTeXt-indent-item ConTeXt-indent-basic)
+(defvar ConTeXt-indent-item-re "\\\\\item\\>")
+
+(defvar ConTeXt-indent-syntax-table (make-syntax-table TeX-mode-syntax-table)
+ "Syntax table used while computing indentation.")
+
+(progn
+ (modify-syntax-entry ?$ "." ConTeXt-indent-syntax-table)
+ (modify-syntax-entry ?\( "." ConTeXt-indent-syntax-table)
+ (modify-syntax-entry ?\) "." ConTeXt-indent-syntax-table))
+
+(defun ConTeXt-indent-line (&optional arg)
+ (with-syntax-table ConTeXt-indent-syntax-table
+ ;; TODO: Rather than ignore $, we should try to be more clever about it.
+ (let ((indent
+ (save-excursion
+ (beginning-of-line)
+ (ConTeXt-find-indent))))
+ (if (< indent 0) (setq indent 0))
+ (if (<= (current-column) (current-indentation))
+ (indent-line-to indent)
+ (save-excursion (indent-line-to indent))))))
+
+(defun ConTeXt-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."
+ (save-excursion
+ (skip-chars-forward " \t")
+ (or
+ ;; Trust the current indentation, if such info is applicable.
+ (and virtual (>= (current-indentation) (current-column))
+ (current-indentation))
+ ;; Put leading close-paren where the matching open brace would be.
+ (condition-case nil
+ (and (eq (char-syntax (char-after)) ?\))
+ (save-excursion
+ (skip-syntax-forward " )")
+ (backward-sexp 1)
+ (ConTeXt-find-indent 'virtual)))
+ (error nil))
+ ;; Default (maybe an argument)
+ (let ((pos (point))
+ (char (char-after))
+ (indent 0)
+ up-list-pos)
+ ;; Look for macros to be outdented
+ (cond ((looking-at (concat (regexp-quote TeX-esc)
+ (ConTeXt-environment-stop-name)))
+ (setq indent (- indent ConTeXt-indent-basic)))
+ ((looking-at ConTeXt-indent-item-re)
+ (setq indent (- indent ConTeXt-indent-item))))
+ ;; Find the previous point which determines our current indentation.
+ (condition-case err
+ (progn
+ (backward-sexp 1)
+ (while (> (current-column) (current-indentation))
+ (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 ConTeXt-indent-allhanging)
+ (> pos (progn (down-list 1)
+ (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)
+ (+ indent ConTeXt-indent-basic (ConTeXt-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 an item.
+ ((looking-at ConTeXt-indent-item-re)
+ ;; Indenting relative to an item, have to re-add the outdenting.
+ (+ indent (current-column) ConTeXt-indent-item))
+ ;; We're looking at an environment starter.
+ ((and (looking-at (concat (regexp-quote TeX-esc)
+ (ConTeXt-environment-start-name)))
+ (not (looking-at (concat (regexp-quote TeX-esc)
+ (ConTeXt-environment-start-name)
+ ConTeXt-text)))) ; other environments?
+ (+ indent (current-column) ConTeXt-indent-basic))
+ (t
+ (let ((col (current-column)))
+ (if (not (and char (eq (char-syntax char) ?\()))
+ ;; 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) (+ ConTeXt-indent-arg col))
+ (skip-syntax-forward " ")
+ (current-column))))))))))
+
+
+;; XML inside ConTeXt support
+
+(defun ConTeXt-last-unended-start-xml ()
+ "Leave point at the beginning of the last `tag' that is unstopped."
+ (while (and (re-search-backward "<[_A-Za-z][-:._A-Za-z0-9]*\\([ \t\r\n]\\|[_A-Za-z][-:._A-Za-z0-9]*\=\"[^\"]*\"\\)*>\\|</[_A-Za-z][-:_A-Za-z0-9]*>")
+ (looking-at "</[_A-Za-z][-:._A-Za-z0-9]*>"))
+ (ConTeXt-last-unended-start-xml)))
+
+(defun ConTeXt-close-xml-tag ()
+ "Create an </...> to match the last unclosed <...>. Not fool-proof."
+ (interactive "*")
+ (let ((new-line-needed (bolp)) text indentation)
+ (save-excursion
+ (condition-case nil
+ (ConTeXt-last-unended-start-xml)
+ (error (error "Couldn't find unended XML tag")))
+ (setq indentation (current-column))
+ (re-search-forward "<\\([_A-Za-z][-:._A-Za-z0-9]*\\)")
+ (setq text (buffer-substring (match-beginning 1) (match-end 1))))
+ (indent-to indentation)
+ (insert "</" text ">")
+ (if new-line-needed (insert ?\n))))
+
+
+;; Key bindings
+
+(defvar ConTeXt-mode-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map TeX-mode-map)
+
+ (define-key map "\e\C-a" 'ConTeXt-find-matching-start)
+ (define-key map "\e\C-e" 'ConTeXt-find-matching-stop)
+ ;; likely to change in the future
+ (define-key map "\C-c!" 'ConTeXt-work-on-environment)
+ (define-key map "\C-c\C-e" 'ConTeXt-environment)
+ (define-key map "\C-c\n" 'ConTeXt-insert-item)
+ (or (key-binding "\e\r")
+ (define-key map "\e\r" 'ConTeXt-insert-item)) ;*** Alias
+ (define-key map "\C-c]" 'ConTeXt-close-environment)
+ (define-key map "\C-c\C-s" 'ConTeXt-section)
+ ;; XML in ConTeXt support
+ (define-key map "\C-c/" 'ConTeXt-close-xml-tag)
+ map)
+ "Keymap used in `ConTeXt-mode'.")
+
+
+;;; Menu building
+
+;; functions to create menu entries
+
+;; ConTeXt \start... \stop... pairs
+;; (Choose a different name than the one in LaTeX mode. Otherwise the
+;; contents of the "Insert Environment" and "Change Environment" menus
+;; will not be updated correctly upon loading and switching between
+;; LaTeX and ConTeXt files. AFAICS this is due to a bug in
+;; easymenu.el not returning the correct keymap when
+;; `easy-menu-change' (and therefore `easy-menu-get-map') is called.
+;; It just sees an entry with a matching name and returns this first
+;; match.)
+(defvar ConTeXt-environment-menu-name "Insert Environment (C-c C-e)")
+
+(defun ConTeXt-environment-menu-entry (entry)
+ "Create an entry for the environment menu."
+ (vector (car entry) (list 'ConTeXt-environment-menu (car entry)) t))
+
+(defvar ConTeXt-environment-modify-menu-name "Change Environment (C-u C-c C-e)")
+
+(defun ConTeXt-environment-modify-menu-entry (entry)
+ "Create an entry for the change environment menu."
+ (vector (car entry) (list 'ConTeXt-modify-environment (car entry)) t))
+
+;; ConTeXt define macros
+(defvar ConTeXt-define-menu-name "Define")
+
+(defun ConTeXt-define-menu-entry (entry)
+ "Create an entry for the define menu."
+ (vector entry (list 'ConTeXt-define-menu entry)))
+
+(defun ConTeXt-define-menu (define)
+ "Insert DEFINE from menu."
+ (ConTeXt-insert-define define))
+
+;; ConTeXt setup macros
+(defvar ConTeXt-setup-menu-name "Setup")
+
+(defun ConTeXt-setup-menu-entry (entry)
+ "Create an entry for the setup menu."
+ (vector entry (list 'ConTeXt-setup-menu entry)))
+
+(defun ConTeXt-setup-menu (setup)
+ "Insert SETUP from menu."
+ (ConTeXt-insert-setup setup))
+
+;; ConTeXt referencing macros
+(defvar ConTeXt-referencing-menu-name "Referencing")
+
+(defun ConTeXt-referencing-menu-entry (entry)
+ "Create an entry for the referencing menu."
+ (vector entry (list 'ConTeXt-referencing-menu entry)))
+
+(defun ConTeXt-referencing-menu (referencing)
+ "Insert REFERENCING from menu."
+ (ConTeXt-insert-referencing referencing))
+
+;; ConTeXt other macros
+(defvar ConTeXt-other-macro-menu-name "Other macro")
+
+(defun ConTeXt-other-macro-menu-entry (entry)
+ "Create an entry for the other macro menu."
+ (vector entry (list 'ConTeXt-other-macro-menu entry)))
+
+(defun ConTeXt-other-macro-menu (other-macro)
+ "Insert OTHER MACRO from menu."
+ (ConTeXt-insert-other-macro other-macro))
+
+
+;; meta-structure project structure menu entries
+
+(defvar ConTeXt-project-structure-menu-name "Project Structure")
+
+(defun ConTeXt-project-structure-menu (project-structure)
+ "Insert project structure from menu."
+ (ConTeXt-project-structure
+ (let ((l ConTeXt-project-structure-list))
+ (- (length l) (length (member project-structure l))))))
+
+(defun ConTeXt-project-structure-menu-entry (entry)
+ "Create an ENTRY for the project structure menu."
+ (vector entry (list 'ConTeXt-project-structure-menu entry)))
+
+
+;; meta-structure section blocks menu entries
+
+(defvar ConTeXt-section-block-menu-name "Section Block")
+
+(defun ConTeXt-section-block-menu (section-block)
+ "Insert section block from menu."
+ (ConTeXt-section-block section-block))
+
+(defun ConTeXt-section-block-menu-entry (entry)
+ "Create an ENTRY for the section block menu."
+ (vector entry (list 'ConTeXt-section-block-menu entry)))
+
+
+;; section menu entries
+
+(defvar ConTeXt-section-menu-name "Section (C-c C-s)")
+
+(defun ConTeXt-section-enable-symbol (level)
+ "Symbol used to enable section LEVEL in the menu bar."
+ (intern (concat "ConTeXt-section-" (int-to-string level) "-enable")))
+
+(defun ConTeXt-section-enable (entry)
+ "Enable or disable section ENTRY from `ConTeXt-section-list'."
+ (let ((level (nth 1 entry)))
+ (set (ConTeXt-section-enable-symbol level)
+ (>= level ConTeXt-largest-level))))
+
+(defun ConTeXt-section-menu (level)
+ "Insert section from menu."
+ (let ((ConTeXt-section-hook (delq 'ConTeXt-section-heading
+ (copy-sequence ConTeXt-section-hook))))
+ (ConTeXt-section level)))
+
+(defun ConTeXt-section-menu-entry (entry)
+ "Create an ENTRY for the section menu."
+ (let ((enable (ConTeXt-section-enable-symbol (nth 1 entry))))
+ (set enable t)
+ (vector (car entry) (list 'ConTeXt-section-menu (nth 1 entry)) enable)))
+
+
+;; etexshow support
+
+(defun ConTeXt-etexshow ()
+ "Call etexshow, if available, to show the definition of a ConText macro."
+ (interactive)
+ (if (fboundp 'etexshow)
+ (let ()
+ (require 'etexshow)
+ (funcall (symbol-function 'etexshow-cmd)))
+ (error "etexshow is not installed. Get it from http://levana.de/emacs/")))
+
+;; menu itself
+
+(easy-menu-define ConTeXt-mode-command-menu
+ ConTeXt-mode-map
+ "Command menu used in ConTeXt mode."
+ (TeX-mode-specific-command-menu 'context-mode))
+
+;; it seems the menu is evaluated at compile/load-time
+;; we don't have ConTeXt-current-interface at that time
+;; so make sure to do updates based on that variable in
+;; ConTeXt-menu-update
+(easy-menu-define ConTeXt-mode-menu
+ ConTeXt-mode-map
+ "Menu used in ConTeXt mode."
+ (TeX-menu-with-help
+ `("ConTeXt"
+ (,ConTeXt-project-structure-menu-name)
+ (,ConTeXt-section-block-menu-name)
+ (,ConTeXt-section-menu-name)
+ ["Add Table of Contents to Emacs Menu" (imenu-add-to-menubar "TOC") t]
+ "-"
+ ["Macro ..." TeX-insert-macro
+ :help "Insert a macro and possibly arguments"]
+ ["Complete" TeX-complete-symbol
+ :help "Complete the current macro or environment name"]
+ ["Show ConTeXt Macro Definition" ConTeXt-etexshow]
+ "-"
+ (,ConTeXt-environment-menu-name)
+ (,ConTeXt-environment-modify-menu-name)
+ ["Item" ConTeXt-insert-item
+ :help "Insert a new \\item into current environment"]
+ (,ConTeXt-define-menu-name)
+ (,ConTeXt-setup-menu-name)
+ (,ConTeXt-other-macro-menu-name)
+ "-"
+ ("Insert Font"
+ ["Emphasize" (TeX-font nil ?\C-e) :keys "C-c C-f C-e"]
+ ["Bold" (TeX-font nil ?\C-b) :keys "C-c C-f C-b"]
+ ["Typewriter" (TeX-font nil ?\C-t) :keys "C-c C-f C-t"]
+ ["Small Caps" (TeX-font nil ?\C-c) :keys "C-c C-f C-c"]
+ ["Sans Serif" (TeX-font nil ?\C-f) :keys "C-c C-f C-f"]
+ ["Italic" (TeX-font nil ?\C-i) :keys "C-c C-f C-i"]
+ ["Slanted" (TeX-font nil ?\C-s) :keys "C-c C-f C-s"]
+ ["Roman" (TeX-font nil ?\C-r) :keys "C-c C-f C-r"]
+ ["Calligraphic" (TeX-font nil ?\C-a) :keys "C-c C-f C-a"])
+ ("Replace Font"
+ ["Emphasize" (TeX-font t ?\C-e) :keys "C-u C-c C-f C-e"]
+ ["Bold" (TeX-font t ?\C-b) :keys "C-u C-c C-f C-b"]
+ ["Typewriter" (TeX-font t ?\C-t) :keys "C-u C-c C-f C-t"]
+ ["Small Caps" (TeX-font t ?\C-c) :keys "C-u C-c C-f C-c"]
+ ["Sans Serif" (TeX-font t ?\C-f) :keys "C-u C-c C-f C-f"]
+ ["Italic" (TeX-font t ?\C-i) :keys "C-u C-c C-f C-i"]
+ ["Slanted" (TeX-font t ?\C-s) :keys "C-u C-c C-f C-s"]
+ ["Roman" (TeX-font t ?\C-r) :keys "C-u C-c C-f C-r"]
+ ["Calligraphic" (TeX-font t ?\C-a) :keys "C-u C-c C-f C-a"])
+ ["Delete Font" (TeX-font t ?\C-d) :keys "C-c C-f C-d"]
+ "-"
+ ["Comment or Uncomment Region"
+ TeX-comment-or-uncomment-region
+ :help "Make the selected region outcommented or active again"]
+ ["Comment or Uncomment Paragraph"
+ TeX-comment-or-uncomment-paragraph
+ :help "Make the current paragraph outcommented or active again"]
+ ,TeX-fold-menu
+ "-" . ,TeX-common-menu-entries)))
+
+(defun ConTeXt-menu-update (&optional menu)
+ "Update entries on AUCTeX menu."
+ (or (not (memq major-mode '(context-mode)))
+ (null ConTeXt-menu-changed)
+ (not (fboundp 'easy-menu-change))
+ (progn
+ (TeX-update-style)
+ (setq ConTeXt-menu-changed nil)
+ (message "Updating section menu...")
+ (mapc 'ConTeXt-section-enable ConTeXt-section-list)
+ (message "Updating environment menu...")
+ (easy-menu-change '("ConTeXt") ConTeXt-environment-menu-name
+ (LaTeX-split-long-menu
+ (mapcar 'ConTeXt-environment-menu-entry
+ (ConTeXt-environment-list))))
+ (message "Updating modify environment menu...")
+ (easy-menu-change '("ConTeXt") ConTeXt-environment-modify-menu-name
+ (LaTeX-split-long-menu
+ (mapcar 'ConTeXt-environment-modify-menu-entry
+ (ConTeXt-environment-list))))
+ (message "Updating define menu...")
+ (easy-menu-change '("ConTeXt") ConTeXt-define-menu-name
+ (LaTeX-split-long-menu
+ (mapcar 'ConTeXt-define-menu-entry
+ ConTeXt-define-list)))
+ (message "Updating setup menu...")
+ (easy-menu-change '("ConTeXt") ConTeXt-setup-menu-name
+ (LaTeX-split-long-menu
+ (mapcar 'ConTeXt-setup-menu-entry
+ ConTeXt-setup-list)))
+ (message "Updating referencing menu...")
+ (easy-menu-change '("ConTeXt") ConTeXt-referencing-menu-name
+ (LaTeX-split-long-menu
+ (mapcar 'ConTeXt-referencing-menu-entry
+ ConTeXt-referencing-list)))
+ (message "Updating other macro's menu...")
+ (easy-menu-change '("ConTeXt") ConTeXt-other-macro-menu-name
+ (LaTeX-split-long-menu
+ (mapcar 'ConTeXt-other-macro-menu-entry
+ ConTeXt-other-macro-list)))
+ (message "Updating project structure menu...")
+ (easy-menu-change '("ConTeXt") ConTeXt-project-structure-menu-name
+ (LaTeX-split-long-menu
+ (mapcar 'ConTeXt-project-structure-menu-entry
+ ConTeXt-project-structure-list)))
+ (message "Updating section block menu...")
+ (easy-menu-change '("ConTeXt") ConTeXt-section-block-menu-name
+ (LaTeX-split-long-menu
+ (mapcar 'ConTeXt-section-block-menu-entry
+ ConTeXt-section-block-list)))
+ (message "Updating section menu...")
+ (easy-menu-change '("ConTeXt") ConTeXt-section-menu-name
+ (LaTeX-split-long-menu
+ (mapcar 'ConTeXt-section-menu-entry
+ ConTeXt-section-list)))
+ (message "Updating...done")
+ (and menu (easy-menu-return-item ConTeXt-mode-menu menu))
+ )))
+
+;;; Option expander
+
+(defvar ConTeXt-texexec-option-nonstop "--nonstop "
+ "Command line option for texexec to use nonstopmode.")
+
+(defun ConTeXt-expand-options ()
+ "Expand options for texexec command."
+ (concat
+ (let ((engine (nth 4 (assq TeX-engine (TeX-engine-alist)))))
+ (when engine
+ (format "--engine=%s " engine)))
+ (unless (eq ConTeXt-current-interface "en")
+ (format "--interface=%s " ConTeXt-current-interface))
+ (when TeX-source-correlate-mode
+ (format "--passon=\"%s\" "
+ (if (eq TeX-source-correlate-method-active 'synctex)
+ TeX-synctex-tex-flags
+ TeX-source-specials-tex-flags)))
+ (unless TeX-interactive-mode
+ ConTeXt-texexec-option-nonstop)))
+
+;;; Mode
+
+;; ConTeXt variables that are interface aware
+;; They are mapped to interface specific variables
+
+(defvar ConTeXt-language-variable-list
+ '(ConTeXt-define-list ConTeXt-setup-list ConTeXt-referencing-list ConTeXt-other-macro-list
+ ConTeXt-project-structure-list
+ ConTeXt-section-block-list ConTeXt-section-list
+ ConTeXt-text ConTeXt-item-list))
+
+(defcustom ConTeXt-clean-intermediate-suffixes
+ ;; See *suffixes in texutil.pl.
+ '("\\.tui" "\\.tup" "\\.ted" "\\.tes" "\\.top" "\\.log" "\\.tmp" "\\.run"
+ "\\.bck" "\\.rlg" "\\.mpt" "\\.mpx" "\\.mpd" "\\.mpo" "\\.tuo" "\\.tub"
+ "\\.top" "-mpgraph\\.mp" "-mpgraph\\.mpd" "-mpgraph\\.mpo" "-mpgraph\\.mpy"
+ "-mprun\\.mp" "-mprun\\.mpd" "-mprun\\.mpo" "-mprun\\.mpy")
+ "List of regexps matching suffixes of files to be deleted.
+The regexps will be anchored at the end of the file name to be matched,
+i.e. you do _not_ have to cater for this yourself by adding \\\\' or $."
+ :type '(repeat regexp)
+ :group 'TeX-command)
+
+(defcustom ConTeXt-clean-output-suffixes
+ '("\\.dvi" "\\.pdf" "\\.ps")
+ "List of regexps matching suffixes of files to be deleted.
+The regexps will be anchored at the end of the file name to be matched,
+i.e. you do _not_ have to cater for this yourself by adding \\\\' or $."
+ :type '(repeat regexp)
+ :group 'TeX-command)
+
+(defun ConTeXt-mode-common-initialization ()
+ "Initialization code that is common for all ConTeXt interfaces."
+ ;; `plain-TeX-common-initialization' kills all local variables, but
+ ;; we need to keep ConTeXt-current-interface, so save and restore
+ ;; it.
+ (let (save-ConTeXt-current-interface)
+ (setq save-ConTeXt-current-interface ConTeXt-current-interface)
+ (plain-TeX-common-initialization)
+ (setq ConTeXt-current-interface save-ConTeXt-current-interface))
+ (setq major-mode 'context-mode)
+
+ ;; Make language specific variables buffer local
+ (dolist (symbol ConTeXt-language-variable-list)
+ (make-variable-buffer-local symbol))
+
+ (require (intern (concat "context-" ConTeXt-current-interface)))
+ (dolist (symbol ConTeXt-language-variable-list)
+ (set symbol (symbol-value (intern (concat (symbol-name symbol) "-"
+ ConTeXt-current-interface)))))
+
+
+ ;; What's the deepest level at we can collapse a document?
+ ;; set only if user has not set it. Need to be set before menu is created.
+ ;; level 2 is "section"
+ (or ConTeXt-largest-level
+ (setq ConTeXt-largest-level 2))
+
+ ;; keybindings
+ (use-local-map ConTeXt-mode-map)
+
+ ;; Indenting
+ (set (make-local-variable 'indent-line-function) 'ConTeXt-indent-line)
+ (set (make-local-variable 'fill-indent-according-to-mode) t)
+
+ ;; Paragraph formatting
+ (set (make-local-variable 'LaTeX-syntactic-comments) nil)
+ (set (make-local-variable 'LaTeX-paragraph-commands-regexp)
+ (ConTeXt-paragraph-commands-regexp))
+ (set (make-local-variable 'paragraph-ignore-fill-prefix) t)
+ (set (make-local-variable 'fill-paragraph-function) 'LaTeX-fill-paragraph)
+ (set (make-local-variable 'adaptive-fill-mode) nil)
+ (setq paragraph-start
+ (concat
+ "[ \t]*\\("
+ (ConTeXt-paragraph-commands-regexp) "\\|"
+ "\\$\\$\\|" ; Plain TeX display math
+ "$\\)"))
+ (setq paragraph-separate
+ (concat
+ "[ \t]*\\("
+ "\\$\\$" ; Plain TeX display math
+ "\\|$\\)"))
+
+ ;; Keybindings and menu
+ (use-local-map ConTeXt-mode-map)
+ (easy-menu-add ConTeXt-mode-menu ConTeXt-mode-map)
+ (easy-menu-add ConTeXt-mode-command-menu ConTeXt-mode-map)
+ (setq ConTeXt-menu-changed t)
+
+ (if (= emacs-major-version 20)
+ (make-local-hook 'activate-menubar-hook))
+ (add-hook 'activate-menubar-hook 'ConTeXt-menu-update nil t)
+
+ ;; Outline support
+ (require 'outline)
+ (set (make-local-variable 'outline-level) 'ConTeXt-outline-level)
+ (set (make-local-variable 'outline-regexp) (ConTeXt-outline-regexp t))
+ ;;(make-local-variable 'outline-heading-end-regexp)
+ (setq TeX-header-end (ConTeXt-header-end)
+ TeX-trailer-start (ConTeXt-trailer-start))
+
+ ;; font switch support
+ (set (make-local-variable 'TeX-font-list) ConTeXt-font-list)
+
+ ;; imenu support
+ (set (make-local-variable 'imenu-create-index-function)
+ 'ConTeXt-imenu-create-index-function)
+
+ ;; run hooks
+ (setq TeX-command-default "ConTeXt")
+ (setq TeX-sentinel-default-function 'TeX-ConTeXt-sentinel)
+ (TeX-run-mode-hooks 'text-mode-hook 'TeX-mode-hook 'ConTeXt-mode-hook))
+
+(defun context-guess-current-interface ()
+ "Guess what ConTeXt interface the current buffer is using."
+ (interactive)
+ (save-excursion
+ (goto-char (point-min))
+ (setq ConTeXt-current-interface
+ (cond ((re-search-forward "%.*?interface=en" (+ 512 (point)) t)
+ "en")
+ ((re-search-forward "%.*?interface=nl" (+ 512 (point)) t)
+ "nl")
+ ((re-search-forward "\\\\starttext" (+ 1024 (point)) t)
+ "en")
+ ((re-search-forward "\\\\starttekst" (+ 1024 (point)) t)
+ "nl")
+ (t
+ ConTeXt-default-interface)))))
+
+;;;###autoload
+(defalias 'ConTeXt-mode 'context-mode)
+
+;;;###autoload
+(defun context-mode ()
+ "Major mode in AUCTeX for editing ConTeXt files.
+
+Special commands:
+\\{ConTeXt-mode-map}
+
+Entering `context-mode' calls the value of `text-mode-hook',
+then the value of `TeX-mode-hook', and then the value
+of context-mode-hook."
+ (interactive)
+ (context-guess-current-interface)
+ (require (intern (concat "context-" ConTeXt-current-interface)))
+ (funcall (intern (concat "context-" ConTeXt-current-interface "-mode"))))
+
+(provide 'context)
+
+;;; context.el ends here
--- /dev/null
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+\1f
+File: dir, Node: Top This is the top of the INFO tree
+
+ This (the Directory node) gives a menu of major topics.
+ Typing "q" exits, "?" lists all Info commands, "d" returns here,
+ "h" gives a primer for first-timers,
+ "mEmacs<Return>" visits the Emacs manual, etc.
+
+ In Emacs, you can click mouse button 2 on a menu item or cross reference
+ to select it.
+
+* Menu:
+
+Emacs
+* AUCTeX: (auctex). A sophisticated TeX environment for Emacs.
+* preview-latex: (preview-latex).
+ Preview LaTeX fragments in Emacs
+
+TeX
+* AUCTeX: (auctex). A sophisticated TeX environment for Emacs.
+* preview-latex: (preview-latex).
+ Preview LaTeX fragments in Emacs
--- /dev/null
+;;; font-latex.el --- LaTeX fontification for Font Lock mode.
+
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+;; 2004, 2005, 2006, 2007, 2008 Free Software Foundation.
+
+;; Authors: Peter S. Galbraith <psg@debian.org>
+;; Simon Marshall <Simon.Marshall@esrin.esa.it>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 06 July 1996
+;; Keywords: tex, wp, faces
+
+;;; This file is not part of GNU Emacs.
+
+;; This package 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, or (at your option)
+;; any later version.
+
+;; This package 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; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+;;
+;; This package enhances font-lock fontification patterns for LaTeX.
+;; font-lock mode is a minor mode that causes your comments to be
+;; displayed in one face, strings in another, reserved words in
+;; another, and so on.
+;;
+;; ** Infinite loops !? **
+;; If you get an infinite loop, send a bug report!
+;; Then set the following in your ~/.emacs file to keep on working:
+;; (setq font-latex-do-multi-line nil)
+
+;;; Code:
+
+(require 'font-lock)
+(require 'tex)
+
+(eval-when-compile
+ (require 'cl))
+
+(defgroup font-latex nil
+ "Font-latex text highlighting package."
+ :prefix "font-latex-"
+ :group 'faces
+ :group 'tex
+ :group 'AUCTeX)
+
+(defgroup font-latex-keywords nil
+ "Keywords for highlighting text in font-latex."
+ :prefix "font-latex-"
+ :group 'font-latex)
+
+(defgroup font-latex-highlighting-faces nil
+ "Faces for highlighting text in font-latex."
+ :prefix "font-latex-"
+ :group 'font-latex)
+
+(defvar font-latex-multiline-boundary 5000
+ "Size of region to search for the start or end of a multiline construct.")
+
+(defvar font-latex-quote-regexp-beg nil
+ "Regexp used to find quotes.")
+(make-variable-buffer-local 'font-latex-quote-regexp-beg)
+
+(defvar font-latex-quote-list '(("``" "''") ("<<" ">>" french) ("«" "»" french))
+ "List of quote specifiers for quotation fontification.
+
+Each element of the list is either a list consisting of two
+strings to be used as opening and closing quotation marks
+independently of the value of `font-latex-quotes' or a list with
+three elements where the first and second element are strings for
+opening and closing quotation marks and the third element being
+either the symbol 'german or 'french describing the order of
+quotes.
+
+If `font-latex-quotes' specifies a different state, order of the
+added quotes will be reversed for fontification. For example if
+'(\"\\\"<\" \"\\\">\" french) is given but `font-latex-quotes'
+specifies 'german, quotes will be used like \">foo\"< for
+fontification.")
+
+(defvar font-latex-quotes-control nil
+ "Internal variable for keeping track if `font-latex-quotes' changed.")
+(make-variable-buffer-local 'font-latex-quotes-control)
+
+(defvar font-latex-quotes-internal nil
+ "Internal variable for tracking outcome of automatic detection.
+If automatic detection is not enabled, it is assigned the value
+of `font-latex-quotes'.")
+(make-variable-buffer-local 'font-latex-quotes-internal)
+
+(defvar font-latex-quotes-fallback 'french
+ "Fallback value for `font-latex-quotes' if automatic detection fails.")
+
+(defvar font-latex-quote-style-list-french
+ '("french" "frenchb" "frenchle" "frenchpro" "francais" "canadien"
+ "acadian" "italian")
+ "List of styles for which French-style quote matching should be activated.")
+
+(defvar font-latex-quote-style-list-german
+ '("austrian" "german" "germanb" "naustrian" "ngerman")
+ "List of styles for which German-style quote matching should be activated.")
+
+(defcustom font-latex-quotes 'auto
+ "Whether to fontify << French quotes >> or >>German quotes<<.
+Also selects \"<quote\"> versus \">quote\"<.
+
+If value `auto' is chosen, an attempt is being made in deriving
+the type of quotation mark matching from document settings like
+the language option supplied to the babel package.
+
+If nil, quoted content will not be fontified."
+ :type '(choice (const auto) (const french) (const german) (const nil))
+ :group 'font-latex)
+(put 'font-latex-quotes 'safe-local-variable
+ '(lambda (x) (memq x '(auto french german nil))))
+
+(defun font-latex-add-quotes (quotes)
+ "Add QUOTES to `font-latex-quote-list'.
+QUOTES has to be a list adhering to the format of an element of
+`font-latex-quote-list'."
+ (setq font-latex-quotes-control nil)
+ (make-local-variable 'font-latex-quote-list)
+ (add-to-list 'font-latex-quote-list quotes))
+
+(defun font-latex-quotes-set-internal ()
+ "Set `font-latex-quotes-internal' according to `font-latex-quotes'.
+If `font-latex-quotes' is set to `auto', try to derive the
+correct value from document properties."
+ (setq font-latex-quotes-internal
+ (if (eq font-latex-quotes 'auto)
+ (or (when (TeX-elt-of-list-member
+ font-latex-quote-style-list-french TeX-active-styles)
+ 'french)
+ (when (TeX-elt-of-list-member
+ font-latex-quote-style-list-german TeX-active-styles)
+ 'german)
+ font-latex-quotes-fallback)
+ font-latex-quotes)))
+;; Update the value of `font-latex-quotes-internal' when the list of
+;; styles changes.
+(add-hook 'TeX-update-style-hook 'font-latex-quotes-set-internal)
+
+;; The definitions of the title faces were originally taken from
+;; info.el (Copyright (C) 1985, 86, 92, 93, 94, 95, 96, 97, 98, 99,
+;; 2000, 2001 Free Software Foundation, Inc.) and adapted to the needs
+;; of font-latex.el.
+
+(defconst font-latex-sectioning-max 5
+ "Highest number for font-latex-sectioning-N-face")
+(defface font-latex-sectioning-5-face
+ (if (featurep 'xemacs)
+ '((((type tty pc) (class color) (background light))
+ (:foreground "blue4" :bold t))
+ (((type tty pc) (class color) (background dark))
+ (:foreground "yellow" :bold t))
+ (((class color) (background light))
+ (:bold t :foreground "blue4" :family "helvetica"))
+ (((class color) (background dark))
+ (:bold t :foreground "yellow" :family "helvetica"))
+ (t (:bold t :family "helvetica")))
+ '((((type tty pc) (class color) (background light))
+ (:foreground "blue4" :weight bold))
+ (((type tty pc) (class color) (background dark))
+ (:foreground "yellow" :weight bold))
+ (((class color) (background light))
+ (:weight bold :inherit variable-pitch :foreground "blue4"))
+ (((class color) (background dark))
+ (:weight bold :inherit variable-pitch :foreground "yellow"))
+ (t (:weight bold :inherit variable-pitch))))
+ "Face for sectioning commands at level 5."
+ :group 'font-latex-highlighting-faces)
+
+(defun font-latex-update-sectioning-faces (&optional max height-scale)
+ "Update sectioning commands faces."
+ (unless height-scale
+ (setq height-scale (if (numberp font-latex-fontify-sectioning)
+ font-latex-fontify-sectioning
+ 1.1)))
+ (unless max
+ (setq max font-latex-sectioning-max))
+ (dotimes (num max)
+ (let* (;; reverse for XEmacs:
+ (num (- max (1+ num)))
+ (face-name (intern (format "font-latex-sectioning-%s-face" num))))
+ (unless (get face-name 'saved-face) ; Do not touch customized faces.
+ (if (featurep 'xemacs)
+ (let ((size
+ ;; Multiply with .9 because `face-height' returns a value
+ ;; slightly larger than the actual font size.
+ ;; `make-face-size' takes numeric points according to Aidan
+ ;; Kehoe in <16989.15536.613916.678965@parhasard.net> (not
+ ;; documented).
+ (round (* 0.9
+ (face-height 'default)
+ (expt height-scale (- max 1 num))))))
+ ;; (message "%s - %s" face-name size)
+ (make-face-size face-name size))
+ (set-face-attribute face-name nil :height height-scale))))))
+
+(defcustom font-latex-fontify-sectioning 1.1
+ "Whether to fontify sectioning macros with varying height or a color face.
+
+If it is a number, use varying height faces. The number is used
+for scaling starting from `font-latex-sectioning-5-face'. Typically
+values from 1.05 to 1.3 give best results, depending on your font
+setup. If it is the symbol `color', use `font-lock-type-face'.
+
+Caveats: Customizing the scaling factor applies to all sectioning
+faces unless those face have been saved by customize. Setting
+this variable directly does not take effect unless you call
+`font-latex-update-sectioning-faces' or restart Emacs.
+
+Switching from `color' to a number or vice versa does not take
+effect unless you call \\[font-lock-fontify-buffer] or restart
+Emacs."
+ ;; Possibly add some words about XEmacs here. :-(
+ :type '(choice (number :tag "Scale factor")
+ (const color))
+ :initialize 'custom-initialize-default
+ :set (lambda (symbol value)
+ (set-default symbol value)
+ (unless (eq value 'color)
+ (font-latex-update-sectioning-faces font-latex-sectioning-max value)))
+ :group 'font-latex)
+
+(defun font-latex-make-sectioning-faces (max &optional height-scale)
+ "Build the faces used to fontify sectioning commands."
+ (unless max (setq max font-latex-sectioning-max))
+ (unless height-scale
+ (setq height-scale (if (numberp font-latex-fontify-sectioning)
+ font-latex-fontify-sectioning
+ 1.1)))
+ (dotimes (num max)
+ (let* (;; reverse for XEmacs:
+ (num (- max (1+ num)))
+ (face-name (intern (format "font-latex-sectioning-%s-face" num)))
+ (f-inherit (intern (format "font-latex-sectioning-%s-face" (1+ num))))
+ (size (when (featurep 'xemacs)
+ (round (* 0.9 (face-height 'default)
+ (expt height-scale (- max 1 num)))))))
+ (eval
+ `(defface ,face-name
+ (if (featurep 'xemacs)
+ '((t (:size ,(format "%spt" size))))
+ '((t (:height ,height-scale :inherit ,f-inherit))))
+ (format "Face for sectioning commands at level %s.
+
+Probably you don't want to customize this face directly. Better
+change the base face `font-latex-sectioning-5-face' or customize the
+variable `font-latex-fontify-sectioning'." num)
+ :group 'font-latex-highlighting-faces))
+ (when (and (featurep 'xemacs)
+ ;; Do not touch customized faces.
+ (not (get face-name 'saved-face)))
+ (set-face-parent face-name f-inherit)
+ ;; Explicitely set the size again to code around the bug that
+ ;; `set-face-parent' overwrites the original face size.
+ (make-face-size face-name size)))))
+
+(font-latex-make-sectioning-faces font-latex-sectioning-max)
+
+
+;;; Keywords
+
+(defvar font-latex-keywords-1 nil
+ "Subdued level highlighting for LaTeX modes.")
+
+(defvar font-latex-keywords-2 nil
+ "High level highlighting for LaTeX modes.")
+
+(defvar font-latex-built-in-keyword-classes
+ '(("warning"
+ ("nopagebreak" "pagebreak" "newpage" "clearpage" "cleardoublepage"
+ "enlargethispage" "nolinebreak" "linebreak" "newline" "-" "\\" "\\*"
+ "appendix" "displaybreak" "allowdisplaybreaks" "include")
+ 'font-latex-warning-face 1 noarg)
+ ("variable"
+ (("setlength" "|{\\{") ("settowidth" "|{\\{") ("setcounter" "{|{\\")
+ ("addtolength" "|{\\{") ("addtocounter" "{|{\\"))
+ 'font-lock-variable-name-face 2 command)
+ ("reference"
+ (("nocite" "{") ("cite" "[{") ("label" "{") ("pageref" "{")
+ ("vref" "{") ("eqref" "{") ("ref" "{") ("include" "{")
+ ("input" "{") ("bibliography" "{") ("index" "{") ("glossary" "{")
+ ("footnote" "[{") ("footnotemark" "[") ("footnotetext" "[{"))
+ 'font-lock-constant-face 2 command)
+ ("function"
+ (("begin" "{") ("end" "{") ("pagenumbering" "{")
+ ("thispagestyle" "{") ("pagestyle" "{") ("nofiles" "")
+ ("includeonly" "{") ("bibliographystyle" "{") ("documentstyle" "[{")
+ ("documentclass" "[{") ("newenvironment" "*{[[{{")
+ ("newcommand" "*|{\\[[{") ("newlength" "|{\\")
+ ("newtheorem" "{[{[")
+ ("newcounter" "{[") ("renewenvironment" "*{[{{")
+ ("renewcommand" "*|{\\[[{") ("renewtheorem" "{[{[")
+ ("usepackage" "[{") ("fbox" "{") ("mbox" "{") ("sbox" "{")
+ ("vspace" "*{") ("hspace" "*{") ("thinspace" "") ("negthinspace" "")
+ ;; XXX: Should macros without arguments rather be listed in a
+ ;; separate category with 'noarg instead of 'command handling?
+ ("enspace" "") ("enskip" "") ("quad" "") ("qquad" "") ("nonumber" "")
+ ("centering" "") ("TeX" "") ("LaTeX" ""))
+ 'font-lock-function-name-face 2 command)
+ ("sectioning-0"
+ (("part" "*[{"))
+ (if (eq font-latex-fontify-sectioning 'color)
+ 'font-lock-type-face
+ 'font-latex-sectioning-0-face)
+ 2 command)
+ ("sectioning-1"
+ (("chapter" "*[{"))
+ (if (eq font-latex-fontify-sectioning 'color)
+ 'font-lock-type-face
+ 'font-latex-sectioning-1-face)
+ 2 command)
+ ("sectioning-2"
+ (("section" "*[{"))
+ (if (eq font-latex-fontify-sectioning 'color)
+ 'font-lock-type-face
+ 'font-latex-sectioning-2-face)
+ 2 command)
+ ("sectioning-3"
+ (("subsection" "*[{"))
+ (if (eq font-latex-fontify-sectioning 'color)
+ 'font-lock-type-face
+ 'font-latex-sectioning-3-face)
+ 2 command)
+ ("sectioning-4"
+ (("subsubsection" "*[{"))
+ (if (eq font-latex-fontify-sectioning 'color)
+ 'font-lock-type-face
+ 'font-latex-sectioning-4-face)
+ 2 command)
+ ("sectioning-5"
+ (("paragraph" "*[{") ("subparagraph" "*[{")
+ ("subsubparagraph" "*[{"))
+ (if (eq font-latex-fontify-sectioning 'color)
+ 'font-lock-type-face
+ 'font-latex-sectioning-5-face)
+ 2 command)
+ ("slide-title" () 'font-latex-slide-title-face 2 command)
+ ("textual"
+ (("item" "[") ("title" "{") ("author" "{") ("date" "{")
+ ("thanks" "{") ("address" "{") ("caption" "[{")
+ ("textsuperscript" "{"))
+ 'font-lock-type-face 2 command)
+ ("bold-command"
+ (("textbf" "{") ("textsc" "{") ("textup" "{") ("boldsymbol" "{")
+ ("pmb" "{"))
+ 'font-latex-bold-face 1 command)
+ ("italic-command"
+ (("emph" "{") ("textit" "{") ("textsl" "{"))
+ 'font-latex-italic-face 1 command)
+ ("math-command"
+ (("ensuremath" "|{\\"))
+ 'font-latex-math-face 1 command)
+ ("type-command"
+ (("texttt" "{") ("textsf" "{") ("textrm" "{") ("textmd" "{"))
+ 'font-lock-type-face 1 command)
+ ("bold-declaration"
+ ("bf" "bfseries" "sc" "scshape" "upshape")
+ 'font-latex-bold-face 1 declaration)
+ ("italic-declaration"
+ ("em" "it" "itshape" "sl" "slshape")
+ 'font-latex-italic-face 1 declaration)
+ ("type-declaration"
+ ("tt" "ttfamily" "sf" "sffamily" "rm" "rmfamily" "mdseries"
+ "tiny" "scriptsize" "footnotesize" "small" "normalsize"
+ "large" "Large" "LARGE" "huge" "Huge")
+ 'font-lock-type-face 1 declaration))
+ "Built-in keywords and specifications for font locking.
+
+The first element of each item is the name of the keyword class.
+
+The second element is a list of keywords (macros without an
+escape character) to highlight or, if the fifth element is the
+symbol 'command, a list of lists where the first element of each
+item is a keyword and the second a string specifying the macro
+syntax. It can contain \"*\" if the macro has a starred variant,
+\"[\" for an optional argument, \"{\" for a mandatory argument,
+and \"\\\" for a macro. A \"|\" means the following two tokens
+should be regarded as alternatives.
+
+The third element is the symbol of a face to be used or a Lisp
+form returning a face symbol.
+
+The fourth element is the fontification level.
+
+The fifth element is the type of construct to be matched. It can
+be one of 'noarg which will match simple macros without
+arguments (like \"\\foo\"), 'declaration which will match macros
+inside a TeX group (like \"{\\bfseries foo}\"), or 'command which
+will match macros of the form \"\\foo[bar]{baz}\".")
+
+(defcustom font-latex-deactivated-keyword-classes nil
+ "List of strings for built-in keyword classes to be deactivated.
+
+Valid entries are \"warning\", \"variable\", \"reference\",
+\"function\" , \"sectioning-0\", \"sectioning-1\", \"sectioning-2\",
+\"sectioning-3\", \"sectioning-4\", \"sectioning-5\", \"textual\",
+\"bold-command\", \"italic-command\", \"math-command\", \"type-command\",
+\"bold-declaration\", \"italic-declaration\", \"type-declaration\".
+
+You have to restart Emacs for a change of this variable to take effect."
+ :group 'font-latex-keywords
+ :type `(set ,@(mapcar
+ (lambda (spec)
+ `(const :tag ,(concat
+ ;; Name of the keyword class
+ (let ((name (split-string (car spec) "-")))
+ (setcar name (capitalize (car name)))
+ (mapconcat 'identity name " "))
+ " keywords in `"
+ ;; Name of the face
+ (symbol-name (eval (nth 2 spec))) "'.\n"
+ ;; List of keywords
+ (with-temp-buffer
+ (insert " Keywords: "
+ (mapconcat (lambda (x)
+ (if (listp x)
+ (car x)
+ x))
+ (nth 1 spec) ", "))
+ (fill-paragraph nil)
+ (buffer-substring-no-properties
+ (point-min) (point-max))))
+ ,(car spec)))
+ font-latex-built-in-keyword-classes)))
+
+(defun font-latex-make-match-defun (prefix name face type)
+ "Return a function definition for keyword matching.
+The variable holding the keywords to match are determined by the
+strings PREFIX and NAME. The type of matcher is determined by
+the symbol TYPE.
+
+This is a helper function for `font-latex-make-built-in-keywords'
+and `font-latex-make-user-keywords' and not intended for general
+use."
+ ;; Note: The functions are byte-compiled at the end of font-latex.el.
+ ;; FIXME: Is the cond-clause possible inside of the defun?
+
+ ;; In an earlier version of font-latex the type could be a list like
+ ;; (command 1). This indicated a macro with one argument. Provide
+ ;; a match function in this case but don't actually support it.
+ (cond ((or (eq type 'command) (listp type))
+ (eval `(defun ,(intern (concat prefix name)) (limit)
+ ,(concat "Fontify `" prefix name "' up to LIMIT.
+
+Generated by `font-latex-make-match-defun'.")
+ (when ,(intern (concat prefix name))
+ (font-latex-match-command-with-arguments
+ ,(intern (concat prefix name))
+ (append
+ (when (boundp ',(intern (concat prefix name
+ "-keywords-local")))
+ ,(intern (concat prefix name "-keywords-local")))
+ ,(intern (concat prefix name "-keywords")))
+ ;; `face' can be a face symbol, a form returning
+ ;; a face symbol, or a list of face attributes.
+ (if (and (listp ,face) (functionp (car ,face)))
+ (eval ,face)
+ ,face)
+ limit)))))
+ ((eq type 'declaration)
+ (eval `(defun ,(intern (concat prefix name)) (limit)
+ ,(concat "Fontify `" prefix name "' up to LIMIT.
+
+Generated by `font-latex-make-match-defun'.")
+ (when ,(intern (concat prefix name))
+ (font-latex-match-command-in-braces
+ ,(intern (concat prefix name)) limit)))))
+ ((eq type 'noarg)
+ (eval `(defun ,(intern (concat prefix name)) (limit)
+ ,(concat "Fontify `" prefix name "' up to LIMIT.
+
+Generated by `font-latex-make-match-defun'.")
+ (when ,(intern (concat prefix name))
+ (re-search-forward
+ ,(intern (concat prefix name)) limit t)))))))
+
+(defun font-latex-keyword-matcher (prefix name face type)
+ "Return a matcher and highlighter as required by `font-lock-keywords'.
+PREFIX and NAME are strings which are concatenated to form the
+respective match function. FACE is a face name or a list of text
+properties that will be applied to the respective part of the
+match returned by the match function. TYPE is the type of
+construct to be highlighted. Currently the symbols 'command,
+'sectioning, 'declaration and 'noarg are valid.
+
+This is a helper function for `font-latex-make-built-in-keywords'
+and `font-latex-make-user-keywords' and not intended for general
+use."
+ ;; In an earlier version of font-latex the type could be a list like
+ ;; (command 1). This indicated a macro with one argument. Provide
+ ;; a matcher in this case but don't actually support it.
+ (cond ((or (eq type 'command) (listp type))
+ `(,(intern (concat prefix name))
+ (0 (font-latex-matched-face 0) append t)
+ (1 (font-latex-matched-face 1) append t)
+ (2 (font-latex-matched-face 2) append t)
+ (3 (font-latex-matched-face 3) append t)
+ (4 (font-latex-matched-face 4) append t)
+ (5 (font-latex-matched-face 5) append t)
+ (6 (font-latex-matched-face 6) append t)
+ (7 (font-latex-matched-face 7) append t)))
+ ((eq type 'noarg)
+ `(,(intern (concat prefix name))
+ (0 ,face)))
+ ((eq type 'declaration)
+ `(,(intern (concat prefix name))
+ (0 'font-latex-warning-face t t)
+ (1 'font-lock-keyword-face append t)
+ (2 ,face append t)))))
+
+(defun font-latex-make-built-in-keywords ()
+ "Build defuns, defvars and defcustoms for built-in keyword fontification."
+ (dolist (item font-latex-built-in-keyword-classes)
+ (let ((prefix "font-latex-match-")
+ (name (nth 0 item))
+ (keywords (nth 1 item))
+ (face (nth 2 item))
+ (level (nth 3 item))
+ (type (nth 4 item)))
+
+ ;; defvar font-latex-match-*-keywords-local
+ (eval `(defvar ,(intern (concat prefix name "-keywords-local"))
+ ',keywords
+ ,(concat "Buffer-local keywords to add to `"
+ prefix name "-keywords'.
+
+This must be a list where each element is a list consisting of a
+keyword string \(not a regular expression\) omitting the leading
+backslash and a format specifier as. The options for the format
+specifier are described in the doc string of
+`font-latex-user-keyword-classes'.
+
+This is an internal variable which should not be set directly.
+Use `font-latex-add-keywords' instead.
+
+Generated by `font-latex-make-built-in-keywords'.")))
+ (eval `(make-variable-buffer-local
+ ',(intern (concat prefix name "-keywords-local"))))
+
+ ;; defun font-latex-match-*-make
+ ;; Note: The functions are byte-compiled at the end of font-latex.el.
+ (eval `(defun ,(intern (concat prefix name "-make")) ()
+ ,(concat "Make or remake the variable `" prefix name "'.
+
+Generated by `font-latex-make-built-in-keywords'.")
+ (let ((keywords
+ (append
+ (unless (member ,name
+ font-latex-deactivated-keyword-classes)
+ ,(intern (concat prefix name "-keywords-local")))
+ ,(intern (concat prefix name "-keywords"))))
+ multi-char-macros single-char-macros)
+ (dolist (elt keywords)
+ (let ((keyword (if (listp elt) (car elt) elt)))
+ (if (string-match "^[A-Za-z]" keyword)
+ (add-to-list 'multi-char-macros keyword)
+ (add-to-list 'single-char-macros keyword))))
+ (when (or multi-char-macros single-char-macros)
+ (setq ,(intern (concat prefix name))
+ (concat
+ "\\\\\\("
+ (when multi-char-macros
+ (concat
+ "\\(?:" (regexp-opt multi-char-macros) "\\)\\>"))
+ (when single-char-macros
+ (concat
+ (when multi-char-macros "\\|")
+ "\\(?:" (regexp-opt single-char-macros) "\\)"))
+ "\\)"))))))
+
+ ;; defcustom font-latex-match-*-keywords
+ (eval `(defcustom ,(intern (concat prefix name "-keywords")) nil
+ ,(concat "List of keywords "
+ (when (eq type 'command) "and formats ")
+ "for " name " face.\n"
+ (if (eq type 'command)
+ "\
+Each element has to be a list consisting of the name of a macro
+omitting the leading backslash and a format specifier as
+described in the doc string of `font-latex-user-keyword-classes'."
+ "\
+Each element has to be the name of a macro as a string, omitting
+the leading backslash.")
+ "\n\n\
+Setting this variable directly does not take effect; restart
+Emacs.
+
+Generated by `font-latex-make-built-in-keywords'.")
+ :type '(repeat (string :tag "Keyword"))
+ :type '(repeat ,(if (eq type 'command)
+ '(list (string :tag "Keyword")
+ (string :tag "Format"))
+ '(string :tag "Keyword")))
+ :set (lambda (symbol value)
+ (set-default symbol value)
+ (funcall ',(intern (concat prefix name "-make"))))
+ :group 'font-latex-keywords))
+
+ ;; defvar font-latex-match-*
+ (eval `(defvar ,(intern (concat prefix name))
+ ,(intern (concat prefix name "-keywords"))))
+ (eval `(make-variable-buffer-local
+ ',(intern (concat prefix name))))
+
+ ;; defun font-latex-match-*
+ (font-latex-make-match-defun prefix name face type)
+
+ ;; Add matchers and highlighters to `font-latex-keywords-{1,2}'.
+ (let ((keywords-entry (font-latex-keyword-matcher
+ prefix name face type)))
+ (add-to-list (intern (concat "font-latex-keywords-"
+ (number-to-string level)))
+ keywords-entry t)
+ (when (= level 1)
+ (add-to-list (intern (concat "font-latex-keywords-2"))
+ keywords-entry t))))))
+(font-latex-make-built-in-keywords)
+
+(defcustom font-latex-user-keyword-classes nil
+ "List of user-defined keyword classes for font locking.
+
+Every keyword class consists of four parts, a name, a list of
+keywords, a face and a specifier for the type of macro to be
+highlighted.
+
+When adding new entries, you have to use unique values for the
+class names, i.e. they must not clash with names of the built-in
+keyword classes or other names given by you. Additionally the
+names must not contain spaces.
+
+The list of keywords defines which commands and declarations
+should be covered by the keyword class. A keyword can either be
+a simple command name omitting the leading backslash or a list
+consisting of the command name and a string specifying the syntax
+of the command. The latter is useful if you want to match LaTeX
+macros with arguments (see below). You can specify the occurence
+and order of optional (\"[\") and mandatory (\"{\") arguments for
+each keyword. For example for \"documentclass\" you'd use \"[{\"
+because the macro has one optional followed by one mandatory
+argument. Optionally starred macros can be indicated with \"*\".
+In case an argument is an unbraced macro, use \"\\\". You can
+also specify two alternative arguments by prefixing them with
+\"|\". As an example, the specifier for \\newcommand is
+\"*|{\\=\\[[{\".
+
+The face argument can either be an existing face or a font
+specification. (The latter option is not available in XEmacs.)
+
+There are three alternatives for the class type:
+
+A value of `command' indicates commands with arguments
+\(\"\\foo[bar]{baz}\"). The mandatory arguments in curly braces
+will get the face you specified.
+
+A value of `declaration' indicates declarations inside of TeX
+groups (\"{\\foo bar}\"). The content inside the braces,
+excluding the command, will get the face you specified. In case
+the braces are missing, the face will be applied to the command
+itself.
+
+A value of `noarg' indicates commands without arguments
+\(\"\\foo\"). The command itself will get the face you
+specified.
+
+Setting this variable directly does not take effect;
+use \\[customize] or restart Emacs."
+ :group 'font-latex-keywords
+ :type `(repeat (list (string :tag "Name")
+ (choice (repeat :tag "Keywords" (string :tag "Keyword"))
+ (repeat
+ :tag "Keywords with specs"
+ (group (string :tag "Keyword")
+ (string :tag "Format specifier"))))
+ ,(if (featurep 'xemacs)
+ '(face :tag "Face name")
+ '(choice (custom-face-edit :tag "Face attributes")
+ (face :tag "Face name")))
+ (choice :tag "Type"
+ ;; Maps to
+ ;;`font-latex-match-command-with-arguments'
+ (const :tag "Command with arguments"
+ command)
+ ;; Maps to
+ ;;`font-latex-match-command-in-braces'
+ (const :tag "Declaration inside TeX group"
+ declaration)
+ ;; Maps to `re-search-forward'
+ (const :tag "Command without arguments"
+ noarg))))
+ :set (lambda (symbol value)
+ (dolist (item value)
+ (when (string-match " " (car item))
+ (error "No spaces allowed in name")))
+ (let (names names-uniq)
+ (dolist (item (append font-latex-built-in-keyword-classes value))
+ (setq names (append names (list (car item)))))
+ (setq names (TeX-sort-strings names))
+ (setq names-uniq (TeX-delete-duplicate-strings names))
+ (dotimes (i (safe-length names-uniq))
+ (unless (string= (nth i names) (nth i names-uniq))
+ (error "Name %S already exists" (nth i names)))))
+ (set-default symbol value)
+ (let ((prefix "font-latex-match-"))
+ (dolist (elt value)
+ (unless (boundp (intern (concat prefix (car elt))))
+ ;; defvar font-latex-match-*
+ (eval `(defvar ,(intern (concat prefix (car elt))) nil)))
+ (let ((keywords (nth 1 elt))
+ single-char-macro-flag)
+ (setq keywords (if (listp (car keywords))
+ (mapcar 'car keywords)
+ keywords))
+ (catch 'single-char
+ (dolist (keyword keywords)
+ (unless (string-match "^[A-Za-z]" keyword)
+ (setq single-char-macro-flag t)
+ (throw 'single-char nil))))
+ (set (intern (concat prefix (car elt)))
+ (when (> (safe-length keywords) 0)
+ (concat "\\\\" (let ((max-specpdl-size 1000))
+ (regexp-opt keywords t))
+ (unless single-char-macro-flag "\\>")))))))))
+
+(defun font-latex-make-user-keywords ()
+ "Build defuns and defvars for user keyword fontification."
+ (let ((keyword-specs font-latex-user-keyword-classes))
+ (dolist (item keyword-specs)
+ (let ((prefix "font-latex-match-")
+ (name (nth 0 item))
+ (keywords (nth 1 item))
+ (face (nth 2 item))
+ (type (nth 3 item)))
+
+ ;; defvar font-latex-match-*-keywords
+ (eval `(defvar ,(intern (concat prefix name "-keywords")) ',keywords
+ ,(concat "Font-latex keywords for " name " face.
+
+Generated by `font-latex-make-user-keywords'.")))
+
+ ;; defun font-latex-match-*
+ (eval `(font-latex-make-match-defun prefix name '',face type))
+
+ ;; Add the matcher to `font-latex-keywords-2'.
+ (add-to-list 'font-latex-keywords-2
+ (font-latex-keyword-matcher prefix name face type) t))))
+
+ ;; Add the "fixed" matchers and highlighters.
+ (dolist (item
+ '(("\\(^\\|[^\\]\\)\\(&+\\)" 2 'font-latex-warning-face)
+ ("\\$\\$\\([^$]+\\)\\$\\$" 1 'font-latex-math-face)
+ (font-latex-match-quotation
+ (0 'font-latex-string-face append)
+ (1 'font-latex-warning-face))
+ ;; Hack to remove the verbatim face from the \ in
+ ;; \end{verbatim} and similar. The same hack is used in
+ ;; tex-mode.el.
+ ("^[ \t]*\\(\\\\\\)end"
+ (1 (get-text-property (match-end 1) 'face) t))))
+ (add-to-list 'font-latex-keywords-1 item)
+ (add-to-list 'font-latex-keywords-2 item))
+ (dolist (item
+ '((font-latex-match-math-env
+ (0 'font-latex-warning-face t t)
+ (1 'font-latex-math-face append t))
+ (font-latex-match-math-envII
+ (0 'font-latex-math-face append t))
+ (font-latex-match-simple-command
+ (0 'font-latex-sedate-face append))
+ (font-latex-match-script
+ (1 (font-latex-script (match-beginning 0)) append))))
+ (add-to-list 'font-latex-keywords-2 item t)))
+(font-latex-make-user-keywords)
+
+(defun font-latex-add-keywords (keywords class)
+ "Add KEYWORDS to CLASS.
+KEYWORDS is a list of keywords or keywords with syntax specs.
+CLASS corresponds to a keyword class and can be one of the
+symbols 'warning, 'variable, 'reference, 'function, sectioning-0,
+'sectioning-1, 'sectioning-2, 'sectioning-3, 'sectioning-4,
+'sectioning-5, 'slide-title, 'textual, 'bold-command,
+'italic-command, 'math-command, 'type-command, 'bold-declaration,
+'italic-declaration or 'type-declaration.
+
+The keywords will be added to the buffer-local list of keywords
+of the respective keyword class and necessary updates of the font
+locking machinery will be triggered."
+ (let* ((class (symbol-name class))
+ (list (intern (format "font-latex-match-%s-keywords-local" class))))
+ (dolist (elt keywords)
+ (add-to-list list elt))
+ (funcall (intern (format "font-latex-match-%s-make" class)))
+ (setq font-lock-set-defaults nil)
+ (font-lock-set-defaults)))
+
+(defvar font-latex-keywords font-latex-keywords-1
+ "Default expressions to highlight in TeX mode.")
+
+
+;;; Subscript and superscript
+
+(defcustom font-latex-fontify-script (not (featurep 'xemacs))
+ "If non-nil, fontify subscript and superscript strings.
+This feature does not work in XEmacs."
+ :type 'boolean
+ :group 'font-latex)
+(put 'font-latex-fontify-script 'safe-local-variable 'TeX-booleanp)
+
+(defcustom font-latex-script-display '((raise -0.3) . (raise 0.3))
+ "Display specification for subscript and superscript content.
+The car is used for subscript, the cdr is used for superscripts."
+ :group 'font-latex
+ :type '(cons (choice (sexp :tag "Subscript form")
+ (const :tag "No lowering" nil))
+ (choice (sexp :tag "Superscript form")
+ (const :tag "No raising" nil))))
+
+
+;;; Syntactic keywords
+
+(defvar font-latex-syntactic-keywords nil
+ "Syntactic keywords used by `font-latex'.")
+(make-variable-buffer-local 'font-latex-syntactic-keywords)
+
+(defvar font-latex-syntactic-keywords-extra nil
+ "List of syntactic keywords to add to `font-latex-syntactic-keywords'.
+The form should be the same as in `font-lock-syntactic-keywords'.")
+(make-variable-buffer-local 'font-latex-syntactic-keywords-extra)
+
+(defun font-latex-set-syntactic-keywords ()
+ "Set the variable `font-latex-syntactic-keywords'.
+This function can be used to refresh the variable in case other
+variables influencing its value, like `LaTeX-verbatim-environments',
+have changed."
+ ;; Checks for non-emptiness of lists added in order to cater for
+ ;; installations where `(regexp-opt-group nil)' would enter a loop.
+ (let ((verb-envs (and (fboundp 'LaTeX-verbatim-environments)
+ (LaTeX-verbatim-environments)))
+ (verb-macros-with-delims
+ (and (fboundp 'LaTeX-verbatim-macros-with-delims)
+ (LaTeX-verbatim-macros-with-delims)))
+ (verb-macros-with-braces
+ (and (fboundp 'LaTeX-verbatim-macros-with-braces)
+ (LaTeX-verbatim-macros-with-braces))))
+ (setq verb-envs (and verb-envs (regexp-opt verb-envs))
+ verb-macros-with-delims (and verb-macros-with-delims
+ (regexp-opt verb-macros-with-delims))
+ verb-macros-with-braces (and verb-macros-with-braces
+ (regexp-opt verb-macros-with-braces))
+ font-latex-syntactic-keywords nil)
+ (unless (= (length verb-envs) 0)
+ (add-to-list 'font-latex-syntactic-keywords
+ `(,(concat "^[ \t]*\\\\begin *{\\(?:" verb-envs
+ "\\)}.*\\(\n\\)")
+ (1 "|" t)))
+ (add-to-list 'font-latex-syntactic-keywords
+ ;; Using the newline character for the syntax
+ ;; property often resulted in fontification
+ ;; problems when text was inserted at the end of
+ ;; the verbatim environment. That's why we now use
+ ;; the starting backslash of \end. There is a hack
+ ;; in `font-latex-make-user-keywords' to remove the
+ ;; spurious fontification of the backslash.
+ `(,(concat "^[ \t]*\\(\\\\\\)end *{\\(?:" verb-envs "\\)}")
+ (1 "|" t))))
+ (unless (= (length verb-macros-with-delims) 0)
+ (add-to-list 'font-latex-syntactic-keywords
+ `(,(concat "\\\\\\(?:" verb-macros-with-delims "\\)"
+ ;; An opening curly brace as delimiter
+ ;; is valid, but allowing it might screw
+ ;; up fontification of stuff like
+ ;; "\url{...} foo \textbf{<--!...}".
+ "\\([^a-z@*\n\f{]\\).*?"
+ ;; Give an escape char at the end of the
+ ;; verbatim construct punctuation syntax.
+ ;; Prevents wrong fontification of stuff
+ ;; like "\verb|foo\|".
+ "\\(" (regexp-quote TeX-esc) "*\\)\\(\\1\\)")
+ (1 "\"") (2 ".") (3 "\""))))
+ (unless (= (length verb-macros-with-braces) 0)
+ (add-to-list 'font-latex-syntactic-keywords
+ `(,(concat "\\\\\\(?:" verb-macros-with-braces "\\)"
+ "\\({\\).*?[^\\]\\(?:\\\\\\\\\\)*\\(}\\)")
+ (1 "|") (2 "|")))))
+ (when font-latex-syntactic-keywords-extra
+ (nconc font-latex-syntactic-keywords font-latex-syntactic-keywords-extra))
+ ;; Cater for docTeX mode.
+ (setq font-latex-doctex-syntactic-keywords
+ (append font-latex-syntactic-keywords
+ ;; For docTeX comment-in-doc.
+ `(("\\(\\^\\)\\^A" (1 (font-latex-doctex-^^A)))))))
+
+
+;;; Syntactic fontification
+
+;; Copy and adaptation of `tex-font-lock-syntactic-face-function' in
+;; `tex-mode.el' of CVS Emacs (March 2004)
+(defun font-latex-syntactic-face-function (state)
+ (let ((char (nth 3 state)))
+ (cond
+ ((not char) 'font-lock-comment-face)
+ ((eq char ?$) 'font-latex-math-face)
+ (t
+ (when (char-valid-p char)
+ ;; This is a \verb?...? construct. Let's find the end and mark it.
+ (save-excursion
+ (skip-chars-forward (string ?^ char)) ;; Use `end' ?
+ (when (eq (char-syntax (preceding-char)) ?/)
+ (put-text-property (1- (point)) (point) 'syntax-table '(1)))
+ (unless (eobp)
+ (put-text-property (point) (1+ (point)) 'syntax-table '(7)))))
+ 'font-latex-verbatim-face))))
+
+
+;;; Faces
+
+(defface font-latex-bold-face
+ (let ((font (cond ((assq :inherit custom-face-attributes) '(:inherit bold))
+ ((assq :weight custom-face-attributes) '(:weight bold))
+ (t '(:bold t)))))
+ `((((class grayscale) (background light))
+ (:foreground "DimGray" ,@font))
+ (((class grayscale) (background dark))
+ (:foreground "LightGray" ,@font))
+ (((class color) (background light))
+ (:foreground "DarkOliveGreen" ,@font))
+ (((class color) (background dark))
+ (:foreground "OliveDrab" ,@font))
+ (t (,@font))))
+ "Face used to highlight text to be typeset in bold."
+ :group 'font-latex-highlighting-faces)
+
+(defface font-latex-italic-face
+ (let ((font (cond ((assq :inherit custom-face-attributes) '(:inherit italic))
+ ((assq :slant custom-face-attributes) '(:slant italic))
+ (t '(:italic t)))))
+ `((((class grayscale) (background light))
+ (:foreground "DimGray" ,@font))
+ (((class grayscale) (background dark))
+ (:foreground "LightGray" ,@font))
+ (((class color) (background light))
+ (:foreground "DarkOliveGreen" ,@font))
+ (((class color) (background dark))
+ (:foreground "OliveDrab" ,@font))
+ (t (,@font))))
+ "Face used to highlight text to be typeset in italic."
+ :group 'font-latex-highlighting-faces)
+
+(defface font-latex-math-face
+ (let ((font (cond ((assq :inherit custom-face-attributes)
+ '(:inherit underline))
+ (t '(:underline t)))))
+ `((((class grayscale) (background light))
+ (:foreground "DimGray" ,@font))
+ (((class grayscale) (background dark))
+ (:foreground "LightGray" ,@font))
+ (((class color) (background light))
+ (:foreground "SaddleBrown"))
+ (((class color) (background dark))
+ (:foreground "burlywood"))
+ (t (,@font))))
+ "Face used to highlight math."
+ :group 'font-latex-highlighting-faces)
+
+(defface font-latex-sedate-face
+ '((((class grayscale) (background light)) (:foreground "DimGray"))
+ (((class grayscale) (background dark)) (:foreground "LightGray"))
+ (((class color) (background light)) (:foreground "DimGray"))
+ (((class color) (background dark)) (:foreground "LightGray"))
+ ;;;(t (:underline t))
+ )
+ "Face used to highlight sedate stuff."
+ :group 'font-latex-highlighting-faces)
+
+(defface font-latex-string-face
+ (let ((font (cond ((assq :inherit custom-face-attributes) '(:inherit italic))
+ ((assq :slant custom-face-attributes) '(:slant italic))
+ (t '(:italic t)))))
+ `((((type tty) (class color))
+ (:foreground "green"))
+ (((class grayscale) (background light))
+ (:foreground "DimGray" ,@font))
+ (((class grayscale) (background dark))
+ (:foreground "LightGray" ,@font))
+ (((class color) (background light))
+ (:foreground "RosyBrown"))
+ (((class color) (background dark))
+ (:foreground "LightSalmon"))
+ (t (,@font))))
+ "Face used to highlight strings."
+ :group 'font-latex-highlighting-faces)
+
+(defface font-latex-warning-face
+ (let ((font (cond ((assq :inherit custom-face-attributes) '(:inherit bold))
+ ((assq :weight custom-face-attributes) '(:weight bold))
+ (t '(:bold t)))))
+ `((((class grayscale)(background light))
+ (:foreground "DimGray" ,@font))
+ (((class grayscale)(background dark))
+ (:foreground "LightGray" ,@font))
+ (((class color)(background light))
+ (:foreground "red" ,@font))
+ (((class color)(background dark))
+ (:foreground "red" ,@font))
+ (t (,@font))))
+ "Face for important keywords."
+ :group 'font-latex-highlighting-faces)
+
+(defface font-latex-verbatim-face
+ (let ((font (if (and (assq :inherit custom-face-attributes)
+ (if (featurep 'xemacs)
+ (find-face 'fixed-pitch)
+ (facep 'fixed-pitch)))
+ '(:inherit fixed-pitch)
+ '(:family "courier"))))
+ `((((class grayscale) (background light))
+ (:foreground "DimGray" ,@font))
+ (((class grayscale) (background dark))
+ (:foreground "LightGray" ,@font))
+ (((class color) (background light))
+ (:foreground "SaddleBrown" ,@font))
+ (((class color) (background dark))
+ (:foreground "burlywood" ,@font))
+ (t (,@font))))
+ "Face used to highlight TeX verbatim environments."
+ :group 'font-latex-highlighting-faces)
+
+(defface font-latex-superscript-face
+ '((t (:height 0.8)))
+ "Face used for superscripts."
+ :group 'font-latex-highlighting-faces)
+
+(defface font-latex-subscript-face
+ '((t (:height 0.8)))
+ "Face used for subscripts."
+ :group 'font-latex-highlighting-faces)
+
+(defface font-latex-slide-title-face
+ (let* ((scale 1.2)
+ (size (when (featurep 'xemacs)
+ (round (* 0.9 (face-height 'default) scale)))))
+ (if (featurep 'xemacs)
+ `((t (:bold t :family "helvetica" :size ,size)))
+ `((t (:inherit (variable-pitch font-lock-type-face)
+ :weight bold :height ,scale)))))
+ "Face for slide titles."
+ :group 'font-latex-highlighting-faces)
+(when (featurep 'xemacs)
+ (set-face-parent 'font-latex-slide-title-face 'font-lock-type-face
+ nil nil 'append))
+
+
+;;; Setup
+
+(defvar font-lock-comment-start-regexp nil
+ "Regexp to match the start of a comment.")
+
+(defvar font-latex-extend-region-functions nil
+ "List of functions extending the region for multiline constructs.
+
+Each function should accept two arguments, the begin and end of
+the region to be fontified, and return the new region start. If
+no extension is necessary, the original region start should be
+returned.
+
+All specified functions will be called and the region extended
+backwards to the minimum over their return values.")
+
+(defvar font-latex-syntax-alist
+ ;; Use word syntax for @ because we use \> for matching macros and
+ ;; we don't want \foo@bar to be found if we search for \foo.
+ '((?\( . ".") (?\) . ".") (?$ . "\"") (?@ . "w"))
+ "List of specifiers for the syntax alist of `font-lock-defaults'.")
+
+(defun font-latex-add-to-syntax-alist (list)
+ "Activate syntactic font locking for the entries in LIST.
+The entries are added to `font-latex-syntax-alist' and eventually
+end up in `font-lock-defaults'. Each entry in LIST should be a
+cons pair as expected by `font-lock-defaults'. The function also
+triggers Font Lock to recognize the change."
+ (make-local-variable 'font-latex-syntax-alist)
+ (nconc font-latex-syntax-alist list)
+;; FIXME: Are there situations where we need to alter `font-lock-defaults'
+;; directly?
+;; (dolist (entry list)
+;; (setcar (cdddr font-lock-defaults)
+;; (cons entry (cadddr font-lock-defaults))))
+ ;; Tell font-lock about the update.
+ (setq font-lock-set-defaults nil)
+ (font-lock-set-defaults))
+
+;;;###autoload
+(defun font-latex-setup ()
+ "Setup this buffer for LaTeX font-lock. Usually called from a hook."
+ (font-latex-set-syntactic-keywords)
+ ;; Trickery to make $$ fontification be in `font-latex-math-face' while
+ ;; strings get whatever `font-lock-string-face' has been set to.
+ (when (fboundp 'built-in-face-specifiers)
+ ;; Cool patch from Christoph Wedler...
+ (let (instance)
+ (mapc (lambda (property)
+ (setq instance
+ (face-property-instance 'font-latex-math-face property
+ nil 0 t))
+ (if (numberp instance)
+ (setq instance
+ (face-property-instance 'default property nil 0)))
+ (or (numberp instance)
+ (set-face-property 'font-lock-string-face property
+ instance (current-buffer))))
+ (built-in-face-specifiers))))
+
+ ;; Activate multi-line fontification facilities if available.
+ (when (boundp 'font-lock-multiline)
+ (set (make-local-variable 'font-lock-multiline) t))
+
+ ;; Functions for extending the region.
+ (dolist (elt '(font-latex-extend-region-backwards-command-with-args
+ font-latex-extend-region-backwards-command-in-braces
+ font-latex-extend-region-backwards-quotation
+ font-latex-extend-region-backwards-math-env
+ font-latex-extend-region-backwards-math-envII))
+ (add-to-list 'font-latex-extend-region-functions elt))
+
+ ;; Tell Font Lock about the support.
+ (make-local-variable 'font-lock-defaults)
+ ;; The test for `major-mode' currently only works with docTeX mode
+ ;; because `TeX-install-font-lock' is called explicitely in
+ ;; `doctex-mode'. In case other modes have to be distinguished as
+ ;; well, remove the call to `TeX-install-font-lock' from
+ ;; `VirTeX-common-initialization' and place it in the different
+ ;; `xxx-mode' calls instead, but _after_ `major-mode' is set.
+ (let ((defaults
+ `((font-latex-keywords font-latex-keywords-1 font-latex-keywords-2)
+ nil nil ,font-latex-syntax-alist nil))
+ (variables
+ '((font-lock-comment-start-regexp . "%")
+ (font-lock-mark-block-function . mark-paragraph)
+ (font-lock-fontify-region-function
+ . font-latex-fontify-region)
+ (font-lock-unfontify-region-function
+ . font-latex-unfontify-region))))
+ ;; Add the mode-dependent stuff to the basic variables defined above.
+ (if (eq major-mode 'doctex-mode)
+ (progn
+ (setcar defaults (append (car defaults)
+ '(font-latex-doctex-keywords)))
+ (setq variables
+ (append variables
+ '((font-lock-syntactic-face-function
+ . font-latex-doctex-syntactic-face-function)
+ (font-lock-syntactic-keywords
+ . font-latex-doctex-syntactic-keywords)))))
+ (setq variables
+ (append variables
+ '((font-lock-syntactic-face-function
+ . font-latex-syntactic-face-function)
+ (font-lock-syntactic-keywords
+ . font-latex-syntactic-keywords)))))
+ ;; Cater for the idiosyncrasies of Emacs and XEmacs.
+ (if (featurep 'xemacs)
+ (progn
+ ;; XEmacs does not set these variables via `font-lock-defaults'
+ ;; but requires them to be set explicitely.
+ (mapc (lambda (alist)
+ (set (car alist) (cdr alist))) variables)
+ ;; Has to be set to t as otherwise syntax properties will not be
+ ;; be picked up during fontification.
+ (set (make-local-variable 'lookup-syntax-properties) t))
+ (setq defaults (append defaults variables)))
+ ;; Set the defaults.
+ (setq font-lock-defaults defaults)))
+
+(defun font-latex-jit-lock-force-redisplay (buf start end)
+ "Compatibility for Emacsen not offering `jit-lock-force-redisplay'."
+ (if (fboundp 'jit-lock-force-redisplay)
+ (jit-lock-force-redisplay buf start end)
+ ;; The following block is an expansion of `jit-lock-force-redisplay'
+ ;; and involved macros taken from CVS Emacs on 2007-04-28.
+ (with-current-buffer buf
+ (let ((modified (buffer-modified-p)))
+ (unwind-protect
+ (let ((buffer-undo-list t)
+ (inhibit-read-only t)
+ (inhibit-point-motion-hooks t)
+ (inhibit-modification-hooks t)
+ deactivate-mark
+ buffer-file-name
+ buffer-file-truename)
+ (put-text-property start end 'fontified t))
+ (unless modified
+ (restore-buffer-modified-p nil)))))))
+
+(defun font-latex-fontify-region (beg end &optional loudly)
+ "Fontify region from BEG to END.
+If optional argument is non-nil, print status messages."
+ (let ((extend-list (delq nil (mapcar (lambda (fun) (funcall fun beg end))
+ font-latex-extend-region-functions))))
+ (when extend-list
+ (let ((orig-beg beg))
+ (setq beg (apply 'min extend-list))
+ (when (featurep 'jit-lock)
+ ;; Stolen from `jit-lock-fontify-now' (2007-04-27) and
+ ;; adapted. Without this stanza only the line in which a
+ ;; change happened will refontified. The rest will only be
+ ;; refontified upon redisplay.
+ (run-with-timer 0 nil 'font-latex-jit-lock-force-redisplay
+ (current-buffer) beg orig-beg))))
+ (font-lock-default-fontify-region beg end loudly)))
+
+;; Copy and adaption of `tex-font-lock-unfontify-region' from
+;; tex-mode.el in GNU Emacs on 2004-08-04.
+;; (XEmacs passes a third argument to the function.)
+(defun font-latex-unfontify-region (beg end &rest ignored)
+ "Unfontify region from BEG to END."
+ (font-lock-default-unfontify-region beg end)
+ ;; XEmacs does not provide `font-lock-extra-managed-props', so
+ ;; remove the `font-latex-multiline' property manually. (The
+ ;; property is only added if `font-lock-multiline' is bound.)
+ (unless (boundp 'font-lock-multiline)
+ (remove-text-properties beg end '(font-latex-multiline)))
+ (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))
+ (list (nth 1 (car font-latex-script-display))
+ (nth 1 (cdr font-latex-script-display))))
+ (null (cddr prop)))
+ (put-text-property beg next 'display nil))
+ (setq beg next))))
+
+(defadvice font-lock-after-change-function (before font-latex-after-change
+ activate)
+ "Extend region for fontification of multiline constructs.
+This is only necessary if the editor does not provide multiline
+fontification facilities like `font-lock-multiline' itself."
+ (unless (boundp 'font-lock-multiline)
+ (let ((ad-beg (ad-get-arg 0))
+ (ad-end (ad-get-arg 1)))
+ (save-excursion
+ (goto-char ad-beg)
+ (beginning-of-line)
+ (when (get-text-property (point) 'font-latex-multiline)
+ (setq ad-beg (previous-single-property-change (point)
+ 'font-latex-multiline))
+ (when (numberp ad-beg)
+ (ad-set-arg 0 ad-beg)))
+ (goto-char ad-end)
+ (end-of-line)
+ (when (get-text-property (point) 'font-latex-multiline)
+ (setq ad-end (next-single-property-change (point)
+ 'font-latex-multiline))
+ (when (numberp ad-end)
+ (ad-set-arg 1 ad-end)))))))
+
+
+;;; Utility functions
+
+(defun font-latex-find-matching-close (openchar closechar)
+ "Skip over matching pairs of OPENCHAR and CLOSECHAR.
+OPENCHAR is the opening character and CLOSECHAR is the closing
+character. Character pairs are usually { } or [ ]. Comments are
+ignored during the search."
+ (let ((parse-sexp-ignore-comments
+ (not (eq major-mode 'doctex-mode))) ; scan-sexps ignores comments
+ (init-point (point))
+ (mycount 1)
+ (esc-char (or (and (boundp 'TeX-esc) TeX-esc) "\\"))
+ ;; XXX: Do not look up syntax-table properties since they may
+ ;; be misleading, e.g. in the case of "{foo}^^A" where the
+ ;; closing brace gets a comment end syntax.
+ (parse-sexp-lookup-properties nil))
+ (or
+ (condition-case nil
+ (progn
+ (goto-char (with-syntax-table
+ (TeX-search-syntax-table openchar closechar)
+ (scan-sexps (point) 1)))
+ ;; No error code. See if closechar is unquoted
+ (save-excursion
+ (backward-char 1)
+ (zerop (mod (skip-chars-backward (regexp-quote esc-char)) 2))))
+ (error nil))
+ (save-match-data
+ (goto-char (1+ init-point))
+ (while (and (> mycount 0)
+ (re-search-forward
+ (string ?\[
+ ;; closechar might be ]
+ ;; and therefor must be first in regexp
+ closechar openchar
+ ?\])
+ nil t))
+ (cond
+ ((font-latex-commented-outp)
+ (forward-line 1))
+ ((save-excursion
+ (backward-char 1)
+ (zerop (mod (skip-chars-backward (regexp-quote esc-char))
+ 2)))
+ (setq mycount (+ mycount
+ (if (= (preceding-char) openchar) 1 -1)))))))
+ (if (= mycount 0)
+ t
+ (goto-char init-point)
+ nil))))
+
+(defun font-latex-commented-outp ()
+ "Return t if comment character is found between bol and point."
+ (save-excursion
+ (let ((limit (point))
+ (esc-char (if (and (boundp 'TeX-esc) TeX-esc) TeX-esc "\\")))
+ (forward-line 0)
+ (if (and (eq (char-after) ?\%)
+ (not (font-latex-faces-present-p 'font-latex-verbatim-face)))
+ (not (eq major-mode 'doctex-mode))
+ (catch 'found
+ (while (progn (skip-chars-forward "^%" limit)
+ (< (point) limit))
+ (when (and (save-excursion
+ (zerop (mod (skip-chars-backward
+ (regexp-quote esc-char)) 2)))
+ (not (font-latex-faces-present-p
+ 'font-latex-verbatim-face)))
+ (throw 'found t))
+ (forward-char)))))))
+
+(defun font-latex-faces-present-p (faces &optional pos)
+ "Return t if FACES are present at position POS.
+FACES may be a single face or a list of faces.
+If POS is omitted, the current position of point is used."
+ (let* ((faces (if (listp faces) faces (list faces)))
+ (pos (or pos (point)))
+ (prop (get-text-property pos 'face))
+ (prop-list (if (listp prop) prop (list prop))))
+ (catch 'member
+ (dolist (item prop-list)
+ (when (memq item faces)
+ (throw 'member t))))))
+
+(defun font-latex-forward-comment ()
+ "Like `forward-comment' but with special provisions for docTeX mode.
+In docTeX mode \"%\" at the start of a line will be treated as whitespace."
+ (if (eq major-mode 'doctex-mode)
+ ;; XXX: We should probably cater for ^^A as well.
+ (progn
+ (while (progn (if (bolp) (skip-chars-forward "%"))
+ (> (skip-chars-forward " \t\n") 0)))
+ (when (eq (char-after) ?%)
+ (beginning-of-line 2)
+ t))
+ (forward-comment 1)))
+
+(defun font-latex-put-multiline-property-maybe (beg end)
+ "Add a multiline property if no equivalent is provided by the editor.
+The text property is used to find the start or end of a multiline
+construct when unfontifying a region. Emacs adds such a text
+property automatically if `font-lock-multiline' is set to t and
+extends the region to be unfontified automatically as well.
+XEmacs does not do this at the time of this writing."
+ (unless (boundp 'font-lock-multiline)
+ (put-text-property beg end 'font-latex-multiline t)))
+
+
+;;; Match functions
+
+(defvar font-latex-matched-faces nil
+ "List of faces corresponding to matches in match data.")
+
+(defun font-latex-matched-face (pos)
+ "Return face at position POS in `font-latex-matched-faces'."
+ (nth pos font-latex-matched-faces))
+
+(defvar font-latex-command-with-args-default-spec nil ; "*[{"
+ "Default specifier for keywords without syntax description.
+Set this to nil if verification of command syntax is unwanted.")
+
+(defvar font-latex-command-with-args-opt-arg-delims
+ '((?[ . ?]) (?< . ?>) (?\( . ?\)))
+ "List character pairs used as delimiters for optional arguments.")
+
+(defvar font-latex-syntax-error-modes '(latex-mode)
+ "List of modes where syntax errors in macros should be indicated.")
+
+(defun font-latex-match-command-with-arguments (regexp keywords face limit)
+ "Search for regexp command KEYWORDS[opt]{arg} before LIMIT.
+Returns nil if none of KEYWORDS is found."
+ (setq font-latex-matched-faces nil)
+ (catch 'match
+ (while (re-search-forward regexp limit t)
+ (unless (font-latex-faces-present-p '(font-lock-comment-face
+ font-latex-verbatim-face)
+ (match-beginning 0))
+ (let* ((beg (match-beginning 0))
+ end ; Used for multiline text property.
+ match-data match-beg syntax-error alternative spec
+ error-indicator-pos
+ (spec-list (string-to-list
+ (or (cadr (assoc (match-string 1) keywords))
+ font-latex-command-with-args-default-spec)))
+ (parse-sexp-ignore-comments t)) ; scan-sexps ignores comments
+ (add-to-list 'match-data beg)
+ (goto-char (match-end 0))
+ ;; Check for starred macro if first spec is an asterisk.
+ (when (eq (car spec-list) ?*)
+ (setq spec-list (cdr spec-list))
+ (skip-chars-forward "*" (1+ (point))))
+ ;; Add current point to match data and use keyword face for
+ ;; region from start to point.
+ (add-to-list 'match-data (point) t)
+ (add-to-list 'font-latex-matched-faces 'font-lock-keyword-face)
+ (setq end (point))
+ (catch 'break
+ ;; Walk the list of specs.
+ (while spec-list
+ (setq spec (pop spec-list)
+ error-indicator-pos beg)
+ (while (and (not (eobp)) (font-latex-forward-comment)))
+ ;; Alternative
+ (when (eq spec ?|)
+ (setq alternative t)
+ (setq spec (pop spec-list)))
+ (cond
+ ;; Macros: \foo
+ ((eq spec ?\\)
+ (if (eq (char-after) spec)
+ (progn
+ (nconc match-data
+ (list (point)
+ (progn
+ (forward-char)
+ (if (zerop (skip-chars-forward "A-Za-z@"))
+ (forward-char) ; Single-char macro.
+ (skip-chars-forward "*"))
+ (point))))
+ (nconc font-latex-matched-faces (list face))
+ (setq end (max end (point)))
+ (when alternative (pop spec-list)))
+ (setq syntax-error t)
+ (throw 'break nil)))
+ ;; Mandatory arguments: {...}
+ ((eq spec ?{)
+ (if (and (eq (char-after) spec)
+ (setq match-beg (point))
+ (font-latex-find-matching-close ?{ ?}))
+ (progn
+ (nconc match-data (list (1+ match-beg) (1- (point))))
+ (nconc font-latex-matched-faces (list face))
+ (setq end (max end (1- (point))))
+ (when alternative (pop spec-list)))
+ (unless alternative
+ (setq syntax-error t)
+ (when (and match-beg (= match-beg (point)))
+ (setq error-indicator-pos match-beg))
+ (throw 'break nil))))
+ ;; Optional arguments: [...] and others
+ ((eq (char-after) spec)
+ (setq match-beg (point))
+ (if (font-latex-find-matching-close
+ spec (cdr (assq
+ spec
+ font-latex-command-with-args-opt-arg-delims)))
+ (progn
+ (nconc match-data (list (1+ match-beg) (1- (point))))
+ (nconc font-latex-matched-faces
+ (list 'font-lock-variable-name-face))
+ (setq end (max end (1- (point)))))
+ (setq syntax-error t
+ error-indicator-pos match-beg)
+ (throw 'break nil))))
+ (setq alternative nil)))
+ (when (and syntax-error (memq major-mode
+ font-latex-syntax-error-modes))
+ ;; Add the warning face at the front of the list because
+ ;; the matcher uses 'append and the face would otherwise
+ ;; be overridden by the keyword face.
+ (setq match-data (append (list error-indicator-pos
+ (1+ error-indicator-pos))
+ match-data))
+ (push 'font-latex-warning-face font-latex-matched-faces))
+ (font-latex-put-multiline-property-maybe beg end)
+ (store-match-data match-data)
+ (throw 'match t))))))
+
+(defun font-latex-extend-region-backwards-command-with-args (beg end)
+ "Return position to extend region backwards for commands with args.
+Return nil if region does not have to be extended for a multiline
+macro to fit in. The region between the positions BEG and END
+marks boundaries for searching for macro ends."
+ (save-excursion
+ (goto-char end)
+ (catch 'extend
+ (while (TeX-search-backward-unescaped "}" beg t)
+ (let ((macro-start (TeX-find-macro-start
+ (max (point-min)
+ (- beg font-latex-multiline-boundary)))))
+ (when (and macro-start
+ (< macro-start beg))
+ (throw 'extend macro-start))))
+ nil)))
+
+(defun font-latex-match-command-in-braces (keywords limit)
+ "Search for command like {\\bfseries fubar} before LIMIT.
+Sets `match-data' so that:
+ subexpression 0 is a warning indicator,
+ subexpression 1 is the keyword, and
+ subexpression 2 is the rest in the TeX group.
+Returns nil if no command is found."
+ (catch 'match
+ (while (re-search-forward keywords limit t)
+ (unless (font-latex-faces-present-p '(font-lock-comment-face
+ font-latex-verbatim-face)
+ (match-beginning 0))
+ (let ((kbeg (match-beginning 0)) (kend (match-end 1))
+ (beg (match-end 0))
+ end cbeg cend
+ (parse-sexp-ignore-comments t)) ; scan-sexps ignores comments
+ (goto-char kbeg)
+ (if (not (eq (preceding-char) ?\{))
+ ;; Fontify only the keyword (no argument found).
+ (progn
+ (setq cbeg kbeg cend kend)
+ (goto-char (match-end 0))
+ (store-match-data (list (point) (point)
+ (point) (point)
+ cbeg cend))
+ (throw 'match t))
+ ;; There's an opening bracket
+ (save-restriction
+ ;; Restrict to LIMIT.
+ (narrow-to-region (point-min) limit)
+ (forward-char -1) ; Move on the opening bracket
+ (if (font-latex-find-matching-close ?\{ ?\})
+ (progn
+ (font-latex-put-multiline-property-maybe beg (1- (point)))
+ (store-match-data (list kbeg kbeg
+ kbeg kend
+ beg (1- (point)))))
+ (goto-char kend)
+ (store-match-data (list (1- kbeg) kbeg
+ kbeg kend
+ kend kend)))
+ (throw 'match t))))))))
+
+(defun font-latex-extend-region-backwards-command-in-braces (beg end)
+ "Return position to extend region backwards for commands in braces.
+Return nil if region does not have to be extended for a multiline
+group to fit in. The region between the positions BEG and END
+marks boundaries for searching for group ends."
+ (save-excursion
+ (goto-char end)
+ (catch 'extend
+ (while (TeX-search-backward-unescaped "}" beg t)
+ (let ((group-start (TeX-find-opening-brace
+ nil (max (point-min)
+ (- beg font-latex-multiline-boundary)))))
+ (when group-start
+ ;; XXX: Actually we'd have to check if any of the
+ ;; declaration-type macros can be found right after the
+ ;; brace. If we don't do this (like now) large regions
+ ;; may be refontified for no good reason. For checking
+ ;; the built-in `font-latex-match-*' variables for
+ ;; declaration-type macros as well as the respective
+ ;; user-defined variables could be concatenated.
+ (goto-char group-start)
+ (when (< group-start beg)
+ (throw 'extend group-start)))))
+ nil)))
+
+(defun font-latex-match-simple-command (limit)
+ "Search for command like \\foo before LIMIT."
+ (TeX-re-search-forward-unescaped "\\\\[@A-Za-z]+" limit t))
+
+(defun font-latex-match-math-env (limit)
+ "Match math pattern up to LIMIT.
+Used for patterns like:
+\\( F = ma \\)
+\\[ F = ma \\] but not \\\\ [len]"
+ (catch 'match
+ (while (re-search-forward "\\(\\\\(\\)\\|\\(\\\\\\[\\)" limit t)
+ (unless (save-excursion
+ (goto-char (match-beginning 0))
+ ;; \\[ does not start a math environment
+ (/= (mod (skip-chars-backward "\\\\") 2) 0))
+ (let ((beg (match-beginning 0))
+ (open-tag (if (match-beginning 1) "\\(" "\\["))
+ (close-tag (if (match-beginning 1) "\\)" "\\]")))
+ ;; Search for both opening and closing tags in order to be
+ ;; able to avoid erroneously matching stuff like "\(foo \(bar\)".
+ (if (and (re-search-forward (concat "[^\\]\\(?:\\\\\\\\\\)*\\("
+ (regexp-quote open-tag) "\\|"
+ (regexp-quote close-tag) "\\)")
+ limit 'move)
+ (string= (match-string 1) close-tag))
+ ;; Found closing tag.
+ (progn
+ (font-latex-put-multiline-property-maybe beg (point))
+ (store-match-data (list beg beg beg (point))))
+ ;; Did not find closing tag.
+ (goto-char (+ beg 2))
+ (store-match-data (list beg (point) (point) (point))))
+ (throw 'match t))))))
+
+(defun font-latex-extend-region-backwards-math-env (beg end)
+ "Return position to extend region backwards for math environments.
+Return nil if region does not have to be extended for a multiline
+environment to fit in. The region between the positions BEG and
+END marks boundaries for searching for environment ends."
+ (save-excursion
+ (goto-char end)
+ (catch 'extend
+ (while (re-search-backward "\\(\\\\)\\)\\|\\(\\\\]\\)" beg t)
+ (when (and (zerop (mod (skip-chars-backward "\\\\") 2))
+ (re-search-backward
+ (concat "[^\\]\\(?:\\\\\\\\\\)*\\("
+ (regexp-quote (if (match-beginning 1) "\\(" "\\["))
+ "\\)")
+ (- beg font-latex-multiline-boundary) t)
+ (goto-char (match-beginning 1))
+ (< (point) beg))
+ (throw 'extend (point))))
+ nil)))
+
+(defcustom font-latex-math-environments
+ '("display" "displaymath" "equation" "eqnarray" "gather" "multline"
+ "align" "alignat" "xalignat")
+ "List of math environment names for font locking."
+ :type '(repeat string)
+ :group 'font-latex)
+
+(defun font-latex-match-math-envII (limit)
+ "Match math patterns up to LIMIT.
+Used for patterns like:
+\\begin{equation}
+ fontified stuff
+\\end{equation}
+The \\begin{equation} and \\end{equation} are not fontified here."
+ (when (re-search-forward (concat "\\\\begin[ \t]*{"
+ (regexp-opt font-latex-math-environments t)
+ "\\*?}")
+ limit t)
+ (let ((beg (match-end 0)) end)
+ (if (re-search-forward (concat "\\\\end[ \t]*{"
+ (regexp-quote
+ (buffer-substring-no-properties
+ (match-beginning 1)
+ (match-end 0))))
+ ;; XXX: Should this rather be done by
+ ;; extending the region to be fontified?
+ (+ limit font-latex-multiline-boundary) 'move)
+ (setq end (match-beginning 0))
+ (goto-char beg)
+ (setq end beg))
+ (font-latex-put-multiline-property-maybe beg end)
+ (store-match-data (list beg end))
+ t)))
+
+(defun font-latex-extend-region-backwards-math-envII (beg end)
+ "Return position to extend region backwards for math environments.
+Return nil if region does not have to be extended for a multiline
+environment to fit in. The region between the positions BEG and
+END marks boundaries for searching for environment ends."
+ (save-excursion
+ (goto-char end)
+ (catch 'extend
+ (while (re-search-backward
+ (concat "\\\\end[ \t]*{"
+ (regexp-opt font-latex-math-environments t)
+ "\\*?}") beg t)
+ (when (and (re-search-backward (concat "\\\\begin[ \t]*{"
+ (buffer-substring-no-properties
+ (match-beginning 1)
+ (match-end 0)))
+ (- beg font-latex-multiline-boundary) t)
+ (< (point) beg))
+ (throw 'extend (point))))
+ nil)))
+
+(defun font-latex-update-quote-list ()
+ "Update quote list and regexp if value of `font-latex-quotes' changed."
+ (unless (eq font-latex-quotes-control font-latex-quotes)
+ (setq font-latex-quotes-control font-latex-quotes)
+ (font-latex-quotes-set-internal)
+ ;; Set order of each entry in `font-latex-quote-list' according to
+ ;; setting of `font-latex-quotes-internal'.
+ (let ((tail font-latex-quote-list)
+ elt)
+ (while tail
+ (setq elt (car tail))
+ (when (and (> (safe-length elt) 2)
+ (not (eq (nth 2 elt) font-latex-quotes-internal)))
+ (setcar tail (list (nth 1 elt) (nth 0 elt)
+ font-latex-quotes-internal)))
+ (setq tail (cdr tail))))
+ (setq font-latex-quote-regexp-beg
+ (regexp-opt (mapcar 'car font-latex-quote-list) t))))
+
+(defun font-latex-match-quotation (limit)
+ "Match quote patterns up to LIMIT.
+Used for patterns like:
+``this is a normal quote'' and these are multilingual quoted strings:
+\"< french \"> and \"`german\"' quotes.
+The quotes << french >> and 8-bit french are used if `font-latex-quotes' is
+set to french, and >>german<< (and 8-bit) are used if set to german."
+ (when font-latex-quotes
+ (font-latex-update-quote-list)
+ ;; Search for matches.
+ (catch 'match
+ (while (TeX-re-search-forward-unescaped
+ font-latex-quote-regexp-beg limit t)
+ (unless (font-latex-faces-present-p '(font-lock-comment-face
+ font-latex-verbatim-face
+ font-latex-math-face)
+ (match-beginning 0))
+ (let* ((beg (match-beginning 0))
+ (after-beg (match-end 0))
+ (opening-quote (match-string 0))
+ (closing-quote
+ (nth 1 (assoc (if (fboundp 'string-make-multibyte)
+ (string-make-multibyte (match-string 0))
+ (match-string 0))
+ font-latex-quote-list)))
+ (nest-count 0)
+ (point-of-surrender (+ beg font-latex-multiline-boundary)))
+ ;; Find closing quote taking nested quotes into account.
+ (while (progn
+ (re-search-forward
+ (concat opening-quote "\\|" closing-quote)
+ point-of-surrender 'move)
+ (when (and (< (point) point-of-surrender) (not (eobp)))
+ (if (string= (match-string 0) opening-quote)
+ (setq nest-count (1+ nest-count))
+ (when (/= nest-count 0)
+ (setq nest-count (1- nest-count)))))))
+ ;; If no closing quote was found, set the second match which
+ ;; will be marked with warning color, if one was found, set
+ ;; the first match which will be marked with string color.
+ (if (or (= (point) point-of-surrender) (eobp))
+ (progn
+ (goto-char after-beg)
+ (store-match-data (list after-beg after-beg beg after-beg)))
+ (font-latex-put-multiline-property-maybe beg (point))
+ (store-match-data (list beg (point) (point) (point))))
+ (throw 'match t)))))))
+
+(defun font-latex-extend-region-backwards-quotation (beg end)
+ "Return position to extend region backwards for quotations.
+Return nil if region does not have to be extended for a multiline
+quotation to fit in. The region between the positions BEG and
+END marks boundaries for searching for quotation ends."
+ (if font-latex-quotes
+ (progn
+ (font-latex-update-quote-list)
+ (let ((regexp-end (regexp-opt (mapcar 'cadr font-latex-quote-list) t)))
+ (save-excursion
+ (goto-char end)
+ (catch 'extend
+ (while (re-search-backward regexp-end beg t)
+ (let ((closing-quote (match-string 0))
+ (nest-count 0)
+ (point-of-surrender (- beg font-latex-multiline-boundary))
+ opening-quote)
+ (catch 'found
+ (dolist (elt font-latex-quote-list)
+ (when (string= (cadr elt) closing-quote)
+ (setq opening-quote (car elt))
+ (throw 'found nil))))
+ ;; Find opening quote taking nested quotes into account.
+ (while (progn
+ (re-search-backward (concat opening-quote "\\|"
+ closing-quote)
+ point-of-surrender 'move)
+ (when (and (> (point) point-of-surrender)
+ (not (bobp)))
+ (if (string= (match-string 0) closing-quote)
+ (setq nest-count (1+ nest-count))
+ (when (/= nest-count 0)
+ (setq nest-count (1- nest-count)))))))
+ (when (< (point) beg)
+ (throw 'extend (point)))))
+ nil))))
+ nil))
+
+(defun font-latex-match-script (limit)
+ "Match subscript and superscript patterns up to LIMIT."
+ (when (and font-latex-fontify-script
+ (re-search-forward "[_^] *\\([^\n\\{}]\\|\
+\\\\\\([a-zA-Z@]+\\|[^ \t\n]\\)\\|\\({\\)\\)" limit t))
+ (if (font-latex-faces-present-p '(font-latex-subscript-face
+ font-latex-superscript-face))
+ ;; Apply subscript and superscript highlighting only once in
+ ;; order to prevent the font size becoming too small. We set
+ ;; an empty match to do that.
+ (let ((point (point)))
+ (store-match-data (list point point point point)))
+ (when (match-end 3)
+ (let ((beg (match-beginning 3))
+ (end (TeX-find-closing-brace
+ ;; Don't match groups spanning more than one line
+ ;; in order to avoid visually wrong indentation in
+ ;; subsequent lines.
+ nil (line-end-position))))
+ (store-match-data (if end
+ (list (match-beginning 0) end beg end)
+ (list beg beg beg beg))))))
+ t))
+
+;; Copy and adaption of `tex-font-lock-suscript' from tex-mode.el in
+;; GNU Emacs on 2004-07-07.
+(defun font-latex-script (pos)
+ "Return face and display spec for subscript and superscript content."
+ (when (and (font-latex-faces-present-p 'font-latex-math-face pos)
+ (not (font-latex-faces-present-p '(font-lock-constant-face
+ font-lock-builtin-face
+ font-lock-comment-face
+ font-latex-verbatim-face) pos))
+ ;; Check for backslash quoting
+ (not (let ((odd nil)
+ (pos pos))
+ (while (eq (char-before pos) ?\\)
+ (setq pos (1- pos) odd (not odd)))
+ odd)))
+ ;; Adding other text properties than `face' is supported by
+ ;; `font-lock-apply-highlight' in CVS Emacsen since 2001-10-28.
+ ;; With the introduction of this feature the variable
+ ;; `font-lock-extra-managed-props' was introduced and serves here
+ ;; for feature checking. XEmacs (CVS and 21.4.15) currently
+ ;; (2004-08-18) does not support this feature.
+ (let ((extra-props-flag (boundp 'font-lock-extra-managed-props)))
+ (if (eq (char-after pos) ?_)
+ (if extra-props-flag
+ `(face font-latex-subscript-face display
+ ,(car font-latex-script-display))
+ 'font-latex-subscript-face)
+ (if extra-props-flag
+ `(face font-latex-superscript-face display
+ ,(cdr font-latex-script-display))
+ 'font-latex-superscript-face)))))
+
+
+;;; docTeX
+
+(defvar font-latex-doctex-preprocessor-face
+ 'font-latex-doctex-preprocessor-face
+ "Face used to highlight preprocessor directives in docTeX mode.")
+
+(defface font-latex-doctex-preprocessor-face
+ '((t (:inherit (font-latex-doctex-documentation-face
+ font-lock-builtin-face ; Emacs 21 does not provide
+ ; the preprocessor face.
+ font-lock-preprocessor-face))))
+ "Face used to highlight preprocessor directives in docTeX mode."
+ :group 'font-latex-highlighting-faces)
+
+(defvar font-latex-doctex-documentation-face
+ 'font-latex-doctex-documentation-face
+ "Face used to highlight the documentation in docTeX mode.")
+
+(defface font-latex-doctex-documentation-face
+ '((((class mono)) (:inverse-video t))
+ (((class grayscale) (background dark)) (:background "#333"))
+ (((class color) (background dark)) (:background "#333"))
+ (t (:background "#eeeeee")))
+ "Face used to highlight the documentation parts in docTeX mode."
+ :group 'font-latex-highlighting-faces)
+
+(defvar font-latex-doctex-keywords
+ (append font-latex-keywords-2
+ '(("^%<[^>]*>" (0 font-latex-doctex-preprocessor-face t)))))
+
+;; Set and updated in `font-latex-set-syntactic-keywords'.
+(defvar font-latex-doctex-syntactic-keywords nil)
+
+;; Copy and adaptation of `doctex-font-lock-^^A' in `tex-mode.el' of
+;; CVS Emacs (March 2004)
+(defun font-latex-doctex-^^A ()
+ (if (eq (char-after (line-beginning-position)) ?\%)
+ (progn
+ (put-text-property
+ (1- (match-beginning 1)) (match-beginning 1) 'syntax-table
+ (if (= (1+ (line-beginning-position)) (match-beginning 1))
+ ;; The `%' is a single-char comment, which Emacs
+ ;; syntax-table can't deal with. We could turn it
+ ;; into a non-comment, or use `\n%' or `%^' as the comment.
+ ;; Instead, we include it in the ^^A comment.
+ ;; COMPATIBILITY for Emacs 20 and XEmacs
+ (eval-when-compile (if (fboundp 'string-to-syntax)
+ (string-to-syntax "< b")
+ '(2097163)))
+ ;; COMPATIBILITY for Emacs 20 and XEmacs
+ (eval-when-compile (if (fboundp 'string-to-syntax)
+ (string-to-syntax ">")
+ '(12)))))
+ (let ((end (line-end-position)))
+ (if (< end (point-max))
+ (put-text-property end (1+ end) 'syntax-table
+ ;; COMPATIBILITY for Emacs 20 and XEmacs
+ (eval-when-compile
+ (if (fboundp 'string-to-syntax)
+ (string-to-syntax "> b")
+ '(2097164))))))
+ ;; COMPATIBILITY for Emacs 20 and XEmacs
+ (eval-when-compile (if (fboundp 'string-to-syntax)
+ (string-to-syntax "< b")
+ '(2097163))))))
+
+;; Copy and adaptation of `doctex-font-lock-syntactic-face-function'
+;; in `tex-mode.el' of CVS Emacs (March 2004)
+(defun font-latex-doctex-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.
+ (font-latex-syntactic-face-function state)
+ font-latex-doctex-documentation-face))
+
+
+;;; Installation in non-AUCTeX LaTeX mode
+
+(add-hook 'latex-mode-hook 'font-latex-setup)
+;; If font-latex is loaded using a latex-mode-hook, then the add-hook above
+;; won't be called this time around. Check for this now:
+(if (eq major-mode 'latex-mode)
+ (font-latex-setup))
+
+
+;;; Byte-compilation of generated functions
+
+(when (byte-code-function-p
+ (symbol-function 'font-latex-make-built-in-keywords))
+ (dolist (elt font-latex-built-in-keyword-classes)
+ (let ((name (nth 0 elt)))
+ (byte-compile (intern (concat "font-latex-" name)))
+ (byte-compile (intern (concat "font-latex-" name "-make"))))))
+
+
+;; Provide ourselves:
+(provide 'font-latex)
+
+;; Local Variables:
+;; coding: iso-8859-1
+;; End:
+
+;;; font-latex.el ends here
--- /dev/null
+/* XPM */
+static char * amstex_xpm[] = {
+"24 24 180 2",
+" c None s backgroundToolBarColor",
+". c #3E9543",
+"+ c #409644",
+"@ c #3D9D45",
+"# c #3F9B42",
+"$ c #4C2A1F",
+"% c #4E3124",
+"& c #727E51",
+"* c #598A4E",
+"= c #5B6647",
+"- c #88624F",
+"; c #89383B",
+"> c #8B343B",
+", c #6D5852",
+"' c #506D48",
+") c #4C843E",
+"! c #648752",
+"~ c #B8A789",
+"{ c #80624D",
+"] c #7D6951",
+"^ c #FFFFC1",
+"/ c #94A676",
+"( c #8F8668",
+"_ c #977567",
+": c #A86660",
+"< c #986C6A",
+"[ c #758660",
+"} c #708C60",
+"| c #6A6C4E",
+"1 c #C3C599",
+"2 c #988167",
+"3 c #5A3125",
+"4 c #561E1C",
+"5 c #958066",
+"6 c #BEA384",
+"7 c #68372B",
+"8 c #672124",
+"9 c #5B392F",
+"0 c #94917B",
+"a c #AFAC91",
+"b c #B8B39C",
+"c c #BDBCA0",
+"d c #B39073",
+"e c #582522",
+"f c #712E2B",
+"g c #6F292C",
+"h c #83826F",
+"i c #908F88",
+"j c #F8FFFD",
+"k c #686C8D",
+"l c #D7DBB8",
+"m c #716D76",
+"n c #7B7B92",
+"o c #D5D5B3",
+"p c #DBBD9A",
+"q c #81463B",
+"r c #691A19",
+"s c #838270",
+"t c #888791",
+"u c #6462D0",
+"v c #2C2B87",
+"w c #DAD9C7",
+"x c #868394",
+"y c #716DDC",
+"z c #2F2C94",
+"A c #C7C6B7",
+"B c #D2AF8D",
+"C c #84473C",
+"D c #6D1E1F",
+"E c #6E262C",
+"F c #BDBDAB",
+"G c #878593",
+"H c #909095",
+"I c #C0BEAF",
+"J c #A09EAD",
+"K c #A6A5A9",
+"L c #C19978",
+"M c #7C3D33",
+"N c #641C1F",
+"O c #662633",
+"P c #DBDCB8",
+"Q c #B4B492",
+"R c #E5D9AA",
+"S c #9F755A",
+"T c #50231F",
+"U c #672424",
+"V c #8E3B4B",
+"W c #E4E3BC",
+"X c #A5A28D",
+"Y c #D2D1B5",
+"Z c #E7E5C1",
+"` c #E3DFC0",
+" . c #E4CCA2",
+".. c #894E3A",
+"+. c #461715",
+"@. c #632524",
+"#. c #95404E",
+"$. c #777776",
+"%. c #C0B396",
+"&. c #AAAB90",
+"*. c #463F31",
+"=. c #665E46",
+"-. c #7C7968",
+";. c #B3AF92",
+">. c #D4BD97",
+",. c #804B37",
+"'. c #461F19",
+"). c #42201F",
+"!. c #5A4F43",
+"~. c #504334",
+"{. c #979183",
+"]. c #DCD8B5",
+"^. c #D0BC9D",
+"/. c #C8A487",
+"(. c #82493F",
+"_. c #3F1310",
+":. c #401613",
+"<. c #664B46",
+"[. c #DCD9BC",
+"}. c #B8B59D",
+"|. c #8C8977",
+"1. c #E9E7C0",
+"2. c #A2897B",
+"3. c #AE8872",
+"4. c #CFB89A",
+"5. c #A6715F",
+"6. c #4B1D19",
+"7. c #68272E",
+"8. c #6E2933",
+"9. c #453E37",
+"0. c #767361",
+"a. c #7F8170",
+"b. c #7B7B6C",
+"c. c #8E897E",
+"d. c #827F6E",
+"e. c #83876F",
+"f. c #847E70",
+"g. c #9C7964",
+"h. c #662F2A",
+"i. c #5D2D2E",
+"j. c #783C3F",
+"k. c #87826E",
+"l. c #B3B99A",
+"m. c #D1D1AB",
+"n. c #DFDDB9",
+"o. c #C3B191",
+"p. c #826453",
+"q. c #6D2B2A",
+"r. c #884144",
+"s. c #772B2F",
+"t. c #702F34",
+"u. c #AEA28C",
+"v. c #C1C3A2",
+"w. c #AEA07E",
+"x. c #C8C09F",
+"y. c #C4C6A3",
+"z. c #B6886B",
+"A. c #774237",
+"B. c #7E3E3D",
+"C. c #854748",
+"D. c #78373B",
+"E. c #6A2932",
+"F. c #5F343C",
+"G. c #7C474A",
+"H. c #815655",
+"I. c #7F534F",
+"J. c #8A5C54",
+"K. c #74504B",
+"L. c #8C615F",
+"M. c #7E2C29",
+"N. c #8C4240",
+"O. c #7C322F",
+"P. c #703634",
+"Q. c #6D1B27",
+"R. c #975F59",
+"S. c #631D22",
+"T. c #65101D",
+"U. c #000000",
+"V. c #868686",
+"W. c #AFAEAE",
+" . + @ # $ ",
+" % & * = - ; > , ' ) ! ~ { ",
+" ] ^ / ( _ : < [ } | 1 2 3 4 ",
+" 5 ^ ^ ^ ^ ^ ^ ^ ^ ^ 6 7 8 ",
+" 9 ^ 0 a ^ b 0 c ^ ^ d e f g ",
+" h i j k l m j n o ^ p q r ",
+" s t u v w x y z A ^ B C D E ",
+" ] F G H ^ I J K ^ ^ L M N O ",
+" ] ^ P Q ^ ^ ^ ^ ^ ^ R S T U V ",
+" ] ^ W X Y Z ` ^ ^ ^ ^ ...+.@.#. ",
+" $.$.%.%.&.*.=.-.;.%.%.%.^ >.,.'.). ",
+" %.%.^ ^ !.~.{.].^ ^ ^ ^./.(._.:. ",
+" $.$.<.[.^ }.|.1.^ 2.3.4.^ 5.6.7.8. ",
+" 9.0.a.b.c.d.e.f.^ ^ g.h.i.j. ",
+" k.^ l.^ ^ m.n.^ o.p.q.r.s.t. ",
+" u.v.%.w.x.y.z.A.B.C.D.E.F. ",
+" G.H.I.J.K.L.M.N.O.P. ",
+" Q.R. S. T. ",
+" ",
+" U.U. V.U.U.W. ",
+" U. U. U.U.V.U.V. U. ",
+" U. U. U. U. U. V.U.U.V. ",
+" U.U.U.U. U. U. U. U. ",
+" U.V. U. U. U. U. U.U.U.V. "};
--- /dev/null
+/* XPM */
+static char * bibtex14_xpm[] = {
+"24 24 55 1",
+" c None s backgroundToolBarColor",
+". c #353535",
+"+ c #877D55",
+"@ c #B9AD74",
+"# c #606060",
+"$ c #878585",
+"% c #A89C6A",
+"& c #726A49",
+"* c #070705",
+"= c #9A9A9A",
+"- c #59533A",
+"; c #938960",
+"> c #C9C7BF",
+", c #7C7C7C",
+"' c #3D3928",
+") c #AFA379",
+"! c #AFAEA8",
+"~ c #938A63",
+"{ c #3F3B2A",
+"] c #8E865E",
+"^ c #B6AA72",
+"/ c #424242",
+"( c #373737",
+"_ c #4E4C41",
+": c #565344",
+"< c #746D4E",
+"[ c #7E7652",
+"} c #8E845A",
+"| c #B0A46E",
+"1 c #775E5E",
+"2 c #F5F4F3",
+"3 c #D7D5D0",
+"4 c #BCB8AC",
+"5 c #A39F94",
+"6 c #817E71",
+"7 c #605D4F",
+"8 c #8A8058",
+"9 c #92885C",
+"0 c #826A6A",
+"a c #CACACA",
+"b c #FFFFFF",
+"c c #E6E6E5",
+"d c #D0D0D0",
+"e c #CCCCCC",
+"f c #C4C2B8",
+"g c #B5B2A5",
+"h c #918F84",
+"i c #59564C",
+"j c #F6F6F6",
+"k c #F3F2F0",
+"l c #AEAEAE",
+"m c #727272",
+"n c #909090",
+"o c #DCDCDC",
+"p c #A3A3A3",
+" ",
+" ",
+" .............. ",
+" .+@@@@@@@@@@@+# ",
+" $.@@@@@@@@@@@+. ",
+" .%&*@@@@@@@@@.= ",
+" .+@--@@*@-;@@+.> ",
+" $.@-*@@@@;*@@@.=>, ",
+" .%@*@*@*@'*@@+.>>..",
+" .+@*;--&&&*)*@.=>!, ",
+" $.@@@*-@*@*~~*@.>>,= ",
+" .%@@@@@@@@@{{@.=>!. ",
+" .+@@@@@@@@@@@@+.>>,= ",
+" $.]^@@@@@@@@@@@.=>!. ",
+" /(_:<[}|@@@@@@+.>>,= ",
+" /12234567:<[89.>>!. ",
+" /0abbb2cdefghi>>>,= ",
+" $#$ajbbbbbkcc>>!. ",
+" l=mnajbbbbbo>,= ",
+" l=mnajbbc>. ",
+" l=mnac,= ",
+" l=m. ",
+" p ",
+" "};
--- /dev/null
+/* XPM */
+static char * dropdown_xpm[] = {
+"10 24 3 1",
+" c None s backgroundToolBarColor",
+". c #292C29",
+"+ c #B3B3B3",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" . . ",
+" ... ... ",
+" ...... ",
+" .... ",
+" .. ",
+" ++ ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "};
--- /dev/null
+/* XPM */
+static char * dvipdf4_xpm[] = {
+"24 24 38 1",
+" c None s backgroundToolBarColor",
+". c #4C4C4C",
+"+ c #000000",
+"@ c #7C7C7C",
+"# c #577A4D",
+"$ c #4C6B43",
+"% c #37452B",
+"& c #76996C",
+"* c #9BB594",
+"= c #648C58",
+"- c #DAE3D6",
+"; c #445636",
+"> c #67865E",
+", c #A7BDA0",
+"' c #8EAB86",
+") c #526741",
+"! c #425D3A",
+"~ c #4C603C",
+"{ c #566B43",
+"] c #5A7046",
+"^ c #295E29",
+"/ c #5ABD5A",
+"( c #D37F71",
+"_ c #CE918A",
+": c #D4897A",
+"< c #67102D",
+"[ c #488148",
+"} c #C47474",
+"| c #D69788",
+"1 c #4CA14C",
+"2 c #4D904D",
+"3 c #CB8984",
+"4 c #D79C8D",
+"5 c #C8807D",
+"6 c #4FA64F",
+"7 c #5A5A5A",
+"8 c #B50000",
+"9 c #AA7979",
+" .+. ++++ ",
+" @+##$+@ +++%++ ",
+" +&**&=+ + +%+ ",
+" .#*-*&=$. +;+ ",
+" +>,*'==$+ +)+ ",
+" .#&&==#!. ++))~++ ",
+" +#==#$+ +{]{+ ",
+" @+!$!+@ +)+ ",
+" .+. + ",
+" ",
+" + ",
+"^^^/ ^ ^ ^ +(+ ",
+"^ ^ ^ ^ ^ +_:<+ ",
+"^ ^ [ [ ^ +}_|<<+ ",
+"^ ^ 1221 ^ +}3_4<<<+ ",
+"^ ^ [[ ^ +}53_4<<<<+",
+"^^^/ 66 ^ +}53_|<<<+ ",
+" 7+}5:<<+ ",
+" 7+(<+ ",
+"8889 8889 8889 ++ ",
+"8 8 8 8 8 ",
+"8889 8 8 889 ",
+"8 8 8 8 ",
+"8 8889 8 "};
--- /dev/null
+/* XPM */
+static char * dvips66_xpm[] = {
+"24 24 62 1",
+" c None s backgroundToolBarColor",
+". c #4C4C4C",
+"+ c #000000",
+"@ c #7C7C7C",
+"# c #577A4D",
+"$ c #4C6B43",
+"% c #37452B",
+"& c #76996C",
+"* c #9BB594",
+"= c #648C58",
+"- c #DAE3D6",
+"; c #445636",
+"> c #67865E",
+", c #A7BDA0",
+"' c #8EAB86",
+") c #526741",
+"! c #425D3A",
+"~ c #4C603C",
+"{ c #566B43",
+"] c #5A7046",
+"^ c #869CB4",
+"/ c #00244C",
+"( c #002248",
+"_ c #0050A9",
+": c #006FEB",
+"< c #0066D9",
+"[ c #00336D",
+"} c #295E29",
+"| c #5ABD5A",
+"1 c #001070",
+"2 c #004BA2",
+"3 c #0078FF",
+"4 c #0075FC",
+"5 c #004DB6",
+"6 c #00072F",
+"7 c #0047FF",
+"8 c #006DFF",
+"9 c #0042CA",
+"0 c #00169E",
+"a c #000A45",
+"b c #488148",
+"c c #0024FF",
+"d c #0027FF",
+"e c #0056ED",
+"f c #001FA7",
+"g c #00179F",
+"h c #4CA14C",
+"i c #4D904D",
+"j c #001DCE",
+"k c #4FA64F",
+"l c #000B4C",
+"m c #0023F5",
+"n c #001492",
+"o c #000E65",
+"p c #00010B",
+"q c #001AB9",
+"r c #0022F0",
+"s c #001387",
+"t c #000942",
+"u c #0037C4",
+"v c #6C84B7",
+"w c #000C57",
+" .+. ++++ ",
+" @+##$+@ +++%++ ",
+" +&**&=+ + +%+ ",
+" .#*-*&=$. +;+ ",
+" +>,*'==$+ +)+ ",
+" .#&&==#!. ++))~++ ",
+" +#==#$+ +{]{+ ",
+" @+!$!+@ +)+ ",
+" .+. + ",
+" ",
+" ^/ ",
+" ^(_:<[ ",
+"}}}| } } } 12:333456",
+"} } } } } 17833390a",
+"} } b b } 1cd7efg0a",
+"} } hiih } 1cccj000a",
+"} } bb } 1cccj000a",
+"}}}| kk } lmccj0nop",
+" lqrjst ",
+" uuuv vuuv 1w ",
+" u u u ",
+" uuuv vuuv ",
+" u u ",
+" u vuuv "};
--- /dev/null
+/* XPM */
+static char * error22_xpm[] = {
+"24 24 8 1",
+" c None s backgroundToolBarColor",
+". c #847000",
+"+ c #000000",
+"@ c #F0C900",
+"# c #AB9100",
+"$ c #887821",
+"% c #AA9629",
+"& c #51470D",
+" ",
+" ",
+" .++. ",
+" +@@@@+ ",
+" #.@@@@.# ",
+" +@@@@@@+ ",
+" #.@@@@@@.# ",
+" +@@@++@@@+ ",
+" #.@@@++@@@.# ",
+" +@@@@++@@@@+ ",
+" #.@@@@++@@@@.# ",
+" +@@@@@++@@@@@+ ",
+" #.@@@@@++@@@@@.# ",
+" +@@@@@@$$@@@@@@+ ",
+" #.@@@@@@%%@@@@@@.# ",
+" +@@@@@@@@@@@@@@@@+ ",
+" .#@@@@@@@++@@@@@@@#. ",
+" &@@@@@@@@++@@@@@@@@& ",
+" &@@@@@@@@@@@@@@@@@@& ",
+" +@@@@@@@@@@@@@@@@+ ",
+" .++++++++++++++. ",
+" ",
+" ",
+" "};
--- /dev/null
+/* XPM */
+static char * exec6_xpm[] = {
+"24 24 41 1",
+" c None s backgroundToolBarColor",
+". c #9F9D96",
+"+ c #3A3A3A",
+"@ c #B3B3B1",
+"# c #000000",
+"$ c #807D74",
+"% c #3C3C3C",
+"& c #76746B",
+"* c #5D5C55",
+"= c #6D6B63",
+"- c #65635C",
+"; c #8C8B89",
+"> c #E4E3E1",
+", c #E2E2E2",
+"' c #484641",
+") c #888781",
+"! c #B0AFAD",
+"~ c #A8A7A1",
+"{ c #908E86",
+"] c #97958E",
+"^ c #595854",
+"/ c #605E57",
+"( c #898883",
+"_ c #464542",
+": c #4A4947",
+"< c #43423E",
+"[ c #E2E2E1",
+"} c #B6B5AF",
+"| c #494847",
+"1 c #434242",
+"2 c #464644",
+"3 c #E6E6E4",
+"4 c #484846",
+"5 c #DFDEDC",
+"6 c #B0AFA9",
+"7 c #D5D4D1",
+"8 c #93918B",
+"9 c #D6D5D2",
+"0 c #ABA9A3",
+"a c #494943",
+"b c #464540",
+" ",
+" . ++ @ ",
+" #@#..#.# ",
+" .@...$$$%. ",
+" #..&$*=# ",
+" +..&##@--+ ",
+" +.$$#;@-%+ ",
+" #$*@@$%# ",
+" @.$=--%%%. ",
+" #%#-%#%# ",
+" . ++ . %%% ",
+" %% %>% %% ",
+" %,@%'.'%)%% ",
+" %!~...{]$'% ",
+" %..^/($&% ",
+" %%'./_:<.='%% ",
+" %[}.^|123$-/% ",
+" %%'.(<4;5-'%% ",
+" %6$}378-%% ",
+" %90.$$&&*'% ",
+" %%^%'&'%a%% ",
+" %% %b%*%% ",
+" %%% ",
+" "};
--- /dev/null
+/* XPM */
+static char * execbibtex8_xpm[] = {
+"24 24 100 2",
+" c None s backgroundToolBarColor",
+". c #1F1D12",
+"+ c #222017",
+"@ c #211F15",
+"# c #211F14",
+"$ c #0C0B07",
+"% c #5E5737",
+"& c #B7AB72",
+"* c #BFB480",
+"= c #BAAF77",
+"- c #B9AD74",
+"; c #9A9061",
+"> c #545144",
+", c #AFA98C",
+"' c #776F4F",
+") c #C0B684",
+"! c #625C3D",
+"~ c #767675",
+"{ c #A79D6F",
+"] c #BEB37E",
+"^ c #93895C",
+"/ c #59574E",
+"( c #A3A3A2",
+"_ c #807A59",
+": c #BCB17E",
+"< c #B9AE75",
+"[ c #B8AC73",
+"} c #7E7650",
+"| c #5B5B5B",
+"1 c #ACACAA",
+"2 c #202120",
+"3 c #60593A",
+"4 c #BAAE76",
+"5 c #A39966",
+"6 c #363635",
+"7 c #B4B4B3",
+"8 c #82857F",
+"9 c #171816",
+"0 c #8A825C",
+"a c #B9AD75",
+"b c #6D6748",
+"c c #6A6A6A",
+"d c #A9AAA6",
+"e c #363735",
+"f c #95948C",
+"g c #A39C82",
+"h c #7A7356",
+"i c #BBB079",
+"j c #BBAF78",
+"k c #20201C",
+"l c #B3B3B2",
+"m c #767774",
+"n c #20211F",
+"o c #1A1112",
+"p c #5D413D",
+"q c #555540",
+"r c #7C7A58",
+"s c #4D4830",
+"t c #8B8A89",
+"u c #ADADAB",
+"v c #4F514E",
+"w c #1E1616",
+"x c #BA9797",
+"y c #DCD6D3",
+"z c #CDCDCA",
+"A c #575651",
+"B c #1B1A19",
+"C c #ABABA9",
+"D c #777775",
+"E c #080808",
+"F c #1B1212",
+"G c #846666",
+"H c #A5A09E",
+"I c #D4D2C6",
+"J c #E7E6DF",
+"K c #F1F0EC",
+"L c #A9AAA8",
+"M c #4F514D",
+"N c #585442",
+"O c #6D6D66",
+"P c #DEDBCA",
+"Q c #EAE9E4",
+"R c #BEC0B9",
+"S c #878A84",
+"T c #000000",
+"U c #47453A",
+"V c #50504D",
+"W c #999474",
+"X c #363731",
+"Y c #020201",
+"Z c #3A3A3A",
+"` c #65635C",
+" . c #9F9D96",
+".. c #807D74",
+"+. c #3C3C3C",
+"@. c #76746B",
+"#. c #5D5C55",
+"$. c #6D6B63",
+"%. c #B3B3B1",
+"&. c #8C8B89",
+" ",
+" . + @ # # # # $ ",
+" % & * = - - - ; > ",
+" , ' ) = - - - - ! ~ ",
+" % { ] - - - - ^ / ( ",
+" , _ : < - - - [ } | 1 2 ",
+" 3 ] 4 - - - - 5 6 7 8 9 ",
+" % 0 ] a - - - - b c d e f ",
+" g h i j - - - - - k l m n ",
+" o p q r ; 5 - - s t u v f ",
+" w x y z u ~ A q B C D E ",
+" F G H I J K K K z L M f ",
+" v M N O f P Q R S T ",
+" ( D U V W X f ",
+" ( v Y Z Z ",
+" T ` T . .T ` T ",
+" ` . . .......+. ",
+" T . .@...#.$.T ",
+" Z . .@.T T %.` ` Z ",
+" Z .....T &.%.` +.Z ",
+" T ..#.%.%...+.T ",
+" ` ..$.` ` +.+.+. ",
+" T +.T ` +.T +.T ",
+" Z Z "};
--- /dev/null
+/* XPM */
+static char * execdvips36_xpm[] = {
+"24 24 25 1",
+" c None s backgroundToolBarColor",
+". c #295E29",
+"+ c #5ABD5A",
+"@ c #488148",
+"# c #818181",
+"$ c #4CA14C",
+"% c #4D904D",
+"& c #ADADAD",
+"* c #4FA64F",
+"= c #6E6E6E",
+"- c #545454",
+"; c #999999",
+"> c #3A3A3A",
+", c #000000",
+"' c #65635C",
+") c #9F9D96",
+"! c #0037C4",
+"~ c #6C84B7",
+"{ c #807D74",
+"] c #3C3C3C",
+"^ c #76746B",
+"/ c #5D5C55",
+"( c #6D6B63",
+"_ c #B3B3B1",
+": c #8C8B89",
+" ",
+" ...+ . . . ",
+" . . . . . ",
+" . . . . . ",
+" . . @ @ . ",
+" # . . $%%$ . ",
+" #& . . @@ . ",
+" #& ...+ ** . ",
+" = ",
+" - ",
+" # ",
+" - ; ",
+" ;- ",
+" ;-- ",
+" >> ",
+" ,',)),', ",
+" !!!~ ~!!~ '))){{{] ",
+" ! ! ! ! ,))^{/(, ",
+" ! ! ! >))^,,_''>",
+" !!!~ ~!!~ >){{,:_']>",
+" ! ! ,{/__{], ",
+" ! ! ! '{('']]] ",
+" ! ~!!~ ,],'],], ",
+" >> "};
--- /dev/null
+/* XPM */
+static char * execerror12_xpm[] = {
+"24 24 22 1",
+" c None s backgroundToolBarColor",
+". c #B09400",
+"+ c #605000",
+"@ c #9C8400",
+"# c #FFD906",
+"$ c #FED90A",
+"% c #957F0D",
+"& c #DEBD0E",
+"* c #6F5D00",
+"= c #8F7900",
+"- c #655500",
+"; c #3A3A3A",
+"> c #000000",
+", c #65635C",
+"' c #9F9D96",
+") c #807D74",
+"! c #3C3C3C",
+"~ c #76746B",
+"{ c #5D5C55",
+"] c #6D6B63",
+"^ c #B3B3B1",
+"/ c #8C8B89",
+" ",
+" ",
+" .++. ",
+" @##@. ",
+" +$###+ ",
+" ..#++#.. ",
+" +$#++#$+ ",
+" ..##++##.. ",
+" +$##%%##$+ ",
+" ..###&&###.. ",
+" +####**###$+ ",
+" +##########+ ",
+" =--------= ",
+" ",
+" ;; ",
+" >,>''>,> ",
+" ,''')))! ",
+" >''~){]> ",
+" ;''~>>^,,;",
+" ;'))>/^,!;",
+" >){^^)!> ",
+" ,)],,!!! ",
+" >!>,!>!> ",
+" ;; "};
--- /dev/null
+/* XPM */
+static char * execpdftex11_xpm[] = {
+"24 24 178 2",
+" c None s backgroundToolBarColor",
+". c #3E9543",
+"+ c #409644",
+"@ c #3D9D45",
+"# c #3F9B42",
+"$ c #4C2A1F",
+"% c #4E3124",
+"& c #727E51",
+"* c #598A4E",
+"= c #5B6647",
+"- c #88624F",
+"; c #89383B",
+"> c #8B343B",
+", c #6D5852",
+"' c #506D48",
+") c #4C843E",
+"! c #648752",
+"~ c #B8A789",
+"{ c #80624D",
+"] c #7D6951",
+"^ c #FFFFC1",
+"/ c #94A676",
+"( c #8F8668",
+"_ c #977567",
+": c #A86660",
+"< c #986C6A",
+"[ c #758660",
+"} c #708C60",
+"| c #6A6C4E",
+"1 c #C3C599",
+"2 c #988167",
+"3 c #5A3125",
+"4 c #958066",
+"5 c #BEA384",
+"6 c #68372B",
+"7 c #672124",
+"8 c #5B392F",
+"9 c #94917B",
+"0 c #AFAC91",
+"a c #B8B39C",
+"b c #BDBCA0",
+"c c #B39073",
+"d c #582522",
+"e c #712E2B",
+"f c #83826F",
+"g c #908F88",
+"h c #F8FFFD",
+"i c #686C8D",
+"j c #D7DBB8",
+"k c #716D76",
+"l c #7B7B92",
+"m c #D5D5B3",
+"n c #DBBD9A",
+"o c #81463B",
+"p c #691A19",
+"q c #838270",
+"r c #888791",
+"s c #6462D0",
+"t c #2C2B87",
+"u c #DAD9C7",
+"v c #868394",
+"w c #716DDC",
+"x c #2F2C94",
+"y c #C7C6B7",
+"z c #D2AF8D",
+"A c #84473C",
+"B c #6D1E1F",
+"C c #975F59",
+"D c #BDBDAB",
+"E c #878593",
+"F c #909095",
+"G c #C0BEAF",
+"H c #A09EAD",
+"I c #A6A5A9",
+"J c #C19978",
+"K c #7C3D33",
+"L c #641C1F",
+"M c #DBDCB8",
+"N c #B4B492",
+"O c #E5D9AA",
+"P c #9F755A",
+"Q c #50231F",
+"R c #672424",
+"S c #E4E3BC",
+"T c #A5A28D",
+"U c #D2D1B5",
+"V c #E7E5C1",
+"W c #E3DFC0",
+"X c #E4CCA2",
+"Y c #894E3A",
+"Z c #461715",
+"` c #632524",
+" . c #665E46",
+".. c #C0B396",
+"+. c #AAAB90",
+"@. c #463F31",
+"#. c #7C7968",
+"$. c #B3AF92",
+"%. c #D4BD97",
+"&. c #804B37",
+"*. c #461F19",
+"=. c #42201F",
+"-. c #5A4F43",
+";. c #504334",
+">. c #979183",
+",. c #DCD8B5",
+"'. c #D0BC9D",
+"). c #C8A487",
+"!. c #82493F",
+"~. c #3F1310",
+"{. c #401613",
+"]. c #664B46",
+"^. c #DCD9BC",
+"/. c #B8B59D",
+"(. c #8C8977",
+"_. c #E9E7C0",
+":. c #A2897B",
+"<. c #AE8872",
+"[. c #CFB89A",
+"}. c #A6715F",
+"|. c #4B1D19",
+"1. c #68272E",
+"2. c #767361",
+"3. c #7F8170",
+"4. c #7B7B6C",
+"5. c #8E897E",
+"6. c #827F6E",
+"7. c #83876F",
+"8. c #847E70",
+"9. c #9C7964",
+"0. c #662F2A",
+"a. c #5D2D2E",
+"b. c #783C3F",
+"c. c #87826E",
+"d. c #B3B99A",
+"e. c #D1D1AB",
+"f. c #DFDDB9",
+"g. c #C3B191",
+"h. c #826453",
+"i. c #6D2B2A",
+"j. c #884144",
+"k. c #772B2F",
+"l. c #3A3A3A",
+"m. c #AEA28C",
+"n. c #C1C3A2",
+"o. c #AEA07E",
+"p. c #C8C09F",
+"q. c #C4C6A3",
+"r. c #B6886B",
+"s. c #774237",
+"t. c #7E3E3D",
+"u. c #854748",
+"v. c #78373B",
+"w. c #000000",
+"x. c #65635C",
+"y. c #9F9D96",
+"z. c #7C474A",
+"A. c #815655",
+"B. c #7F534F",
+"C. c #8A5C54",
+"D. c #74504B",
+"E. c #8C615F",
+"F. c #7E2C29",
+"G. c #8C4240",
+"H. c #7C322F",
+"I. c #703634",
+"J. c #807D74",
+"K. c #3C3C3C",
+"L. c #6D1B27",
+"M. c #631D22",
+"N. c #65101D",
+"O. c #76746B",
+"P. c #5D5C55",
+"Q. c #6D6B63",
+"R. c #B3B3B1",
+"S. c #B50000",
+"T. c #AA7979",
+"U. c #8C8B89",
+" . + @ # $ ",
+" % & * = - ; > , ' ) ! ~ { ",
+" ] ^ / ( _ : < [ } | 1 2 3 ",
+" 4 ^ ^ ^ ^ ^ ^ ^ ^ ^ 5 6 7 ",
+" 8 ^ 9 0 ^ a 9 b ^ ^ c d e ",
+" f g h i j k h l m ^ n o p ",
+" q r s t u v w x y ^ z A B C ",
+" ] D E F ^ G H I ^ ^ J K L ",
+" ] ^ M N ^ ^ ^ ^ ^ ^ O P Q R C ",
+" ] ^ S T U V W ^ ^ ^ ^ X Y Z ` ",
+" .....+.@. .#.$.......^ %.&.*.=. ",
+"....^ ^ -.;.>.,.^ ^ ^ '.).!.~.{. ",
+" .].^.^ /.(._.^ :.<.[.^ }.|.1. ",
+" 2.2.3.4.5.6.7.8.^ ^ 9.0.a.b. ",
+" c.^ d.^ ^ e.f.^ g.h.i.j.k. l.l. ",
+" m.n...o.p.q.r.s.t.u.v. w.x.w.y.y.w.x.w. ",
+" z.A.B.C.D.E.F.G.H.I. x.y.y.y.J.J.J.K. ",
+" L.C M. N. w.y.y.O.J.P.Q.w. ",
+" l.y.y.O.w.w.R.x.x.l.",
+" S.S.T. S.S.T. S.S.T. l.y.J.J.w.U.R.x.K.l.",
+" S. S. S. S. S. w.J.P.R.R.J.K.w. ",
+" S.S.T. S. S. S.S. x.J.Q.x.x.K.K.K. ",
+" S. S. S. S. w.K.w.x.K.w.K.w. ",
+" S. S.S.T. S. l.l. "};
--- /dev/null
+/* XPM */
+static char * exectex40_xpm[] = {
+"24 24 176 2",
+" c None s backgroundToolBarColor",
+". c #3E9543",
+"+ c #409644",
+"@ c #3D9D45",
+"# c #3F9B42",
+"$ c #4C2A1F",
+"% c #4E3124",
+"& c #727E51",
+"* c #598A4E",
+"= c #5B6647",
+"- c #88624F",
+"; c #89383B",
+"> c #8B343B",
+", c #6D5852",
+"' c #506D48",
+") c #4C843E",
+"! c #648752",
+"~ c #B8A789",
+"{ c #80624D",
+"] c #7D6951",
+"^ c #FFFFC1",
+"/ c #94A676",
+"( c #8F8668",
+"_ c #977567",
+": c #A86660",
+"< c #986C6A",
+"[ c #758660",
+"} c #708C60",
+"| c #6A6C4E",
+"1 c #C3C599",
+"2 c #988167",
+"3 c #5A3125",
+"4 c #958066",
+"5 c #BEA384",
+"6 c #68372B",
+"7 c #672124",
+"8 c #5B392F",
+"9 c #94917B",
+"0 c #AFAC91",
+"a c #B8B39C",
+"b c #BDBCA0",
+"c c #B39073",
+"d c #582522",
+"e c #712E2B",
+"f c #83826F",
+"g c #908F88",
+"h c #F8FFFD",
+"i c #686C8D",
+"j c #D7DBB8",
+"k c #716D76",
+"l c #7B7B92",
+"m c #D5D5B3",
+"n c #DBBD9A",
+"o c #81463B",
+"p c #691A19",
+"q c #838270",
+"r c #888791",
+"s c #6462D0",
+"t c #2C2B87",
+"u c #DAD9C7",
+"v c #868394",
+"w c #716DDC",
+"x c #2F2C94",
+"y c #C7C6B7",
+"z c #D2AF8D",
+"A c #84473C",
+"B c #6D1E1F",
+"C c #975F59",
+"D c #BDBDAB",
+"E c #878593",
+"F c #909095",
+"G c #C0BEAF",
+"H c #A09EAD",
+"I c #A6A5A9",
+"J c #C19978",
+"K c #7C3D33",
+"L c #641C1F",
+"M c #DBDCB8",
+"N c #B4B492",
+"O c #E5D9AA",
+"P c #9F755A",
+"Q c #50231F",
+"R c #672424",
+"S c #E4E3BC",
+"T c #A5A28D",
+"U c #D2D1B5",
+"V c #E7E5C1",
+"W c #E3DFC0",
+"X c #E4CCA2",
+"Y c #894E3A",
+"Z c #461715",
+"` c #632524",
+" . c #979183",
+".. c #665E46",
+"+. c #C0B396",
+"@. c #AAAB90",
+"#. c #463F31",
+"$. c #7C7968",
+"%. c #B3AF92",
+"&. c #D4BD97",
+"*. c #804B37",
+"=. c #461F19",
+"-. c #42201F",
+";. c #5A4F43",
+">. c #504334",
+",. c #DCD8B5",
+"'. c #D0BC9D",
+"). c #C8A487",
+"!. c #82493F",
+"~. c #3F1310",
+"{. c #401613",
+"]. c #664B46",
+"^. c #DCD9BC",
+"/. c #B8B59D",
+"(. c #8C8977",
+"_. c #E9E7C0",
+":. c #A2897B",
+"<. c #AE8872",
+"[. c #CFB89A",
+"}. c #A6715F",
+"|. c #4B1D19",
+"1. c #68272E",
+"2. c #767361",
+"3. c #7F8170",
+"4. c #7B7B6C",
+"5. c #8E897E",
+"6. c #827F6E",
+"7. c #83876F",
+"8. c #847E70",
+"9. c #9C7964",
+"0. c #662F2A",
+"a. c #5D2D2E",
+"b. c #783C3F",
+"c. c #87826E",
+"d. c #B3B99A",
+"e. c #D1D1AB",
+"f. c #DFDDB9",
+"g. c #C3B191",
+"h. c #826453",
+"i. c #6D2B2A",
+"j. c #884144",
+"k. c #772B2F",
+"l. c #3A3A3A",
+"m. c #AEA28C",
+"n. c #C1C3A2",
+"o. c #AEA07E",
+"p. c #C8C09F",
+"q. c #C4C6A3",
+"r. c #B6886B",
+"s. c #774237",
+"t. c #7E3E3D",
+"u. c #854748",
+"v. c #78373B",
+"w. c #000000",
+"x. c #65635C",
+"y. c #9F9D96",
+"z. c #7C474A",
+"A. c #815655",
+"B. c #7F534F",
+"C. c #8A5C54",
+"D. c #74504B",
+"E. c #8C615F",
+"F. c #7E2C29",
+"G. c #8C4240",
+"H. c #7C322F",
+"I. c #703634",
+"J. c #807D74",
+"K. c #3C3C3C",
+"L. c #6D1B27",
+"M. c #631D22",
+"N. c #65101D",
+"O. c #76746B",
+"P. c #5D5C55",
+"Q. c #6D6B63",
+"R. c #B3B3B1",
+"S. c #8C8B89",
+" . + @ # $ ",
+" % & * = - ; > , ' ) ! ~ { ",
+" ] ^ / ( _ : < [ } | 1 2 3 ",
+" 4 ^ ^ ^ ^ ^ ^ ^ ^ ^ 5 6 7 ",
+" 8 ^ 9 0 ^ a 9 b ^ ^ c d e ",
+" f g h i j k h l m ^ n o p ",
+" q r s t u v w x y ^ z A B C ",
+" ] D E F ^ G H I ^ ^ J K L ",
+" ] ^ M N ^ ^ ^ ^ ^ ^ O P Q R C ",
+" ] ^ S T U V W ^ ^ ^ ^ X Y Z ` ",
+" ...+.+.@.#...$.%.+.+.+.^ &.*.=.-. ",
+" +.+.^ ^ ;.>. .,.^ ^ ^ '.).!.~.{. ",
+" ...].^.^ /.(._.^ :.<.[.^ }.|.1. ",
+" 2.2.3.4.5.6.7.8.^ ^ 9.0.a.b. ",
+" c.^ d.^ ^ e.f.^ g.h.i.j.k. l.l. ",
+" m.n.+.o.p.q.r.s.t.u.v. w.x.w.y.y.w.x.w. ",
+" z.A.B.C.D.E.F.G.H.I. x.y.y.y.J.J.J.K. ",
+" L.C M. N. w.y.y.O.J.P.Q.w. ",
+" l.y.y.O.w.w.R.x.x.l.",
+" l.y.J.J.w.S.R.x.K.l.",
+" w.J.P.R.R.J.K.w. ",
+" x.J.Q.x.x.K.K.K. ",
+" w.K.w.x.K.w.K.w. ",
+" l.l. "};
--- /dev/null
+/* XPM */
+static char * execviewdvi11_xpm[] = {
+"24 24 19 1",
+" c None s backgroundToolBarColor",
+". c #295E29",
+"+ c #5ABD5A",
+"@ c #488148",
+"# c #4CA14C",
+"$ c #4D904D",
+"% c #000000",
+"& c #4FA64F",
+"* c #FFFFFF",
+"= c #3A3A3A",
+"- c #65635C",
+"; c #9F9D96",
+"> c #807D74",
+", c #3C3C3C",
+"' c #76746B",
+") c #5D5C55",
+"! c #6D6B63",
+"~ c #B3B3B1",
+"{ c #8C8B89",
+" ...+ . . . ",
+" . . . . . ",
+" . . . . . ",
+" . . @ @ . ",
+" . . #$$# . ",
+" . . @@ . ",
+" %% ...+ && . ",
+" % % ",
+" % % ",
+" % % %% ",
+" %% % % ",
+"%* % % % ",
+"%** % %% % % ",
+"%** %%%* %% ",
+" % % %** % == ",
+" %% %** % %-%;;%-% ",
+" % % -;;;>>>, ",
+" %% %;;'>)!% ",
+" =;;'%%~--=",
+" =;>>%{~-,=",
+" %>)~~>,% ",
+" ->!--,,, ",
+" %,%-,%,% ",
+" == "};
--- /dev/null
+/* XPM */
+static char * execviewpdf4_xpm[] = {
+"24 24 15 1",
+" c None s backgroundToolBarColor",
+". c #B50000",
+"+ c #AA7979",
+"@ c #000000",
+"# c #FFFFFF",
+"$ c #3A3A3A",
+"% c #65635C",
+"& c #9F9D96",
+"* c #807D74",
+"= c #3C3C3C",
+"- c #76746B",
+"; c #5D5C55",
+"> c #6D6B63",
+", c #B3B3B1",
+"' c #8C8B89",
+" ...+ ...+ ...+",
+" . . . . . ",
+" . . . . . ",
+" ...+ . . ..+ ",
+" . . . . ",
+" . . . . ",
+" @@ . ...+ . ",
+" @ @ ",
+" @ @ ",
+" @ @ @@ ",
+" @@ @ @ ",
+"@# @ @ @ ",
+"@## @ @@ @ @ ",
+"@## @@@# @@ ",
+" @ @ @## @ $$ ",
+" @@ @## @ @%@&&@%@ ",
+" @ @ %&&&***= ",
+" @@ @&&-*;>@ ",
+" $&&-@@,%%$",
+" $&**@',%=$",
+" @*;,,*=@ ",
+" %*>%%=== ",
+" @=@%=@=@ ",
+" $$ "};
--- /dev/null
+/* XPM */
+static char * execviewps12_xpm[] = {
+"24 24 15 1",
+" c None s backgroundToolBarColor",
+". c #0037C4",
+"+ c #6C84B7",
+"@ c #000000",
+"# c #FFFFFF",
+"$ c #3A3A3A",
+"% c #65635C",
+"& c #9F9D96",
+"* c #807D74",
+"= c #3C3C3C",
+"- c #76746B",
+"; c #5D5C55",
+"> c #6D6B63",
+", c #B3B3B1",
+"' c #8C8B89",
+" ...+ +..+ ",
+" . . . . ",
+" . . . ",
+" ...+ +..+ ",
+" . . ",
+" . . . ",
+" @@ . +..+ ",
+" @ @ ",
+" @ @ ",
+" @ @ @@ ",
+" @@ @ @ ",
+"@# @ @ @ ",
+"@## @ @@ @ @ ",
+"@## @@@# @@ ",
+" @ @ @## @ $$ ",
+" @@ @## @ @%@&&@%@ ",
+" @ @ %&&&***= ",
+" @@ @&&-*;>@ ",
+" $&&-@@,%%$",
+" $&**@',%=$",
+" @*;,,*=@ ",
+" %*>%%=== ",
+" @=@%=@=@ ",
+" $$ "};
--- /dev/null
+/* XPM */
+static char * gv7_xpm[] = {
+"24 24 131 2",
+" c None s backgroundToolBarColor",
+". c #9F9F9F",
+"+ c #2F2F2F",
+"@ c #373737",
+"# c #323232",
+"$ c #303030",
+"% c #525252",
+"& c #ECECEC",
+"* c #FFFFFF",
+"= c #F4F4F4",
+"- c #BE5858",
+"; c #FD6F6F",
+"> c #FF7070",
+", c #FF9898",
+"' c #FFE1E1",
+") c #FE7070",
+"! c #C96363",
+"~ c #FF6B6B",
+"{ c #DD6666",
+"] c #FDCFCF",
+"^ c #FFD1D1",
+"/ c #FF8888",
+"( c #FFCACA",
+"_ c #F37C7C",
+": c #F56767",
+"< c #DA6363",
+"[ c #ECE6E6",
+"} c #F2F2F2",
+"| c #B6B6B6",
+"1 c #D0CBCB",
+"2 c #FD8686",
+"3 c #FE7878",
+"4 c #FE8787",
+"5 c #DCD6D6",
+"6 c #E1E1E1",
+"7 c #F5EFEF",
+"8 c #895B5B",
+"9 c #848484",
+"0 c #000000",
+"a c #2B2B2B",
+"b c #DAACAC",
+"c c #F3C5C5",
+"d c #414141",
+"e c #4C4C4C",
+"f c #B18383",
+"g c #5B5B5B",
+"h c #F86969",
+"i c #A5A5A5",
+"j c #3E3E3E",
+"k c #E4B6B6",
+"l c #F6C8C8",
+"m c #5D5D5D",
+"n c #6C6C6C",
+"o c #F56666",
+"p c #1C1C1C",
+"q c #AFAFAF",
+"r c #F6F6F6",
+"s c #FA9494",
+"t c #F67F7F",
+"u c #FFF9F9",
+"v c #FCFCFC",
+"w c #EDEDED",
+"x c #F3EDED",
+"y c #FF7878",
+"z c #F6F0F0",
+"A c #F8F8F8",
+"B c #EB7474",
+"C c #DA7373",
+"D c #E2E2E2",
+"E c #A4A4A4",
+"F c #F0F0F0",
+"G c #D5D5D5",
+"H c #393939",
+"I c #161616",
+"J c #8C8C8C",
+"K c #F7F7F7",
+"L c #BEBEBE",
+"M c #191919",
+"N c #989898",
+"O c #BCBCBC",
+"P c #2A2A2A",
+"Q c #1B1B1B",
+"R c #313131",
+"S c #AAAAAA",
+"T c #C7C7C7",
+"U c #101010",
+"V c #D3D3D3",
+"W c #595959",
+"X c #E4E4E4",
+"Y c #969696",
+"Z c #FBFBFB",
+"` c #D1D1D1",
+" . c #717171",
+".. c #0A0A0A",
+"+. c #B7B7B7",
+"@. c #EEEEEE",
+"#. c #F9F9F9",
+"$. c #DBDBDB",
+"%. c #EBEBEB",
+"&. c #D2D2D2",
+"*. c #6E6E6E",
+"=. c #7D7D7D",
+"-. c #EAEAEA",
+";. c #A2A2A2",
+">. c #CCCCCC",
+",. c #E8E8E8",
+"'. c #4E4E4E",
+"). c #ABABAB",
+"!. c #F5F5F5",
+"~. c #6B6B6B",
+"{. c #171717",
+"]. c #434343",
+"^. c #CECECE",
+"/. c #4D4D4D",
+"(. c #ADADAD",
+"_. c #D0D0D0",
+":. c #9E9E9E",
+"<. c #808080",
+"[. c #FAFAFA",
+"}. c #858585",
+"|. c #A0A0A0",
+"1. c #BDBDBD",
+"2. c #838383",
+"3. c #181818",
+"4. c #8F8F8F",
+"5. c #959595",
+"6. c #D6D6D6",
+"7. c #DDDDDD",
+"8. c #C1C1C1",
+"9. c #7B7B7B",
+"0. c #8E8E8E",
+" ",
+" . + @ @ @ # . ",
+" $ % & * * * = % % ",
+" - ; > , ' * ' , > ) ! ",
+" ~ { ] ^ / > ( > / ^ ^ _ : ",
+" ~ < [ } | 1 2 3 4 5 | 6 7 { ~ ",
+" ~ 8 * 9 0 a b ~ c d 0 e * f ~ ",
+" $ g h 8 * i 0 j k ~ l m 0 n * f o 0 g ",
+" p q r s t u v w x 4 y / z w A u B C D D @ ",
+" p E F ' > / ^ ^ / > ( > / ^ ^ / ) ' * G H ",
+" I @ J K ' , > > , ' * ' , > > , ' * L E H ",
+" M N * * * * * * * * * * * * * O P Q ",
+" R S * * * * * * * * * * * T a ",
+" U S * * * * * * * * * * * V W ",
+" U S * * * * * * * * * * * X Y U ",
+" U S * * * * * * * * * * * Z ` ... ",
+" R +.* * Z @.#.* * * * * $.%.* &.*.Q ",
+" 0 =.%.* * -.;.>.v v * * ,.'.).!.v >.~.{. ",
+" ].q * * * ^./.(.A A * * _.p :.%.* %.:.p ",
+" @ <.@.* [.r }.R |.1.1.L L 2.3.:.%.%.%.4.Q ",
+" H 5.6.7.8.).0 0 j % % % % M 0 9.9.9. .% ",
+" 3. .0.0.m @ % % % % ",
+" @ @ @ @ ",
+" "};
--- /dev/null
+/* XPM */
+static char * jumpdvi19_xpm[] = {
+"24 24 47 1",
+" c None s backgroundToolBarColor",
+". c #212121",
+"+ c #EAD4CB",
+"@ c #E3C5BA",
+"# c #DBB4A4",
+"$ c #EEDED7",
+"% c #FAF7F5",
+"& c #F2E5E1",
+"* c #D2AC99",
+"= c #000000",
+"- c #8D9E7C",
+"; c #CDD9C2",
+"> c #DEE6D7",
+", c #DAE2D1",
+"' c #9BAD89",
+") c #B79382",
+"! c #707D63",
+"~ c #B4C6A2",
+"{ c #ACC098",
+"] c #636E57",
+"^ c #AB8A7A",
+"/ c #E4E9DD",
+"( c #657158",
+"_ c #C49F8D",
+": c #C3D1B5",
+"< c #808F70",
+"[ c #4C5442",
+"} c #58634E",
+"| c #E6EBE0",
+"1 c #D4DDC9",
+"2 c #CAD7BE",
+"3 c #90A17F",
+"4 c #5F6A53",
+"5 c #535C49",
+"6 c #E9EDE4",
+"7 c #616D56",
+"8 c #A8BC95",
+"9 c #7C8B6E",
+"0 c #4C5443",
+"a c #B6C2AA",
+"b c #5E6953",
+"c c #295E29",
+"d c #5ABD5A",
+"e c #488148",
+"f c #4CA14C",
+"g c #4D904D",
+"h c #4FA64F",
+" ",
+" ",
+" ",
+" ... ",
+" ..+@#.. ",
+" .$%&@*. ",
+" =======+#**. ",
+" =-;>,'=###). ",
+" =!~{]=##*^. ",
+" ==/;{(]=#*_. ",
+" ==/;:{<[}=)).. ",
+" =|12{{34=5=.. ",
+" =6{{{7= == ",
+" =>890= ",
+" =a]= ",
+" =b= ",
+" = cccd c c c ",
+" c c c c c ",
+" c c c c c ",
+" c c e e c ",
+" c c fggf c ",
+" c c ee c ",
+" cccd hh c ",
+" "};
--- /dev/null
+/* XPM */
+static char * ltx_symb_turn_off_xpm[] = {
+"24 24 20 1",
+" c None s backgroundToolBarColor",
+". c #AEAEAE",
+"+ c #000000",
+"@ c #0A0A0A",
+"# c #1F1F1F",
+"$ c #C9C9C9",
+"% c #353535",
+"& c #999999",
+"* c #4D4D4D",
+"= c #777777",
+"- c #141414",
+"; c #878787",
+"> c #686868",
+", c #5A5A5A",
+"' c #FF5858",
+") c #FFB9B9",
+"! c #FF0000",
+"~ c #FF9595",
+"{ c #414141",
+"] c #292929",
+" ",
+" ",
+" ",
+".+@########++@$ ",
+" %@& .*@= ",
+" $--$ ;% ",
+" .@% >$ ",
+" ,+= ",
+" %@. ",
+" $--$ ' ' ",
+" &+* )!' '!)",
+" *@$ ~!~ ",
+" $#; ~!~ ",
+" %, )!' '!)",
+" >% ' ' ",
+" ;#$ &$ ",
+" .-. ${ ",
+" ]; .], ",
+" *]>>>>>>>>]++. ",
+"${{{{{{{{{{{{* ",
+" ",
+" ",
+" ",
+" "};
--- /dev/null
+/* XPM */
+static char * ltx_symb_turn_on_xpm[] = {
+"24 24 19 1",
+" c None s backgroundToolBarColor",
+". c #AEAEAE",
+"+ c #000000",
+"@ c #0A0A0A",
+"# c #1F1F1F",
+"$ c #C9C9C9",
+"% c #353535",
+"& c #999999",
+"* c #4D4D4D",
+"= c #777777",
+"- c #141414",
+"; c #878787",
+"> c #686868",
+", c #5A5A5A",
+"' c #79DECA",
+") c #00AA88",
+"! c #5DC8B3",
+"~ c #414141",
+"{ c #292929",
+" ",
+" ",
+" ",
+".+@########++@$ ",
+" %@& .*@= ",
+" $--$ ;% ",
+" .@% >$ ",
+" ,+= '",
+" %@. ) ",
+" $--$ )) ",
+" &+* ')! )) ",
+" *@$ )))) ",
+" $#; !)) ",
+" %, ')' ",
+" >% ",
+" ;#$ &$ ",
+" .-. $~ ",
+" {; .{, ",
+" *{>>>>>>>>{++. ",
+"$~~~~~~~~~~~~* ",
+" ",
+" ",
+" ",
+" "};
--- /dev/null
+/* XPM */
+static char * pdftex22_xpm[] = {
+"24 24 179 2",
+" c None s backgroundToolBarColor",
+". c #3E9543",
+"+ c #409644",
+"@ c #3D9D45",
+"# c #3F9B42",
+"$ c #4C2A1F",
+"% c #4E3124",
+"& c #727E51",
+"* c #598A4E",
+"= c #5B6647",
+"- c #88624F",
+"; c #89383B",
+"> c #8B343B",
+", c #6D5852",
+"' c #506D48",
+") c #4C843E",
+"! c #648752",
+"~ c #B8A789",
+"{ c #80624D",
+"] c #7D6951",
+"^ c #FFFFC1",
+"/ c #94A676",
+"( c #8F8668",
+"_ c #977567",
+": c #A86660",
+"< c #986C6A",
+"[ c #758660",
+"} c #708C60",
+"| c #6A6C4E",
+"1 c #C3C599",
+"2 c #988167",
+"3 c #5A3125",
+"4 c #561E1C",
+"5 c #958066",
+"6 c #BEA384",
+"7 c #68372B",
+"8 c #672124",
+"9 c #5B392F",
+"0 c #94917B",
+"a c #AFAC91",
+"b c #B8B39C",
+"c c #BDBCA0",
+"d c #B39073",
+"e c #582522",
+"f c #712E2B",
+"g c #6F292C",
+"h c #83826F",
+"i c #908F88",
+"j c #F8FFFD",
+"k c #686C8D",
+"l c #D7DBB8",
+"m c #716D76",
+"n c #7B7B92",
+"o c #D5D5B3",
+"p c #DBBD9A",
+"q c #81463B",
+"r c #691A19",
+"s c #838270",
+"t c #888791",
+"u c #6462D0",
+"v c #2C2B87",
+"w c #DAD9C7",
+"x c #868394",
+"y c #716DDC",
+"z c #2F2C94",
+"A c #C7C6B7",
+"B c #D2AF8D",
+"C c #84473C",
+"D c #6D1E1F",
+"E c #6E262C",
+"F c #BDBDAB",
+"G c #878593",
+"H c #909095",
+"I c #C0BEAF",
+"J c #A09EAD",
+"K c #A6A5A9",
+"L c #C19978",
+"M c #7C3D33",
+"N c #641C1F",
+"O c #662633",
+"P c #DBDCB8",
+"Q c #B4B492",
+"R c #E5D9AA",
+"S c #9F755A",
+"T c #50231F",
+"U c #672424",
+"V c #8E3B4B",
+"W c #E4E3BC",
+"X c #A5A28D",
+"Y c #D2D1B5",
+"Z c #E7E5C1",
+"` c #E3DFC0",
+" . c #E4CCA2",
+".. c #894E3A",
+"+. c #461715",
+"@. c #632524",
+"#. c #95404E",
+"$. c #777776",
+"%. c #C0B396",
+"&. c #AAAB90",
+"*. c #463F31",
+"=. c #665E46",
+"-. c #7C7968",
+";. c #B3AF92",
+">. c #D4BD97",
+",. c #804B37",
+"'. c #461F19",
+"). c #42201F",
+"!. c #5A4F43",
+"~. c #504334",
+"{. c #979183",
+"]. c #DCD8B5",
+"^. c #D0BC9D",
+"/. c #C8A487",
+"(. c #82493F",
+"_. c #3F1310",
+":. c #401613",
+"<. c #664B46",
+"[. c #DCD9BC",
+"}. c #B8B59D",
+"|. c #8C8977",
+"1. c #E9E7C0",
+"2. c #A2897B",
+"3. c #AE8872",
+"4. c #CFB89A",
+"5. c #A6715F",
+"6. c #4B1D19",
+"7. c #68272E",
+"8. c #6E2933",
+"9. c #453E37",
+"0. c #767361",
+"a. c #7F8170",
+"b. c #7B7B6C",
+"c. c #8E897E",
+"d. c #827F6E",
+"e. c #83876F",
+"f. c #847E70",
+"g. c #9C7964",
+"h. c #662F2A",
+"i. c #5D2D2E",
+"j. c #783C3F",
+"k. c #87826E",
+"l. c #B3B99A",
+"m. c #D1D1AB",
+"n. c #DFDDB9",
+"o. c #C3B191",
+"p. c #826453",
+"q. c #6D2B2A",
+"r. c #884144",
+"s. c #772B2F",
+"t. c #702F34",
+"u. c #AEA28C",
+"v. c #C1C3A2",
+"w. c #AEA07E",
+"x. c #C8C09F",
+"y. c #C4C6A3",
+"z. c #B6886B",
+"A. c #774237",
+"B. c #7E3E3D",
+"C. c #854748",
+"D. c #78373B",
+"E. c #6A2932",
+"F. c #5F343C",
+"G. c #7C474A",
+"H. c #815655",
+"I. c #7F534F",
+"J. c #8A5C54",
+"K. c #74504B",
+"L. c #8C615F",
+"M. c #7E2C29",
+"N. c #8C4240",
+"O. c #7C322F",
+"P. c #703634",
+"Q. c #6D1B27",
+"R. c #975F59",
+"S. c #631D22",
+"T. c #65101D",
+"U. c #B50000",
+"V. c #AA7979",
+" . + @ # $ ",
+" % & * = - ; > , ' ) ! ~ { ",
+" ] ^ / ( _ : < [ } | 1 2 3 4 ",
+" 5 ^ ^ ^ ^ ^ ^ ^ ^ ^ 6 7 8 ",
+" 9 ^ 0 a ^ b 0 c ^ ^ d e f g ",
+" h i j k l m j n o ^ p q r ",
+" s t u v w x y z A ^ B C D E ",
+" ] F G H ^ I J K ^ ^ L M N O ",
+" ] ^ P Q ^ ^ ^ ^ ^ ^ R S T U V ",
+" ] ^ W X Y Z ` ^ ^ ^ ^ ...+.@.#. ",
+" $.$.%.%.&.*.=.-.;.%.%.%.^ >.,.'.). ",
+" %.%.^ ^ !.~.{.].^ ^ ^ ^./.(._.:. ",
+" $.$.<.[.^ }.|.1.^ 2.3.4.^ 5.6.7.8. ",
+" 9.0.a.b.c.d.e.f.^ ^ g.h.i.j. ",
+" k.^ l.^ ^ m.n.^ o.p.q.r.s.t. ",
+" u.v.%.w.x.y.z.A.B.C.D.E.F. ",
+" G.H.I.J.K.L.M.N.O.P. ",
+" Q.R. S. T. ",
+" ",
+" U.U.U.V. U.U.U.V. U.U.U.V. ",
+" U. U. U. U. U. ",
+" U.U.U.V. U. U. U.U.V. ",
+" U. U. U. U. ",
+" U. U.U.U.V. U. "};
--- /dev/null
+/* XPM */
+static char *noway16[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 9 1",
+" c red",
+". c #FD0D0D",
+"X c #FA1C1C",
+"o c #F52D2D",
+"O c #FB5B5B",
+"+ c #FC6060",
+"@ c #FFBBBB",
+"# c #FEFEFE",
+"$ c None",
+/* pixels */
+"$$$$$ XXXX $$$$$",
+"$$$X. .X$$$",
+"$$o o$$",
+"$X. .X$",
+"$. .$",
+" ",
+"O@@@@@@@@@@@@@@O",
+"+##############+",
+"+##############+",
+"O@@@@@@@@@@@@@@O",
+" ",
+"$. .$",
+"$X. .X$",
+"$$o o$$",
+"$$$X. .X$$$",
+"$$$$$ XXXX $$$$$"
+};
--- /dev/null
+/* XPM */
+static char *noway20[] = {
+/* columns rows colors chars-per-pixel */
+"20 20 9 1",
+" c red",
+". c #FF0404",
+"X c #FD0F0F",
+"o c #F91919",
+"O c #F82828",
+"+ c #F33636",
+"@ c #ED4A4A",
+"# c #FEFEFE",
+"$ c None",
+/* pixels */
+"$$$$$$@+OXXO+@$$$$$$",
+"$$$$OO. .OO$$$$",
+"$$$@. .@$$$",
+"$$@. .@$$",
+"$O. .O$",
+"$o o$",
+"@. .@",
+"+ +",
+"o##################o",
+"o##################o",
+"o##################o",
+"o##################o",
+"+ +",
+"@. .@",
+"$o o$",
+"$O. .O$",
+"$$@. .@$$",
+"$$$@. .@$$$",
+"$$$$OO. .OO$$$$",
+"$$$$$$@+OXXO+@$$$$$$"
+};
--- /dev/null
+#define wutz_width 24
+#define wutz_height 24
+static unsigned char wutz_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xc0, 0xff, 0x03, 0xf0, 0xff, 0x0f,
+ 0xf8, 0xff, 0x1f, 0xf8, 0xff, 0x1f, 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f,
+ 0xfe, 0xff, 0x7f, 0x02, 0x00, 0x40, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80,
+ 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x02, 0x00, 0x40, 0xfe, 0xff, 0x7f,
+ 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f, 0xf8, 0xff, 0x1f, 0xf8, 0xff, 0x1f,
+ 0xf0, 0xff, 0x0f, 0xc0, 0xff, 0x03, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 };
--- /dev/null
+/* XPM */
+static char *noway24[] = {
+/* columns rows colors chars-per-pixel */
+"24 24 9 1",
+" c red",
+". c #FF0404",
+"X c #FD0C0C",
+"o c #F91919",
+"O c #F62929",
+"+ c #F34C4C",
+"@ c #FF9090",
+"# c #FEFEFE",
+"$ c None",
+/* pixels */
+"$$$$$$$$+OOXXOO+$$$$$$$$",
+"$$$$$$OX XO$$$$$$",
+"$$$$+X X+$$$$",
+"$$$+ +$$$",
+"$$+ +$$",
+"$$X X$$",
+"$O O$",
+"$X X$",
+"+ +",
+"O+@@@@@@@@@@@@@@@@@@@@+O",
+"o######################o",
+"X######################X",
+"X######################X",
+"o######################o",
+"O+@@@@@@@@@@@@@@@@@@@@+O",
+"+ +",
+"$X X$",
+"$O O$",
+"$$X X$$",
+"$$+ +$$",
+"$$$+ +$$$",
+"$$$$+X X+$$$$",
+"$$$$$$OX XO$$$$$$",
+"$$$$$$$$+OOXXOO+$$$$$$$$"
+};
--- /dev/null
+/* XPM */
+static char * preview_cap_up_xpm[] = {
+"33 33 12 1",
+" c None",
+". c #BFBFBF s backgroundToolBarColor",
+"+ c #000000 s foregroundToolBarColor",
+"! c #000000",
+"@ c #FFFFFF",
+"# c #7C7C7C",
+"$ c #A0A0A0",
+"% c #E5E5E5",
+"& c #BABABA",
+"* c #1D1D1D",
+"= c #424242",
+"- c #676767",
+".................................",
+".....!!!!!!!!!!!!!!!!!!!!!!......",
+".....!@@@@@@@@@@@@@@@@@@@@!......",
+".....!@@@@@@@@@#$@@@@@@@@@!......",
+".....!@@@@@@@@%!&@@@@@@@@@!......",
+".....!@@@@@@@@#$@@@@@@@@@@!......",
+".....!@@@@@@@%*#%@%%@@@@&@!......",
+".....!#!!!!=$*#-!$#!&@@#*@!......",
+".....!@@&&@@#$@@%@@%=@%!$@!......",
+".....!@@&&@@&-=$@@@@$$-=@@!......",
+".....!@@&&@@$##&@@@@@=!&@@!......",
+".....!@@&#%@#$@@&&@@@*-@@@!......",
+".....!@@@*!@&!#-*@@@$!$@@@!......",
+".....!@@@%%@@%#$@@@@!#-@@@!......",
+".....!@%==@@@@@@@@@#*@-%@@!......",
+"......!=#=@@@@@@@@%!&@%=#@!......",
+"......%$$=@@@@@@@@$=@@@&=@!......",
+".....#.&$#=&@@@@@@@@@@@@@@!......",
+".....#...#-*$@@@@@@@@@@@@@!......",
+"......#..###===*%%@@@@@@@@!......",
+"......#...#...#.!!!!!!!!!!!......",
+".......#..#...#..#.#..#..#.......",
+".......#..#...#.##.#..#..#.......",
+"........#..##..#.#..###...#......",
+"........#.................#......",
+"..+++............................",
+"..+..+.+.+.+..+..+.+..+..+.+.+...",
+"..+..+.++.+.+.+..+...+.+.+.+.+...",
+"..+++..+..+++.+..+.+.+++.+.+.+...",
+"..+....+..+...+.+..+.+....+.+....",
+"..+....+...++..+...+..++..+.+....",
+".................................",
+"................................."};
--- /dev/null
+/* Created with The GIMP */
+#define preview12_width 12
+#define preview12_height 12
+static unsigned char preview12_bits[] = {
+ 0xff, 0x0f, 0x41, 0x08, 0x21, 0x08, 0x6f, 0x0d, 0x35, 0x0a, 0x75, 0x0a,
+ 0x6b, 0x0b, 0x82, 0x0c, 0x7c, 0x08, 0xf0, 0x08, 0x00, 0x0f, 0x00, 0x00 };
--- /dev/null
+/* XPM */
+static char * preview12_xpm[] = {
+"12 12 17 1",
+" c None",
+". c #020202",
+"+ c #1E1E1A",
+"@ c #626256",
+"# c #7D7D70",
+"$ c #8A8A7A",
+"% c #969686",
+"& c #A6A692",
+"* c #B2B29E",
+"= c #46463E",
+"- c #BEBEAA",
+"; c #1A1A16",
+"> c #CECEB2",
+", c #363632",
+"' c #6E6E62",
+") c #0E0E0E",
+"! c #52524A",
+"............",
+".>>>>$*>>>>.",
+".>>>>&>>>>>.",
+".'.,@+##&$%.",
+".>)>'#>>&!>.",
+".>=%#%%>@&>.",
+"..,@>*>-@&>=",
+" # #,>>#-%%.",
+" . @,%>>>>.",
+" . !;#>>>.",
+" . . ,;.",
+" . .. .."};
--- /dev/null
+/* Created with The GIMP */
+#define preview16_width 16
+#define preview16_height 16
+static unsigned char preview16_bits[] = {
+ 0xff, 0xff, 0x01, 0x81, 0x81, 0x80, 0xbd, 0xad, 0x49, 0xa8, 0xc9, 0x91,
+ 0x49, 0x90, 0x9e, 0x99, 0x1c, 0xac, 0x7d, 0x84, 0xf1, 0x80, 0xf2, 0x87,
+ 0x22, 0xfa, 0x24, 0x52, 0x24, 0x5a, 0xc8, 0x94 };
--- /dev/null
+/* XPM */
+static char * preview16_xpm[] = {
+"16 16 17 1",
+" c None",
+". c #020202",
+"+ c #1A1A16",
+"@ c #636357",
+"# c #6E6E62",
+"$ c #828276",
+"% c #8A8A7A",
+"& c #969686",
+"* c #A6A692",
+"= c #B2B29E",
+"- c #BABAA6",
+"; c #363632",
+"> c #BEBEAA",
+", c #52524A",
+"' c #CECEB2",
+") c #46463E",
+"! c #7A7A6E",
+"................",
+".''''''>@''''''.",
+".''''''%>''''''.",
+".'!..#*;,=#*'#=.",
+".''.''!*>''&=@'.",
+".''.''#@>''>)='.",
+".'',,'#!@>'&@''.",
+" .;@;''*>'')%''.",
+" -$$;'''''%!>@=.",
+". &$@;&'''*''>'.",
+". @,+$'''''''.",
+" . ...;;;+''''.",
+" . . . .....",
+" . . . . . ",
+" . . . .. . ",
+" . .. . . ."};
--- /dev/null
+/* XPM */
+static char * preview20_xpm[] = {
+"20 20 17 1",
+" c None",
+". c #000200",
+"+ c #151614",
+"@ c #20211F",
+"# c #31312A",
+"$ c #3D3C35",
+"% c #474439",
+"& c #504F48",
+"* c #626054",
+"= c #727063",
+"- c #7E7E6F",
+"; c #888A7A",
+"> c #969987",
+", c #A9A992",
+"' c #B8B8A1",
+") c #C6C5AA",
+"! c #CFCDB1",
+" .@@@@@@@@@@@@@@@@. ",
+" %!!!!!!!''!!!!!!!% ",
+" %!!!!!!)&>!!!!!!!% ",
+" %!!!!!!>*'!!!!!!!% ",
+" %!!!!!)&*')')!!''% ",
+" @&@+#*&*=#;&*)'%-% ",
+" %!,>!,=;,)!)=,-$'% ",
+" %!,>!'=&-!!!'*#;!% ",
+" %!,-),=>','!!$&)!% ",
+" %!)$$'&&=%)!,+;!!% ",
+" %!','!);;!!)%**!!% ",
+" $;*$!!!!!!!;%'->)% ",
+" *=$!!!!!!)*-!'*;% ",
+" @>;*='!!!!),)!!''% ",
+" . *&&,!!!!!!!!!!% ",
+" ..+##@>,,,,,,,$ ",
+" . . . ......... ",
+" . . . ... . . ",
+" . . . . ... . ",
+" . . "};
--- /dev/null
+/* Created with The GIMP */
+#define preview_width 24
+#define preview_height 24
+static unsigned char preview_bits[] = {
+ 0xfe, 0xff, 0x7f, 0x02, 0x00, 0x40, 0x02, 0x18, 0x40, 0x02, 0x0c, 0x40,
+ 0x02, 0x04, 0x40, 0x02, 0x00, 0x50, 0xfe, 0xde, 0x59, 0x32, 0x03, 0x49,
+ 0x32, 0x0f, 0x4f, 0x32, 0x07, 0x46, 0x32, 0x23, 0x46, 0x62, 0x1e, 0x47,
+ 0x02, 0x0c, 0x47, 0x02, 0x80, 0x4d, 0x32, 0x80, 0x48, 0x2c, 0xc0, 0x58,
+ 0x42, 0x00, 0x40, 0xc2, 0x01, 0x40, 0xe4, 0x0e, 0x40, 0x44, 0xf4, 0x7f,
+ 0x48, 0xa4, 0x24, 0x48, 0xb4, 0x24, 0x90, 0x29, 0x47, 0x10, 0x00, 0x40 };
--- /dev/null
+/* XPM */
+static char * preview_xpm[] = {
+"24 24 10 1",
+" c None",
+". c #000000",
+"+ c #CECEB2",
+"@ c #656559",
+"# c #818174",
+"$ c #B9B9A4",
+"% c #969686",
+"& c #181815",
+"* c #363630",
+"= c #53534B",
+" ...................... ",
+" .++++++++++++++++++++. ",
+" .+++++++++@#+++++++++. ",
+" .++++++++$.%+++++++++. ",
+" .++++++++@#++++++++++. ",
+" .+++++++$&@$+$$++++%+. ",
+" .@....*#&@=.#@.%++@&+. ",
+" .++%%++@#++$++$*+$.#+. ",
+" .++%%++%=*#++++##=*++. ",
+" .++%%++#@@%+++++*.%++. ",
+" .++%@$+@#++%%+++&=+++. ",
+" .+++&.+%.@=&+++#.#+++. ",
+" .+++$$++$@#++++.@=+++. ",
+" .+$**+++++++++@&+=$++. ",
+" .*@*++++++++$.%+$*@+. ",
+" $##*++++++++#*+++%*+. ",
+" . %#@*%++++++++++++++. ",
+" . @=&#+++++++++++++. ",
+" . ...***&$$++++++++. ",
+" . . . ........... ",
+" . . . . . . . ",
+" . . . .. . . . ",
+" . .. . . ... . ",
+" . . "};
--- /dev/null
+/* XPM */
+static char * nwork12_xpm[] = {
+"12 12 17 1",
+" c None",
+". c #0F110E",
+"+ c #161815",
+"@ c #1F211E",
+"# c #383937",
+"$ c #6A6C69",
+"% c #818380",
+"& c #E46767",
+"* c #FF6467",
+"= c #959794",
+"- c #DC9897",
+"; c #ADAFAC",
+"> c #FF9797",
+", c #C6C8C5",
+"' c #FFCBCA",
+") c #E4E6E3",
+"! c #FBFDFA",
+" >> ",
+" '**' ",
+" >>>> ",
+" '*''*' ",
+" >>!)>> ",
+" '*,==,*' ",
+" >>$@=!>> ",
+" '*';#;!'*' ",
+" >>!$$=!,-> ",
+"'*'=)%!%.@&'",
+">>!=!=;..+$>",
+" ********** "};
--- /dev/null
+/* XPM */
+static char * nwork14_xpm[] = {
+"14 14 17 1",
+" c None",
+". c #000100",
+"+ c #161816",
+"@ c #222421",
+"# c #2A2C29",
+"$ c #363836",
+"% c #525451",
+"& c #686A67",
+"* c #828481",
+"= c #FF6467",
+"- c #949693",
+"; c #A4A6A3",
+"> c #FF9797",
+", c #B8BAB7",
+"' c #D8D6D4",
+") c #FFCBCA",
+"! c #FAFDF9",
+" >> ",
+" )==) ",
+" >>>> ",
+" )=))=) ",
+" >>!!>> ",
+" )=)!!)=) ",
+" >>''@!>> ",
+" )=&%#!!)=) ",
+" >>-@$!!!>> ",
+" )=);%&!!!)=) ",
+" >>!&&;,!&,>> ",
+")=)*',,'@.+'=)",
+">>!-!';$+++%>>",
+" ============ "};
--- /dev/null
+/* XPM */
+static char * nwork16_xpm[] = {
+"16 16 17 1",
+" c None",
+". c #040703",
+"+ c #0E100D",
+"@ c #262825",
+"# c #434542",
+"$ c #4C4E4B",
+"% c #5B5D5A",
+"& c #70726F",
+"* c #868885",
+"= c #D86467",
+"- c #FF6467",
+"; c #A69F9F",
+"> c #FF9797",
+", c #B6B8B5",
+"' c #C7C9C6",
+") c #D5D7D4",
+"! c #FAFCF9",
+" >> ",
+" -- ",
+" >--> ",
+" ->>- ",
+" >-!!-> ",
+" ->!!>- ",
+" >-!!&*-> ",
+" -;#@;)>- ",
+" >-#&.;!!-> ",
+" ->!+@,!!>- ",
+" >-!&@%;!!!-> ",
+" ->)#,%,,&.;- ",
+" >-!%'!#!$..+=> ",
+" ->!&!!&&..++#- ",
+">->>>>>>>>>>>>->",
+" >>>>>>>>>>>>>> "};
--- /dev/null
+/* XPM */
+static char * nwork20_xpm[] = {
+"20 20 17 1",
+" c None",
+". c #000100",
+"+ c #262825",
+"@ c #2B2D2A",
+"# c #444643",
+"$ c #575956",
+"% c #726D6B",
+"& c #D16668",
+"* c #FF6467",
+"= c #979794",
+"- c #E4999A",
+"; c #B1B3B0",
+"> c #FF9797",
+", c #C9CBC8",
+"' c #D3D5D2",
+") c #E5E7E3",
+"! c #FDFFFB",
+" ** ",
+" >**> ",
+" **** ",
+" >****> ",
+" **>>** ",
+" >**!!**> ",
+" **>!!>** ",
+" >**!!)!**> ",
+" **>!'.)>** ",
+" >*%$$;,!!**> ",
+" *&=;.=!!!>** ",
+" >*&;@@=!!!!**> ",
+" **>,$=;!!!!>** ",
+" >**)#%;=!!!!!**> ",
+" **>=,;=';!,#;>** ",
+" >**)%!)%!!=+..,**> ",
+" **>='!)%!;....@-** ",
+">**!;!!!='#####$=**>",
+"********************",
+"********************"};
--- /dev/null
+/* ©2002 David Kastrup, GPL */
+#define prevwork_width 24
+#define prevwork_height 24
+#define prevwork_x_hot 0
+#define prevwork_y_hot 20
+static unsigned char prevwork_bits[] = {
+ 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00,
+ 0x00, 0xe7, 0x00, 0x00, 0xe7, 0x00, 0x80, 0xc3, 0x01, 0x80, 0xc3, 0x01,
+ 0xc0, 0x81, 0x03, 0xc0, 0x81, 0x03, 0xe0, 0x30, 0x07, 0xe0, 0x3f, 0x07,
+ 0x70, 0x0d, 0x0e, 0x70, 0x0d, 0x0e, 0x38, 0x0e, 0x1c, 0x38, 0x0f, 0x1c,
+ 0x1c, 0x1f, 0x38, 0x9c, 0xa5, 0x3b, 0x8e, 0xc4, 0x77, 0xce, 0xe4, 0x7f,
+ 0x47, 0xec, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
--- /dev/null
+/* XPM */
+static char * nwork24_xpm[] = {
+"24 24 17 1",
+" c None",
+". c #000100",
+"+ c #141513",
+"@ c #212320",
+"# c #313230",
+"$ c #3B3D3A",
+"% c #484947",
+"& c #626461",
+"* c #8C8E8B",
+"= c #FF6467",
+"- c #B6AFAC",
+"; c #FF9696",
+"> c #C4C6C3",
+", c #D0D2CE",
+"' c #FFCBCA",
+") c #DDDFDC",
+"! c #FBFDFA",
+" ;; ",
+" ;==; ",
+" ==== ",
+" ;====; ",
+" ==;;== ",
+" ;==''==; ",
+" ==;!!;== ",
+" ;=='!!'==; ",
+" ==;!!!!;== ",
+" ;=='!!>,'==; ",
+" ==;!!!.%!;== ",
+" ;=;$#$*,)!'==; ",
+" ==&,*..!!!!;== ",
+" ;==#,@.$!!!!'==; ",
+" ==;!&.&&!!!!!;== ",
+" ;==')*&*&!!!!!'==; ",
+" ==;!*#&>&!!!!!!;== ",
+" ;==')$)&->-!!)&*'==; ",
+" ==;!&-!,&!!-,%..*;== ",
+" ;==',%!!)$!!>#....-==; ",
+" ==;!&>!!)@!>+.....+;== ",
+";=='!-!!!!*!&%%%%%&&*==;",
+"========================",
+" ====================== "};
--- /dev/null
+/* XPM */
+static char * pspdf5_xpm[] = {
+"24 24 56 1",
+" c None s backgroundToolBarColor",
+". c #869CB4",
+"+ c #00244C",
+"@ c #000000",
+"# c #002248",
+"$ c #0050A9",
+"% c #006FEB",
+"& c #0066D9",
+"* c #00336D",
+"= c #37452B",
+"- c #001070",
+"; c #004BA2",
+"> c #0078FF",
+", c #0075FC",
+"' c #004DB6",
+") c #00072F",
+"! c #0047FF",
+"~ c #006DFF",
+"{ c #0042CA",
+"] c #00169E",
+"^ c #000A45",
+"/ c #445636",
+"( c #0024FF",
+"_ c #0027FF",
+": c #0056ED",
+"< c #001FA7",
+"[ c #00179F",
+"} c #526741",
+"| c #001DCE",
+"1 c #4C603C",
+"2 c #566B43",
+"3 c #5A7046",
+"4 c #000B4C",
+"5 c #0023F5",
+"6 c #001492",
+"7 c #000E65",
+"8 c #00010B",
+"9 c #001AB9",
+"0 c #0022F0",
+"a c #001387",
+"b c #000942",
+"c c #000C57",
+"d c #D37F71",
+"e c #0037C4",
+"f c #6C84B7",
+"g c #CE918A",
+"h c #D4897A",
+"i c #67102D",
+"j c #C47474",
+"k c #D69788",
+"l c #CB8984",
+"m c #D79C8D",
+"n c #C8807D",
+"o c #5A5A5A",
+"p c #B50000",
+"q c #AA7979",
+" .+ @@@@ ",
+" .#$%&* @@@=@@ ",
+" -;%>>>,') @ @=@ ",
+" -!~>>>{]^ @/@ ",
+" -(_!:<[]^ @}@ ",
+" -(((|]]]^ @@}}1@@ ",
+" -(((|]]]^ @232@ ",
+" 45((|]678 @}@ ",
+" 490|ab @ ",
+" -c ",
+" @ ",
+" @d@ ",
+" eeef feef @ghi@ ",
+" e e e @jgkii@ ",
+" eeef feef @jlgmiii@ ",
+" e e @jnlgmiiii@",
+" e e e @jnlgkiii@ ",
+" e feef o@jnhii@ ",
+" o@di@ ",
+"pppq pppq pppq @@ ",
+"p p p p p ",
+"pppq p p ppq ",
+"p p p p ",
+"p pppq p "};
--- /dev/null
+/* XPM */
+static char * sep_xpm[] = {
+"1 24 2 1",
+" c None s backgroundToolBarColor",
+". c #776758",
+" ",
+" ",
+" ",
+".",
+".",
+".",
+".",
+".",
+".",
+".",
+".",
+".",
+".",
+".",
+".",
+".",
+".",
+".",
+".",
+".",
+".",
+" ",
+" ",
+" "};
--- /dev/null
+/* XPM */
+static char * tex6_xpm[] = {
+"24 24 233 2",
+" c None s backgroundToolBarColor",
+". c #3D9944",
+"+ c #3E9842",
+"@ c #3DA243",
+"# c #3C9B47",
+"$ c #3EA442",
+"% c #290400",
+"& c #304116",
+"* c #3E8D43",
+"= c #3F7744",
+"- c #977C5E",
+"; c #842835",
+"> c #9C3635",
+", c #94506A",
+"' c #54764E",
+") c #3DBA41",
+"! c #386C34",
+"~ c #CABC9A",
+"{ c #C1AE8E",
+"] c #795642",
+"^ c #907F62",
+"/ c #FFFFC1",
+"( c #94AC73",
+"_ c #664535",
+": c #8A6A61",
+"< c #6D302B",
+"[ c #943A3B",
+"} c #772437",
+"| c #52382D",
+"1 c #664940",
+"2 c #99A578",
+"3 c #6E4835",
+"4 c #6D5642",
+"5 c #9DBA88",
+"6 c #A3B181",
+"7 c #A3A982",
+"8 c #B9968B",
+"9 c #BF8A7F",
+"0 c #CAA8A0",
+"a c #6F9966",
+"b c #CEE6B0",
+"c c #3E8946",
+"d c #808C6A",
+"e c #947F66",
+"f c #916B50",
+"g c #370708",
+"h c #5D181B",
+"i c #664437",
+"j c #F2DBB4",
+"k c #621E1C",
+"l c #782C33",
+"m c #411712",
+"n c #82806E",
+"o c #868266",
+"p c #C1BFA2",
+"q c #C7C2A8",
+"r c #82806A",
+"s c #84826C",
+"t c #E8E8C7",
+"u c #D1B08B",
+"v c #4A1A16",
+"w c #5C2628",
+"x c #7F3630",
+"y c #6B262B",
+"z c #82826F",
+"A c #BBBABD",
+"B c #F8FFFD",
+"C c #404448",
+"D c #48424A",
+"E c #FFFEFF",
+"F c #BBC0BB",
+"G c #9C6D56",
+"H c #5D201D",
+"I c #712723",
+"J c #868471",
+"K c #A29EF2",
+"L c #3132E4",
+"M c #181766",
+"N c #807E80",
+"O c #2F29CF",
+"P c #A46D56",
+"Q c #6C0E12",
+"R c #6B2731",
+"S c #7F7F6F",
+"T c #8E8BE8",
+"U c #141369",
+"V c #504D7F",
+"W c #848081",
+"X c #2725AA",
+"Y c #A46F58",
+"Z c #833A33",
+"` c #040400",
+" . c #BFBE98",
+".. c #7F7F6C",
+"+. c #8D523D",
+"@. c #580F16",
+"#. c #66283A",
+"$. c #312B23",
+"%. c #DCDFBB",
+"&. c #E4D7A8",
+"*. c #B48566",
+"=. c #4E3025",
+"-. c #3F0810",
+";. c #9C4256",
+">. c #31302E",
+",. c #E2E0C7",
+"'. c #ACA896",
+"). c #CFD1B0",
+"!. c #ECE6CB",
+"~. c #F0D9AC",
+"{. c #A26048",
+"]. c #50271C",
+"^. c #3D030C",
+"/. c #392F26",
+"(. c #E4E2CB",
+"_. c #ACAA92",
+":. c #48453B",
+"<. c #878364",
+"[. c #83806D",
+"}. c #B2B496",
+"|. c #CFBD94",
+"1. c #8C5037",
+"2. c #4C2318",
+"3. c #351114",
+"4. c #522B2B",
+"5. c #B07F6B",
+"6. c #62433A",
+"7. c #A0876A",
+"8. c #BFBB96",
+"9. c #B8C2A0",
+"0. c #1E140C",
+"a. c #35210C",
+"b. c #2B2106",
+"c. c #A09A96",
+"d. c #CCBF9A",
+"e. c #AA8368",
+"f. c #B4846A",
+"g. c #AE826A",
+"h. c #D2B89A",
+"i. c #EAD0AA",
+"j. c #9E6852",
+"k. c #542D25",
+"l. c #441C16",
+"m. c #312019",
+"n. c #5F2D31",
+"o. c #604835",
+"p. c #A29A8F",
+"q. c #3D3123",
+"r. c #A09698",
+"s. c #BFBBA2",
+"t. c #C7BB9C",
+"u. c #B38A71",
+"v. c #A05250",
+"w. c #1A0400",
+"x. c #520308",
+"y. c #350010",
+"z. c #584C44",
+"A. c #444637",
+"B. c #7F625E",
+"C. c #834A3F",
+"D. c #AA7F6D",
+"E. c #D2BC9E",
+"F. c #E6E4BD",
+"G. c #A66456",
+"H. c #2B0702",
+"I. c #602A2B",
+"J. c #5A2229",
+"K. c #3C3831",
+"L. c #6F6B58",
+"M. c #797B6D",
+"N. c #484A3E",
+"O. c #ACA7A2",
+"P. c #4C463E",
+"Q. c #807E71",
+"R. c #686F5A",
+"S. c #605F56",
+"T. c #E0D9BC",
+"U. c #FDFACB",
+"V. c #C5BD9C",
+"W. c #8B5E4E",
+"X. c #561F1A",
+"Y. c #582E2F",
+"Z. c #6F3A3A",
+"`. c #814247",
+" + c #94947D",
+".+ c #858B75",
+"++ c #9C9E81",
+"@+ c #E0DBBB",
+"#+ c #CFC19C",
+"$+ c #483325",
+"%+ c #661718",
+"&+ c #995657",
+"*+ c #732428",
+"=+ c #7B2C2E",
+"-+ c #655347",
+";+ c #DACDA6",
+">+ c #F6E5B8",
+",+ c #73503A",
+"'+ c #643433",
+")+ c #894043",
+"!+ c #9C5156",
+"~+ c #681B23",
+"{+ c #873E43",
+"]+ c #5D2E34",
+"^+ c #623C46",
+"/+ c #775A50",
+"(+ c #858271",
+"_+ c #987B71",
+":+ c #524024",
+"<+ c #7D6C56",
+"[+ c #8A806F",
+"}+ c #7B826D",
+"|+ c #853626",
+"1+ c #894A3C",
+"2+ c #75292C",
+"3+ c #93594C",
+"4+ c #623739",
+"5+ c #8B5A56",
+"6+ c #4E0E1C",
+"7+ c #7E3F47",
+"8+ c #804047",
+"9+ c #6E3A3D",
+"0+ c #9F6662",
+"a+ c #A05A62",
+"b+ c #4C2626",
+"c+ c #A45862",
+"d+ c #731C21",
+"e+ c #964648",
+"f+ c #722020",
+"g+ c #620818",
+"h+ c #A0675E",
+"i+ c #561014",
+"j+ c #5A0414",
+" ",
+" . + @ + # $ % ",
+" % & * = - ; > , ' = ) ! ~ { ] ",
+" ^ / ( _ : < [ } | ' 1 _ 2 ~ % 3 ",
+" 4 / 5 6 7 8 9 0 a b c d / e f g h ",
+" i / / / / / / / / / / / j 3 k l ",
+" m / n o p / q r s t / / u v w x y ",
+" z z A B C / D E F n / / j G H I ",
+" J z K L M / N K O M / / j P h Q R ",
+" S z T U V / W T X V / / u Y h Z ",
+" ` t ...t / t . ./ / / u +.h @.#. ",
+" $.%./ ../ / / / / / / / &.*.=.-.Z ;. ",
+" >.,./ '.)./ / !./ / / / / ~.{.].^.Z ;. ",
+" /.(./ _.:.<.[...}./ / / / / |.1.2.3.4. ",
+"5.5.6.7.8.9.0.a.b.c.d.e.5.f.g.h.i.j.k.l.m.n. ",
+" o./ / / p.q.r.s./ / / / / t.u.v.w.x. ",
+"5.5.y.z./ / / A./ / / B.C.D.E.F.G.H.I.;.J. ",
+" K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. ",
+" +/ .+/ / / ++@+/ / #+$+%+&+*+=+ ",
+" -+/ / / ;+/ / / >+,+'+)+!+~+{+]+^+ ",
+" /+(+_+:+<+[+}+|+1+2+3+4+5+6+ ",
+" 7+7+8+9+0+a+b+c+d+e+ f+ ",
+" g+h+ i+ j+ ",
+" "};
--- /dev/null
+/* XPM */
+static char * view15_xpm[] = {
+"24 24 4 1",
+" c None s backgroundToolBarColor",
+". c #000000",
+"+ c #565656",
+"@ c #FFFFFF",
+" ",
+" ",
+" ",
+" ",
+" ... ",
+" .+ . ",
+" .+ . ",
+" .+ .+ ",
+" .+ .+ ... ",
+" .+ .+ ..",
+" .... .+ .",
+" .@@ +. .+ .+",
+" .@@@ +. .+ .+ ",
+" .@@@ . .... .+ ",
+" . @ ...@@ +.. ",
+" +. +. .@@@ +. ",
+" +.++. .@@@ . ",
+" +.. . @ . ",
+" +. +. ",
+" +.++. ",
+" +.. ",
+" ",
+" ",
+" "};
--- /dev/null
+/* XPM */
+static char * viewdvi11_xpm[] = {
+"24 24 31 1",
+" c None s backgroundToolBarColor",
+". c #090909",
+"+ c #000000",
+"@ c #292929",
+"# c #8E8E8E",
+"$ c #2D2D2D",
+"% c #303030",
+"& c #2B2B2B",
+"* c #3C3C3C",
+"= c #1F1F1F",
+"- c #101010",
+"; c #1A1A1A",
+"> c #2E2E2E",
+", c #FFFFFF",
+"' c #C3C3C3",
+") c #252525",
+"! c #191919",
+"~ c #131313",
+"{ c #1D1D1D",
+"] c #0D0D0D",
+"^ c #121212",
+"/ c #444444",
+"( c #3B3B3B",
+"_ c #3D3D3D",
+": c #080808",
+"< c #295E29",
+"[ c #5ABD5A",
+"} c #488148",
+"| c #4CA14C",
+"1 c #4D904D",
+"2 c #4FA64F",
+" .+ ",
+" @# + ",
+" $# @ ",
+" %# &# ",
+" @# ++ ",
+" *=- ;# + ",
+" >,,') !# ~ ",
+" >,, + !# {# ",
+" ],, ++ *=- =# ",
+" #^ /+ >,,')# ",
+" ($_: >,, + ",
+" ## ],, + ",
+" #^ /+ ",
+" ($_: ",
+" ## ",
+" ",
+" <<<[ < < <",
+" < < < < <",
+" < < < < <",
+" < < } } <",
+" < < |11| <",
+" < < }} <",
+" <<<[ 22 <",
+" "};
--- /dev/null
+/* XPM */
+static char * viewpdf5_xpm[] = {
+"24 24 27 1",
+" c None s backgroundToolBarColor",
+". c #090909",
+"+ c #000000",
+"@ c #292929",
+"# c #8E8E8E",
+"$ c #2D2D2D",
+"% c #303030",
+"& c #2B2B2B",
+"* c #3C3C3C",
+"= c #1F1F1F",
+"- c #101010",
+"; c #1A1A1A",
+"> c #2E2E2E",
+", c #FFFFFF",
+"' c #C3C3C3",
+") c #252525",
+"! c #191919",
+"~ c #131313",
+"{ c #1D1D1D",
+"] c #0D0D0D",
+"^ c #121212",
+"/ c #444444",
+"( c #3B3B3B",
+"_ c #3D3D3D",
+": c #080808",
+"< c #B50000",
+"[ c #AA7979",
+" .+ ",
+" @# + ",
+" $# @ ",
+" %# &# ",
+" @# ++ ",
+" *=- ;# + ",
+" >,,') !# ~ ",
+" >,, + !# {# ",
+" ],, ++ *=- =# ",
+" #^ /+ >,,')# ",
+" ($_: >,, + ",
+" ## ],, + ",
+" #^ /+ ",
+" ($_: ",
+" ## ",
+" ",
+" <<<[ <<<[ <<<[",
+" < < < < < ",
+" < < < < < ",
+" <<<[ < < <<[ ",
+" < < < < ",
+" < < < < ",
+" < <<<[ < ",
+" "};
--- /dev/null
+/* XPM */
+static char * viewps8_xpm[] = {
+"24 24 27 1",
+" c None s backgroundToolBarColor",
+". c #090909",
+"+ c #000000",
+"@ c #292929",
+"# c #8E8E8E",
+"$ c #2D2D2D",
+"% c #303030",
+"& c #2B2B2B",
+"* c #3C3C3C",
+"= c #1F1F1F",
+"- c #101010",
+"; c #1A1A1A",
+"> c #2E2E2E",
+", c #FFFFFF",
+"' c #C3C3C3",
+") c #252525",
+"! c #191919",
+"~ c #131313",
+"{ c #1D1D1D",
+"] c #0D0D0D",
+"^ c #121212",
+"/ c #444444",
+"( c #3B3B3B",
+"_ c #3D3D3D",
+": c #080808",
+"< c #0037C4",
+"[ c #6C84B7",
+" .+ ",
+" @# + ",
+" $# @ ",
+" %# &# ",
+" @# ++ ",
+" *=- ;# + ",
+" >,,') !# ~ ",
+" >,, + !# {# ",
+" ],, ++ *=- =# ",
+" #^ /+ >,,')# ",
+" ($_: >,, + ",
+" ## ],, + ",
+" #^ /+ ",
+" ($_: ",
+" ## ",
+" ",
+" <<<[ [<<[ ",
+" < < < < ",
+" < < < ",
+" <<<[ [<<[ ",
+" < < ",
+" < < < ",
+" < [<<[ ",
+" "};
--- /dev/null
+;;; latex.el --- Support for LaTeX documents.
+
+;; Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2003,
+;; 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+
+;; Maintainer: auctex-devel@gnu.org
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file provides AUCTeX support for LaTeX.
+
+;;; Code:
+
+(require 'tex)
+(require 'tex-style)
+
+;;; Syntax
+
+(defvar LaTeX-optop "["
+ "The LaTeX optional argument opening character.")
+
+(defvar LaTeX-optcl "]"
+ "The LaTeX optional argument closeing character.")
+
+;;; Style
+
+(defcustom LaTeX-default-style "article"
+ "*Default when creating new documents."
+ :group 'LaTeX-environment
+ :type 'string)
+
+(defcustom LaTeX-default-options nil
+ "Default options to documentstyle.
+A list of strings."
+ :group 'LaTeX-environment
+ :type '(repeat (string :format "%v")))
+
+(make-variable-buffer-local 'LaTeX-default-options)
+
+(defcustom LaTeX-insert-into-comments t
+ "*Whether insertion commands stay in comments.
+This allows using the insertion commands even when
+the lines are outcommented, like in dtx files."
+ :group 'LaTeX-environment
+ :type 'boolean)
+
+(defun LaTeX-newline ()
+ "Start a new line potentially staying within comments.
+This depends on `LaTeX-insert-into-comments'."
+ (if LaTeX-insert-into-comments
+ (cond ((and (save-excursion (skip-chars-backward " \t") (bolp))
+ (save-excursion
+ (skip-chars-forward " \t")
+ (looking-at (concat TeX-comment-start-regexp "+"))))
+ (beginning-of-line)
+ (insert (buffer-substring-no-properties
+ (line-beginning-position) (match-end 0)))
+ (newline))
+ ((and (not (bolp))
+ (save-excursion
+ (skip-chars-forward " \t") (not (TeX-escaped-p)))
+ (looking-at
+ (concat "[ \t]*" TeX-comment-start-regexp "+[ \t]*")))
+ (delete-region (match-beginning 0) (match-end 0))
+ (indent-new-comment-line))
+ (t
+ (indent-new-comment-line)))
+ (newline)))
+
+
+;;; Syntax Table
+
+(defvar LaTeX-mode-syntax-table (copy-syntax-table TeX-mode-syntax-table)
+ "Syntax table used in LaTeX mode.")
+
+(progn ; set [] to match for LaTeX.
+ (modify-syntax-entry (string-to-char LaTeX-optop)
+ (concat "(" LaTeX-optcl)
+ LaTeX-mode-syntax-table)
+ (modify-syntax-entry (string-to-char LaTeX-optcl)
+ (concat ")" LaTeX-optop)
+ LaTeX-mode-syntax-table))
+
+;;; Sections
+
+(defun LaTeX-section (arg)
+ "Insert a template for a LaTeX section.
+Determine the type of section to be inserted, by the argument ARG.
+
+If ARG is nil or missing, use the current level.
+If ARG is a list (selected by \\[universal-argument]), go downward one level.
+If ARG is negative, go up that many levels.
+If ARG is positive or zero, use absolute level:
+
+ 0 : part
+ 1 : chapter
+ 2 : section
+ 3 : subsection
+ 4 : subsubsection
+ 5 : paragraph
+ 6 : subparagraph
+
+The following variables can be set to customize:
+
+`LaTeX-section-hook' Hooks to run when inserting a section.
+`LaTeX-section-label' Prefix to all section labels."
+
+ (interactive "*P")
+ (let* ((val (prefix-numeric-value arg))
+ (level (cond ((null arg)
+ (LaTeX-current-section))
+ ((listp arg)
+ (LaTeX-down-section))
+ ((< val 0)
+ (LaTeX-up-section (- val)))
+ (t val)))
+ (name (LaTeX-section-name level))
+ (toc nil)
+ (title (if (TeX-active-mark)
+ (buffer-substring (region-beginning)
+ (region-end))
+ ""))
+ (done-mark (make-marker)))
+ (run-hooks 'LaTeX-section-hook)
+ (LaTeX-newline)
+ (if (marker-position done-mark)
+ (goto-char (marker-position done-mark)))
+ (set-marker done-mark nil)))
+
+(defun LaTeX-current-section ()
+ "Return the level of the section that contain point.
+See also `LaTeX-section' for description of levels."
+ (save-excursion
+ (max (LaTeX-largest-level)
+ (if (re-search-backward (LaTeX-outline-regexp) nil t)
+ (- (LaTeX-outline-level) (LaTeX-outline-offset))
+ (LaTeX-largest-level)))))
+
+(defun LaTeX-down-section ()
+ "Return the value of a section one level under the current.
+Tries to find what kind of section that have been used earlier in the
+text, if this fail, it will just return one less than the current
+section."
+ (save-excursion
+ (let ((current (LaTeX-current-section))
+ (next nil)
+ (regexp (LaTeX-outline-regexp)))
+ (if (not (re-search-backward regexp nil t))
+ (1+ current)
+ (while (not next)
+ (cond
+ ((eq (LaTeX-current-section) current)
+ (if (re-search-forward regexp nil t)
+ (if (<= (setq next (LaTeX-current-section)) current) ;Wow!
+ (setq next (1+ current)))
+ (setq next (1+ current))))
+ ((not (re-search-backward regexp nil t))
+ (setq next (1+ current)))))
+ next))))
+
+(defun LaTeX-up-section (arg)
+ "Return the value of the section ARG levels above this one."
+ (save-excursion
+ (if (zerop arg)
+ (LaTeX-current-section)
+ (let ((current (LaTeX-current-section)))
+ (while (and (>= (LaTeX-current-section) current)
+ (re-search-backward (LaTeX-outline-regexp)
+ nil t)))
+ (LaTeX-up-section (1- arg))))))
+
+(defvar LaTeX-section-list '(("part" 0)
+ ("chapter" 1)
+ ("section" 2)
+ ("subsection" 3)
+ ("subsubsection" 4)
+ ("paragraph" 5)
+ ("subparagraph" 6))
+ "List which elements is the names of the sections used by LaTeX.")
+
+(defun LaTeX-section-list-add-locally (sections &optional clean)
+ "Add SECTIONS to `LaTeX-section-list'.
+SECTIONS can be a single list containing the section macro name
+as a string and the the level as an integer or a list of such
+lists.
+
+If optional argument CLEAN is non-nil, remove any existing
+entries from `LaTeX-section-list' before adding the new ones.
+
+The function will make `LaTeX-section-list' buffer-local and
+invalidate the section submenu in order to let the menu filter
+regenerate it. It is mainly a convenience function which can be
+used in style files."
+ (when (stringp (car sections))
+ (setq sections (list sections)))
+ (make-local-variable 'LaTeX-section-list)
+ (when clean (setq LaTeX-section-list nil))
+ (dolist (elt sections) (add-to-list 'LaTeX-section-list elt t))
+ (setq LaTeX-section-list
+ (sort (copy-sequence LaTeX-section-list)
+ (lambda (a b) (< (nth 1 a) (nth 1 b)))))
+ (setq LaTeX-section-menu nil))
+
+(defun LaTeX-section-name (level)
+ "Return the name of the section corresponding to LEVEL."
+ (let ((entry (TeX-member level LaTeX-section-list
+ (lambda (a b) (equal a (nth 1 b))))))
+ (if entry
+ (nth 0 entry)
+ nil)))
+
+(defun LaTeX-section-level (name)
+ "Return the level of the section NAME."
+ (let ((entry (TeX-member name LaTeX-section-list
+ (lambda (a b) (equal a (nth 0 b))))))
+
+ (if entry
+ (nth 1 entry)
+ nil)))
+
+(defcustom TeX-outline-extra nil
+ "List of extra TeX outline levels.
+
+Each element is a list with two entries. The first entry is the
+regular expression matching a header, and the second is the level of
+the header. See `LaTeX-section-list' for existing header levels."
+ :group 'LaTeX
+ :type '(repeat (group (regexp :tag "Match")
+ (integer :tag "Level"))))
+
+(defun LaTeX-outline-regexp (&optional anywhere)
+ "Return regexp for LaTeX sections.
+
+If optional argument ANYWHERE is not nil, do not require that the
+header is at the start of a line."
+ (concat (if anywhere "" "^")
+ "[ \t]*"
+ (regexp-quote TeX-esc)
+ "\\(appendix\\|documentstyle\\|documentclass\\|"
+ (mapconcat 'car LaTeX-section-list "\\|")
+ "\\)\\b"
+ (if TeX-outline-extra
+ "\\|"
+ "")
+ (mapconcat 'car TeX-outline-extra "\\|")
+ "\\|" TeX-header-end
+ "\\|" TeX-trailer-start))
+
+(defvar LaTeX-largest-level nil
+ "Largest sectioning level with current document class.")
+
+(make-variable-buffer-local 'LaTeX-largest-level)
+
+(defun LaTeX-largest-level ()
+ "Return largest sectioning level with current document class.
+Run style hooks before it has not been done."
+ (TeX-update-style)
+ LaTeX-largest-level)
+
+(defun LaTeX-largest-level-set (section)
+ "Set `LaTeX-largest-level' to the level of SECTION.
+SECTION has to be a string contained in `LaTeX-section-list'.
+Additionally the function will invalidate the section submenu in
+order to let the menu filter regenerate it."
+ (setq LaTeX-largest-level (LaTeX-section-level section))
+ (setq LaTeX-section-menu nil))
+
+(defun LaTeX-outline-offset ()
+ "Offset to add to `LaTeX-section-list' levels to get outline level."
+ (- 2 (LaTeX-largest-level)))
+
+(defun TeX-look-at (list)
+ "Check if we are looking at the first element of a member of LIST.
+If so, return the second element, otherwise return nil."
+ (while (and list
+ (not (looking-at (nth 0 (car list)))))
+ (setq list (cdr list)))
+ (if list
+ (nth 1 (car list))
+ nil))
+
+(defun LaTeX-outline-level ()
+ "Find the level of current outline heading in an LaTeX document."
+ (cond ((looking-at LaTeX-header-end) 1)
+ ((looking-at LaTeX-trailer-start) 1)
+ ((TeX-look-at TeX-outline-extra)
+ (max 1 (+ (TeX-look-at TeX-outline-extra)
+ (LaTeX-outline-offset))))
+ (t
+ (save-excursion
+ (skip-chars-forward " \t")
+ (forward-char 1)
+ (cond ((looking-at "appendix") 1)
+ ((looking-at "documentstyle") 1)
+ ((looking-at "documentclass") 1)
+ ((TeX-look-at LaTeX-section-list)
+ (max 1 (+ (TeX-look-at LaTeX-section-list)
+ (LaTeX-outline-offset))))
+ (t
+ (error "Unrecognized header")))))))
+
+(defun LaTeX-outline-name ()
+ "Guess a name for the current header line."
+ (save-excursion
+ (if (re-search-forward "{\\([^\}]*\\)}" (+ (point) fill-column 10) t)
+ (match-string 1)
+ (buffer-substring (point) (min (point-max) (+ 20 (point)))))))
+
+(add-hook 'TeX-remove-style-hook
+ (lambda () (setq LaTeX-largest-level nil)))
+
+(defcustom LaTeX-section-hook
+ '(LaTeX-section-heading
+ LaTeX-section-title
+;; LaTeX-section-toc ; Most people won't want this
+ LaTeX-section-section
+ LaTeX-section-label)
+ "List of hooks to run when a new section is inserted.
+
+The following variables are set before the hooks are run
+
+level - numeric section level, see the documentation of `LaTeX-section'.
+name - name of the sectioning command, derived from `level'.
+title - The title of the section, default to an empty string.
+toc - Entry for the table of contents list, default nil.
+done-mark - Position of point afterwards, default nil (meaning end).
+
+The following standard hook exist -
+
+LaTeX-section-heading: Query the user about the name of the
+sectioning command. Modifies `level' and `name'.
+
+LaTeX-section-title: Query the user about the title of the
+section. Modifies `title'.
+
+LaTeX-section-toc: Query the user for the toc entry. Modifies
+`toc'.
+
+LaTeX-section-section: Insert LaTeX section command according to
+`name', `title', and `toc'. If `toc' is nil, no toc entry is
+inserted. If `toc' or `title' are empty strings, `done-mark' will be
+placed at the point they should be inserted.
+
+LaTeX-section-label: Insert a label after the section command.
+Controled by the variable `LaTeX-section-label'.
+
+To get a full featured `LaTeX-section' command, insert
+
+ (setq LaTeX-section-hook
+ '(LaTeX-section-heading
+ LaTeX-section-title
+ LaTeX-section-toc
+ LaTeX-section-section
+ LaTeX-section-label))
+
+in your .emacs file."
+ :group 'LaTeX-macro
+ :type 'hook
+ :options '(LaTeX-section-heading
+ LaTeX-section-title
+ LaTeX-section-toc
+ LaTeX-section-section
+ LaTeX-section-label))
+
+
+(defcustom LaTeX-section-label
+ '(("part" . "part:")
+ ("chapter" . "chap:")
+ ("section" . "sec:")
+ ("subsection" . "sec:")
+ ("subsubsection" . "sec:"))
+ "Default prefix when asking for a label.
+
+Some LaTeX packages \(such as `fancyref'\) look at the prefix to generate some
+text around cross-references automatically. When using those packages, you
+should not change this variable.
+
+If it is a string, it it used unchanged for all kinds of sections.
+If it is nil, no label is inserted.
+If it is a list, the list is searched for a member whose car is equal
+to the name of the sectioning command being inserted. The cdr is then
+used as the prefix. If the name is not found, or if the cdr is nil,
+no label is inserted."
+ :group 'LaTeX-label
+ :type '(choice (const :tag "none" nil)
+ (string :format "%v" :tag "Common")
+ (repeat :menu-tag "Level specific"
+ :format "\n%v%i"
+ (cons :format "%v"
+ (string :tag "Type")
+ (choice :tag "Prefix"
+ (const :tag "none" nil)
+ (string :format "%v"))))))
+
+;;; Section Hooks.
+
+(defun LaTeX-section-heading ()
+ "Hook to prompt for LaTeX section name.
+Insert this hook into `LaTeX-section-hook' to allow the user to change
+the name of the sectioning command inserted with `\\[LaTeX-section]'."
+ (let ((string (completing-read
+ (concat "Level: (default " name ") ")
+ LaTeX-section-list
+ nil nil nil)))
+ ; Update name
+ (if (not (zerop (length string)))
+ (setq name string))
+ ; Update level
+ (setq level (LaTeX-section-level name))))
+
+(defun LaTeX-section-title ()
+ "Hook to prompt for LaTeX section title.
+Insert this hook into `LaTeX-section-hook' to allow the user to change
+the title of the section inserted with `\\[LaTeX-section]."
+ (setq title (read-string "Title: " title))
+ (let ((region (and (TeX-active-mark)
+ (cons (region-beginning) (region-end)))))
+ (when region (delete-region (car region) (cdr region)))))
+
+(defun LaTeX-section-toc ()
+ "Hook to prompt for the LaTeX section entry in the table of content .
+Insert this hook into `LaTeX-section-hook' to allow the user to insert
+a different entry for the section in the table of content."
+ (setq toc (read-string "Toc Entry: "))
+ (if (zerop (length toc))
+ (setq toc nil)))
+
+(defun LaTeX-section-section ()
+ "Hook to insert LaTeX section command into the file.
+Insert this hook into `LaTeX-section-hook' after those hooks that set
+the `name', `title', and `toc' variables, but before those hooks that
+assume that the section is already inserted."
+ ;; insert a new line if the current line and the previous line are
+ ;; not empty (except for whitespace), with one exception: do not
+ ;; insert a new line if the previous (or current, sigh) line starts
+ ;; an environment (i.e., starts with `[optional whitespace]\begin')
+ (unless (save-excursion
+ (re-search-backward
+ (concat "^\\s-*\n\\s-*\\=\\|^\\s-*" (regexp-quote TeX-esc)
+ "begin")
+ (line-beginning-position 0) t))
+ (LaTeX-newline))
+ (insert TeX-esc name)
+ (cond ((null toc))
+ ((zerop (length toc))
+ (insert LaTeX-optop)
+ (set-marker done-mark (point))
+ (insert LaTeX-optcl))
+ (t
+ (insert LaTeX-optop toc LaTeX-optcl)))
+ (insert TeX-grop)
+ (if (zerop (length title))
+ (set-marker done-mark (point)))
+ (insert title TeX-grcl)
+ (LaTeX-newline)
+ ;; If RefTeX is available, tell it that we've just made a new section
+ (and (fboundp 'reftex-notice-new-section)
+ (reftex-notice-new-section)))
+
+(defun LaTeX-section-label ()
+ "Hook to insert a label after the sectioning command.
+Insert this hook into `LaTeX-section-hook' to prompt for a label to be
+inserted after the sectioning command.
+
+The behaviour of this hook is controlled by variable `LaTeX-section-label'."
+ (and (LaTeX-label name)
+ (LaTeX-newline)))
+
+;;; Environments
+
+(defgroup LaTeX-environment nil
+ "Environments in AUCTeX."
+ :group 'LaTeX-macro)
+
+(defcustom LaTeX-default-environment "itemize"
+ "*The default environment when creating new ones with `LaTeX-environment'."
+ :group 'LaTeX-environment
+ :type 'string)
+ (make-variable-buffer-local 'LaTeX-default-environment)
+
+(defvar LaTeX-environment-history nil)
+
+;; Variable used to cache the current environment, e.g. for repeated
+;; tasks in an environment, like indenting each line in a paragraph to
+;; be filled. It must not have a non-nil value in general. That
+;; means it is usually let-bound for such operations.
+(defvar LaTeX-current-environment nil)
+
+(defun LaTeX-environment (arg)
+ "Make LaTeX environment (\\begin{...}-\\end{...} pair).
+With optional ARG, modify current environment.
+
+It may be customized with the following variables:
+
+`LaTeX-default-environment' Your favorite environment.
+`LaTeX-default-style' Your favorite document class.
+`LaTeX-default-options' Your favorite document class options.
+`LaTeX-float' Where you want figures and tables to float.
+`LaTeX-table-label' Your prefix to labels in tables.
+`LaTeX-figure-label' Your prefix to labels in figures.
+`LaTeX-default-format' Format for array and tabular.
+`LaTeX-default-width' Width for minipage and tabular*.
+`LaTeX-default-position' Position for array and tabular."
+
+ (interactive "*P")
+ (let ((environment (completing-read (concat "Environment type: (default "
+ (if (TeX-near-bobp)
+ "document"
+ LaTeX-default-environment)
+ ") ")
+ (LaTeX-environment-list)
+ nil nil nil
+ 'LaTeX-environment-history)))
+ ;; Get default
+ (cond ((and (zerop (length environment))
+ (TeX-near-bobp))
+ (setq environment "document"))
+ ((zerop (length environment))
+ (setq environment LaTeX-default-environment))
+ (t
+ (setq LaTeX-default-environment environment)))
+
+ (let ((entry (assoc environment (LaTeX-environment-list))))
+ (if (null entry)
+ (LaTeX-add-environments (list environment)))
+
+ (if arg
+ (LaTeX-modify-environment environment)
+ (LaTeX-environment-menu environment)))))
+
+(defun LaTeX-environment-menu (environment)
+ "Insert ENVIRONMENT around point or region."
+ (let ((entry (assoc environment (LaTeX-environment-list))))
+ (cond ((not (and entry (nth 1 entry)))
+ (LaTeX-insert-environment environment))
+ ((numberp (nth 1 entry))
+ (let ((count (nth 1 entry))
+ (args ""))
+ (while (> count 0)
+ (setq args (concat args TeX-grop TeX-grcl))
+ (setq count (- count 1)))
+ (LaTeX-insert-environment environment args)))
+ ((or (stringp (nth 1 entry)) (vectorp (nth 1 entry)))
+ (let ((prompts (cdr entry))
+ (args ""))
+ (dolist (elt prompts)
+ (let* ((optional (vectorp elt))
+ (elt (if optional (elt elt 0) elt))
+ (arg (read-string (concat (when optional "(Optional) ")
+ elt ": "))))
+ (setq args (concat args
+ (cond ((and optional (> (length arg) 0))
+ (concat LaTeX-optop arg LaTeX-optcl))
+ ((not optional)
+ (concat TeX-grop arg TeX-grcl)))))))
+ (LaTeX-insert-environment environment args)))
+ (t
+ (apply (nth 1 entry) environment (nthcdr 2 entry))))))
+
+(defun LaTeX-close-environment (&optional reopen)
+ "Create an \\end{...} to match the current environment.
+With prefix-argument, reopen environment afterwards."
+ (interactive "*P")
+ (if (> (point)
+ (save-excursion
+ (beginning-of-line)
+ (when LaTeX-insert-into-comments
+ (if (looking-at comment-start-skip)
+ (goto-char (match-end 0))))
+ (skip-chars-forward " \t")
+ (point)))
+ (LaTeX-newline))
+ (let ((environment (LaTeX-current-environment 1)) marker)
+ (insert "\\end{" environment "}")
+ (indent-according-to-mode)
+ (if (or (not (looking-at "[ \t]*$"))
+ (and (TeX-in-commented-line)
+ (save-excursion (beginning-of-line 2)
+ (not (TeX-in-commented-line)))))
+ (LaTeX-newline)
+ (let ((next-line-add-newlines t))
+ (next-line 1)
+ (beginning-of-line)))
+ (indent-according-to-mode)
+ (when reopen
+ (save-excursion
+ (setq marker (point-marker))
+ (set-marker-insertion-type marker t)
+ (LaTeX-environment-menu environment)
+ (delete-region (point)
+ (if (save-excursion (goto-char marker)
+ (bolp))
+ (1- marker)
+ marker))
+ (move-marker marker nil)))))
+
+(defvar LaTeX-after-insert-env-hooks nil
+ "List of functions to be run at the end of `LaTeX-insert-environment'.
+Each function is called with three arguments: the name of the
+environment just inserted, the buffer position just before
+\\begin and the position just before \\end.")
+
+(defun LaTeX-insert-environment (environment &optional extra)
+ "Insert LaTeX ENVIRONMENT with optional argument EXTRA."
+ (let ((active-mark (and (TeX-active-mark) (not (eq (mark) (point)))))
+ prefix content-start env-start env-end)
+ (when (and active-mark (< (mark) (point))) (exchange-point-and-mark))
+ ;; Compute the prefix.
+ (when (and LaTeX-insert-into-comments (TeX-in-commented-line))
+ (save-excursion
+ (beginning-of-line)
+ (looking-at
+ (concat "^\\([ \t]*" TeX-comment-start-regexp "+\\)+[ \t]*"))
+ (setq prefix (match-string 0))))
+ ;; What to do with the line containing point.
+ (cond ((save-excursion (beginning-of-line)
+ (looking-at (concat prefix "[ \t]*$")))
+ (delete-region (match-beginning 0) (match-end 0)))
+ ((TeX-looking-at-backward (concat "^" prefix "[ \t]*")
+ (line-beginning-position))
+ (beginning-of-line)
+ (newline)
+ (beginning-of-line 0))
+ ((bolp)
+ (delete-horizontal-space)
+ (newline)
+ (beginning-of-line 0))
+ (t
+ (delete-horizontal-space)
+ (newline 2)
+ (when prefix (insert prefix))
+ (beginning-of-line 0)))
+ ;; What to do with the line containing mark.
+ (when active-mark
+ (save-excursion
+ (goto-char (mark))
+ (cond ((save-excursion (beginning-of-line)
+ (or (looking-at (concat prefix "[ \t]*$"))
+ (looking-at "[ \t]*$")))
+ (delete-region (match-beginning 0) (match-end 0)))
+ ((TeX-looking-at-backward (concat "^" prefix "[ \t]*")
+ (line-beginning-position))
+ (beginning-of-line)
+ (newline)
+ (beginning-of-line 0))
+ (t
+ (delete-horizontal-space)
+ (insert-before-markers "\n")
+ (newline)
+ (when prefix (insert prefix))))))
+ ;; Now insert the environment.
+ (when prefix (insert prefix))
+ (setq env-start (point))
+ (insert TeX-esc "begin" TeX-grop environment TeX-grcl)
+ (indent-according-to-mode)
+ (when extra (insert extra))
+ (setq content-start (line-beginning-position 2))
+ (unless active-mark
+ (newline)
+ (when prefix (insert prefix))
+ (newline))
+ (when active-mark (goto-char (mark)))
+ (when prefix (insert prefix))
+ (setq env-end (point))
+ (insert TeX-esc "end" TeX-grop environment TeX-grcl)
+ (end-of-line 0)
+ (if active-mark
+ (progn
+ (or (assoc environment LaTeX-indent-environment-list)
+ (LaTeX-fill-region content-start (line-beginning-position 2)))
+ (set-mark content-start))
+ (indent-according-to-mode))
+ (save-excursion (beginning-of-line 2) (indent-according-to-mode))
+ (TeX-math-input-method-off)
+ (run-hook-with-args 'LaTeX-after-insert-env-hooks
+ environment env-start env-end)))
+
+(defun LaTeX-modify-environment (environment)
+ "Modify current ENVIRONMENT."
+ (save-excursion
+ (LaTeX-find-matching-end)
+ (re-search-backward (concat (regexp-quote TeX-esc)
+ "end"
+ (regexp-quote TeX-grop)
+ " *\\([a-zA-Z*]*\\)"
+ (regexp-quote TeX-grcl))
+ (save-excursion (beginning-of-line 1) (point)))
+ (replace-match (concat TeX-esc "end" TeX-grop environment TeX-grcl) t t)
+ (beginning-of-line 1)
+ (LaTeX-find-matching-begin)
+ (re-search-forward (concat (regexp-quote TeX-esc)
+ "begin"
+ (regexp-quote TeX-grop)
+ " *\\([a-zA-Z*]*\\)"
+ (regexp-quote TeX-grcl))
+ (save-excursion (end-of-line 1) (point)))
+ (replace-match (concat TeX-esc "begin" TeX-grop environment TeX-grcl) t t)))
+
+(defun LaTeX-current-environment (&optional arg)
+ "Return the name (a string) of the enclosing LaTeX environment.
+With optional ARG>=1, find that outer level.
+
+If function is called inside a comment and
+`LaTeX-syntactic-comments' is enabled, try to find the
+environment in commented regions with the same comment prefix.
+
+The functions `LaTeX-find-matching-begin' and `LaTeX-find-matching-end'
+work analogously."
+ (setq arg (if arg (if (< arg 1) 1 arg) 1))
+ (let* ((in-comment (TeX-in-commented-line))
+ (comment-prefix (and in-comment (TeX-comment-prefix))))
+ (save-excursion
+ (while (and (/= arg 0)
+ (re-search-backward
+ "\\\\\\(begin\\|end\\) *{ *\\([A-Za-z*]+\\) *}" nil t))
+ (when (or (and LaTeX-syntactic-comments
+ (eq in-comment (TeX-in-commented-line))
+ (or (not in-comment)
+ ;; Consider only matching prefixes in the
+ ;; commented case.
+ (string= comment-prefix (TeX-comment-prefix))))
+ (and (not LaTeX-syntactic-comments)
+ (not (TeX-in-commented-line))))
+ (setq arg (if (string= (match-string 1) "end") (1+ arg) (1- arg)))))
+ (if (/= arg 0)
+ "document"
+ (match-string-no-properties 2)))))
+
+(defun docTeX-in-macrocode-p ()
+ "Determine if point is inside a macrocode environment."
+ (save-excursion
+ (re-search-backward
+ (concat "^% " (regexp-quote TeX-esc)
+ "\\(begin\\|end\\)[ \t]*{macrocode\\*?}") nil 'move)
+ (not (or (bobp)
+ (= (char-after (match-beginning 1)) ?e)))))
+
+
+;;; Environment Hooks
+
+(defvar LaTeX-document-style-hook nil
+ "List of hooks to run when inserting a document environment.
+
+To insert a hook here, you must insert it in the appropiate style file.")
+
+(defun LaTeX-env-document (&optional ignore)
+ "Create new LaTeX document.
+The compatibility argument IGNORE is ignored."
+ (TeX-insert-macro "documentclass")
+ (LaTeX-newline)
+ (LaTeX-newline)
+ (LaTeX-newline)
+ (end-of-line 0)
+ (LaTeX-insert-environment "document")
+ (run-hooks 'LaTeX-document-style-hook)
+ (setq LaTeX-document-style-hook nil))
+
+(defcustom LaTeX-float ""
+ "Default float position for figures and tables.
+If nil, act like the empty string is given, but do not prompt.
+\(The standard LaTeX classes use [tbp] as float position if the
+optional argument is omitted.)"
+ :group 'LaTeX-environment
+ :type '(choice (const :tag "Do not prompt" nil)
+ (const :tag "Empty" "")
+ (string :format "%v")))
+(make-variable-buffer-local 'LaTeX-float)
+
+(defcustom LaTeX-top-caption-list nil
+ "*List of float environments with top caption."
+ :group 'LaTeX-environment
+ :type '(repeat (string :format "%v")))
+
+(defgroup LaTeX-label nil
+ "Adding labels for LaTeX commands in AUCTeX."
+ :group 'LaTeX)
+
+(defcustom LaTeX-label-function nil
+ "*A function inserting a label at point.
+Sole argument of the function is the environment. The function has to return
+the label inserted, or nil if no label was inserted."
+ :group 'LaTeX-label
+ :type 'function)
+
+(defcustom LaTeX-figure-label "fig:"
+ "*Default prefix to figure labels."
+ :group 'LaTeX-label
+ :group 'LaTeX-environment
+ :type 'string)
+
+(defcustom LaTeX-table-label "tab:"
+ "*Default prefix to table labels."
+ :group 'LaTeX-label
+ :group 'LaTeX-environment
+ :type 'string)
+
+(defcustom LaTeX-default-format ""
+ "Default format for array and tabular environments."
+ :group 'LaTeX-environment
+ :type 'string)
+(make-variable-buffer-local 'LaTeX-default-format)
+
+(defcustom LaTeX-default-width "1.0\\linewidth"
+ "Default width for minipage and tabular* environments."
+ :group 'LaTeX-environment
+ :type 'string)
+(make-variable-buffer-local 'LaTeX-default-width)
+
+(defcustom LaTeX-default-position ""
+ "Default position for array and tabular environments.
+If nil, act like the empty string is given, but do not prompt."
+ :group 'LaTeX-environment
+ :type '(choice (const :tag "Do not prompt" nil)
+ (const :tag "Empty" "")
+ string))
+(make-variable-buffer-local 'LaTeX-default-position)
+
+(defcustom LaTeX-equation-label "eq:"
+ "*Default prefix to equation labels."
+ :group 'LaTeX-label
+ :type 'string)
+
+(defcustom LaTeX-eqnarray-label LaTeX-equation-label
+ "*Default prefix to eqnarray labels."
+ :group 'LaTeX-label
+ :type 'string)
+
+(defun LaTeX-env-item (environment)
+ "Insert ENVIRONMENT and the first item."
+ (LaTeX-insert-environment environment)
+ (if (TeX-active-mark)
+ (progn
+ (LaTeX-find-matching-begin)
+ (end-of-line 1))
+ (end-of-line 0))
+ (delete-char 1)
+ (when (looking-at (concat "^[ \t]+$\\|"
+ "^[ \t]*" TeX-comment-start-regexp "+[ \t]*$"))
+ (delete-region (point) (line-end-position)))
+ (delete-horizontal-space)
+ ;; Deactivate the mark here in order to prevent `TeX-parse-macro'
+ ;; from swapping point and mark and the \item ending up right after
+ ;; \begin{...}.
+ (TeX-deactivate-mark)
+ (LaTeX-insert-item)
+ ;; The inserted \item may have outdented the first line to the
+ ;; right. Fill it, if appropriate.
+ (when (and (not (looking-at "$"))
+ (not (assoc environment LaTeX-indent-environment-list))
+ (> (- (line-end-position) (line-beginning-position))
+ (current-fill-column)))
+ (LaTeX-fill-paragraph nil)))
+
+(defcustom LaTeX-label-alist
+ '(("figure" . LaTeX-figure-label)
+ ("table" . LaTeX-table-label)
+ ("figure*" . LaTeX-figure-label)
+ ("table*" . LaTeX-table-label)
+ ("equation" . LaTeX-equation-label)
+ ("eqnarray" . LaTeX-eqnarray-label))
+ "Lookup prefixes for labels.
+An alist where the CAR is the environment name, and the CDR
+either the prefix or a symbol referring to one."
+ :group 'LaTeX-label
+ :type '(repeat (cons (string :tag "Environment")
+ (choice (string :tag "Label prefix")
+ (symbol :tag "Label prefix symbol")))))
+
+(make-variable-buffer-local 'LaTeX-label-alist)
+
+(defun LaTeX-label (environment)
+ "Insert a label for ENVIRONMENT at point.
+If `LaTeX-label-function' is a valid function, LaTeX label will transfer the
+job to this function."
+ (let (label)
+ (if (and (boundp 'LaTeX-label-function)
+ LaTeX-label-function
+ (fboundp LaTeX-label-function))
+
+ (setq label (funcall LaTeX-label-function environment))
+ (let ((prefix
+ (or (cdr (assoc environment LaTeX-label-alist))
+ (if (assoc environment LaTeX-section-list)
+ (if (stringp LaTeX-section-label)
+ LaTeX-section-label
+ (and (listp LaTeX-section-label)
+ (cdr (assoc environment LaTeX-section-label))))
+ ""))))
+ (when prefix
+ (when (symbolp prefix)
+ (setq prefix (symbol-value prefix)))
+ ;; Use completing-read as we do with `C-c C-m \label RET'
+ (setq label (completing-read
+ (TeX-argument-prompt t nil "What label")
+ (LaTeX-label-list) nil nil prefix))
+ ;; No label or empty string entered?
+ (if (or (string= prefix label)
+ (string= "" label))
+ (setq label nil)
+ (insert TeX-esc "label" TeX-grop label TeX-grcl))))
+ (if label
+ (progn
+ (LaTeX-add-labels label)
+ label)
+ nil))))
+
+(defun LaTeX-env-figure (environment)
+ "Create ENVIRONMENT with \\caption and \\label commands."
+ (let ((float (and LaTeX-float ; LaTeX-float can be nil, i.e.
+ ; do not prompt
+ (read-string "(Optional) Float position: " LaTeX-float)))
+ (caption (read-string "Caption: "))
+ (center (y-or-n-p "Center? "))
+ (active-mark (and (TeX-active-mark)
+ (not (eq (mark) (point)))))
+ start-marker end-marker)
+ (when active-mark
+ (if (< (mark) (point))
+ (exchange-point-and-mark))
+ (setq start-marker (point-marker))
+ (set-marker-insertion-type start-marker t)
+ (setq end-marker (copy-marker (mark))))
+ (setq LaTeX-float float)
+ (LaTeX-insert-environment environment
+ (unless (zerop (length float))
+ (concat LaTeX-optop float
+ LaTeX-optcl)))
+ (when active-mark (goto-char start-marker))
+ (when center
+ (insert TeX-esc "centering")
+ (indent-according-to-mode)
+ (LaTeX-newline))
+ (if (member environment LaTeX-top-caption-list)
+ ;; top caption -- do nothing if user skips caption
+ (unless (zerop (length caption))
+ (insert TeX-esc "caption" TeX-grop caption TeX-grcl)
+ (LaTeX-newline)
+ (indent-according-to-mode)
+ ;; ask for a label and insert a new line only if a label is
+ ;; actually inserted
+ (when (LaTeX-label environment)
+ (LaTeX-newline)
+ (indent-according-to-mode)))
+ ;; bottom caption (default) -- do nothing if user skips caption
+ (unless (zerop (length caption))
+ (when active-mark (goto-char end-marker))
+ (LaTeX-newline)
+ (indent-according-to-mode)
+ (insert TeX-esc "caption" TeX-grop caption TeX-grcl)
+ (LaTeX-newline)
+ (indent-according-to-mode)
+ ;; ask for a label -- if user skips label, remove the last new
+ ;; line again
+ (if (LaTeX-label environment)
+ (progn
+ (unless (looking-at "[ \t]*$")
+ (LaTeX-newline)
+ (end-of-line 0)))
+ (delete-blank-lines)
+ (end-of-line 0))
+ ;; if there is a caption or a label, move point upwards again
+ ;; so that it is placed above the caption or the label (or
+ ;; both) -- search the current line (even long captions are
+ ;; inserted on a single line, even if auto-fill is turned on,
+ ;; so it is enough to search the current line) for \label or
+ ;; \caption and go one line upwards if any of them is found
+ (while (re-search-backward
+ (concat "^\\s-*" (regexp-quote TeX-esc)
+ "\\(label\\|caption\\)")
+ (line-beginning-position) t)
+ (end-of-line 0)
+ (indent-according-to-mode))))
+ (when (and (member environment '("table" "table*"))
+ ;; Suppose an existing tabular environment should just
+ ;; be wrapped into a table if there is an active region.
+ (not active-mark))
+ (LaTeX-env-array "tabular"))))
+
+(defun LaTeX-env-array (environment)
+ "Insert ENVIRONMENT with position and column specifications.
+Just like array and tabular."
+ (let ((pos (and LaTeX-default-position ; LaTeX-default-position can
+ ; be nil, i.e. do not prompt
+ (read-string "(Optional) Position: " LaTeX-default-position)))
+ (fmt (read-string "Format: " LaTeX-default-format)))
+ (setq LaTeX-default-position pos)
+ (setq LaTeX-default-format fmt)
+ (LaTeX-insert-environment environment
+ (concat
+ (unless (zerop (length pos))
+ (concat LaTeX-optop pos LaTeX-optcl))
+ (concat TeX-grop fmt TeX-grcl)))))
+
+(defun LaTeX-env-label (environment)
+ "Insert ENVIRONMENT and prompt for label."
+ (LaTeX-insert-environment environment)
+ (when (LaTeX-label environment)
+ (LaTeX-newline)
+ (indent-according-to-mode)))
+
+(defun LaTeX-env-list (environment)
+ "Insert ENVIRONMENT and the first item."
+ (let ((label (read-string "Default Label: ")))
+ (LaTeX-insert-environment environment
+ (format "{%s}{}" label))
+ (end-of-line 0)
+ (delete-char 1)
+ (delete-horizontal-space))
+ (LaTeX-insert-item))
+
+(defun LaTeX-env-minipage (environment)
+ "Create new LaTeX minipage or minipage-like ENVIRONMENT."
+ (let ((pos (and LaTeX-default-position ; LaTeX-default-position can
+ ; be nil, i.e. do not prompt
+ (read-string "(Optional) Position: " LaTeX-default-position)))
+ (width (read-string "Width: " LaTeX-default-width)))
+ (setq LaTeX-default-position pos)
+ (setq LaTeX-default-width width)
+ (LaTeX-insert-environment environment
+ (concat
+ (unless (zerop (length pos))
+ (concat LaTeX-optop pos LaTeX-optcl))
+ (concat TeX-grop width TeX-grcl)))))
+
+(defun LaTeX-env-tabular* (environment)
+ "Insert ENVIRONMENT with width, position and column specifications."
+ (let ((width (read-string "Width: " LaTeX-default-width))
+ (pos (and LaTeX-default-position ; LaTeX-default-position can
+ ; be nil, i.e. do not prompt
+ (read-string "(Optional) Position: " LaTeX-default-position)))
+ (fmt (read-string "Format: " LaTeX-default-format)))
+ (setq LaTeX-default-width width)
+ (setq LaTeX-default-position pos)
+ (setq LaTeX-default-format fmt)
+ (LaTeX-insert-environment environment
+ (concat
+ (concat TeX-grop width TeX-grcl) ;; not optional!
+ (unless (zerop (length pos))
+ (concat LaTeX-optop pos LaTeX-optcl))
+ (concat TeX-grop fmt TeX-grcl)))))
+
+(defun LaTeX-env-picture (environment)
+ "Insert ENVIRONMENT with width, height specifications."
+ (let ((width (read-string "Width: "))
+ (height (read-string "Height: "))
+ (x-offset (read-string "X Offset: "))
+ (y-offset (read-string "Y Offset: ")))
+ (if (zerop (length x-offset))
+ (setq x-offset "0"))
+ (if (zerop (length y-offset))
+ (setq y-offset "0"))
+ (LaTeX-insert-environment environment
+ (concat
+ (format "(%s,%s)" width height)
+ (if (not (and (string= x-offset "0")
+ (string= y-offset "0")))
+ (format "(%s,%s)" x-offset y-offset))))))
+
+(defun LaTeX-env-bib (environment)
+ "Insert ENVIRONMENT with label for bibitem."
+ (LaTeX-insert-environment environment
+ (concat TeX-grop
+ (read-string "Label for BibItem: " "99")
+ TeX-grcl))
+ (end-of-line 0)
+ (delete-char 1)
+ (delete-horizontal-space)
+ (LaTeX-insert-item))
+
+(defun LaTeX-env-contents (environment)
+ "Insert ENVIRONMENT with filename for contents."
+ (save-excursion
+ (when (re-search-backward "^\\\\documentclass.*{" nil t)
+ (error "Put %s environment before \\documentclass" environment)))
+ (LaTeX-insert-environment environment
+ (concat TeX-grop
+ (read-string "File: ")
+ TeX-grcl))
+ (delete-horizontal-space))
+
+(defun LaTeX-env-args (environment &rest args)
+ "Insert ENVIRONMENT and arguments defined by ARGS."
+ (LaTeX-insert-environment environment)
+ (let ((pos (point-marker)))
+ (end-of-line 0)
+ (TeX-parse-arguments args)
+ (goto-char pos)))
+
+;;; Item hooks
+
+(defvar LaTeX-item-list nil
+ "A list of environments where items have a special syntax.
+The cdr is the name of the function, used to insert this kind of items.")
+
+(defun LaTeX-insert-item ()
+ "Insert a new item in an environment.
+You may use `LaTeX-item-list' to change the routines used to insert the item."
+ (interactive "*")
+ (let ((environment (LaTeX-current-environment)))
+ (when (and (TeX-active-mark)
+ (> (point) (mark)))
+ (exchange-point-and-mark))
+ (unless (bolp) (LaTeX-newline))
+ (if (assoc environment LaTeX-item-list)
+ (funcall (cdr (assoc environment LaTeX-item-list)))
+ (TeX-insert-macro "item"))
+ (indent-according-to-mode)))
+
+(defun LaTeX-item-argument ()
+ "Insert a new item with an optional argument."
+ (let ((TeX-arg-item-label-p t))
+ (TeX-insert-macro "item")))
+
+(defun LaTeX-item-bib ()
+ "Insert a new bibitem."
+ (TeX-insert-macro "bibitem"))
+
+;;; Parser
+
+(defvar LaTeX-auto-minimal-regexp-list
+ '(("\\\\document\\(style\\|class\\)\
+\\(\\[\\(\\([^#\\%]\\|%[^\n\r]*[\n\r]\\)*\\)\\]\\)?\
+{\\([^#\\.\n\r]+?\\)}"
+ (3 5 1) LaTeX-auto-style)
+ ("\\\\use\\(package\\)\\(\\[\\([^\]\\]*\\)\\]\\)?\
+{\\(\\([^#}\\.%]\\|%[^\n\r]*[\n\r]\\)+?\\)}"
+ (3 4 1) LaTeX-auto-style))
+ "Minimal list of regular expressions matching LaTeX macro definitions.")
+
+(defvar LaTeX-auto-label-regexp-list
+ '(("\\\\label{\\([^\n\r%\\{}]+\\)}" 1 LaTeX-auto-label))
+ "List of regular expression matching LaTeX labels only.")
+
+(defvar LaTeX-auto-index-regexp-list
+ '(("\\\\\\(index\\|glossary\\){\\([^}{]*\\({[^}{]*\\({[^}{]*\\({[^}{]*}[^}{]*\\)*}[^}{]*\\)*}[^}{]*\\)*\\)}"
+ 2 LaTeX-auto-index-entry))
+ "List of regular expression matching LaTeX index/glossary entries only.
+Regexp allows for up to 3 levels of parenthesis inside the index argument.
+This is necessary since index entries may contain commands and stuff.")
+
+(defvar LaTeX-auto-class-regexp-list
+ '(;; \RequirePackage[<options>]{<package>}[<date>]
+ ("\\\\Require\\(Package\\)\\(\\[\\([^#\\.%]*?\\)\\]\\)?\
+{\\([^#\\.\n\r]+?\\)}"
+ (3 4 1) LaTeX-auto-style)
+ ;; \RequirePackageWithOptions{<package>}[<date>],
+ ("\\\\Require\\(Package\\)WithOptions\\(\\){\\([^#\\.\n\r]+?\\)}"
+ (2 3 1) LaTeX-auto-style)
+ ;; \LoadClass[<options>]{<package>}[<date>]
+ ("\\\\Load\\(Class\\)\\(\\[\\([^#\\.%]*?\\)\\]\\)?{\\([^#\\.\n\r]+?\\)}"
+ (3 4 1) LaTeX-auto-style)
+ ;; \LoadClassWithOptions{<package>}[<date>]
+ ("\\\\Load\\(Class\\)WithOptions\\(\\){\\([^#\\.\n\r]+?\\)}"
+ (2 3 1) LaTeX-auto-style)
+ ;; \DeclareRobustCommand{<cmd>}[<num>][<default>]{<definition>},
+ ;; \DeclareRobustCommand*{<cmd>}[<num>][<default>]{<definition>}
+ ("\\\\DeclareRobustCommand\\*?{?\\\\\\([A-Za-z]+\\)}?\
+\\[\\([0-9]+\\)\\]\\[\\([^\n\r]*?\\)\\]"
+ (1 2 3) LaTeX-auto-optional)
+ ("\\\\DeclareRobustCommand\\*?{?\\\\\\([A-Za-z]+\\)}?\\[\\([0-9]+\\)\\]"
+ (1 2) LaTeX-auto-arguments)
+ ("\\\\DeclareRobustCommand\\*?{?\\\\\\([A-Za-z]+\\)}?"
+ 1 TeX-auto-symbol)
+ ;; Patterns for commands described in "LaTeX2e font selection" (fntguide)
+ ("\\\\DeclareMath\\(?:Symbol\\|Delimiter\\|Accent\\|Radical\\)\
+{?\\\\\\([A-Za-z]+\\)}?"
+ 1 TeX-auto-symbol)
+ ("\\\\\\(Declare\\|Provide\\)Text\
+\\(?:Command\\|Symbol\\|Accent\\|Composite\\){?\\\\\\([A-Za-z]+\\)}?"
+ 1 TeX-auto-symbol)
+ ("\\\\Declare\\(?:Text\\|Old\\)FontCommand{?\\\\\\([A-Za-z]+\\)}?"
+ 1 TeX-auto-symbol))
+ "List of regular expressions matching macros in LaTeX classes and packages.")
+
+(defvar LaTeX-auto-regexp-list
+ (append
+ (let ((token TeX-token-char))
+ `((,(concat "\\\\\\(?:new\\|provide\\)command\\*?{?\\\\\\(" token "+\\)}?\\[\\([0-9]+\\)\\]\\[\\([^\n\r]*\\)\\]")
+ (1 2 3) LaTeX-auto-optional)
+ (,(concat "\\\\\\(?:new\\|provide\\)command\\*?{?\\\\\\(" token "+\\)}?\\[\\([0-9]+\\)\\]")
+ (1 2) LaTeX-auto-arguments)
+ (,(concat "\\\\\\(?:new\\|provide\\)command\\*?{?\\\\\\(" token "+\\)}?") 1 TeX-auto-symbol)
+ (,(concat "\\\\newenvironment\\*?{?\\(" token "+\\)}?\\[\\([0-9]+\\)\\]\\[")
+ 1 LaTeX-auto-environment)
+ (,(concat "\\\\newenvironment\\*?{?\\(" token "+\\)}?\\[\\([0-9]+\\)\\]")
+ (1 2) LaTeX-auto-env-args)
+ (,(concat "\\\\newenvironment\\*?{?\\(" token "+\\)}?") 1 LaTeX-auto-environment)
+ (,(concat "\\\\newtheorem{\\(" token "+\\)}") 1 LaTeX-auto-environment)
+ ("\\\\input{\\(\\.*[^#}%\\\\\\.\n\r]+\\)\\(\\.[^#}%\\\\\\.\n\r]+\\)?}"
+ 1 TeX-auto-file)
+ ("\\\\include{\\(\\.*[^#}%\\\\\\.\n\r]+\\)\\(\\.[^#}%\\\\\\.\n\r]+\\)?}"
+ 1 TeX-auto-file)
+ (, (concat "\\\\bibitem{\\(" token "[^, \n\r\t%\"#'()={}]*\\)}") 1 LaTeX-auto-bibitem)
+ (, (concat "\\\\bibitem\\[[^][\n\r]+\\]{\\(" token "[^, \n\r\t%\"#'()={}]*\\)}")
+ 1 LaTeX-auto-bibitem)
+ ("\\\\bibliography{\\([^#}\\\\\n\r]+\\)}" 1 LaTeX-auto-bibliography)))
+ LaTeX-auto-class-regexp-list
+ LaTeX-auto-label-regexp-list
+ LaTeX-auto-index-regexp-list
+ LaTeX-auto-minimal-regexp-list)
+ "List of regular expression matching common LaTeX macro definitions.")
+
+(defun LaTeX-auto-prepare ()
+ "Prepare for LaTeX parsing."
+ (setq LaTeX-auto-arguments nil
+ LaTeX-auto-optional nil
+ LaTeX-auto-env-args nil
+ LaTeX-auto-style nil
+ LaTeX-auto-end-symbol nil))
+
+(add-hook 'TeX-auto-prepare-hook 'LaTeX-auto-prepare)
+
+(defun LaTeX-listify-package-options (options)
+ "Return a list from a comma-separated string of package OPTIONS.
+The input string may include LaTeX comments and newlines."
+ ;; FIXME: Parse key=value options like "pdftitle={A Perfect
+ ;; Day},colorlinks=false" correctly. When this works, the check for
+ ;; "=" can be removed again.
+ (let (opts)
+ (dolist (elt (TeX-split-string "\\(,\\|%[^\n\r]*[\n\r]\\)+"
+ options))
+ (unless (string-match "=" elt)
+ ;; Strip whitespace.
+ (dolist (item (TeX-split-string "[ \t\r\n]+" elt))
+ (unless (string= item "")
+ (add-to-list 'opts item)))))
+ opts))
+
+(defun LaTeX-auto-cleanup ()
+ "Cleanup after LaTeX parsing."
+
+ ;; Cleanup BibTeX files
+ (setq LaTeX-auto-bibliography
+ (apply 'append (mapcar (lambda (arg)
+ (TeX-split-string "," arg))
+ LaTeX-auto-bibliography)))
+
+ ;; Cleanup document classes and packages
+ (unless (null LaTeX-auto-style)
+ (while LaTeX-auto-style
+ (let* ((entry (car LaTeX-auto-style))
+ (options (nth 0 entry))
+ (style (nth 1 entry))
+ (class (nth 2 entry)))
+
+ ;; Next document style.
+ (setq LaTeX-auto-style (cdr LaTeX-auto-style))
+
+ ;; Get the options.
+ (setq options (LaTeX-listify-package-options options))
+
+ ;; Add them, to the style list.
+ (dolist (elt options)
+ (add-to-list 'TeX-auto-file elt))
+
+ ;; Treat documentclass/documentstyle specially.
+ (if (or (string-equal "package" class)
+ (string-equal "Package" class))
+ (dolist (elt (TeX-split-string
+ "\\([ \t\r\n]\\|%[^\n\r]*[\n\r]\\|,\\)+" style))
+ (add-to-list 'TeX-auto-file elt))
+ ;; And a special "art10" style file combining style and size.
+ (add-to-list 'TeX-auto-file style)
+ (add-to-list 'TeX-auto-file
+ (concat
+ (cond ((string-equal "article" style)
+ "art")
+ ((string-equal "book" style)
+ "bk")
+ ((string-equal "report" style)
+ "rep")
+ ((string-equal "jarticle" style)
+ "jart")
+ ((string-equal "jbook" style)
+ "jbk")
+ ((string-equal "jreport" style)
+ "jrep")
+ ((string-equal "j-article" style)
+ "j-art")
+ ((string-equal "j-book" style)
+ "j-bk")
+ ((string-equal "j-report" style )
+ "j-rep")
+ (t style))
+ (cond ((member "11pt" options)
+ "11")
+ ((member "12pt" options)
+ "12")
+ (t
+ "10")))))
+
+ ;; The third argument if "class" indicates LaTeX2e features.
+ (cond ((equal class "class")
+ (add-to-list 'TeX-auto-file "latex2e"))
+ ((equal class "style")
+ (add-to-list 'TeX-auto-file "latex2"))))))
+
+ ;; Cleanup optional arguments
+ (mapc (lambda (entry)
+ (add-to-list 'TeX-auto-symbol
+ (list (nth 0 entry)
+ (string-to-number (nth 1 entry)))))
+ LaTeX-auto-arguments)
+
+ ;; Cleanup default optional arguments
+ (mapc (lambda (entry)
+ (add-to-list 'TeX-auto-symbol
+ (list (nth 0 entry)
+ (vector "argument")
+ (1- (string-to-number (nth 1 entry))))))
+ LaTeX-auto-optional)
+
+ ;; Cleanup environments arguments
+ (mapc (lambda (entry)
+ (add-to-list 'LaTeX-auto-environment
+ (list (nth 0 entry)
+ (string-to-number (nth 1 entry)))))
+ LaTeX-auto-env-args)
+
+ ;; Cleanup use of def to add environments
+ ;; NOTE: This uses an O(N^2) algorithm, while an O(N log N)
+ ;; algorithm is possible.
+ (mapc (lambda (symbol)
+ (if (not (TeX-member symbol TeX-auto-symbol 'equal))
+ ;; No matching symbol, insert in list
+ (add-to-list 'TeX-auto-symbol (concat "end" symbol))
+ ;; Matching symbol found, remove from list
+ (if (equal (car TeX-auto-symbol) symbol)
+ ;; Is it the first symbol?
+ (setq TeX-auto-symbol (cdr TeX-auto-symbol))
+ ;; Nope! Travel the list
+ (let ((list TeX-auto-symbol))
+ (while (consp (cdr list))
+ ;; Until we find it.
+ (if (equal (car (cdr list)) symbol)
+ ;; Then remove it.
+ (setcdr list (cdr (cdr list))))
+ (setq list (cdr list)))))
+ ;; and add the symbol as an environment.
+ (add-to-list 'LaTeX-auto-environment symbol)))
+ LaTeX-auto-end-symbol))
+
+(add-hook 'TeX-auto-cleanup-hook 'LaTeX-auto-cleanup)
+
+(TeX-auto-add-type "label" "LaTeX")
+(TeX-auto-add-type "bibitem" "LaTeX")
+(TeX-auto-add-type "environment" "LaTeX")
+(TeX-auto-add-type "bibliography" "LaTeX" "bibliographies")
+(TeX-auto-add-type "index-entry" "LaTeX" "index-entries")
+
+(fset 'LaTeX-add-bibliographies-auto
+ (symbol-function 'LaTeX-add-bibliographies))
+(defun LaTeX-add-bibliographies (&rest bibliographies)
+ "Add BIBLIOGRAPHIES to the list of known bibliographies and style files."
+ (apply 'LaTeX-add-bibliographies-auto bibliographies)
+ (apply 'TeX-run-style-hooks bibliographies))
+
+(fset 'LaTeX-add-environments-auto
+ (symbol-function 'LaTeX-add-environments))
+(defun LaTeX-add-environments (&rest environments)
+ "Add ENVIRONMENTS to the list of known environments.
+Additionally invalidate the environment submenus to let them be
+regenerated by the respective menu filter."
+ (apply 'LaTeX-add-environments-auto environments)
+ (setq LaTeX-environment-menu nil)
+ (setq LaTeX-environment-modify-menu nil))
+
+;;; BibTeX
+
+;;;###autoload
+(defun BibTeX-auto-store ()
+ "This function should be called from `bibtex-mode-hook'.
+It will setup BibTeX to store keys in an auto file."
+ ;; We want this to be early in the list, so we do not
+ ;; add it before we enter BibTeX mode the first time.
+ (if (boundp 'local-write-file-hooks)
+ (add-hook 'local-write-file-hooks 'TeX-safe-auto-write)
+ (add-hook 'write-file-hooks 'TeX-safe-auto-write))
+ (make-local-variable 'TeX-auto-update)
+ (setq TeX-auto-update 'BibTeX)
+ (make-local-variable 'TeX-auto-untabify)
+ (setq TeX-auto-untabify nil)
+ (make-local-variable 'TeX-auto-parse-length)
+ (setq TeX-auto-parse-length 999999)
+ (make-local-variable 'TeX-auto-regexp-list)
+ (setq TeX-auto-regexp-list BibTeX-auto-regexp-list)
+ (make-local-variable 'TeX-master)
+ (setq TeX-master t))
+
+(defvar BibTeX-auto-regexp-list
+ `(("@[Ss][Tt][Rr][Ii][Nn][Gg]" 1 ignore)
+ (,(concat "@[a-zA-Z]+[{(][ \t]*\\(" TeX-token-char "[^, \n\r\t%\"#'()={}]*\\)")
+ 1 LaTeX-auto-bibitem))
+ "List of regexp-list expressions matching BibTeX items.")
+
+;;; Macro Argument Hooks
+
+(defun TeX-arg-conditional (optional expr then else)
+ "Implement if EXPR THEN ELSE.
+
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one.
+
+If EXPR evaluate to true, parse THEN as an argument list, else parse
+ELSE as an argument list."
+ (TeX-parse-arguments (if (eval expr) then else)))
+
+(defun TeX-arg-eval (optional &rest args)
+ "Evaluate ARGS and insert value in buffer.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one."
+ (TeX-argument-insert (eval args) optional))
+
+(defun TeX-arg-label (optional &optional prompt definition)
+ "Prompt for a label completing with known labels.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. Use PROMPT as the prompt
+string. If DEFINITION is non-nil, add the chosen label to the
+list of defined labels."
+ (let ((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 optional)))
+
+(defalias 'TeX-arg-ref 'TeX-arg-label)
+
+(defun TeX-arg-index-tag (optional &optional prompt &rest args)
+ "Prompt for an index tag.
+This is the name of an index, not the entry.
+
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. Use PROMPT as the prompt
+string. ARGS is unused."
+ (let (tag)
+ (setq prompt (concat (if optional "(Optional) " "")
+ (if prompt prompt "Index tag")
+ ": (default none) "))
+ (setq tag (read-string prompt))
+ (TeX-argument-insert tag optional)))
+
+(defun TeX-arg-index (optional &optional prompt &rest args)
+ "Prompt for an index entry completing with known entries.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. Use PROMPT as the prompt
+string. ARGS is unused."
+ (let ((entry (completing-read (TeX-argument-prompt optional prompt "Key")
+ (LaTeX-index-entry-list))))
+ (if (and (not (string-equal "" entry))
+ (not (member (list entry) (LaTeX-index-entry-list))))
+ (LaTeX-add-index-entries entry))
+ (TeX-argument-insert entry optional optional)))
+
+(defalias 'TeX-arg-define-index 'TeX-arg-index)
+
+(defun TeX-arg-macro (optional &optional prompt definition)
+ "Prompt for a TeX macro with completion.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. Use PROMPT as the prompt
+string. If DEFINITION is non-nil, add the chosen macro to the
+list of defined macros."
+ (let ((macro (completing-read (TeX-argument-prompt optional prompt
+ (concat "Macro: "
+ TeX-esc)
+ t)
+ (TeX-symbol-list))))
+ (if (and definition (not (string-equal "" macro)))
+ (TeX-add-symbols macro))
+ (TeX-argument-insert macro optional TeX-esc)))
+
+(defun TeX-arg-environment (optional &optional prompt definition)
+ "Prompt for a LaTeX environment with completion.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. Use PROMPT as the prompt
+string. If DEFINITION is non-nil, add the chosen environment to
+the list of defined environments."
+ (let ((environment (completing-read (TeX-argument-prompt optional prompt
+ "Environment")
+ (TeX-symbol-list))))
+ (if (and definition (not (string-equal "" environment)))
+ (LaTeX-add-environments environment))
+
+ (TeX-argument-insert environment optional)))
+
+;; Why is DEFINITION unused?
+(defun TeX-arg-cite (optional &optional prompt definition)
+ "Prompt for a BibTeX citation with completion.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. Use PROMPT as the prompt
+string. DEFINITION is unused."
+ (setq prompt (concat (if optional "(Optional) " "")
+ (if prompt prompt "Add key")
+ ": (default none) "))
+ (let ((items (multi-prompt "," t prompt (LaTeX-bibitem-list))))
+ (apply 'LaTeX-add-bibitems items)
+ (TeX-argument-insert (mapconcat 'identity items ",") optional optional)))
+
+;; Why is DEFINITION unused?
+(defun TeX-arg-counter (optional &optional prompt definition)
+ "Prompt for a LaTeX counter.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. Use PROMPT as the prompt
+string. DEFINITION is unused."
+ ;; Completion not implemented yet.
+ (TeX-argument-insert
+ (read-string (TeX-argument-prompt optional prompt "Counter"))
+ optional))
+
+;; Why is DEFINITION unused?
+(defun TeX-arg-savebox (optional &optional prompt definition)
+ "Prompt for a LaTeX savebox.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. Use PROMPT as the prompt
+string. DEFINITION is unused."
+ ;; Completion not implemented yet.
+ (TeX-argument-insert
+ (read-string (TeX-argument-prompt optional prompt
+ (concat "Savebox: " TeX-esc)
+ t))
+ optional TeX-esc))
+
+(defun TeX-arg-file (optional &optional prompt)
+ "Prompt for a filename in the current directory.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. Use PROMPT as the prompt
+string."
+ (TeX-argument-insert (read-file-name (TeX-argument-prompt optional
+ prompt "File")
+ "" "" nil)
+ optional))
+
+(defun TeX-arg-define-label (optional &optional prompt)
+ "Prompt for a label completing with known labels.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. Use PROMPT as the prompt
+string."
+ (TeX-arg-label optional prompt t))
+
+(defun TeX-arg-define-macro (optional &optional prompt)
+ "Prompt for a TeX macro with completion.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. Use PROMPT as the prompt
+string."
+ (TeX-arg-macro optional prompt t))
+
+(defun TeX-arg-define-environment (optional &optional prompt)
+ "Prompt for a LaTeX environment with completion.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. Use PROMPT as the prompt
+string."
+ (TeX-arg-environment optional prompt t))
+
+(defun TeX-arg-define-cite (optional &optional prompt)
+ "Prompt for a BibTeX citation.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. Use PROMPT as the prompt
+string."
+ (TeX-arg-cite optional prompt t))
+
+(defun TeX-arg-define-counter (optional &optional prompt)
+ "Prompt for a LaTeX counter.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. Use PROMPT as the prompt
+string."
+ (TeX-arg-counter optional prompt t))
+
+(defun TeX-arg-define-savebox (optional &optional prompt)
+ "Prompt for a LaTeX savebox.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. Use PROMPT as the prompt
+string."
+ (TeX-arg-savebox optional prompt t))
+
+(defcustom LaTeX-style-list '(("amsart")
+ ("amsbook")
+ ("article")
+ ("beamer")
+ ("book")
+ ("dinbrief")
+ ("foils")
+ ("letter")
+ ("minimal")
+ ("prosper")
+ ("report")
+ ("scrartcl")
+ ("scrbook")
+ ("scrlttr2")
+ ("scrreprt")
+ ("slides"))
+ "List of document classes offered when inserting a document environment."
+ :group 'LaTeX-environment
+ :type '(repeat (group (string :format "%v"))))
+
+(defun TeX-arg-document (optional &optional ignore)
+ "Insert arguments to documentclass.
+OPTIONAL and IGNORE are ignored."
+ (let ((style (completing-read
+ (concat "Document class: (default " LaTeX-default-style ") ")
+ LaTeX-style-list))
+ (options (read-string "Options: "
+ (if (stringp LaTeX-default-options)
+ LaTeX-default-options
+ (mapconcat 'identity
+ LaTeX-default-options
+ ",")))))
+ (if (zerop (length style))
+ (setq style LaTeX-default-style))
+ (if (not (zerop (length options)))
+ (insert LaTeX-optop options LaTeX-optcl))
+ (insert TeX-grop style TeX-grcl))
+
+ ;; remove old information
+ (TeX-remove-style)
+
+ ;; defined in individual style hooks
+ (TeX-update-style))
+
+(defun LaTeX-arg-usepackage (optional)
+ "Insert arguments to usepackage.
+OPTIONAL is ignored."
+ (let ((TeX-file-extensions '("sty")))
+ (TeX-arg-input-file nil "Package")
+ (save-excursion
+ (search-backward-regexp "{\\(.*\\)}")
+ (let* ((package (match-string 1))
+ (var (intern (format "LaTeX-%s-package-options" package)))
+ (crm-separator ",")
+ (TeX-arg-opening-brace LaTeX-optop)
+ (TeX-arg-closing-brace LaTeX-optcl)
+ options)
+ (if (or (and (boundp var)
+ (listp (symbol-value var)))
+ (fboundp var))
+ (if (functionp var)
+ (setq options (funcall var))
+ (when (symbol-value var)
+ (setq options
+ (mapconcat 'identity
+ (TeX-completing-read-multiple
+ "Options: " (mapcar 'list (symbol-value var)))
+ ","))))
+ (setq options (read-string "Options: ")))
+ (when options
+ ;; XXX: The following statement will add the options
+ ;; supplied to the LaTeX package to the style list. This is
+ ;; consistent with the way the parser works (see
+ ;; `LaTeX-auto-cleanup'). But in a revamped style system
+ ;; such options should be associated with their LaTeX
+ ;; package to avoid confusion. For example a `german' entry
+ ;; in the style list can come from documentclass options and
+ ;; does not necessarily mean that the babel-related
+ ;; extensions should be activated.
+ (mapc 'TeX-run-style-hooks (LaTeX-listify-package-options options))
+ (TeX-argument-insert options t))))))
+
+(defvar TeX-global-input-files nil
+ "List of the non-local TeX input files.
+
+Initialized once at the first time you prompt for an input file.
+May be reset with `\\[universal-argument] \\[TeX-normal-mode]'.")
+
+(defun TeX-arg-input-file (optional &optional prompt local)
+ "Prompt for a tex or sty file.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. PROMPT is the prompt,
+LOCAL is a flag. If the flag is set, only complete with local
+files."
+ (unless (or TeX-global-input-files local)
+ (message "Searching for files...")
+ (setq TeX-global-input-files
+ (mapcar 'list (TeX-search-files (append TeX-macro-private
+ TeX-macro-global)
+ TeX-file-extensions t t))))
+ (let ((file (if TeX-check-path
+ (completing-read
+ (TeX-argument-prompt optional prompt "File")
+ (TeX-delete-dups-by-car
+ (append (mapcar 'list
+ (TeX-search-files '("./")
+ TeX-file-extensions
+ t t))
+ (unless local
+ TeX-global-input-files))))
+ (read-file-name
+ (TeX-argument-prompt optional prompt "File")))))
+ (if (null file)
+ (setq file ""))
+ (if (not (string-equal "" file))
+ (TeX-run-style-hooks file))
+ (TeX-argument-insert file optional)))
+
+(defvar BibTeX-global-style-files nil
+ "Association list of BibTeX style files.
+
+Initialized once at the first time you prompt for an input file.
+May be reset with `\\[universal-argument] \\[TeX-normal-mode]'.")
+
+(defun TeX-arg-bibstyle (optional &optional prompt)
+ "Prompt for a BibTeX style file.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. Use PROMPT as the prompt
+string."
+ (message "Searching for BibTeX styles...")
+ (or BibTeX-global-style-files
+ (setq BibTeX-global-style-files
+ (mapcar 'list
+ (TeX-search-files (append TeX-macro-private
+ TeX-macro-global)
+ BibTeX-style-extensions t t))))
+
+ (TeX-argument-insert
+ (completing-read (TeX-argument-prompt optional prompt "BibTeX style")
+ (append (mapcar 'list
+ (TeX-search-files '("./")
+ BibTeX-style-extensions
+ t t))
+ BibTeX-global-style-files))
+ optional))
+
+(defvar BibTeX-global-files nil
+ "Association list of BibTeX files.
+
+Initialized once at the first time you prompt for an BibTeX file.
+May be reset with `\\[universal-argument] \\[TeX-normal-mode]'.")
+
+(defun TeX-arg-bibliography (optional &optional prompt)
+ "Prompt for a BibTeX database file.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. Use PROMPT as the prompt
+string."
+ (message "Searching for BibTeX files...")
+ (or BibTeX-global-files
+ (setq BibTeX-global-files
+ (mapcar 'list (TeX-search-files nil BibTeX-file-extensions t t))))
+
+ (let ((styles (multi-prompt
+ "," t
+ (TeX-argument-prompt optional prompt "BibTeX files")
+ (append (mapcar 'list
+ (TeX-search-files '("./")
+ BibTeX-file-extensions
+ t t))
+ BibTeX-global-files))))
+ (apply 'LaTeX-add-bibliographies styles)
+ (TeX-argument-insert (mapconcat 'identity styles ",") optional)))
+
+(defun TeX-arg-corner (optional &optional prompt)
+ "Prompt for a LaTeX side or corner position with completion.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. Use PROMPT as the prompt
+string."
+ (TeX-argument-insert
+ (completing-read (TeX-argument-prompt optional prompt "Position")
+ '(("") ("l") ("r") ("t") ("b") ("tl") ("tr") ("bl") ("br"))
+ nil t)
+ optional))
+
+(defun TeX-arg-lr (optional &optional prompt)
+ "Prompt for a LaTeX side with completion.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. Use PROMPT as the prompt
+string."
+ (TeX-argument-insert
+ (completing-read (TeX-argument-prompt optional prompt "Position")
+ '(("") ("l") ("r"))
+ nil t)
+ optional))
+
+(defun TeX-arg-tb (optional &optional prompt)
+ "Prompt for a LaTeX side with completion.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. Use PROMPT as the prompt
+string."
+ (TeX-argument-insert
+ (completing-read (TeX-argument-prompt optional prompt "Position")
+ '(("") ("t") ("b"))
+ nil t)
+ optional))
+
+(defun TeX-arg-pagestyle (optional &optional prompt)
+ "Prompt for a LaTeX pagestyle with completion.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. Use PROMPT as the prompt
+string."
+ (TeX-argument-insert
+ (completing-read (TeX-argument-prompt optional prompt "Pagestyle")
+ '(("plain") ("empty") ("headings") ("myheadings")))
+ optional))
+
+(defcustom LaTeX-default-verb-delimiter ?|
+ "Default delimiter for `\\verb' macros."
+ :group 'LaTeX-macro
+ :type 'character)
+
+(defun TeX-arg-verb (optional &optional ignore)
+ "Prompt for delimiter and text.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. IGNORE is ignored."
+ (let ((del (read-quoted-char
+ (concat "Delimiter: (default "
+ (char-to-string LaTeX-default-verb-delimiter) ") "))))
+ (when (<= del ?\ ) (setq del LaTeX-default-verb-delimiter))
+ (if (TeX-active-mark)
+ (progn
+ (insert del)
+ (goto-char (mark))
+ (insert del))
+ (insert del (read-from-minibuffer "Text: ") del))
+ (setq LaTeX-default-verb-delimiter del)))
+
+(defun TeX-arg-pair (optional first second)
+ "Insert a pair of number, prompted by FIRST and SECOND.
+
+The numbers are surounded by parenthesizes and separated with a
+comma.
+
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one."
+ (insert "(" (read-string (concat first ": ")) ","
+ (read-string (concat second ": ")) ")"))
+
+(defun TeX-arg-size (optional)
+ "Insert width and height as a pair.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one."
+ (TeX-arg-pair optional "Width" "Height"))
+
+(defun TeX-arg-coordinate (optional)
+ "Insert x and y coordinate as a pair.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one."
+ (TeX-arg-pair optional "X position" "Y position"))
+
+(defconst TeX-braces-default-association
+ '(("[" . "]")
+ ("\\{" . "\\}")
+ ("(" . ")")
+ ("|" . "|")
+ ("\\|" . "\\|")
+ ("/" . "/")
+ ("\\backslash" . "\\backslash")
+ ("\\lfloor" . "\\rfloor")
+ ("\\lceil" . "\\rceil")
+ ("\\langle" . "\\rangle")))
+
+(defcustom TeX-braces-user-association nil
+ "A list of your personal association of brace symbols.
+These are used for \\left and \\right.
+
+The car of each entry is the brace used with \\left,
+the cdr is the brace used with \\right."
+ :group 'LaTeX-macro
+ :group 'LaTeX-math
+ :type '(repeat (cons :format "%v"
+ (string :tag "Left")
+ (string :tag "Right"))))
+
+(defvar TeX-braces-association
+ (append TeX-braces-user-association
+ TeX-braces-default-association)
+ "A list of association of brace symbols for \\left and \\right.
+The car of each entry is the brace used with \\left,
+the cdr is the brace used with \\right.")
+
+(defvar TeX-left-right-braces
+ '(("[") ("]") ("\\{") ("\\}") ("(") (")") ("|") ("\\|")
+ ("/") ("\\backslash") ("\\lfloor") ("\\rfloor")
+ ("\\lceil") ("\\rceil") ("\\langle") ("\\rangle")
+ ("\\uparrow") ("\\Uparrow") ("\\downarrow") ("\\Downarrow")
+ ("\\updownarrow") ("\\Updownarrow") ("."))
+ "List of symbols which can follow the \\left or \\right command.")
+
+(defun TeX-arg-insert-braces (optional &optional prompt)
+ "Prompt for a brace for \\left and insert the corresponding \\right.
+If OPTIONAL is non-nil, insert the resulting value as an optional
+argument, otherwise as a mandatory one. Use PROMPT as the prompt
+string."
+ (save-excursion
+ (backward-word 1)
+ (backward-char)
+ (LaTeX-newline)
+ (indent-according-to-mode)
+ (beginning-of-line 0)
+ (if (looking-at "^[ \t]*$")
+ (progn (delete-horizontal-space)
+ (delete-char 1))))
+ (let ((left-brace (completing-read
+ (TeX-argument-prompt optional prompt "Which brace")
+ TeX-left-right-braces)))
+ (insert left-brace)
+ (LaTeX-newline)
+ (indent-according-to-mode)
+ (save-excursion
+ (let ((right-brace (cdr (assoc left-brace
+ TeX-braces-association))))
+ (LaTeX-newline)
+ (insert TeX-esc "right")
+ (if (and TeX-arg-right-insert-p
+ right-brace)
+ (insert right-brace)
+ (insert (completing-read
+ (TeX-argument-prompt optional prompt "Which brace")
+ TeX-left-right-braces)))
+ (indent-according-to-mode)))))
+
+(defun TeX-arg-key-val (optional key-val-alist)
+ "Prompt for keys and values in KEY-VAL-ALIST.
+Insert the given value as a TeX macro argument. If OPTIONAL is
+non-nil, insert it as an optional argument. KEY-VAL-ALIST is an
+alist. The car of each element should be a string representing a
+key and the optional cdr should be a list with strings to be used
+as values for the key."
+ (let ((options (multi-prompt-key-value
+ (TeX-argument-prompt optional "Options" nil)
+ (if (symbolp key-val-alist)
+ (eval key-val-alist)
+ key-val-alist))))
+ (TeX-argument-insert options optional)))
+
+
+;;; Verbatim constructs
+
+(defcustom LaTeX-verbatim-macros-with-delims
+ '("verb" "verb*")
+ "Macros for inline verbatim with arguments in delimiters, like \\foo|...|.
+
+Programs should not use this variable directly but the function
+`LaTeX-verbatim-macros-with-delims' which returns a value
+including buffer-local keyword additions via
+`LaTeX-verbatim-macros-with-delims-local' as well."
+ :group 'LaTeX-macro
+ :type '(repeat (string)))
+
+(defvar LaTeX-verbatim-macros-with-delims-local nil
+ "Buffer-local variable for inline verbatim with args in delimiters.
+
+Style files should add constructs to this variable and not to
+`LaTeX-verbatim-macros-with-delims'.
+
+Programs should not use this variable directly but the function
+`LaTeX-verbatim-macros-with-delims' which returns a value
+including values of the variable
+`LaTeX-verbatim-macros-with-delims' as well.")
+(make-variable-buffer-local 'LaTeX-verbatim-macros-with-delims-local)
+
+(defcustom LaTeX-verbatim-macros-with-braces nil
+ "Macros for inline verbatim with arguments in braces, like \\foo{...}.
+
+Programs should not use this variable directly but the function
+`LaTeX-verbatim-macros-with-braces' which returns a value
+including buffer-local keyword additions via
+`LaTeX-verbatim-macros-with-braces-local' as well."
+ :group 'LaTeX-macro
+ :type '(repeat (string)))
+
+(defvar LaTeX-verbatim-macros-with-braces-local nil
+ "Buffer-local variable for inline verbatim with args in braces.
+
+Style files should add constructs to this variable and not to
+`LaTeX-verbatim-macros-with-braces'.
+
+Programs should not use this variable directly but the function
+`LaTeX-verbatim-macros-with-braces' which returns a value
+including values of the variable
+`LaTeX-verbatim-macros-with-braces' as well.")
+(make-variable-buffer-local 'LaTeX-verbatim-macros-with-braces-local)
+
+(defcustom LaTeX-verbatim-environments
+ '("verbatim" "verbatim*")
+ "Verbatim environments.
+
+Programs should not use this variable directly but the function
+`LaTeX-verbatim-environments' which returns a value including
+buffer-local keyword additions via
+`LaTeX-verbatim-environments-local' as well."
+ :group 'LaTeX-environment
+ :type '(repeat (string)))
+
+(defvar LaTeX-verbatim-environments-local nil
+ "Buffer-local variable for inline verbatim environments.
+
+Style files should add constructs to this variable and not to
+`LaTeX-verbatim-environments'.
+
+Programs should not use this variable directly but the function
+`LaTeX-verbatim-environments' which returns a value including
+values of the variable `LaTeX-verbatim-environments' as well.")
+(make-variable-buffer-local 'LaTeX-verbatim-environments-local)
+
+(defun LaTeX-verbatim-macros-with-delims ()
+ "Return list of verbatim macros with delimiters."
+ (append LaTeX-verbatim-macros-with-delims
+ LaTeX-verbatim-macros-with-delims-local))
+
+(defun LaTeX-verbatim-macros-with-braces ()
+ "Return list of verbatim macros with braces."
+ (append LaTeX-verbatim-macros-with-braces
+ LaTeX-verbatim-macros-with-braces-local))
+
+(defun LaTeX-verbatim-environments ()
+ "Return list of verbatim environments."
+ (append LaTeX-verbatim-environments
+ LaTeX-verbatim-environments-local))
+
+(defun LaTeX-verbatim-macro-boundaries ()
+ "Return boundaries of verbatim macro.
+Boundaries are returned as a cons cell where the car is the macro
+start and the cdr the macro end.
+
+Only macros which enclose their arguments with special
+non-parenthetical delimiters, like \\verb+foo+, are recognized."
+ (save-excursion
+ (let ((orig (point))
+ (verbatim-regexp (regexp-opt (LaTeX-verbatim-macros-with-delims) t)))
+ ;; Search backwards for the macro start, unless we are facing one
+ (unless (looking-at (concat (regexp-quote TeX-esc) verbatim-regexp))
+ (catch 'found
+ (while (progn
+ (skip-chars-backward (concat "^\n" (regexp-quote TeX-esc))
+ (line-beginning-position))
+ (when (looking-at verbatim-regexp) (throw 'found nil))
+ (or (bobp) (forward-char -1))
+ (/= (point) (line-beginning-position))))))
+ ;; Search forward for the macro end, unless we failed to find a start
+ (unless (bolp)
+ (let ((beg (1- (point))))
+ (goto-char (1+ (match-end 0)))
+ (skip-chars-forward (concat "^" (buffer-substring-no-properties
+ (1- (point)) (point))))
+ (when (<= orig (point))
+ (cons beg (1+ (point)))))))))
+
+(defun LaTeX-current-verbatim-macro ()
+ "Return name of verbatim macro containing point, nil if none is present."
+ (let ((macro-boundaries (LaTeX-verbatim-macro-boundaries)))
+ (when macro-boundaries
+ (save-excursion
+ (goto-char (car macro-boundaries))
+ (forward-char (length TeX-esc))
+ (buffer-substring-no-properties
+ (point) (progn (skip-chars-forward "@A-Za-z") (point)))))))
+
+(defun LaTeX-verbatim-p (&optional pos)
+ "Return non-nil if position POS is in a verbatim-like construct."
+ (when pos (goto-char pos))
+ (save-match-data
+ (or (when (fboundp 'font-latex-faces-present-p)
+ (font-latex-faces-present-p 'font-latex-verbatim-face))
+ (member (LaTeX-current-verbatim-macro)
+ (LaTeX-verbatim-macros-with-delims))
+ (member (TeX-current-macro) (LaTeX-verbatim-macros-with-braces))
+ (member (LaTeX-current-environment) (LaTeX-verbatim-environments)))))
+
+
+;;; Formatting
+
+(defcustom LaTeX-syntactic-comments t
+ "If non-nil comments will be handled according to LaTeX syntax.
+This variable influences, among others, the behavior of
+indentation and filling which will take LaTeX syntax into
+consideration just as is in the non-commented source code."
+ :type 'boolean
+ :group 'LaTeX)
+
+
+;;; Indentation
+
+;; We are distinguishing two different types of comments:
+;;
+;; 1) Comments starting in column one (line comments)
+;;
+;; 2) Comments starting after column one with only whitespace
+;; preceding it.
+;;
+;; (There is actually a third type: Comments preceded not only by
+;; whitespace but by some code as well; so-called code comments. But
+;; they are not relevant for the following explanations.)
+;;
+;; Additionally we are distinguishing two different types of
+;; indentation:
+;;
+;; a) Outer indentation: Indentation before the comment character(s).
+;;
+;; b) Inner indentation: Indentation after the comment character(s)
+;; (taking into account possible comment padding).
+;;
+;; Comments can be filled syntax-aware or not.
+;;
+;; In `doctex-mode' line comments should always be indented
+;; syntax-aware and the comment character has to be anchored at the
+;; first column (unless the appear in a macrocode environment). Other
+;; comments not in the documentation parts always start after the
+;; first column and can be indented syntax-aware or not. If they are
+;; indented syntax-aware both the indentation before and after the
+;; comment character(s) have to be checked and adjusted. Indentation
+;; should not move the comment character(s) to the first column. With
+;; `LaTeX-syntactic-comments' disabled, line comments should still be
+;; indented syntax-aware.
+;;
+;; In `latex-mode' comments starting in different columns don't have
+;; to be handled differently. They don't have to be anchored in
+;; column one. That means that in any case indentation before and
+;; after the comment characters has to be checked and adjusted.
+
+(defgroup LaTeX-indentation nil
+ "Indentation of LaTeX code in AUCTeX"
+ :group 'LaTeX
+ :group 'TeX-indentation)
+
+(defcustom LaTeX-indent-level 2
+ "*Indentation of begin-end blocks in LaTeX."
+ :group 'LaTeX-indentation
+ :type 'integer)
+
+(defcustom LaTeX-item-indent (- LaTeX-indent-level)
+ "*Extra indentation for lines beginning with an item."
+ :group 'LaTeX-indentation
+ :type 'integer)
+
+(defcustom LaTeX-item-regexp "\\(bib\\)?item\\b"
+ "*Regular expression matching macros considered items."
+ :group 'LaTeX-indentation
+ :type 'regexp)
+
+(defcustom LaTeX-indent-environment-list
+ '(("verbatim" current-indentation)
+ ("verbatim*" current-indentation)
+ ;; The following should have there own, smart indentation function.
+ ;; Some other day.
+ ("array")
+ ("displaymath")
+ ("eqnarray")
+ ("eqnarray*")
+ ("equation")
+ ("equation*")
+ ("picture")
+ ("tabbing")
+ ("table")
+ ("table*")
+ ("tabular")
+ ("tabular*"))
+ "Alist of environments with special indentation.
+The second element in each entry is the function to calculate the
+indentation level in columns."
+ :group 'LaTeX-indentation
+ :type '(repeat (list (string :tag "Environment")
+ (option function))))
+
+(defcustom LaTeX-indent-environment-check t
+ "*If non-nil, check for any special environments."
+ :group 'LaTeX-indentation
+ :type 'boolean)
+
+(defcustom LaTeX-document-regexp "document"
+ "Regexp matching environments in which the indentation starts at col 0."
+ :group 'LaTeX-indentation
+ :type 'regexp)
+
+(defcustom LaTeX-verbatim-regexp "verbatim\\*?"
+ "*Regexp matching environments with indentation at col 0 for begin/end."
+ :group 'LaTeX-indentation
+ :type 'regexp)
+
+(defcustom LaTeX-begin-regexp "begin\\b"
+ "*Regexp matching macros considered begins."
+ :group 'LaTeX-indentation
+ :type 'regexp)
+
+(defcustom LaTeX-end-regexp "end\\b"
+ "*Regexp matching macros considered ends."
+ :group 'LaTeX-indentation
+ :type 'regexp)
+
+(defcustom LaTeX-left-right-indent-level LaTeX-indent-level
+ "*The level of indentation produced by a \\left macro."
+ :group 'LaTeX-indentation
+ :type 'integer)
+
+(defcustom LaTeX-indent-comment-start-regexp "%"
+ "*Regexp matching comments ending the indent level count.
+This means, we just count the LaTeX tokens \\left, \\right, \\begin,
+and \\end up to the first occurence of text matching this regexp.
+Thus, the default \"%\" stops counting the tokens at a comment. A
+value of \"%[^>]\" would allow you to alter the indentation with
+comments, e.g. with comment `%> \\begin'.
+Lines which start with `%' are not considered at all, regardless if this
+value."
+ :group 'LaTeX-indentation
+ :type 'regexp)
+
+(defvar docTeX-indent-inner-fixed
+ `((,(concat (regexp-quote TeX-esc)
+ "\\(begin\\|end\\)[ \t]*{macrocode\\*?}") 4 t)
+ (,(concat (regexp-quote TeX-esc)
+ "\\(begin\\|end\\)[ \t]*{\\(macro\\|environment\\)\\*?}") 0 nil))
+ "List of items which should have a fixed inner indentation.
+The items consist of three parts. The first is a regular
+expression which should match the respective string. The second
+is the amount of spaces to be used for indentation. The third
+toggles if comment padding is relevant or not. If t padding is
+part of the amount given, if nil the amount of spaces will be
+inserted after potential padding.")
+
+(defun LaTeX-indent-line ()
+ "Indent the line containing point, as LaTeX source.
+Add `LaTeX-indent-level' indentation in each \\begin{ - \\end{ block.
+Lines starting with an item is given an extra indentation of
+`LaTeX-item-indent'."
+ (interactive)
+ (let* ((case-fold-search nil)
+ ;; Compute a fill prefix. Whitespace after the comment
+ ;; characters will be disregarded and replaced by
+ ;; `comment-padding'.
+ (fill-prefix
+ (and (TeX-in-commented-line)
+ (save-excursion
+ (beginning-of-line)
+ (looking-at
+ (concat "\\([ \t]*" TeX-comment-start-regexp "+\\)+"))
+ (concat (match-string 0) (TeX-comment-padding-string)))))
+ (overlays (when (featurep 'xemacs)
+ ;; Isn't that fun? In Emacs an `(overlays-at
+ ;; (line-beginning-position))' would do the
+ ;; trick. How boring.
+ (extent-list
+ nil (line-beginning-position) (line-beginning-position)
+ 'all-extents-closed-open 'overlay)))
+ ol-specs)
+ ;; XEmacs' `indent-to' function (at least in version 21.4.15) has
+ ;; a bug which leads to the insertion of whitespace in front of an
+ ;; invisible overlay. So during indentation we temporarily remove
+ ;; the 'invisible property.
+ (dolist (ol overlays)
+ (when (extent-property ol 'invisible)
+ (add-to-list 'ol-specs (list ol (extent-property ol 'invisible)))
+ (set-extent-property ol 'invisible nil)))
+ (save-excursion
+ (cond ((and fill-prefix
+ (TeX-in-line-comment)
+ (eq major-mode 'doctex-mode))
+ ;; If point is in a line comment in `doctex-mode' we only
+ ;; consider the inner indentation.
+ (let ((inner-indent (LaTeX-indent-calculate 'inner)))
+ (when (/= (LaTeX-current-indentation 'inner) inner-indent)
+ (LaTeX-indent-inner-do inner-indent))))
+ ((and fill-prefix
+ LaTeX-syntactic-comments)
+ ;; In any other case of a comment we have to consider
+ ;; outer and inner indentation if we do syntax-aware
+ ;; indentation.
+ (let ((inner-indent (LaTeX-indent-calculate 'inner))
+ (outer-indent (LaTeX-indent-calculate 'outer)))
+ (when (/= (LaTeX-current-indentation 'inner) inner-indent)
+ (LaTeX-indent-inner-do inner-indent))
+ (when (/= (LaTeX-current-indentation 'outer) outer-indent)
+ (LaTeX-indent-outer-do outer-indent))))
+ (t
+ ;; The default is to adapt whitespace before any
+ ;; non-whitespace character, i.e. to do outer
+ ;; indentation.
+ (let ((outer-indent (LaTeX-indent-calculate 'outer)))
+ (when (/= (LaTeX-current-indentation 'outer) outer-indent)
+ (LaTeX-indent-outer-do outer-indent))))))
+ ;; Make the overlays invisible again.
+ (dolist (ol-spec ol-specs)
+ (set-extent-property (car ol-spec) 'invisible (cadr ol-spec)))
+ (when (< (current-column) (save-excursion
+ (LaTeX-back-to-indentation) (current-column)))
+ (LaTeX-back-to-indentation))))
+
+(defun LaTeX-indent-inner-do (inner-indent)
+ ;; Small helper function for `LaTeX-indent-line' to perform
+ ;; indentation after a comment character. It requires that
+ ;; `LaTeX-indent-line' already set the appropriate variables and
+ ;; should not be used outside of `LaTeX-indent-line'.
+ (move-to-left-margin)
+ (TeX-re-search-forward-unescaped
+ (concat "\\(" TeX-comment-start-regexp "+[ \t]*\\)+") (line-end-position) t)
+ (delete-region (line-beginning-position) (point))
+ (insert fill-prefix)
+ (indent-to (+ inner-indent (length fill-prefix))))
+
+(defun LaTeX-indent-outer-do (outer-indent)
+ ;; Small helper function for `LaTeX-indent-line' to perform
+ ;; indentation of normal lines or before a comment character in a
+ ;; commented line. It requires that `LaTeX-indent-line' already set
+ ;; the appropriate variables and should not be used outside of
+ ;; `LaTeX-indent-line'.
+ (back-to-indentation)
+ (delete-region (line-beginning-position) (point))
+ (indent-to outer-indent))
+
+(defun LaTeX-indent-calculate (&optional force-type)
+ "Return the indentation of a line of LaTeX source.
+FORCE-TYPE can be used to force the calculation of an inner or
+outer indentation in case of a commented line. The symbols
+'inner and 'outer are recognized."
+ (save-excursion
+ (LaTeX-back-to-indentation force-type)
+ (let ((i 0)
+ (list-length (safe-length docTeX-indent-inner-fixed))
+ entry
+ found)
+ (cond ((save-excursion (beginning-of-line) (bobp)) 0)
+ ((and (eq major-mode 'doctex-mode)
+ fill-prefix
+ (TeX-in-line-comment)
+ (progn
+ (while (and (< i list-length)
+ (not found))
+ (setq entry (nth i docTeX-indent-inner-fixed))
+ (when (looking-at (nth 0 entry))
+ (setq found t))
+ (setq i (1+ i)))
+ found))
+ (if (nth 2 entry)
+ (- (nth 1 entry) (if (integerp comment-padding)
+ comment-padding
+ (length comment-padding)))
+ (nth 1 entry)))
+ ((looking-at (concat (regexp-quote TeX-esc)
+ "\\(begin\\|end\\){\\("
+ LaTeX-verbatim-regexp
+ "\\)}"))
+ ;; \end{verbatim} must be flush left, otherwise an unwanted
+ ;; empty line appears in LaTeX's output.
+ 0)
+ ((and LaTeX-indent-environment-check
+ ;; Special environments.
+ (let ((entry (assoc (or LaTeX-current-environment
+ (LaTeX-current-environment))
+ LaTeX-indent-environment-list)))
+ (and entry
+ (nth 1 entry)
+ (funcall (nth 1 entry))))))
+ ((looking-at (concat (regexp-quote TeX-esc)
+ "\\("
+ LaTeX-end-regexp
+ "\\)"))
+ ;; Backindent at \end.
+ (- (LaTeX-indent-calculate-last force-type) LaTeX-indent-level))
+ ((looking-at (concat (regexp-quote TeX-esc) "right\\b"))
+ ;; Backindent at \right.
+ (- (LaTeX-indent-calculate-last force-type)
+ LaTeX-left-right-indent-level))
+ ((looking-at (concat (regexp-quote TeX-esc)
+ "\\("
+ LaTeX-item-regexp
+ "\\)"))
+ ;; Items.
+ (+ (LaTeX-indent-calculate-last force-type) LaTeX-item-indent))
+ ((looking-at "}")
+ ;; End brace in the start of the line.
+ (- (LaTeX-indent-calculate-last force-type)
+ TeX-brace-indent-level))
+ (t (LaTeX-indent-calculate-last force-type))))))
+
+(defun LaTeX-indent-level-count ()
+ "Count indentation change caused by all \\left, \\right, \\begin, and
+\\end commands in the current line."
+ (save-excursion
+ (save-restriction
+ (let ((count 0))
+ (narrow-to-region (point)
+ (save-excursion
+ (re-search-forward
+ (concat "[^" TeX-esc "]"
+ "\\(" LaTeX-indent-comment-start-regexp
+ "\\)\\|\n\\|\\'"))
+ (backward-char)
+ (point)))
+ (while (search-forward TeX-esc nil t)
+ (cond
+ ((looking-at "left\\b")
+ (setq count (+ count LaTeX-left-right-indent-level)))
+ ((looking-at "right\\b")
+ (setq count (- count LaTeX-left-right-indent-level)))
+ ((looking-at LaTeX-begin-regexp)
+ (setq count (+ count LaTeX-indent-level)))
+ ((looking-at LaTeX-end-regexp)
+ (setq count (- count LaTeX-indent-level)))
+ ((looking-at (regexp-quote TeX-esc))
+ (forward-char 1))))
+ count))))
+
+(defun LaTeX-indent-calculate-last (&optional force-type)
+ "Return the correct indentation of a normal line of text.
+The point is supposed to be at the beginning of the current line.
+FORCE-TYPE can be used to force the calculation of an inner or
+outer indentation in case of a commented line. The symbols
+'inner and 'outer are recognized."
+ (let (line-comment-current-flag
+ line-comment-last-flag
+ comment-current-flag
+ comment-last-flag)
+ (beginning-of-line)
+ (setq line-comment-current-flag (TeX-in-line-comment)
+ comment-current-flag (TeX-in-commented-line))
+ (if comment-current-flag
+ (skip-chars-backward "%\n\t ")
+ (skip-chars-backward "\n\t "))
+ (beginning-of-line)
+ ;; If we are called in a non-comment line, skip over comment
+ ;; lines. The computation of indentation should in this case
+ ;; rather take the last non-comment line into account.
+ ;; Otherwise there might arise problems with e.g. multi-line
+ ;; code comments. This behavior is not enabled in docTeX mode
+ ;; where large amounts of line comments may have to be skipped
+ ;; and indentation should not be influenced by unrelated code in
+ ;; other macrocode environments.
+ (while (and (not (eq major-mode 'doctex-mode))
+ (not comment-current-flag)
+ (TeX-in-commented-line)
+ (not (bobp)))
+ (skip-chars-backward "\n\t ")
+ (beginning-of-line))
+ (setq line-comment-last-flag (TeX-in-line-comment)
+ comment-last-flag (TeX-in-commented-line))
+ (LaTeX-back-to-indentation force-type)
+ ;; Separate line comments and other stuff (normal text/code and
+ ;; code comments). Additionally we don't want to compute inner
+ ;; indentation when a commented and a non-commented line are
+ ;; compared.
+ (cond ((or (and (eq major-mode 'doctex-mode)
+ (or (and line-comment-current-flag
+ (not line-comment-last-flag))
+ (and (not line-comment-current-flag)
+ line-comment-last-flag)))
+ (and force-type
+ (eq force-type 'inner)
+ (or (and comment-current-flag
+ (not comment-last-flag))
+ (and (not comment-current-flag)
+ comment-last-flag))))
+ 0)
+ ((looking-at (concat (regexp-quote TeX-esc)
+ "begin *{\\("
+ LaTeX-document-regexp
+ "\\)}"))
+ ;; I dislike having all of the document indented...
+ (+ (LaTeX-current-indentation force-type)
+ ;; Some people have opening braces at the end of the
+ ;; line, e.g. in case of `\begin{letter}{%'.
+ (TeX-brace-count-line)))
+ ((and (eq major-mode 'doctex-mode)
+ (looking-at (concat (regexp-quote TeX-esc)
+ "end[ \t]*{macrocode\\*?}"))
+ fill-prefix
+ (TeX-in-line-comment))
+ ;; Reset indentation to zero after a macrocode
+ ;; environment.
+ 0)
+ ((looking-at (concat (regexp-quote TeX-esc)
+ "begin *{\\("
+ LaTeX-verbatim-regexp
+ "\\)}"))
+ 0)
+ ((looking-at (concat (regexp-quote TeX-esc)
+ "end *{\\("
+ LaTeX-verbatim-regexp
+ "\\)}"))
+ ;; If I see an \end{verbatim} in the previous line I skip
+ ;; back to the preceding \begin{verbatim}.
+ (save-excursion
+ (if (re-search-backward (concat (regexp-quote TeX-esc)
+ "begin *{\\("
+ LaTeX-verbatim-regexp
+ "\\)}") 0 t)
+ (LaTeX-indent-calculate-last force-type)
+ 0)))
+ (t (+ (LaTeX-current-indentation force-type)
+ (if (not (and force-type
+ (eq force-type 'outer)
+ (TeX-in-commented-line)))
+ (+ (LaTeX-indent-level-count)
+ (TeX-brace-count-line))
+ 0)
+ (cond ((looking-at (concat (regexp-quote TeX-esc)
+ "\\("
+ LaTeX-end-regexp
+ "\\)"))
+ LaTeX-indent-level)
+ ((looking-at
+ (concat (regexp-quote TeX-esc) "right\\b"))
+ LaTeX-left-right-indent-level)
+ ((looking-at (concat (regexp-quote TeX-esc)
+ "\\("
+ LaTeX-item-regexp
+ "\\)"))
+ (- LaTeX-item-indent))
+ ((looking-at "}")
+ TeX-brace-indent-level)
+ (t 0)))))))
+
+(defun LaTeX-current-indentation (&optional force-type)
+ "Return the indentation of a line.
+FORCE-TYPE can be used to force the calculation of an inner or
+outer indentation in case of a commented line. The symbols
+'inner and 'outer are recognized."
+ (if (and fill-prefix
+ (or (and force-type
+ (eq force-type 'inner))
+ (and (not force-type)
+ (or
+ ;; If `LaTeX-syntactic-comments' is not enabled,
+ ;; do conventional indentation
+ LaTeX-syntactic-comments
+ ;; Line comments in `doctex-mode' are always
+ ;; indented syntax-aware so we need their inner
+ ;; indentation.
+ (and (TeX-in-line-comment)
+ (eq major-mode 'doctex-mode))))))
+ ;; INNER indentation
+ (save-excursion
+ (beginning-of-line)
+ (looking-at (concat "\\(?:[ \t]*" TeX-comment-start-regexp "+\\)+"
+ "\\([ \t]*\\)"))
+ (- (length (match-string 1)) (length (TeX-comment-padding-string))))
+ ;; OUTER indentation
+ (current-indentation)))
+
+(defun LaTeX-back-to-indentation (&optional force-type)
+ "Move point to the first non-whitespace character on this line.
+If it is commented and comments are formatted syntax-aware move
+point to the first non-whitespace character after the comment
+character(s). The optional argument FORCE-TYPE can be used to
+force point being moved to the inner or outer indentation in case
+of a commented line. The symbols 'inner and 'outer are
+recognized."
+ (if (or (and force-type
+ (eq force-type 'inner))
+ (and (not force-type)
+ (or (and (TeX-in-line-comment)
+ (eq major-mode 'doctex-mode))
+ (and (TeX-in-commented-line)
+ LaTeX-syntactic-comments))))
+ (progn
+ (beginning-of-line)
+ ;; Should this be anchored at the start of the line?
+ (TeX-re-search-forward-unescaped
+ (concat "\\(?:" TeX-comment-start-regexp "+[ \t]*\\)+")
+ (line-end-position) t))
+ (back-to-indentation)))
+
+
+;;; Filling
+
+(defcustom LaTeX-fill-break-at-separators nil
+ "List of separators before or after which respectively a line
+break will be inserted if they do not fit into one line."
+ :group 'LaTeX
+ :type '(set :tag "Contents"
+ (const :tag "Opening Brace" \{)
+ (const :tag "Closing Brace" \})
+ (const :tag "Opening Bracket" \[)
+ (const :tag "Opening Inline Math Switches" \\\()
+ (const :tag "Closing Inline Math Switches" \\\))
+ (const :tag "Opening Display Math Switch" \\\[)
+ (const :tag "Closing Display Math Switch" \\\])))
+
+(defcustom LaTeX-fill-break-before-code-comments t
+ "If non-nil, a line with some code followed by a comment will
+be broken before the last non-comment word in case the comment
+does not fit into the line."
+ :group 'LaTeX
+ :type 'boolean)
+
+(defvar LaTeX-nospace-between-char-regexp
+ (if (featurep 'xemacs)
+ (if (and (boundp 'word-across-newline) word-across-newline)
+ word-across-newline
+ ;; NOTE: Ensure not to have a value of nil for such a rare case that
+ ;; somebody removes the mule test in `LaTeX-fill-delete-newlines' so that
+ ;; it could match only "\n" and this could lead to problem. XEmacs does
+ ;; not have a category `\c|' and `\ct' means `Chinese Taiwan' in XEmacs.
+ "\\(\\cj\\|\\cc\\|\\ct\\)")
+ "\\c|")
+ "Regexp matching a character where no interword space is necessary.
+Words formed by such characters can be broken across newlines.")
+
+(defvar LaTeX-fill-newline-hook nil
+ "Hook run after `LaTeX-fill-newline' inserted and indented a new line.")
+
+(defun LaTeX-fill-region-as-paragraph (from to &optional justify-flag)
+ "Fill region as one paragraph.
+Break lines to fit `fill-column', but leave all lines ending with
+\\\\ \(plus its optional argument) alone. Lines with code
+comments and lines ending with `\par' are included in filling but
+act as boundaries. Prefix arg means justify too. From program,
+pass args FROM, TO and JUSTIFY-FLAG."
+ (interactive "*r\nP")
+ (let ((end-marker (save-excursion (goto-char to) (point-marker))))
+ (if (or (assoc (LaTeX-current-environment) LaTeX-indent-environment-list)
+ ;; This could be generalized, if there are more cases where
+ ;; a special string at the start of a region to fill should
+ ;; inhibit filling.
+ (progn (save-excursion (goto-char from)
+ (looking-at (concat TeX-comment-start-regexp
+ "+[ \t]*"
+ "Local Variables:")))))
+ ;; Filling disabled, only do indentation.
+ (indent-region from to nil)
+ (save-restriction
+ (goto-char from)
+ (while (< (point) end-marker)
+ (if (re-search-forward
+ (concat "\\("
+ ;; Code comments.
+ "[^\r\n%\\]\\([ \t]\\|\\\\\\\\\\)*"
+ TeX-comment-start-regexp
+ "\\|"
+ ;; Lines ending with `\par'.
+ "\\(\\=\\|[^" TeX-esc "\n]\\)\\("
+ (regexp-quote (concat TeX-esc TeX-esc))
+ "\\)*"
+ (regexp-quote TeX-esc) "par[ \t]*"
+ "\\({[ \t]*}\\)?[ \t]*$"
+ "\\)\\|\\("
+ ;; Lines ending with `\\'.
+ (regexp-quote TeX-esc)
+ (regexp-quote TeX-esc)
+ "\\(\\s-*\\*\\)?"
+ "\\(\\s-*\\[[^]]*\\]\\)?"
+ "\\s-*$\\)")
+ end-marker t)
+ (progn
+ (goto-char (line-end-position))
+ (delete-horizontal-space)
+ ;; I doubt very much if we want justify -
+ ;; this is a line with \\
+ ;; if you think otherwise - uncomment the next line
+ ;; (and justify-flag (justify-current-line))
+ (forward-char)
+ ;; keep our position in a buffer
+ (save-excursion
+ ;; Code comments and lines ending with `\par' are
+ ;; included in filling. Lines ending with `\\' are
+ ;; skipped.
+ (if (match-string 1)
+ (LaTeX-fill-region-as-para-do from (point) justify-flag)
+ (LaTeX-fill-region-as-para-do
+ from (line-beginning-position 0) justify-flag)
+ ;; At least indent the line ending with `\\'.
+ (indent-according-to-mode)))
+ (setq from (point)))
+ ;; ELSE part follows - loop termination relies on a fact
+ ;; that (LaTeX-fill-region-as-para-do) moves point past
+ ;; the filled region
+ (LaTeX-fill-region-as-para-do from end-marker justify-flag)))))))
+
+;; The content of `LaTeX-fill-region-as-para-do' was copied from the
+;; function `fill-region-as-paragraph' in `fill.el' (CVS Emacs,
+;; January 2004) and adapted to the needs of AUCTeX.
+
+(defun LaTeX-fill-region-as-para-do (from to &optional justify
+ nosqueeze squeeze-after)
+ "Fill the region defined by FROM and TO as one paragraph.
+It removes any paragraph breaks in the region and extra newlines at the end,
+indents and fills lines between the margins given by the
+`current-left-margin' and `current-fill-column' functions.
+\(In most cases, the variable `fill-column' controls the width.)
+It leaves point at the beginning of the line following the paragraph.
+
+Normally performs justification according to the `current-justification'
+function, but with a prefix arg, does full justification instead.
+
+From a program, optional third arg JUSTIFY can specify any type of
+justification. Fourth arg NOSQUEEZE non-nil means not to make spaces
+between words canonical before filling. Fifth arg SQUEEZE-AFTER, if non-nil,
+means don't canonicalize spaces before that position.
+
+Return the `fill-prefix' used for filling.
+
+If `sentence-end-double-space' is non-nil, then period followed by one
+space does not end a sentence, so don't break a line there."
+ (interactive (progn
+ (barf-if-buffer-read-only)
+ (list (region-beginning) (region-end)
+ (if current-prefix-arg 'full))))
+ (unless (memq justify '(t nil none full center left right))
+ (setq justify 'full))
+
+ ;; Make sure "to" is the endpoint.
+ (goto-char (min from to))
+ (setq to (max from to))
+ ;; Ignore blank lines at beginning of region.
+ (skip-chars-forward " \t\n")
+
+ (let ((from-plus-indent (point))
+ (oneleft nil))
+
+ (beginning-of-line)
+ (setq from (point))
+
+ ;; Delete all but one soft newline at end of region.
+ ;; And leave TO before that one.
+ (goto-char to)
+ (while (and (> (point) from) (eq ?\n (char-after (1- (point)))))
+ (if (and oneleft
+ (not (and use-hard-newlines
+ (get-text-property (1- (point)) 'hard))))
+ (delete-backward-char 1)
+ (backward-char 1)
+ (setq oneleft t)))
+ (setq to (copy-marker (point) t))
+ (goto-char from-plus-indent))
+
+ (if (not (> to (point)))
+ nil ;; There is no paragraph, only whitespace: exit now.
+
+ (or justify (setq justify (current-justification)))
+
+ ;; Don't let Adaptive Fill mode alter the fill prefix permanently.
+ (let ((fill-prefix fill-prefix))
+ ;; Figure out how this paragraph is indented, if desired.
+ (when (and adaptive-fill-mode
+ (or (null fill-prefix) (string= fill-prefix "")))
+ (setq fill-prefix (fill-context-prefix from to))
+ ;; Ignore a white-space only fill-prefix
+ ;; if we indent-according-to-mode.
+ (when (and fill-prefix fill-indent-according-to-mode
+ (string-match "\\`[ \t]*\\'" fill-prefix))
+ (setq fill-prefix nil)))
+
+ (goto-char from)
+ (beginning-of-line)
+
+ (if (not justify) ; filling disabled: just check indentation
+ (progn
+ (goto-char from)
+ (while (< (point) to)
+ (if (and (not (eolp))
+ (< (LaTeX-current-indentation) (current-left-margin)))
+ (fill-indent-to-left-margin))
+ (forward-line 1)))
+
+ (when use-hard-newlines
+ (remove-text-properties from to '(hard nil)))
+ ;; Make sure first line is indented (at least) to left margin...
+ (indent-according-to-mode)
+ ;; COMPATIBILITY for Emacs <= 21.1
+ (if (fboundp 'fill-delete-prefix)
+ ;; Delete the fill-prefix from every line.
+ (fill-delete-prefix from to fill-prefix)
+ ;; Delete the comment prefix and any whitespace from every
+ ;; line of the region in concern except the first. (The
+ ;; implementation is heuristic to a certain degree.)
+ (save-excursion
+ (goto-char from)
+ (forward-line 1)
+ (when (< (point) to)
+ (while (re-search-forward (concat "^[ \t]+\\|^[ \t]*"
+ TeX-comment-start-regexp
+ "+[ \t]*") to t)
+ (delete-region (match-beginning 0) (match-end 0))))))
+
+ (setq from (point))
+
+ ;; FROM, and point, are now before the text to fill,
+ ;; but after any fill prefix on the first line.
+
+ (LaTeX-fill-delete-newlines from to justify nosqueeze squeeze-after)
+
+ ;; This is the actual FILLING LOOP.
+ (goto-char from)
+ (let* (linebeg
+ (code-comment-start (save-excursion
+ (LaTeX-back-to-indentation)
+ (TeX-search-forward-comment-start
+ (line-end-position))))
+ (end-marker (save-excursion
+ (goto-char (or code-comment-start to))
+ (point-marker)))
+ (LaTeX-current-environment (LaTeX-current-environment)))
+ ;; Fill until point is greater than the end point. If there
+ ;; is a code comment, use the code comment's start as a
+ ;; limit.
+ (while (and (< (point) (marker-position end-marker))
+ (or (not code-comment-start)
+ (and code-comment-start
+ (> (- (marker-position end-marker)
+ (line-beginning-position))
+ fill-column))))
+ (setq linebeg (point))
+ (move-to-column (current-fill-column))
+ (if (when (< (point) (marker-position end-marker))
+ ;; Find the position where we'll break the line.
+ (forward-char 1) ; Use an immediately following
+ ; space, if any.
+ (LaTeX-fill-move-to-break-point linebeg)
+
+ ;; Check again to see if we got to the end of
+ ;; the paragraph.
+ (skip-chars-forward " \t")
+ (< (point) (marker-position end-marker)))
+ ;; Found a place to cut.
+ (progn
+ (LaTeX-fill-newline)
+ (when justify
+ ;; Justify the line just ended, if desired.
+ (save-excursion
+ (forward-line -1)
+ (justify-current-line justify nil t))))
+
+ (goto-char end-marker)
+ ;; Justify this last line, if desired.
+ (if justify (justify-current-line justify t t))))
+
+ ;; Fill a code comment if necessary. (Enable this code if
+ ;; you want the comment part in lines with code comments to
+ ;; be filled. Originally it was disabled because the
+ ;; indentation code indented the lines following the line
+ ;; with the code comment to the column of the comment
+ ;; starters. That means, it would have looked like this:
+ ;; | code code code % comment
+ ;; | % comment
+ ;; | code code code
+ ;; This now (2005-07-29) is not the case anymore. But as
+ ;; filling code comments like this would split a single
+ ;; paragraph into two separate ones, we still leave it
+ ;; disabled. I leave the code here in case it is useful for
+ ;; somebody.
+ ;; (when (and code-comment-start
+ ;; (> (- (line-end-position) (line-beginning-position))
+ ;; fill-column))
+ ;; (LaTeX-fill-code-comment justify))
+
+ ;; The following is an alternative strategy to minimize the
+ ;; occurence of overfull lines with code comments. A line
+ ;; will be broken before the last non-comment word if the
+ ;; code comment does not fit into the line.
+ (when (and LaTeX-fill-break-before-code-comments
+ code-comment-start
+ (> (- (line-end-position) (line-beginning-position))
+ fill-column))
+ (beginning-of-line)
+ (goto-char end-marker)
+ (while (not (looking-at TeX-comment-start-regexp)) (forward-char))
+ (skip-chars-backward " \t")
+ (skip-chars-backward "^ \t\n")
+ (unless (or (bolp)
+ ;; Comment starters and whitespace.
+ (TeX-looking-at-backward
+ (concat "^\\([ \t]*" TeX-comment-start-regexp
+ "+\\)+[ \t]*")
+ (line-beginning-position)))
+ (LaTeX-fill-newline)))))
+ ;; Leave point after final newline.
+ (goto-char to)
+ (unless (eobp) (forward-char 1))
+ ;; Return the fill-prefix we used
+ fill-prefix)))
+
+;; Following lines are copied from `fill.el' (CVS Emacs, March 2005).
+;; The `fill-space' property carries the string with which a newline should be
+;; replaced when unbreaking a line (in fill-delete-newlines). It is added to
+;; newline characters by fill-newline when the default behavior of
+;; fill-delete-newlines is not what we want.
+(unless (featurep 'xemacs)
+ ;; COMPATIBILITY for Emacs < 22.1
+ (add-to-list 'text-property-default-nonsticky '(fill-space . t)))
+
+(defun LaTeX-fill-delete-newlines (from to justify nosqueeze squeeze-after)
+ ;; COMPATIBILITY for Emacs < 22.1 and XEmacs
+ (if (fboundp 'fill-delete-newlines)
+ (fill-delete-newlines from to justify nosqueeze squeeze-after)
+ (if (featurep 'xemacs)
+ (when (featurep 'mule)
+ (goto-char from)
+ (let ((unwished-newline (concat LaTeX-nospace-between-char-regexp "\n"
+ LaTeX-nospace-between-char-regexp)))
+ (while (re-search-forward unwished-newline to t)
+ (skip-chars-backward "^\n")
+ (delete-char -1))))
+ ;; This else-sentence was copied from the function `fill-delete-newlines'
+ ;; in `fill.el' (CVS Emacs, 2005-02-17) and adapted accordingly.
+ (while (search-forward "\n" to t)
+ (if (get-text-property (match-beginning 0) 'fill-space)
+ (replace-match (get-text-property (match-beginning 0) 'fill-space))
+ (let ((prev (char-before (match-beginning 0)))
+ (next (following-char)))
+ (when (or (aref (char-category-set next) ?|)
+ (aref (char-category-set prev) ?|))
+ (delete-char -1))))))
+
+ ;; Make sure sentences ending at end of line get an extra space.
+ (if (or (not (boundp 'sentence-end-double-space))
+ sentence-end-double-space)
+ (progn
+ (goto-char from)
+ (while (re-search-forward "[.?!][]})\"']*$" to t)
+ (insert ? ))))
+ ;; Then change all newlines to spaces.
+ (let ((point-max (progn
+ (goto-char to)
+ (skip-chars-backward "\n")
+ (point))))
+ (subst-char-in-region from point-max ?\n ?\ ))
+ (goto-char from)
+ (skip-chars-forward " \t")
+ ;; Remove extra spaces between words.
+ (unless (and nosqueeze (not (eq justify 'full)))
+ (canonically-space-region (or squeeze-after (point)) to)
+ ;; Remove trailing whitespace.
+ (goto-char (line-end-position))
+ (delete-char (- (skip-chars-backward " \t"))))))
+
+(defun LaTeX-fill-move-to-break-point (linebeg)
+ "Move to the position where the line should be broken."
+ ;; COMPATIBILITY for Emacs < 22.1 and XEmacs
+ (if (fboundp 'fill-move-to-break-point)
+ (fill-move-to-break-point linebeg)
+ (if (featurep 'mule)
+ (if (TeX-looking-at-backward
+ (concat LaTeX-nospace-between-char-regexp ".?") 2)
+ ;; Cancel `forward-char' which is called just before
+ ;; `LaTeX-fill-move-to-break-point' if the char before point matches
+ ;; `LaTeX-nospace-between-char-regexp'.
+ (backward-char 1)
+ (when (re-search-backward
+ (concat " \\|\n\\|" LaTeX-nospace-between-char-regexp)
+ linebeg 'move)
+ (forward-char 1)))
+ (skip-chars-backward "^ \n"))
+ ;; Prevent infinite loops: If we cannot find a place to break
+ ;; while searching backward, search forward again.
+ (when (save-excursion
+ (skip-chars-backward " \t%")
+ (bolp))
+ (skip-chars-forward "^ \n" (point-max)))
+ ;; This code was copied from the function `fill-move-to-break-point'
+ ;; in `fill.el' (CVS Emacs, 2005-02-22) and adapted accordingly.
+ (when (and (< linebeg (point))
+ ;; If we are going to break the line after or
+ ;; before a non-ascii character, we may have to
+ ;; run a special function for the charset of the
+ ;; character to find the correct break point.
+ (boundp 'enable-multibyte-characters)
+ enable-multibyte-characters
+ (fboundp 'charset-after) ; Non-MULE XEmacsen don't have this.
+ (not (and (eq (charset-after (1- (point))) 'ascii)
+ (eq (charset-after (point)) 'ascii))))
+ ;; Make sure we take SOMETHING after the fill prefix if any.
+ (if (fboundp 'fill-find-break-point)
+ (fill-find-break-point linebeg)
+ (when (fboundp 'kinsoku-process) ;XEmacs
+ (kinsoku-process)))))
+ ;; Prevent line break between 2-byte char and 1-byte char.
+ (when (and (featurep 'mule)
+ enable-multibyte-characters
+ (or (and (not (looking-at LaTeX-nospace-between-char-regexp))
+ (TeX-looking-at-backward
+ LaTeX-nospace-between-char-regexp 1))
+ (and (not (TeX-looking-at-backward
+ LaTeX-nospace-between-char-regexp 1))
+ (looking-at LaTeX-nospace-between-char-regexp)))
+ (re-search-backward
+ (concat LaTeX-nospace-between-char-regexp
+ LaTeX-nospace-between-char-regexp
+ LaTeX-nospace-between-char-regexp
+ "\\|"
+ ".\\ca\\s +\\ca") linebeg t))
+ (if (looking-at "..\\c>")
+ (forward-char 1)
+ (forward-char 2)))
+ ;; Cater for Japanese Macro
+ (when (and (boundp 'japanese-TeX-mode) japanese-TeX-mode
+ (aref (char-category-set (char-after)) ?j)
+ (TeX-looking-at-backward (concat (regexp-quote TeX-esc) TeX-token-char "*")
+ (1- (- (point) linebeg)))
+ (not (TeX-escaped-p (match-beginning 0))))
+ (goto-char (match-beginning 0)))
+ ;; Cater for \verb|...| (and similar) contructs which should not be
+ ;; broken. (FIXME: Make it work with shortvrb.sty (also loaded by
+ ;; doc.sty) where |...| is allowed. Arbitrary delimiters may be
+ ;; chosen with \MakeShortVerb{<char>}.) This could probably be
+ ;; handled with `fill-nobreak-predicate', but this is not available
+ ;; in XEmacs.
+ (let ((final-breakpoint (point))
+ (verb-macros (regexp-opt (append (LaTeX-verbatim-macros-with-delims)
+ (LaTeX-verbatim-macros-with-braces)))))
+ (save-excursion
+ ;; Look for the start of a verbatim macro in the current line.
+ (when (re-search-backward (concat (regexp-quote TeX-esc)
+ "\\(?:" verb-macros "\\)\\([^a-z@*]\\)")
+ (line-beginning-position) t)
+ ;; Determine start and end of verbatim macro.
+ (let ((beg (point))
+ (end (if (not (string-match "[ [{]" (match-string 1)))
+ (cdr (LaTeX-verbatim-macro-boundaries))
+ (TeX-find-macro-end))))
+ ;; Determine if macro end is behind fill column.
+ (when (and end
+ (> (- end (line-beginning-position))
+ (current-fill-column))
+ (> end final-breakpoint))
+ ;; Search backwards for place to break before the macro.
+ (goto-char beg)
+ (skip-chars-backward "^ \n")
+ ;; Determine if point ended up at the beginning of the line.
+ (when (save-excursion (skip-chars-backward " \t%") (bolp))
+ ;; Search forward for a place to break after the macro.
+ (goto-char end)
+ (skip-chars-forward "^ \n" (point-max)))
+ (setq final-breakpoint (point))))))
+ (goto-char final-breakpoint))
+ (when LaTeX-fill-break-at-separators
+ (let ((orig-breakpoint (point))
+ (final-breakpoint (point))
+ start-point
+ math-sep)
+ (save-excursion
+ (beginning-of-line)
+ (LaTeX-back-to-indentation)
+ (setq start-point (point))
+ ;; Find occurences of [, $, {, }, \(, \), \[, \] or $$.
+ (while (and (= final-breakpoint orig-breakpoint)
+ (TeX-re-search-forward-unescaped
+ (concat "[[{}]\\|\\$\\$?\\|"
+ (regexp-quote TeX-esc) "[][()]")
+ orig-breakpoint t))
+ (let ((match-string (match-string 0)))
+ (cond
+ ;; [ (opening bracket) (The closing bracket should
+ ;; already be handled implicitely by the code for the
+ ;; opening brace.)
+ ((save-excursion
+ (and (memq '\[ LaTeX-fill-break-at-separators)
+ (string= match-string "[")
+ (TeX-re-search-forward-unescaped (concat "\\][ \t]*{")
+ (line-end-position) t)
+ (> (- (or (TeX-find-closing-brace)
+ (line-end-position))
+ (line-beginning-position))
+ fill-column)))
+ (save-excursion
+ (skip-chars-backward "^ \n")
+ (when (> (point) start-point)
+ (setq final-breakpoint (point)))))
+ ;; { (opening brace)
+ ((save-excursion
+ (and (memq '\{ LaTeX-fill-break-at-separators)
+ (string= match-string "{")
+ (> (- (save-excursion
+ ;; `TeX-find-closing-brace' is not enough
+ ;; if there is no breakpoint in form of
+ ;; whitespace after the brace.
+ (goto-char (or (TeX-find-closing-brace)
+ (line-end-position)))
+ (skip-chars-forward "^ \t\n")
+ (point))
+ (line-beginning-position))
+ fill-column)))
+ (save-excursion
+ (skip-chars-backward "^ \n")
+ ;; The following is a primitive and error-prone method
+ ;; to cope with point probably being inside square
+ ;; brackets. A better way would be to use functions
+ ;; to determine if point is inside an optional
+ ;; argument and to jump to the start and end brackets.
+ (when (save-excursion
+ (TeX-re-search-forward-unescaped
+ (concat "\\][ \t]*{") orig-breakpoint t))
+ (TeX-search-backward-unescaped "["
+ (line-beginning-position) t)
+ (skip-chars-backward "^ \n"))
+ (when (> (point) start-point)
+ (setq final-breakpoint (point)))))
+ ;; } (closing brace)
+ ((save-excursion
+ (and (memq '\} LaTeX-fill-break-at-separators)
+ (string= match-string "}")
+ (save-excursion
+ (backward-char 2)
+ (not (TeX-find-opening-brace
+ nil (line-beginning-position))))))
+ (save-excursion
+ (skip-chars-forward "^ \n")
+ (when (> (point) start-point)
+ (setq final-breakpoint (point)))))
+ ;; $ or \( or \[ or $$ (opening math)
+ ((save-excursion
+ (and (or (and (memq '\\\( LaTeX-fill-break-at-separators)
+ (or (and (string= match-string "$")
+ (texmathp))
+ (string= match-string "\\(")))
+ (and (memq '\\\[ LaTeX-fill-break-at-separators)
+ (or (string= match-string "\\[")
+ (and (string= match-string "$$")
+ (texmathp)))))
+ (> (- (save-excursion
+ (TeX-search-forward-unescaped
+ (cond ((string= match-string "\\(")
+ (concat TeX-esc ")"))
+ ((string= match-string "$") "$")
+ ((string= match-string "$$") "$$")
+ (t (concat TeX-esc "]")))
+ (point-max) t)
+ (point))
+ (line-beginning-position))
+ fill-column)))
+ (save-excursion
+ (skip-chars-backward "^ \n")
+ (when (> (point) start-point)
+ (setq final-breakpoint (point)))))
+ ;; $ or \) or \] or $$ (closing math)
+ ((save-excursion
+ (and (or (and (memq '\\\) LaTeX-fill-break-at-separators)
+ (or (and (string= match-string "$")
+ (not (texmathp)))
+ (string= match-string "\\)")))
+ (and (memq '\\\] LaTeX-fill-break-at-separators)
+ (or (string= match-string "\\]")
+ (and (string= match-string "$$")
+ (not (texmathp))))))
+ (if (member match-string '("$" "$$"))
+ (save-excursion
+ (skip-chars-backward "$")
+ (not (TeX-search-backward-unescaped
+ match-string (line-beginning-position) t)))
+ (texmathp-match-switch (line-beginning-position)))))
+ (save-excursion
+ (skip-chars-forward "^ \n")
+ (when (> (point) start-point)
+ (setq final-breakpoint (point)))))))))
+ (goto-char final-breakpoint))))
+
+;; The content of `LaTeX-fill-newline' was copied from the function
+;; `fill-newline' in `fill.el' (CVS Emacs, January 2004) and adapted
+;; to the needs of AUCTeX.
+(defun LaTeX-fill-newline ()
+ "Replace whitespace here with one newline and indent the line."
+ (skip-chars-backward " \t")
+ (newline 1)
+ ;; COMPATIBILITY for XEmacs
+ (unless (featurep 'xemacs)
+ ;; Give newline the properties of the space(s) it replaces
+ (set-text-properties (1- (point)) (point)
+ (text-properties-at (point)))
+ (and (looking-at "\\( [ \t]*\\)\\(\\c|\\)?")
+ (or (aref (char-category-set (or (char-before (1- (point))) ?\000)) ?|)
+ (match-end 2))
+ ;; When refilling later on, this newline would normally not
+ ;; be replaced by a space, so we need to mark it specially to
+ ;; re-install the space when we unfill.
+ (put-text-property (1- (point)) (point) 'fill-space (match-string 1)))
+ ;; COMPATIBILITY for Emacs <= 21.3
+ (when (boundp 'fill-nobreak-invisible)
+ ;; If we don't want breaks in invisible text, don't insert
+ ;; an invisible newline.
+ (if fill-nobreak-invisible
+ (remove-text-properties (1- (point)) (point)
+ '(invisible t)))))
+ ;; Insert the fill prefix.
+ (and fill-prefix (not (equal fill-prefix ""))
+ ;; Markers that were after the whitespace are now at point: insert
+ ;; before them so they don't get stuck before the prefix.
+ (insert-before-markers-and-inherit fill-prefix))
+ (indent-according-to-mode)
+ (run-hooks 'LaTeX-fill-newline-hook))
+
+(defun LaTeX-fill-paragraph (&optional justify)
+ "Like `fill-paragraph', but handle LaTeX comments.
+If any of the current line is a comment, fill the comment or the
+paragraph of it that point is in. Code comments, i.e. comments
+with uncommented code preceding them in the same line, will not
+be filled unless the cursor is placed on the line with the
+code comment.
+
+If LaTeX syntax is taken into consideration during filling
+depends on the value of `LaTeX-syntactic-comments'."
+ (interactive "P")
+ (if (save-excursion
+ (beginning-of-line)
+ (looking-at (concat TeX-comment-start-regexp "*[ \t]*$")))
+ ;; Don't do anything if we look at an empty line and let
+ ;; `fill-paragraph' think we successfully filled the paragraph.
+ t
+ (let (;; Non-nil if the current line contains a comment.
+ has-comment
+ ;; Non-nil if the current line contains code and a comment.
+ has-code-and-comment
+ code-comment-start
+ ;; If has-comment, the appropriate fill-prefix for the comment.
+ comment-fill-prefix)
+
+ ;; Figure out what kind of comment we are looking at.
+ (cond
+ ;; A line only with potential whitespace followed by a
+ ;; comment on it?
+ ((save-excursion
+ (beginning-of-line)
+ (looking-at (concat "^[ \t]*" TeX-comment-start-regexp
+ "\\(" TeX-comment-start-regexp "\\|[ \t]\\)*")))
+ (setq has-comment t
+ comment-fill-prefix (TeX-match-buffer 0)))
+ ;; A line with some code, followed by a comment?
+ ((and (setq code-comment-start (save-excursion
+ (beginning-of-line)
+ (TeX-search-forward-comment-start
+ (line-end-position))))
+ (> (point) code-comment-start)
+ (not (TeX-in-commented-line))
+ (save-excursion
+ (goto-char code-comment-start)
+ ;; See if there is at least one non-whitespace character
+ ;; before the comment starts.
+ (re-search-backward "[^ \t\n]" (line-beginning-position) t)))
+ (setq has-comment t
+ has-code-and-comment t)))
+
+ (cond
+ ;; Code comments.
+ (has-code-and-comment
+ (save-excursion
+ (when (>= (- code-comment-start (line-beginning-position))
+ fill-column)
+ ;; If start of code comment is beyond fill column, fill it as a
+ ;; regular paragraph before it is filled as a code comment.
+ (let ((end-marker (save-excursion (end-of-line) (point-marker))))
+ (LaTeX-fill-region-as-paragraph (line-beginning-position)
+ (line-beginning-position 2)
+ justify)
+ (goto-char end-marker)
+ (beginning-of-line)))
+ (LaTeX-fill-code-comment justify)))
+ ;; Syntax-aware filling:
+ ;; * `LaTeX-syntactic-comments' enabled: Everything.
+ ;; * `LaTeX-syntactic-comments' disabled: Uncommented code and
+ ;; line comments in `doctex-mode'.
+ ((or (or LaTeX-syntactic-comments
+ (and (not LaTeX-syntactic-comments)
+ (not has-comment)))
+ (and (eq major-mode 'doctex-mode)
+ (TeX-in-line-comment)))
+ (let ((fill-prefix comment-fill-prefix))
+ (save-excursion
+ (let* ((end (progn (LaTeX-forward-paragraph)
+ (or (bolp) (newline 1))
+ (and (eobp) (not (bolp)) (open-line 1))
+ (point)))
+ (start
+ (progn
+ (LaTeX-backward-paragraph)
+ (while (and (looking-at
+ (concat "$\\|[ \t]+$\\|"
+ "[ \t]*" TeX-comment-start-regexp
+ "+[ \t]*$"))
+ (< (point) end))
+ (forward-line))
+ (point))))
+ (LaTeX-fill-region-as-paragraph start end justify)))))
+ ;; Non-syntax-aware filling.
+ (t
+ (save-excursion
+ (save-restriction
+ (beginning-of-line)
+ (narrow-to-region
+ ;; Find the first line we should include in the region to fill.
+ (save-excursion
+ (while (and (zerop (forward-line -1))
+ (looking-at (concat "^[ \t]*"
+ TeX-comment-start-regexp))))
+ ;; We may have gone too far. Go forward again.
+ (or (looking-at (concat ".*" TeX-comment-start-regexp))
+ (forward-line 1))
+ (point))
+ ;; Find the beginning of the first line past the region to fill.
+ (save-excursion
+ (while (progn (forward-line 1)
+ (looking-at (concat "^[ \t]*"
+ TeX-comment-start-regexp))))
+ (point)))
+ ;; The definitions of `paragraph-start' and
+ ;; `paragraph-separate' will still make
+ ;; `forward-paragraph' and `backward-paragraph' stop at
+ ;; the respective (La)TeX commands. If these should be
+ ;; disregarded, the definitions would have to be changed
+ ;; accordingly. (Lines with only `%' characters on them
+ ;; can be paragraph boundaries.)
+ (let* ((paragraph-start
+ (concat paragraph-start "\\|"
+ "\\(" TeX-comment-start-regexp "\\|[ \t]\\)*$"))
+ (paragraph-separate
+ (concat paragraph-separate "\\|"
+ "\\(" TeX-comment-start-regexp "\\|[ \t]\\)*$"))
+ (fill-prefix comment-fill-prefix)
+ (end (progn (forward-paragraph)
+ (or (bolp) (newline 1))
+ (point)))
+ (beg (progn (backward-paragraph)
+ (point))))
+ (fill-region-as-paragraph
+ beg end
+ justify nil
+ (save-excursion
+ (goto-char beg)
+ (if (looking-at fill-prefix)
+ nil
+ (re-search-forward comment-start-skip nil t)
+ (point)))))))))
+ t)))
+
+(defun LaTeX-fill-code-comment (&optional justify-flag)
+ "Fill a line including code followed by a comment."
+ (let ((beg (line-beginning-position))
+ fill-prefix code-comment-start)
+ (indent-according-to-mode)
+ (when (when (setq code-comment-start (save-excursion
+ (goto-char beg)
+ (TeX-search-forward-comment-start
+ (line-end-position))))
+ (goto-char code-comment-start)
+ (while (not (looking-at TeX-comment-start-regexp)) (forward-char))
+ ;; See if there is at least one non-whitespace character
+ ;; before the comment starts.
+ (save-excursion
+ (re-search-backward "[^ \t\n]" (line-beginning-position) t)))
+ (setq fill-prefix
+ (concat
+ (if indent-tabs-mode
+ (concat (make-string (/ (current-column) tab-width) ?\t)
+ (make-string (% (current-column) tab-width) ?\ ))
+ (make-string (current-column) ?\ ))
+ (progn
+ (looking-at (concat TeX-comment-start-regexp "+[ \t]*"))
+ (TeX-match-buffer 0))))
+ (fill-region-as-paragraph beg (line-beginning-position 2)
+ justify-flag nil
+ (save-excursion
+ (goto-char beg)
+ (if (looking-at fill-prefix)
+ nil
+ (re-search-forward comment-start-skip nil t)
+ (point)))))))
+
+(defun LaTeX-fill-region (from to &optional justify what)
+ "Fill and indent the text in region from FROM to TO as LaTeX text.
+Prefix arg (non-nil third arg JUSTIFY, if called from program)
+means justify as well. Fourth arg WHAT is a word to be displayed when
+formatting."
+ (interactive "*r\nP")
+ (save-excursion
+ (let ((to (set-marker (make-marker) to))
+ (next-par (make-marker)))
+ (goto-char from)
+ (beginning-of-line)
+ (setq from (point))
+ (catch 'end-of-buffer
+ (while (and (< (point) to))
+ (message "Formatting%s ... %d%%"
+ (or what "")
+ (/ (* 100 (- (point) from)) (- to from)))
+ (save-excursion (LaTeX-fill-paragraph justify))
+ (if (marker-position next-par)
+ (goto-char (marker-position next-par))
+ (LaTeX-forward-paragraph))
+ (when (eobp) (throw 'end-of-buffer t))
+ (LaTeX-forward-paragraph)
+ (set-marker next-par (point))
+ (LaTeX-backward-paragraph)
+ (while (and (not (eobp))
+ (looking-at
+ (concat "^\\($\\|[ \t]+$\\|[ \t]*"
+ TeX-comment-start-regexp "+[ \t]*$\\)")))
+ (forward-line 1))))
+ (set-marker to nil)))
+ (message "Finished"))
+
+(defun LaTeX-find-matching-end ()
+ "Move point to the \\end of the current environment.
+
+If function is called inside a comment and
+`LaTeX-syntactic-comments' is enabled, try to find the
+environment in commented regions with the same comment prefix."
+ (interactive)
+ (let* ((regexp (concat (regexp-quote TeX-esc) "\\(begin\\|end\\)\\b"))
+ (level 1)
+ (in-comment (TeX-in-commented-line))
+ (comment-prefix (and in-comment (TeX-comment-prefix))))
+ (save-excursion
+ (skip-chars-backward "a-zA-Z \t{")
+ (unless (bolp)
+ (backward-char 1)
+ (and (looking-at regexp)
+ (char-equal (char-after (1+ (match-beginning 0))) ?e)
+ (setq level 0))))
+ (while (and (> level 0) (re-search-forward regexp nil t))
+ (when (or (and LaTeX-syntactic-comments
+ (eq in-comment (TeX-in-commented-line))
+ ;; If we are in a commented line, check if the
+ ;; prefix matches the one we started out with.
+ (or (not in-comment)
+ (string= comment-prefix (TeX-comment-prefix))))
+ (and (not LaTeX-syntactic-comments)
+ (not (TeX-in-commented-line))))
+ (if (= (char-after (1+ (match-beginning 0))) ?b) ;;begin
+ (setq level (1+ level))
+ (setq level (1- level)))))
+ (if (= level 0)
+ (search-forward "}")
+ (error "Can't locate end of current environment"))))
+
+(defun LaTeX-find-matching-begin ()
+ "Move point to the \\begin of the current environment.
+
+If function is called inside a comment and
+`LaTeX-syntactic-comments' is enabled, try to find the
+environment in commented regions with the same comment prefix."
+ (interactive)
+ (let* ((regexp (concat (regexp-quote TeX-esc) "\\(begin\\|end\\)\\b"))
+ (level 1)
+ (in-comment (TeX-in-commented-line))
+ (comment-prefix (and in-comment (TeX-comment-prefix))))
+ (skip-chars-backward "a-zA-Z \t{")
+ (unless (bolp)
+ (backward-char 1)
+ (and (looking-at regexp)
+ (char-equal (char-after (1+ (match-beginning 0))) ?b)
+ (setq level 0)))
+ (while (and (> level 0) (re-search-backward regexp nil t))
+ (when (or (and LaTeX-syntactic-comments
+ (eq in-comment (TeX-in-commented-line))
+ ;; If we are in a commented line, check if the
+ ;; prefix matches the one we started out with.
+ (or (not in-comment)
+ (string= comment-prefix (TeX-comment-prefix))))
+ (and (not LaTeX-syntactic-comments)
+ (not (TeX-in-commented-line))))
+ (if (= (char-after (1+ (match-beginning 0))) ?e) ;;end
+ (setq level (1+ level))
+ (setq level (1- level)))))
+ (or (= level 0)
+ (error "Can't locate beginning of current environment"))))
+
+(defun LaTeX-mark-environment (&optional count)
+ "Set mark to end of current environment and point to the matching begin.
+If prefix argument COUNT is given, mark the respective number of
+enclosing environments. The command will not work properly if
+there are unbalanced begin-end pairs in comments and verbatim
+environments."
+ (interactive "p")
+ (setq count (if count (abs count) 1))
+ (let ((cur (point)) beg end)
+ ;; Only change point and mark after beginning and end were found.
+ ;; Point should not end up in the middle of nowhere if the search fails.
+ (save-excursion
+ (dotimes (c count) (LaTeX-find-matching-end))
+ (setq end (line-beginning-position 2))
+ (goto-char cur)
+ (dotimes (c count) (LaTeX-find-matching-begin))
+ (setq beg (point)))
+ (set-mark end)
+ (goto-char beg)
+ (TeX-activate-region)))
+
+(defun LaTeX-fill-environment (justify)
+ "Fill and indent current environment as LaTeX text."
+ (interactive "*P")
+ (save-excursion
+ (LaTeX-mark-environment)
+ (re-search-forward "{\\([^}]+\\)}")
+ (LaTeX-fill-region (region-beginning) (region-end) justify
+ (concat " environment " (TeX-match-buffer 1)))))
+
+(defun LaTeX-fill-section (justify)
+ "Fill and indent current logical section as LaTeX text."
+ (interactive "*P")
+ (save-excursion
+ (LaTeX-mark-section)
+ (re-search-forward "{\\([^}]+\\)}")
+ (LaTeX-fill-region (region-beginning) (region-end) justify
+ (concat " section " (TeX-match-buffer 1)))))
+
+(defun LaTeX-mark-section (&optional no-subsections)
+ "Set mark at end of current logical section, and point at top.
+If optional argument NO-SUBSECTIONS is non-nil, mark only the
+region from the current section start to the next sectioning
+command. Thereby subsections are not being marked.
+
+If the function `outline-mark-subtree' is not available,
+`LaTeX-mark-section' always behaves like this regardless of the
+value of NO-SUBSECTIONS."
+ (interactive "P")
+ (if (or no-subsections
+ (not (fboundp 'outline-mark-subtree)))
+ (progn
+ (re-search-forward (concat "\\(" (LaTeX-outline-regexp)
+ "\\|\\'\\)"))
+ (beginning-of-line)
+ (push-mark (point) nil t)
+ (re-search-backward (concat "\\(" (LaTeX-outline-regexp)
+ "\\|\\`\\)")))
+ (outline-mark-subtree)
+ (when (and (boundp 'transient-mark-mode)
+ transient-mark-mode
+ (boundp 'mark-active)
+ (not mark-active))
+ (setq mark-active t)
+ (run-hooks 'activate-mark-hook)))
+ (TeX-activate-region))
+
+(defun LaTeX-fill-buffer (justify)
+ "Fill and indent current buffer as LaTeX text."
+ (interactive "*P")
+ (save-excursion
+ (LaTeX-fill-region
+ (point-min)
+ (point-max)
+ justify
+ (concat " buffer " (buffer-name)))))
+
+
+;;; Navigation
+
+(defvar LaTeX-paragraph-commands-internal
+ '("[" "]" ; display math
+ "appendix" "begin" "caption" "chapter" "end" "include" "includeonly"
+ "label" "maketitle" "noindent" "par" "paragraph" "part" "section"
+ "subsection" "subsubsection" "tableofcontents")
+ "Internal list of LaTeX macros that should have their own line.")
+
+(defun LaTeX-paragraph-commands-regexp-make ()
+ "Return a regular expression matching defined paragraph commands."
+ (concat (regexp-quote TeX-esc) "\\("
+ (regexp-opt (append LaTeX-paragraph-commands
+ LaTeX-paragraph-commands-internal)) "\\)"))
+
+(defcustom LaTeX-paragraph-commands nil
+ "List of LaTeX macros that should have their own line.
+The list should contain macro names without the leading backslash."
+ :group 'LaTeX-macro
+ :type '(repeat (string))
+ :set (lambda (symbol value)
+ (set-default symbol value)
+ (setq LaTeX-paragraph-commands-regexp
+ (LaTeX-paragraph-commands-regexp-make))))
+
+(defvar LaTeX-paragraph-commands-regexp (LaTeX-paragraph-commands-regexp-make)
+ "Regular expression matching LaTeX macros that should have their own line.")
+
+(defun LaTeX-set-paragraph-start ()
+ "Set `paragraph-start'."
+ (setq paragraph-start
+ (concat
+ "[ \t]*%*[ \t]*\\("
+ LaTeX-paragraph-commands-regexp "\\|"
+ (regexp-quote TeX-esc) "\\(" LaTeX-item-regexp "\\)\\|"
+ "\\$\\$\\|" ; Plain TeX display math (Some people actually
+ ; use this with LaTeX. Yuck.)
+ "$\\)")))
+
+(defun LaTeX-paragraph-commands-add-locally (commands)
+ "Make COMMANDS be recognized as paragraph commands.
+COMMANDS can be a single string or a list of strings which will
+be added to `LaTeX-paragraph-commands-internal'. Additionally
+`LaTeX-paragraph-commands-regexp' will be updated and both
+variables will be made buffer-local. This is mainly a
+convenience function which can be used in style files."
+ (make-local-variable 'LaTeX-paragraph-commands-internal)
+ (make-local-variable 'LaTeX-paragraph-commands-regexp)
+ (unless (listp commands) (setq commands (list commands)))
+ (dolist (elt commands)
+ (add-to-list 'LaTeX-paragraph-commands-internal elt))
+ (setq LaTeX-paragraph-commands-regexp (LaTeX-paragraph-commands-regexp-make))
+ (LaTeX-set-paragraph-start))
+
+(defun LaTeX-forward-paragraph (&optional count)
+ "Move forward to end of paragraph.
+If COUNT is non-nil, do it COUNT times."
+ (or count (setq count 1))
+ (dotimes (i count)
+ (let* ((macro-start (TeX-find-macro-start))
+ (paragraph-command-start
+ (cond
+ ;; Point is inside of a paragraph command.
+ ((and macro-start
+ (save-excursion
+ (goto-char macro-start)
+ (looking-at LaTeX-paragraph-commands-regexp)))
+ (match-beginning 0))
+ ;; Point is before a paragraph command in the same line.
+ ((looking-at
+ (concat "[ \t]*\\(?:" TeX-comment-start-regexp
+ "\\(?:" TeX-comment-start-regexp "\\|[ \t]\\)*\\)?"
+ "\\(" LaTeX-paragraph-commands-regexp "\\)"))
+ (match-beginning 1))))
+ macro-end)
+ ;; If a paragraph command is encountered there are two cases to be
+ ;; distinguished:
+ ;; 1) If the end of the paragraph command coincides (apart from
+ ;; potential whitespace) with the end of the line, is only
+ ;; followed by a comment or is directly followed by a macro,
+ ;; it is assumed that it should be handled separately.
+ ;; 2) If the end of the paragraph command is followed by other
+ ;; code, it is assumed that it should be included with the rest
+ ;; of the paragraph.
+ (if (and paragraph-command-start
+ (save-excursion
+ (goto-char paragraph-command-start)
+ (setq macro-end (goto-char (TeX-find-macro-end)))
+ (looking-at (concat (regexp-quote TeX-esc) "[@A-Za-z]+\\|"
+ "[ \t]*\\($\\|"
+ TeX-comment-start-regexp "\\)"))))
+ (progn
+ (goto-char macro-end)
+ ;; If the paragraph command is followed directly by
+ ;; another macro, regard the latter as part of the
+ ;; paragraph command's paragraph.
+ (when (looking-at (concat (regexp-quote TeX-esc) "[@A-Za-z]+"))
+ (goto-char (TeX-find-macro-end)))
+ (forward-line))
+ (let (limit)
+ (goto-char (min (save-excursion
+ (forward-paragraph)
+ (setq limit (point)))
+ (save-excursion
+ (TeX-forward-comment-skip 1 limit)
+ (point)))))))))
+
+(defun LaTeX-backward-paragraph (&optional count)
+ "Move backward to beginning of paragraph.
+If COUNT is non-nil, do it COUNT times."
+ (or count (setq count 1))
+ (dotimes (i count)
+ (let* ((macro-start (TeX-find-macro-start)))
+ (if (and macro-start
+ ;; Point really has to be inside of the macro, not before it.
+ (not (= macro-start (point)))
+ (save-excursion
+ (goto-char macro-start)
+ (looking-at LaTeX-paragraph-commands-regexp)))
+ ;; Point is inside of a paragraph command.
+ (progn
+ (goto-char macro-start)
+ (beginning-of-line))
+ (let (limit
+ (start (line-beginning-position)))
+ (goto-char
+ (max (save-excursion
+ (backward-paragraph)
+ (setq limit (point)))
+ ;; Search for possible transitions from commented to
+ ;; uncommented regions and vice versa.
+ (save-excursion
+ (TeX-backward-comment-skip 1 limit)
+ (point))
+ ;; Search for paragraph commands.
+ (save-excursion
+ (let ((end-point 0) macro-bol)
+ (when (setq macro-bol
+ (re-search-backward
+ (format "^[ \t]*%s*[ \t]*\\(%s\\)"
+ TeX-comment-start-regexp
+ LaTeX-paragraph-commands-regexp)
+ limit t))
+ (if (and (string= (match-string 1) "\\begin")
+ (progn
+ (goto-char (match-end 1))
+ (skip-chars-forward "{ \t")
+ (member (buffer-substring-no-properties
+ (point) (progn (skip-chars-forward
+ "A-Za-z*") (point)))
+ LaTeX-verbatim-environments)))
+ ;; If inside a verbatim environment, just
+ ;; use the next line. In such environments
+ ;; `TeX-find-macro-end' could otherwise
+ ;; think brackets or braces belong to the
+ ;; \begin macro.
+ (setq end-point (line-beginning-position 2))
+ ;; Jump to the macro end otherwise.
+ (goto-char (match-beginning 1))
+ (goto-char (TeX-find-macro-end))
+ ;; For an explanation of this distinction see
+ ;; `LaTeX-forward-paragraph'.
+ (if (looking-at (concat (regexp-quote TeX-esc)
+ "[@A-Za-z]+\\|[ \t]*\\($\\|"
+ TeX-comment-start-regexp "\\)"))
+ (progn
+ (when (string= (buffer-substring-no-properties
+ (point) (+ (point)
+ (length TeX-esc)))
+ TeX-esc)
+ (goto-char (TeX-find-macro-end)))
+ (forward-line 1)
+ (when (< (point) start)
+ (setq end-point (point))))
+ (setq end-point macro-bol))))
+ end-point)))))))))
+
+(defun LaTeX-search-forward-comment-start (&optional limit)
+ "Search forward for a comment start from current position till LIMIT.
+If LIMIT is omitted, search till the end of the buffer.
+
+This function makes sure that any comment starters found inside
+of verbatim constructs are not considered."
+ (setq limit (or limit (point-max)))
+ (save-excursion
+ (let (start)
+ (catch 'found
+ (while (progn
+ (when (and (TeX-re-search-forward-unescaped
+ TeX-comment-start-regexp limit 'move)
+ (not (LaTeX-verbatim-p)))
+ (setq start (match-beginning 0))
+ (throw 'found t))
+ (< (point) limit))))
+ start)))
+
+
+;;; Math Minor Mode
+
+(defgroup LaTeX-math nil
+ "Mathematics in AUCTeX."
+ :group 'LaTeX-macro)
+
+(defcustom LaTeX-math-list nil
+ "Alist of your personal LaTeX math symbols.
+
+Each entry should be a list with up to four elements, KEY, VALUE,
+MENU and CHARACTER.
+
+KEY is the key (after `LaTeX-math-abbrev-prefix') to be redefined
+in math minor mode. If KEY is nil, the symbol has no associated
+keystroke \(it is available in the menu, though\).
+
+VALUE can be a string with the name of the macro to be inserted,
+or a function to be called. The macro must be given without the
+leading backslash.
+
+The third element MENU is the name of the submenu where the
+command should be added. MENU can be either a string
+\(e.g. \"greek\"\), a list (e.g. \(\"AMS\" \"Delimiters\"\)\) or
+nil. If MENU is nil, no menu item will be created.
+
+The fourth element CHARACTER is a Unicode character position for
+menu display. When nil, no character is shown.
+
+See also `LaTeX-math-menu'."
+ :group 'LaTeX-math
+ :type '(repeat (group (choice :tag "Key"
+ (const :tag "none" nil)
+ (choice (character)
+ (string :tag "Key sequence")))
+ (choice :tag "Value"
+ (string :tag "Macro")
+ (function))
+ (choice :tag "Menu"
+ (string :tag "Top level menu" )
+ (repeat :tag "Submenu"
+ (string :tag "Menu")))
+ (choice :tag "Unicode character"
+ (const :tag "none" nil)
+ (integer :tag "Number")))))
+
+(defconst LaTeX-math-default
+ '((?a "alpha" "Greek Lowercase" 945) ;; #X03B1
+ (?b "beta" "Greek Lowercase" 946) ;; #X03B2
+ (?g "gamma" "Greek Lowercase" 947) ;; #X03B3
+ (?d "delta" "Greek Lowercase" 948) ;; #X03B4
+ (?e "epsilon" "Greek Lowercase" 1013) ;; #X03F5
+ (?z "zeta" "Greek Lowercase" 950) ;; #X03B6
+ (?h "eta" "Greek Lowercase" 951) ;; #X03B7
+ (?j "theta" "Greek Lowercase" 952) ;; #X03B8
+ (nil "iota" "Greek Lowercase" 953) ;; #X03B9
+ (?k "kappa" "Greek Lowercase" 954) ;; #X03BA
+ (?l "lambda" "Greek Lowercase" 955) ;; #X03BB
+ (?m "mu" "Greek Lowercase" 956) ;; #X03BC
+ (?n "nu" "Greek Lowercase" 957) ;; #X03BD
+ (?x "xi" "Greek Lowercase" 958) ;; #X03BE
+ (?p "pi" "Greek Lowercase" 960) ;; #X03C0
+ (?r "rho" "Greek Lowercase" 961) ;; #X03C1
+ (?s "sigma" "Greek Lowercase" 963) ;; #X03C3
+ (?t "tau" "Greek Lowercase" 964) ;; #X03C4
+ (?u "upsilon" "Greek Lowercase" 965) ;; #X03C5
+ (?f "phi" "Greek Lowercase" 981) ;; #X03D5
+ (?q "chi" "Greek Lowercase" 967) ;; #X03C7
+ (?y "psi" "Greek Lowercase" 968) ;; #X03C8
+ (?w "omega" "Greek Lowercase" 969) ;; #X03C9
+ ("v e" "varepsilon" "Greek Lowercase" 949) ;; #X03B5
+ ("v j" "vartheta" "Greek Lowercase" 977) ;; #X03D1
+ ("v p" "varpi" "Greek Lowercase" 982) ;; #X03D6
+ ("v r" "varrho" "Greek Lowercase" 1009) ;; #X03F1
+ ("v s" "varsigma" "Greek Lowercase" 962) ;; #X03C2
+ ("v f" "varphi" "Greek Lowercase" 966) ;; #X03C6
+ (?G "Gamma" "Greek Uppercase" 915) ;; #X0393
+ (?D "Delta" "Greek Uppercase" 916) ;; #X0394
+ (?J "Theta" "Greek Uppercase" 920) ;; #X0398
+ (?L "Lambda" "Greek Uppercase" 923) ;; #X039B
+ (?X "Xi" "Greek Uppercase" 926) ;; #X039E
+ (?P "Pi" "Greek Uppercase" 928) ;; #X03A0
+ (?S "Sigma" "Greek Uppercase" 931) ;; #X03A3
+ (?U "Upsilon" "Greek Uppercase" 978) ;; #X03D2
+ (?F "Phi" "Greek Uppercase" 934) ;; #X03A6
+ (?Y "Psi" "Greek Uppercase" 936) ;; #X03A8
+ (?W "Omega" "Greek Uppercase" 937) ;; #X03A9
+ (?c LaTeX-math-cal "Cal-whatever")
+ (nil "pm" "Binary Op" 177) ;; #X00B1
+ (nil "mp" "Binary Op" 8723) ;; #X2213
+ (?* "times" "Binary Op" 215) ;; #X00D7
+ (nil "div" "Binary Op" 247) ;; #X00F7
+ (nil "ast" "Binary Op" 8727) ;; #X2217
+ (nil "star" "Binary Op" 8902) ;; #X22C6
+ (nil "circ" "Binary Op" 8728) ;; #X2218
+ (nil "bullet" "Binary Op" 8729) ;; #X2219
+ (?. "cdot" "Binary Op" 8901) ;; #X22C5
+ (?- "cap" "Binary Op" 8745) ;; #X2229
+ (?+ "cup" "Binary Op" 8746) ;; #X222A
+ (nil "uplus" "Binary Op" 8846) ;; #X228E
+ (nil "sqcap" "Binary Op" 8851) ;; #X2293
+ (?| "vee" "Binary Op" 8744) ;; #X2228
+ (?& "wedge" "Binary Op" 8743) ;; #X2227
+ (?\\ "setminus" "Binary Op" 8726) ;; #X2216
+ (nil "wr" "Binary Op" 8768) ;; #X2240
+ (nil "diamond" "Binary Op" 8900) ;; #X22C4
+ (nil "bigtriangleup" "Binary Op" 9651) ;; #X25B3
+ (nil "bigtriangledown" "Binary Op" 9661) ;; #X25BD
+ (nil "triangleleft" "Binary Op" 9665) ;; #X25C1
+ (nil "triangleright" "Binary Op" 9655) ;; #X25B7
+ (nil "lhd" "Binary Op")
+ (nil "rhd" "Binary Op")
+ (nil "unlhd" "Binary Op")
+ (nil "unrhd" "Binary Op")
+ (nil "oplus" "Binary Op" 8853) ;; #X2295
+ (nil "ominus" "Binary Op" 8854) ;; #X2296
+ (nil "otimes" "Binary Op" 8855) ;; #X2297
+ (nil "oslash" "Binary Op" 8709) ;; #X2205
+ (nil "odot" "Binary Op" 8857) ;; #X2299
+ (nil "bigcirc" "Binary Op" 9675) ;; #X25CB
+ (nil "dagger" "Binary Op" 8224) ;; #X2020
+ (nil "ddagger" "Binary Op" 8225) ;; #X2021
+ (nil "amalg" "Binary Op" 10815) ;; #X2A3F
+ (?< "leq" "Relational" 8804) ;; #X2264
+ (?> "geq" "Relational" 8805) ;; #X2265
+ (nil "qed" "Relational" 8718) ;; #X220E
+ (nil "equiv" "Relational" 8801) ;; #X2261
+ (nil "models" "Relational" 8871) ;; #X22A7
+ (nil "prec" "Relational" 8826) ;; #X227A
+ (nil "succ" "Relational" 8827) ;; #X227B
+ (nil "sim" "Relational" 8764) ;; #X223C
+ (nil "perp" "Relational" 10178) ;; #X27C2
+ (nil "preceq" "Relational" 10927) ;; #X2AAF
+ (nil "succeq" "Relational" 10928) ;; #X2AB0
+ (nil "simeq" "Relational" 8771) ;; #X2243
+ (nil "mid" "Relational" 8739) ;; #X2223
+ (nil "ll" "Relational" 8810) ;; #X226A
+ (nil "gg" "Relational" 8811) ;; #X226B
+ (nil "asymp" "Relational" 8781) ;; #X224D
+ (nil "parallel" "Relational" 8741) ;; #X2225
+ (?\{ "subset" "Relational" 8834) ;; #X2282
+ (?\} "supset" "Relational" 8835) ;; #X2283
+ (nil "approx" "Relational" 8776) ;; #X2248
+ (nil "bowtie" "Relational" 8904) ;; #X22C8
+ (?\[ "subseteq" "Relational" 8838) ;; #X2286
+ (?\] "supseteq" "Relational" 8839) ;; #X2287
+ (nil "cong" "Relational" 8773) ;; #X2245
+ (nil "Join" "Relational" 10781) ;; #X2A1D
+ (nil "sqsubset" "Relational" 8847) ;; #X228F
+ (nil "sqsupset" "Relational" 8848) ;; #X2290
+ (nil "neq" "Relational" 8800) ;; #X2260
+ (nil "smile" "Relational" 8995) ;; #X2323
+ (nil "sqsubseteq" "Relational" 8849) ;; #X2291
+ (nil "sqsupseteq" "Relational" 8850) ;; #X2292
+ (nil "doteq" "Relational" 8784) ;; #X2250
+ (nil "frown" "Relational" 8994) ;; #X2322
+ (?i "in" "Relational" 8712) ;; #X2208
+ (nil "ni" "Relational" 8715) ;; #X220B
+ (nil "propto" "Relational" 8733) ;; #X221D
+ (nil "vdash" "Relational" 8866) ;; #X22A2
+ (nil "dashv" "Relational" 8867) ;; #X22A3
+ (?\C-b "leftarrow" "Arrows" 8592) ;; #X2190
+ (nil "Leftarrow" "Arrows" 8656) ;; #X21D0
+ (?\C-f "rightarrow" "Arrows" 8594) ;; #X2192
+ (nil "Rightarrow" "Arrows" 8658) ;; #X21D2
+ (nil "leftrightarrow" "Arrows" 8596) ;; #X2194
+ (nil "Leftrightarrow" "Arrows" 8660) ;; #X21D4
+ (nil "mapsto" "Arrows" 8614) ;; #X21A6
+ (nil "hookleftarrow" "Arrows" 8617) ;; #X21A9
+ (nil "leftharpoonup" "Arrows" 8636) ;; #X21BC
+ (nil "leftharpoondown" "Arrows" 8637) ;; #X21BD
+ (nil "longleftarrow" "Arrows" 10229) ;; #X27F5
+ (nil "Longleftarrow" "Arrows" 10232) ;; #X27F8
+ (nil "longrightarrow" "Arrows" 10230) ;; #X27F6
+ (nil "Longrightarrow" "Arrows" 10233) ;; #X27F9
+ (nil "longleftrightarrow" "Arrows" 10231) ;; #X27F7
+ (nil "Longleftrightarrow" "Arrows" 10234) ;; #X27FA
+ (nil "longmapsto" "Arrows" 10236) ;; #X27FC
+ (nil "hookrightarrow" "Arrows" 8618) ;; #X21AA
+ (nil "rightharpoonup" "Arrows" 8640) ;; #X21C0
+ (nil "rightharpoondown" "Arrows" 8641) ;; #X21C1
+ (?\C-p "uparrow" "Arrows" 8593) ;; #X2191
+ (nil "Uparrow" "Arrows" 8657) ;; #X21D1
+ (?\C-n "downarrow" "Arrows" 8595) ;; #X2193
+ (nil "Downarrow" "Arrows" 8659) ;; #X21D3
+ (nil "updownarrow" "Arrows" 8597) ;; #X2195
+ (nil "Updownarrow" "Arrows" 8661) ;; #X21D5
+ (nil "nearrow" "Arrows" 8599) ;; #X2197
+ (nil "searrow" "Arrows" 8600) ;; #X2198
+ (nil "swarrow" "Arrows" 8601) ;; #X2199
+ (nil "nwarrow" "Arrows" 8598) ;; #X2196
+ (nil "ldots" "Punctuation" 8230) ;; #X2026
+ (nil "cdots" "Punctuation" 8943) ;; #X22EF
+ (nil "vdots" "Punctuation" 8942) ;; #X22EE
+ (nil "ddots" "Punctuation" 8945) ;; #X22F1
+ (?: "colon" "Punctuation" 58) ;; #X003A
+ (?N "nabla" "Misc Symbol" 8711) ;; #X2207
+ (nil "aleph" "Misc Symbol" 8501) ;; #X2135
+ (nil "prime" "Misc Symbol" 8242) ;; #X2032
+ (?A "forall" "Misc Symbol" 8704) ;; #X2200
+ (?I "infty" "Misc Symbol" 8734) ;; #X221E
+ (nil "hbar" "Misc Symbol" 8463) ;; #X210F
+ (?0 "emptyset" "Misc Symbol" 8709) ;; #X2205
+ (?E "exists" "Misc Symbol" 8707) ;; #X2203
+ (nil "surd" "Misc Symbol" 8730) ;; #X221A
+ (nil "Box" "Misc Symbol")
+ (nil "triangle" "Misc Symbol" 9651) ;; #X25B3
+ (nil "Diamond" "Misc Symbol")
+ (nil "imath" "Misc Symbol" 305) ;; #X0131
+ (nil "jmath" "Misc Symbol" 120485) ;; #X1D6A5
+ (nil "ell" "Misc Symbol" 8467) ;; #X2113
+ (nil "neg" "Misc Symbol" 172) ;; #X00AC
+ (?/ "not" "Misc Symbol" 824) ;; #X0338
+ (nil "top" "Misc Symbol" 8868) ;; #X22A4
+ (nil "flat" "Misc Symbol" 9837) ;; #X266D
+ (nil "natural" "Misc Symbol" 9838) ;; #X266E
+ (nil "sharp" "Misc Symbol" 9839) ;; #X266F
+ (nil "wp" "Misc Symbol" 8472) ;; #X2118
+ (nil "bot" "Misc Symbol" 8869) ;; #X22A5
+ (nil "clubsuit" "Misc Symbol" 9827) ;; #X2663
+ (nil "diamondsuit" "Misc Symbol" 9826) ;; #X2662
+ (nil "heartsuit" "Misc Symbol" 9825) ;; #X2661
+ (nil "spadesuit" "Misc Symbol" 9824) ;; #X2660
+ (nil "mho" "Misc Symbol" 8487) ;; #X2127
+ (nil "Re" "Misc Symbol" 8476) ;; #X211C
+ (nil "Im" "Misc Symbol" 8465) ;; #X2111
+ (nil "angle" "Misc Symbol" 8736) ;; #X2220
+ (nil "partial" "Misc Symbol" 8706) ;; #X2202
+ (nil "sum" "Var Symbol" 8721) ;; #X2211
+ (nil "prod" "Var Symbol" 8719) ;; #X220F
+ (nil "coprod" "Var Symbol" 8720) ;; #X2210
+ (nil "int" "Var Symbol" 8747) ;; #X222B
+ (nil "oint" "Var Symbol" 8750) ;; #X222E
+ (nil "bigcap" "Var Symbol" 8898) ;; #X22C2
+ (nil "bigcup" "Var Symbol" 8899) ;; #X22C3
+ (nil "bigsqcup" "Var Symbol" 10758) ;; #X2A06
+ (nil "bigvee" "Var Symbol" 8897) ;; #X22C1
+ (nil "bigwedge" "Var Symbol" 8896) ;; #X22C0
+ (nil "bigodot" "Var Symbol" 10752) ;; #X2A00
+ (nil "bigotimes" "Var Symbol" 10754) ;; #X2A02
+ (nil "bigoplus" "Var Symbol" 10753) ;; #X2A01
+ (nil "biguplus" "Var Symbol" 10756) ;; #X2A04
+ (nil "arccos" "Log-like")
+ (nil "arcsin" "Log-like")
+ (nil "arctan" "Log-like")
+ (nil "arg" "Log-like")
+ (?\C-c "cos" "Log-like")
+ (nil "cosh" "Log-like")
+ (nil "cot" "Log-like")
+ (nil "coth" "Log-like")
+ (nil "csc" "Log-like")
+ (nil "deg" "Log-like")
+ (?\C-d "det" "Log-like")
+ (nil "dim" "Log-like")
+ (?\C-e "exp" "Log-like")
+ (nil "gcd" "Log-like")
+ (nil "hom" "Log-like")
+ (?\C-_ "inf" "Log-like")
+ (nil "ker" "Log-like")
+ (nil "lg" "Log-like")
+ (?\C-l "lim" "Log-like")
+ (nil "liminf" "Log-like")
+ (nil "limsup" "Log-like")
+ (nil "ln" "Log-like")
+ (nil "log" "Log-like")
+ (nil "max" "Log-like")
+ (nil "min" "Log-like")
+ (nil "Pr" "Log-like")
+ (nil "sec" "Log-like")
+ (?\C-s "sin" "Log-like")
+ (nil "sinh" "Log-like")
+ (?\C-^ "sup" "Log-like")
+ (?\C-t "tan" "Log-like")
+ (nil "tanh" "Log-like")
+ (nil "{" "Delimiters")
+ (nil "}" "Delimiters")
+ (nil "lfloor" "Delimiters" 8970) ;; #X230A
+ (nil "rfloor" "Delimiters" 8971) ;; #X230B
+ (nil "lceil" "Delimiters" 8968) ;; #X2308
+ (nil "rceil" "Delimiters" 8969) ;; #X2309
+ (?\( "langle" "Delimiters" 10216) ;; #X27E8
+ (?\) "rangle" "Delimiters" 10217) ;; #X27E9
+ (nil "rmoustache" "Delimiters" 9137) ;; #X23B1
+ (nil "lmoustache" "Delimiters" 9136) ;; #X23B0
+ (nil "rgroup" "Delimiters")
+ (nil "lgroup" "Delimiters")
+ (nil "backslash" "Delimiters" 92) ;; #X005C
+ (nil "|" "Delimiters")
+ (nil "arrowvert" "Delimiters")
+ (nil "Arrowvert" "Delimiters")
+ (nil "bracevert" "Delimiters")
+ (nil "widetilde" "Constructs" 771) ;; #X0303
+ (nil "widehat" "Constructs" 770) ;; #X0302
+ (nil "overleftarrow" "Constructs" 8406) ;; #X20D6
+ (nil "overrightarrow" "Constructs")
+ (nil "overline" "Constructs")
+ (nil "underline" "Constructs")
+ (nil "overbrace" "Constructs" 65079) ;; #XFE37
+ (nil "underbrace" "Constructs" 65080) ;; #XFE38
+ (nil "sqrt" "Constructs" 8730) ;; #X221A
+ (nil "frac" "Constructs")
+ (?^ "hat" "Accents" 770) ;; #X0302
+ (nil "acute" "Accents" 769) ;; #X0301
+ (nil "bar" "Accents" 772) ;; #X0304
+ (nil "dot" "Accents" 775) ;; #X0307
+ (nil "breve" "Accents" 774) ;; #X0306
+ (nil "check" "Accents" 780) ;; #X030C
+ (nil "grave" "Accents" 768) ;; #X0300
+ (nil "vec" "Accents" 8407) ;; #X20D7
+ (nil "ddot" "Accents" 776) ;; #X0308
+ (?~ "tilde" "Accents" 771) ;; #X0303
+ (nil "digamma" ("AMS" "Hebrew") 989) ;; #X03DD
+ (nil "varkappa" ("AMS" "Hebrew") 1008) ;; #X03F0
+ (nil "beth" ("AMS" "Hebrew") 8502) ;; #X2136
+ (nil "daleth" ("AMS" "Hebrew") 8504) ;; #X2138
+ (nil "gimel" ("AMS" "Hebrew") 8503) ;; #X2137
+ ("v G" "varGamma" ("AMS" "Greek Uppercase"))
+ ("v D" "varDelta" ("AMS" "Greek Uppercase"))
+ ("v J" "varTheta" ("AMS" "Greek Uppercase"))
+ ("v L" "varLambda" ("AMS" "Greek Uppercase"))
+ ("v X" "varXi" ("AMS" "Greek Uppercase"))
+ ("v P" "varPi" ("AMS" "Greek Uppercase"))
+ ("v S" "varSigma" ("AMS" "Greek Uppercase"))
+ ("v U" "varUpsilon" ("AMS" "Greek Uppercase"))
+ ("v F" "varPhi" ("AMS" "Greek Uppercase"))
+ ("v Y" "varPsi" ("AMS" "Greek Uppercase"))
+ ("v W" "varOmega" ("AMS" "Greek Uppercase"))
+ (nil "dashrightarrow" ("AMS" "Arrows"))
+ (nil "dashleftarrow" ("AMS" "Arrows"))
+ (nil "leftleftarrows" ("AMS" "Arrows") 8647) ;; #X21C7
+ (nil "leftrightarrows" ("AMS" "Arrows") 8646) ;; #X21C6
+ (nil "Lleftarrow" ("AMS" "Arrows") 8666) ;; #X21DA
+ (nil "twoheadleftarrow" ("AMS" "Arrows") 8606) ;; #X219E
+ (nil "leftarrowtail" ("AMS" "Arrows") 8610) ;; #X21A2
+ (nil "looparrowleft" ("AMS" "Arrows") 8619) ;; #X21AB
+ (nil "leftrightharpoons" ("AMS" "Arrows") 8651) ;; #X21CB
+ (nil "curvearrowleft" ("AMS" "Arrows") 8630) ;; #X21B6
+ (nil "circlearrowleft" ("AMS" "Arrows"))
+ (nil "Lsh" ("AMS" "Arrows") 8624) ;; #X21B0
+ (nil "upuparrows" ("AMS" "Arrows") 8648) ;; #X21C8
+ (nil "upharpoonleft" ("AMS" "Arrows") 8639) ;; #X21BF
+ (nil "downharpoonleft" ("AMS" "Arrows") 8643) ;; #X21C3
+ (nil "multimap" ("AMS" "Arrows") 8888) ;; #X22B8
+ (nil "leftrightsquigarrow" ("AMS" "Arrows") 8621) ;; #X21AD
+ (nil "looparrowright" ("AMS" "Arrows") 8620) ;; #X21AC
+ (nil "rightleftharpoons" ("AMS" "Arrows") 8652) ;; #X21CC
+ (nil "curvearrowright" ("AMS" "Arrows") 8631) ;; #X21B7
+ (nil "circlearrowright" ("AMS" "Arrows"))
+ (nil "Rsh" ("AMS" "Arrows") 8625) ;; #X21B1
+ (nil "downdownarrows" ("AMS" "Arrows") 8650) ;; #X21CA
+ (nil "upharpoonright" ("AMS" "Arrows") 8638) ;; #X21BE
+ (nil "downharpoonright" ("AMS" "Arrows") 8642) ;; #X21C2
+ (nil "rightsquigarrow" ("AMS" "Arrows") 8605) ;; #X219D
+ (nil "nleftarrow" ("AMS" "Neg Arrows") 8602) ;; #X219A
+ (nil "nrightarrow" ("AMS" "Neg Arrows") 8603) ;; #X219B
+ (nil "nLeftarrow" ("AMS" "Neg Arrows") 8653) ;; #X21CD
+ (nil "nRightarrow" ("AMS" "Neg Arrows") 8655) ;; #X21CF
+ (nil "nleftrightarrow" ("AMS" "Neg Arrows") 8622) ;; #X21AE
+ (nil "nLeftrightarrow" ("AMS" "Neg Arrows") 8654) ;; #X21CE
+ (nil "leqq" ("AMS" "Relational I") 8806) ;; #X2266
+ (nil "leqslant" ("AMS" "Relational I") 10877) ;; #X2A7D
+ (nil "eqslantless" ("AMS" "Relational I") 10901) ;; #X2A95
+ (nil "lesssim" ("AMS" "Relational I") 8818) ;; #X2272
+ (nil "lessapprox" ("AMS" "Relational I") 10885) ;; #X2A85
+ (nil "approxeq" ("AMS" "Relational I") 8778) ;; #X224A
+ (nil "lessdot" ("AMS" "Relational I") 8918) ;; #X22D6
+ (nil "lll" ("AMS" "Relational I") 8920) ;; #X22D8
+ (nil "lessgtr" ("AMS" "Relational I") 8822) ;; #X2276
+ (nil "lesseqgtr" ("AMS" "Relational I") 8922) ;; #X22DA
+ (nil "lesseqqgtr" ("AMS" "Relational I") 10891) ;; #X2A8B
+ (nil "doteqdot" ("AMS" "Relational I"))
+ (nil "risingdotseq" ("AMS" "Relational I") 8787) ;; #X2253
+ (nil "fallingdotseq" ("AMS" "Relational I") 8786) ;; #X2252
+ (nil "backsim" ("AMS" "Relational I") 8765) ;; #X223D
+ (nil "backsimeq" ("AMS" "Relational I") 8909) ;; #X22CD
+ (nil "subseteqq" ("AMS" "Relational I") 10949) ;; #X2AC5
+ (nil "Subset" ("AMS" "Relational I") 8912) ;; #X22D0
+ (nil "sqsubset" ("AMS" "Relational I") 8847) ;; #X228F
+ (nil "preccurlyeq" ("AMS" "Relational I") 8828) ;; #X227C
+ (nil "curlyeqprec" ("AMS" "Relational I") 8926) ;; #X22DE
+ (nil "precsim" ("AMS" "Relational I") 8830) ;; #X227E
+ (nil "precapprox" ("AMS" "Relational I") 10935) ;; #X2AB7
+ (nil "vartriangleleft" ("AMS" "Relational I") 8882) ;; #X22B2
+ (nil "trianglelefteq" ("AMS" "Relational I") 8884) ;; #X22B4
+ (nil "vDash" ("AMS" "Relational I") 8872) ;; #X22A8
+ (nil "Vvdash" ("AMS" "Relational I") 8874) ;; #X22AA
+ (nil "smallsmile" ("AMS" "Relational I") 8995) ;; #X2323
+ (nil "smallfrown" ("AMS" "Relational I") 8994) ;; #X2322
+ (nil "bumpeq" ("AMS" "Relational I") 8783) ;; #X224F
+ (nil "Bumpeq" ("AMS" "Relational I") 8782) ;; #X224E
+ (nil "geqq" ("AMS" "Relational II") 8807) ;; #X2267
+ (nil "geqslant" ("AMS" "Relational II") 10878) ;; #X2A7E
+ (nil "eqslantgtr" ("AMS" "Relational II") 10902) ;; #X2A96
+ (nil "gtrsim" ("AMS" "Relational II") 8819) ;; #X2273
+ (nil "gtrapprox" ("AMS" "Relational II") 10886) ;; #X2A86
+ (nil "gtrdot" ("AMS" "Relational II") 8919) ;; #X22D7
+ (nil "ggg" ("AMS" "Relational II") 8921) ;; #X22D9
+ (nil "gtrless" ("AMS" "Relational II") 8823) ;; #X2277
+ (nil "gtreqless" ("AMS" "Relational II") 8923) ;; #X22DB
+ (nil "gtreqqless" ("AMS" "Relational II") 10892) ;; #X2A8C
+ (nil "eqcirc" ("AMS" "Relational II") 8790) ;; #X2256
+ (nil "circeq" ("AMS" "Relational II") 8791) ;; #X2257
+ (nil "triangleq" ("AMS" "Relational II") 8796) ;; #X225C
+ (nil "thicksim" ("AMS" "Relational II") 8764) ;; #X223C
+ (nil "thickapprox" ("AMS" "Relational II") 8776) ;; #X2248
+ (nil "supseteqq" ("AMS" "Relational II") 10950) ;; #X2AC6
+ (nil "Supset" ("AMS" "Relational II") 8913) ;; #X22D1
+ (nil "sqsupset" ("AMS" "Relational II") 8848) ;; #X2290
+ (nil "succcurlyeq" ("AMS" "Relational II") 8829) ;; #X227D
+ (nil "curlyeqsucc" ("AMS" "Relational II") 8927) ;; #X22DF
+ (nil "succsim" ("AMS" "Relational II") 8831) ;; #X227F
+ (nil "succapprox" ("AMS" "Relational II") 10936) ;; #X2AB8
+ (nil "vartriangleright" ("AMS" "Relational II") 8883) ;; #X22B3
+ (nil "trianglerighteq" ("AMS" "Relational II") 8885) ;; #X22B5
+ (nil "Vdash" ("AMS" "Relational II") 8873) ;; #X22A9
+ (nil "shortmid" ("AMS" "Relational II") 8739) ;; #X2223
+ (nil "shortparallel" ("AMS" "Relational II") 8741) ;; #X2225
+ (nil "between" ("AMS" "Relational II") 8812) ;; #X226C
+ (nil "pitchfork" ("AMS" "Relational II") 8916) ;; #X22D4
+ (nil "varpropto" ("AMS" "Relational II") 8733) ;; #X221D
+ (nil "blacktriangleleft" ("AMS" "Relational II") 9664) ;; #X25C0
+ (nil "therefore" ("AMS" "Relational II") 8756) ;; #X2234
+ (nil "backepsilon" ("AMS" "Relational II") 1014) ;; #X03F6
+ (nil "blacktriangleright" ("AMS" "Relational II") 9654) ;; #X25B6
+ (nil "because" ("AMS" "Relational II") 8757) ;; #X2235
+ (nil "nless" ("AMS" "Neg Rel I") 8814) ;; #X226E
+ (nil "nleq" ("AMS" "Neg Rel I") 8816) ;; #X2270
+ (nil "nleqslant" ("AMS" "Neg Rel I"))
+ (nil "nleqq" ("AMS" "Neg Rel I"))
+ (nil "lneq" ("AMS" "Neg Rel I") 10887) ;; #X2A87
+ (nil "lneqq" ("AMS" "Neg Rel I") 8808) ;; #X2268
+ (nil "lvertneqq" ("AMS" "Neg Rel I"))
+ (nil "lnsim" ("AMS" "Neg Rel I") 8934) ;; #X22E6
+ (nil "lnapprox" ("AMS" "Neg Rel I") 10889) ;; #X2A89
+ (nil "nprec" ("AMS" "Neg Rel I") 8832) ;; #X2280
+ (nil "npreceq" ("AMS" "Neg Rel I"))
+ (nil "precnsim" ("AMS" "Neg Rel I") 8936) ;; #X22E8
+ (nil "precnapprox" ("AMS" "Neg Rel I") 10937) ;; #X2AB9
+ (nil "nsim" ("AMS" "Neg Rel I") 8769) ;; #X2241
+ (nil "nshortmid" ("AMS" "Neg Rel I") 8740) ;; #X2224
+ (nil "nmid" ("AMS" "Neg Rel I") 8740) ;; #X2224
+ (nil "nvdash" ("AMS" "Neg Rel I") 8876) ;; #X22AC
+ (nil "nvDash" ("AMS" "Neg Rel I") 8877) ;; #X22AD
+ (nil "ntriangleleft" ("AMS" "Neg Rel I") 8938) ;; #X22EA
+ (nil "ntrianglelefteq" ("AMS" "Neg Rel I") 8940) ;; #X22EC
+ (nil "nsubseteq" ("AMS" "Neg Rel I") 8840) ;; #X2288
+ (nil "subsetneq" ("AMS" "Neg Rel I") 8842) ;; #X228A
+ (nil "varsubsetneq" ("AMS" "Neg Rel I"))
+ (nil "subsetneqq" ("AMS" "Neg Rel I") 10955) ;; #X2ACB
+ (nil "varsubsetneqq" ("AMS" "Neg Rel I"))
+ (nil "ngtr" ("AMS" "Neg Rel II") 8815) ;; #X226F
+ (nil "ngeq" ("AMS" "Neg Rel II") 8817) ;; #X2271
+ (nil "ngeqslant" ("AMS" "Neg Rel II"))
+ (nil "ngeqq" ("AMS" "Neg Rel II"))
+ (nil "gneq" ("AMS" "Neg Rel II") 10888) ;; #X2A88
+ (nil "gneqq" ("AMS" "Neg Rel II") 8809) ;; #X2269
+ (nil "gvertneqq" ("AMS" "Neg Rel II"))
+ (nil "gnsim" ("AMS" "Neg Rel II") 8935) ;; #X22E7
+ (nil "gnapprox" ("AMS" "Neg Rel II") 10890) ;; #X2A8A
+ (nil "nsucc" ("AMS" "Neg Rel II") 8833) ;; #X2281
+ (nil "nsucceq" ("AMS" "Neg Rel II"))
+ (nil "succnsim" ("AMS" "Neg Rel II") 8937) ;; #X22E9
+ (nil "succnapprox" ("AMS" "Neg Rel II") 10938) ;; #X2ABA
+ (nil "ncong" ("AMS" "Neg Rel II") 8775) ;; #X2247
+ (nil "nshortparallel" ("AMS" "Neg Rel II") 8742) ;; #X2226
+ (nil "nparallel" ("AMS" "Neg Rel II") 8742) ;; #X2226
+ (nil "nvDash" ("AMS" "Neg Rel II") 8877) ;; #X22AD
+ (nil "nVDash" ("AMS" "Neg Rel II") 8879) ;; #X22AF
+ (nil "ntriangleright" ("AMS" "Neg Rel II") 8939) ;; #X22EB
+ (nil "ntrianglerighteq" ("AMS" "Neg Rel II") 8941) ;; #X22ED
+ (nil "nsupseteq" ("AMS" "Neg Rel II") 8841) ;; #X2289
+ (nil "nsupseteqq" ("AMS" "Neg Rel II"))
+ (nil "supsetneq" ("AMS" "Neg Rel II") 8843) ;; #X228B
+ (nil "varsupsetneq" ("AMS" "Neg Rel II"))
+ (nil "supsetneqq" ("AMS" "Neg Rel II") 10956) ;; #X2ACC
+ (nil "varsupsetneqq" ("AMS" "Neg Rel II"))
+ (nil "dotplus" ("AMS" "Binary Op") 8724) ;; #X2214
+ (nil "smallsetminus" ("AMS" "Binary Op") 8726) ;; #X2216
+ (nil "Cap" ("AMS" "Binary Op") 8914) ;; #X22D2
+ (nil "Cup" ("AMS" "Binary Op") 8915) ;; #X22D3
+ (nil "barwedge" ("AMS" "Binary Op") 8892) ;; #X22BC
+ (nil "veebar" ("AMS" "Binary Op") 8891) ;; #X22BB
+ (nil "doublebarwedge" ("AMS" "Binary Op") 8966) ;; #X2306
+ (nil "boxminus" ("AMS" "Binary Op") 8863) ;; #X229F
+ (nil "boxtimes" ("AMS" "Binary Op") 8864) ;; #X22A0
+ (nil "boxdot" ("AMS" "Binary Op") 8865) ;; #X22A1
+ (nil "boxplus" ("AMS" "Binary Op") 8862) ;; #X229E
+ (nil "divideontimes" ("AMS" "Binary Op") 8903) ;; #X22C7
+ (nil "ltimes" ("AMS" "Binary Op") 8905) ;; #X22C9
+ (nil "rtimes" ("AMS" "Binary Op") 8906) ;; #X22CA
+ (nil "leftthreetimes" ("AMS" "Binary Op") 8907) ;; #X22CB
+ (nil "rightthreetimes" ("AMS" "Binary Op") 8908) ;; #X22CC
+ (nil "curlywedge" ("AMS" "Binary Op") 8911) ;; #X22CF
+ (nil "curlyvee" ("AMS" "Binary Op") 8910) ;; #X22CE
+ (nil "circleddash" ("AMS" "Binary Op") 8861) ;; #X229D
+ (nil "circledast" ("AMS" "Binary Op") 8859) ;; #X229B
+ (nil "circledcirc" ("AMS" "Binary Op") 8858) ;; #X229A
+ (nil "centerdot" ("AMS" "Binary Op"))
+ (nil "intercal" ("AMS" "Binary Op") 8890) ;; #X22BA
+ (nil "hbar" ("AMS" "Misc") 8463) ;; #X210F
+ (nil "hslash" ("AMS" "Misc") 8463) ;; #X210F
+ (nil "vartriangle" ("AMS" "Misc") 9653) ;; #X25B5
+ (nil "triangledown" ("AMS" "Misc") 9663) ;; #X25BF
+ (nil "square" ("AMS" "Misc") 9633) ;; #X25A1
+ (nil "lozenge" ("AMS" "Misc") 9674) ;; #X25CA
+ (nil "circledS" ("AMS" "Misc") 9416) ;; #X24C8
+ (nil "angle" ("AMS" "Misc") 8736) ;; #X2220
+ (nil "measuredangle" ("AMS" "Misc") 8737) ;; #X2221
+ (nil "nexists" ("AMS" "Misc") 8708) ;; #X2204
+ (nil "mho" ("AMS" "Misc") 8487) ;; #X2127
+ (nil "Finv" ("AMS" "Misc") 8498) ;; #X2132
+ (nil "Game" ("AMS" "Misc") 8513) ;; #X2141
+ (nil "Bbbk" ("AMS" "Misc") 120156) ;; #X1D55C
+ (nil "backprime" ("AMS" "Misc") 8245) ;; #X2035
+ (nil "varnothing" ("AMS" "Misc") 8709) ;; #X2205
+ (nil "blacktriangle" ("AMS" "Misc") 9652) ;; #X25B4
+ (nil "blacktriangledown" ("AMS" "Misc") 9662) ;; #X25BE
+ (nil "blacksquare" ("AMS" "Misc") 9632) ;; #X25A0
+ (nil "blacklozenge" ("AMS" "Misc") 10731) ;; #X29EB
+ (nil "bigstar" ("AMS" "Misc") 9733) ;; #X2605
+ (nil "sphericalangle" ("AMS" "Misc") 8738) ;; #X2222
+ (nil "complement" ("AMS" "Misc") 8705) ;; #X2201
+ (nil "eth" ("AMS" "Misc") 240) ;; #X00F0
+ (nil "diagup" ("AMS" "Misc") 9585) ;; #X2571
+ (nil "diagdown" ("AMS" "Misc") 9586) ;; #X2572
+ (nil "dddot" ("AMS" "Accents") 8411) ;; #X20DB
+ (nil "ddddot" ("AMS" "Accents") 8412) ;; #X20DC
+ (nil "bigl" ("AMS" "Delimiters"))
+ (nil "bigr" ("AMS" "Delimiters"))
+ (nil "Bigl" ("AMS" "Delimiters"))
+ (nil "Bigr" ("AMS" "Delimiters"))
+ (nil "biggl" ("AMS" "Delimiters"))
+ (nil "biggr" ("AMS" "Delimiters"))
+ (nil "Biggl" ("AMS" "Delimiters"))
+ (nil "Biggr" ("AMS" "Delimiters"))
+ (nil "lvert" ("AMS" "Delimiters"))
+ (nil "rvert" ("AMS" "Delimiters"))
+ (nil "lVert" ("AMS" "Delimiters"))
+ (nil "rVert" ("AMS" "Delimiters"))
+ (nil "ulcorner" ("AMS" "Delimiters") 8988) ;; #X231C
+ (nil "urcorner" ("AMS" "Delimiters") 8989) ;; #X231D
+ (nil "llcorner" ("AMS" "Delimiters") 8990) ;; #X231E
+ (nil "lrcorner" ("AMS" "Delimiters") 8991) ;; #X231F
+ (nil "nobreakdash" ("AMS" "Special"))
+ (nil "leftroot" ("AMS" "Special"))
+ (nil "uproot" ("AMS" "Special"))
+ (nil "accentedsymbol" ("AMS" "Special"))
+ (nil "xleftarrow" ("AMS" "Special"))
+ (nil "xrightarrow" ("AMS" "Special"))
+ (nil "overset" ("AMS" "Special"))
+ (nil "underset" ("AMS" "Special"))
+ (nil "dfrac" ("AMS" "Special"))
+ (nil "genfrac" ("AMS" "Special"))
+ (nil "tfrac" ("AMS" "Special"))
+ (nil "binom" ("AMS" "Special"))
+ (nil "dbinom" ("AMS" "Special"))
+ (nil "tbinom" ("AMS" "Special"))
+ (nil "smash" ("AMS" "Special"))
+ (nil "eucal" ("AMS" "Special"))
+ (nil "boldsymbol" ("AMS" "Special"))
+ (nil "text" ("AMS" "Special"))
+ (nil "intertext" ("AMS" "Special"))
+ (nil "substack" ("AMS" "Special"))
+ (nil "subarray" ("AMS" "Special"))
+ (nil "sideset" ("AMS" "Special")))
+ "Alist of LaTeX math symbols.
+
+Each entry should be a list with upto four elements, KEY, VALUE,
+MENU and CHARACTER, see `LaTeX-math-list' for details.")
+
+(defcustom LaTeX-math-abbrev-prefix "`"
+ "Prefix key for use in `LaTeX-math-mode'.
+This has to be a string representing a key sequence in a format
+understood by the `kbd' macro. This corresponds to the syntax
+usually used in the Emacs and Elisp manuals.
+
+Setting this variable directly does not take effect;
+use \\[customize]."
+ :group 'LaTeX-math
+ :initialize 'custom-initialize-default
+ :set '(lambda (symbol value)
+ (define-key LaTeX-math-mode-map (LaTeX-math-abbrev-prefix) t)
+ (set-default symbol value)
+ (define-key LaTeX-math-mode-map
+ (LaTeX-math-abbrev-prefix) LaTeX-math-keymap))
+ :type '(string :tag "Key sequence"))
+
+(defun LaTeX-math-abbrev-prefix ()
+ "Make a key definition from the variable `LaTeX-math-abbrev-prefix'."
+ (if (stringp LaTeX-math-abbrev-prefix)
+ (read-kbd-macro LaTeX-math-abbrev-prefix)
+ LaTeX-math-abbrev-prefix))
+
+(defvar LaTeX-math-keymap
+ (let ((map (make-sparse-keymap)))
+ (define-key map (LaTeX-math-abbrev-prefix) 'self-insert-command)
+ map)
+ "Keymap used for `LaTeX-math-mode' commands.")
+
+(defvar LaTeX-math-menu
+ '("Math"
+ ("Greek Uppercase") ("Greek Lowercase") ("Binary Op") ("Relational")
+ ("Arrows") ("Punctuation") ("Misc Symbol") ("Var Symbol") ("Log-like")
+ ("Delimiters") ("Constructs") ("Accents") ("AMS"))
+ "Menu containing LaTeX math commands.
+The menu entries will be generated dynamically, but you can specify
+the sequence by initializing this variable.")
+
+(defcustom LaTeX-math-menu-unicode
+ (and (string-match "\\<GTK\\>" (emacs-version)) t)
+ "Whether the LaTeX menu should try using Unicode for effect."
+ :type 'boolean
+ :group 'LaTeX-math)
+
+(let ((math (reverse (append LaTeX-math-list LaTeX-math-default)))
+ (map LaTeX-math-keymap)
+ (unicode (and LaTeX-math-menu-unicode (fboundp 'decode-char))))
+ (while math
+ (let* ((entry (car math))
+ (key (nth 0 entry))
+ (prefix
+ (and unicode
+ (nth 3 entry)))
+ value menu name)
+ (setq math (cdr math))
+ (if (and prefix
+ (setq prefix (decode-char 'ucs (nth 3 entry))))
+ (setq prefix (concat (string prefix) " \\"))
+ (setq prefix "\\"))
+ (if (listp (cdr entry))
+ (setq value (nth 1 entry)
+ menu (nth 2 entry))
+ (setq value (cdr entry)
+ menu nil))
+ (if (stringp value)
+ (progn
+ (setq name (intern (concat "LaTeX-math-" value)))
+ (fset name (list 'lambda (list 'arg) (list 'interactive "*P")
+ (list 'LaTeX-math-insert value 'arg))))
+ (setq name value))
+ (if key
+ (progn
+ (setq key (cond ((numberp key) (char-to-string key))
+ ((stringp key) (read-kbd-macro key))
+ (t (vector key))))
+ (define-key map key name)))
+ (if menu
+ (let ((parent LaTeX-math-menu))
+ (if (listp menu)
+ (progn
+ (while (cdr menu)
+ (let ((sub (assoc (car menu) LaTeX-math-menu)))
+ (if sub
+ (setq parent sub)
+ (setcdr parent (cons (list (car menu)) (cdr parent))))
+ (setq menu (cdr menu))))
+ (setq menu (car menu))))
+ (let ((sub (assoc menu parent)))
+ (if sub
+ (if (stringp value)
+ (setcdr sub (cons (vector (concat prefix value)
+ name t)
+ (cdr sub)))
+ (error "Cannot have multiple special math menu items"))
+ (setcdr parent
+ (cons (if (stringp value)
+ (list menu (vector (concat prefix value)
+ name t))
+ (vector menu name t))
+ (cdr parent))))))))))
+
+(define-minor-mode LaTeX-math-mode
+ "A minor mode with easy access to TeX math macros.
+
+Easy insertion of LaTeX math symbols. If you give a prefix argument,
+the symbols will be surrounded by dollar signs. The following
+commands are defined:
+
+\\{LaTeX-math-mode-map}"
+ nil nil (list (cons (LaTeX-math-abbrev-prefix) LaTeX-math-keymap))
+ (if LaTeX-math-mode
+ (easy-menu-add LaTeX-math-mode-menu LaTeX-math-mode-map)
+ (easy-menu-remove LaTeX-math-mode-menu))
+ (TeX-set-mode-name))
+(defalias 'latex-math-mode 'LaTeX-math-mode)
+
+(easy-menu-define LaTeX-math-mode-menu
+ LaTeX-math-mode-map
+ "Menu used in math minor mode."
+ LaTeX-math-menu)
+
+(defcustom LaTeX-math-insert-function 'TeX-insert-macro
+ "Function called with argument STRING to insert \\STRING."
+ :group 'LaTeX-math
+ :type 'function)
+
+(defun LaTeX-math-insert (string dollar)
+ "Insert \\STRING{}. If DOLLAR is non-nil, put $'s around it."
+ (if dollar (insert "$"))
+ (funcall LaTeX-math-insert-function string)
+ (if dollar (insert "$")))
+
+(defun LaTeX-math-cal (char dollar)
+ "Insert a {\\cal CHAR}. If DOLLAR is non-nil, put $'s around it."
+ (interactive "*c\nP")
+ (if dollar (insert "$"))
+ (if (member "latex2e" (TeX-style-list))
+ (insert "\\mathcal{" (char-to-string char) "}")
+ (insert "{\\cal " (char-to-string char) "}"))
+ (if dollar (insert "$")))
+
+
+;;; Folding
+
+(defcustom LaTeX-fold-macro-spec-list nil
+ "List of display strings and macros to fold in LaTeX mode."
+ :type '(repeat (group (choice (string :tag "Display String")
+ (integer :tag "Number of argument" :value 1))
+ (repeat :tag "Macros" (string))))
+ :group 'TeX-fold)
+
+(defcustom LaTeX-fold-env-spec-list nil
+ "List of display strings and environments to fold in LaTeX mode."
+ :type '(repeat (group (choice (string :tag "Display String")
+ (integer :tag "Number of argument" :value 1))
+ (repeat :tag "Environments" (string))))
+ :group 'TeX-fold)
+
+(defcustom LaTeX-fold-math-spec-list
+ (delete nil
+ (mapcar (lambda (elt)
+ (let ((tex-token (nth 1 elt))
+ (submenu (nth 2 elt))
+ (unicode (nth 3 elt))
+ uchar noargp)
+ (when (and (fboundp 'decode-char) (integerp unicode))
+ (setq uchar (decode-char 'ucs unicode)))
+ (when (listp submenu) (setq submenu (nth 1 submenu)))
+ (setq noargp
+ (not (string-match
+ (concat "^" (regexp-opt '("Constructs"
+ "Accents")))
+ submenu)))
+ (when (and (stringp tex-token) (integerp uchar) noargp)
+ `(,(char-to-string uchar) (,tex-token)))))
+ `((nil "to" "" 8594)
+ (nil "gets" "" 8592)
+ ,@LaTeX-math-default)))
+ "List of display strings and math macros to fold in LaTeX mode."
+ :type '(repeat (group (choice (string :tag "Display String")
+ (integer :tag "Number of argument" :value 1))
+ (repeat :tag "Math Macros" (string))))
+ :group 'TeX-fold)
+
+
+;;; Keymap
+
+(defvar LaTeX-mode-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map TeX-mode-map)
+
+ ;; Standard
+ (define-key map "\n" 'reindent-then-newline-and-indent)
+
+ ;; From latex.el
+ ;; We now set `fill-paragraph-function' instead.
+ ;; (define-key map "\eq" 'LaTeX-fill-paragraph) ;*** Alias
+ ;; This key is now used by Emacs for face settings.
+ ;; (define-key map "\eg" 'LaTeX-fill-region) ;*** Alias
+ (define-key map "\e\C-e" 'LaTeX-find-matching-end)
+ (define-key map "\e\C-a" 'LaTeX-find-matching-begin)
+
+ (define-key map "\C-c\C-q\C-p" 'LaTeX-fill-paragraph)
+ (define-key map "\C-c\C-q\C-r" 'LaTeX-fill-region)
+ (define-key map "\C-c\C-q\C-s" 'LaTeX-fill-section)
+ (define-key map "\C-c\C-q\C-e" 'LaTeX-fill-environment)
+
+ (define-key map "\C-c." 'LaTeX-mark-environment) ;*** Dubious
+ (define-key map "\C-c*" 'LaTeX-mark-section) ;*** Dubious
+
+ (define-key map "\C-c\C-e" 'LaTeX-environment)
+ (define-key map "\C-c\n" 'LaTeX-insert-item)
+ (or (key-binding "\e\r")
+ (define-key map "\e\r" 'LaTeX-insert-item)) ;*** Alias
+ (define-key map "\C-c]" 'LaTeX-close-environment)
+ (define-key map "\C-c\C-s" 'LaTeX-section)
+
+ (define-key map "\C-c~" 'LaTeX-math-mode) ;*** Dubious
+
+ (define-key map "-" 'LaTeX-babel-insert-hyphen)
+ map)
+ "Keymap used in `LaTeX-mode'.")
+
+(defvar LaTeX-environment-menu-name "Insert Environment (C-c C-e)")
+
+(defun LaTeX-environment-menu-entry (entry)
+ "Create an entry for the environment menu."
+ (vector (car entry) (list 'LaTeX-environment-menu (car entry)) t))
+
+(defvar LaTeX-environment-modify-menu-name "Change Environment (C-u C-c C-e)")
+
+(defun LaTeX-environment-modify-menu-entry (entry)
+ "Create an entry for the change environment menu."
+ (vector (car entry) (list 'LaTeX-modify-environment (car entry)) t))
+
+(defun LaTeX-section-enable-symbol (LEVEL)
+ "Symbol used to enable section LEVEL in the menu bar."
+ (intern (concat "LaTeX-section-" (int-to-string (nth 1 entry)) "-enable")))
+
+(defun LaTeX-section-enable (entry)
+ "Enable or disable section ENTRY from `LaTeX-section-list'."
+ (let* ((level (nth 1 entry))
+ (symbol (LaTeX-section-enable-symbol level)))
+ (set symbol (or (= level 0) (>= level LaTeX-largest-level)))
+ (make-variable-buffer-local symbol)))
+
+(defun LaTeX-section-menu (level)
+ "Insert section from menu."
+ (let ((LaTeX-section-hook (delq 'LaTeX-section-heading
+ (copy-sequence LaTeX-section-hook))))
+ (LaTeX-section level)))
+
+(defun LaTeX-section-menu-entry (entry)
+ "Create an ENTRY for the section menu."
+ (let ((enable (LaTeX-section-enable-symbol (nth 1 entry))))
+ (vector (car entry) (list 'LaTeX-section-menu (nth 1 entry)) enable)))
+
+(defcustom LaTeX-menu-max-items 25
+ "*Maximum number of items in the menu for LaTeX environments.
+If number of entries in a menu is larger than this value, split menu
+into submenus of nearly equal length. If nil, never split menu into
+submenus."
+ :group 'LaTeX-environment
+ :type '(choice (const :tag "no submenus" nil)
+ (integer)))
+
+(defcustom LaTeX-submenu-name-format "%-12.12s ... %.12s"
+ "*Format specification of the submenu name.
+Used by `LaTeX-split-long-menu' if the number of entries in a menu is
+larger than `LaTeX-menu-max-items'.
+This string should contain one %s for the name of the first entry and
+one %s for the name of the last entry in the submenu.
+If the value is a function, it should return the submenu name. The
+function is called with two arguments, the names of the first and
+the last entry in the menu."
+ :group 'LaTeX-environment
+ :type '(choice (string :tag "Format string")
+ (function)))
+
+(defun LaTeX-split-long-menu (menu)
+ "Split MENU according to `LaTeX-menu-max-items'."
+ (let ((len (length menu)))
+ (if (or (null LaTeX-menu-max-items)
+ (null (featurep 'lisp-float-type))
+ (<= len LaTeX-menu-max-items))
+ menu
+ ;; Submenu is max 2 entries longer than menu, never shorter, number of
+ ;; entries in submenus differ by at most one (with longer submenus first)
+ (let* ((outer (floor (sqrt len)))
+ (inner (/ len outer))
+ (rest (% len outer))
+ (result nil))
+ (setq menu (reverse menu))
+ (while menu
+ (let ((in inner)
+ (sub nil)
+ (to (car menu)))
+ (while (> in 0)
+ (setq in (1- in)
+ sub (cons (car menu) sub)
+ menu (cdr menu)))
+ (setq result
+ (cons (cons (if (stringp LaTeX-submenu-name-format)
+ (format LaTeX-submenu-name-format
+ (aref (car sub) 0) (aref to 0))
+ (funcall LaTeX-submenu-name-format
+ (aref (car sub) 0) (aref to 0)))
+ sub)
+ result)
+ rest (1+ rest))
+ (if (= rest outer) (setq inner (1+ inner)))))
+ result))))
+
+(defvar LaTeX-section-menu nil)
+(make-variable-buffer-local 'LaTeX-section-menu)
+(defun LaTeX-section-menu-filter (ignored)
+ "Filter function for the section submenu in the mode menu.
+The argument IGNORED is not used in any way."
+ (TeX-update-style)
+ (or LaTeX-section-menu
+ (progn
+ (setq LaTeX-section-list-changed nil)
+ (mapc 'LaTeX-section-enable LaTeX-section-list)
+ (setq LaTeX-section-menu
+ (mapcar 'LaTeX-section-menu-entry LaTeX-section-list)))))
+
+(defvar LaTeX-environment-menu nil)
+(make-variable-buffer-local 'LaTeX-environment-menu)
+(defvar LaTeX-environment-modify-menu nil)
+(make-variable-buffer-local 'LaTeX-environment-modify-menu)
+(defun LaTeX-environment-menu-filter (menu)
+ "Filter function for the environment submenus in the mode menu.
+The argument MENU is the name of the submenu in concern and
+corresponds to the variables `LaTeX-environment-menu-name' and
+`LaTeX-environment-modify-menu-name'."
+ (TeX-update-style)
+ (cond
+ ((string= menu LaTeX-environment-menu-name)
+ (or LaTeX-environment-menu
+ (setq LaTeX-environment-menu
+ (LaTeX-split-long-menu
+ (mapcar 'LaTeX-environment-menu-entry
+ (LaTeX-environment-list))))))
+ ((string= menu LaTeX-environment-modify-menu-name)
+ (or LaTeX-environment-modify-menu
+ (setq LaTeX-environment-modify-menu
+ (LaTeX-split-long-menu
+ (mapcar 'LaTeX-environment-modify-menu-entry
+ (LaTeX-environment-list))))))))
+
+(easy-menu-define LaTeX-mode-command-menu
+ LaTeX-mode-map
+ "Command menu used in LaTeX mode."
+ (TeX-mode-specific-command-menu 'latex-mode))
+
+(easy-menu-define LaTeX-mode-menu
+ LaTeX-mode-map
+ "Menu used in LaTeX mode."
+ (TeX-menu-with-help
+ `("LaTeX"
+ ("Section (C-c C-s)" :filter LaTeX-section-menu-filter)
+ ["Macro..." TeX-insert-macro
+ :help "Insert a macro and possibly arguments"]
+ ["Complete Macro" TeX-complete-symbol
+ :help "Complete the current macro or environment name"]
+ ,(list LaTeX-environment-menu-name
+ :filter (lambda (ignored) (LaTeX-environment-menu-filter
+ LaTeX-environment-menu-name)))
+ ,(list LaTeX-environment-modify-menu-name
+ :filter (lambda (ignored) (LaTeX-environment-menu-filter
+ LaTeX-environment-modify-menu-name)))
+ ["Close Environment" LaTeX-close-environment
+ :help "Insert the \\end part of the current environment"]
+ ["Item" LaTeX-insert-item
+ :help "Insert a new \\item into current environment"]
+ "-"
+ ("Insert Font"
+ ["Emphasize" (TeX-font nil ?\C-e) :keys "C-c C-f C-e"]
+ ["Bold" (TeX-font nil ?\C-b) :keys "C-c C-f C-b"]
+ ["Typewriter" (TeX-font nil ?\C-t) :keys "C-c C-f C-t"]
+ ["Small Caps" (TeX-font nil ?\C-c) :keys "C-c C-f C-c"]
+ ["Sans Serif" (TeX-font nil ?\C-f) :keys "C-c C-f C-f"]
+ ["Italic" (TeX-font nil ?\C-i) :keys "C-c C-f C-i"]
+ ["Slanted" (TeX-font nil ?\C-s) :keys "C-c C-f C-s"]
+ ["Roman" (TeX-font nil ?\C-r) :keys "C-c C-f C-r"]
+ ["Calligraphic" (TeX-font nil ?\C-a) :keys "C-c C-f C-a"])
+ ("Replace Font"
+ ["Emphasize" (TeX-font t ?\C-e) :keys "C-u C-c C-f C-e"]
+ ["Bold" (TeX-font t ?\C-b) :keys "C-u C-c C-f C-b"]
+ ["Typewriter" (TeX-font t ?\C-t) :keys "C-u C-c C-f C-t"]
+ ["Small Caps" (TeX-font t ?\C-c) :keys "C-u C-c C-f C-c"]
+ ["Sans Serif" (TeX-font t ?\C-f) :keys "C-u C-c C-f C-f"]
+ ["Italic" (TeX-font t ?\C-i) :keys "C-u C-c C-f C-i"]
+ ["Slanted" (TeX-font t ?\C-s) :keys "C-u C-c C-f C-s"]
+ ["Roman" (TeX-font t ?\C-r) :keys "C-u C-c C-f C-r"]
+ ["Calligraphic" (TeX-font t ?\C-a) :keys "C-u C-c C-f C-a"])
+ ["Delete Font" (TeX-font t ?\C-d) :keys "C-c C-f C-d"]
+ "-"
+ ["Comment or Uncomment Region"
+ TeX-comment-or-uncomment-region
+ :help "Make the selected region outcommented or active again"]
+ ["Comment or Uncomment Paragraph"
+ TeX-comment-or-uncomment-paragraph
+ :help "Make the current paragraph outcommented or active again"]
+ ("Formatting and Marking"
+ ["Format Environment" LaTeX-fill-environment
+ :help "Fill and indent the current environment"]
+ ["Format Paragraph" LaTeX-fill-paragraph
+ :help "Fill and ident the current paragraph"]
+ ["Format Region" LaTeX-fill-region
+ :help "Fill and indent the currently selected region"]
+ ["Format Section" LaTeX-fill-section
+ :help "Fill and indent the current section"]
+ "-"
+ ["Mark Environment" LaTeX-mark-environment
+ :help "Mark the current environment"]
+ ["Mark Section" LaTeX-mark-section
+ :help "Mark the current section"]
+ "-"
+ ["Beginning of Environment" LaTeX-find-matching-begin
+ :help "Move point to the beginning of the current environment"]
+ ["End of Environment" LaTeX-find-matching-end
+ :help "Move point to the end of the current environment"])
+ ,TeX-fold-menu
+ ["Math Mode" LaTeX-math-mode
+ :style toggle :selected LaTeX-math-mode
+ :help "Toggle math mode"]
+ "-"
+ [ "Convert 209 to 2e" LaTeX-209-to-2e
+ :visible (member "latex2" (TeX-style-list)) ]
+ . ,TeX-common-menu-entries)))
+
+(defcustom LaTeX-font-list
+ '((?\C-a "" "" "\\mathcal{" "}")
+ (?\C-b "\\textbf{" "}" "\\mathbf{" "}")
+ (?\C-c "\\textsc{" "}")
+ (?\C-e "\\emph{" "}")
+ (?\C-f "\\textsf{" "}" "\\mathsf{" "}")
+ (?\C-i "\\textit{" "}" "\\mathit{" "}")
+ (?\C-m "\\textmd{" "}")
+ (?\C-n "\\textnormal{" "}" "\\mathnormal{" "}")
+ (?\C-r "\\textrm{" "}" "\\mathrm{" "}")
+ (?\C-s "\\textsl{" "}" "\\mathbb{" "}")
+ (?\C-t "\\texttt{" "}" "\\mathtt{" "}")
+ (?\C-u "\\textup{" "}")
+ (?\C-d "" "" t))
+ "Font commands used with LaTeX2e. See `TeX-font-list'."
+ :group 'LaTeX-macro
+ :type '(repeat
+ (group
+ :value (?\C-a "" "")
+ (character :tag "Key")
+ (string :tag "Prefix")
+ (string :tag "Suffix")
+ (option (group
+ :inline t
+ (string :tag "Math Prefix")
+ (string :tag "Math Suffix")))
+ (option (sexp :format "Replace\n" :value t)))))
+
+
+;;; Simple Commands
+
+(defcustom LaTeX-babel-hyphen "\"="
+ "String to be used when typing `-'.
+This usually is a hyphen alternative or hyphenation aid, like
+\"=, \"~ or \"-, provided by babel and the related language style
+files.
+
+Set it to an empty string or nil in order to disable this
+feature. Alter `LaTeX-babel-hyphen-language-alist' in case you
+want to change the behavior for a specific language only."
+ :group 'LaTeX-macro
+ :type 'string)
+
+(defcustom LaTeX-babel-hyphen-after-hyphen t
+ "Control insertion of hyphen strings.
+If non-nil insert normal hyphen on first key press and swap it
+with the language-specific hyphen string specified in the
+variable `LaTeX-babel-hyphen' on second key press. If nil do it
+the other way round."
+ :group 'LaTeX-macro
+ :type 'boolean)
+
+(defcustom LaTeX-babel-hyphen-language-alist nil
+ "Alist controlling hyphen insertion for specific languages.
+It may be used to override the defaults given by `LaTeX-babel-hyphen'
+and `LaTeX-babel-hyphen-after-hyphen' respectively. The first item
+in each element is a string specifying the language as set by the
+language-specific style file. The second item is the string to be
+used instead of `LaTeX-babel-hyphen'. The third element is the
+value overriding `LaTeX-bybel-hyphen-after-hyphen'."
+ :group 'LaTeX-macro
+ :type '(alist :key-type (string :tag "Language")
+ :value-type (group (string :tag "Hyphen string")
+ (boolean :tag "Insert plain hyphen first"
+ :value t))))
+
+(defvar LaTeX-babel-hyphen-language nil
+ "String determining language-specific behavior of hyphen insertion.
+It serves as an indicator that the babel hyphenation string
+should be used and as a means to find a potential customization
+in `LaTeX-babel-hyphen-language-alist' related to the active
+language. It is usually set by language-related style files.")
+(make-variable-buffer-local 'LaTeX-babel-hyphen-language)
+
+(defun LaTeX-babel-insert-hyphen (force)
+ "Insert a hyphen string.
+The string can be either a normal hyphen or the string specified
+in `LaTeX-babel-hyphen'. Wether one or the other is chosen
+depends on the value of `LaTeX-babel-hyphen-after-hyphen' and
+the buffer context.
+If prefix argument FORCE is non-nil, always insert a regular hyphen."
+ (interactive "*P")
+ (if (or force
+ (zerop (length LaTeX-babel-hyphen))
+ (not LaTeX-babel-hyphen-language)
+ ;; FIXME: It would be nice to check for verbatim constructs in the
+ ;; non-font-locking case, but things like `LaTeX-current-environment'
+ ;; are rather expensive in large buffers.
+ (and (fboundp 'font-latex-faces-present-p)
+ (font-latex-faces-present-p '(font-latex-verbatim-face
+ font-latex-math-face
+ font-lock-comment-face)))
+ (texmathp)
+ (TeX-in-comment))
+ (call-interactively 'self-insert-command)
+ (let* ((lang (assoc LaTeX-babel-hyphen-language
+ LaTeX-babel-hyphen-language-alist))
+ (hyphen (if lang (nth 1 lang) LaTeX-babel-hyphen))
+ (h-after-h (if lang (nth 2 lang) LaTeX-babel-hyphen-after-hyphen))
+ (hyphen-length (length hyphen)))
+ (cond
+ ;; "= --> -- / -
+ ((string= (buffer-substring (max (- (point) hyphen-length) (point-min))
+ (point))
+ hyphen)
+ (if h-after-h
+ (progn (delete-backward-char hyphen-length)
+ (insert "--"))
+ (delete-backward-char hyphen-length)
+ (call-interactively 'self-insert-command)))
+ ;; -- --> [+]-
+ ((string= (buffer-substring (max (- (point) 2) (point-min))
+ (point))
+ "--")
+ (call-interactively 'self-insert-command))
+ ;; - --> "= / [+]-
+ ((eq (char-before) ?-)
+ (if h-after-h
+ (progn (delete-backward-char 1)
+ (insert hyphen))
+ (call-interactively 'self-insert-command)))
+ (h-after-h
+ (call-interactively 'self-insert-command))
+ (t (insert hyphen))))))
+;; Cater for Delete Selection mode
+(put 'LaTeX-babel-insert-hyphen 'delete-selection t)
+
+(defcustom LaTeX-enable-toolbar t
+ "Enable LaTeX tool bar."
+ :group 'TeX-tool-bar
+ :type 'boolean)
+
+(defun LaTeX-maybe-install-toolbar ()
+ "Conditionally install tool bar buttons for LaTeX mode.
+Install tool bar if `LaTeX-enable-toolbar' is non-nil."
+ (when LaTeX-enable-toolbar
+ ;; Defined in `tex-bar.el':
+ (LaTeX-install-toolbar)))
+
+;;; Mode
+
+(defgroup LaTeX-macro nil
+ "Special support for LaTeX macros in AUCTeX."
+ :prefix "TeX-"
+ :group 'LaTeX
+ :group 'TeX-macro)
+
+(defcustom TeX-arg-cite-note-p nil
+ "*If non-nil, ask for optional note in citations."
+ :type 'boolean
+ :group 'LaTeX-macro)
+
+(defcustom TeX-arg-footnote-number-p nil
+ "*If non-nil, ask for optional number in footnotes."
+ :type 'boolean
+ :group 'LaTeX-macro)
+
+(defcustom TeX-arg-item-label-p nil
+ "*If non-nil, always ask for optional label in items.
+Otherwise, only ask in description environments."
+ :type 'boolean
+ :group 'LaTeX-macro)
+
+(defcustom TeX-arg-right-insert-p t
+ "*If non-nil, always insert automatically the corresponding \\right.
+This happens when \\left is inserted."
+ :type 'boolean
+ :group 'LaTeX-macro)
+
+(defcustom LaTeX-mode-hook nil
+ "A hook run in LaTeX mode buffers."
+ :type 'hook
+ :group 'LaTeX)
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.drv\\'" . latex-mode))
+
+;;;###autoload
+(defun TeX-latex-mode ()
+ "Major mode in AUCTeX for editing LaTeX files.
+See info under AUCTeX for full documentation.
+
+Special commands:
+\\{LaTeX-mode-map}
+
+Entering LaTeX mode calls the value of `text-mode-hook',
+then the value of `TeX-mode-hook', and then the value
+of `LaTeX-mode-hook'."
+ (interactive)
+ (LaTeX-common-initialization)
+ (setq TeX-base-mode-name "LaTeX")
+ (setq major-mode 'latex-mode)
+ (setq TeX-command-default "LaTeX")
+ (setq TeX-sentinel-default-function 'TeX-LaTeX-sentinel)
+ (add-hook 'tool-bar-mode-on-hook 'LaTeX-maybe-install-toolbar nil t)
+ (when (if (featurep 'xemacs)
+ (featurep 'toolbar)
+ (and (boundp 'tool-bar-mode) tool-bar-mode))
+ (LaTeX-maybe-install-toolbar))
+ (TeX-run-mode-hooks 'text-mode-hook 'TeX-mode-hook 'LaTeX-mode-hook)
+ (TeX-set-mode-name)
+ ;; Defeat filladapt
+ (if (and (boundp 'filladapt-mode)
+ filladapt-mode)
+ (turn-off-filladapt-mode)))
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.dtx\\'" . doctex-mode))
+
+;;;###autoload
+(define-derived-mode docTeX-mode TeX-latex-mode "docTeX"
+ "Major mode in AUCTeX for editing .dtx files derived from `LaTeX-mode'.
+Runs `LaTeX-mode', sets a few variables and
+runs the hooks in `docTeX-mode-hook'."
+ (setq major-mode 'doctex-mode)
+ (set (make-local-variable 'LaTeX-insert-into-comments) t)
+ (set (make-local-variable 'LaTeX-syntactic-comments) t)
+ (setq TeX-default-extension docTeX-default-extension)
+ ;; Make filling and indentation aware of DocStrip guards.
+ (setq paragraph-start (concat paragraph-start "\\|%<")
+ paragraph-separate (concat paragraph-separate "\\|%<")
+ TeX-comment-start-regexp "\\(?:%\\(?:<[^>]+>\\)?\\)")
+ (setq TeX-base-mode-name "docTeX")
+ (TeX-set-mode-name)
+ (funcall TeX-install-font-lock))
+
+;;This is actually a mess: to fit the scheme properly, our derived
+;;mode definition would have had to be made for TeX-doctex-mode in the
+;;first place, but then we could not have used define-derived-mode, or
+;;all mode-specific variables would have gotten non-AUCTeX names.
+;;This solution has the advantage that documentation strings are
+;;provided in the autoloads, and has the disadvantage that docTeX-mode
+;;is not aliased to doctex-mode (not even when the AUCTeX version is
+;;disabled) as would be normal for our scheme.
+
+;;;###autoload
+(defalias 'TeX-doctex-mode 'docTeX-mode)
+
+(defcustom docTeX-clean-intermediate-suffixes
+ TeX-clean-default-intermediate-suffixes
+ "List of regexps matching suffixes of files to be deleted.
+The regexps will be anchored at the end of the file name to be matched,
+i.e. you do _not_ have to cater for this yourself by adding \\\\' or $."
+ :type '(repeat regexp)
+ :group 'TeX-command)
+
+(defcustom docTeX-clean-output-suffixes TeX-clean-default-output-suffixes
+ "List of regexps matching suffixes of files to be deleted.
+The regexps will be anchored at the end of the file name to be matched,
+i.e. you do _not_ have to cater for this yourself by adding \\\\' or $."
+ :type '(repeat regexp)
+ :group 'TeX-command)
+
+(defvar LaTeX-header-end
+ (concat "^[^%\n]*" (regexp-quote TeX-esc) "begin *"
+ TeX-grop "document" TeX-grcl)
+ "Default end of header marker for LaTeX documents.")
+
+(defvar LaTeX-trailer-start
+ (concat "^[^%\n]*" (regexp-quote TeX-esc) "end *"
+ TeX-grop "document" TeX-grcl)
+ "Default start of trailer marker for LaTeX documents.")
+
+(defcustom LaTeX-clean-intermediate-suffixes
+ TeX-clean-default-intermediate-suffixes
+ "List of regexps matching suffixes of files to be deleted.
+The regexps will be anchored at the end of the file name to be matched,
+i.e. you do _not_ have to cater for this yourself by adding \\\\' or $."
+ :type '(repeat regexp)
+ :group 'TeX-command)
+
+(defcustom LaTeX-clean-output-suffixes TeX-clean-default-output-suffixes
+ "List of regexps matching suffixes of files to be deleted.
+The regexps will be anchored at the end of the file name to be matched,
+i.e. you do _not_ have to cater for this yourself by adding \\\\' or $."
+ :type '(repeat regexp)
+ :group 'TeX-command)
+
+(defun LaTeX-common-initialization ()
+ "Common initialization for LaTeX derived modes."
+ (VirTeX-common-initialization)
+ (set-syntax-table LaTeX-mode-syntax-table)
+ (make-local-variable 'indent-line-function)
+ (setq indent-line-function 'LaTeX-indent-line)
+
+ ;; Filling
+ (make-local-variable 'paragraph-ignore-fill-prefix)
+ (setq paragraph-ignore-fill-prefix t)
+ (make-local-variable 'fill-paragraph-function)
+ (setq fill-paragraph-function 'LaTeX-fill-paragraph)
+ (make-local-variable 'adaptive-fill-mode)
+ (setq adaptive-fill-mode nil)
+
+ (or LaTeX-largest-level
+ (setq LaTeX-largest-level (LaTeX-section-level "section")))
+
+ (setq TeX-header-end LaTeX-header-end
+ TeX-trailer-start LaTeX-trailer-start)
+
+ (require 'outline)
+ (make-local-variable 'outline-level)
+ (setq outline-level 'LaTeX-outline-level)
+ (make-local-variable 'outline-regexp)
+ (setq outline-regexp (LaTeX-outline-regexp t))
+ (when (boundp 'outline-heading-alist)
+ (setq outline-heading-alist
+ (mapcar (lambda (x)
+ (cons (concat "\\" (nth 0 x)) (nth 1 x)))
+ LaTeX-section-list)))
+
+ (make-local-variable 'TeX-auto-full-regexp-list)
+ (setq TeX-auto-full-regexp-list
+ (append LaTeX-auto-regexp-list plain-TeX-auto-regexp-list))
+
+ (LaTeX-set-paragraph-start)
+ (setq paragraph-separate
+ (concat
+ "[ \t]*%*[ \t]*\\("
+ "\\$\\$" ; Plain TeX display math
+ "\\|$\\)"))
+
+ (setq TeX-verbatim-p-function 'LaTeX-verbatim-p)
+ (setq TeX-search-forward-comment-start-function
+ 'LaTeX-search-forward-comment-start)
+
+ (make-local-variable 'LaTeX-item-list)
+ (setq LaTeX-item-list '(("description" . LaTeX-item-argument)
+ ("thebibliography" . LaTeX-item-bib)))
+
+ (setq TeX-complete-list
+ (append '(("\\\\cite\\[[^]\n\r\\%]*\\]{\\([^{}\n\r\\%,]*\\)"
+ 1 LaTeX-bibitem-list "}")
+ ("\\\\cite{\\([^{}\n\r\\%,]*\\)" 1 LaTeX-bibitem-list "}")
+ ("\\\\cite{\\([^{}\n\r\\%]*,\\)\\([^{}\n\r\\%,]*\\)"
+ 2 LaTeX-bibitem-list)
+ ("\\\\nocite{\\([^{}\n\r\\%,]*\\)" 1 LaTeX-bibitem-list "}")
+ ("\\\\nocite{\\([^{}\n\r\\%]*,\\)\\([^{}\n\r\\%,]*\\)"
+ 2 LaTeX-bibitem-list)
+ ("\\\\ref{\\([^{}\n\r\\%,]*\\)" 1 LaTeX-label-list "}")
+ ("\\\\eqref{\\([^{}\n\r\\%,]*\\)" 1 LaTeX-label-list "}")
+ ("\\\\pageref{\\([^{}\n\r\\%,]*\\)" 1 LaTeX-label-list "}")
+ ("\\\\\\(index\\|glossary\\){\\([^{}\n\r\\%]*\\)"
+ 2 LaTeX-index-entry-list "}")
+ ("\\\\begin{\\([A-Za-z]*\\)" 1 LaTeX-environment-list "}")
+ ("\\\\end{\\([A-Za-z]*\\)" 1 LaTeX-environment-list "}")
+ ("\\\\renewcommand\\*?{\\\\\\([A-Za-z]*\\)"
+ 1 LaTeX-symbol-list "}")
+ ("\\\\renewenvironment\\*?{\\([A-Za-z]*\\)"
+ 1 LaTeX-environment-list "}"))
+ TeX-complete-list))
+
+ (LaTeX-add-environments
+ '("document" LaTeX-env-document)
+ '("enumerate" LaTeX-env-item)
+ '("itemize" LaTeX-env-item)
+ '("list" LaTeX-env-list)
+ '("trivlist" LaTeX-env-item)
+ '("picture" LaTeX-env-picture)
+ '("tabular" LaTeX-env-array)
+ '("tabular*" LaTeX-env-tabular*)
+ '("array" LaTeX-env-array)
+ '("eqnarray" LaTeX-env-label)
+ '("equation" LaTeX-env-label)
+ '("minipage" LaTeX-env-minipage)
+
+ ;; The following have no special support, but are included in
+ ;; case the auto files are missing.
+
+ "sloppypar" "picture" "tabbing" "verbatim" "verbatim*"
+ "flushright" "flushleft" "displaymath" "math" "quote" "quotation"
+ "abstract" "center" "titlepage" "verse" "eqnarray*"
+
+ ;; The following are not defined in latex.el, but in a number of
+ ;; other style files. I'm to lazy to copy them to all the
+ ;; corresponding .el files right now.
+
+ ;; This means that AUCTeX will complete e.g.
+ ;; ``thebibliography'' in a letter, but I guess we can live with
+ ;; that.
+
+ '("description" LaTeX-env-item)
+ '("figure" LaTeX-env-figure)
+ '("figure*" LaTeX-env-figure)
+ '("table" LaTeX-env-figure)
+ '("table*" LaTeX-env-figure)
+ '("thebibliography" LaTeX-env-bib)
+ '("theindex" LaTeX-env-item))
+
+ (TeX-add-symbols
+ '("addtocounter" TeX-arg-counter "Value")
+ '("alph" TeX-arg-counter)
+ '("arabic" TeX-arg-counter)
+ '("fnsymbol" TeX-arg-counter)
+ '("newcounter" TeX-arg-define-counter
+ [ TeX-arg-counter "Within counter" ])
+ '("roman" TeX-arg-counter)
+ '("setcounter" TeX-arg-counter "Value")
+ '("usecounter" TeX-arg-counter)
+ '("value" TeX-arg-counter)
+ '("stepcounter" TeX-arg-counter)
+ '("refstepcounter" TeX-arg-counter)
+ '("label" TeX-arg-define-label)
+ '("pageref" TeX-arg-ref)
+ '("ref" TeX-arg-ref)
+ '("newcommand" TeX-arg-define-macro [ "Number of arguments" ] t)
+ '("renewcommand" TeX-arg-macro [ "Number of arguments" ] t)
+ '("newenvironment" TeX-arg-define-environment
+ [ "Number of arguments"] t t)
+ '("renewenvironment" TeX-arg-environment
+ [ "Number of arguments"] t t)
+ '("providecommand" TeX-arg-define-macro [ "Number of arguments" ] t)
+ '("providecommand*" TeX-arg-define-macro [ "Number of arguments" ] t)
+ '("newcommand*" TeX-arg-define-macro [ "Number of arguments" ] t)
+ '("renewcommand*" TeX-arg-macro [ "Number of arguments" ] t)
+ '("newenvironment*" TeX-arg-define-environment
+ [ "Number of arguments"] t t)
+ '("renewenvironment*" TeX-arg-environment
+ [ "Number of arguments"] t t)
+ '("newtheorem" TeX-arg-define-environment
+ [ TeX-arg-environment "Numbered like" ]
+ t [ (TeX-arg-eval progn (if (eq (save-excursion
+ (backward-char 2)
+ (preceding-char)) ?\])
+ ()
+ (TeX-arg-counter t "Within counter"))
+ "") ])
+ '("newfont" TeX-arg-define-macro t)
+ '("circle" "Diameter")
+ '("circle*" "Diameter")
+ '("dashbox" "Dash Length" TeX-arg-size
+ [ TeX-arg-corner ] t)
+ '("frame" t)
+ '("framebox" (TeX-arg-conditional
+ (string-equal (LaTeX-current-environment) "picture")
+ (TeX-arg-size [ TeX-arg-corner ] t)
+ ([ "Length" ] [ TeX-arg-lr ] t)))
+ '("line" (TeX-arg-pair "X slope" "Y slope") "Length")
+ '("linethickness" "Dimension")
+ '("makebox" (TeX-arg-conditional
+ (string-equal (LaTeX-current-environment) "picture")
+ (TeX-arg-size [ TeX-arg-corner ] t)
+ ([ "Length" ] [ TeX-arg-lr ] t)))
+ '("multiput"
+ TeX-arg-coordinate
+ (TeX-arg-pair "X delta" "Y delta")
+ "Number of copies"
+ t)
+ '("oval" TeX-arg-size [ TeX-arg-corner "Portion" ])
+ '("put" TeX-arg-coordinate t)
+ '("savebox" TeX-arg-savebox
+ (TeX-arg-conditional
+ (string-equal (LaTeX-current-environment) "picture")
+ (TeX-arg-size [ TeX-arg-corner ] t)
+ ([ "Length" ] [ TeX-arg-lr ] t)))
+ '("shortstack" [ TeX-arg-lr ] t)
+ '("vector" (TeX-arg-pair "X slope" "Y slope") "Length")
+ '("cline" "Span `i-j'")
+ '("multicolumn" "Columns" "Format" t)
+ '("item"
+ (TeX-arg-conditional (or TeX-arg-item-label-p
+ (string-equal (LaTeX-current-environment)
+ "description"))
+ ([ "Item label" ])
+ ())
+ (TeX-arg-literal " "))
+ '("bibitem" [ "Bibitem label" ] TeX-arg-define-cite)
+ '("cite"
+ (TeX-arg-conditional TeX-arg-cite-note-p ([ "Note" ]) ())
+ TeX-arg-cite)
+ '("nocite" TeX-arg-cite)
+ '("bibliographystyle" TeX-arg-bibstyle)
+ '("bibliography" TeX-arg-bibliography)
+ '("footnote"
+ (TeX-arg-conditional TeX-arg-footnote-number-p ([ "Number" ]) nil)
+ t)
+ '("footnotetext"
+ (TeX-arg-conditional TeX-arg-footnote-number-p ([ "Number" ]) nil)
+ t)
+ '("footnotemark"
+ (TeX-arg-conditional TeX-arg-footnote-number-p ([ "Number" ]) nil))
+ '("newlength" TeX-arg-define-macro)
+ '("setlength" TeX-arg-macro "Length")
+ '("addtolength" TeX-arg-macro "Length")
+ '("settowidth" TeX-arg-macro t)
+ '("\\" [ "Space" ])
+ '("\\*" [ "Space" ])
+ '("hyphenation" t)
+ '("linebreak" [ "How much [0 - 4]" ])
+ '("nolinebreak" [ "How much [0 - 4]" ])
+ '("nopagebreak" [ "How much [0 - 4]" ])
+ '("pagebreak" [ "How much [0 - 4]" ])
+ '("stackrel" t nil)
+ '("frac" t nil)
+ '("lefteqn" t)
+ '("overbrace" t)
+ '("overline" t)
+ '("overleftarrow" t)
+ '("overrightarrow" t)
+ '("sqrt" [ "Root" ] t)
+ '("underbrace" t)
+ '("underline" t)
+ '("author" t)
+ '("date" t)
+ '("thanks" t)
+ '("title" t)
+ '("pagenumbering" (TeX-arg-eval
+ completing-read "Numbering style: "
+ '(("arabic") ("roman") ("Roman") ("alph") ("Alph"))))
+ '("pagestyle" TeX-arg-pagestyle)
+ '("markboth" t nil)
+ '("markright" t)
+ '("thispagestyle" TeX-arg-pagestyle)
+ '("addvspace" "Length")
+ '("fbox" t)
+ '("hspace*" "Length")
+ '("hspace" "Length")
+ '("mbox" t)
+ '("newsavebox" TeX-arg-define-savebox)
+ '("parbox" [ TeX-arg-tb ] [ "Height" ] [ TeX-arg-tb "Inner position" ]
+ "Width" t)
+ '("raisebox" "Raise" [ "Height above" ] [ "Depth below" ] t)
+ '("rule" [ "Raise" ] "Width" "Thickness")
+ '("sbox" TeX-arg-savebox t)
+ '("usebox" TeX-arg-savebox)
+ '("vspace*" "Length")
+ '("vspace" "Length")
+ '("documentstyle" TeX-arg-document)
+ '("include" (TeX-arg-input-file "File" t))
+ '("includeonly" t)
+ '("input" TeX-arg-input-file)
+ '("addcontentsline" TeX-arg-file
+ (TeX-arg-eval
+ completing-read "Numbering style: " LaTeX-section-list)
+ t)
+ '("addtocontents" TeX-arg-file t)
+ '("typeout" t)
+ '("typein" [ TeX-arg-define-macro ] t)
+ '("verb" TeX-arg-verb)
+ '("verb*" TeX-arg-verb)
+ '("extracolsep" t)
+ '("index" TeX-arg-index)
+ '("glossary" TeX-arg-index)
+ '("numberline" "Section number" "Heading")
+ '("caption" t)
+ '("marginpar" [ "Left margin text" ] "Text")
+ '("left" TeX-arg-insert-braces)
+
+ ;; These have no special support, but are included in case the
+ ;; auto files are missing.
+
+ "TeX" "LaTeX"
+ "samepage" "newline"
+ "smallskip" "medskip" "bigskip" "fill" "stretch"
+ "thinspace" "negthinspace" "enspace" "enskip" "quad" "qquad"
+ "nonumber" "centering" "raggedright"
+ "raggedleft" "kill" "pushtabs" "poptabs" "protect" "arraystretch"
+ "hline" "vline" "cline" "thinlines" "thicklines" "and" "makeindex"
+ "makeglossary" "reversemarginpar" "normalmarginpar"
+ "raggedbottom" "flushbottom" "sloppy" "fussy" "newpage"
+ "clearpage" "cleardoublepage" "twocolumn" "onecolumn"
+
+ "maketitle" "tableofcontents" "listoffigures" "listoftables"
+ "tiny" "scriptsize" "footnotesize" "small"
+ "normalsize" "large" "Large" "LARGE" "huge" "Huge"
+ "pounds" "copyright"
+ "hfil" "hfill" "vfil" "vfill" "hrulefill" "dotfill"
+ "indent" "noindent" "today"
+ "appendix"
+ "dots")
+
+ (when (string-equal LaTeX-version "2e")
+ (LaTeX-add-environments
+ '("filecontents" LaTeX-env-contents)
+ '("filecontents*" LaTeX-env-contents))
+
+ (TeX-add-symbols
+ '("enlargethispage" "Length")
+ '("enlargethispage*" "Length")
+ '("tabularnewline" [ "Length" ])
+ '("suppressfloats" [ TeX-arg-tb "Suppress floats position" ])
+ '("ensuremath" "Math commands")
+ '("textsuperscript" "Text")
+ '("textcircled" "Text")
+
+ "LaTeXe"
+ "listfiles" "frontmatter" "mainmatter" "backmatter"
+ "textcompwordmark" "textvisiblespace" "textemdash" "textendash"
+ "textexclamdown" "textquestiondown" "textquotedblleft"
+ "textquotedblright" "textquoteleft" "textquoteright"
+ "textbullet" "textperiodcentered"
+ "textbackslash" "textbar" "textless" "textgreater"
+ "textasciicircum" "textasciitilde"
+ "textregistered" "texttrademark"
+ "rmfamily" "sffamily" "ttfamily" "mdseries" "bfseries"
+ "itshape" "slshape" "upshape" "scshape"))
+
+ (TeX-run-style-hooks "LATEX")
+
+ (make-local-variable 'TeX-font-list)
+ (make-local-variable 'TeX-font-replace-function)
+ (if (string-equal LaTeX-version "2")
+ ()
+ (setq TeX-font-list LaTeX-font-list)
+ (setq TeX-font-replace-function 'TeX-font-replace-macro)
+ (TeX-add-symbols
+ '("newcommand" TeX-arg-define-macro
+ [ "Number of arguments" ] [ "Default value for first argument" ] t)
+ '("renewcommand" TeX-arg-macro
+ [ "Number of arguments" ] [ "Default value for first argument" ] t)
+ '("providecommand" TeX-arg-define-macro
+ [ "Number of arguments" ] [ "Default value for first argument" ] t)
+ '("providecommand*" TeX-arg-define-macro
+ [ "Number of arguments" ] [ "Default value for first argument" ] t)
+ '("newcommand*" TeX-arg-define-macro
+ [ "Number of arguments" ] [ "Default value for first argument" ] t)
+ '("renewcommand*" TeX-arg-macro
+ [ "Number of arguments" ] [ "Default value for first argument" ] t)
+ '("usepackage" LaTeX-arg-usepackage)
+ '("RequirePackage" LaTeX-arg-usepackage)
+ '("documentclass" TeX-arg-document)))
+
+ (TeX-add-style-hook "latex2e"
+ ;; Use new fonts for `\documentclass' documents.
+ (lambda ()
+ (setq TeX-font-list LaTeX-font-list)
+ (setq TeX-font-replace-function 'TeX-font-replace-macro)
+ (run-hooks 'LaTeX2e-hook)))
+
+ (TeX-add-style-hook "latex2"
+ ;; Use old fonts for `\documentstyle' documents.
+ (lambda ()
+ (setq TeX-font-list (default-value 'TeX-font-list))
+ (setq TeX-font-replace-function
+ (default-value 'TeX-font-replace-function))
+ (run-hooks 'LaTeX2-hook)))
+
+ ;; There must be something better-suited, but I don't understand the
+ ;; parsing properly. -- dak
+ (TeX-add-style-hook "pdftex" 'TeX-PDF-mode-on)
+ (TeX-add-style-hook "pdftricks" 'TeX-PDF-mode-on)
+ (TeX-add-style-hook "pst-pdf" 'TeX-PDF-mode-on)
+ (TeX-add-style-hook "dvips" 'TeX-PDF-mode-off)
+;; This is now done in style/pstricks.el because it prevents other
+;; pstricks style files from being loaded.
+;; (TeX-add-style-hook "pstricks" 'TeX-PDF-mode-off)
+ (TeX-add-style-hook "psfrag" 'TeX-PDF-mode-off)
+ (TeX-add-style-hook "dvipdf" 'TeX-PDF-mode-off)
+ (TeX-add-style-hook "dvipdfm" 'TeX-PDF-mode-off)
+;; (TeX-add-style-hook "DVIoutput" 'TeX-PDF-mode-off)
+;;
+;; Well, DVIoutput indicates that we want to run PDFTeX and expect to
+;; get DVI output. Ugh.
+ (TeX-add-style-hook "ifpdf" (lambda ()
+ (TeX-PDF-mode-on)
+ (TeX-PDF-mode-off)))
+;; ifpdf indicates that we cater for either. So calling both
+;; functions will make sure that the default will get used unless the
+;; user overrode it.
+
+ (set (make-local-variable 'imenu-create-index-function)
+ 'LaTeX-imenu-create-index-function)
+
+ (use-local-map LaTeX-mode-map)
+ ;; Calling `easy-menu-add' may result in the menu filters being
+ ;; executed which call `TeX-update-style'. So this is placed very
+ ;; late in mode initialization to assure that all relevant variables
+ ;; are properly initialized before style files try to alter them.
+ (easy-menu-add LaTeX-mode-menu LaTeX-mode-map)
+ (easy-menu-add LaTeX-mode-command-menu LaTeX-mode-map))
+
+(defun LaTeX-imenu-create-index-function ()
+ "Imenu support function for LaTeX."
+ (TeX-update-style)
+ (let (entries level
+ (regexp (LaTeX-outline-regexp)))
+ (goto-char (point-max))
+ (while (re-search-backward regexp nil t)
+ (let* ((name (LaTeX-outline-name))
+ (level (make-string (1- (LaTeX-outline-level)) ?\ ))
+ (label (concat level level name))
+ (mark (make-marker)))
+ (set-marker mark (point))
+ (set-text-properties 0 (length label) nil label)
+ (setq entries (cons (cons label mark) entries))))
+ entries))
+
+(defvar LaTeX-builtin-opts
+ '("12pt" "11pt" "10pt" "twocolumn" "twoside" "draft")
+ "Built in options for LaTeX standard styles.")
+
+(defun LaTeX-209-to-2e ()
+ "Make a stab at changing 2.09 doc header to 2e style."
+ (interactive)
+ (TeX-home-buffer)
+ (let (optstr optlist 2eoptlist 2epackages docline docstyle)
+ (goto-char (point-min))
+ (if
+ (search-forward-regexp
+ "\\documentstyle\\[\\([^]]*\\)\\]{\\([^}]*\\)}"
+ (point-max) t)
+ (setq optstr (TeX-match-buffer 1)
+ docstyle (TeX-match-buffer 2)
+ optlist (TeX-split-string "," optstr))
+ (if (search-forward-regexp
+ "\\documentstyle{\\([^}]*\\)}"
+ (point-max) t)
+ (setq docstyle (TeX-match-buffer 1))
+ (error "No documentstyle defined")))
+ (beginning-of-line 1)
+ (setq docline (point))
+ (insert "%%%")
+ (while optlist
+ (if (member (car optlist) LaTeX-builtin-opts)
+ (setq 2eoptlist (cons (car optlist) 2eoptlist))
+ (setq 2epackages (cons (car optlist) 2epackages)))
+ (setq optlist (cdr optlist)))
+ ;;(message (format "%S %S" 2eoptlist 2epackages))
+ (goto-char docline)
+ (forward-line 1)
+ (insert "\\documentclass")
+ (if 2eoptlist
+ (insert "["
+ (mapconcat (lambda (x) x)
+ (nreverse 2eoptlist) ",") "]"))
+ (insert "{" docstyle "}\n")
+ (if 2epackages
+ (insert "\\usepackage{"
+ (mapconcat (lambda (x) x)
+ (nreverse 2epackages) "}\n\\usepackage{") "}\n"))
+ (if (equal docstyle "slides")
+ (progn
+ (goto-char (point-min))
+ (while (re-search-forward "\\\\blackandwhite{" nil t)
+ (replace-match "\\\\input{" nil nil)))))
+ (TeX-normal-mode nil))
+
+(provide 'latex)
+
+;;; latex.el ends here
--- /dev/null
+%%
+%% This is file `prauctex.cfg',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% preview.dtx (with options: `auccfg')
+%%
+%% IMPORTANT NOTICE:
+%%
+%% For the copyright see the source file.
+%%
+%% Any modified versions of this file must be renamed
+%% with new filenames distinct from prauctex.cfg.
+%%
+%% For distribution of the original source see the terms
+%% for copying and modification in the file preview.dtx.
+%%
+%% This generated file may be distributed as long as the
+%% original source files, as listed above, are part of the
+%% same distribution. (The sources need not necessarily be
+%% in the same archive or directory.)
+%% The preview style for extracting previews from LaTeX documents.
+%% Developed as part of AUCTeX <URL:http://www.gnu.org/software/auctex>.
+\PreviewMacro*[[][#1{}]\footnote
+\PreviewMacro*[?[{@{[]}}{}][#1]\item
+\PreviewMacro*\emph
+\PreviewMacro*\textrm
+\PreviewMacro*\textit
+\PreviewMacro*\textsc
+\PreviewMacro*\textsf
+\PreviewMacro*\textsl
+\PreviewMacro*\texttt
+\PreviewMacro*\textcolor
+\PreviewMacro*\mbox
+\PreviewMacro*[][#1{}]\author
+\PreviewMacro*[][#1{}]\title
+\PreviewMacro*\and
+\PreviewMacro*\thanks
+\PreviewMacro*[][#1{}]\caption
+\preview@delay{\@ifundefined{pr@\string\@startsection}{%
+ \PreviewMacro*[!!!!!!*][#1{}]\@startsection}{}}
+\preview@delay{\@ifundefined{pr@\string\chapter}{%
+ \PreviewMacro*[*][#1{}]\chapter}{}}
+\PreviewMacro*\index
+\endinput
+%%
+%% End of file `prauctex.cfg'.
--- /dev/null
+%%
+%% This is file `prauctex.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% preview.dtx (with options: `auctex')
+%%
+%% IMPORTANT NOTICE:
+%%
+%% For the copyright see the source file.
+%%
+%% Any modified versions of this file must be renamed
+%% with new filenames distinct from prauctex.def.
+%%
+%% For distribution of the original source see the terms
+%% for copying and modification in the file preview.dtx.
+%%
+%% This generated file may be distributed as long as the
+%% original source files, as listed above, are part of the
+%% same distribution. (The sources need not necessarily be
+%% in the same archive or directory.)
+%% The preview style for extracting previews from LaTeX documents.
+%% Developed as part of AUCTeX <URL:http://www.gnu.org/software/auctex>.
+\ifPreview\else\expandafter\endinput\fi
+\nofiles
+\preview@delay{\nonstopmode}
+\begingroup
+\lccode`\~=`\-
+\lccode`\{=`\<
+\lccode`\}=`\>
+\lowercase{\endgroup
+ \def\pr@msgi{{~}}}
+\def\pr@msgii{Preview:
+ Snippet \number\pr@snippet\space}
+\begingroup
+\catcode`\-=13
+\catcode`\<=13
+\@firstofone{\endgroup
+\def\pr@msg#1{{%
+ \let<\pr@msgi
+ \def-{\pr@msgii#1}%
+ \errhelp{Not a real error.}%
+ \errmessage<}}}
+\g@addto@macro\pr@ship@start{\pr@msg{started}}
+\g@addto@macro\pr@ship@end{\pr@msg{ended.%
+ (\number\ht\pr@box+\number\dp\pr@box x\number\wd\pr@box)}}
+\hbadness=\maxdimen
+\newcount\hbadness
+\vbadness=\maxdimen
+\let\vbadness=\hbadness
+\hfuzz=\maxdimen
+\newdimen\hfuzz
+\vfuzz=\maxdimen
+\let\vfuzz=\hfuzz
+\showboxdepth=-1
+\showboxbreadth=-1
+\pr@loadcfg{prauctex}
+\endinput
+%%
+%% End of file `prauctex.def'.
--- /dev/null
+%%
+%% This is file `prcounters.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% preview.dtx (with options: `counters')
+%%
+%% IMPORTANT NOTICE:
+%%
+%% For the copyright see the source file.
+%%
+%% Any modified versions of this file must be renamed
+%% with new filenames distinct from prcounters.def.
+%%
+%% For distribution of the original source see the terms
+%% for copying and modification in the file preview.dtx.
+%%
+%% This generated file may be distributed as long as the
+%% original source files, as listed above, are part of the
+%% same distribution. (The sources need not necessarily be
+%% in the same archive or directory.)
+%% The preview style for extracting previews from LaTeX documents.
+%% Developed as part of AUCTeX <URL:http://www.gnu.org/software/auctex>.
+\ifPreview\else\expandafter\endinput\fi
+\def\pr@eltprint#1{\expandafter\@gobble\ifnum\value{#1}=0%
+ \csname pr@c@#1\endcsname\else\relax
+ \space{#1}{\arabic{#1}}\fi}
+\def\pr@eltdef#1{\expandafter\xdef
+ \csname pr@c@#1\endcsname{\arabic{#1}}}
+\def\pr@ckpt#1{{\let\@elt\pr@eltprint\edef\next{\cl@@ckpt}%
+ \ifx\next\@empty\else\typeout{Preview: Counters\next#1}%
+ \let\@elt\pr@eltdef\cl@@ckpt\fi}}
+\pr@addto@front\pr@ship@start{\pr@ckpt:}
+\pr@addto@front\pr@ship@end{\pr@ckpt.}
+\endinput
+%%
+%% End of file `prcounters.def'.
--- /dev/null
+%%
+%% This is file `preview.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% preview.dtx (with options: `style')
+%% preview.dtx (with options: `style,active')
+%%
+%% IMPORTANT NOTICE:
+%%
+%% For the copyright see the source file.
+%%
+%% Any modified versions of this file must be renamed
+%% with new filenames distinct from preview.sty.
+%%
+%% For distribution of the original source see the terms
+%% for copying and modification in the file preview.dtx preview.dtx.
+%%
+%% This generated file may be distributed as long as the
+%% original source files, as listed above, are part of the
+%% same distribution. (The sources need not necessarily be
+%% in the same archive or directory.)
+%% The preview style for extracting previews from LaTeX documents.
+%% Developed as part of AUCTeX <URL:http://www.gnu.org/software/auctex>.
+\NeedsTeXFormat{LaTeX2e} \def\reserved@a #1#2$#3:
+#4${\xdef#1{\reserved@c #2#4 $}} \def\reserved@c #1 #2${#1}
+\begingroup \catcode`\_=12
+\reserved@a\pr@version $Name: release_11_86 $ \ifx\pr@version\@empty
+\reserved@a\pr@version CVS-$Revision: 1.126 $ \endgroup \else
+ \def\next release_{} \lccode`\_=`.
+ \edef\next{\lowercase{\endgroup
+ \def\noexpand\pr@version{\expandafter\next\pr@version}}} \next \fi
+\reserved@a\next $Date: 2010/02/14 16:19:00 $
+\edef\next{\noexpand\ProvidesPackage{preview}%
+ [\next\space \pr@version\space (AUCTeX/preview-latex)]}
+\next
+\let\ifPreview\iffalse
+\let\preview@delay=\@gobble
+\let\pr@advise=\@gobbletwo
+\long\def\pr@advise@ship#1#2#3{}
+\def\pr@loadcfg#1{\InputIfFileExists{#1.cfg}{}{}}
+\DeclareOption{noconfig}{\let\pr@loadcfg=\@gobble}
+\long\def\pr@addto@front#1#2{%
+ \toks@{#2}\toks@\expandafter{\the\expandafter\toks@#1}%
+ \xdef#1{\the\toks@}}
+\DeclareOption{active}{%
+ \let\ifPreview\iftrue
+ \def\pr@advise#1{%
+ \expandafter\pr@adviseii\csname pr@\string#1\endcsname#1}%
+ \long\def\pr@advise@ship#1#2#3{\pr@advise#1{\pr@protect@ship{#2}{#3}}}%
+ \let\preview@delay\@firstofone}
+\long\def\pr@adviseii#1#2#3{\preview@delay{%
+ \ifx#1\relax \let#1#2\fi
+ \toks@{#3#1}%
+ \ifx\@undefined\protected \else \protected\fi
+ \long\edef#2{\the\toks@}}}
+\DeclareOption{delayed}{%
+ \ifPreview \def\preview@delay{\AtBeginDocument}\fi
+}
+\newif\ifpr@fixbb
+\pr@fixbbfalse
+\DeclareOption{psfixbb}{\ifPreview%
+ \pr@fixbbtrue
+ \newbox\pr@markerbox
+ \setbox\pr@markerbox\hbox{\special{psfile=/dev/null}}\fi
+}
+\let\pr@graphicstype=\z@
+\DeclareOption{dvips}{%
+ \let\pr@graphicstype\@ne
+ \preview@delay{\AtBeginDvi{%
+ \special{!/preview@version(\pr@version)def}
+ \special{!userdict begin/preview-bop-level 0 def%
+ /bop-hook{/preview-bop-level dup load dup 0 le{/isls false def%
+ /vsize 792 def/hsize 612 def}if 1 add store}bind def%
+ /eop-hook{/preview-bop-level dup load dup 0 gt{1 sub}if
+ store}bind def end}}}}
+\DeclareOption{pdftex}{%
+ \let\pr@graphicstype\tw@}
+\DeclareOption{xetex}{%
+ \let\pr@graphicstype\thr@@}
+\begingroup
+\catcode`\*=11
+\@firstofone{\endgroup
+\DeclareOption{displaymath}{%
+ \preview@delay{\toks@{%
+ \pr@startbox{\noindent$$%
+ \aftergroup\pr@endbox\@gobbletwo}{$$}\@firstofone}%
+ \everydisplay\expandafter{\the\expandafter\toks@
+ \expandafter{\the\everydisplay}}}%
+ \pr@advise@ship\equation{\begingroup\aftergroup\pr@endbox
+ \def\dt@ptrue{\m@ne=\m@ne}\noindent}%
+ {\endgroup}%
+ \pr@advise@ship\equation*{\begingroup\aftergroup\pr@endbox
+ \def\dt@ptrue{\m@ne=\m@ne}\noindent}%
+ {\endgroup}%
+ \PreviewOpen[][\def\dt@ptrue{\m@ne=\m@ne}\noindent#1]\[%
+ \PreviewClose\]%
+ \PreviewEnvironment[][\noindent#1]{eqnarray}%
+ \PreviewEnvironment[][\noindent#1]{eqnarray*}%
+ \PreviewEnvironment{displaymath}%
+}}
+\begingroup
+\def\next#1#2{%
+ \endgroup
+ \DeclareOption{textmath}{%
+ \PreviewEnvironment{math}%
+ \preview@delay{\ifx#1\@undefined \let#1=$%$
+ \fi\catcode`\$=\active
+ \ifx\xyreuncatcodes\@undefined\else
+ \edef\next{\catcode`@=\the\catcode`@\relax}%
+ \makeatother\expandafter\xyreuncatcodes\next\fi}%
+ \pr@advise@ship\(\pr@endaftergroup{}% \)
+ \pr@advise@ship#1{\@firstoftwo{\let#1=#2%
+ \futurelet\reserved@a\pr@textmathcheck}}{}}%
+ \def\pr@textmathcheck{\expandafter\pr@endaftergroup
+ \ifx\reserved@a#1{#2#2}\expandafter\@gobbletwo\fi#2}}
+\lccode`\~=`\$
+\lowercase{\expandafter\next\expandafter~}%
+ \csname pr@\string$%$
+ \endcsname
+\DeclareOption{graphics}{%
+ \PreviewMacro[*[[!]{\includegraphics}%]]
+}
+\def\pr@floatfix#1#2{\ifx#1#2%
+ \ifx#1\@undefined\else
+ \PackageWarningNoLine{preview}{%
+Your document class has a bad definition^^J
+of \string#1, most likely^^J
+\string\let\string#1=\string#2^^J
+which has now been changed to^^J
+\string\def\string#1{\string#2}^^J
+because otherwise subsequent changes to \string#2^^J
+(like done by several packages changing float behaviour)^^J
+can't take effect on \string#1.^^J
+Please complain to your document class author}%
+ \def#1{#2}\fi\fi}
+\begingroup
+\def\next#1#2{\endgroup
+ \DeclareOption{floats}{%
+ \pr@floatfix\endfigure\end@float
+ \pr@floatfix\endtable\end@float
+ \pr@floatfix#1\end@dblfloat
+ \pr@floatfix#2\end@dblfloat
+ \PreviewSnarfEnvironment[![]{@float}%]
+ \PreviewSnarfEnvironment[![]{@dblfloat}%]
+ }}
+\expandafter\next\csname endfigure*\expandafter\endcsname
+ \csname endtable*\endcsname
+\DeclareOption{sections}{%
+ \PreviewMacro[!!!!!!*[[!]{\@startsection}%]]
+ \PreviewMacro[*[[!]{\chapter}%]]
+}
+\DeclareOption*
+ {\InputIfFileExists{pr\CurrentOption.def}{}{\OptionNotUsed}}
+\def\PreviewMacro{\@ifstar\pr@starmacro\pr@macro}
+\long\def\pr@domacro#1#2{%
+ \long\def\next##1{#2}%
+ \pr@callafter\next#1]\pr@endparse}
+\newcommand\pr@macro[1][]{%
+ \toks@{\pr@domacro{#1}}%
+ \long\edef\next[##1]##2{%
+ \noexpand\pr@advise@ship{##2}{\the\toks@{##1\noexpand\pr@endbox}}{}}%
+ \@ifnextchar[\next\pr@macroii}
+\def\pr@macroii{\next[##1]}
+\long\def\pr@endmacro#1{#1\pr@endbox}
+\long\def\pr@protect@domacro#1#2{\pr@protect{%
+ \long\def\next##1{#2}%
+ \pr@callafter\next#1]\pr@endparse}}
+\newcommand\pr@starmacro[1][]{\toks@{\pr@protect@domacro{#1}}%
+ \long\edef\next[##1]##2{%
+ \noexpand\pr@advise##2{\the\toks@{##1}}}%
+ \@ifnextchar[\next{\next[]}}
+\def\PreviewOpen{\@ifstar\pr@starmacro\pr@open}
+\newcommand\pr@open[1][]{%
+ \toks@{\pr@domacro{#1}}%
+ \long\edef\next[##1]##2{%
+ \noexpand\pr@advise##2{\begingroup
+ \noexpand\pr@protect@ship
+ {\the\toks@{\begingroup\aftergroup\noexpand\pr@endbox##1}}%
+ {\endgroup}}}%
+ \@ifnextchar[\next\pr@macroii}
+\def\PreviewClose{\@ifstar\pr@starmacro\pr@close}
+\newcommand\pr@close[1][]{%
+ \toks@{\pr@domacro{#1}}%
+ \long\edef\next[##1]##2{%
+ \noexpand\pr@advise{##2}{\the\toks@{##1\endgroup}}}%
+ \@ifnextchar[\next\pr@macroii}
+\def\PreviewEnvironment{\@ifstar\pr@starenv\pr@env}
+\newcommand\pr@starenv[1][]{\toks@{\pr@starmacro[{#1}]}%
+ \long\edef\next##1##2{%
+ \the\toks@[{##2}]##1}%
+ \begingroup\pr@starenvii}
+\newcommand\pr@starenvii[2][]{\endgroup
+ \expandafter\next\csname#2\endcsname{#1}%
+ \expandafter\pr@starmacro\csname end#2\endcsname}
+\newcommand\pr@env[1][]{%
+ \toks@{\pr@domacro{#1}}%
+ \long\edef\next[##1]##2{%
+ \noexpand\expandafter\noexpand\pr@advise@ship
+ \noexpand\csname##2\noexpand\endcsname{\the\toks@
+ {\begingroup\aftergroup\noexpand\pr@endbox##1}}{\endgroup}}%
+ \@ifnextchar[\next\pr@macroii %]
+ }
+\newcommand{\PreviewSnarfEnvironment}[2][]{%
+ \expandafter\pr@advise
+ \csname #2\endcsname{\pr@snarfafter{#1}}%
+ \expandafter\pr@advise
+ \csname end#2\endcsname{\pr@endsnarf}}
+\let\pr@ship@start\@empty
+\let\pr@ship@end\@empty
+\newenvironment{preview}{\ignorespaces}{\ifhmode\unskip\fi}
+\newenvironment{nopreview}{\ignorespaces}{\ifhmode\unskip\fi}
+\ProcessOptions\relax
+\ifPreview\else\expandafter\endinput\fi
+%% The preview style for extracting previews from LaTeX documents.
+%% Developed as part of AUCTeX <URL:http://www.gnu.org/software/auctex>.
+\newif\ifpr@outer
+\pr@outertrue
+\newcount\pr@snippet
+\global\pr@snippet=1
+\def\pr@protect{\ifx\protect\@typeset@protect
+ \ifpr@outer \expandafter\expandafter\expandafter
+ \@secondoftwo\fi\fi\@gobble}
+\def\pr@protect@ship{\pr@protect{\@firstoftwo\pr@startbox}%
+ \@gobbletwo}
+\def\pr@insert{\begingroup\afterassignment\pr@insertii\count@}
+\def\pr@insertii{\endgroup\setbox\pr@box\vbox}
+\def\pr@mark{{\afterassignment}\toks@}
+\def\pr@marks{{\aftergroup\pr@mark\afterassignment}\count@}
+\newbox\pr@box
+\long\def\pr@startbox#1#2{%
+ \ifpr@outer
+ \toks@{#2}%
+ \edef\pr@cleanup{\the\toks@}%
+ \setbox\pr@box\vbox\bgroup
+ \break
+ \pr@outerfalse\@arrayparboxrestore
+ \let\insert\pr@insert
+ \let\mark\pr@mark
+ \let\marks\pr@marks
+ \expandafter\expandafter\expandafter
+ \pr@ship@start
+ \expandafter\@firstofone
+ \else
+ \expandafter \@gobble
+ \fi{#1}}
+\def\pr@endbox{%
+ \let\reserved@a\relax
+ \ifvmode \edef\reserved@a{\the\everypar}%
+ \ifx\reserved@a\@empty\else
+ \dimen@\prevdepth
+ \noindent\par
+ \setbox\z@\lastbox\unskip\unpenalty
+ \prevdepth\dimen@
+ \setbox\z@\hbox\bgroup\penalty-\maxdimen\unhbox\z@
+ \ifnum\lastpenalty=-\maxdimen\egroup
+ \else\egroup\box\z@ \fi\fi\fi
+ \ifhmode \par\unskip\setbox\z@\lastbox
+ \nointerlineskip\hbox{\unhbox\z@\/}%
+ \else \unskip\unpenalty\unskip \fi
+ \egroup
+ \setbox\pr@box\vbox{%
+ \baselineskip\z@skip \lineskip\z@skip \lineskiplimit\z@
+ \@begindvi
+ \nointerlineskip
+ \splittopskip\z@skip\setbox\z@\vsplit\pr@box to\z@
+ \unvbox\z@
+ \nointerlineskip
+ %\color@setgroup
+ \box\pr@box
+ %\color@endgroup
+ }%
+ \pr@ship@end
+ {\let\protect\noexpand
+ \ifx\pr@offset@override\@undefined
+ \voffset=-\ht\pr@box
+ \hoffset=\z@
+ \fi
+ \c@page=\pr@snippet
+ \pr@shipout
+ \ifpr@fixbb\hbox{%
+ \dimen@\wd\pr@box
+ \@tempdima\ht\pr@box
+ \@tempdimb\dp\pr@box
+ \box\pr@box
+ \llap{\raise\@tempdima\copy\pr@markerbox\kern\dimen@}%
+ \lower\@tempdimb\copy\pr@markerbox}%
+ \else \box\pr@box \fi}%
+ \global\advance\pr@snippet\@ne
+ \pr@cleanup
+}
+\let\pr@shipout=\shipout
+\def\shipout{\deadcycles\z@\bgroup\setbox\z@\box\voidb@x
+ \afterassignment\pr@shipoutegroup\setbox\z@}
+\def\pr@shipoutegroup{\ifvoid\z@ \expandafter\aftergroup\fi \egroup}
+\def\pr@parseit#1{\csname pr@parse#1\endcsname}
+\let\pr@endparse=\@percentchar
+\def\next#1{%
+\def\pr@callafter{%
+ \afterassignment\pr@parseit
+ \let#1= }}
+\expandafter\next\csname pr@parse\pr@endparse\endcsname
+\long\expandafter\def\csname pr@parse*\endcsname#1\pr@endparse#2{%
+ \begingroup\toks@{#1\pr@endparse{#2}}%
+ \edef\next##1{\endgroup##1\the\toks@}%
+ \@ifstar{\next{\pr@parse@*}}{\next\pr@parseit}}
+\long\expandafter\def\csname pr@parse[\endcsname#1\pr@endparse#2{%
+ \begingroup\toks@{#1\pr@endparse{#2}}%
+ \edef\next##1{\endgroup##1\the\toks@}%
+ \@ifnextchar[{\next\pr@bracket}{\next\pr@parseit}}
+\long\def\pr@bracket#1\pr@endparse#2[#3]{%
+ \pr@parseit#1\pr@endparse{#2[{#3}]}}
+\expandafter\let\csname pr@parse]\endcsname=\pr@parseit
+\long\def\pr@parse#1\pr@endparse#2#3{%
+ \pr@parseit#1\pr@endparse{#2{#3}}}
+\expandafter\let\csname pr@parse!\endcsname=\pr@parse
+\long\expandafter\def\csname pr@parse?\endcsname#1#2\pr@endparse#3{%
+ \begingroup\toks@{#2\pr@endparse{#3}}%
+ \@ifnextchar#1{\pr@parsecond\@firstoftwo}%
+ {\pr@parsecond\@secondoftwo}}
+\def\pr@parsecond#1{\expandafter\endgroup
+ \expandafter\expandafter\expandafter\pr@parseit
+ \expandafter#1\the\toks@}
+ \long\def\pr@parse@#1#2\pr@endparse#3{%
+ \pr@parseit #2\pr@endparse{#3#1}}
+\long\expandafter\def\csname pr@parse-\endcsname
+ #1\pr@endparse#2{\begingroup
+ \toks@{\endgroup\pr@parseit #1\pr@endparse{#2}}%
+ {\aftergroup\the\aftergroup\toks@ \afterassignment}%
+ \let\next= }
+\long\expandafter\def\csname pr@parse:\endcsname
+ #1#2#3\pr@endparse#4{\begingroup
+ \toks@{\endgroup \pr@parseit#3\pr@endparse{#4}}%
+ \long\def\next#1{#2}%
+ \the\expandafter\toks@\next}
+\long\expandafter\def\csname pr@parse#\endcsname
+ #1#2#3\pr@endparse#4{\begingroup
+ \toks@{#4}%
+ \long\edef\next##1{\toks@{\the\toks@##1}}%
+ \toks@{\endgroup \pr@parseit#3\pr@endparse}%
+ \long\def\reserved@a#1{{#2}}%
+ \the\expandafter\next\reserved@a}
+\def\pr@endaftergroup#1{#1\aftergroup\pr@endbox}
+\let\pr@endsnarf\relax
+\long\def\pr@snarfafter#1{\ifpr@outer
+ \pr@ship@start
+ \let\pr@ship@start\relax
+ \let\pr@endsnarf\endgroup
+ \else
+ \let\pr@endsnarf\relax
+ \fi
+ \pr@protect{\pr@callafter\pr@startsnarf#1]\pr@endparse}}
+\def\pr@startsnarf#1{#1\begingroup
+ \pr@startbox{\begingroup\aftergroup\pr@endbox}{\endgroup}%
+ \ignorespaces}
+\renewenvironment{preview}{\begingroup
+ \pr@startbox{\begingroup\aftergroup\pr@endbox}%
+ {\endgroup}%
+ \ignorespaces}%
+ {\ifhmode\unskip\fi\endgroup}
+\renewenvironment{nopreview}{\pr@outerfalse\ignorespaces}%
+ {\ifhmode\unskip\fi}
+\newtoks\pr@output
+\pr@output\output
+\output{%
+ \pr@outerfalse
+ \let\@begindvi\@empty
+ \the\pr@output}
+\let\output\pr@output
+\def\pr@typeinfos{\typeout{Preview: Fontsize \f@size pt}%
+ \ifnum\mag=\@m\else\typeout{Preview: Magnification \number\mag}\fi
+ \ifx\pdfoutput\@undefined
+ \ifx\XeTeXversion\@undefined \else
+ % FIXME: The message should not be emitted if XeTeX does not produce
+ % PDF. There does not seem to be a primitive for that, though.
+ \typeout{Preview: PDFoutput 1}%
+ \fi
+ \else
+ \ifx\pdfoutput\relax \else
+ \ifnum\pdfoutput>\z@
+ \typeout{Preview: PDFoutput 1}%
+ \fi
+ \fi
+ \fi
+}
+\AtBeginDocument{\pr@typeinfos}
+\pr@loadcfg{prdefault}
+\endinput
+%%
+%% End of file `preview.sty'.
--- /dev/null
+%%
+%% This is file `prfootnotes.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% preview.dtx (with options: `footnotes')
+%%
+%% IMPORTANT NOTICE:
+%%
+%% For the copyright see the source file.
+%%
+%% Any modified versions of this file must be renamed
+%% with new filenames distinct from prfootnotes.def.
+%%
+%% For distribution of the original source see the terms
+%% for copying and modification in the file preview.dtx.
+%%
+%% This generated file may be distributed as long as the
+%% original source files, as listed above, are part of the
+%% same distribution. (The sources need not necessarily be
+%% in the same archive or directory.)
+%% The preview style for extracting previews from LaTeX documents.
+%% Developed as part of AUCTeX <URL:http://www.gnu.org/software/auctex>.
+\PreviewMacro[[!]\footnote %]
+\endinput
+%%
+%% End of file `prfootnotes.def'.
--- /dev/null
+%%
+%% This is file `prlyx.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% preview.dtx (with options: `lyx')
+%%
+%% IMPORTANT NOTICE:
+%%
+%% For the copyright see the source file.
+%%
+%% Any modified versions of this file must be renamed
+%% with new filenames distinct from prlyx.def.
+%%
+%% For distribution of the original source see the terms
+%% for copying and modification in the file preview.dtx.
+%%
+%% This generated file may be distributed as long as the
+%% original source files, as listed above, are part of the
+%% same distribution. (The sources need not necessarily be
+%% in the same archive or directory.)
+%% The preview style for extracting previews from LaTeX documents.
+%% Developed as part of AUCTeX <URL:http://www.gnu.org/software/auctex>.
+\ifPreview\else\expandafter\endinput\fi
+\pr@loadcfg{prlyx}
+\g@addto@macro\pr@ship@end{\typeout{Preview:
+ Snippet \number\pr@snippet\space
+ \number\ht\pr@box\space \number\dp\pr@box \space\number\wd\pr@box}}
+\endinput
+%%
+%% End of file `prlyx.def'.
--- /dev/null
+%%
+%% This is file `prshowbox.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% preview.dtx (with options: `showbox')
+%%
+%% IMPORTANT NOTICE:
+%%
+%% For the copyright see the source file.
+%%
+%% Any modified versions of this file must be renamed
+%% with new filenames distinct from prshowbox.def.
+%%
+%% For distribution of the original source see the terms
+%% for copying and modification in the file preview.dtx.
+%%
+%% This generated file may be distributed as long as the
+%% original source files, as listed above, are part of the
+%% same distribution. (The sources need not necessarily be
+%% in the same archive or directory.)
+%% The preview style for extracting previews from LaTeX documents.
+%% Developed as part of AUCTeX <URL:http://www.gnu.org/software/auctex>.
+\ifPreview\else\expandafter\endinput\fi
+\AtEndOfPackage{%
+ \showboxbreadth\maxdimen
+ \showboxdepth\maxdimen}
+\g@addto@macro\pr@ship@end{\showbox\pr@box}
+\endinput
+%%
+%% End of file `prshowbox.def'.
--- /dev/null
+%%
+%% This is file `prshowlabels.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% preview.dtx (with options: `showlabels')
+%%
+%% IMPORTANT NOTICE:
+%%
+%% For the copyright see the source file.
+%%
+%% Any modified versions of this file must be renamed
+%% with new filenames distinct from prshowlabels.def.
+%%
+%% For distribution of the original source see the terms
+%% for copying and modification in the file preview.dtx.
+%%
+%% This generated file may be distributed as long as the
+%% original source files, as listed above, are part of the
+%% same distribution. (The sources need not necessarily be
+%% in the same archive or directory.)
+%% The preview style for extracting previews from LaTeX documents.
+%% Developed as part of AUCTeX <URL:http://www.gnu.org/software/auctex>.
+\ifPreview\else\expandafter\endinput\fi
+\newbox\pr@labelbox
+\def\pr@label#1{\pr@@label{#1}%
+ \ifpr@setbox\z@{#1}%
+ \global\setbox\pr@labelbox\vbox{\unvbox\pr@labelbox
+ \box\z@}\egroup\fi}
+\def\ifpr@setbox#1#2{%
+ \romannumeral%
+ \ifx\protect\@typeset@protect\ifpr@outer\else
+ \z@\bgroup
+ \protected@edef\next{#2}\@onelevel@sanitize\next
+ \ifx\next\@empty\egroup\romannumeral\else
+ \ifx\next\pr@lastlabel\egroup\romannumeral\else
+ \global\let\pr@lastlabel\next
+ \setbox#1\pr@boxlabel\pr@lastlabel
+ \expandafter\expandafter\romannumeral\fi\fi\fi\fi
+ \z@\iffalse\iftrue\fi}
+\def\pr@boxlabel#1{\hbox{\normalfont
+ \footnotesize\ttfamily\fboxsep0.4ex\relax\fbox{#1}}}
+\def\pr@maketag#1{\pr@@maketag{#1}%
+ \ifpr@setbox\z@{\df@label}%
+ \global\setbox\pr@labelbox\vbox{%
+ \hrule\@width\wd\z@\@height\z@
+ \unvbox\pr@labelbox}%
+ \wd\z@\z@\box\z@ \egroup\fi}
+\g@addto@macro\pr@ship@start{%
+ \global\setbox\pr@labelbox\box\voidb@x
+ \xdef\pr@lastlabel{}%
+ \global\let\pr@@label\label \let\label\pr@label
+ \global\let\pr@@maketag\maketag@@@
+ \let\maketag@@@\pr@maketag
+}
+\pr@addto@front\pr@ship@end{%
+ \ifx \label\pr@label \global\let\label\pr@@label \fi
+ \ifx \maketag@@@\pr@maketag
+ \global\let\maketag@@@\pr@@maketag \fi
+ \ifvoid\pr@labelbox
+ \else \setbox\pr@box\hbox{%
+ \box\pr@box\,\box\pr@labelbox}%
+ \fi}
+\endinput
+%%
+%% End of file `prshowlabels.def'.
--- /dev/null
+%%
+%% This is file `prtightpage.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% preview.dtx (with options: `tightpage')
+%%
+%% IMPORTANT NOTICE:
+%%
+%% For the copyright see the source file.
+%%
+%% Any modified versions of this file must be renamed
+%% with new filenames distinct from prtightpage.def.
+%%
+%% For distribution of the original source see the terms
+%% for copying and modification in the file preview.dtx.
+%%
+%% This generated file may be distributed as long as the
+%% original source files, as listed above, are part of the
+%% same distribution. (The sources need not necessarily be
+%% in the same archive or directory.)
+%% The preview style for extracting previews from LaTeX documents.
+%% Developed as part of AUCTeX <URL:http://www.gnu.org/software/auctex>.
+\ifx\PreviewBorder\@undefined
+ \newdimen\PreviewBorder
+ \PreviewBorder=0.50001bp
+\fi
+\ifx\PreviewBbAdjust\@undefined
+ \def\PreviewBbAdjust{-\PreviewBorder -\PreviewBorder
+ \PreviewBorder \PreviewBorder}
+\fi
+\ifPreview\else\expandafter\endinput\fi
+\def\pr@nextbb{\edef\next{\next\space\number\dimen@}%
+ \expandafter\xdef\csname pr@bb@%
+ \romannumeral\count@\endcsname{\the\dimen@}%
+ \advance\count@\@ne\ifnum\count@<5
+ \afterassignment\pr@nextbb\dimen@=\fi}
+\ifnum\pr@graphicstype=\z@
+ \ifcase
+ \ifx\XeTeXversion\@undefined
+ \ifx\pdfoutput\@undefined \@ne\fi
+ \ifx\pdfoutput\relax \@ne\fi
+ \ifnum\pdfoutput>\z@ \tw@\fi \@ne
+ \else \thr@@\fi
+ \or \ExecuteOptions{dvips}\relax
+ \or \ExecuteOptions{pdftex}\relax
+ \or \ExecuteOptions{xetex}\relax\fi\fi
+\global\let\pr@bbadjust\@empty
+\pr@addto@front\pr@ship@end{\begingroup
+ \let\next\@gobble
+ \count@\@ne\afterassignment\pr@nextbb
+ \dimen@\PreviewBbAdjust
+ \ifx\pr@bbadjust\next
+ \else \global\let\pr@bbadjust\next
+ \typeout{Preview: Tightpage \pr@bbadjust}%
+ \fi\endgroup}
+\ifcase\pr@graphicstype
+\or
+ \g@addto@macro\pr@ship@end{\setbox\pr@box\hbox{%
+ \special{ps::\pr@bbadjust\space
+ \number\ifdim\ht\pr@box>\z@ \ht\pr@box
+ \else \z@
+ \fi \space
+ \number\ifdim\dp\pr@box>\z@ \dp\pr@box
+ \else \z@
+ \fi \space
+ \number\ifdim\wd\pr@box>\z@ \wd\pr@box
+ \else \z@
+ \fi}\box\pr@box}}
+\or
+ \g@addto@macro\pr@ship@end{{\dimen@\ht\pr@box
+ \ifdim\dimen@<\z@ \dimen@\z@\fi
+ \advance\dimen@\pr@bb@iv
+ \dimen@ii=\dimen@
+ \global\pdfvorigin\dimen@
+ \dimen@\dp\pr@box
+ \ifdim\dimen@<\z@ \dimen@\z@\fi
+ \advance\dimen@-\pr@bb@ii
+ \advance\dimen@\dimen@ii
+ \global\pdfpageheight\dimen@
+ \dimen@\wd\pr@box
+ \ifdim\dimen@<\z@ \dimen@=\z@\fi
+ \advance\dimen@-\pr@bb@i
+ \advance\dimen@\pr@bb@iii
+ \global\pdfpagewidth\dimen@
+ \global\pdfhorigin-\pr@bb@i}}
+\or
+ \g@addto@macro\pr@ship@end{\dimen@\ht\pr@box
+ \ifdim\dimen@<\z@ \dimen@\z@\fi
+ \advance\dimen@\pr@bb@iv
+ \dimen@ii=\dimen@
+ \voffset=-1in
+ \advance\voffset\dimen@
+ \advance\voffset-\ht\pr@box
+ \dimen@\dp\pr@box
+ \ifdim\dimen@<\z@ \dimen@\z@\fi
+ \advance\dimen@-\pr@bb@ii
+ \advance\dimen@\dimen@ii
+ \global\pdfpageheight\dimen@
+ \global\paperheight\dimen@
+ \dimen@\wd\pr@box
+ \ifdim\dimen@<\z@ \dimen@=\z@\fi
+ \advance\dimen@-\pr@bb@i
+ \advance\dimen@\pr@bb@iii
+ \global\pdfpagewidth\dimen@
+ \hoffset=-1in
+ \advance\hoffset-\pr@bb@i
+ \let\pr@offset@override\@empty}
+\fi
+\ifnum\pr@graphicstype=\@ne
+\preview@delay{\AtBeginDvi{%
+ \special{!/preview@tightpage true def (%
+ compatibility PostScript comment for dvipng<=1.5 }
+ \special{!userdict begin/bop-hook{%
+ 7{currentfile token not{stop}if
+ 65781.76 div DVImag mul}repeat
+ 72 add 72 2 copy gt{exch}if 4 2 roll
+ neg 2 copy lt{exch}if dup 0 gt{pop 0 exch}%
+ {exch dup 0 lt{pop 0}if}ifelse 720 add exch 720 add
+ 3 1 roll
+ 4{5 -1 roll add 4 1 roll}repeat
+ <</PageSize[5 -1 roll 6 index sub 5 -1 roll 5 index sub]%
+ /PageOffset[7 -2 roll [1 1 dtransform exch]%
+ {0 ge{neg}if exch}forall]>>setpagedevice%
+ //bop-hook exec}bind def end}
+ \special{!userdict (some extra code to avoid
+ dvipng>=1.6 unknown special:
+ 7{currentfile token not{stop}if 65781.76 div })) pop}
+ \special{!userdict begin/bop-hook{%
+ preview-bop-level 0 le{%
+ 7{currentfile token not{stop}if
+ 65781.76 div DVImag mul}repeat
+ 72 add 72 2 copy gt{exch}if 4 2 roll
+ neg 2 copy lt{exch}if dup 0 gt{pop 0 exch}%
+ {exch dup 0 lt{pop 0}if}ifelse 720 add exch 720 add
+ 3 1 roll
+ 4{5 -1 roll add 4 1 roll}repeat
+ <</PageSize[5 -1 roll 6 index sub 5 -1 roll 5 index sub]%
+ /PageOffset[7 -2 roll [1 1 dtransform exch]%
+ {0 ge{neg}if exch}forall]>>setpagedevice}if%
+ //bop-hook exec}bind def end}}}
+\fi
+\endinput
+%%
+%% End of file `prtightpage.def'.
--- /dev/null
+%%
+%% This is file `prtracingall.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% preview.dtx (with options: `tracingall')
+%%
+%% IMPORTANT NOTICE:
+%%
+%% For the copyright see the source file.
+%%
+%% Any modified versions of this file must be renamed
+%% with new filenames distinct from prtracingall.def.
+%%
+%% For distribution of the original source see the terms
+%% for copying and modification in the file preview.dtx.
+%%
+%% This generated file may be distributed as long as the
+%% original source files, as listed above, are part of the
+%% same distribution. (The sources need not necessarily be
+%% in the same archive or directory.)
+%% The preview style for extracting previews from LaTeX documents.
+%% Developed as part of AUCTeX <URL:http://www.gnu.org/software/auctex>.
+\ifPreview\else\expandafter\endinput\fi
+\pr@addto@front\pr@ship@start{\let\tracingonline\count@
+ \let\errorstopmode\@empty\tracingall}
+\endinput
+%%
+%% End of file `prtracingall.def'.
--- /dev/null
+;;; multi-prompt.el --- Completing read of multiple strings
+
+;; Copyright (C) 1996, 1997, 2000, 2009 Free Software Foundation
+
+;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 1996-08-31
+;; Keywords: extensions
+
+;; This program 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, or (at your option)
+;; any later version.
+;;
+;; This program 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 this program; if not, write to the Free Software
+;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+;;; Commentary:
+
+;; This package is written for use in emacs lisp programs, where the
+;; user is prompted for a string of the form:
+;;
+;; FOO,BAR,BAZ
+;;
+;; where FOO, BAR, and BAZ are elements of some table. The function
+;; `multi-prompt' is a replacement `completing-read' that will allow
+;; the user to enter a string like the above, yet get completion on
+;; all FOO, BAR, and BAZ.
+
+;;; Code:
+
+(defvar multi-prompt-found nil
+ "List of entries currently added during a `multi-prompt'.")
+
+;;;###autoload
+(defun multi-prompt (separator
+ unique prompt table
+ &optional mp-predicate require-match initial history)
+ "Completing prompt for a list of strings.
+The first argument SEPARATOR should be the string (of length 1) to
+separate the elements in the list. The second argument UNIQUE should
+be non-nil, if each element must be unique. The remaining elements
+are the arguments to `completing-read'. See that."
+ (let ((old-map (if require-match
+ minibuffer-local-must-match-map
+ minibuffer-local-completion-map))
+ (new-map (make-sparse-keymap)))
+ (if (fboundp 'set-keymap-parent)
+ ;; `set-keymap-parent' was introduced in Emacs 19.32.
+ (set-keymap-parent new-map old-map)
+ (setq new-map (copy-keymap old-map)))
+ (define-key new-map separator (if require-match
+ 'multi-prompt-next-must-match
+ 'multi-prompt-next))
+ (define-key new-map "\C-?" 'multi-prompt-delete)
+ (let* ((minibuffer-local-completion-map new-map)
+ (minibuffer-local-must-match-map new-map)
+ (multi-prompt-found nil)
+ (done nil)
+ (filter (cond (unique
+ (lambda (x)
+ (and (not (member (car x) multi-prompt-found))
+ (or (null mp-predicate)
+ (funcall mp-predicate x)))))
+ (mp-predicate)))
+ (answer (catch 'multi-prompt-exit
+ (while t
+ (let ((extra (catch 'multi-prompt-next
+ (throw 'multi-prompt-exit
+ (completing-read prompt
+ table
+ filter
+ require-match
+ initial
+ history)))))
+ (cond ((eq extra 'back)
+ (when multi-prompt-found
+ (setq prompt (substring
+ prompt 0
+ (- 0 (length separator)
+ (length
+ (car multi-prompt-found))))
+ initial (car multi-prompt-found))
+ (setq multi-prompt-found
+ (cdr multi-prompt-found))))
+ (t
+ (setq prompt (concat prompt extra separator)
+ initial nil)
+ (setq multi-prompt-found
+ (cons extra multi-prompt-found)))))))))
+ (if answer
+ (nreverse (cons answer multi-prompt-found))
+ multi-prompt-found))))
+
+(defun multi-prompt-delete ()
+ (interactive)
+ (if (bobp)
+ (throw 'multi-prompt-next 'back)
+ (call-interactively 'backward-delete-char)))
+
+(defun multi-prompt-next ()
+ (interactive)
+ (throw 'multi-prompt-next
+ (cond
+ ((fboundp 'minibuffer-contents-no-properties)
+ ;; buffer-substring no longer works in emacs-21, it returns
+ ;; the whole prompt line. Use this instead.
+ (minibuffer-contents-no-properties))
+ (t
+ (buffer-substring-no-properties (point-min) (point-max))))))
+
+(defun multi-prompt-next-must-match ()
+ (interactive)
+ (when (call-interactively 'minibuffer-complete)
+ (let ((content (buffer-substring-no-properties (point-min) (point-max))))
+ (when (or (not require-match)
+ (assoc content table))
+ (throw 'multi-prompt-next content)))))
+
+
+;;; Support for key=value completion
+
+;; The following code was ripped out of crm.el
+;; (completing-read-multiple) and extended to support comma-separated
+;; key=value lists. The code is separate from the code above.
+
+;; WARNING: This obviously relies on internals of crm.el and
+;; minibuffer.el and will therefore have to be adapted if these
+;; change.
+
+;; TODO: How to support stuff like "caption={[one]two}" or
+;; "morekeywords={one,three,five}"?
+
+(defvar multi-prompt-key-value-sep "="
+ "Single-character string separating key=value pairs.")
+(defvar multi-prompt-completion-table nil
+ "Completion table used by `multi-prompt-key-value'.")
+
+(defun multi-prompt-key-value-collection-fn (string predicate flag)
+ "Function used by `multi-prompt-key-value' to compute completion values.
+The value of STRING is the string to be completed.
+
+The value of PREDICATE is a function to filter possible matches, or
+nil if none.
+
+The value of FLAG is used to specify the type of completion operation.
+A value of nil specifies `try-completion'. A value of t specifies
+`all-completions'. A value of lambda specifes a test for an exact match.
+
+For more information on STRING, PREDICATE, and FLAG, see the Elisp
+Reference sections on 'Programmed Completion' and 'Basic Completion
+Functions'."
+ (let ((beg 0) (last 0) matched)
+ (while (string-match multi-prompt-key-value-sep string beg)
+ (setq matched t
+ last beg
+ beg (match-end 0)))
+ (completion-table-with-context
+ (substring string 0 beg)
+ (if (not matched)
+ multi-prompt-completion-table
+ (cadr (assoc (substring string last (1- beg))
+ multi-prompt-completion-table)))
+ (substring string beg)
+ predicate
+ flag)))
+
+(defun multi-prompt-expand-completion-table (table)
+ "Return an expanded version of completion table TABLE.
+This is achieved by eval'ing all variables in the value parts of
+the alist elements."
+ (mapcar (lambda (x)
+ (if (and (cadr x) (symbolp (cadr x)) (not (functionp (cadr x))))
+ (cons (car x) (list (eval (cadr x))))
+ x))
+ table))
+
+;; Silence the byte compiler.
+(defvar crm-local-must-match-map)
+(defvar crm-local-completion-map)
+
+;;;###autoload
+(defun multi-prompt-key-value
+ (prompt table &optional predicate require-match initial-input
+ hist def inherit-input-method)
+ "Read multiple strings, with completion and key=value support.
+PROMPT is a string to prompt with, usually ending with a colon
+and a space. TABLE is an alist. The car of each element should
+be a string representing a key and the optional cdr should be a
+list with strings to be used as values for the key.
+
+See the documentation for `completing-read' for details on the
+other arguments: PREDICATE, REQUIRE-MATCH, INITIAL-INPUT, HIST,
+DEF, and INHERIT-INPUT-METHOD.
+
+The return value is the string as entered in the minibuffer."
+ (require 'crm)
+ (let* ((minibuffer-completion-table #'multi-prompt-key-value-collection-fn)
+ (minibuffer-completion-predicate predicate)
+ (minibuffer-completion-confirm
+ (unless (eq require-match t) require-match))
+ (multi-prompt-completion-table
+ ;; Expand the table here because completion would otherwise
+ ;; interpret symbols in the table as functions. However, it
+ ;; would be nicer if this could be done during the actual
+ ;; completion in order to avoid walking through the whole
+ ;; table.
+ (multi-prompt-expand-completion-table table))
+ (map (if require-match
+ crm-local-must-match-map
+ crm-local-completion-map))
+ (input (read-from-minibuffer
+ prompt initial-input map
+ nil hist def inherit-input-method)))
+ (and def (string-equal input "") (setq input def))
+ input))
+
+(provide 'multi-prompt)
+
+;;; multi-prompt.el ends here
--- /dev/null
+This is preview-latex.info, produced by makeinfo version 4.13 from
+preview-latex.texi.
+
+This manual is for preview-latex, a LaTeX preview mode for AUCTeX
+(version 11.86 from 2010-02-21).
+
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software
+Foundation, Inc.
+
+ 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, no Front-Cover Texts and
+ no Back-Cover Texts. A copy of the license is included in the
+ section entitled "GNU Free Documentation License."
+
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* preview-latex: (preview-latex). Preview LaTeX fragments in Emacs
+END-INFO-DIR-ENTRY
+INFO-DIR-SECTION TeX
+START-INFO-DIR-ENTRY
+* preview-latex: (preview-latex). Preview LaTeX fragments in Emacs
+END-INFO-DIR-ENTRY
+
+\1f
+File: preview-latex.info, Node: Top, Prev: (dir), Up: (dir)
+
+preview-latex
+*************
+
+This manual may be copied under the conditions spelled out in *note
+Copying this Manual::.
+
+ preview-latex is a package embedding preview fragments into Emacs
+source buffers under the AUCTeX editing environment for LaTeX. It uses
+`preview.sty' for the extraction of certain environments (most notably
+displayed formulas). Other applications of this style file are
+possible and exist.
+
+ The name of the package is really `preview-latex', all in lowercase
+letters, with a hyphen. If you typeset it, you can use a sans-serif
+font to visually offset it.
+
+* Menu:
+
+* Copying:: Copying
+* Introduction:: Getting started.
+* Installation:: Make Install.
+* Keys and lisp:: Key bindings and user-level lisp functions.
+* Simple customization:: To make it fit in.
+* Known problems:: When things go wrong.
+* For advanced users:: Internals and more customizations.
+* ToDo:: Future development.
+* Frequently Asked Questions:: All about preview-latex
+* Copying this Manual:: GNU Free Documentation License
+* Index:: A menu of many topics.
+
+\1f
+File: preview-latex.info, Node: Copying, Next: Introduction, Prev: Top, Up: Top
+
+Copying
+*******
+
+For the conditions for copying parts of preview-latex, see the General
+Public Licenses referres to in the copyright notices of the files, the
+General Public Licenses accompanying them and the explanatory section in
+*note Copying: (auctex)Copying.
+
+ This manual specifically is covered by the GNU Free Documentation
+License (*note Copying this Manual::).
+
+\1f
+File: preview-latex.info, Node: Introduction, Next: Installation, Prev: Copying, Up: Top
+
+1 Introduction
+**************
+
+Does your neck hurt from turning between previewer windows and the
+source too often? This AUCTeX component will render your displayed
+LaTeX equations right into the editing window where they belong.
+
+ The purpose of preview-latex is to embed LaTeX environments such as
+display math or figures into the source buffers and switch conveniently
+between source and image representation.
+
+* Menu:
+
+* What use is it?::
+* Activating preview-latex::
+* Getting started::
+* Basic modes of operation::
+* More documentation::
+* Availability::
+* Contacts::
+
+\1f
+File: preview-latex.info, Node: What use is it?, Next: Activating preview-latex, Prev: Introduction, Up: Introduction
+
+1.1 What use is it?
+===================
+
+ WYSIWYG (what you see is what you get) sometimes is considered all
+the rage, sometimes frowned upon. Do we really want it? Wrong
+question. The right question is _what_ we want from it. Except when
+finetuning the layout, we don't want to use printer fonts for on-screen
+text editing. The low resolution and contrast of a computer screen
+render all but the coarsest printer fonts (those for low-quality
+newsprint) unappealing, and the margins and pagination of the print are
+not wanted on the screen, either. On the other hand, more complex
+visual compositions like math formulas and tables can't easily be taken
+in when seen only in the source. preview-latex strikes a balance: it
+only uses graphic renditions of the output for certain, configurable
+constructs, does this only when told, and then right in the source code.
+Switching back and forth between the source and preview is easy and
+natural and can be done for each image independently. Behind the scenes
+of preview-latex, a sophisticated framework of other programs like
+`dvipng', Dvips and Ghostscript are employed together with a special
+LaTeX style file for extracting the material of interest in the
+background and providing fast interactive response.
+
+\1f
+File: preview-latex.info, Node: Activating preview-latex, Next: Getting started, Prev: What use is it?, Up: Introduction
+
+1.2 Activating preview-latex
+============================
+
+After installation, the package may need to be activated (and remember
+to activate AUCTeX too). In XEmacs, and in any prepackaged versions
+worth their salt, activation should be automatic upon installation. If
+this seems not the case, complain to your installation provider.
+
+ The usual activation (if it is not done automatically) would be
+
+ (load "preview-latex.el" nil t t)
+
+ If you still don't get a "Preview" menu in LaTeX mode in spite of
+AUCTeX showing its "Command", your installation is broken. One
+possible cause are duplicate Lisp files that might be detectable with
+`<M-x> list-load-path-shadows <RET>'.
+
+\1f
+File: preview-latex.info, Node: Getting started, Next: Basic modes of operation, Prev: Activating preview-latex, Up: Introduction
+
+1.3 Getting started
+===================
+
+Once activated, preview-latex and its documentation will be accessible
+via its menus (note that preview-latex requires AUCTeX to be loaded).
+When you have loaded a LaTeX document (a sample document `circ.tex' is
+included in the distribution, but most documents including math and/or
+figures should do), you can use its menu or `C-c C-p C-d' (for
+`Preview/Document'). Previews will now be generated for various
+objects in your document. You can use the time to take a short look at
+the other menu entries and key bindings in the `Preview' menu. You'll
+see the previewed objects change into a roadworks sign when
+preview-latex has determined just what it is going to preview. Note
+that you can freely navigate the buffer while this is going on. When
+the process is finished you will see the objects typeset in your buffer.
+
+ It is a bad idea, however, to edit the buffer before the roadworks
+signs appear, since that is the moment when the correlation between the
+original text and the buffer locations gets established. If the buffer
+changes before that point of time, the previews will not be placed where
+they belong. If you do want to change some obvious error you just
+spotted, we recommend you stop the background process by pressing `C-c
+C-k'.
+
+ To see/edit the LaTeX code for a specific object, put the point (the
+cursor) on it and press `C-c C-p C-p' (for `Preview/at point'). It
+will also do to click with the middle mouse button on the preview. Now
+you can edit the code, and generate a new preview by again pressing
+`C-c C-p C-p' (or by clicking with the middle mouse button on the icon
+before the edited text).
+
+ If you are using the `desktop' package, previews will remain from
+one session to the next as long as you don't kill your buffer. If you
+are using XEmacs, you will probably need to upgrade the package to the
+newest one; things are being fixed just as I am writing this.
+
+\1f
+File: preview-latex.info, Node: Basic modes of operation, Next: More documentation, Prev: Getting started, Up: Introduction
+
+1.4 Basic modes of operation
+============================
+
+preview-latex has a number of methods for generating its graphics. Its
+default operation is equivalent to using the `LaTeX' command from
+AUCTeX. If this happens to be a call of PDFLaTeX generating PDF output
+(you need at least AUCTeX 11.51 for this), then Ghostscript will be
+called directly on the resulting PDF file. If a DVI file gets
+produced, first Dvips and then Ghostscript get called by default.
+
+ The image type to be generated by Ghostscript can be configured with
+
+ M-x customize-variable RET preview-image-type RET
+
+The default is `png' (the most efficient image type). A special
+setting is `dvipng' in case you have the `dvipng' program installed.
+In this case, `dvipng' will be used for converting DVI files and
+Ghostscript (with a `PNG' device) for converting PDF files. `dvipng'
+is much faster than the combination of Dvips and Ghostscript. You can
+get downloads, access to its CVS archive and further information from
+its project site (http://savannah.nongnu.org/projects/dvipng).
+
+\1f
+File: preview-latex.info, Node: More documentation, Next: Availability, Prev: Basic modes of operation, Up: Introduction
+
+1.5 More documentation
+======================
+
+After the installation, documentation in the form of this info manual
+will be available. You can access it with the standalone info reader
+with
+
+ info preview-latex
+
+or by pressing `C-h i d m preview-latex <RET>' in Emacs. Once
+preview-latex is activated, you can instead use `C-c C-p <TAB>' (or the
+menu entry `Preview/Read documentation').
+
+ Depending on your installation, a printable manual may also be
+available in the form of `preview-latex.dvi' or `preview-latex.ps'.
+
+ Detailed documentation for the LaTeX style used for extracting the
+preview images is placed in `preview.dvi' in a suitable directory
+during installation; on typical teTeX-based systems,
+
+ texdoc preview
+
+will display it.
+
+\1f
+File: preview-latex.info, Node: Availability, Next: Contacts, Prev: More documentation, Up: Introduction
+
+1.6 Availability
+================
+
+The preview-latex project is now part of AUCTeX and accessible as part
+of the AUCTeX project page (http://savannah.gnu.org/projects/auctex).
+You can get its files from the AUCTeX download area
+(ftp://ftp.gnu.org/pub/gnu/auctex). As of AUCTeX 11.81, preview-latex
+should already be integrated into AUCTeX, so no separate download will
+be necessary.
+
+ You will also find `.rpm' files there for Fedora and possibly SuSE.
+Anonymous CVS is available as well.
+
+\1f
+File: preview-latex.info, Node: Contacts, Prev: Availability, Up: Introduction
+
+1.7 Contacts
+============
+
+Bug reports should be sent by using `M-x preview-report-bug <RET>', as
+this will fill in a lot of information interesting to us. If the
+installation fails (but this should be a rare event), report bugs to
+<bug-auctex@gnu.org>.
+
+ There is a general discussion list for AUCTeX which also covers
+preview-latex, look at `http://lists.gnu.org/mailman/listinfo/auctex'.
+For more information on the mailing list, send a message with just the
+word "help" as subject or body to <auctex-request@gnu.org>. For the
+developers, there is the <auctex-devel@gnu.org> list; it would probably
+make sense to direct feature requests and questions about internal
+details there. There is a low-volume read-only announcement list
+available to which you can subscribe by sending a mail with "subscribe"
+in the subject to <info-auctex-request@gnu.org>.
+
+ Offers to support further development will be appreciated. If you
+want to show your appreciation with a donation to the main developer,
+you can do so via PayPal to <dak@gnu.org>, and of course you can arrange
+for service contracts or for added functionality. Take a look at the
+`TODO' list for suggestions in that area.
+
+\1f
+File: preview-latex.info, Node: Installation, Next: Keys and lisp, Prev: Introduction, Up: Top
+
+2 Installation
+**************
+
+Installation is now being covered in *note Installation:
+(auctex)Installation.
+
+\1f
+File: preview-latex.info, Node: Keys and lisp, Next: Simple customization, Prev: Installation, Up: Top
+
+3 Key bindings and user-level lisp functions
+********************************************
+
+preview-latex adds key bindings starting with `C-c C-p' to the
+supported modes of AUCTeX (*note (auctex)Key Index::). It will also
+add its own `Preview' menu in the menu bar, as well as an icon in the
+toolbar.
+
+ The following only describes the interactive use: view the
+documentation strings with `C-h f' if you need the Lisp information.
+
+`C-c C-p C-p'
+`preview-at-point'
+Preview/Generate previews (or toggle) at point
+ If the cursor is positioned on or inside of a preview area, this
+ toggles its visibility, regenerating the preview if necessary. If
+ not, it will run the surroundings through preview. The
+ surroundings include all areas up to the next valid preview,
+ unless invalid previews occur before, in which case the area will
+ include the last such preview in either direction. And overriding
+ any other action, if a region is active (`transient-mark-mode' or
+ `zmacs-regions'), it is run through `preview-region'.
+
+`<mouse-2>'
+ The middle mouse button has a similar action bound to it as
+ `preview-at-point', only that it knows which preview to apply it to
+ according to the position of the click. You can click either
+ anywhere on a previewed image, or when the preview is opened and
+ showing the source text, you can click on the icon preceding the
+ source text. In other areas, the usual mouse key action
+ (typically: paste) is not affected.
+
+`<mouse-3>'
+ The right mouse key pops up a context menu with several options:
+ toggling the preview, regenerating it, removing it (leaving the
+ unpreviewed text), copying the text inside of the preview, and
+ copying it in a form suitable for copying as an image into a mail
+ or news article. This is a one-image variant of the following
+ command:
+
+`C-c C-p C-w'
+`preview-copy-region-as-mml'
+Copy a region as MML
+ This command is also available as a variant in the context menu on
+ the right mouse button (where the region is the preview that has
+ been clicked on). It copies the current region into the kill
+ buffer in a form suitable for copying as a text including images
+ into a mail or news article using mml-mode (*note Composing:
+ (emacs-mime)Composing.).
+
+ If you regenerate or otherwise kill the preview in its source
+ buffer before the mail or news gets posted, this will fail. Also
+ you should generate images you want to send with
+ `preview-transparent-border' set to `nil', or the images will have
+ an ugly border. preview-latex detects this condition and asks
+ whether to regenerate the region with borders switched off. As
+ this is an asynchronous operation running in the background,
+ you'll need to call this command explicitly again to get the newly
+ generated images into the kill ring.
+
+ Preview your articles with `mml-preview' (on `M-m P', or `C-c C-m
+ P' in Emacs 22) to make sure they look fine.
+
+`C-c C-p C-e'
+`preview-environment'
+Preview/Generate previews for environment
+ Run preview on LaTeX environment. The environments in
+ `preview-inner-environments' are treated as inner levels so that
+ for instance, the `split' environment in
+ `\begin{equation}\begin{split}...\end{split}\end{equation}' is
+ properly displayed. If called with a numeric argument, the
+ corresponding number of outward nested environments is treated as
+ inner levels.
+
+`C-c C-p C-s'
+`preview-section'
+Preview/Generate previews for section
+ Run preview on this LaTeX section.
+
+`C-c C-p C-r'
+`preview-region'
+Preview/Generate previews for region
+ Run preview on current region.
+
+`C-c C-p C-b'
+`preview-buffer'
+Preview/Generate previews for buffer
+ Run preview on the current buffer.
+
+`C-c C-p C-d'
+`preview-document'
+Preview/Generate previews for document
+ Run preview on the current document.
+
+`C-c C-p C-c C-p'
+`preview-clearout-at-point'
+Preview/Remove previews at point
+ Clear out (remove) the previews that are immediately adjacent to
+ point.
+
+`C-c C-p C-c C-s'
+`preview-clearout-section'
+Preview/Remove previews from section
+ Clear out all previews in current section.
+
+`C-c C-p C-c C-r'
+`preview-clearout'
+Preview/Remove previews from region
+ Clear out all previews in the current region.
+
+`C-c C-p C-c C-b'
+`preview-clearout-buffer'
+Preview/Remove previews from buffer
+ Clear out all previews in current buffer. This makes the current
+ buffer lose all previews.
+
+`C-c C-p C-c C-d'
+`preview-clearout-document'
+Preview/Remove previews from document
+ Clear out all previews in current document. The document consists
+ of all buffers that have the same master file as the current
+ buffer. This makes the current document lose all previews.
+
+`C-c C-p C-f'
+`preview-cache-preamble'
+Preview/Turn preamble cache on
+ Dump a pregenerated format file. For the rest of the session,
+ this file is used when running on the same master file. Use this
+ if you know your LaTeX takes a long time to start up, the speedup
+ will be most noticeable when generating single or few previews.
+ If you change your preamble, do this again. preview-latex will
+ try to detect the necessity of that automatically when editing
+ changes to the preamble are done from within Emacs, but it will
+ not notice if the preamble effectively changes because some
+ included file or style file is tampered with.
+
+`C-c C-p C-c C-f'
+`preview-cache-preamble-off'
+Preview/Turn preamble cache off
+ Clear the pregenerated format file and stop using preambles for the
+ current document. If the caching gives you problems, use this.
+
+`C-c C-p C-i'
+`preview-goto-info-page'
+Preview/Read Documentation
+ Read this info manual.
+
+`M-x preview-report-bug <RET>'
+`preview-report-bug'
+Preview/Report Bug
+ This is the preferred way of reporting bugs as it will fill in what
+ version of preview-latex you are using as well as versions of
+ relevant other software, and also some of the more important
+ settings. Please use this method of reporting, if at all possible
+ and before reporting a bug, have a look at *note Known problems::.
+
+`C-c C-k'
+LaTeX/TeX Output/Kill Job
+ Kills the preview-generating process. This is really an AUCTeX
+ keybinding, but it is included here as a hint. If you are
+ generating a preview and then make a change to the buffer,
+ preview-latex may be confused and place the previews wrong.
+
+\1f
+File: preview-latex.info, Node: Simple customization, Next: Known problems, Prev: Keys and lisp, Up: Top
+
+4 Simple customization
+**********************
+
+Customization options can be found by typing `M-x customize-group <RET>
+preview <RET>'. Remember to set the option when you have changed it.
+The list of suggestions can be made very long (and is covered in detail
+in *note For advanced users::), but some are:
+
+ * Change the color of the preview background
+
+ If you use a non-white background in Emacs, you might have color
+ artifacts at the edges of your previews. Playing around with the
+ option `preview-transparent-color' in the `Preview Appearance'
+ group might improve things. With some settings, the cursor may
+ cover the whole background of a preview, however.
+
+ This option is specific to the display engine in use. Its default
+ is different in Emacs 21 and Emacs 22, and it is not available in
+ XEmacs.
+
+ * Showing `\label's
+
+ When using preview-latex, the `\label's are hidden by the
+ previews. It is possible to make them visible in the output by
+ using the LaTeX package `showkeys' alternatively `showlabels'.
+ However, the boxes of these labels will be outside the region
+ preview-latex considers as the preview image. To enable a similar
+ mechanism internal to preview-latex, enable the `showlabels'
+ option in the variable `preview-default-option-list' in the
+ `Preview Latex' group.
+
+ It must be noted, however, that a much better idea may be to use
+ the RefTeX package for managing references. *Note RefTeX in a
+ Nutshell: (reftex)RefTeX in a Nutshell.
+
+ * Open previews automatically
+
+ The current default is to open previews automatically when you
+ enter them with cursor left/right motions. Auto-opened previews
+ will close again once the cursor leaves them again (this is also
+ done when doing incremental search, or query-replace operations),
+ unless you changed anything in it. In that case, you will have to
+ regenerate the preview (via e.g., `C-c C-p C-p'). Other options
+ for `preview-auto-reveal' are available via `customize'.
+
+ * Automatically cache preambles
+
+ Currently preview-latex asks you whether you want to cache the
+ document preamble (everything before `\begin{document}') before it
+ generates previews for a buffer the first time. Caching the
+ preamble will significantly speed up regeneration of previews.
+ The larger your preamble is, the more this will be apparent. Once
+ a preamble is cached, preview-latex will try to keep track of when
+ it is changed, and dump a fresh format in that case. If you
+ experience problems with this, or if you want it to happen without
+ asking you the first time, you can customize the variable
+ `preview-auto-cache-preamble'.
+
+ * Attempt to keep counters accurate when editing
+
+ Since preview-latex frequently runs only small regions through
+ LaTeX, values like equation counters are not consistent from run to
+ run. If this bothers you, customize the variable
+ `preview-preserve-counters' to `t' (this is consulted by
+ `preview-required-option-list'). LaTeX will then output a load of
+ counter information during compilation, and this information will
+ be used on subsequent updates to keep counters set to useful
+ values. The additional information takes additional time to
+ analyze, but this is relevant mostly only when you are
+ regenerating all previews at once, and maybe you will be less
+ tempted to do so when counters appear more or less correct.
+
+ * Preview your favourite LaTeX constructs
+
+ If you have a certain macro or environment that you want to
+ preview, first check if it can be chosen by cutomizing
+ `preview-default-options-list' in the `Preview Latex' group.
+
+ If it is not available there, you can add it to
+ `preview-default-preamble' also in the `Preview Latex' group, by
+ adding a `\PreviewMacro' or `\PreviewEnvironment' entry (*note
+ Provided commands::) _after_ the `\RequirePackage' line. For
+ example, if you want to preview the `center' environment, press
+ the <Show> button and the last <INS> button, then add
+
+ \PreviewEnvironment{center}
+ in the space that just opened. Note that since `center' is a
+ generic formatting construct of LaTeX, a general configuration like
+ that is not quite prudent. You better to do this on a per-document
+ base so that it is easy to disable this behavior when you find this
+ particular entry gives you trouble.
+
+ One possibility is to save such settings in the corresponding
+ file-local variable instead of your global configuration (*note
+ Local Variables in Files: (emacs)File Variables.). A perhaps more
+ convenient place for such options would be in a configuration file
+ in the same directory with your project (*note Package options::).
+
+ The usual file for preview-latex preconfiguration is
+ `prauctex.cfg'. If you also want to keep the systemwide defaults,
+ you should add a line
+
+ \InputIfFileExists{preview/prauctex.cfg}{}{}
+ to your own version of `prauctex.cfg' (this is assuming that
+ global files relating to the `preview' package are installed in a
+ subdirectory `preview', the default behavior).
+
+ * Don't preview inline math
+
+ If you have performance problems because your document is full of
+ inline math (`$...$'), or if your usage of `$' conflicts with
+ preview-latex's, you can turn off inline math previews. In the
+ `Preview Latex' group, remove `textmath' from
+ `preview-default-option-list' by customizing this variable.
+
+\1f
+File: preview-latex.info, Node: Known problems, Next: For advanced users, Prev: Simple customization, Up: Top
+
+5 Known problems
+****************
+
+A number of issues are known concerning the interoperation with various
+other software. Some of the known problems can be solved by moving to
+newer versions of the problematic software or by simple patches.
+
+* Menu:
+
+* Problems with Ghostscript::
+* Font problems with Dvips::
+* Emacs problems::
+* Too small bounding boxes::
+* x-symbol interoperation::
+* Middle-clicks paste instead of toggling::
+
+ If you find something not mentioned here, please send a bug report
+using `M-x preview-report-bug <RET>', which will fill in a lot of
+information interesting to us and send it to the <bug-auctex@gnu.org>
+list. Please use the bug reporting commands if at all possible.
+
+\1f
+File: preview-latex.info, Node: Problems with Ghostscript, Next: Font problems with Dvips, Up: Known problems
+
+5.1 Problems with Ghostscript
+=============================
+
+ Most of the problems encountered come from interaction with
+Ghostscript. It is a good idea to have a fairly recent version of
+Ghostscript installed. One problem occurs if you have specified the
+wrong executable under Windows: the command line version of Ghostscript
+is called `GSWIN32C.EXE', not `GSWIN32.EXE'.
+
+ When Ghostscript fails, the necessary information and messages from
+Ghostscript go somewhere. If Ghostscript fails before starting to
+process images, you'll find the information at the end of the process
+buffer you can see with `C-c C-l'. If Ghostscript fails while
+processing a particular image, this image will be tagged with clickable
+buttons for the error description and for the corresponding source file.
+
+ The default options configurable with
+
+ `M-x customize-variable <RET> preview-gs-options <RET>'
+ include the options `-dTextAlphaBits=4' and `-dGraphicsAlphaBits=4'.
+These options have been reported to make Ghostscript 5.50 fail, but
+should work under Ghostscript 6.51 and later. If you are experiencing
+problems, it might help to customize them away. Of course, this also
+takes away the joy of antialiasing, so upgrading Ghostscript might not
+be the worst idea after all.
+
+ The device names have changed over time, so when using an old
+Ghostscript, you may have problems with the devices demanded by the
+customizable variable `preview-image-creators'. In that case, make
+sure they fit your version of Ghostscript, at least the entry
+corresponding to the current value of `preview-image-type'. While not
+being best in file size and image quality, setting
+`preview-image-creators' to `jpeg' should probably be one of the best
+bets for the purpose of checking basic operation, since that device
+name has not changed in quite some time. But JPEG is not intended for
+text, but for photographic images. On a more permanent time scale, the
+best choice is to use PNG and complain to your suppliers if either
+Emacs or Ghostscript fail to properly accommodate this format.
+
+\1f
+File: preview-latex.info, Node: Font problems with Dvips, Next: Emacs problems, Prev: Problems with Ghostscript, Up: Known problems
+
+5.2 Font problems with Dvips
+============================
+
+Some fonts have been reported to produce wrong characters with
+preview-latex. preview-latex calls Dvips by default with the option
+`-Pwww' in order to get scalable fonts for nice results. If you are
+using antialiasing, however, the results might be sufficiently nice
+with bitmapped fonts, anyway. You might try `-Ppdf' for another stab
+at scalable fonts, or other printer definitions. Use
+
+ `M-x customize-variable <RET> preview-fast-dvips-command <RET>'
+ and
+ `M-x customize-variable <RET> preview-dvips-command <RET>'
+ in order to customize this.
+
+ One particular problem is that several printer setup files
+(typically in a file called `/usr/share/texmf/dvips/config/config.pdf'
+if you are using the `-Ppdf' switch) contain the `G' option for
+`character shifting'. This option will result in `fi' being rendered
+as `#' (British Pounds sign) in several fonts, unless your version of
+Dvips has a long-standing bug in its implementation fixed (only very
+recent versions of Dvips have).
+
+\1f
+File: preview-latex.info, Node: Emacs problems, Next: Too small bounding boxes, Prev: Font problems with Dvips, Up: Known problems
+
+5.3 Emacs problems
+==================
+
+ * GNU Emacs versions
+
+ Don't use Emacsen older than 21.3 on X11-based systems. On most
+ other systems, you'll need at least Emacs 22.1 or one of the
+ developer versions leading up to it. Details can be found in
+ *note Prerequisites: (auctex)Prerequisites.
+
+ * Emacsen on Windows operating systems
+
+ For Emacs 21, no image support is available in Emacs under Windows.
+ Without images, preview-latex is useless. The current CVS version
+ of Emacs available from `http://savannah.gnu.org/projects/emacs'
+ now supports images including the PNG format, so Emacs 22 should
+ work out of the box once it is released. Precompiled versions are
+ available from `http://crasseux.com/emacs' and
+ `http://nqmacs.sf.net'.
+
+ For detailed installation instructions for Windows, see *note
+ Installation under MS Windows: (auctex)Installation under MS
+ Windows.
+
+ * XEmacs
+
+ There is are two larger problems known with older XEmacs releases.
+ One leads to seriously mispositioned baselines and previews
+ hanging far above other text on the same line. This should be
+ fixed as of XEmacs-21.4.9.
+
+ The other core bug causes a huge delay when XEmacs's idea of the
+ state of processes (like ghostscript) is wrong, and can lead to
+ nasty spurious error messages. It should be fixed in version
+ 21.4.8.
+
+ Previews will only remain from one session to the next if you have
+ version 1.81 or above of the `edit-utils' package, first released
+ in the 2002-03-12 sumo tarball.
+
+\1f
+File: preview-latex.info, Node: Too small bounding boxes, Next: x-symbol interoperation, Prev: Emacs problems, Up: Known problems
+
+5.4 Too small bounding boxes
+============================
+
+The bounding box of a preview is determined by the LaTeX package using
+the pure TeX bounding boxes. If there is material extending outside of
+the TeX box, that material will be missing from the preview image.
+This happens for the label-showing boxes from the `showkeys' package.
+This particular problem can be circumvented by using the `showlabels'
+option of the preview package.
+
+ In general, you should try to fix the problem in the TeX code, like
+avoiding drawing outside of the picture with PSTricks.
+
+ One possible remedy is to set `preview-fast-conversion' to `Off'
+(*note The Emacs interface::). The conversion will take more time, but
+will then use the bounding boxes from EPS files generated by Dvips.
+
+ Dvips generally does not miss things, but it does not understand
+PostScript constructs like `\resizebox' or `\rotate' commands, so will
+generate rather wrong boxes for those. Dvips can be helped with the
+`psfixbb' package option to preview (*note The LaTeX style file::),
+which will tag the corners of the included TeX box. This will mostly
+be convenient for _pure_ PostScript stuff like that created by
+PSTricks, which Dvips would otherwise reserve no space for.
+
+\1f
+File: preview-latex.info, Node: x-symbol interoperation, Next: Middle-clicks paste instead of toggling, Prev: Too small bounding boxes, Up: Known problems
+
+5.5 x-symbol interoperation
+===========================
+
+Thanks to the work of Christoph Wedler, starting with version
+`4.0h/beta' of x-symbol, the line parsing of AUCTeX and preview-latex
+is fully supported. Earlier versions exhibit problems. However,
+versions before 4.2.2 will cause a drastic slowdown of preview-latex's
+parsing pass, so we don't recommend to use versions earlier than that.
+
+ If you wonder what x-symbol is, it is a package that transforms
+various tokens and subscripts to a more readable form while editing and
+offers a few input methods handy especially for dealing with math. Take
+a look at `http://x-symbol.sourceforge.net'.
+
+ x-symbol versions up to 4.5.1-beta at least require an 8bit-clean TeX
+implementation (meaning that its terminal output should not use
+`^^'-started escape sequences) for cooperation with preview-latex.
+Later versions may get along without it, like preview-latex does now.
+
+ If you experience problems with `circ.tex' in connection with both
+x-symbol and Latin-1 characters, you may need to change your language
+environment or, as a last resort, customize the variable
+`LaTeX-command-style' by replacing the command `latex' with `latex
+-translate-file=cp8bit'.
+
+\1f
+File: preview-latex.info, Node: Middle-clicks paste instead of toggling, Prev: x-symbol interoperation, Up: Known problems
+
+5.6 Middle-clicks paste instead of toggling
+===========================================
+
+This is probably the fault of your favorite package. `flyspell.el' and
+`mouse-drag.el' are known to be affected in versions before Emacs 21.3.
+Upgrade to the most recent version. What version of XEmacs might
+contain the fixes is unknown.
+
+ `isearch.el' also shows this effect while searches are in progress,
+but the code is such a complicated mess that no patch is in sight.
+Better just end the search with `<RET>' before toggling and resume with
+`C-s C-s' or similar afterwards. Since previews over the current match
+will auto-open, anyway, this should not be much of a problem in
+practice.
+
+\1f
+File: preview-latex.info, Node: For advanced users, Next: ToDo, Prev: Known problems, Up: Top
+
+6 For advanced users
+********************
+
+This package consists of two parts: a LaTeX style that splits the
+output into appropriate parts with one preview object on each page, and
+an Emacs-lisp part integrating the thing into Emacs (aided by AUCTeX).
+
+* Menu:
+
+* The LaTeX style file::
+* The Emacs interface::
+* The preview images::
+* Misplaced previews::
+
+\1f
+File: preview-latex.info, Node: The LaTeX style file, Next: The Emacs interface, Prev: For advanced users, Up: For advanced users
+
+6.1 The LaTeX style file
+========================
+
+The main purpose of this package is the extraction of certain
+environments (most notably displayed formulas) from LaTeX sources as
+graphics. This works with DVI files postprocessed by either Dvips and
+Ghostscript or dvipng, but it also works when you are using PDFTeX for
+generating PDF files (usually also postprocessed by Ghostscript).
+
+ Current uses of the package include the preview-latex package for
+WYSIWYG functionality in the AUCTeX editing environment, generation of
+previews in LyX, as part of the operation of the ps4pdf package, the
+tbook XML system and some other tools.
+
+ Producing EPS files with Dvips and its derivatives using the `-E'
+option is not a good alternative: People make do by fiddling around
+with `\thispagestyle{empty}' and hoping for the best (namely, that the
+specified contents will indeed fit on single pages), and then trying to
+guess the baseline of the resulting code and stuff, but this is at best
+dissatisfactory. The preview package provides an easy way to ensure
+that exactly one page per request gets shipped, with a well-defined
+baseline and no page decorations. While you still can use the preview
+package with the `classic'
+
+ dvips -E -i
+
+invocation, there are better ways available that don't rely on Dvips
+not getting confused by PostScript specials.
+
+ For most applications, you'll want to make use of the `tightpage'
+option. This will embed the page dimensions into the PostScript or PDF
+code, obliterating the need to use the `-E -i' options to Dvips. You
+can then produce all image files with a single run of Ghostscript from
+a single PDF or PostScript (as opposed to EPS) file.
+
+ Various options exist that will pass TeX dimensions and other
+information about the respective shipped out material (including
+descender size) into the log file, where external applications might
+make use of it.
+
+ The possibility for generating a whole set of graphics with a single
+run of Ghostscript (whether from LaTeX or PDFLaTeX) increases both
+speed and robustness of applications. It is also feasible to use
+dvipng on a DVI file with the options
+
+ -picky -noghostscript
+
+to omit generating any image file that requires Ghostscript, then let a
+script generate all missing files using Dvips/Ghostscript. This will
+usually speed up the process significantly.
+
+* Menu:
+
+* Package options::
+* Provided commands::
+
+\1f
+File: preview-latex.info, Node: Package options, Next: Provided commands, Prev: The LaTeX style file, Up: The LaTeX style file
+
+6.1.1 Package options
+---------------------
+
+The package is included with the customary
+
+ \usepackage[OPTIONS]{preview}
+
+You should usually load this package as the last one, since it
+redefines several things that other packages may also provide.
+
+ The following options are available:
+
+`active'
+ is the most essential option. If this option is not specified,
+ the `preview' package will be inactive and the document will be
+ typeset as if the `preview' package were not loaded, except that
+ all declarations and environments defined by the package are still
+ legal but have no effect. This allows defining previewing
+ characteristics in your document, and only activating them by
+ calling LaTeX as
+
+ latex '\PassOptionsToPackage{active}{preview} \input{FILENAME}'
+
+`noconfig'
+ Usually the file `prdefault.cfg' gets loaded whenever the
+ `preview' package gets activated. `prdefault.cfg' is supposed to
+ contain definitions that can cater for otherwise bad results, for
+ example, if a certain document class would otherwise lead to
+ trouble. It also can be used to override any settings made in
+ this package, since it is loaded at the very end of it. In
+ addition, there may be configuration files specific for certain
+ `preview' options like `auctex' which have more immediate needs.
+ The `noconfig' option suppresses loading of those option files,
+ too.
+
+`psfixbb'
+ Dvips determines the bounding boxes from the material in the DVI
+ file it understands. Lots of PostScript specials are not part of
+ that. Since the TeX boxes do not make it into the DVI file, but
+ merely characters, rules and specials do, Dvips might include far
+ too small areas. The option `psfixbb' will include `/dev/null' as
+ a graphic file in the ultimate upper left and lower right corner
+ of the previewed box. This will make Dvips generate an
+ appropriate bounding box.
+
+`dvips'
+ If this option is specified as a class option or to other
+ packages, several packages pass things like page size information
+ to Dvips, or cause crop marks or draft messages written on pages.
+ This seriously hampers the usability of previews. If this option
+ is specified, the changes will be undone if possible.
+
+`pdftex'
+ If this option is set, PDFTeX is assumed as the output driver.
+ This mainly affects the `tightpage' option.
+
+`xetex'
+ If this option is set, XeTeX is assumed as the output driver.
+ This mainly affects the `tightpage' option.
+
+`displaymath'
+ will make all displayed math environments subject to preview
+ processing. This will typically be the most desired option.
+
+`floats'
+ will make all float objects subject to preview processing. If you
+ want to be more selective about what floats to pass through to a
+ preview, you should instead use the `\PreviewSnarfEnvironment'
+ command on the floats you want to have previewed.
+
+`textmath'
+ will make all text math subject to previews. Since math mode is
+ used throughly inside of LaTeX even for other purposes, this works
+ by redefining `\(', `\)' and `$' and the `math' environment
+ (apparently some people use that). Only occurences of these text
+ math delimiters in later loaded packages and in the main document
+ will thus be affected.
+
+`graphics'
+ will subject all `\includegraphics' commands to a preview.
+
+`sections'
+ will subject all section headers to a preview.
+
+`delayed'
+ will delay all activations and redefinitions the `preview' package
+ makes until `\'`begin{document}'. The purpose of this is to cater
+ for documents which should be subjected to the `preview' package
+ without having been prepared for it. You can process such
+ documents with
+
+ latex '\RequirePackage[active,delayed,OPTIONS]{preview}
+ \input{FILENAME}'
+
+ This relaxes the requirement to be loading the `preview' package
+ as last package.
+
+DRIVER
+ loads a special driver file `prDRIVER.def'. The remaining options
+ are implemented through the use of driver files.
+
+`auctex'
+ This driver will produce fake error messages at the start and end
+ of every preview environment that enable the Emacs package
+ preview-latex in connection with AUCTeX to pinpoint the exact
+ source location where the previews have originated.
+ Unfortunately, there is no other reliable means of passing the
+ current TeX input position _in_ a line to external programs. In
+ order to make the parsing more robust, this option also switches
+ off quite a few diagnostics that could be misinterpreted.
+
+ You should not specify this option manually, since it will only be
+ needed by automated runs that want to parse the pseudo error
+ messages. Those runs will then use `\PassOptionsToPackage' in
+ order to effect the desired behaviour. In addition,
+ `prauctex.cfg' will get loaded unless inhibited by the `noconfig'
+ option. This caters for the most frequently encountered
+ problematic commands.
+
+`showlabels'
+ During the editing process, some people like to see the label
+ names in their equations, figures and the like. Now if you are
+ using Emacs for editing, and in particular preview-latex, I'd
+ strongly recommend that you check out the RefTeX package which
+ pretty much obliterates the need for this kind of functionality.
+ If you still want it, standard LaTeX provides it with the
+ `showkeys' package, and there is also the less encompassing
+ `showlabels' package. Unfortunately, since those go to some pain
+ not to change the page layout and spacing, they also don't change
+ `preview''s idea of the TeX dimensions of the involved boxes. So
+ if you are using `preview' for determing bounding boxes, those
+ packages are mostly useless. The option `showlabels' offers a
+ substitute for them.
+
+`tightpage'
+ It is not uncommon to want to use the results of `preview' as
+ graphic images for some other application. One possibility is to
+ generate a flurry of EPS files with
+
+ dvips -E -i -Pwww -o OUTPUTFILE.000 INPUTFILE
+
+ However, in case those are to be processed further into graphic
+ image files by Ghostscript, this process is inefficient since all
+ of those files need to be processed one by one. In addition, it
+ is necessary to extract the bounding box comments from the EPS
+ files and convert them into page dimension parameters for
+ Ghostscript in order to avoid full-page graphics. This is not
+ even possible if you wanted to use Ghostscript in a _single_ run
+ for generating the files from a single PostScript file, since
+ Dvips will in that case leave no bounding box information anywhere.
+
+ The solution is to use the `tightpage' option. That way a single
+ command line like
+
+ `gs -sDEVICE=png16m -dTextAlphaBits=4 -r300
+ -dGraphicsAlphaBits=4 -dSAFER -q -dNOPAUSE
+ -sOutputFile=OUTPUTFILE%d.png INPUTFILE.ps'
+
+ will be able to produce tight graphics from a single PostScript
+ file generated with Dvips _without_ use of the options `-E -i', in
+ a single run.
+
+ The `tightpage' option actually also works when using the `pdftex'
+ option and generating PDF files with PDFTeX. The resulting PDF
+ file has separate page dimensions for every page and can directly
+ be converted with one run of Ghostscript into image files.
+
+ If neither `dvips' or `pdftex' have been specified, the
+ corresponding option will get autodetected and invoked.
+
+ If you need this in a batch environment where you don't want to
+ use `preview''s automatic extraction facilities, no problem: just
+ don't use any of the extraction options, and wrap everything to be
+ previewed into `preview' environments. This is how LyX does its
+ math previews.
+
+ If the pages under the `tightpage' option are just too tight, you
+ can adjust by setting the length `\PreviewBorder' to a different
+ value by using `\setlength'. The default value is `0.50001bp',
+ which is half of a usual PostScript point, rounded up. If you go
+ below this value, the resulting page size may drop below `1bp',
+ and Ghostscript does not seem to like that. If you need finer
+ control, you can adjust the bounding box dimensions individually
+ by changing the macro `\PreviewBbAdjust' with the help of
+ `\renewcommand'. Its default value is
+
+ \newcommand \PreviewBbAdjust
+ {-\PreviewBorder -\PreviewBorder
+ \PreviewBorder \PreviewBorder}
+
+ This adjusts the left, lower, right and upper borders by the given
+ amount. The macro must contain 4 TeX dimensions after another,
+ and you may not omit the units if you specify them explicitly
+ instead of by register. PostScript points have the unit `bp'.
+
+`lyx'
+ This option is for the sake of LyX developers. It will output a
+ few diagnostics relevant for the sake of LyX' preview
+ functionality (at the time of writing, mostly implemented for math
+ insets, in versions of LyX starting with 1.3.0).
+
+`counters'
+ This writes out diagnostics at the start and the end of previews.
+ Only the counters changed since the last output get written, and
+ if no counters changed, nothing gets written at all. The list
+ consists of counter name and value, both enclosed in `{}' braces,
+ followed by a space. The last such pair is followed by a colon
+ (`:') if it is at the start of the preview snippet, and by a
+ period (`.') if it is at the end. The order of different
+ diagnostics like this being issued depends on the order of the
+ specification of the options when calling the package.
+
+ Systems like preview-latex use this for keeping counters accurate
+ when single previews are regenerated.
+
+`footnotes'
+ This makes footnotes render as previews, and only as their
+ footnote symbol. A convenient editing feature inside of Emacs.
+
+ The following options are just for debugging purposes of the package
+and similar to the corresponding TeX commands they allude to:
+
+`tracingall'
+ causes lots of diagnostic output to appear in the log file during
+ the preview collecting phases of TeX's operation. In contrast to
+ the similarly named TeX command, it will not switch to
+ `\errorstopmode', nor will it change the setting of
+ `\tracingonline'.
+
+`showbox'
+ This option will show the contents of the boxes shipped out to the
+ DVI files. It also sets `\showboxbreadth' and `\showboxdepth' to
+ their maximum values at the end of loading this package, but you
+ may reset them if you don't like that.
+
+\1f
+File: preview-latex.info, Node: Provided commands, Prev: Package options, Up: The LaTeX style file
+
+6.1.2 Provided commands
+-----------------------
+
+`\begin{preview}...\end{preview}'
+ The `preview' environment causes its contents to be set as a
+ single preview image. Insertions like figures and footnotes
+ (except those included in minipages) will typically lead to error
+ messages or be lost. In case the `preview' package has not been
+ activated, the contents of this environment will be typeset
+ normally.
+
+`\begin{nopreview}...\end{nopreview}'
+ The `nopreview' environment will cause its contents not to undergo
+ any special treatment by the `preview' package. When `preview' is
+ active, the contents will be discarded like all main text that
+ does not trigger the `preview' hooks. When `preview' is not
+ active, the contents will be typeset just like the main text.
+
+ Note that both of these environments typeset things as usual when
+ preview is not active. If you need something typeset
+ conditionally, use the `\ifPreview' conditional for it.
+
+`\PreviewMacro'
+ If you want to make a macro like `\includegraphics' (actually,
+ this is what is done by the `graphics' option to `preview')
+ produce a preview image, you put a declaration like
+
+ \PreviewMacro[*[[!]{\includegraphics}
+
+ or, more readable,
+
+ \PreviewMacro[{*[][]{}}]{\includegraphics}
+
+ into your preamble. The optional argument to `\PreviewMacro'
+ specifies the arguments `\includegraphics' accepts, since this is
+ necessary information for properly ending the preview box. Note
+ that if you are using the more readable form, you have to enclose
+ the argument in a `[{' and `}]' pair. The inner braces are
+ necessary to stop any included `[]' pairs from prematurely ending
+ the optional argument, and to make a single `{}' denoting an
+ optional argument not get stripped away by TeX's argument parsing.
+
+ The letters simply mean
+
+ `*'
+ indicates an optional `*' modifier, as in `\includegraphics*'.
+
+ `['
+ ^^A] indicates an optional argument in brackets. This syntax
+ is somewhat baroque, but brief.
+
+ `[]'
+ also indicates an optional argument in brackets. Be sure to
+ have encluded the entire optional argument specification in
+ an additional pair of braces as described above.
+
+ `!'
+ indicates a mandatory argument.
+
+ `{}'
+ indicates the same. Again, be sure to have that additional
+ level of braces around the whole argument specification.
+
+ `?'DELIMITER{TRUE CASE}{FALSE CASE}
+ is a conditional. The next character is checked against
+ being equal to DELIMITER. If it is, the specification TRUE
+ CASE is used for the further parsing, otherwise FALSE CASE
+ will be employed. In neither case is something consumed from
+ the input, so {TRUE CASE} will still have to deal with the
+ upcoming delimiter.
+
+ `@'{LITERAL SEQUENCE}
+ will insert the given sequence literally into the executed
+ call of the command.
+
+ `-'
+ will just drop the next token. It will probably be most
+ often used in the true branch of a `?' specification.
+
+ `#'{ARGUMENT}{REPLACEMENT}
+ is a transformation rule that calls a macro with the given
+ argument and replacement text on the rest of the argument
+ list. The replacement is used in the executed call of the
+ command. This can be used for parsing arbitrary constructs.
+ For example, the `[]' option could manually be implemented
+ with the option string `?[{#{[#1]}{[{#1}]}}{}'. PStricks
+ users might enjoy this sort of flexibility.
+
+ `:'{ARGUMENT}{REPLACEMENT}
+ is again a transformation rule. As opposed to `#', however,
+ the result of the transformation is parsed again. You'll
+ rarely need this.
+
+ There is a second optional argument in brackets that can be used to
+ declare any default action to be taken instead. This is mostly for
+ the sake of macros that influence numbering: you would want to keep
+ their effects in that respect. The default action should use `#1'
+ for referring to the original (not the patched) command with the
+ parsed options appended. Not specifying a second optional argument
+ here is equivalent to specifying `[#1]'.
+
+`\PreviewMacro*'
+ A similar invocation `\PreviewMacro*' simply throws the macro and
+ all of its arguments declared in the manner above away. This is
+ mostly useful for having things like `\footnote' not do their
+ magic on their arguments. More often than not, you don't want to
+ declare any arguments to scan to `\PreviewMacro*' since you would
+ want the remaining arguments to be treated as usual text and
+ typeset in that manner instead of being thrown away. An exception
+ might be, say, sort keys for `\cite'.
+
+ A second optional argument in brackets can be used to declare any
+ default action to be taken instead. This is for the sake of macros
+ that influence numbering: you would want to keep their effects in
+ that respect. The default action might use `#1' for referring to
+ the original (not the patched) command with the parsed options
+ appended. Not specifying a second optional argument here is
+ equivalent to specifying `[]' since the command usually gets thrown
+ away.
+
+ As an example for using this argument, you might want to specify
+
+ \PreviewMacro*\footnote[{[]}][#1{}]
+
+ This will replace a footnote by an empty footnote, but taking any
+ optional parameter into account, since an optional paramter changes
+ the numbering scheme. That way the real argument for the footnote
+ remains for processing by preview-latex.
+
+`\PreviewEnvironment'
+ The macro `\PreviewEnvironment' works just as `\PreviewMacro' does,
+ only for environments.
+
+`\PreviewEnvironment*'
+ And the same goes for `\PreviewEnvironment*' as compared to
+ `\PreviewMacro*'.
+
+`\PreviewSnarfEnvironment'
+ This macro does not typeset the original environment inside of a
+ preview box, but instead typesets just the contents of the
+ original environment inside of the preview box, leaving nothing
+ for the original environment. This has to be used for figures,
+ for example, since they would
+
+ 1. produce insertion material that cannot be extracted to the
+ preview properly,
+
+ 2. complain with an error message about not being in outer par
+ mode.
+
+`\PreviewOpen'
+
+`\PreviewClose'
+ Those Macros form a matched preview pair. This is for macros that
+ behave similar as `\begin' and `\end' of an environment. It is
+ essential for the operation of `\PreviewOpen' that the macro
+ treated with it will open an additional group even when the preview
+ falls inside of another preview or inside of a `nopreview'
+ environment. Similarly, the macro treated with `PreviewClose'
+ will close an environment even when inactive.
+
+`\ifPreview'
+ In case you need to know whether `preview' is active, you can use
+ the conditional `\ifPreview' together with `\else' and `\fi'.
+
+
+\1f
+File: preview-latex.info, Node: The Emacs interface, Next: The preview images, Prev: The LaTeX style file, Up: For advanced users
+
+6.2 The Emacs interface
+=======================
+
+You can use `M-x customize-group <RET> preview-latex <RET>' in order to
+customize these variables, or use the menus for it. We explain the
+various available options together with explaining how they work
+together in making preview-latex work as intended.
+
+`preview-LaTeX-command'
+ When you generate previews on a buffer or a region, the command in
+ `preview-LaTeX-command' gets run (that variable should only be
+ changed with Customize since its structure is somewhat peculiar,
+ though expressive). As usual with AUCTeX, you can continue
+ working while this is going on. It is not a good idea to change
+ the file until after preview-latex has established where to place
+ the previews which it can only do after the LaTeX run completes.
+ This run produces a host of pseudo-error messages that get parsed
+ by preview-latex at the end of the LaTeX run and give it the
+ necessary information about where in the source file the LaTeX
+ code for the various previews is located exactly. The parsing
+ takes a moment and will render Emacs busy.
+
+`preview-LaTeX-command-replacements'
+ This variable specifies transformations to be used before calling
+ the configured command. One possibility is to have `\pdfoutput=0 '
+ appended to every command starting with `pdf'. This particular
+ setting is available as the shortcut
+ `preview-LaTeX-disable-pdfoutput'. Since preview-latex can work
+ with PDF files by now, there is little incentive for using this
+ option, anymore (for projects not requiring PDF output, the added
+ speed of `dvipng' might make this somewhat attractive).
+
+`preview-required-option-list'
+ `preview-LaTeX-command' uses `preview-required-option-list' in
+ order to pass options such as `auctex', `active' and `dvips' to
+ the `preview' package. This means that the user need (and should)
+ not supply these in the document itself in case he wants to be
+ able to still compile his document without it turning into an
+ incoherent mass of little pictures. These options even get passed
+ in when the user loads `preview' explicitly in his document.
+
+ The default includes an option `counters' that is controlled by the
+ boolean variable
+
+`preview-preserve-counters'
+ This option will cause the `preview' package to emit information
+ that will assist in keeping things like equation counters and
+ section numbers reasonably correct even when you are regenerating
+ only single previews.
+
+`preview-default-option-list'
+`preview-default-preamble'
+ If the document does not call in the package `preview' itself (via
+ `\usepackage') in the preamble, the preview package is loaded using
+ default options from `preview-default-option-list' and additional
+ commands specified in `preview-default-preamble'.
+
+`preview-fast-conversion'
+ This is relevant only for DVI mode. It defaults to `On' and
+ results in the whole document being processed as one large
+ PostScript file from which the single images are extracted with
+ the help of parsing the PostScript for use of so-called DSC
+ comments. The bounding boxes are extracted with the help of TeX
+ instead of getting them from Dvips. If you are experiencing
+ bounding box problems, try setting this option to `Off'.
+
+`preview-prefer-TeX-bb'
+ If this option is `On', it tells preview-latex never to try to
+ extract bounding boxes from the bounding box comments of EPS files,
+ but rather rely on the boxes it gets from TeX. If you activated
+ `preview-fast-conversion', this is done, anyhow, since there are no
+ EPS files from which to read this information. The option
+ defaults to `Off', simply because about the only conceivable
+ reason to switch off `preview-fast-conversion' would be that you
+ have some bounding box problem and want to get Dvips' angle on
+ that matter.
+
+`preview-scale-function'
+`preview-reference-face'
+`preview-document-pt-list'
+`preview-default-document-pt'
+ `preview-scale-function' determines by what factor images should
+ be scaled when appearing on the screen. If you specify a
+ numerical value here, the physical size on the screen will be that
+ of the original paper output scaled by the specified factor, at
+ least if Emacs' information about screen size and resolution are
+ correct. The default is to let `preview-scale-from-face'
+ determine the scale function. This function determines the scale
+ factor by making the size of the default font in the document
+ match that of the on-screen fonts.
+
+ The size of the screen fonts is deduced from the font
+ `preview-reference-face' (usually the default face used for
+ display), the size of the default font for the document is
+ determined by calling `preview-document-pt'. This function
+ consults the members of `preview-document-pt-list' in turn until
+ it gets the desired information. The default consults first
+ `preview-parsed-font-size', then calls `preview-auctex-font-size' which
+ asks AUCTeX about any size specification like `12pt' to the
+ documentclass that it might have detected when parsing the
+ document, and finally reverts to just assuming
+ `preview-default-document-pt' as the size used in the document
+ (defaulting to 10pt).
+
+ If you find that the size of previews and the other Emacs display
+ clashes, something goes wrong. `preview-parsed-font-size' is
+ determined at `\begin{document}' time; if the default font size
+ changes after that, it will not get reported. If you have an
+ outdated version of `preview.sty' in your path, the size might not
+ be reported at all. If in this case AUCTeX is unable to find a
+ size specification, and if you are using a document class with a
+ different default value (like KomaScript), the default fallback
+ assumption will probably be wrong and preview-latex will scale up
+ things too large. So better specify those size options even when
+ you know that LaTeX does not need them: preview-latex might
+ benefit from them. Another possibility for error is that you have
+ not enabled AUCTeX's document parsing options. The fallback
+ method of asking AUCTeX about the size might be disabled in future
+ versions of preview-latex since in general it is more reliable to
+ get this information from the LaTeX run itself.
+
+`preview-fast-dvips-command'
+`preview-dvips-command'
+ The regular command for turning a DVI file into a single
+ PostScript file is `preview-fast-dvips-command', while
+ `preview-dvips-command' is used for cranking out a DVI file where
+ every preview is in a separate EPS file. Which of the two
+ commands gets used depends on the setting of
+ `preview-fast-conversion'. The printer specified here by default
+ is `-Pwww' by default, which will usually get you scalable fonts
+ where available. If you are experiencing problems, you might want
+ to try playing around with Dvips options (*note
+ (dvips)Command-line options::).
+
+ The conversion of the previews into PostScript or EPS files gets
+ started after the LaTeX run completes when Emacs recognizes the
+ first image while parsing the error messages. When Emacs has
+ finished parsing the error messages, it activates all detected
+ previews. This entails throwing away any previous previews
+ covering the same areas, and then replacing the text in its visual
+ appearance by a placeholder looking like a roadworks sign.
+
+`preview-nonready-icon-specs'
+ This is the roadworks sign displayed while previews are being
+ prepared. You may want to customize the font sizes at which
+ preview-latex switches over between different icon sizes, and the
+ ascent ratio which determines how high above the base line the
+ icon gets placed.
+
+`preview-error-icon-specs'
+`preview-icon-specs'
+ Those are icons placed before the source code of an opened preview
+ and, respectively, the image specs to be used for PostScript
+ errors, and a normal open preview in text representation.
+
+`preview-inner-environments'
+ This is a list of environments that are regarded as inner levels
+ of an outer environment when doing `preview-environment'. One
+ example when this is needed is in
+ `\begin{equation}\begin{split}...\end{split}\end{equation}', and
+ accordingly `split' is one entry in `preview-inner-environments'.
+
+`preview-use-balloon-help'
+ If you turn this XEmacs-only option `on', then moving the mouse
+ over previews and icons will show appropriate help texts. This
+ works by switching on `balloon-help-mode' in the buffer if it is
+ not already enabled. The default now is `off' since some users
+ reported problems with their version of XEmacs. GNU Emacs has its
+ corresponding `tooltip-mode' enabled by default and in usable
+ condition.
+
+
+\1f
+File: preview-latex.info, Node: The preview images, Next: Misplaced previews, Prev: The Emacs interface, Up: For advanced users
+
+6.3 The preview images
+======================
+
+`preview-image-type'
+`preview-image-creators'
+`preview-gs-image-type-alist'
+ What happens when LaTeX is finished depends on the configuration of
+ `preview-image-type'. What to do for each of the various settings
+ is specified in the variable `preview-image-creators'. The options
+ to pass into Ghostscript and what Emacs image type to use is
+ specified in `preview-gs-image-type-alist'.
+
+ `preview-image-type' defaults to `png'. For this to work, your
+ version of Ghostscript needs to support the `png16m' device. If
+ you are experiencing problems here, you might want to reconfigure
+ `gs-image-type-alist' or `preview-image-type'. Reconfiguring
+ `preview-image-creators' is only necessary for adding additional
+ image types.
+
+ Most devices make preview-latex start up a single Ghostscript
+ process for the entire preview run (as opposed to one per image)
+ and feed it either sections of a PDF file (if PDFLaTeX was used),
+ or (after running Dvips) sections of a single PostScript file or
+ separate EPS files in sequence for conversion into PNG format
+ which can be displayed much faster by Emacs. Actually, not in
+ sequence but backwards since you are most likely editing at the
+ end of the document. And as an added convenience, any preview
+ that happens to be on-screen is given higher priority so that
+ preview-latex will first cater for the images that are displayed.
+ There are various options customizable concerning aspects of that
+ operation, see the customization group `Preview Gs' for this.
+
+ Another noteworthy setting of `preview-image-type' is `dvipng': in
+ this case, the `dvipng'will get run on DVI output (see below for
+ PDF). This is in general much faster than Dvips and Ghostscript.
+ In that case, the option
+
+`preview-dvipng-command'
+ will get run for doing the conversion, and it is expected that
+
+`preview-dvipng-image-type'
+ images get produced (`dvipng' might be configured for other image
+ types as well). You will notice that `preview-gs-image-type-alist'
+ contains an entry for `dvipng': this actually has nothing to with
+ `dvipng' itself but specifies the image type and Ghostscript device
+ option to use when `dvipng' can't be used. This will obviously be
+ the case for PDF output by PDFLaTeX, but it will also happen if
+ the DVI file contains PostScript specials in which case the
+ affected images will get run through Dvips and Ghostscript once
+ `dvipng' finishes.
+
+`preview-gs-options'
+ Most interesting to the user perhaps is the setting of this
+ variable. It contains the default antialiasing settings
+ `-dTextAlphaBits=4' and `-dGraphicsAlphaBits=4'. Decreasing those
+ values to 2 or 1 might increase Ghostscript's performance if you
+ find it lacking.
+
+ Running and feeding Ghostscript from preview-latex happens
+asynchronously again: you can resume editing while the images arrive.
+While those pretty pictures filling in the blanks on screen tend to
+make one marvel instead of work, rendering the non-displayed images
+afterwards will not take away your attention and will eventually
+guarantee that jumping around in the document will encounter only
+prerendered images.
+
+\1f
+File: preview-latex.info, Node: Misplaced previews, Prev: The preview images, Up: For advanced users
+
+6.4 Misplaced previews
+======================
+
+If you are reading this section, the first thing is to check that your
+problem is not caused by x-symbol in connection with an installation not
+supporting 8-bit characters (*note x-symbol interoperation::). If not,
+here's the beef:
+
+ As explained previously, Emacs uses pseudo-error messages generated
+by the `preview' package in order to pinpoint the exact source location
+where a preview originated. This works in running text, but fails when
+preview material happens to lie in macro arguments, like the contents
+of `\emph'. Those macros first read in their entire argument, munge it
+through, perhaps transform it somehow, process it and perhaps then
+typeset something. When they finally typeset something, where is the
+location where the stuff originated? TeX, having read in the entire
+argument before, does not know and actually there would be no sane way
+of defining it.
+
+ For previews contained inside such a macro argument, the default
+behaviour of preview-latex is to use a position immediately after the
+closing brace of the argument. All the previews get placed there, all at
+a zero-width position, which means that Emacs displays it in an order
+that preview-latex cannot influence (currently in Emacs it is even
+possible that the order changes between runs). And since the placement
+of those previews is goofed up, you will not be able to regenerate them
+by clicking on them. The default behaviour is thus somewhat undesirable.
+
+ The solution (like with other preview problems) is to tell the LaTeX
+`preview' package how to tackle this problem (*note The LaTeX style
+file::). Simply, you don't need `\emph' do anything at all during
+previews! You only want the text math previewed, so the solution is to
+use `\PreviewMacro*\emph' in the preamble of your document which will
+make LaTeX ignore `\emph' completely as long as it is not part of a
+larger preview (in which case it gets typeset as usual). Its argument
+thus becomes ordinary text and gets treated like ordinary text.
+
+ Note that it would be a bad idea to declare
+`\PreviewMacro*[{{}}]\emph' since then both `\emph' as well as its
+argument would be ignored instead of previewed. For user-level macros,
+this is almost never wanted, but there may be internal macros where you
+might want to ignore internal arguments.
+
+ The same mechanism can be used for a number of other text-formatting
+commands like `\textrm', `\textit' and the like. While they all use the
+same internal macro `\text@command', it will not do to redefine just
+that, since they call it only after having read their argument in, and
+then it already is too late. So you need to disable every of those
+commands by hand in your document preamble.
+
+ Actually, we wrote all of the above just to scare you. At least all
+of the above mentioned macros and a few more are already catered for by
+a configuration file `prauctex.cfg' that gets loaded by default unless
+the `preview' package gets loaded with the `noconfig' option. You can
+make your own copy of this file in a local directory and edit it in
+case of need. You can also add loading of a file of your liking to
+`preview-default-preamble', or alternatively do the manual disabling of
+your favorite macro in `preview-default-preamble', which is
+customizable in the Preview Latex group.
+
+\1f
+File: preview-latex.info, Node: ToDo, Next: Frequently Asked Questions, Prev: For advanced users, Up: Top
+
+Appendix A ToDo
+***************
+
+ * Support other formats than just LaTeX
+
+ plain TeX users and ConTeXt users should not have to feel left
+ out. While ConTeXt is not supported yet by released versions of
+ AUCTeX, at least supporting plain would help people, and be a start
+ for ConTeXt as well. There are plain-based formats like MusiXTeX
+ that could benefit a lot from preview-latex. The main part of the
+ difficulties here is to adapt `preview.dtx' to produce stuff not
+ requiring LaTeX.
+
+ * Support nested snippets
+
+ Currently you can't have both a footnote (which gets displayed as
+ just its footnote number) and math inside of a footnote rendered
+ as an image: such nesting might be achieved by rerunning
+ preview-latex on the footnote contents when one opens the footnote
+ for editing.
+
+ * Support other text properties than just images
+
+ Macros like `\textit' can be rendered as images, but the resulting
+ humungous blob is not suitable for editing, in particular since the
+ line filling from LaTeX does not coincide with that of Emacs. It
+ would be much more useful if text properties just switched the
+ relevant font to italics rather than replacing the whole text with
+ an image. It would also make editing quite easier. Then there
+ are things like footnotes that are currently just replaced by
+ their footnote number. While editing is not a concern here (the
+ number is not in the original text, anyway), it would save a lot
+ of conversion time if no images were generated, but Emacs just
+ displayed a properly fontified version of the footnote number.
+ Also, this might make preview-latex useful even on text terminals.
+
+ * Find a way to facilitate Source Specials
+
+ Probably in connection with adding appropriate support to
+ `dvipng', it would be nice if clicking on an image from a larger
+ piece of source code would place the cursor at the respective
+ source code location.
+
+ * Make `preview.dtx' look reasonable in AUCTeX
+
+ It is a bit embarrassing that `preview.dtx' is written in a manner
+ that will not give either good syntax highlighting or good
+ indentation when employing AUCTeX.
+
+ * Web page work
+
+ Currently, preview-latex's web page is not structured at all.
+ Better navigation would be desirable, as well as separate News and
+ Errata eye catchers.
+
+ * Manual improvements
+
+ - Pepper the manual with screen shots and graphics
+
+ This will be of interest for the HTML and TeX renditions of
+ the texinfo manual. Since Texinfo now supports images as
+ well, this could well be nice to have.
+
+ - Fix duplicates
+
+ Various stuff appears several times.
+
+
+ * Implement rendering pipelines for Emacs
+
+ The current `gs.el' interface is fundamentally flawed, not only
+ because of a broken implementation. A general batchable and
+ daemonizable rendering infrastructure that can work on all kinds of
+ preview images for embedding into buffers is warranted. The
+ current implementation has a rather adhoc flavor and is not easily
+ extended. It will not work outside of AUCTeX, either.
+
+ * Integrate into RefTeX
+
+ When referencing to equations and the like, the preview-images of
+ the source rather than plain text should be displayed. If the
+ preview in question covers labels, those should appear in the
+ bubble help and/or a context menu. Apropos:
+
+ * Implement LaTeX error indicators
+
+ Previews on erroneous LaTeX passages might gain a red border or
+ similar.
+
+ * Pop up relevant online documentation for frequent errors
+
+ A lot of errors are of the "badly configured" variety. Perhaps the
+ relevant info pages should be delivered in addition to the error
+ message.
+
+ * Implement a table editing mode where every table cell gets output
+ as a separate preview. Alternatively, output the complete table
+ metrics in a way that lets people click on individual cells for
+ editing purposes.
+
+ * Benchmark and kill Emacs inefficiencies
+
+ Both the LaTeX run under Emacs control as well as actual image
+ insertion in Emacs could be faster. CVS Emacs has improved in that
+ respect, but it still is slower than desirable.
+
+ * Improve image support under Emacs
+
+ The general image and color handling in Emacs is inefficient and
+ partly defective. This is still the case in CVS. One option
+ would be to replace the whole color and image handling with GDK
+ routines when this library is available, since it has been
+ optimized for it.
+
+
+\1f
+File: preview-latex.info, Node: Frequently Asked Questions, Next: Copying this Manual, Prev: ToDo, Up: Top
+
+Appendix B Frequently Asked Questions
+*************************************
+
+* Menu:
+
+* Introduction to FAQ::
+* Requirements::
+* Installation Trouble::
+* Customization::
+* Troubleshooting::
+* Other formats::
+
+\1f
+File: preview-latex.info, Node: Introduction to FAQ, Next: Requirements, Prev: Frequently Asked Questions, Up: Frequently Asked Questions
+
+B.1 Introduction
+================
+
+B.1.1 How can I contribute to the FAQ?
+--------------------------------------
+
+Send an email with the subject:
+ Preview FAQ
+ to <auctex-devel@gnu.org>.
+
+\1f
+File: preview-latex.info, Node: Requirements, Next: Installation Trouble, Prev: Introduction to FAQ, Up: Frequently Asked Questions
+
+B.2 Requirements
+================
+
+B.2.1 Which version of (X)Emacs is needed?
+------------------------------------------
+
+See also the table at the end of the section.
+
+ preview-latex nominally requires GNU Emacs with a version of at
+least 21.1. However, Emacs 22 (currently under development) offers
+superior performance and wider platform support, and is even now the
+recommended platform to use.
+
+ While recent versions of XEmacs 21.4 are supported, doing this in a
+satisfactory manner has proven to be difficult due to technical
+shortcomings and differing API's which are hard to come by. If
+preview-latex is an important part of your editing workflow, you are
+likely to get better results and support by switching to Emacs. Of
+course, you can improve support for your favorite editor by giving
+feedback in case you encounter bugs.
+
+B.2.2 Which versions of Ghostscript and AUCTeX are needed?
+----------------------------------------------------------
+
+We recommend to use GNU or AFPL Ghostscript with a version of at least
+7.07.
+
+ preview-latex has been distributed as part of AUCTeX since version
+11.80. If your version of AUCTeX is older than that, or if it does not
+contain a working copy of preview-latex, complain to wherever you got
+it from.
+
+B.2.3 I have trouble with the display format...
+-----------------------------------------------
+
+We recommend keeping the variable `preview-image-type' set to `dvipng'
+(if you have it installed) or `png'. This is the default and can be
+set via the Preview/Customize menu.
+
+ All other formats are known to have inconveniences, either in file
+size or quality. There are some Emacs versions around not supporting
+PNG; the proper way to deal with that is to complain to your Emacs
+provider. Short of that, checking out PNM or JPEG formats might be a
+good way to find out whether the lack of PNG format support might be
+the only problem with your Emacs.
+
+B.2.4 For which OS does preview work?
+-------------------------------------
+
+It is known to work under the X Window System for Linux and for several
+flavors of Unix: we have reports for HP and Solaris.
+
+ There are several development versions of Emacs around for native
+MacOS Carbon, and preview-latex is working with them, too.
+
+ With Windows, Cygwin and native ports of XEmacs should work.
+preview-latex will not work with any native version 21 of Emacs under
+Windows: you need to get a hold of Emacs 22 which is at the time of
+this writing not released but available as a developer snapshot.
+
+ The entry "X11/Unix" currently means Linux, Solaris or HP/UX, as
+well as the X-specific version for Mac/OSX.
+
+OS Emacs version XEmacs version
+X11/Unix 21.1 21.4.9
+Win9x cygwin 21.3.50? 21.4.8
+Win9x native 22.1 21.4.8
+MacOSX native 22.1 -
+
+\1f
+File: preview-latex.info, Node: Installation Trouble, Next: Customization, Prev: Requirements, Up: Frequently Asked Questions
+
+B.3 Installation Trouble
+========================
+
+B.3.1 I just get `LaTeX found no preview images'.
+-------------------------------------------------
+
+The reason for this is that LaTeX found no preview images in the
+document in question.
+
+ One reason might be that there are no previews to be seen. If you
+have not used preview-latex before, you might not know its manner of
+operation. One sure-fire way to test if you just have a document where
+no previews are to be found is to use the provided example document
+`circ.tex' (you will have to copy it to some directory where you have
+write permissions). If the symptom persists, you have a problem, and
+the problem is most likely a LaTeX problem. Here are possible reasons:
+
+Filename database not updated
+ Various TeX distributions have their own ways of knowing where the
+ files are without actually searching directories. The normal
+ preview-latex installation should detect common tools for that
+ purpose and use them. If this goes wrong, or if the files get
+ installed into a place where they are not looked for, the LaTeX
+ run will fail.
+
+An incomplete manual installation
+ This should not happen if you followed installation instructions.
+ Unfortunately, people know better all the time. If only
+ `preview.sty' gets installed without a set of supplementary files
+ also in the `latex' subdirectory, preview-latex runs will not
+ generate any errors, but they will not produce any previews,
+ either.
+
+An outdated `preview' installation
+ The `preview.sty' package is useful for more than just
+ preview-latex. For example, it is part of TeXlive. So you have
+ to make sure that preview-latex does not get to work with outdated
+ style and configuration files: some newer features will not work
+ with older TeX style files, and really old files will make
+ preview-latex fail completely. There usual is a local `texmf'
+ tree, or even a user-specific tree that are searched before the
+ default tree. Make sure that the first version of those files
+ that gets found is the correct one.
+
+B.3.2 I have problems with the XEmacs installation
+--------------------------------------------------
+
+Please note that the XEmacs installation is different, since XEmacs has
+a package system that gets used here. Please make sure that you read
+and follow the installation instructions for XEmacs.
+
+\1f
+File: preview-latex.info, Node: Customization, Next: Troubleshooting, Prev: Installation Trouble, Up: Frequently Asked Questions
+
+B.4 Customization
+=================
+
+B.4.1 Why don't I get balloon help like in the screen shots?
+------------------------------------------------------------
+
+Some users have reported problems with their XEmacs version, so balloon
+help is no longer switched on by default. Use the Preview/Customize
+menu or `<M-x> customize-variable' in order to customize
+`preview-use-balloon-help' to `On'. This only concerns XEmacs:
+tooltips under GNU Emacs are enabled by default and unproblematic.
+
+B.4.2 How to include additional environments like `enumerate'
+-------------------------------------------------------------
+
+By default, preview-latex is intended mainly for displaying
+mathematical formulas, so environments like `enumerate' or `tabular'
+(except where contained in a float) are not included. You can include
+them however manually by adding the lines:
+
+ \usepackage[displaymath,textmath,sections,graphics,floats]{preview}
+ \PreviewEnvironment{enumerate}
+
+ in your document header, that is before
+
+ \begin{document}
+ In general, `preview' should be loaded as the last thing before the
+start of document.
+
+ Be aware that
+
+ \PreviewEnvironment{...}
+
+ does not accept a comma separated list! Also note that by putting
+more and more
+
+ \PreviewEnvironment{...}
+
+ in your document, it will look more and more like a DVI file preview
+when running preview-latex. Since each preview is treated as one large
+monolithic block by Emacs, one should really restrict previews to those
+elements where the improvement in visual representation more than makes
+up for the decreased editability.
+
+B.4.3 What if I don't want to change the document?
+--------------------------------------------------
+
+The easiest way is to generate a configuration file in the current
+directory. You can basically either create `prdefault.cfg' which is
+used for any use of the `preview' package, or you can use
+`prauctex.cfg' which only applies to the use from with Emacs. Let us
+assume you use the latter. In that case you should write something like
+
+ \InputIfFileExists{preview/prauctex.cfg}{}{}
+ \PreviewEnvironment{enumerate}
+
+ in it. The first line inputs the system-wide default configuration
+(the file name should match that, but not your own `prauctex.cfg'),
+then you add your own stuff.
+
+B.4.4 Suddenly I get gazillions of ridiculous pages?!?
+------------------------------------------------------
+
+When preview-latex works on extracting its stuff, it typesets each
+single preview on a page of its own. This only happens when actual
+previews get generated. Now if you want to configure preview-latex in
+your document, you need to add your own `\usepackage' call to `preview'
+so that it will be able to interpret its various definition commands.
+It is an error to add the `active' option to this invocation: you don't
+want the package to be active unless preview-latex itself enables the
+previewing operation (which it will).
+
+B.4.5 Does preview-latex work with presentation classes?
+--------------------------------------------------------
+
+preview-latex should work with most presentation classes. However,
+since those classes often have macros or pseudo environments
+encompassing a complete slide, you will need to use the customization
+facilities of `preview.sty' to tell it how to resolve this, whether you
+want no previews, previews of whole slides or previews of inner
+material.
+
+\1f
+File: preview-latex.info, Node: Troubleshooting, Next: Other formats, Prev: Customization, Up: Frequently Asked Questions
+
+B.5 Troubleshooting
+===================
+
+B.5.1 Preview causes all sort of strange error messages
+-------------------------------------------------------
+
+When running preview-latex and taking a look at either log file or
+terminal output, lots of messages like
+
+ ! Preview: Snippet 3 started.
+ <-><->
+
+ l.52 \item Sie lassen sich als Funktion $
+ y = f(x)$ darstellen.
+ ! Preview: Snippet 3 ended.(491520+163840x2494310).
+ <-><->
+
+ l.52 \item Sie lassen sich als Funktion $y = f(x)$
+ darstellen.
+
+ appear (previous versions generated messages looking even more like
+errors). Those are not real errors (as will be noted in the log file).
+Or rather, while they *are* really TeX error messages, they are
+intentional. This currently is the only reliable way to pass the
+information from the LaTeX run of preview-latex to its Emacs part about
+where the previews originated in the source text. Since they are
+actual errors, you will also get AUCTeX to state
+ Preview-LaTeX exited as expected with code 1 at Wed Sep 4 17:03:30
+ after the LaTeX run in the run buffer. This merely indicates that
+errors were present, and errors will always be present when
+preview-latex is operating. There might be also real errors, so in
+case of doubt, look for them explicitly in either run buffer or the
+resulting `.log' file.
+
+B.5.2 Why do my DVI and PDF output files vanish?
+------------------------------------------------
+
+In order to produce the preview images preview-latex runs LaTeX on the
+master or region file. The resulting DVI or PDF file can happen to
+have the same name as the output file of a regular LaTeX run. So the
+regular output file gets overwritten and is subsequently deleted by
+preview-latex.
+
+B.5.3 My output file suddenly only contains preview images?!
+------------------------------------------------------------
+
+As mentioned in the previews FAQ entry, preview-latex might use the
+file name of the original output file for the creation of preview
+images. If the original output file is being displayed with a viewer
+when this happens, you might see strange effects depending on the
+viewer, e.g. a message about the file being corrupted or the display of
+all the preview images instead of your typeset document. (Also *Note
+Customization::.)
+
+\1f
+File: preview-latex.info, Node: Other formats, Prev: Troubleshooting, Up: Frequently Asked Questions
+
+B.6 preview-latex when not using LaTeX
+======================================
+
+B.6.1 Does preview-latex work with PDFLaTeX?
+---------------------------------------------
+
+Yes, as long as you use AUCTeX's own PDFLaTeX mode and have not messed
+with `TeX-command-list'.
+
+B.6.2 Does preview-latex work with `elatex'?
+--------------------------------------------
+
+No problem here. If you configure your AUCTeX to use `elatex', or
+simply have `latex' point to `elatex', this will work fine. Modern TeX
+distributions use eTeX for LaTeX, anyway.
+
+B.6.3 Does preview-latex work with ConTeXt?
+-------------------------------------------
+
+In short, no. The `preview' package is LaTeX-dependent. Adding
+support for other formats requires volunteers.
+
+B.6.4 Does preview-latex work with plain TeX?
+---------------------------------------------
+
+Again, no. Restructuring the `preview' package for `plain' operation
+would be required. Volunteers welcome.
+
+ In some cases you might get around by making a wrapper pseudo-Master
+file looking like the following:
+
+ \documentclass{article}
+ \usepackage{plain}
+ \begin{document}
+ \begin{plain}
+ \input myplainfile
+ \end{plain}
+ \end{document}
+
+\1f
+File: preview-latex.info, Node: Copying this Manual, Next: Index, Prev: Frequently Asked Questions, Up: Top
+
+Appendix C Copying this Manual
+******************************
+
+The copyright notice for this manual is:
+
+ This manual is for preview-latex, a LaTeX preview mode for AUCTeX
+(version 11.86 from 2010-02-21).
+
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software
+Foundation, Inc.
+
+ 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, no Front-Cover Texts and
+ no Back-Cover Texts. A copy of the license is included in the
+ section entitled "GNU Free Documentation License."
+
+The full license text can be read here:
+
+* Menu:
+
+* GNU Free Documentation License:: License for copying this manual.
+
+\1f
+File: preview-latex.info, Node: GNU Free Documentation License, Up: Copying this Manual
+
+C.1 GNU Free Documentation License
+==================================
+
+ Version 1.3, 3 November 2008
+
+ Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software
+ Foundation, Inc. `http://fsf.org/'
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ 0. PREAMBLE
+
+ The purpose of this License is to make a manual, textbook, or other
+ functional and useful document "free" in the sense of freedom: to
+ assure everyone the effective freedom to copy and redistribute it,
+ with or without modifying it, either commercially or
+ noncommercially. Secondarily, this License preserves for the
+ author and publisher a way to get credit for their work, while not
+ being considered responsible for modifications made by others.
+
+ This License is a kind of "copyleft", which means that derivative
+ works of the document must themselves be free in the same sense.
+ It complements the GNU General Public License, which is a copyleft
+ license designed for free software.
+
+ We have designed this License in order to use it for manuals for
+ free software, because free software needs free documentation: a
+ free program should come with manuals providing the same freedoms
+ that the software does. But this License is not limited to
+ software manuals; it can be used for any textual work, regardless
+ of subject matter or whether it is published as a printed book.
+ We recommend this License principally for works whose purpose is
+ instruction or reference.
+
+ 1. APPLICABILITY AND DEFINITIONS
+
+ This License applies to any manual or other work, in any medium,
+ that contains a notice placed by the copyright holder saying it
+ can be distributed under the terms of this License. Such a notice
+ grants a world-wide, royalty-free license, unlimited in duration,
+ to use that work under the conditions stated herein. The
+ "Document", below, refers to any such manual or work. Any member
+ of the public is a licensee, and is addressed as "you". You
+ accept the license if you copy, modify or distribute the work in a
+ way requiring permission under copyright law.
+
+ A "Modified Version" of the Document means any work containing the
+ Document or a portion of it, either copied verbatim, or with
+ modifications and/or translated into another language.
+
+ A "Secondary Section" is a named appendix or a front-matter section
+ of the Document that deals exclusively with the relationship of the
+ publishers or authors of the Document to the Document's overall
+ subject (or to related matters) and contains nothing that could
+ fall directly within that overall subject. (Thus, if the Document
+ is in part a textbook of mathematics, a Secondary Section may not
+ explain any mathematics.) The relationship could be a matter of
+ historical connection with the subject or with related matters, or
+ of legal, commercial, philosophical, ethical or political position
+ regarding them.
+
+ The "Invariant Sections" are certain Secondary Sections whose
+ titles are designated, as being those of Invariant Sections, in
+ the notice that says that the Document is released under this
+ License. If a section does not fit the above definition of
+ Secondary then it is not allowed to be designated as Invariant.
+ The Document may contain zero Invariant Sections. If the Document
+ does not identify any Invariant Sections then there are none.
+
+ The "Cover Texts" are certain short passages of text that are
+ listed, as Front-Cover Texts or Back-Cover Texts, in the notice
+ that says that the Document is released under this License. A
+ Front-Cover Text may be at most 5 words, and a Back-Cover Text may
+ be at most 25 words.
+
+ A "Transparent" copy of the Document means a machine-readable copy,
+ represented in a format whose specification is available to the
+ general public, that is suitable for revising the document
+ straightforwardly with generic text editors or (for images
+ composed of pixels) generic paint programs or (for drawings) some
+ widely available drawing editor, and that is suitable for input to
+ text formatters or for automatic translation to a variety of
+ formats suitable for input to text formatters. A copy made in an
+ otherwise Transparent file format whose markup, or absence of
+ markup, has been arranged to thwart or discourage subsequent
+ modification by readers is not Transparent. An image format is
+ not Transparent if used for any substantial amount of text. A
+ copy that is not "Transparent" is called "Opaque".
+
+ Examples of suitable formats for Transparent copies include plain
+ ASCII without markup, Texinfo input format, LaTeX input format,
+ SGML or XML using a publicly available DTD, and
+ standard-conforming simple HTML, PostScript or PDF designed for
+ human modification. Examples of transparent image formats include
+ PNG, XCF and JPG. Opaque formats include proprietary formats that
+ can be read and edited only by proprietary word processors, SGML or
+ XML for which the DTD and/or processing tools are not generally
+ available, and the machine-generated HTML, PostScript or PDF
+ produced by some word processors for output purposes only.
+
+ The "Title Page" means, for a printed book, the title page itself,
+ plus such following pages as are needed to hold, legibly, the
+ material this License requires to appear in the title page. For
+ works in formats which do not have any title page as such, "Title
+ Page" means the text near the most prominent appearance of the
+ work's title, preceding the beginning of the body of the text.
+
+ The "publisher" means any person or entity that distributes copies
+ of the Document to the public.
+
+ A section "Entitled XYZ" means a named subunit of the Document
+ whose title either is precisely XYZ or contains XYZ in parentheses
+ following text that translates XYZ in another language. (Here XYZ
+ stands for a specific section name mentioned below, such as
+ "Acknowledgements", "Dedications", "Endorsements", or "History".)
+ To "Preserve the Title" of such a section when you modify the
+ Document means that it remains a section "Entitled XYZ" according
+ to this definition.
+
+ The Document may include Warranty Disclaimers next to the notice
+ which states that this License applies to the Document. These
+ Warranty Disclaimers are considered to be included by reference in
+ this License, but only as regards disclaiming warranties: any other
+ implication that these Warranty Disclaimers may have is void and
+ has no effect on the meaning of this License.
+
+ 2. VERBATIM COPYING
+
+ You may copy and distribute the Document in any medium, either
+ commercially or noncommercially, provided that this License, the
+ copyright notices, and the license notice saying this License
+ applies to the Document are reproduced in all copies, and that you
+ add no other conditions whatsoever to those of this License. You
+ may not use technical measures to obstruct or control the reading
+ or further copying of the copies you make or distribute. However,
+ you may accept compensation in exchange for copies. If you
+ distribute a large enough number of copies you must also follow
+ the conditions in section 3.
+
+ You may also lend copies, under the same conditions stated above,
+ and you may publicly display copies.
+
+ 3. COPYING IN QUANTITY
+
+ If you publish printed copies (or copies in media that commonly
+ have printed covers) of the Document, numbering more than 100, and
+ the Document's license notice requires Cover Texts, you must
+ enclose the copies in covers that carry, clearly and legibly, all
+ these Cover Texts: Front-Cover Texts on the front cover, and
+ Back-Cover Texts on the back cover. Both covers must also clearly
+ and legibly identify you as the publisher of these copies. The
+ front cover must present the full title with all words of the
+ title equally prominent and visible. You may add other material
+ on the covers in addition. Copying with changes limited to the
+ covers, as long as they preserve the title of the Document and
+ satisfy these conditions, can be treated as verbatim copying in
+ other respects.
+
+ If the required texts for either cover are too voluminous to fit
+ legibly, you should put the first ones listed (as many as fit
+ reasonably) on the actual cover, and continue the rest onto
+ adjacent pages.
+
+ If you publish or distribute Opaque copies of the Document
+ numbering more than 100, you must either include a
+ machine-readable Transparent copy along with each Opaque copy, or
+ state in or with each Opaque copy a computer-network location from
+ which the general network-using public has access to download
+ using public-standard network protocols a complete Transparent
+ copy of the Document, free of added material. If you use the
+ latter option, you must take reasonably prudent steps, when you
+ begin distribution of Opaque copies in quantity, to ensure that
+ this Transparent copy will remain thus accessible at the stated
+ location until at least one year after the last time you
+ distribute an Opaque copy (directly or through your agents or
+ retailers) of that edition to the public.
+
+ It is requested, but not required, that you contact the authors of
+ the Document well before redistributing any large number of
+ copies, to give them a chance to provide you with an updated
+ version of the Document.
+
+ 4. MODIFICATIONS
+
+ You may copy and distribute a Modified Version of the Document
+ under the conditions of sections 2 and 3 above, provided that you
+ release the Modified Version under precisely this License, with
+ the Modified Version filling the role of the Document, thus
+ licensing distribution and modification of the Modified Version to
+ whoever possesses a copy of it. In addition, you must do these
+ things in the Modified Version:
+
+ A. Use in the Title Page (and on the covers, if any) a title
+ distinct from that of the Document, and from those of
+ previous versions (which should, if there were any, be listed
+ in the History section of the Document). You may use the
+ same title as a previous version if the original publisher of
+ that version gives permission.
+
+ B. List on the Title Page, as authors, one or more persons or
+ entities responsible for authorship of the modifications in
+ the Modified Version, together with at least five of the
+ principal authors of the Document (all of its principal
+ authors, if it has fewer than five), unless they release you
+ from this requirement.
+
+ C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+
+ D. Preserve all the copyright notices of the Document.
+
+ E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+
+ F. Include, immediately after the copyright notices, a license
+ notice giving the public permission to use the Modified
+ Version under the terms of this License, in the form shown in
+ the Addendum below.
+
+ G. Preserve in that license notice the full lists of Invariant
+ Sections and required Cover Texts given in the Document's
+ license notice.
+
+ H. Include an unaltered copy of this License.
+
+ I. Preserve the section Entitled "History", Preserve its Title,
+ and add to it an item stating at least the title, year, new
+ authors, and publisher of the Modified Version as given on
+ the Title Page. If there is no section Entitled "History" in
+ the Document, create one stating the title, year, authors,
+ and publisher of the Document as given on its Title Page,
+ then add an item describing the Modified Version as stated in
+ the previous sentence.
+
+ J. Preserve the network location, if any, given in the Document
+ for public access to a Transparent copy of the Document, and
+ likewise the network locations given in the Document for
+ previous versions it was based on. These may be placed in
+ the "History" section. You may omit a network location for a
+ work that was published at least four years before the
+ Document itself, or if the original publisher of the version
+ it refers to gives permission.
+
+ K. For any section Entitled "Acknowledgements" or "Dedications",
+ Preserve the Title of the section, and preserve in the
+ section all the substance and tone of each of the contributor
+ acknowledgements and/or dedications given therein.
+
+ L. Preserve all the Invariant Sections of the Document,
+ unaltered in their text and in their titles. Section numbers
+ or the equivalent are not considered part of the section
+ titles.
+
+ M. Delete any section Entitled "Endorsements". Such a section
+ may not be included in the Modified Version.
+
+ N. Do not retitle any existing section to be Entitled
+ "Endorsements" or to conflict in title with any Invariant
+ Section.
+
+ O. Preserve any Warranty Disclaimers.
+
+ If the Modified Version includes new front-matter sections or
+ appendices that qualify as Secondary Sections and contain no
+ material copied from the Document, you may at your option
+ designate some or all of these sections as invariant. To do this,
+ add their titles to the list of Invariant Sections in the Modified
+ Version's license notice. These titles must be distinct from any
+ other section titles.
+
+ You may add a section Entitled "Endorsements", provided it contains
+ nothing but endorsements of your Modified Version by various
+ parties--for example, statements of peer review or that the text
+ has been approved by an organization as the authoritative
+ definition of a standard.
+
+ You may add a passage of up to five words as a Front-Cover Text,
+ and a passage of up to 25 words as a Back-Cover Text, to the end
+ of the list of Cover Texts in the Modified Version. Only one
+ passage of Front-Cover Text and one of Back-Cover Text may be
+ added by (or through arrangements made by) any one entity. If the
+ Document already includes a cover text for the same cover,
+ previously added by you or by arrangement made by the same entity
+ you are acting on behalf of, you may not add another; but you may
+ replace the old one, on explicit permission from the previous
+ publisher that added the old one.
+
+ The author(s) and publisher(s) of the Document do not by this
+ License give permission to use their names for publicity for or to
+ assert or imply endorsement of any Modified Version.
+
+ 5. COMBINING DOCUMENTS
+
+ You may combine the Document with other documents released under
+ this License, under the terms defined in section 4 above for
+ modified versions, provided that you include in the combination
+ all of the Invariant Sections of all of the original documents,
+ unmodified, and list them all as Invariant Sections of your
+ combined work in its license notice, and that you preserve all
+ their Warranty Disclaimers.
+
+ The combined work need only contain one copy of this License, and
+ multiple identical Invariant Sections may be replaced with a single
+ copy. If there are multiple Invariant Sections with the same name
+ but different contents, make the title of each such section unique
+ by adding at the end of it, in parentheses, the name of the
+ original author or publisher of that section if known, or else a
+ unique number. Make the same adjustment to the section titles in
+ the list of Invariant Sections in the license notice of the
+ combined work.
+
+ In the combination, you must combine any sections Entitled
+ "History" in the various original documents, forming one section
+ Entitled "History"; likewise combine any sections Entitled
+ "Acknowledgements", and any sections Entitled "Dedications". You
+ must delete all sections Entitled "Endorsements."
+
+ 6. COLLECTIONS OF DOCUMENTS
+
+ You may make a collection consisting of the Document and other
+ documents released under this License, and replace the individual
+ copies of this License in the various documents with a single copy
+ that is included in the collection, provided that you follow the
+ rules of this License for verbatim copying of each of the
+ documents in all other respects.
+
+ You may extract a single document from such a collection, and
+ distribute it individually under this License, provided you insert
+ a copy of this License into the extracted document, and follow
+ this License in all other respects regarding verbatim copying of
+ that document.
+
+ 7. AGGREGATION WITH INDEPENDENT WORKS
+
+ A compilation of the Document or its derivatives with other
+ separate and independent documents or works, in or on a volume of
+ a storage or distribution medium, is called an "aggregate" if the
+ copyright resulting from the compilation is not used to limit the
+ legal rights of the compilation's users beyond what the individual
+ works permit. When the Document is included in an aggregate, this
+ License does not apply to the other works in the aggregate which
+ are not themselves derivative works of the Document.
+
+ If the Cover Text requirement of section 3 is applicable to these
+ copies of the Document, then if the Document is less than one half
+ of the entire aggregate, the Document's Cover Texts may be placed
+ on covers that bracket the Document within the aggregate, or the
+ electronic equivalent of covers if the Document is in electronic
+ form. Otherwise they must appear on printed covers that bracket
+ the whole aggregate.
+
+ 8. TRANSLATION
+
+ Translation is considered a kind of modification, so you may
+ distribute translations of the Document under the terms of section
+ 4. Replacing Invariant Sections with translations requires special
+ permission from their copyright holders, but you may include
+ translations of some or all Invariant Sections in addition to the
+ original versions of these Invariant Sections. You may include a
+ translation of this License, and all the license notices in the
+ Document, and any Warranty Disclaimers, provided that you also
+ include the original English version of this License and the
+ original versions of those notices and disclaimers. In case of a
+ disagreement between the translation and the original version of
+ this License or a notice or disclaimer, the original version will
+ prevail.
+
+ If a section in the Document is Entitled "Acknowledgements",
+ "Dedications", or "History", the requirement (section 4) to
+ Preserve its Title (section 1) will typically require changing the
+ actual title.
+
+ 9. TERMINATION
+
+ You may not copy, modify, sublicense, or distribute the Document
+ except as expressly provided under this License. Any attempt
+ otherwise to copy, modify, sublicense, or distribute it is void,
+ and will automatically terminate your rights under this License.
+
+ However, if you cease all violation of this License, then your
+ license from a particular copyright holder is reinstated (a)
+ provisionally, unless and until the copyright holder explicitly
+ and finally terminates your license, and (b) permanently, if the
+ copyright holder fails to notify you of the violation by some
+ reasonable means prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+ reinstated permanently if the copyright holder notifies you of the
+ violation by some reasonable means, this is the first time you have
+ received notice of violation of this License (for any work) from
+ that copyright holder, and you cure the violation prior to 30 days
+ after your receipt of the notice.
+
+ Termination of your rights under this section does not terminate
+ the licenses of parties who have received copies or rights from
+ you under this License. If your rights have been terminated and
+ not permanently reinstated, receipt of a copy of some or all of
+ the same material does not give you any rights to use it.
+
+ 10. FUTURE REVISIONS OF THIS LICENSE
+
+ The Free Software Foundation may publish new, revised versions of
+ the GNU Free Documentation License from time to time. Such new
+ versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns. See
+ `http://www.gnu.org/copyleft/'.
+
+ Each version of the License is given a distinguishing version
+ number. If the Document specifies that a particular numbered
+ version of this License "or any later version" applies to it, you
+ have the option of following the terms and conditions either of
+ that specified version or of any later version that has been
+ published (not as a draft) by the Free Software Foundation. If
+ the Document does not specify a version number of this License,
+ you may choose any version ever published (not as a draft) by the
+ Free Software Foundation. If the Document specifies that a proxy
+ can decide which future versions of this License can be used, that
+ proxy's public statement of acceptance of a version permanently
+ authorizes you to choose that version for the Document.
+
+ 11. RELICENSING
+
+ "Massive Multiauthor Collaboration Site" (or "MMC Site") means any
+ World Wide Web server that publishes copyrightable works and also
+ provides prominent facilities for anybody to edit those works. A
+ public wiki that anybody can edit is an example of such a server.
+ A "Massive Multiauthor Collaboration" (or "MMC") contained in the
+ site means any set of copyrightable works thus published on the MMC
+ site.
+
+ "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
+ license published by Creative Commons Corporation, a not-for-profit
+ corporation with a principal place of business in San Francisco,
+ California, as well as future copyleft versions of that license
+ published by that same organization.
+
+ "Incorporate" means to publish or republish a Document, in whole or
+ in part, as part of another Document.
+
+ An MMC is "eligible for relicensing" if it is licensed under this
+ License, and if all works that were first published under this
+ License somewhere other than this MMC, and subsequently
+ incorporated in whole or in part into the MMC, (1) had no cover
+ texts or invariant sections, and (2) were thus incorporated prior
+ to November 1, 2008.
+
+ The operator of an MMC Site may republish an MMC contained in the
+ site under CC-BY-SA on the same site at any time before August 1,
+ 2009, provided the MMC is eligible for relicensing.
+
+
+ADDENDUM: How to use this License for your documents
+====================================================
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and license
+notices just after the title page:
+
+ Copyright (C) YEAR YOUR NAME.
+ 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, no Front-Cover Texts, and no Back-Cover
+ Texts. A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+
+ If you have Invariant Sections, Front-Cover Texts and Back-Cover
+Texts, replace the "with...Texts." line with this:
+
+ with the Invariant Sections being LIST THEIR TITLES, with
+ the Front-Cover Texts being LIST, and with the Back-Cover Texts
+ being LIST.
+
+ If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+ If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License, to
+permit their use in free software.
+
+\1f
+File: preview-latex.info, Node: Index, Prev: Copying this Manual, Up: Top
+
+Index
+*****
+
+\0\b[index\0\b]
+* Menu:
+
+* \PreviewEnvironment: Provided commands. (line 133)
+* \PreviewMacro: Provided commands. (line 26)
+* Activation: Activating preview-latex.
+ (line 6)
+* C-c C-k: Keys and lisp. (line 161)
+* C-c C-m P: Keys and lisp. (line 64)
+* C-c C-p C-b: Keys and lisp. (line 90)
+* C-c C-p C-c C-b: Keys and lisp. (line 116)
+* C-c C-p C-c C-d: Keys and lisp. (line 122)
+* C-c C-p C-c C-p: Keys and lisp. (line 100)
+* C-c C-p C-c C-r: Keys and lisp. (line 111)
+* C-c C-p C-c C-s: Keys and lisp. (line 106)
+* C-c C-p C-d: Keys and lisp. (line 95)
+* C-c C-p C-e: Keys and lisp. (line 75)
+* C-c C-p C-f: Keys and lisp. (line 129)
+* C-c C-p C-i: Keys and lisp. (line 148)
+* C-c C-p C-p: Keys and lisp. (line 24)
+* C-c C-p C-r: Keys and lisp. (line 85)
+* C-c C-p C-s: Keys and lisp. (line 80)
+* C-c C-p C-w: Keys and lisp. (line 46)
+* C-u C-c C-p C-f: Keys and lisp. (line 142)
+* Caching a preamble: Simple customization.
+ (line 59)
+* Contacts: Contacts. (line 6)
+* Copying: Copying. (line 6)
+* Copyright: Copying. (line 6)
+* CVS access: Availability. (line 6)
+* Distribution: Copying. (line 6)
+* Download: Availability. (line 6)
+* FDL, GNU Free Documentation License: GNU Free Documentation License.
+ (line 6)
+* Free: Copying. (line 6)
+* Free software: Copying. (line 6)
+* General Public License: Copying. (line 6)
+* GPL: Copying. (line 6)
+* Inline math: Simple customization.
+ (line 110)
+* Kill preview-generating process: Keys and lisp. (line 161)
+* License: Copying. (line 6)
+* M-m P: Keys and lisp. (line 64)
+* M-x preview-report-bug <RET>: Keys and lisp. (line 153)
+* Mailing list: Contacts. (line 6)
+* Menu entries: Keys and lisp. (line 6)
+* Philosophy of preview-latex: What use is it?. (line 6)
+* preview-at-point: Keys and lisp. (line 24)
+* preview-auctex-font-size: The Emacs interface. (line 100)
+* preview-auto-cache-preamble: Simple customization.
+ (line 59)
+* preview-buffer: Keys and lisp. (line 90)
+* preview-cache-preamble: Keys and lisp. (line 129)
+* preview-cache-preamble-off: Keys and lisp. (line 142)
+* preview-clearout: Keys and lisp. (line 111)
+* preview-clearout-at-point: Keys and lisp. (line 100)
+* preview-clearout-buffer: Keys and lisp. (line 116)
+* preview-clearout-document: Keys and lisp. (line 106)
+* preview-copy-region-as-mml: Keys and lisp. (line 46)
+* preview-default-document-pt: The Emacs interface. (line 83)
+* preview-default-option-list: The Emacs interface. (line 53)
+* preview-default-preamble <1>: Misplaced previews. (line 59)
+* preview-default-preamble: The Emacs interface. (line 54)
+* preview-document: Keys and lisp. (line 95)
+* preview-document-pt: The Emacs interface. (line 97)
+* preview-document-pt-list: The Emacs interface. (line 82)
+* preview-dvipng-command: The preview images. (line 40)
+* preview-dvipng-image-type: The preview images. (line 43)
+* preview-dvips-command: The Emacs interface. (line 125)
+* preview-environment: Keys and lisp. (line 75)
+* preview-error-icon-specs: The Emacs interface. (line 152)
+* preview-fast-conversion: The Emacs interface. (line 60)
+* preview-fast-dvips-command: The Emacs interface. (line 124)
+* preview-goto-info-page: Keys and lisp. (line 148)
+* preview-gs-image-type-alist: The preview images. (line 8)
+* preview-gs-options <1>: The preview images. (line 54)
+* preview-gs-options: Problems with Ghostscript.
+ (line 22)
+* preview-icon-specs: The Emacs interface. (line 153)
+* preview-image-creators <1>: The preview images. (line 7)
+* preview-image-creators: Problems with Ghostscript.
+ (line 31)
+* preview-image-type <1>: The preview images. (line 6)
+* preview-image-type <2>: Problems with Ghostscript.
+ (line 33)
+* preview-image-type: Basic modes of operation.
+ (line 16)
+* preview-inner-environments: The Emacs interface. (line 158)
+* preview-LaTeX-command: The Emacs interface. (line 11)
+* preview-LaTeX-command-replacements: The Emacs interface. (line 25)
+* preview-nonready-icon-specs: The Emacs interface. (line 145)
+* preview-parsed-font-size: The Emacs interface. (line 100)
+* preview-prefer-TeX-bb: The Emacs interface. (line 69)
+* preview-preserve-counters <1>: The Emacs interface. (line 47)
+* preview-preserve-counters: Simple customization.
+ (line 63)
+* preview-reference-face: The Emacs interface. (line 81)
+* preview-region: Keys and lisp. (line 85)
+* preview-report-bug: Keys and lisp. (line 153)
+* preview-required-option-list <1>: The Emacs interface. (line 35)
+* preview-required-option-list: Simple customization.
+ (line 63)
+* preview-scale-function: The Emacs interface. (line 80)
+* preview-section: Keys and lisp. (line 80)
+* preview-transparent-border: Keys and lisp. (line 56)
+* preview-use-balloon-help: The Emacs interface. (line 165)
+* Readme: Introduction. (line 6)
+* Report a bug: Keys and lisp. (line 153)
+* Right: Copying. (line 6)
+* Showing \labels: Simple customization.
+ (line 23)
+* Using dvipng: Basic modes of operation.
+ (line 18)
+* Warranty: Copying. (line 6)
+
+
+\1f
+Tag Table:
+Node: Top\7f942
+Node: Copying\7f2214
+Node: Introduction\7f2675
+Node: What use is it?\7f3348
+Node: Activating preview-latex\7f4740
+Node: Getting started\7f5555
+Node: Basic modes of operation\7f7642
+Node: More documentation\7f8846
+Node: Availability\7f9734
+Node: Contacts\7f10339
+Node: Installation\7f11611
+Node: Keys and lisp\7f11824
+Node: Simple customization\7f18492
+Node: Known problems\7f24253
+Node: Problems with Ghostscript\7f25074
+Node: Font problems with Dvips\7f27267
+Node: Emacs problems\7f28470
+Node: Too small bounding boxes\7f30207
+Node: x-symbol interoperation\7f31591
+Node: Middle-clicks paste instead of toggling\7f32973
+Node: For advanced users\7f33789
+Node: The LaTeX style file\7f34248
+Node: Package options\7f36809
+Node: Provided commands\7f47744
+Node: The Emacs interface\7f55099
+Node: The preview images\7f64279
+Node: Misplaced previews\7f67751
+Node: ToDo\7f71194
+Node: Frequently Asked Questions\7f75979
+Node: Introduction to FAQ\7f76302
+Node: Requirements\7f76641
+Node: Installation Trouble\7f79605
+Node: Customization\7f82167
+Node: Troubleshooting\7f85715
+Node: Other formats\7f88232
+Node: Copying this Manual\7f89549
+Node: GNU Free Documentation License\7f90474
+Node: Index\7f115615
+\1f
+End Tag Table
--- /dev/null
+;;; preview.el --- embed preview LaTeX images in source buffer
+
+;; Copyright (C) 2001, 2002, 2003, 2004, 2005,
+;; 2006 Free Software Foundation, Inc.
+
+;; Author: David Kastrup
+;; Keywords: tex, wp, convenience
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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; see the file COPYING. If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; $Id: preview.el,v 1.284 2009/06/18 19:20:46 angeli Exp $
+;;
+;; This style is for the "seamless" embedding of generated images
+;; into LaTeX source code. Please see the README and INSTALL files
+;; for further instruction.
+;;
+;; Please use the usual configure script for installation: more than
+;; just Elisp files are involved: a LaTeX style, icon files, startup
+;; code and so on.
+;;
+;; Quite a few things with regard to preview-latex's operation can be
+;; configured by using
+;; M-x customize-group RET preview RET
+;;
+;; Please report bugs with M-x preview-report-bug RET
+;;
+
+;;; Code:
+
+(require 'tex-site)
+(require 'tex)
+(require 'tex-buf)
+(require 'latex)
+
+(eval-when-compile
+ (condition-case nil
+ (require 'desktop)
+ (file-error (message "Missing desktop package:
+preview-latex buffers will not survive across sessions.")))
+ (condition-case nil
+ (require 'reporter)
+ (file-error (message "Missing reporter library, probably from the mail-lib package:
+preview-latex's bug reporting commands will probably not work.")))
+ (require 'info)
+ (defvar error))
+
+;; we need the compatibility macros which do _not_ get byte-compiled.
+(eval-when-compile
+ (if (featurep 'xemacs)
+ (load-library "prv-xemacs.el")))
+
+;; if the above load-library kicked in, this will not cause anything
+;; to get loaded.
+(require (if (featurep 'xemacs)
+ 'prv-xemacs 'prv-emacs))
+
+(defgroup preview nil "Embed Preview images into LaTeX buffers."
+ :group 'AUCTeX
+ :prefix "preview-"
+ :link '(custom-manual "(preview-latex)Top")
+ :link '(info-link "(preview-latex)The Emacs interface")
+ :link '(url-link :tag "Homepage" "http://www.gnu.org/software/auctex/"))
+
+(defgroup preview-gs nil "Preview's Ghostscript renderer."
+ :group 'preview
+ :prefix "preview-")
+
+(defgroup preview-appearance nil "Preview image appearance."
+ :group 'preview
+ :prefix "preview-")
+
+(defconst preview-specs-type
+ '(repeat
+ (list :tag "Image spec"
+ ;; Use an extra :value keyword to avoid a bug in
+ ;; `widget-convert' of XEmacs 21.4 and Emacs 21.
+ ;; Analogously for the following `const' statements.
+ (const :format "" :value :type)
+ (choice :tag "Image type"
+ (const xpm)
+ (const xbm)
+ (symbol :tag "Other"))
+ (set :inline t :tag "Minimum font size"
+ (list :inline t :tag ""
+ (const :format "" :value :min)
+ (integer :tag "pixels")))
+ (const :format "" :value :file) (string :tag "Filename")
+ (set :inline t :tag "Ascent ratio"
+ (list :inline t :tag ""
+ (const :format "" :value :ascent)
+ (integer :tag "percent of image"
+ :value 50))))))
+
+(defun preview-specs-setter (symbol value)
+ "Set SYMBOL to VALUE and clear `preview-min-alist' property.
+This is used in icon specs, so that customizing will
+clear cached icons."
+ (put symbol 'preview-min-alist nil)
+ (set-default symbol value))
+
+(defcustom preview-nonready-icon-specs
+ '((:type xpm :min 26 :file "prvwrk24.xpm" :ascent 90)
+ (:type xpm :min 22 :file "prvwrk20.xpm" :ascent 90)
+ (:type xpm :min 17 :file "prvwrk16.xpm" :ascent 90)
+ (:type xpm :min 15 :file "prvwrk14.xpm" :ascent 90)
+ (:type xpm :file "prvwrk12.xpm" :ascent 90)
+ (:type xbm :file "prvwrk24.xbm" :ascent 90))
+ "The icon used for previews to be generated.
+The spec must begin with `:type'. File names are relative to
+`load-path' and `data-directory', a spec `:min' requires a
+minimal pixel height for `preview-reference-face' before the spec
+will be considered. Since evaluating the `:file' spec takes
+considerable time under XEmacs, it should come after the `:min'
+spec to avoid unnecessary evaluation time."
+ :group 'preview-appearance
+ :type preview-specs-type
+ :set #'preview-specs-setter)
+
+(defvar preview-nonready-icon)
+
+(defcustom preview-error-icon-specs
+ '((:type xpm :min 22 :file "prverr24.xpm" :ascent 90)
+ (:type xpm :min 18 :file "prverr20.xpm" :ascent 90)
+ (:type xpm :file "prverr16.xpm" :ascent 90)
+ (:type xbm :file "prverr24.xbm" :ascent 90))
+ "The icon used for PostScript errors.
+The spec must begin with `:type'. File names are relative to
+`load-path' and `data-directory', a spec `:min' requires a
+minimal pixel height for `preview-reference-face' before the spec
+will be considered. Since evaluating the `:file' spec takes
+considerable time under XEmacs, it should come after the `:min'
+spec to avoid unnecessary evaluation time."
+ :group 'preview-appearance
+ :type preview-specs-type
+ :set #'preview-specs-setter
+)
+
+(defvar preview-error-icon)
+
+(defcustom preview-icon-specs
+ '((:type xpm :min 24 :file "prvtex24.xpm" :ascent 75)
+ (:type xpm :min 20 :file "prvtex20.xpm" :ascent 75)
+ (:type xpm :min 16 :file "prvtex16.xpm" :ascent 75)
+ (:type xpm :file "prvtex12.xpm" :ascent 75)
+ (:type xbm :min 24 :file "prvtex24.xbm" :ascent 75)
+ (:type xbm :min 16 :file "prvtex16.xbm" :ascent 75)
+ (:type xbm :file "prvtex12.xbm" :ascent 75))
+ "The icon used for an open preview.
+The spec must begin with `:type'. File names are relative to
+`load-path' and `data-directory', a spec `:min' requires a
+minimal pixel height for `preview-reference-face' before the spec
+will be considered. Since evaluating the `:file' spec takes
+considerable time under XEmacs, it should come after the `:min'
+spec to avoid unnecessary evaluation time."
+ :group 'preview-appearance
+ :type preview-specs-type
+ :set #'preview-specs-setter)
+
+(defvar preview-icon)
+
+(defgroup preview-latex nil "LaTeX options for preview."
+ :group 'preview
+ :prefix "preview-")
+
+(defcustom preview-image-creators
+ '((dvipng
+ (open preview-gs-open preview-dvipng-process-setup)
+ (place preview-gs-place)
+ (close preview-dvipng-close))
+ (png (open preview-gs-open)
+ (place preview-gs-place)
+ (close preview-gs-close))
+ (jpeg (open preview-gs-open)
+ (place preview-gs-place)
+ (close preview-gs-close))
+ (pnm (open preview-gs-open)
+ (place preview-gs-place)
+ (close preview-gs-close))
+ (tiff (open preview-gs-open)
+ (place preview-gs-place)
+ (close preview-gs-close)))
+ "Define functions for generating images.
+These functions get called in the process of generating inline
+images of the specified type. The open function is called
+at the start of a rendering pass, the place function for
+placing every image, the close function at the end of
+the pass. Look at the documentation of the various
+functions used here for the default settings, and at
+the function `preview-call-hook' through which those are
+called. Additional argument lists specified in here
+are passed to the functions before any additional
+arguments given to `preview-call-hook'.
+
+Not all of these image types may be supported by your copy
+of Ghostscript, or by your copy of Emacs."
+ :group 'preview-gs
+ :type '(alist :key-type (symbol :tag "Preview's image type")
+ :value-type
+ (alist :tag "Handler" :key-type (symbol :tag "Operation:")
+ :value-type (list :tag "Handler"
+ (function :tag "Handler function")
+ (repeat :tag "Additional \
+function args" :inline t sexp))
+ :options (open place close))))
+
+(defcustom preview-gs-image-type-alist
+ '((png png "-sDEVICE=png16m")
+ (dvipng png "-sDEVICE=png16m")
+ (jpeg jpeg "-sDEVICE=jpeg")
+ (pnm pbm "-sDEVICE=pnmraw")
+ (tiff tiff "-sDEVICE=tiff12nc"))
+ "*Alist of image types and corresponding Ghostscript options.
+The `dvipng' and `postscript' (don't use) entries really specify
+a fallback device when images can't be processed by the requested
+method, like when PDFTeX was used."
+ :group 'preview-gs
+ :type '(repeat (list :tag nil (symbol :tag "preview image-type")
+ (symbol :tag "Emacs image-type")
+ (repeat :inline t :tag "Ghostscript options" string))))
+
+(defcustom preview-image-type 'png
+ "*Image type to be used in images."
+ :group 'preview-gs
+ :type (append '(choice)
+ (mapcar (lambda (symbol) (list 'const (car symbol)))
+ preview-image-creators)
+ '((symbol :tag "Other"))))
+
+(defun preview-call-hook (symbol &rest rest)
+ "Call a function from `preview-image-creators'.
+This looks up SYMBOL in the `preview-image-creators' entry
+for the image type `preview-image-type' and calls the
+hook function given there with the arguments specified there
+followed by REST. If such a function is specified in there,
+that is."
+ (let ((hook (cdr (assq symbol
+ (cdr (assq preview-image-type
+ preview-image-creators))))))
+ (when hook
+ (apply (car hook) (append (cdr hook) rest)))))
+
+
+(defvar TeX-active-tempdir nil
+ "List of directory name, top directory name and reference count.")
+(make-variable-buffer-local 'TeX-active-tempdir)
+
+(defcustom preview-bb-filesize 1024
+ "Size of file area scanned for bounding box information."
+ :group 'preview-gs :type 'integer)
+
+(defcustom preview-preserve-indentation t
+ "*Whether to keep additional whitespace at the left of a line."
+ :group 'preview-appearance :type 'boolean)
+
+(defun preview-extract-bb (filename)
+ "Extract EPS bounding box vector from FILENAME."
+ (with-temp-buffer
+ (insert-file-contents-literally filename nil 0 preview-bb-filesize
+ t)
+ (goto-char (point-min))
+ (when (search-forward-regexp "%%BoundingBox:\
+ +\\([-+]?[0-9.]+\\)\
+ +\\([-+]?[0-9.]+\\)\
+ +\\([-+]?[0-9.]+\\)\
+ +\\([-+]?[0-9.]+\\)" nil t)
+ (vector
+ (if preview-preserve-indentation
+ (min 72 (string-to-number (match-string 1)))
+ (string-to-number (match-string 1)))
+ (string-to-number (match-string 2))
+ (string-to-number (match-string 3))
+ (string-to-number (match-string 4))
+ ))))
+
+(defcustom preview-prefer-TeX-bb nil
+ "*Prefer TeX bounding box to EPS one if available.
+If `preview-fast-conversion' is set, this option is not
+ consulted since the TeX bounding box has to be used anyway."
+ :group 'preview-gs
+ :type 'boolean)
+
+(defcustom preview-TeX-bb-border 0.5
+ "*Additional space in pt around Bounding Box from TeX."
+ :group 'preview-gs
+ :type 'number)
+
+(defvar preview-coding-system nil
+ "Coding system used for LaTeX process.")
+(make-variable-buffer-local 'preview-coding-system)
+(defvar preview-parsed-font-size nil
+ "Font size as parsed from the log of LaTeX run.")
+(make-variable-buffer-local 'preview-parsed-font-size)
+(defvar preview-parsed-magnification nil
+ "Magnification as parsed from the log of LaTeX run.")
+(make-variable-buffer-local 'preview-parsed-magnification)
+(defvar preview-parsed-pdfoutput nil
+ "PDFoutput as parsed from the log of LaTeX run.")
+(make-variable-buffer-local 'preview-parsed-pdfoutput)
+(defvar preview-parsed-counters nil
+ "Counters as parsed from the log of LaTeX run.")
+(make-variable-buffer-local 'preview-parsed-counters)
+(defvar preview-parsed-tightpage nil
+ "Tightpage as parsed from the log of LaTeX run.")
+(make-variable-buffer-local 'preview-parsed-tightpage)
+
+(defun preview-get-magnification ()
+ "Get magnification from `preview-parsed-magnification'."
+ (if preview-parsed-magnification
+ (/ preview-parsed-magnification 1000.0) 1.0))
+
+(defun preview-TeX-bb (list)
+ "Calculate bounding box from (ht dp wd).
+LIST consists of TeX dimensions in sp (1/65536 TeX point)."
+ (and
+ (consp list)
+ (let* ((dims (vconcat (mapcar
+ #'(lambda (x)
+ (/ x 65781.76)) list)))
+ (box
+ (vector
+ (+ 72 (min 0 (aref dims 2)))
+ (+ 720 (min (aref dims 0) (- (aref dims 1)) 0))
+ (+ 72 (max 0 (aref dims 2)))
+ (+ 720 (max (aref dims 0) (- (aref dims 1)) 0))))
+ (border (if preview-parsed-tightpage
+ (vconcat (mapcar
+ #'(lambda(x)
+ (/ x 65781.76)) preview-parsed-tightpage))
+ (vector (- preview-TeX-bb-border)
+ (- preview-TeX-bb-border)
+ preview-TeX-bb-border
+ preview-TeX-bb-border))))
+ (dotimes (i 4 box)
+ (aset box i (+ (aref box i) (aref border i)))))))
+
+(defcustom preview-gs-command (if (eq system-type 'windows-nt)
+ "GSWIN32C.EXE"
+ "gs")
+ "*How to call gs for conversion from EPS. See also `preview-gs-options'."
+ :group 'preview-gs
+ :type 'string)
+
+(defcustom preview-gs-options '("-q" "-dSAFER" "-dNOPAUSE"
+ "-DNOPLATFONTS" "-dPrinted"
+ "-dTextAlphaBits=4"
+ "-dGraphicsAlphaBits=4")
+ "*Options with which to call gs for conversion from EPS.
+See also `preview-gs-command'."
+ :group 'preview-gs
+ :type '(repeat string))
+
+(defvar preview-gs-queue nil
+ "List of overlays to convert using gs.
+Buffer-local to the appropriate TeX process buffer.")
+(make-variable-buffer-local 'preview-gs-queue)
+
+(defvar preview-gs-outstanding nil
+ "Overlays currently processed.")
+(make-variable-buffer-local 'preview-gs-outstanding)
+
+(defcustom preview-gs-outstanding-limit 2
+ "*Number of requests allowed to be outstanding.
+This is the number of not-yet-completed requests we
+might at any time have piped into Ghostscript. If
+this number is larger, the probability of Ghostscript
+working continuously is higher when Emacs is rather
+busy. If this number is smaller, redisplay will
+follow changes in the displayed buffer area faster."
+ :group 'preview-gs
+ :type '(restricted-sexp
+ :match-alternatives
+ ((lambda (value) (and
+ (integerp value)
+ (> value 0)
+ (< value 10))))
+ :tag "small number"))
+
+(defvar preview-gs-answer nil
+ "Accumulated answer of Ghostscript process.")
+(make-variable-buffer-local 'preview-gs-answer)
+
+(defvar preview-gs-image-type nil
+ "Image type for gs produced images.")
+(make-variable-buffer-local 'preview-gs-image-type)
+
+(defvar preview-gs-sequence nil
+ "Pair of sequence numbers for gs produced images.")
+(make-variable-buffer-local 'preview-gs-sequence)
+
+(defvar preview-scale nil
+ "Screen scale of images.
+Magnify by this factor to make images blend with other
+screen content. Buffer-local to rendering buffer.")
+(make-variable-buffer-local 'preview-scale)
+
+(defvar preview-colors nil
+ "Color setup list.
+An array with elements 0, 1 and 2 for background,
+foreground and border colors, respectively. Each element
+is a list of 3 real numbers between 0 and 1, or NIL
+of nothing special should be done for the color")
+(make-variable-buffer-local 'preview-colors)
+
+(defvar preview-gs-init-string nil
+ "Ghostscript setup string.")
+(make-variable-buffer-local 'preview-gs-init-string)
+
+(defvar preview-ps-file nil
+ "PostScript file name for fast conversion.")
+(make-variable-buffer-local 'preview-ps-file)
+
+(defvar preview-gs-dsc nil
+ "Parsed DSC information.")
+(make-variable-buffer-local 'preview-gs-dsc)
+
+(defvar preview-resolution nil
+ "Screen resolution where rendering started.
+Cons-cell of x and y resolution, given in
+dots per inch. Buffer-local to rendering buffer.")
+(make-variable-buffer-local 'preview-resolution)
+
+(defun preview-gs-resolution (scale xres yres)
+ "Generate resolution argument for gs.
+Calculated from real-life factor SCALE and XRES and
+YRES, the screen resolution in dpi."
+ (format "-r%gx%g"
+ (/ (* scale xres) (preview-get-magnification))
+ (/ (* scale yres) (preview-get-magnification))))
+
+(defun preview-gs-behead-outstanding (err)
+ "Remove leading element of outstanding queue after error.
+Return element if non-nil. ERR is the error string to
+show as response of Ghostscript."
+ (let ((ov (pop preview-gs-outstanding)))
+ (when ov
+ (preview-gs-flag-error ov err)
+ (overlay-put ov 'queued nil))
+ ov))
+
+(defvar preview-gs-command-line nil)
+(make-variable-buffer-local 'preview-gs-command-line)
+(defvar preview-gs-file nil)
+(make-variable-buffer-local 'preview-gs-file)
+
+(defcustom preview-fast-conversion t
+ "*Set this for single-file PostScript conversion.
+This will have no effect when `preview-image-type' is
+set to `postscript'."
+ :group 'preview-latex
+ :type 'boolean)
+
+(defun preview-string-expand (arg &optional separator)
+ "Expand ARG as a string.
+It can already be a string. Or it can be a list, then it is
+recursively evaluated using SEPARATOR as separator. If a list
+element is in itself a CONS cell, the CAR of the list (after symbol
+dereferencing) can evaluate to either a string, in which case it is
+used as a separator for the rest of the list,
+or a boolean (t or nil) in which case the rest of the list is
+either evaluated and concatenated or ignored, respectively.
+ARG can be a symbol, and so can be the CDR
+of a cell used for string concatenation."
+ (cond
+ ((stringp arg) arg)
+ ((consp arg)
+ (mapconcat
+ #'identity
+ (delq nil
+ (mapcar
+ (lambda(x)
+ (if (consp x)
+ (let ((sep (car x)))
+ (while (and (symbolp sep)
+ (not (memq sep '(t nil))))
+ (setq sep (symbol-value sep)))
+ (if (stringp sep)
+ (preview-string-expand (cdr x) sep)
+ (and sep
+ (preview-string-expand (cdr x)))))
+ (preview-string-expand x)))
+ arg))
+ (or separator "")))
+ ((and (symbolp arg) (not (memq arg '(t nil))))
+ (preview-string-expand (symbol-value arg) separator))
+ (t (error "Bad string expansion"))))
+
+(defconst preview-expandable-string
+ ((lambda (f) (funcall f (funcall f 'sexp)))
+ (lambda (x)
+ `(choice
+ string
+ (repeat :tag "Concatenate"
+ (choice
+ string
+ (cons :tag "Separated list"
+ (choice (string :tag "Separator")
+ (symbol :tag "Indirect separator or flag"))
+ ,x)
+ (symbol :tag "Indirect variable (no separator)")))
+ (symbol :tag "Indirect variable (with separator)"))))
+ "Type to be used for `preview-string-expand'.
+Just a hack until we get to learn how to do this properly.
+Recursive definitions are not popular with Emacs,
+so we define this type just two levels deep. This
+kind of expandible string can either be just a string, or a
+cons cell with a separator string in the CAR, and either
+an explicit list of elements in the CDR, or a symbol to
+be consulted recursively.")
+
+(defcustom preview-dvipng-command
+ "dvipng -picky -noghostscript %d -o \"%m/prev%%03d.png\""
+ "*Command used for converting to separate PNG images.
+
+You might specify options for converting to other image types,
+but then you'll need to adapt `preview-dvipng-image-type'."
+ :group 'preview-latex
+ :type 'string)
+
+(defcustom preview-dvipng-image-type
+ 'png
+ "*Image type that dvipng produces.
+
+You'll need to change `preview-dvipng-command' too,
+if you customize this."
+ :group 'preview-latex
+ :type '(choice (const png)
+ (const gif)
+ (symbol :tag "Other" :value png)))
+
+(defcustom preview-dvips-command
+ "dvips -Pwww -i -E %d -o %m/preview.000"
+ "*Command used for converting to separate EPS images."
+ :group 'preview-latex
+ :type 'string)
+
+(defcustom preview-fast-dvips-command
+ "dvips -Pwww %d -o %m/preview.ps"
+ "*Command used for converting to a single PS file."
+ :group 'preview-latex
+ :type 'string)
+
+(defcustom preview-pdf2dsc-command
+ "pdf2dsc %s.pdf %m/preview.dsc"
+ "*Command used for generating dsc from a PDF file."
+ :group 'preview-latex
+ :type 'string)
+
+(defun preview-gs-queue-empty ()
+ "Kill off everything remaining in `preview-gs-queue'."
+ (mapc #'preview-delete preview-gs-outstanding)
+ (dolist (ov preview-gs-queue)
+ (if (overlay-get ov 'queued)
+ (preview-delete ov)))
+ (setq preview-gs-outstanding nil)
+ (setq preview-gs-queue nil))
+
+(defvar preview-error-condition nil
+ "Last error raised and to be reported.")
+
+(defun preview-log-error (err context &optional process)
+ "Log an error message to run buffer.
+ERR is the caught error syndrome, CONTEXT is where it
+occured, PROCESS is the process for which the run-buffer
+is to be used."
+ (when (or (null process) (buffer-name (process-buffer process)))
+ (with-current-buffer (or (and process
+ (process-buffer process))
+ (current-buffer))
+ (save-excursion
+ (goto-char (or (and process
+ (process-buffer process)
+ (marker-buffer (process-mark process))
+ (process-mark process))
+ (point-max)))
+ (insert-before-markers
+ (format "%s: %s\n"
+ context (error-message-string err)))
+ (display-buffer (current-buffer)))))
+ (setq preview-error-condition err))
+
+(defun preview-reraise-error (&optional process)
+ "Raise an error that has been logged.
+Makes sure that PROCESS is removed from the \"Compilation\"
+tag in the mode line."
+ (when preview-error-condition
+ (unwind-protect
+ (signal (car preview-error-condition) (cdr preview-error-condition))
+ (setq preview-error-condition nil
+ compilation-in-progress (delq process compilation-in-progress)))))
+
+(defun preview-gs-sentinel (process string)
+ "Sentinel function for rendering process.
+Gets the default PROCESS and STRING arguments
+and tries to restart Ghostscript if necessary."
+ (condition-case err
+ (let ((status (process-status process)))
+ (when (memq status '(exit signal))
+ (setq compilation-in-progress (delq process compilation-in-progress)))
+ (when (buffer-name (process-buffer process))
+ (with-current-buffer (process-buffer process)
+ (goto-char (point-max))
+ (insert-before-markers "\n" mode-name " " string)
+ (forward-char -1)
+ (insert " at "
+ (substring (current-time-string) 0 -5))
+ (forward-char 1)
+ (TeX-command-mode-line process)
+ (when (memq status '(exit signal))
+ ;; process died.
+ ;; Throw away culprit, go on.
+ (let* ((err (concat preview-gs-answer "\n"
+ (process-name process) " " string))
+ (ov (preview-gs-behead-outstanding err)))
+ (when (and (null ov) preview-gs-queue)
+ (save-excursion
+ (goto-char (if (marker-buffer (process-mark process))
+ (process-mark process)
+ (point-max)))
+ (insert-before-markers err)))
+ (delete-process process)
+ (if (or (null ov)
+ (eq status 'signal))
+ ;; if process was killed explicitly by signal, or if nothing
+ ;; was processed, we give up on the matter altogether.
+ (progn
+ (when preview-ps-file
+ (condition-case nil
+ (preview-delete-file preview-ps-file)
+ (file-error nil)))
+ (preview-gs-queue-empty))
+
+ ;; restart only if we made progress since last call
+ (let (filenames)
+ (dolist (ov preview-gs-outstanding)
+ (setq filenames (overlay-get ov 'filenames))
+ (condition-case nil
+ (preview-delete-file (nth 1 filenames))
+ (file-error nil))
+ (setcdr filenames nil)))
+ (setq preview-gs-queue (nconc preview-gs-outstanding
+ preview-gs-queue))
+ (setq preview-gs-outstanding nil)
+ (preview-gs-restart)))))))
+ (error (preview-log-error err "Ghostscript" process)))
+ (preview-reraise-error process))
+
+(defun preview-gs-filter (process string)
+ "Filter function for processing Ghostscript output.
+Gets the usual PROCESS and STRING parameters, see
+`set-process-filter' for a description."
+ (with-current-buffer (process-buffer process)
+ (setq preview-gs-answer (concat preview-gs-answer string))
+ (while (string-match "GS\\(<[0-9]+\\)?>" preview-gs-answer)
+ (let* ((pos (match-end 0))
+ (answer (substring preview-gs-answer 0 pos)))
+ (setq preview-gs-answer (substring preview-gs-answer pos))
+ (condition-case err
+ (preview-gs-transact process answer)
+ (error (preview-log-error err "Ghostscript filter" process))))))
+ (preview-reraise-error))
+
+(defun preview-gs-restart ()
+ "Start a new Ghostscript conversion process."
+ (when preview-gs-queue
+ (if preview-gs-sequence
+ (setcar preview-gs-sequence (1+ (car preview-gs-sequence)))
+ (setq preview-gs-sequence (list 1)))
+ (setcdr preview-gs-sequence 1)
+ (let* ((process-connection-type nil)
+ (outfile (format "-dOutputFile=%s"
+ (preview-ps-quote-filename
+ (format "%s/pr%d-%%d.%s"
+ (car TeX-active-tempdir)
+ (car preview-gs-sequence)
+ preview-gs-image-type))))
+ (process
+ (apply #'start-process
+ "Preview-Ghostscript"
+ (current-buffer)
+ preview-gs-command
+ outfile
+ preview-gs-command-line)))
+ (goto-char (point-max))
+ (insert-before-markers "Running `Preview-Ghostscript' with ``"
+ (mapconcat #'shell-quote-argument
+ (append
+ (list preview-gs-command
+ outfile)
+ preview-gs-command-line)
+ " ") "''\n")
+ (setq preview-gs-answer "")
+ (process-kill-without-query process)
+ (set-process-sentinel process #'preview-gs-sentinel)
+ (set-process-filter process #'preview-gs-filter)
+ (process-send-string process preview-gs-init-string)
+ (setq mode-name "Preview-Ghostscript")
+ (push process compilation-in-progress)
+ (TeX-command-mode-line process)
+ (set-buffer-modified-p (buffer-modified-p))
+ process)))
+
+(defun preview-gs-open (&optional setup)
+ "Start a Ghostscript conversion pass.
+SETUP may contain a parser setup function."
+ (let ((image-info (assq preview-image-type preview-gs-image-type-alist)))
+ (setq preview-gs-image-type (nth 1 image-info))
+ (setq preview-gs-sequence nil)
+ (setq preview-gs-command-line (append
+ preview-gs-options
+ (nthcdr 2 image-info))
+ preview-gs-init-string
+ (format "{DELAYSAFER{.setsafe}if}stopped pop\
+/.preview-BP currentpagedevice/BeginPage get dup \
+null eq{pop{pop}bind}if def\
+<</BeginPage{currentpagedevice/PageSize get dup 0 get 1 ne exch 1 get 1 ne or\
+{.preview-BP %s}{pop}ifelse}bind/PageSize[1 1]>>setpagedevice\
+/preview-do{[count 3 roll save]3 1 roll dup length 0 eq\
+{pop}{setpagedevice}{ifelse .runandhide}\
+stopped{handleerror quit}if \
+aload pop restore}bind def "
+ (preview-gs-color-string preview-colors)))
+ (preview-gs-queue-empty)
+ (preview-parse-messages (or setup #'preview-gs-dvips-process-setup))))
+
+(defun preview-gs-color-value (value)
+ "Return string to be used as color value for an RGB component.
+Conversion from Emacs color numbers (0 to 65535) in VALUE
+to Ghostscript floats."
+ (format "%g" (/ value 65535.0)))
+
+(defun preview-pdf-color-string (colors)
+ "Return a string that patches PDF foreground color to work properly."
+ ;; Actually, this is rather brutal. It will only be invoked in
+ ;; cases, however, where previously it was not expected that
+ ;; anything readable turned up, anyway.
+ (let ((fg (aref colors 1)))
+ (if fg
+ (concat
+ "/GS_PDF_ProcSet GS_PDF_ProcSet dup maxlength dict copy dup begin\
+/graphicsbeginpage{//graphicsbeginpage exec "
+ (mapconcat #'preview-gs-color-value fg " ")
+ " 3 copy rg RG}bind store end readonly store "))))
+
+(defun preview-gs-color-string (colors)
+ "Return a string setting up colors"
+ (let ((bg (aref colors 0))
+ (fg (aref colors 1))
+ (mask (aref colors 2))
+ (border (aref colors 3)))
+ (concat
+ (and (or (and mask border) (and bg (not fg)))
+ "gsave ")
+ (and bg
+ (concat
+ (mapconcat #'preview-gs-color-value bg " ")
+ " setrgbcolor clippath fill "))
+ (and mask border
+ (format "%s setrgbcolor false setstrokeadjust %g \
+setlinewidth clippath strokepath \
+matrix setmatrix true \
+{2 index{newpath}if round exch round exch moveto pop false}\
+{round exch round exch lineto}{curveto}{closepath}\
+pathforall pop fill "
+ (mapconcat #'preview-gs-color-value mask " ")
+ (* 2 border)))
+ ;; I hate antialiasing. Warp border to integral coordinates.
+ (and (or (and mask border) (and bg (not fg)))
+ "grestore ")
+ (and fg
+ (concat
+ (mapconcat #'preview-gs-color-value fg " ")
+ " setrgbcolor")))))
+
+(defun preview-dvipng-color-string (colors res)
+ "Return color setup tokens for dvipng.
+Makes a string of options suitable for passing to dvipng.
+Pure borderless black-on-white will return an empty string."
+ (let
+ ((bg (aref colors 0))
+ (fg (aref colors 1))
+ (mask (aref colors 2))
+ (border (aref colors 3)))
+ (concat
+ (and bg
+ (format "--bg 'rgb %s' "
+ (mapconcat #'preview-gs-color-value bg " ")))
+ (and fg
+ (format "--fg 'rgb %s' "
+ (mapconcat #'preview-gs-color-value fg " ")))
+ (and mask border
+ (format "--bd 'rgb %s' "
+ (mapconcat #'preview-gs-color-value mask " ")))
+ (and border
+ (format "--bd %d" (max 1 (round (/ (* res border) 72.0))))))))
+
+(defun preview-gs-dvips-process-setup ()
+ "Set up Dvips process for conversions via gs."
+ (unless (preview-supports-image-type preview-gs-image-type)
+ (error "preview-image-type setting '%s unsupported by this Emacs"
+ preview-gs-image-type))
+ (setq preview-gs-command-line (append
+ preview-gs-command-line
+ (list (preview-gs-resolution
+ (preview-hook-enquiry preview-scale)
+ (car preview-resolution)
+ (cdr preview-resolution)))))
+ (if preview-parsed-pdfoutput
+ (preview-pdf2dsc-process-setup)
+ (let ((process (preview-start-dvips preview-fast-conversion)))
+ (setq TeX-sentinel-function #'preview-gs-dvips-sentinel)
+ (list process (current-buffer) TeX-active-tempdir preview-ps-file
+ preview-gs-image-type))))
+
+(defun preview-dvipng-process-setup ()
+ "Set up dvipng process for conversion."
+ (setq preview-gs-command-line (append
+ preview-gs-command-line
+ (list (preview-gs-resolution
+ (preview-hook-enquiry preview-scale)
+ (car preview-resolution)
+ (cdr preview-resolution)))))
+ (if preview-parsed-pdfoutput
+ (if (preview-supports-image-type preview-gs-image-type)
+ (preview-pdf2dsc-process-setup)
+ (error "preview-image-type setting '%s unsupported by this Emacs"
+ preview-gs-image-type))
+ (unless (preview-supports-image-type preview-dvipng-image-type)
+ (error "preview-dvipng-image-type setting '%s unsupported by this Emacs"
+ preview-dvipng-image-type))
+ (let ((process (preview-start-dvipng)))
+ (setq TeX-sentinel-function #'preview-dvipng-sentinel)
+ (list process (current-buffer) TeX-active-tempdir t
+ preview-dvipng-image-type))))
+
+
+(defun preview-pdf2dsc-process-setup ()
+ (let ((process (preview-start-pdf2dsc)))
+ (setq TeX-sentinel-function #'preview-pdf2dsc-sentinel)
+ (list process (current-buffer) TeX-active-tempdir preview-ps-file
+ preview-gs-image-type)))
+
+(defun preview-dvips-abort ()
+ "Abort a Dvips run."
+ (preview-gs-queue-empty)
+ (condition-case nil
+ (delete-file
+ (let ((gsfile preview-gs-file))
+ (with-current-buffer TeX-command-buffer
+ (funcall (car gsfile) "dvi"))))
+ (file-error nil))
+ (when preview-ps-file
+ (condition-case nil
+ (preview-delete-file preview-ps-file)
+ (file-error nil)))
+ (setq TeX-sentinel-function nil))
+
+(defalias 'preview-dvipng-abort 'preview-dvips-abort)
+; "Abort a DviPNG run.")
+
+(defun preview-gs-dvips-sentinel (process command &optional gsstart)
+ "Sentinel function for indirect rendering DviPS process.
+The usual PROCESS and COMMAND arguments for
+`TeX-sentinel-function' apply. Starts gs if GSSTART is set."
+ (condition-case err
+ (let ((status (process-status process))
+ (gsfile preview-gs-file))
+ (cond ((eq status 'exit)
+ (delete-process process)
+ (setq TeX-sentinel-function nil)
+ (condition-case nil
+ (delete-file
+ (with-current-buffer TeX-command-buffer
+ (funcall (car gsfile) "dvi")))
+ (file-error nil))
+ (if preview-ps-file
+ (preview-prepare-fast-conversion))
+ (when gsstart
+ (if preview-gs-queue
+ (preview-gs-restart)
+ (when preview-ps-file
+ (condition-case nil
+ (preview-delete-file preview-ps-file)
+ (file-error nil))))))
+ ((eq status 'signal)
+ (delete-process process)
+ (preview-dvips-abort))))
+ (error (preview-log-error err "DviPS sentinel" process)))
+ (preview-reraise-error process))
+
+(defun preview-pdf2dsc-sentinel (process command &optional gsstart)
+ "Sentinel function for indirect rendering PDF process.
+The usual PROCESS and COMMAND arguments for
+`TeX-sentinel-function' apply. Starts gs if GSSTART is set."
+ (condition-case err
+ (let ((status (process-status process)))
+ (cond ((eq status 'exit)
+ (delete-process process)
+ (setq TeX-sentinel-function nil)
+ (setq preview-gs-init-string
+ (concat preview-gs-init-string
+ (preview-pdf-color-string preview-colors)))
+ (preview-prepare-fast-conversion)
+ (when gsstart
+ (if preview-gs-queue
+ (preview-gs-restart)
+ (when preview-ps-file
+ (condition-case nil
+ (preview-delete-file preview-ps-file)
+ (file-error nil))))))
+ ((eq status 'signal)
+ (delete-process process)
+ (preview-dvips-abort))))
+ (error (preview-log-error err "PDF2DSC sentinel" process)))
+ (preview-reraise-error process))
+
+(defun preview-gs-close (process closedata)
+ "Clean up after PROCESS and set up queue accumulated in CLOSEDATA."
+ (setq preview-gs-queue (nconc preview-gs-queue closedata))
+ (if process
+ (if preview-gs-queue
+ (if TeX-process-asynchronous
+ (if (and (eq (process-status process) 'exit)
+ (null TeX-sentinel-function))
+ ;; Process has already finished and run sentinel
+ (progn
+ (when preview-ps-file
+ (condition-case nil
+ (preview-delete-file preview-ps-file)
+ (file-error nil)))
+ (preview-gs-restart))
+ (setq TeX-sentinel-function
+ `(lambda (process command)
+ (,(if preview-parsed-pdfoutput
+ 'preview-pdf2dsc-sentinel
+ 'preview-gs-dvips-sentinel)
+ process
+ command
+ t))))
+ (TeX-synchronous-sentinel "Preview-DviPS" (cdr preview-gs-file)
+ process))
+ ;; pathological case: no previews although we sure thought so.
+ (delete-process process)
+ (unless (eq (process-status process) 'signal)
+ (preview-dvips-abort)))))
+
+(defun preview-dvipng-sentinel (process command &optional placeall)
+ "Sentinel function for indirect rendering DviPNG process.
+The usual PROCESS and COMMAND arguments for
+`TeX-sentinel-function' apply. Places all snippets if PLACEALL is set."
+ (condition-case err
+ (let ((status (process-status process)))
+ (cond ((eq status 'exit)
+ (delete-process process)
+ (setq TeX-sentinel-function nil)
+ (when placeall
+ (preview-dvipng-place-all)))
+ ((eq status 'signal)
+ (delete-process process)
+ (preview-dvipng-abort))))
+ (error (preview-log-error err "DviPNG sentinel" process)))
+ (preview-reraise-error process))
+
+(defun preview-dvipng-close (process closedata)
+ "Clean up after PROCESS and set up queue accumulated in CLOSEDATA."
+ (if preview-parsed-pdfoutput
+ (preview-gs-close process closedata)
+ (setq preview-gs-queue (nconc preview-gs-queue closedata))
+ (if process
+ (if preview-gs-queue
+ (if TeX-process-asynchronous
+ (if (and (eq (process-status process) 'exit)
+ (null TeX-sentinel-function))
+ ;; Process has already finished and run sentinel
+ (preview-dvipng-place-all)
+ (setq TeX-sentinel-function (lambda (process command)
+ (preview-dvipng-sentinel
+ process
+ command
+ t))))
+ (TeX-synchronous-sentinel "Preview-DviPNG" (cdr preview-gs-file)
+ process))
+ ;; pathological case: no previews although we sure thought so.
+ (delete-process process)
+ (unless (eq (process-status process) 'signal)
+ (preview-dvipng-abort))))))
+
+(defun preview-dsc-parse (file)
+ "Parse DSC comments of FILE.
+Returns a vector with offset/length pairs corresponding to
+the pages. Page 0 corresponds to the initialization section."
+ (with-temp-buffer
+ (set-buffer-multibyte nil)
+ (insert-file-contents-literally file)
+ (let ((last-pt (point-min))
+ trailer
+ pagelist
+ lastbegin
+ pt
+ case-fold-search
+ (level 0))
+ (while (search-forward-regexp "\
+%%\\(?:\\(BeginDocument:\\)\\|\
+\\(EndDocument[\n\r]\\)\\|\
+\\(Page:\\)\\|\
+\\(Trailer[\n\r]\\)\\)" nil t)
+ (setq pt (match-beginning 0))
+ (cond ((null (memq (char-before pt) '(?\C-j ?\C-m nil))))
+ (trailer (error "Premature %%%%Trailer in `%s' at offsets %d/%d"
+ file trailer pt))
+ ((match-beginning 1)
+ (if (zerop level)
+ (setq lastbegin pt))
+ (setq level (1+ level)))
+ ((match-beginning 2)
+ (if (zerop level)
+ (error "Unmatched %%%%EndDocument in `%s' at offset %d"
+ file pt)
+ (setq level (1- level))))
+ ((> level 0))
+ ((match-beginning 3)
+ (push (list last-pt (- pt last-pt)) pagelist)
+ (setq last-pt pt))
+ ((match-beginning 4)
+ (setq trailer pt))))
+ (unless (zerop level)
+ (error "Unmatched %%%%BeginDocument in `%s' at offset %d"
+ file lastbegin))
+ (push (list last-pt
+ (- (or trailer (point-max)) last-pt)) pagelist)
+ (vconcat (nreverse pagelist)))))
+
+(defun preview-gs-dsc-cvx (page dsc)
+ "Generate PostScript code accessing PAGE in the DSC object.
+The returned PostScript code will need the file on
+top of the stack, and will replace it with an executable
+object corresponding to the wanted page."
+ (let ((curpage (aref dsc page)))
+ (format "dup %d setfileposition %d()/SubFileDecode filter cvx"
+ (1- (car curpage)) (nth 1 curpage))))
+
+(defun preview-ps-quote-filename (str &optional nonrel)
+ "Make a PostScript string from filename STR.
+The file name is first made relative unless
+NONREL is not NIL."
+ (unless nonrel (setq str (file-relative-name str)))
+ (let ((index 0))
+ (while (setq index (string-match "[\\()]" str index))
+ (setq str (replace-match "\\\\\\&" t nil str)
+ index (+ 2 index)))
+ (concat "(" str ")")))
+
+(defun preview-prepare-fast-conversion ()
+ "This fixes up all parameters for fast conversion."
+ (let ((file (if (consp (car preview-ps-file))
+ (if (consp (caar preview-ps-file))
+ (car (last (caar preview-ps-file)))
+ (caar preview-ps-file))
+ (car preview-ps-file))))
+ (setq preview-gs-dsc (preview-dsc-parse file))
+ (setq preview-gs-init-string
+ (concat preview-gs-init-string
+ (format "[%s(r)file]aload exch %s .runandhide aload pop "
+ (preview-ps-quote-filename file)
+ (preview-gs-dsc-cvx 0 preview-gs-dsc))))))
+
+(defun preview-gs-urgentize (ov buff)
+ "Make a displayed overlay render with higher priority.
+This function is used in fake conditional display properties
+for reordering the conversion order to prioritize on-screen
+images. OV is the overlay in question, and BUFF is the
+Ghostscript process buffer where the buffer-local queue
+is located."
+ ;; It does not matter that ov gets queued twice in that process: the
+ ;; first version to get rendered will clear the 'queued property.
+ ;; It cannot get queued more than twice since we remove the
+ ;; conditional display property responsible for requeuing here.
+ ;; We don't requeue if the overlay has been killed (its buffer made
+ ;; nil). Not necessary, but while we are checking...
+ ;; We must return t.
+ (preview-remove-urgentization ov)
+ (when (and (overlay-get ov 'queued)
+ (overlay-buffer ov))
+ (with-current-buffer buff
+ (push ov preview-gs-queue)))
+ t)
+
+
+(defun preview-gs-place (ov snippet box run-buffer tempdir ps-file imagetype)
+ "Generate an image placeholder rendered over by Ghostscript.
+This enters OV into all proper queues in order to make it render
+this image for real later, and returns the overlay after setting
+a placeholder image. SNIPPET gives the number of the
+snippet in question for the file to be generated.
+BOX is a bounding box if we already know one via TeX.
+RUN-BUFFER is the buffer of the TeX process,
+TEMPDIR is the correct copy of `TeX-active-tempdir',
+PS-FILE is a copy of `preview-ps-file', IMAGETYPE is the image type
+for the file extension."
+ (overlay-put ov 'filenames
+ (unless (eq ps-file t)
+ (list
+ (preview-make-filename
+ (or ps-file
+ (format "preview.%03d" snippet))
+ tempdir))))
+ (overlay-put ov 'queued
+ (vector box nil snippet))
+ (overlay-put ov 'preview-image
+ (list (preview-icon-copy preview-nonready-icon)))
+ (preview-add-urgentization #'preview-gs-urgentize ov run-buffer)
+ (list ov))
+
+(defun preview-mouse-open-error (string)
+ "Display STRING in a new view buffer on click."
+ (let ((buff (get-buffer-create
+ "*Preview-Ghostscript-Error*")))
+ (with-current-buffer buff
+ (kill-all-local-variables)
+ (set (make-local-variable 'view-exit-action) #'kill-buffer)
+ (setq buffer-undo-list t)
+ (erase-buffer)
+ (insert string)
+ (goto-char (point-min)))
+ (view-buffer-other-window buff)))
+
+(defun preview-mouse-open-eps (file &optional position)
+ "Display eps FILE in a view buffer on click.
+Place point at POSITION, else beginning of file."
+ (let ((default-major-mode
+ (or
+ (assoc-default "x.ps" auto-mode-alist #'string-match)
+ default-major-mode))
+ (buff (get-file-buffer file)))
+ (save-excursion
+ (if buff
+ (pop-to-buffer buff)
+ (view-file-other-window file))
+ (goto-char (or position (point-min)))
+ (if (eq major-mode 'ps-mode) ; Bundled with GNU Emacs
+ (message "%s" (substitute-command-keys "\
+Try \\[ps-run-start] \\[ps-run-buffer] and \
+\\<ps-run-mode-map>\\[ps-run-mouse-goto-error] on error offset." )))
+ (if (eq major-mode 'postscript-mode) ; Bundled with XEmacs, limited
+ (message "%s" (substitute-command-keys "\
+Try \\[ps-shell] and \\[ps-execute-buffer]."))))))
+
+(defun preview-gs-flag-error (ov err)
+ "Make an eps error flag in overlay OV for ERR string."
+ (let* ((filenames (overlay-get ov 'filenames))
+ (file (car (nth 0 filenames)))
+ (outfile (format "-dOutputFile=%s"
+ (preview-ps-quote-filename
+ (car (nth 1 filenames)))))
+ (ps-open
+ `(lambda() (interactive "@")
+ (preview-mouse-open-error
+ ,(concat
+ (mapconcat #'shell-quote-argument
+ (append (list
+ preview-gs-command
+ outfile)
+ preview-gs-command-line)
+ " ")
+ "\nGS>"
+ preview-gs-init-string
+ (aref (overlay-get ov 'queued) 1)
+ err))))
+ (str
+ (preview-make-clickable
+ nil
+ preview-error-icon
+ "%s views error message
+%s more options"
+ ps-open
+ `(lambda() (interactive)
+ (popup-menu
+ '("PostScript error"
+ ["View error" ,ps-open]
+ ["View source"
+ (lambda () (interactive "@")
+ ,(if preview-ps-file
+ `(preview-mouse-open-eps
+ ,(if (consp (car file))
+ (nth 1 (car file))
+ (car file))
+ ,(nth 0 (aref preview-gs-dsc
+ (aref (overlay-get ov 'queued) 2))))
+ `(preview-mouse-open-eps ,file)))]))))))
+ (overlay-put ov 'strings (cons str str))
+ (preview-toggle ov)))
+
+(defun preview-gs-transact (process answer)
+ "Work off Ghostscript transaction.
+This routine is the action routine called via the process filter.
+The Ghostscript process buffer of PROCESS will already be selected, and
+and the standard output of Ghostscript up to the next prompt will be
+given as ANSWER."
+ (let ((ov (pop preview-gs-outstanding))
+ (have-error (not
+ (string-match "\\`GS\\(<[0-9]+\\)?>\\'" answer ))))
+ (when (and ov (overlay-buffer ov))
+ (let ((queued (overlay-get ov 'queued)))
+ (when queued
+ (let* ((bbox (aref queued 0))
+ (filenames (overlay-get ov 'filenames))
+ (oldfile (nth 0 filenames))
+ (newfile (nth 1 filenames)))
+ (if have-error
+ (preview-gs-flag-error ov answer)
+ (condition-case nil
+ (preview-delete-file oldfile)
+ (file-error nil))
+ (overlay-put ov 'filenames (cdr filenames))
+ (preview-replace-active-icon
+ ov
+ (preview-create-icon (car newfile)
+ preview-gs-image-type
+ (preview-ascent-from-bb
+ bbox)
+ (aref preview-colors 2))))
+ (overlay-put ov 'queued nil)))))
+ (while (and (< (length preview-gs-outstanding)
+ preview-gs-outstanding-limit)
+ (setq ov (pop preview-gs-queue)))
+ (let ((queued (overlay-get ov 'queued)))
+ (when (and queued
+ (not (memq ov preview-gs-outstanding))
+ (overlay-buffer ov))
+ (let* ((filenames (overlay-get ov 'filenames))
+ (oldfile (car (nth 0
+ (nconc filenames
+ (list
+ (preview-make-filename
+ (format "pr%d-%d.%s"
+ (car preview-gs-sequence)
+ (cdr preview-gs-sequence)
+ preview-gs-image-type)
+ TeX-active-tempdir))))))
+ (bbox (aset queued 0
+ (or (and preview-prefer-TeX-bb
+ (aref queued 0))
+ (and (stringp oldfile)
+ (preview-extract-bb
+ oldfile))
+ (aref queued 0)
+ (error "No bounding box"))))
+ (snippet (aref queued 2))
+ (gs-line
+ (format
+ "%s<<%s>>preview-do\n"
+ (if preview-ps-file
+ (concat "dup "
+ (preview-gs-dsc-cvx
+ snippet
+ preview-gs-dsc))
+ (format "%s(r)file cvx"
+ (preview-ps-quote-filename
+ (if (listp oldfile)
+ (car (last oldfile))
+ oldfile))))
+ (if preview-parsed-tightpage
+ ""
+ (format "/PageSize[%g %g]/PageOffset[%g \
+%g[1 1 dtransform exch]{0 ge{neg}if exch}forall]"
+ (- (aref bbox 2) (aref bbox 0))
+ (- (aref bbox 3) (aref bbox 1))
+ (aref bbox 0) (aref bbox 1))))))
+ (setcdr preview-gs-sequence (1+ (cdr preview-gs-sequence)))
+ (setq preview-gs-outstanding
+ (nconc preview-gs-outstanding
+ (list ov)))
+ (aset queued 1 gs-line)
+ ;; ignore errors because of dying processes: they will get
+ ;; caught by the sentinel, anyway.
+ (condition-case nil
+ (process-send-string
+ process
+ gs-line)
+ (error nil))))))
+ (unless preview-gs-outstanding
+ (condition-case nil
+ (process-send-eof process)
+ (error nil)))))
+
+(defun preview-hook-enquiry (hook)
+ "Gets a value from a configured hook.
+HOOK is a list or single item, for which the first resolving to
+non-nil counts. Entries can be a callable function, or
+a symbol that is consulted, or a value. Lists are evaluated
+recursively."
+ (cond ((functionp hook)
+ (funcall hook))
+ ((consp hook)
+ (let (res)
+ (while (and (not res) hook)
+ (setq res (preview-hook-enquiry (car hook))
+ hook (cdr hook)))
+ res))
+ ((and (symbolp hook) (boundp hook))
+ (symbol-value hook))
+ (t hook)))
+
+(defcustom preview-scale-function #'preview-scale-from-face
+ "*Scale factor for included previews.
+This can be either a function to calculate the scale, or
+a fixed number."
+ :group 'preview-appearance
+ :type '(choice (function-item preview-scale-from-face)
+ (const 1.0)
+ (number :value 1.0)
+ (function :value preview-scale-from-face)))
+
+(defcustom preview-default-document-pt 10
+ "*Assumed document point size for `preview-scale-from-face'.
+If the point size (such as 11pt) of the document cannot be
+determined from the document options itself, assume this size.
+This is for matching screen font size and previews."
+ :group 'preview-appearance
+ :type
+ '(choice (const :tag "10pt" 10)
+ (const :tag "11pt" 11)
+ (const :tag "12pt" 12)
+ (number :tag "Other" :value 11.0))
+)
+
+(defcustom preview-document-pt-list '(preview-parsed-font-size
+ preview-auctex-font-size
+ preview-default-document-pt)
+ "*How `preview-document-pt' figures out the document size."
+ :group 'preview-appearance
+ :type
+ '(repeat (choice
+ ;; This is a bug: type function seems to match variables, too.
+ (restricted-sexp :match-alternatives (functionp)
+ :tag "Function" :value preview-auctex-font-size)
+ (variable :value preview-parsed-font-size)
+ (number :value 11))))
+
+(defun preview-auctex-font-size ()
+ "Calculate the default font size of document.
+If packages, classes or styles were called with an option
+like 10pt, size is taken from the first such option if you
+had let your document be parsed by AucTeX."
+ (catch 'return (dolist (option (TeX-style-list))
+ (if (string-match "\\`\\([0-9]+\\)pt\\'" option)
+ (throw 'return
+ (string-to-number
+ (match-string 1 option)))))))
+
+(defsubst preview-document-pt ()
+ "Calculate the default font size of document."
+ (preview-hook-enquiry preview-document-pt-list))
+
+(defun preview-scale-from-face ()
+ "Calculate preview scale from `preview-reference-face'.
+This calculates the scale of EPS images from a document assumed
+to have a default font size given by function `preview-document-pt'
+so that they match the reference face in height."
+ `(lambda nil
+ (/ ,(/ (preview-inherited-face-attribute 'preview-reference-face :height
+ 'default) 10.0)
+ (preview-document-pt))))
+
+(defvar preview-min-spec)
+
+(defun preview-make-image (symbol)
+ "Make an image from a preview spec list.
+The first spec that is workable (given the current setting of
+`preview-min-spec') from the given symbol is used here. The
+icon is cached in the property list of the symbol."
+ (let ((alist (get 'preview-min-alist symbol)))
+ (cdr (or
+ (assq preview-min-spec alist)
+ (car (put symbol 'preview-min-alist
+ (cons
+ (cons preview-min-spec
+ (preview-filter-specs
+ (symbol-value symbol)))
+ alist)))))))
+
+(defun preview-filter-specs (spec-list)
+ "Find the first of the fitting specs and make an image."
+ (let (image)
+ (while (and spec-list
+ (not (setq image
+ (catch 'preview-filter-specs
+ (preview-filter-specs-1 (car spec-list))))))
+ (setq spec-list (cdr spec-list)))
+ image))
+
+(defun preview-filter-specs-1 (specs)
+ (and specs
+ (if (get 'preview-filter-specs (car specs))
+ (apply (get 'preview-filter-specs (car specs)) specs)
+ `(,(nth 0 specs) ,(nth 1 specs)
+ ,@(preview-filter-specs-1 (nthcdr 2 specs))))))
+
+(put 'preview-filter-specs :min
+ #'(lambda (keyword value &rest args)
+ (if (> value preview-min-spec)
+ (throw 'preview-filter-specs nil)
+ (preview-filter-specs-1 args))))
+
+(defvar preview-datadir (file-name-directory load-file-name)
+ "The directory relative to which package data may be found.
+This should be hardwired into the startup file containing the
+autoloads for preview-latex.")
+
+(put 'preview-filter-specs :file
+ #'(lambda (keyword value &rest args)
+ `(:file ,(expand-file-name value (expand-file-name "images"
+ preview-datadir))
+ ,@(preview-filter-specs-1 args))))
+
+(defun preview-ascent-from-bb (bb)
+ "This calculates the image ascent from its bounding box.
+The bounding box BB needs to be a 4-component vector of
+numbers (can be float if available)."
+ ;; baseline is at 1in from the top of letter paper (11in), so it is
+ ;; at 10in from the bottom precisely, which is 720 in PostScript
+ ;; coordinates. If our bounding box has its bottom not above this
+ ;; line, and its top above, we can calculate a useful ascent value.
+ ;; If not, something is amiss. We just use 100 in that case.
+
+ (let ((bottom (aref bb 1))
+ (top (aref bb 3)))
+ (if (and (<= bottom 720)
+ (> top 720))
+ (round (* 100.0 (/ (- top 720.0) (- top bottom))))
+ 100)))
+
+(defface preview-face '((((background dark))
+ (:background "dark slate gray"))
+ (t
+ (:background "beige")))
+ "Face to use for the preview source."
+ :group 'preview-appearance)
+
+(defface preview-reference-face '((t nil))
+ "Face consulted for colors and scale of active previews.
+Fallback to :inherit and 'default implemented."
+ :group 'preview-appearance)
+
+(defcustom preview-auto-reveal '(eval (preview-arrived-via
+ (key-binding [left])
+ (key-binding [right])))
+ "*Cause previews to open automatically when entered.
+Possibilities are:
+T autoopens,
+NIL doesn't,
+a symbol will have its value consulted if it exists,
+defaulting to NIL if it doesn't.
+An integer will specify a maximum cursor movement distance.
+Larger movements won't open the preview.
+A CONS-cell means to call a function for determining the value.
+The CAR of the cell is the function to call which receives
+the CDR of the CONS-cell in the rest of the arguments, while
+point and current buffer point to the position in question.
+All of the options show reasonable defaults."
+ :group 'preview-appearance
+ :type '(choice (const :tag "Off" nil)
+ (const :tag "On" t)
+ (symbol :tag "Indirect variable" :value reveal-mode)
+ (integer :tag "Maximum distance" :value 1)
+ (cons :tag "Function call"
+ :value (eval (preview-arrived-via
+ (key-binding [left])
+ (key-binding [right])))
+ function (list :tag "Argument list"
+ (repeat :inline t sexp)))))
+
+(defun preview-auto-reveal-p (mode distance)
+ "Decide whether to auto-reveal.
+Returns non-NIL if region should be auto-opened.
+See `preview-auto-reveal' for definitions of MODE, which gets
+set to `preview-auto-reveal'. DISTANCE specifies the movement
+distance with which point has been reached in case it has been
+a movement starting in the current buffer."
+ (cond ((symbolp mode)
+ (and (boundp mode)
+ (symbol-value mode)))
+ ((integerp mode)
+ (and distance (/= 0 distance) (<= (abs distance) mode)))
+ ((consp mode)
+ (apply (car mode) (cdr mode)))
+ (t mode)))
+
+(defun preview-arrived-via (&rest list)
+ "Indicate auto-opening.
+Returns non-NIL if called by one of the commands in LIST."
+ (memq this-command list))
+
+(defcustom preview-equality-transforms '(identity
+ preview-canonical-spaces)
+"Transformation functions for region changes.
+These functions are tried in turn on the strings from the
+regions of a preview to decide whether a preview is to be considered
+changed. If any transform leads to equal results, the preview is
+considered unchanged."
+ :group 'preview-appearance
+ :type '(repeat function))
+
+(defun preview-relaxed-string= (&rest args)
+"Check for functional equality of arguments.
+The arguments ARGS are checked for equality by using
+`preview-equality-transforms' on them until it is exhausted
+or one transform returns equality."
+ (let ((lst preview-equality-transforms))
+ (while (and lst (not (apply #'string= (mapcar (car lst) args))))
+ (setq lst (cdr lst)))
+ lst))
+
+(defun preview-canonical-spaces (arg)
+ "Convert ARG into canonical form.
+Removes comments and collapses white space, except for multiple newlines."
+ (let (pos)
+ (while (setq pos (string-match "\\s<.*[\n\r][ \t]*" arg pos))
+ (setq arg (replace-match "" t t arg 0)))
+ (while (setq pos (string-match "[ \t]*\\(\\([ \t]\\)\\|[\n\r][ \t]*\\)"
+ arg pos))
+ (setq arg (replace-match (if (match-beginning 2) " " "\n") t t arg 0)
+ pos (1+ pos)))
+ (while (setq pos (string-match "\n+" arg pos))
+ (if (string= "\n" (match-string 0 arg))
+ (setq arg (replace-match " " t t arg 0)
+ pos (1+ pos))
+ (setq pos (match-end 0)))))
+ arg)
+
+(defun preview-regenerate (ovr)
+ "Pass the modified region in OVR again through LaTeX."
+ (let ((begin (overlay-start ovr))
+ (end (overlay-end ovr)))
+ (with-current-buffer (overlay-buffer ovr)
+ (preview-delete ovr)
+ (preview-region begin end))))
+
+(defcustom preview-inner-environments '("Bmatrix" "Vmatrix" "aligned"
+ "array" "bmatrix" "cases"
+ "gathered" "matrix" "pmatrix"
+ "smallmatrix" "split"
+ "subarray" "vmatrix")
+ "Environments not to be previewed on their own."
+ :group 'preview-latex
+ :type '(repeat string))
+
+
+(defun preview-next-border (backwards)
+ "Search for the next interesting border for `preview-at-point'.
+Searches backwards if BACKWARDS is non-nil."
+ (let (history preview-state (pt (point)))
+ (catch 'exit
+ (while
+ (null
+ (memq
+ (setq preview-state
+ (if backwards
+ (if (> (setq pt
+ (previous-single-char-property-change
+ pt 'preview-state)) (point-min))
+ (get-char-property (1- pt) 'preview-state)
+ (throw 'exit (or history (point-min))))
+ (if (< (setq pt
+ (next-single-char-property-change
+ pt 'preview-state)) (point-max))
+ (get-char-property pt 'preview-state)
+ (throw 'exit (or history (point-max))))))
+ '(active inactive)))
+ (setq history (and (not preview-state) pt)))
+ (or history pt))))
+
+(defun preview-at-point ()
+ "Do the appropriate preview thing at point.
+If point is positioned on or inside of an unmodified preview area,
+its visibility is toggled.
+
+If not, the surroundings are run through preview. The
+surroundings don't extend into unmodified previews or past
+contiguous previews invalidated by modifications.
+
+Overriding any other action, if a region is
+active (`transient-mark-mode' or `zmacs-regions'), it is run
+through `preview-region'."
+ (interactive)
+ (if (TeX-active-mark)
+ (preview-region (region-beginning) (region-end))
+ (catch 'exit
+ (dolist (ovr (overlays-in (max (point-min) (1- (point)))
+ (min (point-max) (1+ (point)))))
+ (let ((preview-state (overlay-get ovr 'preview-state)))
+ (when preview-state
+ (unless (eq preview-state 'disabled)
+ (preview-toggle ovr 'toggle (selected-window))
+ (throw 'exit t)))))
+ (preview-region (preview-next-border t)
+ (preview-next-border nil)))))
+
+(defun preview-disabled-string (ov)
+ "Generate a before-string for disabled preview overlay OV."
+ (concat (preview-make-clickable
+ (overlay-get ov 'preview-map)
+ preview-icon
+ "\
+%s regenerates preview
+%s more options"
+ `(lambda() (interactive) (preview-regenerate ,ov)))
+;; icon on separate line only for stuff starting on its own line
+ (with-current-buffer (overlay-buffer ov)
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (overlay-start ov))
+ (if (bolp) "\n" ""))))))
+
+(defun preview-disable (ovr)
+ "Change overlay behaviour of OVR after source edits."
+ (overlay-put ovr 'queued nil)
+ (preview-remove-urgentization ovr)
+ (overlay-put ovr 'preview-image nil)
+ (overlay-put ovr 'timestamp nil)
+ (setcdr (overlay-get ovr 'strings) (preview-disabled-string ovr))
+ (preview-toggle ovr)
+ (overlay-put ovr 'preview-state 'disabled)
+ (dolist (filename (overlay-get ovr 'filenames))
+ (condition-case nil
+ (preview-delete-file filename)
+ (file-error nil))
+ (overlay-put ovr 'filenames nil)))
+
+(defun preview-delete (ovr &rest ignored)
+ "Delete preview overlay OVR, taking any associated file along.
+IGNORED arguments are ignored, making this function usable as
+a hook in some cases"
+ (let ((filenames (overlay-get ovr 'filenames)))
+ (overlay-put ovr 'filenames nil)
+ (delete-overlay ovr)
+ (dolist (filename filenames)
+ (condition-case nil
+ (preview-delete-file filename)
+ (file-error nil)))))
+
+(defun preview-clearout (&optional start end timestamp)
+ "Clear out all previews in the current region.
+When called interactively, the current region is used.
+Non-interactively, the region between START and END is
+affected. Those two values default to the borders of
+the entire buffer. If TIMESTAMP is non-nil, previews
+with a `timestamp' property of it are kept."
+ (interactive "r")
+ (dolist (ov (overlays-in (or start (point-min))
+ (or end (point-max))))
+ (and (overlay-get ov 'preview-state)
+ (not (and timestamp
+ (equal timestamp (overlay-get ov 'timestamp))))
+ (preview-delete ov))))
+
+(defun preview-clearout-buffer (&optional buffer)
+ "Clearout BUFFER from previews, current buffer if nil."
+ (interactive)
+ (if buffer
+ (with-current-buffer buffer (preview-clearout))
+ (preview-clearout)))
+
+(defun preview-clearout-section ()
+ "Clearout previews from LaTeX section."
+ (interactive)
+ (save-excursion
+ (LaTeX-mark-section)
+ (preview-clearout (region-beginning) (region-end))))
+
+(defun preview-clearout-at-point ()
+ "Clearout any preview at point."
+ (interactive)
+ (preview-clearout (max (point-min) (1- (point)))
+ (min (point-max) (1+ (point)))))
+
+(defun preview-walk-document (func)
+ "Cycle through all buffers belonging to current document.
+Each buffer having the same master file as the current file
+has FUNC called with its current buffer being set to it."
+ (let* ((buffers (buffer-list))
+ (master (expand-file-name (TeX-master-file t)))
+ (default-buffers (list (current-buffer)
+ (find-buffer-visiting master))))
+ (while buffers
+ (with-current-buffer (pop buffers)
+ (when
+ (or (memq (current-buffer) default-buffers)
+ (and (memq major-mode '(plain-tex-mode latex-mode))
+ (or (stringp TeX-master)
+ (eq TeX-master t))
+ (string= (expand-file-name (TeX-master-file t))
+ master)))
+ (funcall func))))))
+
+(defun preview-clearout-document ()
+ "Clear out all previews in current document.
+The document consists of all buffers that have the same master file
+as the current buffer. This makes the current document lose
+all previews."
+ (interactive)
+ (preview-walk-document #'preview-clearout-buffer))
+
+(defun preview-kill-buffer-cleanup (&optional buf)
+ "This is a cleanup function just for use in hooks.
+Cleans BUF or current buffer. The difference to
+`preview-clearout-buffer' is that previews
+associated with the last buffer modification time are
+kept."
+ (with-current-buffer (or buf (current-buffer))
+ (save-restriction
+ (widen)
+ (preview-clearout (point-min) (point-max) (visited-file-modtime)))))
+
+(add-hook 'kill-buffer-hook #'preview-kill-buffer-cleanup)
+(add-hook 'before-revert-hook #'preview-kill-buffer-cleanup)
+
+(defvar preview-last-counter)
+
+(defun preview-extract-counters (ctr)
+ (setq preview-last-counter
+ (prog1 (copy-sequence ctr)
+ (dolist (elt preview-last-counter)
+ (setq ctr (delete elt ctr)))))
+ (apply #'concat ctr))
+
+(defun desktop-buffer-preview-misc-data (&rest ignored)
+ "Hook function that extracts previews for persistent sessions."
+ (unless (buffer-modified-p)
+ (setq preview-last-counter nil)
+ (save-restriction
+ (widen)
+ (let (save-info (timestamp (visited-file-modtime)))
+ (dolist (ov (sort (overlays-in (point-min) (point-max))
+ (lambda (x y) (< (overlay-start x)
+ (overlay-start y)))))
+ (when (and (memq (overlay-get ov 'preview-state) '(active inactive))
+ (null (overlay-get ov 'queued))
+ (cdr (overlay-get ov 'preview-image)))
+ (push (preview-dissect ov timestamp) save-info)))
+ (and save-info
+ (cons 'preview (cons timestamp (nreverse save-info))))))))
+
+(eval-after-load "desktop"
+ '(add-hook
+ 'desktop-buffer-misc-functions
+ #'desktop-buffer-preview-misc-data))
+
+(defvar preview-temp-dirs nil
+"List of top level temporary directories in use from preview.
+Any directory not in this list will be cleared out by preview
+on first use.")
+
+(defun preview-dissect (ov timestamp)
+ "Extract all persistent data from OV and TIMESTAMP it."
+ (let ((filenames (butlast (nth 0 (overlay-get ov 'filenames)))))
+ (overlay-put ov 'timestamp timestamp)
+ (list (overlay-start ov)
+ (overlay-end ov)
+ (cdr (overlay-get ov 'preview-image))
+ filenames
+ (let ((ctr (overlay-get ov 'preview-counters)))
+ (and ctr
+ (cons (preview-extract-counters (car ctr))
+ (preview-extract-counters (cdr ctr))))))))
+
+(defun preview-buffer-restore-internal (buffer-misc)
+ "Restore previews from BUFFER-MISC if proper.
+Remove them if they have expired."
+ (let ((timestamp (visited-file-modtime)) tempdirlist files)
+ (setq preview-parsed-counters nil)
+ (when (eq 'preview (pop buffer-misc))
+ (preview-get-geometry)
+ (if (equal (pop buffer-misc) timestamp)
+ (dolist (ovdata buffer-misc)
+ (setq tempdirlist
+ (apply #'preview-reinstate-preview tempdirlist
+ timestamp ovdata)))
+ (dolist (ovdata buffer-misc)
+ (setq files (nth 3 ovdata))
+ (condition-case nil
+ (delete-file (nth 0 files))
+ (file-error nil))
+ (unless (member (nth 1 files) tempdirlist)
+ (push (nth 1 files) tempdirlist)))
+ (dolist (dir tempdirlist)
+ (condition-case nil
+ (delete-directory dir)
+ (file-error nil)))))))
+
+
+(defun preview-buffer-restore (buffer-misc)
+ "At end of desktop load, reinstate previews.
+This delay is so that minor modes changing buffer positions
+\(like `x-symbol-mode' does) will not wreak havoc.
+BUFFER-MISC is the appropriate data to be used."
+ (add-hook 'desktop-delay-hook `(lambda ()
+ (with-current-buffer ,(current-buffer)
+ (preview-buffer-restore-internal
+ ',buffer-misc)))))
+
+(defun desktop-buffer-preview (desktop-buffer-file-name
+ desktop-buffer-name
+ desktop-buffer-misc)
+ "Hook function for restoring persistent previews into a buffer."
+ (when (and desktop-buffer-file-name
+ (file-readable-p desktop-buffer-file-name))
+ (let ((buf (find-file-noselect desktop-buffer-file-name)))
+ (if (eq (car desktop-buffer-misc) 'preview)
+ (with-current-buffer buf
+ (preview-buffer-restore desktop-buffer-misc)
+ buf)
+ buf))))
+
+(eval-after-load "desktop"
+ '(if (boundp 'desktop-buffer-mode-handlers)
+ (add-to-list 'desktop-buffer-mode-handlers
+ '(latex-mode . desktop-buffer-preview))
+ (add-hook 'desktop-buffer-handlers '(lambda ()
+ (desktop-buffer-preview
+ desktop-buffer-file-name
+ desktop-buffer-name
+ desktop-buffer-misc)))))
+
+(defcustom preview-auto-cache-preamble 'ask
+ "*Whether to generate a preamble cache format automatically.
+Possible values are nil, t, and `ask'."
+ :group 'preview-latex
+ :type '(choice (const :tag "Cache" t)
+ (const :tag "Don't cache" nil)
+ (const :tag "Ask" ask)))
+
+(defvar preview-dumped-alist nil
+ "Alist of dumped masters.
+The elements are (NAME . ASSOC). NAME is the master file name
+\(without extension), ASSOC is what to do with regard to this
+format. Possible values: NIL means no format is available
+and none should be generated. T means no format is available,
+it should be generated on demand. If the value is a cons cell,
+the CAR of the cons cell is the command with which the format
+has been generated, and the CDR is some Emacs-flavor specific
+value used for maintaining a watch on possible changes of the
+preamble.")
+
+(defun preview-cleanout-tempfiles ()
+ "Clean out all directories and files with non-persistent data.
+This is called as a hook when exiting Emacs."
+ (mapc #'preview-kill-buffer-cleanup (buffer-list))
+ (mapc #'preview-format-kill preview-dumped-alist))
+
+(defun preview-inactive-string (ov)
+ "Generate before-string for an inactive preview overlay OV.
+This is for overlays where the source text has been clicked
+visible. For efficiency reasons it is expected that the buffer
+is already selected and unnarrowed."
+ (concat
+ (preview-make-clickable (overlay-get ov 'preview-map)
+ preview-icon
+ "\
+%s redisplays preview
+%s more options")
+;; icon on separate line only for stuff starting on its own line
+ (with-current-buffer (overlay-buffer ov)
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (overlay-start ov))
+ (if (bolp) "\n" ""))))))
+
+(defun preview-dvipng-place-all ()
+ "Place all images dvipng has created, if any.
+Deletes the dvi file when finished."
+ (let (filename queued oldfiles snippet)
+ (dolist (ov (prog1 preview-gs-queue (setq preview-gs-queue nil)))
+ (when (and (setq queued (overlay-get ov 'queued))
+ (setq snippet (aref (overlay-get ov 'queued) 2))
+ (setq filename (preview-make-filename
+ (format "prev%03d.%s"
+ snippet preview-dvipng-image-type)
+ TeX-active-tempdir)))
+ (if (file-exists-p (car filename))
+ (progn
+ (overlay-put ov 'filenames (list filename))
+ (preview-replace-active-icon
+ ov
+ (preview-create-icon (car filename)
+ preview-dvipng-image-type
+ (preview-ascent-from-bb
+ (aref queued 0))
+ (aref preview-colors 2)))
+ (overlay-put ov 'queued nil))
+ (push filename oldfiles)
+ (overlay-put ov 'filenames nil)
+ (push ov preview-gs-queue))))
+ (if (setq preview-gs-queue (nreverse preview-gs-queue))
+ (progn
+ (preview-start-dvips preview-fast-conversion)
+ (setq TeX-sentinel-function (lambda (process command)
+ (preview-gs-dvips-sentinel
+ process
+ command
+ t)))
+ (dolist (ov preview-gs-queue)
+ (setq snippet (aref (overlay-get ov 'queued) 2))
+ (overlay-put ov 'filenames
+ (list
+ (preview-make-filename
+ (or preview-ps-file
+ (format "preview.%03d" snippet))
+ TeX-active-tempdir))))
+ (while (setq filename (pop oldfiles))
+ (condition-case nil
+ (preview-delete-file filename)
+ (file-error nil))))
+ (condition-case nil
+ (let ((gsfile preview-gs-file))
+ (delete-file
+ (with-current-buffer TeX-command-buffer
+ (funcall (car gsfile) "dvi"))))
+ (file-error nil)))))
+
+(defun preview-active-string (ov)
+ "Generate before-string for active image overlay OV."
+ (preview-make-clickable
+ (overlay-get ov 'preview-map)
+ (car (overlay-get ov 'preview-image))
+ "%s opens text
+%s more options"))
+
+(defun preview-make-filename (file tempdir)
+ "Generate a preview filename from FILE and TEMPDIR.
+Filenames consist of a CONS-cell with absolute file name as CAR
+and TEMPDIR as CDR. TEMPDIR is a copy of `TeX-active-tempdir'
+with the directory name, the reference count and its top directory
+name elements. If FILE is already in that form, the file name itself
+gets converted into a CONS-cell with a name and a reference count."
+ (if (consp file)
+ (progn
+ (if (consp (car file))
+ (setcdr (car file) (1+ (cdr (car file))))
+ (setcar file (cons (car file) 1)))
+ file)
+ (setcar (nthcdr 2 tempdir) (1+ (nth 2 tempdir)))
+ (cons (expand-file-name file (nth 0 tempdir))
+ tempdir)))
+
+(defun preview-attach-filename (attached file)
+ "Attaches the absolute file name ATTACHED to FILE."
+ (if (listp (caar file))
+ (setcar (car file) (cons attached (caar file)))
+ (setcar (car file) (list attached (caar file))))
+ file)
+
+(defun preview-delete-file (file)
+ "Delete a preview FILE.
+See `preview-make-filename' for a description of the data
+structure. If the containing directory becomes empty,
+it gets deleted as well."
+ (let ((filename
+ (if (consp (car file))
+ (and (zerop
+ (setcdr (car file) (1- (cdr (car file)))))
+ (car (car file)))
+ (car file))))
+ (if filename
+ (unwind-protect
+ (if (listp filename)
+ (dolist (elt filename) (delete-file elt))
+ (delete-file filename))
+ (let ((tempdir (cdr file)))
+ (when tempdir
+ (if (> (nth 2 tempdir) 1)
+ (setcar (nthcdr 2 tempdir) (1- (nth 2 tempdir)))
+ (setcdr file nil)
+ (delete-directory (nth 0 tempdir)))))))))
+
+(defvar preview-buffer-has-counters nil)
+(make-variable-buffer-local 'preview-buffer-has-counters)
+
+(defun preview-place-preview (snippet start end
+ box counters tempdir place-opts)
+ "Generate and place an overlay preview image.
+This generates the filename for the preview
+snippet SNIPPET in the current buffer, and uses it for the
+region between START and END. BOX is an optional preparsed
+TeX bounding BOX passed on to the `place' hook.
+COUNTERS is the info about saved counter structures.
+TEMPDIR is a copy of `TeX-active-tempdir'.
+PLACE-OPTS are additional arguments passed into
+`preview-parse-messages'. Returns
+a list with additional info from the placement hook.
+Those lists get concatenated together and get passed
+to the close hook."
+ (preview-clearout start end tempdir)
+ (let ((ov (make-overlay start end nil nil nil)))
+ (when (fboundp 'TeX-overlay-prioritize)
+ (overlay-put ov 'priority (TeX-overlay-prioritize start end)))
+ (overlay-put ov 'preview-map
+ (preview-make-clickable
+ nil nil nil
+ `(lambda(event) (interactive "e")
+ (preview-toggle ,ov 'toggle event))
+ `(lambda(event) (interactive "e")
+ (preview-context-menu ,ov event))))
+ (overlay-put ov 'timestamp tempdir)
+ (when (cdr counters)
+ (overlay-put ov 'preview-counters counters)
+ (setq preview-buffer-has-counters t))
+ (prog1 (apply #'preview-call-hook 'place ov snippet box
+ place-opts)
+ (overlay-put ov 'strings
+ (list (preview-active-string ov)))
+ (preview-toggle ov t))))
+
+;; The following is a brutal hack. It relies on `begin' being let to
+;; the start of the interesting area when TeX-region-create is being
+;; called.
+
+(defun preview-counter-find (begin)
+ "Fetch the next preceding or next preview-counters property.
+Factored out because of compatibility macros XEmacs would
+not use in advice."
+ ;; The following two lines are bug workaround for Emacs < 22.1.
+ (if (markerp begin)
+ (setq begin (marker-position begin)))
+ (or (car (get-char-property begin 'preview-counters))
+ (cdr (get-char-property (max (point-min)
+ (1- begin))
+ 'preview-counters))
+ (cdr (get-char-property
+ (max (point-min)
+ (1- (previous-single-char-property-change
+ begin
+ 'preview-counters)))
+ 'preview-counters))
+ (car (get-char-property
+ (next-single-char-property-change begin 'preview-counters)
+ 'preview-counters))))
+
+(defadvice TeX-region-create (around preview-counters)
+ "Write out counter information to region."
+ (let ((TeX-region-extra
+ (concat
+ (and (boundp 'begin)
+ preview-buffer-has-counters
+ (mapconcat
+ #'identity
+ (cons
+ ""
+ (preview-counter-find (symbol-value 'begin)))
+ "\\setcounter"))
+ TeX-region-extra)))
+ ad-do-it))
+
+(defun preview-reinstate-preview (tempdirlist timestamp start end
+ image filename &optional counters)
+ "Reinstate a single preview.
+This gets passed TEMPDIRLIST, a list consisting of the kind
+of entries used in `TeX-active-tempdir', and TIMESTAMP, the
+time stamp under which the file got read in. It returns an augmented
+list. START and END give the buffer location where the preview
+is to be situated, IMAGE the image to place there, and FILENAME
+the file to use: a triple consisting of filename, its temp directory
+and the corresponding topdir. COUNTERS is saved counter information,
+if any."
+ (when
+ (or (null filename) (file-readable-p (car filename)))
+ (when filename
+ (unless (equal (nth 1 filename) (car TeX-active-tempdir))
+ (setq TeX-active-tempdir
+ (or (assoc (nth 1 filename) tempdirlist)
+ (car (push (append (cdr filename) (list 0))
+ tempdirlist))))
+ (setcar (cdr TeX-active-tempdir)
+ (car (or (member (nth 1 TeX-active-tempdir)
+ preview-temp-dirs)
+ (progn
+ (add-hook 'kill-emacs-hook
+ #'preview-cleanout-tempfiles t)
+ (push (nth 1 TeX-active-tempdir)
+ preview-temp-dirs))))))
+ (setcar (nthcdr 2 TeX-active-tempdir)
+ (1+ (nth 2 TeX-active-tempdir)))
+ (setcdr filename TeX-active-tempdir)
+ (setq filename (list filename)))
+ (let ((ov (make-overlay start end nil nil nil)))
+ (when (fboundp 'TeX-overlay-prioritize)
+ (overlay-put ov 'priority (TeX-overlay-prioritize start end)))
+ (overlay-put ov 'preview-map
+ (preview-make-clickable
+ nil nil nil
+ `(lambda(event) (interactive "e")
+ (preview-toggle ,ov 'toggle event))
+ `(lambda(event) (interactive "e")
+ (preview-context-menu ,ov event))))
+ (when counters
+ (overlay-put
+ ov 'preview-counters
+ (cons
+ (mapcar #'cdr
+ (if (string= (car counters) "")
+ preview-parsed-counters
+ (setq preview-parsed-counters
+ (preview-parse-counters (car counters)))))
+ (mapcar #'cdr
+ (if (string= (cdr counters) "")
+ preview-parsed-counters
+ (setq preview-parsed-counters
+ (preview-parse-counters (cdr counters)))))))
+ (setq preview-buffer-has-counters t))
+ (overlay-put ov 'filenames filename)
+ (overlay-put ov 'preview-image (cons (preview-import-image image)
+ image))
+ (overlay-put ov 'strings
+ (list (preview-active-string ov)))
+ (overlay-put ov 'timestamp timestamp)
+ (preview-toggle ov t)))
+ tempdirlist)
+
+(defun preview-back-command (&optional nocomplex)
+ "Move backward a TeX token.
+If NOCOMPLEX is set, only basic tokens and no argument sequences
+will be skipped over backwards."
+ (let ((oldpos (point)) oldpoint)
+ (condition-case nil
+ (or (search-backward-regexp "\\(\\$\\$?\
+\\|\\\\[^a-zA-Z@]\
+\\|\\\\[a-zA-Z@]+\
+\\|\\\\begin[ \t]*{[^}]+}\
+\\)\\=" (line-beginning-position) t)
+ nocomplex
+ (if (eq ?\) (char-syntax (char-before)))
+ (while
+ (progn
+ (setq oldpoint (point))
+ (backward-sexp)
+ (and (not (eq oldpoint (point)))
+ (eq ?\( (char-syntax (char-after))))))
+ (backward-char)))
+ (error (goto-char oldpos)))))
+
+(defcustom preview-required-option-list '("active" "tightpage" "auctex"
+ (preview-preserve-counters
+ "counters"))
+ "Specifies required options passed to the preview package.
+These are passed regardless of whether there is an explicit
+\\usepackage of that package present."
+ :group 'preview-latex
+ :type preview-expandable-string)
+
+(defcustom preview-preserve-counters nil
+ "Try preserving counters for partial runs if set."
+ :group 'preview-latex
+ :type 'boolean)
+
+(defcustom preview-default-option-list '("displaymath" "floats"
+ "graphics" "textmath" "sections"
+ "footnotes")
+ "*Specifies default options to pass to preview package.
+These options are only used when the LaTeX document in question does
+not itself load the preview package, namely when you use preview
+on a document not configured for preview. \"auctex\", \"active\",
+\"dvips\" and \"delayed\" need not be specified here."
+ :group 'preview-latex
+ :type '(list (set :inline t :tag "Options known to work"
+ :format "%t:\n%v%h" :doc
+ "The above options are all the useful ones
+at the time of the release of this package.
+You should not need \"Other options\" unless you
+upgraded to a fancier version of just the LaTeX style.
+Please also note that `psfixbb' fails to have an effect if
+`preview-fast-conversion' or `preview-prefer-TeX-bb'
+are selected."
+ (const "displaymath")
+ (const "floats")
+ (const "graphics")
+ (const "textmath")
+ (const "sections")
+ (const "footnotes")
+ (const "showlabels")
+ (const "psfixbb"))
+ (set :tag "Expert options" :inline t
+ :format "%t:\n%v%h" :doc
+ "Expert options should not be enabled permanently."
+ (const "noconfig")
+ (const "showbox")
+ (const "tracingall"))
+ (repeat :inline t :tag "Other options" (string))))
+
+(defcustom preview-default-preamble
+ '("\\RequirePackage[" ("," . preview-default-option-list)
+ "]{preview}[2004/11/05]")
+ "*Specifies default preamble code to add to a LaTeX document.
+If the document does not itself load the preview package, that is,
+when you use preview on a document not configured for preview, this
+list of LaTeX commands is inserted just before \\begin{document}."
+ :group 'preview-latex
+ :type preview-expandable-string)
+
+(defcustom preview-LaTeX-command '("%`%l \"\\nonstopmode\\nofiles\
+\\PassOptionsToPackage{" ("," . preview-required-option-list) "}{preview}\
+\\AtBeginDocument{\\ifx\\ifPreview\\undefined"
+preview-default-preamble "\\fi}\"%' %t")
+ "*Command used for starting a preview.
+See description of `TeX-command-list' for details."
+ :group 'preview-latex
+ :type preview-expandable-string)
+
+(defun preview-goto-info-page ()
+ "Read documentation for preview-latex in the info system."
+ (interactive)
+ (info "(preview-latex)"))
+
+(eval-after-load 'info '(add-to-list 'Info-file-list-for-emacs
+ '("preview" . "preview-latex")))
+
+(defvar preview-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "\C-p" #'preview-at-point)
+ (define-key map "\C-r" #'preview-region)
+ (define-key map "\C-b" #'preview-buffer)
+ (define-key map "\C-d" #'preview-document)
+ (define-key map "\C-f" #'preview-cache-preamble)
+ (define-key map "\C-c\C-f" #'preview-cache-preamble-off)
+ (define-key map "\C-i" #'preview-goto-info-page)
+ ;; (define-key map "\C-q" #'preview-paragraph)
+ (define-key map "\C-e" #'preview-environment)
+ (define-key map "\C-s" #'preview-section)
+ (define-key map "\C-w" #'preview-copy-region-as-mml)
+ (define-key map "\C-c\C-p" #'preview-clearout-at-point)
+ (define-key map "\C-c\C-r" #'preview-clearout)
+ (define-key map "\C-c\C-s" #'preview-clearout-section)
+ (define-key map "\C-c\C-b" #'preview-clearout-buffer)
+ (define-key map "\C-c\C-d" #'preview-clearout-document)
+ map))
+
+(defun preview-copy-text (ov)
+ "Copy the text of OV into the kill buffer."
+ (save-excursion
+ (set-buffer (overlay-buffer ov))
+ (copy-region-as-kill (overlay-start ov) (overlay-end ov))))
+
+(defun preview-copy-mml (ov)
+ "Copy an MML representation of OV into the kill buffer.
+This can be used to send inline images in mail and news when
+using MML mode."
+ (when (catch 'badcolor
+ (let ((str (car (preview-format-mml ov))))
+ (if str
+ (if (eq last-command 'kill-region)
+ (kill-append str nil)
+ (kill-new str))
+ (error "No image file available")))
+ nil)
+ (let (preview-transparent-border)
+ (preview-regenerate ov))))
+
+(defun preview-copy-region-as-mml (start end)
+ (interactive "r")
+ (when (catch 'badcolor
+ (let (str lst dont-ask)
+ (dolist (ov (overlays-in start end))
+ (when (setq str (preview-format-mml ov dont-ask))
+ (setq dont-ask (cdr str))
+ (and
+ (>= (overlay-start ov) start)
+ (<= (overlay-end ov) end)
+ (push (list (- (overlay-start ov) start)
+ (- (overlay-end ov) start)
+ (car str)) lst))))
+ (setq str (buffer-substring start end))
+ (dolist (elt (nreverse (sort lst #'car-less-than-car)))
+ (setq str (concat (substring str 0 (nth 0 elt))
+ (nth 2 elt)
+ (substring str (nth 1 elt)))))
+ (if (eq last-command 'kill-region)
+ (kill-append str nil)
+ (kill-new str)))
+ nil)
+ (let (preview-transparent-border)
+ (preview-region start end))))
+
+(autoload 'mailcap-extension-to-mime "mailcap")
+
+(defun preview-format-mml (ov &optional dont-ask)
+ "Return an MML representation of OV as string.
+This can be used to send inline images in mail and news when
+using MML mode. If there is nothing current available,
+NIL is returned. If the image has a colored border and the
+user wants it removed when asked (unless DONT-ASK is set),
+'badcolor is thrown a t. The MML is returned in the car of the
+result, DONT-ASK in the cdr."
+ (and (memq (overlay-get ov 'preview-state) '(active inactive))
+ (not (overlay-get ov 'queued))
+ (let* ((text (with-current-buffer (overlay-buffer ov)
+ (buffer-substring (overlay-start ov)
+ (overlay-end ov))))
+ (image (cdr (overlay-get ov 'preview-image)))
+ file type)
+ (cond ((consp image)
+ (and (not dont-ask)
+ (nth 3 image)
+ (if (y-or-n-p "Replace colored borders? ")
+ (throw 'badcolor t)
+ (setq dont-ask t)))
+ (setq file (car (car (last (overlay-get ov 'filenames))))
+ type (mailcap-extension-to-mime
+ (file-name-extension file)))
+ (cons
+ (format "<#part %s
+description=\"%s\"
+filename=%s>
+<#/part>"
+ (if type
+ (format "type=\"%s\" disposition=inline" type)
+ "disposition=attachment")
+ (if (string-match "[\n\"]" text)
+ "preview-latex image"
+ text)
+ (if (string-match "[ \n<>]" file)
+ (concat "\"" file "\"")
+ file))
+ dont-ask))
+ ((stringp image)
+ (cons image dont-ask))))))
+
+(defun preview-active-contents (ov)
+ "Check whether we have a valid image associated with OV."
+ (and (memq (overlay-get ov 'preview-state) '(active inactive)) t))
+
+(defun preview-context-menu (ov ev)
+ "Pop up a menu for OV at position EV."
+ (popup-menu
+ `("Preview"
+ ["Toggle" (preview-toggle ,ov 'toggle ',ev)
+ (preview-active-contents ,ov)]
+ ["Regenerate" (preview-regenerate ,ov)]
+ ["Remove" (preview-delete ,ov)]
+ ["Copy text" (preview-copy-text ,ov)]
+ ["Copy MIME" (preview-copy-mml ,ov)
+ (preview-active-contents ,ov)])
+ ev))
+
+(defvar preview-TeX-style-dir)
+
+(defun preview-TeX-style-cooked ()
+ "Return `preview-TeX-style-dir' in cooked form.
+This will be fine for prepending to a `TEXINPUT' style
+environment variable, including an initial `.' at the front."
+ (if (or (zerop (length preview-TeX-style-dir))
+ (member (substring preview-TeX-style-dir -1) '(";" ":")))
+ preview-TeX-style-dir
+ (let ((sep
+ (cond
+ ((stringp TeX-kpathsea-path-delimiter)
+ TeX-kpathsea-path-delimiter)
+ ((string-match
+ "\\`.[:]"
+ (if (file-name-absolute-p preview-TeX-style-dir)
+ preview-TeX-style-dir
+ (expand-file-name preview-TeX-style-dir)))
+ ";")
+ (t ":"))))
+ (concat "." sep preview-TeX-style-dir sep))))
+
+(defun preview-set-texinputs (&optional remove)
+ "Add `preview-TeX-style-dir' into `TEXINPUTS' variables.
+With prefix argument REMOVE, remove it again."
+ (interactive "P")
+ (let ((case-fold-search nil)
+ (preview-TeX-style-dir (preview-TeX-style-cooked))
+ pattern)
+ (if remove
+ (progn
+ (setq pattern (concat "\\`\\(TEXINPUTS[^=]*\\)=\\(.*\\)"
+ (regexp-quote preview-TeX-style-dir)))
+ (dolist (env (copy-sequence process-environment))
+ (if (string-match pattern env)
+ (setenv (match-string 1 env)
+ (and (or (< (match-beginning 2) (match-end 2))
+ (< (match-end 0) (length env)))
+ (concat (match-string 2 env)
+ (substring env (match-end 0))))))))
+ (setq pattern (regexp-quote preview-TeX-style-dir))
+ (dolist (env (cons "TEXINPUTS=" (copy-sequence process-environment)))
+ (if (string-match "\\`\\(TEXINPUTS[^=]*\\)=" env)
+ (unless (string-match pattern env)
+ (setenv (match-string 1 env)
+ (concat preview-TeX-style-dir
+ (substring env (match-end 0))))))))))
+
+(defcustom preview-TeX-style-dir nil
+ "This variable contains the location of uninstalled TeX styles.
+If this is nil, the preview styles are considered to be part of
+the installed TeX system.
+
+Otherwise, it can either just specify an absolute directory, or
+it can be a complete TEXINPUTS specification. If it is the
+latter, it has to be followed by the character with which
+kpathsea separates path components, either `:' on Unix-like
+systems, or `;' on Windows-like systems. And it should be
+preceded with .: or .; accordingly in order to have . first in
+the search path.
+
+The `TEXINPUT' environment type variables will get this prepended
+at load time calling \\[preview-set-texinputs] to reflect this.
+You can permanently install the style files using
+\\[preview-install-styles].
+
+Don't set this variable other than with customize so that its
+changes get properly reflected in the environment."
+ :group 'preview-latex
+ :set (lambda (var value)
+ (and (boundp var)
+ (symbol-value var)
+ (preview-set-texinputs t))
+ (set var value)
+ (and (symbol-value var)
+ (preview-set-texinputs)))
+ :type '(choice (const :tag "Installed" nil)
+ (string :tag "Style directory or TEXINPUTS path")))
+
+;;;###autoload
+(defun preview-install-styles (dir &optional force-overwrite
+ force-save)
+ "Installs the TeX style files into a permanent location.
+This must be in the TeX search path. If FORCE-OVERWRITE is greater
+than 1, files will get overwritten without query, if it is less
+than 1 or nil, the operation will fail. The default of 1 for interactive
+use will query.
+
+Similarly FORCE-SAVE can be used for saving
+`preview-TeX-style-dir' to record the fact that the uninstalled
+files are no longer needed in the search path."
+ (interactive "DPermanent location for preview TeX styles
+pp")
+ (unless preview-TeX-style-dir
+ (error "Styles are already installed"))
+ (dolist (file (or
+ (condition-case nil
+ (directory-files
+ (progn
+ (string-match
+ "\\`\\(\\.[:;]\\)?\\(.*?\\)\\([:;]\\)?\\'"
+ preview-TeX-style-dir)
+ (match-string 2 preview-TeX-style-dir))
+ t "\\.\\(sty\\|def\\|cfg\\)\\'")
+ (error nil))
+ (error "Can't find files to install")))
+ (copy-file file dir (cond ((eq force-overwrite 1) 1)
+ ((numberp force-overwrite)
+ (> force-overwrite 1))
+ (t force-overwrite))))
+ (if (cond ((eq force-save 1)
+ (y-or-n-p "Stop using non-installed styles permanently "))
+ ((numberp force-save)
+ (> force-save 1))
+ (t force-save))
+ (customize-save-variable 'preview-TeX-style-dir nil)
+ (customize-set-variable 'preview-TeX-style-dir nil)))
+
+;;;###autoload
+(defun LaTeX-preview-setup ()
+ "Hook function for embedding the preview package into AUCTeX.
+This is called by `LaTeX-mode-hook' and changes AUCTeX variables
+to add the preview functionality."
+ (remove-hook 'LaTeX-mode-hook #'LaTeX-preview-setup)
+ (add-hook 'LaTeX-mode-hook #'preview-mode-setup)
+ (define-key LaTeX-mode-map "\C-c\C-p" preview-map)
+ (easy-menu-define preview-menu LaTeX-mode-map
+ "This is the menu for preview-latex."
+ '("Preview"
+ "Generate previews"
+ ["(or toggle) at point" preview-at-point]
+ ["for environment" preview-environment]
+ ["for section" preview-section]
+ ["for region" preview-region (preview-mark-active)]
+ ["for buffer" preview-buffer]
+ ["for document" preview-document]
+ "---"
+ "Remove previews"
+ ["at point" preview-clearout-at-point]
+ ["from section" preview-clearout-section]
+ ["from region" preview-clearout (preview-mark-active)]
+ ["from buffer" preview-clearout-buffer]
+ ["from document" preview-clearout-document]
+ "---"
+ "Turn preamble cache"
+ ["on" preview-cache-preamble]
+ ["off" preview-cache-preamble-off]
+ "---"
+ ("Customize"
+ ["Browse options"
+ (customize-group 'preview)]
+ ["Extend this menu"
+ (easy-menu-add-item
+ nil '("Preview")
+ (customize-menu-create 'preview))])
+ ["Read documentation" preview-goto-info-page]
+ ["Report Bug" preview-report-bug]))
+ (if (eq major-mode 'latex-mode)
+ (preview-mode-setup))
+ (if (boundp 'desktop-buffer-misc)
+ (preview-buffer-restore desktop-buffer-misc)))
+
+(defun preview-clean-subdir (dir)
+ "Cleans out a temporary DIR with preview image files."
+ (condition-case err
+ (progn
+ (mapc #'delete-file
+ (directory-files dir t "\\`pr" t))
+ (delete-directory dir))
+ (error (message "Deletion of `%s' failed: %s" dir
+ (error-message-string err)))))
+
+(defun preview-clean-topdir (topdir)
+ "Cleans out TOPDIR from temporary directories.
+This does not erase the directory itself since its permissions
+might be needed for colloborative work on common files."
+ (mapc #'preview-clean-subdir
+ (condition-case nil
+ (directory-files topdir t "\\`tmp" t)
+ (file-error nil))))
+
+(defun preview-create-subdirectory ()
+ "Create a temporary subdir for the current TeX process.
+If necessary, generates a fitting top
+directory or cleans out an existing one (if not yet
+visited in this session), then returns the name of
+the created subdirectory relative to the master directory,
+in shell-quoted form. `TeX-active-tempdir' is
+set to the corresponding TEMPDIR descriptor as described
+in `preview-make-filename'. The directory is registered
+in `preview-temp-dirs' in order not to be cleaned out
+later while in use."
+ (let ((topdir (expand-file-name (TeX-active-master "prv"))))
+ (if (file-directory-p topdir)
+ (unless (member topdir preview-temp-dirs)
+ ;; Cleans out the top preview directory by
+ ;; removing subdirs possibly left from a previous session.
+ (preview-clean-topdir topdir)
+ (push topdir preview-temp-dirs))
+ (make-directory topdir)
+ (add-to-list 'preview-temp-dirs topdir))
+ (add-hook 'kill-emacs-hook #'preview-cleanout-tempfiles t)
+ (setq TeX-active-tempdir
+ (list (make-temp-file (expand-file-name
+ "tmp" (file-name-as-directory topdir)) t)
+ topdir
+ 0))
+ (shell-quote-argument
+ (concat (file-name-as-directory (file-name-nondirectory topdir))
+ (file-name-nondirectory (nth 0 TeX-active-tempdir))))))
+
+;; Hook into TeX immediately if it's loaded, use LaTeX-mode-hook if not.
+(if (featurep 'latex)
+ (LaTeX-preview-setup)
+ (add-hook 'LaTeX-mode-hook #'LaTeX-preview-setup))
+
+;;;###autoload (add-hook 'LaTeX-mode-hook #'LaTeX-preview-setup)
+
+(defun preview-parse-counters (string)
+ "Extract counter information from STRING."
+ (let ((list preview-parsed-counters) (pos 0))
+ (while (eq pos (string-match " *\\({\\([^{}]+\\)}{[-0-9]+}\\)" string pos))
+ (setcdr (or (assoc (match-string 2 string) list)
+ (car (push (list (match-string 2 string)) list)))
+ (match-string 1 string))
+ (setq pos (match-end 1)))
+ list))
+
+(defun preview-parse-tightpage (string)
+ "Build tightpage vector from STRING,"
+ (read (concat "[" string "]")))
+
+(defvar preview-parse-variables
+ '(("Fontsize" preview-parsed-font-size
+ "\\` *\\([0-9.]+\\)pt\\'" 1 string-to-number)
+ ("Magnification" preview-parsed-magnification
+ "\\` *\\([0-9]+\\)\\'" 1 string-to-number)
+ ("PDFoutput" preview-parsed-pdfoutput
+ "" 0 stringp)
+ ("Counters" preview-parsed-counters
+ ".*" 0 preview-parse-counters)
+ ("Tightpage" preview-parsed-tightpage
+ "\\` *\\(-?[0-9]+ *\\)\\{4\\}\\'" 0 preview-parse-tightpage)))
+
+(defun preview-error-quote (string run-coding-system)
+ "Turn STRING with potential ^^ sequences into a regexp.
+To preserve sanity, additional ^ prefixes are matched literally,
+so the character represented by ^^^ preceding extended characters
+will not get matched, usually."
+ (let (output case-fold-search)
+ (when (featurep 'mule)
+ (setq string (encode-coding-string string run-coding-system)))
+ (while (string-match "\\^\\{2,\\}\\(\\([@-_?]\\)\\|[8-9a-f][0-9a-f]\\)"
+ string)
+ (setq output
+ (concat output
+ (regexp-quote (substring string
+ 0
+ (- (match-beginning 1) 2)))
+ (if (match-beginning 2)
+ (concat
+ "\\(?:" (regexp-quote
+ (substring string
+ (- (match-beginning 1) 2)
+ (match-end 0)))
+ "\\|"
+ (char-to-string
+ (logxor (aref string (match-beginning 2)) 64))
+ "\\)")
+ (char-to-string
+ (string-to-number (match-string 1 string) 16))))
+ string (substring string (match-end 0))))
+ (setq output (concat output (regexp-quote string)))
+ (if (featurep 'mule)
+ (decode-coding-string output
+ (or (and (boundp 'TeX-japanese-process-output-coding-system)
+ TeX-japanese-process-output-coding-system)
+ buffer-file-coding-system))
+ output)))
+
+(defun preview-parse-messages (open-closure)
+ "Turn all preview snippets into overlays.
+This parses the pseudo error messages from the preview
+document style for LaTeX. OPEN-CLOSURE is called once
+it is certain that we have a valid output file, and it has
+to return in its CAR the PROCESS parameter for the CLOSE
+call, and in its CDR the final stuff for the placement hook."
+ (with-temp-message "locating previews..."
+ (let (TeX-error-file TeX-error-offset snippet box counters
+ file line
+ (lsnippet 0) lstart (lfile "") lline lbuffer lpoint
+ lcounters
+ string after-string error context-start
+ context offset
+ parsestate (case-fold-search nil)
+ (run-buffer (current-buffer))
+ (run-coding-system preview-coding-system)
+ (run-directory default-directory)
+ tempdir
+ close-data
+ open-data
+ fast-hook
+ slow-hook)
+ ;; clear parsing variables
+ (dolist (var preview-parse-variables)
+ (set (nth 1 var) nil))
+ (goto-char (point-min))
+ (unwind-protect
+ (progn
+ (while
+ (re-search-forward "\
+^\\(!\\|\\(.*?\\):[0-9]+:\\) \\|\
+\(\\(/*\
+\\(?:\\.+[^()\r\n{} /]*\\|[^()\r\n{} ./]+\
+\\(?: [^()\r\n{} ./]+\\)*\\(?:\\.[-0-9a-zA-Z_.]*\\)?\\)\
+\\(?:/+\\(?:\\.+[^()\r\n{} /]*\\|[^()\r\n{} ./]+\
+\\(?: [^()\r\n{} ./]+\\)*\\(?:\\.[-0-9a-zA-Z_.]*\\)?\\)?\\)*\\)\
+)*\\(?: \\|\r?$\\)\\|\
+\\()+\\)\\|\
+ !\\(?:offset(\\([---0-9]+\\))\\|\
+name(\\([^)]+\\))\\)\\|\
+^Preview: \\([a-zA-Z]+\\) \\([^\n\r]*\\)\r?$" nil t)
+;;; Ok, here is a line by line breakdown:
+;;; match-alternative 1:
+;;; error indicator for TeX error, either style.
+;;; match-alternative 2:
+;;; The same, but file-line-error-style, matching on file name.
+;;; match-alternative 3:
+;;; Too ugly to describe in detail. In short, we try to catch file
+;;; names built from path components that don't contain spaces or
+;;; other special characters once the file extension has started.
+;;;
+;;; Position for searching immediately after the file name so as to
+;;; not miss closing parens or something.
+;;; (match-string 3) is the file name.
+;;; match-alternative 4:
+;;; )+\( \|$\)
+;;; a closing paren followed by the end of line or a space: a just
+;;; closed file.
+;;; match-alternative 5 (wrapped into one shy group with
+;;; match-alternative 6, so that the match on first char is slightly
+;;; faster):
+;;; !offset(\([---0-9]+\))
+;;; an AUCTeX offset message. (match-string 5) is the offset itself
+;;; !name(\([^)]+\))
+;;; an AUCTeX file name message. (match-string 6) is the file name
+;;; TODO: Actually, the latter two should probably again match only
+;;; after a space or newline, since that it what \message produces.
+;;;disabled in prauctex.def:
+;;;\(?:Ov\|Und\)erfull \\.*[0-9]*--[0-9]*
+;;;\(?:.\{79\}
+;;;\)*.*$\)\|
+;;; This would have caught overfull box messages that consist of
+;;; several lines of context all with 79 characters in length except
+;;; of the last one. prauctex.def kills all such messages.
+ (setq file (match-string-no-properties 2))
+ (cond
+ ((match-beginning 1)
+ (if (looking-at "\
+\\(?:Preview\\|Package Preview Error\\): Snippet \\([---0-9]+\\) \\(started\\|ended\\(\
+\\.? *(\\([---0-9]+\\)\\+\\([---0-9]+\\)x\\([---0-9]+\\))\\)?\\)\\.")
+ (progn
+ (when file
+ (unless TeX-error-file
+ (push nil TeX-error-file)
+ (push nil TeX-error-offset))
+ (unless (car TeX-error-offset)
+ (rplaca TeX-error-file file)))
+ (setq snippet (string-to-number (match-string 1))
+ box (unless
+ (string= (match-string 2) "started")
+ (if (match-string 4)
+ (mapcar #'(lambda (x)
+ (* (preview-get-magnification)
+ (string-to-number x)))
+ (list
+ (match-string 4)
+ (match-string 5)
+ (match-string 6)))
+ t))
+ counters (mapcar #'cdr preview-parsed-counters)
+ error (progn
+ (setq lpoint (point))
+ (end-of-line)
+ (buffer-substring lpoint (point)))
+
+ ;; And the context for the help window.
+ context-start (point)
+
+ ;; And the line number to position the cursor.
+;;; variant 1: profiling seems to indicate the regexp-heavy solution
+;;; to be favorable. Removing incomplete characters from the error
+;;; context is an absolute nuisance.
+ line (and (re-search-forward "\
+^l\\.\\([0-9]+\\) \\(\\.\\.\\.\\(?:\\^*\\(?:[89a-f][0-9a-f]\\|[]@-\\_?]\\)\\|\
+\[0-9a-f]?\\)\\)?\\([^\n\r]*?\\)\r?
+\\([^\n\r]*?\\)\\(\\(?:\\^+[89a-f]?\\)?\\.\\.\\.\\)?\r?$" nil t)
+ (string-to-number (match-string 1)))
+ ;; And a string of the context to search for.
+ string (and line (match-string 3))
+ after-string (and line (buffer-substring
+ (+ (match-beginning 4)
+ (- (match-end 3)
+ (match-beginning 0)))
+ (match-end 4)))
+
+ ;; And we have now found to the end of the context.
+ context (buffer-substring context-start (point))
+ ;; We may use these in another buffer.
+ offset (or (car TeX-error-offset) 0)
+ file (car TeX-error-file))
+ (when (and (stringp file)
+ (or (string= file "<none>")
+ (TeX-match-extension file)))
+ ;; if we are the first time round, check for fast hooks:
+ (when (null parsestate)
+ (setq open-data
+ (save-excursion (funcall open-closure))
+ tempdir TeX-active-tempdir)
+ (dolist
+ (lst (if (listp TeX-translate-location-hook)
+ TeX-translate-location-hook
+ (list TeX-translate-location-hook)))
+ (let ((fast
+ (and (symbolp lst)
+ (get lst 'TeX-translate-via-list))))
+ (if fast
+ (setq fast-hook
+ (nconc fast-hook (list fast)))
+ (setq slow-hook
+ (nconc slow-hook (list lst)))))))
+ (condition-case err
+ (save-excursion (run-hooks 'slow-hook))
+ (error (preview-log-error err "Translation hook")))
+ (push (vector file (+ line offset)
+ string after-string
+ snippet box counters) parsestate)))
+ ;; else normal error message
+ (forward-line)
+ (re-search-forward "^l\\.[0-9]" nil t)
+ (forward-line 2)))
+ ((match-beginning 3)
+ ;; New file -- Push on stack
+ (push (match-string-no-properties 3) TeX-error-file)
+ (push nil TeX-error-offset)
+ (goto-char (match-end 3)))
+ ((match-beginning 4)
+ ;; End of file -- Pop from stack
+ (when (> (length TeX-error-file) 1)
+ (pop TeX-error-file)
+ (pop TeX-error-offset))
+ (goto-char (1+ (match-beginning 0))))
+ ((match-beginning 5)
+ ;; Hook to change line numbers
+ (setq TeX-error-offset
+ (list (string-to-number (match-string 5)))))
+ ((match-beginning 6)
+ ;; Hook to change file name
+ (setq TeX-error-file (list (match-string-no-properties 6))))
+ ((match-beginning 7)
+ (let ((var
+ (assoc (match-string-no-properties 7)
+ preview-parse-variables))
+ (offset (- (match-beginning 0) (match-beginning 8)))
+ (str (match-string-no-properties 8)))
+ ;; paste together continuation lines:
+ (while (= (- (length str) offset) 79)
+ (search-forward-regexp "^\\([^\n\r]*\\)\r?$")
+ (setq offset (- (length str))
+ str (concat str (match-string-no-properties 1))))
+ (when (and var
+ (string-match (nth 2 var) str))
+ (set (nth 1 var)
+ (funcall (nth 4 var)
+ (match-string-no-properties
+ (nth 3 var)
+ str))))))))
+ (when (null parsestate)
+ (error "LaTeX found no preview images")))
+ (unwind-protect
+ (save-excursion
+ (setq parsestate (nreverse parsestate))
+ (condition-case err
+ (dolist (fun fast-hook)
+ (setq parsestate
+ (save-excursion (funcall fun parsestate))))
+ (error (preview-log-error err "Fast translation hook")))
+ (setq snippet 0)
+ (dolist (state parsestate)
+ (setq lsnippet snippet
+ file (aref state 0)
+ line (aref state 1)
+ string (aref state 2)
+ after-string (aref state 3)
+ snippet (aref state 4)
+ box (aref state 5)
+ counters (aref state 6))
+ (unless (string= lfile file)
+ (set-buffer (if (string= file "<none>")
+ (with-current-buffer run-buffer
+ TeX-command-buffer)
+ (find-file-noselect
+ (expand-file-name file run-directory))))
+ (setq lfile file))
+ (save-excursion
+ (save-restriction
+ (widen)
+ ;; a fast hook might have positioned us already:
+ (if (number-or-marker-p string)
+ (progn
+ (goto-char string)
+ (setq lpoint
+ (if (number-or-marker-p after-string)
+ after-string
+ (line-beginning-position))))
+ (if (and (eq (current-buffer) lbuffer)
+ (<= lline line))
+ ;; while Emacs does the perfectly correct
+ ;; thing even when when the line differences
+ ;; get zero or negative, I don't trust this
+ ;; to be universally the case across other
+ ;; implementations. Besides, if the line
+ ;; number gets smaller again, we are probably
+ ;; rereading the file, and restarting from
+ ;; the beginning will probably be faster.
+ (progn
+ (goto-char lpoint)
+ (if (/= lline line)
+ (if (eq selective-display t)
+ (re-search-forward "[\n\C-m]" nil
+ 'end
+ (- line lline))
+ (forward-line (- line lline)))))
+ (goto-line line))
+ (setq lpoint (point))
+ (cond
+ ((search-forward (concat string after-string)
+ (line-end-position) t)
+ (backward-char (length after-string)))
+ ;;ok, transform ^^ sequences
+ ((search-forward-regexp
+ (concat "\\("
+ (setq string
+ (preview-error-quote
+ string
+ run-coding-system))
+ "\\)"
+ (setq after-string
+ (preview-error-quote
+ after-string
+ run-coding-system)))
+ (line-end-position) t)
+ (goto-char (match-end 1)))
+ ((search-forward-regexp
+ (concat "\\("
+ (if (string-match
+ "^[^\0-\177]\\{1,6\\}" string)
+ (setq string
+ (substring string (match-end 0)))
+ string)
+ "\\)"
+ (if (string-match
+ "[^\0-\177]\\{1,6\\}$" after-string)
+ (setq after-string
+ (substring after-string
+ 0 (match-beginning 0)))))
+ (line-end-position) t)
+ (goto-char (match-end 1)))
+ (t (search-forward-regexp
+ string
+ (line-end-position) t))))
+ (setq lline line
+ lbuffer (current-buffer))
+ (if box
+ (progn
+ (if (and lstart (= snippet lsnippet))
+ (setq close-data
+ (nconc
+ (preview-place-preview
+ snippet
+ (save-excursion
+ (preview-back-command
+ (= (prog1 (point)
+ (goto-char lstart))
+ lstart))
+ (point))
+ (point)
+ (preview-TeX-bb box)
+ (cons lcounters counters)
+ tempdir
+ (cdr open-data))
+ close-data))
+ (with-current-buffer run-buffer
+ (preview-log-error
+ (list 'error
+ (format
+ "End of Preview snippet %d unexpected"
+ snippet)) "Parser")))
+ (setq lstart nil))
+ ;; else-part of if box
+ (setq lstart (point) lcounters counters)
+ ;; >= because snippets in between might have
+ ;; been ignored because of TeX-default-extension
+ (unless (>= snippet (1+ lsnippet))
+ (with-current-buffer run-buffer
+ (preview-log-error
+ (list 'error
+ (format
+ "Preview snippet %d out of sequence"
+ snippet)) "Parser"))))))))
+ (preview-call-hook 'close (car open-data) close-data))))))
+
+(defun preview-get-geometry ()
+ "Transfer display geometry parameters from current display.
+Returns list of scale, resolution and colors. Calculation
+is done in current buffer."
+ (condition-case err
+ (let* ((geometry
+ (list (preview-hook-enquiry preview-scale-function)
+ (cons (/ (* 25.4 (display-pixel-width))
+ (display-mm-width))
+ (/ (* 25.4 (display-pixel-height))
+ (display-mm-height)))
+ (preview-get-colors)))
+ (preview-min-spec
+ (* (cdr (nth 1 geometry))
+ (/
+ (preview-inherited-face-attribute
+ 'preview-reference-face :height 'default)
+ 720.0))))
+ (setq preview-icon (preview-make-image 'preview-icon-specs)
+ preview-error-icon (preview-make-image
+ 'preview-error-icon-specs)
+ preview-nonready-icon (preview-make-image
+ 'preview-nonready-icon-specs))
+ geometry)
+ (error (error "Display geometry unavailable: %s"
+ (error-message-string err)))))
+
+(defun preview-set-geometry (geometry)
+ "Set geometry variables from GEOMETRY.
+Buffer-local `preview-scale', `preview-resolution',
+and `preview-colors' are set as given."
+ (setq preview-scale (nth 0 geometry)
+ preview-resolution (nth 1 geometry)
+ preview-colors (nth 2 geometry)))
+
+(defun preview-start-dvipng ()
+ "Start a DviPNG process.."
+ (let* ((file preview-gs-file)
+ tempdir
+ (res (/ (* (car preview-resolution)
+ (preview-hook-enquiry preview-scale))
+ (preview-get-magnification)))
+ (resolution (format " -D%d " res))
+ (colors (preview-dvipng-color-string preview-colors res))
+ (command (with-current-buffer TeX-command-buffer
+ (prog1
+ (concat (TeX-command-expand preview-dvipng-command
+ (car file))
+ " " colors resolution)
+ (setq tempdir TeX-active-tempdir))))
+ (name "Preview-DviPNG"))
+ (setq TeX-active-tempdir tempdir)
+ (goto-char (point-max))
+ (insert-before-markers "Running `" name "' with ``" command "''\n")
+ (setq mode-name name)
+ (setq TeX-sentinel-function
+ (lambda (process name) (message "%s: done." name)))
+ (if TeX-process-asynchronous
+ (let ((process (start-process name (current-buffer) TeX-shell
+ TeX-shell-command-option
+ command)))
+ (if TeX-after-start-process-function
+ (funcall TeX-after-start-process-function process))
+ (TeX-command-mode-line process)
+ (set-process-filter process 'TeX-command-filter)
+ (set-process-sentinel process 'TeX-command-sentinel)
+ (set-marker (process-mark process) (point-max))
+ (push process compilation-in-progress)
+ (sit-for 0)
+ process)
+ (setq mode-line-process ": run")
+ (set-buffer-modified-p (buffer-modified-p))
+ (sit-for 0) ; redisplay
+ (call-process TeX-shell nil (current-buffer) nil
+ TeX-shell-command-option
+ command))))
+
+(defun preview-start-dvips (&optional fast)
+ "Start a DviPS process.
+If FAST is set, do a fast conversion."
+ (let* ((file preview-gs-file)
+ tempdir
+ (command (with-current-buffer TeX-command-buffer
+ (prog1
+ (TeX-command-expand (if fast
+ preview-fast-dvips-command
+ preview-dvips-command)
+ (car file))
+ (setq tempdir TeX-active-tempdir))))
+ (name "Preview-DviPS"))
+ (setq TeX-active-tempdir tempdir)
+ (setq preview-ps-file (and fast
+ (preview-make-filename
+ (preview-make-filename
+ "preview.ps" tempdir) tempdir)))
+ (goto-char (point-max))
+ (insert-before-markers "Running `" name "' with ``" command "''\n")
+ (setq mode-name name)
+ (setq TeX-sentinel-function
+ (lambda (process name) (message "%s: done." name)))
+ (if TeX-process-asynchronous
+ (let ((process (start-process name (current-buffer) TeX-shell
+ TeX-shell-command-option
+ command)))
+ (if TeX-after-start-process-function
+ (funcall TeX-after-start-process-function process))
+ (TeX-command-mode-line process)
+ (set-process-filter process 'TeX-command-filter)
+ (set-process-sentinel process 'TeX-command-sentinel)
+ (set-marker (process-mark process) (point-max))
+ (push process compilation-in-progress)
+ (sit-for 0)
+ process)
+ (setq mode-line-process ": run")
+ (set-buffer-modified-p (buffer-modified-p))
+ (sit-for 0) ; redisplay
+ (call-process TeX-shell nil (current-buffer) nil
+ TeX-shell-command-option
+ command))))
+
+(defun preview-start-pdf2dsc ()
+ "Start a PDF2DSC process."
+ (let* ((file preview-gs-file)
+ tempdir
+ pdfsource
+ (command (with-current-buffer TeX-command-buffer
+ (prog1
+ (TeX-command-expand preview-pdf2dsc-command
+ (car file))
+ (setq tempdir TeX-active-tempdir
+ pdfsource (funcall `,(car file) "pdf")))))
+ (name "Preview-PDF2DSC"))
+ (setq TeX-active-tempdir tempdir)
+ (setq preview-ps-file (preview-attach-filename
+ pdfsource
+ (preview-make-filename
+ (preview-make-filename
+ "preview.dsc" tempdir) tempdir)))
+ (goto-char (point-max))
+ (insert-before-markers "Running `" name "' with ``" command "''\n")
+ (setq mode-name name)
+ (setq TeX-sentinel-function
+ (lambda (process name) (message "%s: done." name)))
+ (if TeX-process-asynchronous
+ (let ((process (start-process name (current-buffer) TeX-shell
+ TeX-shell-command-option
+ command)))
+ (if TeX-after-start-process-function
+ (funcall TeX-after-start-process-function process))
+ (TeX-command-mode-line process)
+ (set-process-filter process 'TeX-command-filter)
+ (set-process-sentinel process 'TeX-command-sentinel)
+ (set-marker (process-mark process) (point-max))
+ (push process compilation-in-progress)
+ (sit-for 0)
+ process)
+ (setq mode-line-process ": run")
+ (set-buffer-modified-p (buffer-modified-p))
+ (sit-for 0) ; redisplay
+ (call-process TeX-shell nil (current-buffer) nil
+ TeX-shell-command-option
+ command))))
+
+(defun preview-TeX-inline-sentinel (process name)
+ "Sentinel function for preview.
+See `TeX-sentinel-function' and `set-process-sentinel'
+for definition of PROCESS and NAME."
+ (if process (TeX-format-mode-line process))
+ (let ((status (process-status process)))
+ (if (memq status '(signal exit))
+ (delete-process process))
+ (when (eq status 'exit)
+ (save-excursion
+ (goto-char (point-max))
+ (forward-line -1)
+ (if (search-forward "abnormally with code 1" nil t)
+ (replace-match "as expected with code 1" t t)
+ (if (search-forward "finished" nil t)
+ (insert " with nothing to show"))))
+ (condition-case err
+ (preview-call-hook 'open)
+ (error (preview-log-error err "LaTeX" process)))
+ (preview-reraise-error process))))
+
+(defcustom preview-format-extensions '(".fmt" ".efmt")
+ "Possible extensions for format files.
+Those are just needed for cleanup."
+ :group 'preview-latex
+ :type '(repeat string))
+
+(defun preview-format-kill (format-cons)
+ "Kill a cached format.
+FORMAT-CONS is intended to be an element of `preview-dumped-alist'.
+Tries through `preview-format-extensions'."
+ (dolist (ext preview-format-extensions)
+ (condition-case nil
+ (delete-file (preview-dump-file-name (concat (car format-cons) ext)))
+ (file-error nil))))
+
+(defun preview-dump-file-name (file)
+ "Make a file name suitable for dumping from FILE."
+ (if file
+ (concat (file-name-directory file)
+ "prv_"
+ (progn
+ (setq file (file-name-nondirectory file))
+ (while (string-match " " file)
+ (setq file (replace-match "_" t t file)))
+ file))
+ "prv_texput"))
+
+(defun preview-do-replacements (string replacements)
+ "Perform replacements in string.
+STRING is the input string, REPLACEMENTS is a list of replacements.
+A replacement is a cons-cell, where the car is the match string,
+and the cdr is a list of strings or symbols. Symbols get dereferenced,
+and strings get evaluated as replacement strings."
+ (let (rep case-fold-search)
+ (while replacements
+ (setq rep (pop replacements))
+ (cond ((symbolp rep)
+ (setq string (preview-do-replacements
+ string (symbol-value rep))))
+ ((string-match (car rep) string)
+ (setq string
+ (mapconcat (lambda(x)
+ (if (symbolp x)
+ (symbol-value x)
+ (replace-match x t nil string)))
+ (cdr rep) ""))))))
+ string)
+
+(defconst preview-LaTeX-disable-pdfoutput
+ '(("\\`\\(pdf[^ ]*\\)\
+\\(\\( [-&]\\([^ \"]\\|\"[^\"]*\"\\)*\\|\
+ \"[-&][^\"]*\"\\)*\\)\\(.*\\)\\'"
+ . ("\\1\\2 \"\\\\pdfoutput=0 \" \\5")))
+ "This replacement places `\"\\pdfoutput=0 \"' after the options
+of any command starting with `pdf'.")
+
+(defcustom preview-LaTeX-command-replacements
+ nil
+ "Replacement for `preview-LaTeX-command'.
+This is passed through `preview-do-replacements'."
+ :group 'preview-latex
+ :type '(repeat
+ (choice
+ (symbol :tag "Named replacement" :value preview-LaTeX-disable-pdfoutput)
+ (cons (string :tag "Matched string")
+ (repeat :tag "Concatenated elements for replacement"
+ (choice (symbol :tag "Variable with literal string")
+ (string :tag "non-literal regexp replacement")))))))
+
+(defvar preview-format-name)
+
+(defcustom preview-dump-replacements
+ '(preview-LaTeX-command-replacements
+ ("\\`\\([^ ]+\\)\
+\\(\\( +-\\([^ \\\\\"]\\|\\\\\\.\\|\"[^\"]*\"\\)*\\)*\\)\\(.*\\)\\'"
+ . ("\\1 -ini -interaction=nonstopmode \"&\\1\" " preview-format-name ".ini \\5")))
+ "Generate a dump command from the usual preview command."
+ :group 'preview-latex
+ :type '(repeat
+ (choice (symbol :tag "Named replacement")
+ (cons string (repeat (choice symbol string))))))
+
+(defcustom preview-undump-replacements
+ '(("\\`\\([^ ]+\\)\
+ .*? \"\\\\input\" \\(.*\\)\\'"
+ . ("\\1 -interaction=nonstopmode \"&" preview-format-name "\" \\2")))
+ "Use a dumped format for reading preamble."
+ :group 'preview-latex
+ :type '(repeat
+ (choice (symbol :tag "Named replacement")
+ (cons string (repeat (choice symbol string))))))
+
+
+(defun preview-cache-preamble (&optional format-cons)
+ "Dump a pregenerated format file.
+For the rest of the session, this file is used when running
+on the same master file.
+
+Returns the process for dumping, nil if there is still a valid
+format available.
+
+If FORMAT-CONS is non-nil, a previous format may get reused."
+ (interactive)
+ (let* ((dump-file
+ (expand-file-name (preview-dump-file-name (TeX-master-file "ini"))))
+ (master (TeX-master-file))
+ (format-name (expand-file-name master))
+ (preview-format-name (shell-quote-argument
+ (preview-dump-file-name (file-name-nondirectory
+ master))))
+ (master-file (expand-file-name (TeX-master-file t)))
+ (command (preview-do-replacements
+ (TeX-command-expand
+ (preview-string-expand preview-LaTeX-command)
+ 'TeX-master-file)
+ preview-dump-replacements))
+ (preview-auto-cache-preamble nil))
+ (unless (and (consp (cdr format-cons))
+ (string= command (cadr format-cons)))
+ (unless format-cons
+ (setq format-cons (assoc format-name preview-dumped-alist)))
+ (if format-cons
+ (preview-cache-preamble-off format-cons)
+ (setq format-cons (list format-name))
+ (push format-cons preview-dumped-alist))
+ ;; mylatex.ltx expects a file name to follow. Bad. `.tex'
+ ;; in the tools bundle is an empty file.
+ (write-region "\\ifx\\pdfoutput\\undefined\\else\
+\\let\\PREVIEWdump\\dump\\def\\dump{%
+\\edef\\next{{\\catcode`\\ 9 \\pdfoutput=\\the\\pdfoutput\\relax\
+\\the\\everyjob}}\\everyjob\\next\\catcode`\\ 10 \\let\\dump\\PREVIEWdump\\dump}\\fi\\input mylatex.ltx \\relax\n" nil dump-file)
+ (TeX-save-document master)
+ (prog1
+ (preview-generate-preview
+ nil (file-name-nondirectory master)
+ command)
+ (add-hook 'kill-emacs-hook #'preview-cleanout-tempfiles t)
+ (setq TeX-sentinel-function
+ `(lambda (process string)
+ (condition-case err
+ (progn
+ (if (and (eq (process-status process) 'exit)
+ (zerop (process-exit-status process)))
+ (preview-watch-preamble
+ ',master-file
+ ',command
+ ',format-cons)
+ (preview-format-kill ',format-cons))
+ (delete-file ',dump-file))
+ (error (preview-log-error err "Dumping" process)))
+ (preview-reraise-error process)))))))
+
+(defun preview-cache-preamble-off (&optional old-format)
+ "Clear the pregenerated format file.
+The use of the format file is discontinued.
+OLD-FORMAT may already contain a format-cons as
+stored in `preview-dumped-alist'."
+ (interactive)
+ (unless old-format
+ (setq old-format
+ (let ((master-file (expand-file-name (TeX-master-file))))
+ (or (assoc master-file preview-dumped-alist)
+ (car (push (list master-file) preview-dumped-alist))))))
+ (preview-unwatch-preamble old-format)
+ (preview-format-kill old-format)
+ (setcdr old-format nil))
+
+(defun preview-region (begin end)
+ "Run preview on region between BEGIN and END."
+ (interactive "r")
+ (TeX-region-create (TeX-region-file TeX-default-extension)
+ (buffer-substring begin end)
+ (if buffer-file-name
+ (file-name-nondirectory buffer-file-name)
+ "<none>")
+ (save-restriction
+ (widen)
+ (let ((inhibit-point-motion-hooks t)
+ (inhibit-field-text-motion t))
+ (+ (count-lines (point-min) begin)
+ (save-excursion
+ (goto-char begin)
+ (if (bolp) 0 -1))))))
+ (preview-generate-preview t (TeX-region-file nil t)
+ (preview-do-replacements
+ (TeX-command-expand
+ (preview-string-expand preview-LaTeX-command)
+ 'TeX-region-file)
+ preview-LaTeX-command-replacements)))
+
+(defun preview-buffer ()
+ "Run preview on current buffer."
+ (interactive)
+ (preview-region (point-min) (point-max)))
+
+;; We have a big problem: When we are dumping preambles, diagnostics
+;; issued in later runs will not make it to the output when the
+;; predumped format skips the preamble. So we have to place those
+;; after \begin{document}. This we can only do if regions never
+;; include the preamble. We could do this in our own functions, but
+;; that would not extend to the operation of C-c C-r g RET. So we
+;; make this preamble skipping business part of TeX-region-create.
+;; This will fail if the region is to contain just part of the
+;; preamble -- a bad idea anyhow.
+
+(defadvice TeX-region-create (before preview-preamble preactivate activate)
+ "Skip preamble for the sake of predumped formats."
+ (when (string-match TeX-header-end (ad-get-arg 1))
+ (ad-set-arg 1
+ (prog1 (substring (ad-get-arg 1) (match-end 0))
+ (ad-set-arg 3
+ (with-temp-buffer
+ (insert (substring (ad-get-arg 1)
+ 0 (match-end 0)))
+ (+ (ad-get-arg 3)
+ (count-lines (point-min) (point-max))
+ (if (bolp) 0 -1))))))))
+
+(defun preview-document ()
+ "Run preview on master document."
+ (interactive)
+ (TeX-save-document (TeX-master-file))
+ (preview-generate-preview
+ nil (TeX-master-file nil t)
+ (preview-do-replacements
+ (TeX-command-expand
+ (preview-string-expand preview-LaTeX-command)
+ 'TeX-master-file)
+ preview-LaTeX-command-replacements)))
+
+(defun preview-environment (count)
+ "Run preview on LaTeX environment.
+This avoids running environments through preview that are
+indicated in `preview-inner-environments'. If you use a prefix
+argument COUNT, the corresponding level of outward nested
+environments is selected."
+ (interactive "p")
+ (save-excursion
+ (let (currenv)
+ (dotimes (i (1- count))
+ (setq currenv (LaTeX-current-environment))
+ (if (string= currenv "document")
+ (error "No enclosing outer environment found"))
+ (LaTeX-find-matching-begin))
+ (while (member (setq currenv (LaTeX-current-environment))
+ preview-inner-environments)
+ (LaTeX-find-matching-begin))
+ (if (string= currenv "document")
+ (error "No enclosing outer environment found"))
+ (preview-region
+ (save-excursion (LaTeX-find-matching-begin) (point))
+ (save-excursion (LaTeX-find-matching-end) (point))))))
+
+(defun preview-section ()
+ "Run preview on LaTeX section." (interactive)
+ (save-excursion
+ (LaTeX-mark-section)
+ (preview-region (region-beginning) (region-end))))
+
+
+(defun preview-generate-preview (region-p file command)
+ "Generate a preview.
+REGION-P is the region flag, FILE the file (without default
+extension and directory), COMMAND is the command to use.
+
+It returns the started process."
+ (setq TeX-current-process-region-p region-p)
+ (let* ((geometry (preview-get-geometry))
+ (commandbuff (current-buffer))
+ (pr-file (cons
+ (if TeX-current-process-region-p
+ 'TeX-region-file
+ 'TeX-master-file)
+ file))
+ (master (TeX-master-file))
+ (master-file (expand-file-name master))
+ (dumped-cons (assoc master-file
+ preview-dumped-alist))
+ process)
+ (unless dumped-cons
+ (push (setq dumped-cons (cons master-file
+ (if (eq preview-auto-cache-preamble 'ask)
+ (y-or-n-p "Cache preamble? ")
+ preview-auto-cache-preamble)))
+ preview-dumped-alist))
+ (when (cdr dumped-cons)
+ (let* (TeX-current-process-region-p)
+ (setq process (preview-cache-preamble dumped-cons))
+ (if process
+ (setq TeX-sentinel-function
+ `(lambda (process string)
+ (funcall ,TeX-sentinel-function process string)
+ (TeX-inline-preview-internal
+ ,command ,file
+ ',pr-file ,commandbuff
+ ',dumped-cons
+ ',master
+ ',geometry
+ (buffer-string)))))))
+ (or process
+ (TeX-inline-preview-internal command file
+ pr-file commandbuff
+ dumped-cons master
+ geometry))))
+
+(defun TeX-inline-preview-internal (command file pr-file
+ commandbuff dumped-cons master
+ geometry
+ &optional str)
+ "Internal stuff for previewing.
+COMMAND and FILE should be explained in `TeX-command-list'.
+PR-FILE is the target file name in the form for `preview-gs-file'.
+COMMANDBUFF, DUMPED-CONS, MASTER, and GEOMETRY are
+internal parameters, STR may be a log to insert into the current log."
+ (set-buffer commandbuff)
+ (let*
+ ((preview-format-name (shell-quote-argument
+ (preview-dump-file-name
+ (file-name-nondirectory master))))
+ (process
+ (TeX-run-command
+ "Preview-LaTeX"
+ (if (consp (cdr dumped-cons))
+ (preview-do-replacements
+ command preview-undump-replacements)
+ command) file)))
+ (condition-case err
+ (progn
+ (when str
+ (save-excursion
+ (goto-char (point-min))
+ (insert str)
+ (when (= (process-mark process) (point-min))
+ (set-marker (process-mark process) (point)))))
+ (preview-set-geometry geometry)
+ (setq preview-gs-file pr-file)
+ (setq TeX-sentinel-function 'preview-TeX-inline-sentinel)
+ (when (featurep 'mule)
+ (setq preview-coding-system
+ (or (and (boundp 'TeX-japanese-process-output-coding-system)
+ TeX-japanese-process-output-coding-system)
+ (with-current-buffer commandbuff
+ buffer-file-coding-system)))
+ (when preview-coding-system
+ (setq preview-coding-system
+ (preview-buffer-recode-system
+ (coding-system-base preview-coding-system))))
+ (set-process-coding-system
+ process preview-coding-system))
+ (TeX-parse-reset)
+ (setq TeX-parse-function 'TeX-parse-TeX)
+ (if TeX-process-asynchronous
+ process
+ (TeX-synchronous-sentinel "Preview-LaTeX" file process)))
+ (error (preview-log-error err "Preview" process)
+ (delete-process process)
+ (preview-reraise-error process)))))
+
+(defconst preview-version (eval-when-compile
+ (let ((name "$Name: release_11_86 $")
+ (rev "$Revision: 1.284 $"))
+ (or (when (string-match "\\`[$]Name: *release_\\([^ ]+\\) *[$]\\'" name)
+ (setq name (match-string 1 name))
+ (while (string-match "_" name)
+ (setq name (replace-match "." t t name)))
+ name)
+ (if (string-match "\\`[$]Revision: *\\([^ ]+\\) *[$]\\'" rev)
+ (format "CVS-%s" (match-string 1 rev)))
+ "unknown")))
+ "Preview version.
+If not a regular release, CVS revision of `preview.el'.")
+
+(defconst preview-release-date
+ (eval-when-compile
+ (let ((date "$Date: 2009/06/18 19:20:46 $"))
+ (string-match
+ "\\`[$]Date: *\\([0-9]+\\)/\\([0-9]+\\)/\\([0-9]+\\)"
+ date)
+ (format "%s.%s%s" (match-string 1 date) (match-string 2 date)
+ (match-string 3 date))))
+ "Preview release date.
+In the form of yyyy.mmdd")
+
+(defun preview-dump-state (buffer)
+ (condition-case nil
+ (progn
+ (unless (local-variable-p 'TeX-command-buffer)
+ (setq buffer (with-current-buffer buffer (TeX-active-buffer))))
+ (when (bufferp buffer)
+ (insert "\nRun buffer contents:\n\n")
+ (if (< (buffer-size buffer) 5000)
+ (insert-buffer-substring buffer)
+ (insert-buffer-substring buffer 1 2500)
+ (insert "...\n\n[...]\n\n\t...")
+ (insert-buffer-substring buffer
+ (- (buffer-size buffer) 2500)
+ (buffer-size buffer)))
+ (insert "\n")))
+ (error nil)))
+
+;;;###autoload
+(defun preview-report-bug () "Report a bug in the preview-latex package."
+ (interactive)
+ (let ((reporter-prompt-for-summary-p "Bug report subject: "))
+ (reporter-submit-bug-report
+ "bug-auctex@gnu.org"
+ (if (string-match "^CVS-" preview-version)
+ (concat "preview-" (substring preview-version 4))
+ preview-version)
+ '(AUCTeX-version
+ LaTeX-command-style
+ image-types
+ preview-image-type
+ preview-image-creators
+ preview-dvipng-image-type
+ preview-dvipng-command
+ preview-pdf2dsc-command
+ preview-gs-command
+ preview-gs-options
+ preview-gs-image-type-alist
+ preview-fast-conversion
+ preview-prefer-TeX-bb
+ preview-dvips-command
+ preview-fast-dvips-command
+ preview-scale-function
+ preview-LaTeX-command
+ preview-required-option-list
+ preview-preserve-counters
+ preview-default-option-list
+ preview-default-preamble
+ preview-LaTeX-command-replacements
+ preview-dump-replacements
+ preview-undump-replacements
+ preview-auto-cache-preamble
+ preview-TeX-style-dir)
+ `(lambda () (preview-dump-state ,(current-buffer)))
+ (lambda ()
+ (insert (format "\nOutput from running `%s -h':\n"
+ preview-gs-command))
+ (call-process preview-gs-command nil t nil "-h")
+ (insert "\n"))
+ "Remember to cover the basics. Including a minimal LaTeX example
+file exhibiting the problem might help."
+ )))
+
+(eval-when-compile
+ (when (boundp 'preview-compatibility-macros)
+ (dolist (elt preview-compatibility-macros)
+ (if (consp elt)
+ (fset (car elt) (cdr elt))
+ (fmakunbound elt)))))
+
+(makunbound 'preview-compatibility-macros)
+
+(provide 'preview)
+;;; preview.el ends here
--- /dev/null
+;;; prv-emacs.el --- GNU Emacs specific code for preview.el
+
+;; Copyright (C) 2001, 02, 03, 04, 05 Free Software Foundation, Inc.
+
+;; Author: David Kastrup
+;; Keywords: convenience, tex, wp
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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; see the file COPYING. If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'tex-site)
+(require 'tex)
+(require 'latex)
+
+(defvar preview-compatibility-macros nil
+ "List of macros only present when compiling/loading.")
+
+(defcustom preview-transparent-color '(highlight :background)
+ "Color to appear transparent in previews.
+Set this to something unusual when using `preview-transparent-border',
+to the default background in most other cases."
+ :type '(radio (const :tag "None" nil)
+ (const :tag "Autodetect" t)
+ (color :tag "By name" :value "white")
+ (list :tag "Take from face"
+ :value (default :background)
+ (face)
+ (choice :tag "What to take"
+ (const :tag "Background" :value :background)
+ (const :tag "Foreground" :value :foreground))))
+ :group 'preview-appearance)
+
+;;; Note that the following default introduces a border only when
+;;; Emacs blinks politely when point is on an image (the tested
+;;; unrelated function was introduced at about the time image blinking
+;;; became tolerable).
+(defcustom preview-transparent-border (unless (fboundp 'posn-object-x-y) 1.5)
+ "Width of transparent border for previews in pt.
+Setting this to a numeric value will add a border of
+`preview-transparent-color' around images, and will turn
+the heuristic-mask setting of images to default to 't since
+then the borders are correctly detected even in case of
+palette operations. If the transparent color is something
+not present otherwise in the image, the cursor display
+will affect just this border. A width of 0 is interpreted
+by PostScript as meaning a single pixel, other widths are
+interpreted as PostScript points (1/72 of 1in)"
+ :group 'preview-appearance
+ :type '(choice (const :value nil :tag "No border")
+ (number :value 1.5 :tag "Border width in pt")))
+
+(defun preview-get-heuristic-mask ()
+ "Get heuristic-mask to use for previews.
+Consults `preview-transparent-color'."
+ (cond ((stringp preview-transparent-color)
+ (color-values preview-transparent-color))
+ ((or (not (consp preview-transparent-color))
+ (integerp (car preview-transparent-color)))
+ preview-transparent-color)
+ (t (color-values (preview-inherited-face-attribute
+ (nth 0 preview-transparent-color)
+ (nth 1 preview-transparent-color)
+ 'default)))))
+
+(defsubst preview-create-icon-1 (file type ascent border)
+ `(image
+ :file ,file
+ :type ,type
+ :ascent ,ascent
+ ,@(and border
+ '(:mask (heuristic t)))))
+
+(defun preview-create-icon (file type ascent border)
+ "Create an icon from FILE, image TYPE, ASCENT and BORDER."
+ (list
+ (preview-create-icon-1 file type ascent border)
+ file type ascent border))
+
+(put 'preview-filter-specs :type
+ #'(lambda (keyword value &rest args)
+ (if (image-type-available-p value)
+ `(image :type ,value
+ ,@(preview-filter-specs-1 args))
+ (throw 'preview-filter-specs nil))))
+
+;; No defcustom here: does not seem to make sense.
+
+(defvar preview-tb-icon-specs
+ '((:type xpm :file "prvtex24.xpm")
+ (:type xbm :file "prvtex24.xbm")))
+
+(defvar preview-tb-icon nil)
+
+(defun preview-add-urgentization (fun ov &rest rest)
+ "Cause FUN (function call form) to be called when redisplayed.
+FUN must be a form with OV as first argument,
+REST as the remainder, returning T."
+ (let ((dispro (overlay-get ov 'display)))
+ (unless (eq (car dispro) 'when)
+ (overlay-put ov 'display `(when (,fun ,ov ,@rest) . ,dispro)))))
+
+(defun preview-remove-urgentization (ov)
+ "Undo urgentization of OV by `preview-add-urgentization'.
+Returns the old arguments to `preview-add-urgentization'
+if there was any urgentization."
+ (let ((dispro (overlay-get ov 'display)))
+ (when (eq (car-safe dispro) 'when)
+ (prog1
+ (car (cdr dispro))
+ (overlay-put ov 'display (cdr (cdr dispro)))))))
+
+(defsubst preview-icon-copy (icon)
+ "Prepare a later call of `preview-replace-active-icon'."
+
+ ;; This is just a GNU Emacs specific efficiency hack because it
+ ;; is easy to do. When porting, don't do anything complicated
+ ;; here, rather deliver just the unchanged icon and make
+ ;; `preview-replace-active-icon' do the necessary work of replacing
+ ;; the icon where it actually has been stored, probably
+ ;; in the car of the strings property of the overlay. This string
+ ;; might probably serve as a begin-glyph as well, in which case
+ ;; modifying the string in the strings property would change that
+ ;; glyph automatically.
+
+ (cons 'image (cdr icon)))
+
+(defsubst preview-replace-active-icon (ov replacement)
+ "Replace the active Icon in OV by REPLACEMENT, another icon."
+ (let ((img (overlay-get ov 'preview-image)))
+ (setcdr (car img) (cdar replacement))
+ (setcdr img (cdr replacement))))
+
+(defvar preview-button-1 [mouse-2])
+(defvar preview-button-2 [mouse-3])
+
+(defmacro preview-make-clickable (&optional map glyph helpstring click1 click2)
+ "Generate a clickable string or keymap.
+If MAP is non-nil, it specifies a keymap to add to, otherwise
+a new one is created. If GLYPH is given, the result is made
+to display it wrapped in a string. In that case,
+HELPSTRING is a format string with one or two %s specifiers
+for preview's clicks, displayed as a help-echo. CLICK1 and CLICK2
+are functions to call on preview's clicks."
+ `(let ((resmap ,(or map '(make-sparse-keymap))))
+ ,@(if click1
+ `((define-key resmap preview-button-1 ,click1)))
+ ,@(if click2
+ `((define-key resmap preview-button-2 ,click2)))
+ ,(if glyph
+ `(propertize
+ "x"
+ 'display ,glyph
+ 'mouse-face 'highlight
+ 'help-echo
+ ,(if (stringp helpstring)
+ (format helpstring preview-button-1 preview-button-2)
+ `(format ,helpstring preview-button-1 preview-button-2))
+ 'keymap resmap)
+ 'resmap)))
+
+(defvar preview-overlay nil)
+
+(put 'preview-overlay
+ 'modification-hooks
+ '(preview-handle-modification))
+
+(put 'preview-overlay
+ 'insert-in-front-hooks
+ '(preview-handle-insert-in-front))
+
+(put 'preview-overlay
+ 'insert-behind-hooks
+ '(preview-handle-insert-behind))
+
+;; We have to fake our way around atomicity.
+
+;; Here is the beef: for best intuitiveness, we want to have
+;; insertions be carried out as expected before iconized text
+;; passages, but we want to insert *into* the overlay when not
+;; iconized. A preview that has become empty can not get content
+;; again: we remove it. A disabled preview needs no insert-in-front
+;; handler.
+
+(defvar preview-change-list nil
+ "List of tentatively changed overlays.")
+
+(defcustom preview-dump-threshold
+ "^ *\\\\begin *{document}[ %]*$"
+ "*Regexp denoting end of preamble.
+This is the location up to which preamble changes are considered
+to require redumping of a format."
+ :group 'preview-latex
+ :type 'string)
+
+(defun preview-preamble-changed-function
+ (ov after-change beg end &optional length)
+ "Hook function for change hooks on preamble.
+See info node `(elisp) Overlay Properties' for
+definition of OV, AFTER-CHANGE, BEG, END and LENGTH."
+ (let ((format-cons (overlay-get ov 'format-cons)))
+ (preview-unwatch-preamble format-cons)
+ (preview-format-kill format-cons)
+ (setcdr format-cons t)))
+
+(defun preview-watch-preamble (file command format-cons)
+ "Set up a watch on master file FILE.
+FILE can be an associated buffer instead of a filename.
+COMMAND is the command that generated the format.
+FORMAT-CONS contains the format info for the main
+format dump handler."
+ (let ((buffer (if (bufferp file)
+ file
+ (find-buffer-visiting file))) ov)
+ (setcdr
+ format-cons
+ (cons command
+ (when buffer
+ (with-current-buffer buffer
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (unless (re-search-forward preview-dump-threshold nil t)
+ (error "Can't find preamble of `%s'" file))
+ (setq ov (make-overlay (point-min) (point)))
+ (overlay-put ov 'format-cons format-cons)
+ (overlay-put ov 'insert-in-front-hooks
+ '(preview-preamble-changed-function))
+ (overlay-put ov 'modification-hooks
+ '(preview-preamble-changed-function))
+ ov))))))))
+
+(defun preview-unwatch-preamble (format-cons)
+ "Stop watching a format on FORMAT-CONS.
+The watch has been set up by `preview-watch-preamble'."
+ (when (consp (cdr format-cons))
+ (when (cddr format-cons)
+ (delete-overlay (cddr format-cons)))
+ (setcdr (cdr format-cons) nil)))
+
+(defun preview-register-change (ov)
+ "Register not yet changed OV for verification.
+This stores the old contents of the overlay in the
+`preview-prechange' property and puts the overlay into
+`preview-change-list' where `preview-check-changes' will
+find it at some later point of time."
+ (unless (overlay-get ov 'preview-prechange)
+ (if (eq (overlay-get ov 'preview-state) 'disabled)
+ (overlay-put ov 'preview-prechange t)
+ (overlay-put ov 'preview-prechange
+ (save-restriction
+ (widen)
+ (buffer-substring-no-properties
+ (overlay-start ov) (overlay-end ov)))))
+ (push ov preview-change-list)))
+
+(defun preview-check-changes ()
+ "Check whether the contents under the overlay have changed.
+Disable it if that is the case. Ignores text properties."
+ (dolist (ov preview-change-list)
+ (condition-case nil
+ (with-current-buffer (overlay-buffer ov)
+ (let ((text (save-restriction
+ (widen)
+ (buffer-substring-no-properties
+ (overlay-start ov) (overlay-end ov)))))
+ (if (zerop (length text))
+ (preview-delete ov)
+ (unless
+ (or (eq (overlay-get ov 'preview-state) 'disabled)
+ (preview-relaxed-string=
+ text (overlay-get ov 'preview-prechange)))
+ (overlay-put ov 'insert-in-front-hooks nil)
+ (overlay-put ov 'insert-behind-hooks nil)
+ (preview-disable ov)))))
+ (error nil))
+ (overlay-put ov 'preview-prechange nil))
+ (setq preview-change-list nil))
+
+(defun preview-handle-insert-in-front
+ (ov after-change beg end &optional length)
+ "Hook function for `insert-in-front-hooks' property.
+See info node `(elisp) Overlay Properties' for
+definition of OV, AFTER-CHANGE, BEG, END and LENGTH."
+ (if after-change
+ (unless undo-in-progress
+ (if (eq (overlay-get ov 'preview-state) 'active)
+ (move-overlay ov end (overlay-end ov))))
+ (preview-register-change ov)))
+
+(defun preview-handle-insert-behind
+ (ov after-change beg end &optional length)
+ "Hook function for `insert-behind-hooks' property.
+This is needed in case `insert-before-markers' is used at the
+end of the overlay. See info node `(elisp) Overlay Properties'
+for definition of OV, AFTER-CHANGE, BEG, END and LENGTH."
+ (if after-change
+ (unless undo-in-progress
+ (if (eq (overlay-get ov 'preview-state) 'active)
+ (move-overlay ov (overlay-start ov) beg)))
+ (preview-register-change ov)))
+
+(defun preview-handle-modification
+ (ov after-change beg end &optional length)
+ "Hook function for `modification-hooks' property.
+See info node `(elisp) Overlay Properties' for
+definition of OV, AFTER-CHANGE, BEG, END and LENGTH."
+ (unless after-change
+ (preview-register-change ov)))
+
+(defun preview-toggle (ov &optional arg event)
+ "Toggle visibility of preview overlay OV.
+ARG can be one of the following: t displays the overlay,
+nil displays the underlying text, and 'toggle toggles.
+If EVENT is given, it indicates the window where the event
+occured, either by being a mouse event or by directly being
+the window in question. This may be used for cursor restoration
+purposes."
+ (let ((old-urgent (preview-remove-urgentization ov))
+ (preview-state
+ (if (if (eq arg 'toggle)
+ (null (eq (overlay-get ov 'preview-state) 'active))
+ arg)
+ 'active
+ 'inactive))
+ (strings (overlay-get ov 'strings)))
+ (unless (eq (overlay-get ov 'preview-state) 'disabled)
+ (overlay-put ov 'preview-state preview-state)
+ (if (eq preview-state 'active)
+ (progn
+ (overlay-put ov 'category 'preview-overlay)
+ (if (eq (overlay-start ov) (overlay-end ov))
+ (overlay-put ov 'before-string (car strings))
+ (dolist (prop '(display keymap mouse-face help-echo))
+ (overlay-put ov prop
+ (get-text-property 0 prop (car strings))))
+ (overlay-put ov 'before-string nil))
+ (overlay-put ov 'face nil))
+ (dolist (prop '(display keymap mouse-face help-echo))
+ (overlay-put ov prop nil))
+ (overlay-put ov 'face 'preview-face)
+ (unless (cdr strings)
+ (setcdr strings (preview-inactive-string ov)))
+ (overlay-put ov 'before-string (cdr strings)))
+ (if old-urgent
+ (apply 'preview-add-urgentization old-urgent))))
+ (if event
+ (preview-restore-position
+ ov
+ (if (windowp event)
+ event
+ (posn-window (event-start event))))))
+
+(defsubst preview-buffer-recode-system (base)
+ "This is supposed to translate unrepresentable base encodings
+into something that can be used safely for byte streams in the
+run buffer. A noop for Emacs."
+ base)
+
+(defun preview-mode-setup ()
+ "Setup proper buffer hooks and behavior for previews."
+ (set (make-local-variable 'desktop-save-buffer)
+ #'desktop-buffer-preview-misc-data)
+ (add-hook 'pre-command-hook #'preview-mark-point nil t)
+ (add-hook 'post-command-hook #'preview-move-point nil t)
+ (easy-menu-add preview-menu LaTeX-mode-map)
+ (unless preview-tb-icon
+ (setq preview-tb-icon (preview-filter-specs preview-tb-icon-specs)))
+ (when preview-tb-icon
+ (define-key LaTeX-mode-map [tool-bar preview]
+ `(menu-item "Preview at point" preview-at-point
+ :image ,preview-tb-icon
+ :help "Preview on/off at point")))
+ (when buffer-file-name
+ (let* ((filename (expand-file-name buffer-file-name))
+ format-cons)
+ (when (string-match (concat "\\." TeX-default-extension "\\'")
+ filename)
+ (setq filename (substring filename 0 (match-beginning 0))))
+ (setq format-cons (assoc filename preview-dumped-alist))
+ (when (consp (cdr format-cons))
+ (preview-unwatch-preamble format-cons)
+ (preview-watch-preamble (current-buffer)
+ (cadr format-cons)
+ format-cons)))))
+
+(defvar preview-marker (make-marker)
+ "Marker for fake intangibility.")
+
+(defvar preview-temporary-opened nil)
+
+(defvar preview-last-location nil
+ "Restored cursor position marker for reopened previews.")
+(make-variable-buffer-local 'preview-last-location)
+
+(defun preview-mark-point ()
+ "Mark position for fake intangibility."
+ (when (eq (get-char-property (point) 'preview-state) 'active)
+ (unless preview-last-location
+ (setq preview-last-location (make-marker)))
+ (set-marker preview-last-location (point))
+ (set-marker preview-marker (point))
+ (preview-move-point))
+ (set-marker preview-marker (point)))
+
+(defun preview-restore-position (ov window)
+ "Tweak position after opening/closing preview.
+The treated overlay OV has been triggered in WINDOW. This function
+records the original buffer position for reopening, or restores it
+after reopening. Note that by using the mouse, you can open/close
+overlays not in the active window."
+ (when (eq (overlay-buffer ov) (window-buffer window))
+ (with-current-buffer (overlay-buffer ov)
+ (if (eq (overlay-get ov 'preview-state) 'active)
+ (setq preview-last-location
+ (set-marker (or preview-last-location (make-marker))
+ (window-point window)))
+ (when (and
+ (markerp preview-last-location)
+ (eq (overlay-buffer ov) (marker-buffer preview-last-location))
+ (< (overlay-start ov) preview-last-location)
+ (> (overlay-end ov) preview-last-location))
+ (set-window-point window preview-last-location))))))
+
+(defun preview-move-point ()
+ "Move point out of fake-intangible areas."
+ (preview-check-changes)
+ (let* (newlist (pt (point)) (lst (overlays-at pt)) distance)
+ (setq preview-temporary-opened
+ (dolist (ov preview-temporary-opened newlist)
+ (and (overlay-buffer ov)
+ (eq (overlay-get ov 'preview-state) 'inactive)
+ (if (and (eq (overlay-buffer ov) (current-buffer))
+ (or (<= pt (overlay-start ov))
+ (>= pt (overlay-end ov))))
+ (preview-toggle ov t)
+ (push ov newlist)))))
+ (when lst
+ (if (or disable-point-adjustment
+ global-disable-point-adjustment
+ (preview-auto-reveal-p
+ preview-auto-reveal
+ (setq distance
+ (and (eq (marker-buffer preview-marker)
+ (current-buffer))
+ (- pt (marker-position preview-marker))))))
+ (preview-open-overlays lst)
+ (while lst
+ (setq lst
+ (if (and
+ (eq (overlay-get (car lst) 'preview-state) 'active)
+ (> pt (overlay-start (car lst))))
+ (overlays-at
+ (setq pt (if (and distance (< distance 0))
+ (overlay-start (car lst))
+ (overlay-end (car lst)))))
+ (cdr lst))))
+ (goto-char pt)))))
+
+(defun preview-open-overlays (list &optional pos)
+ "Open all previews in LIST, optionally restricted to enclosing POS."
+ (dolist (ovr list)
+ (when (and (eq (overlay-get ovr 'preview-state) 'active)
+ (or (null pos)
+ (and
+ (> pos (overlay-start ovr))
+ (< pos (overlay-end ovr)))))
+ (preview-toggle ovr)
+ (push ovr preview-temporary-opened))))
+
+(defadvice replace-highlight (before preview)
+ "Make `query-replace' open preview text about to be replaced."
+ (preview-open-overlays
+ (overlays-in (ad-get-arg 0) (ad-get-arg 1))))
+
+(defcustom preview-query-replace-reveal t
+ "*Make `query-replace' autoreveal previews."
+ :group 'preview-appearance
+ :type 'boolean
+ :require 'preview
+ :set (lambda (symbol value)
+ (set-default symbol value)
+ (if value
+ (ad-enable-advice 'replace-highlight 'before 'preview)
+ (ad-disable-advice 'replace-highlight 'before 'preview))
+ (ad-activate 'replace-highlight))
+ :initialize #'custom-initialize-reset)
+
+;; Check whether the four-argument form of `face-attribute' exists.
+;; If not, we will get a `wrong-number-of-arguments' error thrown.
+;; Use `defun' instead of `defsubst' here so that the decision may be
+;; reverted at load time if you are compiling with one Emacs and using
+;; another.
+(if (condition-case nil
+ (progn
+ (face-attribute 'default :height nil nil)
+ t)
+ (wrong-number-of-arguments nil))
+
+ (defun preview-inherited-face-attribute (face attribute &optional inherit)
+ "Fetch face attribute while adhering to inheritance.
+This searches FACE for an ATTRIBUTE, using INHERIT
+for resolving unspecified or relative specs. See the fourth
+argument of function `face-attribute' for details."
+ (face-attribute face attribute nil inherit))
+
+ (defun preview-inherited-face-attribute (face attribute &optional inherit)
+ "Fetch face attribute while adhering to inheritance.
+This searches FACE for an ATTRIBUTE. If it is 'unspecified,
+first inheritance is consulted (if INHERIT is non-NIL), then
+INHERIT is searched if it is a face or a list of faces.
+Relative specs are evaluated recursively until they get absolute or
+are not resolvable. Relative specs are float values."
+ (let ((value (face-attribute face attribute)))
+ (when inherit
+ (setq inherit
+ (append
+ (let ((ancestors (face-attribute face :inherit)))
+ (cond ((facep ancestors) (list ancestors))
+ ((consp ancestors) ancestors)))
+ (cond ((facep inherit) (list inherit))
+ ((consp inherit) inherit)))))
+ (cond ((null inherit) value)
+ ((floatp value)
+ (let ((avalue
+ (preview-inherited-face-attribute
+ (car inherit) attribute (or (cdr inherit) t))))
+ (cond ((integerp avalue)
+ (round (* avalue value)))
+ ((floatp avalue)
+ (* value avalue))
+ (t value))))
+ ((eq value 'unspecified)
+ (preview-inherited-face-attribute
+ (car inherit) attribute (or (cdr inherit) t)))
+ (t value)))))
+
+(defun preview-get-colors ()
+ "Return colors from the current display.
+Fetches the current screen colors and makes a vector
+of colors as numbers in the range 0..65535.
+Pure borderless black-on-white will return triple NIL.
+The fourth value is the transparent border thickness."
+ (let
+ ((bg (color-values (preview-inherited-face-attribute
+ 'preview-reference-face :background 'default)))
+ (fg (color-values (preview-inherited-face-attribute
+ 'preview-reference-face :foreground 'default)))
+ (mask (preview-get-heuristic-mask)))
+ (if (equal '(65535 65535 65535) bg)
+ (setq bg nil))
+ (if (equal '(0 0 0) fg)
+ (setq fg nil))
+ (unless (and (numberp preview-transparent-border)
+ (consp mask) (integerp (car mask)))
+ (setq mask nil))
+ (vector bg fg mask preview-transparent-border)))
+
+(defmacro preview-mark-active ()
+ "Return t if the mark is active."
+ 'mark-active)
+
+(defun preview-import-image (image)
+ "Convert the printable IMAGE rendition back to an image."
+ (cond ((stringp image)
+ (propertize image 'face 'preview-face))
+ ((eq (car image) 'image)
+ image)
+ (t
+ (preview-create-icon-1 (nth 0 image)
+ (nth 1 image)
+ (nth 2 image)
+ (if (< (length image) 4)
+ (preview-get-heuristic-mask)
+ (nth 3 image))))))
+
+(defsubst preview-supports-image-type (imagetype)
+ "Check if IMAGETYPE is supported."
+ (image-type-available-p imagetype))
+
+(provide 'prv-emacs)
+;;; prv-emacs.el ends here
--- /dev/null
+;; AUCTeX style/ and auto/ directories should not appear in load path.
--- /dev/null
+;;; CJK.el --- AUCTeX style for the CJK package.
+
+;; Copyright (C) 2009 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@caeruleus.net>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2009-01-04
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for the CJK package, version 4.8.0
+;; (22-May-2008).
+
+;;; Code:
+
+(defvar LaTeX-CJK-package-options
+ '("lowercase" "global" "local" "active" "encapsulated")
+ "Package options for the CJK package.")
+
+(defvar LaTeX-CJK-enc-list
+ '("Bg5" "Bg5+" "HK" "GB" "GBt" "GBK" "JIS" "JIS2" "SJIS" "KS" "UTF8" "CNS1"
+ "CNS2" "CNS3" "CNS4" "CNS5" "CNS6" "CNS7" "CEFX" "CEFY")
+ "List of encodings supported by the CJK package.")
+
+(defun LaTeX-env-CJK (env)
+ "Prompt for the arguments of ENV and insert it.
+The function can be used for CJK and CJK* environments."
+ (LaTeX-insert-environment
+ env
+ (concat
+ (let ((font-enc (read-string "(Optional) Font encoding: ")))
+ (unless (zerop (length font-enc)) (format "[%s]" font-enc)))
+ (format "{%s}" (completing-read "Encoding: "
+ (mapcar 'list LaTeX-CJK-enc-list)))
+ (format "{%s}" (read-string "Font family: ")))))
+
+(TeX-add-style-hook
+ "CJK"
+ (lambda ()
+ ;; New symbols
+ (TeX-add-symbols
+ '("CJKencfamily" ["Font encoding"] "Encoding" "Font family")
+ '("CJKchar" ["Encoding"] "First byte" "Second byte")
+ '("CJKcaption" 1)
+ '("CJKfamily" 1)
+ '("CJKfontenc" "Encoding" "Font encoding")
+ '("CJKenc" 1)
+ '("Unicode" "First byte" "Second byte")
+ '("CJKsymbols" 2)
+ '("CJKsymbol" 1)
+ "CJKbold"
+ "CJKnormal"
+ "CJKboldshift"
+ "CJKCJKchar"
+ "CJKhangulchar"
+ "CJKlatinchar"
+ "CJKhwkatakana"
+ "CJKnohwkatakana"
+ "CJKglue"
+ "CJKtolerance"
+ "CJKtilde"
+ "nbs"
+ "standardtilde"
+ "CJKspace"
+ "CJKnospace"
+ "CJKindent"
+ '("CJKaddEncHook" 2)
+ "CJKkern"
+ "CJKverbatim")
+ ;; New environments
+ (LaTeX-add-environments
+ '("CJK" LaTeX-env-CJK)
+ '("CJK*" LaTeX-env-CJK))))
+
+;;; CJK.el ends here
--- /dev/null
+;;; CJKutf8.el --- AUCTeX style for the CJKutf8 package.
+
+;; Copyright (C) 2009 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@caeruleus.net>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2009-01-04
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for the CJKutf8 package.
+
+;;; Code:
+
+(TeX-add-style-hook
+ "CJKutf8"
+ (lambda ()
+ (TeX-run-style-hooks "CJK")))
+
+;;; CJKutf8.el ends here
--- /dev/null
+;;; MinionPro.el -- AUCTeX style for MinionPro.sty
+
+;; Copyright (C) 2005 Free Software Foundation, Inc.
+
+;; Author: Mark Trettin <Mark.Trettin@gmx.de>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2005-11-26
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `MinionPro.sty' (v2.0).
+
+;;; Code
+
+(TeX-add-style-hook
+ "MinionPro"
+ (lambda ()
+ (TeX-add-symbols
+ ;; New symbols
+ '("figureversion"
+ (TeX-arg-eval completing-read "Figure style: "
+ '(("text") ("osf")
+ ("lining") ("lf")
+ ("tabular") ("tab")
+ ("proportional") ("prop"))))
+ '("smallfrac" "Numerator" "Denominator")
+ '("slantfrac" "Numerator" "Denominator")
+ ;; IMHO they should be added to the other \text.. and \..shape commands
+ '("textsw" 1)
+ '("textssc" 1)
+ "sscshape"
+ "swshape")
+ ;; Run style hook for amsmath which is loaded via MnSymbol
+ (TeX-run-style-hooks "amsmath")
+ ;; Fontification
+ (when (and (featurep 'font-latex)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ (font-latex-add-keywords '(("smallfrac" "{{")
+ ("slantfrac" "{{")
+ ("textsw" "{")
+ ("textssc" "{"))
+ 'textual)
+ (font-latex-add-keywords '(("figureversion" "{")) 'variable))))
+
+(defvar LaTeX-MinionPro-package-options
+ '("smallfamily" "medfamily" "fullfamily" "noopticals" "opticals"
+ "slides" "textosf" "mathosf" "osf" "textlf" "mathlf" "lf"
+ "mathtabular" "mnsy" "cmsy" "swash" "abx" "amsbb" "fourierbb"
+ "lucidabb" "mixedgreek" "italicgreek" "frenchmath" "minionint"
+ "footnotefigures")
+"Package options for the MinionPro package.")
+
+;;; MinionPro.el ends here
--- /dev/null
+;;; alltt.el --- AUCTeX style for `alltt.sty'
+
+;; Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@iwi.uni-sb.de>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2004-04-30
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `alltt.sty'.
+
+;;; Code:
+
+(TeX-add-style-hook
+ "alltt"
+ (lambda ()
+ (LaTeX-add-environments "alltt")
+ (make-local-variable 'LaTeX-indent-environment-list)
+ (add-to-list 'LaTeX-indent-environment-list
+ '("alltt" current-indentation))
+ (make-local-variable 'LaTeX-verbatim-regexp)
+ (setq LaTeX-verbatim-regexp (concat LaTeX-verbatim-regexp "\\|alltt"))
+ (add-to-list 'LaTeX-verbatim-environments-local "alltt")
+ ;; Fontification
+ (when (and (featurep 'font-latex)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ ;; For syntactic fontification, e.g. verbatim constructs.
+ (font-latex-set-syntactic-keywords)
+ ;; Tell font-lock about the update.
+ (setq font-lock-set-defaults nil)
+ (font-lock-set-defaults))))
+
+(defvar LaTeX-alltt-package-options nil
+ "Package options for the alltt package.")
+
+;;; alltt.el ends here
--- /dev/null
+;;; alphanum.el --- AUCTeX style for `alphanum.sty'
+
+;; Copyright (C) 2004 Free Software Foundation, Inc.
+
+;; Author: Frank Küster <frank@kuesterei.ch>
+;; Maintainer: auctex-devel@gnu.org
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This is file alphanum.el, which makes AUCTeX usable with jura.cls
+;; and its style file alphanum.sty.
+;;
+;; Contributed by Frank Küster <frank@kuesterei.ch>. The code for
+;; reftex has been written by Carsten Dominik, the maintainer of
+;; reftex, but all the errors are mine.
+
+;;; Code:
+
+
+(defun TeX-arg-none (arg)
+ (insert " "))
+
+(defun reftex-get-section-level-alphanum ()
+ (save-excursion ; preserve position
+ (save-match-data ; preserve matching data (important!)
+ ;; Go back to the beginning of the sectioning command
+ (goto-char (match-beginning 0))
+ ;; Define an initial level number, depending on the current macro.
+ (let* ((macro (reftex-match-string 3)) ; "toc" or "sub"
+ (lev (cond ((string= macro "toc") 1) ; min level for "toc"
+ ((string= macro "sub") 2) ; min level for "sub"
+ (t 0)))
+ ;; Make a regular expression which will match sectioning commands
+ ;; and the levelup macro.
+ (re (concat "\\(^[^%]*\\\\levelup\\>\\)"
+ "\\|"
+ "\\(" reftex-section-regexp "\\)")))
+ ;; Now parse backwards for all sectioning and levelup macros,
+ ;; and keep track of the relative level changes.
+ (while (re-search-backward re nil t)
+ (cond
+ ((match-beginning 1)
+ ;; levelup matched, reduce level counter
+ (setq lev (1- lev)))
+ ((string= (reftex-match-string 4) "toc")
+ ;; a toc entry, nothing changes
+ )
+ ((string= (reftex-match-string 4) "sub")
+ ;; a sub entry, increase level counter
+ (setq lev (1+ lev)))))
+ ;; return the level
+ lev))))
+
+(TeX-add-style-hook
+ "alphanum"
+ (lambda ()
+ (LaTeX-largest-level-set "chapter")
+ (TeX-add-symbols '("levelup" TeX-arg-none))
+ (make-local-variable 'LaTeX-section-list)
+ (LaTeX-section-list-add-locally
+ '(("part" 0)
+ ;; the levels don't make sense with alphanum, I randomly chose 0...
+ ("toc" 0)
+ ("sub" 0)) t)
+ (setq LaTeX-section-label
+ '(("part" . "part:")
+ ("toc" . "sec:")
+ ("sub" . "sec:")))
+ ;;
+ ;; ****************** reftex part ******************
+ ;; this won't work in multifile documents, but at least there is
+ ;; something.
+
+ (if (fboundp 'reftex-add-section-levels)
+ (reftex-add-section-levels
+ '(("toc" . reftex-get-section-level-alphanum)
+ ("sub" . reftex-get-section-level-alphanum))))))
+
+;; Local Variables:
+;; coding: iso-8859-1
+;; End:
--- /dev/null
+;;; amsart.el --- Style hook for the AMS-LaTeX article document class.
+
+;;; Code:
+
+(TeX-add-style-hook "amsart"
+ (function
+ (lambda ()
+ (TeX-run-style-hooks "amsmath" "amsthm"))))
+
+;;; amsart.el ends here.
--- /dev/null
+;;; amsbook.el --- Style hook for the AMS-LaTeX book document class.
+
+;;; Code:
+
+(TeX-add-style-hook "amsbook"
+ (function
+ (lambda ()
+ (TeX-run-style-hooks "amsmath" "amsthm"))))
+
+;;; amsbook.el ends here.
--- /dev/null
+;;; amsbsy.el --- Style hook for the AMS-LaTeX amsbsy package.
+;;;
+;;; AUTHOR: Carsten Dominik <dominik@strw.leidenuniv.nl>
+
+;;; Code:
+
+(TeX-add-style-hook "amsbsy"
+ (function
+ (lambda ()
+ (TeX-add-symbols
+ '("boldsymbol" "Symbol")
+ '("pmb" "Symbol")
+ ))))
+
+(defvar LaTeX-amsbsy-package-options nil
+ "Package options for the amsbsy package.")
+
+;;; amsbsy.el ends here.
--- /dev/null
+;;; amsmath.el --- Style hook for the AMS-LaTeX amsmath package.
+
+;; Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+;; FIXME: What about the copyright for <= 2001?
+
+;; Author: Carsten Dominik <dominik@strw.leidenuniv.nl>
+;; Maintainer: auctex-devel@gnu.org
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This will also load the amstext, amsbsy and amsopn style files.
+
+;;; Code:
+
+(TeX-add-style-hook "amsmath"
+ (function
+ (lambda ()
+
+ (LaTeX-add-environments
+ '("align" LaTeX-env-label)
+ '("gather" LaTeX-env-label)
+ '("flalign" LaTeX-env-label)
+ '("multline" LaTeX-env-label)
+ '("alignat" LaTeX-amsmath-env-alignat)
+ '("alignat*" LaTeX-amsmath-env-alignat)
+ '("xalignat" LaTeX-amsmath-env-alignat)
+ '("xalignat*" LaTeX-amsmath-env-alignat)
+ '("xxalignat" LaTeX-amsmath-env-alignat)
+ '("aligned" LaTeX-amsmath-env-aligned)
+ '("gathered" LaTeX-amsmath-env-aligned)
+ "align*" "gather*" "flalign*" "multline*" "equation*"
+ "split"
+ "cases"
+ "matrix" "smallmatrix" "pmatrix" "bmatrix" "Bmatrix" "vmatrix" "Vmatrix"
+ "subequations"
+ '("subarray" "Alignment"))
+
+ (TeX-add-symbols
+ '("eqref" TeX-arg-ref)
+ '("numberwithin" TeX-arg-counter "Section level")
+ '("raisetag" "Dimension")
+ '("intertext" t)
+ '("hdotsfor" ["Stretch"] "Number of columns to cover")
+ '("xleftarrow" ["Below"] "Above")
+ '("xrightarrow" ["Below"] "Above")
+ '("overset" "Accent symbol" "Symbol")
+ '("underset" "Accent symbol" "Symbol")
+ '("dfrac" 2)
+ '("tfrac" 2)
+ '("binom" 2)
+ '("dbinom" 2)
+ '("tbinom" 2)
+ '("genfrac" "Left delimiter" "Right delimiter" "Thickness"
+ "Mathstyle" 2)
+ '("cfrac" ["position (l or r)"] t)
+ '("smash" ["where (t or b)"] t)
+ '("sideset" "Left" "Right")
+ '("tag" "(Tag)")
+ '("tag*" "Tag")
+ '("displaybreak" ["Weight (0..4)"])
+ '("allowdisplaybreaks" ["Weight (1..4)"])
+ '("substack" t)
+ '("leftroot" "Push root index left by")
+ '("uproot" "Push root index upward by")
+ '("boxed" t)
+ '("mspace" t)
+ '("mod" t)
+ '("pmod" t)
+ '("pod" t)
+ '("overleftrightarrow" t)
+ '("underleftarrow" t)
+ '("underrightarrow" t)
+ '("underleftrightarrow" t)
+ '("dddot" t)
+ '("ddddot" t)
+ "bmod" "notag"
+ "dots" "dotsb" "dotsc" "dotsi" "dotsm" "dotso" "nobreakdash"
+ "lvert" "rvert" "lVert" "rVert"
+ "iint" "iiint" "iiiint" "idotsint"
+ )
+
+ (setq LaTeX-item-list
+ (append '(("split" . LaTeX-item-equation)
+ ("multline" . LaTeX-item-equation)
+ ("multline*" . LaTeX-item-equation)
+ ("gather" . LaTeX-item-equations)
+ ("gather*" . LaTeX-item-equation)
+ ("gathered" . LaTeX-item-equation)
+ ("align" . LaTeX-item-equations)
+ ("align*" . LaTeX-item-equation)
+ ("aligned" . LaTeX-item-equation)
+ ("alignat" . LaTeX-item-equations)
+ ("alignat*" . LaTeX-item-equation)
+ ("xalignat" . LaTeX-item-equations)
+ ("xalignat*" . LaTeX-item-equation)
+ ("xxalignat" . LaTeX-item-equation)
+ ("flalign" . LaTeX-item-equations)
+ ("flalign*" . LaTeX-item-equation)
+ ("matrix" . LaTeX-item-equation)
+ ("pmatrix" . LaTeX-item-equation)
+ ("bmatrix" . LaTeX-item-equation)
+ ("Bmatrix" . LaTeX-item-equation)
+ ("vmatrix" . LaTeX-item-equation)
+ ("Vmatrix" . LaTeX-item-equation)
+ ("cases" . LaTeX-item-equation))
+ LaTeX-item-list))
+
+ ;; When `LaTeX-amsmath-label' is nil, use value of LaTeX-equation-label:
+ (unless LaTeX-amsmath-label
+ (setq LaTeX-amsmath-label LaTeX-equation-label))
+
+ (setq LaTeX-label-alist
+ (append '(("align" . LaTeX-amsmath-label)
+ ("alignat" . LaTeX-amsmath-label)
+ ("xalignat" . LaTeX-amsmath-label)
+ ("multline" . LaTeX-amsmath-label)
+ ("flalign" . LaTeX-amsmath-label)
+ ("gather" . LaTeX-amsmath-label))
+ LaTeX-label-alist))
+
+ ;; amsmath includes amstext, amsbsy, & amsopn.
+ ;; So we run their hooks, too.
+ (TeX-run-style-hooks "amstext" "amsbsy" "amsopn")
+
+ ;; If RefTeX is loaded, make it recognize the amsmath environments.
+ (when (fboundp 'reftex-add-to-label-alist)
+ (reftex-add-to-label-alist '(AMSTeX))))))
+
+(defun LaTeX-amsmath-env-alignat (env)
+ (let ((ncols (read-string "Number of columns: ")))
+ (LaTeX-insert-environment env (concat TeX-grop ncols TeX-grcl))
+ (and (not (string= "xxalignat" env))
+ (not (string= "*" (substring env -1)))
+ (LaTeX-label env)
+ (newline-and-indent))))
+
+(defun LaTeX-amsmath-env-aligned (env)
+ (let ((where (read-string "(optional) Vertical position (t or b): ")))
+ (if (string= where "")
+ (setq where "")
+ (setq where (concat "[" where "]")))
+ (LaTeX-insert-environment env where)))
+
+(defun LaTeX-item-equation ()
+ (end-of-line 0)
+ (just-one-space)
+ (insert "\\\\")
+ (forward-line 1)
+ (indent-according-to-mode))
+
+(defun LaTeX-item-equations ()
+ (LaTeX-item-equation)
+ (let ((environment (LaTeX-current-environment 1)))
+ (and (LaTeX-label environment)
+ (newline-and-indent))))
+
+(defvar LaTeX-amsmath-package-options '("intlimits" "nointlimits"
+ "sumlimits" "nosumlimits"
+ "namelimits" "nonamelimits"
+ "leqno" "reqno" "centertags"
+ "tbtags" "cmex10" "fleqn" "?")
+ "Package options for the amsmath package.")
+
+;;; amsmath.el ends here.
--- /dev/null
+;;; amsopn.el --- Style hook for the AMS-LaTeX amsopn package.
+;;;
+;;; AUTHOR: Carsten Dominik <dominik@strw.leidenuniv.nl>
+
+;;; Code:
+
+(TeX-add-style-hook "amsopn"
+ (function
+ (lambda ()
+ (TeX-add-symbols
+ '("DeclareMathOperator" "Operator (with \\)" "Text")
+ '("DeclareMathOperator*" "Operator (with \\)" "Text")
+ '("operatorname" t)
+ '("operatorname*" t)))))
+
+(defvar LaTeX-amsopn-package-options '("namelimits" "nonamelimits")
+ "Package options for the amsopn package.")
+
+;;; amsopn.el ends here.
--- /dev/null
+;;; amstex.el --- AMS-LaTeX support.
+
+;; Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+;; Maintainer: auctex-devel@gnu.org
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file is only needed when using AMS-LaTeX 1.1 and LaTeX 2.09.
+;; In later versions of LaTeX and AMS-LaTeX this file is never used,
+;; because there is no longer a class or package name amstex.
+;;
+;; As far as AUCTeX is concerned, the old amstex style is fairly
+;; similar to the new amsmath package. So we will just run that hook
+;; here.
+;;
+;; amsmath.el should not be loaded, if an AMS-TeX (in contrast to
+;; AMS-LaTeX) file is opened. The commands defined in amsmath.el
+;; mostly have no meaning in this case and errors about unknown
+;; variables or functions may occur due to latex.el possibly not being
+;; loaded.
+
+;;; Code:
+
+(TeX-add-style-hook
+ "amstex"
+ (function
+ (lambda ()
+ (unless (memq major-mode '(plain-tex-mode ams-tex-mode))
+ (TeX-run-style-hooks "amsmath")))))
+
+(defvar LaTeX-amstex-package-options '("noamsfonts" "psamsfonts"
+ "intlimits" "nointlimits"
+ "sumlimits" "nosumlimits"
+ "namelimits" "nonamelimits"
+ "leqno" "reqno" "centertags"
+ "tbtags" "fleqn" "righttag"
+ "ctagsplt" "intlim" "nosumlim"
+ "nonamelm")
+ "Package options for the amstex package.")
+
+;;; amstex.el ends here.
--- /dev/null
+;;; amstext.el --- Style hook for the AMS-LaTeX amstext package.
+;;;
+;;; AUTHOR: Carsten Dominik <dominik@strw.leidenuniv.nl>
+
+;;; Code:
+
+(TeX-add-style-hook "amstext"
+ (function
+ (lambda ()
+ (TeX-add-symbols
+ '("text" t)))))
+
+(defvar LaTeX-amstext-package-option nil
+ "Package options for the amstext package.")
+
+;;; amstext.el ends here.
--- /dev/null
+;;; amsthm.el --- Style hook for the AMS-LaTeX amsthm package.
+
+;; Copyright (C) 1997 Free Software Foundation, Inc.
+
+;; Author: Carsten Dominik <dominik@strw.leidenuniv.nl>
+;; Maintainer: auctex-devel@gnu.org
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Code:
+
+(TeX-add-style-hook "amsthm"
+ (function
+ (lambda ()
+ (LaTeX-add-environments
+ '("proof" (lambda (env &rest ignore)
+ (LaTeX-insert-environment
+ env
+ (let ((heading (read-string "(optional) Heading: ")))
+ (if (string= heading "")
+ ""
+ (format "[%s]" heading))))))
+ )
+ (TeX-add-symbols
+ '("newtheorem" "Environment name" ["Share numbering with"] "Heading"
+ ["Number subordinated in each"])
+ '("newtheorem*" "Environment name" "Heading")
+ '("theoremstyle" LaTeX-amsthm-complete-theoremstyle)
+ ))))
+
+(defun LaTeX-amsthm-complete-theoremstyle (&rest ignore)
+ (insert TeX-grop
+ (completing-read "Style: " '(("plain" . nil)
+ ("definition" . nil)
+ ("remark" . nil)))
+ TeX-grcl))
+
+;;; amsthm.el ends here
--- /dev/null
+;;; article.el - Special code for article style.
+
+;; $Id: article.el,v 1.4 2005/03/17 10:02:06 angeli Exp $
+
+;;; Code:
+
+(TeX-add-style-hook
+ "article"
+ (lambda ()
+ (LaTeX-largest-level-set "section")))
+
+;;; article.el ends here
--- /dev/null
+;;; austrian.el --- AUCTeX style for the `austrian' babel option.
+
+;; Copyright (C) 2009 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@caeruleus.net>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2009-12-28
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; Set up AUCTeX for editing Austrian text in connection with the
+;; `austrian' babel option.
+
+;;; Code:
+
+(TeX-add-style-hook
+ "austrian"
+ (lambda ()
+ (TeX-run-style-hooks "german")))
+
+;;; austrian.el ends here
--- /dev/null
+;;; babel.el --- AUCTeX style for `babel.sty'
+
+;; Copyright (C) 2005 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@iwi.uni-sb.de>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2005-05-29
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `babel.sty'.
+
+;;; Code:
+
+(defvar LaTeX-babel-language-list
+ '("acadian" "afrikaans" "american" "austrian""bahasa" "basque" "brazil"
+ "brazilian" "breton" "british" "bulgarian" "canadian" "canadien"
+ "catalan" "croatian" "czech" "danish" "dutch" "english" "esperanto"
+ "estonian" "finnish" "francais" "frenchb" "french" "galician"
+ "german" "germanb" "greek" "polutonikogreek" "hebrew" "hungarian"
+ "icelandic" "irish" "italian" "latin" "lowersorbian" "magyar"
+ "naustrian" "ngerman" "norsk" "samin" "nynorsk" "polish" "portuges"
+ "portuguese" "romanian" "russian" "scottish" "serbian" "slovak"
+ "slovene" "spanish" "swedish" "turkish" "ukrainian" "uppersorbian"
+ "welsh" "UKenglish" "USenglish")
+ "List of languages supported by the babel LaTeX package.")
+
+(if (fboundp 'defvaralias)
+ (defvaralias 'LaTeX-babel-package-options 'LaTeX-babel-language-list)
+ (defvar LaTeX-babel-package-options LaTeX-babel-language-list
+ "Package options for the babel package."))
+
+(defun LaTeX-babel-active-languages ()
+ "Return a list of languages used in the document."
+ (let (active-languages)
+ (dolist (elt LaTeX-babel-language-list)
+ (when (member elt TeX-active-styles)
+ (add-to-list 'active-languages (list elt))))
+ active-languages))
+
+(defun TeX-arg-babel-lang (optional &optional prompt)
+ "Prompt for a language with completion and insert it as an argument."
+ (TeX-argument-insert
+ (completing-read "Language: " (LaTeX-babel-active-languages)) nil))
+
+(defun LaTeX-env-babel-lang (env)
+ "Prompt for a language and insert it as an argument of ENV."
+ (LaTeX-insert-environment
+ env (format "{%s}" (completing-read "Language: "
+ (LaTeX-babel-active-languages)))))
+
+(TeX-add-style-hook
+ "babel"
+ (lambda ()
+ ;; New symbols
+ (TeX-add-symbols
+ '("selectlanguage" TeX-arg-babel-lang)
+ '("foreignlanguage" TeX-arg-babel-lang t)
+ "languagename"
+ '("iflanguage" TeX-arg-babel-lang t nil)
+ '("useshorthands" t)
+ '("defineshorthand" t nil)
+ '("aliasshorthand" t nil)
+ '("languageshorthands" TeX-arg-babel-lang)
+ '("shorthandon" t)
+ '("shorthandoff" t)
+ '("languageattribute" TeX-arg-babel-lang t))
+ ;; New environments
+ (LaTeX-add-environments
+ '("otherlanguage" LaTeX-env-babel-lang)
+ '("otherlanguage*" LaTeX-env-babel-lang)
+ '("hyphenrules" LaTeX-env-babel-lang))
+ ;; Fontification
+ (when (and (featurep 'font-latex)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ (font-latex-add-keywords '(("selectlanguage" "{")
+ ("foreignlanguage" "{{")
+ ("iflanguage" "{{{")
+ ("languagename" "")
+ ("useshorthands" "{")
+ ("languageshorthands" "{")
+ ("shorthandon" "{")
+ ("shorthandoff" "{"))
+ 'function)
+ (font-latex-add-keywords '(("defineshorthand" "{{")
+ ("aliasshorthand" "{{")
+ ("languageattribute" "{{"))
+ 'variable))))
+
+;;; babel.el ends here
--- /dev/null
+;;; beamer.el --- AUCTeX style for the latex-beamer class
+
+;; Copyright (C) 2003, 2004, 2005,2008 Free Software Foundation
+
+;; Author: Thomas Baumann <thomas.baumann@ch.tum.de>
+;; Created: 2003-12-20
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for the latex-beamer class.
+
+;;; Code:
+
+(defun LaTeX-beamer-after-insert-env (env start end)
+ "Do beamer-specific stuff after the insertion of an environment."
+ ;; Add `fragile' as an optional argument to the frame environment if
+ ;; a verbatim environment is inserted.
+ (when (and (TeX-member env (LaTeX-verbatim-environments) 'string-equal)
+ (save-excursion
+ (goto-char start)
+ (string-equal (LaTeX-current-environment) "frame")))
+ (save-excursion
+ (when (re-search-backward "\\\\begin[ \t]*{frame}" nil t)
+ (let ((end-of-begin (match-end 0)))
+ (goto-char end-of-begin)
+ (while (forward-comment 1))
+ (if (eq (char-after) (string-to-char LaTeX-optop))
+ (progn
+ (forward-char)
+ (insert "fragile")
+ (unless (looking-at (concat "[ \t]*" LaTeX-optcl))
+ (insert ",")))
+ (goto-char end-of-begin)
+ (insert "[fragile]")))))))
+
+(TeX-add-style-hook
+ "beamer"
+ (lambda ()
+ (add-hook 'LaTeX-after-insert-env-hooks 'LaTeX-beamer-after-insert-env nil t)
+
+ (unless LaTeX-beamer-section-labels-flag
+ (make-local-variable 'LaTeX-section-hook)
+ (setq LaTeX-section-hook
+ '(LaTeX-section-heading
+ LaTeX-section-title
+ LaTeX-section-section)))
+
+ (setq LaTeX-item-list
+ (append '(("itemize" . LaTeX-item-beamer)
+ ("enumerate" . LaTeX-item-beamer))
+ LaTeX-item-list))
+
+ (LaTeX-paragraph-commands-add-locally "frametitle")
+
+ (TeX-add-symbols
+ '("alert" 1)
+ '("alt" TeX-arg-beamer-overlay-spec 2)
+ '("beamerbutton" 1)
+ '("beamergotobutton" 1)
+ '("beamerreturnbutton" 1)
+ '("beamerskipbutton" 1)
+ '("frame" TeX-arg-beamer-frametitle)
+ '("frametitle" 1)
+ '("hyperlink" TeX-arg-beamer-overlay-spec 2)
+ '("hyperlinkslideprev" TeX-arg-beamer-overlay-spec 1)
+ '("hyperlinkslidenext" TeX-arg-beamer-overlay-spec 1)
+ '("hyperlinkframestart" TeX-arg-beamer-overlay-spec 1)
+ '("hyperlinkframeend" TeX-arg-beamer-overlay-spec 1)
+ '("hyperlinkframestartnext" TeX-arg-beamer-overlay-spec 1)
+ '("hyperlinkframeendprev" TeX-arg-beamer-overlay-spec 1)
+ '("hyperlinkpresentationstart" TeX-arg-beamer-overlay-spec 1)
+ '("hyperlinkpresentationend" TeX-arg-beamer-overlay-spec 1)
+ '("hyperlinkappendixstart" TeX-arg-beamer-overlay-spec 1)
+ '("hyperlinkappendixend" TeX-arg-beamer-overlay-spec 1)
+ '("hyperlinkdocumentstart" TeX-arg-beamer-overlay-spec 1)
+ '("hyperlinkdocumentend" TeX-arg-beamer-overlay-spec 1)
+ '("hypertarget" TeX-arg-beamer-overlay-spec 2)
+ '("institute" 1)
+ '("invisible" TeX-arg-beamer-overlay-spec 1)
+ '("label" TeX-arg-beamer-overlay-spec 1)
+ '("logo" 1)
+ '("note" TeX-arg-beamer-note 1)
+ '("only" TeX-arg-beamer-overlay-spec 1)
+ '("onslide" TeX-arg-beamer-overlay-spec)
+ '("partpage")
+ '("pause")
+ '("structure" TeX-arg-beamer-overlay-spec 1)
+ '("temporal" TeX-arg-beamer-overlay-spec 3)
+ '("titlepage")
+ '("titlegraphic" 1)
+ '("uncover" TeX-arg-beamer-overlay-spec 1)
+ '("usetheme" LaTeX-arg-beamer-theme)
+ '("useinnertheme" LaTeX-arg-beamer-inner-theme)
+ '("useoutertheme" LaTeX-arg-beamer-outer-theme)
+ '("usecolortheme" LaTeX-arg-beamer-color-theme)
+ '("usefonttheme" LaTeX-arg-beamer-font-theme)
+ '("usetheme" LaTeX-arg-beamer-theme)
+ '("visible" TeX-arg-beamer-overlay-spec 1))
+
+ (LaTeX-add-environments
+ '("actionenv")
+ '("alertblock" 1)
+ '("beamerboxesrounded" 1)
+ '("block" 1)
+ '("column" "Width")
+ "columns"
+ "columnsonlytextwidth"
+ '("exampleblock" 1)
+ '("frame" (lambda (env &rest ignore)
+ (let ((title (read-string "(Optional) Title: ")))
+ (LaTeX-insert-environment env)
+ (unless (zerop (length title))
+ (save-excursion
+ (LaTeX-find-matching-begin)
+ (end-of-line)
+ (LaTeX-newline)
+ (insert (format "\\frametitle{%s}" title))
+ ;; This works because \frametitle is a
+ ;; paragraph command.
+ (backward-char)
+ (LaTeX-fill-paragraph))))))
+ '("onlyenv" (lambda (env &rest ignore)
+ (LaTeX-insert-environment
+ env
+ (let ((overlay (read-string "(Optional) Overlay: ")))
+ (unless (zerop (length overlay))
+ (format "<%s>" overlay))))))
+ '("overlayarea" "Area width" "Area height")
+ '("overprint" (lambda (env &rest ignore)
+ (LaTeX-insert-environment
+ env
+ (let ((width (read-string "(Optional) Area width: ")))
+ (unless (zerop (length width))
+ (format "[%s]" width))))))
+ "semiverbatim")
+
+ (make-local-variable 'LaTeX-indent-environment-list)
+ (add-to-list 'LaTeX-indent-environment-list
+ '("semiverbatim" current-indentation))
+ (make-local-variable 'LaTeX-verbatim-regexp)
+ (setq LaTeX-verbatim-regexp (concat LaTeX-verbatim-regexp "\\|semiverbatim"))
+ (add-to-list 'LaTeX-verbatim-environments-local "semiverbatim")
+
+ ;; Fontification
+ (when (and (featurep 'font-latex)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ (font-latex-add-keywords '(("frametitle" "<[{")) 'slide-title)
+ ;; For syntactic fontification, e.g. verbatim constructs.
+ (font-latex-set-syntactic-keywords)
+ ;; Tell font-lock about the update.
+ (setq font-lock-set-defaults nil)
+ (font-lock-set-defaults))))
+
+(defun TeX-arg-beamer-overlay-spec (optional &optional prompt)
+ "Prompt for overlay specification."
+ (let ((overlay (read-string "(Optional) Overlay: ")))
+ (unless (zerop (length overlay))
+ (insert "<" overlay ">"))
+ (indent-according-to-mode)))
+
+(defun TeX-arg-beamer-frametitle (optional &optional prompt)
+ "Prompt for the frametitle."
+ (let ((title (read-string "Title: ")))
+ (if (not (zerop (length title)))
+ (insert TeX-grop TeX-esc "frametitle" TeX-grop
+ title TeX-grcl TeX-grcl)
+ (insert TeX-grop TeX-grcl))))
+
+(defun LaTeX-item-beamer ()
+ "Insert a new item with an optional overlay argument. You
+can turn off the prompt for the overlay argument by setting
+`LaTeX-beamer-item-overlay-flag' to nil. Calling the function
+with a prefix argument prompts for the overlay specification
+unconditionally."
+ (if (listp current-prefix-arg)
+ (setq current-prefix-arg (car current-prefix-arg))
+ current-prefix-arg)
+ (TeX-insert-macro "item")
+ (delete-horizontal-space)
+ (if (or current-prefix-arg LaTeX-beamer-item-overlay-flag)
+ (TeX-arg-beamer-overlay-spec 0))
+ (insert " ")
+ (indent-according-to-mode))
+
+(defun TeX-arg-beamer-note (optional &optional prompt)
+ "Prompt for overlay specification and optional argument."
+ (let ((overlay (read-string "(Optional) Overlay: "))
+ (options (read-string "(Optional) Options: ")))
+ (unless (zerop (length overlay))
+ (insert "<" overlay ">"))
+ (unless (zerop (length options))
+ (insert "[" options "]"))
+ (indent-according-to-mode)))
+
+(defun LaTeX-beamer-search-themes (&optional regexp extensions length)
+ "Search for beamer themes matching REGEXP with EXTENSIONS.
+The function removes the first LENGTH characters and the
+extension of the file and returns a list of strings. LENGTH may
+also be a string. Then the length of the string is used."
+ (let* ((match (or regexp "^beamertheme[A-Z]"))
+ (exts (or extensions '("tex" "sty")))
+ (chars (cond ((integerp length)
+ length)
+ ((stringp length)
+ (string-width length))
+ ;; Try some DWIM magic...
+ ((and (not length)
+ (string-match "beamer[A-Za-z0-9]*theme" match))
+ (- (match-end 0) (match-beginning 0)))
+ (t (error "Invalid length: `%s'" length)))))
+ ;; (message "match=`%s' chars=`%s'" match chars)
+ (TeX-delete-duplicate-strings
+ (delete nil
+ (mapcar
+ (lambda (file)
+ (let ((case-fold-search nil))
+ (and (numberp (string-match match file))
+ (substring file chars))))
+ (TeX-search-files nil exts t t))))))
+
+(defun LaTeX-arg-beamer-theme (&rest ignore)
+ "Prompt for beamer theme with completion."
+ (TeX-argument-insert
+ (completing-read
+ (TeX-argument-prompt nil nil "Theme")
+ (mapcar 'list
+ (cond ((eq LaTeX-beamer-themes 'local)
+ (set (make-local-variable 'LaTeX-beamer-themes)
+ (LaTeX-beamer-search-themes)))
+ ((functionp LaTeX-beamer-themes)
+ (funcall LaTeX-beamer-themes))
+ ((listp LaTeX-beamer-themes)
+ LaTeX-beamer-themes)
+ (t (error
+ "`LaTeX-beamer-themes' should be a list: `%s'"
+ LaTeX-beamer-themes))))
+ nil nil nil)
+ t))
+
+(defun LaTeX-arg-beamer-inner-theme (&rest ignore)
+ "Prompt for beamer inner theme with completion."
+ (TeX-argument-insert
+ (completing-read
+ (TeX-argument-prompt nil nil "Theme")
+ (mapcar 'list
+ (cond ((eq LaTeX-beamer-inner-themes 'local)
+ (set (make-local-variable 'LaTeX-beamer-inner-themes)
+ (LaTeX-beamer-search-themes "^beamerinnertheme")))
+ ((functionp LaTeX-beamer-inner-themes)
+ (funcall LaTeX-beamer-inner-themes))
+ ((listp LaTeX-beamer-inner-themes)
+ LaTeX-beamer-inner-themes)
+ (t (error
+ "`LaTeX-beamer-inner-themes' should be a list: `%s'"
+ LaTeX-beamer-inner-themes))))
+ nil nil nil)
+ t))
+
+(defun LaTeX-arg-beamer-outer-theme (&rest ignore)
+ "Prompt for beamer outer theme with completion."
+ (TeX-argument-insert
+ (completing-read
+ (TeX-argument-prompt nil nil "Theme")
+ (mapcar 'list
+ (cond ((eq LaTeX-beamer-outer-themes 'local)
+ (set (make-local-variable 'LaTeX-beamer-outer-themes)
+ (LaTeX-beamer-search-themes "^beameroutertheme")))
+ ((functionp LaTeX-beamer-outer-themes)
+ (funcall LaTeX-beamer-outer-themes))
+ ((listp LaTeX-beamer-outer-themes)
+ LaTeX-beamer-outer-themes)
+ (t (error
+ "`LaTeX-beamer-outer-themes' should be a list: `%s'"
+ LaTeX-beamer-outer-themes))))
+ nil nil nil)
+ t))
+
+(defun LaTeX-arg-beamer-color-theme (&rest ignore)
+ "Prompt for beamer color theme with completion."
+ (TeX-argument-insert
+ (completing-read
+ (TeX-argument-prompt nil nil "Theme")
+ (mapcar 'list
+ (cond ((eq LaTeX-beamer-color-themes 'local)
+ (set (make-local-variable 'LaTeX-beamer-color-themes)
+ (LaTeX-beamer-search-themes "^beamercolortheme")))
+ ((functionp LaTeX-beamer-color-themes)
+ (funcall LaTeX-beamer-color-themes))
+ ((listp LaTeX-beamer-color-themes)
+ LaTeX-beamer-color-themes)
+ (t (error
+ "`LaTeX-beamer-color-themes' should be a list: `%s'"
+ LaTeX-beamer-color-themes))))
+ nil nil nil)
+ t))
+
+(defun LaTeX-arg-beamer-font-theme (&rest ignore)
+ "Prompt for beamer font theme with completion."
+ (TeX-argument-insert
+ (completing-read
+ (TeX-argument-prompt nil nil "Theme")
+ (mapcar 'list
+ (cond ((eq LaTeX-beamer-font-themes 'local)
+ (set (make-local-variable 'LaTeX-beamer-font-themes)
+ (LaTeX-beamer-search-themes "^beamerfonttheme")))
+ ((functionp LaTeX-beamer-font-themes)
+ (funcall LaTeX-beamer-font-themes))
+ ((listp LaTeX-beamer-font-themes)
+ LaTeX-beamer-font-themes)
+ (t (error
+ "`LaTeX-beamer-font-themes' should be a list: `%s'"
+ LaTeX-beamer-font-themes))))
+ nil nil nil)
+ t))
+
+;;; beamer.el ends here
--- /dev/null
+;;; book.el - Special code for book style.
+
+;; $Id: book.el,v 1.5 2005/03/17 10:02:06 angeli Exp $
+
+;;; Code:
+
+(TeX-add-style-hook
+ "book"
+ (lambda ()
+ (LaTeX-largest-level-set "chapter")))
+
+;;; book.el ends here
--- /dev/null
+;;; booktabs.el -- AUCTeX style for booktabs.sty
+
+;; Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@iwi.uni-sb.de>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2003-10-21
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `booktabs.sty'.
+
+;;; Code:
+
+(defun LaTeX-booktabs-arg-paren (optional prompt)
+ "Prompt for a value and use parentheses when it is inserted.
+If OPTIONAL is non-nil the parameter is labeled as optional.
+PROMPT is the value of the prompt to be shown."
+ (let ((< "\(")
+ (> "\)"))
+ (TeX-parse-argument optional prompt)))
+
+(TeX-add-style-hook
+ "booktabs"
+ (lambda ()
+
+ ;; New symbols
+ (TeX-add-symbols
+ '("toprule" [ "Thickness" ])
+ '("midrule" [ "Thickness" ])
+ '("bottomrule" [ "Thickness" ])
+ ;; FIXME: The qestion for the trim parameter will only be asked if
+ ;; a value for the thickness parameter was given. Is this a
+ ;; feature of `TeX-parse-arguments'?
+ '("cmidrule" [ "Thickness" ] [ LaTeX-booktabs-arg-paren "Trim" ]
+ "Column(s)")
+ '("addlinespace" [ "Height" ])
+ '("morecmidrules")
+ '("specialrule" "Thickness" "Space above" "Space below"))
+
+ ;; Fontification
+ (when (and (featurep 'font-latex)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ (font-latex-add-keywords '(("toprule" "[")
+ ("midrule" "[")
+ ("bottomrule" "[")
+ ("cmidrule" "[({")
+ ("addlinespace" "[")
+ ("morecmidrules" "")
+ ("specialrule" "{{{"))
+ 'function))))
+
+(defvar LaTeX-booktabs-package-options nil
+ "Package options for the booktabs package.")
+
+;;; booktabs.el ends here
--- /dev/null
+;;; bulgarian.el --- AUCTeX style for the `bulgarian' babel option.
+
+;; Copyright (C) 2008 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@caeruleus.net>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2008-06-28
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; Set up AUCTeX for editing Bulgarian text in connection with the
+;; `bulgarian' babel option.
+
+;;; Code:
+
+(defvar LaTeX-bulgarian-mode-syntax-table
+ (copy-syntax-table LaTeX-mode-syntax-table)
+ "Syntax table used in LaTeX mode when using `bulgarian.sty'.")
+
+(modify-syntax-entry ?\" "w" LaTeX-bulgarian-mode-syntax-table)
+
+(TeX-add-style-hook
+ "bulgarian"
+ (lambda ()
+ (set-syntax-table LaTeX-bulgarian-mode-syntax-table)
+ (setq TeX-quote-language `("bulgarian" "\"`" "\"'" ,TeX-quote-after-quote))
+ (setq LaTeX-babel-hyphen-language "bulgarian")
+ ;; Fontification of quotation marks.
+ (when (fboundp 'font-latex-add-quotes)
+ (font-latex-add-quotes '("\"`" "\"'"))
+ (font-latex-add-quotes '("\"<" "\">" french)))
+ (run-hooks 'TeX-language-bg-hook)))
+
+;;; bulgarian.el ends here
--- /dev/null
+;; captcont.el --- AUCTeX style file for captcont.sty
+
+;; Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+
+;; Author: Reiner Steib <Reiner.Steib@gmx.de>
+;; Maintainer: auctex-devel@gnu.org
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; AUCTeX style file for captcont.sty
+
+;;; Code:
+
+(TeX-add-style-hook
+ "captcont"
+ (lambda ()
+ (TeX-add-symbols
+ '("captcont" [ "list entry" ] "Caption")
+ '("captcont*" [ "list entry" ] "Caption"))
+ ;; Fontification
+ (when (featurep 'font-latex)
+ (font-latex-add-keywords '(("captcont" "*[{")) 'textual))))
+
+(defvar LaTeX-captcont-package-options '("figbotcap" "figtopcap" "tabbotcap"
+ "tabtopcap")
+ "Package options for the captcont package.")
+
+;;; captcont.el ends here
--- /dev/null
+;;; comment.el --- AUCTeX style for `comment.sty'
+
+;; Copyright (C) 2007 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@caeruleus.net>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2007-03-18
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+;; 02111-1307, USA.
+
+;;; Commentary:
+
+;; This file adds support for `comment.sty'.
+
+;;; Code:
+
+(TeX-add-style-hook
+ "comment"
+ (lambda ()
+ ;; New symbols
+ (TeX-add-symbols
+ '("includecomment" "Name")
+ '("excludecomment" "Name")
+ '("specialcomment" "Name" "Before commands" "After commands")
+ '("processcomment" "Name" "Each-line commands"
+ "Before commands" "After commands"))
+ ;; New environments
+ (mapc 'LaTeX-add-environments LaTeX-comment-env-list)
+ ;; Fontification
+ (when (and (featurep 'font-latex)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ ;; For syntactic fontification.
+ (add-to-list 'font-latex-syntactic-keywords-extra
+ ;; \begin is supposed to start at the beginning of a line.
+ `(,(format "^\\\\begin *{\\(?:%s\\)}.*\\(\n\\)"
+ (regexp-opt LaTeX-comment-env-list))
+ (1 "<" t)))
+ (add-to-list 'font-latex-syntactic-keywords-extra
+ ;; \end is supposed to start at the beginning of a line.
+ `(,(format "^\\(\\\\\\)end *{\\(?:%s\\)}"
+ (regexp-opt LaTeX-comment-env-list))
+ (1 ">" t)))
+ (font-latex-set-syntactic-keywords)
+ (font-latex-add-keywords '(("includecomment" "{")
+ ("excludecomment" "{")
+ ("specialcomment" "{{{")
+ ("processcomment" "{{{{"))
+ 'variable)
+ ;; Tell font-lock about the update.
+ (setq font-lock-set-defaults nil)
+ (font-lock-set-defaults))))
+
+;;; comment.el ends here
--- /dev/null
+;;; csquotes.el --- AUCTeX style for `csquotes.sty'
+
+;; Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@caeruleus.net>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2004-11-29
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `csquotes.sty', version 3.7.
+
+
+;;; Code:
+
+;; FIXME: It would be nice to be able to dump this function in favor
+;; of a generalized handling of additional arguments for environments
+;; specified via `LaTeX-add-environments'. `TeX-parse-arguments' and
+;; friends would be the functions to be used for that, but those
+;; functions currently insert text directly into the buffer. There
+;; would either have to be a way of preventing this and letting them
+;; return a string, or the insertion could happen in a temporary buffer
+;; and the buffer content be returned.
+(defun LaTeX-csquotes-insert-environment (env &rest args)
+ "Insert environment ENV considering optional arguments ARGS.
+
+This is basically a variant of `LaTeX-environment-menu'
+specialized for csquotes.el. ARGS can be made up of strings and
+vectors containing single strings. Plain strings will be used as
+prompts for mandatory arguments and strings in vectors as prompts
+for optional arguments of the environment to be inserted.
+
+That means, in contrast to `LaTeX-environment-menu' it supports
+the insertion of optional arguments."
+ (let (env-extra prompt optional user-input)
+ (dolist (elt args)
+ (if (vectorp elt)
+ (setq prompt (aref elt 0)
+ optional t)
+ (setq prompt elt
+ optional nil))
+ (setq user-input (read-string (TeX-argument-prompt optional prompt nil)))
+ (unless (and optional (zerop (length user-input)))
+ (setq env-extra (concat env-extra
+ (if optional LaTeX-optop TeX-grop)
+ user-input
+ (if optional LaTeX-optcl TeX-grcl)))))
+ (LaTeX-insert-environment env env-extra)))
+
+(TeX-add-style-hook
+ "csquotes"
+ (lambda ()
+ (let ((quote-style-variant-list '(("quotes") ("guillemets") ("american")
+ ("british") ("oldstyle") ("imprimerie")
+ ("swiss")))
+ (quote-style-name-list '(("danish") ("dutch") ("english") ("finnish")
+ ("french") ("german") ("italian")
+ ("norwegian") ("swedish"))))
+ ;; New symbols
+ (TeX-add-symbols
+ '("enquote" 1)
+ '("enquote*" 1)
+ '("foreignquote" 2)
+ '("foreignquote*" 2)
+ '("hyphenquote" 2)
+ '("hyphenquote*" 2)
+ '("textquote" ["Citation"] ["Punctuation"] t)
+ '("textquote*" ["Citation"] ["Punctuation"] t)
+ '("foreigntextquote" "Language" ["Citation"] ["Punctuation"] t)
+ '("foreigntextquote*" "Language" ["Citation"] ["Punctuation"] t)
+ '("hyphentextquote" "Language" ["Citation"] ["Punctuation"] t)
+ '("hyphentextquote*" "Language" ["Citation"] ["Punctuation"] t)
+ '("blockquote" ["Citation"] ["Punctuation"] t)
+ '("foreignblockquote" "Language" ["Citation"] ["Punctuation"] t)
+ '("hyphenblockquote" "Language" ["Citation"] ["Punctuation"] t)
+ `("setquotestyle"
+ [ (TeX-arg-eval completing-read "Quote style variant: "
+ ',quote-style-variant-list) ]
+ (TeX-arg-eval completing-read "Quote style name or alias: "
+ ',quote-style-name-list))
+ "setquotestyle*"
+ '("MakeInnerQuote" "Character")
+ '("MakeOuterQuote" "Character")
+ '("MakeAutoQuote" "Opening quotation mark" "Closing quotation mark")
+ '("MakeAutoQuote*" "Opening quotation mark" "Closing quotation mark")
+ '("MakeForeignQuote" "Babel's language name"
+ "Opening quotation mark" "Closing quotation mark")
+ '("MakeForeignQuote*" "Babel's language name"
+ "Opening quotation mark" "Closing quotation mark")
+ '("MakeHyphenQuote" "Babel's language name"
+ "Opening quotation mark" "Closing quotation mark")
+ '("MakeHyphenQuote" "Babel's language name"
+ "Opening quotation mark" "Closing quotation mark")
+ '("MakeBlockQuote" "Opening quotation mark" "Delimiter for citation"
+ "Closing quotation mark")
+ '("MakeForeignBlockQuote" "Language" "Opening quotation mark"
+ "Delimiter for citation" "Closing quotation mark")
+ '("MakeHyphenBlockQuote" "Language" "Opening quotation mark"
+ "Delimiter for citation" "Closing quotation mark")
+ "EnableQuotes"
+ "DisableQuotes"
+ "VerbatimQuotes"
+ "DeleteQuotes"
+ '("textcquote" ["Pre-note"] ["Post-note"] "Key" ["Punctuation"] t)
+ '("textcquote*" ["Pre-note"] ["Post-note"] "Key" ["Punctuation"] t)
+ '("foreigntextcquote" "Language" ["Pre-note"] ["Post-note"] "Key"
+ ["Punctuation"] t)
+ '("foreigntextcquote*" "Language" ["Pre-note"] ["Post-note"] "Key"
+ ["Punctuation"] t)
+ '("hyphentextcquote" "Language" ["Pre-note"] ["Post-note"] "Key"
+ ["Punctuation"] t)
+ '("hyphentextcquote*" "Language" ["Pre-note"] ["Post-note"] "Key"
+ ["Punctuation"] t)
+ '("blockcquote" ["Pre-note"] ["Post-note"] "Key" ["Punctuation"] t)
+ '("foreignblockcquote" "Language" ["Pre-note"] ["Post-note"] "Key"
+ ["Punctuation"] t)
+ '("hyphenblockcquote" "Language" ["Pre-note"] ["Post-note"] "Key"
+ ["Punctuation"] t)
+ `("DeclareQuoteStyle"
+ [ (TeX-arg-eval completing-read "Quote style variant: "
+ ',quote-style-variant-list) ]
+ (TeX-arg-eval completing-read "Quote style name: "
+ ',quote-style-name-list)
+ ["Outer quote initialization"] ["Inner quote initialization"]
+ "Opening outer quotation mark" ["Middle outer quotation mark"]
+ "Closing outer quotation mark" ["Kerning between adjoining marks"]
+ "Opening inner quotation mark" ["Middle inner quotation mark"]
+ "Closing inner quotation mark")
+ `("DeclareQuoteAlias"
+ [ (TeX-arg-eval completing-read "Quote style variant: "
+ ',quote-style-variant-list) ]
+ (TeX-arg-eval completing-read "Quote style name: "
+ ',quote-style-name-list)
+ "Alias name")
+ '("DeclareQuoteOption" 1)
+ '("ExecuteQuoteOptions" 1)
+ '("DeclarePlainStyle" "Opening outer quotation mark"
+ "Closing outer quotation mark" "Opening inner quotation mark"
+ "Closing inner quotation mark")
+ '("SetBlockThreshold" "Number of lines")
+ '("SetBlockEnvironment" "Environment")
+ '("SetCiteCommand" "Command")
+ "mkcitation"
+ "mkccitation"
+ "mkpreblockpunct"
+ "mkmidblockpunct"
+ "mkfinblockpunct"
+ "mkpretextpunct"
+ "mkmidtextpunct"
+ "mkfintextpunct"
+ "mkpredisppunct"
+ "mkmiddisppunct"
+ "mkfindisppunct"
+ '("ifblockquote" 2)
+ '("ifquotepunct" 2)
+ '("ifquoteterm" 2)
+ '("ifquoteperiod" 2)
+ '("ifquotecomma" 2)
+ '("ifquotesemicolon" 2)
+ '("ifquotecolon" 2)
+ '("ifquoteexclam" 2)
+ '("ifquotequestion" 2)
+ '("ifstringblank" 2)
+ '("BlockquoteDisable" 1))
+ ;; New environments
+ (LaTeX-add-environments
+ "quoteblock"
+ "quotetext"
+ '("displayquote" LaTeX-csquotes-insert-environment ["Citation"]
+ ["Punctuation"])
+ '("foreigndisplayquote" LaTeX-csquotes-insert-environment "Language"
+ ["Citation"] ["Punctuation"])
+ '("hyphendisplayquote" LaTeX-csquotes-insert-environment "Language"
+ ["Citation"] ["Punctuation"])
+ '("displaycquote" LaTeX-csquotes-insert-environment
+ ["Pre-note"] ["Post-note"] "Key" ["Punctuation"])
+ '("foreigndisplaycquote" LaTeX-csquotes-insert-environment
+ "Language" ["Pre-note"] ["Post-note"] "Key" ["Punctuation"])
+ '("hyphendisplaycquote" LaTeX-csquotes-insert-environment
+ "Language" ["Pre-note"] ["Post-note"] "Key" ["Punctuation"]))
+ ;; Quotation marks
+ (when (and (> (length LaTeX-csquotes-open-quote) 0)
+ (> (length LaTeX-csquotes-close-quote) 0))
+ (setq TeX-quote-language
+ `(override ,LaTeX-csquotes-open-quote ,LaTeX-csquotes-close-quote
+ ,LaTeX-csquotes-quote-after-quote)))
+ ;; Fontification
+ (when (and (featurep 'font-latex)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ (font-latex-add-keywords '(("DisableQuotes" "")
+ ("RestoreQuotes" ""))
+ 'function)
+ (font-latex-add-keywords '(("enquote" "*{")
+ ("foreignquote" "*{{")
+ ("hyphenquote" "*{{")
+ ("textcquote" "*[[{[{")
+ ("foreigntextcquote" "*{[[{[{")
+ ("hyphentextcquote" "*{[[{[{")
+ ("textquote" "*[[{")
+ ("foreigntextquote" "*{[[{")
+ ("hyphentextquote" "*{[[{")
+ ("blockquote" "[[{")
+ ("foreignblockquote" "{[[{")
+ ("hyphenblockquote" "{[[{")
+ ("blockcquote" "[[{[{")
+ ("foreignblockcquote" "{[[{[{")
+ ("hyphenblockcquote" "{[[{[{"))
+ 'textual)
+ (font-latex-add-keywords '(("setquotestyle" "[{")
+ ("MakeOuterQuote" "{")
+ ("MakeInnerQuote" "{")
+ ("MakeAutoQuote" "*{{")
+ ("MakeForeignQuote" "*{{{")
+ ("MakeHyphenQuote" "*{{{")
+ ("MakeBlockQuote" "{{{")
+ ("MakeForeignBlockQuote" "{{{{")
+ ("MakeHyphenBlockQuote" "{{{{")
+ ("DeclareQuoteStyle" "[{[[{[{[{[{")
+ ("DeclareQuoteAlias" "[{{")
+ ("DeclareQuoteOption" "{")
+ ("DeclarePlainStyle" "{{{{")
+ ("SetBlockThreshold" "{")
+ ("SetBlockEnvironment" "{")
+ ("SetCiteCommand" "{"))
+ 'variable)))))
+
+;;; csquotes.el ends here
--- /dev/null
+;;; czech.el --- Setup AUCTeX for editing Czech text.
+
+(TeX-add-style-hook
+ "czech"
+ (lambda ()
+ (setq TeX-quote-language `("czech" "\\uv{" "}" ,TeX-quote-after-quote))
+ (run-hooks 'TeX-language-cz-hook)))
--- /dev/null
+;;; danish.el --- Setup AUCTeX for editing Danish text.
+
+;;; Code:
+
+(TeX-add-style-hook
+ "danish"
+ (lambda ()
+ (setq TeX-quote-language `("danish" "\"`" "\"'" ,TeX-quote-after-quote))
+ (setq LaTeX-babel-hyphen-language "danish")
+ ;; Fontification of quotation marks.
+ (when (fboundp 'font-latex-add-quotes)
+ (font-latex-add-quotes '("\"`" "\"'"))
+ (font-latex-add-quotes '("\"<" "\">" french)))
+ (run-hooks 'TeX-language-dk-hook)))
+
+;;; danish.el ends here
--- /dev/null
+;;; dk-bib.el --- AUCTeX style for `dk-bib.sty'
+
+;; Copyright (C) 2005 Free Software Foundation, Inc.
+
+;; Author: Arne Jørgensen <arne@arnested.dk>
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+;; MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Prompt for package option for dk-bib.sty.
+
+;;; Code:
+
+(defun LaTeX-dk-bib-package-options nil
+ "Prompt for package options for the dk-bib package."
+ (let ((options
+ (mapconcat 'identity
+ (TeX-completing-read-multiple
+ "Options: "
+ '(("isbn") ("issn") ("url") ("annote")
+ ("printing") ("apalike") ("fixcitedash=false")
+ ("ordinals2word") ("ordinaldepth=")))
+ ","))
+ (depth -1))
+ (when (string-match "\\(ordinaldepth=\\)\\([^0-9]\\|$\\)" options)
+ (while (or (< depth 0)
+ (> depth 20))
+ (setq depth (if (fboundp 'read-number)
+ (read-number "Ordinal depth: ")
+ (string-to-number (read-string "Ordinal depth: "))))
+ (when (or (< depth 0)
+ (> depth 20))
+ (message "Ordinal depth must be between 0 and 20")
+ (sit-for 1)))
+ (setq options (concat
+ (substring options 0 (match-end 1))
+ (number-to-string depth)
+ (substring options (match-end 1)))))
+ options))
+
+;; Local Variables:
+;; coding: iso-8859-1
+;; End:
+
+;;; dk-bib.el ends here
--- /dev/null
+;;; dk.el - Setup AUC TeX for editing Danish text.
+
+;; $Id: dk.el,v 1.2 1993/12/15 21:42:40 amanda Exp $
+
+;;; Code:
+
+(TeX-add-style-hook "dk"
+ (function (lambda ()
+ (run-hooks 'TeX-language-dk-hook))))
+
+;;; dk.el ends here
--- /dev/null
+;;; doc.el --- AUCTeX style for `doc.sty'
+
+;; Copyright (C) 2004, 2008 Free Software Foundation, Inc.
+
+;; Author: Frank Küster <frank@kuesterei.ch>
+;; Maintainer: auctex-devel@gnu.org
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `doc.sty'.
+
+;;; Code:
+
+(defun LaTeX-env-no-comment (environment)
+ "Insert ENVIRONMENT and make sure there is no commented empty line inside."
+ (LaTeX-insert-environment environment)
+ (unless (TeX-active-mark)
+ (when (save-excursion
+ (beginning-of-line)
+ (looking-at (concat "[ \t]+$\\|[ \t]*"
+ TeX-comment-start-regexp "+[ \t]*$")))
+ (delete-region (line-beginning-position) (line-end-position))
+ (indent-according-to-mode))))
+
+(defun LaTeX-doc-after-insert-macrocode (env start end)
+ "Make sure the macrocode environment is properly formatted after insertion."
+ (when (TeX-member env '("macrocode" "macrocode*") 'string-equal)
+ (save-excursion
+ (goto-char end)
+ (skip-chars-backward " \t")
+ (when (bolp)
+ (insert "%")
+ (indent-according-to-mode))
+ (goto-char start)
+ (skip-chars-backward " \t")
+ (when (bolp)
+ (insert "%")
+ (indent-according-to-mode)))))
+
+(TeX-add-style-hook
+ "doc"
+ (function
+ (lambda ()
+ (add-to-list (make-local-variable 'LaTeX-indent-environment-list)
+ '("macrocode" current-indentation))
+ (add-to-list 'LaTeX-indent-environment-list
+ '("macrocode*" current-indentation))
+ (add-hook 'LaTeX-after-insert-env-hooks 'LaTeX-doc-after-insert-macrocode
+ nil t)
+ (LaTeX-add-environments
+ "theglossary"
+ '("macrocode" LaTeX-env-no-comment)
+ '("macrocode*" LaTeX-env-no-comment)
+ '("macro" "Macro"))
+ (TeX-add-symbols
+ "EnableCrossrefs"
+ "DisableCrossrefs"
+ "DoNotIndex"
+ "DontCheckModules"
+ "CheckModules"
+ "Module"
+ '("DescribeMacro" "Macro")
+ '("DescribeEnv" "Environment")
+ "verbatim"
+ "verb"
+ "parg"
+ "oarg"
+ "marg"
+ "meta"
+ "cmd"
+ "makelabel"
+ "MacroFont"
+ "MacroFont"
+ "AltMacroFont"
+ "AltMacroFont"
+ "PrintMacroName"
+ "PrintDescribeMacro"
+ "PrintDescribeEnv"
+ "PrintEnvName"
+ "MakePrivateLetters"
+ "actualchar"
+ "quotechar"
+ "levelchar"
+ "encapchar"
+ "verbatimchar"
+ "SpecialIndex"
+ "SpecialMainIndex"
+ "SpecialMainEnvIndex"
+ "SpecialUsageIndex"
+ "SpecialEnvIndex"
+ "SortIndex"
+ "LeftBraceIndex"
+ "RightBraceIndex"
+ "PercentIndex"
+ "OldMakeindex"
+ "PercentIndex"
+ "IndexPrologue"
+ "IndexParms"
+ "subitem"
+ "subsubitem"
+ "indexspace"
+ "efill"
+ "pfill"
+ "PrintIndex"
+ '("changes" "version" "date (YYYY/MM/DD)")
+ "generalname"
+ "RecordChanges"
+ "GlossaryPrologue"
+ "GlossaryParms"
+ "PrintChanges"
+ "AlsoImplementation"
+ "StopEventually"
+ "OnlyDescription"
+ "Finale"
+ "IndexInput"
+ "maketitle"
+ "MakeShortVerb"
+ "DeleteShortVerb"
+ "MakeShortverb"
+ "DeleteShortverb"
+ "CheckSum"
+ "CharacterTable"
+ "CharTableChanges"
+ "CodelineNumbered"
+ "CodelineIndex"
+ "PageIndex"
+ "theCodelineNo"
+ "theCodelineNo"
+ "DocstyleParms"
+ "MakePercentIgnore"
+ "MakePercentComment"
+ "DocInput"
+ "DocInclude"
+ "GetFileInfo"
+ "filename"
+ "fileinfo"))))
+
+;; Local Variables:
+;; coding: iso-8859-1
+;; End:
--- /dev/null
+;;; dutch.el - Setup AUC TeX for editing Dutch text.
+
+;; $Id: dutch.el,v 1.2 1993/12/15 21:42:42 amanda Exp $
+
+;;; Code:
+
+(TeX-add-style-hook "dutch"
+ (function (lambda ()
+ (run-hooks 'TeX-language-nl-hook))))
+
+;;; dutch.el ends here
--- /dev/null
+;;; emp.el --- AUCTeX support for emp.sty
+
+;; Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+;; Author: Yvon Henel aka TeXnicien de surface <Yvon.Henel@wanadoo.fr>
+;; Maintainer: auctex-devel@gnu.org
+;; Keywords: tex
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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; see the file COPYING. If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;; version 1.0 2004-03-04
+
+;;; Code:
+
+
+(TeX-add-style-hook "emp"
+ (function
+ (lambda ()
+ (TeX-add-symbols "empuse" "empTeX" "empaddtoTeX"
+ "emprelude" "empaddtoprelude" "unitlength"
+ )
+ (LaTeX-add-environments
+ '("empfile" LaTeX-env-empfile)
+ '("emp" LaTeX-env-emp-gen)
+ '("empdef" LaTeX-env-emp-gen)
+ '("empgraph" LaTeX-env-emp-gen)
+ '("empcmds")
+ ))))
+
+(defun LaTeX-env-emp-gen (environment-name)
+ "Ask for file, width and length. Insert environment-name environment
+Used for emp, empdef, and empgraph environments."
+ (let ((emp-fig-name (read-string "figure name: " ""))
+ (emp-fig-width (read-string "figure width: " "1" ))
+ (emp-fig-height (read-string "figure height: " "1" ))
+ ;;; emp.sty demands a width and a height for each of the
+ ;;; emp, empdef, and empgraph environments
+ ;;; we give them 1 by default
+ ;;; not necessarily the best thing to do?
+ )
+ (if (not (zerop (length emp-fig-name)))
+ (progn
+ (setq LaTeX-emp-fig-name (concat LaTeX-optop emp-fig-name LaTeX-optcl))
+ (LaTeX-insert-environment environment-name LaTeX-emp-fig-name))
+ (LaTeX-insert-environment environment-name))
+ (forward-line -1)
+ (end-of-line)
+ (insert "(" emp-fig-width "," emp-fig-height ")")
+ (forward-line 1)
+ (indent-according-to-mode)
+ ))
+
+(defun LaTeX-env-empfile (optional)
+ "Ask for file. Insert empfile environment"
+ (let ((empfile (read-string "empfile: " "")))
+ (if (not (zerop (length empfile)))
+ (progn
+ (setq LaTeX-emp-file-name (concat LaTeX-optop empfile LaTeX-optcl))
+ (setq mpost-emp-file-name (concat empfile ".mp"))
+ (LaTeX-insert-environment "empfile" LaTeX-emp-file-name))
+ (progn
+ (setq mpost-emp-file-name "\\jobname")
+ (LaTeX-insert-environment "empfile")))
+ (if LaTeX-write18-enabled-p
+ (progn
+ (forward-line 1)
+ (end-of-line)
+ (newline-and-indent)
+ (insert "\\immediate\\write18{mpost -tex=latex " mpost-emp-file-name TeX-grcl)
+ (forward-line -2)))))
+;;; emp.el ends here
--- /dev/null
+;;; fancyref.el --- AUCTeX style file with support for fancyref.sty
+
+;; Copyright (C) 1999 Free Software Foundation, Inc.
+
+;; Author: Carsten Dominik <dominik@strw.leidenuniv.nl>
+;; Maintainer: auctex-devel@gnu.org
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Code:
+
+(TeX-add-style-hook "fancyref"
+ (lambda ()
+
+ (TeX-add-symbols
+
+ ;; The macros with label arguments
+ '("fref" [ TeX-arg-fancyref-format ] TeX-arg-label)
+ '("Fref" [ TeX-arg-fancyref-format ] TeX-arg-label)
+
+ ;; The macros which define new prefixes and formats
+ '("fancyrefchangeprefix" TeX-arg-macro "Prefix")
+ '("Frefformat" TeX-arg-fancyref-format TeX-arg-macro "Output")
+ '("frefformat" TeX-arg-fancyref-format TeX-arg-macro "Output")
+
+ ;; The delimiter
+ "fancyrefargdelim"
+
+ ;; All those names and abbreviations.
+ ;; Part
+ "fancyrefpartlabelprefix"
+ "Frefpartname" "frefpartname"
+ ;; Chapter
+ "fancyrefchalabelprefix"
+ "Frefchaname" "frefchaname"
+ ;; Section
+ "fancyrefseclabelprefix"
+ "Frefsecname" "frefsecname"
+ ;; Equation
+ "fancyrefeqlabelprefix"
+ "Frefeqname" "frefeqname"
+ ;; Figure
+ "fancyreffiglabelprefix"
+ "Freffigname" "freffigname" "Freffigshortname"
+ ;; Footnote
+ "fancyreffnlabelprefix"
+ "Freffnname" "freffnname"
+ ;; Item
+ "fancyrefitemlabelprefix"
+ "Frefitemname" "frefitemname"
+ ;; Table
+ "fancyreftablabelprefix"
+ "Freftabname" "freftabname" "Freftabshortname"
+ ;; Page
+ "Frefpgname" "frefpgname" "Frefpgshortname"
+ ;; On
+ "Frefonname" "frefonname"
+ ;; See
+ "Frefseename" "frefseename"
+
+ ;; The spacing macros
+ "fancyrefloosespacing" "fancyreftightspacing" "fancyrefdefaultspacing"
+
+ ;; And the hook
+ "fancyrefhook")
+
+ ;; Insatall completion for labels and formats
+ (setq TeX-complete-list
+ (append
+ '(("\\\\[fF]ref\\(\\[[^]]*\\]\\)?{\\([^{}\n\r\\%,]*\\)"
+ 2 LaTeX-label-list "}")
+ ("\\\\[fF]ref\\[\\([^{}\n\r\\%,]*\\)"
+ 1 LaTeX-fancyref-formats "]")
+ ("\\\\[fF]refformat{\\([^{}\n\r\\%,]*\\)"
+ 1 LaTeX-fancyref-formats "}"))
+ TeX-complete-list))
+ ;; Fontification
+ (when (and (featurep 'font-latex)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ (font-latex-add-keywords '(("fref" "[{") ("Fref" "[{")) 'reference))))
+
+;; The following list keeps a list of available format names
+;; Note that this list is only updated when a format is used, not
+;; during buffer parsing. We could install a regexp to look for
+;; formats, but this would not work in multifile documents since the
+;; formats are not written out to the auto files.
+;; For now, we just leave it at that.
+(defvar LaTeX-fancyref-formats '(("plain") ("vario") ("margin") ("main"))
+ "List of formats for fancyref.")
+
+(defun LaTeX-fancyref-formats () LaTeX-fancyref-formats)
+
+(defun TeX-arg-fancyref-format (optional &optional prompt definition)
+ "Prompt for a fancyref format name.
+If the user gives an unknown name, add it to the list."
+ (let ((format (completing-read (TeX-argument-prompt optional prompt "Format")
+ LaTeX-fancyref-formats)))
+ (if (not (string-equal "" format))
+ (add-to-list 'LaTeX-fancyref-formats (list format)))
+ (TeX-argument-insert format optional)))
+
+(defvar LaTeX-fancyref-package-options '("english" "german" "loose"
+ "margin" "paren" "plain" "tight"
+ "vario")
+ "Package options for the fancyref package.")
+
+;;; fancyref.el ends here
--- /dev/null
+;;; flashcards.el --- AUCTeX style for the flashcards class.
+
+;; Copyright (C) 2007 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@caeruleus.net>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2007-04-23
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for the flashcards class.
+
+;;; Code:
+
+(TeX-add-style-hook
+ "flashcards"
+ (lambda ()
+ (TeX-add-symbols
+ '("cardfrontstyle" ["Format"] "Style")
+ '("cardfrontfoot" "Footer text")
+ '("cardbackstyle" ["Format"] "Style")
+ '("cardfrontheadstyle" ["Format"] "Style")
+ '("cardfrontfootstyle" ["Format"] "Style")
+ "cardmargin"
+ "cardpaper"
+ "cardpapermode"
+ "cardrows"
+ "cardcolumns"
+ "cardheight"
+ "cardwidth")
+ (LaTeX-add-environments '("flashcard" ["Header"] "Front side"))
+ ;; Fontification
+ (when (and (fboundp 'font-latex-add-keywords)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ (font-latex-add-keywords '(("cardfrontstyle" "[{")
+ ("cardfrontfoot" "{")
+ ("cardbackstyle" "[{")
+ ("cardfrontheadstyle" "[{")
+ ("cardfrontfootstyle" "[{"))
+ 'variable))))
+
+;;; flashcards.el ends here
--- /dev/null
+;;; foils.el - Special code for FoilTeX.
+
+;; $Id: foils.el,v 1.5 2008/07/28 20:40:18 angeli Exp $
+
+;;; Code:
+
+(require 'timezone)
+
+(TeX-add-style-hook "foils"
+ (function
+ (lambda ()
+ (add-hook 'LaTeX-document-style-hook 'LaTeX-style-foils)
+ (setq LaTeX-default-style "foils")
+ (setq LaTeX-default-options '("landscape"))
+ (TeX-add-symbols
+ '("foilhead" [ "Rubric-body separation" ] "Foil rubric")))))
+
+(defun LaTeX-style-foils nil
+ "Prompt for and insert foiltex options."
+ (let* ((date (timezone-parse-date (current-time-string)))
+ (year (string-to-number (aref date 0)))
+ (month (string-to-number (aref date 1)))
+ (day (string-to-number (aref date 2)))
+ (title (read-string "Title: ")))
+ (save-excursion
+ (goto-char (point-max))
+ (re-search-backward ".begin.document.")
+ (insert TeX-esc "title"
+ TeX-grop title TeX-grcl "\n")
+ (insert TeX-esc "author"
+ TeX-grop (user-full-name) TeX-grcl "\n")
+ (insert TeX-esc "date" TeX-grop
+ (format "%d-%02d-%02d" year month day)
+ TeX-grcl "\n")
+ (insert "" TeX-esc "MyLogo" TeX-grop TeX-grcl "\n")
+ (insert "%" TeX-esc "Restriction" TeX-grop TeX-grcl "\n")
+ (insert "%" TeX-esc "rightfooter" TeX-grop TeX-grcl "\n")
+ (insert "%" TeX-esc "leftheader" TeX-grop TeX-grcl "\n")
+ (insert "%" TeX-esc "rightheader" TeX-grop TeX-grcl "\n\n")
+ (re-search-forward ".begin.document.")
+ (end-of-line)
+ (newline-and-indent)
+ (insert "" TeX-esc "maketitle\n\n"))
+ (forward-line -1)))
+
+;;; foils.el ends here
--- /dev/null
+;;; francais.el --- AUCTeX style for the `francais' babel option.
+
+;; Copyright (C) 2005 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@iwi.uni-sb.de>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2005-10-28
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; Set up AUCTeX for editing French text. In particular for commands
+;; provided by the `francais' option of the `babel' LaTeX package. As
+;; this is equivalent to the `frenchb' option, this file only loads
+;; `frenchb.el'.
+
+;;; Code:
+
+(TeX-add-style-hook
+ "francais"
+ (lambda ()
+ (TeX-run-style-hooks "frenchb")))
+
+;;; francais.el ends here
--- /dev/null
+;;; frenchb.el --- AUCTeX style for the `frenchb' babel option.
+
+;; Copyright (C) 2005 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@iwi.uni-sb.de>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2005-10-28
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; Set up AUCTeX for editing French text. In particular for commands
+;; provided by the `frenchb' option of the `babel' LaTeX package. The
+;; `frenchb' option is equivalent to the `francais' option and since
+;; babel version 3.7j with the `french' option. `french', however, is
+;; ambiguous because another package by that name made by Bernard
+;; Gaulle could be loaded. In order to avoid this, either `frenchb'
+;; (or `francais') or `frenchle' (or `frenchPRO') should be used. See
+;; the documentation of `frenchb' at
+;; <URL:http://daniel.flipo.free.fr/frenchb/frenchb-doc.pdf>.
+
+;;; Code:
+
+(TeX-add-style-hook
+ "frenchb"
+ (lambda ()
+ (TeX-add-symbols
+ "og"
+ "fg"
+ "up"
+ "ier"
+ "iere"
+ "iers"
+ "ieres"
+ "ieme"
+ "iemes"
+ '("bsc" t)
+ "primo"
+ "secundo"
+ "tertio"
+ "quarto"
+ "No"
+ "no"
+ "degre"
+ "degres"
+ "DecimalMathComma"
+ "StandardMathComma"
+ '("nombre" "Nombre")
+ "ThinSpaceInFrenchNumbers"
+ "FrenchLayout"
+ "StandardLayout")
+ (setq TeX-quote-language
+ `("french" "\\og "
+ (lambda ()
+ (concat "\\fg"
+ (unless (member "xspace" TeX-active-styles) "{}")))
+ ,TeX-quote-after-quote))
+ (run-hooks 'TeX-language-fr-hook)))
+
+;;; frenchb.el ends here
--- /dev/null
+;;; german.el --- Setup AUCTeX for editing German text.
+
+;;; Commentary:
+;;
+;; Cater for some specialities of `(n)german.sty', e.g. special quote
+;; and hyphen strings or that `"' makes the following letter an
+;; umlaut.
+
+;;; Code:
+
+(defvar LaTeX-german-mode-syntax-table
+ (copy-syntax-table LaTeX-mode-syntax-table)
+ "Syntax table used in LaTeX mode when using `german.sty'.")
+
+(modify-syntax-entry ?\" "w" LaTeX-german-mode-syntax-table)
+
+(TeX-add-style-hook
+ "german"
+ (lambda ()
+ (set-syntax-table LaTeX-german-mode-syntax-table)
+ ;; XXX: Handle former customizations of the now defunct
+ ;; German-specific variables. References to the respective
+ ;; variables are to be deleted in future versions. (now = 2005-04-01)
+ (unless (eq (car TeX-quote-language) 'override)
+ (let ((open-quote (if (and (boundp 'LaTeX-german-open-quote)
+ LaTeX-german-open-quote)
+ LaTeX-german-open-quote
+ "\"`"))
+ (close-quote (if (and (boundp 'LaTeX-german-close-quote)
+ LaTeX-german-close-quote)
+ LaTeX-german-close-quote
+ "\"'"))
+ (q-after-q (if (and (boundp 'LaTeX-german-quote-after-quote)
+ LaTeX-german-quote-after-quote)
+ LaTeX-german-quote-after-quote
+ t)))
+ (setq TeX-quote-language
+ `("german" ,open-quote ,close-quote ,q-after-q))))
+ (setq LaTeX-babel-hyphen-language "german")
+ ;; Fontification of quotation marks.
+ (when (fboundp 'font-latex-add-quotes)
+ (font-latex-add-quotes '("\"`" "\"'"))
+ (font-latex-add-quotes '("\">" "\"<" german)))
+ (run-hooks 'TeX-language-de-hook)))
+
+;;; german.el ends here
--- /dev/null
+;;; graphics.el --- Handle graphical commands in LaTeX 2e.
+
+;;; Code:
+
+(TeX-add-style-hook "graphics"
+ (function
+ (lambda ()
+ (TeX-run-style-hooks "graphicx"))))
+
+;;; graphics.el ends here.
--- /dev/null
+;;; graphicx.el --- AUCTeX style file for graphicx.sty
+
+;; Copyright (C) 2000, 2004, 2005 by Free Software Foundation, Inc.
+
+;; Author: Ryuichi Arafune <arafune@debian.org>
+;; Created: 1999/3/20
+;; Keywords: tex
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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; see the file COPYING. If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This package supports the includegraphcics macro in graphicx style.
+
+;; Acknowledgements
+;; Dr. Thomas Baumann <thomas.baumann@ch.tum.de>
+;; David Kastrup <David.Kastrup@t-online.de>
+;; Masayuki Akata <ataka@milk.freemail.ne.jp>
+
+;;; Code:
+
+(TeX-add-style-hook
+ "graphicx"
+ (lambda ()
+ (TeX-add-symbols
+ '("reflectbox" "Argument")
+ '("resizebox" "Width" "Height" "Argument")
+ '("resizebox*" "Width" "Total height" "Argument")
+ '("rotatebox" [ "Options" ] "Angle" "Argument")
+ '("scalebox" "Horizontal scale" [ "Vertical scale" ] "Argument")
+ '("includegraphics" LaTeX-arg-includegraphics))
+ ;; Fontification
+ (when (and (featurep 'font-latex)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ (font-latex-add-keywords '(("reflectbox" "{")
+ ("resizebox" "*{{{")
+ ("rotatebox" "[{{")
+ ("scalebox" "{[{"))
+ 'textual)
+ (font-latex-add-keywords '(("includegraphics" "*[[{")) 'reference))))
+
+(defun LaTeX-includegraphics-extensions (&optional list)
+ "Return appropriate extensions for input files to \\includegraphics."
+ ;; FIXME: This function may check for latex/pdflatex later.
+ (concat "\\."
+ (mapconcat 'identity
+ (or list LaTeX-includegraphics-extensions)
+ "$\\|\\.")
+ "$"))
+
+(defun LaTeX-includegraphics-read-file-TeX ()
+ "Read image file for \\includegraphics.
+Offers all graphic files found in the TeX search path. See
+`LaTeX-includegraphics-read-file' for more."
+ ;; Drop latex/pdflatex differences for now. Might be (re-)included later.
+ (completing-read
+ "Image file: "
+ (TeX-delete-dups-by-car
+ (mapcar 'list
+ (TeX-search-files nil LaTeX-includegraphics-extensions t t)))
+ nil nil nil))
+
+(defun LaTeX-includegraphics-read-file-relative ()
+ "Read image file for \\includegraphics.
+
+Lists all graphic files in the master directory and its
+subdirectories and inserts the relative file name. This option
+doesn't works with Emacs 21.3 or XEmacs. See
+`LaTeX-includegraphics-read-file' for more."
+ (file-relative-name
+ (read-file-name
+ "Image file: " nil nil nil nil
+ ;; FIXME: Emacs 21.3 and XEmacs 21.4.15 dont have PREDICATE as the sixth
+ ;; argument (Emacs 21.3: five args; XEmacs 21.4.15: sixth is HISTORY).
+ (lambda (fname)
+ (or (file-directory-p fname)
+ (string-match (LaTeX-includegraphics-extensions) fname))))
+ (TeX-master-directory)))
+
+(defun LaTeX-arg-includegraphics (prefix)
+ "Ask for mandantory and optional arguments for the \\includegraphics command.
+
+The extent of the optional arguments is determined by the prefix argument and
+`LaTeX-includegraphics-options-alist'."
+ (let* ((maybe-left-brace "[")
+ (maybe-comma "")
+ show-hint
+ (image-file (funcall LaTeX-includegraphics-read-file))
+ (incl-opts
+ (cond
+ ((numberp
+ (if (listp current-prefix-arg)
+ (setq current-prefix-arg (car current-prefix-arg))
+ current-prefix-arg))
+ (cdr
+ (assq current-prefix-arg LaTeX-includegraphics-options-alist)))
+ ;; If no prefix is given, use `0' and tell the user about the
+ ;; prefix.
+ ((eq current-prefix-arg nil)
+ (setq show-hint t)
+ (cdr (assq 0 LaTeX-includegraphics-options-alist)))
+ (t
+ (cdr (assq 0 LaTeX-includegraphics-options-alist)))))
+ ;; Order the optional aruments like in the tables in epslatex.ps,
+ ;; page 14. But collect y-or-n options at the end, so that the use
+ ;; can skip some options by typing `RET RET ... RET n n n ... n'
+ ;;
+ ;; Options from Table 1 (epslatex.ps, page 14):
+ (totalheight
+ (TeX-arg-maybe
+ 'totalheight incl-opts
+ '(read-string
+ (concat "Total Height (" TeX-default-unit-for-image "): "))))
+ (height
+ (TeX-arg-maybe
+ 'height incl-opts
+ ;; Either totalheight or height make sense:
+ '(when (zerop (length totalheight))
+ (read-string
+ (concat "Figure height (" TeX-default-unit-for-image "): ")))))
+ (width
+ (TeX-arg-maybe
+ 'width incl-opts
+ '(read-string
+ (concat "Figure width (" TeX-default-unit-for-image "): "))))
+ (scale
+ (TeX-arg-maybe
+ 'angle incl-opts
+ ;; If size is already specified, don't ask for scale:
+ '(when (zerop (+ (length totalheight)
+ (length height)
+ (length width)))
+ (read-string "Scale: "))))
+ (angle
+ (TeX-arg-maybe
+ 'angle incl-opts
+ '(read-string "Rotation angle: ")))
+ (origin
+ (TeX-arg-maybe
+ 'origin incl-opts
+ '(read-string
+ (concat
+ "Origin (any combination of `lcr' (horizontal) "
+ "and `tcbB' (vertical)): "))))
+ (page ;; Not in any table; Only for PDF.
+ (TeX-arg-maybe
+ 'page incl-opts
+ '(read-string "Page: ")))
+ (bb
+ (TeX-arg-maybe
+ 'bb incl-opts
+ '(y-or-n-p "Set Bounding Box? ")))
+ ;; Table 2:
+ (viewport
+ (TeX-arg-maybe
+ 'viewport incl-opts
+ '(y-or-n-p "Set viewport? ")))
+ (trim
+ (TeX-arg-maybe
+ 'trim incl-opts
+ '(and (not viewport)
+ (y-or-n-p "Set trim? "))))
+ ;; Table 3:
+ (clip
+ (TeX-arg-maybe
+ 'clip incl-opts
+ ;; If viewport, we also use clip.
+ '(or viewport
+ (y-or-n-p "Clipping figure? "))))
+ (keepaspectratio
+ (TeX-arg-maybe
+ 'keepaspectratio incl-opts
+ ;; If we have width and [total]height...
+ '(or (and (not (zerop (length width)))
+ (or (not (zerop (length totalheight)))
+ (not (zerop (length height)))))
+ (y-or-n-p "Keep Aspectratio? "))))
+ ;; Used for bb, trim, viewport, ...:
+ llx lly urx ury)
+ ;; Now insert stuff...
+ (when (not (zerop (length totalheight)))
+ (insert
+ maybe-left-brace maybe-comma "totalheight="
+ (car (TeX-string-divide-number-unit totalheight))
+ (if (zerop
+ (length
+ (car (cdr (TeX-string-divide-number-unit totalheight)))))
+ TeX-default-unit-for-image
+ (car (cdr (TeX-string-divide-number-unit totalheight)))))
+ (setq maybe-comma ",")
+ (setq maybe-left-brace ""))
+ (when (not (zerop (length height)))
+ (insert maybe-left-brace maybe-comma
+ "height=" (car (TeX-string-divide-number-unit height))
+ (if (zerop
+ (length
+ (car (cdr (TeX-string-divide-number-unit height)))))
+ TeX-default-unit-for-image
+ (car (cdr (TeX-string-divide-number-unit height)))))
+ (setq maybe-comma ",")
+ (setq maybe-left-brace ""))
+ (when (not (zerop (length width)))
+ (insert maybe-left-brace maybe-comma
+ "width=" (car (TeX-string-divide-number-unit width))
+ (if (zerop
+ (length
+ (car (cdr (TeX-string-divide-number-unit width)))))
+ TeX-default-unit-for-image
+ (car (cdr (TeX-string-divide-number-unit width)))))
+ (setq maybe-comma ",")
+ (setq maybe-left-brace ""))
+ (when (not (zerop (length scale)))
+ (insert maybe-left-brace maybe-comma "scale=" scale)
+ (setq maybe-comma ",")
+ (setq maybe-left-brace ""))
+ (when (not (zerop (length angle)))
+ (insert maybe-left-brace maybe-comma "angle=" angle)
+ (setq maybe-comma ",")
+ (setq maybe-left-brace ""))
+ (when (not (zerop (length origin)))
+ (insert maybe-left-brace maybe-comma "origin=" origin)
+ (setq maybe-comma ",")
+ (setq maybe-left-brace ""))
+ (when bb
+ (setq llx (read-string "Bounding Box lower left x: "))
+ (setq lly (read-string "Bounding Box lower left y: "))
+ (setq urx (read-string "Bounding Box upper right x: "))
+ (setq ury (read-string "Bounding Box upper right y: "))
+ (insert maybe-left-brace maybe-comma
+ "bb=" llx " " lly " " urx " " ury)
+ (setq maybe-comma ",")
+ (setq maybe-left-brace ""))
+ ;;
+ (when viewport
+ (setq llx (read-string "Viewport lower left x: "))
+ (setq lly (read-string "Viewport lower left y: "))
+ (setq urx (read-string "Viewport upper right x: "))
+ (setq ury (read-string "Viewport upper right y: "))
+ (insert maybe-left-brace maybe-comma
+ "viewport=" llx " " lly " " urx " " ury)
+ (setq maybe-comma ",")
+ (setq maybe-left-brace ""))
+ (when trim
+ (setq llx (read-string "Trim lower left x: "))
+ (setq lly (read-string "Trim lower left y: "))
+ (setq urx (read-string "Trim Upper right x: "))
+ (setq ury (read-string "Trim Upper right y: "))
+ (insert maybe-left-brace maybe-comma
+ "trim=" llx " " lly " " urx " " ury)
+ (setq maybe-comma ",")
+ (setq maybe-left-brace ""))
+ ;;
+ (when clip
+ (insert maybe-left-brace maybe-comma "clip")
+ (setq maybe-comma ",")
+ (setq maybe-left-brace ""))
+ (when keepaspectratio
+ (insert maybe-left-brace maybe-comma "keepaspectratio")
+ (setq maybe-comma ",")
+ (setq maybe-left-brace ""))
+ ;;
+ (when (not (zerop (length page)))
+ (insert maybe-left-brace maybe-comma "page=" page)
+ (setq maybe-comma ",")
+ (setq maybe-left-brace ""))
+ ;;
+ (if (zerop (length maybe-left-brace))
+ (insert "]"))
+ (TeX-insert-braces 0)
+ (insert
+ (if LaTeX-includegraphics-strip-extension-flag
+ ;; We don't have `replace-regexp-in-string' in all (X)Emacs versions:
+ (with-temp-buffer
+ (insert image-file)
+ (goto-char (point-max))
+ (when (search-backward-regexp (LaTeX-includegraphics-extensions)
+ nil t 1)
+ (replace-match ""))
+ (buffer-string))
+ image-file))
+ (when show-hint
+ (message
+ (concat
+ "Adding `C-u C-u' before the command asks for more optional arguments."
+ "\nSee `LaTeX-includegraphics-options-alist' for details."))
+ (sit-for 3))
+ t))
+
+;;; graphicx.el ends here
--- /dev/null
+;;; harvard.el --- Support for Harvard Citation style package for AUCTeX.
+
+;; Harvard citation style is from Peter Williams
+;; available on the CTAN servers
+
+;; Version: $Id: harvard.el,v 1.10 2008/02/03 14:53:30 angeli Exp $
+
+;; Copyright (C) 1994 Berwin Turlach <berwin@core.ucl.ac.be>
+;; Copyright (C) 1997 Berwin Turlach <berwin.turlach@anu.edu.au>
+;; Copyright (C) 2005 Free Software Foundation, Inc.
+
+;; This program 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, or (at your option)
+;; any later version.
+;;
+;; This program 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 this program; if not, write to the Free Software Foundation,
+;; Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+;;; Code:
+
+(TeX-add-style-hook "harvard"
+ (function
+ (lambda ()
+
+ (LaTeX-add-environments
+ '("thebibliography" LaTeX-env-harvardbib ignore))
+
+ (TeX-add-symbols
+ "harvardand"
+ '("citeasnoun"
+ (TeX-arg-conditional TeX-arg-cite-note-p ([ "Note" ]) nil)
+ TeX-arg-cite)
+ '("possessivecite"
+ (TeX-arg-conditional TeX-arg-cite-note-p ([ "Note" ]) nil)
+ TeX-arg-cite)
+ '("citeaffixed"
+ (TeX-arg-conditional TeX-arg-cite-note-p ([ "Note" ]) nil)
+ TeX-arg-cite "Affix")
+ '("citeyear"
+ (TeX-arg-conditional TeX-arg-cite-note-p ([ "Note" ]) nil)
+ TeX-arg-cite)
+ '("citename"
+ (TeX-arg-conditional TeX-arg-cite-note-p ([ "Note" ]) nil)
+ TeX-arg-cite)
+ '("citationstyle"
+ (TeX-arg-eval completing-read "Citation style: " '(("agsm") ("dcu"))))
+ '("citationmode"
+ (TeX-arg-eval completing-read "Citation mode: "
+ '(("full") ("abbr") ("default"))))
+ '("harvardparenthesis"
+ (TeX-arg-eval completing-read "Harvardparenthesis: "
+ '(("round") ("curly") ("angle") ("square"))))
+ '("bibliographystyle"
+ (TeX-arg-eval
+ completing-read "Bibliography style: "
+ '(("agsm") ("apsr") ("dcu") ("jmr") ("jphysicsB") ("kluwer") ("nederlands") ("econometrica")))
+ ignore)
+ '("harvarditem" [ "Short citation" ]
+ "Complete citation" "Year" TeX-arg-define-cite))
+
+ (setq TeX-complete-list
+ (append '(("\\\\citeasnoun\\[[^]\n\r\\%]*\\]{\\([^{}\n\r\\%,]*\\)"
+ 1 LaTeX-bibitem-list "}")
+ ("\\\\citeasnoun{\\([^{}\n\r\\%,]*\\)" 1
+ LaTeX-bibitem-list "}")
+ ("\\\\possessivecite\\[[^]\n\r\\%]*\\]{\\([^{}\n\r\\%,]*\\)"
+ 1 LaTeX-bibitem-list "}")
+ ("\\\\possessivecite{\\([^{}\n\r\\%,]*\\)" 1
+ LaTeX-bibitem-list "}")
+ ("\\\\citename\\[[^]\n\r\\%]*\\]{\\([^{}\n\r\\%,]*\\)"
+ 1 LaTeX-bibitem-list "}")
+ ("\\\\citename{\\([^{}\n\r\\%,]*\\)" 1
+ LaTeX-bibitem-list "}")
+ ("\\\\citeaffixed\\[[^]\n\r\\%]*\\]{\\([^{}\n\r\\%,]*\\)"
+ 1 LaTeX-bibitem-list "}")
+ ("\\\\citeaffixed{\\([^{}\n\r\\%,]*\\)" 1
+ LaTeX-bibitem-list "}")
+ ("\\\\citeaffixed{\\([^{}\n\r\\%]*,\\)\\([^{}\n\r\\%,]*\\)"
+ 2 LaTeX-bibitem-list)
+ ("\\\\citeyear\\[[^]\n\r\\%]*\\]{\\([^{}\n\r\\%,]*\\)"
+ 1 LaTeX-bibitem-list "}")
+ ("\\\\citeyear{\\([^{}\n\r\\%,]*\\)" 1
+ LaTeX-bibitem-list "}")
+ ("\\\\citeyear{\\([^{}\n\r\\%]*,\\)\\([^{}\n\r\\%,]*\\)"
+ 2 LaTeX-bibitem-list))
+ TeX-complete-list))
+
+ (setq LaTeX-auto-regexp-list
+ (append '(("\\\\harvarditem{\\([a-zA-Z][^%#'()={}]*\\)}{\\([0-9][^, %\"#'()={}]*\\)}{\\([a-zA-Z][^, %\"#'()={}]*\\)}" 3 LaTeX-auto-bibitem)
+ ("\\\\harvarditem\\[[^][\n\r]+\\]{\\([a-zA-Z][^%#'()={}]*\\)}{\\([0-9][^, %\"#'()={}]*\\)}{\\([a-zA-Z][^, %\"#'()={}]*\\)}" 3 LaTeX-auto-bibitem)
+ )
+ LaTeX-auto-regexp-list))
+
+ (setq LaTeX-item-list
+ (cons '("thebibliography" . LaTeX-item-harvardbib)
+ LaTeX-item-list))
+
+ ;; Tell RefTeX
+ (when (fboundp 'reftex-set-cite-format)
+ (reftex-set-cite-format 'harvard)))))
+
+(defun LaTeX-env-harvardbib (environment &optional ignore)
+ "Insert ENVIRONMENT with label for harvarditem."
+ (LaTeX-insert-environment environment
+ (concat TeX-grop "xx" TeX-grcl))
+ (end-of-line 0)
+ (delete-char 1)
+ (delete-horizontal-space)
+ (LaTeX-insert-item))
+
+;; Analog to LaTeX-item-bib from latex.el
+(defun LaTeX-item-harvardbib ()
+ "Insert a new harvarditem."
+ (TeX-insert-macro "harvarditem"))
+
+(defvar LaTeX-harvard-package-options '("full" "abbr" "default"
+ "agsmcite" "dcucite" "round"
+ "curly" "angle" "square" "none")
+ "Package options for the harvard package.")
+
+;; harvard.el ends here
--- /dev/null
+;;; hyperref.el --- AUCTeX style for the hyperref class.
+
+;; Copyright (C) 2008 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@caeruleus.net>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2008-06-21
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for the hyperref package.
+
+;;; Code:
+
+(defvar LaTeX-hyperref-package-options
+ '("a4paper" "a5paper" "anchorcolor" "b5paper" "backref" "baseurl"
+ "bookmarks" "bookmarksnumbered" "bookmarksopen"
+ "bookmarksopenlevel \maxdimen" "bookmarkstype" "breaklinks"
+ "CJKbookmarks" "citebordercolor" "citecolor" "colorlinks" "debug"
+ "draft" "dvipdf" "dvipdfm" "dvipdfmx" "dvips" "dvipsone"
+ "dviwindo" "encap" "executivepaper" "extension" "filebordercolor"
+ "filecolor" "final" "frenchlinks" "hyperfigures" "hyperfootnotes"
+ "hyperindex" "hypertex" "hypertexnames" "implicit" "latex2html"
+ "legalpaper" "letterpaper" "linkbordercolor" "linkcolor"
+ "linktocpage" "menubordercolor" "menucolor" "nativepdf"
+ "naturalnames" "nesting" "pageanchor" "pagebackref"
+ "pagebordercolor" "pagecolor" "pdfauthor" "pdfborder"
+ "pdfcenterwindow" "pdfcreator" "pdfdirection" "pdfdisplaydoctitle"
+ "pdfduplex" "pdffitwindow" "pdfhighlight" "pdfkeywords" "pdflang"
+ "pdfmark" "pdfmenubar" "pdfnewwindow" "pdfnonfullscreenpagemode"
+ "pdfnumcopies" "pdfpagelayout" "pdfpagemode" "pdfpagelabels"
+ "pdfpagescrop" "pdfpagetransition" "pdfpicktrackbypdfsize"
+ "pdfprintarea" "pdfprintclip" "pdfprintpagerange"
+ "pdfprintscaling" "pdfproducer" "pdfstartpage" "pdfstartview"
+ "pdfsubject" "pdftex" "pdftitle" "pdftoolbar" "pdfview"
+ "pdfviewarea" "pdfviewclip" "pdfwindowui" "plainpages" "ps2pdf"
+ "raiselinks" "runbordercolor" "setpagesize" "tex4ht" "textures"
+ "unicode" "urlbordercolor" "urlcolor" "verbose" "vtex" "xetex")
+ "Package options for the hyperref package.")
+
+(TeX-add-style-hook
+ "hyperref"
+ (lambda ()
+ ;; hyperref.sty loads url.sty
+ (TeX-run-style-hooks "url")
+ (TeX-add-symbols
+ '("href" "URL" "Text")
+ '("nolinkurl" t)
+ '("hyperbaseurl" t)
+ '("hyperimage" "Image URL" "Text")
+ '("hyperdef" "Category" "Name" "Text")
+ '("hyperref" "URL" "Category" "Name" "Text")
+ '("hyperlink" "Name" "Text")
+ '("hypertarget" "Name" "Text")
+ '("phantomsection" 0)
+ '("autoref" TeX-arg-ref)
+ '("ref*" TeX-arg-ref)
+ '("pageref*" TeX-arg-ref)
+ '("pdfstringdef" "Macro name" "TeX string")
+ '("texorpdfstring" "TeX string" "PDF string")
+ '("hypercalcbp" t)
+ '("Acrobatmenu" "Menu option" "Text")
+ '("TextField" ["Parameters"] "Label")
+ '("CheckBox" ["Parameters"] "Label")
+ '("ChoiceMenu" ["Parameters"] "Label" "Choices")
+ '("PushButton" ["Parameters"] "Label")
+ '("Submit" ["Parameters"] "Label")
+ '("Reset" ["Parameters"] "Label")
+ '("LayoutTextField" "Label" "Field")
+ '("LayoutChoiceField" "Label" "Field")
+ '("LayoutCheckField" "Label" "Field")
+ '("MakeRadioField" "Width" "Height")
+ '("MakeCheckField" "Width" "Height")
+ '("MakeTextField" "Width" "Height")
+ '("MakeChoiceField" "Width" "Height")
+ '("MakeButtonField" "Text"))
+
+ (add-to-list 'LaTeX-verbatim-macros-with-braces-local "nolinkurl")
+ (add-to-list 'LaTeX-verbatim-macros-with-braces-local "hyperbaseurl")
+ (add-to-list 'LaTeX-verbatim-macros-with-braces-local "hyperimage")
+ (add-to-list 'LaTeX-verbatim-macros-with-braces-local "hyperref")
+
+ ;; Fontification
+ (when (and (fboundp 'font-latex-add-keywords)
+ (fboundp 'font-latex-set-syntactic-keywords)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ (font-latex-add-keywords '(("href" "{{")
+ ("nolinkurl" "{")
+ ("hyperbaseurl" "{")
+ ("hyperimage" "{{")
+ ("hyperdef" "{{{")
+ ("hyperref" "{{{{")
+ ("hyperlink" "{{")
+ ("hypertarget" "{{")
+ ("autoref" "{")
+ ("ref" "*{")
+ ("pageref" "*{"))
+ 'reference)
+ ;; For syntactic fontification, e.g. verbatim constructs.
+ (font-latex-set-syntactic-keywords))
+
+ ;; RefTeX
+ (when (fboundp 'reftex-ref-style-activate)
+ (reftex-ref-style-activate "Hyperref"))))
+
+;;; hyperref.el ends here
--- /dev/null
+;;; icelandic.el --- AUCTeX style for the `icelandic' babel option.
+
+;; Copyright (C) 2007 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@caeruleus.net>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2007-03-11
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; Set up AUCTeX for editing Icelandic text in connection with the
+;; `icelandic' babel option.
+
+;;; Code:
+
+(defvar LaTeX-icelandic-mode-syntax-table
+ (copy-syntax-table LaTeX-mode-syntax-table)
+ "Syntax table used in LaTeX mode when using `icelandic.sty'.")
+
+(modify-syntax-entry ?\" "w" LaTeX-icelandic-mode-syntax-table)
+
+(TeX-add-style-hook
+ "icelandic"
+ (lambda ()
+ (set-syntax-table LaTeX-icelandic-mode-syntax-table)
+ (setq TeX-quote-language '("icelandic" "\"`" "\"'" t))
+ (setq LaTeX-babel-hyphen-language "icelandic")
+ ;; Fontification of quotation marks.
+ (when (fboundp 'font-latex-add-quotes)
+ (font-latex-add-quotes '("\"`" "\"'"))
+ (font-latex-add-quotes '("\"<" "\">" french)))
+ (run-hooks 'TeX-language-is-hook)))
+
+;;; icelandic.el ends here
--- /dev/null
+;;; index.el --- AUCTeX support for indices with index.sty.
+
+;; Copyright (C) 1999 Free Software Foundation, Inc.
+
+;; Author: Carsten Dominik <dominik@strw.leidenuniv.nl>
+;; Maintainer: auctex-devel@gnu.org
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Code:
+
+(TeX-add-style-hook "index"
+ (lambda ()
+
+ (TeX-add-symbols
+
+ ;; New indices
+ '("newindex" [ "Counter" ] "Tag"
+ "Extension of raw index" "Extension of processed index" "Index title")
+ '("renewindex" [ "Counter" ] "Tag"
+ "Extension of raw index" "Extension of processed index" "Index title")
+ "makeindex"
+ '("disableindex" "Tag[,tag...]")
+
+ ;; Printing the index
+ '("printindex" [ "Indextag" ] [ "Prologue" ])
+ "indexspace"
+
+ ;; Index entries
+ '("index" [ TeX-arg-index-tag ] TeX-arg-index)
+ '("index*" [ TeX-arg-index-tag ] TeX-arg-index)
+
+ ;; Showidx-like stuff
+ "proofmodetrue" "proofmodefalse" '("indexproofstyle" "Style")
+
+ ;; Shortcuts (THESE ARE DEPRECATED AND SHOULD NOT BE USED
+ "shortindexingon" "shortindexinoff")
+
+ ;; Parsing index macros
+ (setq LaTeX-auto-regexp-list
+ (append
+
+ ;; The first regexp is faster, but less accurate
+ ;;'(("\\\\index\\*?\\[[^{}]*\\]{\\([^}]*\\)"
+ ;; 1 LaTeX-auto-index-entry))
+
+ ;; The second regexp is very good, but slower.
+ '(("\\\\index\\*?\\[[^{}]*\\]{\\([^}{]*\\({[^}{]*\\({[^}{]*\\({[^}{]*}[^}{]*\\)*}[^}{]*\\)*}[^}{]*\\)*\\)}"
+ 1 LaTeX-auto-index-entry))
+
+ LaTeX-auto-regexp-list))
+
+ ;; Completion for the index entries in \index and |see commands
+ (setq TeX-complete-list
+ (append
+ '(("\\\\index\\*?\\(\\[[^][{}]*\\]\\)?{\\([^{}\n\r]*\\)"
+ 2 LaTeX-index-entry-list)
+ ("|see{\\([^}]*\\)" 1 LaTeX-index-entry-list))
+ TeX-complete-list))
+
+ ;; RefTeX support
+ (and (fboundp 'reftex-add-index-macros)
+ (reftex-add-index-macros '(index)))))
+
+(defvar LaTeX-index-package-options nil
+ "Package options for the index package.")
+
+;;; index.el ends here
--- /dev/null
+;;; inputenc.el --- AUCTeX style for `inputenc.sty'
+
+;; Copyright (C) 2005 Free Software Foundation, Inc.
+
+;; Author: Arne Jørgensen <arne@arnested.dk>
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+;; MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `inputenc.sty'.
+
+;;; Code:
+
+(defun LaTeX-inputenc-package-options nil
+ "Prompt for package options for the inputenc package."
+ ;; separate the condition in three to silence the byte compiler
+ (if (boundp 'latex-inputenc-coding-alist)
+ (when (fboundp 'latexenc-coding-system-to-inputenc)
+ (when (fboundp 'latexenc-inputenc-to-coding-system)
+ (let ((default (latexenc-coding-system-to-inputenc
+ (or coding-system-for-write
+ buffer-file-coding-system)))
+ (selected 'undecided))
+ (setq selected (completing-read
+ (if default
+ (format "Input encoding (default %s): " default)
+ "Input encoding: ")
+ (mapcar 'car latex-inputenc-coding-alist)
+ nil
+ nil
+ nil
+ nil
+ default))
+
+ ;; if necessary offer to set the coding system for saving
+ ;; this buffer based on the selected input encoding
+ (when (and (null
+ (coding-system-equal
+ (coding-system-base
+ (or coding-system-for-write
+ buffer-file-coding-system))
+ (coding-system-base
+ (latexenc-inputenc-to-coding-system selected))))
+ (y-or-n-p "Set coding system for saving this buffer? ")
+ (set-buffer-file-coding-system
+ (coding-system-base
+ (latexenc-inputenc-to-coding-system selected)))
+ (message nil)))
+
+ ;; return selected input encoding
+ selected)))
+ (read-string "Input encoding: ")))
+
+(defun LaTeX-arg-inputenc-inputenc (optional)
+ "Prompt for input encoding."
+ (TeX-argument-insert (LaTeX-inputenc-package-options) nil))
+
+(TeX-add-style-hook
+ "inputenc"
+ (lambda ()
+ ;; New symbols
+ (TeX-add-symbols
+ '("inputencoding" LaTeX-arg-inputenc-inputenc))))
+
+;; Local Variables:
+;; coding: iso-8859-1
+;; End:
+
+;;; inputenc.el ends here
--- /dev/null
+;;; italian.el --- Setup AUCTeX for editing Italian text.
+
+;; Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+;; Author: Davide G. M. Salvetti <salve@debian.org>
+;; Maintainer: Davide G. M. Salvetti <salve@debian.org>
+;; Created: 2004-05-12
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+;;
+;; I believe that the Italian correct quoting is achieved with `\"<' and
+;; `\">'. However, I will be glad to see a normative reference. -- DGMS
+
+;;; Code:
+
+(defvar TeX-language-it-hook nil
+ "Hook run for Italian texts.")
+
+(TeX-add-style-hook
+ "italian"
+ (lambda ()
+ ;; XXX: Handle former customizations of the now defunct
+ ;; Italian-specific variables. References to the respective
+ ;; variables are to be deleted in future versions. (now = 2005-04-01)
+ (unless (eq (car TeX-quote-language) 'override)
+ (let ((open-quote (if (and (boundp 'LaTeX-italian-open-quote)
+ LaTeX-italian-open-quote)
+ LaTeX-italian-open-quote
+ "\"<"))
+ (close-quote (if (and (boundp 'LaTeX-italian-close-quote)
+ LaTeX-italian-close-quote)
+ LaTeX-italian-close-quote
+ "\">")))
+ (setq TeX-quote-language
+ `("italian" ,open-quote ,close-quote TeX-quote-after-quote))))
+ ;; Fontification of quotation marks.
+ (when (fboundp 'font-latex-add-quotes)
+ (font-latex-add-quotes '("\"<" "\">" french)))
+ (run-hooks 'TeX-language-it-hook)))
+
+;;; italian.el ends here
--- /dev/null
+;;; j-article.el - Special code for j-article style.
+
+;; $Id: j-article.el,v 1.4 2005/03/17 10:02:06 angeli Exp $
+
+;;; Code:
+
+(TeX-add-style-hook
+ "j-article"
+ (lambda ()
+ (LaTeX-largest-level-set "section")))
+
+;;; j-article.el ends here
--- /dev/null
+;;; j-book.el - Special code for j-book style.
+
+;; $Id: j-book.el,v 1.3 2005/03/17 10:02:06 angeli Exp $
+
+;;; Code:
+
+(TeX-add-style-hook
+ "j-book"
+ (lambda ()
+ (LaTeX-largest-level-set "chapter")))
+
+;;; j-book.el ends here
--- /dev/null
+;;; j-report.el - Special code for j-report style.
+
+;; $Id: j-report.el,v 1.3 2005/03/17 10:02:06 angeli Exp $
+
+;;; Code:
+
+(TeX-add-style-hook
+ "j-report"
+ (lambda ()
+ (LaTeX-largest-level-set "chapter")))
+
+;;; j-report.el ends here
--- /dev/null
+;;; jarticle.el - Special code for jarticle style.
+
+;; $Id: jarticle.el,v 1.4 2005/03/17 10:02:06 angeli Exp $
+
+;;; Code:
+
+(TeX-add-style-hook
+ "jarticle"
+ (lambda ()
+ (LaTeX-largest-level-set "section")))
+
+;;; jarticle.el ends here
--- /dev/null
+;;; jbook.el - Special code for jbook style.
+
+;; $Id: jbook.el,v 1.3 2005/03/17 10:02:06 angeli Exp $
+
+;;; Code:
+
+(TeX-add-style-hook
+ "jbook"
+ (lambda ()
+ (LaTeX-largest-level-set "chapter")))
+
+;;; jbook.el ends here
--- /dev/null
+;;; jreport.el - Special code for jreport style.
+
+;; $Id: jreport.el,v 1.3 2005/03/17 10:02:06 angeli Exp $
+
+;;; Code:
+
+(TeX-add-style-hook
+ "jreport"
+ (lambda ()
+ (LaTeX-largest-level-set "chapter")))
+
+
+;;; jreport.el ends here
--- /dev/null
+;;; jsarticle.el - Special code for jsarticle style.
+
+;; $Id: jsarticle.el,v 1.2 2005/03/17 10:02:06 angeli Exp $
+
+;;; Code:
+
+(TeX-add-style-hook
+ "jsarticle"
+ (lambda ()
+ (LaTeX-largest-level-set "section")))
+
+;;; jsarticle.el ends here
--- /dev/null
+;;; jsbook.el - Special code for jsbook style.
+
+;; $Id: jsbook.el,v 1.2 2005/03/17 10:02:06 angeli Exp $
+
+;;; Code:
+
+(TeX-add-style-hook
+ "jsbook"
+ (lambda ()
+ (LaTeX-largest-level-set "chapter")))
+
+;;; jsbook.el ends here
--- /dev/null
+;;; jura.el --- AUCTeX style for `jura.cls'
+
+;; Copyright (C) 2004 Free Software Foundation, Inc.
+
+;; Author: Frank Küster <frank@kuesterei.ch>
+;; Maintainer: auctex-devel@gnu.org
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `jura.cls'.
+
+;;; Code:
+
+(TeX-add-style-hook
+ "jura"
+ (lambda ()
+ (TeX-run-style-hooks "alphanum")))
+
+;; Local Variables:
+;; coding: iso-8859-1
+;; End:
--- /dev/null
+;;; jurabib.el --- AUCTeX style for the `jurabib' package
+
+;; Copyright (C) 2004, 2007 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@iwi.uni-sb.de>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2004-10-05
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for the `jurabib' package.
+
+;; Currently only the citation-related commands are supported. Feel
+;; free to complete the support and send the result to the AUCTeX
+;; mailing list. But be aware that the code can only be included if
+;; you assign the copyright to the FSF.
+
+;;; Code:
+
+(TeX-add-style-hook
+ "jurabib"
+ (lambda ()
+ ;; Taken from natbib.el and adapted.
+ (let ((citecmds
+ '(("cite" . 2) ("cite*" . 2)
+ ("citetitle" . 2) ("fullcite" . 2)
+ ("citet" . 1) ("citealt" . 1)
+ ("citep" . 2) ("citealp" . 2)
+ ("citeauthor" . 2) ("citeyear" . 2)
+ ("footcite" . 2) ("footcite*" . 2)
+ ("footcitetitle" . 2) ("footfullcite" . 2)
+ ("footcitet" . 1) ("footcitealt" . 1)
+ ("footcitep" . 2) ("footcitealp" . 2)
+ ("footciteauthor" . 2) ("footciteyear" . 2))))
+ ;; Add these symbols
+ (apply
+ 'TeX-add-symbols
+ (mapcar
+ (lambda (cmd)
+ (cond
+ ((= (cdr cmd) 0)
+ ;; No optional arguments
+ (list (car cmd) 'TeX-arg-cite))
+ ((= (cdr cmd) 1)
+ ;; Just one optional argument, the post note
+ (list
+ (car cmd)
+ '(TeX-arg-conditional TeX-arg-cite-note-p (["Post-note"]) nil)
+ 'TeX-arg-cite))
+ ((= (cdr cmd) 2)
+ ;; Pre and post notes
+ (list
+ (car cmd)
+ '(TeX-arg-conditional TeX-arg-cite-note-p (natbib-note-args) nil)
+ 'TeX-arg-cite))))
+ citecmds))
+ ;; Special cases
+ (TeX-add-symbols
+ ;; FIXME: Completing read for field.
+ '("citefield" ; \citefield[]{}{}
+ (TeX-arg-conditional TeX-arg-cite-note-p (["Post-note"]) nil)
+ "Field" TeX-arg-cite)
+ '("footcitefield" ; \footcitefield[]{}{}
+ (TeX-arg-conditional TeX-arg-cite-note-p (["Post-note"]) nil)
+ "Field" TeX-arg-cite))
+
+ ;; Make an entry in TeX-complete-list
+ (add-to-list
+ 'TeX-complete-list
+ (list
+ (concat "\\\\\\("
+ (mapconcat (lambda (x) (regexp-quote (car x)))
+ (append citecmds
+ '(("citefield") ("footcitefield"))) "\\|")
+ "\\)\\(\\[[^]\n\r\\%]*\\]\\)*{\\([^{}\n\r\\%,]*,\\)*"
+ "\\([^{}\n\r\\%,]*\\)")
+ 4 'LaTeX-bibitem-list "}"))
+
+ ;; Add further symbols
+ (TeX-add-symbols
+ '("citefullfirstfortype" 1)
+ '("citenotitlefortype" 1)
+ '("citeswithoutentry" 1)
+ '("citetitlefortype" 1)
+ '("citeworkwithtitle" 1)
+ '("nextcitefull" 1)
+ '("nextcitenotitle" 1)
+ '("nextcitereset" 1)
+ '("nextciteshort" 1)
+ '("jurabibsetup" 1))
+
+ ;; Fontification
+ (when (and (featurep 'font-latex)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ (font-latex-add-keywords '(("cite" "*[[{")
+ ("citetitle" "[[{")
+ ("fullcite" "[[{")
+ ("citet" "[{")
+ ("citealt" "[{")
+ ("citep" "[[{")
+ ("citealp" "[[{")
+ ("citeauthor" "[[{")
+ ("citeyear" "[[{")
+ ("footcite" "[[{")
+ ("footcite*" "[[{")
+ ("footcitetitle" "[[{")
+ ("footfullcite" "[[{")
+ ("footcitet" "[{")
+ ("footcitealt" "[{")
+ ("footcitep" "[[{")
+ ("footcitealp" "[[{")
+ ("footciteauthor" "[[{")
+ ("footciteyear" "[[{")
+ ("citefield" "[{{")
+ ("footcitefield" "[{{"))
+ 'reference)
+ (font-latex-add-keywords '(("citeswithoutentry" "{")
+ ("nextcitefull" "{")
+ ("nextcitenotitle" "{")
+ ("nextcitereset" "{")
+ ("nextciteshort" "{"))
+ 'function)
+ (font-latex-add-keywords '(("citenotitlefortype" "{")
+ ("citetitlefortype" "{")
+ ("jurabibsetup" "{"))
+ 'variable))
+
+ ;; Tell RefTeX (Thanks, Carsten)
+ (when (and (fboundp 'reftex-set-cite-format)
+ ;; Is it `reftex-cite-format' customized?
+ (not (get 'reftex-cite-format 'saved-value)))
+ ;; Check if RefTeX supports jurabib.
+ (if (assoc 'jurabib reftex-cite-format-builtin)
+ ;; Yes, use the provided default.
+ (reftex-set-cite-format 'jurabib)
+ ;; No, set it by hand.
+ (reftex-set-cite-format
+ '((?\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}"))))))
+
+ ;; FIXME: The following list is the edited output of
+ ;; `TeX-auto-generate' which probably includes internal macros of
+ ;; jurabib. Unfortunately the macros which should be accessible to
+ ;; the user are not fully documented at the time of this writing.
+ ;; But instead of including only the limited part which is
+ ;; documented we rather give the user a bit too much. The list
+ ;; should be reduced when there is proper documentation, though.
+ (TeX-add-symbols
+ '("Wrapquotes" 1)
+ '("apyformat" 1)
+ '("artnumberformat" 1)
+ '("artvolnumformat" 2)
+ '("artvolumeformat" 1)
+ '("artyearformat" 1)
+ '("bibAnnote" 1)
+ '("bibAnnoteFile" 1)
+ '("bibAnnotePath" 1)
+ '("bibEIMfont" 1)
+ '("bibIMfont" 1)
+ '("bibYear" 1)
+ '("bibedformat" 1)
+ '("bibedinformat" 1)
+ '("bibenf" 5)
+ '("biblenf" 5)
+ '("bibnf" 5)
+ '("bibnumberformat" 1)
+ '("bibrenf" 5)
+ '("bibrlenf" 5)
+ '("bibrnf" 5)
+ '("biburlfont" 1)
+ '("edfont" 1)
+ '("formatarticlepages" ["argument"] 2)
+ '("fsted" 1)
+ '("fullnameoxfordcrossref" 1)
+ '("incolledformat" 5)
+ '("jbArchPages" 1)
+ '("jbPages" 1)
+ '("jbannoteformat" 1)
+ '("jbapifont" 1)
+ '("jbarchnameformat" 1)
+ '("jbarchsig" 2)
+ '("jbartPages" 1)
+ '("jbartcrossrefchecked" ["argument"] 1)
+ '("jbauthorindexfont" 1)
+ '("jbbibargs" 5)
+ '("jbbibyearformat" 1)
+ '("jbcitationoyearformat" 1)
+ '("jbcitationyearformat" 1)
+ '("jbcrossrefchecked" ["argument"] 1)
+ '("jbedafti" 1)
+ '("jbedbyincollcrossreflong" 1)
+ '("jbedbyincollcrossrefshort" 1)
+ '("jbedbyincollcrossrefshortnoapy" 1)
+ '("jbedbyincollcrossrefshortwithapy" 1)
+ '("jbedition" 1)
+ '("jbeditorindexfont" 1)
+ '("jbendnote" 1)
+ '("jbflanguage" 1)
+ '("jbincollcrossref" 2)
+ '("jbisbn" 1)
+ '("jbissn" 1)
+ '("jbnote" 2)
+ '("jborganizationindexfont" 1)
+ '("jbpagesformat" 1)
+ '("jbprformat" 1)
+ '("jbrealcitation" 2)
+ '("jbshortarchformat" 1)
+ '("jbshortsubarchformat" 1)
+ '("jbsy" 1)
+ '("jbtiafed" 1)
+ '("lookatfortype" 1)
+ '("nobibliography" 1)
+ '("nocitebuthowcited" 1)
+ '("numberandseries" 2)
+ '("pageadd" 1)
+ '("pernumberformat" 1)
+ '("pervolnumformat" 2)
+ '("pervolumeformat" 1)
+ '("peryearformat" 1)
+ '("revnumberformat" 1)
+ '("revvolnumformat" 2)
+ '("revvolumeformat" 1)
+ '("revyearformat" 1)
+ '("snded" 1)
+ '("textitswitch" 1)
+ '("translator" 3)
+ '("volumeformat" 1)
+ "Bibbfsasep"
+ "Bibbfsesep"
+ "Bibbstasep"
+ "Bibbstesep"
+ "Bibbtasep"
+ "Bibbtesep"
+ "Bibchaptername"
+ "Bibetal"
+ "Edbyname"
+ "IbidemMidName"
+ "IbidemName"
+ "NAT"
+ "OpCit"
+ "Reprint"
+ "SSS"
+ "Transfrom"
+ "Volumename"
+ "addtoalllanguages"
+ "afterfoundersep"
+ "aftervolsep"
+ "ajtsep"
+ "alsothesisname"
+ "aprname"
+ "augname"
+ "bibBTsep"
+ "bibJTsep"
+ "bibPageName"
+ "bibPagesName"
+ "bibaesep"
+ "bibaldelim"
+ "bibaltformatalign"
+ "bibandname"
+ "bibanfont"
+ "bibansep"
+ "bibapifont"
+ "bibapyldelim"
+ "bibapyrdelim"
+ "bibarchpagename"
+ "bibarchpagesname"
+ "bibardelim"
+ "bibartperiodhowcited"
+ "bibatsep"
+ "bibauthormultiple"
+ "bibbdsep"
+ "bibbfsasep"
+ "bibbfsesep"
+ "bibbstasep"
+ "bibbstesep"
+ "bibbtasep"
+ "bibbtesep"
+ "bibbtfont"
+ "bibbtsep"
+ "bibbudcsep"
+ "bibces"
+ "bibchapterlongname"
+ "bibchaptername"
+ "bibcite"
+ "bibcolumnsep"
+ "bibcommenthowcited"
+ "bibcontinuedname"
+ "bibcrossrefcite"
+ "bibcrossrefciteagain"
+ "bibeandname"
+ "bibedformat"
+ "bibefnfont"
+ "bibeimfont"
+ "bibelnfont"
+ "bibenf"
+ "bibfnfmt"
+ "bibfnfont"
+ "bibhowcited"
+ "bibibidfont"
+ "bibidemPfname"
+ "bibidemPmname"
+ "bibidemPnname"
+ "bibidemSfname"
+ "bibidemSmname"
+ "bibidemSnname"
+ "bibidempfname"
+ "bibidempmname"
+ "bibidempnname"
+ "bibidemsfname"
+ "bibidemsmname"
+ "bibidemsnname"
+ "bibimfont"
+ "bibincollcrossrefcite"
+ "bibincollcrossrefciteagain"
+ "bibjtfont"
+ "bibjtsep"
+ "bibleftcolumn"
+ "bibleftcolumnadjust"
+ "bibleftcolumnstretch"
+ "biblenf"
+ "biblnfmt"
+ "biblnfont"
+ "bibnf"
+ "bibnotcited"
+ "bibpagename"
+ "bibpagesname"
+ "bibpagesnamesep"
+ "bibpldelim"
+ "bibprdelim"
+ "bibrevtfont"
+ "bibrightcolumn"
+ "bibrightcolumnadjust"
+ "bibrightcolumnstretch"
+ "bibsall"
+ "bibsdanish"
+ "bibsdutch"
+ "bibsenglish"
+ "bibsfinnish"
+ "bibsfrench"
+ "bibsgerman"
+ "bibsitalian"
+ "bibsnfont"
+ "bibsnorsk"
+ "bibsportuguese"
+ "bibsspanish"
+ "bibtabularitemsep"
+ "bibtfont"
+ "bibtotalpagesname"
+ "biburlprefix"
+ "biburlsuffix"
+ "bibvolumecomment"
+ "bibvtfont"
+ "bothaesep"
+ "bpubaddr"
+ "byname"
+ "citetitleonly"
+ "citeyearpar"
+ "commaename"
+ "commaname"
+ "dateldelim"
+ "daterdelim"
+ "decname"
+ "diffpageibidemmidname"
+ "diffpageibidemname"
+ "edbyname"
+ "edbysep"
+ "editionname"
+ "editorname"
+ "editorsname"
+ "enoteformat"
+ "etalname"
+ "etalnamenodot"
+ "febname"
+ "fifthedname"
+ "firstedname"
+ "footcitetitleonly"
+ "formatpages"
+ "foundername"
+ "fourthedname"
+ "fromdutch"
+ "fromenglish"
+ "fromfinnish"
+ "fromfrench"
+ "fromgerman"
+ "fromitalian"
+ "fromnorsk"
+ "fromportuguese"
+ "fromspanish"
+ "herename"
+ "howcitedprefix"
+ "howcitedsuffix"
+ "ibidem"
+ "ibidemmidname"
+ "ibidemname"
+ "idemPfedbyname"
+ "idemPfname"
+ "idemPmedbyname"
+ "idemPmname"
+ "idemPnedbyname"
+ "idemPnname"
+ "idemSfedbyname"
+ "idemSfname"
+ "idemSmedbyname"
+ "idemSmname"
+ "idemSnedbyname"
+ "idemSnname"
+ "idemmidname"
+ "idemname"
+ "idempfedbyname"
+ "idempfname"
+ "idempmedbyname"
+ "idempmname"
+ "idempnedbyname"
+ "idempnname"
+ "idemsfedbyname"
+ "idemsfname"
+ "idemsmedbyname"
+ "idemsmname"
+ "idemsnedbyname"
+ "idemsnname"
+ "incollinname"
+ "inname"
+ "inseriesname"
+ "janname"
+ "jbCheckedFirst"
+ "jbFirst"
+ "jbFirstAbbrv"
+ "jbJunior"
+ "jbLast"
+ "jbNotRevedNoVonJr"
+ "jbNotRevedNoVonNoJr"
+ "jbNotRevedOnlyLast"
+ "jbNotRevedVonJr"
+ "jbNotRevedVonNoJr"
+ "jbPAGES"
+ "jbPageName"
+ "jbPages"
+ "jbPagesName"
+ "jbRevedFirstNoVonJr"
+ "jbRevedFirstNoVonNoJr"
+ "jbRevedFirstOnlyLast"
+ "jbRevedFirstVonJr"
+ "jbRevedFirstVonNoJr"
+ "jbRevedNotFirstNoVonJr"
+ "jbRevedNotFirstNoVonNoJr"
+ "jbRevedNotFirstOnlyLast"
+ "jbRevedNotFirstVonJr"
+ "jbRevedNotFirstVonNoJr"
+ "jbVon"
+ "jbactualauthorfnfont"
+ "jbactualauthorfont"
+ "jbaddtomakehowcited"
+ "jbaensep"
+ "jbafterstartpagesep"
+ "jbannotatorfont"
+ "jbapifont"
+ "jbarchnamesep"
+ "jbarchpagename"
+ "jbarchpagesname"
+ "jbartPages"
+ "jbatsep"
+ "jbauthorfnfont"
+ "jbauthorfont"
+ "jbauthorfontifannotator"
+ "jbauthorinfo"
+ "jbbeforestartpagesep"
+ "jbbfsasep"
+ "jbbfsesep"
+ "jbbookedaftertitle"
+ "jbbstasep"
+ "jbbstesep"
+ "jbbtasep"
+ "jbbtesep"
+ "jbbtfont"
+ "jbbtitlefont"
+ "jbcitationyearformat"
+ "jbcrossrefchecked"
+ "jbdisablecitationcrossref"
+ "jbdoitem"
+ "jbdonotindexauthors"
+ "jbdonotindexeditors"
+ "jbdonotindexorganizations"
+ "jbdotafterbibentry"
+ "jbdotafterendnote"
+ "jbdy"
+ "jbedbyincollcrossrefcite"
+ "jbedbyincollcrossrefciteagain"
+ "jbedition"
+ "jbedseplikecite"
+ "jbeimfont"
+ "jbfirstcitepageranges"
+ "jbfootnoteformat"
+ "jbfootnotenumalign"
+ "jbfulltitlefont"
+ "jbhowcitedcomparepart"
+ "jbhowcitednormalpart"
+ "jbhowsepannotatorfirst"
+ "jbhowsepannotatorlast"
+ "jbhowsepbeforetitle"
+ "jbhowsepbeforetitleae"
+ "jbhowsepbeforetitleibidemname"
+ "jbignorevarioref"
+ "jbimfont"
+ "jbindexbib"
+ "jbindexonlyfirstauthors"
+ "jbindexonlyfirsteditors"
+ "jbindexonlyfirstorganizations"
+ "jbindextype"
+ "jblookforgender"
+ "jbmakeinbib"
+ "jbmakeinbiblist"
+ "jbmakeindexactual"
+ "jbnotsamearch"
+ "jbonlyforbib"
+ "jbonlyforcitations"
+ "jbonlyforfirstcitefullbegin"
+ "jbonlyforfirstcitefullend"
+ "jborgauthorfont"
+ "jboyearincitation"
+ "jbpagename"
+ "jbpagenamenodot"
+ "jbpages"
+ "jbpagesep"
+ "jbpagesname"
+ "jbpagesnamesep"
+ "jbsamearch"
+ "jbsamesubarch"
+ "jbsamesubarchindent"
+ "jbshorttitlefont"
+ "jbshowbibextralabel"
+ "jbssedbd"
+ "jbsubarchsep"
+ "jbsuperscripteditionafterauthor"
+ "jbtitlefont"
+ "jbts"
+ "jburldef"
+ "jbuseidemhrule"
+ "jbyear"
+ "jbyearaftertitle"
+ "julname"
+ "junname"
+ "jurthesisname"
+ "marname"
+ "mastersthesisname"
+ "mayname"
+ "nofirstnameforcitation"
+ "noibidem"
+ "noidem"
+ "nopage"
+ "novname"
+ "numbername"
+ "octname"
+ "ofseriesname"
+ "opcit"
+ "organizationname"
+ "origPAGES"
+ "origartPages"
+ "origbibces"
+ "origcrossref"
+ "origpages"
+ "osep"
+ "phdthesisname"
+ "reprint"
+ "reprintname"
+ "reviewbyname"
+ "reviewname"
+ "reviewofname"
+ "samepageibidemmidname"
+ "samepageibidemname"
+ "secondedname"
+ "sepname"
+ "sndecmd"
+ "snded"
+ "sndeditorname"
+ "sndeditorsname"
+ "technicalreportname"
+ "testnosig"
+ "textandname"
+ "texteandname"
+ "theHlvla"
+ "theHlvlb"
+ "theHlvlc"
+ "theHlvld"
+ "theHlvle"
+ "theHlvlf"
+ "theHlvlg"
+ "theHlvlh"
+ "theHlvli"
+ "theHlvlj"
+ "theHlvlk"
+ "theHlvll"
+ "thedname"
+ "thirdedname"
+ "trans"
+ "transby"
+ "transfrom"
+ "updatename"
+ "updatesep"
+ "urldatecomment"
+ "volname"
+ "volumename"
+ "volumeofname")))
+
+;;; jurabib.el ends here
--- /dev/null
+;;; letter.el - Special code for letter style.
+
+;; $Id: letter.el,v 1.4 2008/05/25 06:50:33 angeli Exp $
+
+;;; Code:
+
+;; You may want to define this in tex-site.el to contain your
+;; organizations address.
+(defvar LaTeX-letter-sender-address ""
+ "Initial value when prompting for a sender address in the letter style.")
+
+(TeX-add-style-hook "letter"
+ (function
+ (lambda ()
+ (LaTeX-add-environments
+ '("letter" LaTeX-env-recipient))
+ (TeX-add-symbols
+ '("name" "Sender: ")
+ '("address" "Sender address: ")
+ '("signature" "Signature: ")
+ '("opening" "Opening: ")
+ '("closing" "Closing: ")))))
+
+(defun LaTeX-env-recipient (environment)
+ "Insert ENVIRONMENT and prompt for recipient and address."
+ (let ((sender (read-string "Sender: " (user-full-name)))
+ (sender-address (read-string "Sender address: "
+ LaTeX-letter-sender-address))
+ (recipient (read-string "Recipient: "))
+ (address (read-string "Recipient address: "))
+ (signature (read-string "Signature: "))
+ (opening (read-string "Opening: "))
+ (closing (read-string "Closing: "))
+ (date (read-string "Date: " (LaTeX-today))))
+
+ (insert TeX-esc "name" TeX-grop sender TeX-grcl)
+ (newline-and-indent)
+ (if (not (zerop (length sender-address)))
+ (progn
+ (setq LaTeX-letter-sender-address sender-address)
+ (insert TeX-esc "address" TeX-grop sender-address TeX-grcl)
+ (newline-and-indent)))
+ (if (not (zerop (length signature)))
+ (progn
+ (insert TeX-esc "signature" TeX-grop signature TeX-grcl)
+ (newline-and-indent)))
+ (if (not (zerop (length date)))
+ (progn
+ (insert TeX-esc "def" TeX-esc "today" TeX-grop date TeX-grcl)
+ (newline-and-indent)))
+ (newline-and-indent)
+
+ (let ((indentation (current-column)))
+ (LaTeX-insert-environment
+ environment
+ (concat TeX-grop recipient
+ (if (not (zerop (length address)))
+ (concat
+ (if (not (zerop (length recipient)))
+ (concat " " TeX-esc TeX-esc " "))
+ address))
+ TeX-grcl))
+ (save-excursion ; Fix indentation of address
+ (if (search-backward TeX-grcl nil 'move)
+ (let ((addr-end (point-marker)))
+ (if (search-backward TeX-grop nil 'move)
+ (let ((addr-column (current-column)))
+ (while (search-forward
+ (concat TeX-esc TeX-esc)
+ (marker-position addr-end) 'move)
+ (progn
+ (newline)
+ (indent-to addr-column))))))))
+ (insert "\n")
+ (indent-to indentation))
+ (insert TeX-esc "opening"
+ TeX-grop
+ (if (zerop (length opening))
+ (concat TeX-esc " ")
+ opening)
+ TeX-grcl "\n")
+
+ (indent-relative-maybe)
+ (save-excursion
+ (insert "\n" TeX-esc "closing"
+ TeX-grop
+ (if (zerop (length closing))
+ (concat TeX-esc " ")
+ closing)
+ TeX-grcl "\n")
+ (indent-relative-maybe))))
+
+(defun LaTeX-today nil
+ "Return a string representing todays date according to flavor."
+ (interactive)
+ (let ((ctime-string (current-time-string))
+ (month-alist '(("Jan". "01")
+ ("Feb" . "02")
+ ("Mar" . "03")
+ ("Apr" . "04")
+ ("May" . "05")
+ ("Jun" . "06")
+ ("Jul" . "07")
+ ("Aug" . "08")
+ ("Sep" . "09")
+ ("Oct" . "10")
+ ("Nov" . "11")
+ ("Dec" . "12"))))
+ (string-match
+ "^\\S-+\\s-+\\(\\S-+\\)\\s-+\\(\\S-+\\)\\s-+\\S-+\\s-+\\(\\S-+\\)"
+ ctime-string)
+ (let ((year (substring ctime-string (match-beginning 3) (match-end 3)))
+ (month (substring ctime-string (match-beginning 1) (match-end 1)))
+ (day (substring ctime-string (match-beginning 2) (match-end 2))))
+ (if (assoc month month-alist)
+ (progn
+ (setq month (cdr (assoc month month-alist)))
+ (if (> 2 (length day))
+ (setq day (concat "0" day)))))
+ (format "%s-%s-%s" year month day))))
+
+;;; letter.el ends here
--- /dev/null
+;;; listings.el --- AUCTeX style for `listings.sty'
+
+;; Copyright (C) 2004, 2005, 2009 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@iwi.uni-sb.de>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2004-10-17
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `listings.sty'.
+;;
+;; FIXME: Please make me more sophisticated!
+
+;;; Code:
+
+;; The following are options taken from chapter 4 of the listings
+;; manual (2006/05/08 Version 1.3c). Experimental options described
+;; in chapter 5 are not included.
+(defvar LaTeX-listings-key-val-options
+ '(;; Space and placement
+ ("float" ("t" "b" "p" "h")) ; Support [*] as an optional prefix and that
+ ; tbph are not exclusive.
+ ("floatplacement" ("t" "b" "p" "h"))
+ ("aboveskip")
+ ("belowskip")
+ ("lineskip")
+ ("boxpos" ("b" "c" "t"))
+ ;; The printed range
+ ("print" ("true" "false"))
+ ("firstline")
+ ("lastline")
+ ("linerange")
+ ("showlines" ("true" "false"))
+ ("emptylines")
+ ("gobble")
+ ;; Languages and styles
+ ("style")
+ ("language")
+ ("alsolanguage")
+ ("defaultdialect")
+ ("printpod" ("true" "false"))
+ ("usekeywordsintag" ("true" "false"))
+ ("tagstyle")
+ ("markfirstintag")
+ ("makemacrouse" ("true" "false"))
+ ;; Figure out the appearance
+ ("basicstyle")
+ ("identifierstyle")
+ ("commentstyle")
+ ("stringstyle")
+ ("keywordstyle")
+ ("classoffset")
+ ("texcsstyle")
+ ("directivestyle")
+ ("emph")
+ ("moreemph")
+ ("deleteemph")
+ ("emphstyle")
+ ("delim")
+ ("moredelim")
+ ("deletedelim")
+ ;; Getting all characters right
+ ("extendedchars" ("true" "false"))
+ ("inputencoding") ; Could make use of `latex-inputenc-coding-alist'.
+ ("upquote" ("true" "false"))
+ ("tabsize")
+ ("showtabs" ("true" "false"))
+ ("tab")
+ ("showspaces" ("true" "false"))
+ ("showstringspaces" ("true" "false"))
+ ("formfeed")
+ ;; Line numbers
+ ("numbers" ("none" "left" "right"))
+ ("stepnumber")
+ ("numberfirstline" ("true" "false"))
+ ("numberstyle")
+ ("numbersep")
+ ("numberblanklines" ("true" "false"))
+ ("firstnumber" ("auto" "last")) ; Can also take a number.
+ ("name")
+ ;; Captions
+ ("title")
+ ("caption") ; Insert braces?
+ ("label")
+ ("nolol" ("true" "false"))
+ ("captionpos" ("t" "b")) ; Can be a subset of tb.
+ ("abovecaptionskip")
+ ("belowcaptionskip")
+ ;; Margins and line shape
+ ("linewidth")
+ ("xleftmargin")
+ ("xrightmargin")
+ ("resetmargins" ("true" "false"))
+ ("breaklines" ("true" "false"))
+ ("breakatwhitespace" ("true" "false"))
+ ("prebreak")
+ ("postbreak")
+ ("breakindent")
+ ("breakautoindent" ("true" "false"))
+ ;; Frames
+ ("frame" ("none" "leftline" "topline" "bottomline" "lines" "single"
+ "shadowbox"
+ ;; Alternative to the above values. A subset of trblTRBL can be
+ ;; given.
+ "t" "r" "b" "l" "T" "R" "B" "L"))
+ ("frameround" ("t" "f")) ; The input actually has to be four times {t,f}.
+ ("framesep")
+ ("rulesep")
+ ("framerule")
+ ("framexleftmargin")
+ ("framexrightmargin")
+ ("framextopmargin")
+ ("framebottommargin")
+ ("backgroundcolor")
+ ("rulecolor")
+ ("fillcolor")
+ ("fulesepcolor")
+ ("frameshape")
+ ;; Indexing
+ ("index")
+ ("moreindex")
+ ("deleteindex")
+ ("indexstyle")
+ ;; Column alignment
+ ("columns" ("fixed" "flexible" "fullflexible")) ; Also supports an optional
+ ; argument with {c,l,r}.
+ ("flexiblecolumns" ("true" "false"))
+ ("keepspaces" ("true" "false"))
+ ("basewidth")
+ ("fontadjust" ("true" "false"))
+ ;; Escaping to LaTeX
+ ("texcl" ("true" "false"))
+ ("mathescape" ("true" "false"))
+ ("escapechar")
+ ("escapeinside")
+ ("escapebegin")
+ ("escapeend")
+ ;; Interface to fancyvrb
+ ("fancyvrb" ("true" "false"))
+ ("fvcmdparams")
+ ("morefvcmdparams")
+ ;; Language definitions
+ ("keywordsprefix")
+ ("keywords")
+ ("morekeywords")
+ ("deletekeywords")
+ ("texcs")
+ ("moretexcs")
+ ("deletetexcs")
+ ("directives")
+ ("moredirectives")
+ ("deletedirectives")
+ ("sensitive" ("true" "false"))
+ ("alsoletter")
+ ("alsodigit")
+ ("alsoother")
+ ("otherkeywords")
+ ("tag")
+ ("string")
+ ("morestring")
+ ("deletestring")
+ ("comment")
+ ("morecomment")
+ ("deletecomment")
+ ("keywordcomment")
+ ("morekeywordcomment")
+ ("deletekeywordcomment")
+ ("keywordcommentsemicolon")
+ ("podcomment" ("true" "false")))
+ "Key=value options for listings macros and environments.")
+
+(TeX-add-style-hook
+ "listings"
+ (lambda ()
+ ;; New symbols
+ (TeX-add-symbols
+ '("lstalias" ["Alias dialect"] "Alias" ["Dialect"] "Language")
+ '("lstdefinestyle" "Style name"
+ (TeX-arg-key-val LaTeX-listings-key-val-options))
+ '("lstinline" TeX-arg-verb)
+ '("lstinputlisting" [TeX-arg-key-val LaTeX-listings-key-val-options]
+ TeX-arg-file)
+ "lstlistoflistings"
+ '("lstnewenvironment" "Name" ["Number or arguments"] ["Default argument"]
+ "Starting code" "Ending code")
+ '("lstset" (TeX-arg-key-val LaTeX-listings-key-val-options)))
+ ;; New environments
+ (LaTeX-add-environments
+ '("lstlisting" LaTeX-env-args
+ [TeX-arg-key-val LaTeX-listings-key-val-options]))
+ ;; Filling
+ (make-local-variable 'LaTeX-indent-environment-list)
+ (add-to-list 'LaTeX-indent-environment-list
+ '("lstlisting" current-indentation))
+ (make-local-variable 'LaTeX-verbatim-regexp)
+ (setq LaTeX-verbatim-regexp (concat LaTeX-verbatim-regexp "\\|lstlisting"))
+ (add-to-list 'LaTeX-verbatim-environments-local "lstlisting")
+ (add-to-list 'LaTeX-verbatim-macros-with-delims-local "lstinline")
+ (add-to-list 'LaTeX-verbatim-macros-with-braces-local "lstinline")
+ ;; Fontification
+ (when (and (fboundp 'font-latex-add-keywords)
+ (fboundp 'font-latex-set-syntactic-keywords)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ (font-latex-add-keywords '(("lstnewenvironment" "{[[{{")) 'function)
+ (font-latex-add-keywords '(("lstinputlisting" "[{")) 'reference)
+ (font-latex-add-keywords '(("lstinline" "[{") ; The second argument should
+ ; actually be verbatim.
+ ("lstlistoflistings" ""))
+ 'textual)
+ (font-latex-add-keywords '(("lstalias" "{{")
+ ("lstdefinestyle" "{{")
+ ("lstset" "{"))
+ 'variable)
+ ;; For syntactic fontification, e.g. verbatim constructs.
+ (font-latex-set-syntactic-keywords)
+ ;; Tell font-lock about the update.
+ (setq font-lock-set-defaults nil)
+ (font-lock-set-defaults))))
+
+(defvar LaTeX-listings-package-options '("draft" "final" "savemem"
+ "noaspects")
+ "Package options for the listings package.")
+
+;;; listings.el ends here
--- /dev/null
+;;; ltx-base.el --- AUCTeX style for basic LaTeX commands.
+
+;; Copyright (C) 2004 Free Software Foundation, Inc.
+
+;; Author: Frank Küster <frank@kuesterei.ch>
+;; Maintainer: auctex-devel@gnu.org
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds general support for basic LaTeX commands used for
+;; writing LaTeX class files (.cls), style files (.sty) and package
+;; files (.dtx).
+
+;;; Code:
+
+(TeX-add-style-hook
+ "ltx-base"
+ (function
+ (lambda ()
+ (TeX-add-symbols
+ '("DeclareRobustCommand" TeX-arg-define-macro [ "Number of arguments" ] t)
+ '("CheckCommand" TeX-arg-define-macro [ "Number of arguments" ] t)
+ '("@addtoreset" TeX-arg-counter "Within counter" "counter")
+ '("addvspace" "space")
+ '("addpenalty" "penalty")
+ '("ProvidesClass" "name" [ "release information" ])
+ '("ProvidesPackage" "name" [ "release information" ])
+ '("ProvidesFile" "filename" [ "release information" ])
+ '("NeedsTeXFormat" "format" [ "release" ])
+ '("DeclareOption" "option" t)
+ ;; would be great if DeclareOption RET * RET would give
+ ;; \DeclareOption*!
+ "DeclareOption*"
+ '("CurrentOption" 0)
+ '("PassOptionsToPackage" "option list" "package")
+ '("ExecuteOptions" "option list")
+ "ProcessOptions"
+ "ProcessOptions*"
+ '("OptionNotUsed" 0)
+ ;; candidate for opt/mand toggling
+ '("RequirePackage" [ "option list" ] "package" [ "release" ])
+ '("LoadClass" [ "option list" ] "class" [ "release" ])
+ "AtEndOfPackage"
+ "AtEndOfClass"
+ "AtBeginDocument"
+ "AtEndDocument"
+ '("IfFileExists" "filename" 2)
+ '("InputIfFileExists" "filename" 2)
+ '("PackageWarning" "name" t)
+ '("PackageWarningNoLine" "name" t)
+ '("PackageInfo" "name" t)
+ '("PackageError" "name" "short text" t)
+ '("ClassWarning" "name" t)
+ '("ClassWarningNoLine" "name" t)
+ '("ClassInfo" "name" t)
+ '("ClassError" "name" "short text" t)
+ '("MessageBreak" 0)
+ '("@ifpackageloaded" "package" 2)
+ '("@ifpackagelater" "package" "date" 2)
+ '("@ifpackagewith" "package" "options" 2)
+ '("message" "Log Message")
+ '("@ifundefined" "Macro Name" 2)
+ '("@ifnextchar" (TeX-arg-literal " ") (TeX-arg-free "character") 2 )
+ "expandafter"))))
+
+;; Local Variables:
+;; coding: iso-8859-1
+;; End:
--- /dev/null
+;;; ltxdoc.el --- AUCTeX style for `ltxdoc.cls'
+
+;; Copyright (C) 2004 Free Software Foundation, Inc.
+
+;; Author: Frank Küster <frank@kuesterei.ch>
+;; Maintainer: auctex-devel@gnu.org
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `ltxdoc.cls'.
+
+;;; Code:
+
+(TeX-add-style-hook
+ "ltxdoc"
+ (lambda ()
+ (TeX-run-style-hooks "doc")
+ (TeX-run-style-hooks "ltx-base")))
+
+;; Local Variables:
+;; coding: iso-8859-1
+;; End:
--- /dev/null
+;;; makeidx.el --- AUCTeX support for makeidx.sty
+
+;; Copyright (C) 1999 Free Software Foundation, Inc.
+
+;; Author: Carsten Dominik <dominik@strw.leidenuniv.nl>
+;; Maintainer: auctex-devel@gnu.org
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Code:
+
+(TeX-add-style-hook "makeidx"
+ (lambda ()
+ (TeX-add-symbols
+ "printindex" "indexspace")
+
+ ;; Parsing the default index macro is defined in latex.el
+ ;; The same is true form completion in the index macro
+
+ ;; Completion for the |see macro
+ (setq TeX-complete-list
+ (append
+ '(("|see{\\([^{}\n\r]*\\)" 1 LaTeX-index-entry-list))
+ TeX-complete-list))
+
+ ;; RefTeX support
+ (and (fboundp 'reftex-add-index-macros)
+ (reftex-add-index-macros '(default)))))
+
+(defvar LaTeX-makeidx-package-options nil
+ "Package options for the makeidx package.")
+
+;;; makeidx.el ends here
--- /dev/null
+;;; mdwlist.el --- AUCTeX style for `mdwlist.sty'
+
+;; Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+;; Maintainer: auctex-devel@gnu.org
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `mdwlist.sty'.
+
+;;; Code:
+
+(TeX-add-style-hook
+ "mdwlist"
+ (lambda ()
+ (TeX-add-symbols
+ '("makecompactlist" "New environment" "Existing environment")
+ '("suspend" "Environment") ; this could be done nicer by automatically
+ '("resume" "Environment")) ; determining the environment
+ (LaTeX-add-environments
+ '("enumerate*" LaTeX-env-item)
+ '("itemize*" LaTeX-env-item)
+ '("description*" LaTeX-env-item))
+ ;; Indentation and filling
+ (make-local-variable 'LaTeX-begin-regexp)
+ (setq LaTeX-begin-regexp (concat LaTeX-begin-regexp "\\|resume\\b"))
+ (make-local-variable 'LaTeX-end-regexp)
+ (setq LaTeX-end-regexp (concat LaTeX-end-regexp "\\|suspend\\b"))
+ (make-local-variable 'paragraph-start)
+ (setq paragraph-start (concat paragraph-start
+ "\\|[ \t]*" TeX-comment-start-regexp "*[ \t]*"
+ (regexp-quote TeX-esc)
+ "\\(resume\\b\\|suspend\\b\\)"))
+ ;; Fontification
+ (when (and (featurep 'font-latex)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ (font-latex-add-keywords '(("makecompactlist" "{{")
+ ("suspend" "[{")
+ ("resume" "[{["))
+ 'function))))
+
+(defvar LaTeX-mdwlist-package-options nil
+ "Package options for the mdwlist package.")
+
+;;; mdwlist.el ends here
--- /dev/null
+;;; multido.el --- AUCTeX style for `multido.sty'
+
+;; Copyright (C) 2007 Free Software Foundation, Inc.
+
+;; Author: Holger Sparr <holger.sparr@gmx.net>
+;; Created: 21 Jun 2007
+;; Based on: Jean-Philippe Georget's multido.el
+;; Keywords: latex, pstricks, auctex, emacs
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `multido.sty'.
+
+;;; TODO:
+;;
+;; -- better argument support for multido
+;; -- parsing for fpAdd resp. fpSub
+
+;;; Code:
+
+(TeX-add-style-hook
+ "multido"
+ (function
+ (lambda ()
+ (TeX-add-symbols
+ '("multido" "\var=<start value>+-<inc>" "Repititions" t)
+ '("Multido" "\var=<start value>+-<inc>" "Repititions" t)
+ '("mmultido" "\var=<start value>+-<inc>" "Repititions" t)
+ '("MMultido" "\var=<start value>+-<inc>" "Repititions" t)
+ "multidostop"
+ "multidocount"
+ '("fpAdd" "Summand 1" "Summand 2" "Register")
+ '("fpSub" "Minuend" "Subtrahend" "Register")))))
+
+;;; multido.el ends here
--- /dev/null
+;;; multind.el --- AUCTeX support for multiple indices with multind.sty.
+
+;; Copyright (C) 1999 Free Software Foundation, Inc.
+
+;; Author: Carsten Dominik <dominik@strw.leidenuniv.nl>
+;; Maintainer: auctex-devel@gnu.org
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Code:
+
+(TeX-add-style-hook "multind"
+ (lambda ()
+
+ ;; Commands
+ (TeX-add-symbols
+ '("makeindex" "Indextag")
+ '("index" TeX-arg-index-tag TeX-arg-index)
+ '("printindex" TeX-arg-index-tag "Title")
+ "printindex" "indexspace")
+
+ ;; Parsing index macros
+ (setq LaTeX-auto-regexp-list
+ (append
+ ;; The first regexp is faster, but less accurate
+ ;; '(("\\\\index\\*?{[^{}]*}{\\([^}]*\\)" 1 LaTeX-auto-index-entry))
+ ;; The second regexp is very good, but slower
+ '(("\\\\index\\*?{[^{}]*}{\\([^}{]*\\({[^}{]*\\({[^}{]*\\({[^}{]*}[^}{]*\\)*}[^}{]*\\)*}[^}{]*\\)*\\)}"
+ 1 LaTeX-auto-index-entry))
+ LaTeX-auto-regexp-list))
+
+ ;; Completion for index entries in the |see and \index commands
+ (setq TeX-complete-list
+ (append
+ '(("\\\\index{[^{}]*}{\\([^{}\n\r]*\\)" 1 LaTeX-index-entry-list)
+ ("|see{\\([^}]*\\)" 1 LaTeX-index-entry-list))
+ TeX-complete-list))
+
+ ;; RefTeX support
+ (and (fboundp 'reftex-add-index-macros)
+ (reftex-add-index-macros '(multind)))))
+
+(defvar LaTeX-multind-package-options nil
+ "Package options for the multind package.")
+
+;;; multind.el ends here
--- /dev/null
+;;; natbib.el --- Style hook for the NatBib package
+;;;
+;;; AUTHOR: Carsten Dominik <dominik@strw.leidenuniv.nl>
+;;; building on older code from Berwin Turlach
+
+;;; Code:
+
+(TeX-add-style-hook "natbib"
+ (function
+ (lambda ()
+ ;; The number in the cdr of the following list indicates how many
+ ;; optional note arguments we consider useful. Prompting for those
+ ;; arguments will still depend upon `TeX-arg-cite-note-p'.
+ (let ((citecmds
+ '(("cite" . 0)
+ ("citet" . 1) ("citet*" . 1) ("citealt" . 1) ("citealt*" . 1)
+ ("citep" . 2) ("citep*" . 2) ("citealp" . 2) ("citealp*" . 2)
+ ("citeauthor" . 0) ("citeauthor*" . 0) ("citefullauthor" . 0)
+ ("citeyear" . 0) ("citeyearpar" . 0)
+ ("shortcites" . 0))))
+
+ ;; Add these symbols
+ (apply
+ 'TeX-add-symbols
+ (mapcar
+ (lambda (cmd)
+ (cond
+ ((= (cdr cmd) 0)
+ ;; No optional arguments
+ (list (car cmd) 'TeX-arg-cite))
+ ((= (cdr cmd) 1)
+ ;; Just one optional argument, the post note
+ (list
+ (car cmd)
+ '(TeX-arg-conditional TeX-arg-cite-note-p (["Post-note"]) nil)
+ 'TeX-arg-cite))
+ ((= (cdr cmd) 2)
+ ;; Pre and post notes
+ (list
+ (car cmd)
+ '(TeX-arg-conditional TeX-arg-cite-note-p (natbib-note-args) nil)
+ 'TeX-arg-cite))))
+ citecmds))
+
+ ;; Add the other symbols
+ (TeX-add-symbols
+ '("citetext" "Text")
+ '("bibpunct" ["Post note separator"]
+ "Opening bracket"
+ "Closing bracket"
+ "Punctuation between multiple citations"
+ "style [n]umeric [s]uperscript [a]uthor-year"
+ "Punctuation between author and year"
+ "Punctuation between years for common authors")
+ '("citestyle" "Style")
+ '("citeindextrue")
+ '("citeindexfalse")
+ '("citeindextype"))
+
+ ;; Make an entry in TeX-complete-list
+ (add-to-list
+ 'TeX-complete-list
+ (list
+ (concat "\\\\\\("
+ (mapconcat (lambda (x) (regexp-quote (car x)))
+ citecmds "\\|")
+ "\\)\\(\\[[^]\n\r\\%]*\\]\\)*{\\([^{}\n\r\\%,]*,\\)*\\([^{}\n\r\\%,]*\\)")
+ 4 'LaTeX-bibitem-list "}")))
+
+ ;; Fontification
+ (when (and (fboundp 'font-latex-add-keywords)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ (font-latex-add-keywords '(("cite" "*[[{")
+ ("citet" "*[[{")
+ ("citealt" "*[[{")
+ ("citep" "*[[{")
+ ("citealp" "*[[{")
+ ("citeauthor" "*[[{")
+ ("citefullauthor" "[[{")
+ ("citeyear" "[[{")
+ ("citeyearpar" "[[{")
+ ("shortcites" "{"))
+ 'reference))
+
+ ;; Tell RefTeX
+ (if (fboundp 'reftex-set-cite-format)
+ (reftex-set-cite-format 'natbib)))))
+
+(defun natbib-note-args (optional &optional prompt definition)
+ "Prompt for two note arguments a natbib citation command."
+ (if TeX-arg-cite-note-p
+ (let* ((pre (read-string
+ (TeX-argument-prompt optional optional "Pre-note")))
+ (post (read-string
+ (TeX-argument-prompt optional optional "Post-note"))))
+ (if (not (string= pre "")) (insert "[" pre "]"))
+ (if (not (string= post ""))
+ (insert "[" post "]")
+ ;; Make sure that we have an empty post note if pre is not empty
+ (if (string= pre "") (insert "[]"))))))
+
+(defvar LaTeX-natbib-package-options '("numbers" "super" "authoryear"
+ "round" "square" "angle" "curly"
+ "comma" "colon" "nobibstyle"
+ "bibstyle" "openbib" "sectionbib"
+ "sort" "sort&compress"
+ "longnamesfirst" "nonamebreak")
+ "Package options for the natbib package.")
+
+;; natbib.el ends here
--- /dev/null
+;;; naustrian.el --- AUCTeX style for the `naustrian' babel option.
+
+;; Copyright (C) 2009 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@caeruleus.net>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2009-12-28
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; Set up AUCTeX for editing Austrian text in connection with the
+;; `naustrian' babel option.
+
+;;; Code:
+
+(TeX-add-style-hook
+ "naustrian"
+ (lambda ()
+ (TeX-run-style-hooks "ngerman")))
+
+;;; naustrian.el ends here
--- /dev/null
+;;; ngerman.el --- Setup AUCTeX for editing German text.
+
+;;; Commentary:
+;;
+;; Cater for some specialities of `(n)german.sty', e.g. special quote
+;; and hyphen strings or that `"' makes the following letter an
+;; umlaut.
+
+;;; Code:
+
+(defvar LaTeX-german-mode-syntax-table
+ (copy-syntax-table LaTeX-mode-syntax-table)
+ "Syntax table used in LaTeX mode when using `german.sty'.")
+
+(modify-syntax-entry ?\" "w" LaTeX-german-mode-syntax-table)
+
+(TeX-add-style-hook
+ "ngerman"
+ (lambda ()
+ (set-syntax-table LaTeX-german-mode-syntax-table)
+ ;; XXX: Handle former customizations of the now defunct
+ ;; German-specific variables. References to the respective
+ ;; variables are to be deleted in future versions. (now = 2005-04-01)
+ (unless (eq (car TeX-quote-language) 'override)
+ (let ((open-quote (if (and (boundp 'LaTeX-german-open-quote)
+ LaTeX-german-open-quote)
+ LaTeX-german-open-quote
+ "\"`"))
+ (close-quote (if (and (boundp 'LaTeX-german-close-quote)
+ LaTeX-german-close-quote)
+ LaTeX-german-close-quote
+ "\"'"))
+ (q-after-q (if (and (boundp 'LaTeX-german-quote-after-quote)
+ LaTeX-german-quote-after-quote)
+ LaTeX-german-quote-after-quote
+ t)))
+ (setq TeX-quote-language
+ `("ngerman" ,open-quote ,close-quote ,q-after-q))))
+ (setq LaTeX-babel-hyphen-language "ngerman")
+ ;; Fontification of quotation marks.
+ (when (fboundp 'font-latex-add-quotes)
+ (font-latex-add-quotes '("\"`" "\"'"))
+ (font-latex-add-quotes '("\">" "\"<" german)))
+ (run-hooks 'TeX-language-de-hook)))
+
+;;; ngerman.el ends here
--- /dev/null
+;;; nicefrac.el --- AUCTeX style for the LaTeX package `nicefrac.sty' (v0.9b)
+
+;; Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+;; Author: Christian Schlauer <cschl@arcor.de>
+;; Maintainer: auctex-devel@gnu.org
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `nicefrac.sty'.
+
+;;; Code:
+
+(TeX-add-style-hook
+ "nicefrac"
+ (lambda ()
+ (TeX-add-symbols
+ '("nicefrac" [ "Font changing command" ] "Numerator" "Denominator"))
+ ;; Fontification
+ (when (and (featurep 'font-latex)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ (font-latex-add-keywords '(("nicefrac" "[{{")) 'textual))))
+
+(defvar LaTeX-nicefrac-package-options '("nice" "ugly")
+ "Package options for the nicefrac package.")
+
+;;; nicefrac.el ends here
--- /dev/null
+;;; nomencl.el --- AUCTeX style for the nomencl class.
+
+;; Copyright (C) 2007 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@caeruleus.net>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2007-10-09
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for the nomencl package.
+
+;;; Code:
+
+(defvar LaTeX-nomencl-package-options
+ '("refeq" "norefeq" "refpage" "norefpage" "prefix" "noprefix" "cfg" "nocfg"
+ "intoc" "notintoq" "compatible" "noncompatible" "croatian" "danish"
+ "english" "french" "german" "italian" "polish" "portuguese" "russian"
+ "spanish" "ukrainian")
+ "Package options for the nomencl package.")
+
+(TeX-add-style-hook
+ "nomencl"
+ (lambda ()
+ (TeX-add-symbols
+ '("makenomenclature" 0)
+ '("printnomenclature" ["Label width"])
+ '("nomenclature" ["Prefix"] "Symbol" "Description")
+ "nomrefeq"
+ "nomrefpage"
+ "nomrefeqpage"
+ "nomnorefeq"
+ "nomnorefpage"
+ "nomnorefeqpage"
+ '("nomlabelwidth" 0)
+ '("nomname" 0)
+ '("nomgroup" 0)
+ '("nompreamble" 0)
+ '("nompostamble" 0)
+ '("nomitemsep" 0)
+ '("nomprefix" 0)
+ '("nomlabel" 0)
+ '("nomentryend" 0)
+ '("eqdeclaration" 0)
+ '("pagedeclaration" 0))
+ ;; Fontification
+ (when (and (featurep 'font-latex)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ (font-latex-add-keywords '(("nomenclature" "[{{"))
+ 'reference))))
+
+;;; nomencl.el ends here
--- /dev/null
+;;; paralist.el -- AUCTeX style for paralist.sty
+
+;; Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@iwi.uni-sb.de>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2003-10-22
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `paralist.sty'.
+
+;;; Code:
+
+;; Insert an itemize-ish environment and ask for an optional label
+(defun LaTeX-paralist-env-item-opt-label (environment)
+ "Insert ENVIRONMENT, an optional label and the first item."
+ (LaTeX-insert-environment
+ environment
+ (let ((label (read-string "(Optional) Label: ")))
+ (concat (unless (zerop (length label))
+ (format "[%s]" label)))))
+ (LaTeX-find-matching-begin)
+ (end-of-line 1)
+ (delete-char 1)
+ (delete-horizontal-space)
+ (LaTeX-insert-item))
+
+(TeX-add-style-hook
+ "paralist"
+ (lambda ()
+
+ ;; Add compactdesc to the list of environments which have an optional
+ ;; argument for each item.
+ (add-to-list 'LaTeX-item-list '("compactdesc" . LaTeX-item-argument))
+
+ ;; New symbols
+ (TeX-add-symbols
+ '("pointedenum")
+ '("pointlessenum")
+ '("paradescriptionlabel")
+ '("setdefaultitem" "First level" "Second level" "Third level"
+ "Fourth level")
+ '("setdefaultenum" "First level" "Second level" "Third level"
+ "Fourth level")
+ '("setdefaultleftmargin" "First level" "Second level" "Third level"
+ "Fourth level" "Fifth level" "Sixth level"))
+
+ ;; New environments
+ (LaTeX-add-environments
+ '("asparaenum" LaTeX-paralist-env-item-opt-label)
+ '("inparaenum" LaTeX-paralist-env-item-opt-label)
+ '("compactenum" LaTeX-paralist-env-item-opt-label)
+ '("asparaitem" LaTeX-paralist-env-item-opt-label)
+ '("inparaitem" LaTeX-paralist-env-item-opt-label)
+ '("compactitem" LaTeX-paralist-env-item-opt-label)
+ '("compactdesc" LaTeX-env-item)
+ ;; FIXME: Should not be available if package is loaded with option
+ ;; `olditem':
+ '("itemize" LaTeX-paralist-env-item-opt-label)
+ ;; FIXME: Should not be available if package is loaded with option
+ ;; `oldenum':
+ '("enumerate" LaTeX-paralist-env-item-opt-label)
+ ;; FIXME: Only defined if package is loaded with option
+ ;; `defblank':
+ '("asparablank" LaTeX-env-item)
+ '("inparablank" LaTeX-env-item))
+
+ ;; Fontification
+ (when (and (featurep 'font-latex)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ (font-latex-add-keywords '(("setdefaultitem" "{{{{")
+ ("setdefaultenum" "{{{{")
+ ("setdefaultleftmargin" "{{{{{{"))
+ 'variable))))
+
+(defvar LaTeX-paralist-package-options '("newitem" "olditem" "newenum"
+ "oldenum" "alwaysadjust"
+ "neveradjust" "neverdecrease"
+ "increaseonly" "defblank"
+ "pointedenum" "pointlessenum"
+ "cfg" "nocfg" "flushright"
+ "flushleft")
+ "Package options for the paralist package.")
+
+;;; paralist.el ends here
--- /dev/null
+;;; pdfsync.el --- AUCTeX style for `pdfsync.sty'
+
+;; Copyright (C) 2005, 2008 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@iwi.uni-sb.de>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2005-12-28
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `pdfsync.sty'.
+
+;;; Code:
+
+(defun LaTeX-pdfsync-output-page ()
+ "Return page number in output file corresponding to buffer position."
+ (let* ((line (TeX-line-number-at-pos))
+ (master (TeX-active-master))
+ (file (file-name-sans-extension
+ (file-relative-name (buffer-file-name)
+ (file-name-directory master))))
+ (pdfsync-file (concat master ".pdfsync"))
+ (buf-live-p (get-file-buffer pdfsync-file))
+ (sync-record "0")
+ (sync-line "-1")
+ (sync-page "1")
+ last-match)
+ (when (file-exists-p pdfsync-file)
+ (with-current-buffer (find-file-noselect pdfsync-file)
+ (save-restriction
+ (goto-char (point-min))
+ ;; Narrow region to file in question.
+ (when (not (string= file master))
+ (re-search-forward (concat "^(" file "\\(.tex\\)?$") nil t)
+ (let ((beg (match-beginning 0)))
+ (goto-char beg)
+ (narrow-to-region (line-beginning-position 2)
+ (progn (forward-sexp) (point))))
+ (goto-char (point-min)))
+ ;; Look for the record number.
+ (catch 'break
+ (while (re-search-forward "^(\\|^l \\([0-9]+\\) \\([0-9]+\\)" nil t)
+ (cond ((string= (match-string 0) "(")
+ (goto-char (match-beginning 0))
+ (forward-sexp))
+ ((> (string-to-number (match-string 2)) line)
+ (throw 'break nil))
+ (t
+ (setq sync-record (match-string 1)
+ sync-line (match-string 2)
+ last-match (match-beginning 0))))))
+ ;; Look for the page number.
+ (goto-char (or last-match (point-min)))
+ ;; There might not be any p or s lines for the current file,
+ ;; so make it possible to search further.
+ (widen)
+ (catch 'break
+ (while (re-search-forward "^p \\([0-9]+\\)" nil t)
+ (when (>= (string-to-number (match-string 1))
+ (string-to-number sync-record))
+ (re-search-backward "^s \\([0-9]+\\)" nil t)
+ (setq sync-page (match-string 1))
+ (throw 'break nil)))))
+ ;; Kill the buffer if it was loaded by us.
+ (unless buf-live-p (kill-buffer (current-buffer)))))
+ sync-page))
+
+(TeX-add-style-hook
+ "pdfsync"
+ (lambda ()
+ (setq TeX-source-correlate-output-page-function 'LaTeX-pdfsync-output-page)))
+
+;;; pdfsync.el ends here
--- /dev/null
+;;; plfonts.el - Setup AUC TeX for editing Polish text with plfonts.sty
+
+;; $Id: plfonts.el,v 1.1 1994/01/30 21:17:25 amanda Exp $
+
+;;; Commentary:
+;;
+;; `plfonts.sty' use `"' to make next character Polish.
+;; `plfonts.sty' <C> L. Holenderski, IIUW, lhol@mimuw.edu.pl
+
+;;; Code:
+
+(defvar LaTeX-plfonts-mode-syntax-table
+ (copy-syntax-table LaTeX-mode-syntax-table)
+ "Syntax table used in LaTeX mode when using `plfonts.sty'.")
+
+(modify-syntax-entry ?\" "w" LaTeX-plfonts-mode-syntax-table)
+
+(TeX-add-style-hook "plfonts"
+ (function (lambda ()
+ (set-syntax-table LaTeX-plfonts-mode-syntax-table)
+ (make-local-variable 'TeX-open-quote)
+ (make-local-variable 'TeX-close-quote)
+ (make-local-variable 'TeX-quote-after-quote)
+ (make-local-variable 'TeX-command-default)
+ (setq TeX-open-quote "\"<")
+ (setq TeX-close-quote "\">")
+ (setq TeX-quote-after-quote t)
+ (setq TeX-command-default "plLaTeX")
+ (run-hooks 'TeX-language-pl-hook))))
+
+;;; plfonts.el ends here
--- /dev/null
+;;; plhb.el - Setup AUC TeX for editing Polish text with plhb.sty
+
+;; $Id: plhb.el,v 1.1 1994/01/30 21:17:27 amanda Exp $
+
+;;; Commentary:
+;;
+;; `plhb.sty' use `"' to make next character Polish.
+;; `plhb.sty' <C> J. S. Bie\'n, IIUW, jsbien@mimuw.edu.pl
+
+;;; Code:
+
+(defvar LaTeX-plhb-mode-syntax-table
+ (copy-syntax-table LaTeX-mode-syntax-table)
+ "Syntax table used in LaTeX mode when using `plhb.sty'.")
+
+(modify-syntax-entry ?\" "w" LaTeX-plhb-mode-syntax-table)
+
+(TeX-add-style-hook "plhb"
+ (function (lambda ()
+ (set-syntax-table LaTeX-plhb-mode-syntax-table)
+ (make-local-variable 'TeX-open-quote)
+ (make-local-variable 'TeX-close-quote)
+ (make-local-variable 'TeX-command-default)
+ (make-local-variable 'TeX-quote-after-quote)
+ (setq TeX-open-quote "\"<")
+ (setq TeX-close-quote "\">")
+ (setq TeX-quote-after-quote t)
+ (setq TeX-command-default "plLaTeX")
+ (run-hooks 'TeX-language-pl-hook))))
+
+;;; plhb.el ends here
--- /dev/null
+;;; polish.el --- AUCTeX style for the `polish' babel option.
+
+;; Copyright (C) 2007 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@caeruleus.net>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2007-01-08
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; Set up AUCTeX for editing Polish text in connection with the
+;; `polish' babel option.
+
+;;; Code:
+
+(defvar LaTeX-polish-mode-syntax-table
+ (copy-syntax-table LaTeX-mode-syntax-table)
+ "Syntax table used in LaTeX mode when using `polish.sty'.")
+
+(modify-syntax-entry ?\" "w" LaTeX-polish-mode-syntax-table)
+
+(TeX-add-style-hook
+ "polish"
+ (lambda ()
+ (set-syntax-table LaTeX-polish-mode-syntax-table)
+ (setq TeX-quote-language '("polish" "\"`" "\"'" t))
+ ;; Fontification of quotation marks.
+ (when (fboundp 'font-latex-add-quotes)
+ (font-latex-add-quotes '("\"`" "\"'"))
+ (font-latex-add-quotes '("\"<" "\">" french)))
+ (run-hooks 'TeX-language-pl-hook)))
+
+;;; polish.el ends here
--- /dev/null
+;;; polski.el --- AUCTeX style for `polski.sty'.
+
+;; Copyright (C) 2007 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@caeruleus.net>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2007-01-11
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; Set up AUCTeX for editing Polish text in connection with
+;; `polski.sty'.
+
+;;; Code:
+
+(defvar LaTeX-polski-package-options
+ '("plmath" "nomathsymbols" "MeX" "T1" "QX" "OT1" "OT4" "prefixinginverb"
+ "noprefixinginverb" "roku" "r." "noroku")
+ "Package options for polski.sty.")
+
+(TeX-add-style-hook
+ "polski"
+ (lambda ()
+ (TeX-add-symbols
+ ;; Dashes
+ "dywiz"
+ "pauza"
+ "ppauza")
+ ;; Quotation marks
+ (setq TeX-quote-language '("polski" ",," "''" t))
+ ;; Fontification of quotation marks.
+ (when (fboundp 'font-latex-add-quotes)
+ (font-latex-add-quotes '(",," "''")))
+ (run-hooks 'TeX-language-pl-hook)))
+
+;;; polski.el ends here
--- /dev/null
+;;; pst-grad.el --- AUCTeX style for `pst-grad.sty'
+
+;; Copyright (C) 2007 Free Software Foundation, Inc.
+
+;; Author: Holger Sparr <holger.sparr@gmx.net>
+;; Created: 21 Jun 2007
+;; Keywords: latex, pstricks, auctex, emacs
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `pst-grad.sty'.
+
+;;; TODO:
+;;
+;; --
+
+;;; Code:
+
+;;; Parameters
+(defvar LaTeX-pstgrad-parameters-name-list
+ '("gradangle" "gradbegin" "gradend" "gradlines" "gradmidpoint"
+ "gradientHSB" "GradientCircle" "GradientPos" "GradientScale")
+ "A list of parameter names in pst-grad.")
+
+;;; Aliases
+(defvaralias 'LaTeX-pst-gradbegin-list 'LaTeX-pst-color-list)
+(defvaralias 'LaTeX-pst-gradend-list 'LaTeX-pst-color-list)
+
+;;; Hook
+(TeX-add-style-hook
+ "pst-grad"
+ (function
+ (lambda ()
+ (TeX-run-style-hooks
+ "pstricks")
+ (unless (member "gradient" LaTeX-pst-fillstyle-list)
+ (setq LaTeX-pst-fillstyle-list (append LaTeX-pst-fillstyle-list
+ '("gradient")))
+ (setq LaTeX-pst-parameters-completion-regexp
+ (concat
+ (substring LaTeX-pst-parameters-completion-regexp 0 -2)
+ "\\|gradbegin\\|gradend\\)")))
+ (make-local-variable 'LaTeX-pst-parameters-name-list)
+ (setq LaTeX-pst-parameters-name-list
+ (append LaTeX-pstgrad-parameters-name-list
+ LaTeX-pst-parameters-name-list)))))
+
+;;; pst-grad.el ends here
--- /dev/null
+;;; pst-node.el --- AUCTeX style for `pst-node.sty'
+
+;; Copyright (C) 2007 Free Software Foundation, Inc.
+
+;; Author: Holger Sparr <holger.sparr@gmx.net>
+;; Created: 21 Jun 2007
+;; Based on: Jean-Philippe Georget's pst-plot.el
+;; Keywords: latex, pstricks, auctex, emacs
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `pst-node.sty'.
+
+;;; TODO:
+;;
+;; -- self parsing of possible node names
+;; -- adding more macro support
+
+;;; Code:
+
+(defalias 'LaTeX-pst-node 'LaTeX-pst-point)
+
+(defvar LaTeX-pstnode-parameters-completion-regexp
+ "\\(npos\\|nrot\\)"
+ "Regexp for `string-match'ing a parameter.")
+
+(defvar LaTeX-pstnode-parameters-boolean-regexp "show\\([a-zA-Z]+\\)"
+ "Regexp for `string-match'ing a parameter.")
+
+(defvar LaTeX-pstnode-npos-list '(".25" ".5" ".75" "1" "1.5" "2")
+ "A list of values for npos in nput.")
+
+(defvar LaTeX-pstnode-nrot-list '(":U" ":D" ":R" ":L")
+ "A list of values for nrot in nput.")
+
+(defvar LaTeX-pstnode-psmatrix-list
+ '("mnode" "emnode" "name" "nodealign" "mocl" "rowsep" "colsep"
+ "mnodesize")
+ "A list of values for trimode in pstribox.")
+
+;;; Parameters
+(defvar LaTeX-pstnode-parameters-history nil
+ "History of values for parameters in pst-node.")
+
+(defvar LaTeX-pstnode-parameters-value-history nil
+ "History of parameter values in pst-node.")
+
+(defvar LaTeX-pstnode-parameters-name-list
+ '("angle" "angleA" "angleB" "arcangle" "arcangleA" "arcangleB" "arm"
+ "armA" "armB" "boxsize" "colsep" "framesize" "href" "loopsize"
+ "ncurv" "ncurvA" "ncurvB" "nodesepA" "nodesepB" "npos" "nrot"
+ "offset" "offsetA" "offsetB" "radius" "vref" "Xnodesep" "XnodesepA"
+ "XnodesepB" "Ynodesep" "YnodesepA" "YnodesepB")
+ "A list of parameters' name in pst-node.")
+
+(defvar LaTeX-pstnode-parameters-name-history nil
+ "History of parameter names in pst-node.")
+
+;;; Derived Functions from pstricks.el defuns
+(defun LaTeX-pstnode-parameter-value (param)
+ "See documentation of `LaTeX-package-parameter-value'."
+ (LaTeX-package-parameter-value param "pstnode"))
+
+(defun LaTeX-pstnode-parameters-pref-and-chosen (param &optional noskip)
+ "See documentation of `LaTeX-package-parameters-pref-and-chosen'."
+ (LaTeX-package-parameters-pref-and-chosen param "pstnode" noskip))
+
+(defun LaTeX-pstnode-parameters (optional &optional preparam param)
+ "See documentation of `LaTeX-package-parameters-pref-and-chosen'."
+ (LaTeX-package-parameters optional "pstnode" preparam param))
+
+;;; Macros
+(defun LaTeX-pstnode-macro-nput (optional &optional arg)
+ "Return \\nput arguments after querying."
+ (insert "[rot=" (LaTeX-pst-angle) "]{" (LaTeX-pst-angle) "}{"
+ (LaTeX-pst-node) "}"))
+
+(defun LaTeX-pstnode-macro-cnodeput (optional &optional arg)
+ "Return \\cnodeput arguments after querying."
+ (let ((rotation (if current-prefix-arg (LaTeX-pst-angle) nil))
+ (pnt (if current-prefix-arg (LaTeX-pst-point) nil)))
+ (insert (if rotation (format "{%s}" rotation) "")
+ (if pnt (format "(%s)" pnt) "") "{" (LaTeX-pst-node) "}")))
+
+(defun LaTeX-pstnode-macro-nc (optional &optional arg)
+ "Return \\nc* arguments after querying."
+ (let ((arrows (LaTeX-pst-arrows)))
+ (insert (if arrows (format "{%s}" arrows) "") "{" (LaTeX-pst-node)
+ "}{" (LaTeX-pst-node) "}")))
+
+(defun LaTeX-pstnode-macro-pc (optional &optional arg)
+ "Return \\pc* arguments after querying."
+ (let ((arrows (LaTeX-pst-arrows)))
+ (insert (if arrows (format "{%s}" arrows) "") "(" (LaTeX-pst-point)
+ ")(" (LaTeX-pst-point) ")")))
+
+(defun LaTeX-pstnode-macro-tnabcput (optional &optional arg)
+ "Return \\t?put or \\n?put arguments after querying."
+ (TeX-argument-insert (LaTeX-pstnode-parameters-pref-and-chosen
+ '("nrot" "npos")) optional))
+
+;;; Environments
+(defun LaTeX-pstnode-env-psmatrix (env)
+ "Return psmatrix environment with arguments."
+ (let ((opt (completing-read-multiple "Options: "
+ LaTeX-pstnode-psmatrix-list)))
+ (LaTeX-insert-environment env opt)))
+
+(TeX-add-style-hook
+ "pst-node"
+ (function
+ (lambda ()
+ (LaTeX-add-environments
+ '("psmatrix" LaTeX-pstnode-env-psmatrix))
+ (TeX-add-symbols
+ '("MakeShortNab" 2) '("MakeShortTablr" 4) '("PSTnodesLoaded" 0)
+ '("nput" LaTeX-pstnode-macro-nput TeX-arg-macro)
+ '("cnodeput" [LaTeX-pst-parameters] LaTeX-pstnode-macro-cnodeput t)
+ '("Cnode" [LaTeX-pstnode-parameters] LaTeX-pst-point-in-parens t)
+ '("cnode" [LaTeX-pstnode-parameters] "Radius" t)
+ '("fnode" [LaTeX-pstnode-parameters] LaTeX-pst-point-in-parens t)
+ '("fnode*" [LaTeX-pstnode-parameters] LaTeX-pst-point-in-parens t)
+ '("dotnode" [LaTeX-pstnode-parameters] LaTeX-pst-point-in-parens t)
+ '("pnode" LaTeX-pst-point-in-parens t)
+ '("Rnode" [LaTeX-pstnode-parameters ("href" "vref")]
+ (TeX-arg-eval LaTeX-pst-point) t)
+ '("rnode" [LaTeX-pstnode-parameters ("ref")]
+ (TeX-arg-eval LaTeX-pst-point) t)
+ '("circlenode" [LaTeX-pst-parameters]
+ (TeX-arg-eval LaTeX-pst-point) t)
+ '("dianode" [LaTeX-pst-parameters] "Node Name" t)
+ '("ovalnode" [LaTeX-pst-parameters] "Node Name" t)
+ '("trinode" [LaTeX-pst-parameters] "Node Name" t)
+ '("dotnode" [LaTeX-pst-parameters] LaTeX-pst-point-in-parens
+ "Node Name")
+ '("naput" [LaTeX-pstnode-macro-tnabcput] t)
+ '("nbput" [LaTeX-pstnode-macro-tnabcput] t)
+ '("ncput" [LaTeX-pstnode-macro-tnabcput] t)
+ '("taput" [LaTeX-pstnode-macro-tnabcput] t)
+ '("tbput" [LaTeX-pstnode-macro-tnabcput] t)
+ '("thput" [LaTeX-pstnode-macro-tnabcput] t)
+ '("tlput" [LaTeX-pstnode-macro-tnabcput] t)
+ '("trput" [LaTeX-pstnode-macro-tnabcput] t)
+ '("tvput" [LaTeX-pstnode-macro-tnabcput] t)
+ '("ncline" [LaTeX-pst-parameters] LaTeX-pstnode-macro-nc)
+ '("ncarc" [LaTeX-pst-parameters] LaTeX-pstnode-macro-nc)
+ '("ncdiag" [LaTeX-pst-parameters] LaTeX-pstnode-macro-nc)
+ '("ncdiagg" [LaTeX-pst-parameters] LaTeX-pstnode-macro-nc)
+ '("ncbar" [LaTeX-pst-parameters] LaTeX-pstnode-macro-nc)
+ '("ncangle" [LaTeX-pst-parameters] LaTeX-pstnode-macro-nc)
+ '("ncangles" [LaTeX-pst-parameters] LaTeX-pstnode-macro-nc)
+ '("ncloop" [LaTeX-pst-parameters] LaTeX-pstnode-macro-nc)
+ '("nccurve" [LaTeX-pst-parameters] LaTeX-pstnode-macro-nc)
+ '("nccircle" [LaTeX-pst-parameters] LaTeX-pstnode-macro-nc)
+ '("ncbox" [LaTeX-pst-parameters] LaTeX-pstnode-macro-nc)
+ '("ncarcbox" [LaTeX-pst-parameters] LaTeX-pstnode-macro-nc)
+ '("pcline" [LaTeX-pst-parameters] LaTeX-pstnode-macro-pc)
+ '("pccurve" [LaTeX-pst-parameters] LaTeX-pstnode-macro-pc)
+ '("pcarc" [LaTeX-pst-parameters] LaTeX-pstnode-macro-pc)
+ '("pcbar" [LaTeX-pst-parameters] LaTeX-pstnode-macro-pc)
+ '("pcdiag" [LaTeX-pst-parameters] LaTeX-pstnode-macro-pc)
+ '("pcdiagg" [LaTeX-pst-parameters] LaTeX-pstnode-macro-pc)
+ '("pcangle" [LaTeX-pst-parameters] LaTeX-pstnode-macro-pc)
+ '("pcangles" [LaTeX-pst-parameters] LaTeX-pstnode-macro-pc)
+ '("pcloop" [LaTeX-pst-parameters] LaTeX-pstnode-macro-pc)
+ '("pcbox" [LaTeX-pst-parameters] LaTeX-pstnode-macro-pc)
+ '("pcarcbox" [LaTeX-pst-parameters] LaTeX-pstnode-macro-pc)
+ '("psspan" (TeX-arg-eval LaTeX-pst-input-int))
+ '("psrowhook" t)
+ '("pscolhook" t))
+ (TeX-run-style-hooks
+ "pstricks"))))
+
+;;; pst-node.el ends here
--- /dev/null
+;;; pst-plot.el --- AUCTeX style for `pst-plot.sty'
+
+;; Copyright (C) 2007 Free Software Foundation, Inc.
+
+;; Author: Holger Sparr <holger.sparr@gmx.net>
+;; Created: 21 Jun 2007
+;; Based on: Jean-Philippe Georget's pst-plot.el
+;; Keywords: latex, pstricks, auctex, emacs
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `pst-plot.sty'.
+
+;;; TODO:
+;;
+;; -- improve symbol support (especially the pstScalePoints macros)
+;; -- check for multido.el necessity
+
+;;; Code:
+
+;; Self Parsing -- see (info "(auctex)Hacking the Parser")
+(defvar LaTeX-auto-pstplot-regexp-list
+ '(("\\\\\\(save\\|read\\)data{?\\(\\\\[a-zA-Z]+\\)}?"
+ 2 LaTeX-auto-pstplot))
+ "List of regular expressions to extract arguments of \\*data
+ macros.")
+
+(defvar LaTeX-auto-pstplot nil
+ "Temporary for parsing \\*data definitions.")
+
+(defun LaTeX-pstplot-cleanup ()
+ "Move symbols from `LaTeX-auto-pstplot to `TeX-auto-symbol'."
+ (mapcar (lambda (symbol)
+ ;; (setq TeX-symbol-list (cons (list symbol 0) TeX-symbol-list))
+ ;; (setq TeX-auto-symbol (cons (list symbol 0) TeX-auto-symbol)))
+ (add-to-list 'LaTeX-pstplot-datasets symbol))
+ LaTeX-auto-pstplot))
+
+(defun LaTeX-pstplot-prepare ()
+ "Clear `LaTeX-auto-pstplot' before use."
+ (setq LaTeX-auto-pstplot nil))
+
+(add-hook 'TeX-auto-prepare-hook 'LaTeX-pstplot-prepare)
+(add-hook 'TeX-auto-cleanup-hook 'LaTeX-pstplot-cleanup)
+
+;;; Parameters
+(defvar LaTeX-pstplot-datasets nil
+ "List of parsed data sets defined with \\savedata or \\readdata.")
+
+(defvar LaTeX-pstplot-parameters-name-list
+ '("axesstyle" "labels" "plotpoints" "plotstyle" "showorigin" "ticks"
+ "ticksize" "tickstyle")
+ "A list of parameters' name in pst-plot.")
+
+(defvar LaTeX-pst-ticks-list '(t "none" "all" "x" "y")
+ "A list of values for ticks in pst-plot.")
+
+(defvaralias 'LaTeX-pst-labels-list 'LaTeX-pst-ticks-list)
+
+(defvar LaTeX-pst-plotstyle-list
+ '(t "dots" "line" "polygon" "curve" "ecurve" "ccurve")
+ "A list of values for tickstyles in pst-plot.")
+
+(defvar LaTeX-pst-tickstyle-list '(t "full" "top" "bottom")
+ "A list of values for tickstyles in pst-plot.")
+
+(defvar LaTeX-pst-axesstyle-list '(t "axes" "frame" "none")
+ "A list of values for axesstyles in pst-plot.")
+
+;;; Macros
+(defun LaTeX-pst-macro-psaxes (optional &optional arg)
+ "Return \\psaxes arguments after querying."
+(let* ((cpref (if current-prefix-arg (car current-prefix-arg) 0))
+ (arrows (LaTeX-pst-arrows))
+ (pnt1 (if (> cpref 4) (LaTeX-pst-point) nil))
+ (pnt2 (if (> cpref 0) (LaTeX-pst-point) nil))
+ (pnt3 (LaTeX-pst-point)))
+ ;; insert \psaxes arguments
+ (insert (if arrows (format "{%s}" arrows) "")
+ (if pnt1 (format "(%s)" pnt1) "")
+ (if pnt2 (format "(%s)" pnt2) "") "(" pnt3 ")")))
+
+;;; Derived defuns
+(defun LaTeX-pstplot-datasets-read ()
+ (TeX-arg-compl-list "Datasets" LaTeX-pstplot-datasets))
+
+;;; Hook
+(TeX-add-style-hook
+ "pst-plot"
+ (function
+ (lambda ()
+ (mapcar 'TeX-auto-add-regexp LaTeX-auto-pstplot-regexp-list)
+ (TeX-add-symbols
+ '("readdata" "Macro Name" TeX-arg-file)
+ '("savedata" "Macro Name" ["Values"])
+ '("dataplot" ["Options"]
+ (TeX-arg-eval LaTeX-pstplot-datasets-read))
+ '("fileplot" ["Options"] TeX-arg-file)
+ '("listplot" ["Options"] "Values")
+ '("pstScalePoints" "X-Mod" "Y-Mod")
+ '("psplot" [LaTeX-pst-parameter] "xmin" "xmax" t)
+ '("parametricplot" [LaTeX-pst-parameter] "xmin" "xmax" t)
+ '("psaxes" [LaTeX-pst-parameters] LaTeX-pst-macro-psaxes)
+ "pshlabel"
+ "psvlabel")
+ (TeX-run-style-hooks
+ "pstricks"
+ "multido")
+ (unless (string-match "plotstyle"
+ LaTeX-pst-parameters-completion-regexp)
+ (setq LaTeX-pst-parameters-completion-regexp
+ (concat
+ (substring LaTeX-pst-parameters-completion-regexp 0 -2)
+ "\\|plotstyle\\|ticks\\|tickstyle\\|axesstyle\\|labels\\)")))
+ (make-local-variable 'LaTeX-pst-parameters-name-list)
+ (setq LaTeX-pst-parameters-name-list
+ (append LaTeX-pstplot-parameters-name-list
+ LaTeX-pst-parameters-name-list)))))
+
+;;; pst-plot.el ends here
--- /dev/null
+;;; pst-slpe.el --- AUCTeX style for `pst-slpe.sty'
+
+;; Copyright (C) 2007 Free Software Foundation, Inc.
+
+;; Author: Holger Sparr <holger.sparr@gmx.net>
+;; Created: 21 Jun 2007
+;; Keywords: latex, pstricks, auctex, emacs
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `pst-slpe.sty'.
+
+;;; TODO:
+;;
+;; --
+
+;;; Code:
+
+;;; Parameters
+(defvar LaTeX-pstslpe-parameters-name-list
+ '("slopeangle" "slopecenter" "slopecolors" "slopebegin" "slopeend"
+ "sloperadius" "slopesteps")
+ "A list of parameter names in pst-slpe.")
+
+;;; Aliases
+(defvaralias 'LaTeX-pst-slopebegin-list 'LaTeX-pst-color-list)
+(defvaralias 'LaTeX-pst-slopeend-list 'LaTeX-pst-color-list)
+
+;;; Define hook
+(TeX-add-style-hook
+ "pst-slpe"
+ (function
+ (lambda ()
+ (TeX-run-style-hooks
+ "pstricks")
+ (unless (member "slope" LaTeX-pst-fillstyle-list)
+ (setq LaTeX-pst-fillstyle-list
+ (append LaTeX-pst-fillstyle-list
+ '("slope" "slopes" "ccslope" "ccslopes" "radslope"
+ "radslopes")))
+ (setq LaTeX-pst-parameters-completion-regexp
+ (concat
+ (substring LaTeX-pst-parameters-completion-regexp 0 -2)
+ "\\|slopebegin\\|slopeend\\)")))
+ (make-local-variable 'LaTeX-pst-parameters-name-list)
+ (setq LaTeX-pst-parameters-name-list
+ (append LaTeX-pstslpe-parameters-name-list
+ LaTeX-pst-parameters-name-list)))))
+
+;;; pst-slpe.el ends here
--- /dev/null
+;;; pstricks.el --- AUCTeX style for the `pstricks' package.
+
+;; Copyright (C) 2007, 2009 Free Software Foundation, Inc.
+
+;; Author: Holger Sparr <holger.sparr@gmx.net>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2007-06-14
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+;;
+;; AUCTeX style file for PSTricks
+;;
+;; Support for basic PSTricks macros and their arguments. Separate
+;; history variables for point, angle, ... arguments.
+;;
+;; Parameter input completion together with input completion for certain
+;; parameters (e.g. linestyle, linecolor and the like).
+;;
+;; There is a PSTricks-specific support for adding new parameters to
+;; existing parameter lists or changing existing ones in optional
+;; macro arguments. You might want to make those available through
+;; key bindings by using something like
+;; (define-key LaTeX-mode-map (kbd "C-c p a")
+;; 'LaTeX-pst-parameter-add)
+;; (define-key LaTeX-mode-map (kbd "C-c p c")
+;; 'LaTeX-pst-parameter-change-value)
+;; in a personal style file for PSTricks.
+
+;;; History:
+;;
+;; 14/06/2007 rewrite of pstricks.el based on Jean-Philippe Georget's
+;; pstricks.el version found on <URI:
+;; http://www.emacswiki.org/cgi-bin/wiki/pstricks.el>
+
+;;; TODO:
+;;
+;; -- Use alist or hash-table for parameter input
+;; -- Add more regularly used PSTricks macros
+;; -- Prevent errors in AUCTeX modes other than LaTeX mode.
+;; -- Check if the functionality for adding and changing parameters
+;; can be generalized.
+
+;;; Code:
+
+;;; General Functions
+
+(defun TeX-arg-compl-list (list &optional prompt hist)
+ "Input a value after PROMPT with completion from LIST and HISTORY."
+ (let ((first (car list)))
+ (if (and first (listp first))
+ (let ((func (nth 0 first))
+ (prompt (concat (or (nth 1 first) prompt) ": "))
+ (compl (nth 2 first))
+ (hist (or (nth 3 first) hist))
+ (crm-separator (nth 4 first))
+ res)
+ (setq list (cdr list))
+ (cond ((eq func 'completing-read-multiple)
+ (setq res (funcall func prompt list nil compl nil hist))
+ (mapconcat 'identity res crm-separator))
+ ((eq func 'completing-read)
+ (setq res
+ (funcall func prompt list nil compl nil hist)))))
+ (completing-read (concat prompt ": ") list nil nil nil hist))))
+
+;; XXX: Show default value in prompt. Perhaps extend
+;; `TeX-argument-prompt' to do that.
+(defun LaTeX-pst-what (what prompt default &optional arg)
+ "Ask for WHAT with PROMPT with DEFAULT.
+The corresponding lists LaTeX-pst-<what>-\\(list\\|history\\)
+have to exist.
+
+\(Used to define functions named LaTeX-pst-<what>.\))"
+ (let ((list (intern (concat "LaTeX-pst-" what "-list")))
+ (hist (intern (concat "LaTeX-pst-" what "-history"))))
+ (if (not arg)
+ (setq arg (TeX-arg-compl-list (symbol-value list) prompt hist)))
+ (if (string= arg "")
+ default
+ (add-to-list list arg)
+ arg)))
+
+(defun LaTeX-pst-input-int (prompt arg)
+ "Return number as string asked for with PROMPT if no number
+passed with ARG."
+ (unless (numberp arg)
+ (setq arg (read-number (concat prompt ": ") 2)))
+ (number-to-string arg))
+
+(defun LaTeX-pst-enclose-obj (symbol op cl)
+ "Enclose string returned by the `funcall' SYMBOL in OP and CL
+character."
+ (let ((str (funcall symbol)))
+ (if str (insert (char-to-string op) str (char-to-string cl)))))
+
+(defun LaTeX-package-parameter-value (param pname)
+ "Ask for possible value of parameter PARAM given as string
+available through package name PNAME and return \"param=value\"."
+ (add-to-list (intern (concat "LaTeX-" pname "-parameters-name-list"))
+ param)
+ ;; select predefined set
+ (let* ((cregexp
+ (symbol-value
+ (intern (concat "LaTeX-" pname
+ "-parameters-completion-regexp"))))
+ (bregexp
+ (symbol-value (intern (concat "LaTeX-" pname
+ "-parameters-boolean-regexp"))))
+ (parlist (cond
+ ((string-match cregexp param)
+ (intern (concat "LaTeX-" pname "-"
+ (match-string 0 param) "-list")))
+ ((string-match bregexp param)
+ 'LaTeX-pst-boolean-list)))
+ val compl)
+ ;; ask for value
+ (setq val (TeX-arg-compl-list
+ (symbol-value parlist)
+ (concat "(Press TAB for completions) " param)
+ (intern (concat "LaTeX-" pname
+ "-parameters-value-history"))))
+ ;; FIXME: This looks broken. `compl' is never set and unless ""
+ ;; is added to parlist (at least in the Boolean case), the prompt
+ ;; shown by `TeX-arg-compl-list' will be incorrect.
+ (if (and (not compl) parlist) (add-to-list parlist val))
+ (if (string= val "") "" (concat param "=" val))))
+
+(defun LaTeX-package-parameters-pref-and-chosen (param pname noskip)
+ "Set values for elements of PARAM from package PNAME and
+further explicitly typed in parameters and return a comma
+separated list as string."
+ (let ((allpars "")
+ (fask (intern (concat "LaTeX-" pname "-parameter-value")))
+ tpara parval)
+ (when param
+ (while param
+ (setq tpara (pop param))
+ (setq parval (funcall fask tpara))
+ (setq allpars
+ (concat allpars
+ (if (or (string= "" allpars) (string= "" parval))
+ "" ",") parval))))
+ ;; ask for parameter names as long as none is given
+ (when noskip
+ (while
+ (not
+ (string=
+ ""
+ (setq tpara
+ (completing-read
+ "Parameter name (RET to stop): "
+ (symbol-value (intern
+ (concat "LaTeX-" pname
+ "-parameters-name-list")))
+ nil nil nil (intern
+ (concat "LaTeX-" pname
+ "-parameters-name-history"))))))
+ (setq parval (funcall fask tpara))
+ ;; concat param=value with other ones
+ (setq allpars
+ (concat allpars
+ (if (or (string= "" allpars) (string= "" parval))
+ ""
+ ",")
+ parval))))
+ (add-to-list
+ (intern (concat "LaTeX-" pname "-parameters-history")) allpars)
+ allpars))
+
+(defun LaTeX-package-parameters (optional pname preparam param)
+ "Ask for parameters and manage several parameter lists for
+package PNAME"
+ (let ((fask (intern
+ (concat "LaTeX-" pname "-parameters-pref-and-chosen")))
+ (hlist (intern (concat "LaTeX-" pname "-parameters-history")))
+ (nlist
+ (symbol-value
+ (intern (concat "LaTeX-" pname "-parameters-name-list")))))
+ ;;
+ (when (and preparam (listp preparam))
+ (setq preparam (funcall fask preparam)))
+ ;;
+ (setq param
+ (completing-read-multiple
+ (concat
+ "Params (use <Up,Down> for history or RET for choices): ")
+ nlist nil nil nil hlist))
+ ;;
+ (if (and (string= "" (car param)) (= (length param) 1))
+ (setq param (funcall fask nil t))
+ (setq param (car (symbol-value hlist))))
+ (TeX-argument-insert
+ (if (or (string= "" preparam) (eq preparam nil))
+ param
+ (concat preparam (if (string= "" param) "" (concat "," param))))
+ optional)))
+
+;;; Points
+(defvar LaTeX-pst-point-list (list "0,0")
+ "A list of values for point in pstricks.")
+
+(defvar LaTeX-pst-point-history LaTeX-pst-point-list
+ "History of values for point in pstricks.")
+
+(defun LaTeX-pst-point ()
+ "Ask for a point and manage point list."
+ (LaTeX-pst-what "point"
+ (concat "Point (default " (car LaTeX-pst-point-history) ")")
+ (car LaTeX-pst-point-history)))
+
+(defun LaTeX-pst-point-in-parens (optional)
+ "Enclose point in parentheses."
+ (LaTeX-pst-enclose-obj 'LaTeX-pst-point ?( ?)))
+
+;;; Angles
+(defvar LaTeX-pst-angle-list (list "0")
+ "A list of values for angle in pstricks.")
+
+(defvar LaTeX-pst-angle-history nil
+ "History of values for angle in pstricks.")
+
+(defun LaTeX-pst-angle ()
+ "Ask for a angle and manage angle list"
+ (LaTeX-pst-what "angle"
+ (concat "Angle (default " (car LaTeX-pst-angle-list) ")")
+ (car LaTeX-pst-angle-list)))
+
+;;; Extension in one Direction
+(defvar LaTeX-pst-extdir-list (list "1")
+ "A list of values for extdir in pstricks.")
+
+(defvar LaTeX-pst-extdir-history nil
+ "History of values for extdir in pstricks.")
+
+(defun LaTeX-pst-extdir (descr)
+ "Ask for a extdir and manage extdir list"
+ (LaTeX-pst-what "extdir"
+ (concat descr " (default " (car LaTeX-pst-extdir-list) ")")
+ (car LaTeX-pst-extdir-list)))
+
+;;; Relative Points
+(defvar LaTeX-pst-delpoint-list nil
+ "A list of values for delpoint in pstricks.")
+
+(defvar LaTeX-pst-delpoint-history nil
+ "History of values for delpoint in pstricks.")
+
+;;; Arrows
+(defvar LaTeX-pst-arrows-list
+ '("->" "<-" "<->" ">-<" ">-" "-<" "<<->>" "<<-" "->>" "|-|" "|-" "-|"
+ "|*-|*" "[-]" "[-" "-]" "(-)" "(-" "-)" "*-*" "*-" "-*" "0-0" "0-"
+ "-0" "c-c" "c-" "-c" "C-C" "C-" "-C" "cc-cc" "cc-" "-cc" "|<->|" "|<-"
+ "->|" "|<*->|*" "|<*-" "->|*" "-")
+ "A list of values for arrows in pstricks.")
+
+(defvar LaTeX-pst-arrows-history nil
+ "History of values for arrows in pstricks.")
+
+;; XXX: Better ask for arrow start and end separately?
+;; `LaTeX-pst-arrows-list' is not exhaustive.
+(defun LaTeX-pst-arrows ()
+ "Ask for a arrow type and manage arrow type list"
+ (or (LaTeX-pst-what "arrows" "Arrow type" nil) ""))
+
+;;; Dots
+(defvar LaTeX-pst-dotstyle-list
+ '((completing-read "Dot style" nil LaTeX-pst-dotstyle-history)
+ "*" "o" "+" "|" "triangle" "triangle*" "square" "square*" "pentagon"
+ "pentagon*")
+ "A list of values for dotstyle in pstricks.")
+
+(defvar LaTeX-pst-dotstyle-history nil
+ "History of values for dotstyle in pstricks.")
+
+;;; Reference Point
+(defvar LaTeX-pst-refpoint-list
+ '((completing-read "Reference point" t LaTeX-pst-refpoint-history)
+ "l" "r" "t" "tl" "lt" "tr" "rt" "b" "bl" "br" "lb" "rb" "B" "Bl"
+ "Br" "lB" "rB")
+ "A list of values for refpoint in pstricks.")
+
+(defvar LaTeX-pst-refpoint-history nil
+ "History of values for refpoint in pstricks.")
+
+(defun LaTeX-pst-refpoint ()
+ "Ask for a refpoint and manage refpoint list"
+ (LaTeX-pst-what "refpoint" "Reference point" nil))
+
+;;; Color
+
+;; FIXME: Still used?
+(defvar LaTeX-pst-color-history nil
+ "History of values for color in pstricks.")
+
+;;; Others without History in Completion
+
+(defvar LaTeX-pst-style-list
+ '((completing-read "Defined Style" t))
+ "A list of values for user defined styles in pstricks.")
+
+;;; Parameters
+
+(defvar LaTeX-pst-parameters-history nil
+ "History of values for parameters in pstricks.")
+
+(defvar LaTeX-pst-parameters-value-history nil
+ "History of parameter values in pstricks.")
+
+(defvar LaTeX-pst-basic-parameters-name-list
+ '("arcsep" "arcsepA" "arcsepB" "arrowinset" "arrowlength" "arrows"
+ "arrowscale" "arrowsize" "border" "bordercolor" "boxsep"
+ "bracketlength" "cornersize" "curvature" "dash" "dimen" "dotangle"
+ "dotscale" "dotsep" "dotsize" "dotstyle" "doublecolor" "doubleline"
+ "doublesep" "doubleset" "fillcolor" "fillstyle" "framearc"
+ "framesep" "gangle" "gridcolor" "griddots" "gridlabelcolor"
+ "gridlabels" "gridwidth" "hatchangle" "hatchcolor" "hatchsep"
+ "hatchsepinc" "hatchwidth" "hatchwidthinc" "header" "labelsep"
+ "liftpen" "linearc" "linecolor" "linestyle" "linetype" "linewidth"
+ "rbracketlength" "ref" "runit" "shadow" "shadowangle" "shadowcolor"
+ "shadowsize" "showgrid" "showpoints" "style" "subgridcolor"
+ "subgriddiv" "subgriddots" "subgridwidth" "swapaxes" "tbarsize"
+ "trimode" "unit" "xunit" "yunit")
+ "A list of parameter names in pstricks.")
+
+
+(defvar LaTeX-pst-boolean-list '("true" "false")
+ "List of binary values for key=value completion.")
+
+;; XXX: Colors can actually be given as [-]<color>[!<num>].
+(defvar LaTeX-pst-color-list
+ '("black" "darkgray" "gray" "lightgray" "white"
+ "red" "green" "blue" "cyan" "magenta" "yellow")
+ "List of colors predefined in PSTricks.")
+
+(defvar LaTeX-pst-fillstyle-list
+ '("none" "solid" "vlines" "vlines*" "hlines" "hlines*" "crosshatch"
+ "crosshatch*" "boxfill")
+ "List of fill styles defined in PSTricks.")
+
+;; From PSTricks: PostScript macros for Generic TeX, User's Guide,
+;; Timothy Van Zandt, 25 July 2003, Version 97.
+;; FIXME: Provide separate variables tailored to the different macros.
+(defvar LaTeX-pst-basic-parameters-list
+ '(;; Dimensions, coordinates and angles
+ ("unit")
+ ("xunit")
+ ("yunit")
+ ("runit")
+ ;; Basic graphics parameters
+ ("linewidth")
+ ("linecolor" LaTeX-pst-color-list)
+ ("fillstyle" LaTeX-pst-fillstyle-list)
+ ("fillcolor" LaTeX-pst-color-list)
+ ("arrows" LaTeX-pst-arrows-list)
+ ("showpoints" LaTeX-pst-boolean-list)
+ ;; Lines and polygons
+ ("linearc")
+ ("framearc")
+ ("cornersize" ("relative" "absolute"))
+ ("gangle")
+ ;; Arcs, circles and ellipses
+ ("arcsepA")
+ ("arcsepB")
+ ("arcsep")
+ ;; Curves
+ ("curvature")
+ ;; Dots
+ ("dotstyle" ("*" "o" "Bo" "x" "+" "B+" "asterisk" "Basterisk" "oplus"
+ "otimes" "|" "B|" "square" "Bsquare" "square*" "diamond"
+ "Bdiamond" "diamond*" "triangle" "Btriangle" "triangle*"
+ "pentagon" "Bpentagon" "pentagon*"))
+ ("dotsize")
+ ("dotscale")
+ ("dotangle")
+ ;; Grids
+ ("gridwidth")
+ ("gridcolor" LaTeX-pst-color-list)
+ ("griddots")
+ ("gridlabels")
+ ("gridlabelcolor" LaTeX-pst-color-list)
+ ("subgriddiv")
+ ("subgridwidth")
+ ("subgridcolor" LaTeX-pst-color-list)
+ ("subgriddots")
+ ;; Plots
+ ("plotstyle" ("dots" "line" "polygon" "curve" "ecurve" "ccurve"))
+ ("plotpoints")
+ ;; Coordinate systems
+ ("origin")
+ ("swapaxes" LaTeX-pst-boolean-list)
+ ;; Line styles
+ ("linestyle" ("none" "solid" "dashed" "dotted"))
+ ("dash")
+ ("dotsep")
+ ("border")
+ ("bordercolor" LaTeX-pst-color-list)
+ ("doubleline" LaTeX-pst-boolean-list)
+ ("doublesep")
+ ("doublecolor" LaTeX-pst-color-list)
+ ("shadow" LaTeX-pst-boolean-list)
+ ("shadowsize")
+ ("shadowangle")
+ ("shadowcolor" LaTeX-pst-color-list)
+ ("dimen" ("outer" "inner" "middle"))
+ ;; Fill styles
+ ("hatchwidth")
+ ("hatchsep")
+ ("hatchcolor" LaTeX-pst-color-list)
+ ("hatchangle")
+ ("addfillstyle" LaTeX-pst-fillstyle-list)
+ ;; Arrowheads and such
+ ("arrowsize")
+ ("arrowlength")
+ ("arrowwinset")
+ ("tbarsize")
+ ("bracketlength")
+ ("rbracketlength")
+ ("arrowscale")
+ ;; Parameters
+ ("linetype")
+ ;; Graphics objects
+ ("liftpen")
+ ;; Placing and rotating whatever
+ ("labelsep")
+ ;; Axes
+ ("labels" ("all" "x" "y" "none"))
+ ("showorigin" LaTeX-pst-boolean-list)
+ ("ticks" ("all" "x" "y" "none"))
+ ("tickstyle" ("full" "top" "bottom"))
+ ("ticksize")
+ ("axesstyle" ("axes" "frame" "none"))
+ ;; Framed boxes
+ ("framesep")
+ ("boxsep")
+ ("trimode" ("*" "U" "D" "R" "L"))
+ ;; Nodes
+ ("href")
+ ("vref")
+ ("radius")
+ ;; Node connections
+ ("nodesep")
+ ("arcangle")
+ ("angle")
+ ("arm")
+ ("loopsize")
+ ("ncurv")
+ ("boxsize")
+ ("offset")
+ ;; Node connections labels: I
+ ("ref")
+ ("nrot")
+ ("npos")
+ ("shortput" ("none" "nab" "tablr" "tab"))
+ ;; Node connection labels: II
+ ("tpos")
+ ;; Attaching labels to nodes
+ ("rot")
+ ;; Mathematical diagrams and graphs
+ ("mnode" ("R" "r" "C" "f" "p" "circle" "oval" "dia" "tri" "dot" "none"))
+ ("emnode" ("R" "r" "C" "f" "p" "circle" "oval" "dia" "tri" "dot" "none"))
+ ("name")
+ ("nodealign" LaTeX-pst-boolean-list)
+ ("mcol" ("l" "r" "c"))
+ ("rowsep")
+ ("colsep")
+ ("mnodesize")
+ ;; ...
+ )
+ "List of keys and values for PSTricks macro arguments.")
+
+(defvar LaTeX-pst-parameters-name-list
+ LaTeX-pst-basic-parameters-name-list
+ "A list of all parameters with completion.")
+
+(defvar LaTeX-pst-parameters-name-history nil
+ "History of parameter names in pstricks.")
+
+(defvar LaTeX-pst-parameters-completion-regexp
+ "\\(arrows\\|linestyle\\|fillstyle\\|color\\|trimode\\|dotstyle\\|\\<style\\)"
+ "Regexp for `string-match'ing a parameter.")
+
+(defvar LaTeX-pst-parameters-boolean-regexp
+ "\\(doubleline\\|shadow\\>\\|show[a-zA-Z]+\\)"
+ "Regexp for `string-match'ing a parameter.")
+
+(defun LaTeX-pst-parameter-value (param)
+ "See documentation of `LaTeX-package-parameter-value'."
+ (LaTeX-package-parameter-value param "pst"))
+
+(defun LaTeX-pst-parameters-pref-and-chosen (param &optional noskip)
+ "See documentation of `LaTeX-package-parameters-pref-and-chosen'."
+ (LaTeX-package-parameters-pref-and-chosen param "pst" noskip))
+
+;; FIXME: This is likely only a transitional function used until all
+;; macros got their calls to `TeX-arg-key-val' with tailored parameter
+;; lists.
+(defun LaTeX-pst-parameters (optional)
+ "Prompt for general parameters of a PSTricks argument."
+ (TeX-arg-key-val optional LaTeX-pst-basic-parameters-list))
+
+;;; Macros
+(defun LaTeX-pst-macro-psarc (optional &optional arg)
+ "Return \\psarc arguments after querying."
+ (let ((arrows (LaTeX-pst-arrows))
+ (pnt (if current-prefix-arg nil (LaTeX-pst-point))))
+ (insert (if arrows (format "{%s}" arrows) "")
+ (if pnt (format "(%s)" pnt) "")
+ "{" (LaTeX-pst-extdir "Radius") "}{" (LaTeX-pst-angle) "}{"
+ (LaTeX-pst-angle) "}")))
+
+(defun LaTeX-pst-macro-pscircle (optional &optional arg)
+ "Return \\pscircle arguments after querying."
+ (insert "(" (LaTeX-pst-point) "){" (LaTeX-pst-extdir "Radius") "}"))
+
+(defun LaTeX-pst-macro-rput (optional &optional arg)
+ "Return \\rput arguments after querying."
+ (let ((refpoint (LaTeX-pst-refpoint))
+ (rotation (if current-prefix-arg (LaTeX-pst-angle) nil)))
+ (insert (if refpoint (concat "[" refpoint "]") "")
+ (if rotation
+ (concat "{" rotation "}")
+ "") "(" (LaTeX-pst-point) ")")))
+
+(defun LaTeX-pst-macro-uput (optional &optional arg)
+ "Return \\uput arguments after querying."
+ (let ((dist (LaTeX-pst-extdir "Distance"))
+ (refpoint (LaTeX-pst-refpoint)))
+ (insert (if dist (concat "{" dist "}") "")
+ (if refpoint
+ (concat "[" (LaTeX-pst-refpoint) "]")
+ "[]")
+ "{" (LaTeX-pst-angle) "}(" (LaTeX-pst-point) ")")))
+
+(defun LaTeX-pst-macro-multirputps (optional &optional arg)
+ "Return \\multirput or \\multips arguments after querying."
+ (let ((refpoint (LaTeX-pst-refpoint))
+ (rotation (if current-prefix-arg (LaTeX-pst-angle) nil))
+ (pnt (LaTeX-pst-point))
+ (dpnt (LaTeX-pst-what "delpoint" "Increment (default 1,1)" "1,1"))
+ (repi (LaTeX-pst-input-int "Repetitions" nil)))
+ (insert (if refpoint (format "[%s]" refpoint) "")
+ (if rotation (format "{%s}" rotation) "")
+ "(" pnt ")(" dpnt "){" repi "}")))
+
+(defun LaTeX-pst-macro-psline (optional &optional arg)
+ "Return \\psline or \\ps[ce]?curve[*] arguments after querying."
+ (let ((arrows (LaTeX-pst-arrows))
+ (pnt1 (LaTeX-pst-point))
+ (pnt2 (LaTeX-pst-point)))
+ (insert (if arrows (format "{%s}" arrows) "") "(" pnt1 ")" )
+ (while (and (not (string= pnt2 "")) (not (string= pnt1 pnt2)))
+ (insert "(" pnt2 ")")
+ (setq pnt1 pnt2)
+ (setq pnt2 (LaTeX-pst-point)))))
+
+(defun LaTeX-pst-macro-psdots (optional single)
+ "Return \\psdot[s]? arguments after querying."
+ (let* ((pnt1 (LaTeX-pst-point))
+ (pnt2 (if single pnt1 (LaTeX-pst-point))))
+ (insert "(" pnt1 ")")
+ (while (and (not (string= pnt2 "")) (not (string= pnt1 pnt2)))
+ (setq pnt1 pnt2)
+ (insert "(" pnt1 ")")
+ (setq pnt2 (LaTeX-pst-point)))))
+
+(defun LaTeX-pst-macro-parabola (optional &optional arg)
+ "Return \\parabola arguments after querying."
+ (let ((arrows (LaTeX-pst-arrows)))
+ (insert (if arrows (format "{%s}" arrows) "")
+ "(" (LaTeX-pst-point) ")(" (LaTeX-pst-point) ")")))
+
+(defun LaTeX-pst-macro-pnt-twolen (optional prompt1 prompt2)
+ "Return point and 2 paired lengths in separate parens as arguments."
+ ;; insert \psellipse[*]?, \psdiamond or \pstriangle arguments
+ (let ((pnt (if current-prefix-arg nil (LaTeX-pst-point))))
+ (insert (if pnt (format "(%s)" pnt) "")
+ "(" (LaTeX-pst-extdir prompt1) ","
+ (LaTeX-pst-extdir prompt2) ")")))
+
+(defun LaTeX-pst-macro-psbezier (optional &optional arg)
+ "Return \\psbezier arguments after querying."
+ (let ((arrows (LaTeX-pst-arrows))
+ (pnt1 (LaTeX-pst-point))
+ (pnt2 (LaTeX-pst-point))
+ (pnt3 (LaTeX-pst-point)))
+ (insert (if arrows (format "{%s}" arrows) "")
+ "(" pnt1 ")(" pnt2 ")")
+ (while (not (string= pnt2 pnt3))
+ (insert "(" pnt3 ")")
+ (setq pnt2 pnt3)
+ (setq pnt3 (LaTeX-pst-point)))))
+
+(defun LaTeX-pst-macro-pspolygon (optional &optional arg)
+ "Return \\pspolygon arguments after querying."
+ (let ((pnt1 (LaTeX-pst-point))
+ (pnt2 (LaTeX-pst-point))
+ (pnt3 (LaTeX-pst-point)))
+ (insert "(" pnt1 ")(" pnt2 ")")
+ (while (not (string= pnt2 pnt3))
+ (insert "(" pnt3 ")")
+ (setq pnt2 pnt3)
+ (setq pnt3 (LaTeX-pst-point)))))
+
+(defun LaTeX-pst-macro-psframe (optional &optional arg)
+ "Return \\psframe arguments after querying."
+ (let ((pnt1 (if current-prefix-arg nil (LaTeX-pst-point)))
+ (pnt2 (LaTeX-pst-point)))
+ (insert (if pnt1 (format "(%s)" pnt1) "") "(" pnt2 ")")))
+
+(defun LaTeX-pst-macro-psgrid (optional &optional arg)
+ "Return \\psgrid arguments after querying."
+ (let* ((cpref (if current-prefix-arg (car current-prefix-arg) 0))
+ (pnt1 (if (> cpref 4) (LaTeX-pst-point) nil))
+ (pnt2 (if (> cpref 0) (LaTeX-pst-point) nil))
+ (pnt3 (if (> cpref 0) (LaTeX-pst-point) nil)))
+ (insert (if pnt1 (format "(%s)" pnt1) "")
+ (if pnt2 (format "(%s)(%s)" pnt2 pnt3) ""))))
+
+(defun LaTeX-pst-macro-newpsobject (&optional arg)
+ "Return \\newpsobject arguments after querying."
+ (insert "{" (read-string "New PSObject Name: ") "}"
+ ;; FIXME: It would be better to use something more confined
+ ;; than `TeX-symbol-list'.
+ "{" (completing-read "Parent Object: " (TeX-symbol-list))
+ "}"))
+
+;;; Environments
+(defun LaTeX-pst-env-pspicture (env)
+ "Create new pspicure environment."
+ (let ((opt (multi-prompt-key-value
+ (TeX-argument-prompt t "Options" nil)
+ '(("showgrid") ("shift"))))
+ (p0 (LaTeX-pst-what "point" "Lower left (default 0,0)" "0,0"))
+ (p1 (LaTeX-pst-what "point" "Upper right (default 1,1)" "1,1"))
+ corn)
+ (setq corn (concat (unless (string= "" opt) (format "[%s]" opt))
+ (if (string= "0,0" p0) "" (format "(%s)" p0))
+ "(" p1 ")"))
+ (LaTeX-insert-environment env corn)))
+
+;;; Self Parsing -- see (info "(auctex)Hacking the Parser")
+(defvar LaTeX-auto-pstricks-regexp-list
+ '(("\\\\newps\\(object\\){\\([a-zA-Z]+\\)}{\\([a-zA-Z]+\\)}" (1 2 3)
+ LaTeX-auto-pstricks)
+ ("\\\\newps\\(fontdot\\){\\([a-zA-Z]+\\)}" (1 2)
+ LaTeX-auto-pstricks)
+ ("\\\\newps\\(style\\){\\([a-zA-Z]+\\)}" (1 2)
+ LaTeX-auto-pstricks)
+ ("\\\\define\\(color\\){\\([a-zA-Z]+\\)}{\\(rgb\\|cmyk\\)}" (1 2 3)
+ LaTeX-auto-pstricks)
+ ("\\\\new\\(rgb\\|hsb\\|cmyk\\)\\(color\\){\\([a-zA-Z]+\\)}" (2 3 1)
+ LaTeX-auto-pstricks))
+ "List of regular expressions to extract arguments of \\newps* macros.")
+
+(defvar LaTeX-auto-pstricks nil
+ "Temporary for parsing \\newps* definitions.")
+
+(defun LaTeX-pst-cleanup ()
+ "Move symbols from `LaTeX-auto-pstricks' to `TeX-auto-symbol'."
+ (mapcar
+ (lambda (list)
+ (let ((type (car list)))
+ (cond ((string= type "object")
+ (setq TeX-auto-symbol
+ (cons (list (nth 1 list)
+ (caddr (assoc (nth 2 list)
+ (TeX-symbol-list))))
+ TeX-auto-symbol)))
+ ((string= type "fontdot")
+ (add-to-list 'LaTeX-pst-dotstyle-list (nth 1 list) t))
+ ((string= type "style")
+ (add-to-list 'LaTeX-pst-style-list (nth 1 list) t))
+ ((string= type "color")
+ (add-to-list 'LaTeX-pst-color-list (nth 1 list) t)
+ ;; FIXME: Why is an entry with "-" in front added?
+ (add-to-list 'LaTeX-pst-color-list
+ (concat "-" (nth 1 list)) t)))))
+ LaTeX-auto-pstricks))
+
+(defun LaTeX-pst-prepare ()
+ "Clear `LaTeX-auto-pstricks' before use."
+ (setq LaTeX-auto-pstricks nil))
+
+;; FIXME: This does not seem to work unless one does a manual reparse.
+;; Check e.g. with "\definecolor" and "fillcolor=".
+(add-hook 'TeX-auto-prepare-hook 'LaTeX-pst-prepare)
+(add-hook 'TeX-auto-cleanup-hook 'LaTeX-pst-cleanup)
+
+;;; Additional Functionality
+(defun LaTeX-pst-parameters-add (&optional arg)
+ "With ARG as prefix-argument insert new parameter\(s\) behind
+nearest backward LaTeX macro in brackets. Without ARG add
+parameter\(s\) to the already existing ones at the end of the
+comma separated list. Point has to be within the sexp to modify."
+ (interactive "P")
+ (let ((newpara (LaTeX-pst-parameters-pref-and-chosen nil t))
+ (regexp "\\(") beg end check)
+ (if arg
+ (progn
+ (re-search-backward "\\\\\\([a-zA-Z]\\)")
+ (forward-word 1)
+ (insert-pair nil ?[ ?]))
+ (up-list 1)
+ (backward-char 1)
+ (save-excursion
+ (setq end (point))
+ (up-list -1)
+ (while (re-search-forward "\\([a-zA-Z]+\\)=" end 'limit)
+ (setq regexp (concat regexp
+ (match-string-no-properties 1) "\\|")))
+ (setq regexp (concat (substring regexp 0 -1) ")"))
+ (setq check (string-match regexp newpara))))
+ (when newpara
+ (insert (if arg "" ",") newpara)
+ (when check
+ (message
+ "At least one Parameters appears twice. PLEASE CHECK!")))))
+;; FIXME: Only define a key for this once it is a general-purpose
+;; facility, i.e. not just for pstricks but all types of macros.
+;; (define-key LaTeX-mode-map "\C-c\C-x\C-a" 'LaTeX-pst-parameters-add)
+
+(defvar LaTeX-pst-value-regexp
+ "\\([-!.a-zA-Z0-9]*\\s\\?[-!.a-zA-Z0-9]+\\)"
+ "Expression matching a parameter value.")
+
+(defun LaTeX-pst-parameter-remove-value ()
+ "Remove value of current parameter and return parameter name."
+ (re-search-backward
+ (concat "\\(\\s(\\|,\\)[a-zA-Z]+\\([a-zA-Z]\\|=\\|="
+ LaTeX-pst-value-regexp "\\)"))
+ (re-search-forward "\\([a-zA-Z]+\\)=")
+ (let ((para (match-string-no-properties 1)))
+ (re-search-forward LaTeX-pst-value-regexp)
+ (delete-region (match-beginning 1) (match-end 1))
+ para))
+
+(defun LaTeX-pst-parameter-change-value ()
+ "Replace parameter value with a new one."
+ (interactive)
+ (let* ((para (LaTeX-pst-parameter-remove-value))
+ (symb
+ (when (and
+ (string-match
+ LaTeX-pst-parameters-completion-regexp para)
+ (boundp
+ (intern
+ (concat "LaTeX-pst-" (match-string 0 para) "-list"))))
+ (intern (concat "LaTeX-pst-" (match-string 0 para)
+ "-list")))))
+ (insert (TeX-arg-compl-list (symbol-value symb) "New Value"
+ 'LaTeX-pst-parameters-value-history))))
+;; FIXME: Only define a key for this once it is a general-purpose
+;; facility, i.e. not just for pstricks but all types of macros. (See
+;; also `LaTeX-pst-parameters-add'. Note that a parameter change
+;; should better be made available through a `C-u' prefix of the
+;; binding for the function doing the parameter addition.)
+;; (define-key LaTeX-mode-map "\C-c\C-x\C-v" 'LaTeX-pst-parameter-change-value)
+
+(TeX-add-style-hook
+ "pstricks"
+ (lambda ()
+ (unless (member "pst-pdf" TeX-active-styles)
+ (TeX-PDF-mode-off))
+ (mapc 'TeX-auto-add-regexp LaTeX-auto-pstricks-regexp-list)
+ (LaTeX-add-environments
+ '("pspicture" LaTeX-pst-env-pspicture)
+ "overlaybox" "psclip")
+ (TeX-add-symbols
+ '("AltClipMode" 0) '("DontKillGlue" 0) '("KillGlue" 0)
+ '("NormalCoor" 0) '("SpecialCoor" 0) '("PSTricksLoaded" 0)
+ '("PSTricksOff" 0) '("altcolormode" 0) '("pslinecolor" 0)
+ '("pslinestyle" 0) '("pslinetype" 0) '("pslinewidth" 0)
+ '("pslabelsep" 0) '("radian" 0) '("psunit" 0) '("psrunit" 0)
+ '("psxunit" 0) '("psyunit" 0)
+ '("arrows" (TeX-arg-eval LaTeX-pst-arrows))
+ '("clipbox" ["Border"] t)
+ '("closedshadow" [LaTeX-pst-parameters])
+ '("openshadow" [LaTeX-pst-parameters])
+ "closepath" "code" "coor" "curveto" "degrees" "dim" "endpsclip"
+ "file" "fill" "grestore" "gsave" "lineto" "movepath" "moveto"
+ "mrestore" "msave" "newpath" "rcoor" "rcurveto" "rlineto" "rotate"
+ "scale" "stroke" "swapaxes" "translate"
+ '("newcmykcolor" "Name" "Quadruple")
+ '("newrgbcolor" "Name" "Triple") '("newhsbcolor" "Name" "Triple")
+ '("newgray" "Name" "Value")
+ '("newpsobject" LaTeX-pst-macro-newpsobject LaTeX-pst-parameters)
+ '("newpsstyle" "New PSStyle Name" LaTeX-pst-parameters)
+ '("newpsfontdot" "New PSDot Name" ["Factors"]
+ "Fontname" "Character Number (Hex)")
+ '("parabola" [LaTeX-pst-parameters] LaTeX-pst-macro-parabola)
+ '("parabola*" [LaTeX-pst-parameters] LaTeX-pst-macro-parabola)
+ '("psarc" [LaTeX-pst-parameters] LaTeX-pst-macro-psarc)
+ '("psarc*" [LaTeX-pst-parameters] LaTeX-pst-macro-psarc)
+ '("psarcn" [LaTeX-pst-parameters] LaTeX-pst-macro-psarc)
+ '("pswedge" [LaTeX-pst-parameters] LaTeX-pst-macro-psarc)
+ '("psbezier" [LaTeX-pst-parameters] LaTeX-pst-macro-psbezier)
+ '("psbezier*" [LaTeX-pst-parameters] LaTeX-pst-macro-psbezier)
+ '("pscbezier" [LaTeX-pst-parameters] LaTeX-pst-macro-pspolygon)
+ '("pscircle" [LaTeX-pst-parameters] LaTeX-pst-macro-pscircle)
+ '("psccurve" [LaTeX-pst-parameters] LaTeX-pst-macro-psline)
+ '("psccurve*" [LaTeX-pst-parameters] LaTeX-pst-macro-psline)
+ '("pscurve" [LaTeX-pst-parameters] LaTeX-pst-macro-psline)
+ '("pscurve*" [LaTeX-pst-parameters] LaTeX-pst-macro-psline)
+ '("pscustom" [LaTeX-pst-parameters])
+ '("psdiamond" [LaTeX-pst-parameters]
+ (LaTeX-pst-macro-pnt-twolen "Width" "Height"))
+ '("pstriangle" [LaTeX-pst-parameters]
+ (LaTeX-pst-macro-pnt-twolen "Width" "Height"))
+ '("psdot" [LaTeX-pst-parameters] (LaTeX-pst-macro-psdots t))
+ '("psdots" [LaTeX-pst-parameters] (LaTeX-pst-macro-psdots nil))
+ '("psecurve" [LaTeX-pst-parameters] LaTeX-pst-macro-psline)
+ '("psecurve*" [LaTeX-pst-parameters] LaTeX-pst-macro-psline)
+ '("psellipse" [LaTeX-pst-parameters]
+ (LaTeX-pst-macro-pnt-twolen "Radius x" "Radius y"))
+ '("psellipse*" [LaTeX-pst-parameters]
+ (LaTeX-pst-macro-pnt-twolen "Radius x" "Radius y"))
+ '("psframe" [LaTeX-pst-parameters] LaTeX-pst-macro-psframe)
+ '("psframe*" [LaTeX-pst-parameters] LaTeX-pst-macro-psframe)
+ '("psframebox" [LaTeX-pst-parameters] t)
+ '("pscirclebox" [LaTeX-pst-parameters] t)
+ '("psdblframebox" [LaTeX-pst-parameters] t)
+ '("psdiabox" [LaTeX-pst-parameters] t)
+ '("psovalbox" [LaTeX-pst-parameters] t)
+ '("psshadowbox" [LaTeX-pst-parameters] t)
+ '("pstribox" [LaTeX-pst-parameters] t)
+ '("psscalebox" "Scaling Factor(s)" t)
+ '("psscaleboxto" LaTeX-pst-point-in-parens t)
+ '("psgrid" [LaTeX-pst-parameters] LaTeX-pst-macro-psgrid 0)
+ '("psline" [LaTeX-pst-parameters] LaTeX-pst-macro-psline)
+ '("psoverlay" t)
+ '("pspolygon" [LaTeX-pst-parameters] LaTeX-pst-macro-pspolygon)
+ '("pspolygon*" [LaTeX-pst-parameters] LaTeX-pst-macro-pspolygon)
+ '("psset" LaTeX-pst-parameters)
+ '("pssetlength" TeX-arg-macro "Length")
+ '("psaddtolength" TeX-arg-macro "Length")
+ '("degrees" ["Full Circle"])
+ '("qdisk" LaTeX-pst-point-in-parens "Radius")
+ '("qline" LaTeX-pst-point-in-parens LaTeX-pst-point-in-parens)
+ "pslongbox" "psrotatedown" "psrotateleft" "psrotateright"
+ '("rput" LaTeX-pst-macro-rput t)
+ '("rput*" LaTeX-pst-macro-rput t)
+ '("cput" [LaTeX-pst-parameters]
+ (TeX-arg-eval LaTeX-pst-angle) LaTeX-pst-point-in-parens t)
+ '("uput" LaTeX-pst-macro-uput t)
+ '("multirput" (LaTeX-pst-macro-multirputps t) t)
+ '("multips" (LaTeX-pst-macro-multirputps nil) t))))
+
+;;; pstricks.el ends here
--- /dev/null
+;;; report.el - Special code for report style.
+
+;; $Id: report.el,v 1.3 2005/03/17 10:02:06 angeli Exp $
+
+;;; Code:
+
+(TeX-add-style-hook
+ "report"
+ (lambda ()
+ (LaTeX-largest-level-set "chapter")))
+
+;;; report.el ends here
--- /dev/null
+;;; ruby.el --- AUCTeX style for the ruby package.
+
+;; Copyright (C) 2009 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@caeruleus.net>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2009-01-04
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for the ruby package.
+
+;;; Code:
+
+(defvar LaTeX-ruby-package-options
+ '("overlap" "nooverlap" "CJK" "latin")
+ "Package options for the ruby package.")
+
+(TeX-add-style-hook
+ "ruby"
+ (lambda ()
+ (TeX-add-symbols
+ '("rubyoverlap" 0)
+ '("rubynooverlap" 0)
+ '("rubyCJK" 0)
+ '("rubylatin" 0)
+ '("rubysize" 0)
+ '("rubysep" 0)
+ '("ruby" t nil))))
+
+;;; ruby.el ends here
--- /dev/null
+;;; -*- emacs-lisp -*-
+;;; scrartcl.el -- AUCTeX style for scrartcl.cls
+
+;; Copyright (C) 2002, 2005 Free Software Foundation
+;; License: GPL, see the file COPYING in the base directory of AUCTeX
+
+;; Author: Mark Trettin <Mark.Trettin@gmx.de>
+;; Created: 2002-09-26
+;; Version: $Id: scrartcl.el,v 1.4 2005/03/17 10:02:06 angeli Exp $
+;; Keywords: tex
+
+;;; Commentary:
+
+;; This file adds support for `scrartcl.cls'. This file needs
+;; `scrbase.el'.
+
+;; This file is part of AUCTeX.
+
+;;; Code:
+(TeX-add-style-hook "scrartcl"
+ (lambda ()
+ (LaTeX-largest-level-set "section")
+ ;; load basic definitons
+ (TeX-run-style-hooks "scrbase")))
+
+;;; scrartcl.el ends here
--- /dev/null
+;;; scrbase.el --- AUCTeX style for the KOMA-Script bundle.
+
+;; Copyright (C) 2002, 2004, 2005, 2007 Free Software Foundation, Inc.
+
+;; Author: Mark Trettin <Mark.Trettin@gmx.de>
+;; Created: 2002-09-26
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for the KOMA-Script bundle. This file
+;; contains the base definitions that work with all KOMA-Script
+;; classes (scrarctl.cls, scrreprt.cls, scrbook.cls and scrlttr2.cls).
+;; You need this file since it's loaded from the class-styles.
+
+;;; Code:
+(TeX-add-style-hook "scrbase"
+ (lambda ()
+ (TeX-add-symbols
+ "appendixmore"
+ "autodot"
+ '("addtokomafont" TeX-arg-KOMA-fontelements t)
+ '("areaset" [ "BCOR" ] "Width" "Height")
+ '("captionabove" [ "Lof entry" ] "Caption")
+ '("captionbelow" [ "Lof entry" ] "Caption")
+ '("cleardoubleemptypage")
+ '("cleardoubleplainpage")
+ '("cleardoublestandardpage")
+ '("dedication" t)
+ '("deffootnote" [ "Mark width" ] "Indent" "Parindent" "Definition")
+ '("deffootnotemark" "Definition")
+ '("extratitle" t)
+ '("ifpdfoutput" t nil)
+ '("ifthispageodd" t nil)
+ '("lowertitleback" t)
+ '("maketitle" [ "Pagenumber" ])
+ '("marginline" t)
+ '("publishers" "Publishers")
+ '("sectionmark" "Running head")
+ '("setbibpreamble" "Preamble")
+ '("setcaphanging")
+ '("setcapindent" "Indent")
+ '("setcapindent*" "X-Indent")
+ '("setcapmargin" [ "Margin left" ] "Margin")
+ '("setcapmargin*" [ "Margin inside" ] "Margin")
+ '("setcapwidth" [ TeX-arg-KOMA-capjust ] "Width")
+ '("setindexpreamble" "Preamble")
+ '("setkomafont" TeX-arg-KOMA-fontelements t)
+ '("subject" "Subject")
+ '("subsectionmark" "Running head")
+ '("textsubscript" "Text")
+ '("thanks" "Footnote")
+ '("thefootnotemark")
+ '("titlehead" t)
+ '("uppertitleback" t)
+ '("usekomafont" TeX-arg-KOMA-fontelements))
+ (LaTeX-add-environments
+ '("labeling" (lambda (env &rest ignore)
+ (LaTeX-insert-environment
+ env
+ (let ((delim (read-string "(Optional) Delimiter: "))
+ (width (read-string "Longest item: ")))
+ (concat
+ (if (not (zerop (length delim)))
+ (format "[%s]" delim))
+ (format "{%s}" width))))
+ (LaTeX-find-matching-begin)
+ (end-of-line 1)
+ (LaTeX-insert-item)))
+ '("addmargin" (lambda (env &rest ignore)
+ (LaTeX-insert-environment
+ env
+ (let ((leftin (read-string "(Optional) Left Indentation: "))
+ (indent (read-string "Indentation: ")))
+ (concat
+ (if (not (zerop (length leftin)))
+ (format "[%s]" leftin))
+ (format "{%s}" indent))))))
+ '("addmargin*" (lambda (env &rest ignore)
+ (LaTeX-insert-environment
+ env
+ (let ((innin (read-string "(Optional) Inner Indentation: "))
+ (indent (read-string "Indentation: ")))
+ (concat
+ (if (not (zerop (length innin)))
+ (format "[%s]" innin))
+ (format "{%s}" indent))))))
+ '("captionbeside" (lambda (env &rest ignore)
+ (LaTeX-insert-environment
+ env
+ (let ((lofent (read-string "(Optional) Lof Entry: "))
+ (title (read-string "Caption: "))
+ (place (read-string "(Optional) Placement (l,r,o,i): "))
+ (width (read-string "(Optional) Width: "))
+ (offset (read-string "(Optional) Offset: ")))
+ (concat
+ (if (not (zerop (length lofent)))
+ (format "[%s]" lofent))
+ (format "{%s}" title)
+ (if (not (zerop (length place)))
+ (format "[%s]" place))
+ (if (not (zerop (length width)))
+ (format "[%s]" width))
+ (and
+ (not (zerop (length place)))
+ (not (zerop (length offset)))
+ (format "[%s]%s" offset
+ (if (y-or-n-p "Starred? ")
+ "*" "")))))))))
+ (LaTeX-section-list-add-locally '(("addpart" 0)
+ ("addsec" 2)
+ ("minisec" 7)))
+ ;; This doesn't work. Maybe it's RefTeX's label insertion?
+ (make-local-variable 'LaTeX-section-label)
+ (setq LaTeX-section-label (append
+ LaTeX-section-label
+ '(("addpart" . nil)
+ ("addsec" . nil)
+ ("minisec" . nil))))
+ ;; Fontification
+ (when (and (featurep 'font-latex)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ ;; Textual keywords
+ (font-latex-add-keywords '(("captionabove" "[{")
+ ("captionbelow" "[{")
+ ("dedication" "{")
+ ("extratitle" "{")
+ ("lowertitleback" "{")
+ ("maketitle" "[")
+ ("marginline" "{")
+ ("publishers" "{")
+ ("subject" "{")
+ ("sectionmark" "{")
+ ("setbibpreamble" "{")
+ ("setindexpreamble" "{")
+ ("subsectionmark" "{")
+ ("textsubscript" "{")
+ ("titlehead" "{")
+ ("uppertitleback" "{"))
+ 'textual)
+ ;; Function keywords
+ (font-latex-add-keywords '(("deffootnote" "[{{{")
+ ("deffootnotemark" "{")
+ ("ifpdfoutput" "{{")
+ ("ifthispageodd" "{{"))
+ 'function)
+ ;; Variable keywords
+ (font-latex-add-keywords '(("addtokomafont" "{{")
+ ("areaset" "[{{")
+ ("setcaphanging" "")
+ ("setcapindent" "{")
+ ("setcapmargin" "*[{")
+ ("setcapwidth" "[{")
+ ("setkomafont" "{{")
+ ("typearea" "[{")
+ ("usekomafont" "{"))
+ 'variable)
+ ;; Warning keywords
+ (font-latex-add-keywords '("cleardoublestandardpage"
+ "cleardoubleplainpage"
+ "cleardoubleemptypage")
+ 'warning)
+ ;; Sectioning keywords
+ (font-latex-add-keywords '(("addpart" "[{")) 'sectioning-1)
+ (font-latex-add-keywords '(("addsec" "[{")) 'sectioning-2)
+ (font-latex-add-keywords '(("minisec" "[{")) 'sectioning-4))))
+
+(defun TeX-arg-KOMA-setpreamble (optional &optional prompt)
+ "Prompt for KOMA-Script's \\set*preamble position with completion."
+ (TeX-argument-insert
+ (completing-read
+ (TeX-argument-prompt optional prompt "Position")
+ '(("") ("l") ("r") ("c") ("o") ("u")
+ ("lo") ("lu") ("ro") ("ru") ("co") ("cu"))
+ nil t)
+ optional))
+
+(defun TeX-arg-KOMA-capjust (optional &optional prompt)
+ "Prompt for KOMA-Script's \\setcapwidth justification with completion."
+ (TeX-argument-insert
+ (completing-read
+ (TeX-argument-prompt optional prompt "Justification")
+ '(("") ("l") ("r") ("c") ("i") ("o"))
+ nil t)
+ optional))
+
+(defun TeX-arg-KOMA-fontelements (optional &optional prompt)
+ "Prompt for KOMA-Script's fontelements with completion."
+ (TeX-argument-insert
+ (completing-read
+ (TeX-argument-prompt optional prompt "Element")
+ '(("")
+ ("caption") ("captionlabel")
+ ("descriptionlabel") ("dictum") ("dictumauthor") ("dictumtext")
+ ("footnote") ("footnotelabel") ("footnotereference")
+ ("pagefoot") ("pagehead") ("pagenumber") ("pagination")
+ ("sectioning") ("part") ("partnumber") ("chapter") ("section")
+ ("subsection") ("subsubsection") ("paragraph") ("subparagraph")
+ ("title") ("disposition") ("minisec"))
+ nil t)
+ optional))
+
+(add-to-list 'LaTeX-item-list '("labeling" . LaTeX-item-argument))
+
+;;; scrbase.el ends here
--- /dev/null
+;;; scrbook.el --- AUCTeX style for scrbook.cls
+
+;; Copyright (C) 2002, 2005 Free Software Foundation
+
+;; Author: Mark Trettin <Mark.Trettin@gmx.de>
+;; Created: 2002-09-26
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `scrbook.cls'. This file needs
+;; `scrbase.el'.
+
+;;; Code:
+
+(TeX-add-style-hook "scrbook"
+ (lambda ()
+ (LaTeX-largest-level-set "chapter")
+ ;; load basic definitons
+ (TeX-run-style-hooks "scrbase")
+ (TeX-add-symbols
+ "chapapp"
+ "raggeddictum"
+ '("chapappifchapterprefix" "Additional text")
+ '("setpartpreamble" [ TeX-arg-KOMA-setpreamble ] [ "Width" ] t)
+ '("setchapterpreamble" [ TeX-arg-KOMA-setpreamble ] [ "Width" ] t)
+ '("dictum" [ "Author" ] t))
+ (LaTeX-section-list-add-locally '("addchap" 1))
+ (make-local-variable 'LaTeX-section-label)
+ (setq LaTeX-section-label (append
+ LaTeX-section-label
+ '(("addchap" . nil))))
+ ;; Definitions for font-latex
+ (when (and (featurep 'font-latex)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ ;; Textual keywords
+ (font-latex-add-keywords '(("addchap" "[{")
+ ("setpartpreamble" "[[{")
+ ("setchapterpreamble" "[[{")
+ ("dictum" "[{"))
+ 'textual)
+ ;; Sectioning keywords
+ (font-latex-add-keywords '(("addchap" "[{")) 'sectioning-1))))
+
+;;; scrbook.el ends here
--- /dev/null
+;;; scrlttr2.el --- AUCTeX style for scrlttr2.cls.
+
+;; Copyright (C) 2002, 2007 Free Software Foundation
+
+;; Author: Mark Trettin <Mark.Trettin@gmx.de>
+;; Created: 2002-10-26
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `scrlttr2.cls'.
+
+;; Since I just recently switched from `g-brief.cls' to the
+;; KOMA-Script letter class *and* I don't really write many
+;; snailmails, there are probably some superflous macros included and
+;; important ones left out. Comments appreciated.
+
+;; I left out any length and positioning macros since those should be
+;; set in a personal `*.lco'-File. IMHO.
+
+;;; Code
+
+(TeX-add-style-hook "scrlttr2"
+ (lambda ()
+ (TeX-add-symbols
+ '("AtBeginLetter" t)
+ '("KOMAoptions" t)
+ '("LetterOptionNeedsPapersize" "Name of lco file" "Paper size")
+ '("LoadLetterOption" "Name of lco file")
+ '("addrchar" "Initial letter")
+ '("addrentry" "Lastname" "Firstname" "Address" "Telephone" "F1"
+ "F2" "F3" "F4" "Key")
+ '("addtokomafont" TeX-arg-KOMA-scrlttr-fontelements t)
+ '("addtolengthplength" [ "Factor" ] "Name of length"
+ "Name of pseudo length")
+ '("addtoreffields" TeX-arg-KOMA-scrlttr-vars)
+ '("adrchar" "Initial letter")
+ '("adrentry" "Lastname" "Firstname" "Address" "Telephone" "F1"
+ "F2" "Comment" "Key")
+ '("bankname" t)
+ '("captionsUKenglish" nil)
+ '("captionsUSenglish" nil)
+ '("captionsamerican" nil)
+ '("captionsaustrian" nil)
+ '("captionsbritish" nil)
+ '("captionscroatian" nil)
+ '("captionsdutch" nil)
+ '("captionsenglish" nil)
+ '("captionsfrench" nil)
+ '("captionsgerman" nil)
+ '("captionsitalian" nil)
+ '("captionsngerman" nil)
+ '("captionsspanish" nil)
+ '("cc" t)
+ '("ccname" t)
+ '("cleardoubleemptypage")
+ '("cleardoubleplainpage")
+ '("cleardoublestandardpage")
+ '("closing" "Closing Phrase")
+ '("customername" t)
+ '("dateUKenglish" nil)
+ '("dateUSenglish" nil)
+ '("dateamerican" nil)
+ '("dateaustrian" nil)
+ '("datebritish" nil)
+ '("datecroatian" nil)
+ '("datedutch" nil)
+ '("dateenglish" nil)
+ '("datefrench" nil)
+ '("dategerman" nil)
+ '("dateitalian" nil)
+ '("datename" t)
+ '("datengerman" nil)
+ '("datespanish" nil)
+ '("emailname" t)
+ '("encl" t)
+ '("enclname" t)
+ '("faxname" t)
+ '("firstfoot" t)
+ '("firsthead" t)
+ '("headfromname" t)
+ '("headtoname" t)
+ '("ifkomavarempty" TeX-arg-KOMA-scrlttr-vars 2)
+ '("ifkomavarempty*" TeX-arg-KOMA-scrlttr-vars 2)
+ '("invoicename" t)
+ '("myrefname" t)
+ '("newcaptionname" "Language" "Term" "Definition")
+ '("newkomavar" [ "Description" ] "Name")
+ '("newkomavar*" [ "Description" ] "Name")
+ '("nextfoot" t)
+ '("nexthead" t)
+ '("opening" "Opening")
+ '("pagename" t)
+ '("phonename" t)
+ '("providecaptionname" "Language" "Term" "Definition")
+ '("ps")
+ '("raggedsignature" nil)
+ '("renewcaptionname" "Language" "Term" "Definition")
+ '("setkomafont" TeX-arg-KOMA-scrlttr-fontelements t)
+ '("setkomavar" TeX-arg-KOMA-scrlttr-vars [ "Description" ] t)
+ '("setkomavar*" TeX-arg-KOMA-scrlttr-vars "Description")
+ '("setlengthtoplength" [ "Factor" ] "Name of length"
+ "Name of pseudo length")
+ '("subjectname" t)
+ '("usekomafont" TeX-arg-KOMA-scrlttr-fontelements)
+ '("usekomavar" [ "Command" ] TeX-arg-KOMA-scrlttr-vars)
+ '("usekomavar*" [ "Command" ] TeX-arg-KOMA-scrlttr-vars)
+ '("useplength" "Name")
+ '("wwwname" t)
+ '("yourmailname" t)
+ '("yourrefname" t))
+ (LaTeX-add-environments
+ '("letter" (lambda (env &rest ignore)
+ (LaTeX-insert-environment
+ env
+ (let ((options (read-string "Optional options: "))
+ (recip (read-string "Recipient: ")))
+ (concat
+ (if (not (zerop (length options)))
+ (format "[%s]" options))
+ (format "{%s}" recip)))))))
+ ;; Definitions for font-latex
+ (when (and (featurep 'font-latex)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ ;; Textual keywords
+ (font-latex-add-keywords '(("addrentry" "{{{{{{{{{")
+ ("adrentry" "{{{{{{{{")
+ ("bankname" "{")
+ ("cc" "{")
+ ("ccname" "{")
+ ("closing" "{")
+ ("customername" "{")
+ ("datename" "{")
+ ("emailname" "{")
+ ("encl" "{")
+ ("enclname" "{")
+ ("faxname" "{")
+ ("firstfoot" "{")
+ ("firsthead" "{")
+ ("headfromname" "{")
+ ("headtoname" "{")
+ ("invoicename" "{")
+ ("myrefname" "{")
+ ("nextfoot" "{")
+ ("nexthead" "{")
+ ("opening" "{")
+ ("pagename" "{")
+ ("phonename" "{")
+ ("ps" "")
+ ("subjectname" "{")
+ ("wwwname" "{")
+ ("yourmailname" "{")
+ ("yourrefname" "{"))
+ 'textual)
+ ;; Function keywords
+ (font-latex-add-keywords '(("AtBeginLetter" "{")
+ ("LetterOptionNeedsPapersize" "{{")
+ ("LoadLetterOption" "{")
+ ("addrchar" "{")
+ ("adrchar" "{")
+ ("ifkomavarempty" "*{{{"))
+ 'function)
+ ;; Variable keywords
+ (font-latex-add-keywords '(("KOMAoptions" "{")
+ ("addtokomafont" "{{")
+ ("addtolengthplength" "[{{")
+ ("addtoreffields" "{")
+ ("newcaptionname" "{{{")
+ ("newkomavar" "*[{")
+ ("providecaptionname" "{{{")
+ ("renewcaptionname" "{{{")
+ ("setkomafont" "{{")
+ ("setkomavar" "*{[{")
+ ("setlengthtoplength" "[{{")
+ ("usekomafont" "{")
+ ("usekomavar" "*[{")
+ ("useplength" "{"))
+ 'variable)
+ ;; Warning keywords
+ (font-latex-add-keywords '("cleardoublestandardpage"
+ "cleardoubleplainpage"
+ "cleardoubleemptypage")
+ 'warning))))
+
+(defun TeX-arg-KOMA-scrlttr-vars (optional &optional prompt)
+ "Prompt for KOMA-Script's scrlttr2 predefined variables with completion."
+ (TeX-argument-insert
+ (completing-read
+ (TeX-argument-prompt optional prompt "Variable")
+ '(("")
+ ("backaddress") ("backaddressseparator")
+ ("ccseparator") ("customer")
+ ("date")
+ ("emailseparator") ("enclseparator")
+ ("faxseparator") ("frombank") ("fromaddress") ("fromemail")
+ ("fromfax") ("fromlogo") ("fromname") ("fromphone") ("fromurl")
+ ("invoice")
+ ("location")
+ ("myref")
+ ("place") ("placeseparator") ("phoneseparator")
+ ("signature") ("specialmail") ("subject") ("subjectseparator")
+ ("title") ("toname") ("toaddress")
+ ("yourmail") ("yourref"))
+ nil nil)
+ optional))
+
+(defun TeX-arg-KOMA-scrlttr-fontelements (optional &optional prompt)
+ "Prompt for KOMA-Script's scrlttr2 fontelements with completion."
+ (TeX-argument-insert
+ (completing-read
+ (TeX-argument-prompt optional prompt "Element")
+ '(("")
+ ("backaddress")
+ ("descriptionlabel")
+ ("fromaddress") ("fromname")
+ ("pagefoot") ("pagehead") ("pagenumber")
+ ("subject")
+ ("title"))
+ nil t)
+ optional))
+
+;;; scrlttr2.el ends here
--- /dev/null
+;;; scrpage2.el --- AUCTeX style for scrpage2.sty.
+
+;; Author: Ralf Angeli <angeli@iwi.uni-sb.de>
+;; Created: 2003-11-01
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `scrpage2.sty'.
+
+;;; Code:
+
+(TeX-add-style-hook
+ "scrpage2"
+ (lambda ()
+
+ ;; New symbols
+ (TeX-add-symbols
+ '("lehead" [ "scrplain-left-even" ] "scrheadings-left-even")
+ '("cehead" [ "scrplain-center-even" ] "scrheadings-center-even")
+ '("rehead" [ "scrplain-right-even" ] "scrheadings-right-even")
+ '("lefoot" [ "scrplain-left-even" ] "scrheadings-left-even")
+ '("cefoot" [ "scrplain-center-even" ] "scrheadings-center-even")
+ '("refoot" [ "scrplain-right-even" ] "scrheadings-right-even")
+ '("lohead" [ "scrplain-left-odd" ] "scrheadings-left-odd")
+ '("cohead" [ "scrplain-center-odd" ] "scrheadings-center-odd")
+ '("rohead" [ "scrplain-right-odd" ] "scrheadings-right-odd")
+ '("lofoot" [ "scrplain-left-odd" ] "scrheadings-left-odd")
+ '("cofoot" [ "scrplain-center-odd" ] "scrheadings-center-odd")
+ '("rofoot" [ "scrplain-right-odd" ] "scrheadings-right-odd")
+ '("ihead" [ "scrplain-inside" ] "scrheadings-inside")
+ '("chead" [ "scrplain-center" ] "scrheadings-center")
+ '("ohead" [ "scrplain-outside" ] "scrheadings-outside")
+ '("ifoot" [ "scrplain-inside" ] "scrheadings-inside")
+ '("cfoot" [ "scrplain-center" ] "scrheadings-center")
+ '("ofoot" [ "scrplain-outside" ] "scrheadings-outside")
+ '("clearscrheadfoot")
+ '("clearscrheadings")
+ '("clearscrplain")
+ '("automark" [ "Right page" ] "Left page")
+ '("headmark")
+ '("manualmark")
+ '("pagemark")
+ '("leftmark")
+ '("rightmark")
+ '("setfootwidth" [ "Offset" ] "Width")
+ '("setheadwidth" [ "Offset" ] "Width")
+ '("setfootbotline" [ "Length" ] "Thickness")
+ '("setfootsepline" [ "Length" ] "Thickness")
+ '("setheadtopline" [ "Length" ] "Thickness")
+ '("setheadsepline" [ "Length" ] "Thickness")
+ '("deftripstyle" "Name" [ "Thickness of outer line" ]
+ [ "Thickness of inner line" ] "Inner box of page head"
+ "Center box of page head" "Outer box of page head"
+ "Inner box of page foot" "Center box of page foot"
+ "Outer box of page foot")
+ '("defpagestyle" "Name" "Head definition" "Foot definition")
+ '("newpagestyle" "Name" "Head definition" "Foot definition")
+ '("renewpagestyle" "Name" "Head definition" "Foot definition")
+ '("providepagestyle" "Name" "Head definition" "Foot definition"))
+
+ ;; Fontification
+ (when (and (featurep 'font-latex)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ (font-latex-add-keywords '(("lehead" "[{")
+ ("cehead" "[{")
+ ("rehead" "[{")
+ ("lefoot" "[{")
+ ("cefoot" "[{")
+ ("refoot" "[{")
+ ("lohead" "[{")
+ ("cohead" "[{")
+ ("rohead" "[{")
+ ("lofoot" "[{")
+ ("cofoot" "[{")
+ ("rofoot" "[{")
+ ("ihead" "[{")
+ ("chead" "[{")
+ ("ohead" "[{")
+ ("ifoot" "[{")
+ ("cfoot" "[{")
+ ("ofoot" "[{")
+ ("automark" "[{")
+ ("setfootwidth" "[{")
+ ("setheadwidth" "[{")
+ ("setfootbotline" "[{")
+ ("setfootsepline" "[{")
+ ("setheadtopline" "[{")
+ ("setheadsepline" "[{"))
+ 'variable)
+ (font-latex-add-keywords '(("deftripstyle" "{[[{{{{{{")
+ ("defpagestyle" "{{{")
+ ("newpagestyle" "{{{")
+ ("renewpagestyle" "{{{")
+ ("providepagestyle" "{{{"))
+ 'function))))
+
+(defvar LaTeX-scrpage2-package-options '("headinclude" "headexclude"
+ "footinclude" "footexclude"
+ "mpinclude" "mpexclude"
+ "headtopline" "headsepline"
+ "footsepline" "footbotline"
+ "plainheadtopline" "plainheadsepline"
+ "plainfootsepline" "plainfootbotline"
+ "ilines" "clines" "olines"
+ "automark" "manualmark"
+ "autooneside" "markuppercase"
+ "markusedcase" "nouppercase"
+ "komastyle" "standardstyle")
+ "Package options for the scrpage2 package.")
+
+;;; scrpage2.el ends here
--- /dev/null
+;;; scrreprt.el --- AUCTeX style for scrreprt.cls.
+
+;; Copyright (C) 2002, 2005 Free Software Foundation
+
+;; Author: Mark Trettin <Mark.Trettin@gmx.de>
+;; Created: 2002-09-26
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `scrreprt.cls'. This file needs
+;; `scrbase.el'.
+
+;;; Code:
+
+(TeX-add-style-hook
+ "scrreprt"
+ (lambda ()
+ (LaTeX-largest-level-set "chapter")
+ ;; load basic definitons
+ (TeX-run-style-hooks "scrbase")
+ (TeX-add-symbols
+ "chapapp"
+ "raggeddictum"
+ '("chapappifchapterprefix" "Additional text")
+ '("setpartpreamble" [ TeX-arg-KOMA-setpreamble ] [ "Width" ] t)
+ '("setchapterpreamble" [ TeX-arg-KOMA-setpreamble ] [ "Width" ] t)
+ '("dictum" [ "Author" ] t))
+ (LaTeX-section-list-add-locally '("addchap" 1))
+ (make-local-variable 'LaTeX-section-label)
+ (setq LaTeX-section-label (append
+ LaTeX-section-label
+ '(("addchap" . nil))))
+ ;; Definitions for font-latex
+ (when (and (featurep 'font-latex)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ ;; Textual keywords
+ (font-latex-add-keywords '(("addchap" "[{")
+ ("setpartpreamble" "[[{")
+ ("setchapterpreamble" "[[{")
+ ("dictum" "[{"))
+ 'textual)
+ ;; Sectioning keywords
+ (font-latex-add-keywords '(("addchap" "[{")) 'sectioning-1))))
+
+;;; scrreprt.el ends here
--- /dev/null
+;;; shortvrb.el --- AUCTeX style for `shortvrb.sty'
+
+;; Copyright (C) 2009 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@caeruleus.net>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2009-12-23
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `shortvrb.sty'.
+
+;; XXX: We might want provide users with the possibility to activate
+;; something like this for any file (incl. Plain TeX). That would
+;; bring us one step closer to the goal of displaying texbook.tex
+;; without font locking going haywire.
+
+;; FIXME: The code does not work for preview.dtx because in that file
+;; the style list is empty. In its master file, preview.drv, it
+;; works, however. However, even if the style file is loaded by hand,
+;; it fails to fontify verbatim text in the documentation parts of the
+;; file.
+
+;;; Code:
+
+(TeX-add-style-hook
+ "shortvrb"
+ (lambda ()
+ ;; Fontification
+ (when (and LaTeX-shortvrb-chars
+ (fboundp 'font-latex-set-syntactic-keywords)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ (let (syntax-alist)
+ (dolist (char LaTeX-shortvrb-chars)
+ (add-to-list 'syntax-alist (cons char "|")))
+ (font-latex-add-to-syntax-alist syntax-alist)))))
+
+;;; shortvrb.el ends here
--- /dev/null
+;;; slides.el --- AUCTeX style for the `slides' document class
+
+;; Copyright (C) 2004 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@iwi.uni-sb.de>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2004-04-21
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for the `slides' document class. Currently
+;; the support is very limited. You are welcome to improve it.
+
+;;; Code:
+
+(TeX-add-style-hook
+ "slides"
+ (lambda ()
+ (LaTeX-add-environments "slide"
+ "overlay"
+ "note")))
+
+;;; slides.el ends here
--- /dev/null
+;;; slovak.el --- Setup AUCTeX for editing Slovak text.
+
+(TeX-add-style-hook
+ "slovak"
+ (lambda ()
+ (setq TeX-quote-language `("slovak" "\\uv{" "}" ,TeX-quote-after-quote))
+ (when (fboundp 'font-latex-add-quotes)
+ (font-latex-add-quotes '("\"`" "\"'"))
+ (font-latex-add-quotes '("\"<" "\">" french)))
+ (run-hooks 'TeX-language-sk-hook)))
--- /dev/null
+;;; subfigure.el --- AUCTeX style file for subfigure.sty
+
+;; Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+
+;; Author: Reiner Steib <Reiner.Steib@gmx.de>
+;; Maintainer: auctex-devel@gnu.org
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; AUCTeX style file for subfigure.sty
+
+;;; Code:
+
+(TeX-add-style-hook
+ "subfigure"
+ (lambda ()
+ (TeX-add-symbols
+ '("subfigure" [ "list entry" ] [ "sub caption" ] "figure")
+ '("subtable" [ "list entry" ] [ "sub caption" ] "figure")
+ '("Subref" TeX-arg-label)
+ '("subref" TeX-arg-label))
+ ;; TODO: add \subfig* lengths
+
+ ;; Install completion for labels:
+ (setq TeX-complete-list
+ (append
+ '(("\\\\subref{\\([^{}\n\r\\%,]*\\)" 1 LaTeX-label-list "}")
+ ("\\\\Subref{\\([^{}\n\r\\%,]*\\)" 1 LaTeX-label-list "}"))
+ TeX-complete-list))
+ ;; Fontification
+ (when (and (featurep 'font-latex)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ (font-latex-add-keywords '(("subfigure" "[[{")
+ ("subtable" "[[{"))
+ 'textual)
+ (font-latex-add-keywords '(("Subref" "{")
+ ("subref" "{"))
+ 'reference))))
+
+(defvar LaTeX-subfigure-package-options '("normal" "hang" "center"
+ "centerlast" "nooneline"
+ "raggedright" "isu" "anne"
+ "scriptsize" "footnotesize"
+ "small" "normalsize" "large"
+ "Large" "rm" "sf" "tt" "md"
+ "bf" "up" "it" "sl" "sc" "RM"
+ "SF" "TT" "MD" "BF" "IT" "SL"
+ "SC" "UP" "figbotcap"
+ "figtopcap" "tabbotcap"
+ "tabtopcap" "FIGBOTCAP"
+ "FIGTOPCAP" "TABBOTCAP"
+ "TABTOPCAP" "loose" "tight")
+ "Package options for the subfigure package.")
+
+;;; subfigure.el ends here
--- /dev/null
+;;; swedish.el --- Setup AUCTeX for editing Swedish text.
+
+;;; Commentary:
+;;
+;; Apparently the Swedes use ''this style'' quotations.
+
+(TeX-add-style-hook
+ "swedish"
+ (lambda ()
+ (setq TeX-quote-language
+ `("swedish" "''" ,TeX-close-quote ,TeX-quote-after-quote))
+ (setq LaTeX-babel-hyphen-language "swedish")
+ (run-hooks 'TeX-language-sv-hook)))
--- /dev/null
+;;; tabularx.el --- AUCTeX style for the tabularx package.
+
+;; Copyright (C) 2009 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@caeruleus.net>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2009-02-22
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for the tabularx package.
+
+;;; Code:
+
+(defvar LaTeX-tabularx-package-options
+ '("infoshow" "debugshow")
+ "Package options for the tabularx package.")
+
+(TeX-add-style-hook
+ "tabularx"
+ (lambda ()
+ ;; New symbols
+ (TeX-add-symbols
+ "tracingtabularx"
+ '("tabularxcolumn" 0))
+ ;; New environments
+ (LaTeX-add-environments
+ ;; XXX: The tabularx environment takes the same arguments as the
+ ;; tabular* environment. However, the supported tokens in the
+ ;; format can differ, so at some point in time we might want to
+ ;; separate tabular* and tabularx.
+ '("tabularx" LaTeX-env-tabular*))))
+
+;;; tabularx.el ends here
--- /dev/null
+;;; units.el --- AUCTeX style for the LaTeX package `units.sty' (v0.9b)
+
+;; Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+;; Author: Christian Schlauer <cschl@arcor.de>
+;; Maintainer: auctex-devel@gnu.org
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `units.sty'.
+
+;;; Code:
+
+(TeX-add-style-hook
+ "units"
+ (lambda ()
+ (TeX-add-symbols
+ '("unit" [ "Value" ] "Unit")
+ '("unitfrac" [ "Value" ] "Unit in numerator" "Unit in denominator"))
+ ;; units.sty requires the package nicefrac.sty, thus we enable the
+ ;; macros of nicefrac.sty, too
+ (TeX-run-style-hooks "nicefrac")
+ ;; Fontification
+ (when (and (featurep 'font-latex)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ (font-latex-add-keywords '(("unit" "[{") ("unitfrac" "[{{")) 'textual))))
+
+(defvar LaTeX-units-package-options '("tight" "loose")
+ "Package options for the units package.")
+
+;;; units.el ends here
--- /dev/null
+;;; url.el --- AUCTeX style for `url.sty'
+
+;; Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@iwi.uni-sb.de>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2004-10-13
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file adds support for `url.sty'.
+
+;;; Code:
+
+(TeX-add-style-hook
+ "url"
+ (lambda ()
+ ;; New symbols
+ (TeX-add-symbols
+ "Url"
+ "UrlBigBreakPenalty"
+ "UrlBigBreaks"
+ "UrlBreakPenalty"
+ "UrlBreaks"
+ "UrlFont"
+ "UrlLeft"
+ "UrlNoBreaks"
+ "UrlOrds"
+ "UrlRight"
+ "UrlSpecials"
+ "path"
+ "url"
+ "urldef"
+ '("urlstyle" TeX-arg-urlstyle))
+
+ (add-to-list 'LaTeX-verbatim-macros-with-delims-local "path")
+ (add-to-list 'LaTeX-verbatim-macros-with-delims-local "url")
+ (add-to-list 'LaTeX-verbatim-macros-with-braces-local "path")
+ (add-to-list 'LaTeX-verbatim-macros-with-braces-local "url")
+
+ ;; Fontification
+ (when (and (featurep 'font-latex)
+ (eq TeX-install-font-lock 'font-latex-setup))
+ (font-latex-add-keywords '(("path" "{") ("url" "{")) 'reference)
+ (font-latex-add-keywords '(("Url" "")
+ ("UrlBigBreakPenalty" "")
+ ("UrlBigBreaks" "")
+ ("UrlBreakPenalty" "")
+ ("UrlBreaks" "")
+ ("UrlFont" "")
+ ("UrlLeft" "")
+ ("UrlNoBreaks" "")
+ ("UrlOrds" "")
+ ("UrlRight" "")
+ ("UrlSpecials" "")
+ ("urldef" "")
+ ("urlstyle" "{"))
+ 'variable)
+ ;; For syntactic fontification, e.g. verbatim constructs.
+ (font-latex-set-syntactic-keywords)
+ ;; Tell font-lock about the update.
+ (setq font-lock-set-defaults nil)
+ (font-lock-set-defaults))))
+
+(defun TeX-arg-urlstyle (optional &optional prompt)
+ "Prompt for style used in \\urlstyle with completion."
+ (TeX-argument-insert
+ (completing-read (TeX-argument-prompt optional prompt "Style")
+ (mapcar 'list '("rm" "same" "sf" "tt"))
+ nil t)
+ optional))
+
+(defvar LaTeX-url-package-options '("hyphens" "obeyspaces" "spaces" "LY1"
+ "T1" "allowmove")
+ "Package options for the url package.")
+
+;;; url.el ends here
--- /dev/null
+;;; varioref.el --- AUCTeX style file with support for varioref.sty
+
+;; Copyright (C) 1999 Free Software Foundation, Inc.
+
+;; Author: Carsten Dominik <dominik@strw.leidenuniv.nl>
+;; Maintainer: auctex-devel@gnu.org
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Code:
+
+(TeX-add-style-hook "varioref"
+ (lambda ()
+
+ (TeX-add-symbols
+
+ ;; The macros with label arguments
+ '("vref" TeX-arg-label)
+ '("vpageref" [ "Same page text" ] [ "different page text" ] TeX-arg-label)
+ '("fullref" TeX-arg-label)
+
+ ;; And the other macros used for customization
+ "reftextbefore" "reftextfacebefore"
+ "reftextafter" "reftextfaceafter"
+ "reftextfaraway" "vreftextvario" "vrefwarning")
+
+ ;; Install completion for labels
+ (setq TeX-complete-list
+ (append
+ '(("\\\\vref{\\([^{}\n\r\\%,]*\\)" 1 LaTeX-label-list "}")
+ ("\\\\vpageref\\(\\[[^]]*\\]\\)*{\\([^{}\n\r\\%,]*\\)"
+ 2 LaTeX-label-list "}"))
+ TeX-complete-list))))
+
+(defvar LaTeX-varioref-package-options '("draft" "final" "afrikaans"
+ "american" "austrian" "naustrian"
+ "brazil" "breton" "catalan" "croatian"
+ "czech" "danish" "dutch" "english"
+ "esperanto" "finnish" "french"
+ "galician" "german" "ngerman" "greek"
+ "italian" "magyar" "norsk" "nynorsk"
+ "polish" "portuges" "romanian"
+ "russian" "slovak" "slovene"
+ "spanish" "swedish" "turkish"
+ "francais" "germanb")
+ "Package options for the varioref package.")
+
+;;; varioref.el ends here
--- /dev/null
+;;; verbatim.el --- Style hook for the verbatim package.
+
+;; Copyright (C) 2001 Free Software Foundation, Inc.
+
+;; Author: Masayuki Ataka <masayuki.ataka@gmail.com>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2001/05/01
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; M-x TeX-auto-generate verbatim.sty makes garbages.
+
+;;; Code
+
+(TeX-add-style-hook "verbatim"
+ (function
+ (lambda ()
+ (LaTeX-add-environments
+ "comment")
+ (TeX-add-symbols
+ '("verbatiminput" TeX-arg-file)))))
+
+(defvar LaTeX-verbatim-package-options nil
+ "Package options for the verbatim package.")
+
+;;; verbatim.el ends here.
--- /dev/null
+;;; virtex.el - Common code for all TeX formats.
+
+;; $Id: virtex.el,v 1.1 1994/01/23 08:14:44 amanda Exp $
+
+;;; Code:
+
+(TeX-add-style-hook "virtex"
+ (function
+ (lambda ()
+ (TeX-add-symbols "/" "above" "abovedisplayshortskip"
+ "abovedisplayskip" "abovewithdelims" "accent"
+ "adjdemerits" "advance" "afterassignment"
+ "aftergroup" "atop" "atopwithdelims" "badness"
+ "baselineskip" "batchmode" "begingroup"
+ "belowdisplayshortskip" "belowdisplayskip"
+ "binoppenalty" "botmark" "box" "boxmaxdepth"
+ "brokenpenalty" "catcode" "char" "chardef"
+ "cleaders" "closein" "closeout" "clubpenalty"
+ "copy" "count" "countdef" "cr" "crcr" "csname"
+ "day" "deadcycles" "def" "defaulthyphenchar"
+ "defaultskewchar" "delcode" "delimiter"
+ "delimiterfactor" "delimitershortfall" "dimen"
+ "dimendef" "discretionary" "displayindent"
+ "displaylimits" "displaystyle"
+ "displaywidowpenalty" "displaywidth" "divide"
+ "doublehyphendemerits" "dp" "dump" "edef" "else"
+ "emergencystretch" "end" "endcsname" "endgroup"
+ "endinput" "endlinechar" "eqno" "errhelp"
+ "errmessage" "errorcontextlines" "errorstopmode"
+ "escapechar" "everycr" "everydisplay"
+ "everyhbox" "everyjob" "everymath" "everypar"
+ "everyvbox" "exhyphenpenalty" "expandafter"
+ "fam" "fi" "finalhyphendemerits" "firstmark"
+ "floatingpenalty" "font" "fontdimen" "fontname"
+ "futurelet" "gdef" "global" "globaldefs"
+ "halign" "hangafter" "hangindent" "hbadness"
+ "hbox" "hfil" "hfill" "hfilneg" "hfuzz"
+ "hoffset" "holdinginserts" "hrule" "hsize"
+ "hskip" "hss" "ht" "hyphenpenation" "hyphenchar"
+ "hyphenpenalty" "if" "ifcase" "ifcat" "ifdim"
+ "ifeof" "iffalse" "ifhbox" "ifinner" "ifhmode"
+ "ifmmode" "ifnum" "ifodd" "iftrue" "ifvbox"
+ "ifvoid" "ifx" "ignorespaces" "immediate"
+ "indent" "input" "inputlineno" "insert"
+ "insertpenalties" "interlinepenalty" "jobname"
+ "kern" "language" "lastbox" "lastkern"
+ "lastpenalty" "lastskip" "lccode" "leaders"
+ "left" "lefthyphenmin" "leftskip" "leqno" "let"
+ "limits" "linepenalty" "lineskip"
+ "lineskiplimit" "long" "looseness" "lower"
+ "lowercase" "mag" "markaccent" "mathbin"
+ "mathchar" "mathchardef" "mathchoise"
+ "mathclose" "mathcode" "mathinner" "mathhop"
+ "mathopen" "mathord" "mathpunct" "mathrel"
+ "mathsurround" "maxdeadcycles" "maxdepth"
+ "meaning" "medmuskip" "message" "mkern" "month"
+ "moveleft" "moveright" "mskip" "multiply"
+ "muskip" "muskipdef" "newlinechar" "noalign"
+ "noboundary" "noexpand" "noindent" "nolimits"
+ "nonscript" "nonstopmode" "nulldelimiterspace"
+ "nullfont" "number" "omit" "openin" "openout"
+ "or" "outer" "output" "outputpenalty"
+ "overfullrule" "parfillskip" "parindent"
+ "parskip" "pausing" "postdisplaypenalty"
+ "predisplaypenalty" "predisplaysize"
+ "pretolerance" "relpenalty" "rightskip"
+ "scriptspace" "showboxbreadth" "showboxdepth"
+ "smallskipamount" "spaceskip" "splitmaxdepth"
+ "splittopskip" "tabskip" "thickmuskip"
+ "thinmuskip" "time" "tolerance" "topskip"
+ "tracingcommands" "tracinglostchars"
+ "tracingmacros" "tracingonline" "tracingoutput"
+ "tracingpages" "tracingparagraphs"
+ "tracingrestores" "tracingstats" "uccode"
+ "uchyph" "underline" "unhbox" "unhcopy" "unkern"
+ "unpenalty" "unskip" "unvbox" "unvcopy"
+ "uppercase" "vadjust" "valign" "vbadness" "vbox"
+ "vcenter" "vfil" "vfill" "vfilneg" "vfuzz"
+ "voffset" "vrule" "vsize" "vskip" "vss" "vtop"
+ "wd" "widowpenalty" "write" "xdef" "xleaders"
+ "xspaceskip" "year"))))
+
+;;; virtex.el ends here
--- /dev/null
+;;; tex-bar.el --- toolbar icons on AUCTeX in GNU emacs and XEmacs
+
+;; Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+;; This program 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.
+
+;; This program 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 this program; if not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+;; MA 02110-1301 USA
+
+;; Author: Miguel V. S. Frasson <frasson@math.leidenuniv.nl>
+;; Keywords: tool-bar, tex, latex
+
+;;; Commentary:
+;;
+
+;; This package also needs `toolbar-x.el', and `latex.el' for the
+;; symbol-toolbar.
+
+;;; Use of this preliminary version:
+
+;; - Add `LaTeX-install-toolbar' to `LaTeX-mode-hook'.
+
+;; Special requirements for the use of experimental symbol-toolbar:
+
+;; - Customize `TeX-bar-LaTeX-buttons', adding the label
+;; `LaTeX-symbols-experimental' at the end.
+
+;; - You should have a folder called "symb-pics" with the pics of the
+;; symbols (xpm format is a good one), and the *parent* of this
+;; folder should be in `load-path'.
+
+;; Did you read carefully this item? I will say again: the folder
+;; "symb-pics" should *not* be in `load-path', but its *parent*.
+
+;; - each image file is named after the command that it represents in
+;; the following rules: the base name is the name of the command
+;; without the escape character "\", like \delta -> "delta.xpm";
+;; however, since in some OS filenames are case insensitive, all
+;; occurences of capital letter should be replaced by the letter
+;; plus a dash: \Rightarrow -> "R-ightarrow.xpm" --- actually, for
+;; the correct name, apply `TeX-bar-img-filename' to "Rightarrow"
+;; (TeX-bar-img-filename "Rightarrow")
+;; --> "R-ightarrow"
+;; The function `TeX-bar-img-filename' also treats special commands
+;; like `\{', `\|', etc.
+
+;; You can get the symbol images on (temporary solution)
+;; http://www.math.leidenuniv.nl/~frasson/symb-pics.tar.gz
+
+;;; Code:
+
+(require 'custom)
+
+(require 'toolbar-x)
+
+;; for error handling
+(require 'tex-buf)
+
+;; For the symbol toolbar
+(require 'latex)
+
+;;; Standard buttons
+
+;; help strings
+(defun TeX-bar-help-from-command-list (item)
+ "Return the help string of ITEM in `TeX-command-list'.
+If there is no help, the empty string is returned."
+ (let ((help (nth 1 (memq :help (assoc item TeX-command-list)))))
+ (if help help "")))
+
+(defgroup TeX-tool-bar nil
+ "Tool bar support in AUCTeX."
+ :group 'AUCTeX)
+
+(defcustom TeX-bar-TeX-buttons
+ '(new-file open-file dired kill-buffer save-buffer cut copy paste undo
+ [separator nil] tex next-error view bibtex)
+ "List of buttons available in `tex-mode'.
+It should be a list in the same format of the BUTTONS parameter
+in function `toolbarx-install-toolbar', often a symbol that
+labels a button or Emacs/XEmacs choice of buttons.
+
+Type `\\[TeX-bar-TeX-buttons]' for a list of available buttons.
+
+Buttons are defined in alists (labels associated to properties
+that define a button). For a list of variables that hold such
+alists, see variable `TeX-bar-TeX-all-button-alists'."
+ :type '(list (set :inline t
+ (const new-file)
+ (const open-file)
+ (const dired)
+ (const kill-buffer)
+ (const save-buffer)
+ (const write-file)
+ (const undo)
+ (const cut)
+ (const copy)
+ (const paste)
+ (const search-forward)
+ (const print-buffer)
+ (const [separator nil])
+ (const tex)
+ (const next-error)
+ (const view)
+ (const file)
+ (const bibtex)
+ (const clean))
+ ;; (const latex-symbols-experimental)
+ (repeat (choice (symbol :tag "Label")
+ (vector :args ((symbol :tag "Label in Emacs ")
+ (symbol :tag "Label in XEmacs"))
+ :tag "Emacs/XEmacs choice")
+ (sexp :tag "General element"))))
+ :group 'TeX-tool-bar)
+
+(defun TeX-bar-TeX-buttons ()
+ "Display in a buffer a list of buttons for `tex-bar.el'."
+ (interactive)
+ (let ((assqs-button-alists)
+ (labels))
+ (dolist (m-alist TeX-bar-TeX-all-button-alists)
+ (setq labels nil)
+ (dolist (as (eval m-alist))
+ (setq labels (cons (car as) labels)))
+ (setq assqs-button-alists (cons (cons m-alist (nreverse labels))
+ assqs-button-alists)))
+ (setq assqs-button-alists (nreverse assqs-button-alists))
+ ;; displaying results
+ (save-excursion
+ (set-buffer (get-buffer-create "*TeX tool bar buttons*"))
+ (erase-buffer)
+ (insert "Available buttons for TeX mode
+================================")
+ (dolist (i assqs-button-alists)
+ (insert (format "\n\n`%s' provides the following buttons:\n " (car i)))
+ (dolist (j (cdr i))
+ (insert (format " %s" j)))
+ (fill-region (point-at-bol) (point-at-eol))))
+ (display-buffer "*TeX tool bar buttons*" t)))
+
+(defgroup TeX-tool-bar-button-definitions nil
+ "Collections of button definitions."
+ :group 'TeX-tool-bar)
+
+(defcustom TeX-bar-TeX-all-button-alists
+ '(TeX-bar-TeX-button-alist
+ toolbarx-default-toolbar-meaning-alist)
+ "List of variables that hold buttons properties.
+Each element should be a symbol bound to list in the format of
+the argument BUTTON-ALIST in function `toolbarx-install-toolbar'."
+ :type '(repeat variable)
+ :group 'TeX-tool-bar-button-definitions)
+
+(defcustom TeX-bar-TeX-button-alist
+ '((tex :image (lambda nil (if TeX-PDF-mode "pdftex" "tex"))
+ :command (progn
+ (TeX-save-document (TeX-master-file))
+ (TeX-command "TeX" 'TeX-master-file -1))
+ :help (lambda (&rest ignored)
+ (TeX-bar-help-from-command-list "TeX")))
+ (pdftex :image "pdftex"
+ :command (progn
+ (TeX-save-document (TeX-master-file))
+ (TeX-command "PDFTeX" 'TeX-master-file -1))
+ :help (lambda (&rest ignored)
+ (TeX-bar-help-from-command-list "PDFTeX")))
+ (next-error :image "error"
+ :command TeX-next-error
+ :enable (plist-get TeX-error-report-switches
+ (intern (TeX-master-file)))
+ :visible (plist-get TeX-error-report-switches
+ (intern (TeX-master-file))))
+ (view :image (lambda nil (if TeX-PDF-mode "viewpdf" "viewdvi"))
+ :command (TeX-command "View" 'TeX-master-file -1)
+ :help (lambda (&rest ignored)
+ (TeX-bar-help-from-command-list "View")))
+ (file :image "dvips"
+ :command (TeX-command "File" 'TeX-master-file -1)
+ :visible (not TeX-PDF-mode)
+ :help (lambda (&rest ignored)
+ (TeX-bar-help-from-command-list "File")))
+ (bibtex :image "bibtex"
+ :command (TeX-command "BibTeX" 'TeX-master-file -1)
+ :help (lambda (&rest ignored)
+ (TeX-bar-help-from-command-list "BibTeX")))
+ (clean :image "delete"
+ :command (TeX-command "Clean" 'TeX-master-file -1)
+ :help (lambda (&rest ignored)
+ (TeX-bar-help-from-command-list "Clean"))))
+ ;; latex-symbols-experimental?
+ "Alist for button definitions in TeX bar.
+Value should le a list where each element is of format (KEY .
+PROPS), where KEY is a symbol that labels the button and PROPS is
+a list of properties of the button. For a description of the
+format of PROPS, please see documentation of function
+`toolbarx-install-toolbar'. This custom variable is in the same
+format of the argument MEANING-ALIST in the mentioned function."
+ :type '(alist :key-type symbol :value-type sexp)
+ :group 'TeX-tool-bar-button-definitions)
+
+;;; Installation of the tool bar
+;;;###autoload
+(defun TeX-install-toolbar ()
+ "Install toolbar buttons for TeX mode."
+ (interactive)
+ (require 'toolbar-x)
+ (add-to-list 'toolbarx-image-path
+ (expand-file-name "images" TeX-data-directory))
+ (add-hook 'TeX-PDF-mode-hook 'toolbarx-refresh nil t)
+ (toolbarx-install-toolbar TeX-bar-TeX-buttons
+ (let ((append-list))
+ (dolist (elt TeX-bar-TeX-all-button-alists)
+ (setq append-list (append append-list
+ (eval elt))))
+ append-list)))
+
+(defcustom TeX-bar-LaTeX-buttons
+ '(new-file open-file dired kill-buffer save-buffer cut copy paste undo
+ [separator nil] latex next-error view bibtex)
+ "List of buttons available in `latex-mode'.
+It should be a list in the same format of the BUTTONS parameter
+in function `toolbarx-install-toolbar', often a symbol that
+labels a button or Emacs/XEmacs choice of buttons.
+
+Type `\\[TeX-bar-LaTeX-buttons]' for a list of available buttons.
+
+Buttons are defined in alists (labels associated to properties
+that define a button). For a list of variables that hold such
+alists, see variable `TeX-bar-LaTeX-all-button-alists'."
+ :type '(list (set :inline t
+ (const new-file)
+ (const open-file)
+ (const dired)
+ (const kill-buffer)
+ (const save-buffer)
+ (const write-file)
+ (const undo)
+ (const cut)
+ (const copy)
+ (const paste)
+ (const search-forward)
+ (const print-buffer)
+ (const [separator nil])
+ (const latex)
+ (const next-error)
+ (const view)
+ (const file)
+ (const bibtex)
+ (const clean)
+ (const latex-symbols-experimental))
+ (repeat (choice (symbol :tag "Label")
+ (vector :args ((symbol :tag "Label in Emacs ")
+ (symbol :tag "Label in XEmacs"))
+ :tag "Emacs/XEmacs choice")
+ (sexp :tag "General element"))))
+ :group 'TeX-tool-bar)
+
+(defun TeX-bar-LaTeX-buttons ()
+ "Display in a buffer a list of buttons for `tex-bar.el'."
+ (interactive)
+ (let ((assqs-button-alists)
+ (labels))
+ (dolist (m-alist TeX-bar-LaTeX-all-button-alists)
+ (setq labels nil)
+ (dolist (as (eval m-alist))
+ (setq labels (cons (car as) labels)))
+ (setq assqs-button-alists (cons (cons m-alist (nreverse labels))
+ assqs-button-alists)))
+ (setq assqs-button-alists (nreverse assqs-button-alists))
+ ;; displaying results
+ (save-excursion
+ (set-buffer (get-buffer-create "*TeX tool bar buttons*"))
+ (erase-buffer)
+ (insert "Available buttons for LaTeX mode
+================================")
+ (dolist (i assqs-button-alists)
+ (insert (format "\n\n`%s' provides the following buttons:\n " (car i)))
+ (dolist (j (cdr i))
+ (insert (format " %s" j)))
+ (fill-region (point-at-bol) (point-at-eol))))
+ (display-buffer "*TeX tool bar buttons*" t)))
+
+(defgroup TeX-tool-bar-button-definitions nil
+ "Collections of button definitions."
+ :group 'TeX-tool-bar)
+
+(defcustom TeX-bar-LaTeX-all-button-alists
+ '(TeX-bar-LaTeX-button-alist
+ toolbarx-default-toolbar-meaning-alist)
+ "List of variables that hold buttons properties.
+Each element should be a symbol bound to list in the format of
+the argument BUTTON-ALIST in function `toolbarx-install-toolbar'."
+ :type '(repeat variable)
+ :group 'TeX-tool-bar-button-definitions)
+
+(defcustom TeX-bar-LaTeX-button-alist
+ '((latex :image (lambda nil (if TeX-PDF-mode "pdftex" "tex"))
+ :command (progn
+ (TeX-save-document (TeX-master-file))
+ (TeX-command "LaTeX" 'TeX-master-file -1))
+ :help (lambda (&rest ignored)
+ (TeX-bar-help-from-command-list "LaTeX")))
+ (pdflatex :image "pdftex"
+ :command (progn
+ (TeX-save-document (TeX-master-file))
+ (TeX-command "PDFLaTeX" 'TeX-master-file -1))
+ :help (lambda (&rest ignored)
+ (TeX-bar-help-from-command-list "PDFLaTeX")))
+ (next-error :image "error"
+ :command TeX-next-error
+ :enable (plist-get TeX-error-report-switches
+ (intern (TeX-master-file)))
+ :visible (plist-get TeX-error-report-switches
+ (intern (TeX-master-file))))
+ (view :image (lambda nil (if TeX-PDF-mode "viewpdf" "viewdvi"))
+ :command (TeX-command "View" 'TeX-master-file -1)
+ :help (lambda (&rest ignored)
+ (TeX-bar-help-from-command-list "View")))
+ (file :image "dvips"
+ :command (TeX-command "File" 'TeX-master-file -1)
+ :visible (not TeX-PDF-mode)
+ :help (lambda (&rest ignored)
+ (TeX-bar-help-from-command-list "File")))
+ (bibtex :image "bibtex"
+ :command (TeX-command "BibTeX" 'TeX-master-file -1)
+ :help (lambda (&rest ignored)
+ (TeX-bar-help-from-command-list "BibTeX")))
+ (clean :image "delete"
+ :command (TeX-command "Clean" 'TeX-master-file -1)
+ :help (lambda (&rest ignored)
+ (TeX-bar-help-from-command-list "Clean")))
+ (latex-symbols-experimental . (:alias :eval-group
+ LaTeX-symbols-toolbar-switch-contents
+ LaTeX-symbols-toolbar-contents)))
+ "Alist for button definitions in TeX bar.
+Value should le a list where each element is of format (KEY .
+PROPS), where KEY is a symbol that labels the button and PROPS is
+a list of properties of the button. For a description of the
+format of PROPS, please see documentation of function
+`toolbarx-install-toolbar'. This custom variable is in the same
+format of the argument MEANING-ALIST in the mentioned function."
+ :type '(alist :key-type symbol :value-type sexp)
+ :group 'TeX-tool-bar-button-definitions)
+
+;;; Installation of the tool bar
+;;;###autoload
+(defun LaTeX-install-toolbar ()
+ "Install toolbar buttons for LaTeX mode."
+ (interactive)
+ (require 'toolbar-x)
+ (add-to-list 'toolbarx-image-path
+ (expand-file-name "images" TeX-data-directory))
+ (add-hook 'TeX-PDF-mode-hook 'toolbarx-refresh nil t)
+ (toolbarx-install-toolbar TeX-bar-LaTeX-buttons
+ (let ((append-list))
+ (dolist (elt TeX-bar-LaTeX-all-button-alists)
+ (setq append-list (append append-list
+ (eval elt))))
+ append-list)))
+
+;;; Experimental Symbol Toolbar
+
+;;; symbol toolbar
+(defun TeX-bar-img-filename (tex-command)
+ "Return the filename (no extension) for the image button of TEX-COMMAND."
+ (let ((str-list (append tex-command nil))
+ (str-result))
+ (dolist (i str-list)
+ (cond
+ ;; capital letter -> letter + "-"
+ ((and (>= i ?A) (<= i ?Z))
+ (setq str-result (cons ?- (cons i str-result))))
+ ;; lowercase letter -> letter
+ ((and (>= i ?a) (<= i ?z))
+ (setq str-result (cons i str-result)))
+ ;; open curly brackets `{' -> "ocb--"
+ ((eq i ?{)
+ (setq str-result (cons ?o str-result))
+ (setq str-result (cons ?c str-result))
+ (setq str-result (cons ?b str-result))
+ (setq str-result (cons ?- str-result))
+ (setq str-result (cons ?- str-result)))
+ ;; close curly brackets `}' -> "ccb--"
+ ((eq i ?})
+ (setq str-result (cons ?c str-result))
+ (setq str-result (cons ?c str-result))
+ (setq str-result (cons ?b str-result))
+ (setq str-result (cons ?- str-result))
+ (setq str-result (cons ?- str-result)))
+ ;; vertical bar `|' -> "v--"
+ ((eq i ?|)
+ (setq str-result (cons ?v str-result))
+ (setq str-result (cons ?- str-result))
+ (setq str-result (cons ?- str-result)))
+ ;; slash `/' -> "s--"
+ ((eq i ?/)
+ (setq str-result (cons ?s str-result))
+ (setq str-result (cons ?- str-result))
+ (setq str-result (cons ?- str-result)))))
+ (concat (nreverse str-result))))
+
+(let* ((menu-strings-buttons-alist
+ ;; make a alist os strings with the symbol classes and store it in
+ ;; `menu-strings-alist'
+ (let* ((menu-strings-alist-temp))
+ (dolist (item-external (cdr LaTeX-math-menu)
+ (nreverse menu-strings-alist-temp))
+ (when (listp item-external)
+ ;; if first element is vector, I am supposing that all are
+ ;; vectors as well
+ (if (vectorp (cadr item-external))
+ (let* ((menu-str (car item-external))
+ (menu-buttons))
+ (dolist (button (cdr item-external))
+ (setq menu-buttons
+ (cons (list (intern (TeX-bar-img-filename
+ (aref button 0)))
+ :image
+ (concat "symb-pics/"
+ (TeX-bar-img-filename
+ (aref button 0)))
+ :help (aref button 0)
+ :command (aref button 1))
+ menu-buttons)))
+ (setq menu-buttons (nreverse menu-buttons))
+ (setq menu-strings-alist-temp
+ (cons (cons menu-str (list menu-buttons))
+ menu-strings-alist-temp)))
+ ;; if another list (therefore, up to second level menu)
+ (let ((parent-str (concat (car item-external) " ")))
+ (dolist (item-internal (cdr item-external))
+ (unless (equal (car item-internal) "Special")
+ (let* ((menu-str (concat parent-str
+ (car item-internal)))
+ (menu-buttons))
+ (dolist (button (cdr item-internal))
+ (setq menu-buttons
+ (cons (list (intern (aref button 0))
+ :image
+ (concat "symb-pics/"
+ (TeX-bar-img-filename
+ (aref button 0)))
+ :help (aref button 0)
+ :command (aref button 1))
+ menu-buttons)))
+ (setq menu-buttons (nreverse menu-buttons))
+ (setq menu-strings-alist-temp
+ (cons (cons menu-str (list menu-buttons))
+ menu-strings-alist-temp)))))))))))
+ (list-strings (let* ((list-str-temp))
+ (dolist (i menu-strings-buttons-alist
+ (nreverse list-str-temp))
+ (setq list-str-temp (cons (car i)
+ list-str-temp))))))
+ (defvar LaTeX-symbols-toolbar-visible-flag nil
+ "Non-nil means that the LaTeX symbols on toolbar are visible.
+Internal variable.")
+ (defconst LaTeX-symbols-toolbar-switch-contents
+ `(;; the on-off switch button
+ (latex-symbols-switch
+ :image (lambda nil (if LaTeX-symbols-toolbar-visible-flag
+ "ltx-symb-turn-off"
+ "ltx-symb-turn-on"))
+ :command (progn
+ (setq LaTeX-symbols-toolbar-visible-flag
+ (not LaTeX-symbols-toolbar-visible-flag))
+ (toolbarx-refresh))
+ ;; help message depends on if symb-toolbar is on or off, and in
+ ;; the name of the current class of symbols
+ :help (lambda (&rest ignore)
+ (concat "Turn "
+ (if LaTeX-symbols-toolbar-visible-flag "off " "on ")
+ "the toolbar of LaTeX symbols (current class: "
+ (nth (1- LaTeX-symbols-active-menuitem)
+ (quote ,list-strings))
+ ")")))
+ ;; the dropdown button, that also switch on the symbols
+ ,(append '(:dropdown-group)
+ list-strings
+ '(:variable
+ LaTeX-symbols-active-menuitem
+ :save offer
+ :dropdown-prepend-command
+ (setq LaTeX-symbols-toolbar-visible-flag t)
+ :dropdown-help "Select a class of symbols to be displayed"))))
+ (defconst LaTeX-symbols-toolbar-contents
+ (let* ((ltx-symb)
+ (count 0))
+ (dolist (i menu-strings-buttons-alist
+ (append (nreverse ltx-symb)
+ '(:insert
+ LaTeX-symbols-toolbar-visible-flag
+ :toolbar (bottom . top))))
+ (setq count (1+ count))
+ (setq ltx-symb
+ (cons (append (cdr i)
+ `(:insert (eq LaTeX-symbols-active-menuitem
+ ,count)))
+ ltx-symb))))))
+
+(provide 'tex-bar)
+
+;;; tex-bar.el ends here
--- /dev/null
+;;; tex-buf.el --- External commands for AUCTeX.
+
+;; Copyright (C) 1991, 1993, 1996, 2001, 2003, 2004, 2005, 2006, 2007,
+;; 2008, 2009 Free Software Foundation, Inc.
+
+;; Maintainer: auctex-devel@gnu.org
+;; Keywords: tex, wp
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file provides support for external commands.
+
+;;; Code:
+
+(require 'tex)
+
+;;; Customization:
+
+(defcustom TeX-process-asynchronous (not (eq system-type 'ms-dos))
+ "*Use asynchronous processes."
+ :group 'TeX-command
+ :type 'boolean)
+
+(defcustom TeX-shell
+ (if (memq system-type '(ms-dos emx windows-nt))
+ shell-file-name
+ "/bin/sh")
+ "Name of shell used to parse TeX commands."
+ :group 'TeX-command
+ :type 'file)
+
+(defcustom TeX-shell-command-option
+ (cond ((memq system-type '(ms-dos emx windows-nt) )
+ (cond ((boundp 'shell-command-option)
+ shell-command-option)
+ ((boundp 'shell-command-switch)
+ shell-command-switch)
+ (t
+ "/c")))
+ (t ;Unix & EMX (Emacs 19 port to OS/2)
+ "-c"))
+ "Shell argument indicating that next argument is the command."
+ :group 'TeX-command
+ :type 'string)
+
+;;; Interactive Commands
+;;
+;; The general idea is, that there is one process and process buffer
+;; associated with each master file, and one process and process buffer
+;; for running TeX on a region. Thus, if you have N master files, you
+;; can run N + 1 processes simultaneously.
+;;
+;; Some user commands operates on ``the'' process. The following
+;; algorithm determine what ``the'' process is.
+;;
+;; IF last process started was on a region
+;; THEN ``the'' process is the region process
+;; ELSE ``the'' process is the master file (of the current buffer) process
+
+(defun TeX-save-document (name)
+ "Save all files belonging to the current document.
+Return non-nil if document need to be re-TeX'ed."
+ (interactive (list (TeX-master-file)))
+ (if (string-equal name "")
+ (setq name (TeX-master-file)))
+
+ (TeX-check-files (concat name "." (TeX-output-extension))
+ (cons name (TeX-style-list))
+ TeX-file-extensions))
+
+(defun TeX-command-master (&optional override-confirm)
+ "Run command on the current document.
+
+If a prefix argument OVERRIDE-CONFIRM is given, confirmation will
+depend on it being positive instead of the entry in `TeX-command-list'."
+ (interactive "P")
+ (TeX-command (TeX-command-query (TeX-master-file)) 'TeX-master-file
+ override-confirm))
+
+(defvar TeX-command-region-begin nil)
+(defvar TeX-command-region-end nil)
+;; Used for marking the last region.
+
+(make-variable-buffer-local 'TeX-command-region-begin)
+(make-variable-buffer-local 'TeX-command-region-end)
+
+(defun TeX-current-offset (&optional pos)
+ "Calculate line offset of POS, or of point if POS is nil."
+ (save-restriction
+ (widen)
+ (save-excursion
+ (let ((inhibit-point-motion-hooks t)
+ (inhibit-field-text-motion t))
+ (if pos (goto-char pos))
+ (+ (count-lines (point-min) (point))
+ (if (bolp) 0 -1))))))
+
+(defun TeX-pin-region (begin end)
+ "Pin the TeX region specified by BEGIN and END.
+If BEGIN is nil, the region is unpinned.
+
+In interactive use, a positive prefix arg will pin the region,
+a non-positive one will unpin it. Without a prefix arg, if
+a region is actively marked, it will get pinned. If not, a
+pinned region will get unpinned and vice versa."
+ (interactive
+ (if
+ (if current-prefix-arg
+ (> (prefix-numeric-value current-prefix-arg) 0)
+ (or (TeX-active-mark)
+ (null TeX-command-region-begin)))
+ (list (region-beginning) (region-end))
+ '(nil nil)))
+ (if begin
+ (progn
+ (unless (markerp TeX-command-region-begin)
+ (setq TeX-command-region-begin (make-marker))
+ (setq TeX-command-region-end (make-marker)))
+ (set-marker TeX-command-region-begin begin)
+ (set-marker TeX-command-region-end end)
+ (message "TeX region pinned."))
+ (when (markerp TeX-command-region-begin)
+ (set-marker TeX-command-region-begin nil)
+ (set-marker TeX-command-region-end nil))
+ (setq TeX-command-region-begin nil)
+ (setq TeX-command-region-end nil)
+ (message "TeX region unpinned.")))
+
+(defun TeX-command-region (&optional override-confirm)
+ "Run TeX on the current region.
+
+Query the user for a command to run on the temporary file specified by
+the variable `TeX-region'. If there is an explicitly active region,
+it is stored for later commands. If not, a previously stored region
+\(can be also be set with `TeX-pin-region') overrides the current region,
+if present.
+
+If a prefix argument OVERRIDE-CONFIRM is given, prompting will
+ignore the prompting flag from `TeX-command-list' and instead
+will prompt iff the prefix is positive.
+
+If the master file for the document has a header, it is written to the
+temporary file before the region itself. The document's header is all
+text before `TeX-header-end'.
+
+If the master file for the document has a trailer, it is written to
+the temporary file before the region itself. The document's trailer is
+all text after `TeX-trailer-start'."
+ (interactive "P")
+ ;; Note that TeX-command-region-begin is not a marker when called
+ ;; from TeX-command-buffer.
+ (and (or (null TeX-command-region-begin)
+ (markerp TeX-command-region-begin))
+ (TeX-active-mark)
+ (TeX-pin-region (region-beginning) (region-end)))
+ (let ((begin (or TeX-command-region-begin (region-beginning)))
+ (end (or TeX-command-region-end (region-end))))
+ (TeX-region-create (TeX-region-file TeX-default-extension)
+ (buffer-substring begin end)
+ (file-name-nondirectory (buffer-file-name))
+ (TeX-current-offset begin)))
+ (TeX-command (TeX-command-query (TeX-region-file nil t)) 'TeX-region-file
+ override-confirm))
+
+(defun TeX-command-buffer (&optional override-confirm)
+ "Run TeX on the current buffer.
+
+Query the user for a command to run on the temporary file specified by
+the variable `TeX-region'. The region file will be recreated from the
+visible part of the buffer.
+
+If a prefix argument OVERRIDE-CONFIRM is given, confirmation will
+depend on it being positive instead of the entry in `TeX-command-list'."
+ (interactive "P")
+ (let ((TeX-command-region-begin (point-min))
+ (TeX-command-region-end (point-max)))
+ (TeX-command-region override-confirm)))
+
+(unless (featurep 'xemacs)
+ ;; This variable is not defined in XEmacs because XEmacs' version of
+ ;; `pop-to-buffer' doesn't support the optional NORECORD argument. In
+ ;; XEmacs, the third arg is ON-FRAME (Emacs: NORECORD).
+ (defcustom TeX-record-buffer nil
+ "Whether to record buffer names of generated TeX buffers.
+When non-nil, these buffers are put at the front of the list of
+recently selected ones."
+ :group 'TeX-command
+ :type 'boolean))
+
+(defun TeX-pop-to-buffer (buffer &optional other-window norecord)
+ "Compatibility wrapper for `pop-to-buffer'.
+
+Select buffer BUFFER in some window, preferably a different one.
+BUFFER may be a buffer, a string (a buffer name), or nil.
+If BUFFER is a string which is not the name of an existing buffer,
+then this function creates a buffer with that name.
+If BUFFER is nil, then it chooses some other buffer.
+If `pop-up-windows' is non-nil, windows can be split to do this.
+If optional second arg OTHER-WINDOW is non-nil, insist on finding another
+window even if BUFFER is already visible in the selected window,
+and ignore `same-window-regexps' and `same-window-buffer-names'.
+This function returns the buffer it switched to.
+This uses the function `display-buffer' as a subroutine; see the documentation
+of `display-buffer' for additional customization information.
+
+Optional third arg NORECORD non-nil means do not put this buffer
+at the front of the list of recently selected ones.
+
+NORECORD is ignored in XEmacs."
+ ;; Make sure not to use third arg in XEmacs. In XEmacs, the third arg is
+ ;; ON-FRAME (Emacs: NORECORD), so we set it to nil.
+ (pop-to-buffer buffer other-window (and norecord
+ (boundp 'TeX-record-buffer)
+ TeX-record-buffer)))
+
+(defun TeX-recenter-output-buffer (line)
+ "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
+at bottom if LINE is nil."
+ (interactive "P")
+ (let ((buffer (TeX-active-buffer)))
+ (if buffer
+ (let ((old-buffer (current-buffer)))
+ (TeX-pop-to-buffer buffer t t)
+ (bury-buffer buffer)
+ (goto-char (point-max))
+ (recenter (if line
+ (prefix-numeric-value line)
+ (/ (window-height) 2)))
+ (TeX-pop-to-buffer old-buffer nil t))
+ (message "No process for this document."))))
+
+(defun TeX-kill-job ()
+ "Kill the currently running TeX job."
+ (interactive)
+ (let ((process (TeX-active-process)))
+ (if process
+ (kill-process process)
+ ;; Should test for TeX background process here.
+ (error "No TeX process to kill"))))
+
+(defun TeX-home-buffer ()
+ "Go to the buffer where you last issued a TeX command.
+If there is no such buffer, or you already are in that buffer, find
+the master file."
+ (interactive)
+ (if (or (null TeX-command-buffer)
+ (null (buffer-name TeX-command-buffer))
+ (eq TeX-command-buffer (current-buffer)))
+ (find-file (TeX-master-file TeX-default-extension))
+ (switch-to-buffer TeX-command-buffer)))
+
+(defun TeX-next-error (reparse)
+ "Find the next error in the TeX output buffer.
+With \\[universal-argument] prefix, start from the beginning of the errors."
+ (interactive "P")
+ (if (null (TeX-active-buffer))
+ (next-error reparse)
+ (funcall (TeX-process-get-variable (with-current-buffer TeX-command-buffer
+ (TeX-active-master))
+ 'TeX-parse-function)
+ reparse)))
+
+(defun TeX-previous-error (arg)
+ "Find the previous error in the TeX output buffer."
+ (interactive "P")
+ (if (null (TeX-active-buffer))
+ (previous-error arg)
+ (error "Jumping to previous error not supported")))
+
+;;; Command Query
+
+(defun TeX-command (name file &optional override-confirm)
+ "Run command NAME on the file returned by calling FILE.
+
+FILE is the symbol of a function returning a file name. The
+function has one optional argument, the extension to use on the
+file.
+
+Use the information in `TeX-command-list' to determine how to run
+the command.
+
+If OVERRIDE-CONFIRM is a prefix argument, confirmation will be
+asked if it is positive, and suppressed if it is not."
+ (cond ((eq file 'TeX-region-file)
+ (setq TeX-current-process-region-p t))
+ ((eq file 'TeX-master-file)
+ (setq TeX-current-process-region-p nil)))
+ (let ((command (TeX-command-expand (nth 1 (assoc name TeX-command-list))
+ file))
+ (hook (nth 2 (assoc name TeX-command-list)))
+ (confirm (if override-confirm
+ (> (prefix-numeric-value override-confirm) 0)
+ (nth 3 (assoc name TeX-command-list)))))
+
+ ;; Verify the expanded command
+ (if confirm
+ (setq command
+ (read-from-minibuffer (concat name " command: ") command
+ nil nil)))
+
+ ;; Now start the process
+ (setq file (funcall file))
+ (TeX-process-set-variable file 'TeX-command-next TeX-command-Show)
+ (funcall hook name command file)))
+
+(defun TeX-command-expand (command file &optional list)
+ "Expand COMMAND for FILE as described in LIST.
+LIST default to `TeX-expand-list'. As a special exception,
+`%%' can be used to produce a single `%' sign in the output
+without further expansion."
+ (let (pat
+ pos
+ entry TeX-command-text TeX-command-pos
+ (file `(lambda (&rest args)
+ (shell-quote-argument
+ (concat (and (stringp TeX-command-pos) TeX-command-pos)
+ (apply ',file args)
+ (and (stringp TeX-command-pos) TeX-command-pos)))))
+ case-fold-search string expansion arguments)
+ (setq list (cons
+ (list "%%" (lambda nil
+ (setq pos (1+ pos))
+ "%"))
+ (or list TeX-expand-list))
+ pat (regexp-opt (mapcar #'car list)))
+ (while (setq pos (string-match pat command pos))
+ (setq string (match-string 0 command)
+ entry (assoc string list)
+ expansion (car (cdr entry)) ;Second element
+ arguments (cdr (cdr entry)) ;Remaining elements
+ string (save-match-data
+ ;; Note regarding the special casing of `file':
+ ;; `file' is prevented from being evaluated as a
+ ;; function because inside of AUCTeX it only has
+ ;; a meaning as a variable. This makes sure that
+ ;; a function definition made by an external
+ ;; package (e.g. icicles) is not picked up.
+ (cond ((and (not (eq expansion 'file))
+ (TeX-function-p expansion))
+ (apply expansion arguments))
+ ((boundp expansion)
+ (apply (eval expansion) arguments))
+ (t
+ (error "Nonexpansion %s" expansion)))))
+ (if (stringp string)
+ (setq command
+ (replace-match string t t command)))))
+ command)
+
+(defun TeX-check-files (derived originals extensions)
+ "Check that DERIVED is newer than any of the ORIGINALS.
+Try each original with each member of EXTENSIONS, in all directories
+in `TeX-check-path'."
+ (let ((found nil)
+ (regexp (concat "\\`\\("
+ (mapconcat (lambda (dir)
+ (regexp-quote
+ (expand-file-name
+ (file-name-as-directory dir))))
+ TeX-check-path "\\|")
+ "\\).*\\("
+ (mapconcat 'regexp-quote originals "\\|")
+ "\\)\\.\\("
+ (mapconcat 'regexp-quote extensions "\\|")
+ "\\)\\'"))
+ (buffers (buffer-list)))
+ (while buffers
+ (let* ((buffer (car buffers))
+ (name (buffer-file-name buffer)))
+ (setq buffers (cdr buffers))
+ (if (and name (string-match regexp name))
+ (progn
+ (and (buffer-modified-p buffer)
+ (or (not TeX-save-query)
+ (y-or-n-p (concat "Save file "
+ (buffer-file-name buffer)
+ "? ")))
+ (save-excursion (set-buffer buffer) (save-buffer)))
+ (if (file-newer-than-file-p name derived)
+ (setq found t))))))
+ found))
+
+(defcustom TeX-save-query t
+ "*If non-nil, ask user for permission to save files before starting TeX."
+ :group 'TeX-command
+ :type 'boolean)
+
+(defvar TeX-command-history nil)
+
+(defun TeX-command-query (name)
+ "Query the user for what TeX command to use."
+ (let* ((default (cond ((if (string-equal name TeX-region)
+ (TeX-check-files (concat name "." (TeX-output-extension))
+ (list name)
+ TeX-file-extensions)
+ (TeX-save-document (TeX-master-file)))
+ TeX-command-default)
+ ((and (memq major-mode '(doctex-mode latex-mode))
+ (TeX-check-files (concat name ".bbl")
+ (mapcar 'car
+ (LaTeX-bibliography-list))
+ BibTeX-file-extensions))
+ ;; We should check for bst files here as well.
+ TeX-command-BibTeX)
+ ((TeX-process-get-variable name
+ 'TeX-command-next
+ TeX-command-Show))
+ (TeX-command-Show)))
+ (completion-ignore-case t)
+ (answer (or TeX-command-force
+ (completing-read
+ (concat "Command: (default " default ") ")
+ (TeX-mode-specific-command-list major-mode) nil t
+ nil 'TeX-command-history))))
+ ;; If the answer "latex" it will not be expanded to "LaTeX"
+ (setq answer (car-safe (TeX-assoc answer TeX-command-list)))
+ (if (and answer
+ (not (string-equal answer "")))
+ answer
+ default)))
+
+(defvar TeX-command-next nil
+ "The default command next time `TeX-command' is invoked.")
+
+ (make-variable-buffer-local 'TeX-command-next)
+
+(defun TeX-printer-query (&optional queue)
+ "Query the user for a printer name.
+QUEUE is non-nil when we are checking for the printer queue."
+ (let (command element printer)
+ (if queue
+ (unless (setq element 2 command TeX-queue-command)
+ (error "Need to customize `TeX-queue-command'"))
+ (unless (setq element 1 command TeX-print-command)
+ (error "Need to customize `TeX-print-command'")))
+ (while (progn
+ (setq printer (if TeX-printer-list
+ (let ((completion-ignore-case t))
+ (completing-read
+ (concat "Printer: "
+ (and TeX-printer-default
+ (concat "(default "
+ TeX-printer-default ") ")))
+ TeX-printer-list))
+ ""))
+ (setq printer (or (car-safe (TeX-assoc printer TeX-printer-list))
+ printer))
+ (not (if (or (null printer) (string-equal "" printer))
+ (setq printer TeX-printer-default)
+ (setq TeX-printer-default printer)))))
+
+ (let ((expansion (let ((entry (assoc printer TeX-printer-list)))
+ (or (nth element entry)
+ command))))
+ (if (string-match "%p" printer)
+ (error "Don't use %s in printer names" "%p"))
+ (while (string-match "%p" expansion)
+ (setq expansion (replace-match printer t t expansion 0)))
+ expansion)))
+
+(defun TeX-style-check (styles)
+ "Check STYLES compared to the current style options."
+ (let ((files (TeX-style-list)))
+ (while (and styles
+ (not (TeX-member (car (car styles)) files 'string-match)))
+ (setq styles (cdr styles))))
+ (if styles
+ (nth 1 (car styles))
+ ""))
+
+(defun TeX-output-extension ()
+ "Get the extension of the current TeX output file."
+ (if (listp TeX-output-extension)
+ (car TeX-output-extension)
+ (or (TeX-process-get-variable (TeX-active-master)
+ 'TeX-output-extension
+ TeX-output-extension)
+ TeX-output-extension)))
+
+(defun TeX-view-mouse (event)
+ "Start `TeX-view' at mouse position."
+ (interactive "e")
+ (save-excursion
+ (set-buffer (window-buffer (posn-window (event-start event))))
+ (goto-char (posn-point (event-start event)))
+ (TeX-view)))
+
+(defun TeX-view ()
+ "Start a viewer without confirmation.
+The viewer is started either on region or master file,
+depending on the last command issued."
+ (interactive)
+ (let ((output-file (TeX-active-master (TeX-output-extension))))
+ (if (file-exists-p output-file)
+ (TeX-command "View" 'TeX-active-master 0)
+ (message "Output file %S does not exist." output-file))))
+
+(defun TeX-output-style-check (styles)
+ "Check STYLES compared to the current view output file extension and
+the current style options."
+ (let ((ext (TeX-output-extension))
+ (files (TeX-style-list)))
+ (while (and
+ styles
+ (or
+ (not (string-match (car (car styles)) ext))
+ (let ((style (nth 1 (car styles))))
+ (cond
+ ((listp style)
+ (while
+ (and style
+ (TeX-member (car style) files 'string-match))
+ (setq style (cdr style)))
+ style)
+ ((not (TeX-member style files 'string-match)))))))
+ (setq styles (cdr styles)))
+ (if styles
+ (nth 2 (car styles))
+ "%v")))
+
+;;; Command Hooks
+
+(defvar TeX-after-start-process-function nil
+ "Hooks to run after starting an asynchronous process.
+Used by Japanese TeX to set the coding system.")
+
+(defcustom TeX-show-compilation nil
+ "*If non-nil, show output of TeX compilation in other window."
+ :group 'TeX-command
+ :type 'boolean)
+
+(defun TeX-run-command (name command file)
+ "Create a process for NAME using COMMAND to process FILE.
+Return the new process."
+ (let ((default TeX-command-default)
+ (buffer (TeX-process-buffer-name file))
+ (dir (TeX-master-directory))
+ (command-buff (current-buffer)))
+ (TeX-process-check file) ; Check that no process is running
+ (setq-default TeX-command-buffer command-buff)
+ (get-buffer-create buffer)
+ (set-buffer buffer)
+ (buffer-disable-undo)
+ (erase-buffer)
+ (set (make-local-variable 'line-number-display-limit) 0)
+ (setq TeX-output-extension nil)
+ (set (make-local-variable 'TeX-command-buffer) command-buff)
+ (if dir (cd dir))
+ (insert "Running `" name "' on `" file "' with ``" command "''\n")
+ (setq mode-name name)
+ (if TeX-show-compilation
+ (display-buffer buffer)
+ (message "Type `%s' to display results of compilation."
+ (substitute-command-keys
+ "\\<TeX-mode-map>\\[TeX-recenter-output-buffer]")))
+ (setq TeX-parse-function 'TeX-parse-command)
+ (setq TeX-command-default default)
+ (setq TeX-sentinel-function
+ (lambda (process name)
+ (message (concat name ": done."))))
+ (if TeX-process-asynchronous
+ (let ((process (start-process name buffer TeX-shell
+ TeX-shell-command-option command)))
+ (if TeX-after-start-process-function
+ (funcall TeX-after-start-process-function process))
+ (TeX-command-mode-line process)
+ (set-process-filter process 'TeX-command-filter)
+ (set-process-sentinel process 'TeX-command-sentinel)
+ (set-marker (process-mark process) (point-max))
+ (setq compilation-in-progress (cons process compilation-in-progress))
+ process)
+ (setq mode-line-process ": run")
+ (set-buffer-modified-p (buffer-modified-p))
+ (sit-for 0) ; redisplay
+ (call-process TeX-shell nil buffer nil
+ TeX-shell-command-option command))))
+
+(defun TeX-run-set-command (name command)
+ "Remember TeX command to use to NAME and set corresponding output extension."
+ (setq TeX-command-default name
+ TeX-output-extension (if TeX-PDF-mode "pdf" "dvi"))
+ (let ((case-fold-search t)
+ (lst TeX-command-output-list))
+ (while lst
+ (if (string-match (car (car lst)) command)
+ (setq TeX-output-extension (car (cdr (car lst)))
+ lst nil)
+ (setq lst (cdr lst))))))
+
+(defun TeX-run-format (name command file)
+ "Create a process for NAME using COMMAND to format FILE with TeX."
+ (TeX-run-set-command name command)
+ (let ((buffer (TeX-process-buffer-name file))
+ (process (TeX-run-command name command file)))
+ ;; Hook to TeX debuger.
+ (save-excursion
+ (set-buffer buffer)
+ (TeX-parse-reset)
+ (setq TeX-parse-function 'TeX-parse-TeX)
+ (setq TeX-sentinel-function 'TeX-TeX-sentinel)
+ (if TeX-process-asynchronous
+ (progn
+ ;; Updating the mode line.
+ (setq TeX-current-page "[0]")
+ (TeX-format-mode-line process)
+ (set-process-filter process 'TeX-format-filter)))
+ process)))
+
+(defvar TeX-error-report-switches nil
+ "Reports presence of errors after `TeX-run-TeX'.
+To test whether the current buffer has an compile error from last
+run of `TeX-run-TeX', use
+ (plist-get TeX-error-report-switches (intern (TeX-master-file)))")
+
+(defun TeX-run-TeX (name command file)
+ "Create a process for NAME using COMMAND to format FILE with TeX."
+
+ ;; Save information in TeX-error-report-switches
+ ;; Initialize error to nil (no error) for current master.
+ ;; Presence of error is reported inside `TeX-TeX-sentinel-check'
+ (let ((current-master (TeX-master-file)))
+ ;; the current master file is saved because error routines are
+ ;; parsed in other buffers;
+ (setq TeX-error-report-switches
+ (plist-put TeX-error-report-switches
+ 'TeX-current-master current-master))
+ ;; reset error to nil (no error)
+ (setq TeX-error-report-switches
+ (plist-put TeX-error-report-switches
+ (intern current-master) nil)))
+
+ ;; can we assume that TeX-sentinel-function will not be changed
+ ;; during (TeX-run-format ..)? --pg
+ ;; rather use let* ? --pg
+
+ (if TeX-interactive-mode
+ (TeX-run-interactive name command file)
+ (let ((sentinel-function TeX-sentinel-default-function))
+ (let ((process (TeX-run-format name command file)))
+ (setq TeX-sentinel-function sentinel-function)
+ (if TeX-process-asynchronous
+ process
+ (TeX-synchronous-sentinel name file process))))))
+
+;; backward compatibilty
+
+(defalias 'TeX-run-LaTeX 'TeX-run-TeX)
+
+
+(defun TeX-run-BibTeX (name command file)
+ "Create a process for NAME using COMMAND to format FILE with BibTeX."
+ (let ((process (TeX-run-command name command file)))
+ (setq TeX-sentinel-function 'TeX-BibTeX-sentinel)
+ (if TeX-process-asynchronous
+ process
+ (TeX-synchronous-sentinel name file process))))
+
+(defun TeX-run-compile (name command file)
+ "Ignore first and third argument, start compile with second argument."
+ (compile command))
+
+(defun TeX-run-shell (name command file)
+ "Ignore first and third argument, start shell-command with second argument."
+ (let ((default-directory (TeX-master-directory)))
+ (shell-command command)
+ (if (eq system-type 'ms-dos)
+ (redraw-display))))
+
+(defun TeX-run-discard (name command file)
+ "Start COMMAND as process, discarding its output.
+NAME and FILE are ignored."
+ (let ((default-directory (TeX-master-directory)))
+ (call-process TeX-shell
+ nil 0 nil
+ TeX-shell-command-option
+ command)))
+
+(defun TeX-run-discard-foreground (name command file)
+ "Call process with second argument in the foreground, discarding its output.
+With support for MS-DOS, especially when dviout is used with PC-9801 series."
+ (if (and (boundp 'dos-machine-type) (eq dos-machine-type 'pc98)) ;if PC-9801
+ (send-string-to-terminal "\e[2J")) ; clear screen
+ (call-process TeX-shell (if (eq system-type 'ms-dos) "con") nil nil
+ TeX-shell-command-option command)
+ (if (eq system-type 'ms-dos)
+ (redraw-display)))
+(defalias 'TeX-run-dviout 'TeX-run-discard-foreground)
+
+(defun TeX-run-background (name command file)
+ "Start process with second argument, show output when and if it arrives."
+ (let ((dir (TeX-master-directory)))
+ (set-buffer (get-buffer-create "*TeX background*"))
+ (if dir (cd dir))
+ (erase-buffer)
+ (let ((process (start-process (concat name " background")
+ nil TeX-shell
+ TeX-shell-command-option command)))
+ (if TeX-after-start-process-function
+ (funcall TeX-after-start-process-function process))
+ (set-process-filter process 'TeX-background-filter)
+ (process-kill-without-query process))))
+
+(defun TeX-run-silent (name command file)
+ "Start process with second argument."
+ (let ((dir (TeX-master-directory)))
+ (set-buffer (get-buffer-create "*TeX silent*"))
+ (if dir (cd dir))
+ (erase-buffer)
+ (let ((process (start-process (concat name " silent")
+ nil TeX-shell
+ TeX-shell-command-option command)))
+ (if TeX-after-start-process-function
+ (funcall TeX-after-start-process-function process))
+ (process-kill-without-query process))))
+
+(defun TeX-run-interactive (name command file)
+ "Run TeX interactively.
+Run command in a buffer (in comint-shell-mode) so that it accepts user
+interaction. If you return to the file buffer after the TeX run,
+Error parsing on \\[next-error] should work with a bit of luck."
+ (TeX-run-set-command name command)
+ (require 'comint)
+ (let ((default TeX-command-default)
+ (buffer (TeX-process-buffer-name file))
+ (process nil)
+ (dir (TeX-master-directory))
+ (command-buff (current-buffer))
+ (sentinel-function TeX-sentinel-default-function)) ; inherit from major mode
+ (TeX-process-check file) ; Check that no process is running
+ (setq-default TeX-command-buffer command-buff)
+ (with-output-to-temp-buffer buffer)
+ (set-buffer buffer)
+ (set (make-local-variable 'TeX-command-buffer) command-buff)
+ (setq buffer-read-only nil)
+ (if dir (cd dir))
+ (insert "Running `" name "' on `" file "' with ``" command "''\n")
+ (comint-exec buffer name TeX-shell nil
+ (list TeX-shell-command-option command))
+ (comint-mode)
+ (add-hook 'comint-output-filter-functions 'TeX-interactive-goto-prompt)
+ (setq mode-name name)
+ (setq TeX-command-default default)
+ (setq process (get-buffer-process buffer))
+ (if TeX-after-start-process-function
+ (funcall TeX-after-start-process-function process))
+ (TeX-command-mode-line process)
+ (set-process-sentinel process 'TeX-command-sentinel)
+ (set-marker (process-mark process) (point-max))
+ (setq compilation-in-progress (cons process compilation-in-progress))
+ (TeX-parse-reset)
+ (setq TeX-parse-function 'TeX-parse-TeX)
+ ;; use the sentinel-function that the major mode sets, not the LaTeX one
+ (setq TeX-sentinel-function sentinel-function)))
+
+(defun TeX-run-function (name command file)
+ "Execute Lisp function or function call given as the string COMMAND.
+Parameters NAME and FILE are ignored."
+ (let ((fun (car (read-from-string command))))
+ (if (functionp fun) (funcall fun) (eval fun))))
+
+(defun TeX-run-discard-or-function (name command file)
+ "Start COMMAND as process or execute it as a Lisp function.
+If run as a process, the output is discarded. COMMAND is
+expected to be a string. NAME and FILE are ignored."
+ (if (functionp (car (read-from-string command)))
+ (TeX-run-function name command file)
+ (TeX-run-discard name command file)))
+
+(defun TeX-run-ispell-on-document (command ignored name)
+ "Run ispell on all open files belonging to the current document.
+This function is *obsolete* and only here for compatibility
+reasons. Use `TeX-run-function' instead."
+ (interactive)
+ (TeX-ispell-document ""))
+
+
+;;; Command Sentinels
+
+(defun TeX-synchronous-sentinel (name file result)
+ "Process TeX command output buffer after the process dies."
+ (let* ((buffer (TeX-process-buffer file)))
+ (save-excursion
+ (set-buffer buffer)
+
+ ;; Append post-mortem information to the buffer
+ (goto-char (point-max))
+ (insert "\n" mode-name (if (and result (zerop result))
+ " finished" " exited") " at "
+ (substring (current-time-string) 0 -5))
+ (setq mode-line-process ": exit")
+
+ ;; Do command specific actions.
+ (setq TeX-command-next TeX-command-Show)
+ (goto-char (point-min))
+ (apply TeX-sentinel-function nil name nil)
+
+ ;; Force mode line redisplay soon
+ (set-buffer-modified-p (buffer-modified-p)))))
+
+(defun TeX-command-sentinel (process msg)
+ "Process TeX command output buffer after the process dies."
+ ;; Set `TeX-transient-master' here because `preview-parse-messages'
+ ;; may open files and thereby trigger master file questions which we
+ ;; don't want and need because we already know the master. Use
+ ;; `TeX-master-file' instead of `TeX-active-master' to determine the
+ ;; master because the region file should never be the master.
+ (let* ((TeX-transient-master (TeX-master-file))
+ (buffer (process-buffer process))
+ (name (process-name process)))
+ (cond ((null (buffer-name buffer)) ; buffer killed
+ (set-process-buffer process nil)
+ (set-process-sentinel process nil))
+ ((memq (process-status process) '(signal exit))
+ (save-excursion
+ (set-buffer buffer)
+
+ ;; Append post-mortem information to the buffer
+ (goto-char (point-max))
+ (insert-before-markers "\n" mode-name " " msg)
+ (forward-char -1)
+ (insert " at "
+ (substring (current-time-string) 0 -5))
+ (forward-char 1)
+
+ ;; Do command specific actions.
+ (TeX-command-mode-line process)
+ (setq TeX-command-next TeX-command-Show)
+ (goto-char (point-min))
+ (apply TeX-sentinel-function process name nil)
+
+
+ ;; If buffer and mode line will show that the process
+ ;; is dead, we can delete it now. Otherwise it
+ ;; will stay around until M-x list-processes.
+ (delete-process process)
+
+ ;; Force mode line redisplay soon
+ (set-buffer-modified-p (buffer-modified-p))))))
+ (setq compilation-in-progress (delq process compilation-in-progress)))
+
+
+(defvar TeX-sentinel-function (lambda (process name))
+ "Hook to cleanup TeX command buffer after temination of PROCESS.
+NAME is the name of the process.")
+
+ (make-variable-buffer-local 'TeX-sentinel-function)
+
+
+(defvar TeX-sentinel-default-function (lambda (process name))
+ "Default for `TeX-sentinel-function'. To be set in major mode.
+Hook to cleanup TeX command buffer after temination of PROCESS.
+NAME is the name of the process.")
+
+ (make-variable-buffer-local 'TeX-sentinel-default-function)
+
+(defun TeX-TeX-sentinel (process name)
+ "Cleanup TeX output buffer after running TeX."
+ (if (TeX-TeX-sentinel-check process name)
+ ()
+ (message (concat name ": formatted " (TeX-current-pages)))
+ (setq TeX-command-next TeX-command-Show)))
+
+(defun TeX-current-pages ()
+ "Return string indicating the number of pages formatted."
+ (cond ((null TeX-current-page)
+ "some pages")
+ ((string-match "[^0-9]1[^0-9]" TeX-current-page)
+ (concat TeX-current-page " page"))
+ (t
+ (concat TeX-current-page " pages"))))
+
+(defun TeX-TeX-sentinel-check (process name)
+ "Cleanup TeX output buffer after running TeX.
+Return nil ifs no errors were found."
+ (save-excursion
+ (goto-char (point-max))
+ (if (re-search-backward "^Output written on \\(.*?\\) (\\([0-9]+\\) page"
+ nil t)
+ (let ((output-file (TeX-match-buffer 1)))
+ (setq TeX-current-page (concat "{" (TeX-match-buffer 2) "}"))
+ ;; Shave off quotation marks if present.
+ (when (string-match "\\`\"\\(.*\\)\"\\'" output-file)
+ (setq output-file (match-string 1 output-file)))
+ (setq TeX-output-extension
+ (if (string-match "\\.\\([^.]*\\)$" output-file)
+ (match-string 1 output-file)
+ "dvi")))))
+ (if process (TeX-format-mode-line process))
+ (if (re-search-forward "^\\(!\\|.*:[0-9]+:\\) " nil t)
+ (progn
+ (message "%s errors in `%s'. Use %s to display." name (buffer-name)
+ (substitute-command-keys
+ "\\<TeX-mode-map>\\[TeX-next-error]"))
+ (setq TeX-command-next TeX-command-default)
+ ;; error reported to TeX-error-report-switches
+ (setq TeX-error-report-switches
+ (plist-put TeX-error-report-switches
+ (intern (plist-get TeX-error-report-switches
+ 'TeX-current-master))
+ t))
+ t)
+ (setq TeX-command-next TeX-command-Show)
+ nil))
+
+(defun TeX-LaTeX-sentinel-has-warnings ()
+ "Return non-nil, if the output buffer contains warnings.
+Warnings can be indicated by LaTeX or packages."
+ (save-excursion
+ (goto-char (point-min))
+ (re-search-forward
+ "^\\(LaTeX [A-Za-z]*\\|Package [A-Za-z]+ \\)Warning:" nil t)))
+
+(defun TeX-LaTeX-sentinel-has-bad-boxes ()
+ "Return non-nil, if LaTeX output indicates overfull or underfull boxes."
+ (save-excursion
+ (goto-char (point-min))
+ (re-search-forward "^\\(Ov\\|Und\\)erfull \\\\" nil t)))
+
+;; should go into latex.el? --pg
+(defun TeX-LaTeX-sentinel (process name)
+ "Cleanup TeX output buffer after running LaTeX."
+ (cond ((TeX-TeX-sentinel-check process name))
+ ((and (save-excursion
+ (re-search-forward
+ "^\\(?:LaTeX\\|Package natbib\\) Warning: Citation" nil t))
+ (with-current-buffer TeX-command-buffer
+ (and (LaTeX-bibliography-list)
+ (TeX-check-files (TeX-master-file "bbl")
+ (TeX-style-list)
+ (append TeX-file-extensions
+ BibTeX-file-extensions)))))
+ (message "%s%s" "You should run BibTeX to get citations right, "
+ (TeX-current-pages))
+ (setq TeX-command-next (with-current-buffer TeX-command-buffer
+ TeX-command-BibTeX)))
+ ((re-search-forward "^\\(?:LaTeX Warning: Label(s)\\|\
+Package natbib Warning: Citation(s)\\)" nil t)
+ (message "%s%s" "You should run LaTeX again to get references right, "
+ (TeX-current-pages))
+ (setq TeX-command-next TeX-command-default))
+ ((re-search-forward "^LaTeX Warning: Reference" nil t)
+ (message "%s%s%s" name ": there were unresolved references, "
+ (TeX-current-pages))
+ (setq TeX-command-next TeX-command-Show))
+ ((re-search-forward "^\\(?:LaTeX Warning: Citation\\|\
+Package natbib Warning:.*undefined citations\\)" nil t)
+ (message "%s%s%s" name ": there were unresolved citations, "
+ (TeX-current-pages))
+ (setq TeX-command-next TeX-command-Show))
+ ((re-search-forward "Package longtable Warning: Table widths have \
+changed\\. Rerun LaTeX\\." nil t)
+ (message
+ "%s" "You should run LaTeX again to get table formatting right")
+ (setq TeX-command-next TeX-command-default))
+ ((re-search-forward
+ "^\\(\\*\\* \\)?J?I?p?\\(La\\|Sli\\)TeX\\(2e\\)? \
+\\(Version\\|ver\\.\\|<[0-9/]*>\\)" nil t)
+ (let* ((warnings (and TeX-debug-warnings
+ (TeX-LaTeX-sentinel-has-warnings)))
+ (bad-boxes (and TeX-debug-bad-boxes
+ (TeX-LaTeX-sentinel-has-bad-boxes)))
+ (add-info (when (or warnings bad-boxes)
+ (concat " (with "
+ (when warnings "warnings")
+ (when (and warnings bad-boxes) " and ")
+ (when bad-boxes "bad boxes")
+ ")"))))
+ (message "%s" (concat name ": successfully formatted "
+ (TeX-current-pages) add-info)))
+ (setq TeX-command-next TeX-command-Show))
+ (t
+ (message "%s%s%s" name ": problems after " (TeX-current-pages))
+ (setq TeX-command-next TeX-command-default))))
+
+;; should go into latex.el? --pg
+(defun TeX-BibTeX-sentinel (process name)
+ "Cleanup TeX output buffer after running BibTeX."
+ (goto-char (point-max))
+ (cond
+ ;; Check whether BibTeX reports any warnings or errors.
+ ((re-search-backward (concat
+ "^(There \\(?:was\\|were\\) \\([0-9]+\\) "
+ "\\(warnings?\\|error messages?\\))") nil t)
+ ;; Tell the user their number so that she sees whether the
+ ;; situation is getting better or worse.
+ (message (concat "BibTeX finished with %s %s. "
+ "Type `%s' to display output.")
+ (match-string 1) (match-string 2)
+ (substitute-command-keys
+ "\\<TeX-mode-map>\\[TeX-recenter-output-buffer]")))
+ (t
+ (message (concat "BibTeX finished successfully. "
+ "Run LaTeX again to get citations right."))))
+ (setq TeX-command-next TeX-command-default))
+
+;;; Process Control
+
+
+;; This variable is chared with `compile.el'.
+(defvar compilation-in-progress nil
+ "List of compilation processes now running.")
+
+(or (assq 'compilation-in-progress minor-mode-alist)
+ (setq minor-mode-alist (cons '(compilation-in-progress " Compiling")
+ minor-mode-alist)))
+
+(defun TeX-process-get-variable (name symbol &optional default)
+ "Return the value in the process buffer for NAME of SYMBOL.
+
+Return DEFAULT if the process buffer does not exist or SYMBOL is not
+defined."
+ (let ((buffer (TeX-process-buffer name)))
+ (if (and buffer
+ (local-variable-p symbol buffer))
+ (save-excursion
+ (set-buffer buffer)
+ (symbol-value symbol))
+ default)))
+
+(defun TeX-process-set-variable (name symbol value)
+ "Set the variable SYMBOL in the process buffer to VALUE.
+Return nil iff no process buffer exist."
+ (let ((buffer (TeX-process-buffer name)))
+ (if buffer
+ (save-excursion
+ (set-buffer buffer)
+ (set symbol value)
+ t)
+ nil)))
+
+(defun TeX-process-check (name)
+ "Check if a process for the TeX document NAME already exist.
+If so, give the user the choice of aborting the process or the current
+command."
+ (let (process)
+ (while (and (setq process (TeX-process name))
+ (eq (process-status process) 'run))
+ (cond
+ ((yes-or-no-p (concat "Process `"
+ (process-name process)
+ "' for document `"
+ name
+ "' running, kill it? "))
+ (delete-process process))
+ ((eq (process-status process) 'run)
+ (error "Cannot have two processes for the same document"))))))
+
+(defun TeX-process-buffer-name (name)
+ "Return name of AUCTeX buffer associated with the document NAME."
+ (concat "*" (abbreviate-file-name (expand-file-name name)) " output*"))
+
+(defun TeX-process-buffer (name)
+ "Return the AUCTeX buffer associated with the document NAME."
+ (get-buffer (TeX-process-buffer-name name)))
+
+(defun TeX-process (name)
+ "Return AUCTeX process associated with the document NAME."
+ (and TeX-process-asynchronous
+ (get-buffer-process (TeX-process-buffer name))))
+
+;;; Process Filters
+
+(defun TeX-command-mode-line (process)
+ "Format the mode line for a buffer containing output from PROCESS."
+ (setq mode-line-process (concat ": "
+ (symbol-name (process-status process))))
+ (set-buffer-modified-p (buffer-modified-p)))
+
+(defun TeX-command-filter (process string)
+ "Filter to process normal output."
+ (with-current-buffer (process-buffer process)
+ (save-excursion
+ (goto-char (process-mark process))
+ (insert-before-markers string)
+ (set-marker (process-mark process) (point)))))
+
+(defvar TeX-current-page nil
+ "The page number currently being formatted, enclosed in brackets.")
+
+ (make-variable-buffer-local 'TeX-current-page)
+
+(defun TeX-format-mode-line (process)
+ "Format the mode line for a buffer containing TeX output from PROCESS."
+ (setq mode-line-process (concat " " TeX-current-page ": "
+ (symbol-name (process-status process))))
+ (set-buffer-modified-p (buffer-modified-p)))
+
+(defun TeX-format-filter (process string)
+ "Filter to process TeX output."
+ (with-current-buffer (process-buffer process)
+ (let (str pos end (pt (marker-position (process-mark process))))
+ (save-excursion
+ (goto-char pt)
+ (insert-before-markers string)
+ (set-marker (process-mark process) (point))
+ ;; Remove line breaks at column 79
+ (while (> (point) pt)
+ (end-of-line 0)
+ (when (and (= (current-column) 79)
+ ;; Heuristic: Don't delete the linebreak if the
+ ;; next line is empty or starts with an opening
+ ;; parenthesis or if point is located after a period.
+ (not (memq (char-after (1+ (point))) '(?\n ?\()))
+ (not (eq (char-before) ?.)))
+ (delete-char 1)))
+ (goto-char (marker-position (process-mark process)))
+ ;; Determine current page
+ (while (and pt
+ (skip-chars-backward "^]" pt)
+ (> (point) pt))
+ (setq end (point))
+ (backward-char)
+ (skip-chars-backward "-0-9\n." (max (point-min) (- pt 128)))
+ (when (and (eq ?\[ (char-before))
+ (not (eq ?\] (char-after)))
+ (progn
+ (setq str (buffer-substring (1- (point)) end)
+ pos nil)
+ (while (setq pos (string-match "\n" str pos))
+ (setq str (replace-match "" t t str)))
+ (string-match
+ "\\`\\[-?[0-9]+\\(\\.-?[0-9]+\\)\\{0,9\\}\\]\\'"
+ str)))
+ (setq TeX-current-page str
+ pt nil)
+ (TeX-format-mode-line process)))))))
+
+(defvar TeX-parse-function nil
+ "Function to call to parse content of TeX output buffer.")
+ (make-variable-buffer-local 'TeX-parse-function)
+
+(defun TeX-background-filter (process string)
+ "Filter to process background output."
+ (let ((old-window (selected-window))
+ (pop-up-windows t))
+ (TeX-pop-to-buffer "*TeX background*" nil t)
+ (goto-char (point-max))
+ (insert string)
+ (select-window old-window)))
+
+;; Copy and adaption of `comint-postoutput-scroll-to-bottom' from CVS
+;; Emacs of 2005-04-24.
+(defun TeX-interactive-goto-prompt (string)
+ "Move point to prompt of an interactive TeX run."
+ (let* ((selected (selected-window))
+ (current (current-buffer))
+ (process (get-buffer-process current)))
+ (unwind-protect
+ (when process
+ (walk-windows
+ (lambda (window)
+ (when (eq (window-buffer window) current)
+ (select-window window)
+ (when (and (< (point) (process-mark process))
+ (string-match "^\\? $" string))
+ (goto-char (process-mark process)))
+ (select-window selected)))
+ nil t))
+ (set-buffer current))))
+
+
+;;; Active Process
+
+(defvar TeX-current-process-region-p nil
+ "This variable is set to t iff the last TeX command is on a region.")
+
+(defun TeX-active-process ()
+ "Return the active process for the current buffer."
+ (TeX-process (TeX-active-master)))
+
+(defun TeX-active-buffer ()
+ "Return the buffer of the active process for this buffer."
+ (and TeX-command-buffer
+ (TeX-process-buffer (with-current-buffer TeX-command-buffer
+ (TeX-active-master)))))
+
+(defun TeX-active-master (&optional extension nondirectory)
+ "The master file currently being compiled.
+
+If optional argument EXTENSION is non-nil, add that file extension to
+the name. Special value t means use `TeX-default-extension'.
+
+If optional second argument NONDIRECTORY is non-nil, do not include
+the directory."
+ (if TeX-current-process-region-p
+ (TeX-region-file extension nondirectory)
+ (TeX-master-file extension nondirectory)))
+
+(defvar TeX-command-buffer nil
+ "The buffer from where the last TeX command was issued.")
+
+;;; Region File
+
+(defcustom TeX-region-extra ""
+ "*String to insert in the region file between the header and the text."
+ :group 'TeX-command
+ :type 'string)
+
+;; This was "{\\makeatletter\\gdef\\AucTeX@cite#1[#2]#3{[#3#1#2]}\
+;; \\gdef\\cite{\\@ifnextchar[{\\AucTeX@cite{, }}\
+;; {\\AucTeX@cite{}[]}}}\n"
+;; However, that string is inappropriate for plain TeX and ConTeXt.
+;; This needs reconsideration.
+
+
+(defvar TeX-region-hook nil
+ "List of hooks to run before the region file is saved.
+The hooks are run in the region buffer, you may use the variable
+`master-buffer' to access the buffer of the master file and
+`orig-buffer' to access the buffer where \\[TeX-command-region] or
+\\[TeX-command-buffer] is invoked from.")
+
+(defun TeX-quote-filename (file)
+ "Convert file name into a form acceptable to TeX."
+ (let (pos)
+ (while (setq pos (string-match "\\\\" file pos))
+ (setq file (replace-match "/" t t file 0)
+ pos (1+ pos)))
+ (while (setq pos (string-match "[~#]" file pos))
+ (setq file (replace-match "\\\\string\\&" t nil file 0)
+ pos (+ pos 8))))
+ file)
+
+(defun TeX-region-create (file region original offset)
+ "Create a new file named FILE with the string REGION.
+The region is taken from ORIGINAL starting at line OFFSET.
+
+The current buffer and master file is searched, in order to ensure
+that the TeX header and trailer information is also included.
+
+The OFFSET is used to provide the debugger with information about the
+original file."
+ (let* (;; We shift buffer a lot, so we must keep track of the buffer
+ ;; local variables.
+ (header-end TeX-header-end)
+ (trailer-start TeX-trailer-start)
+
+ ;; We seach for header and trailer in the master file.
+ (orig-buffer (current-buffer))
+ (master-name (TeX-master-file TeX-default-extension))
+ (master-buffer (find-file-noselect master-name))
+
+ ;; Attempt to disable font lock.
+ (font-lock-defaults-alist nil)
+ (font-lock-defaults nil)
+ (font-lock-maximum-size 0)
+ (font-lock-mode-hook nil)
+ (font-lock-auto-fontify nil)
+ (font-lock-mode-enable-list nil)
+ ;; And insert them into the FILE buffer.
+ (file-buffer (let ((TeX-transient-master t))
+ (find-file-noselect file)))
+ ;; But remember original content.
+ original-content
+
+ ;; We search for the header from the master file, if it is
+ ;; not present in the region.
+ (header (if (string-match header-end region)
+ ""
+ (save-excursion
+ (save-restriction
+ (set-buffer master-buffer)
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ ;; NOTE: We use the local value of
+ ;; TeX-header-end from the master file.
+ (if (not (re-search-forward TeX-header-end nil t))
+ ""
+ (re-search-forward "[\r\n]" nil t)
+ (buffer-substring (point-min) (point)))))))))
+
+ ;; We search for the trailer from the master file, if it is
+ ;; not present in the region.
+ (trailer-offset 0)
+ (trailer (if (string-match trailer-start region)
+ ""
+ (save-excursion
+ (save-restriction
+ (set-buffer master-buffer)
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-max))
+ ;; NOTE: We use the local value of
+ ;; TeX-trailer-start from the master file.
+ (if (not (re-search-backward TeX-trailer-start nil t))
+ ""
+ ;;(beginning-of-line 1)
+ (re-search-backward "[\r\n]" nil t)
+ (setq trailer-offset (TeX-current-offset))
+ (buffer-substring (point) (point-max))))))))))
+ ;; file name should be relative to master
+ (setq original (TeX-quote-filename (file-relative-name
+ original (TeX-master-directory)))
+ master-name (TeX-quote-filename master-name))
+ (save-excursion
+ (set-buffer file-buffer)
+ (setq buffer-undo-list t)
+ (setq original-content (buffer-string))
+ (erase-buffer)
+ (when (boundp 'buffer-file-coding-system)
+ (setq buffer-file-coding-system
+ (with-current-buffer master-buffer buffer-file-coding-system)))
+ (insert "\\message{ !name(" master-name ")}"
+ header
+ TeX-region-extra
+ "\n\\message{ !name(" original ") !offset(")
+ (insert (int-to-string (- offset
+ (1+ (TeX-current-offset))))
+ ") }\n"
+ region
+ "\n\\message{ !name(" master-name ") !offset(")
+ (insert (int-to-string (- trailer-offset
+ (1+ (TeX-current-offset))))
+ ") }\n"
+ trailer)
+ (run-hooks 'TeX-region-hook)
+ (if (string-equal (buffer-string) original-content)
+ (set-buffer-modified-p nil)
+ (save-buffer 0)))))
+
+(defun TeX-region-file (&optional extension nondirectory)
+ "Return TeX-region file name with EXTENSION.
+If optional second argument NONDIRECTORY is non-nil, do not include
+the directory."
+ (concat (if nondirectory "" (TeX-master-directory))
+ (cond ((eq extension t)
+ (concat TeX-region "." TeX-default-extension))
+ (extension
+ (concat TeX-region "." extension))
+ (t
+ TeX-region))))
+
+(defcustom TeX-region "_region_"
+ "*Base name of temporary file for `TeX-command-region' and `TeX-command-buffer'."
+ :group 'TeX-command
+ :type 'string)
+
+;;; Parsing
+
+;;; - Global Parser Variables
+
+(defvar TeX-error-point nil
+ "How far we have parsed until now.")
+
+ (make-variable-buffer-local 'TeX-error-point)
+
+(defvar TeX-error-file nil
+ "Stack of files in which errors have occured.")
+
+ (make-variable-buffer-local 'TeX-error-file)
+
+(defvar TeX-error-offset nil
+ "Add this to any line numbers from TeX. Stack like `TeX-error-file'.")
+
+ (make-variable-buffer-local 'TeX-error-offset)
+
+(defun TeX-parse-reset ()
+ "Reset all variables used for parsing TeX output."
+ (setq TeX-error-point (point-min))
+ (setq TeX-error-offset nil)
+ (setq TeX-error-file nil))
+
+;;; - Parsers Hooks
+
+(defun TeX-parse-command (reparse)
+ "We can't parse anything but TeX."
+ (error "I cannot parse %s output, sorry"
+ (if (TeX-active-process)
+ (process-name (TeX-active-process))
+ "this")))
+
+(defun TeX-parse-TeX (reparse)
+ "Find the next error produced by running TeX.
+With \\[universal-argument] prefix, start from the beginning of the errors.
+
+If the file occurs in an included file, the file is loaded (if not
+already in an Emacs buffer) and the cursor is placed at the error."
+ (let ((old-buffer (current-buffer))
+ (default-major-mode major-mode))
+ (with-current-buffer (TeX-active-buffer)
+ (if reparse
+ (TeX-parse-reset))
+ (goto-char TeX-error-point)
+ (TeX-parse-error old-buffer))))
+
+;;; - Parsing (La)TeX
+
+(defvar TeX-translate-location-hook nil
+ "List of functions to be called before showing an error or warning.
+
+You might want to examine and modify the free variables `file',
+`offset', `line', `string', `error', and `context' from this hook.")
+
+(defun TeX-parse-error (old)
+ "Goto next error. Pop to OLD buffer if no more errors are found."
+ (let ((regexp
+ (concat
+ ;; TeX error
+ "^\\(!\\|\\(.*?\\):[0-9]+:\\) \\|"
+ ;; New file
+ "(\\(\"[^\"]*?\"\\|/*\
+\\(?:\\.+[^()\r\n{} \\/]*\\|[^()\r\n{} .\\/]+\
+\\(?: [^()\r\n{} .\\/]+\\)*\\(?:\\.[-0-9a-zA-Z_.]*\\)?\\)\
+\\(?:[\\/]+\\(?:\\.+[^()\r\n{} \\/]*\\|[^()\r\n{} .\\/]+\
+\\(?: [^()\r\n{} .\\/]+\\)*\\(?:\\.[-0-9a-zA-Z_.]*\\)?\\)?\\)*\\)\
+)*\\(?: \\|\r?$\\)\\|"
+ ;; End of file
+ "\\()\\))*\\|"
+ ;; Hook to change line numbers
+ " !\\(?:offset(\\([---0-9]+\\))\\|"
+ ;; Hook to change file name
+ "name(\\([^)]+\\))\\)\\|"
+ ;; LaTeX bad box
+ "^\\(\\(?:Overfull\\|Underfull\\|Tight\\|Loose\\)\
+ \\\\.*?[0-9]+--[0-9]+\\)\\|"
+ ;; LaTeX warning
+ "^\\(LaTeX [A-Za-z]*\\|Package [A-Za-z]+ \\)Warning:.*")))
+ (while
+ (cond
+ ((null
+ (re-search-forward regexp nil t))
+ ;; No more errors.
+ (message "No more errors.")
+ (beep)
+ (TeX-pop-to-buffer old)
+ nil)
+ ;; TeX error
+ ((match-beginning 1)
+ (when (match-beginning 2)
+ (unless TeX-error-file
+ (push nil TeX-error-file)
+ (push nil TeX-error-offset))
+ (unless (car TeX-error-offset)
+ (rplaca TeX-error-file (TeX-match-buffer 2))))
+ (if (looking-at "Preview ")
+ t
+ (TeX-error)
+ nil))
+ ;; LaTeX bad box
+ ((match-beginning 7)
+ (if TeX-debug-bad-boxes
+ (progn
+ (TeX-warning (TeX-match-buffer 7))
+ nil)
+ (re-search-forward "\r?\n\
+\\(?:.\\{79\\}\r?\n\
+\\)*.*\r?$")
+ t))
+ ;; LaTeX warning
+ ((match-beginning 8)
+ (if TeX-debug-warnings
+ (progn
+ (TeX-warning (TeX-match-buffer 8))
+ nil)
+ t))
+
+ ;; New file -- Push on stack
+ ((match-beginning 3)
+ (let ((file (TeX-match-buffer 3))
+ (end (match-end 3)))
+ ;; Strip quotation marks and remove newlines if necessary
+ (when (or (eq (string-to-char file) ?\")
+ (string-match "\n" file))
+ (setq file
+ (mapconcat 'identity (split-string file "[\"\n]+") "")))
+ (push file TeX-error-file)
+ (push nil TeX-error-offset)
+ (goto-char end))
+ t)
+
+ ;; End of file -- Pop from stack
+ ((match-beginning 4)
+ (when (> (length TeX-error-file) 1)
+ (pop TeX-error-file)
+ (pop TeX-error-offset))
+ (goto-char (match-end 4))
+ t)
+
+ ;; Hook to change line numbers
+ ((match-beginning 5)
+ (setq TeX-error-offset
+ (list (string-to-number (TeX-match-buffer 5))))
+ t)
+
+ ;; Hook to change file name
+ ((match-beginning 6)
+ (setq TeX-error-file
+ (list (TeX-match-buffer 6)))
+ t)))))
+
+(defun TeX-error ()
+ "Display an error."
+
+ (let* (;; We need the error message to show the user.
+ (error (progn
+ (re-search-forward "\\(.*\\)")
+ (TeX-match-buffer 1)))
+
+ ;; And the context for the help window.
+ (context-start (point))
+ context-available
+
+ ;; And the line number to position the cursor.
+ (line (cond
+ ;; regular style
+ ((re-search-forward "l\\.\\([0-9]+\\)" nil t)
+ (setq context-available t)
+ (string-to-number (TeX-match-buffer 1)))
+ ;; file:line:error style
+ ((save-excursion
+ (re-search-backward ":\\([0-9]+\\): "
+ (line-beginning-position) t))
+ (string-to-number (TeX-match-buffer 1)))
+ ;; nothing found
+ (t 1)))
+
+ ;; And a string of the context to search for.
+ (string (progn
+ (beginning-of-line)
+ (re-search-forward " \\(\\([^ \t]*$\\)\\|\\($\\)\\)")
+ (TeX-match-buffer 1)))
+
+ ;; And we have now found to the end of the context.
+ (context (if context-available
+ (buffer-substring context-start (progn (forward-line 1)
+ (end-of-line)
+ (point)))
+ ;; There is no real context available, so we
+ ;; simply show the line with the error message.
+ (buffer-substring (1- (line-beginning-position))
+ context-start)))
+ ;; We may use these in another buffer.
+ (offset (or (car TeX-error-offset) 0))
+ (file (car TeX-error-file)))
+
+ ;; Remember where we was.
+ (setq TeX-error-point (point))
+
+ ;; Find the error.
+ (if (null file)
+ (error "Error occured after last TeX file closed"))
+ (let ((runbuf (current-buffer))
+ (master (with-current-buffer
+ TeX-command-buffer
+ (expand-file-name (TeX-master-file))))
+ (command-buffer TeX-command-buffer)
+ error-file-buffer)
+ (run-hooks 'TeX-translate-location-hook)
+ (setq error-file-buffer (find-file file))
+ ;; Set the value of `TeX-command-buffer' in the next file with an
+ ;; error to be displayed to the value it has in the current buffer.
+ (with-current-buffer error-file-buffer
+ (set (make-local-variable 'TeX-command-buffer) command-buffer))
+ (goto-line (+ offset line))
+ (if (not (string= string " "))
+ (search-forward string nil t))
+
+ ;; Explain the error.
+ (cond ((eq TeX-display-help 'expert)
+ (TeX-pop-to-buffer runbuf nil t)
+ (goto-char TeX-error-point)
+ (TeX-pop-to-buffer error-file-buffer nil t))
+ (TeX-display-help
+ (TeX-help-error error context runbuf))
+ (t
+ (message (concat "! " error)))))))
+
+(defun TeX-warning (string)
+ "Display a warning for STRING."
+
+ (let* ((error (concat "** " string))
+
+ ;; bad-box is nil if this is a "LaTeX Warning"
+ (bad-box (string-match "\\\\[vh]box.*[0-9]*--[0-9]*" string))
+ ;; line-string: match 1 is beginning line, match 2 is end line
+ (line-string (if bad-box " \\([0-9]*\\)--\\([0-9]*\\)"
+ "on input line \\([0-9]*\\)\\."))
+ ;; word-string: match 1 is the word
+ (word-string (if bad-box "[][\\W() ---]\\(\\w+\\)[][\\W() ---]*$"
+ "`\\(\\w+\\)'"))
+
+ ;; Get error-line (warning)
+ (line (when (re-search-backward line-string nil t)
+ (string-to-number (TeX-match-buffer 1))))
+ (line-end (if bad-box (string-to-number (TeX-match-buffer 2))
+ line))
+
+ ;; Find the context
+ (context-start (progn (if bad-box (end-of-line)
+ (beginning-of-line))
+ (point)))
+
+ (context (progn
+ (forward-line 1)
+ (end-of-line)
+ (while (equal (current-column) 79)
+ (forward-line 1)
+ (end-of-line))
+ (buffer-substring context-start (point))))
+
+ ;; This is where we want to be.
+ (error-point (point))
+
+ ;; Now find the error word.
+ (string (when (re-search-backward word-string context-start t)
+ (TeX-match-buffer 1)))
+
+ ;; We might use these in another file.
+ (offset (or (car TeX-error-offset) 0))
+ (file (car TeX-error-file)))
+
+ ;; This is where we start next time.
+ (goto-char error-point)
+ (setq TeX-error-point (point))
+
+ ;; Go back to TeX-buffer
+ (let ((runbuf (current-buffer))
+ (master (with-current-buffer
+ TeX-command-buffer
+ (expand-file-name (TeX-master-file))))
+ (command-buffer TeX-command-buffer)
+ error-file-buffer)
+ (run-hooks 'TeX-translate-location-hook)
+ (setq error-file-buffer (find-file file))
+ ;; Set the value of `TeX-command-buffer' in the next file with an
+ ;; error to be displayed to the value it has in the current buffer.
+ (with-current-buffer error-file-buffer
+ (set (make-local-variable 'TeX-command-buffer) command-buffer))
+ ;; Find line and string
+ (when line
+ (goto-line (+ offset line))
+ (beginning-of-line 0)
+ (let ((start (point)))
+ (goto-line (+ offset line-end))
+ (end-of-line)
+ (when string
+ (search-backward string start t)
+ (search-forward string nil t))))
+ ;; Display help
+ (cond ((eq TeX-display-help 'expert)
+ (TeX-pop-to-buffer runbuf nil t)
+ (goto-char TeX-error-point)
+ (TeX-pop-to-buffer error-file-buffer nil t))
+ (TeX-display-help
+ (TeX-help-error error (if bad-box context (concat "\n" context))
+ runbuf))
+ (t
+ (message (concat "! " error)))))))
+
+;;; - Help
+
+(defun TeX-help-error (error output runbuffer)
+ "Print ERROR in context OUTPUT from RUNBUFFER in another window."
+
+ (let ((old-buffer (current-buffer))
+ (log-file (with-current-buffer runbuffer
+ (with-current-buffer TeX-command-buffer
+ (expand-file-name (TeX-active-master "log")))))
+ (TeX-error-pointer 0))
+
+ ;; Find help text entry.
+ (while (not (string-match (car (nth TeX-error-pointer
+ TeX-error-description-list))
+ error))
+ (setq TeX-error-pointer (+ TeX-error-pointer 1)))
+
+ (TeX-pop-to-buffer (get-buffer-create "*TeX Help*") nil t)
+ (erase-buffer)
+ (insert "ERROR: " error
+ "\n\n--- TeX said ---"
+ output
+ "\n--- HELP ---\n"
+ (let ((help (cdr (nth TeX-error-pointer
+ TeX-error-description-list))))
+ (save-excursion
+ (if (and (string= help "No help available")
+ (let* ((log-buffer (find-buffer-visiting log-file)))
+ (if log-buffer
+ (progn
+ (set-buffer log-buffer)
+ (revert-buffer t t))
+ (setq log-buffer
+ (find-file-noselect log-file))
+ (set-buffer log-buffer))
+ (auto-save-mode nil)
+ (setq buffer-read-only t)
+ (goto-line (point-min))
+ (search-forward error nil t 1))
+ (re-search-forward "^l\\." nil t)
+ (re-search-forward "^ [^\n]+$" nil t))
+ (let ((start (1+ (point))))
+ (forward-char 1)
+ (re-search-forward "^$")
+ (concat "From the .log file...\n\n"
+ (buffer-substring start (point))))
+ help))))
+ (goto-char (point-min))
+ (TeX-pop-to-buffer old-buffer nil t)))
+
+;;; Error Messages
+
+(defcustom TeX-error-description-list
+ '(("\\(?:Package Preview Error\\|Preview\\):.*" .
+"The `auctex' option to `preview' should not be applied manually.
+If you see this error message outside of a preview run, either
+you did something too clever, or AUCTeX something too stupid.")
+
+ ("Bad \\\\line or \\\\vector argument.*" .
+"The first argument of a \\line or \\vector command, which specifies the
+slope, is illegal\.")
+
+ ("Bad math environment delimiter.*" .
+"TeX has found either a math-mode-starting command such as \\[ or \\(
+when it is already in math mode, or else a math-mode-ending command
+such as \\) or \\] while in LR or paragraph mode. The problem is caused
+by either unmatched math mode delimiters or unbalanced braces\.")
+
+ ("Bad use of \\\\\\\\.*" .
+"A \\\\ command appears between paragraphs, where it makes no sense. This
+error message occurs when the \\\\ is used in a centering or flushing
+environment or else in the scope of a centering or flushing
+declaration.")
+
+ ("\\\\begin{[^ ]*} ended by \\\\end{[^ ]*}." .
+"LaTeX has found an \\end command that doesn't match the corresponding
+\\begin command. You probably misspelled the environment name in the
+\\end command, have an extra \\begin, or else forgot an \\end.")
+
+ ("Can be used only in preamble." .
+"LaTeX has encountered, after the \\begin{document}, one of the
+following commands that should appear only in the preamble:
+\\documentclass, \\nofiles, \\includeonly, \\makeindex, or
+\\makeglossary. The error is also caused by an extra \\begin{document}
+command.")
+
+ ("Command name [^ ]* already used.*" .
+"You are using \\newcommand, \\newenvironment, \\newlength, \\newsavebox,
+or \\newtheorem to define a command or environment name that is
+already defined, or \\newcounter to define a counter that already
+exists. (Defining an environment named gnu automatically defines the
+command \\gnu.) You'll have to choose a new name or, in the case of
+\\newcommand or \\newenvironment, switch to the \\renew ... command.")
+
+ ("Counter too large." .
+"1. Some object that is numbered with letters, probably an item in a
+enumerated list, has received a number greater than 26. Either you're
+making a very long list or you've been resetting counter values.
+
+2. Footnotes are being ``numbered'' with letters or footnote symbols
+and LaTeX has run out of letters or symbols. This is probably caused
+by too many \\thanks commands.")
+
+ ("Environment [^ ]* undefined." .
+"LaTeX has encountered a \\begin command for a nonexistent environment.
+You probably misspelled the environment name. ")
+
+ ("Float(s) lost." .
+"You put a figure or table environment or a \\marginpar command inside a
+parbox---either one made with a minipage environment or \\parbox
+command, or one constructed by LaTeX in making a footnote, figure,
+etc. This is an outputting error, and the offending environment or
+command may be quite a way back from the point where LaTeX discovered
+the problem. One or more figures, tables, and/or marginal notes have
+been lost, but not necessarily the one that caused the error.")
+
+ ("Illegal character in array arg." .
+"There is an illegal character in the argument of an array or tabular
+environment, or in the second argument of a \\multicolumn command.")
+
+ ("Missing \\\\begin{document}." .
+"LaTeX produced printed output before encountering a \\begin{document}
+command. Either you forgot the \\begin{document} command or there is
+something wrong in the preamble. The problem may be a stray character
+or an error in a declaration---for example, omitting the braces around
+an argument or forgetting the \\ in a command name.")
+
+ ("Missing p-arg in array arg.*" .
+"There is a p that is not followed by an expression in braces in the
+argument of an array or tabular environment, or in the second argument
+of a \\multicolumn command.")
+
+ ("Missing @-exp in array arg." .
+"There is an @ character not followed by an @-expression in the
+argument of an array or tabular environment, or in the second argument
+of a \\multicolumn command.")
+
+ ("No such counter." .
+"You have specified a nonexistent counter in a \\setcounter or
+\\addtocounter command. This is probably caused by a simple typing
+error. However, if the error occurred while a file with the extension
+aux is being read, then you probably used a \\newcounter command
+outside the preamble.")
+
+ ("Not in outer par mode." .
+"You had a figure or table environment or a \\marginpar command in math
+mode or inside a parbox.")
+
+ ("\\\\pushtabs and \\\\poptabs don't match." .
+"LaTeX found a \\poptabs with no matching \\pushtabs, or has come to the
+\\end{tabbing} command with one or more unmatched \\pushtabs commands.")
+
+ ("Something's wrong--perhaps a missing \\\\item." .
+"The most probable cause is an omitted \\item command in a list-making
+environment. It is also caused by forgetting the argument of a
+thebibliography environment.")
+
+ ("Tab overflow." .
+"A \\= command has exceeded the maximum number of tab stops that LaTeX
+permits.")
+
+ ("There's no line here to end." .
+"A \\newline or \\\\ command appears between paragraphs, where it makes no
+sense. If you're trying to ``leave a blank line'', use a \\vspace
+command.")
+
+ ("This may be a LaTeX bug." .
+"LaTeX has become thoroughly confused. This is probably due to a
+previously detected error, but it is possible that you have found an
+error in LaTeX itself. If this is the first error message produced by
+the input file and you can't find anything wrong, save the file and
+contact the person listed in your Local Guide.")
+
+ ("Too deeply nested." .
+"There are too many list-making environments nested within one another.
+How many levels of nesting are permitted may depend upon what computer
+you are using, but at least four levels are provided, which should be
+enough.")
+
+ ("Too many unprocessed floats." .
+"While this error can result from having too many \\marginpar commands
+on a page, a more likely cause is forcing LaTeX to save more figures
+and tables than it has room for. When typesetting its continuous
+scroll, LaTeX saves figures and tables separately and inserts them as
+it cuts off pages. This error occurs when LaTeX finds too many figure
+and/or table environments before it is time to cut off a page, a
+problem that is solved by moving some of the environments farther
+towards the end of the input file. The error can also be caused by a
+``logjam''---a figure or table that cannot be printed causing others
+to pile up behind it, since LaTeX will not print figures or tables out
+of order. The jam can be started by a figure or table that either is
+too large to fit on a page or won't fit where its optional placement
+argument says it must go. This is likely to happen if the argument
+does not contain a p option.")
+
+ ("Undefined tab position." .
+"A \\>, \\+, \\-, or \\< command is trying to go to a nonexistent tab
+position---one not defined by a \\= command.")
+
+ ("\\\\< in mid line." .
+"A \\< command appears in the middle of a line in a tabbing environment.
+This command should come only at the beginning of a line.")
+
+ ("Double subscript." .
+"There are two subscripts in a row in a mathematical
+formula---something like x_{2}_{3}, which makes no sense.")
+
+ ("Double superscript." .
+"There are two superscripts in a row in a mathematical
+formula---something like x^{2}^{3}, which makes no sense.")
+
+ ("Extra alignment tab has been changed to \\\\cr." .
+"There are too many separate items (column entries) in a single row of
+an array or tabular environment. In other words, there were too many &
+'s before the end of the row. You probably forgot the \\\\ at the end of
+the preceding row.")
+
+ ("Extra \\}, or forgotten \\$." .
+"The braces or math mode delimiters don't match properly. You probably
+forgot a {, \\[, \\(, or $.")
+
+ ("Font [^ ]* not loaded: Not enough room left." .
+"The document uses more fonts than TeX has room for. If different parts
+of the document use different fonts, then you can get around the
+problem by processing it in parts.")
+
+ ("I can't find file `.*'." .
+"TeX can't find a file that it needs. If the name of the missing file
+has the extension tex, then it is looking for an input file that you
+specified---either your main file or another file inserted with an
+\\input or \\include command. If the missing file has the extension sty
+, then you have specified a nonexistent document style or style
+option.")
+
+ ("Illegal parameter number in definition of .*" .
+"This is probably caused by a \\newcommand, \\renewcommand,
+\\newenvironment, or \\renewenvironment command in which a # is used
+incorrectly. A # character, except as part of the command name \\#,
+can be used only to indicate an argument parameter, as in #2, which
+denotes the second argument. This error is also caused by nesting one
+of the above four commands inside another, or by putting a parameter
+like #2 in the last argument of a \\newenvironment or \\renewenvironment
+command.")
+
+ ("Illegal unit of measure ([^ ]* inserted)." .
+"If you just got a
+
+ ! Missing number, treated as zero.
+
+error, then this is part of the same problem. If not, it means that
+LaTeX was expecting a length as an argument and found a number
+instead. The most common cause of this error is writing 0 instead of
+something like 0in for a length of zero, in which case typing return
+should result in correct output. However, the error can also be caused
+by omitting a command argument.")
+
+ ("Misplaced alignment tab character \\&." .
+"The special character &, which should be used only to separate items
+in an array or tabular environment, appeared in ordinary text. You
+probably meant to type \\&.")
+
+ ("Missing control sequence inserted." .
+"This is probably caused by a \\newcommand, \\renewcommand, \\newlength,
+or \\newsavebox command whose first argument is not a command name.")
+
+ ("Missing number, treated as zero." .
+"This is usually caused by a LaTeX command expecting but not finding
+either a number or a length as an argument. You may have omitted an
+argument, or a square bracket in the text may have been mistaken for
+the beginning of an optional argument. This error is also caused by
+putting \\protect in front of either a length command or a command such
+as \\value that produces a number.")
+
+ ("Missing [{}] inserted." .
+"TeX has become confused. The position indicated by the error locator
+is probably beyond the point where the incorrect input is.")
+
+ ("Missing \\$ inserted." .
+"TeX probably found a command that can be used only in math mode when
+it wasn't in math mode. Remember that unless stated otherwise, all
+all the commands of Section 3.3 in LaTeX Book (Lamport) can be used
+only in math mode. TeX is not in math mode when it begins processing
+the argument of a box-making command, even if that command is inside a
+math environment. This error also occurs if TeX encounters a blank
+line when it is in math mode.")
+
+ ("Not a letter." .
+"Something appears in the argument of a \\hyphenation command that
+doesn't belong there.")
+
+ ("Paragraph ended before [^ ]* was complete." .
+"A blank line occurred in a command argument that shouldn't contain
+one. You probably forgot the right brace at the end of an argument.")
+
+ ("\\\\[^ ]*font [^ ]* is undefined .*" .
+"These errors occur when an uncommon font is used in math mode---for
+example, if you use a \\sc command in a formula inside a footnote,
+calling for a footnote-sized small caps font. This problem is solved
+by using a \\load command.")
+
+ ("Font .* not found." .
+"You requested a family/series/shape/size combination that is totally
+unknown. There are two cases in which this error can occur:
+ 1) You used the \\size macro to select a size that is not available.
+ 2) If you did not do that, go to your local `wizard' and
+ complain fiercely that the font selection tables are corrupted!")
+
+ ("TeX capacity exceeded, sorry .*" .
+"TeX has just run out of space and aborted its execution. Before you
+panic, remember that the least likely cause of this error is TeX not
+having the capacity to process your document. It was probably an
+error in your input file that caused TeX to run out of room. The
+following discussion explains how to decide whether you've really
+exceeded TeX's capacity and, if so, what to do. If the problem is an
+error in the input, you may have to use the divide and conquer method
+described previously to locate it. LaTeX seldom runs out of space on a
+short input file, so if running it on the last few pages before the
+error indicator's position still produces the error, then there's
+almost certainly something wrong in the input file.
+
+The end of the error indicator tells what kind of space TeX ran out
+of. The more common ones are listed below, with an explanation of
+their probable causes.
+
+buffer size
+===========
+Can be caused by too long a piece of text as the argument
+of a sectioning, \\caption, \\addcontentsline, or \\addtocontents
+command. This error will probably occur when the \\end{document} is
+being processed, but it could happen when a \\tableofcontents,
+\\listoffigures, or \\listoftables command is executed. To solve this
+problem, use a shorter optional argument. Even if you're producing a
+table of contents or a list of figures or tables, such a long entry
+won't help the reader.
+
+exception dictionary
+====================
+You have used \\hyphenation commands to give TeX
+more hyphenation information than it has room for. Remove some of the
+less frequently used words from the \\hyphenation commands and insert
+\\- commands instead.
+
+hash size
+=========
+Your input file defines too many command names and/or uses
+too many cross-ref- erencing labels.
+
+input stack size
+================
+This is probably caused by an error in a command
+definition. For example, the following command makes a circular
+definition, defining \\gnu in terms of itself:
+
+ \\newcommand{\\gnu}{a \\gnu} % This is wrong!
+
+When TeX encounters this \\gnu command, it will keep chasing its tail
+trying to figure out what \\gnu should produce, and eventually run out
+of ``input stack''.
+
+main memory size
+================
+This is one kind of space that TeX can run out of when processing a
+short file. There are three ways you can run TeX out of main memory
+space: (1) defining a lot of very long, complicated commands, (2)
+making an index or glossary and having too many \\index or \\glossary
+commands on a single page, and (3) creating so complicated a page of
+output that TeX can't hold all the information needed to generate it.
+The solution to the first two problems is obvious: define fewer
+commands or use fewer \\index and \\glossary commands. The third problem
+is nastier. It can be caused by large tabbing, tabular, array, and
+picture environments. TeX's space may also be filled up with figures
+and tables waiting for a place to go. To find out if you've really
+exceeded TeX's capacity in this way, put a \\clearpage command in your
+input file right before the place where TeX ran out of room and try
+running it again. If it doesn't run out of room with the \\clearpage
+command there, then you did exceed TeX's capacity. If it still runs
+out of room, then there's probably an error in your file. If TeX is
+really out of room, you must give it some help. Remember that TeX
+processes a complete paragraph before deciding whether to cut the
+page. Inserting a \\newpage command in the middle of the paragraph,
+where TeX should break the page, may save the day by letting TeX write
+the current page before processing the rest of the paragraph. (A
+\\pagebreak command won't help.) If the problem is caused by
+accumulated figures and tables, you can try to prevent them from
+accumulating---either by moving them further towards the end of the
+document or by trying to get them to come out sooner. If you are
+still writing the document, simply add a \\clearpage command and forget
+about the problem until you're ready to produce the final version.
+Changes to the input file are likely to make the problem go away.
+
+pool size
+=========
+You probably used too many cross-ref-erencing \\labels and/or defined
+too many new command names. More precisely, the labels and command
+names that you define have too many characters, so this problem can be
+solved by using shorter names. However, the error can also be caused
+by omitting the right brace that ends the argument of either a counter
+command such as \\setcounter, or a \\newenvironment or \\newtheorem
+command.
+
+save size
+=========
+This occurs when commands, environments, and the scopes of
+declarations are nested too deeply---for example, by having the
+argument of a \\multiput command contain a picture environment that in
+turn has a \\footnotesize declaration whose scope contains a \\multiput
+command containing a ....")
+
+ ("Text line contains an invalid character." .
+"The input contains some strange character that it shouldn't. A mistake
+when creating the file probably caused your text editor to insert this
+character. Exactly what could have happened depends upon what text
+editor you used. If examining the input file doesn't reveal the
+offending character, consult the Local Guide for suggestions.")
+
+ ("Undefined control sequence." .
+"TeX encountered an unknown command name. You probably misspelled the
+name. If this message occurs when a LaTeX command is being processed,
+the command is probably in the wrong place---for example, the error
+can be produced by an \\item command that's not inside a list-making
+environment. The error can also be caused by a missing \\documentclass
+command.")
+
+ ("Use of [^ ]* doesn't match its definition." .
+"It's probably one of the picture-drawing commands, and you have used
+the wrong syntax for specifying an argument. If it's \\@array that
+doesn't match its definition, then there is something wrong in an
+@-expression in the argument of an array or tabular
+environment---perhaps a fragile command that is not \\protect'ed.")
+
+ ("You can't use `macro parameter character \\#' in [^ ]* mode." .
+"The special character # has appeared in ordinary text. You probably
+meant to type \\#.")
+
+ ("Overfull \\\\hbox .*" .
+"Because it couldn't find a good place for a line break, TeX put more
+on this line than it should.")
+
+ ("Overfull \\\\vbox .*" .
+"Because it couldn't find a good place for a page break, TeX put more
+on the page than it should. ")
+
+ ("Underfull \\\\hbox .*" .
+"Check your output for extra vertical space. If you find some, it was
+probably caused by a problem with a \\\\ or \\newline command---for
+example, two \\\\ commands in succession. This warning can also be
+caused by using the sloppypar environment or \\sloppy declaration, or
+by inserting a \\linebreak command.")
+
+ ("Underfull \\\\vbox .*" .
+"TeX could not find a good place to break the page, so it produced a
+page without enough text on it. ")
+
+;; New list items should be placed here
+;;
+;; ("err-regexp" . "context")
+;;
+;; the err-regexp item should match anything
+
+ (".*" . "No help available")) ; end definition
+"A list of the form (\"err-regexp\" . \"context\") used by function
+`TeX-help-error' to display help-text on an error message or warning.
+err-regexp should be a regular expression matching the error message
+given from TeX/LaTeX, and context should be some lines describing that
+error."
+ :group 'TeX-output
+ :type '(repeat (cons :tag "Entry"
+ (regexp :tag "Match")
+ (string :format "Description:\n%v"))))
+
+(provide 'tex-buf)
+
+;;; tex-buf.el ends here
--- /dev/null
+;;; tex-fold.el --- Fold TeX macros.
+
+;; Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+;; Author: Ralf Angeli <angeli@caeruleus.net>
+;; Maintainer: auctex-devel@gnu.org
+;; Created: 2004-07-04
+;; Keywords: tex, wp
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file provides support for hiding and unhiding TeX, LaTeX,
+;; ContTeXt, Texinfo and similar macros and environments inside of
+;; AUCTeX.
+;;
+;; Caveats:
+;;
+;; The display string of content which should display part of itself
+;; is made by copying the text from the buffer together with its text
+;; properties. If fontification has not happened when this is done
+;; (e.g. because of lazy or just-in-time font locking) the intended
+;; fontification will not show up. Maybe this could be improved by
+;; using some sort of "lazy folding" or refreshing the window upon
+;; scrolling. As a workaround fontification of the whole buffer
+;; currently is forced before folding it.
+
+;;; Code:
+
+(when (featurep 'xemacs)
+ (require 'overlay))
+(require 'tex)
+(autoload 'LaTeX-forward-paragraph "latex")
+(autoload 'LaTeX-backward-paragraph "latex")
+(autoload 'LaTeX-find-matching-begin "latex")
+(autoload 'LaTeX-find-matching-end "latex")
+(autoload 'ConTeXt-find-matching-start "context")
+(autoload 'ConTeXt-find-matching-stop "context")
+(autoload 'Texinfo-find-env-start "tex-info")
+(autoload 'Texinfo-find-env-end "tex-info")
+
+(defgroup TeX-fold nil
+ "Fold TeX macros."
+ :group 'AUCTeX)
+
+(defcustom TeX-fold-type-list '(env macro math)
+ "List of item types to consider when folding.
+Valid items are the symbols 'env for environments, 'macro for
+macros, 'math for math macros and 'comment for comments."
+ :type '(set (const :tag "Environments" env)
+ (const :tag "Macros" macro)
+ (const :tag "Math Macros" math)
+ (const :tag "Comments" comment))
+ :group 'TeX-fold)
+
+(defcustom TeX-fold-macro-spec-list
+ `(("[f]" ("footnote" "marginpar"))
+ ("[c]" ("cite"))
+ ("[l]" ("label"))
+ ("[r]" ("ref" "pageref" "eqref"))
+ ("[i]" ("index" "glossary"))
+ ("[1]:||*" ("item"))
+ ("..." ("dots"))
+ ("(C)" ("copyright"))
+ ("(R)" ("textregistered"))
+ ("TM" ("texttrademark"))
+ (1 ("part" "chapter" "section" "subsection" "subsubsection"
+ "paragraph" "subparagraph"
+ "part*" "chapter*" "section*" "subsection*" "subsubsection*"
+ "paragraph*" "subparagraph*"
+ "emph" "textit" "textsl" "textmd" "textrm" "textsf" "texttt"
+ "textbf" "textsc" "textup")))
+ "List of replacement specifiers and macros to fold.
+
+The first element of each item can be a string, an integer or a
+function symbol. The second element is a list of macros two fold
+without the leading backslash.
+
+If the first element is a string, it will be used as a display
+replacement for the whole macro. Numbers in braces, brackets,
+parens or angle brackets will be replaced by the respective macro
+argument. For example \"{1}\" will be replaced by the first
+mandatory argument of the macro. One can also define
+alternatives within the specifier which are used if an argument
+is not found. Alternatives are separated by \"||\". They are
+most useful with optional arguments. As an example, the default
+specifier for \\item is \"[1]:||*\" which means that if there is
+an optional argument, its value is shown followed by a colon. If
+there is no optional argument, only an asterisk is used as the
+display string.
+
+If the first element is an integer, the macro will be replaced by
+the respective macro argument.
+
+If the first element is a function symbol, the function will be
+called with all mandatory arguments of the macro and the result
+of the function call will be used as a replacement for the macro.
+
+Setting this variable does not take effect immediately. Use
+Customize or reset the mode."
+ :type '(repeat (group (choice (string :tag "Display String")
+ (integer :tag "Number of argument" :value 1)
+ (function :tag "Function to execute"))
+ (repeat :tag "Macros" (string))))
+ :group 'TeX-fold)
+
+(defvar TeX-fold-macro-spec-list-internal nil
+ "Internal list of display strings and macros to fold.
+Is updated when the TeX Fold mode is being activated and then
+contains all constructs to fold for the given buffer or mode
+respectively, i.e. contents of both `TeX-fold-macro-spec-list'
+and <mode-prefix>-fold-macro-spec-list.")
+(make-variable-buffer-local 'TeX-fold-macro-spec-list-internal)
+
+(defcustom TeX-fold-env-spec-list
+ '(("[comment]" ("comment")))
+ "List of display strings and environments to fold."
+ :type '(repeat (group (choice (string :tag "Display String")
+ (integer :tag "Number of argument" :value 1))
+ (repeat :tag "Environments" (string))))
+ :group 'TeX-fold)
+
+(defvar TeX-fold-env-spec-list-internal nil
+ "Internal list of display strings and environments to fold.
+Is updated when the TeX Fold mode is being activated and then
+contains all constructs to fold for the given buffer or mode
+respectively, i.e. contents of both `TeX-fold-env-spec-list'
+and <mode-prefix>-fold-env-spec-list.")
+(make-variable-buffer-local 'TeX-fold-env-spec-list-internal)
+
+(defcustom TeX-fold-math-spec-list nil
+ "List of display strings and math macros to fold."
+ :type '(repeat (group (choice (string :tag "Display String")
+ (integer :tag "Number of argument" :value 1))
+ (repeat :tag "Math Macros" (string))))
+ :group 'TeX-fold)
+
+(defvar TeX-fold-math-spec-list-internal nil
+ "Internal list of display strings and math macros to fold.
+Is updated when the TeX Fold mode is being activated and then
+contains all constructs to fold for the given buffer or mode
+respectively, i.e. contents of both `TeX-fold-math-spec-list'
+and <mode-prefix>-fold-math-spec-list.")
+(make-variable-buffer-local 'TeX-fold-math-spec-list-internal)
+
+(defcustom TeX-fold-unspec-macro-display-string "[m]"
+ "Display string for unspecified macros.
+This string will be displayed if a single macro is being hidden
+which is not specified in `TeX-fold-macro-spec-list'."
+ :type '(string)
+ :group 'TeX-fold)
+
+(defcustom TeX-fold-unspec-env-display-string "[env]"
+ "Display string for unspecified environments.
+This string will be displayed if a single environment is being
+hidden which is not specified in `TeX-fold-env-spec-list'."
+ :type '(string)
+ :group 'TeX-fold)
+
+(defcustom TeX-fold-unspec-use-name t
+ "If non-nil use the name of an unspecified item as display string.
+Set it to nil if you want to use the values of the variables
+`TeX-fold-unspec-macro-display-string' or
+`TeX-fold-unspec-env-display-string' respectively as a display
+string for any unspecified macro or environment."
+ :type 'boolean
+ :group 'TeX-fold)
+
+(defcustom TeX-fold-preserve-comments nil
+ "If non-nil do not fold in comments."
+ :type 'boolean
+ :group 'TeX-fold)
+
+(defcustom TeX-fold-unfold-around-mark t
+ "Unfold text around the mark, if active."
+ :type 'boolean
+ :group 'TeX-fold)
+
+(defcustom TeX-fold-help-echo-max-length 70
+ "Maximum length of help echo message for folded overlays.
+Set it to zero in order to disable help echos."
+ :type 'integer
+ :group 'TeX-fold)
+
+(defcustom TeX-fold-force-fontify t
+ "Force the buffer to be fully fontified by folding it."
+ :group 'TeX-fold
+ :type 'boolean)
+
+(defcustom TeX-fold-auto nil
+ "If non-nil, fold macros automatically after `TeX-insert-macro'."
+ :group 'TeX-fold
+ :type 'boolean)
+
+(defface TeX-fold-folded-face
+ '((((class color) (background light))
+ (:foreground "SlateBlue"))
+ (((class color) (background dark))
+ (:foreground "SlateBlue1"))
+ (((class grayscale) (background light))
+ (:foreground "DimGray"))
+ (((class grayscale) (background dark))
+ (:foreground "LightGray"))
+ (t (:slant italic)))
+ "Face for the display string of folded content."
+ :group 'TeX-fold)
+
+(defvar TeX-fold-folded-face 'TeX-fold-folded-face
+ "Face for the display string of folded content.")
+
+(defface TeX-fold-unfolded-face
+ '((((class color) (background light))
+ (:background "#f2f0fd"))
+ (((class color) (background dark))
+ (:background "#38405d"))
+ (((class grayscale) (background light))
+ (:background "LightGray"))
+ (((class grayscale) (background dark))
+ (:background "DimGray"))
+ (t (:inverse-video t)))
+ "Face for folded content when it is temporarily opened."
+ :group 'TeX-fold)
+
+(defvar TeX-fold-unfolded-face 'TeX-fold-unfolded-face
+ "Face for folded content when it is temporarily opened.")
+
+(defvar TeX-fold-ellipsis "..."
+ "String used as display string for overlays instead of a zero-length string.")
+
+(defvar TeX-fold-open-spots nil)
+(make-variable-buffer-local 'TeX-fold-open-spots)
+
+(defcustom TeX-fold-command-prefix "\C-c\C-o"
+ "Prefix key to use for commands in TeX Fold mode.
+The value of this variable is checked as part of loading TeX Fold mode.
+After that, changing the prefix key requires manipulating keymaps."
+ :type 'string
+ :group 'TeX-fold)
+
+(defvar TeX-fold-keymap
+ (let ((map (make-sparse-keymap)))
+ (define-key map "\C-o" 'TeX-fold-dwim)
+ (define-key map "\C-b" 'TeX-fold-buffer)
+ (define-key map "\C-r" 'TeX-fold-region)
+ (define-key map "\C-p" 'TeX-fold-paragraph)
+ (define-key map "\C-m" 'TeX-fold-macro)
+ (define-key map "\C-e" 'TeX-fold-env)
+ (define-key map "\C-c" 'TeX-fold-comment)
+ (define-key map "b" 'TeX-fold-clearout-buffer)
+ (define-key map "r" 'TeX-fold-clearout-region)
+ (define-key map "p" 'TeX-fold-clearout-paragraph)
+ (define-key map "i" 'TeX-fold-clearout-item)
+ map))
+
+
+;;; Folding
+
+(defun TeX-fold-dwim ()
+ "Hide or show items according to the current context.
+If there is folded content, unfold it. If there is a marked
+region, fold all configured content in this region. If there is
+no folded content but a macro or environment, fold it."
+ (interactive)
+ (cond ((TeX-fold-clearout-item))
+ ((TeX-active-mark) (TeX-fold-region (mark) (point)))
+ ((TeX-fold-item 'macro))
+ ((TeX-fold-item 'math))
+ ((TeX-fold-item 'env))
+ ((TeX-fold-comment))))
+
+(defun TeX-fold-buffer ()
+ "Hide all configured macros and environments in the current buffer.
+The relevant macros are specified in the variable `TeX-fold-macro-spec-list'
+and `TeX-fold-math-spec-list', and environments in `TeX-fold-env-spec-list'."
+ (interactive)
+ (TeX-fold-clearout-region (point-min) (point-max))
+ (when (and TeX-fold-force-fontify
+ (boundp 'jit-lock-mode)
+ jit-lock-mode
+ (fboundp 'jit-lock-fontify-now))
+ ;; We force fontification here only because it should rarely be
+ ;; needed for the other folding commands.
+ (jit-lock-fontify-now))
+ (TeX-fold-region (point-min) (point-max)))
+
+(defun TeX-fold-paragraph ()
+ "Hide all configured macros and environments in the current paragraph.
+The relevant macros are specified in the variable `TeX-fold-macro-spec-list'
+and `TeX-fold-math-spec-list', and environments in `TeX-fold-env-spec-list'."
+ (interactive)
+ (save-excursion
+ (let ((end (progn (LaTeX-forward-paragraph) (point)))
+ (start (progn (LaTeX-backward-paragraph) (point))))
+ (TeX-fold-clearout-region start end)
+ (TeX-fold-region start end))))
+
+(defun TeX-fold-region (start end)
+ "Fold all items in region from START to END."
+ (interactive "r")
+ (when (and (memq 'env TeX-fold-type-list)
+ (not (eq major-mode 'plain-tex-mode)))
+ (TeX-fold-region-macro-or-env start end 'env))
+ (when (memq 'macro TeX-fold-type-list)
+ (TeX-fold-region-macro-or-env start end 'macro))
+ (when (memq 'math TeX-fold-type-list)
+ (TeX-fold-region-macro-or-env start end 'math))
+ (when (memq 'comment TeX-fold-type-list)
+ (TeX-fold-region-comment start end)))
+
+(defun TeX-fold-region-macro-or-env (start end type)
+ "Fold all items of type TYPE in region from START to END.
+TYPE can be one of the symbols 'env for environments, 'macro
+for macros and 'math for math macros."
+ (save-excursion
+ (let (fold-list item-list regexp)
+ (dolist (item (cond ((eq type 'env) TeX-fold-env-spec-list-internal)
+ ((eq type 'math) TeX-fold-math-spec-list-internal)
+ (t TeX-fold-macro-spec-list-internal)))
+ (dolist (i (cadr item))
+ (add-to-list 'fold-list (list i (car item)))
+ (add-to-list 'item-list i)))
+ (when item-list
+ (setq regexp (cond ((and (eq type 'env)
+ (eq major-mode 'context-mode))
+ (concat (regexp-quote TeX-esc)
+ "start" (regexp-opt item-list t)))
+ ((and (eq type 'env)
+ (eq major-mode 'texinfo-mode))
+ (concat (regexp-quote TeX-esc)
+ (regexp-opt item-list t)))
+ ((eq type 'env)
+ (concat (regexp-quote TeX-esc)
+ "begin[ \t]*{"
+ (regexp-opt item-list t) "}"))
+ (t
+ (concat (regexp-quote TeX-esc)
+ (regexp-opt item-list t)))))
+ (save-restriction
+ (narrow-to-region start end)
+ ;; Start from the bottom so that it is easier to prioritize
+ ;; nested macros.
+ (goto-char (point-max))
+ (let ((case-fold-search nil)
+ item-name)
+ (while (re-search-backward regexp nil t)
+ (setq item-name (match-string 1))
+ (unless (or (and TeX-fold-preserve-comments
+ (TeX-in-commented-line))
+ ;; Make sure no partially matched macros are
+ ;; folded. For macros consisting of letters
+ ;; this means there should be none of the
+ ;; characters [A-Za-z@*] after the matched
+ ;; string. Single-char non-letter macros like
+ ;; \, don't have this requirement.
+ (and (memq type '(macro math))
+ (save-match-data
+ (string-match "[A-Za-z]" item-name))
+ (save-match-data
+ (string-match "[A-Za-z@*]"
+ (string (char-after
+ (match-end 0)))))))
+ (let* ((item-start (match-beginning 0))
+ (display-string-spec (cadr (assoc item-name
+ fold-list)))
+ (item-end (TeX-fold-item-end item-start type))
+ (ov (TeX-fold-make-overlay item-start item-end type
+ display-string-spec)))
+ (TeX-fold-hide-item ov))))))))))
+
+(defun TeX-fold-region-comment (start end)
+ "Fold all comments in region from START to END."
+ (save-excursion
+ (goto-char start)
+ (let (beg)
+ (while (setq beg (TeX-search-forward-comment-start end))
+ (goto-char beg)
+ ;; Determine the start of the region to be folded just behind
+ ;; the comment starter.
+ (looking-at TeX-comment-start-regexp)
+ (setq beg (match-end 0))
+ ;; Search for the end of the comment.
+ (while (TeX-comment-forward))
+ (end-of-line 0)
+ ;; Hide the whole region.
+ (TeX-fold-hide-item (TeX-fold-make-overlay beg (point) 'comment
+ TeX-fold-ellipsis))))))
+
+(defun TeX-fold-macro ()
+ "Hide the macro on which point currently is located."
+ (interactive)
+ (unless (TeX-fold-item 'macro)
+ (message "No macro found")))
+
+(defun TeX-fold-math ()
+ "Hide the math macro on which point currently is located."
+ (interactive)
+ (unless (TeX-fold-item 'math)
+ (message "No macro found")))
+
+(defun TeX-fold-env ()
+ "Hide the environment on which point currently is located."
+ (interactive)
+ (unless (TeX-fold-item 'env)
+ (message "No environment found")))
+
+(defun TeX-fold-comment ()
+ "Hide the comment on which point currently is located."
+ (interactive)
+ (unless (TeX-fold-comment-do)
+ (message "No comment found")))
+
+(defun TeX-fold-item (type)
+ "Hide the item on which point currently is located.
+TYPE specifies the type of item and can be one of the symbols
+'env for environments, 'macro for macros or 'math for math
+macros.
+Return non-nil if an item was found and folded, nil otherwise."
+ (if (and (eq type 'env)
+ (eq major-mode 'plain-tex-mode))
+ (message
+ "Folding of environments is not supported in current mode")
+ (let ((item-start (cond ((and (eq type 'env)
+ (eq major-mode 'context-mode))
+ (save-excursion
+ (ConTeXt-find-matching-start) (point)))
+ ((and (eq type 'env)
+ (eq major-mode 'texinfo-mode))
+ (save-excursion
+ (Texinfo-find-env-start) (point)))
+ ((eq type 'env)
+ (condition-case nil
+ (save-excursion
+ (LaTeX-find-matching-begin) (point))
+ (error nil)))
+ (t
+ (TeX-find-macro-start)))))
+ (when item-start
+ (let* ((item-name (save-excursion
+ (goto-char item-start)
+ (looking-at
+ (cond ((and (eq type 'env)
+ (eq major-mode 'context-mode))
+ (concat (regexp-quote TeX-esc)
+ "start\\([A-Za-z]+\\)"))
+ ((and (eq type 'env)
+ (eq major-mode 'texinfo-mode))
+ (concat (regexp-quote TeX-esc)
+ "\\([A-Za-z]+\\)"))
+ ((eq type 'env)
+ (concat (regexp-quote TeX-esc)
+ "begin[ \t]*{"
+ "\\([A-Za-z]+\\)}"))
+ (t
+ (concat (regexp-quote TeX-esc)
+ "\\([A-Za-z@*]+\\)"))))
+ (if (fboundp 'match-string-no-properties)
+ (match-string-no-properties 1)
+ (match-string 1))))
+ (fold-list (cond ((eq type 'env) TeX-fold-env-spec-list-internal)
+ ((eq type 'math)
+ TeX-fold-math-spec-list-internal)
+ (t TeX-fold-macro-spec-list-internal)))
+ fold-item
+ (display-string-spec
+ (or (catch 'found
+ (while fold-list
+ (setq fold-item (car fold-list))
+ (setq fold-list (cdr fold-list))
+ (when (member item-name (cadr fold-item))
+ (throw 'found (car fold-item)))))
+ ;; Item is not specified.
+ (if TeX-fold-unspec-use-name
+ (concat "[" item-name "]")
+ (if (eq type 'env)
+ TeX-fold-unspec-env-display-string
+ TeX-fold-unspec-macro-display-string))))
+ (item-end (TeX-fold-item-end item-start type))
+ (ov (TeX-fold-make-overlay item-start item-end type
+ display-string-spec)))
+ (TeX-fold-hide-item ov))))))
+
+(defun TeX-fold-comment-do ()
+ "Hide the comment on which point currently is located.
+This is the function doing the work for `TeX-fold-comment'. It
+is an internal function communicating with return values rather
+than with messages for the user.
+Return non-nil if a comment was found and folded, nil otherwise."
+ (if (and (not (TeX-in-comment)) (not (TeX-in-line-comment)))
+ nil
+ (let (beg)
+ (save-excursion
+ (while (progn
+ (beginning-of-line 0)
+ (and (TeX-in-line-comment)
+ (not (bobp)))))
+ (goto-char (TeX-search-forward-comment-start (line-end-position 2)))
+ (looking-at TeX-comment-start-regexp)
+ (setq beg (match-end 0))
+ (while (TeX-comment-forward))
+ (end-of-line 0)
+ (when (> (point) beg)
+ (TeX-fold-hide-item (TeX-fold-make-overlay beg (point) 'comment
+ TeX-fold-ellipsis)))))))
+
+
+;;; Utilities
+
+(defun TeX-fold-make-overlay (ov-start ov-end type display-string-spec)
+ "Make a TeX-fold overlay extending from OV-START to OV-END.
+TYPE is a symbol which is used to describe the content to hide
+and may be 'macro for macros, 'math for math macro and 'env for
+environments.
+DISPLAY-STRING-SPEC is the original specification of the display
+string in the variables `TeX-fold-macro-spec-list' or
+`TeX-fold-env-spec-list' and may be a string or an integer."
+ ;; Calculate priority before the overlay is instantiated. We don't
+ ;; want `TeX-overlay-prioritize' to pick up a non-prioritized one.
+ (let ((priority (TeX-overlay-prioritize ov-start ov-end))
+ (ov (make-overlay ov-start ov-end (current-buffer) t nil)))
+ (overlay-put ov 'category 'TeX-fold)
+ (overlay-put ov 'priority priority)
+ (overlay-put ov 'evaporate t)
+ (overlay-put ov 'TeX-fold-type type)
+ (overlay-put ov 'TeX-fold-display-string-spec display-string-spec)
+ ov))
+
+(defun TeX-fold-item-end (start type)
+ "Return the end of an item of type TYPE starting at START.
+TYPE can be either 'env for environments, 'macro for macros or
+'math for math macros."
+ (save-excursion
+ (cond ((and (eq type 'env)
+ (eq major-mode 'context-mode))
+ (goto-char start)
+ (ConTeXt-find-matching-stop)
+ (point))
+ ((and (eq type 'env)
+ (eq major-mode 'texinfo-mode))
+ (goto-char (1+ start))
+ (Texinfo-find-env-end)
+ (point))
+ ((eq type 'env)
+ (goto-char (1+ start))
+ (LaTeX-find-matching-end)
+ (point))
+ (t
+ (goto-char start)
+ (TeX-find-macro-end)))))
+
+(defun TeX-fold-overfull-p (ov-start ov-end display-string)
+ "Return t if an overfull line will result after adding an overlay.
+The overlay extends from OV-START to OV-END and will display the
+string DISPLAY-STRING."
+ (and (not (featurep 'xemacs)) ; Linebreaks in glyphs don't
+ ; work in XEmacs anyway.
+ (save-excursion
+ (goto-char ov-end)
+ (search-backward "\n" ov-start t))
+ (not (string-match "\n" display-string))
+ (> (+ (- ov-start
+ (save-excursion
+ (goto-char ov-start)
+ (line-beginning-position)))
+ (length display-string)
+ (- (save-excursion
+ (goto-char ov-end)
+ (line-end-position))
+ ov-end))
+ (current-fill-column))))
+
+(defun TeX-fold-macro-nth-arg (n macro-start &optional macro-end delims)
+ "Return a property list of the argument number N of a macro.
+The start of the macro to examine is given by MACRO-START, its
+end optionally by MACRO-END. With DELIMS the type of delimiters
+can be specified as a cons cell containing the opening char as
+the car and the closing char as the cdr. The chars have to have
+opening and closing syntax as defined in
+`TeX-search-syntax-table'.
+
+The first item in the returned list is the string specified in
+the argument, the second item may be a face if the argument
+string was fontified. In Emacs the string holds text properties
+as well, so the second item is always nil. In XEmacs the string
+does not enclose any faces, so these are given in the second item
+of the resulting list."
+ (save-excursion
+ (let* ((macro-end (or macro-end
+ (save-excursion (goto-char macro-start)
+ (TeX-find-macro-end))))
+ (open-char (if delims (car delims) ?{))
+ (open-string (char-to-string open-char))
+ (close-char (if delims (cdr delims) ?}))
+ (close-string (char-to-string close-char))
+ content-start content-end)
+ (goto-char macro-start)
+ (if (condition-case nil
+ (progn
+ (while (> n 0)
+ (skip-chars-forward (concat "^" open-string) macro-end)
+ (when (= (point) macro-end)
+ (error nil))
+ (setq content-start (progn
+ (skip-chars-forward
+ (concat open-string " \t"))
+ (point)))
+ (goto-char
+ (if delims
+ (with-syntax-table
+ (TeX-search-syntax-table open-char close-char)
+ (scan-lists (point) 1 1))
+ (TeX-find-closing-brace)))
+ (setq content-end (save-excursion
+ (backward-char)
+ (skip-chars-backward " \t")
+ (point)))
+ (setq n (1- n)))
+ t)
+ (error nil))
+ (list (TeX-fold-buffer-substring content-start content-end)
+ (when (and (featurep 'xemacs)
+ (extent-at content-start))
+ ;; A glyph in XEmacs does not seem to be able to hold more
+ ;; than one face, so we just use the first one we get.
+ (car (extent-property (extent-at content-start) 'face))))
+ nil))))
+
+(defun TeX-fold-buffer-substring (start end)
+ "Return the contents of buffer from START to END as a string.
+Like `buffer-substring' but copy overlay display strings as well."
+ ;; Swap values of `start' and `end' if necessary.
+ (when (> start end) (let ((tmp start)) (setq start end end tmp)))
+ (let ((overlays (overlays-in start end))
+ result)
+ ;; Get rid of overlays not under our control or not completely
+ ;; inside the specified region.
+ (dolist (ov overlays)
+ (when (or (not (eq (overlay-get ov 'category) 'TeX-fold))
+ (< (overlay-start ov) start)
+ (> (overlay-end ov) end))
+ (setq overlays (remove ov overlays))))
+ (if (null overlays)
+ (buffer-substring start end)
+ ;; Sort list according to ascending starts.
+ (setq overlays (sort (copy-sequence overlays)
+ (lambda (a b)
+ (< (overlay-start a) (overlay-start b)))))
+ ;; Get the string from the start of the region up to the first overlay.
+ (setq result (buffer-substring start (overlay-start (car overlays))))
+ (let (ov)
+ (while overlays
+ (setq ov (car overlays)
+ overlays (cdr overlays))
+ ;; Add the display string of the overlay.
+ (setq result (concat result (overlay-get ov 'display)))
+ ;; Remove overlays contained in the current one.
+ (dolist (elt overlays)
+ (when (< (overlay-start elt) (overlay-end ov))
+ (setq overlays (remove elt overlays))))
+ ;; Add the string from the end of the current overlay up to
+ ;; the next overlay or the end of the specified region.
+ (setq result (concat result (buffer-substring (overlay-end ov)
+ (if overlays
+ (overlay-start
+ (car overlays))
+ end))))))
+ result)))
+
+(defun TeX-fold-make-help-echo (start end)
+ "Return a string to be used as the help echo of folded overlays.
+The text between START and END will be used for this but cropped
+to the length defined by `TeX-fold-help-echo-max-length'. Line
+breaks will be replaced by spaces."
+ (let* ((spill (+ start TeX-fold-help-echo-max-length))
+ (lines (split-string (buffer-substring start (min end spill)) "\n"))
+ (result (pop lines)))
+ (dolist (line lines)
+ ;; Strip leading whitespace
+ (when (string-match "^[ \t]+" line)
+ (setq line (replace-match "" nil nil line)))
+ ;; Strip trailing whitespace
+ (when (string-match "[ \t]+$" line)
+ (setq line (replace-match "" nil nil line)))
+ (setq result (concat result " " line)))
+ (when (> end spill) (setq result (concat result "...")))
+ result))
+
+(defun TeX-fold-update-at-point ()
+ "Update all TeX-fold overlays at point displaying computed content."
+ (let (overlays)
+ ;; Get all overlays at point under our control.
+ (dolist (ov (overlays-at (point)))
+ (when (and (eq (overlay-get ov 'category) 'TeX-fold)
+ (numberp (overlay-get ov 'TeX-fold-display-string-spec)))
+ (add-to-list 'overlays ov)))
+ (when overlays
+ ;; Sort list according to descending starts.
+ (setq overlays (sort (copy-sequence overlays)
+ (lambda (a b)
+ (> (overlay-start a) (overlay-start b)))))
+ (dolist (ov overlays)
+ (TeX-fold-hide-item ov)))))
+
+
+;;; Removal
+
+(defun TeX-fold-clearout-buffer ()
+ "Permanently show all macros in the buffer."
+ (interactive)
+ (TeX-fold-clearout-region (point-min) (point-max)))
+
+(defun TeX-fold-clearout-paragraph ()
+ "Permanently show all macros in the paragraph point is located in."
+ (interactive)
+ (save-excursion
+ (let ((end (progn (LaTeX-forward-paragraph) (point)))
+ (start (progn (LaTeX-backward-paragraph) (point))))
+ (TeX-fold-clearout-region start end))))
+
+(defun TeX-fold-clearout-region (start end)
+ "Permanently show all macros in region starting at START and ending at END."
+ (interactive "r")
+ (let ((overlays (overlays-in start end)))
+ (TeX-fold-remove-overlays overlays)))
+
+(defun TeX-fold-clearout-item ()
+ "Permanently show the macro on which point currently is located."
+ (interactive)
+ (let ((overlays (overlays-at (point))))
+ (TeX-fold-remove-overlays overlays)))
+
+(defun TeX-fold-remove-overlays (overlays)
+ "Remove all overlays set by TeX-fold in OVERLAYS.
+Return non-nil if a removal happened, nil otherwise."
+ (let (found)
+ (while overlays
+ (when (eq (overlay-get (car overlays) 'category) 'TeX-fold)
+ (delete-overlay (car overlays))
+ (setq found t))
+ (setq overlays (cdr overlays)))
+ found))
+
+
+;;; Toggling
+
+(defun TeX-fold-expand-spec (spec ov-start ov-end)
+ "Expand instances of {<num>}, [<num>], <<num>>, and (<num>).
+Replace them with the respective macro argument."
+ (let ((spec-list (split-string spec "||"))
+ (delims '((?{ . ?}) (?[ . ?]) (?< . ?>) (?\( . ?\))))
+ match-end success)
+ (catch 'success
+ ;; Iterate over alternatives.
+ (dolist (elt spec-list)
+ (setq spec elt)
+ ;; Find and expand every placeholder.
+ (while (and (string-match "\\([[{<]\\)\\([1-9]\\)\\([]}>]\\)" elt
+ match-end)
+ ;; Does the closing delim fit to the opening one?
+ (string-equal
+ (match-string 3 elt)
+ (char-to-string
+ (cdr (assq (string-to-char (match-string 1 elt))
+ delims)))))
+ (setq match-end (match-beginning 0))
+ (let ((arg (car (save-match-data
+ ;; Get the argument.
+ (TeX-fold-macro-nth-arg
+ (string-to-number (match-string 2 elt))
+ ov-start ov-end
+ (assoc (string-to-char (match-string 1 elt))
+ delims))))))
+ (when arg (setq success t))
+ ;; Replace the placeholder in the string.
+ (setq elt (replace-match (or arg TeX-fold-ellipsis) nil t elt)
+ spec elt)))
+ (when success (throw 'success nil))))
+ spec))
+
+(defun TeX-fold-hide-item (ov)
+ "Hide a single macro or environment.
+That means, put respective properties onto overlay OV."
+ (let* ((ov-start (overlay-start ov))
+ (ov-end (overlay-end ov))
+ (spec (overlay-get ov 'TeX-fold-display-string-spec))
+ (computed (cond
+ ((stringp spec)
+ (TeX-fold-expand-spec spec ov-start ov-end))
+ ((functionp spec)
+ (let (arg arg-list
+ (n 1))
+ (while (setq arg (TeX-fold-macro-nth-arg
+ n ov-start ov-end))
+ (add-to-list 'arg-list (car arg) t)
+ (setq n (1+ n)))
+ (or (condition-case nil
+ (apply spec arg-list)
+ (error nil))
+ "[Error: No content or function found]")))
+ (t (or (TeX-fold-macro-nth-arg spec ov-start ov-end)
+ "[Error: No content found]"))))
+ (display-string (if (listp computed) (car computed) computed))
+ (face (when (listp computed) (cadr computed))))
+ ;; Cater for zero-length display strings.
+ (when (string= display-string "") (setq display-string TeX-fold-ellipsis))
+ ;; Add a linebreak to the display string and adjust the overlay end
+ ;; in case of an overfull line.
+ (when (TeX-fold-overfull-p ov-start ov-end display-string)
+ (setq display-string (concat display-string "\n"))
+ (move-overlay ov ov-start (save-excursion
+ (goto-char ov-end)
+ (skip-chars-forward " \t")
+ (point))))
+ (overlay-put ov 'mouse-face 'highlight)
+ (overlay-put ov 'display display-string)
+ (if (featurep 'xemacs)
+ (let ((glyph (make-glyph (if (listp display-string)
+ (car display-string)
+ display-string))))
+ (overlay-put ov 'invisible t)
+ (when font-lock-mode
+ (if face
+ (set-glyph-property glyph 'face face)
+ (set-glyph-property glyph 'face TeX-fold-folded-face)))
+ (set-extent-property ov 'end-glyph glyph))
+ (when font-lock-mode
+ (overlay-put ov 'face TeX-fold-folded-face))
+ (unless (zerop TeX-fold-help-echo-max-length)
+ (overlay-put ov 'help-echo (TeX-fold-make-help-echo
+ (overlay-start ov) (overlay-end ov)))))))
+
+(defun TeX-fold-show-item (ov)
+ "Show a single LaTeX macro or environment.
+Remove the respective properties from the overlay OV."
+ (overlay-put ov 'mouse-face nil)
+ (if (featurep 'xemacs)
+ (progn
+ (set-extent-property ov 'end-glyph nil)
+ (overlay-put ov 'invisible nil))
+ (overlay-put ov 'display nil)
+ (overlay-put ov 'help-echo nil)
+ (when font-lock-mode
+ (overlay-put ov 'face TeX-fold-unfolded-face))))
+
+;; Copy and adaption of `reveal-post-command' from reveal.el in GNU
+;; Emacs on 2004-07-04.
+(defun TeX-fold-post-command ()
+ ;; `with-local-quit' is not supported in XEmacs.
+ (condition-case nil
+ (let ((inhibit-quit nil))
+ (condition-case err
+ (let* ((spots (TeX-fold-partition-list
+ (lambda (x)
+ ;; We refresh any spot in the current
+ ;; window as well as any spots associated
+ ;; with a dead window or a window which
+ ;; does not show this buffer any more.
+ (or (eq (car x) (selected-window))
+ (not (window-live-p (car x)))
+ (not (eq (window-buffer (car x))
+ (current-buffer)))))
+ TeX-fold-open-spots))
+ (old-ols (mapcar 'cdr (car spots))))
+ (setq TeX-fold-open-spots (cdr spots))
+ (when (or (and (boundp 'disable-point-adjustment)
+ disable-point-adjustment)
+ (and (boundp 'global-disable-point-adjustment)
+ global-disable-point-adjustment)
+ ;; See preview.el on how to make this configurable.
+ (memq this-command (list (key-binding [left])
+ (key-binding [right])
+ 'mouse-set-point)))
+ ;; Open new overlays.
+ (dolist (ol (nconc (when (and TeX-fold-unfold-around-mark
+ (boundp 'mark-active)
+ mark-active)
+ (overlays-at (mark)))
+ (overlays-at (point))))
+ (when (eq (overlay-get ol 'category) 'TeX-fold)
+ (push (cons (selected-window) ol) TeX-fold-open-spots)
+ (setq old-ols (delq ol old-ols))
+ (TeX-fold-show-item ol))))
+ ;; Close old overlays.
+ (dolist (ol old-ols)
+ (when (and (eq (current-buffer) (overlay-buffer ol))
+ (not (rassq ol TeX-fold-open-spots))
+ (or (not (featurep 'xemacs))
+ (and (featurep 'xemacs)
+ (not (extent-detached-p ol)))))
+ (if (and (>= (point) (overlay-start ol))
+ (<= (point) (overlay-end ol)))
+ ;; Still near the overlay: keep it open.
+ (push (cons (selected-window) ol) TeX-fold-open-spots)
+ ;; Really close it.
+ (TeX-fold-hide-item ol)))))
+ (error (message "TeX-fold: %s" err))))
+ (quit (setq quit-flag t))))
+
+
+;;; Misc
+
+;; Copy and adaption of `cvs-partition' from pcvs-util.el in GNU Emacs
+;; on 2004-07-05 to make tex-fold.el mainly self-contained.
+(defun TeX-fold-partition-list (p l)
+ "Partition a list L into two lists based on predicate P.
+The function returns a `cons' cell where the `car' contains
+elements of L for which P is true while the `cdr' contains
+the other elements. The ordering among elements is maintained."
+ (let (car cdr)
+ (dolist (x l)
+ (if (funcall p x) (push x car) (push x cdr)))
+ (cons (nreverse car) (nreverse cdr))))
+
+
+;;; The mode
+
+;; This autoload cookie had to be changed because of XEmacs. This is
+;; very dissatisfactory, because we now don't have the full doc string
+;; available to tell people what to expect when using this mode before
+;; loading it.
+
+;;;###autoload (autoload 'TeX-fold-mode "tex-fold" "Minor mode for hiding and revealing macros and environments." t)
+(define-minor-mode TeX-fold-mode
+ "Minor mode for hiding and revealing macros and environments.
+
+Called interactively, with no prefix argument, toggle the mode.
+With universal prefix ARG (or if ARG is nil) turn mode on.
+With zero or negative ARG turn mode off."
+ nil nil (list (cons TeX-fold-command-prefix TeX-fold-keymap))
+ (if TeX-fold-mode
+ (progn
+ (set (make-local-variable 'search-invisible) t)
+ (add-hook 'post-command-hook 'TeX-fold-post-command nil t)
+ (add-hook 'LaTeX-fill-newline-hook 'TeX-fold-update-at-point nil t)
+ (add-hook 'TeX-after-insert-macro-hook
+ (lambda ()
+ (when (and TeX-fold-mode TeX-fold-auto)
+ (save-excursion
+ (backward-char)
+ (or (TeX-fold-item 'macro)
+ (TeX-fold-item 'math)
+ (TeX-fold-item 'env))))))
+ ;; Update the `TeX-fold-*-spec-list-internal' variables.
+ (dolist (elt '("macro" "env" "math"))
+ (set (intern (format "TeX-fold-%s-spec-list-internal" elt))
+ ;; Append the value of `TeX-fold-*-spec-list' to the
+ ;; mode-specific `<mode-prefix>-fold-*-spec-list' variable.
+ (append (symbol-value (intern (format "TeX-fold-%s-spec-list"
+ elt)))
+ (let ((symbol (intern (format "%s-fold-%s-spec-list"
+ (TeX-mode-prefix) elt))))
+ (when (boundp symbol)
+ (symbol-value symbol)))))))
+ (kill-local-variable 'search-invisible)
+ (remove-hook 'post-command-hook 'TeX-fold-post-command t)
+ (remove-hook 'LaTeX-fill-newline-hook 'TeX-fold-update-at-point t)
+ (TeX-fold-clearout-buffer))
+ (TeX-set-mode-name))
+
+;;;###autoload
+(defalias 'tex-fold-mode 'TeX-fold-mode)
+
+(provide 'tex-fold)
+
+;;; tex-fold.el ends here
--- /dev/null
+;;; tex-font.el --- Font-Lock support stolen from Emacs 21.
+;;
+;; Copyright (C) 1985, 86, 89, 92, 94, 95, 96, 97, 98, 1999
+;; Free Software Foundation, Inc.
+
+;; Maintainer: auctex-devel@gnu.org
+;; Keywords: tex, faces
+
+;; This file is part of AUC TeX.
+
+;; AUC TeX 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, or (at your option)
+;; any later version.
+
+;; AUC TeX 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 AUC TeX; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Comments:
+
+;; Please keep this file in sync with GNU Emacs 21.
+
+;;; Code:
+
+(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" "newenvironment"
+ "newtheorem")
+ 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))
+ ;; Miscellany.
+ (slash "\\\\")
+ (opt " *\\(\\[[^]]*\\] *\\)*")
+ ;; This would allow highlighting \newcommand\CMD but requires
+ ;; adapting subgroup numbers below.
+ ;; (arg "\\(?:{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)\\|\\\\[a-z*]+\\)"))
+ (arg "{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)"))
+ (list
+ ;; Heading args.
+ (list (concat slash headings "\\*?" opt arg)
+ ;; If ARG ends up matching too much (if the {} don't match, f.ex)
+ ;; 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)
+ (list (concat slash "\\(re\\)?newcommand\\** *\\(\\\\[A-Za-z@]+\\)")
+ 2 'font-lock-function-name-face 'keep)
+ ;; Variable args.
+ (list (concat slash variables " *" arg) 2 'font-lock-variable-name-face)
+ ;; Include args.
+ (list (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.")
+
+(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))
+ (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"
+ ;; These are text, rather than citations.
+ ;; "caption" "footnote" "footnotemark" "footnotetext"
+ )
+ t))
+ ;;
+ ;; Names of commands that should be fontified.
+ (specials (regexp-opt
+ '("\\" "\\*" ;; "-"
+ "linebreak" "nolinebreak" "pagebreak" "nopagebreak"
+ "newline" "newpage" "clearpage" "cleardoublepage"
+ "displaybreak" "allowdisplaybreaks" "enlargethispage")
+ t))
+ (general "\\([a-zA-Z@]+\\**\\|[^ \t\n]\\)")
+ ;;
+ ;; Miscellany.
+ (slash "\\\\")
+ (opt " *\\(\\[[^]]*\\] *\\)*")
+ (arg "{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)"))
+ (list
+ ;;
+ ;; Citation args.
+ (list (concat slash citations opt arg) 3 'font-lock-constant-face)
+ ;;
+ ;; Text between `` quotes ''.
+ (cons (concat (regexp-opt `("``" "\"<" "\"`" "<<" "«") t)
+ "[^'\">»]+" ;a bit pessimistic
+ (regexp-opt `("''" "\">" "\"'" ">>" "»") t))
+ 'font-lock-string-face)
+ ;;
+ ;; Command names, special and general.
+ (cons (concat slash specials) '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 '(quote bold) 'append)
+ (list (concat slash italic " *" arg) 2 '(quote 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 "\\\\\\(\\(bf\\)\\|em\\|it\\|sl\\)\\>"
+ "\\(\\([^}&\\]\\|\\\\[^\\]\\)+\\)")
+ 3 '(if (match-beginning 2) 'bold 'italic) 'append)))))
+ "Gaudy expressions to highlight in TeX modes.")
+
+(defvar tex-font-lock-keywords tex-font-lock-keywords-1
+ "Default expressions to highlight in TeX modes.")
+
+
+(defface tex-math-face
+ '((t :inherit font-lock-string-face))
+ "Face used to highlight TeX math expressions.")
+(defvar tex-math-face 'tex-math-face)
+
+;; Use string syntax but math face for $...$.
+(defun tex-font-lock-syntactic-face-function (state)
+ (if (nth 3 state) tex-math-face font-lock-comment-face))
+
+;;;###autoload
+(defun tex-font-setup ()
+ "Setup font lock support for TeX."
+ (set (make-local-variable 'font-lock-defaults)
+ '((tex-font-lock-keywords
+ tex-font-lock-keywords-1 tex-font-lock-keywords-2)
+ 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)))
+ )
+
+(provide 'tex-font)
+
+;;; tex-font.el ends here
\ No newline at end of file
--- /dev/null
+;;; tex-fptex.el --- fpTeX support for AUCTeX.
+
+;; Copyright (C) 2000 Fabrice Popineau
+;; Copyright (C) 2004 Free Software Foundation, Inc.
+
+;; Author: Fabrice Popineau <Fabrice.Popineau@supelec.fr>
+;; Maintainer: auctex-devel@gnu.org
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+;;
+;; This file contains variables customized for fpTeX.
+
+;;; Code:
+
+(defmacro parent-directory (f)
+ "Return safe parent directory of the directory given as argument."
+ `(directory-file-name
+ (file-name-directory
+ (directory-file-name ,f))))
+
+(unless (get 'TeX-lisp-directory 'saved-value)
+ (setq-default TeX-lisp-directory
+ (concat (parent-directory (invocation-directory))
+ "/site-lisp/auctex")))
+
+ ;; Remove the Queue entry from the default, and make a non-Unix
+ ;; specific print entry, assuming that dvips will print by default.
+(unless (get 'TeX-queue-command 'saved-value)
+ (setq TeX-queue-command nil))
+
+(unless (get 'TeX-printer-list 'saved-value)
+ (setq TeX-printer-list nil))
+
+(unless (get 'TeX-print-command 'saved-value)
+ (setq TeX-print-command
+ "dvips %d"))
+
+(unless (get 'TeX-view-style 'saved-value)
+ (setq TeX-view-style '(("^a5\\(?:comb\\|paper\\)?$" "windvi %d -qpaper a5")
+ ("^landscape$" "windvi %d -qpaper a4r -s 4")
+ ("^epsf$" "start \"\" %f")
+ ("." "windvi %d"))))
+
+(unless (get 'TeX-output-view-style 'saved-value)
+ (setq TeX-output-view-style
+ '(("^dvi$" "^pstricks$\\|^pst-\\|^psfrag$" "dvips %d -o && start \"\" %f")
+ ("^dvi$" ("^a5\\(?:comb\\|paper\\)$" "^landscape$")
+ "windvi %d %dS -qpaper a5r -s 0")
+ ("^dvi$" "^a5\\(?:comb\\|paper\\)$" "windvi %d %dS -qpaper a5")
+ ("^dvi$" "^b5paper$" "windvi %d %dS -qpaper b5")
+ ("^dvi$" ("^landscape$" "^pstricks$\\|^psfrag$")
+ "dvips -t landscape %d -o && start \"\" %f")
+ ("^dvi$" "^letterpaper$" "windvi %d %dS -qpaper us")
+ ("^dvi$" "^legalpaper$" "windvi %d %dS -qpaper legal")
+ ("^dvi$" "^executivepaper$" "windvi %d %dS -qpaper 7.25x10.5in")
+ ("^dvi$" "^landscape$" "windvi %d %dS -qpaper a4r")
+ ("^dvi$" "." "windvi %d %dS")
+ ("^pdf$" "." "start \"\" %o")
+ ("^html?$" "." "start \"\" %o"))))
+
+;; WinDVI does not support source specials?
+(unless (get 'TeX-source-specials-view-position-flags 'saved-value)
+ (setq TeX-source-specials-view-position-flags ""))
+
+(unless (get 'TeX-source-specials-view-editor-flags 'saved-value)
+ (setq TeX-source-specials-view-editor-flags ""))
+
+(unless (get 'TeX-kpathsea-path-delimiter 'saved-value)
+ (setq TeX-kpathsea-path-delimiter ";"))
+
+(provide 'tex-fptex)
+(require 'tex-site)
+
+;;; tex-fptex.el ends here
--- /dev/null
+;;; tex-info.el --- Support for editing Texinfo source.
+
+;; Copyright (C) 1993, 1994, 1997, 2000, 2001,
+;; 2004, 2005, 2006 Free Software Foundation, Inc.
+
+;; Maintainer: auctex-devel@gnu.org
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Code:
+
+(require 'tex)
+
+(require 'texinfo)
+;; Make sure the Texinfo mode of AUCTeX is still used after loading
+;; texinfo.el. (This is only an issue on Emacs 21.)
+(when (and (boundp 'TeX-modes)
+ (memq 'texinfo-mode TeX-modes))
+ (defalias 'texinfo-mode 'TeX-texinfo-mode))
+
+;;; Environments:
+
+(defvar Texinfo-environment-list
+ '(("cartouche") ("command") ("copying") ("defcv") ("deffn") ("defivar")
+ ("defmac") ("defmethod") ("defop") ("defopt") ("defspec")
+ ("deftp") ("deftypefn") ("deftypefun") ("deftypevar") ("deftypevr")
+ ("defun") ("defvar") ("defvr") ("description") ("detailmenu")
+ ("direntry") ("display") ("documentdescription") ("enumerate")
+ ("example") ("flushleft") ("flushright") ("format") ("ftable")
+ ("group") ("ifclear") ("ifdocbook") ("ifhtml") ("ifinfo")
+ ("ifnotdocbook") ("ifnothtml") ("ifnotinfo") ("ifnotplaintext")
+ ("ifnottex") ("ifnotxml") ("ifplaintext") ("ifset") ("iftex")
+ ("ifxml") ("ignore") ("itemize") ("lisp") ("macro") ("menu")
+ ("multitable") ("quotation") ("smalldisplay") ("smallexample")
+ ("smallformat") ("smalllisp") ("table") ("tex") ("titlepage")
+ ("verbatim") ("vtable"))
+ "Alist of Texinfo environments.")
+
+(defconst texinfo-environment-regexp
+ ;; Overwrite version from `texinfo.el'.
+ (concat "^@\\("
+ (mapconcat 'car Texinfo-environment-list "\\|")
+ "\\|end\\)\\>")
+ "Regexp for environment-like Texinfo list commands.
+Subexpression 1 is what goes into the corresponding `@end' statement.")
+
+(defun Texinfo-environment (env &optional arg)
+ "Make Texinfo environment ENV.
+With optional ARG, modify current environment."
+ ;; XXX: This could be enhanced to act like `LaTeX-environment',
+ ;; i.e. suggest a default environment and have its own history.
+ (interactive (list (completing-read "Environment: "
+ Texinfo-environment-list)
+ current-prefix-arg))
+ (if arg
+ (Texinfo-modify-environment env)
+ (Texinfo-insert-environment env)))
+
+(defun Texinfo-insert-environment (env)
+ "Insert Texinfo environment ENV."
+ (if (and (TeX-active-mark)
+ (not (eq (mark) (point))))
+ (progn
+ (when (< (mark) (point))
+ (exchange-point-and-mark))
+ (unless (TeX-looking-at-backward "^[ \t]*")
+ (newline))
+ (insert "@" env)
+ (newline)
+ (goto-char (mark))
+ (unless (TeX-looking-at-backward "^[ \t]*")
+ (newline))
+ (insert "@end " env)
+ (save-excursion (newline))
+ (end-of-line 0))
+ (insert "@" env "\n\n@end " env "\n")
+ (if (null (cdr-safe (assoc "defcv" Texinfo-environment-list)))
+ (forward-line -2))))
+
+(defun Texinfo-modify-environment (env)
+ "Change current environment to environment ENV."
+ (save-excursion
+ (Texinfo-find-env-end)
+ (re-search-backward (concat (regexp-quote TeX-esc) "end \\([a-zA-Z]*\\)")
+ (line-beginning-position))
+ (replace-match env t t nil 1)
+ (beginning-of-line)
+ (Texinfo-find-env-start)
+ (re-search-forward (concat (regexp-quote TeX-esc) "\\([a-zA-Z]*\\)")
+ (line-end-position))
+ (replace-match env t t nil 1)))
+
+(defun Texinfo-find-env-end ()
+ "Move point to the end of the current environment."
+ (interactive)
+ (let* ((envs (mapcar 'car Texinfo-environment-list))
+ (regexp (concat "^[ \t]*" (regexp-quote TeX-esc) "\\(end \\)*"
+ (regexp-opt envs t) "\\b"))
+ (level 1)
+ case-fold-search)
+ (save-restriction
+ (save-excursion
+ (save-excursion
+ (beginning-of-line)
+ (when (and (looking-at regexp)
+ (match-string 1))
+ (setq level 0)))
+ (while (and (> level 0) (re-search-forward regexp nil t))
+ (if (match-string 1)
+ (setq level (1- level))
+ (setq level (1+ level)))))
+ (if (= level 0)
+ (goto-char (match-end 0))
+ (error "Can't locate end of current environment")))))
+
+(defun Texinfo-find-env-start ()
+ "Move point to the start of the current environment."
+ (interactive)
+ (let* ((envs (mapcar 'car Texinfo-environment-list))
+ (regexp (concat "^[ \t]*" (regexp-quote TeX-esc) "\\(end \\)*"
+ (regexp-opt envs t) "\\b"))
+ (level 1)
+ case-fold-search)
+ (save-restriction
+ (save-excursion
+ (save-excursion
+ (beginning-of-line)
+ (when (and (looking-at regexp)
+ (not (match-string 1)))
+ (setq level 0)))
+ (while (and (> level 0) (re-search-backward regexp nil t))
+ (if (match-string 1)
+ (setq level (1+ level))
+ (setq level (1- level)))))
+ (if (= level 0)
+ (goto-char (match-beginning 0))
+ (error "Can't locate start of current environment")))))
+
+(defun Texinfo-insert-node ()
+ "Insert a Texinfo node in the current buffer.
+That means, insert the string `@node' and prompt for current,
+next, previous and upper node. If there is an active region, use
+this for the current node and inhibit the prompt for it. Insert
+a comment on the following line indicating the order of arguments
+for @node."
+ (interactive)
+ (let ((active-mark (and (TeX-active-mark) (not (eq (mark) (point)))))
+ nodes node-name next-node previous-node up-node)
+ ;; Build list of nodes in current buffer.
+ ;; (What about using `imenu--index-alist'?)
+ ;; FIXME: Support multi-file documents.
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward "^@node\\b" nil t)
+ (skip-chars-forward " \t")
+ (add-to-list 'nodes
+ (list (buffer-substring-no-properties
+ (point) (progn (skip-chars-forward "^,")
+ (point)))))))
+ (unless active-mark
+ (setq node-name (read-string "Node name: ")))
+ ;; FIXME: What if key binding for `minibuffer-complete' was changed?
+ ;; `substitute-command-keys' doesn't return the correct value.
+ (setq next-node (completing-read "Next node (TAB completes): " nodes))
+ (setq previous-node
+ (completing-read "Previous node (TAB completes): " nodes))
+ (setq up-node (completing-read "Upper node (TAB completes): " nodes))
+ (when (and active-mark
+ (< (mark) (point)))
+ (exchange-point-and-mark))
+ (insert "@node ")
+ (if active-mark
+ (goto-char (mark))
+ (insert node-name))
+ (insert ", " next-node ", " previous-node ", " up-node
+ "\n@comment node-name, next, previous, up\n")
+ ;; Position point at first empty field.
+ (unless (and (or (> (length node-name) 0) active-mark)
+ (> (length next-node) 0)
+ (> (length previous-node) 0)
+ (> (length up-node) 0))
+ (forward-line -2)
+ (forward-char 6)
+ (catch 'break
+ (if (or (> (length node-name) 0) active-mark)
+ (progn (skip-chars-forward "^,") (forward-char 2))
+ (throw 'break nil))
+ (dolist (node (list next-node previous-node up-node))
+ (if (> (length node) 0)
+ (progn (skip-chars-forward "^,") (forward-char 2))
+ (throw 'break nil)))))))
+
+
+;;; Keymap:
+
+(defvar Texinfo-mode-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map TeX-mode-map)
+
+ ;; From texinfo.el
+ ;; 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)
+
+ ;; Simulating LaTeX-mode
+ (define-key map "\C-c\C-e" 'Texinfo-environment)
+ (define-key map "\C-c\n" 'texinfo-insert-@item)
+ (or (key-binding "\e\r")
+ (define-key map "\e\r" 'texinfo-insert-@item)) ;*** Alias
+ (define-key map "\C-c\C-s" 'Texinfo-insert-node)
+ (define-key map "\C-c]" 'texinfo-insert-@end)
+ map)
+ "Keymap for Texinfo mode.")
+
+(easy-menu-define Texinfo-command-menu
+ Texinfo-mode-map
+ "Menu used in Texinfo mode for external commands."
+ (TeX-mode-specific-command-menu 'texinfo-mode))
+
+(easy-menu-define Texinfo-mode-menu
+ Texinfo-mode-map
+ "Menu used in Texinfo mode."
+ (TeX-menu-with-help
+ `("Texinfo"
+ ["Node ..." texinfo-insert-@node
+ :help "Insert a node"]
+ ["Macro ..." TeX-insert-macro
+ :help "Insert a macro and possibly arguments"]
+ ["Complete Macro" TeX-complete-symbol
+ :help "Complete the current macro"]
+ ["Environment ..." Texinfo-insert-environment
+ :help "Insert an environment"]
+ ["Item" texinfo-insert-@item
+ :help "Insert an @item"]
+ "-"
+ ("Insert Font"
+ ["Emphasize" (TeX-font nil ?\C-e) :keys "C-c C-f C-e"]
+ ["Bold" (TeX-font nil ?\C-b) :keys "C-c C-f C-b"]
+ ["Typewriter" (TeX-font nil ?\C-t) :keys "C-c C-f C-t"]
+ ["Small Caps" (TeX-font nil ?\C-c) :keys "C-c C-f C-c"]
+ ["Italic" (TeX-font nil ?\C-i) :keys "C-c C-f C-i"]
+ ["Sample" (TeX-font nil ?\C-s) :keys "C-c C-f C-s"]
+ ["Roman" (TeX-font nil ?\C-r) :keys "C-c C-f C-r"])
+ ("Replace Font"
+ ["Emphasize" (TeX-font t ?\C-e) :keys "C-u C-c C-f C-e"]
+ ["Bold" (TeX-font t ?\C-b) :keys "C-u C-c C-f C-b"]
+ ["Typewriter" (TeX-font t ?\C-t) :keys "C-u C-c C-f C-t"]
+ ["Small Caps" (TeX-font t ?\C-c) :keys "C-u C-c C-f C-c"]
+ ["Italic" (TeX-font t ?\C-i) :keys "C-u C-c C-f C-i"]
+ ["Sample" (TeX-font t ?\C-s) :keys "C-u C-c C-f C-s"]
+ ["Roman" (TeX-font t ?\C-r) :keys "C-u C-c C-f C-r"])
+ ["Delete Font" (TeX-font t ?\C-d) :keys "C-c C-f C-d"]
+ "-"
+ ["Create Master Menu" texinfo-master-menu
+ :help "Make a master menu for the whole Texinfo file"]
+ ["Create Menu" texinfo-make-menu
+ :help "Make or update the menu for the current section"]
+ ["Update Node" texinfo-update-node
+ :help "Update the current node"]
+ ["Update Every Node" texinfo-every-node-update
+ :help "Update every node in the current file"]
+ ["Update All Menus" texinfo-all-menus-update
+ :help "Update every menu in the current file"]
+ "-"
+ ("Commenting"
+ ["Comment or Uncomment Region"
+ TeX-comment-or-uncomment-region
+ :help "Comment or uncomment the currently selected region"]
+ ["Comment or Uncomment Paragraph"
+ TeX-comment-or-uncomment-paragraph
+ :help "Comment or uncomment the current paragraph"])
+ ,TeX-fold-menu
+ "-"
+ . ,TeX-common-menu-entries)))
+
+(defvar Texinfo-font-list
+ '((?\C-b "@b{" "}")
+ (?\C-c "@sc{" "}")
+ (?\C-e "@emph{" "}")
+ (?\C-i "@i{" "}")
+ (?\C-r "@r{" "}")
+ (?\C-s "@samp{" "}")
+ (?\C-t "@t{" "}")
+ (?s "@strong{" "}")
+ (?\C-f "@file{" "}")
+ (?d "@dfn{" "}")
+ (?\C-v "@var{" "}")
+ (?k "@key{" "}")
+ (?\C-k "@kbd{" "}")
+ (?c "@code{" "}")
+ (?C "@cite{" "}")
+ (?\C-d "" "" t))
+ "Font commands used in Texinfo mode. See `TeX-font-list'.")
+
+;;; Mode:
+
+;;;###autoload
+(defalias 'Texinfo-mode 'texinfo-mode)
+
+;;;###autoload
+(defun TeX-texinfo-mode ()
+ "Major mode in AUCTeX for editing Texinfo files.
+
+Special commands:
+\\{Texinfo-mode-map}
+
+Entering Texinfo mode calls the value of `text-mode-hook' and then the
+value of `Texinfo-mode-hook'."
+ (interactive)
+ (kill-all-local-variables)
+ (setq TeX-mode-p t)
+ ;; Mostly stolen from texinfo.el
+ (setq TeX-base-mode-name "Texinfo")
+ (setq major-mode 'texinfo-mode)
+ (use-local-map Texinfo-mode-map)
+ (set-syntax-table texinfo-mode-syntax-table)
+ (make-local-variable 'page-delimiter)
+ (setq page-delimiter
+ (concat
+ "^@node [ \t]*[Tt]op\\|^@\\("
+ texinfo-chapter-level-regexp
+ "\\)"))
+ (make-local-variable 'require-final-newline)
+ (setq require-final-newline t)
+ (make-local-variable 'indent-tabs-mode)
+ (setq indent-tabs-mode nil)
+ (make-local-variable 'paragraph-separate)
+ (setq paragraph-separate
+ (concat "\b\\|^@[a-zA-Z]*[ \n]\\|" paragraph-separate))
+ (make-local-variable 'paragraph-start)
+ (setq paragraph-start
+ (concat "\b\\|^@[a-zA-Z]*[ \n]\\|" paragraph-start))
+ (make-local-variable 'fill-column)
+ (setq fill-column 72)
+ (make-local-variable 'comment-start)
+ (setq comment-start "@c ")
+ (make-local-variable 'comment-start-skip)
+ (setq comment-start-skip "@c +\\|@comment +")
+ (set (make-local-variable 'comment-use-syntax) nil)
+ (make-local-variable 'words-include-escapes)
+ (setq words-include-escapes t)
+ (if (not (boundp 'texinfo-imenu-generic-expression))
+ ;; This was introduced in 19.30.
+ ()
+ (make-local-variable 'imenu-generic-expression)
+ (setq imenu-generic-expression texinfo-imenu-generic-expression))
+ (make-local-variable 'font-lock-defaults)
+ (setq font-lock-defaults
+ ;; COMPATIBILITY for Emacs 20
+ (if (boundp 'texinfo-font-lock-syntactic-keywords)
+ '(texinfo-font-lock-keywords
+ nil nil nil backward-paragraph
+ (font-lock-syntactic-keywords
+ . texinfo-font-lock-syntactic-keywords))
+ '(texinfo-font-lock-keywords t)))
+ (if (not (boundp 'texinfo-section-list))
+ ;; This was included in 19.31.
+ ()
+ (make-local-variable 'outline-regexp)
+ (setq outline-regexp
+ (concat "@\\("
+ (mapconcat 'car texinfo-section-list "\\>\\|")
+ "\\>\\)"))
+ (make-local-variable 'outline-level)
+ (setq outline-level 'texinfo-outline-level))
+
+ ;; Mostly AUCTeX stuff
+ (easy-menu-add Texinfo-mode-menu Texinfo-mode-map)
+ (easy-menu-add Texinfo-command-menu Texinfo-mode-map)
+ (make-local-variable 'TeX-command-current)
+ (setq TeX-command-current 'TeX-command-master)
+
+ (setq TeX-default-extension "texi")
+ (make-local-variable 'TeX-esc)
+ (setq TeX-esc "@")
+
+ (make-local-variable 'TeX-auto-regexp-list)
+ (setq TeX-auto-regexp-list 'TeX-auto-empty-regexp-list)
+ (make-local-variable 'TeX-auto-update)
+ (setq TeX-auto-update t)
+
+ (setq TeX-command-default "TeX")
+ (setq TeX-header-end "%*end")
+ (setq TeX-trailer-start (regexp-quote (concat TeX-esc "bye")))
+
+ (make-local-variable 'TeX-complete-list)
+ (setq TeX-complete-list
+ (list (list "@\\([a-zA-Z]*\\)" 1 'TeX-symbol-list nil)
+ (list "" TeX-complete-word)))
+
+ (make-local-variable 'TeX-font-list)
+ (setq TeX-font-list Texinfo-font-list)
+ (make-local-variable 'TeX-font-replace-function)
+ (setq TeX-font-replace-function 'TeX-font-replace-macro)
+
+ (add-hook 'find-file-hooks (lambda ()
+ (unless (file-exists-p (buffer-file-name))
+ (TeX-master-file nil nil t))) nil t)
+
+ (TeX-add-symbols
+ '("appendix" (TeX-arg-literal " ") (TeX-arg-free "Title"))
+ '("appendixsec" (TeX-arg-literal " ") (TeX-arg-free "Title"))
+ '("appendixsection" (TeX-arg-literal " ") (TeX-arg-free "Title"))
+ '("appendixsubsec" (TeX-arg-literal " ") (TeX-arg-free "Title"))
+ '("appendixsubsubsec" (TeX-arg-literal " ") (TeX-arg-free "Title"))
+ '("asis")
+ '("author" (TeX-arg-literal " ") (TeX-arg-free "Author"))
+ '("b" "Text")
+ '("bullet")
+ '("bye")
+ '("c" (TeX-arg-literal " ") (TeX-arg-free "Comment"))
+ '("center" (TeX-arg-literal " ") (TeX-arg-free "Line of text"))
+ '("chapheading" (TeX-arg-literal " ") (TeX-arg-free "Title"))
+ '("chapter" (TeX-arg-literal " ") (TeX-arg-free "Title"))
+ '("cindex" (TeX-arg-literal " ") (TeX-arg-free "Entry"))
+ '("cite" "Reference")
+ '("clear" (TeX-arg-literal " ") (TeX-arg-free "Flag"))
+ '("code" "Sample code")
+ '("command" "Command")
+ '("comment" (TeX-arg-literal " ") (TeX-arg-free "Comment"))
+ '("contents")
+ '("copyright" nil)
+ '("defcodeindex" (TeX-arg-literal " ") (TeX-arg-free "Index name"))
+ '("defindex" (TeX-arg-literal " ") (TeX-arg-free "Index name"))
+ '("dfn" "Term")
+ '("dmn" "Dimension")
+ '("dots" nil)
+ '("emph" "Text")
+ '("email" "Email address")
+ '("equiv" nil)
+ '("error")
+ '("evenfooting" Texinfo-lrc-argument-hook)
+ '("evenheading" Texinfo-lrc-argument-hook)
+ '("everyfooting" Texinfo-lrc-argument-hook)
+ '("everyheading" Texinfo-lrc-argument-hook)
+ '("exdent" (TeX-arg-literal " ") (TeX-arg-free "Line of text"))
+ '("expansion" nil)
+ '("file" "Filename")
+ '("finalout")
+ '("findex" (TeX-arg-literal " ") (TeX-arg-free "Entry"))
+ '("footnote" "Text of footnote")
+ '("footnotestyle" (TeX-arg-literal " ") (TeX-arg-free "Style"))
+ '("group")
+ '("heading" (TeX-arg-literal " ") (TeX-arg-free "Title"))
+ ;; XXX: Would be nice with completion.
+ '("headings" (TeX-arg-literal " ") (TeX-arg-free "On off single double"))
+ '("i" "Text")
+ '("ignore")
+ '("include" (TeX-arg-literal " ") (TeX-arg-free "Filename"))
+ '("inforef" "Node name" "Info file name")
+ '("item")
+ '("itemx")
+ '("kbd" "Keyboard characters")
+ '("key" "Key name")
+ '("kindex" (TeX-arg-literal " ") (TeX-arg-free "Entry"))
+ '("lowersections" 0)
+ '("majorheading" (TeX-arg-literal " ") (TeX-arg-free "Title"))
+ '("menu")
+ '("minus")
+ '("need" "N")
+ '("node" (TeX-arg-literal " ") (TeX-arg-free "Name")
+ (TeX-arg-literal ", ") (TeX-arg-free "Next")
+ (TeX-arg-literal ", ") (TeX-arg-free "Previous")
+ (TeX-arg-literal ", ") (TeX-arg-free "Up"))
+ '("noindent")
+ '("oddfooting" Texinfo-lrc-argument-hook)
+ '("oddheading" Texinfo-lrc-argument-hook)
+ '("page")
+ '("paragraphindent" (TeX-arg-literal " ") (TeX-arg-free "Indent"))
+ '("pindex" "Entry")
+ '("point" nil)
+ '("print")
+ '("printindex" (TeX-arg-literal " ") (TeX-arg-free "Index name"))
+ '("pxref" "Node name")
+ '("r" "Text")
+ '("raisesections" 0)
+ '("ref" "Node name")
+ '("refill")
+ '("result")
+ '("samp" "Text")
+ '("sc" "Text")
+ '("section" (TeX-arg-literal " ") (TeX-arg-free "Title"))
+ '("set" (TeX-arg-literal " ") (TeX-arg-free "Flag"))
+ ;; XXX: Would be nice with completion.
+ '("setchapternewpage" (TeX-arg-literal " ") (TeX-arg-free "On off odd"))
+ '("setfilename" (TeX-arg-literal " ") (TeX-arg-free "Info file name"))
+ '("settitle" (TeX-arg-literal " ") (TeX-arg-free "Title"))
+ '("shortcontents")
+ '("smallbook")
+ '("sp" "N")
+ '("strong" "Text")
+ '("subheading" (TeX-arg-literal " ") (TeX-arg-free "Title"))
+ '("subsection" (TeX-arg-literal " ") (TeX-arg-free "Title"))
+ '("subsubheading" (TeX-arg-literal " ") (TeX-arg-free "Title"))
+ '("subsubsection" (TeX-arg-literal " ") (TeX-arg-free "Title"))
+ '("subtitle" (TeX-arg-literal " ") (TeX-arg-free "Title"))
+ '("summarycontents")
+ '("syncodeindex" (TeX-arg-literal " ") (TeX-arg-free "From index")
+ (TeX-arg-literal " ") (TeX-arg-free "Into index"))
+ '("synindex" (TeX-arg-literal " ") (TeX-arg-free "From index")
+ (TeX-arg-literal " ") (TeX-arg-free "Into index"))
+ '("t" "Text")
+ '("TeX" nil)
+ '("thischapter")
+ '("thischaptername")
+ '("thisfile")
+ '("thispage")
+ '("tindex" (TeX-arg-literal " ") (TeX-arg-free "Entry"))
+ '("title" (TeX-arg-literal " ") (TeX-arg-free "Title"))
+ '("titlefont" "Text")
+ '("titlepage")
+ '("today" nil)
+ '("top" (TeX-arg-literal " ") (TeX-arg-free "Title"))
+ '("unnumbered" (TeX-arg-literal " ") (TeX-arg-free "Title"))
+ '("unnumberedsec" (TeX-arg-literal " ") (TeX-arg-free "Title"))
+ '("unnumberedsubsec" (TeX-arg-literal " ") (TeX-arg-free "Title"))
+ '("unnumberedsubsubsec" (TeX-arg-literal " ") (TeX-arg-free "Title"))
+ '("value" "Flag")
+ '("var" "Metasyntactic variable")
+ '("vindex" (TeX-arg-literal " ") (TeX-arg-free "Entry"))
+ '("vskip" (TeX-arg-literal " ") (TeX-arg-free "Amount"))
+ '("w" "Text")
+ '("xref" "Node name"))
+
+ (TeX-run-mode-hooks 'text-mode-hook 'Texinfo-mode-hook)
+ (TeX-set-mode-name))
+
+(defcustom Texinfo-clean-intermediate-suffixes nil
+ "List of regexps matching suffixes of files to be deleted.
+The regexps will be anchored at the end of the file name to be matched,
+i.e. you do _not_ have to cater for this yourself by adding \\\\' or $."
+ :type '(repeat regexp)
+ :group 'TeX-command)
+
+(defcustom Texinfo-clean-output-suffixes
+ ;; See `man texi2html' for the HTML stuff.
+ '("\\.info\\(-[0-9]+\\)?" "\\.dvi" "\\.pdf" "\\.ps" "\\.html"
+ "_toc\\.html" "_fot\\.html" "_abt\\.html" "_[0-9]+\\.html" "_l2h_img.+")
+ "List of regexps matching suffixes of files to be deleted.
+The regexps will be anchored at the end of the file name to be matched,
+i.e. you do _not_ have to cater for this yourself by adding \\\\' or $."
+ :type '(repeat regexp)
+ :group 'TeX-command)
+
+(provide 'tex-info)
+
+;;; tex-info.el ends here
--- /dev/null
+;;; tex-jp.el --- Support for Japanese TeX.
+
+;; Copyright (C) 1999, 2001 Hidenobu Nabetani <nabe@debian.or.jp>
+;; Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
+
+;; Author: KOBAYASHI Shinji <koba@flab.fujitsu.co.jp>
+;; Maintainer: Masayuki Ataka <masayuki.ataka@gmail.com>
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file was written by KOBAYASHI Shinji <koba@flab.fujitsu.co.jp>
+;; based on many patches developed by Japanese NetNews community.
+;; Japanese message translation by MATUI Takao <mat@nuis.ac.jp>.
+
+;;; Code:
+
+(require 'latex)
+
+;;; Customization
+
+(defgroup AUCTeX-jp nil
+ "Japanese support in AUCTeX."
+ :group 'AUCTeX)
+
+(defcustom japanese-TeX-command-list
+ ;; Changed to double quotes for Windows afflicted people. I don't
+ ;; use the %(latex) and %(tex) shorthands here because I have not
+ ;; clue whether Omega-related versions exist. --dak
+ '(("jTeX" "%(PDF)jtex %`%S%(PDFout)%(mode)%' %t"
+ TeX-run-TeX nil (plain-tex-mode) :help "Run NTT jTeX")
+ ("jLaTeX" "%(PDF)jlatex %`%S%(PDFout)%(mode)%' %t"
+ TeX-run-TeX nil (latex-mode) :help "Run NTT jLaTeX")
+ ("pTeX" "%(PDF)ptex %`%S%(PDFout)%(mode)%' %t"
+ TeX-run-TeX nil (plain-tex-mode) :help "Run ASCII pTeX")
+ ("pLaTeX" "%(PDF)platex %`%S%(PDFout)%(mode)%' %t"
+ TeX-run-TeX nil (latex-mode) :help "Run ASCII pLaTeX")
+ ("Mendex" "mendex %s" TeX-run-command nil t :help "Create index file with mendex")
+ ("jBibTeX" "jbibtex %s" TeX-run-BibTeX nil t :help "Run jBibTeX"))
+ "Additional list of commands, especially for Japanese.
+For detail, see `TeX-command-list', which this list is appended to."
+ :group 'AUCTeX-jp
+ :type '(repeat (group :value ("" "" TeX-run-command nil t)
+ (string :tag "Name")
+ (string :tag "Command")
+ (choice :tag "How"
+ :value TeX-run-command
+ (function-item TeX-run-command)
+ (function-item TeX-run-format)
+ (function-item TeX-run-TeX)
+ (function-item TeX-run-interactive)
+ (function-item TeX-run-BibTeX)
+ (function-item TeX-run-compile)
+ (function-item TeX-run-shell)
+ (function-item TeX-run-discard)
+ (function-item TeX-run-background)
+ (function-item TeX-run-silent)
+ (function-item TeX-run-discard-foreground)
+ (function-item TeX-run-function)
+ (function :tag "Other"))
+ (boolean :tag "Prompt")
+ (choice :tag "Modes"
+ (const :tag "All" t)
+ (set (const :tag "Plain TeX" plain-tex-mode)
+ (const :tag "LaTeX" latex-mode)
+ (const :tag "DocTeX" doctex-mode)
+ (const :tag "ConTeXt" context-mode)
+ (const :tag "Texinfo" texinfo-mode)
+ (const :tag "AmSTeX" ams-tex-mode)))
+ (repeat :tag "Menu elements" :inline t sexp))))
+
+(setq TeX-command-list
+ (append japanese-TeX-command-list
+ '(("-" "" ignore nil t)) ;; separator for command menu
+ TeX-command-list))
+
+(mapc (lambda (dir) (add-to-list 'TeX-macro-global dir t))
+ (or (TeX-tree-expand
+ '("$SYSTEXMF" "$TEXMFLOCAL" "$TEXMFMAIN" "$TEXMFDIST")
+ "platex" '("/ptex/" "/jbibtex/bst/"))
+ '("/usr/share/texmf/ptex/" "/usr/share/texmf/jbibtex/bst/")))
+
+(mapc (lambda (dir) (add-to-list 'TeX-macro-global dir t))
+ (or (TeX-tree-expand
+ '("$SYSTEXMF" "$TEXMFLOCAL" "$TEXMFMAIN" "$TEXMFDIST")
+ "jlatex" '("/jtex/" "/jbibtex/bst/"))
+ '("/usr/share/texmf/jtex/" "/usr/share/texmf/jbibtex/bst/")))
+
+;; Menus
+
+(setq LaTeX-command-style
+ (append '(("^j-\\(article\\|report\\|book\\)$"
+ "%(PDF)jlatex %S%(PDFout)")
+ ("^[jt]s?\\(article\\|report\\|book\\)$"
+ "%(PDF)platex %S%(PDFout)"))
+ LaTeX-command-style))
+
+(defcustom japanese-TeX-error-messages t
+ "*If non-nil, explain TeX error messages in Japanese."
+ :group 'AUCTeX-jp
+ :type 'boolean)
+
+(when (featurep 'mule)
+
+;; FIX-ME (2007-02-09) The default coding system in recent Unix (like Fedora and
+;; Ubuntu) is utf-8. But Japanese TeX system is not support utf-8 yet
+;; (platex-utf is under development, may be alpha phase). So,
+;; process-coding-system for Japanese TeX is not defined from
+;; default-coding-system. When platex-utf is out, we should look this setting,
+;; again.
+
+(defcustom TeX-japanese-process-input-coding-system
+ (cond ((memq system-type '(windows-nt ms-dos cygwin)) 'shift_jis-dos)
+ ((memq system-type '(mac darwin)) 'shift_jis-mac)
+ (t 'euc-jp-unix))
+ "TeX-process' coding system with standard input."
+ :group 'AUCTeX-jp
+ :type 'coding-system)
+
+(defcustom TeX-japanese-process-output-coding-system
+ (cond ((memq system-type '(windows-nt ms-dos cygwin)) 'shift_jis-dos)
+ ((memq system-type '(mac darwin)) 'shift_jis-mac)
+ (t 'euc-jp-unix))
+ "TeX-process' coding system with standard output."
+ :group 'AUCTeX-jp
+ :type 'coding-system)
+
+)
+
+(defcustom japanese-TeX-command-default "pTeX"
+ "*The default command for `TeX-command' in the japanese-TeX mode."
+ :group 'AUCTeX-jp
+ :type 'string)
+ (make-variable-buffer-local 'japanese-TeX-command-default)
+
+(defcustom japanese-LaTeX-command-default "LaTeX"
+ "*The default command for `TeX-command' in the japanese-LaTeX mode."
+ :group 'AUCTeX-jp
+ :type 'string)
+ (make-variable-buffer-local 'japanese-LaTeX-command-default)
+
+(defcustom japanese-LaTeX-default-style "jarticle"
+ "*Default when creating new Japanese documents."
+ :group 'AUCTeX-jp
+ :type 'string)
+
+(defcustom japanese-LaTeX-style-list
+ '(("j-article")
+ ("j-report")
+ ("j-book")
+ ("jslides")
+ ("jarticle")
+ ("jreport")
+ ("jbook")
+ ("tarticle")
+ ("treport")
+ ("tbook")
+ ("jsarticle")
+ ("jsbook"))
+ "*List of Japanese document styles."
+ :group 'AUCTeX-jp
+ :type '(repeat (group (string :format "%v"))))
+
+(setq LaTeX-style-list
+ (append japanese-LaTeX-style-list LaTeX-style-list))
+
+;;; Coding system
+
+(when (featurep 'mule)
+
+(defun japanese-TeX-set-process-coding-system (process)
+ "Set proper coding system for japanese TeX PROCESS."
+ (if (with-current-buffer TeX-command-buffer japanese-TeX-mode)
+ (set-process-coding-system process
+ TeX-japanese-process-output-coding-system
+ TeX-japanese-process-input-coding-system)))
+(setq TeX-after-start-process-function
+ 'japanese-TeX-set-process-coding-system)
+)
+
+;;; Japanese TeX modes
+
+(defvar japanese-TeX-mode nil
+ "Non-nil means the current buffer handles Japanese TeX/LaTeX.")
+(make-variable-buffer-local 'japanese-TeX-mode)
+(put 'japanese-TeX-mode 'permanent-local t)
+
+;;;###autoload
+(defun japanese-plain-tex-mode ()
+ "Major mode in AUCTeX for editing Japanese plain TeX files.
+Set `japanese-TeX-mode' to t, and enter `TeX-plain-tex-mode'."
+ (interactive)
+ (setq japanese-TeX-mode t)
+ (TeX-plain-tex-mode))
+
+(defun japanese-plain-tex-mode-initialization ()
+ "Japanese plain-TeX specific initializations."
+ (when japanese-TeX-mode
+ (setq TeX-command-default japanese-TeX-command-default)))
+
+(add-hook 'plain-TeX-mode-hook 'japanese-plain-tex-mode-initialization)
+
+;;;###autoload
+(defun japanese-latex-mode ()
+ "Major mode in AUCTeX for editing Japanese LaTeX files.
+Set `japanese-TeX-mode' to t, and enter `TeX-latex-mode'."
+ (interactive)
+ (setq japanese-TeX-mode t)
+ (TeX-latex-mode))
+
+(defun japanese-latex-mode-initialization ()
+ "Japanese LaTeX specific initializations."
+ (when japanese-TeX-mode
+ (setq TeX-command-default japanese-LaTeX-command-default)
+ (setq LaTeX-default-style japanese-LaTeX-default-style)
+ (setq TeX-command-BibTeX "jBibTeX")))
+
+(add-hook 'LaTeX-mode-hook 'japanese-latex-mode-initialization)
+
+
+;;; Support for various self-insert-command
+
+(fset 'japanese-TeX-self-insert-command
+ (cond ((fboundp 'can-n-egg-self-insert-command)
+ 'can-n-egg-self-insert-command)
+ ((fboundp 'egg-self-insert-command)
+ 'egg-self-insert-command)
+ ((fboundp 'canna-self-insert-command)
+ 'canna-self-insert-command)
+ (t
+ 'self-insert-command)))
+
+(defun TeX-insert-punctuation ()
+ "Insert point or comma, cleaning up preceding space."
+ (interactive)
+ (expand-abbrev)
+ (if (TeX-looking-at-backward "\\\\/\\(}+\\)" 50)
+ (replace-match "\\1" t))
+ (call-interactively 'japanese-TeX-self-insert-command))
+
+;;; Error Messages
+
+(if japanese-TeX-error-messages
+(setq TeX-error-description-list
+ '(("Bad \\\\line or \\\\vector argument.*" .
+"\e$B@~$N79$-$r;XDj$9$k!$\e(B\\line\e$B$^$?$O\e(B\\vector\e$B$N:G=i$N0z?t$,IT@5$G$9!%\e(B")
+
+ ("Bad math environment delimiter.*" .
+"\e$B?t<0%b!<%ICf$G?t<0%b!<%I3+;O%3%^%s%I\e(B\\[\e$B$^$?$O\e(B\\(\e$B!$$^$?$O!$?t<0%b!<%I30$G\e(B
+\e$B?t<0%b!<%I=*N;%3%^%s%I\e(B\\]\e$B$^$?$O\e(B\\)\e$B$r\e(BTeX\e$B$,8+$D$1$^$7$?!%$3$NLdBj$O!$?t<0%b!<\e(B
+\e$B%I$N%G%j%_%?$,%^%C%A$7$F$$$J$+$C$?$j!$3g8L$N%P%i%s%9$,$H$l$F$$$J$+$C$?$j$9\e(B
+\e$B$k$?$a$K@8$8$^$9!%\e(B")
+
+ ("Bad use of \\\\\\\\.*" .
+"\\\\\e$B%3%^%s%I$,%Q%i%0%i%UCf$K$"$j$^$7$?!%$3$N;H$$$+$?$OL50UL#$G$9!%\e(B
+\e$B$3$N%(%i!<%a%C%;!<%8$O\e(B\\\\\e$B$,\e(Bcentering\e$B4D6-$d\e(Bflushing\e$B4D6-$G;H$o$l$?\e(B
+\e$B;~!$$"$k$$$O\e(Bcentering/flushing\e$B@k8@$,M-8z$J$H$3$m$G;H$o$l$?;~$K@8$8$^$9!%\e(B")
+
+ ("\\\\begin{[^ ]*} ended by \\\\end{[^ ]*}." .
+"\e$BBP1~$9$k\e(B\\begin\e$BL?Na$N$J$$\e(B\\end\e$BL?Na$r\e(BLaTeX\e$B$,8+$D$1$^$7$?!%\e(B\\end\e$BL?Na$N4D\e(B
+\e$B6-L>$r4V0c$($?$+!$M>J,$J\e(B\\begin\e$BL?Na$,$"$k$+!$\e(B\\end\e$BL?Na$r$o$9$l$?$+$N$$$:\e(B
+\e$B$l$+$G$7$g$&!%\e(B")
+
+ ("Can be used only in preamble." .
+"\e$B%W%j%"%s%V%k$G$7$+;H$($J$$\e(B\\documentclass\e$B!&\e(B\\nofiles\e$B!&\e(B\\includeonly
+\\makeindex\e$B!&\e(B\\makeglossary\e$B$N$&$A$N$$$:$l$+$,\e(B\\begin{document}\e$B$h$j$b\e(B
+\e$B8e$G;H$o$l$F$$$k$N$r\e(BLaTeX\e$B$,8!=P$7$^$7$?!%$3$N%(%i!<$O\e(B\\begin{document}
+\e$B$,M>J,$K$"$C$?;~$K$b@8$8$^$9!%\e(B")
+
+ ("Command name [^ ]* already used.*" .
+"\e$B$9$G$KDj5A$5$l$F$$$kL?NaL>$^$?$O4D6-L>$KBP$7$F\e(B\\newcommand\e$B!&\e(B
+\\newenvironment\e$B!&\e(B\\newlength\e$B!&\e(B\\newsavebox\e$B!&\e(B\\newtheorem\e$B$N$&$A$N$$$:\e(B
+\e$B$l$+$r<B9T$7$h$&$H$7$F$$$^$9\e(B(\e$B$"$k4D6-$rDj5A$9$k$HF1$8L>A0$NL?Na$,<+F0\e(B
+\e$BE*$KDj5A$5$l$k$N$G!$4{$KB8:_$9$k4D6-$HF1L>$NL?Na$ODj5A$G$-$^$;$s\e(B)\e$B!%?7\e(B
+\e$B$7$$L>A0$r9M$($k$+!$\e(B\\newcommand\e$B$+\e(B\\newenvironment\e$B$N>l9g$J$iBP1~$9$k\e(B
+\\renew...\e$BL?Na$r;H$o$J$1$l$P$J$j$^$;$s!%\e(B")
+
+ ("Counter too large." .
+"1. \e$BJ8;z$G=g=xIU$1$5$l$?$b$N!$$?$V$sHV9fIU$1$5$l$?%j%9%H4D6-$N%i%Y%k$,!$\e(B
+26\e$B$h$j$bBg$-$$HV9f$r<u$1<h$j$^$7$?!%Hs>o$KD9$$%j%9%H$r;H$C$F$$$k$+!$\e(B
+\e$B%+%&%s%?$r:F@_Dj$7$F$7$^$C$?$+$N$$$:$l$+$G$7$g$&!%\e(B
+
+2. \e$B5SCm$,J8;z$^$?$O5SCm5-9f$G=g=x$E$1$5$l$F$$$^$9$,!$J8;z$^$?$O5-9f$r\e(B
+\e$B;H$$@Z$C$F$7$^$$$^$7$?!%$*$=$i$/\e(B\\thanks\e$BL?Na$N;H$$$9$.$G$9!%\e(B")
+
+
+ ("Environment [^ ]* undefined." .
+"\e$BDj5A$5$l$F$$$J$$4D6-$KBP$9$k\e(B\\begin\e$BL?Na$r\e(BLaTeX\e$B$,8+$D$1$^$7$?!%$*$=$i$/\e(B
+\e$B4D6-L>$r4V0c$($?$N$G$7$g$&!%\e(B")
+
+ ("Float(s) lost." .
+"parbox\e$B$N$J$+$K\e(Bfigure\e$B4D6-!&\e(Btable\e$B4D6-$^$?$O\e(B\\marginpar\e$BL?Na$,$"$j$^$7$?\e(B
+\(\e$B$J$*!$\e(Bparbox\e$B$O\e(Bminipage\e$B4D6-$+\e(B\\parbox\e$BL?Na$K$h$C$F:n$i$l$k$+!$5SCm$d?^\e(B
+\e$B$J$I$KBP$7$F\e(BLaTeX\e$B$,@8@.$9$k$b$N$G$9\e(B\)\e$B!%$3$l$O=PNO;~$N%(%i!<$J$N$G!$860x\e(B
+\e$B$H$J$C$F$$$k4D6-$"$k$$$OL?Na$O!$\e(BLaTeX\e$B$,LdBj$rH/8+$7$?>l=j$h$j$b$@$$$V\e(B
+\e$B$sA0$K$"$k2DG=@-$,$"$j$^$9!%=PNO$5$l$F$$$J$$?^!&I=!&K5Cm$J$I$,$$$/$D$+\e(B
+\e$B$"$k$+$b$7$l$^$;$s$,!$$=$l$i$,860x$G$"$k$H$O8B$j$^$;$s!%\e(B")
+
+ ("Illegal character in array arg." .
+"array\e$B4D6-$^$?$O\e(Btabular\e$B4D6-$N0z?t!$$^$?$O\e(B\\multicolumn\e$BL?Na$NBh\e(B2\e$B0z?t\e(B
+\e$B$NCf$KIT@5$JJ8;z$,$"$j$^$7$?!%\e(B")
+
+ ("Missing \\\\begin{document}." .
+"\\begin{document}\e$BL?Na$h$jA0$K\e(BLaTeX\e$B$,=PNO$r9T$J$C$F$7$^$$$^$7$?!%\e(B
+\\begin{document}\e$BL?Na$rK:$l$?$+!$%W%j%"%s%V%k$K2?$+4V0c$$$,$"$k$N$G$7$g$&!%\e(B
+\e$BBG$A4V0c$$$K$h$kJ8;z$d!$@k8@$N8m$j$K$h$k2DG=@-$b$"$j$^$9!%Nc$($P!$0z?t$r\e(B
+\e$B0O$`3g8L$rH4$+$7$?$H$+!$L?NaL>$N\e(B\\\e$B$rK:$l$?>l9g$J$I$G$9!%\e(B")
+
+ ("Missing p-arg in array arg.*" .
+"array\e$B4D6-!&\e(Btabular\e$B4D6-$N0z?t!$$"$k$$$O\e(B\\multicolumn\e$BL?Na$NBh\e(B2\e$B0z?t$NCf$K!$\e(B
+\e$B3g8L$K0O$^$l$?I=8=$N$D$$$F$$$J$$\e(Bp\e$B$,$"$j$^$7$?!%\e(B")
+
+ ("Missing @-exp in array arg." .
+"array\e$B4D6-!&\e(Btabular\e$B4D6-$N0z?t!$$"$k$$$O\e(B\\multicolumn\e$BL?Na$NBh\e(B2\e$B0z?t$NCf$K!$\e(B
+@\e$BI=8=$N$D$$$F$$$J$$\e(B@\e$B$,$"$j$^$7$?!%\e(B")
+
+ ("No such counter." .
+"\\setcounter\e$BL?Na$^$?$O\e(B\\addtocounter\e$BL?Na$G!$B8:_$7$J$$%+%&%s%?$,;XDj$5$l\e(B
+\e$B$^$7$?!%$*$=$i$/$?$@$N%?%$%W%_%9$G$7$g$&!%$?$@$7!$%(%i!<$,\e(Baux\e$B%U%!%$%k$NCf\e(B
+\e$B$G@8$8$?>l9g$O!$\e(B\\newcounter\e$BL?Na$r%W%j%"%s%V%k$N30$G;H$C$?$N$@$H;W$o$l$^$9!%\e(B")
+
+ ("Not in outer par mode." .
+"figure\e$B4D6-!&\e(Btable\e$B4D6-$"$k$$$O\e(B\\marginpar\e$BL?Na$,?t<0%b!<%I$^$?$O\e(Bparbox\e$B$NCf\e(B
+\e$B$G;H$o$l$^$7$?!%\e(B")
+
+ ("\\\\pushtabs and \\\\poptabs don't match." .
+"\\pushtabs\e$B$HBP1~$7$J$$\e(B\\poptabs\e$B$,$_$D$+$C$?$+!$$^$?$O!$BP1~$9$k\e(B\\poptabs
+\e$B$r$b$?$J$$\e(B\\pushtabs\e$B$,$"$k$N$K\e(B\\end{tabbing}\e$B$,8=$l$F$7$^$$$^$7$?!%\e(B")
+
+ ("Something's wrong--perhaps a missing \\\\item." .
+"\e$B%j%9%H4D6-$NCf$K\e(B\\item\e$BL?Na$,$J$$$N$,:G$b$"$j$=$&$J%1!<%9$G$9!%\e(B
+thebibliography\e$B4D6-$G0z?t$rK:$l$?>l9g$K$b@8$8$^$9!%\e(B")
+
+ ("Tab overflow." .
+"\\=\e$B$,!$\e(BLaTeX\e$B$G5v$5$l$k%?%V%9%H%C%W$N:GBg?t$rD6$($F$$$^$9!%\e(B")
+
+ ("There's no line here to end." .
+"\\newline\e$BL?Na$^$?$O\e(B\\\\\e$BL?Na$,%Q%i%0%i%U4V$K$"$j$^$9!%$3$N;H$$$+$?$O\e(B
+\e$BL50UL#$G$9!%$b$76u9T$r$"$1$?$$$N$G$7$?$i!$\e(B\\vspace\e$B$r;H$C$F$/$@$5$$!%\e(B")
+
+ ("This may be a LaTeX bug." .
+"\e$B$^$C$?$/$o$1$,$o$+$i$J$/$J$C$F$7$^$$$^$7$?!%$?$V$s$3$l0JA0$K8!=P$5$l$?\e(B
+\e$B%(%i!<$N$;$$$@$H;W$o$l$^$9!%$7$+$7!$\e(BLaTeX\e$B<+BN$N%P%0$G$"$k2DG=@-$b$"$j$^$9!%\e(B
+\e$B$b$7$3$N%(%i!<$,F~NO%U%!%$%k$KBP$9$k:G=i$N%(%i!<$G$"$j!$2?$b4V0c$$$,8+$D\e(B
+\e$B$+$i$J$$>l9g$O!$$=$N%U%!%$%k$rJ]B8$7$F!$%m!<%+%k%,%$%I$K=q$+$l$F$$$k@UG$\e(B
+\e$B<T$KO"Mm$7$F$/$@$5$$!%\e(B")
+
+ ("Too deeply nested." .
+"\e$B%j%9%H4D6-$NF~$l;R$,?<$9$.$^$9!%2?CJ3,$NF~$l;R$,5v$5$l$k$+$O;H$C$F$$$k\e(B
+\e$B%3%s%T%e!<%?$K0MB8$7$^$9$,!$>/$J$/$H$b\e(B4\e$BCJ3,$^$G$O5v$5$l$F$$$^$9\e(B(\e$BIaDL$O\e(B
+\e$B$=$l$G==J,$G$7$g$&\e(B)\e$B!%\e(B")
+
+ ("Too many unprocessed floats." .
+"\e$B$3$N%(%i!<$O\e(B1\e$B%Z!<%8Cf$N\e(B\\marginpar\e$BL?Na$,B?$9$.$k$?$a$K@8$8$k>l9g$b$"\e(B
+\e$B$j$^$9$,!$$b$C$H$"$j$=$&$J$N$O!$8B3&$rD6$($F?^$dI=$rJ]B8$7$h$&$H$7$?>l\e(B
+\e$B9g$G$9!%D9$$J8=q$rAHHG$7$F$$$/$H$-!$\e(BLaTeX\e$B$O?^$dI=$r8D!9$KJ]B8$7!$%Z!<\e(B
+\e$B%8$NJ,3d$r9T$J$&;~$K$=$l$i$rA^F~$7$^$9!%$3$N%(%i!<$O!$%Z!<%8$X$NJ,3d$,\e(B
+\e$B9T$J$o$l$kA0$K!$$"$^$j$K$bB?$/$N\e(Bfigure\e$B4D6-$d\e(Btable\e$B4D6-$,8+$D$+$C$?>l9g\e(B
+\e$B$K@8$8$^$9!%$3$NLdBj$O4D6-$N$&$A$N$$$/$D$+$rJ8=q$N=*$o$j$NJ}$K0\F0$9$l\e(B
+\e$B$P2r7h$G$-$^$9!%$^$?!$$3$N%(%i!<$O\e(B``logjam''\e$B$K$h$C$F@8$8$k$3$H$b$"$j$^\e(B
+\e$B$9!%\e(B``logjam''\e$B$H$O!$\e(BLaTeX\e$B$,=P8==g=xDL$j$K$7$+?^I=$r=PNO$G$-$J$$$;$$$G!$\e(B
+\e$B$D$^$C$F$$$k8e$m$N?^I=$N$?$a$KA0$N?^I=$r=PNO$G$-$J$/$J$k$3$H$r$$$$$^$9!%\e(B
+\e$B$3$N%8%c%`$N860x$O!$Bg$-$9$.$F\e(B1\e$B%Z!<%8$J$$$7$O;XDj$5$l$?NN0h$K<}$^$i$J\e(B
+\e$B$$$h$&$J?^$dI=$G$"$k2DG=@-$,$"$j$^$9!%$3$l$O!$0z?t$K\e(Bp\e$B%*%W%7%g%s$,;XDj\e(B
+\e$B$5$l$F$$$J$$$H5/$-$d$9$/$J$j$^$9!%\e(B")
+
+ ("Undefined tab position." .
+"\\>\e$B!&\e(B\\+\e$B!&\e(B\\-\e$B$^$?$O\e(B\\<\e$BL?Na$G!$B8:_$7$J$$%?%V0LCV!$$9$J$o$A\e(B\\=\e$BL?Na$GDj\e(B
+\e$B5A$5$l$F$$$J$$%?%V0LCV$r;XDj$7$h$&$H$7$F$$$^$9!%\e(B")
+
+ ("\\\\< in mid line." .
+"\\<\e$BL?Na$,\e(Btabbing\e$B4D6-$N9T$NESCf$K8=$l$^$7$?!%$3$NL?Na$O9T$N@hF,$K$J$1$l$P\e(B
+\e$B$J$j$^$;$s!%\e(B")
+
+ ("Double subscript." .
+"\e$B?t<0Cf$N\e(B1\e$B$D$NNs$K\e(B2\e$B$D$N2<IU$-J8;z$,$D$$$F$$$^$9!%Nc$($P\e(Bx_{2}_{3}\e$B$N$h$&$K!%\e(B
+\e$B$3$N$h$&$JI=8=$OL50UL#$G$9!%\e(B")
+
+ ("Double superscript." .
+"\e$B?t<0Cf$N\e(B1\e$B$D$NNs$K\e(B2\e$B$D$N>eIU$-J8;z$,$D$$$F$$$^$9!%Nc$($P\e(Bx^{2}^{3}\e$B$N$h$&$K!%\e(B
+\e$B$3$N$h$&$JI=8=$OL50UL#$G$9!%\e(B")
+
+ ("Extra alignment tab has been changed to \\\\cr." .
+"array\e$B4D6-$^$?$O\e(Btabular\e$B4D6-$N\e(B1\e$BNsCf$K$"$k9`L\$,B?$9$.$^$9!%8@$$49$($k$H!$\e(B
+\e$BNs$N=*$o$j$^$G$K$"$k\e(B&\e$B$N?t$,B?$9$.$^$9!%$*$=$i$/A0$NNs$N:G8e$K\e(B\\\\\e$B$r$D$1\e(B
+\e$B$k$N$rK:$l$?$N$G$7$g$&!%\e(B")
+
+ ("Extra \\}, or forgotten \\$." .
+"\e$B3g8L$^$?$O?t<0%b!<%I$N%G%j%_%?$,@5$7$/BP1~$7$F$$$^$;$s!%$*$=$i$/\e(B{\e$B!&\e(B\\[\e$B!&\e(B
+\\(\e$B$"$k$$$O\e(B$\e$B$N$&$A$N$$$:$l$+$r=q$-K:$l$?$N$G$7$g$&!%\e(B")
+
+ ("Font [^ ]* not loaded: Not enough room left." .
+"\e$B$3$NJ8=q$O8B3&$h$j$bB?$/$N%U%)%s%H$r;H$C$F$$$^$9!%$b$7J8=q$NItJ,$4$H$K\e(B
+\e$BJL!9$N%U%)%s%H$,;H$o$l$F$$$k$N$J$i!$J,3d$7$F=hM}$9$l$PLdBj$O2r7h$5$l$^$9!%\e(B")
+
+ ("I can't find file `.*'." .
+"\e$BI,MW$J%U%!%$%k$,8+$D$+$j$^$;$s$G$7$?!%$b$78+$D$+$i$J$$%U%!%$%k$N3HD%;R\e(B
+\e$B$,\e(Btex\e$B$N>l9g!$$"$J$?$,;XDj$7$?%U%!%$%k!$$9$J$o$A%a%$%s%U%!%$%k$^$?$O\e(B
+\\input\e$BL?Na!&\e(B\\include\e$BL?Na$GA^F~$5$l$k%U%!%$%k$,8+$D$+$i$J$$$N$G$9!%\e(B
+\e$B3HD%;R$,\e(Bsty\e$B$G$"$l$P!$B8:_$7$J$$J8=q%9%?%$%k$^$?$O%9%?%$%k%*%W%7%g%s$r\e(B
+\e$B;XDj$7$h$&$H$7$F$$$^$9!%\e(B")
+
+ ("Illegal parameter number in definition of .*" .
+"\e$B$3$l$O$*$=$i$/!$\e(B\\newcommand\e$B!&\e(B\\renewcommand\e$B!&\e(B\\newenvironment\e$B$^$?$O\e(B
+\\renewenvironment\e$BL?Na$N$J$+$G\e(B#\e$B$,@5$7$/;H$o$l$J$+$C$?$?$a$K@8$8$?%(%i!<\e(B
+\e$B$G$9!%\e(B\\#\e$BL?Na$H$7$F;H$o$l$k>l9g$r=|$1$P!$\e(B#\e$B$H$$$&J8;z$O!$Nc$($P\e(B2\e$BHVL\$N\e(B
+\e$B0z?t$r;XDj$9$k\e(B#2\e$B$N$h$&$K!$0z?t%Q%i%a!<%?$H$7$F$7$+;H$($^$;$s!%$^$?!$\e(B
+\e$B$3$N%(%i!<$O!$>e$K$"$2$?\e(B4\e$B$D$N%3%^%s%I$,$*8_$$$KF~$l;R$K$J$C$F$$$k>l9g\e(B
+\e$B$d!$\e(B\\newenvironment\e$BL?Na!&\e(B\\renewenvironment\e$BL?Na$G\e(B#2\e$B$N$h$&$J%Q%i%a!<%?\e(B
+\e$B$,:G8e$N0z?t$NCf$G;H$o$l$F$$$k>l9g$K$b@8$8$^$9!%\e(B")
+
+ ("Illegal unit of measure ([^ ]* inserted)." .
+"\e$B$b$7\e(B
+ ! Missing number, treated as zero.
+\e$B$H$$$&%(%i!<$,5/$-$?D>8e$G$"$l$P!$$3$N%(%i!<$N860x$b$=$l$HF1$8$G$9!%\e(B
+\e$B$=$&$G$J$$>l9g$O!$\e(BLaTeX\e$B$,0z?t$H$7$F\e(Blength\e$B$r4|BT$7$F$$$k$N$K\e(Bnumber\e$B$,\e(B
+\e$B8=$l$?$3$H$r0UL#$7$F$$$^$9!%$3$N%(%i!<$N:G$b$"$j$,$A$J860x$OD9$5\e(B0\e$B$r\e(B
+\e$BI=$o$9\e(B0in\e$B$N$h$&$JI=8=$NBe$o$j$K\e(B0\e$B$H$+$$$F$7$^$&$3$H$K$"$j$^$9!%$?$@$7!$\e(B
+\e$BL?Na$N0z?t$r=q$-K:$l$?>l9g$K$b$3$N%(%i!<$,@8$8$k$3$H$,$"$j$^$9!%\e(B")
+
+ ("Misplaced alignment tab character \\&." .
+"array\e$B$^$?$O\e(Btabular\e$B4D6-$G$N9`L\6h@Z$j$K$N$_;H$o$l$k$Y$-J8;z\e(B&\e$B$,IaDL$NJ8\e(B
+\e$B$NCf$K$"$j$^$7$?!%$?$V$s\e(B\\&\e$B$HF~NO$7$?$+$C$?$N$G$7$g$&!%\e(B")
+
+ ("Missing control sequence inserted." .
+"\e$B$3$N%(%i!<$O!$$*$=$i$/L?NaL>$G$J$$$b$N$r\e(B\\newcommand\e$B!&\e(B\\renewcommand\e$B!&\e(B
+\\newlength\e$B$^$?$O\e(B\\newsavebox\e$B$NBh\e(B1\e$B0z?t$H$7$F;H$C$?$?$a$K@8$8$?$N$G$7$g$&!%\e(B")
+
+ ("Missing number, treated as zero." .
+"\e$B$3$N%(%i!<$O$?$$$F$$!$0z?t$H$7$F\e(Bnumber\e$B$^$?$O\e(Blength\e$B$rI,MW$H$7$F$$$kL?Na$K\e(B
+\e$BBP$7$F0z?t$,M?$($i$l$J$+$C$?$?$a$K@8$8$^$9!%0z?t$r=q$-K:$l$?$N$+!$%F%-%9%H\e(B
+\e$B$NCf$NBg3g8L\e(B([])\e$B$,%*%W%7%g%s0z?t$N;XDj$H4V0c$($i$l$F$7$^$C$?$+$N$I$A$i$+$G\e(B
+\e$B$7$g$&!%$^$?!$?t$r@8@.$9$k\e(B\\value\e$B$N$h$&$JL?Na$d\e(Blength\e$BL?Na$NA0$K\e(B\\protect\e$B$r\e(B
+\e$BCV$$$?>l9g$K$b$3$N%(%i!<$O@8$8$^$9!%\e(B")
+
+ ("Missing [{}] inserted." .
+"TeX\e$B$O4{$K$o$1$,$o$+$i$J$/$J$C$F$$$^$9!%%(%i!<%a%C%;!<%8$K$h$C$F<($5$l$F\e(B
+\e$B$$$k>l=j$O$?$V$sF~NO$K4V0c$$$,$"$C$?$H$3$m$h$j$b8e$m$K$J$C$F$7$^$C$F$$$k\e(B
+\e$B$G$7$g$&!%\e(B")
+
+ ("Missing \\$ inserted." .
+"\e$B$*$=$i$/!$?t<0%b!<%ICf$G$7$+;H$($J$$L?Na$r\e(BTeX\e$B$,?t<0%b!<%I30$G8!=P$7$?\e(B
+\e$B$N$@$H;W$o$l$^$9!%FC$K5-=R$5$l$F$$$J$$8B$j!$\e(BLaTeX Book(Lamport\e$BCx\e(B,\e$BLu=q\e(B
+\e$B$O%"%9%-!<=PHG\e(B)\e$B$N\e(B3.3\e$B@a$K$"$kE:;z!&J,?t!&?t3X5-9f$J$I$N%3%^%s%I$O$9$Y$F\e(B
+\e$B?t<0%b!<%I$G$7$+;H$($J$$$N$@$H$$$&$3$H$KCm0U$7$F$/$@$5$$!%$?$H$(L?Na$,\e(B
+\e$B?t<04D6-$NCf$K$"$C$?$H$7$F$b!$\e(Bbox\e$B$r@8@.$9$kL?Na$N0z?t$r=hM}$7$O$8$a$?\e(B
+\e$B;~E@$G$O!$\e(BTeX\e$B$O$^$@?t<0%b!<%I$KF~$C$F$$$J$$$N$G$9!%$^$?!$$3$N%(%i!<$O!$\e(B
+\e$B?t<0%b!<%ICf$G\e(BTeX\e$B$,6u9T$r8!=P$7$?>l9g$K$b@8$8$^$9!%\e(B")
+
+ ("Not a letter." .
+"\\hyphenation\e$BL?Na$N0z?t$NCf$K$J$K$+@5$7$/$J$$$b$N$,$"$j$^$9!%\e(B")
+
+ ("Paragraph ended before [^ ]* was complete." .
+"\e$BL?Na$N0z?t$NCf$KIT@5$J6u9T$,F~$C$F$7$^$C$F$$$^$9!%$*$=$i$/0z?t$N=*$o$j\e(B
+\e$B$KJD$83g8L$r$D$1$k$N$rK:$l$?$N$G$7$g$&!%\e(B")
+
+ ("\\\\[^ ]*font [^ ]* is undefined .*" .
+"\e$B$3$N%(%i!<$O$"$^$j0lHLE*$G$J$$%U%)%s%H$,?t<0%b!<%I$G;H$o$l$?;~$K@8$8\e(B
+\e$B$^$9!%Nc$($P!$5SCm$NCf$N?t<0$G\e(B\\sc\e$BL?Na$,;H$o$l$k$H!$\e(Bfootnotesize\e$B$N\e(B
+small caps\e$B%U%)%s%H$,8F$S$@$5$l$k$3$H$K$J$j$^$9!%$3$NLdBj$O\e(B\\load\e$BL?Na$r\e(B
+\e$B;H$($P2r7h$G$-$^$9!%\e(B")
+
+ ("Font .* not found." .
+"\e$BL$CN$N\e(Bfamily/series/shape/size\e$B$NAH$_9g$o$;$N%U%)%s%H$,;XDj$5$l$^$7$?!%\e(B
+\e$B$3$N%(%i!<$,5/$-$k%1!<%9$O\e(B2\e$B$D9M$($i$l$^$9!%\e(B
+ 1) \\size\e$B%^%/%m$G;H$($J$$%5%$%:$rA*Br$7$h$&$H$7$?!%\e(B
+ 2) \e$B$=$&$G$J$1$l$P!$4IM}<T$N$H$3$m$K9T$C$F!$%U%)%s%HA*Br%F!<%V%k$,\e(B
+ \e$BIe$C$F$$$k$HJ86g$r$D$1$F$d$j$^$7$g$&\e(B!")
+
+ ("TeX capacity exceeded, sorry .*" .
+"TeX\e$B$,%a%b%j$r;H$$$-$C$F$7$^$$!$<B9T$rCfCG$7$^$7$?!%$7$+$7!$92$F$J$$$G\e(B
+\e$B$/$@$5$$!%$3$N%(%i!<$,@8$8$?860x$O!$$?$V$s!$\e(BTeX\e$B$K$"$J$?$NJ8=q$r=hM}$G\e(B
+\e$B$-$k$@$1$NG=NO$,$J$$$+$i$G$O$"$j$^$;$s!%\e(BTeX\e$B$K%a%b%j$r;H$$$-$i$;$?860x\e(B
+\e$B$O!$$*$=$i$/F~NO$7$?%U%!%$%k$NA0$NJ}$G@8$8$?%(%i!<$G$9!%$"$J$?$,K\Ev$K\e(B
+TeX\e$B$NMFNL$rD6$($?$3$H$r$7$h$&$H$7$?$N$+$I$&$+!$$=$7$F$=$N>l9g$I$&$9$l\e(B
+\e$B$P$$$$$N$+$rH=CG$9$kJ}K!$r0J2<$K@bL@$7$^$9!%$b$7LdBj$,F~NO%U%!%$%kCf$N\e(B
+\e$B%(%i!<$K$"$k>l9g$O!$8D!9$N%(%i!<$r2r7h$7$F$$$/J}K!$r$H$k$N$,$h$$$G$7$g\e(B
+\e$B$&!%\e(BLaTeX\e$B$,C;$$%U%!%$%k$G%a%b%j$r;H$$$-$k$3$H$O$a$C$?$K$"$j$^$;$s$+$i!$\e(B
+\e$B%(%i!<$N5/$-$?0LCV$h$jA0$K=hM}$7$?%Z!<%8$,?t%Z!<%8$7$+$J$1$l$P!$$^$:4V\e(B
+\e$B0c$$$J$/F~NO%U%!%$%k$KLdBj$,$"$k$O$:$G$9!%\e(B
+
+\e$B%(%i!<%a%C%;!<%8$N:G8e$K!$\e(BTeX\e$B$,;H$$$-$C$F$7$^$C$?%a%b%j$N<oN`$,<($5$l\e(B
+\e$B$F$$$^$9!%$=$l$i$N$&$A0lHLE*$J$b$N$K$D$$$F!$9M$($i$l$k860x$r0J2<$K5s$2\e(B
+\e$B$^$9!%\e(B
+
+buffer size
+===========
+\e$B>O@a!&\e(B\\caption\e$B!&\e(B\\addcontentsline\e$B$"$k$$$O\e(B\\addtocontents\e$BL?Na$N0z?t$H\e(B
+\e$B$7$FM?$($?%F%-%9%H$,D9$9$.$k>l9g$K@8$8$k$3$H$,$"$j$^$9!%$3$N%(%i!<$O\e(B
+\e$B$?$$$F$$\e(B\\end{document}\e$B$r=hM}$7$F$$$k;~$K@8$8$^$9$,!$\e(B\\tableofcontents\e$B!&\e(B
+\\listoffigures\e$B$"$k$$$O\e(B\\listoftables\e$BL?Na$r<B9T$7$F$$$k>l9g$K$b5/$-$k\e(B
+\e$B$3$H$,$"$j$^$9!%$3$NLdBj$r2r7h$9$k$K$O!$$b$C$HC;$$%F%-%9%H$r%*%W%7%g%s\e(B
+\e$B0z?t$H$7$FM?$($F$/$@$5$$!%L\<!$d?^I=0lMw$r:n@.$7$F$b!$8+=P$7$,D9$9$.$k\e(B
+\e$B$HFI$_$K$/$/$J$k$O$:$G$9!%\e(B
+
+exception dictionary
+====================
+TeX\e$B$,;}$C$F$$$kNN0h0J>e$K%O%$%U%M!<%7%g%s>pJs$rM?$($h$&$H$7$F$$$^$9!%\e(B
+\e$B$"$^$j;H$o$J$$C18l$N\e(B\\hyphenation\e$BL?Na$r<h$j=|$$$F!$Be$o$j$K\e(B\\-\e$BL?Na$r;H$C\e(B
+\e$B$F$/$@$5$$!%\e(B
+
+hash size
+=========
+\e$BL?NaL>$NDj5A$^$?$OAj8_;2>H%i%Y%k$NDj5A$,B?$9$.$^$9!%\e(B
+
+input stack size
+================
+\e$B$3$N%(%i!<$O$*$=$i$/L?NaDj5ACf$N8m$j$K$h$k$b$N$G$9!%Nc$($P!$<!$NL?Na$O\e(B
+\e$B:F5"E*Dj5A$H$J$C$F$*$j!$<+J,<+?H$r;H$C$F\e(B\\gnu\e$B$rDj5A$7$F$$$^$9!%\e(B
+
+ \\newcommand{\\gnu}{a \\gnu} % \e$B$3$l$O$@$a\e(B
+
+\e$B$3$N\e(B\\gnu\e$BL?Na$r8+$D$1$k$H\e(BTeX\e$B$O\e(B\\gnu\e$B$,2?$r$&$_$@$9$N$+$r7hDj$7$h$&$H$7\e(B
+\e$B$F$=$NKvHx$r$$$D$^$G$bDI$$$D$E$1!$$d$,$F\e(B``input stack''\e$B$r;H$$$-$C$F$7\e(B
+\e$B$^$$$^$9!%\e(B
+
+main memory size
+================
+\e$B$3$l$O!$\e(BTeX\e$B$,C;$$%U%!%$%k$r=hM}$7$F$$$k;~$K;H$$$-$k2DG=@-$N$"$k%a%b%j\e(B
+\e$B$N$R$H$D$G$9!%\e(Bmain memory\e$B$r;H$$$-$k$N$O<!$N\e(B3\e$B$D$N>l9g$N$$$:$l$+$G$9!%\e(B
+\(1\)\e$BHs>o$KD9$/J#;($JL?Na$r?tB?$/Dj5A$7$?!%\e(B(2)index\e$B$^$?$O\e(Bglossary\e$B$r:n$C\e(B
+\e$B$F$$$k$H$-!$\e(B1\e$B%Z!<%8Cf$K$"$^$j$K$bB?$/$N\e(B\\index\e$B$^$?$O\e(B\\glossary\e$BL?Na$,$"\e(B
+\e$B$k!%\e(B(3)\e$B@8@.$N$?$a$N>pJs$r\e(BTeX\e$B$,J];}$7$-$l$J$$$h$&$J!$$"$^$j$K$bJ#;($J%Z!<\e(B
+\e$B%8$r@8@.$7$h$&$H$7$?!%:G=i$N\e(B2\e$B$D$NLdBj$N2r7hJ}K!$OL@$i$+$G$9!%L?NaDj5A\e(B
+\e$B$N?t$"$k$$$O\e(B\\index\e$B!&\e(B\\glossary\e$BL?Na$N?t$r8:$i$9$3$H$G$9!%\e(B3\e$BHVL\$NLdBj$O\e(B
+\e$B$A$g$C$HLq2p$G$9!%$3$l$O!$Bg$-$J\e(Btabbing\e$B!&\e(Btabular\e$B!&\e(Barray\e$B!&\e(Bpicture\e$B4D6-$N\e(B
+\e$B$;$$$G@8$8$k$3$H$,$"$j$^$9!%=PNO0LCV$,7hDj$5$l$k$N$rBT$C$F$$$k?^$dI=$G\e(B
+TeX\e$B$N%a%b%j$,$$$C$Q$$$K$J$C$F$$$k$N$+$b$7$l$^$;$s!%K\Ev$K\e(BTeX\e$B$NMFNL$rD6\e(B
+\e$B$($F$7$^$C$?$N$+$I$&$+D4$Y$k$?$a$K$O!$%(%i!<$N5/$3$C$?>l=j$ND>A0$K\e(B
+\\clearpage\e$BL?Na$rF~$l$F$b$&0lEY%3%s%Q%$%k$r<B9T$7$F$_$F$/$@$5$$!%$b$7\e(B
+\e$B$=$l$G$b%a%b%j$,B-$j$J$/$J$k$h$&$J$i!$$J$s$i$+$N<jCJ$r9V$8$kI,MW$,$"$j\e(B
+\e$B$^$9!%\e(BTeX\e$B$,%Z!<%8$r@ZCG$9$k$+$I$&$+7hDj$9$k$?$a$K$OCJMnA4BN$r=hM}$7$J\e(B
+\e$B$1$l$P$J$i$J$$$H$$$&$3$H$r;W$$$@$7$F$/$@$5$$!%CJMn$NESCf$K\e(B\\newpage\e$BL?\e(B
+\e$BNa$rF~$l$l$P!$CJMn$N;D$j$r=hM}$9$kA0$K:#$N%Z!<%8$r\e(BTeX\e$B$K=PNO$5$;$k$3$H\e(B
+\e$B$GM>M5$,$G$-$k$+$b$7$l$^$;$s\e(B(\\pagebreak\e$BL?Na$G$O$@$a$G$9\e(B)\e$B!%$b$7?^$dI=\e(B
+\e$B$,N/$^$C$F$$$k$3$H$,LdBj$J$N$J$i$P!$?^I=$r$b$C$H8e$m$NJ}$K0\F0$9$k$H$+!$\e(B
+\e$B$"$k$$$O$b$C$HA0$N;~E@$G=PNO$5$l$k$h$&$K$9$l$P2sHr$G$-$^$9!%$b$7$^$@J8\e(B
+\e$B=q$r:n@.$7$F$$$kESCf$J$i!$$H$j$"$($:\e(B\\clearpage\e$BL?Na$rF~$l$F$*$$$F!$:G\e(B
+\e$B=*HG$r:n$k;~$^$G$3$NLdBj$OC*>e$2$7$F$*$-$^$7$g$&!%F~NO%U%!%$%k$,JQ$o$k\e(B
+\e$B$HLdBj$,2r>C$5$l$k>l9g$b$"$k$N$G$9!%\e(B
+
+pool size
+=========
+\e$BAj8_;2>H$N\e(B\\label\e$B$,B?$9$.$k$+!$L?Na$NDj5A$,B?$9$.$k$+$N$I$A$i$+$G$9!%\e(B
+\e$B@53N$K$$$($P!$Dj5A$7$?%i%Y%kL>$*$h$SL?NaL>$K;H$C$?J8;z?t$,B?$9$.$k$H$$\e(B
+\e$B$&$3$H$G$9!%$G$9$+$i!$$b$C$HC;$$L>A0$r;H$($P$3$NLdBj$O2r7h$7$^$9!%$?$@\e(B
+\e$B$7!$$3$N%(%i!<$O!$\e(B\\setcounter\e$B$J$I$N%+%&%s%?L?Na$d\e(B\\newenvironment\e$B!&\e(B
+\\newtheorem\e$BL?Na$N0z?t$N=*$o$j$r<($91&3g8L$rK:$l$?>l9g$K$b@8$8$^$9!%\e(B
+
+save size
+=========
+\e$B$3$N%(%i!<$O!$@k8@$NM-8zHO0O$dL?Na!&4D6-$,$"$^$j$K$b?<$/F~$l;R$K$J$C$F\e(B
+\e$B$$$k>l9g$K@8$8$^$9!%$?$H$($P!$\e(B\\multiput\e$BL?Na$N0z?t$K\e(Bpicture\e$B4D6-$,$"$j!$\e(B
+\e$B$=$N$J$+$K\e(B\\footnotesize\e$B@k8@$,$"$j!$$=$N@k8@$NM-8zHO0O$K\e(B\\multiput\e$BL?Na\e(B
+\e$B$,$"$C$F!$$=$N0z?t$K\e(B... \e$B$H$$$&$h$&$J>l9g$G$9!%\e(B")
+
+ ("Text line contains an invalid character." .
+"\e$BF~NOCf$KIT@5$JJ8;z$,4^$^$l$F$$$^$9!%%U%!%$%k:n@.$N8m$j$K$h$C$F%F%-%9%H\e(B
+\e$B%(%G%#%?$,$3$NJ8;z$rA^F~$7$F$7$^$C$?$N$G$7$g$&!%<B:]$K2?$,5/$-$?$N$+$O\e(B
+\e$B%(%G%#%?$K$h$j$^$9!%F~NO%U%!%$%k$rD4$Y$F$_$F!$;XE&$5$l$?J8;z$,8+$D$+$i\e(B
+\e$B$J$$>l9g$K$O%m!<%+%k%,%$%I$r8+$F$/$@$5$$!%\e(B")
+
+ ("Undefined control sequence." .
+"TeX\e$B$,L$Dj5A$NL?NaL>$rH/8+$7$^$7$?!%$*$=$i$/F~NO$N8m$j$G$7$g$&!%$b$7$3\e(B
+\e$B$N%(%i!<$,\e(BLaTeX\e$BL?Na$N=hM}Cf$K@8$8$?>l9g$O!$$=$NL?Na$O4V0c$C$?0LCV$KCV$+\e(B
+\e$B$l$F$$$^$9!%Nc$($P!$%j%9%H4D6-$NCf$G$J$$$N$K\e(B\\item\e$BL?Na$,;H$o$l$?>l9g$J$I\e(B
+\e$B$G$9!%$^$?!$\e(B\\documentclass\e$BL?Na$,$J$$>l9g$K$b$3$N%(%i!<$,@8$8$^$9!%\e(B")
+
+ ("Use of [^ ]* doesn't match its definition." .
+"\e$B$*$=$i$/IA2h$N$?$a$NL?Na$@$H;W$o$l$^$9$,!$0z?t$N;H$$$+$?$,4V0c$C$F$$\e(B
+\e$B$^$9!%4V0c$C$F$$$k$N$,\e(B\\@array\e$BL?Na$N>l9g$O!$\e(Barray\e$B4D6-$+\e(Btabular\e$B4D6-$G$N\e(B
+@\e$BI=8=$N0z?t$K$J$K$+8m$j$,$"$k$N$G$7$g$&!%\e(Bfragile\e$B$JL?Na$,\e(B\\protect\e$B$5$l$F\e(B
+\e$B$$$J$$$N$+$b$7$l$^$;$s!%\e(B")
+
+ ("You can't use `macro parameter character \\#' in [^ ]* mode." .
+"\e$BFC<lJ8;z\e(B#\e$B$,IaDL$N%F%-%9%H$NCf$K8=$l$^$7$?!%$*$=$i$/\e(B\\#\e$B$H=q$-$?$+$C$?\e(B
+\e$B$N$G$7$g$&!%\e(B")
+
+ ("Overfull \\\\hbox .*" .
+"\e$B9TJ,3d$N$?$a$NE,@Z$J>l=j$,8+$D$+$i$J$+$C$?$N$G!$\e(B1\e$B9T$K<}$^$k$Y$-J,NL0J>e\e(B
+\e$B$N=PNO$,9T$J$o$l$F$7$^$$$^$7$?!%\e(B")
+
+ ("Overfull \\\\vbox .*" .
+"\e$B%Z!<%8J,3d$N$?$a$NE,@Z$J>l=j$,8+$D$+$i$J$+$C$?$N$G!$\e(B1\e$B%Z!<%8$K<}$^$k$Y$-\e(B
+\e$BJ,NL0J>e$N=PNO$,9T$J$o$l$F$7$^$$$^$7$?!%\e(B")
+
+ ("Underfull \\\\hbox .*" .
+"\e$BM>J,$J?bD>%9%Z!<%9$,$J$$$+$I$&$+=PNO$r3N$+$a$F$/$@$5$$!%$b$7$"$l$P!$$=\e(B
+\e$B$l$O\e(B\\\\\e$BL?Na$^$?$O\e(B\\newline\e$BL?Na$K4X78$9$kLdBj$N$?$a$K@8$8$?$b$N$G$9!%Nc\e(B
+\e$B$($P\e(B2\e$B$D$N\e(B\\\\\e$BL?Na$,B3$$$F$$$k>l9g$J$I$G$9!%$3$N7Y9p$O\e(Bsloppypar\e$B4D6-$d\e(B
+\\sloppy\e$B@k8@$N;HMQ!$$"$k$$$O\e(B\\linebreak\e$BL?Na$NA^F~$J$I$K$h$k>l9g$b$"$j$^$9!%\e(B")
+
+ ("Underfull \\\\vbox .*" .
+"\e$B%Z!<%8$rJ,3d$9$k$?$a$NE,@Z$J>l=j$,8+$D$1$i$l$:!$==J,$J%F%-%9%H$N$J$$\e(B
+\e$B%Z!<%8$,$G$-$F$7$^$$$^$7$?!%\e(B")
+
+;; New list items should be placed here
+;;
+;; ("err-regexp" . "context")
+;;
+;; the err-regexp item should match anything
+
+ (".*" . "\e$B$4$a$s$J$5$$!%3:Ev$9$k%X%k%W%a%C%;!<%8$,$"$j$^$;$s!%\e(B"))))
+
+(provide 'tex-jp)
+
+;;; tex-jp.el ends here
--- /dev/null
+;;; tex-mik.el --- MiKTeX support for AUCTeX.
+
+;; Copyright (C) 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
+
+;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
+;; Maintainer: auctex-devel@gnu.org
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+;;
+;; This file contains variables customized for MiKTeX.
+
+;;; Code:
+
+ ;; Remove the Queue entry from the default, and make a non-Unix
+ ;; specific print entry, assuming that we'll print via gsview32.
+(unless (get 'TeX-queue-command 'saved-value)
+ (setq TeX-queue-command nil))
+
+(unless (get 'TeX-printer-list 'saved-value)
+ (setq TeX-printer-list nil))
+
+(unless (get 'TeX-print-command 'saved-value)
+ (setq TeX-print-command
+ "start \"\" %f"))
+
+(unless (get 'TeX-view-style 'saved-value)
+ (setq TeX-view-style '(("^epsf$" "start \"\" %f")
+ ("." "yap -1 %dS %d"))))
+
+(unless (get 'TeX-output-view-style 'saved-value)
+ (setq TeX-output-view-style
+ '(("^dvi$" "^pstricks$\\|^pst-\\|^psfrag$" "dvips %d -o && start \"\" %f")
+ ("^dvi$" "." "yap -1 %dS %d")
+ ("^pdf$" "." "start \"\" %o")
+ ("^html?$" "." "start \"\" %o"))))
+
+(unless (get 'TeX-source-specials-view-position-flags 'saved-value)
+ (setq TeX-source-specials-view-position-flags "-s %n%b"))
+
+;; Yap does not support a command line option for inverse searching.
+;; The editor command has to be configured inside Yap in
+;; "View/Options/Inverse Search" instead.
+(unless (get 'TeX-source-specials-view-editor-flags 'saved-value)
+ (setq TeX-source-specials-view-editor-flags ""))
+
+;; kpsewhich in MiKTeX (aka findtexmf) does not emit any useful
+;; information if fed with kpathsea-related variables anyway.
+(unless (get 'TeX-kpathsea-path-delimiter 'saved-value)
+ (setq TeX-kpathsea-path-delimiter nil))
+
+(provide 'tex-mik)
+
+;;; tex-mik.el ends here
--- /dev/null
+;;; tex-site.el - Site specific variables. Don't edit.
+
+;; Copyright (C) 2005 Free Software Foundation, Inc.
+;;
+;; completely rewritten.
+
+;; Author: David Kastrup <dak@gnu.org>
+;; Maintainer: auctex-devel@gnu.org
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file contains startup code, autoloads and variables adapted to
+;; the local site configuration. It is generated and placed by the
+;; installation procedure and should not be edited by hand, nor moved
+;; to a different place, as some settings may be established relative
+;; to the file.
+
+;; All user customization should be done with
+;; M-x customize-variable RET
+
+;;; Code:
+
+(if (< emacs-major-version 21)
+ (error "AUCTeX requires Emacs 21 or later"))
+
+;; Define here in order for `M-x customize-group <RET> AUCTeX <RET>'
+;; to work if the main AUCTeX files are not loaded yet.
+(defgroup AUCTeX nil
+ "A (La)TeX environment."
+ :tag "AUCTeX"
+ :link '(custom-manual "(auctex)Top")
+ :link '(url-link :tag "Home Page" "http://www.gnu.org/software/auctex/")
+ :prefix "TeX-"
+ :group 'tex
+ :load "tex" :load "latex" :load "tex-style")
+
+(defvar TeX-lisp-directory (file-name-directory load-file-name)
+ "The directory where most of the AUCTeX lisp files are located.
+For the location of lisp files associated with
+styles, see the variables TeX-style-* (hand-generated lisp) and
+TeX-auto-* (automatically generated lisp).")
+
+(add-to-list 'load-path TeX-lisp-directory)
+
+(defvar TeX-data-directory (file-name-directory load-file-name)
+ "The directory where the AUCTeX non-Lisp data is located.")
+
+(defcustom TeX-auto-global "/usr/local/var/auctex"
+ "Directory containing automatically generated information.
+Must end with a directory separator.
+
+For storing automatic extracted information about the TeX macros
+shared by all users of a site."
+ :group 'TeX-file
+ :type 'directory)
+
+(defconst TeX-mode-alist
+ '((tex-mode . tex-mode)
+ (plain-tex-mode . tex-mode)
+ (texinfo-mode . texinfo)
+ (latex-mode . tex-mode)
+ (doctex-mode . tex-mode))
+ "Alist of built-in TeX modes and their load files.")
+
+(defalias 'TeX-load-hack 'ignore)
+
+(add-hook 'tex-site-unload-hook
+ (lambda ()
+ (let ((list after-load-alist))
+ (while list
+ ;; Adapted copy of the definition of `assq-delete-all'
+ ;; from Emacs 21 as substitute for
+ ;; `(assq-delete-all'TeX-modes-set (car list))' which
+ ;; fails on non-list elements in Emacs 21.
+ (let* ((alist (car list))
+ (tail alist)
+ (key 'TeX-modes-set))
+ (while tail
+ (if (and (consp (car tail))
+ (eq (car (car tail)) key))
+ (setq alist (delq (car tail) alist)))
+ (setq tail (cdr tail))))
+ (setq list (cdr list))))
+ (setq load-path (delq TeX-lisp-directory load-path))))
+
+(defun TeX-modes-set (var value &optional update)
+ "Set VAR (which should be `TeX-modes') to VALUE.
+
+This places either the standard or the AUCTeX versions of
+functions into the respective function cell of the mode.
+If UPDATE is set, a previously saved value for
+the non-AUCTeX function gets overwritten with the current
+definition."
+ (custom-set-default var value)
+ (let ((list TeX-mode-alist) elt)
+ (while list
+ (setq elt (car (pop list)))
+ (when (or update (null (get elt 'tex-saved)))
+ (when (fboundp elt)
+ (put elt 'tex-saved (symbol-function elt))))
+ (defalias elt
+ (if (memq elt value)
+ (intern (concat "TeX-" (symbol-name elt)))
+ (get elt 'tex-saved))))))
+
+(defcustom TeX-modes
+ (mapcar 'car TeX-mode-alist)
+ "List of modes provided by AUCTeX.
+
+This variable can't be set normally; use customize for that, or
+set it with `TeX-modes-set'."
+ :type (cons 'set
+ (mapcar (lambda(x) (list 'const (car x))) TeX-mode-alist))
+ :set 'TeX-modes-set
+ :group 'AUCTeX
+ :initialize (lambda (var value)
+ (custom-initialize-reset var value)
+ (let ((list TeX-mode-alist))
+ (while list
+ (eval-after-load (cdar list)
+ `(TeX-modes-set ',var ,var t))
+ (setq list (cdr list))))))
+
+(defconst AUCTeX-version "11.86"
+ "AUCTeX version.
+If not a regular release, the date of the last change.")
+
+(defconst AUCTeX-date "2010-02-21"
+ "AUCTeX release date using the ISO 8601 format, yyyy-mm-dd.")
+
+;; Store bibitems when saving a BibTeX buffer
+(add-hook 'bibtex-mode-hook 'BibTeX-auto-store)
+
+\f
+;;; Code specific to ELPA packaging:
+
+;; From preview-latex.el:
+
+(defvar preview-TeX-style-dir
+ (expand-file-name "latex" (file-name-directory load-file-name)))
+
+;;; Ensure that loading the autoloads file also loads this file.
+;;;###autoload (require 'tex-site)
+
+(provide 'tex-site)
+;;; tex-site.el ends here
--- /dev/null
+;;; tex-style.el --- Customizable variables for AUCTeX style files
+
+;; Copyright (C) 2005 Free Software Foundation, Inc.
+
+;; Author: Reiner Steib <Reiner.Steib@gmx.de>
+;; Keywords: tex, wp, convenience
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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; see the file COPYING. If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file provides customizable variables for AUCTeX style files.
+
+;;; Code:
+
+(defgroup LaTeX-style nil
+ "Support for special LaTeX style files in AUCTeX."
+ :group 'LaTeX-macro)
+
+;; Note: We don't have any defcustom in plain TeX style files yet. Else we
+;; should also create a TeX-style group.
+
+;; style/amsmath.el
+
+(defcustom LaTeX-amsmath-label nil
+ "Default prefix to amsmath equation labels.
+
+Amsmath equations include \"align\", \"alignat\", \"xalignat\",
+\"multline\", \"flalign\" and \"gather\". If it is nil,
+`LaTeX-equation-label' is used."
+ :group 'LaTeX-label
+ :type '(choice (const :tag "Use `LaTeX-equation-label'" nil)
+ (string)))
+
+;; style/beamer.el
+
+(defcustom LaTeX-beamer-section-labels-flag nil
+ "If non-nil section labels are added"
+ :type 'boolean
+ :group 'LaTeX-style)
+
+(defcustom LaTeX-beamer-item-overlay-flag t
+ "If non-nil do prompt for an overlay in itemize-like environments."
+ :type 'boolean
+ :group 'LaTeX-style)
+
+(defcustom LaTeX-beamer-themes 'local
+ "Presentation themes for the LaTeX beamer package.
+It can be a list of themes or a function. If it is the symbol
+`local', search only once per buffer."
+ :group 'LaTeX-style
+ :type
+ '(choice
+ (const :tag "TeX search" LaTeX-beamer-search-themes)
+ (const :tag "Search once per buffer" local)
+ (function :tag "Other function")
+ (list
+ :value
+ ;; Work around (bug in customize?), see
+ ;; <news:v9is48jrj1.fsf@marauder.physik.uni-ulm.de>
+ ("Antibes" "Bergen" "Berkeley" "Berlin" "Boadilla" "Copenhagen"
+ "Darmstadt" "Dresden" "Frankfurt" "Goettingen" "Hannover"
+ "Ilmenau" "JuanLesPins" "Luebeck" "Madrid" "Malmoe" "Marburg"
+ "Montpellier" "PaloAlto" "Pittsburgh" "Rochester" "Singapore"
+ "Szeged" "Warsaw")
+ (set :inline t
+ (const "Antibes")
+ (const "Bergen")
+ (const "Berkeley")
+ (const "Berlin")
+ (const "Boadilla")
+ (const "Copenhagen")
+ (const "Darmstadt")
+ (const "Dresden")
+ (const "Frankfurt")
+ (const "Goettingen")
+ (const "Hannover")
+ (const "Ilmenau")
+ (const "JuanLesPins")
+ (const "Luebeck")
+ (const "Madrid")
+ (const "Malmoe")
+ (const "Marburg")
+ (const "Montpellier")
+ (const "PaloAlto")
+ (const "Pittsburgh")
+ (const "Rochester")
+ (const "Singapore")
+ (const "Szeged")
+ (const "Warsaw"))
+ (repeat :inline t
+ :tag "Other"
+ (string)))))
+
+(defcustom LaTeX-beamer-inner-themes 'local
+ "Presentation inner themes for the LaTeX beamer package.
+It can be a list of themes or a function. If it is the symbol
+`local', search only once per buffer."
+ :group 'LaTeX-style
+ :type '(choice
+ (const :tag "TeX search" LaTeX-beamer-search-inner-themes)
+ (const :tag "Search once per buffer" local)
+ (function :tag "Other function")
+ (list
+ :value ("circles" "default" "inmargin" "rectangles" "rounded")
+ (set :inline t
+ (const "circles")
+ (const "default")
+ (const "inmargin")
+ (const "rectangles")
+ (const "rounded"))
+ (repeat :inline t
+ :tag "Other"
+ (string)))))
+
+(defcustom LaTeX-beamer-outer-themes 'local
+ "Presentation outer themes for the LaTeX beamer package.
+It can be a list of themes or a function. If it is the symbol
+`local', search only once per buffer."
+ :group 'LaTeX-style
+ :type
+ '(choice
+ (const :tag "TeX search" LaTeX-beamer-search-outer-themes)
+ (const :tag "Search once per buffer" local)
+ (function :tag "Other function")
+ (list
+ :value
+ ("default" "infolines" "miniframes" "shadow" "sidebar" "smoothbars"
+ "smoothtree" "split" "tree")
+ (set :inline t
+ (const "default")
+ (const "infolines")
+ (const "miniframes")
+ (const "shadow")
+ (const "sidebar")
+ (const "smoothbars")
+ (const "smoothtree")
+ (const "split")
+ (const "tree"))
+ (repeat :inline t
+ :tag "Other"
+ (string)))))
+
+(defcustom LaTeX-beamer-color-themes 'local
+ "Presentation color themes for the LaTeX beamer package.
+It can be a list of themes or a function. If it is the symbol
+`local', search only once per buffer."
+ :group 'LaTeX-style
+ :type
+ '(choice
+ (const :tag "TeX search" LaTeX-beamer-search-color-themes)
+ (const :tag "Search once per buffer" local)
+ (function :tag "Other function")
+ (list
+ :value
+ ("albatross" "beetle" "crane" "default" "dolphin" "dove" "fly" "lily"
+ "orchid" "rose" "seagull" "seahorse" "sidebartab" "structure" "whale")
+ (set :inline t
+ (const "albatross")
+ (const "beetle")
+ (const "crane")
+ (const "default")
+ (const "dolphin")
+ (const "dove")
+ (const "fly")
+ (const "lily")
+ (const "orchid")
+ (const "rose")
+ (const "seagull")
+ (const "seahorse")
+ (const "sidebartab")
+ (const "structure")
+ (const "whale"))
+ (repeat :inline t
+ :tag "Other"
+ (string)))))
+
+(defcustom LaTeX-beamer-font-themes 'local
+ "Presentation font themes for the LaTeX beamer package.
+It can be a list of themes or a function. If it is the symbol
+`local', search only once per buffer."
+ :group 'LaTeX-style
+ :type
+ '(choice
+ (const :tag "TeX search" LaTeX-beamer-search-font-themes)
+ (const :tag "Search once per buffer" local)
+ (function :tag "Other function")
+ (list
+ :value
+ ("default" "professionalfonts" "serif" "structurebold"
+ "structureitalicserif" "structuresmallcapsserif")
+ (set :inline t
+ (const "default")
+ (const "professionalfonts")
+ (const "serif")
+ (const "structurebold")
+ (const "structureitalicserif")
+ (const "structuresmallcapsserif"))
+ (repeat :inline t
+ :tag "Other"
+ (string)))))
+
+;; style/comment.el
+
+(defcustom LaTeX-comment-env-list '("comment")
+ "List of environment names defined with comment.sty.
+Setting this variable does not take effect unless you
+reinitialize affected buffers."
+ :type '(repeat string)
+ :group 'LaTeX-style)
+
+;; style/csquotes.el
+
+(defcustom LaTeX-csquotes-quote-after-quote nil
+ "Initial value of `TeX-quote-after-quote' for `csquotes.el'"
+ :type 'boolean
+ :group 'LaTeX-style)
+
+(defcustom LaTeX-csquotes-open-quote ""
+ "Opening quotation mark to be used with the csquotes package.
+The specified string will be used for `TeX-open-quote' (and override
+any language-specific setting) only if both `LaTeX-csquotes-open-quote'
+and `LaTeX-csquotes-close-quote' are non-empty strings."
+ :type 'string
+ :group 'LaTeX-style)
+
+(defcustom LaTeX-csquotes-close-quote ""
+ "Closing quotation mark to be used with the csquotes package.
+The specified string will be used for `TeX-close-quote' (and override
+any language-specific setting) only if both `LaTeX-csquotes-open-quote'
+and `LaTeX-csquotes-close-quote' are non-empty strings."
+ :type 'string
+ :group 'LaTeX-style)
+
+;; style/emp.el
+
+(defcustom LaTeX-write18-enabled-p t
+ "*If non-nil, insert automatically the \\write18 calling metapost.
+When disabled, you have to use mpost on the mp files automatically
+produced by emp.sty and then re-LaTeX the document."
+ :type 'boolean
+ :group 'LaTeX-style)
+
+;; style/graphicx.el
+
+(defcustom LaTeX-includegraphics-extensions
+ '("eps" "jpe?g" "pdf" "png")
+ "Extensions for images files used by \\includegraphics."
+ :group 'LaTeX-style
+ :type '(list (set :inline t
+ (const "eps")
+ (const "jpe?g")
+ (const "pdf")
+ (const "png"))
+ (repeat :inline t
+ :tag "Other"
+ (string))))
+
+(defcustom LaTeX-includegraphics-options-alist
+ '((0 width)
+ ;; (1 width height clip)
+ ;; (2 width height keepaspectratio clip)
+ (4) ;; --> (4 nil)
+ (5 trim)
+ (16
+ ;; Table 1 in epslatex.ps: ``includegraphics Options''
+ height totalheight width scale angle origin bb
+ ;; Table 2 in epslatex.ps: ``cropping Options''
+ viewport trim
+ ;; Table 3 in epslatex.ps: ``Boolean Options''
+ ;; [not implemented:] noclip draft final
+ clip keepaspectratio
+ ;; Only for PDF:
+ page))
+ "Controls for which optional arguments of \\includegraphics you get prompted.
+
+An alist, consisting of \(NUMBER . LIST\) pairs. Valid elements of LIST are
+`width', `height', `keepaspectratio', `clip', `angle', `totalheight', `trim'
+and `bb' \(Bounding Box\).
+
+The list corresponding to 0 is used if no prefix is given. Note that 4 \(one
+\\[universal-argument]\) and 16 \(two \\[universal-argument]'s\) are easy to
+type and should be used for frequently needed combinations."
+ :group 'LaTeX-style
+ :type '(repeat (cons (integer :tag "Argument")
+ (list (set :inline t
+ (const height)
+ (const totalheight)
+ (const width)
+ (const scale)
+ (const angle)
+ (const origin)
+ (const :tag "Bounding Box" bb)
+ ;;
+ (const viewport)
+ (const trim)
+ ;;
+ (const clip)
+ (const keepaspectratio))))))
+
+(defcustom LaTeX-includegraphics-strip-extension-flag t
+ "Non-nil means to strip known extensions from image file name."
+ :group 'LaTeX-style
+ :type 'boolean)
+
+(defcustom LaTeX-includegraphics-read-file
+ 'LaTeX-includegraphics-read-file-TeX
+ "Function for reading \\includegraphics files.
+
+`LaTeX-includegraphics-read-file-TeX' lists all graphic files
+found in the TeX search path.
+
+`LaTeX-includegraphics-read-file-relative' lists all graphic files
+in the master directory and its subdirectories and inserts the
+relative file name. This option does not work with Emacs 21 or
+XEmacs.
+
+The custom option `simple' works as
+`LaTeX-includegraphics-read-file-relative' but it lists all kind of
+files.
+
+Inserting the subdirectory in the filename (as
+`LaTeX-includegraphics-read-file-relative') is discouraged by
+`epslatex.ps'."
+;; ,----[ epslatex.ps; Section 12; (page 26) ]
+;; | Instead of embedding the subdirectory in the filename, there are two
+;; | other options
+;; | 1. The best method is to modify the TeX search path [...]
+;; | 2. Another method is to specify sub/ in a \graphicspath command
+;; | [...]. However this is much less efficient than modifying the
+;; | TeX search path
+;; `----
+;; See "Inefficiency" and "Unportability" in the same section for more
+;; information.
+ :group 'LaTeX-style
+ :type '(choice (const :tag "TeX" LaTeX-includegraphics-read-file-TeX)
+ (const :tag "relative"
+ LaTeX-includegraphics-read-file-relative)
+ (const :tag "simple" (lambda ()
+ (file-relative-name
+ (read-file-name "Image file: ")
+ (TeX-master-directory))))
+ (function :tag "other")))
+
+;; style/shortvrb.el
+
+(defcustom LaTeX-shortvrb-chars '(?|)
+ "List of characters toggling verbatim mode."
+ :group 'LaTeX-style
+ :type '(repeat character))
+
+(provide 'tex-style)
+
+;;; tex-style.el ends here
--- /dev/null
+;;; tex.el --- Support for TeX documents.
+
+;; Copyright (C) 1985, 1986, 1987, 1991, 1993, 1994, 1996, 1997, 1999,
+;; 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; Maintainer: auctex-devel@gnu.org
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file provides AUCTeX support for plain TeX as well as basic
+;; functions used by other AUCTeX modes (e.g. for LaTeX, Texinfo and
+;; ConTeXt).
+
+;;; Code:
+
+(when (< emacs-major-version 21)
+ (error "AUCTeX requires Emacs 21 or later"))
+
+(require 'custom)
+(require 'tex-site)
+(eval-when-compile
+ (require 'cl))
+
+(defgroup TeX-file nil
+ "Files used by AUCTeX."
+ :group 'AUCTeX)
+
+(defgroup TeX-command nil
+ "Calling external commands from AUCTeX."
+ :group 'AUCTeX)
+
+(defgroup LaTeX nil
+ "LaTeX support in AUCTeX."
+ :tag "LaTeX"
+ :group 'AUCTeX
+ :prefix "LaTeX-")
+
+(defgroup TeX-misc nil
+ "Various AUCTeX settings."
+ :group 'AUCTeX)
+
+;;; Site Customization
+;;
+;; The following variables are likely to need to be changed for your
+;; site. You should do this with customize. Here is the beef: If you
+;; want to print, TeX-print-command must be non-nil (if it is nil,
+;; you'll get a complaint when using the print menu). If you want to
+;; view the queue, TeX-queue-command needs to be non-nil (if it is
+;; nil, it won't get mentioned in the menu). If TeX-printer-list is
+;; nil, nothing else gets asked: the menu entries lead directly to the
+;; respective commands. If those commands contain %p, the value of
+;; TeX-printer-default gets inserted there, no questions asked. Now
+;; if TeX-printer-list is non-nil, you'll always get asked which
+;; printer you want to use. You can enter a configured printer from
+;; TeX-printer-list, or an unknown one. The respective menus will
+;; show all configured printers. Since you can enter unknown
+;; printers, the printer name _must_ be set with %p in
+;; TeX-print-command.
+
+;; How to print.
+
+(defcustom TeX-print-command "%(o?)dvips -P%p %r %s"
+ "*Command used to print a file.
+
+First `%p' is expanded to the printer name, then ordinary expansion is
+performed as specified in `TeX-expand-list'. If it is nil,
+then customization is requested."
+ :group 'TeX-command
+ :type '(choice (string :tag "Print command")
+ (const :tag "No print command customized" nil)))
+
+(defcustom TeX-command "tex"
+ "Command to run plain TeX."
+ :group 'TeX-command
+ :type 'string)
+
+(defcustom TeX-Omega-command "omega"
+ "Command to run plain TeX on Omega."
+ :group 'TeX-command
+ :type 'string)
+
+(defcustom LaTeX-command "latex"
+ "Command to run LaTeX."
+ :group 'TeX-command
+ :type 'string)
+
+(defcustom LaTeX-Omega-command "lambda"
+ "Command to run LaTeX on Omega."
+ :group 'TeX-command
+ :type 'string)
+
+(defcustom ConTeXt-engine nil
+ "Engine to use for --engine in the texexec command.
+If nil, none is specified."
+ :group 'TeX-command
+ :type '(choice (const :tag "Unspecified" nil)
+ string))
+
+(defcustom ConTeXt-Omega-engine TeX-Omega-command
+ "Engine to use for --engine in the texexec command in Omega mode.
+If nil, none is specified."
+ :group 'TeX-command
+ :type '(choice (const :tag "Unspecified" nil)
+ string))
+;; At least in TeXLive 2009 ConTeXt does not support an omega option anymore.
+(make-obsolete-variable 'ConTeXt-Omega-engine 'TeX-engine-alist)
+
+(defcustom TeX-queue-command "lpq -P%p"
+ "*Command used to show the status of a printer queue.
+
+First `%p' is expanded to the printer name, then ordinary expansion is
+performed as specified in `TeX-expand-list'. If this is nil,
+the printer has no corresponding command."
+ :group 'TeX-command
+ :type '(choice (string :tag "Queue check command")
+ (const :tag "No such command" nil)))
+
+(defcustom TeX-mode-hook nil
+ "A hook run in TeX mode buffers."
+ :type 'hook
+ :group 'TeX-misc)
+
+(defcustom AmS-TeX-mode-hook nil
+ "A hook run in AmS-TeX mode buffers."
+ :type 'hook
+ :group 'TeX-misc)
+
+;; This is the major configuration variable. Most sites will only
+;; need to change the second string in each entry, which is the name
+;; of a command to send to the shell. If you use other formatters
+;; like AMSLaTeX or AMSTeX, you can add those to the list. See
+;; TeX-expand-list for a description of the % escapes
+
+(defcustom TeX-command-list
+ `(("TeX" "%(PDF)%(tex) %`%S%(PDFout)%(mode)%' %t"
+ TeX-run-TeX nil
+ (plain-tex-mode ams-tex-mode texinfo-mode) :help "Run plain TeX")
+ ("LaTeX" "%`%l%(mode)%' %t"
+ TeX-run-TeX nil
+ (latex-mode doctex-mode) :help "Run LaTeX")
+ ;; Not part of standard TeX.
+ ("Makeinfo" "makeinfo %t" TeX-run-compile nil
+ (texinfo-mode) :help "Run Makeinfo with Info output")
+ ("Makeinfo HTML" "makeinfo --html %t" TeX-run-compile nil
+ (texinfo-mode) :help "Run Makeinfo with HTML output")
+ ("AmSTeX" "%(PDF)amstex %`%S%(PDFout)%(mode)%' %t"
+ TeX-run-TeX nil (ams-tex-mode) :help "Run AMSTeX")
+ ;; support for ConTeXt --pg
+ ;; first version of ConTeXt to support nonstopmode: 2003.2.10
+ ("ConTeXt" "texexec --once --texutil %(execopts)%t"
+ TeX-run-TeX nil (context-mode) :help "Run ConTeXt once")
+ ("ConTeXt Full" "texexec %(execopts)%t"
+ TeX-run-TeX nil
+ (context-mode) :help "Run ConTeXt until completion")
+ ("BibTeX" "bibtex %s" TeX-run-BibTeX nil t :help "Run BibTeX")
+ ,(if (or window-system (getenv "DISPLAY"))
+ '("View" "%V" TeX-run-discard-or-function t t :help "Run Viewer")
+ '("View" "dvi2tty -q -w 132 %s" TeX-run-command t t
+ :help "Run Text viewer"))
+ ("Print" "%p" TeX-run-command t t :help "Print the file")
+ ("Queue" "%q" TeX-run-background nil t :help "View the printer queue"
+ :visible TeX-queue-command)
+ ("File" "%(o?)dvips %d -o %f " TeX-run-command t t
+ :help "Generate PostScript file")
+ ("Index" "makeindex %s" TeX-run-command nil t :help "Create index file")
+ ("Check" "lacheck %s" TeX-run-compile nil (latex-mode)
+ :help "Check LaTeX file for correctness")
+ ("Spell" "(TeX-ispell-document \"\")" TeX-run-function nil t
+ :help "Spell-check the document")
+ ("Clean" "TeX-clean" TeX-run-function nil t
+ :help "Delete generated intermediate files")
+ ("Clean All" "(TeX-clean t)" TeX-run-function nil t
+ :help "Delete generated intermediate and output files")
+ ("Other" "" TeX-run-command t t :help "Run an arbitrary command"))
+ "List of commands to execute on the current document.
+
+Each element is a list, whose first element is the name of the command
+as it will be presented to the user.
+
+The second element is the string handed to the shell after being
+expanded. The expansion is done using the information found in
+`TeX-expand-list'.
+
+The third element is the function which actually start the process.
+Several such hooks has been defined:
+
+TeX-run-command: Start up the process and show the output in a
+separate buffer. Check that there is not two commands running for the
+same file. Return the process object.
+
+TeX-run-format: As `TeX-run-command', but assume the output is created
+by a TeX macro package. Return the process object.
+
+TeX-run-TeX: For TeX output.
+
+TeX-run-interactive: Run TeX or LaTeX interactively.
+
+TeX-run-BibTeX: For BibTeX output.
+
+TeX-run-compile: Use `compile' to run the process.
+
+TeX-run-shell: Use `shell-command' to run the process.
+
+TeX-run-discard: Start the process in the background, discarding its
+output.
+
+TeX-run-background: Start the process in the background, show output
+in other window.
+
+TeX-run-silent: Start the process in the background.
+
+TeX-run-discard-foreground: Start the process in the foreground,
+discarding its output.
+
+TeX-run-function: Execute the Lisp function or function call
+specified by the string in the second element. Consequently,
+this hook does not start a process.
+
+TeX-run-discard-or-function: If the command is a Lisp function,
+execute it as such, otherwise start the command as a process,
+discarding its output.
+
+To create your own hook, define a function taking three arguments: The
+name of the command, the command string, and the name of the file to
+process. It might be useful to use `TeX-run-command' in order to
+create an asynchronous process.
+
+If the fourth element is non-nil, the user will get a chance to
+modify the expanded string.
+
+The fifth element indicates in which mode(s) the command should be
+present in the Command menu. Use t if it should be active in any
+mode. If it should only be present in some modes, specify a list with
+the respective mode names.
+
+Any additional elements get just transferred to the respective menu entries."
+ :group 'TeX-command
+ :type '(repeat (group :value ("" "" TeX-run-command nil t)
+ (string :tag "Name")
+ (string :tag "Command")
+ (choice :tag "How"
+ :value TeX-run-command
+ (function-item TeX-run-command)
+ (function-item TeX-run-format)
+ (function-item TeX-run-TeX)
+ (function-item TeX-run-interactive)
+ (function-item TeX-run-BibTeX)
+ (function-item TeX-run-compile)
+ (function-item TeX-run-shell)
+ (function-item TeX-run-discard)
+ (function-item TeX-run-background)
+ (function-item TeX-run-silent)
+ (function-item TeX-run-discard-foreground)
+ (function-item TeX-run-function)
+ (function-item TeX-run-discard-or-function)
+ (function :tag "Other"))
+ (boolean :tag "Prompt")
+ (choice :tag "Modes"
+ (const :tag "All" t)
+ (set (const :tag "Plain TeX" plain-tex-mode)
+ (const :tag "LaTeX" latex-mode)
+ (const :tag "DocTeX" doctex-mode)
+ (const :tag "ConTeXt" context-mode)
+ (const :tag "Texinfo" texinfo-mode)
+ (const :tag "AmSTeX" ams-tex-mode)))
+ (repeat :tag "Menu elements" :inline t sexp))))
+
+(defcustom TeX-command-output-list
+ '(
+; Add the following line if you want to use htlatex (tex4ht)
+; ("\\`htlatex" ("html"))
+ )
+ "List of regexps and file extensions.
+
+Each element is a list, whose first element is a regular expression to
+match against the name of the command that will be used to process the TeX
+file.
+
+The second element is either a string or a list with a string as element.
+If it is a string this is the default file extension that will be expected
+for output files that are produced by commands that match the first
+element. The real file extension will be obtained from the logging output
+if possible, defaulting to the given string.
+If it is a list, the element of the list will be the fixed extension used
+without looking at the logging output.
+
+If this list does not yield an extension, the default is either \"dvi\"
+or \"pdf\", depending on the setting of `TeX-PDF-mode'.
+Extensions must be given without the \".\"."
+
+ :group 'TeX-command
+ :type '(repeat (group (regexp :tag "Command Regexp")
+ (choice (string :tag "Default Extension")
+ (group (string :tag "Fixed Extension"))))))
+
+;; You may want to change the default LaTeX version for your site.
+(defcustom LaTeX-version "2e"
+ "Default LaTeX version. Currently recognized is \"2\" and \"2e\"."
+ :group 'LaTeX
+ :type '(radio (const :format "%v\n%h"
+ :doc "\
+The executable `latex' is LaTeX version 2."
+ "2")
+ (const :format "%v\n%h"
+ :doc "\
+The executable `latex' is LaTeX version 2e."
+ "2e")
+ (string :tag "Other")))
+
+
+;; Use different compilation commands depending on style.
+;; Only works if parsing is enabled.
+
+(defcustom LaTeX-command-style
+ ;; They have all been combined in LaTeX 2e.
+ '(("" "%(PDF)%(latex) %S%(PDFout)"))
+"List of style options and LaTeX commands.
+
+If the first element (a regular expression) matches the name of one of
+the style files, any occurrence of the string `%l' in a command in
+`TeX-command-list' will be replaced with the second element. The first
+match is used, if no match is found the `%l' is replaced with the empty
+string."
+ :group 'TeX-command
+ :type '(repeat (group :value ("" "")
+ regexp (string :tag "Style"))))
+
+;; Enter the names of the printers available at your site, or nil if
+;; you only have one printer.
+
+(defcustom TeX-printer-list
+ '(("Default" "%(o?)dvips -f %s | lpr" "lpq"))
+ "List of available printers.
+
+The first element of each entry is the printer name.
+
+The second element is the command used to print to this
+printer. It defaults to the value of `TeX-print-command' when nil.
+
+The third element is the command used to examine the print queue for
+this printer. It defaults to the value of `TeX-queue-command' similarly.
+
+Any occurrence of `%p' in the second or third element is expanded to
+the printer name given in the first element, then ordinary expansion
+is performed as specified in `TeX-expand-list'.
+
+If this list is empty, only `TeX-print-command' and `TeX-queue-command'
+get consulted."
+ :group 'TeX-command
+ :type '(repeat (group (string :tag "Name")
+ (option (group :inline t
+ :extra-offset -4
+ (choice :tag "Print"
+ (const :tag "default")
+ (string :format "%v"))
+ (option (choice :tag "Queue"
+ (const :tag "default")
+ (string
+ :format "%v"))))))))
+
+;; The name of the most used printer.
+
+(defcustom TeX-printer-default (or (getenv "PRINTER")
+ (and TeX-printer-list
+ (car (car TeX-printer-list)))
+ "lp")
+ "*Default printer to use with `TeX-command'."
+ :group 'TeX-command
+ :type 'string)
+
+(defcustom TeX-print-style '(("^landscape$" "-t landscape"))
+ "List of style options and print options.
+
+If the first element (a regular expression) matches the name of one of
+the style files, any occurrence of the string `%r' in a command in
+`TeX-command-list' will be replaced with the second element. The first
+match is used, if no match is found the `%r' is replaced with the empty
+string."
+ :group 'TeX-command
+ :type '(repeat (group regexp (string :tag "Command"))))
+
+;; This is the list of expansion for the commands in
+;; TeX-command-list. Not likely to be changed, but you may e.g. want
+;; to handle .ps files.
+
+(defcustom TeX-expand-list
+ '(("%p" TeX-printer-query) ;%p must be the first entry
+ ("%q" (lambda ()
+ (TeX-printer-query t)))
+ ("%V" (lambda ()
+ (TeX-source-correlate-start-server-maybe)
+ (TeX-view-command-raw)))
+ ("%vv" (lambda ()
+ (TeX-source-correlate-start-server-maybe)
+ (TeX-output-style-check TeX-output-view-style)))
+ ("%v" (lambda ()
+ (TeX-source-correlate-start-server-maybe)
+ (TeX-style-check TeX-view-style)))
+ ("%r" (lambda ()
+ (TeX-style-check TeX-print-style)))
+ ("%l" (lambda ()
+ (TeX-style-check LaTeX-command-style)))
+ ("%(PDF)" (lambda ()
+ (if (and (eq TeX-engine 'default)
+ (or TeX-PDF-mode
+ TeX-DVI-via-PDFTeX))
+ "pdf"
+ "")))
+ ("%(PDFout)" (lambda ()
+ (cond ((and (eq TeX-engine 'xetex)
+ (not TeX-PDF-mode))
+ " -no-pdf")
+ ((and (eq TeX-engine 'luatex)
+ (not TeX-PDF-mode))
+ " --output-format=dvi")
+ ((and (eq TeX-engine 'default)
+ (not TeX-PDF-mode)
+ TeX-DVI-via-PDFTeX)
+ " \"\\pdfoutput=0 \"")
+ (t ""))))
+ ("%(mode)" (lambda ()
+ (if TeX-interactive-mode
+ ""
+ " -interaction=nonstopmode")))
+ ("%(o?)" (lambda () (if (eq TeX-engine 'omega) "o" "")))
+ ("%(tex)" (lambda () (eval (nth 2 (assq TeX-engine (TeX-engine-alist))))))
+ ("%(latex)" (lambda () (eval (nth 3 (assq TeX-engine (TeX-engine-alist))))))
+ ("%(execopts)" ConTeXt-expand-options)
+ ("%S" TeX-source-correlate-expand-options)
+ ("%dS" TeX-source-specials-view-expand-options)
+ ("%cS" TeX-source-specials-view-expand-client)
+ ("%(outpage)" (lambda ()
+ (if TeX-source-correlate-output-page-function
+ (funcall TeX-source-correlate-output-page-function)
+ "1")))
+ ;; `file' means to call `TeX-master-file' or `TeX-region-file'
+ ("%s" file nil t)
+ ("%t" file t t)
+ ("%`" (lambda nil
+ (setq TeX-command-pos t TeX-command-text "")))
+ (" \"\\" (lambda nil
+ (if (eq TeX-command-pos t)
+ (setq TeX-command-pos pos
+ pos (+ 3 pos))
+ (setq pos (1+ pos)))))
+ ("\"" (lambda nil (if (numberp TeX-command-pos)
+ (setq TeX-command-text
+ (concat
+ TeX-command-text
+ (substring command
+ TeX-command-pos
+ (1+ pos)))
+ command
+ (concat
+ (substring command
+ 0
+ TeX-command-pos)
+ (substring command
+ (1+ pos)))
+ pos TeX-command-pos
+ TeX-command-pos t)
+ (setq pos (1+ pos)))))
+ ("%'" (lambda nil
+ (prog1
+ (if (stringp TeX-command-text)
+ (progn
+ (setq pos (+ (length TeX-command-text) 9)
+ TeX-command-pos
+ (and (string-match " "
+ (funcall file t t))
+ "\""))
+ (concat TeX-command-text " \"\\input\""))
+ (setq TeX-command-pos nil)
+ "")
+ (setq TeX-command-text nil))))
+ ("%n" TeX-current-line)
+ ("%d" file "dvi" t)
+ ("%f" file "ps" t)
+ ("%o" (lambda nil (funcall file (TeX-output-extension) t)))
+ ;; for source specials the file name generated for the xdvi
+ ;; command needs to be relative to the master file, just in
+ ;; case the file is in a different subdirectory
+ ("%b" TeX-current-file-name-master-relative)
+ ;; the following is for preview-latex.
+ ("%m" preview-create-subdirectory))
+ "List of expansion strings for TeX command names.
+
+Each entry is a list with two or more elements. The first element is
+the string to be expanded. The second element is the name of a
+function returning the expanded string when called with the remaining
+elements as arguments. The special value `file' will be expanded to
+the name of the file being processed, with an optional extension."
+ :group 'TeX-command
+ :type '(repeat (group (string :tag "Key")
+ (sexp :tag "Expander")
+ (repeat :inline t
+ :tag "Arguments"
+ (sexp :format "%v")))))
+
+
+;; The following dependencies are not done with autoload cookies since
+;; they are only useful when tex.el is loaded, anyway. tex-buf.el
+;; should remain unloaded as long as one is only editing files, so
+;; requiring it here would be wrong.
+
+(autoload 'TeX-region-create "tex-buf" nil nil)
+(autoload 'TeX-save-document "tex-buf" nil t)
+(autoload 'TeX-home-buffer "tex-buf" nil t)
+(autoload 'TeX-pin-region "tex-buf" nil t)
+(autoload 'TeX-command-region "tex-buf" nil t)
+(autoload 'TeX-command-buffer "tex-buf" nil t)
+(autoload 'TeX-command-master "tex-buf" nil t)
+(autoload 'TeX-command "tex-buf" nil nil)
+(autoload 'TeX-kill-job "tex-buf" nil t)
+(autoload 'TeX-recenter-output-buffer "tex-buf" nil t)
+(autoload 'TeX-next-error "tex-buf" nil t)
+(autoload 'TeX-region-file "tex-buf" nil nil)
+(autoload 'TeX-current-offset "tex-buf" nil nil)
+(autoload 'TeX-process-set-variable "tex-buf" nil nil)
+(autoload 'TeX-view "tex-buf" nil t)
+
+;;; Portability.
+
+(require 'easymenu)
+
+(eval-and-compile
+ (if (featurep 'xemacs)
+ (defun TeX-maybe-remove-help (menu)
+ "Removes :help entries from menus, since XEmacs does not like them.
+Also does other stuff."
+ (cond ((consp menu)
+ (cond ((eq (car menu) :help)
+ (TeX-maybe-remove-help (cddr menu)))
+ ((eq (car menu) :visible)
+ (cons :included
+ (cons (cadr menu)
+ (TeX-maybe-remove-help (cddr menu)))))
+ (t (cons (TeX-maybe-remove-help (car menu))
+ (TeX-maybe-remove-help (cdr menu))))))
+ ((vectorp menu)
+ (vconcat (TeX-maybe-remove-help (append menu nil))))
+ (t menu)))
+ (defun TeX-maybe-remove-help (menu)
+ "Compatibility function that would remove :help entries if on XEmacs,
+but does nothing in Emacs."
+ menu))
+ (defmacro TeX-menu-with-help (menu)
+ "Compatibility macro that removes :help entries if on XEmacs.
+Also does other stuff."
+ (TeX-maybe-remove-help menu)))
+
+
+;;; Documentation for Info-goto-emacs-command-node and similar
+
+(eval-after-load 'info '(dolist (elt '("TeX" "LaTeX" "ConTeXt" "Texinfo"
+ "docTeX"))
+ (add-to-list 'Info-file-list-for-emacs
+ (cons elt "AUCTeX"))))
+
+(defadvice hack-one-local-variable (after TeX-hack-one-local-variable-after
+ activate)
+ "Call minor mode function if minor mode variable is found."
+ (let ((var (ad-get-arg 0))
+ (val (ad-get-arg 1)))
+ ;; Instead of checking for each mode explicitely `minor-mode-list'
+ ;; could be used. But this may make the byte compiler pop up.
+ (when (memq var '(TeX-PDF-mode
+ TeX-source-correlate-mode TeX-interactive-mode
+ TeX-fold-mode LaTeX-math-mode))
+ (if (symbol-value val) (funcall var 1) (funcall var 0)))))
+
+(defvar TeX-overlay-priority-step 16
+ "Numerical difference of priorities between nested overlays.
+The step should be big enough to allow setting a priority for new
+overlays between two existing ones.")
+
+
+;;; Special support for XEmacs
+
+(when (featurep 'xemacs)
+
+ (defun TeX-read-string
+ (prompt &optional initial-input history default-value)
+ (condition-case nil
+ (read-string prompt initial-input history default-value t)
+ (wrong-number-of-arguments
+ (read-string prompt initial-input history default-value))))
+
+ (defun TeX-mark-active ()
+ ;; In Lucid (mark) returns nil when not active.
+ (if zmacs-regions
+ (mark)
+ (mark t)))
+
+ (defun TeX-active-mark ()
+ (and zmacs-regions (mark)))
+
+ (fset 'TeX-activate-region (symbol-function 'zmacs-activate-region))
+
+ ;; I am aware that this counteracts coding conventions but I am sick
+ ;; of it.
+ (unless (fboundp 'line-beginning-position)
+ (defalias 'line-beginning-position 'point-at-bol))
+ (unless (fboundp 'line-end-position)
+ (defalias 'line-end-position 'point-at-eol))
+
+ (defun TeX-overlay-prioritize (start end)
+ "Calculate a priority for an overlay extending from START to END.
+The calculated priority is lower than the minimum of priorities
+of surrounding overlays and higher than the maximum of enclosed
+overlays."
+ (let (inner-priority outer-priority
+ (prios (cons nil nil)))
+ (map-extents
+ #'(lambda (ov prios)
+ (and
+ (or (eq (extent-property ov 'category) 'TeX-fold)
+ (extent-property ov 'preview-state))
+ (setcar prios
+ (max (or (car prios) 0)
+ (extent-property ov 'priority))))
+ nil)
+ nil start end prios 'start-and-end-in-region 'priority)
+ (map-extents
+ #'(lambda (ov prios)
+ (and
+ (or (eq (extent-property ov 'category) 'TeX-fold)
+ (extent-property ov 'preview-state))
+ (setcdr prios
+ (min (or (cdr prios) most-positive-fixnum)
+ (extent-property ov 'priority))))
+ nil)
+ nil start end prios
+ '(start-and-end-in-region negate-in-region) 'priority)
+ (setq inner-priority (car prios) outer-priority (cdr prios))
+ (cond ((and inner-priority (not outer-priority))
+ (+ inner-priority TeX-overlay-priority-step))
+ ((and (not inner-priority) outer-priority)
+ (/ outer-priority 2))
+ ((and inner-priority outer-priority)
+ (+ (/ (- outer-priority inner-priority) 2) inner-priority))
+ (t TeX-overlay-priority-step)))) )
+
+
+(if (fboundp 'completing-read-multiple)
+ (defalias 'TeX-completing-read-multiple 'completing-read-multiple)
+ (defun TeX-completing-read-multiple
+ (prompt table &optional predicate require-match initial-input
+ hist def inherit-input-method)
+ "Poor mans implementation of Emacs' `completing-read-multiple' for XEmacs.
+The XEmacs package edit-utils-2.32 includes `crm.el'."
+ (multi-prompt "," nil prompt table predicate require-match initial-input
+ hist)))
+
+(if (fboundp 'line-number-at-pos)
+ (defalias 'TeX-line-number-at-pos 'line-number-at-pos)
+ ;; `line-number-at-pos' from `simple.el' in Emacs CVS (2006-06-07)
+ (defun TeX-line-number-at-pos (&optional pos)
+ "Return (narrowed) buffer line number at position POS.
+If POS is nil, use current buffer location."
+ (let ((opoint (or pos (point))) start)
+ (save-excursion
+ (goto-char (point-min))
+ (setq start (point))
+ (goto-char opoint)
+ (forward-line 0)
+ (1+ (count-lines start (point)))))))
+
+;;; Special support for GNU Emacs
+
+(unless (featurep 'xemacs)
+
+ (defun TeX-read-string (prompt &optional initial-input history default-value)
+ (read-string prompt initial-input history default-value t))
+
+ (defun TeX-mark-active ()
+ ;; In FSF 19 mark-active indicates if mark is active.
+ mark-active)
+
+ (defun TeX-active-mark ()
+ (and transient-mark-mode mark-active))
+
+ (defun TeX-activate-region ()
+ nil)
+
+ (defun TeX-overlay-prioritize (start end)
+ "Calculate a priority for an overlay extending from START to END.
+The calculated priority is lower than the minimum of priorities
+of surrounding overlays and higher than the maximum of enclosed
+overlays."
+ (let (outer-priority inner-priority ov-priority)
+ (dolist (ov (overlays-in start end))
+ (when (or (eq (overlay-get ov 'category) 'TeX-fold)
+ (overlay-get ov 'preview-state))
+ (setq ov-priority (overlay-get ov 'priority))
+ (if (>= (overlay-start ov) start)
+ (setq inner-priority (max ov-priority (or inner-priority
+ ov-priority)))
+ (setq outer-priority (min ov-priority (or outer-priority
+ ov-priority))))))
+ (cond ((and inner-priority (not outer-priority))
+ (+ inner-priority TeX-overlay-priority-step))
+ ((and (not inner-priority) outer-priority)
+ (/ outer-priority 2))
+ ((and inner-priority outer-priority)
+ (+ (/ (- outer-priority inner-priority) 2) inner-priority))
+ (t TeX-overlay-priority-step)))) )
+
+(defun TeX-delete-dups-by-car (alist &optional keep-list)
+ "Return a list of all elements in ALIST, but each car only once.
+Elements of KEEP-LIST are not removed even if duplicate."
+ ;; Copy of `reftex-uniquify-by-car' (written by David Kastrup).
+ (setq keep-list (sort (copy-sequence keep-list) #'string<))
+ (setq alist (sort (copy-sequence alist)
+ (lambda (a b)
+ (string< (car a) (car b)))))
+ (let ((new alist) elt)
+ (while new
+ (setq elt (caar new))
+ (while (and keep-list (string< (car keep-list) elt))
+ (setq keep-list (cdr keep-list)))
+ (unless (and keep-list (string= elt (car keep-list)))
+ (while (string= elt (car (cadr new)))
+ (setcdr new (cddr new))))
+ (setq new (cdr new))))
+ alist)
+
+(defun TeX-delete-duplicate-strings (list)
+ "Return a list of all strings in LIST, but each only once."
+ (setq list (TeX-sort-strings list))
+ (let ((new list) elt)
+ (while new
+ (setq elt (car new))
+ (while (string= elt (cadr new))
+ (setcdr new (cddr new)))
+ (setq new (cdr new))))
+ list)
+
+(defun TeX-sort-strings (list)
+ "Return sorted list of all strings in LIST."
+ (sort (copy-sequence list) #'string<))
+
+;;; Buffer
+
+(defgroup TeX-output nil
+ "Parsing TeX output."
+ :prefix "TeX-"
+ :group 'AUCTeX)
+
+(defcustom TeX-display-help t
+ "Control type of help display when stepping through errors with \\[TeX-next-error].
+If t display help buffer. If nil display message about error in
+echo area. If `expert' display output buffer with raw processor output."
+ :group 'TeX-output
+ :type '(choice (const :tag "Help buffer" t)
+ (const :tag "Echo area" nil)
+ (const :tag "Output buffer" expert)))
+
+(defcustom TeX-debug-bad-boxes nil
+ "Non-nil means also find overfull/underfull box warnings with \\[TeX-next-error]."
+ :group 'TeX-output
+ :type 'boolean)
+
+(defcustom TeX-debug-warnings nil
+ "Non-nil means also find LaTeX or package warnings with \\[TeX-next-error]."
+ :group 'TeX-output
+ :type 'boolean)
+
+(defun TeX-toggle-debug-bad-boxes ()
+ "Toggle if the debugger should display \"bad boxes\" too."
+ (interactive)
+ (setq TeX-debug-bad-boxes (not TeX-debug-bad-boxes))
+ (message (concat "TeX-debug-bad-boxes: "
+ (if TeX-debug-bad-boxes "on" "off"))))
+
+(defun TeX-toggle-debug-warnings ()
+ "Toggle if the debugger should display warnings too."
+ (interactive)
+ (setq TeX-debug-warnings (not TeX-debug-warnings))
+ (message (concat "TeX-debug-warnings: "
+ (if TeX-debug-warnings "on" "off"))))
+
+;;; Mode names.
+
+(defvar TeX-base-mode-name nil
+ "Base name of mode.")
+(make-variable-buffer-local 'TeX-base-mode-name)
+
+(defun TeX-set-mode-name (&optional changed local reset)
+ "Build and set the mode name.
+The base mode name will be concatenated with indicators for
+helper modes where appropriate.
+
+If CHANGED is non-nil, it indicates which global mode
+may have changed so that all corresponding buffers
+without a local value might get their name updated.
+A value of t will thus update all buffer names.
+
+If LOCAL is non-nil and CHANGED is buffer-local, only
+a local change has been performed and only the local
+name is to be updated.
+
+If RESET is non-nil, `TeX-command-next' is reset to
+`TeX-command-default' in updated buffers."
+ (if (and changed
+ (not (and local (local-variable-p changed (current-buffer)))))
+ (dolist (buffer (buffer-list))
+ (and (local-variable-p 'TeX-mode-p buffer)
+ (not (local-variable-p changed buffer))
+ (with-current-buffer buffer (TeX-set-mode-name nil nil reset))))
+ (if TeX-mode-p
+ (let ((trailing-flags
+ (concat
+ (and (boundp 'TeX-fold-mode) TeX-fold-mode "F")
+ (and (boundp 'LaTeX-math-mode) LaTeX-math-mode "M")
+ (and TeX-PDF-mode "P")
+ (and TeX-interactive-mode "I")
+ (and TeX-source-correlate-mode "S"))))
+ (setq mode-name (concat TeX-base-mode-name
+ (when (> (length trailing-flags) 0)
+ (concat "/" trailing-flags))))
+ (when reset
+ (TeX-process-set-variable (TeX-master-file)
+ 'TeX-command-next TeX-command-default)
+ (TeX-process-set-variable (TeX-region-file)
+ 'TeX-command-next TeX-command-default))
+ (set-buffer-modified-p (buffer-modified-p))))))
+
+(defun TeX-mode-prefix ()
+ "Return the prefix of the current mode as string."
+ (cdr (assoc major-mode '((plain-tex-mode . "plain-TeX")
+ (latex-mode . "LaTeX")
+ (doctex-mode . "docTeX")
+ (texinfo-mode . "Texinfo")
+ (context-mode . "ConTeXt")))))
+
+;;; Viewing
+
+(defgroup TeX-view nil
+ "Calling viewers from AUCTeX."
+ :group 'TeX-command)
+
+(defcustom TeX-view-style
+ `((,(concat
+ "^" (regexp-opt '("a4paper" "a4dutch" "a4wide" "sem-a4")) "$")
+ "%(o?)xdvi %dS -paper a4 %d")
+ (,(concat "^" (regexp-opt '("a5paper" "a5comb")) "$")
+ "%(o?)xdvi %dS -paper a5 %d")
+ ("^b5paper$" "%(o?)xdvi %dS -paper b5 %d")
+ ("^letterpaper$" "%(o?)xdvi %dS -paper us %d")
+ ("^legalpaper$" "%(o?)xdvi %dS -paper legal %d")
+ ("^executivepaper$" "%(o?)xdvi %dS -paper 7.25x10.5in %d")
+ ("^landscape$" "%(o?)xdvi %dS -paper a4r -s 0 %d")
+ ;; The latest xdvi can show embedded postscript. If you don't
+ ;; have that, uncomment next line.
+ ;; ("^epsf$" "ghostview %f")
+ ("." "%(o?)xdvi %dS %d"))
+ "List of style options and view options.
+
+If the first element (a regular expression) matches the name of
+one of the style files, any occurrence of the string `%v' in a
+command in `TeX-command-list' will be replaced with the second
+element. The first match is used, if no match is found the `%v'
+is replaced with the empty string.
+
+As a default, the \"View\" command in `TeX-command-list' is set
+to `%V'. This means that `TeX-output-view-style' will be
+consulted before `TeX-view-style'. Only if no match is found in
+`TeX-output-view-style' the settings in `TeX-view-style' will be
+considered. If you want to bypass `TeX-output-view-style', which
+is not recommended because it is more powerful than
+`TeX-view-style', use `%v' in the \"View\" command."
+ :group 'TeX-view
+ :type '(repeat (group regexp (string :tag "Command"))))
+
+(defcustom TeX-output-view-style
+ `(("^dvi$" ("^landscape$" "^pstricks$\\|^pst-\\|^psfrag$")
+ "%(o?)dvips -t landscape %d -o && gv %f")
+ ("^dvi$" "^pstricks$\\|^pst-\\|^psfrag$" "%(o?)dvips %d -o && gv %f")
+ ("^dvi$" (,(concat
+ "^" (regexp-opt '("a4paper" "a4dutch" "a4wide" "sem-a4")) "$")
+ "^landscape$")
+ "%(o?)xdvi %dS -paper a4r -s 0 %d")
+ ("^dvi$" ,(concat
+ "^" (regexp-opt '("a4paper" "a4dutch" "a4wide" "sem-a4")) "$")
+ "%(o?)xdvi %dS -paper a4 %d")
+ ("^dvi$" (,(concat "^" (regexp-opt '("a5paper" "a5comb")) "$")
+ "^landscape$")
+ "%(o?)xdvi %dS -paper a5r -s 0 %d")
+ ("^dvi$" ,(concat "^" (regexp-opt '("a5paper" "a5comb")) "$")
+ "%(o?)xdvi %dS -paper a5 %d")
+ ("^dvi$" "^b5paper$" "%(o?)xdvi %dS -paper b5 %d")
+ ("^dvi$" "^letterpaper$" "%(o?)xdvi %dS -paper us %d")
+ ("^dvi$" "^legalpaper$" "%(o?)xdvi %dS -paper legal %d")
+ ("^dvi$" "^executivepaper$" "%(o?)xdvi %dS -paper 7.25x10.5in %d")
+ ("^dvi$" "." "%(o?)xdvi %dS %d")
+ ("^pdf$" "." "xpdf -remote %s -raise %o %(outpage)")
+ ("^html?$" "." "netscape %o"))
+ "List of output file extensions and view options.
+
+If the first element (a regular expression) matches the output
+file extension, and the second element (a regular expression)
+matches the name of one of the style options, any occurrence of
+the string `%V' in a command in `TeX-command-list' will be
+replaced with the third element. The first match is used; if no
+match is found the `%V' is replaced with `%v'. The outcome of `%v'
+is determined by the settings in `TeX-view-style' which therefore
+serves as a fallback for `TeX-output-view-style'. The second
+element may also be a list of regular expressions, in which case
+all the regular expressions must match for the element to apply."
+ :group 'TeX-view
+ :type '(repeat (group
+ (regexp :tag "Extension")
+ (choice regexp (repeat :tag "List" regexp))
+ (string :tag "Command"))))
+
+;;; Viewing (new implementation)
+
+(defvar TeX-view-predicate-list-builtin
+ '((output-dvi
+ (string-match "dvi" (TeX-output-extension)))
+ (output-pdf
+ (string-match "pdf" (TeX-output-extension)))
+ (output-html
+ (string-match "html" (TeX-output-extension)))
+ (style-pstricks
+ (TeX-match-style "^pstricks$\\|^pst-\\|^psfrag$"))
+ (engine-omega
+ (eq TeX-engine 'omega))
+ (engine-xetex
+ (eq TeX-engine 'xetex))
+ (mode-io-correlate
+ TeX-source-correlate-mode)
+ (paper-landscape
+ (TeX-match-style "\\`landscape\\'"))
+ (paper-portrait
+ (not (TeX-match-style "\\`landscape\\'")))
+ (paper-a4
+ (TeX-match-style "\\`a4paper\\|a4dutch\\|a4wide\\|sem-a4\\'"))
+ (paper-a5
+ (TeX-match-style "\\`a5paper\\|a5comb\\'"))
+ (paper-b5
+ (TeX-match-style "\\`b5paper\\'"))
+ (paper-letter
+ (TeX-match-style "\\`letterpaper\\'"))
+ (paper-legal
+ (TeX-match-style "\\`legalpaper\\'"))
+ (paper-executive
+ (TeX-match-style "\\`executivepaper\\'")))
+ "Alist of built-in predicates for viewer selection and invocation.
+See the doc string of `TeX-view-predicate-list' for a short
+description of each predicate.")
+
+(defcustom TeX-view-predicate-list nil
+ "Alist of predicates for viewer selection and invocation.
+The key of each list item is a symbol and the value a Lisp form
+to be evaluated. The form should return nil if the predicate is
+not fulfilled.
+
+Built-in predicates provided in `TeX-view-predicate-list-builtin'
+can be overwritten by defining predicates with the same symbol.
+
+The following built-in predicates are available:
+ `output-dvi': The output is a DVI file.
+ `output-pdf': The output is a PDF file.
+ `output-html': The output is an HTML file.
+ `style-pstricks': The document loads a PSTricks package.
+ `engine-omega': The Omega engine is used for typesetting.
+ `engine-xetex': The XeTeX engine is used for typesetting.
+ `mode-io-correlate': TeX Source Correlate mode is active.
+ `paper-landscape': The document is typeset in landscape orientation.
+ `paper-portrait': The document is not typeset in landscape orientation.
+ `paper-a4': The paper format is A4.
+ `paper-a5': The paper format is A5.
+ `paper-b5': The paper format is B5.
+ `paper-letter': The paper format is letter.
+ `paper-legal': The paper format is legal.
+ `paper-executive': The paper format is executive."
+ :group 'TeX-view
+ :type '(alist :key-type symbol :value-type (group sexp)))
+
+(defvar TeX-view-program-list-builtin
+ (cond
+ ((eq system-type 'windows-nt)
+ '(("Yap" ("yap -1" (mode-io-correlate " -s %n%b") " %o"))
+ ("dvips and start" "dvips %d -o && start \"\" %f")
+ ("start" "start \"\" %o")))
+;; XXX: We need the advice of a Mac OS X user to configure this
+;; correctly and test it.
+;; ((eq system-type 'darwin)
+;; '(("Preview.app" "open -a Preview.app %o")
+;; ("Skim" "open -a Skim.app %o")
+;; ("displayline" "displayline %n %o %b")
+;; ("open" "open %o")))
+ (t
+ '(("xdvi" ("%(o?)xdvi"
+ (mode-io-correlate " -sourceposition \"%n %b\" -editor \"%cS\"")
+ ((paper-a4 paper-portrait) " -paper a4")
+ ((paper-a4 paper-landscape) " -paper a4r")
+ ((paper-a5 paper-portrait) " -paper a5")
+ ((paper-a5 paper-landscape) " -paper a5r")
+ (paper-b5 " -paper b5")
+ (paper-letter " -paper us")
+ (paper-legal " -paper legal")
+ (paper-executive " -paper 7.25x10.5in")
+ " %d"))
+ ("dvips and gv" "%(o?)dvips %d -o && gv %f")
+ ("gv" "gv %o")
+ ("xpdf" ("xpdf -remote %s -raise %o" (mode-io-correlate " %(outpage)")))
+ ("Evince" ("evince" (mode-io-correlate " -p %(outpage)") " %o"))
+ ("xdg-open" "xdg-open %o"))))
+ "Alist of built-in viewer specifications.
+This variable should not be changed by the user who can use
+`TeX-view-program-list' to add new viewers or overwrite the
+definition of built-in ones. The latter variable also contains a
+description of the data format.")
+
+(defcustom TeX-view-program-list nil
+ "Alist of viewer specifications.
+This variable can be used to specify how a viewer is to be
+invoked and thereby add new viewers on top of the built-in list
+of viewers defined in `TeX-view-program-list-builtin' or override
+entries in the latter.
+
+The car of each item is a string with a user-readable name. The
+second element can be a command line to be run as a process or a
+Lisp function to be executed. The command line can either be
+specified as a single string or a list of strings and two-part
+lists. The first element of the two-part lists is a symbol or a
+list of symbols referring to one or more of the predicates in
+`TeX-view-predicate-list' or `TeX-view-predicate-list-builtin'.
+The second part of the two-part lists is a command line part.
+The command line for the viewer is constructed by concatenating
+the command line parts. Parts with a predicate are only
+considered if the predicate was evaluated with a positive result.
+Note that the command line can contain placeholders as defined in
+`TeX-expand-list' which are expanded before the viewer is called.
+
+The use of a function as the second element only works if the
+View command in `TeX-command-list' makes use of the hook
+`TeX-run-discard-or-function'.
+
+Note: Predicates defined in the current Emacs session will only
+show up in the customization interface for this variable after
+restarting Emacs."
+ :group 'TeX-view
+ :type
+ `(alist
+ :key-type (string :tag "Name")
+ :value-type
+ (choice
+ (group :tag "Command" (string :tag "Command"))
+ (group :tag "Command parts"
+ (repeat
+ :tag "Command parts"
+ (choice
+ (string :tag "Command part")
+ (list :tag "Predicate and command part"
+ ,(let (list)
+ ;; Build the list of available predicates.
+ (mapc (lambda (spec)
+ (add-to-list 'list `(const ,(car spec))))
+ (append TeX-view-predicate-list
+ TeX-view-predicate-list-builtin))
+ ;; Sort the list alphabetically.
+ (setq list (sort list
+ (lambda (a b)
+ (string<
+ (downcase (symbol-name (cadr a)))
+ (downcase (symbol-name (cadr b)))))))
+ `(choice
+ (choice :tag "Predicate" ,@list)
+ (repeat :tag "List of predicates"
+ (choice :tag "Predicate" ,@list))))
+ (string :tag "Command part")))))
+ (group :tag "Function" function))))
+
+;; XXX: Regarding a possibility to (manually) run an update command,
+;; one could support this through `TeX-view' by letting it temporarily
+;; set a variable which is checked with a predicate in the viewer
+;; selection. If the check is positive, the update command is run
+;; instead of the normal viewer command. Direct support through the
+;; View command would require a predicate which knows when an update
+;; has to be done.
+(defcustom TeX-view-program-selection
+ (cond
+ ((eq system-type 'windows-nt)
+ '(((output-dvi style-pstricks) "dvips and start")
+ (output-dvi "Yap")
+ (output-pdf "start")
+ (output-html "start")))
+;; XXX: We need the advice of a Mac OS X user to configure this
+;; correctly and test it.
+;; ((eq system-type 'darwin)
+;; '((output-dvi "open")
+;; (output-pdf "open")
+;; (output-html "open")))
+ (t
+ '(((output-dvi style-pstricks) "dvips and gv")
+ (output-dvi "xdvi")
+ (output-pdf "Evince")
+ (output-html "xdg-open"))))
+ "Alist of predicates and viewers.
+Each entry consists of a list with two elements. The first
+element is a symbol or list of symbols referring to predicates as
+defined in `TeX-view-predicate-list' or
+`TeX-view-predicate-list-builtin'. The second element is a
+string referring to the name of a viewer as defined in
+`TeX-view-program-list' or `TeX-view-program-list-builtin'.
+
+When a viewer is called for, the entries are evaluated in turn
+and the viewer related to the first entry all predicates of which
+are evaluated positively is chosen."
+ :group 'TeX-view
+ :type `(alist :key-type
+ ;; Offer list of defined predicates.
+ ,(let (list)
+ (mapc (lambda (spec)
+ (add-to-list 'list `(const ,(car spec))))
+ (append TeX-view-predicate-list
+ TeX-view-predicate-list-builtin))
+ (setq list (sort list
+ (lambda (a b)
+ (string<
+ (downcase (symbol-name (cadr a)))
+ (downcase (symbol-name (cadr b)))))))
+ `(choice (choice :tag "Single predicate" ,@list)
+ (repeat :tag "Multiple predicates"
+ (choice ,@list))))
+ :value-type
+ ;; Offer list of defined viewers.
+ (group (choice :tag "Viewer"
+ ,@(let (list)
+ (mapc (lambda (spec)
+ (add-to-list 'list
+ `(const ,(car spec))))
+ (append TeX-view-program-list
+ TeX-view-program-list-builtin))
+ (sort list
+ (lambda (a b)
+ (string< (downcase (cadr a))
+ (downcase (cadr b))))))))))
+
+(defun TeX-match-style (regexp)
+ "Check if a style matching REGEXP is active."
+ (TeX-member regexp (TeX-style-list) 'string-match))
+
+(defun TeX-view-match-predicate (predicate)
+ "Check if PREDICATE is true.
+PREDICATE can be a symbol or a list of symbols defined in
+`TeX-view-predicate-list-builtin' or `TeX-view-predicate-list'.
+In case of a single symbol, return t if the predicate is true,
+nil otherwise. In case of a list of symbols, return t if all
+predicates are true, nil otherwise."
+ (let ((pred-symbols (if (listp predicate) predicate (list predicate)))
+ (pred-defs (append TeX-view-predicate-list
+ TeX-view-predicate-list-builtin))
+ (result t)
+ elt)
+ (while (and (setq elt (pop pred-symbols)) result)
+ (unless (eval (cadr (assq elt pred-defs)))
+ (setq result nil)))
+ result))
+
+(defun TeX-view-command-raw ()
+ "Choose a viewer and return its unexpanded command string."
+ (let ((selection TeX-view-program-selection)
+ entry viewer spec command)
+ ;; Find the appropriate viewer.
+ (while (and (setq entry (pop selection)) (not viewer))
+ (when (TeX-view-match-predicate (car entry))
+ (setq viewer (cadr entry))))
+ (unless viewer
+ (error "No matching viewer found"))
+ ;; Get the command line or function spec.
+ (setq spec (cadr (assoc viewer (append TeX-view-program-list
+ TeX-view-program-list-builtin))))
+ (cond ((functionp spec)
+ ;; Converting the function call to a string is ugly, but
+ ;; the backend currently only supports strings.
+ (prin1-to-string spec))
+ ((stringp spec)
+ spec)
+ (t
+ ;; Build the unexpanded command line. Pieces with predicates are
+ ;; only added if the predicate is evaluated positively.
+ (dolist (elt spec)
+ (cond ((stringp elt)
+ (setq command (concat command elt)))
+ ((listp elt)
+ (when (TeX-view-match-predicate (car elt))
+ (setq command (concat command (cadr elt)))))))
+ command))))
+
+;;; Engine
+
+(defvar TeX-engine-alist-builtin
+ '((default "Default" TeX-command LaTeX-command ConTeXt-engine)
+ (xetex "XeTeX" "xetex" "xelatex" "xetex")
+ (luatex "LuaTeX" "luatex" "lualatex" "luatex")
+ (omega "Omega" TeX-Omega-command LaTeX-Omega-command ConTeXt-Omega-engine))
+ "Alist of built-in TeX engines and associated commands.
+For a description of the format see `TeX-engine-alist'.")
+
+(defcustom TeX-engine-alist nil
+ "Alist of TeX engines and associated commands.
+Each entry is a list with a maximum of five elements. The first
+element is a symbol used to identify the engine. The second is a
+string describing the engine. The third is the command to be
+used for plain TeX. The fourth is the command to be used for
+LaTeX. The fifth is the command to be used for the --engine
+parameter of ConTeXt's texexec program. Each command can either
+be a variable or a string. An empty string or nil means there is
+no command available.
+
+You can override a built-in engine defined in the variable
+`TeX-engine-alist-builtin' by adding an entry beginning with the
+same symbol as the built-in entry to `TeX-engine-alist'."
+ :group 'TeX-command
+ :type '(repeat (group symbol
+ (string :tag "Name")
+ (choice :tag "Plain TeX command" string variable)
+ (choice :tag "LaTeX command" string variable)
+ (choice :tag "ConTeXt command" string variable))))
+
+(defun TeX-engine-alist ()
+ "Return an alist of TeX engines.
+The function appends the built-in engine specs from
+`TeX-engine-alist-builtin' and the user-defined engines from
+`TeX-engine-alist' and deletes any entries from the built-in part
+where an entry with the same car exists in the user-defined part."
+ (TeX-delete-dups-by-car (append TeX-engine-alist TeX-engine-alist-builtin)))
+
+(defcustom TeX-engine 'default
+ (concat "Type of TeX engine to use.
+It should be one of the following symbols:\n\n"
+ (mapconcat (lambda (x) (format "* `%s'" (car x)))
+ (TeX-engine-alist) "\n"))
+ :group 'TeX-command
+ :type `(choice ,@(mapcar (lambda (x)
+ `(const :tag ,(nth 1 x) ,(car x)))
+ (TeX-engine-alist))))
+(make-variable-buffer-local 'TeX-engine)
+(put 'TeX-engine 'safe-local-variable
+ (lambda (arg) (memq arg (mapcar 'car TeX-engine-alist-builtin))))
+
+(defun TeX-engine-set (type)
+ (concat "Set TeX engine to TYPE.
+TYPE can be one of the following symbols:\n"
+ (mapconcat (lambda (x) (format "* `%s'" (car x)))
+ (TeX-engine-alist) "\n"))
+ (interactive (list (completing-read "Engine: "
+ (mapcar (lambda (x)
+ (symbol-name (car x)))
+ (TeX-engine-alist))
+ nil t)))
+ (when (stringp type)
+ (setq type (intern type)))
+ (setq TeX-engine type)
+ ;; Automatically enable or disable TeX PDF mode as a convenience
+ (cond ((eq type 'xetex) (TeX-PDF-mode 1))
+ ((eq type 'omega) (TeX-PDF-mode 0))))
+
+(define-minor-mode TeX-Omega-mode
+ "Minor mode for using the Omega engine."
+ nil nil nil
+ :group 'TeX-command
+ (TeX-engine-set (if TeX-Omega-mode 'omega 'default)))
+(defalias 'tex-omega-mode 'TeX-Omega-mode)
+(make-obsolete 'TeX-Omega-mode 'TeX-engine-set)
+(make-obsolete-variable 'TeX-Omega-mode 'TeX-engine)
+
+;;; Forward and inverse search
+
+(defcustom TeX-source-correlate-method 'auto
+ "Method to use for enabling forward and inverse search.
+This can be `source-specials' if source specials should be used,
+`synctex' if SyncTeX should be used, or`auto' if AUCTeX should
+decide.
+
+Setting this variable does not take effect if TeX Source
+Correlate mode has already been active. Restart Emacs in this
+case."
+ :type '(choice (const auto) (const synctex) (const source-specials))
+ :group 'TeX-view)
+
+(defvar TeX-source-correlate-method-active nil
+ "Method actually used for forward and inverse search.")
+
+(defvar TeX-source-correlate-output-page-function nil
+ "Symbol of function returning an output page relating to buffer position.
+The function should take no arguments and return the page numer
+as a string.")
+(make-variable-buffer-local 'TeX-source-correlate-output-page-function)
+
+(defcustom TeX-source-correlate-start-server 'ask
+ "Control if server should be started for inverse search."
+ :type '(choice (const :tag "Always" t)
+ (const :tag "Never" nil)
+ (const :tag "Ask" ask))
+ :group 'TeX-view)
+(when (fboundp 'defvaralias)
+ (defvaralias 'TeX-source-specials-view-start-server
+ 'TeX-source-correlate-start-server))
+
+(defvar TeX-source-correlate-start-server-asked nil
+ "Keep track if question about server start search was asked.")
+
+(defvar TeX-source-correlate-start-server-flag nil
+ "If non-nil, `TeX-source-correlate-start-server-maybe' will start a server.
+Code related to features requiring a server, e.g. for inverse
+search, can set the variable.")
+
+(defun TeX-source-correlate-gnuserv-p ()
+ "Guess whether to use gnuserv when a server is requested."
+ (cond ((and (boundp 'gnuserv-process)
+ (processp gnuserv-process)))
+ ((and (boundp 'server-process)
+ (processp server-process))
+ nil)
+ ((featurep 'xemacs))))
+
+(defun TeX-source-correlate-server-enabled-p ()
+ "Return non-nil if Emacs server or gnuserv is enabled."
+ (let* ((gnuserv-p (TeX-source-correlate-gnuserv-p))
+ (process (if gnuserv-p 'gnuserv-process 'server-process)))
+ (and (boundp process) (processp (symbol-value process)))))
+
+(defun TeX-source-correlate-start-server-maybe ()
+ "Start Emacs server or gnuserv if a feature using it is enabled.
+This is the case if `TeX-source-correlate-start-server-flag' is non-nil."
+ (when (and TeX-source-correlate-start-server-flag
+ (not (TeX-source-correlate-server-enabled-p)))
+ (let* ((gnuserv-p (TeX-source-correlate-gnuserv-p))
+ (start (if gnuserv-p 'gnuserv-start 'server-start)))
+ (cond
+ ;; Server should be started unconditionally
+ ((eq TeX-source-correlate-start-server t)
+ (funcall start))
+ ;; Ask user if server is to be started
+ ((and (eq TeX-source-correlate-start-server 'ask)
+ (not TeX-source-correlate-start-server-asked)
+ (prog1
+ (y-or-n-p (format "Start %s for inverse search in viewer? "
+ (if gnuserv-p
+ "gnuserv"
+ "Emacs server")))
+ (setq TeX-source-correlate-start-server-asked t)))
+ (funcall start))))))
+
+(defun TeX-source-correlate-determine-method ()
+ "Determine which method is available for forward and inverse search."
+ (let ((help (condition-case nil
+ (with-output-to-string
+ (call-process LaTeX-command
+ nil (list standard-output nil) nil "--help"))
+ (error ""))))
+ (if (string-match "^[ ]*-synctex" help)
+ 'synctex
+ 'source-specials)))
+
+(defun TeX-source-correlate-expand-options ()
+ "Return TeX engine command line option for forward search facilities.
+The return value depends on the value of `TeX-source-correlate-mode'.
+If this is nil, an empty string will be returned."
+ (if TeX-source-correlate-mode
+ (if (eq TeX-source-correlate-method-active 'source-specials)
+ (concat TeX-source-specials-tex-flags
+ (if TeX-source-specials-places
+ ;; -src-specials=WHERE: insert source specials
+ ;; in certain places of the DVI file. WHERE is a
+ ;; comma-separated value list: cr display hbox
+ ;; math par parend vbox
+ (concat "=" (mapconcat 'identity
+ TeX-source-specials-places ","))))
+ TeX-synctex-tex-flags)
+ ""))
+
+(defvar TeX-source-correlate-map
+ (let ((map (make-sparse-keymap)))
+ ;; (if (featurep 'xemacs)
+ ;; (define-key map [(control button1)] #'TeX-view-mouse)
+ ;; (define-key map [C-down-mouse-1] #'TeX-view-mouse))
+ map)
+ "Keymap for `TeX-source-correlate-mode'.
+You could use this for unusual mouse bindings.")
+
+(define-minor-mode TeX-source-correlate-mode
+ "Minor mode for forward and inverse search.
+
+If enabled, the viewer can be advised to show the output page
+corresponding to the point in the source and vice versa.
+
+The method to be used can be controlled with the variable
+`TeX-source-correlate-method'. Currently source specials or
+SyncTeX are recognized."
+ :group 'TeX-view
+ ;; Since this is a global minor mode and we don't want to require
+ ;; tex.el when the mode variable is set, the mode function is called
+ ;; explicitely (if necessary) in `VirTeX-common-initialization'. We
+ ;; do it there because otherwise `kill-all-local-variables' would
+ ;; reset `TeX-source-correlate-output-page-function' which is
+ ;; buffer-local.
+ :global t
+ (set-keymap-parent TeX-mode-map (and TeX-source-correlate-mode
+ TeX-source-correlate-map))
+ (TeX-set-mode-name 'TeX-source-correlate-mode t t)
+ (setq TeX-source-correlate-start-server-flag TeX-source-correlate-mode)
+ (unless TeX-source-correlate-method-active
+ (setq TeX-source-correlate-method-active
+ (if (eq TeX-source-correlate-method 'auto)
+ (TeX-source-correlate-determine-method)
+ TeX-source-correlate-method)))
+ (when (eq TeX-source-correlate-method-active 'synctex)
+ (setq TeX-source-correlate-output-page-function
+ (when TeX-source-correlate-mode
+ 'TeX-synctex-output-page))))
+(defalias 'TeX-source-specials-mode 'TeX-source-correlate-mode)
+(make-obsolete 'TeX-source-specials-mode 'TeX-source-correlate-mode)
+(defalias 'tex-source-correlate-mode 'TeX-source-correlate-mode)
+(put 'TeX-source-correlate-mode 'safe-local-variable 'TeX-booleanp)
+;; We do not want the custom variable to require tex.el. This is only
+;; necessary if AUCTeX was compiled with Emacs 21.
+(put 'TeX-source-correlate-mode 'custom-requests nil)
+(setq minor-mode-map-alist
+ (delq (assq 'TeX-source-correlate-mode minor-mode-map-alist)
+ minor-mode-map-alist))
+
+
+;;; Source Specials
+
+(defcustom TeX-source-specials-tex-flags "-src-specials"
+ "Extra flags to pass to TeX commands to generate source specials."
+ :group 'TeX-view
+ :type 'string)
+
+(defcustom TeX-source-specials-places nil
+ "List of places where to insert source specials into the DVI file.
+If nil, use (La)TeX's defaults."
+ :group 'TeX-view
+ :type '(list (set :inline t
+ ;; :tag "Options known to work"
+ ;; cr display hbox math par parend vbox
+ (const "cr")
+ (const "display")
+ (const "hbox")
+ (const "math")
+ (const "par")
+ (const "parend")
+ (const "vbox"))
+ (repeat :inline t
+ :tag "Other options"
+ (string))))
+
+(defcustom TeX-source-specials-view-position-flags
+ "-sourceposition \"%n %b\""
+ "Flags to pass to the DVI viewer commands for the position in the source."
+ :group 'TeX-view
+ :type 'string)
+
+(defcustom TeX-source-specials-view-editor-flags
+ "-editor \"%cS\""
+ "Flags to pass to DVI viewer commands for inverse search."
+ :group 'TeX-view
+ :type 'string)
+
+(defcustom TeX-source-specials-view-gnuclient-flags
+ "-q +%%l %%f"
+ "Flags to pass to gnuclient for inverse search."
+ :group 'TeX-view
+ :type 'string)
+
+(defcustom TeX-source-specials-view-emacsclient-flags
+ "--no-wait +%%l %%f"
+ "Flags to emacsclient for inverse search."
+ :group 'TeX-view
+ :type 'string)
+
+;; FIXME: Make client binaries configurable.
+(defun TeX-source-specials-view-expand-client ()
+ "Return gnuclient or emacslient executable with options.
+Return the full path to the executable if possible."
+ (let* ((gnuserv-p (TeX-source-correlate-gnuserv-p))
+ (client-base (if gnuserv-p
+ "gnuclient"
+ "emacsclient"))
+ (client-full (and invocation-directory
+ (expand-file-name client-base
+ invocation-directory)))
+ (options (if gnuserv-p
+ TeX-source-specials-view-gnuclient-flags
+ TeX-source-specials-view-emacsclient-flags)))
+ (if (and client-full (file-executable-p client-full))
+ (concat client-full " " options)
+ (concat client-base " " options))))
+
+(defun TeX-source-specials-view-expand-options (&optional viewer)
+ "Return source specials command line option for viewer command.
+The return value depends on the values of
+`TeX-source-correlate-mode' and
+`TeX-source-correlate-method-active'. If those are nil or not
+`source-specials' respectively, an empty string will be
+returned."
+ (if (and TeX-source-correlate-mode
+ (eq TeX-source-correlate-method-active 'source-specials))
+ (concat TeX-source-specials-view-position-flags
+ (when (TeX-source-correlate-server-enabled-p)
+ (concat " " TeX-source-specials-view-editor-flags)))
+ ""))
+
+;;; SyncTeX
+
+(defvar TeX-synctex-tex-flags "--synctex=1"
+ "Extra flags to pass to TeX commands to enable SyncTeX.")
+
+(defun TeX-synctex-output-page ()
+ "Return the page corresponding to the current source position.
+This method assumes that the document was compiled with SyncTeX
+enabled and the `synctex' binary is available."
+ (let ((synctex-output
+ (with-output-to-string
+ (call-process "synctex" nil (list standard-output nil) nil "view"
+ "-i" (format "%s:%s:%s" (line-number-at-pos)
+ (current-column)
+ ;; The file name relative to the
+ ;; directory of the master file.
+ (file-relative-name
+ (buffer-file-name)
+ (file-name-directory
+ (TeX-active-master))))
+ "-o" (TeX-active-master (TeX-output-extension))))))
+ (when (string-match "Page:\\([0-9]+\\)" synctex-output)
+ (match-string 1 synctex-output))))
+
+;;; Miscellaneous minor modes
+
+(defvar TeX-mode-p nil
+ "This indicates a TeX mode being active.")
+(make-variable-buffer-local 'TeX-mode-p)
+
+(defun TeX-mode-set (var value)
+ (set-default var value)
+ (TeX-set-mode-name var nil t))
+
+(defcustom TeX-PDF-mode nil nil
+ :group 'TeX-command
+ :set 'TeX-mode-set
+ :type 'boolean)
+(put 'TeX-PDF-mode 'safe-local-variable 'TeX-booleanp)
+
+(define-minor-mode TeX-PDF-mode
+ "Minor mode for using PDFTeX.
+
+If enabled, PDFTeX will be used as an executable by default.
+You can customize an initial value, and you can use the
+function `TeX-global-PDF-mode' for toggling this value."
+ :group 'TeX-command
+ (when (eq TeX-engine 'omega)
+ (setq TeX-PDF-mode nil))
+ (setq TeX-PDF-mode-parsed nil)
+ (TeX-set-mode-name nil nil t)
+ (setq TeX-output-extension
+ (if TeX-PDF-mode "pdf" "dvi")))
+(add-to-list 'minor-mode-alist '(TeX-PDF-mode ""))
+
+(defun TeX-global-PDF-mode (&optional arg)
+ "Toggle default for `TeX-PDF-mode'."
+ (interactive "P")
+ (prog1
+ (setq-default TeX-PDF-mode
+ (if arg (> (prefix-numeric-value arg) 0)
+ (not (default-value 'TeX-PDF-mode))))
+ (TeX-set-mode-name 'TeX-PDF-mode nil t)))
+
+(defalias 'tex-pdf-mode 'TeX-PDF-mode)
+
+(defvar TeX-PDF-mode-parsed nil
+ "Set if `TeX-PDF-mode' has come about by parsing.")
+
+(make-variable-buffer-local 'TeX-PDF-mode-parsed)
+
+(defun TeX-PDF-mode-parsed (arg)
+ "Change `TeX-PDF-mode' to ARG based on parsing.
+If this conflicts with previous parsed settings,
+just use the default. If an explicit setting is
+already established, don't do anything."
+
+;; Basically we have the following situations:
+;; TeX-PDF-mode-parsed (local-variable-p 'TeX-PDF-mode):
+;; nil nil : virgin state
+;; nil t : stably set state (possibly because of conflicting parse info)
+;; t t : non-conflicting parsed info
+
+ (if TeX-PDF-mode-parsed
+ (unless (eq TeX-PDF-mode arg)
+ (TeX-PDF-mode (if (default-value 'TeX-PDF-mode) 1 0)))
+ (unless (local-variable-p 'TeX-PDF-mode (current-buffer))
+ (TeX-PDF-mode (if arg 1 0))
+ (setq TeX-PDF-mode-parsed t))))
+
+(defun TeX-PDF-mode-on ()
+ "Use only from parsing routines."
+ (TeX-PDF-mode-parsed t))
+
+(defun TeX-PDF-mode-off ()
+ "Use only from parsing routines."
+ (TeX-PDF-mode-parsed nil))
+
+(defcustom TeX-DVI-via-PDFTeX nil
+ "Whether to use PDFTeX also for producing DVI files."
+ :group 'TeX-command
+ :type 'boolean)
+
+(define-minor-mode TeX-interactive-mode
+ "Minor mode for interactive runs of TeX."
+ nil nil nil
+ :group 'TeX-command
+ (TeX-set-mode-name 'TeX-interactive-mode t t))
+(defalias 'tex-interactive-mode 'TeX-interactive-mode)
+(add-to-list 'minor-mode-alist '(TeX-interactive-mode ""))
+
+;;; Commands
+
+(defgroup TeX-command-name nil
+ "Names for external commands in AUCTeX."
+ :group 'TeX-command)
+
+(defcustom TeX-command-BibTeX "BibTeX"
+ "*The name of the BibTeX entry in `TeX-command-list'."
+ :group 'TeX-command-name
+ :type 'string)
+ (make-variable-buffer-local 'TeX-command-BibTeX)
+
+(defcustom TeX-command-Show "View"
+ "*The default command to show (view or print) a TeX file.
+Must be the car of an entry in `TeX-command-list'."
+ :group 'TeX-command-name
+ :type 'string)
+ (make-variable-buffer-local 'TeX-command-Show)
+
+(defcustom TeX-command-Print "Print"
+ "The name of the Print entry in `TeX-command-Print'."
+ :group 'TeX-command-name
+ :type 'string)
+
+(defcustom TeX-command-Queue "Queue"
+ "The name of the Queue entry in `TeX-command-Queue'."
+ :group 'TeX-command-name
+ :type 'string)
+
+(defvar TeX-trailer-start nil
+ "Regular expression delimiting start of trailer in a TeX file.")
+
+ (make-variable-buffer-local 'TeX-trailer-start)
+
+(defvar TeX-header-end nil
+ "Regular expression delimiting end of header in a TeX file.")
+
+ (make-variable-buffer-local 'TeX-header-end)
+
+(defvar TeX-command-default nil
+ "The default command for `TeX-command' in the current major mode.")
+
+ (make-variable-buffer-local 'TeX-command-default)
+
+(put 'TeX-command-default 'safe-local-variable 'stringp)
+
+(defvar TeX-clean-default-intermediate-suffixes
+ '("\\.aux" "\\.bbl" "\\.blg" "\\.brf" "\\.fot"
+ "\\.glo" "\\.gls" "\\.idx" "\\.ilg" "\\.ind"
+ "\\.lof" "\\.log" "\\.lot" "\\.nav" "\\.out"
+ "\\.snm" "\\.toc" "\\.url" "\\.synctex\\.gz")
+ "List of regexps matching suffixes of files to be cleaned.
+Used as a default in TeX, LaTeX and docTeX mode.")
+
+(defvar TeX-clean-default-output-suffixes
+ '("\\.dvi" "\\.pdf" "\\.ps" "\\.xdv")
+ "List of regexps matching suffixes of files to be cleaned.
+Used as a default in TeX, LaTeX and docTeX mode.")
+
+(defcustom TeX-clean-confirm t
+ "If non-nil, ask before deleting files."
+ :type 'boolean
+ :group 'TeX-command)
+
+(autoload 'dired-mark-pop-up "dired")
+
+(defun TeX-clean (&optional arg)
+ "Delete generated files associated with current master and region files.
+If prefix ARG is non-nil, not only remove intermediate but also
+output files."
+ (interactive "P")
+ (let* ((mode-prefix (TeX-mode-prefix))
+ (suffixes (append (symbol-value
+ (intern (concat mode-prefix
+ "-clean-intermediate-suffixes")))
+ (when arg
+ (symbol-value
+ (intern (concat mode-prefix
+ "-clean-output-suffixes"))))))
+ (master (TeX-active-master))
+ (master-dir (file-name-directory master))
+ (regexp (concat "\\("
+ (file-name-nondirectory master) "\\|"
+ (TeX-region-file nil t)
+ "\\)"
+ "\\("
+ (mapconcat 'identity suffixes "\\|")
+ "\\)\\'"
+ "\\|" (TeX-region-file t t)))
+ (files (when regexp
+ (directory-files (or master-dir ".") nil regexp))))
+ (if files
+ (when (or (not TeX-clean-confirm)
+ (condition-case nil
+ (dired-mark-pop-up " *Deletions*" 'delete
+ (if (> (length files) 1)
+ files
+ (cons t files))
+ 'y-or-n-p "Delete files? ")
+ (wrong-type-argument ; e.g. with Emacs 21
+ (y-or-n-p (format "Delete %S? " (car files))))))
+ (dolist (file files)
+ (delete-file (concat master-dir file))))
+ (message "No files to be deleted"))))
+
+
+;;; Master File
+
+(defcustom TeX-master t
+ "*The master file associated with the current buffer.
+If the file being edited is actually included from another file, you
+can tell AUCTeX the name of the master file by setting this variable.
+If there are multiple levels of nesting, specify the top level file.
+
+If this variable is nil, AUCTeX will query you for the name.
+
+If the variable is t, AUCTeX will assume the file is a master file
+itself.
+
+If the variable is 'shared, AUCTeX will query for the name, but not
+change the file.
+
+If the variable is 'dwim, AUCTeX will try to avoid querying by
+attempting to `do what I mean'; and then change the file.
+
+It is suggested that you use the File Variables (see the info node in
+the Emacs manual) to set this variable permanently for each file."
+ :group 'TeX-command
+ :group 'TeX-parse
+ :type '(choice (const :tag "Query" nil)
+ (const :tag "This file" t)
+ (const :tag "Shared" shared)
+ (const :tag "Dwim" dwim)
+ (string :format "%v")))
+(make-variable-buffer-local 'TeX-master)
+(put 'TeX-master 'safe-local-variable
+ '(lambda (x)
+ (or (stringp x)
+ (member x (quote (t nil shared dwim))))))
+
+(defcustom TeX-one-master "\\.\\(texi?\\|dtx\\)$"
+ "*Regular expression matching ordinary TeX files.
+
+You should set this variable to match the name of all files, where
+automatically adding a file variable with the name of the master file
+is a good idea. When AUCTeX adds the name of the master file as a
+file variable, it does not need to ask next time you edit the file.
+
+If you dislike AUCTeX automatically modifying your files, you can set
+this variable to \"<none>\"."
+ :group 'TeX-command
+ :type 'regexp)
+
+(defvar TeX-convert-master t
+ "*If not nil, automatically convert ``Master:'' lines to file variables.
+This will be done when AUCTeX first try to use the master file.")
+
+;; Can be let-bound temporarily in order to inhibit the master file question
+;; by using its value instead in case `TeX-master' is nil or 'shared.
+(defvar TeX-transient-master nil)
+
+(defun TeX-dwim-master ()
+ "Find a likely `TeX-master'."
+ (let ((dir default-directory))
+ (dolist (buf (buffer-list))
+ (when (with-current-buffer buf
+ (and (equal dir default-directory)
+ (stringp TeX-master)))
+ (return (with-current-buffer buf TeX-master))))))
+
+(defun TeX-master-file-ask ()
+ "Ask for master file, set `TeX-master' and add local variables."
+ (interactive)
+ (if (TeX-local-master-p)
+ (error "Master file already set")
+ (let* ((default (TeX-dwim-master))
+ (name (or (and (eq 'dwim TeX-master) default)
+ (condition-case nil
+ (read-file-name (format "Master file: (default %s) "
+ (or default "this file"))
+ nil default)
+ (quit "<quit>")))))
+ (cond ((string= name "<quit>")
+ (setq TeX-master t))
+ ((string= name default)
+ (setq TeX-master default)
+ (TeX-add-local-master))
+ ((or
+ ;; Default `read-file-name' proposes and buffer visits a file.
+ (string= (expand-file-name name) (buffer-file-name))
+ ;; Default of `read-file-name' and buffer does not visit a file.
+ (string= name default-directory)
+ ;; User typed <RET> in an empty minibuffer.
+ (string= name ""))
+ (setq TeX-master t)
+ (TeX-add-local-master))
+ (t
+ (setq TeX-master (TeX-strip-extension (file-relative-name name)
+ (list TeX-default-extension)
+ 'path))
+ (TeX-add-local-master))))))
+
+(defun TeX-master-file (&optional extension nondirectory ask)
+ "Set and return the name of the master file for the current document.
+
+If optional argument EXTENSION is non-nil, add that file extension to
+the name. Special value t means use `TeX-default-extension'.
+
+If optional second argument NONDIRECTORY is non-nil, do not include
+the directory.
+
+If optional third argument ASK is non-nil, ask the user for the
+name of master file if it cannot be determined otherwise.
+
+Currently it will check for the presence of a ``Master:'' line in
+the beginning of the file, but that feature will be phased out."
+ (interactive)
+ (if (eq extension t)
+ (setq extension TeX-default-extension))
+ (let ((my-name (if (buffer-file-name)
+ (TeX-strip-extension nil (list TeX-default-extension) t)
+ "<none>")))
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (cond
+ ((and TeX-transient-master
+ (or (not TeX-master) (eq TeX-master 'shared)))
+ (setq TeX-master TeX-transient-master))
+ ;; Special value 't means it is own master (a free file).
+ ((equal TeX-master my-name)
+ (setq TeX-master t))
+
+ ;; For files shared between many documents.
+ ((and (eq 'shared TeX-master) ask)
+ (setq TeX-master
+ (let* ((default (TeX-dwim-master))
+ (name (read-file-name
+ (format "Master file: (default %s) "
+ (or default "this file"))
+ nil default)))
+ (cond ((string= name default)
+ default)
+ ((or
+ ;; Default `read-file-name' proposes and
+ ;; buffer visits a file.
+ (string= (expand-file-name name)
+ (buffer-file-name))
+ ;; Default of `read-file-name' and
+ ;; buffer does not visit a file.
+ (string= name default-directory)
+ ;; User typed <RET> in an empty minibuffer.
+ (string= name ""))
+ t)
+ (t
+ (TeX-strip-extension
+ name (list TeX-default-extension) 'path))))))
+
+ ;; We might already know the name.
+ ((or (eq TeX-master t) (stringp TeX-master)) TeX-master)
+
+ ;; Support the ``Master:'' line (under protest!)
+ ((re-search-forward
+ "^%% *[Mm]aster:?[ \t]*\\([^ \t\n]+\\)" 500 t)
+ (setq TeX-master
+ (TeX-strip-extension (TeX-match-buffer 1)
+ (list TeX-default-extension)))
+ (if TeX-convert-master
+ (progn
+ (beginning-of-line)
+ (kill-line 1)
+ (TeX-add-local-master))))
+
+ ;; Ask the user (but add it as a local variable).
+ (ask (TeX-master-file-ask)))))
+
+ (let ((name (if (stringp TeX-master)
+ TeX-master
+ my-name)))
+
+ (if (TeX-match-extension name)
+ ;; If it already has an extension...
+ (if (equal extension TeX-default-extension)
+ ;; Use instead of the default extension
+ (setq extension nil)
+ ;; Otherwise drop it.
+ (setq name (TeX-strip-extension name))))
+
+ ;; Remove directory if needed.
+ (if nondirectory
+ (setq name (file-name-nondirectory name)))
+
+ (if extension
+ (concat name "." extension)
+ name))))
+
+(defun TeX-master-directory ()
+ "Directory of master file."
+ (file-name-as-directory
+ (abbreviate-file-name
+ (substitute-in-file-name
+ (expand-file-name
+ (let ((dir (file-name-directory (TeX-master-file))))
+ (if dir (directory-file-name dir) "."))
+ (and buffer-file-name
+ (file-name-directory buffer-file-name)))))))
+
+(defun TeX-add-local-master ()
+ "Add local variable for `TeX-master'."
+ (when (and (buffer-file-name)
+ (string-match TeX-one-master
+ (file-name-nondirectory (buffer-file-name)))
+ (not buffer-read-only))
+ (goto-char (point-max))
+ (if (re-search-backward (concat "^\\([^\n]+\\)Local " "Variables:")
+ (- (point-max) 3000) t)
+ (let ((prefix (TeX-match-buffer 1)))
+ (re-search-forward (regexp-quote (concat prefix
+ "End:")))
+ (beginning-of-line 1)
+ (insert prefix "TeX-master: " (prin1-to-string TeX-master) "\n"))
+ (let ((comment-prefix (cond ((eq major-mode 'texinfo-mode) "@c ")
+ ((eq major-mode 'doctex-mode) "% ")
+ (t "%%% ")))
+ (mode (concat (and (boundp 'japanese-TeX-mode) japanese-TeX-mode
+ "japanese-")
+ (substring (symbol-name major-mode) 0 -5))))
+ (newline)
+ (when (eq major-mode 'doctex-mode)
+ (insert comment-prefix TeX-esc "endinput\n"))
+ (insert
+ comment-prefix "Local " "Variables: \n"
+ comment-prefix "mode: " mode "\n"
+ comment-prefix "TeX-master: " (prin1-to-string TeX-master) "\n"
+ comment-prefix "End: \n")))))
+
+(defun TeX-local-master-p ()
+ "Return non-nil if there is a `TeX-master' entry in local variables spec.
+Return nil otherwise."
+ (save-excursion
+ ;; XXX: Checking -*- line necessary as well?
+ (goto-char (point-max))
+ (search-backward "\n\^L" (max (- (point-max) 3000) (point-min)) 'move)
+ (re-search-forward "^%+ *TeX-master:" nil t)))
+
+;;; Style Paths
+
+(defcustom TeX-style-global (expand-file-name "style" TeX-data-directory)
+ "*Directory containing hand generated TeX information.
+
+These correspond to TeX macros shared by all users of a site."
+ :group 'TeX-file
+ :type 'directory)
+
+(defcustom TeX-auto-local "auto"
+ "*Directory containing automatically generated TeX information.
+
+This correspond to TeX macros found in the current directory, and must
+be relative to that."
+ :group 'TeX-file
+ :type 'string)
+
+(defcustom TeX-style-local "style"
+ "*Directory containing hand generated TeX information.
+
+These correspond to TeX macros found in the current directory, and must
+be relative to that."
+ :group 'TeX-file
+ :type 'string)
+
+(defun TeX-split-string (regexp string)
+ "Return a list of strings.
+Given REGEXP the STRING is split into sections which in string was
+seperated by REGEXP.
+
+Examples:
+
+ (TeX-split-string \"\:\" \"abc:def:ghi\")
+ -> (\"abc\" \"def\" \"ghi\")
+
+ (TeX-split-string \" +\" \"dvips -Plw -p3 -c4 testfile.dvi\")
+
+ -> (\"dvips\" \"-Plw\" \"-p3\" \"-c4\" \"testfile.dvi\")
+
+If REGEXP is nil, or \"\", an error will occur."
+
+ (let ((start 0) result match)
+ (while (setq match (string-match regexp string start))
+ (push (substring string start match) result)
+ (setq start (match-end 0)))
+ (push (substring string start) result)
+ (nreverse result)))
+
+(defun TeX-parse-path (env)
+ "Return a list if private TeX directories found in environment variable ENV."
+ (let* ((value (getenv env))
+ (entries (and value
+ (TeX-split-string
+ (if (string-match ";" value) ";" ":")
+ value)))
+ entry
+ answers)
+ (while entries
+ (setq entry (car entries))
+ (setq entries (cdr entries))
+ (setq entry (file-name-as-directory
+ (if (string-match "/?/?\\'" entry)
+ (substring entry 0 (match-beginning 0))
+ entry)))
+ (or (not (file-name-absolute-p entry))
+ (member entry (append '("/" "\\") TeX-macro-global))
+ (setq answers (cons entry answers))))
+ answers))
+
+(defun TeX-macro-global ()
+ "Return directories containing the site's TeX macro and style files."
+ (or (TeX-tree-expand '("$SYSTEXMF" "$TEXMFLOCAL" "$TEXMFMAIN" "$TEXMFDIST")
+ "latex" '("/tex/" "/bibtex/bst/"))
+ '("/usr/share/texmf/tex/" "/usr/share/texmf/bibtex/bst/")))
+
+(defun TeX-macro-private ()
+ "Return directories containing the user's TeX macro and style files."
+ (TeX-tree-expand '("$TEXMFHOME") "latex" '("/tex/" "/bibtex/bst/")))
+
+(defun TeX-tree-expand (trees program subdirs)
+ "Return directories corresponding to the TeX trees TREES.
+This is done calling `kpsewhich' where PROGRAM is passed as the
+parameter for --progname. SUBDIRS are subdirectories which are
+appended to the directories of the TeX trees."
+ (let (path-list path exit-status input-dir-list)
+ (condition-case nil
+ (catch 'success
+ (dotimes (i (safe-length trees))
+ (setq path (with-output-to-string
+ (setq exit-status
+ (call-process
+ "kpsewhich" nil
+ (list standard-output nil) nil
+ "--progname" program
+ "--expand-braces" (nth i trees)))))
+ (if (zerop exit-status)
+ (progn (add-to-list 'path-list path)
+ (when (zerop i) (throw 'success nil)))
+ (setq path (with-output-to-string
+ (setq exit-status
+ (call-process
+ "kpsewhich" nil
+ (list standard-output nil) nil
+ "--progname" program
+ "--expand-path" (nth i trees)))))
+ (when (zerop exit-status) (add-to-list 'path-list path)))))
+ (error nil))
+ (dolist (elt path-list)
+ (let ((separators (if (string-match "^[A-Za-z]:" elt)
+ "[\n\r;]"
+ "[\n\r:]")))
+ (dolist (item (condition-case nil
+ (split-string elt separators t)
+ ;; COMPATIBILITY for XEmacs <= 21.4.15
+ (error (delete "" (split-string elt separators)))))
+ (when (string-match "^!+" item)
+ (setq item (substring item (match-end 0) (length item))))
+ (when (string-match "/+$" item)
+ (setq item (substring item 0 (match-beginning 0))))
+ (dolist (subdir subdirs)
+ (when (file-exists-p (file-name-as-directory (concat item subdir)))
+ (add-to-list 'input-dir-list (concat item subdir)))))))
+ input-dir-list))
+
+(defcustom TeX-macro-global (TeX-macro-global)
+ "Directories containing the site's TeX macro and style files."
+ :group 'TeX-file
+ :type '(repeat (directory :format "%v")))
+
+(defcustom TeX-macro-private (or (append (TeX-parse-path "TEXINPUTS")
+ (TeX-parse-path "BIBINPUTS"))
+ (TeX-macro-private))
+ "Directories where you store your personal TeX macros."
+ :group 'TeX-file
+ :type '(repeat (file :format "%v")))
+
+(defcustom TeX-auto-private
+ (list (expand-file-name TeX-auto-local
+ (or (and (boundp 'user-emacs-directory)
+ (concat user-emacs-directory "auctex/"))
+ "~/.emacs.d/auctex/")))
+ "List of directories containing automatically generated AUCTeX style files.
+
+These correspond to the personal TeX macros."
+ :group 'TeX-file
+ :type '(repeat (file :format "%v")))
+
+(if (stringp TeX-auto-private) ;Backward compatibility
+ (setq TeX-auto-private (list TeX-auto-private)))
+
+(defcustom TeX-style-private
+ (list (expand-file-name TeX-style-local
+ (or (and (boundp 'user-emacs-directory)
+ (concat user-emacs-directory "auctex/"))
+ "~/.emacs.d/auctex/")))
+ "List of directories containing hand-generated AUCTeX style files.
+
+These correspond to the personal TeX macros."
+ :group 'TeX-file
+ :type '(repeat (file :format "%v")))
+
+(if (stringp TeX-style-private) ;Backward compatibility
+ (setq TeX-style-private (list TeX-style-private)))
+
+(defcustom TeX-style-path
+ (let ((path))
+ ;; Put directories in an order where the more local files can
+ ;; override the more global ones.
+ (mapcar (lambda (file) (when file (add-to-list 'path file t)))
+ (append (list TeX-auto-global TeX-style-global)
+ TeX-auto-private TeX-style-private
+ (list TeX-auto-local TeX-style-local)))
+ path)
+ "List of directories to search for AUCTeX style files.
+Per default the list is built from the values of the variables
+`TeX-auto-global', `TeX-style-global', `TeX-auto-private',
+`TeX-style-private', `TeX-auto-local', and `TeX-style-local'."
+ :group 'TeX-file
+ :type '(repeat (file :format "%v")))
+
+(defcustom TeX-check-path
+ (append (list ".") TeX-macro-private TeX-macro-global)
+ "Directory path to search for dependencies.
+
+If nil, just check the current file.
+Used when checking if any files have changed."
+ :group 'TeX-file
+ :type '(repeat (file :format "%v")))
+
+;;; Style Files
+
+(defvar TeX-style-hook-list nil
+ "List of TeX style hooks currently loaded.
+
+Each entry is a list where the first element is the name of the style,
+and the remaining elements are hooks to be run when that style is
+active.")
+
+(defcustom TeX-byte-compile nil
+ "*Not nil means try to byte compile auto files before loading."
+ :group 'TeX-parse
+ :type 'boolean)
+
+(defun TeX-load-style (style)
+ "Search for and load each definition for STYLE in `TeX-style-path'."
+ (cond ((assoc style TeX-style-hook-list)) ; We already found it
+ ((string-match "\\`\\(.+[/\\]\\)\\([^/\\]*\\)\\'" style) ;Complex path
+ (let* ((dir (substring style (match-beginning 1) (match-end 1)))
+ (style (substring style (match-beginning 2) (match-end 2)))
+ (master-dir (if (stringp TeX-master)
+ (file-name-directory
+ (file-relative-name TeX-master))
+ "./"))
+ (TeX-style-path (append (list (expand-file-name
+ TeX-auto-local dir)
+ (expand-file-name
+ TeX-auto-local master-dir)
+ (expand-file-name
+ TeX-style-local dir)
+ (expand-file-name
+ TeX-style-local master-dir))
+ TeX-style-path)))
+ (TeX-load-style style)))
+ (t ;Relative path
+ ;; Insert empty list to mark the fact that we have searched.
+ (setq TeX-style-hook-list (cons (list style) TeX-style-hook-list))
+ ;; Now check each element of the path
+ (dolist (name TeX-style-path)
+ (TeX-load-style-file (expand-file-name style name))))))
+
+(defun TeX-load-style-file (file)
+ "Load FILE checking for a Lisp extensions."
+ (let ((el (concat file ".el"))
+ (elc (concat file ".elc")))
+ (cond ((file-newer-than-file-p el elc)
+ (if (file-readable-p el)
+ (if (and TeX-byte-compile
+ (file-writable-p elc)
+ (save-excursion
+ ;; `byte-compile-file' switches buffer in Emacs 20.3.
+ (byte-compile-file el))
+ (file-readable-p elc))
+ (load-file elc)
+ (load-file el))))
+ ((file-readable-p elc)
+ (load-file elc))
+ ((file-readable-p el)
+ (load-file el)))))
+
+(defun TeX-add-style-hook (style hook)
+ "Give STYLE yet another HOOK to run."
+ (let ((entry (assoc style TeX-style-hook-list)))
+ (cond ((null entry)
+ ;; New style, add entry.
+ (setq TeX-style-hook-list (cons (list style hook)
+ TeX-style-hook-list)))
+ ((member hook entry)
+ ;; Old style, hook already there, do nothing.
+ nil)
+ (t
+ ;; Old style, new hook.
+ (setcdr entry (cons hook (cdr entry)))))))
+
+(defun TeX-unload-style (style)
+ "Forget that we once loaded STYLE."
+ (cond ((null (assoc style TeX-style-hook-list)))
+ ((equal (car (car TeX-style-hook-list)) style)
+ (setq TeX-style-hook-list (cdr TeX-style-hook-list)))
+ (t
+ (let ((entry TeX-style-hook-list))
+ (while (not (equal (car (car (cdr entry))) style))
+ (setq entry (cdr entry)))
+ (setcdr entry (cdr (cdr entry)))))))
+
+(defcustom TeX-virgin-style (if (and TeX-auto-global
+ (file-directory-p TeX-auto-global))
+ "virtex"
+ "NoVirtexSymbols")
+ "Style all documents use."
+ :group 'TeX-parse
+ :type 'string)
+
+(defvar TeX-active-styles nil
+ "List of styles currently active in the document.")
+ (make-variable-buffer-local 'TeX-active-styles)
+
+(defun TeX-run-style-hooks (&rest styles)
+ "Run the TeX style hooks STYLES."
+ (mapcar (lambda (style)
+ ;; Avoid recursion.
+ (unless (TeX-member style TeX-active-styles 'string-equal)
+ (setq TeX-active-styles
+ (cons style TeX-active-styles))
+ (TeX-load-style style)
+ (let ((default-directory default-directory))
+ ;; Complex path.
+ (when (string-match "\\`\\(.+[/\\]\\)\\([^/\\]*\\)\\'" style)
+ ;; Set `default-directory' to directory of master
+ ;; file since style files not stored in the fixed
+ ;; style directories are usually located there.
+ (setq default-directory (save-match-data
+ (TeX-master-directory))
+ style (substring style
+ (match-beginning 2) (match-end 2))))
+ (mapcar 'funcall
+ (cdr-safe (assoc style TeX-style-hook-list))))))
+ styles))
+
+(defcustom TeX-parse-self nil
+ "Parse file after loading it if no style hook is found for it."
+ :group 'TeX-parse
+ :type 'boolean)
+
+(defvar TeX-style-hook-applied-p nil
+ "Nil, unless the style specific hooks have been applied.")
+ (make-variable-buffer-local 'TeX-style-hook-applied-p)
+
+(defvar TeX-update-style-hook nil
+ "Hook run as soon as style specific hooks were applied.")
+
+(defun TeX-update-style (&optional force)
+ "Run style specific hooks for the current document.
+
+Only do this if it has not been done before, or if optional argument
+FORCE is not nil."
+ (unless (or (and (boundp 'TeX-auto-update)
+ (eq TeX-auto-update 'BibTeX)) ; Not a real TeX buffer
+ (and (not force)
+ TeX-style-hook-applied-p))
+ (setq TeX-style-hook-applied-p t)
+ (message "Applying style hooks...")
+ (TeX-run-style-hooks (TeX-strip-extension nil nil t))
+ ;; Run parent style hooks if it has a single parent that isn't itself.
+ (if (or (not (memq TeX-master '(nil t)))
+ (and (buffer-file-name)
+ (string-match TeX-one-master
+ (file-name-nondirectory (buffer-file-name)))))
+ (TeX-run-style-hooks (TeX-master-file)))
+ (if (and TeX-parse-self
+ (null (cdr-safe (assoc (TeX-strip-extension nil nil t)
+ TeX-style-hook-list))))
+ (TeX-auto-apply))
+ (run-hooks 'TeX-update-style-hook)
+ (message "Applying style hooks... done")))
+
+(defvar TeX-remove-style-hook nil
+ "List of hooks to call when we remove the style specific information.")
+ (make-variable-buffer-local 'TeX-remove-style-hook)
+
+(defun TeX-remove-style ()
+ "Remove all style specific information."
+ (setq TeX-style-hook-applied-p nil)
+ (run-hooks 'TeX-remove-style-hook)
+ (setq TeX-active-styles (list TeX-virgin-style)))
+
+(defun TeX-style-list ()
+ "Return a list of all styles (subfiles) used by the current document."
+ (TeX-update-style)
+ TeX-active-styles)
+
+;;; Special Characters
+
+(defvar TeX-esc "\\" "The TeX escape character.")
+ (make-variable-buffer-local 'TeX-esc)
+
+(defvar TeX-grop "{" "The TeX group opening character.")
+ (make-variable-buffer-local 'TeX-grop)
+
+(defvar TeX-grcl "}" "The TeX group closing character.")
+ (make-variable-buffer-local 'TeX-grcl)
+
+(defcustom plain-TeX-enable-toolbar t
+ "Enable TeX tool bar in plain TeX mode."
+ :group 'TeX-tool-bar
+ :type 'boolean)
+
+(defun plain-TeX-maybe-install-toolbar ()
+ "Conditionally install tool bar buttons for plain TeX mode.
+Install tool bar if `plain-TeX-enable-toolbar' is non-nil."
+ (when plain-TeX-enable-toolbar
+ ;; Defined in `tex-bar.el':
+ (TeX-install-toolbar)))
+
+;;; Symbols
+
+;; Must be before keymaps.
+
+(defgroup TeX-macro nil
+ "Support for TeX macros in AUCTeX."
+ :prefix "TeX-"
+ :group 'AUCTeX)
+
+(defcustom TeX-complete-word 'ispell-complete-word
+ "*Function to call for completing non-macros in `tex-mode'."
+ :group 'TeX-macro)
+
+(defvar TeX-complete-list nil
+ "List of ways to complete the preceding text.
+
+Each entry is a list with the following elements:
+
+0. Regexp matching the preceding text.
+1. A number indicating the subgroup in the regexp containing the text.
+2. A function returning an alist of possible completions.
+3. Text to append after a succesful completion.
+
+Or alternatively:
+
+0. Regexp matching the preceding text.
+1. Function to do the actual completion.")
+
+(defun TeX-complete-symbol ()
+ "Perform completion on TeX/LaTeX symbol preceding point."
+ (interactive "*")
+ (let ((list TeX-complete-list)
+ entry)
+ (while list
+ (setq entry (car list)
+ list (cdr list))
+ (if (TeX-looking-at-backward (car entry) 250)
+ (setq list nil)))
+ (if (numberp (nth 1 entry))
+ (let* ((sub (nth 1 entry))
+ (close (nth 3 entry))
+ (begin (match-beginning sub))
+ (end (match-end sub))
+ (pattern (TeX-match-buffer 0))
+ (symbol (buffer-substring begin end))
+ (list (funcall (nth 2 entry)))
+ (completion (try-completion symbol list)))
+ (cond ((eq completion t)
+ (and close
+ (not (looking-at (regexp-quote close)))
+ (insert close)))
+ ((null completion)
+ (error "Can't find completion for \"%s\"" pattern))
+ ((not (string-equal symbol completion))
+ (delete-region begin end)
+ (insert completion)
+ (and close
+ (eq (try-completion completion list) t)
+ (not (looking-at (regexp-quote close)))
+ (insert close)))
+ (t
+ (message "Making completion list...")
+ (let ((list (all-completions symbol list nil)))
+ (with-output-to-temp-buffer "*Completions*"
+ (display-completion-list list)))
+ (message "Making completion list...done"))))
+ (funcall (nth 1 entry)))))
+
+(defcustom TeX-default-macro "ref"
+ "*The default macro when creating new ones with `TeX-insert-macro'."
+ :group 'TeX-macro
+ :type 'string)
+
+(make-variable-buffer-local 'TeX-default-macro)
+
+(defcustom TeX-insert-braces t
+ "*If non-nil, append a empty pair of braces after inserting a macro."
+ :group 'TeX-macro
+ :type 'boolean)
+
+(defcustom TeX-insert-macro-default-style 'show-optional-args
+ "Specifies whether `TeX-insert-macro' will ask for all optional arguments.
+
+If set to the symbol `show-optional-args', `TeX-insert-macro' asks for
+optional arguments of TeX marcos. If set to `mandatory-args-only',
+`TeX-insert-macro' asks only for mandatory argument.
+
+When `TeX-insert-macro' is called with \\[universal-argument], it's the other
+way round.
+
+Note that for some macros, there are special mechanisms, see e.g.
+`LaTeX-includegraphics-options-alist'."
+ :group 'TeX-macro
+ :type '(choice (const mandatory-args-only)
+ (const show-optional-args)))
+
+(defvar TeX-arg-opening-brace nil
+ "String used as an opening brace for argument insertion.
+The variable will be temporarily let-bound with the necessary value.")
+
+(defvar TeX-arg-closing-brace nil
+ "String used as a closing brace for argument insertion.
+The variable will be temporarily let-bound with the necessary value.")
+
+(defvar TeX-after-insert-macro-hook nil
+ "A hook run after `TeX-insert-macro'.")
+
+(defvar TeX-macro-history nil)
+
+(defun TeX-insert-macro (symbol)
+ "Insert TeX macro SYMBOL with completion.
+
+AUCTeX knows of some macros and may query for extra arguments, depending on
+the value of `TeX-insert-macro-default-style' and whether `TeX-insert-macro'
+is called with \\[universal-argument]."
+ ;; When called with a prefix (C-u), only ask for mandatory arguments,
+ ;; i.e. all optional arguments are skipped. See `TeX-parse-arguments' for
+ ;; details. Note that this behavior may be changed in favor of a more
+ ;; flexible solution in the future, therefore we don't document it at the
+ ;; moment.
+ (interactive (list (completing-read (concat "Macro (default "
+ TeX-default-macro
+ "): "
+ TeX-esc)
+ (TeX-symbol-list) nil nil nil
+ 'TeX-macro-history)))
+ (cond ((string-equal symbol "")
+ (setq symbol TeX-default-macro))
+ ((interactive-p)
+ (setq TeX-default-macro symbol)))
+ (TeX-parse-macro symbol (cdr-safe (assoc symbol (TeX-symbol-list))))
+ (run-hooks 'TeX-after-insert-macro-hook))
+
+(defvar TeX-electric-macro-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map minibuffer-local-completion-map)
+ (define-key map " " 'minibuffer-complete-and-exit)
+ map))
+
+(defun TeX-electric-macro ()
+ "Insert TeX macro with completion.
+
+AUCTeX knows of some macros, and may query for extra arguments.
+Space will complete and exit."
+ (interactive)
+ (cond ((eq (preceding-char) ?\\)
+ (call-interactively 'self-insert-command))
+ ((eq (preceding-char) ?.)
+ (let ((TeX-default-macro " ")
+ (minibuffer-local-completion-map TeX-electric-macro-map))
+ (call-interactively 'TeX-insert-macro)))
+ (t
+ (let ((minibuffer-local-completion-map TeX-electric-macro-map))
+ (call-interactively 'TeX-insert-macro)))))
+
+(defun TeX-parse-macro (symbol args)
+ "How to parse TeX macros which takes one or more arguments.
+
+First argument SYMBOL is the name of the macro.
+
+If called with no additional arguments, insert macro with point
+inside braces. Otherwise, each argument of this function should
+match an argument to the TeX macro. What is done depend on the
+type of ARGS:
+
+ string: Use the string as a prompt to prompt for the argument.
+
+ number: Insert that many braces, leave point inside the first.
+
+ nil: Insert empty braces.
+
+ t: Insert empty braces, leave point between the braces.
+
+ other symbols: Call the symbol as a function. You can define
+ your own hook, or use one of the predefined argument hooks. If
+ you add new hooks, you can assume that point is placed directly
+ after the previous argument, or after the macro name if this is
+ the first argument. Please leave point located after the
+ argument you are inserting. If you want point to be located
+ somewhere else after all hooks have been processed, set the value
+ of `exit-mark'. It will point nowhere, until the argument hook
+ set it. By convention, these hooks all start with `TeX-arg-'.
+
+ list: If the car is a string, insert it as a prompt and the next
+ element as initial input. Otherwise, call the car of the list
+ with the remaining elements as arguments.
+
+ vector: Optional argument. If it has more than one element,
+ parse it as a list, otherwise parse the only element as above.
+ Use square brackets instead of curly braces, and is not inserted
+ on empty user input."
+
+ (if (and (TeX-active-mark)
+ (> (point) (mark)))
+ (exchange-point-and-mark))
+ (insert TeX-esc symbol)
+ (let ((exit-mark (make-marker))
+ (position (point)))
+ (TeX-parse-arguments args)
+ (cond ((marker-position exit-mark)
+ (goto-char (marker-position exit-mark))
+ (set-marker exit-mark nil))
+ ((and TeX-insert-braces
+ ;; Do not add braces for macros defined as `("foo" 0)'
+ (not (and (= (safe-length args) 1)
+ (numberp (car args))
+ (= (car args) 0)))
+ (equal position (point))
+ (string-match "[a-zA-Z]+" symbol)
+ (not (texmathp)))
+ (insert TeX-grop)
+ (if (TeX-active-mark)
+ (progn
+ (exchange-point-and-mark)
+ (insert TeX-grcl))
+ (insert TeX-grcl)
+ (backward-char))))))
+
+(defun TeX-arg-string (optional &optional prompt initial-input)
+ "Prompt for a string.
+
+If OPTIONAL is not nil then the PROMPT will start with ``(Optional) ''.
+INITIAL-INPUT is a string to insert before reading input."
+ (TeX-argument-insert
+ (if (and (not optional) (TeX-active-mark))
+ (let ((TeX-argument (buffer-substring (point) (mark))))
+ (delete-region (point) (mark))
+ TeX-argument)
+ (read-string (TeX-argument-prompt optional prompt "Text") initial-input))
+ optional))
+
+(defun TeX-parse-arguments (args)
+ "Parse TeX macro arguments ARGS.
+
+See `TeX-parse-macro' for details."
+ (let ((last-optional-rejected nil)
+ skip-opt)
+ ;; Maybe get rid of all optional arguments. See `TeX-insert-macro' for
+ ;; more comments. See `TeX-insert-macro-default-style'.
+ (when (or (and (eq TeX-insert-macro-default-style 'show-optional-args)
+ (equal current-prefix-arg '(4)))
+ (and (eq TeX-insert-macro-default-style 'mandatory-args-only)
+ (null (equal current-prefix-arg '(4)))))
+ (while (vectorp (car args))
+ (setq args (cdr args))))
+
+ (while args
+ (if (vectorp (car args))
+ (unless last-optional-rejected
+ (let ((TeX-arg-opening-brace LaTeX-optop)
+ (TeX-arg-closing-brace LaTeX-optcl))
+ (TeX-parse-argument t (if (equal (length (car args)) 1)
+ (aref (car args) 0)
+ (append (car args) nil)))))
+ (let ((TeX-arg-opening-brace TeX-grop)
+ (TeX-arg-closing-brace TeX-grcl))
+ (setq last-optional-rejected nil)
+ (TeX-parse-argument nil (car args))))
+ (setq args (cdr args)))))
+
+(defun TeX-parse-argument (optional arg)
+ "Depending on OPTIONAL, insert TeX macro argument ARG.
+If OPTIONAL is set, only insert if there is anything to insert, and
+then use square brackets instead of curly braces.
+
+See `TeX-parse-macro' for details."
+ (let (insert-flag)
+ (cond ((stringp arg)
+ (TeX-arg-string optional arg)
+ (setq insert-flag t))
+ ((numberp arg)
+ (unless (< arg 1)
+ (TeX-parse-argument optional t)
+ (while (> arg 1)
+ (TeX-parse-argument optional nil)
+ (setq arg (- arg 1)))))
+ ((null arg)
+ (insert TeX-arg-opening-brace)
+ (when (and (not optional) (TeX-active-mark))
+ (exchange-point-and-mark))
+ (insert TeX-arg-closing-brace)
+ (setq insert-flag t))
+ ((eq arg t)
+ (insert TeX-arg-opening-brace)
+ (if (and (not optional) (TeX-active-mark))
+ (progn
+ (exchange-point-and-mark))
+ (set-marker exit-mark (point)))
+ (insert TeX-arg-closing-brace)
+ (setq insert-flag t))
+ ((symbolp arg)
+ (funcall arg optional))
+ ((listp arg)
+ (let ((head (car arg))
+ (tail (cdr arg)))
+ (cond ((stringp head)
+ (apply 'TeX-arg-string optional arg))
+ ((symbolp head)
+ (apply head optional tail))
+ (t (error "Unknown list argument type %s"
+ (prin1-to-string head))))))
+ (t (error "Unknown argument type %s" (prin1-to-string arg))))
+ (when (and insert-flag (not optional) (TeX-active-mark))
+ (TeX-deactivate-mark))))
+
+(defun TeX-argument-insert (name optional &optional prefix)
+ "Insert NAME surrounded by curly braces.
+
+If OPTIONAL, only insert it if not empty, and then use square brackets.
+If PREFIX is given, insert it before NAME."
+ (if (and optional (string-equal name ""))
+ (setq last-optional-rejected t)
+ (insert TeX-arg-opening-brace)
+ (if prefix
+ (insert prefix))
+ (if (and (string-equal name "")
+ (null (marker-position exit-mark)))
+ (set-marker exit-mark (point))
+ (insert name))
+ (insert TeX-arg-closing-brace)))
+
+(defun TeX-argument-prompt (optional prompt default &optional complete)
+ "Return a argument prompt.
+
+If OPTIONAL is not nil then the prompt will start with ``(Optional) ''.
+
+PROMPT will be used if not nil, otherwise use DEFAULT.
+
+Unless optional argument COMPLETE is non-nil, ``: '' will be appended."
+ (concat (if optional "(Optional) " "")
+ (if prompt prompt default)
+ (if complete "" ": ")))
+
+(defun TeX-string-divide-number-unit (string)
+ "Divide number and unit in STRING.
+Return the number as car and unit as cdr."
+ (if (string-match "[0-9]*\\.?[0-9]+" string)
+ (list (substring string 0 (string-match "[^.0-9]" string))
+ (substring string (if (string-match "[^.0-9]" string)
+ (string-match "[^.0-9]" string)
+ (length string))))
+ (list "" string)))
+
+(defcustom TeX-default-unit-for-image "cm"
+ "Default unit when prompting for an image size."
+ :group 'TeX-macro
+ :type '(choice (const "cm")
+ (const "in")
+ (const "\\linewidth")
+ (string :tag "Other")))
+
+(defun TeX-arg-maybe (symbol list form)
+ "Evaluates FORM, if SYMBOL is an element of LIST."
+ (when (memq symbol list)
+ (eval form)))
+
+(defun TeX-arg-free (optional &rest args)
+ "Parse its arguments but use no braces when they are inserted."
+ (let ((TeX-arg-opening-brace "")
+ (TeX-arg-closing-brace ""))
+ (if (equal (length args) 1)
+ (TeX-parse-argument optional (car args))
+ (TeX-parse-argument optional args))))
+
+(defun TeX-arg-literal (optional &rest args)
+ "Insert its arguments ARGS into the buffer.
+Used for specifying extra syntax for a macro."
+ ;; FIXME: What is the purpose of OPTIONAL here? -- rs
+ (apply 'insert args))
+
+
+;;; Font Locking
+
+(defcustom TeX-install-font-lock 'font-latex-setup
+ "Function to call to install font lock support.
+Choose `ignore' if you don't want AUCTeX to install support for font locking."
+ :group 'TeX-misc
+ :type '(radio (function-item font-latex-setup)
+ (function-item tex-font-setup)
+ (function-item ignore)
+ (function :tag "Other")))
+
+;;; The Mode
+
+(defvar TeX-format-list
+ '(("JLATEX" japanese-latex-mode
+ "\\\\\\(documentstyle\\|documentclass\\)[^%\n]*{\\(j[s-]?\\|t\\)\
+\\(article\\|report\\|book\\|slides\\)")
+ ("JTEX" japanese-plain-tex-mode
+ "-- string likely in Japanese TeX --")
+ ("AMSTEX" ams-tex-mode
+ "\\\\document\\b")
+ ("CONTEXT" context-mode
+ "\\\\\\(start\\(text\\|tekst\\|proje[ck]t\\|proiect\\|\
+produ[ck]t\\|produs\\|environment\\|omgeving\\|umgebung\\|prostredi\\|mediu\\|\
+component\\|onderdeel\\|komponent[ea]\\|componenta\\)\
+\\|inizia\\(testo\\|progetto\\|prodotto\\|ambiente\\|componente\\)\
+\\)\\|%.*?interface=")
+ ("LATEX" latex-mode
+ "\\\\\\(begin\\|\\(?:sub\\)\\{0,2\\}section\\|chapter\\|documentstyle\\|\
+documentclass\\)\\b")
+ ("TEX" plain-tex-mode "."))
+ "*List of format packages to consider when choosing a TeX mode.
+
+A list with an entry for each format package available at the site.
+
+Each entry is a list with three elements.
+
+1. The name of the format package.
+2. The name of the major mode.
+3. A regexp typically matched in the beginning of the file.
+
+When entering `tex-mode', each regexp is tried in turn in order to find
+the major mode to be used.")
+
+(defcustom TeX-default-mode 'latex-mode
+ "*Mode to enter for a new file when it can't be determined otherwise."
+ :group 'TeX-misc
+ :type '(radio (function-item latex-mode)
+ (function-item plain-tex-mode)
+ (function :tag "Other")))
+
+(defcustom TeX-force-default-mode nil
+ "*If set to nil, try to infer the mode of the file from its content."
+ :group 'TeX-misc
+ :type 'boolean)
+
+;;;###autoload
+(defun TeX-tex-mode ()
+ "Major mode in AUCTeX for editing TeX or LaTeX files.
+Tries to guess whether this file is for plain TeX or LaTeX.
+
+The algorithm is as follows:
+
+ 1) if the file is empty or `TeX-force-default-mode' is not set to nil,
+ `TeX-default-mode' is chosen
+ 2) If \\documentstyle or \\begin{, \\section{, \\part{ or \\chapter{ is
+ found, `latex-mode' is selected.
+ 3) Otherwise, use `plain-tex-mode'"
+ (interactive)
+
+ (funcall (if (or (equal (buffer-size) 0)
+ TeX-force-default-mode)
+ TeX-default-mode
+ (save-excursion
+ (goto-char (point-min))
+ (let ((comment-start-skip ;Used by TeX-in-comment
+ (concat
+ "\\(\\(^\\|[^\\\n]\\)\\("
+ (regexp-quote TeX-esc)
+ (regexp-quote TeX-esc)
+ "\\)*\\)\\(%+ *\\)"))
+ (entry TeX-format-list)
+ answer)
+ (while (and entry (not answer))
+ (if (re-search-forward (nth 2 (car entry))
+ 10000 t)
+ (if (not (TeX-in-comment))
+ (setq answer (nth 1 (car entry))))
+ (setq entry (cdr entry))))
+ (if answer
+ answer
+ TeX-default-mode))))))
+
+(defun VirTeX-common-initialization ()
+ "Perform basic initialization."
+ (kill-all-local-variables)
+ (setq TeX-mode-p t)
+ (setq TeX-output-extension (if TeX-PDF-mode "pdf" "dvi"))
+ (setq local-abbrev-table text-mode-abbrev-table)
+ (setq indent-tabs-mode nil)
+
+ ;; Ispell support
+ (make-local-variable 'ispell-parser)
+ (setq ispell-parser 'tex)
+ (make-local-variable 'ispell-tex-p)
+ (setq ispell-tex-p t)
+
+ ;; Redefine some standard variables
+ (make-local-variable 'paragraph-start)
+ (make-local-variable 'paragraph-separate)
+ (make-local-variable 'comment-start)
+ (setq comment-start "%")
+ (make-local-variable 'comment-start-skip)
+ (setq comment-start-skip
+ (concat
+ "\\(\\(^\\|[^\\\n]\\)\\("
+ (regexp-quote TeX-esc)
+ (regexp-quote TeX-esc)
+ "\\)*\\)\\(%+[ \t]*\\)"))
+ (set (make-local-variable 'comment-end-skip) "[ \t]*\\(\\s>\\|\n\\)")
+ (set (make-local-variable 'comment-use-syntax) t)
+ ;; `comment-padding' is defined here as an integer for compatibility
+ ;; reasons because older Emacsen could not cope with a string.
+ (make-local-variable 'comment-padding)
+ (setq comment-padding 1)
+ ;; Removed as commenting in (La)TeX is done with one `%' not two
+ ;; (make-local-variable 'comment-add)
+ ;; (setq comment-add 1) ;default to `%%' in comment-region
+ (make-local-variable 'comment-indent-function)
+ (setq comment-indent-function 'TeX-comment-indent)
+ (make-local-variable 'comment-multi-line)
+ (setq comment-multi-line nil)
+ (make-local-variable 'compile-command)
+ (unless (boundp 'compile-command)
+ (setq compile-command "make"))
+ (make-local-variable 'words-include-escapes)
+ (setq words-include-escapes nil)
+
+ ;; Make TAB stand out
+ ;; (make-local-variable 'buffer-display-table)
+ ;; (setq buffer-display-table (if standard-display-table
+ ;; (copy-sequence standard-display-table)
+ ;; (make-display-table)))
+ ;; (aset buffer-display-table ?\t (apply 'vector (append "<TAB>" nil)))
+
+ ;; Symbol completion.
+ (make-local-variable 'TeX-complete-list)
+ (setq TeX-complete-list
+ (list (list "\\\\\\([a-zA-Z]*\\)"
+ 1 'TeX-symbol-list (if TeX-insert-braces "{}"))
+ (list "" TeX-complete-word)))
+
+ (funcall TeX-install-font-lock)
+
+ ;; We want this to be early in the list, so we do not add it before
+ ;; we enter TeX mode the first time.
+ (if (boundp 'local-write-file-hooks)
+ (add-hook 'local-write-file-hooks 'TeX-safe-auto-write)
+ (add-hook 'write-file-hooks 'TeX-safe-auto-write))
+ (make-local-variable 'TeX-auto-update)
+ (setq TeX-auto-update t)
+
+ ;; Minor modes
+ (when TeX-source-correlate-mode
+ (TeX-source-correlate-mode 1))
+
+ ;; Let `TeX-master-file' be called after a new file was opened and
+ ;; call `TeX-update-style' on any file opened. (The addition to the
+ ;; hook has to be made here because its local value will be deleted
+ ;; by `kill-all-local-variables' if it is added e.g. in `tex-mode'.)
+ ;;
+ ;; `TeX-update-style' has to be called before
+ ;; `global-font-lock-mode', which may also be specified in
+ ;; `find-file-hooks', gets called. Otherwise style-based
+ ;; fontification will break (in XEmacs). That means, `add-hook'
+ ;; cannot be called with a non-nil value of the APPEND argument.
+ ;;
+ ;; `(TeX-master-file nil nil t)' has to be called *before*
+ ;; `TeX-update-style' as the latter will call `TeX-master-file'
+ ;; without the `ask' bit set.
+ (when (and (featurep 'xemacs) (not (emacs-version>= 21 5)))
+ (make-local-hook 'find-file-hooks))
+ (add-hook 'find-file-hooks
+ (lambda ()
+ ;; Check if we are looking at a new or shared file.
+ (when (or (not (file-exists-p (buffer-file-name)))
+ (eq TeX-master 'shared))
+ (TeX-master-file nil nil t))
+ (TeX-update-style t)) nil t))
+
+;;; Plain TeX mode
+
+(defcustom plain-TeX-clean-intermediate-suffixes
+ TeX-clean-default-intermediate-suffixes
+ "List of regexps matching suffixes of intermediate files to be deleted.
+The regexps will be anchored at the end of the file name to be matched,
+i.e. you do _not_ have to cater for this yourself by adding \\\\' or $."
+ :type '(repeat regexp)
+ :group 'TeX-command)
+
+(defcustom plain-TeX-clean-output-suffixes TeX-clean-default-output-suffixes
+ "List of regexps matching suffixes of output files to be deleted.
+The regexps will be anchored at the end of the file name to be matched,
+i.e. you do _not_ have to cater for this yourself by adding \\\\' or $."
+ :type '(repeat regexp)
+ :group 'TeX-command)
+
+(defcustom plain-TeX-mode-hook nil
+ "A hook run in plain TeX mode buffers."
+ :type 'hook
+ :group 'TeX-misc)
+
+;;;###autoload
+(defun TeX-plain-tex-mode ()
+ "Major mode in AUCTeX for editing plain TeX files.
+See info under AUCTeX for documentation.
+
+Special commands:
+\\{plain-TeX-mode-map}
+
+Entering `plain-tex-mode' calls the value of `text-mode-hook',
+then the value of `TeX-mode-hook', and then the value
+of plain-TeX-mode-hook."
+ (interactive)
+ (plain-TeX-common-initialization)
+ (setq major-mode 'plain-tex-mode)
+ (use-local-map plain-TeX-mode-map)
+ (easy-menu-add plain-TeX-mode-menu plain-TeX-mode-map)
+ (easy-menu-add plain-TeX-mode-command-menu plain-TeX-mode-map)
+ (setq TeX-base-mode-name "TeX")
+ (setq TeX-command-default "TeX")
+ (setq TeX-sentinel-default-function 'TeX-TeX-sentinel)
+ (add-hook 'tool-bar-mode-on-hook 'plain-TeX-maybe-install-toolbar nil t)
+ (when (if (featurep 'xemacs)
+ (featurep 'toolbar)
+ (and (boundp 'tool-bar-mode) tool-bar-mode))
+ (plain-TeX-maybe-install-toolbar))
+ (TeX-run-mode-hooks 'text-mode-hook 'TeX-mode-hook 'plain-TeX-mode-hook)
+ (TeX-set-mode-name))
+
+(defun plain-TeX-common-initialization ()
+ "Common initialization for plain TeX like modes."
+ (VirTeX-common-initialization)
+ (set-syntax-table TeX-mode-syntax-table)
+ (setq paragraph-start
+ (concat
+ "\\(^[ \t]*$"
+ "\\|" (regexp-quote TeX-esc) "par\\|"
+ "^[ \t]*"
+ (regexp-quote TeX-esc)
+ "\\("
+ "begin\\|end\\|part\\|chapter\\|"
+ "section\\|subsection\\|subsubsection\\|"
+ "paragraph\\|include\\|includeonly\\|"
+ "tableofcontents\\|appendix\\|label\\|caption\\|"
+ "\\[\\|\\]" ; display math delimitors
+ "\\)"
+ "\\|"
+ "^[ \t]*\\$\\$" ; display math delimitor
+ "\\)" ))
+ (setq paragraph-separate
+ (concat
+ "[ \t]*"
+ "\\("
+ (regexp-quote TeX-esc) "par\\|"
+ "%\\|"
+ "$\\|"
+ "\\$\\$\\|"
+ (regexp-quote TeX-esc)
+ "\\("
+ "begin\\|end\\|label\\|caption\\|part\\|chapter\\|"
+ "section\\|subsection\\|subsubsection\\|"
+ "paragraph\\|include\\|includeonly\\|"
+ "tableofcontents\\|appendix\\|" (regexp-quote TeX-esc)
+ "\\)"
+ "\\)"))
+ (setq TeX-header-end (regexp-quote "%**end of header"))
+ (setq TeX-trailer-start (regexp-quote (concat TeX-esc "bye")))
+ (TeX-run-style-hooks "TEX"))
+
+;;; Hilighting
+
+(if (boundp 'hilit-patterns-alist)
+ (let ((latex-patterns (cdr-safe (assq 'latex-mode hilit-patterns-alist)))
+ (plain-tex-patterns (cdr-safe (assq 'plain-tex-mode
+ hilit-patterns-alist))))
+ (if (and latex-patterns plain-tex-patterns)
+ (setq hilit-patterns-alist
+ (append (list (cons 'ams-tex-mode plain-tex-patterns))
+ hilit-patterns-alist)))))
+
+;;; Parsing
+
+(defgroup TeX-parse nil
+ "Parsing TeX files from AUCTeX."
+ :group 'AUCTeX)
+
+(defvar TeX-auto-parser '((styles TeX-auto-file TeX-run-style-hooks)))
+;; Alist of parsed information.
+;; Each entry is a list with the following elements:
+;;
+;; 0. Name of information type.
+;; 1. Name of temporary variable used when parsing.
+;; 2. Name of function to add information to add to #3.
+;; 3. Name of variable holding buffer local information.
+;; 4. Name of variable indicating that #3 has changed.
+
+
+(defconst TeX-auto-parser-temporary 1)
+(defconst TeX-auto-parser-add 2)
+(defconst TeX-auto-parser-local 3)
+(defconst TeX-auto-parser-change 4)
+
+(defun TeX-auto-add-type (name prefix &optional plural)
+ "Add information about NAME to the parser using PREFIX.
+
+Optional third argument PLURAL is the plural form of TYPE.
+By default just add an `s'.
+
+This function create a set of variables and functions to maintain a
+separate type of information in the parser."
+ (let* ((names (or plural (concat name "s")))
+ (tmp (intern (concat prefix "-auto-" name)))
+ (add (intern (concat prefix "-add-" names)))
+ (local (intern (concat prefix "-" name "-list")))
+ (change (intern (concat prefix "-" name "-changed"))))
+ (setq TeX-auto-parser
+ (cons (list name tmp add local change) TeX-auto-parser))
+ (set local nil)
+ (make-variable-buffer-local local)
+ (set change nil)
+ (make-variable-buffer-local change)
+ (fset add `(lambda (&rest entries)
+ ,(concat "Add information about " (upcase name)
+ " to the current buffer.
+Generated by `TeX-auto-add-type'.")
+ (TeX-auto-add-information ,name entries)))
+ (fset local `(lambda nil
+ ,(concat "List of " names
+ " active in the current buffer.
+Generated by `TeX-auto-add-type'.")
+ (TeX-auto-list-information ,name)))
+ (add-hook 'TeX-remove-style-hook
+ `(lambda nil (setq ,(symbol-name local) nil)))))
+
+(defun TeX-auto-add-information (name entries)
+ "For NAME in `TeX-auto-parser' add ENTRIES."
+ (let* ((entry (assoc name TeX-auto-parser))
+ (change (nth TeX-auto-parser-change entry))
+ (change-value (symbol-value change))
+ (local (nth TeX-auto-parser-local entry))
+ (local-value (symbol-value local)))
+ (if change-value
+ (set local (cons entries local-value))
+ (set change t)
+ (set local (list entries local-value)))))
+
+(defun TeX-auto-list-information (name)
+ "Return information in `TeX-auto-parser' about NAME."
+ (TeX-update-style)
+ (let* ((entry (assoc name TeX-auto-parser))
+ (change (nth TeX-auto-parser-change entry))
+ (change-value (symbol-value change))
+ (local (nth TeX-auto-parser-local entry)))
+ (if (not change-value)
+ ()
+ (set change nil)
+ ;; Sort it
+ (message "Sorting %s..." name)
+ (set local
+ (sort (mapcar 'TeX-listify (apply 'append (symbol-value local)))
+ 'TeX-car-string-lessp))
+ ;; Make it unique
+ (message "Removing duplicates...")
+ (let ((entry (symbol-value local)))
+ (while (and entry (cdr entry))
+ (let ((this (car entry))
+ (next (car (cdr entry))))
+ (if (not (string-equal (car this) (car next)))
+ (setq entry (cdr entry))
+ ;; We have two equal symbols. Use the one with
+ ;; most arguments.
+ (if (> (length next) (length this))
+ (setcdr this (cdr next)))
+ (setcdr entry (cdr (cdr entry)))))))
+ (message "Removing duplicates... done"))
+ (symbol-value local)))
+
+(TeX-auto-add-type "symbol" "TeX")
+
+(defvar TeX-auto-apply-hook nil
+ "Hook run when a buffer is parsed and the information is applied.")
+
+(defun TeX-auto-apply ()
+ "Parse and apply TeX information in the current buffer."
+ (TeX-auto-parse)
+ (run-hooks 'TeX-auto-apply-hook)
+ (mapcar 'TeX-auto-apply-entry TeX-auto-parser))
+
+(defun TeX-auto-apply-entry (entry)
+ "Apply the information in ENTRY in `TeX-auto-parser'."
+ (let ((value (symbol-value (nth TeX-auto-parser-temporary entry)))
+ (add (nth TeX-auto-parser-add entry)))
+ (if value (apply add value))))
+
+(defun TeX-safe-auto-write ()
+ "Call `TeX-auto-write' safely."
+ (condition-case name
+ (and (boundp 'TeX-auto-update)
+ TeX-auto-update
+ (TeX-auto-write))
+ (error nil))
+ ;; Continue with the other write file hooks.
+ nil)
+
+(defcustom TeX-auto-save nil
+ "*Automatically save style information when saving the buffer."
+ :group 'TeX-parse
+ :type 'boolean)
+
+(defcustom TeX-auto-untabify nil
+ "*Automatically untabify when saving the buffer."
+ :group 'TeX-parse
+ :type 'boolean)
+
+(defun TeX-auto-write ()
+ "Save all relevant TeX information from the current buffer."
+ (if TeX-auto-untabify
+ (untabify (point-min) (point-max)))
+ (if (and TeX-auto-save TeX-auto-local)
+ (let* ((file (expand-file-name
+ (concat
+ (file-name-as-directory TeX-auto-local)
+ (TeX-strip-extension nil TeX-all-extensions t)
+ ".el")
+ (TeX-master-directory)))
+ (dir (file-name-directory file)))
+ ;; Create auto directory if possible.
+ (if (not (file-exists-p dir))
+ (condition-case name
+ (make-directory dir)
+ (error nil)))
+ (if (file-writable-p file)
+ (save-excursion
+ (TeX-update-style)
+ (TeX-auto-store file))
+ (message "Can't write style information.")))))
+
+(defcustom TeX-macro-default (car-safe TeX-macro-private)
+ "*Default directory to search for TeX macros."
+ :group 'TeX-file
+ :type 'directory)
+
+(defcustom TeX-auto-default (car-safe TeX-auto-private)
+ "*Default directory to place automatically generated TeX information."
+ :group 'TeX-file
+ :type 'directory)
+
+;;;###autoload
+(defun TeX-auto-generate (tex auto)
+ "Generate style file for TEX and store it in AUTO.
+If TEX is a directory, generate style files for all files in the directory."
+ (interactive (list (setq TeX-macro-default
+ (expand-file-name (read-file-name
+ "TeX file or directory: "
+ TeX-macro-default
+ TeX-macro-default 'confirm)))
+ (setq TeX-auto-default
+ (expand-file-name (read-file-name
+ "AUTO lisp directory: "
+ TeX-auto-default
+ TeX-auto-default 'confirm)))))
+ (cond ((not (file-readable-p tex)))
+ ((string-match TeX-ignore-file tex))
+ ((file-directory-p tex)
+ (let ((files (directory-files (expand-file-name tex)))
+ (default-directory (file-name-as-directory
+ (expand-file-name tex)))
+ (TeX-file-recurse (cond ((symbolp TeX-file-recurse)
+ TeX-file-recurse)
+ ((zerop TeX-file-recurse)
+ nil)
+ ((1- TeX-file-recurse)))))
+ (mapcar (lambda (file)
+ (if (or TeX-file-recurse
+ (not (file-directory-p file)))
+ (TeX-auto-generate file auto)))
+ files)))
+ ((not (file-newer-than-file-p
+ tex
+ (concat (file-name-as-directory auto)
+ (TeX-strip-extension tex TeX-all-extensions t)
+ ".el"))))
+ ((TeX-match-extension tex (append TeX-file-extensions
+ BibTeX-file-extensions))
+ (save-excursion
+ (set-buffer (let (enable-local-eval)
+ (find-file-noselect tex)))
+ (message "Parsing %s..." tex)
+ (TeX-auto-store (concat (file-name-as-directory auto)
+ (TeX-strip-extension tex
+ TeX-all-extensions
+ t)
+ ".el"))
+ (kill-buffer (current-buffer))
+ (message "Parsing %s... done" tex)))))
+
+;;;###autoload
+(defun TeX-auto-generate-global ()
+ "Create global auto directory for global TeX macro definitions."
+ (interactive)
+ (unless (file-directory-p TeX-auto-global)
+ (make-directory TeX-auto-global))
+ (let ((TeX-file-extensions '("cls" "sty"))
+ (BibTeX-file-extensions nil))
+ (mapc (lambda (macro) (TeX-auto-generate macro TeX-auto-global))
+ TeX-macro-global))
+ (byte-recompile-directory TeX-auto-global 0))
+
+(defun TeX-auto-store (file)
+ "Extract information for AUCTeX from current buffer and store it in FILE."
+ (TeX-auto-parse)
+
+ (if (member nil (mapcar 'TeX-auto-entry-clear-p TeX-auto-parser))
+ (let ((style (TeX-strip-extension nil TeX-all-extensions t)))
+ (TeX-unload-style style)
+ (save-excursion
+ (set-buffer (generate-new-buffer file))
+ (erase-buffer)
+ (insert "(TeX-add-style-hook \"" style "\"\n"
+ " (lambda ()")
+ (mapc (lambda (el) (TeX-auto-insert el style))
+ TeX-auto-parser)
+ (insert "))\n\n")
+ (write-region (point-min) (point-max) file nil 'silent)
+ (kill-buffer (current-buffer))))
+ (if (file-exists-p (concat file "c"))
+ (delete-file (concat file "c")))
+ (if (file-exists-p file)
+ (delete-file file))))
+
+(defun TeX-auto-entry-clear-p (entry)
+ "Check if the temporary for `TeX-auto-parser' entry ENTRY is clear."
+ ;; FIXME: This doc-string isn't clear to me. -- rs
+ (null (symbol-value (nth TeX-auto-parser-temporary entry))))
+
+(defun TeX-auto-insert (entry &optional skip)
+ "Insert code to initialize ENTRY from `TeX-auto-parser'.
+
+If SKIP is not-nil, don't insert code for SKIP."
+ (let ((name (symbol-name (nth TeX-auto-parser-add entry)))
+ (list (symbol-value (nth TeX-auto-parser-temporary entry))))
+ (unless (null list)
+ (insert "\n (" name)
+ (dolist (el list)
+ (cond ((and (stringp el) (not (string= el skip)))
+ (insert "\n ")
+ (insert (prin1-to-string el)))
+ ((not (stringp el))
+ (insert "\n ")
+ (insert "'" (prin1-to-string el)))))
+ (insert ")"))))
+
+(defvar TeX-auto-ignore
+ '("csname" "filedate" "fileversion" "docdate" "next" "labelitemi"
+ "labelitemii" "labelitemiii" "labelitemiv" "labelitemv"
+ "labelenumi" "labelenumii" "labelenumiii" "labelenumiv"
+ "labelenumv" "theenumi" "theenumii" "theenumiii" "theenumiv"
+ "theenumv" "document" "par" "do" "expandafter")
+ "List of symbols to ignore when scanning a TeX style file.")
+
+(defun TeX-auto-add-regexp (regexp)
+ "Add REGEXP to `TeX-auto-regexp-list' if not already a member."
+ (if (symbolp TeX-auto-regexp-list)
+ (setq TeX-auto-regexp-list (symbol-value TeX-auto-regexp-list)))
+ (or (memq regexp TeX-auto-regexp-list)
+ (setq TeX-auto-regexp-list (cons regexp TeX-auto-regexp-list))))
+
+(defvar TeX-auto-empty-regexp-list
+ '(("<IMPOSSIBLE>\\(\\'\\`\\)" 1 ignore))
+ "List of regular expressions guaranteed to match nothing.")
+
+(defvar TeX-token-char
+ (if (featurep 'mule)
+ "\\(?:[a-zA-Z]\\|\\cj\\)"
+ "[a-zA-Z]")
+ "Regexp matching a character in a TeX macro.
+
+Please use a shy group if you use a grouping construct, because
+the functions/variables which use `TeX-token-char' expect not to
+alter the numbering of any ordinary, non-shy groups.")
+
+(defvar plain-TeX-auto-regexp-list
+ (let ((token TeX-token-char))
+ `((,(concat "\\\\def\\\\\\(" token "+\\)[^a-zA-Z@]") 1 TeX-auto-symbol-check)
+ (,(concat "\\\\let\\\\\\(" token "+\\)[^a-zA-Z@]") 1 TeX-auto-symbol-check)
+ (,(concat "\\\\font\\\\\\(" token "+\\)[^a-zA-Z@]") 1 TeX-auto-symbol)
+ (,(concat "\\\\chardef\\\\\\(" token "+\\)[^a-zA-Z@]") 1 TeX-auto-symbol)
+ (,(concat "\\\\new\\(?:count\\|dimen\\|muskip\\|skip\\)\\\\\\(" token "+\\)[^a-zA-Z@]")
+ 1 TeX-auto-symbol)
+ (,(concat "\\\\newfont{?\\\\\\(" token "+\\)}?") 1 TeX-auto-symbol)
+ (,(concat "\\\\typein\\[\\\\\\(" token "+\\)\\]") 1 TeX-auto-symbol)
+ ("\\\\input +\\(\\.*[^#%\\\\\\.\n\r]+\\)\\(\\.[^#%\\\\\\.\n\r]+\\)?"
+ 1 TeX-auto-file)
+ (,(concat "\\\\mathchardef\\\\\\(" token "+\\)[^a-zA-Z@]") 1 TeX-auto-symbol)))
+ "List of regular expression matching common LaTeX macro definitions.")
+
+(defvar TeX-auto-full-regexp-list plain-TeX-auto-regexp-list
+ "Full list of regular expression matching TeX macro definitions.")
+
+(defvar TeX-auto-prepare-hook nil
+ "List of hooks to be called before parsing a TeX file.")
+
+(defvar TeX-auto-cleanup-hook nil
+ "List of hooks to be called after parsing a TeX file.")
+
+(defcustom TeX-auto-parse-length 999999
+ "Maximal length of TeX file (in characters) that will be parsed."
+ :group 'TeX-parse
+ :type 'integer)
+ (make-variable-buffer-local 'TeX-auto-parse-length)
+
+(defcustom TeX-auto-x-parse-length 0
+ "Maximum length of TeX file that will be parsed additionally.
+Use `TeX-auto-x-regexp-list' for parsing the region between
+`TeX-auto-parse-length' and this value."
+ :group 'TeX-parse
+ :type 'integer)
+ (make-variable-buffer-local 'TeX-auto-x-parse-length)
+
+(defcustom TeX-auto-x-regexp-list 'LaTeX-auto-label-regexp-list
+ "List of regular expressions used for additional parsing.
+See `TeX-auto-x-parse-length'."
+ :type '(radio (variable-item TeX-auto-empty-regexp-list)
+ (variable-item TeX-auto-full-regexp-list)
+ (variable-item plain-TeX-auto-regexp-list)
+ (variable-item LaTeX-auto-minimal-regexp-list)
+ (variable-item LaTeX-auto-label-regexp-list)
+ (variable-item LaTeX-auto-regexp-list)
+ (symbol :tag "Other")
+ (repeat :tag "Specify"
+ (group (regexp :tag "Match")
+ (sexp :tag "Groups")
+ symbol)))
+ :group 'TeX-parse)
+ (make-variable-buffer-local 'TeX-auto-x-regexp-list)
+
+(defun TeX-regexp-group-count (regexp)
+ "Return number of groups in a REGEXP. This is not foolproof:
+you should not use something like `[\\(]' for a character range."
+ (let (start (n 0))
+ (while (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\([^?]"
+ regexp start)
+ (setq start (- (match-end 0) 2)
+ n (1+ n)))
+ n))
+
+(defun TeX-auto-parse-region (regexp-list beg end)
+ "Parse TeX information according to REGEXP-LIST between BEG and END."
+ (if (symbolp regexp-list)
+ (setq regexp-list (and (boundp regexp-list) (symbol-value regexp-list))))
+ (if regexp-list
+ ;; Extract the information.
+ (let* (groups
+ (count 1)
+ (regexp (concat "\\("
+ (mapconcat
+ (lambda(x)
+ (push (cons count x) groups)
+ (setq count
+ (+ 1 count
+ (TeX-regexp-group-count (car x))))
+ (car x))
+ regexp-list "\\)\\|\\(")
+ "\\)"))
+ syms
+ lst)
+ (setq count 0)
+ (goto-char (if end (min end (point-max)) (point-max)))
+ (while (re-search-backward regexp beg t)
+ (let* ((entry (cdr (TeX-member nil groups
+ (lambda (a b)
+ (match-beginning (car b))))))
+ (symbol (nth 2 entry))
+ (match (nth 1 entry)))
+ (unless (TeX-in-comment)
+ (looking-at (nth 0 entry))
+ (if (fboundp symbol)
+ (funcall symbol match)
+ (puthash (if (listp match)
+ (mapcar #'TeX-match-buffer match)
+ (TeX-match-buffer match))
+ (setq count (1- count))
+ (cdr (or (assq symbol syms)
+ (car (push
+ (cons symbol
+ (make-hash-table :test 'equal))
+ syms)))))))))
+ (setq count 0)
+ (dolist (symbol syms)
+ (setq lst (symbol-value (car symbol)))
+ (while lst
+ (puthash (pop lst)
+ (setq count (1+ count))
+ (cdr symbol)))
+ (maphash (lambda (key value)
+ (push (cons value key) lst))
+ (cdr symbol))
+ (clrhash (cdr symbol))
+ (set (car symbol) (mapcar #'cdr (sort lst #'car-less-than-car)))))))
+
+
+(defun TeX-auto-parse ()
+ "Parse TeX information in current buffer.
+
+Call the functions in `TeX-auto-prepare-hook' before parsing, and the
+functions in `TeX-auto-cleanup-hook' after parsing."
+
+ (let ((case-fold-search nil))
+
+ (mapc 'TeX-auto-clear-entry TeX-auto-parser)
+ (run-hooks 'TeX-auto-prepare-hook)
+
+ (save-excursion
+ (and (> TeX-auto-x-parse-length TeX-auto-parse-length)
+ (> (point-max) TeX-auto-parse-length)
+ (TeX-auto-parse-region TeX-auto-x-regexp-list
+ TeX-auto-parse-length
+ TeX-auto-x-parse-length))
+ (TeX-auto-parse-region TeX-auto-regexp-list
+ nil TeX-auto-parse-length))
+
+ ;; Cleanup ignored symbols.
+
+ ;; NOTE: This is O(N M) where it could be O(N log N + M log M) if we
+ ;; sorted the lists first.
+ (while (member (car TeX-auto-symbol) TeX-auto-ignore)
+ (setq TeX-auto-symbol (cdr TeX-auto-symbol)))
+ (let ((list TeX-auto-symbol))
+ (while (and list (cdr list))
+ (if (member (car (cdr list)) TeX-auto-ignore)
+ (setcdr list (cdr (cdr list)))
+ (setq list (cdr list)))))
+
+ (run-hooks 'TeX-auto-cleanup-hook)))
+
+(defun TeX-auto-clear-entry (entry)
+ "Set the temporary variable in ENTRY to nil."
+ (set (nth TeX-auto-parser-temporary entry) nil))
+
+(defvar LaTeX-auto-end-symbol nil)
+
+(defun TeX-auto-symbol-check (match)
+ "Add MATCH to TeX-auto-symbols.
+Check for potential LaTeX environments."
+ (let ((symbol (if (listp match)
+ (mapcar 'TeX-match-buffer match)
+ (TeX-match-buffer match))))
+ (if (and (stringp symbol)
+ (string-match "^end\\(.+\\)$" symbol))
+ (add-to-list 'LaTeX-auto-end-symbol
+ (substring symbol (match-beginning 1) (match-end 1)))
+ (if (listp symbol)
+ (dolist (elt symbol)
+ (add-to-list 'TeX-auto-symbol elt))
+ (add-to-list 'TeX-auto-symbol symbol)))))
+
+;;; Utilities
+;;
+;; Some of these functions has little to do with TeX, but nonetheless we
+;; should use the "TeX-" prefix to avoid name clashes.
+
+(defcustom TeX-auto-regexp-list 'TeX-auto-full-regexp-list
+ "*List of regular expressions used for parsing the current file."
+ :type '(radio (variable-item TeX-auto-empty-regexp-list)
+ (variable-item TeX-auto-full-regexp-list)
+ (variable-item plain-TeX-auto-regexp-list)
+ (variable-item LaTeX-auto-minimal-regexp-list)
+ (variable-item LaTeX-auto-label-regexp-list)
+ (variable-item LaTeX-auto-regexp-list)
+ (symbol :tag "Other")
+ (repeat :tag "Specify"
+ (group (regexp :tag "Match")
+ (sexp :tag "Groups")
+ symbol)))
+ :group 'TeX-parse)
+ (make-variable-buffer-local 'TeX-auto-regexp-list)
+
+(defgroup TeX-file-extension nil
+ "File extensions recognized by AUCTeX."
+ :group 'TeX-file)
+
+(defcustom TeX-file-extensions '("tex" "sty" "cls" "ltx" "texi" "texinfo" "dtx")
+ "*File extensions used by manually generated TeX files."
+ :group 'TeX-file-extension
+ :type '(repeat (string :format "%v")))
+
+(defcustom TeX-all-extensions '("[^.\n]+")
+ "All possible file extensions."
+ :group 'TeX-file-extension
+ :type '(repeat (regexp :format "%v")))
+
+(defcustom TeX-default-extension "tex"
+ "*Default extension for TeX files."
+ :group 'TeX-file-extension
+ :type 'string)
+
+ (make-variable-buffer-local 'TeX-default-extension)
+
+(defcustom docTeX-default-extension "dtx"
+ "*Default extension for docTeX files."
+ :group 'TeX-file-extension
+ :type 'string)
+
+(defvar TeX-output-extension nil
+ "Extension of TeX output file.
+This is either a string or a list with
+a string as element. Its value is obtained from `TeX-command-output-list'.
+Access to the value should be through the function `TeX-output-extension'.")
+
+ (make-variable-buffer-local 'TeX-output-extension)
+
+(defcustom BibTeX-file-extensions '("bib")
+ "Valid file extensions for BibTeX files."
+ :group 'TeX-file-extension
+ :type '(repeat (string :format "%v")))
+
+(defcustom BibTeX-style-extensions '("bst")
+ "Valid file extensions for BibTeX styles."
+ :group 'TeX-file-extension
+ :type '(repeat (string :format "%v")))
+
+(defcustom TeX-ignore-file "\\(^\\|[/\\]\\)\\(\\.\\|\\.\\.\\|RCS\\|SCCS\\|CVS\\|babel\\..*\\)$"
+ "Regular expression matching file names to ignore.
+
+These files or directories will not be considered when searching for
+TeX files in a directory."
+ :group 'TeX-parse
+ :type 'regexp)
+
+(defcustom TeX-file-recurse t
+ "*Whether to search TeX directories recursively.
+nil means do not recurse, a positive integer means go that far deep in the
+directory hierarchy, t means recurse indefinitely."
+ :group 'TeX-parse
+ :type '(choice (const :tag "On" t)
+ (const :tag "Off" nil)
+ (integer :tag "Depth" :value 1)))
+
+(defun TeX-match-extension (file &optional extensions)
+ "Return non-nil if FILE has one of EXTENSIONS.
+
+If EXTENSIONS is not specified or nil, the value of
+`TeX-file-extensions' is used instead."
+
+ (if (null extensions)
+ (setq extensions TeX-file-extensions))
+
+ (let ((regexp (concat "\\.\\("
+ (mapconcat 'identity extensions "\\|")
+ "\\)$"))
+ (case-fold-search t))
+ (string-match regexp file)))
+
+(defun TeX-strip-extension (&optional string extensions nodir nostrip)
+ "Return STRING without any trailing extension in EXTENSIONS.
+If NODIR is t, also remove directory part of STRING.
+If NODIR is `path', remove directory part of STRING if it is equal to
+the current directory, `TeX-macro-private' or `TeX-macro-global'.
+If NOSTRIP is set, do not remove extension after all.
+STRING defaults to the name of the current buffer.
+EXTENSIONS defaults to `TeX-file-extensions'."
+
+ (if (null string)
+ (setq string (or (buffer-file-name) "<none>")))
+
+ (if (null extensions)
+ (setq extensions TeX-file-extensions))
+
+ (let* ((strip (if (and (not nostrip)
+ (TeX-match-extension string extensions))
+ (substring string 0 (match-beginning 0))
+ string))
+ (dir (expand-file-name (or (file-name-directory strip) "./"))))
+ (if (or (eq nodir t)
+ (string-equal dir (expand-file-name "./"))
+ (member dir TeX-macro-global)
+ (member dir TeX-macro-private))
+ (file-name-nondirectory strip)
+ strip)))
+
+(defcustom TeX-kpathsea-path-delimiter t
+ "Path delimiter for kpathsea output.
+t means autodetect, nil means kpathsea is disabled."
+ :group 'TeX-file
+ :type '(choice (const ":")
+ (const ";")
+ (const :tag "Autodetect" t)
+ (const :tag "Off" nil)))
+
+(defcustom TeX-kpathsea-format-alist
+ '(("tex" "${TEXINPUTS.latex}" TeX-file-extensions)
+ ("sty" "${TEXINPUTS.latex}" '("sty"))
+ ("dvi" "${TEXDOCS}" '("dvi" "pdf" "ps" "txt" "html"
+ "dvi.gz" "pdf.gz" "ps.gz" "txt.gz" "html.gz"
+ "dvi.bz2" "pdf.bz2" "ps.bz2" "txt.bz2" "html.bz2"))
+ ("eps" "${TEXINPUTS}" LaTeX-includegraphics-extensions)
+ ("pdf" "${TEXINPUTS}" LaTeX-includegraphics-extensions)
+ ("png" "${TEXINPUTS}" LaTeX-includegraphics-extensions)
+ ("jpg" "${TEXINPUTS}" LaTeX-includegraphics-extensions)
+ ("jpeg" "${TEXINPUTS}" LaTeX-includegraphics-extensions)
+ ("bib" "$BIBINPUTS" BibTeX-file-extensions)
+ ("bst" "$BSTINPUTS" BibTeX-style-extensions))
+ "Formats to search for expansion using kpathsea.
+The key of the alist represents the name of the format. The
+first element of the cdr of the alist is string to expand by the
+respective kpathsea program and the second element is a list of
+file extensions to match."
+ :group 'TeX-file
+ :type '(alist :key-type string :value-type (group string sexp)))
+
+;; FIXME: Despite the first parameter named `extensions',
+;; `TeX-search-files-kpathsea' basically treats this as a format
+;; specifier. Only the first element in the respective list will be
+;; used to determine the search paths and file extensions with the
+;; help of `TeX-kpathsea-format-alist'. Out of these differences
+;; arises a need to unify the behavior of `TeX-search-files' and
+;; `TeX-search-files-kpathsea' and their treatment of parameters.
+;; Additionally `TeX-search-files-kpathsea' should be made more
+;; general to work with other platforms and TeX systems as well.
+(defun TeX-search-files-kpathsea (extensions nodir strip)
+ "The kpathsea-enabled version of `TeX-search-files'.
+Except for DIRECTORIES (a kpathsea string), the arguments for
+EXTENSIONS, NODIR and STRIP are explained there."
+ (and TeX-kpathsea-path-delimiter
+ (catch 'no-kpathsea
+ (let* ((format-spec (assoc (car extensions)
+ TeX-kpathsea-format-alist))
+ (dirs (with-output-to-string
+ (unless (zerop
+ (call-process
+ "kpsewhich" nil (list standard-output nil)
+ nil
+ (concat
+ "-expand-path="
+ (nth 1 format-spec))))
+ (if (eq TeX-kpathsea-path-delimiter t)
+ (throw 'no-kpathsea
+ (setq TeX-kpathsea-path-delimiter nil))
+ (error "kpsewhich error")))))
+ result)
+ (when (eq TeX-kpathsea-path-delimiter t)
+ (setq TeX-kpathsea-path-delimiter
+ (cond ((string-match ";" dirs)
+ ";")
+ ((string-match ":" dirs)
+ ":"))))
+ (unless TeX-kpathsea-path-delimiter
+ (throw 'no-kpathsea nil))
+ (setq dirs (split-string dirs (concat "[\n\r"
+ TeX-kpathsea-path-delimiter
+ "]+")))
+ (setq extensions (concat "\\."
+ (regexp-opt (eval (nth 2 format-spec)) t)
+ "\\'"))
+ (setq result
+ (apply #'append
+ (mapcar
+ (lambda(x) (directory-files x
+ (not nodir)
+ extensions))
+ dirs)))
+ (if strip
+ (mapcar (lambda(x)
+ (if (string-match extensions x)
+ (substring x 0 (match-beginning 0))
+ x))
+ result)
+ result)))))
+
+(defun TeX-search-files (&optional directories extensions nodir strip)
+ "Return a list of all reachable files in DIRECTORIES ending with EXTENSIONS.
+If optional argument NODIR is set, remove directory part.
+If optional argument STRIP is set, remove file extension.
+If optional argument DIRECTORIES is set, search in those directories.
+Otherwise, search in all TeX macro directories.
+If optional argument EXTENSIONS is not set, use `TeX-file-extensions'"
+ (if (null extensions)
+ (setq extensions TeX-file-extensions))
+ (or (TeX-search-files-kpathsea extensions nodir strip)
+ (progn
+ (if (null directories)
+ (setq directories
+ (cons "./" (append TeX-macro-private TeX-macro-global))))
+ (let (match
+ (TeX-file-recurse (cond ((symbolp TeX-file-recurse)
+ TeX-file-recurse)
+ ((zerop TeX-file-recurse)
+ nil)
+ ((1- TeX-file-recurse)))))
+ (while directories
+ (let* ((directory (car directories))
+ (content (and directory
+ (file-readable-p directory)
+ (file-directory-p directory)
+ (directory-files directory))))
+ (setq directories (cdr directories))
+ (while content
+ (let ((file (concat directory (car content))))
+ (setq content (cdr content))
+ (cond ((string-match TeX-ignore-file file))
+ ((not (file-readable-p file)))
+ ((file-directory-p file)
+ (if TeX-file-recurse
+ (setq match
+ (append match
+ (TeX-search-files
+ (list (file-name-as-directory file))
+ extensions
+ nodir strip)))))
+ ((TeX-match-extension file extensions)
+ (setq match (cons (TeX-strip-extension file
+ extensions
+ nodir
+ (not strip))
+ match))))))))
+ match))))
+
+(defun TeX-car-string-lessp (s1 s2)
+ "Compare the cars of S1 and S2 in lexicographic order.
+Return t if first is less than second in lexicographic order."
+ (string-lessp (car s1) (car s2)))
+
+(defun TeX-listify (elt)
+ "Return a newly created list with element ELT.
+If ELT already is a list, return ELT."
+ (if (listp elt) elt (list elt)))
+
+(defun TeX-member (elt list how)
+ "Return the member ELT in LIST. Comparison done with HOW.
+Return nil if ELT is not a member of LIST."
+ (while (and list (not (funcall how elt (car list))))
+ (setq list (cdr list)))
+ (car-safe list))
+
+(defun TeX-elt-of-list-member (elts list)
+ "Return non-nil if an element of ELTS is a member of LIST."
+ (catch 'found
+ (dolist (elt elts)
+ (when (member elt list)
+ (throw 'found t)))))
+
+(defun TeX-assoc (key list)
+ "Return non-nil if KEY is `equal' to the car of an element of LIST.
+Like assoc, except case insensitive."
+ (let ((case-fold-search t))
+ (TeX-member key list
+ (lambda (a b)
+ (string-match (concat "^" (regexp-quote a) "$")
+ (car b))))))
+
+(defun TeX-match-buffer (n)
+ "Return the substring corresponding to the N'th match.
+See `match-data' for details."
+ (if (match-beginning n)
+ (buffer-substring-no-properties (match-beginning n) (match-end n))
+ ""))
+
+(defun TeX-function-p (arg)
+ "Return non-nil if ARG is callable as a function."
+ (or (and (fboundp 'byte-code-function-p)
+ (byte-code-function-p arg))
+ (and (listp arg)
+ (eq (car arg) 'lambda))
+ (and (symbolp arg)
+ (fboundp arg))))
+
+(defun TeX-booleanp (arg)
+ "Return non-nil if ARG is t or nil."
+ (memq arg '(t nil)))
+
+(defun TeX-looking-at-backward (regexp &optional limit)
+ "Return non-nil if the text before point matches REGEXP.
+Optional second argument LIMIT gives a max number of characters
+to look backward for."
+ (let ((pos (point)))
+ (save-excursion
+ (and (re-search-backward regexp
+ (if limit (max (point-min) (- (point) limit)))
+ t)
+ (eq (match-end 0) pos)))))
+
+(defun TeX-current-line ()
+ "The current line number."
+ (format "%d" (1+ (TeX-current-offset))))
+
+(defun TeX-current-file-name-master-relative ()
+ "Return current filename, relative to master directory."
+ (file-relative-name
+ (buffer-file-name)
+ (TeX-master-directory)))
+
+(defun TeX-near-bobp ()
+ "Return t iff there's nothing but whitespace between (bob) and (point)."
+ (save-excursion
+ (skip-chars-backward " \t\n")
+ (bobp)))
+
+(defun TeX-deactivate-mark ()
+ "Deactivate the mark.
+This is a compatibility function which works both in Emacs and
+XEmacs. In XEmacs the region is deactivated instead of the
+mark which is sort of equivalent."
+ (if (featurep 'xemacs)
+ (zmacs-deactivate-region)
+ (deactivate-mark)))
+
+(defalias 'TeX-run-mode-hooks
+ (if (fboundp 'run-mode-hooks) 'run-mode-hooks 'run-hooks))
+
+
+;;; Syntax Table
+
+(defvar TeX-mode-syntax-table (make-syntax-table)
+ "Syntax table used while in TeX mode.")
+
+ (make-variable-buffer-local 'TeX-mode-syntax-table)
+
+(progn ; Define TeX-mode-syntax-table.
+ (modify-syntax-entry (string-to-char TeX-esc)
+ "\\" TeX-mode-syntax-table)
+ (modify-syntax-entry ?\f ">" TeX-mode-syntax-table)
+ (modify-syntax-entry ?\n ">" TeX-mode-syntax-table)
+ (modify-syntax-entry (string-to-char TeX-grop)
+ (concat "(" TeX-grcl)
+ TeX-mode-syntax-table)
+ (modify-syntax-entry (string-to-char TeX-grcl)
+ (concat ")" TeX-grop)
+ TeX-mode-syntax-table)
+ (modify-syntax-entry ?% "<" TeX-mode-syntax-table)
+ (modify-syntax-entry ?\" "." TeX-mode-syntax-table)
+ (modify-syntax-entry ?& "." TeX-mode-syntax-table)
+ (modify-syntax-entry ?_ "." TeX-mode-syntax-table)
+ (modify-syntax-entry ?@ "_" TeX-mode-syntax-table)
+ (modify-syntax-entry ?~ "." TeX-mode-syntax-table)
+ (modify-syntax-entry ?$ "$" TeX-mode-syntax-table)
+ (modify-syntax-entry ?' "w" TeX-mode-syntax-table)
+ (modify-syntax-entry ?« "." TeX-mode-syntax-table)
+ (modify-syntax-entry ?» "." TeX-mode-syntax-table))
+
+;;; Menu Support
+
+(defvar TeX-command-current 'TeX-command-master
+ "Specify whether to run command on master, buffer or region.")
+;; Function used to run external command.
+
+(defun TeX-command-select-master ()
+ "Determine that the next command will be on the master file."
+ (interactive)
+ (message "Next command will be on the master file.")
+ (setq TeX-command-current 'TeX-command-master))
+
+(defun TeX-command-select-buffer ()
+ "Determine that the next command will be on the buffer."
+ (interactive)
+ (message "Next command will be on the buffer")
+ (setq TeX-command-current 'TeX-command-buffer))
+
+(defun TeX-command-select-region ()
+ "Determine that the next command will be on the region."
+ (interactive)
+ (message "Next command will be on the region")
+ (setq TeX-command-current 'TeX-command-region))
+
+(defvar TeX-command-force nil)
+;; If non-nil, TeX-command-query will return the value of this
+;; variable instead of quering the user.
+
+(defun TeX-command-menu (name)
+ "Execute `TeX-command-list' NAME from a menu."
+ (let ((TeX-command-force name))
+ (funcall TeX-command-current)))
+
+(defun TeX-command-menu-print (printer command name)
+ "Print on PRINTER using method COMMAND to run NAME."
+ (let ((TeX-printer-default (unless (string= printer "Other") printer))
+ (TeX-printer-list (and (string= printer "Other") TeX-printer-list))
+ (TeX-print-command command)
+ (TeX-queue-command command))
+ (TeX-command-menu name)))
+
+(defun TeX-command-menu-printer-entry (entry lookup command name)
+ "Return `TeX-printer-list' ENTRY as a menu item."
+ (vector (nth 0 entry)
+ (list 'TeX-command-menu-print
+ (nth 0 entry)
+ (or (nth lookup entry) command)
+ name)))
+
+(defun TeX-command-menu-entry (entry)
+ "Return `TeX-command-list' ENTRY as a menu item."
+ (let ((name (car entry)))
+ (cond ((and (string-equal name TeX-command-Print)
+ TeX-printer-list)
+ (cons TeX-command-Print
+ (mapcar (lambda (entry)
+ (TeX-command-menu-printer-entry
+ entry 1 TeX-print-command name))
+ (append TeX-printer-list '(("Other"))))))
+ ((and (string-equal name TeX-command-Queue)
+ TeX-printer-list)
+ (cons TeX-command-Queue
+ (mapcar (lambda (entry)
+ (TeX-command-menu-printer-entry
+ entry 2 TeX-queue-command name))
+ (append TeX-printer-list '(("Other"))))))
+ (t
+ (vconcat `(,name (TeX-command-menu ,name))
+ (nthcdr 5 entry))))))
+
+(defconst TeX-command-menu-name "Command"
+ "Name to be displayed for the command menu in all modes defined by AUCTeX.")
+
+;;; Keymap
+
+(defcustom TeX-electric-escape nil
+ "If non-nil, ``\\'' will be bound to `TeX-electric-macro'."
+ :group 'TeX-macro
+ :type 'boolean)
+
+(defcustom TeX-electric-sub-and-superscript nil
+ "If non-nil, insert braces after typing `^' and `_' in math mode."
+ :group 'TeX-macro
+ :type 'boolean)
+
+(defcustom TeX-newline-function 'newline
+ "Function to be called upon pressing `RET'."
+ :group 'TeX-indentation
+ :type '(choice (const newline)
+ (const newline-and-indent)
+ (const reindent-then-newline-and-indent)
+ (sexp :tag "Other")))
+
+(defun TeX-insert-backslash (arg)
+ "Either insert typed key ARG times or call `TeX-electric-macro'.
+`TeX-electric-macro' will be called if `TeX-electric-escape' is non-nil."
+ (interactive "*p")
+ (if TeX-electric-escape
+ (TeX-electric-macro)
+ (self-insert-command arg)))
+
+(defun TeX-insert-sub-or-superscript (arg)
+ "Insert typed key ARG times and possibly a pair of braces.
+Brace insertion is only done if point is in a math construct and
+`TeX-electric-sub-and-superscript' has a non-nil value."
+ (interactive "*p")
+ (self-insert-command arg)
+ (when (and TeX-electric-sub-and-superscript (texmathp))
+ (insert (concat TeX-grop TeX-grcl))
+ (backward-char)))
+
+(defun TeX-newline ()
+ "Call the function specified by the variable `TeX-newline-function'."
+ (interactive) (funcall TeX-newline-function))
+
+(defvar TeX-mode-map
+ (let ((map (make-sparse-keymap)))
+ ;; Standard
+ ;; (define-key map "\177" 'backward-delete-char-untabify)
+ (define-key map "\C-c}" 'up-list)
+ (define-key map "\C-c#" 'TeX-normal-mode)
+ (define-key map "\C-c\C-n" 'TeX-normal-mode)
+ (define-key map "\C-c?" 'TeX-doc)
+ (define-key map "\C-c\C-i" 'TeX-goto-info-page)
+ (define-key map "\r" 'TeX-newline)
+
+ ;; From tex.el
+ (define-key map "\"" 'TeX-insert-quote)
+ (define-key map "$" 'TeX-insert-dollar)
+ ;; Removed because LaTeX 2e have a better solution to italic correction.
+ ;; (define-key map "." 'TeX-insert-punctuation)
+ ;; (define-key map "," 'TeX-insert-punctuation)
+ (define-key map "\C-c{" 'TeX-insert-braces)
+ (define-key map "\C-c\C-f" 'TeX-font)
+ (define-key map "\C-c\C-m" 'TeX-insert-macro)
+ (define-key map "\\" 'TeX-insert-backslash)
+ (define-key map "^" 'TeX-insert-sub-or-superscript)
+ (define-key map "_" 'TeX-insert-sub-or-superscript)
+ (define-key map "\e\t" 'TeX-complete-symbol) ;*** Emacs 19 way
+
+ (define-key map "\C-c'" 'TeX-comment-or-uncomment-paragraph) ;*** Old way
+ (define-key map "\C-c:" 'TeX-comment-or-uncomment-region) ;*** Old way
+ (define-key map "\C-c\"" 'TeX-uncomment) ;*** Old way
+
+ (define-key map "\C-c;" 'TeX-comment-or-uncomment-region)
+ (define-key map "\C-c%" 'TeX-comment-or-uncomment-paragraph)
+
+ (define-key map "\C-c\C-t\C-p" 'TeX-PDF-mode)
+ (define-key map "\C-c\C-t\C-i" 'TeX-interactive-mode)
+ (define-key map "\C-c\C-t\C-s" 'TeX-source-correlate-mode)
+ (define-key map "\C-c\C-t\C-r" 'TeX-pin-region)
+ (define-key map "\C-c\C-w" 'TeX-toggle-debug-bad-boxes); to be removed
+ (define-key map "\C-c\C-t\C-b" 'TeX-toggle-debug-bad-boxes)
+ (define-key map "\C-c\C-t\C-w" 'TeX-toggle-debug-warnings)
+ (define-key map "\C-c\C-v" 'TeX-view)
+ ;; From tex-buf.el
+ (define-key map "\C-c\C-d" 'TeX-save-document)
+ (define-key map "\C-c\C-r" 'TeX-command-region)
+ (define-key map "\C-c\C-b" 'TeX-command-buffer)
+ (define-key map "\C-c\C-c" 'TeX-command-master)
+ (define-key map "\C-c\C-k" 'TeX-kill-job)
+ (define-key map "\C-c\C-l" 'TeX-recenter-output-buffer)
+ (define-key map "\C-c^" 'TeX-home-buffer)
+ (define-key map "\C-c`" 'TeX-next-error)
+ ;; Remap bindings of `next-error'
+ (if (featurep 'xemacs)
+ (substitute-key-definition 'next-error 'TeX-next-error map global-map)
+ (define-key map [remap next-error] 'TeX-next-error))
+ ;; Remap bindings of `previous-error'
+ (if (featurep 'xemacs)
+ (substitute-key-definition 'previous-error 'TeX-previous-error
+ map global-map)
+ (define-key map [remap previous-error] 'TeX-previous-error))
+ ;; From tex-fold.el
+ (define-key map "\C-c\C-o\C-f" 'TeX-fold-mode)
+
+ ;; Multifile
+ (define-key map "\C-c_" 'TeX-master-file-ask) ;*** temporary
+ map)
+ "Keymap for common TeX and LaTeX commands.")
+
+(defvar plain-TeX-mode-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map TeX-mode-map)
+ map)
+ "Keymap used in plain TeX mode.")
+
+(defun TeX-mode-specific-command-menu (mode)
+ "Return a Command menu specific to the major MODE."
+ ;; COMPATIBILITY for Emacs < 21
+ (if (and (not (featurep 'xemacs))
+ (= emacs-major-version 20))
+ (cons TeX-command-menu-name
+ (TeX-mode-specific-command-menu-entries mode))
+ (list TeX-command-menu-name
+ :filter `(lambda (&rest ignored)
+ (TeX-mode-specific-command-menu-entries ',mode))
+ "Bug.")))
+
+(defun TeX-mode-specific-command-menu-entries (mode)
+ "Return the entries for a Command menu specific to the major MODE."
+ (append
+ (TeX-menu-with-help
+ `("Command on"
+ [ "Master File" TeX-command-select-master
+ :keys "C-c C-c" :style radio
+ :selected (eq TeX-command-current 'TeX-command-master)
+ :help "Commands in this menu work on the Master File"]
+ [ "Buffer" TeX-command-select-buffer
+ :keys "C-c C-b" :style radio
+ :selected (eq TeX-command-current 'TeX-command-buffer)
+ :help "Commands in this menu work on the current buffer"]
+ [ "Region" TeX-command-select-region
+ :keys "C-c C-r" :style radio
+ :selected (eq TeX-command-current 'TeX-command-region)
+ :help "Commands in this menu work on the region"]
+ [ "Fix the Region" TeX-pin-region
+ :active (or (if prefix-arg
+ (<= (prefix-numeric-value prefix-arg) 0)
+ (and (boundp 'TeX-command-region-begin)
+ (markerp TeX-command-region-begin)))
+ (TeX-mark-active))
+ ;;:visible (eq TeX-command-current 'TeX-command-region)
+ :style toggle
+ :selected (and (boundp 'TeX-command-region-begin)
+ (markerp TeX-command-region-begin))
+ :help "Fix the region for \"Command on Region\""]
+ "-"
+ ["Recenter Output Buffer" TeX-recenter-output-buffer
+ :help "Show the output of current TeX process"]
+ ["Kill Job" TeX-kill-job
+ :help "Kill the current TeX process"]
+ ["Next Error" TeX-next-error
+ :help "Jump to the next error of the last TeX run"]
+ ["Quick View" TeX-view
+ :help "Start a viewer without prompting"]
+ "-"
+ ("TeXing Options"
+ ,@(mapcar (lambda (x)
+ (let ((symbol (car x)) (name (nth 1 x)))
+ `[ ,(format "Use %s engine" name) (TeX-engine-set ',symbol)
+ :style radio :selected (eq TeX-engine ',symbol)
+ :help ,(format "Use %s engine for compiling" name) ]))
+ (TeX-engine-alist))
+ "-"
+ [ "Generate PDF" TeX-PDF-mode
+ :style toggle :selected TeX-PDF-mode
+ :active (not (eq TeX-engine 'omega))
+ :help "Use PDFTeX to generate PDF instead of DVI"]
+ [ "Run Interactively" TeX-interactive-mode
+ :style toggle :selected TeX-interactive-mode :keys "C-c C-t C-i"
+ :help "Stop on errors in a TeX run"]
+ [ "Correlate I/O" TeX-source-correlate-mode
+ :style toggle :selected TeX-source-correlate-mode
+ :help "Enable forward and inverse search in the previewer"]
+ ["Debug Bad Boxes" TeX-toggle-debug-bad-boxes
+ :style toggle :selected TeX-debug-bad-boxes :keys "C-c C-t C-b"
+ :help "Make \"Next Error\" show overfull and underfull boxes"]
+ ["Debug Warnings" TeX-toggle-debug-warnings
+ :style toggle :selected TeX-debug-warnings
+ :help "Make \"Next Error\" show warnings"])))
+ (let ((file 'TeX-command-on-current));; is this actually needed?
+ (TeX-maybe-remove-help
+ (delq nil
+ (mapcar 'TeX-command-menu-entry
+ (TeX-mode-specific-command-list mode)))))))
+
+(defun TeX-mode-specific-command-list (mode)
+ "Return the list of commands available in the given MODE."
+ (let ((full-list TeX-command-list)
+ out-list
+ entry)
+ (while (setq entry (pop full-list))
+ ;; `(nth 4 entry)' may be either an atom in case of which the
+ ;; entry should be present in any mode or a list of major modes.
+ (if (or (atom (nth 4 entry))
+ (memq mode (nth 4 entry)))
+ (push entry out-list)))
+ (nreverse out-list)))
+
+(defvar TeX-fold-menu
+ (TeX-menu-with-help
+ '("Show/Hide"
+ ["Fold Mode" TeX-fold-mode
+ :style toggle
+ :selected (and (boundp 'TeX-fold-mode) TeX-fold-mode)
+ :help "Toggle folding mode"]
+ "-"
+ ["Hide All in Current Buffer" TeX-fold-buffer
+ :active (and (boundp 'TeX-fold-mode) TeX-fold-mode)
+ :help "Hide all configured TeX constructs in the current buffer"]
+ ["Hide All in Current Region" TeX-fold-region
+ :active (and (boundp 'TeX-fold-mode) TeX-fold-mode)
+ :help "Hide all configured TeX constructs in the marked region"]
+ ["Hide All in Current Paragraph" TeX-fold-paragraph
+ :active (and (boundp 'TeX-fold-mode) TeX-fold-mode)
+ :help "Hide all configured TeX constructs in the paragraph containing point"]
+ ["Hide Current Macro" TeX-fold-macro
+ :active (and (boundp 'TeX-fold-mode) TeX-fold-mode)
+ :help "Hide the macro containing point"]
+ ["Hide Current Environment" TeX-fold-env
+ :visible (not (eq major-mode 'plain-tex-mode))
+ :active (and (boundp 'TeX-fold-mode) TeX-fold-mode)
+ :help "Hide the environment containing point"]
+ ["Hide Current Comment" TeX-fold-comment
+ :active (and (boundp 'TeX-fold-mode) TeX-fold-mode)
+ :help "Hide the comment containing point"]
+ "-"
+ ["Show All in Current Buffer" TeX-fold-clearout-buffer
+ :active (and (boundp 'TeX-fold-mode) TeX-fold-mode)
+ :help "Permanently show all folded content again"]
+ ["Show All in Current Region" TeX-fold-clearout-region
+ :active (and (boundp 'TeX-fold-mode) TeX-fold-mode)
+ :help "Permanently show all folded content in marked region"]
+ ["Show All in Current Paragraph" TeX-fold-clearout-paragraph
+ :active (and (boundp 'TeX-fold-mode) TeX-fold-mode)
+ :help "Permanently show all folded content in paragraph containing point"]
+ ["Show Current Item" TeX-fold-clearout-item
+ :active (and (boundp 'TeX-fold-mode) TeX-fold-mode)
+ :help "Permanently show the item containing point"]
+ "-"
+ ["Hide or Show Current Item" TeX-fold-dwim
+ :active (and (boundp 'TeX-fold-mode) TeX-fold-mode)
+ :help "Hide or show the item containing point"]))
+ "Menu definition for commands from tex-fold.el.")
+
+
+;;; Menus for plain TeX mode
+(easy-menu-define plain-TeX-mode-command-menu
+ plain-TeX-mode-map
+ "Command menu used in TeX mode."
+ (TeX-mode-specific-command-menu 'plain-tex-mode))
+
+(defvar TeX-customization-menu nil)
+
+(defvar TeX-common-menu-entries
+ (TeX-menu-with-help
+ `(("Multifile/Parsing"
+ ["Switch to Master File" TeX-home-buffer
+ :help "Switch to buffer of Master File, or buffer of last TeX command"]
+ ["Save Document" TeX-save-document
+ :help "Save all buffers associated with the current Master File"]
+ ["Set Master File" TeX-master-file-ask
+ :active (not (TeX-local-master-p))
+ :help "Set the main file to run TeX commands on"]
+ ["Reset Buffer" TeX-normal-mode
+ :help "Save and reparse the current buffer for style information"]
+ ["Reset AUCTeX" (TeX-normal-mode t) :keys "C-u C-c C-n"
+ :help "Reset buffer and reload AUCTeX style files"])
+ ["Find Documentation..." TeX-doc
+ :help "Get help on commands, packages, or TeX-related topics in general"]
+ ["Read the AUCTeX Manual" TeX-goto-info-page
+ :help "Everything worth reading"]
+ ("Customize AUCTeX"
+ ["Browse Options"
+ (customize-group 'AUCTeX)
+ :help "Open the customization buffer for AUCTeX"]
+ ["Extend this Menu"
+ (progn
+ (easy-menu-add-item
+ nil
+ ;; Ugly hack because docTeX mode uses the LaTeX menu.
+ (list (if (eq major-mode 'doctex-mode) "LaTeX" TeX-base-mode-name))
+ (or TeX-customization-menu
+ (setq TeX-customization-menu
+ (customize-menu-create 'AUCTeX "Customize AUCTeX")))))
+ :help "Make this menu a full-blown customization menu"])
+ ["Report AUCTeX Bug" TeX-submit-bug-report
+ :help ,(format "Problems with AUCTeX %s? Mail us!"
+ AUCTeX-version)])))
+
+(defvar plain-TeX-menu-entries
+ (TeX-menu-with-help
+ `(["Macro..." TeX-insert-macro
+ :help "Insert a macro and possibly arguments"]
+ ["Complete" TeX-complete-symbol
+ :help "Complete the current macro"]
+ "-"
+ ("Insert Font"
+ ["Emphasize" (TeX-font nil ?\C-e) :keys "C-c C-f C-e"]
+ ["Bold" (TeX-font nil ?\C-b) :keys "C-c C-f C-b"]
+ ["Typewriter" (TeX-font nil ?\C-t) :keys "C-c C-f C-t"]
+ ["Small Caps" (TeX-font nil ?\C-c) :keys "C-c C-f C-c"]
+ ["Sans Serif" (TeX-font nil ?\C-f) :keys "C-c C-f C-f"]
+ ["Italic" (TeX-font nil ?\C-i) :keys "C-c C-f C-i"]
+ ["Slanted" (TeX-font nil ?\C-s) :keys "C-c C-f C-s"]
+ ["Roman" (TeX-font nil ?\C-r) :keys "C-c C-f C-r"]
+ ["Calligraphic" (TeX-font nil ?\C-a) :keys "C-c C-f C-a"])
+ ("Replace Font"
+ ["Emphasize" (TeX-font t ?\C-e) :keys "C-u C-c C-f C-e"]
+ ["Bold" (TeX-font t ?\C-b) :keys "C-u C-c C-f C-b"]
+ ["Typewriter" (TeX-font t ?\C-t) :keys "C-u C-c C-f C-t"]
+ ["Small Caps" (TeX-font t ?\C-c) :keys "C-u C-c C-f C-c"]
+ ["Sans Serif" (TeX-font t ?\C-f) :keys "C-u C-c C-f C-f"]
+ ["Italic" (TeX-font t ?\C-i) :keys "C-u C-c C-f C-i"]
+ ["Slanted" (TeX-font t ?\C-s) :keys "C-u C-c C-f C-s"]
+ ["Roman" (TeX-font t ?\C-r) :keys "C-u C-c C-f C-r"]
+ ["Calligraphic" (TeX-font t ?\C-a) :keys "C-u C-c C-f C-a"])
+ ["Delete Font" (TeX-font t ?\C-d) :keys "C-c C-f C-d"]
+ "-"
+ ["Comment or Uncomment Region" TeX-comment-or-uncomment-region
+ :help "Comment or uncomment the currently selected region"]
+ ["Comment or Uncomment Paragraph" TeX-comment-or-uncomment-paragraph
+ :help "Comment or uncomment the paragraph containing point"]
+ ,TeX-fold-menu
+ "-" . ,TeX-common-menu-entries)))
+
+(easy-menu-define plain-TeX-mode-menu
+ plain-TeX-mode-map
+ "Menu used in plain TeX mode."
+ (cons "TeX" plain-TeX-menu-entries))
+
+;;; AmSTeX
+
+(defvar AmSTeX-mode-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map TeX-mode-map)
+ map)
+ "Keymap used in `AmSTeX-mode'.")
+
+;; Menu for AmSTeX mode
+(easy-menu-define AmSTeX-mode-command-menu
+ AmSTeX-mode-map
+ "Command menu used in AmsTeX mode."
+ (TeX-mode-specific-command-menu 'ams-tex-mode))
+
+(easy-menu-define AmSTeX-mode-menu
+ AmSTeX-mode-map
+ "Menu used in AMS-TeX mode."
+ (cons "AmS-TeX" plain-TeX-menu-entries))
+
+;;;###autoload
+(defun ams-tex-mode ()
+ "Major mode in AUCTeX for editing AmS-TeX files.
+See info under AUCTeX for documentation.
+
+Special commands:
+\\{AmSTeX-mode-map}
+
+Entering AmS-tex-mode calls the value of `text-mode-hook',
+then the value of `TeX-mode-hook', and then the value
+of `AmS-TeX-mode-hook'."
+ (interactive)
+ (plain-TeX-common-initialization)
+ (setq major-mode 'ams-tex-mode)
+ (use-local-map AmSTeX-mode-map)
+
+ ;; Menu
+ (easy-menu-add AmSTeX-mode-menu AmSTeX-mode-map)
+ (easy-menu-add AmSTeX-mode-command-menu AmSTeX-mode-map)
+
+ (setq TeX-base-mode-name "AmS-TeX")
+ (setq TeX-command-default "AmSTeX")
+ (TeX-run-mode-hooks 'text-mode-hook 'TeX-mode-hook 'AmS-TeX-mode-hook)
+ (TeX-set-mode-name))
+
+
+;;; Verbatim constructs
+
+(defvar TeX-verbatim-p-function nil
+ "Mode-specific function to be called by `TeX-verbatim-p'.")
+(make-variable-buffer-local 'TeX-verbatim-p-function)
+
+;; XXX: We only have an implementation for LaTeX mode at the moment (Oct 2009).
+(defun TeX-verbatim-p (&optional pos)
+ "Return non-nil if position POS is in a verbatim-like construct.
+A mode-specific implementation is required. If it is not
+available, the function always returns nil."
+ (when TeX-verbatim-p-function
+ (funcall TeX-verbatim-p-function)))
+
+
+;;; Comments
+
+(defvar TeX-comment-start-regexp "%"
+ "Regular expression matching a comment starter.
+Unlike the variable `comment-start-skip' it should not match any
+whitespace after the comment starter or any character before it.")
+(make-variable-buffer-local 'TeX-comment-start-regexp)
+
+(defun TeX-comment-region (beg end &optional arg)
+ "Comment each line in the region from BEG to END.
+Numeric prefix arg ARG means use ARG comment characters.
+If ARG is negative, delete that many comment characters instead."
+ (interactive "*r\nP")
+ ;; `comment-padding' will not be recognized in XEmacs' (21.4)
+ ;; `comment-region', so we temporarily modify `comment-start' to get
+ ;; proper spacing. Unfortunately we have to check for the XEmacs
+ ;; version and cannot test if `comment-padding' is bound as this
+ ;; gets initialized in `VirTeX-common-initialization'.
+ (let ((comment-start (if (and (featurep 'xemacs)
+ (= emacs-major-version 21)
+ (<= emacs-minor-version 4))
+ (concat comment-start (TeX-comment-padding-string))
+ comment-start)))
+ (comment-region beg end arg)))
+
+(eval-and-compile
+ ;; COMPATIBILITY for Emacs <= 21.3
+ (if (fboundp 'comment-or-uncomment-region)
+ (defalias 'TeX-comment-or-uncomment-region 'comment-or-uncomment-region)
+ ;; The following function was copied from `newcomment.el' on
+ ;; 2004-01-30 and adapted accordingly
+ (defun TeX-comment-or-uncomment-region (beg end &optional arg)
+ "Comment or uncomment a the region from BEG to END.
+Call `TeX-comment-region', unless the region only consists of
+comments, in which case call `TeX-uncomment-region'. If a prefix
+arg ARG is given, it is passed on to the respective function."
+ (interactive "*r\nP")
+ (funcall (if (save-excursion ;; check for already commented region
+ (goto-char beg)
+ (TeX-comment-forward (point-max))
+ (<= end (point)))
+ 'TeX-uncomment-region 'TeX-comment-region)
+ beg end arg)))
+
+ ;; COMPATIBILITY for Emacs <= 20. (Introduced in 21.1?)
+ (if (fboundp 'uncomment-region)
+ (defalias 'TeX-uncomment-region 'uncomment-region)
+ (defun TeX-uncomment-region (beg end &optional arg)
+ "Remove comment characters from the beginning of each line
+in the region from BEG to END. Numeric prefix arg ARG means use
+ARG comment characters. If ARG is negative, delete that many
+comment characters instead."
+ (interactive "*r\nP")
+ (or arg
+ ;; Determine the number of comment characters at the
+ ;; beginning of the first commented line.
+ (setq arg
+ (save-excursion
+ (goto-char beg)
+ (re-search-forward
+ (concat "^" TeX-comment-start-regexp "+") end t)
+ (length (match-string 0)))))
+ (comment-region beg end (- arg)))))
+
+(defun TeX-uncomment ()
+ "Delete comment characters from the beginning of each line in a comment."
+ (interactive)
+ (save-excursion
+ ;; Find first comment line
+ (beginning-of-line)
+ (while (and (looking-at (concat "^[ \t]*" TeX-comment-start-regexp))
+ (not (bobp)))
+ (forward-line -1))
+ (let ((beg (point)))
+ (forward-line 1)
+ ;; Find last comment line
+ (while (and (looking-at (concat "^[ \t]*" TeX-comment-start-regexp))
+ (not (eobp)))
+ (forward-line 1))
+ ;; Uncomment region
+ (TeX-uncomment-region beg (point)))))
+
+(defun TeX-comment-or-uncomment-paragraph ()
+ "Comment or uncomment current paragraph."
+ (interactive)
+ (if (TeX-in-commented-line)
+ (TeX-uncomment)
+ (save-excursion
+ (beginning-of-line)
+ ;; Don't do anything if we are in an empty line. If this line
+ ;; is followed by a lot of commented lines, this shall prevent
+ ;; that mark-paragraph skips over these lines and marks a
+ ;; paragraph outside the visible window which might get
+ ;; commented without the user noticing.
+ (unless (looking-at "^[ \t]*$")
+ (mark-paragraph)
+ (TeX-comment-region (point) (mark))))))
+
+(defun TeX-in-comment ()
+ "Return non-nil if point is in a comment."
+ (if (or (bolp)
+ (null comment-start-skip)
+ (eq (preceding-char) ?\r))
+ nil
+ (save-excursion
+ (save-match-data
+ (let ((pos (point)))
+ (beginning-of-line)
+ (and (or (looking-at comment-start-skip)
+ (re-search-forward comment-start-skip pos t))
+ (not (TeX-verbatim-p))))))))
+
+(defun TeX-in-commented-line ()
+ "Return non-nil if point is in a line consisting only of a comment.
+The comment can be preceded by whitespace. This means that
+`TeX-in-commented-line' is more general than `TeX-in-line-comment'
+which will not match commented lines with leading whitespace. But
+`TeX-in-commented-line' will match commented lines without leading
+whitespace as well."
+ (save-excursion
+ (forward-line 0)
+ (skip-chars-forward " \t")
+ (string= (buffer-substring-no-properties
+ (point) (min (point-max) (+ (point) (length comment-start))))
+ comment-start)))
+
+(defun TeX-in-line-comment ()
+ "Return non-nil if point is in a line comment.
+A line comment is a comment starting in column one, i.e. there is
+no whitespace before the comment sign."
+ (save-excursion
+ (forward-line 0)
+ (string= (buffer-substring-no-properties
+ (point) (min (point-max) (+ (point) (length comment-start))))
+ comment-start)))
+
+(defun TeX-comment-prefix ()
+ "Return the comment prefix of the current line.
+If there are no comment starters after potential whitespace at
+the beginning of the line, return nil."
+ (save-excursion
+ (beginning-of-line)
+ (save-match-data
+ (when (looking-at (concat "\\([ \t]*" TeX-comment-start-regexp "+\\)+"))
+ (match-string 0)))))
+
+(defun TeX-forward-comment-skip (&optional count limit)
+ "Move forward to the next comment skip.
+This may be a switch between commented and not commented adjacent
+lines or between lines with different comment prefixes. With
+argument COUNT do it COUNT times. If argument LIMIT is given, do
+not move point further than this value."
+ (unless count (setq count 1))
+ ;; A value of 0 is nonsense.
+ (when (= count 0) (setq count 1))
+ (unless limit (setq limit (point-max)))
+ (dotimes (i (abs count))
+ (if (< count 0)
+ (forward-line -1)
+ (beginning-of-line))
+ (let ((prefix (when (looking-at (concat "\\([ \t]*"
+ TeX-comment-start-regexp "+\\)+"))
+ (buffer-substring (+ (line-beginning-position)
+ (current-indentation))
+ (match-end 0)))))
+ (while (save-excursion
+ (and (if (> count 0)
+ (<= (point) limit)
+ (>= (point) limit))
+ (zerop (if (> count 0)
+ (forward-line 1)
+ (forward-line -1)))
+ (if prefix
+ (if (looking-at (concat "\\([ \t]*"
+ TeX-comment-start-regexp
+ "+\\)+"))
+ ;; If the preceding line is a commented line
+ ;; as well, check if the prefixes are
+ ;; identical.
+ (string= prefix
+ (buffer-substring
+ (+ (line-beginning-position)
+ (current-indentation))
+ (match-end 0)))
+ nil)
+ (not (looking-at (concat "[ \t]*"
+ TeX-comment-start-regexp))))))
+ (if (> count 0)
+ (forward-line 1)
+ (forward-line -1)))
+ (if (> count 0)
+ (forward-line 1)))))
+
+(defun TeX-backward-comment-skip (&optional count limit)
+ "Move backward to the next comment skip.
+This may be a switch between commented and not commented adjacent
+lines or between lines with different comment prefixes. With
+argument COUNT do it COUNT times. If argument LIMIT is given, do
+not move point to a position less than this value."
+ (unless count (setq count 1))
+ (when (= count 0) (setq count 1))
+ (unless limit (setq limit (point-min)))
+ (TeX-forward-comment-skip (- count) limit))
+
+;; Taken from `comment-forward' in Emacs' CVS on 2006-12-26. Used as
+;; a compatibility function for XEmacs 21.4.
+(defun TeX-comment-forward (&optional n)
+ "Skip forward over N comments.
+Just like `forward-comment' but only for positive N
+and can use regexps instead of syntax."
+ (when (fboundp 'comment-normalize-vars)
+ (comment-normalize-vars))
+ (if (fboundp 'comment-forward)
+ (comment-forward n)
+ (setq n (or n 1))
+ (if (< n 0) (error "No comment-backward")
+ (if comment-use-syntax (forward-comment n)
+ (while (> n 0)
+ (setq n
+ (if (or (forward-comment 1)
+ (and (looking-at comment-start-skip)
+ (goto-char (match-end 0))
+ (re-search-forward comment-end-skip nil 'move)))
+ (1- n) -1)))
+ (= n 0)))))
+
+(defun TeX-comment-padding-string ()
+ "Return comment padding as a string.
+The variable `comment-padding' can hold an integer or a string.
+This function will return the appropriate string representation
+regardless of its data type."
+ (if (integerp comment-padding)
+ (make-string comment-padding ? )
+ comment-padding))
+
+
+;;; Indentation
+
+(defgroup TeX-indentation nil
+ "Indentation of TeX buffers in AUCTeX."
+ :group 'AUCTeX)
+
+(defcustom TeX-brace-indent-level 2
+ "*The level of indentation produced by an open brace."
+ :group 'TeX-indentation
+ :type 'integer)
+
+(defun TeX-comment-indent ()
+ "Determine the indentation of a comment."
+ (if (looking-at "%%%")
+ (current-column)
+ (skip-chars-backward " \t")
+ (max (if (bolp) 0 (1+ (current-column)))
+ comment-column)))
+
+(defun TeX-brace-count-line ()
+ "Count number of open/closed braces."
+ (save-excursion
+ (let ((count 0) (limit (line-end-position)) char)
+ (while (progn
+ (skip-chars-forward "^{}\\\\" limit)
+ (when (and (< (point) limit) (not (TeX-in-comment)))
+ (setq char (char-after))
+ (forward-char)
+ (cond ((eq char ?\{)
+ (setq count (+ count TeX-brace-indent-level)))
+ ((eq char ?\})
+ (setq count (- count TeX-brace-indent-level)))
+ ((eq char ?\\)
+ (when (< (point) limit)
+ (forward-char)
+ t))))))
+ count)))
+
+;;; Navigation
+
+(defvar TeX-search-syntax-table
+ (let ((table (make-syntax-table (make-char-table (if (featurep 'xemacs)
+ 'syntax
+ 'syntax-table)))))
+ ;; Preset mode-independent syntax entries. (Mode-dependent
+ ;; entries are set in the function `TeX-search-syntax-table'.)
+ ;; ?\", ?\( and ?\) explicitely get whitespace syntax because
+ ;; Emacs 21.3 and XEmacs don't generate a completely empty syntax
+ ;; table.
+ (dolist (elt '((?\f . ">") (?\n . ">") (?\" . " ") (?\( . " ") (?\) . " ")))
+ (modify-syntax-entry (car elt) (cdr elt) table))
+ table)
+ "Syntax table used for searching purposes.
+It should be accessed through the function `TeX-search-syntax-table'.")
+
+(defun TeX-search-syntax-table (&rest args)
+ "Return a syntax table for searching purposes.
+ARGS may be a list of characters. For each of them the
+respective predefined syntax is set. Currently the parenthetical
+characters ?{, ?}, ?[, ?], ?\(, ?\), ?<, and ?> are supported.
+The syntax of each of these characters not specified will be
+reset to \" \"."
+ (let ((char-syntax-alist '((?\{ . "(}") (?\} . "){")
+ (?\[ . "(]") (?\] . ")[")
+ (?\( . "()") (?\) . ")(")
+ (?\< . "(>") (?\> . ")<"))))
+ ;; Clean entries possibly set before.
+ (modify-syntax-entry ?\\ " " TeX-search-syntax-table)
+ (modify-syntax-entry ?@ " " TeX-search-syntax-table)
+ (modify-syntax-entry ?\% " " TeX-search-syntax-table)
+ ;; Preset mode-dependent syntax entries. (Mode-independent entries
+ ;; are set when the variable `TeX-search-syntax-table' is created.)
+ (modify-syntax-entry (string-to-char TeX-esc) "\\" TeX-search-syntax-table)
+ (unless (eq major-mode 'texinfo-mode)
+ (modify-syntax-entry ?\% "<" TeX-search-syntax-table))
+ ;; Clean up the entries which can be specified as arguments.
+ (dolist (elt char-syntax-alist)
+ (modify-syntax-entry (car elt) " " TeX-search-syntax-table))
+ ;; Now set what we got.
+ (dolist (elt args)
+ (unless (assoc elt char-syntax-alist) (error "Char not supported"))
+ (modify-syntax-entry elt (cdr (assoc elt char-syntax-alist))
+ TeX-search-syntax-table))
+ ;; Return the syntax table.
+ TeX-search-syntax-table))
+
+(defun TeX-find-balanced-brace (&optional count depth limit)
+ "Return the position of a balanced brace in a TeX group.
+The function scans forward COUNT parenthetical groupings.
+Default is 1. If COUNT is negative, it searches backwards. With
+optional DEPTH>=1, find that outer level. If LIMIT is non-nil,
+do not search further than this position in the buffer."
+ (let ((count (if count
+ (if (= count 0) (error "COUNT has to be <> 0") count)
+ 1))
+ (depth (if depth
+ (if (< depth 1) (error "DEPTH has to be > 0") depth)
+ 1)))
+ (save-restriction
+ (when limit
+ (if (> count 0)
+ (narrow-to-region (point-min) limit)
+ (narrow-to-region limit (point-max))))
+ (with-syntax-table (TeX-search-syntax-table ?\{ ?\})
+ (condition-case nil
+ (scan-lists (point) count depth)
+ (error nil))))))
+
+(defun TeX-find-closing-brace (&optional depth limit)
+ "Return the position of the closing brace in a TeX group.
+The function assumes that point is inside the group, i.e. after
+an opening brace. With optional DEPTH>=1, find that outer level.
+If LIMIT is non-nil, do not search further down than this
+position in the buffer."
+ (TeX-find-balanced-brace 1 depth limit))
+
+(defun TeX-find-opening-brace (&optional depth limit)
+ "Return the position of the opening brace in a TeX group.
+The function assumes that point is inside the group, i.e. before
+a closing brace. With optional DEPTH>=1, find that outer level.
+If LIMIT is non-nil, do not search further up than this position
+in the buffer."
+ (TeX-find-balanced-brace -1 depth limit))
+
+(defun TeX-find-macro-boundaries (&optional lower-bound)
+ "Return a list containing the start and end of a macro.
+If LOWER-BOUND is given, do not search backward further than this
+point in buffer. Arguments enclosed in brackets or braces are
+considered part of the macro."
+ (save-restriction
+ (when lower-bound
+ (narrow-to-region lower-bound (point-max)))
+ (let ((orig-point (point))
+ start-point)
+ ;; Point is located directly at the start of a macro. (-!-\foo{bar})
+ (when (and (eq (char-after) (aref TeX-esc 0))
+ (not (TeX-escaped-p)))
+ (setq start-point (point)))
+ ;; Point is located on a macro. (\fo-!-o{bar})
+ (unless start-point
+ (save-excursion
+ (skip-chars-backward "A-Za-z@*")
+ (when (and (eq (char-before) (aref TeX-esc 0))
+ (not (TeX-escaped-p (1- (point)))))
+ (setq start-point (1- (point))))))
+ ;; Point is located in the argument of a macro. (\foo{ba-!-r})
+ (unless start-point
+ (save-excursion
+ (catch 'abort
+ (let ((parse-sexp-ignore-comments t))
+ (when (condition-case nil (progn (up-list) t) (error nil))
+ (while (progn
+ (condition-case nil (backward-sexp)
+ (error (throw 'abort nil)))
+ (forward-comment -1)
+ (and (memq (char-before) '(?\] ?\}))
+ (not (TeX-escaped-p (1- (point)))))))
+ (skip-chars-backward "A-Za-z@*")
+ (when (and (eq (char-before) (aref TeX-esc 0))
+ (not (TeX-escaped-p (1- (point)))))
+ (setq start-point (1- (point)))))))))
+ ;; Search forward for the end of the macro.
+ (when start-point
+ (save-excursion
+ (goto-char (TeX-find-macro-end-helper start-point))
+ (if (< orig-point (point))
+ (cons start-point (point))
+ nil))))))
+
+(defun TeX-find-macro-end-helper (start)
+ "Find the end of a macro given its START.
+START is the position just before the starting token of the macro.
+If the macro is followed by square brackets or curly braces,
+those will be considered part of it."
+ (save-excursion
+ (save-match-data
+ (catch 'found
+ (goto-char (1+ start))
+ (if (zerop (skip-chars-forward "A-Za-z@"))
+ (forward-char)
+ (skip-chars-forward "*"))
+ (while (not (eobp))
+ (cond
+ ;; Skip over pairs of square brackets
+ ((or (looking-at "[ \t]*\n?\\(\\[\\)") ; Be conservative: Consider
+ ; only consecutive lines.
+ (and (looking-at (concat "[ \t]*" TeX-comment-start-regexp))
+ (save-excursion
+ (forward-line 1)
+ (looking-at "[ \t]*\\(\\[\\)"))))
+ (goto-char (match-beginning 1))
+ (condition-case nil
+ (forward-sexp)
+ (scan-error (throw 'found (point)))))
+ ;; Skip over pairs of curly braces
+ ((or (looking-at "[ \t]*\n?{") ; Be conservative: Consider
+ ; only consecutive lines.
+ (and (looking-at (concat "[ \t]*" TeX-comment-start-regexp))
+ (save-excursion
+ (forward-line 1)
+ (looking-at "[ \t]*{"))))
+ (goto-char (match-end 0))
+ (goto-char (or (TeX-find-closing-brace)
+ ;; If we cannot find a regular end, use the
+ ;; next whitespace.
+ (save-excursion (skip-chars-forward "^ \t\n")
+ (point))))
+ (when (eobp) (throw 'found (point))))
+ (t
+ (throw 'found (point)))))))))
+
+(defun TeX-find-macro-start (&optional limit)
+ "Return the start of a macro.
+If LIMIT is given, do not search backward further than this point
+in buffer. Arguments enclosed in brackets or braces are
+considered part of the macro."
+ (car (TeX-find-macro-boundaries limit)))
+
+(defun TeX-find-macro-end ()
+ "Return the end of a macro.
+Arguments enclosed in brackets or braces are considered part of
+the macro."
+ (cdr (TeX-find-macro-boundaries)))
+
+(defun TeX-search-forward-unescaped (string &optional bound noerror)
+ "Search forward from point for unescaped STRING.
+The optional argument BOUND limits the search to the respective
+buffer position.
+If NOERROR is non-nil, return nil if the search failed instead of
+throwing an error.
+A pattern is escaped, if it is preceded by an odd number of escape
+characters."
+ (TeX-search-unescaped string 'forward nil bound noerror))
+
+(defun TeX-search-backward-unescaped (string &optional bound noerror)
+ "Search backward from point for unescaped STRING.
+The optional argument BOUND limits the search to the respective
+buffer position.
+If NOERROR is non-nil, return nil if the search failed instead of
+throwing an error.
+A pattern is escaped, if it is preceded by an odd number of escape
+characters."
+ (TeX-search-unescaped string 'backward nil bound noerror))
+
+(defun TeX-re-search-forward-unescaped (regexp &optional bound noerror)
+ "Search forward from point for unescaped regular expression REGEXP.
+The optional argument BOUND limits the search to the respective
+buffer position.
+If NOERROR is non-nil, return nil if the search failed instead of
+throwing an error.
+A pattern is escaped, if it is preceded by an odd number of escape
+characters."
+ (TeX-search-unescaped regexp 'forward t bound noerror))
+
+(defun TeX-search-unescaped (pattern
+ &optional direction regexp-flag bound noerror)
+ "Search for unescaped PATTERN in a certain DIRECTION.
+DIRECTION can be indicated by the symbols 'forward and 'backward.
+If DIRECTION is omitted, a forward search is carried out.
+If REGEXP-FLAG is non-nil, PATTERN may be a regular expression,
+otherwise a string.
+The optional argument BOUND limits the search to the respective
+buffer position.
+If NOERROR is non-nil, return nil if the search failed instead of
+throwing an error.
+A pattern is escaped, if it is preceded by an odd number of escape
+characters."
+ (let ((search-fun (if (eq direction 'backward)
+ (if regexp-flag 're-search-backward 'search-backward)
+ (if regexp-flag 're-search-forward 'search-forward))))
+ (catch 'found
+ (while (funcall search-fun pattern bound noerror)
+ (when (not (TeX-escaped-p (match-beginning 0)))
+ (throw 'found (point)))))))
+
+(defun TeX-escaped-p (&optional pos)
+ "Return t if the character at position POS is escaped.
+If POS is omitted, examine the character at point.
+A character is escaped if it is preceded by an odd number of
+escape characters, such as \"\\\" in LaTeX."
+ (save-excursion
+ (when pos (goto-char pos))
+ (not (zerop (mod (skip-chars-backward (regexp-quote TeX-esc)) 2)))))
+
+(defun TeX-current-macro ()
+ "Return the name of the macro containing point, nil if there is none."
+ (let ((macro-start (TeX-find-macro-start)))
+ (when macro-start
+ (save-excursion
+ (goto-char macro-start)
+ (forward-char (length TeX-esc))
+ (buffer-substring-no-properties
+ (point) (progn (skip-chars-forward "@A-Za-z") (point)))))))
+
+(defvar TeX-search-forward-comment-start-function nil
+ "Function to find the start of a comment.
+The function should accept an optional argument for specifying
+the limit of the search. It should return the position just
+before the comment if one is found and nil otherwise. Point
+should not be moved.")
+(make-variable-buffer-local 'TeX-search-forward-comment-start-function)
+
+(defun TeX-search-forward-comment-start (&optional limit)
+ "Search forward for a comment start from current position till LIMIT.
+If LIMIT is omitted, search till the end of the buffer.
+
+The search relies on `TeX-comment-start-regexp' being set
+correctly for the current mode.
+
+Set `TeX-search-forward-comment-start-defun' in order to override
+the default implementation."
+ (if TeX-search-forward-comment-start-function
+ (funcall TeX-search-forward-comment-start-function limit)
+ (setq limit (or limit (point-max)))
+ (when (TeX-re-search-forward-unescaped TeX-comment-start-regexp limit t)
+ (match-beginning 0))))
+
+;;; Fonts
+
+(defcustom TeX-font-list '((?\C-b "{\\bf " "}")
+ (?\C-c "{\\sc " "}")
+ (?\C-e "{\\em " "\\/}")
+ (?\C-i "{\\it " "\\/}")
+ (?\C-r "{\\rm " "}")
+ (?\C-s "{\\sl " "\\/}")
+ (?\C-t "{\\tt " "}")
+ (?\C-d "" "" t))
+ "List of fonts used by `TeX-font'.
+
+Each entry is a list.
+The first element is the key to activate the font.
+The second element is the string to insert before point, and the third
+element is the string to insert after point.
+If the fourth and fifth element are strings, they specify the prefix and
+suffix to be used in math mode.
+An optional fourth (or sixth) element means always replace if t."
+ :group 'TeX-macro
+ :type '(repeat
+ (group
+ :value (?\C-a "" "")
+ (character :tag "Key")
+ (string :tag "Prefix")
+ (string :tag "Suffix")
+ (option (group
+ :inline t
+ (string :tag "Math Prefix")
+ (string :tag "Math Suffix")))
+ (option (sexp :format "Replace\n" :value t)))))
+
+(defvar TeX-font-replace-function 'TeX-font-replace
+ "Determines the function which is called when a font should be replaced.")
+
+(defun TeX-describe-font-entry (entry)
+ "A textual description of an ENTRY in `TeX-font-list'."
+ (concat (format "%16s " (key-description (char-to-string (nth 0 entry))))
+ (if (or (eq t (nth 3 entry)) (eq t (nth 5 entry)))
+ "-- delete font"
+ (format "%14s %-3s %14s %-3s"
+ (nth 1 entry) (nth 2 entry)
+ (if (stringp (nth 3 entry)) (nth 3 entry) "")
+ (if (stringp (nth 4 entry)) (nth 4 entry) "")))))
+
+(defun TeX-font (replace what)
+ "Insert template for font change command.
+If REPLACE is not nil, replace current font. WHAT determines the font
+to use, as specified by `TeX-font-list'."
+ (interactive "*P\nc")
+ (TeX-update-style)
+ (let* ((entry (assoc what TeX-font-list))
+ (in-math (texmathp))
+ (before (nth 1 entry))
+ (after (nth 2 entry)))
+ (setq replace (or replace (eq t (nth 3 entry)) (eq t (nth 5 entry))))
+ (if (and in-math (stringp (nth 3 entry)))
+ (setq before (nth 3 entry)
+ after (nth 4 entry)))
+ (cond ((null entry)
+ (let ((help (concat
+ "Font list: "
+ "KEY TEXTFONT MATHFONT\n\n"
+ (mapconcat 'TeX-describe-font-entry
+ TeX-font-list "\n"))))
+ (with-output-to-temp-buffer "*Help*"
+ (set-buffer "*Help*")
+ (insert help))))
+ (replace
+ (funcall TeX-font-replace-function before after))
+ ((TeX-active-mark)
+ (save-excursion
+ (cond ((> (mark) (point))
+ (insert before)
+ (goto-char (mark))
+ (insert after))
+ (t
+ (insert after)
+ (goto-char (mark))
+ (insert before)))))
+ (t
+ (insert before)
+ (save-excursion
+ (insert after))))))
+
+(defun TeX-font-replace (start end)
+ "Replace font specification around point with START and END.
+For modes with font specifications like `{\\font text}'.
+See also `TeX-font-replace-macro' and `TeX-font-replace-function'."
+ (save-excursion
+ (while (not (looking-at "{\\\\[a-zA-Z]+ "))
+ (up-list -1))
+ (forward-sexp)
+ (save-excursion
+ (replace-match start t t))
+ (if (save-excursion
+ (backward-char 3)
+ (if (looking-at (regexp-quote "\\/}"))
+ (progn
+ (delete-char 3)
+ nil)
+ t))
+ (delete-backward-char 1))
+ (insert end)))
+
+(defun TeX-font-replace-macro (start end)
+ "Replace font specification around point with START and END.
+For modes with font specifications like `\\font{text}'.
+See also `TeX-font-replace' and `TeX-font-replace-function'."
+ (let ((font-list TeX-font-list)
+ cmds strings regexp)
+ (while font-list
+ (setq strings (cdr (car font-list))
+ font-list (cdr font-list))
+ (and (stringp (car strings)) (null (string= (car strings) ""))
+ (setq cmds (cons (car strings) cmds)))
+ (setq strings (cdr (cdr strings)))
+ (and (stringp (car strings)) (null (string= (car strings) ""))
+ (setq cmds (cons (car strings) cmds))))
+ (setq regexp (mapconcat 'regexp-quote cmds "\\|"))
+ (save-excursion
+ (catch 'done
+ (while t
+ (if (/= ?\\ (following-char))
+ (skip-chars-backward "a-zA-Z "))
+ (skip-chars-backward (regexp-quote TeX-esc))
+ (if (looking-at regexp)
+ (throw 'done t)
+ (up-list -1))))
+ ;; Use stripped syntax table in order to get stuff like "\emph{(}" right.
+ (with-syntax-table (TeX-search-syntax-table ?\{ ?\})
+ (forward-sexp 2))
+ (save-excursion
+ (replace-match start t t))
+ (delete-backward-char 1)
+ (insert end))))
+
+;;; Dollars
+;;
+;; Rewritten from scratch with use of `texmathp' by
+;; Carsten Dominik <dominik@strw.leidenuniv.nl>
+
+(defvar TeX-symbol-marker nil)
+
+(defvar TeX-symbol-marker-pos 0)
+
+;; The following constants are no longer used, but kept in case some
+;; foreign code uses any of them.
+(defvar TeX-dollar-sign ?$
+ "*Character used to enter and leave math mode in TeX.")
+(defconst TeX-dollar-string (char-to-string TeX-dollar-sign))
+(defconst TeX-dollar-regexp
+ (concat "^" (regexp-quote TeX-dollar-string) "\\|[^" TeX-esc "]"
+ (regexp-quote TeX-dollar-string)))
+
+(defcustom TeX-math-toggle-off-input-method t
+ "*If non-nil, auto toggle off CJK input methods when entering math mode."
+ :group 'TeX-macro
+ :type 'boolean)
+
+(defcustom TeX-math-close-double-dollar nil
+ "If non-nil close double dollar math by typing a single `$'."
+ :group 'TeX-macro
+ :type 'boolean)
+
+(defun TeX-insert-dollar (&optional arg)
+ "Insert dollar sign.
+
+If current math mode was not entered with a dollar, refuse to
+insert one. Show matching dollar sign if this dollar sign ends
+the TeX math mode and `blink-matching-paren' is non-nil. Ensure
+double dollar signs match up correctly by inserting extra dollar
+signs when needed.
+
+With raw \\[universal-argument] prefix, insert exactly one dollar
+sign. With optional ARG, insert that many dollar signs."
+ (interactive "P")
+ (cond
+ ((and arg (listp arg))
+ ;; C-u always inserts one
+ (insert "$"))
+ (arg
+ ;; Numerical arg inserts that many
+ (insert (make-string (prefix-numeric-value arg) ?\$)))
+ ((TeX-escaped-p)
+ ;; This is escaped with `\', so just insert one.
+ (insert "$"))
+ ((texmathp)
+ ;; We are inside math mode
+ (if (and (stringp (car texmathp-why))
+ (string-equal (substring (car texmathp-why) 0 1) "\$"))
+ ;; Math mode was turned on with $ or $$ - so finish it accordingly.
+ (progn
+ (if TeX-math-close-double-dollar
+ (insert (car texmathp-why))
+ (insert "$"))
+ (when (and blink-matching-paren
+ (or (string= (car texmathp-why) "$")
+ (zerop (mod (save-excursion
+ (skip-chars-backward "$")) 2))))
+ (save-excursion
+ (goto-char (cdr texmathp-why))
+ (if (pos-visible-in-window-p)
+ (sit-for 1)
+ (message "Matches %s"
+ (buffer-substring
+ (point) (progn (end-of-line) (point))))))))
+ ;; Math mode was not entered with dollar - we cannot finish it with one.
+ (message "Math mode started with `%s' cannot be closed with dollar"
+ (car texmathp-why))
+ (insert "$")))
+ (t
+ ;; Just somewhere in the text.
+ (insert "$")))
+ (TeX-math-input-method-off))
+
+(defvar TeX-math-input-method-off-regexp
+ "^\\(chinese\\|japanese\\|korean\\bulgarian\\russian\\)"
+ "Regexp matching input methods to be deactivated when entering math mode.")
+
+(defun TeX-math-input-method-off ()
+ "Toggle off input method when entering math mode."
+ (and TeX-math-toggle-off-input-method
+ (texmathp)
+ (boundp 'current-input-method) current-input-method
+ (string-match TeX-math-input-method-off-regexp current-input-method)
+ (inactivate-input-method)))
+
+;;; Simple Commands
+
+(defun TeX-normal-mode (arg)
+ "Remove all information about this buffer, and apply the style hooks again.
+Save buffer first including style information.
+With optional argument ARG, also reload the style hooks."
+ ;; FIXME: Shouldn't it be (&optional arg)? -- rs
+ (interactive "*P")
+ (if arg
+ (setq TeX-style-hook-list nil
+ BibTeX-global-style-files nil
+ BibTeX-global-files nil
+ TeX-global-input-files nil))
+ (let ((TeX-auto-save t))
+ (if (buffer-modified-p)
+ (save-buffer)
+ (TeX-auto-write)))
+ (normal-mode)
+ ;; See also addition to `find-file-hooks' in `VirTeX-common-initialization'.
+ (when (eq TeX-master 'shared) (TeX-master-file nil nil t))
+ (TeX-update-style t))
+
+(defgroup TeX-quote nil
+ "Quoting in AUCTeX."
+ :group 'AUCTeX)
+
+(defcustom TeX-open-quote "``"
+ "String inserted by typing \\[TeX-insert-quote] to open a quotation."
+ :group 'TeX-quote
+ :type 'string)
+
+(defcustom TeX-close-quote "''"
+ "String inserted by typing \\[TeX-insert-quote] to close a quotation."
+ :group 'TeX-quote
+ :type 'string)
+
+(defcustom TeX-quote-after-quote nil
+ "Behaviour of \\[TeX-insert-quote].
+Nil means standard behaviour; when non-nil, opening and closing
+quotes are inserted only after \"."
+ :group 'TeX-quote
+ :type 'boolean)
+
+(defcustom TeX-quote-language-alist nil
+ "Alist for overriding the default language-specific quote insertion.
+First element in each item is the name of the language as set by
+the language style file as a string. Second element is the
+opening quotation mark. Third elemxent is the closing quotation
+mark. Opening and closing quotation marks can be specified
+directly as strings or as functions returning a string. Fourth
+element is a boolean specifying insertion behavior, overriding
+`TeX-quote-after-quote'. See Info node `(auctex)European' for
+valid languages."
+ :group 'TeX-quote
+ :link '(custom-manual "(auctex)European")
+ :type '(repeat (group (choice
+ (const "czech")
+ (const "danish")
+ (const "dutch")
+ (const "german")
+ (const "ngerman")
+ (const "french") ;; not frenchb or francais
+ (const "italian")
+ (const "polish")
+ (const "slovak")
+ (const "swedish")
+ (string :tag "Other Language"))
+ (choice :tag "Opening quotation mark" string function)
+ (choice :tag "Closing quotation mark" string function)
+ (boolean :tag "Insert plain quote first" :value t))))
+
+(defvar TeX-quote-language nil
+ "If non-nil determines behavior of quote insertion.
+It is usually set by language-related style files. Its value has
+the same structure as the elements of `TeX-quote-language-alist'.
+The symbol 'override can be used as its car in order to override
+the settings of style files. Style files should therefore check
+if this symbol is present and not alter `TeX-quote-language' if
+it is.")
+(make-variable-buffer-local 'TeX-quote-language)
+
+(defun TeX-insert-quote (force)
+ "Insert the appropriate quotation marks for TeX.
+Inserts the value of `TeX-open-quote' (normally ``) or `TeX-close-quote'
+\(normally '') depending on the context. If `TeX-quote-after-quote'
+is non-nil, this insertion works only after \".
+With prefix argument FORCE, always inserts \" characters."
+ (interactive "*P")
+ (if (or force
+ ;; Do not insert TeX quotes in verbatim, math or comment constructs.
+ (and (fboundp 'font-latex-faces-present-p)
+ (font-latex-faces-present-p '(font-latex-verbatim-face
+ font-latex-math-face
+ font-lock-comment-face))
+ (font-latex-faces-present-p '(font-latex-verbatim-face
+ font-latex-math-face
+ font-lock-comment-face)
+ (1- (point))))
+ (texmathp)
+ (and (TeX-in-comment) (not (eq major-mode 'doctex-mode))))
+ (self-insert-command (prefix-numeric-value force))
+ (TeX-update-style)
+ (let* ((lang-override (if (eq (car TeX-quote-language) 'override)
+ TeX-quote-language
+ (assoc (car TeX-quote-language)
+ TeX-quote-language-alist)))
+ (lang (or lang-override TeX-quote-language))
+ (open-quote (if lang (nth 1 lang) TeX-open-quote))
+ (close-quote (if lang (nth 2 lang) TeX-close-quote))
+ (q-after-q (if lang (nth 3 lang) TeX-quote-after-quote)))
+ (when (functionp open-quote)
+ (setq open-quote (funcall open-quote)))
+ (when (functionp close-quote)
+ (setq close-quote (funcall close-quote)))
+ (if q-after-q
+ (insert (cond ((bobp)
+ ?\")
+ ((save-excursion
+ (TeX-looking-at-backward
+ (concat (regexp-quote open-quote) "\\|"
+ (regexp-quote close-quote))
+ (max (length open-quote) (length close-quote))))
+ (delete-backward-char (length (match-string 0)))
+ "\"\"")
+ ((< (save-excursion (skip-chars-backward "\"")) -1)
+ ?\")
+ ((not (= (preceding-char) ?\"))
+ ?\")
+ ((save-excursion
+ (forward-char -1)
+ (bobp))
+ (delete-backward-char 1)
+ open-quote)
+ ((save-excursion
+ (forward-char -2) ;;; at -1 there is double quote
+ (looking-at "[ \t\n]\\|\\s("))
+ (delete-backward-char 1)
+ open-quote)
+ (t
+ (delete-backward-char 1)
+ close-quote)))
+ (insert (cond ((bobp)
+ open-quote)
+ ((= (preceding-char) (string-to-char TeX-esc))
+ ?\")
+ ((= (preceding-char) ?\")
+ ?\")
+ ((save-excursion
+ (forward-char (- (length open-quote)))
+ (looking-at (regexp-quote open-quote)))
+ (delete-backward-char (length open-quote))
+ ?\")
+ ((save-excursion
+ (forward-char (- (length close-quote)))
+ (looking-at (regexp-quote close-quote)))
+ (delete-backward-char (length close-quote))
+ ?\")
+ ((save-excursion
+ (forward-char -1)
+ (looking-at "[ \t\n]\\|\\s("))
+ open-quote)
+ (t
+ close-quote)))))))
+
+(defun TeX-insert-punctuation ()
+ "Insert point or comma, cleaning up preceding space."
+ (interactive)
+ (expand-abbrev)
+ (if (TeX-looking-at-backward "\\\\/\\(}+\\)" 50)
+ (replace-match "\\1" t))
+ (call-interactively 'self-insert-command))
+
+(defun TeX-insert-braces (arg)
+ "Make a pair of braces around next ARG sexps and leave point inside.
+No argument is equivalent to zero: just insert braces and leave point
+between.
+
+If there is an active region, ARG will be ignored, braces will be
+inserted around the region, and point will be left after the
+closing brace."
+ (interactive "P")
+ (if (TeX-active-mark)
+ (progn
+ (if (< (point) (mark))
+ (exchange-point-and-mark))
+ (insert TeX-grcl)
+ (save-excursion
+ (goto-char (mark))
+ (insert TeX-grop)))
+ (insert TeX-grop)
+ (save-excursion
+ (if arg (forward-sexp (prefix-numeric-value arg)))
+ (insert TeX-grcl))))
+
+;;;###autoload
+(defun TeX-submit-bug-report ()
+ "Submit a bug report on AUCTeX via mail.
+
+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 AUCTeX version and AUCTeX configuration."
+ (interactive)
+ (require 'reporter)
+ (let ((reporter-prompt-for-summary-p "Bug report subject: "))
+ (reporter-submit-bug-report
+ "bug-auctex@gnu.org"
+ AUCTeX-version
+ (list 'AUCTeX-date
+ 'window-system
+ 'LaTeX-version
+ 'TeX-style-path
+ 'TeX-auto-save
+ 'TeX-parse-self
+ 'TeX-master
+ 'TeX-command-list)
+ nil nil
+ "Remember to cover the basics, that is, what you expected to happen and
+what in fact did happen.
+
+Be sure to consult the FAQ section in the manual before submitting
+a bug report. In addition check if the bug is reproducable with an
+up-to-date version of AUCTeX. So please upgrade to the version
+available from http://www.gnu.org/software/auctex/ if your
+installation is older than the one available from the web site.
+
+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.
+------------------------------------------------------------------------")))
+
+
+;;; Documentation
+
+(defun TeX-goto-info-page ()
+ "Read documentation for AUCTeX in the info system."
+ (interactive)
+ (info "auctex"))
+
+(autoload 'info-lookup->completions "info-look")
+
+(defvar TeX-doc-backend-alist
+ '((texdoc (plain-tex-mode latex-mode doctex-mode ams-tex-mode context-mode)
+ (lambda ()
+ (when (executable-find "texdoc")
+ (TeX-search-files
+ ;; Explicitely supply doc directory for
+ ;; non-kpathsea-based TeX systems.
+ (unless (stringp TeX-kpathsea-path-delimiter)
+ (or (TeX-tree-expand
+ '("$SYSTEXMF" "$TEXMFLOCAL" "$TEXMFMAIN" "$TEXMFDIST")
+ "latex" '("/doc/"))
+ `(,@TeX-macro-global ,@TeX-macro-private)))
+ '("dvi" "pdf" "ps" "txt" "html") t t)))
+ (lambda (doc)
+ ;; texdoc in MiKTeX requires --view in order to start
+ ;; the viewer instead of an intermediate web page.
+ (call-process "texdoc" nil 0 nil "--view" doc)))
+ (latex-info (latex-mode)
+ (lambda ()
+ (when (condition-case nil
+ (save-window-excursion
+ (let ((buf (generate-new-buffer-name "*info*")))
+ (info "latex" buf)
+ (kill-buffer buf))
+ t)
+ (error nil))
+ (mapcar (lambda (x)
+ (let ((x (car x)))
+ (if (string-match "\\`\\\\" x)
+ (substring x 1) x)))
+ (info-lookup->completions 'symbol 'latex-mode))))
+ (lambda (doc)
+ (info-lookup-symbol (concat "\\" doc) 'latex-mode)))
+ (texinfo-info (texinfo-mode)
+ (lambda ()
+ (when (condition-case nil
+ (save-window-excursion
+ (let ((buf (generate-new-buffer-name "*info*")))
+ (info "texinfo" buf)
+ (kill-buffer buf))
+ t)
+ (error nil))
+ (mapcar (lambda (x)
+ (let ((x (car x)))
+ (if (string-match "\\`@" x)
+ (substring x 1) x)))
+ (info-lookup->completions 'symbol
+ 'texinfo-mode))))
+ (lambda (doc)
+ (info-lookup-symbol (concat "@" doc) 'texinfo-mode))))
+ "Alist of backends used for looking up documentation.
+Each item consists of four elements.
+
+The first is a symbol describing the backend's name.
+
+The second is a list of modes the backend should be activated in.
+
+The third is a function returning a list of documents available
+to the backend. It should return nil if the backend is not
+available, e.g. if a required executable is not present on the
+system in question.
+
+The fourth is a function for displaying the documentation. The
+function should accept a single argument, the chosen package,
+command, or document name.")
+
+(defun TeX-doc (&optional name)
+ "Display documentation for string NAME.
+NAME may be a package, a command, or a document."
+ (interactive)
+ (let (docs)
+ ;; Build the lists of available documentation used for completion.
+ (dolist (elt TeX-doc-backend-alist)
+ (when (memq major-mode (nth 1 elt))
+ (let ((completions (funcall (nth 2 elt))))
+ (unless (null completions)
+ (add-to-list 'docs (cons completions (nth 0 elt)))))))
+ (if (null docs)
+ (progn
+ (if (executable-find "texdoc")
+ ;; Fallback if we did not find anything via the backend list.
+ (let ((doc (read-from-minibuffer "Input for `texdoc': ")))
+ (when doc (call-process "texdoc" nil 0 nil "--view" doc)))
+ ;; Give up.
+ (message "No documentation found")))
+ ;; Ask the user about the package, command, or document.
+ (when (and (interactive-p)
+ (or (not name) (string= name "")))
+ (let ((symbol (thing-at-point 'symbol))
+ contained completions doc)
+ ;; Is the symbol at point contained in the lists of available
+ ;; documentation?
+ (setq contained (catch 'found
+ (dolist (elt docs)
+ (when (member symbol (car elt))
+ (throw 'found t)))))
+ ;; Setup completion list in a format suitable for `completing-read'.
+ (dolist (elt docs)
+ (setq completions (nconc (mapcar 'list (car elt)) completions)))
+ ;; Query user.
+ (setq doc (completing-read
+ (if contained
+ (format "Package, command, or document (default %s): "
+ symbol)
+ "Package, command, or document: ")
+ completions))
+ (setq name (if (string= doc "") symbol doc))))
+ (if (not name)
+ (message "No documentation specified")
+ ;; XXX: Provide way to choose in case a symbol can be found in
+ ;; more than one backend.
+ (let* ((backend (catch 'found
+ (dolist (elt docs)
+ (when (member name (car elt))
+ (throw 'found (cdr elt)))))))
+ (if backend
+ (funcall (nth 3 (assoc backend TeX-doc-backend-alist)) name)
+ (message "Documentation not found")))))))
+
+
+;;; Ispell Support
+
+;; FIXME: Document those functions and variables. -- rs
+
+;; The FSF ispell.el use this.
+(defun ispell-tex-buffer-p ()
+ (and (boundp 'ispell-tex-p) ispell-tex-p))
+
+;; The FSF ispell.el might one day use this.
+(setq ispell-enable-tex-parser t)
+
+(defun TeX-run-ispell (command string file)
+ "Run ispell on current TeX buffer."
+ (cond ((and (string-equal file (TeX-region-file))
+ (fboundp 'ispell-region))
+ (call-interactively 'ispell-region))
+ ((string-equal file (TeX-region-file))
+ (call-interactively 'spell-region))
+ ((fboundp 'ispell-buffer)
+ (ispell-buffer))
+ ((fboundp 'ispell)
+ (ispell))
+ (t
+ (spell-buffer))))
+
+(defun TeX-ispell-document (name)
+ "Run ispell on all open files belonging to the current document."
+ (interactive (list (TeX-master-file)))
+ (if (string-equal name "")
+ (setq name (TeX-master-file)))
+
+ (let ((found nil)
+ (regexp (concat "\\`\\("
+ (mapconcat (lambda (dir)
+ (regexp-quote
+ (expand-file-name
+ (file-name-as-directory dir))))
+ (append (when (file-name-directory name)
+ (list (file-name-directory name)))
+ TeX-check-path)
+ "\\|")
+ "\\).*\\("
+ (mapconcat 'regexp-quote
+ (cons (file-name-nondirectory name)
+ (TeX-style-list)) "\\|")
+ "\\)\\.\\("
+ (mapconcat 'regexp-quote TeX-file-extensions "\\|")
+ "\\)\\'"))
+ (buffers (buffer-list)))
+ (while buffers
+ (let* ((buffer (car buffers))
+ (name (buffer-file-name buffer)))
+ (setq buffers (cdr buffers))
+ (if (and name (string-match regexp name))
+ (progn
+ (save-excursion (switch-to-buffer buffer) (ispell-buffer))
+ (setq found t)))))))
+
+;; Some versions of ispell 3 use this.
+(defvar ispell-tex-major-modes nil)
+(setq ispell-tex-major-modes
+ (append '(plain-tex-mode ams-tex-mode latex-mode doctex-mode)
+ ispell-tex-major-modes))
+
+
+;;; Special provisions for other modes and libraries
+
+;; desktop-locals-to-save is broken by design. Don't have
+;; buffer-local values of it.
+(eval-after-load "desktop"
+ '(progn
+ (dolist (elt '(TeX-master))
+ (unless (member elt (default-value 'desktop-locals-to-save))
+ (setq-default desktop-locals-to-save
+ (cons elt (default-value 'desktop-locals-to-save)))))
+ (add-hook 'desktop-after-read-hook '(lambda ()
+ (TeX-set-mode-name t)))))
+
+;; delsel.el, `delete-selection-mode'
+(put 'TeX-newline 'delete-selection t)
+(put 'TeX-insert-dollar 'delete-selection t)
+(put 'TeX-insert-quote 'delete-selection t)
+(put 'TeX-insert-backslash 'delete-selection t)
+
+(provide 'tex)
+
+;; Local Variables:
+;; coding: iso-8859-1
+;; End:
+
+;;; tex.el ends here
--- /dev/null
+;;; texmathp.el -- Code to check if point is inside LaTeX math environment
+
+;; Copyright (C) 1998, 2004 Free Software Foundation, Inc.
+
+;; Author: Carsten Dominik <dominik@strw.LeidenUniv.nl>
+;; Maintainer: auctex-devel@gnu.org
+;; Keywords: tex
+
+;; This file is part of AUCTeX.
+
+;; AUCTeX 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, or (at your option)
+;; any later version.
+
+;; AUCTeX 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 AUCTeX; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+;;
+;; This code provides a function to determine if point in a buffer is
+;; inside a (La)TeX math environment. This is not trivial since many
+;; different ways are used to switch between the two. Examples:
+;;
+;; \begin{equation} ... \end{equation}
+;; $ ... $
+;; $$ ... $$
+;; \[ ... \]
+;; \ensuremath{...}
+;; \mbox{...}
+;;
+;; To install, put this file on your load-path and compile it.
+;;
+;; To use this in a Lisp program, do
+;;
+;; (require 'texmathp)
+;;
+;; You can then write code like this:
+;;
+;; (if (texmathp) ...)
+;;
+;; The call to `texmathp' leaves some extra information in the
+;; variable `texmathp-why'. It's value is a cons cell (MATCH . POSITION),
+;; specifying which command at what position is responsible for math
+;; mode being on or off.
+;;
+;; To configure which macros and environments influence LaTeX math mode,
+;; customize the variable `texmathp-tex-commands'. By default
+;; it recognizes the LaTeX core as well as AMS-LaTeX (see the variable
+;; `texmathp-tex-commands-default', also as an example).
+;;
+;; To try out the code interactively, use `M-x texmathp RET'.
+;;
+;; Of course, in order to work this function has to assume that the
+;; LaTeX above point is syntactically correct. In particular:
+;;
+;; o The different math delimiters are paired correctly. Thus if
+;; you do things like "\begin{equation} $" or "\[ ... \)"
+;; the result of (texmathp) is undefined. It is in fact possible
+;; in LaTeX to pair \[ with $$ and \( with $, but this will confuse
+;; texmathp (and human readers as well).
+;;
+;; o However, texmathp will correctly work with nested delimiters.
+;; Something like the following will be parsed correctly at any point:
+;;
+;; \begin{equation}
+;; x = y \mbox{abc \ensuremath{\alpha} cba $2^3$}
+;; \end{equation}
+;;
+;; o texmathp is somewhat forgiving if you have an empty line inside
+;; the current math environment, which is not legal in TeX but may
+;; easily happen during editing. Depending upon the variable
+;; `texmathp-search-n-paragraphs' several paragraphs are checked
+;; backwards, by default 2. Paragraph here means something limited
+;; by an empty line.
+;;--------------------------------------------------------------------------
+;;
+;; BUGS:
+;;
+;; If any of the the special macros like \mbox or \ensuremath has optional
+;; arguments, math mode inside these optional arguments is *not* influenced
+;; by the macro.
+;;--------------------------------------------------------------------------
+\f
+;;; Code:
+
+(defgroup texmathp nil
+ "Testing TeX and LaTeX documents for math mode."
+ :tag "Test For TeX and LaTeX Math Mode"
+ :prefix "texmathp-"
+ :group 'tex)
+
+;; Some internal variables which are computed from `texmathp-tex-commands'
+;; and `texmathp-tex-commands-default'.
+(defvar texmathp-environments nil)
+(defvar texmathp-macros nil)
+(defvar texmathp-onoff-regexp nil)
+(defvar texmathp-toggle-regexp nil)
+(defvar texmathp-tex-commands1 nil)
+(defvar texmathp-memory nil)
+
+(defvar texmathp-tex-commands) ; silence the compiler
+
+(defvar texmathp-tex-commands-default
+ '(;; Plain TeX
+ ("$$" sw-toggle) ("$" sw-toggle)
+ ("\\hbox" arg-off)
+ ("\\vbox" arg-off)
+ ("\\vtop" arg-off)
+ ("\\vcenter" arg-off)
+
+ ;; Standard LaTeX
+ ("equation" env-on) ("equation*" env-on)
+ ("eqnarray" env-on) ("eqnarray*" env-on)
+ ("math" env-on)
+ ("displaymath" env-on)
+ ("minipage" env-off)
+ ("\\fbox" arg-off)
+ ("\\mbox" arg-off)
+ ("\\framebox" arg-off)
+ ("\\label" arg-off)
+ ("\\textrm" arg-off)
+ ("\\(" sw-on) ("\\)" sw-off)
+ ("\\[" sw-on) ("\\]" sw-off)
+ ("\\ensuremath" arg-on)
+
+ ;; AMS-LaTeX
+ ("align" env-on) ("align*" env-on)
+ ("gather" env-on) ("gather*" env-on)
+ ("multline" env-on) ("multline*" env-on)
+ ("flalign" env-on) ("flalign*" env-on)
+ ("alignat" env-on) ("alignat*" env-on)
+ ("xalignat" env-on) ("xalignat*" env-on)
+ ("xxalignat" env-on) ("\\boxed" arg-on)
+ ("\\text" arg-off) ("\\intertext" arg-off))
+ "The default entries for `texmathp-tex-commands', which see.")
+
+(defun texmathp-compile ()
+ "Compile the value of `texmathp-tex-commands' into the internal lists.
+Call this when you have changed the value of that variable without using
+customize (customize calls it when setting the variable)."
+ (interactive)
+ ;; Extract lists and regexp.
+ (setq texmathp-macros nil texmathp-environments nil)
+ (setq texmathp-memory
+ (cons texmathp-tex-commands texmathp-tex-commands-default))
+ (setq texmathp-tex-commands1 (append texmathp-tex-commands
+ texmathp-tex-commands-default))
+ (let ((list (reverse texmathp-tex-commands1))
+ var entry type switches togglers)
+ (while (setq entry (car list))
+ (setq type (nth 1 entry)
+ list (cdr list)
+ var (cond ((memq type '(env-on env-off)) 'texmathp-environments)
+ ((memq type '(arg-on arg-off)) 'texmathp-macros)
+ ((memq type '(sw-on sw-off)) 'switches)
+ ((memq type '(sw-toggle)) 'togglers)))
+ (set var (cons (car entry) (symbol-value var))))
+ (setq texmathp-onoff-regexp
+ (concat "[^\\\\]\\("
+ (mapconcat 'regexp-quote switches "\\|")
+ "\\)")
+ texmathp-toggle-regexp
+ (concat "\\([^\\\\\\$]\\|\\`\\)\\("
+ (mapconcat 'regexp-quote togglers "\\|")
+ "\\)"))))
+
+(defcustom texmathp-tex-commands nil
+ "List of environments and macros influencing (La)TeX math mode.
+This user-defined list is used in addition to LaTeX and AMSLaTeX defaults.
+The structure of each entry is (NAME TYPE)
+
+- The first item in each entry is the name of an environment or macro.
+ If it's a macro, include the backslash.
+
+- The second item is a symbol indicating how the command works:
+ `env-on' Environment: turns math mode for its body on
+ `env-off' Environment: turns math mode for its body off
+ `arg-on' Command: turns math mode for its arguments on
+ `arg-off' Command: turns math mode for its arguments off
+ `sw-on' Switch: turns math-mode of following text on
+ `sw-off' Switch: turns math-mode of following text off
+ `sw-toggle' Switch: toggles math mode of following text"
+ :group 'texmathp
+ :set '(lambda (symbol value) (set-default symbol value) (texmathp-compile))
+ :type
+ '(repeat
+ (list :value ("" env-on)
+ (string :tag "Name")
+ (choice :tag "Type"
+ (const :tag "Environment: turns math mode for its body on" env-on)
+ (const :tag "Environment: turns math mode for its body off" env-off)
+ (const :tag "Command: turns math mode for its argument on" arg-on)
+ (const :tag "Command: turns math-mode for its argument off" arg-off)
+ (const :tag "Switch: turns math-mode of following text on" sw-on)
+ (const :tag "Switch: turns math-mode of following text off" sw-off)
+ (const :tag "Switch: toggles math mode of following text" sw-toggle)))))
+
+(defcustom texmathp-search-n-paragraphs 2
+ "*Number of paragraphs to check before point.
+Normally, you cannot have an empty line in a math environment in (La)TeX.
+The fastest method to test for math mode is then limiting the search
+backward to the nearest empty line.
+However, during editing it happens that such lines exist temporarily.
+Therefore we look a little further. This variable determines how many
+empty lines we go back to fix the search limit."
+ :group 'texmathp
+ :type 'number)
+
+(defcustom texmathp-allow-detached-args nil
+ "*Non-nil means, allow arguments of macros to be detached by whitespace.
+When this is t, `aaa' will be interpreted as an argument of \bb in the
+following construct: \bbb [xxx] {aaa}
+This is legal in TeX. The disadvantage is that any number of braces expressions
+will be considered arguments of the macro independent of its definition."
+ :group 'texmathp
+ :type 'boolean)
+
+(defvar texmathp-why nil
+ "After a call to `texmathp' this variable shows why math-mode is on or off.
+The value is a cons cell (MATCH . POSITION).
+MATCH is a string like a car of an entry in `texmathp-tex-commands', e.q.
+\"equation\" or \"\\ensuremath\" or \"\\[\" or \"$\".
+POSITION is the buffer position of the match. If there was no match,
+it points to the limit used for searches, usually two paragraphs up.")
+
+;; We need our own syntax table to play with the syntax of () [] and {}
+;; For speed reasons we define it statically instead of copying it each time.
+(defvar texmathp-syntax-table
+ (let ((table (make-syntax-table)))
+ (mapc (lambda (x) (modify-syntax-entry (car x) (cdr x) table))
+ '((?\\ . "\\") (?\f .">") (?\n . ">") (?% . "<")
+ (?\[ . ".") (?\] . ".") (?\{ . "(}") (?\} . "){")
+ (?\( . ".") (?\) . ".") (?\" . ".") (?& . ".") (?_ . ".")
+ (?@ . "_") (?~ . " ") (?$ . "$") (?' . "w")))
+ table)
+ "Syntax table used while texmathp is parsing.")
+
+;;;###autoload
+(defun texmathp ()
+ "Determine if point is inside (La)TeX math mode.
+Returns t or nil. Additional info is placed into `texmathp-why'.
+The functions assumes that you have (almost) syntactically correct (La)TeX in
+the buffer.
+See the variable `texmathp-tex-commands' about which commands are checked."
+ (interactive)
+ (let* ((pos (point)) math-on sw-match
+ (bound (save-excursion
+ (if (re-search-backward "[\n\t][ \t]*[\n\r]"
+ nil 1 texmathp-search-n-paragraphs)
+ (match-beginning 0)
+ (point-min))))
+ (mac-match (texmathp-match-macro bound))
+ (env-match (texmathp-match-environment
+ (if (and mac-match (> (cdr mac-match) bound))
+ (cdr mac-match)
+ bound)))
+ (match (cons nil bound)))
+
+ ;; Select the nearer match
+ (and env-match (setq match env-match))
+ (and mac-match (> (cdr mac-match) (cdr match)) (setq match mac-match))
+ (setq math-on (memq (nth 1 (assoc (car match) texmathp-tex-commands1))
+ '(env-on arg-on)))
+
+ ;; Check for switches
+ (and (not math-on)
+ (setq sw-match (texmathp-match-switch bound))
+ (> (cdr sw-match) (cdr match))
+ (eq (nth 1 (assoc (car sw-match) texmathp-tex-commands1)) 'sw-on)
+ (setq match sw-match math-on t))
+
+ ;; Check for togglers
+ (if (not math-on)
+ (save-excursion
+ (goto-char (cdr match))
+ (while (re-search-forward texmathp-toggle-regexp pos t)
+ (if (setq math-on (not math-on))
+ (setq sw-match (cons (match-string 2) (match-beginning 2)))
+ (setq sw-match nil)))
+ (and math-on sw-match (setq match sw-match))))
+
+ ;; Store info, show as message when interactive, and return
+ (setq texmathp-why match)
+ (and (interactive-p)
+ (message "math-mode is %s: %s begins at buffer position %d"
+ (if math-on "on" "off")
+ (or (car match) "new paragraph")
+ (cdr match)))
+ (and math-on t)))
+
+(defun texmathp-match-environment (bound)
+ "Find out if point is inside any of the math environments.
+Limit searched to BOUND. The return value is like (\"equation\" . (point))."
+ (catch 'exit
+ (save-excursion
+ (and (null texmathp-environments) (throw 'exit nil))
+ ;; Check if the line we are starting with is a commented one.
+ (let ((orig-comment-flag
+ ;; Could be replaced by `TeX-in-commented-line'.
+ (progn
+ (save-excursion
+ (beginning-of-line)
+ (skip-chars-forward " \t")
+ (string= (buffer-substring-no-properties
+ (point) (min (point-max)
+ (+ (point) (length comment-start))))
+ comment-start))))
+ end-list env)
+ (while (re-search-backward "\\\\\\(begin\\|end\\)[ \t]*{\\([^}]+\\)}"
+ bound t)
+ ;; Check if the match found is inside of a comment.
+ (let ((current-comment-flag
+ ;; Could be replaced by `TeX-in-comment'.
+ (when (save-match-data
+ (re-search-backward comment-start-skip
+ (line-beginning-position) t))
+ ;; We need a t for comparison with `orig-comment-flag',
+ ;; not a number.
+ t)))
+ ;; Only consider matching alternatives with respect to
+ ;; "in-commentness", i.e. if we started with a comment
+ ;; only consider matches which are in comments as well and
+ ;; vice versa.
+ (when (eq orig-comment-flag current-comment-flag)
+ (setq env (buffer-substring-no-properties
+ (match-beginning 2) (match-end 2)))
+ (cond ((string= (match-string 1) "end")
+ (setq end-list (cons env end-list)))
+ ((equal env (car end-list))
+ (setq end-list (cdr end-list)))
+ ((member env texmathp-environments)
+ (throw 'exit (cons env (point))))))))
+ nil))))
+
+(defun texmathp-match-macro (bound)
+ "Find out if point is within the arguments of any of the Math macros.
+Limit searches to BOUND. The return value is like (\"\\macro\" . (point))."
+ (catch 'exit
+ (and (null texmathp-macros) (throw 'exit nil))
+ (let (pos cmd (syntax-table (syntax-table)))
+ (unwind-protect
+ (save-restriction
+ (save-excursion
+ (set-syntax-table texmathp-syntax-table)
+ (narrow-to-region (max 1 bound) (point))
+ ;; Move back out of the current parenthesis
+ (while (condition-case nil (progn (up-list -1) t) (error nil))
+ ;; Move back over any touching sexps (in fact also non-touching)
+ (while
+ (and
+ (cond
+ ((memq (preceding-char) '(?\] ?\})))
+ ((and
+ texmathp-allow-detached-args
+ (re-search-backward
+ "[]}][ \t]*[\n\r]?\\([ \t]*%[^\n\r]*[\n\r]\\)*[ \t]*\\="
+ bound t))
+ (goto-char (1+ (match-beginning 0))) t))
+ (if (eq (preceding-char) ?\})
+ ;; Jump back over {}
+ (condition-case nil
+ (progn (backward-sexp) t)
+ (error nil))
+ ;; Jump back over []. Modify syntax temporarily for this.
+ (unwind-protect
+ (progn
+ (modify-syntax-entry ?\{ ".")
+ (modify-syntax-entry ?\} ".")
+ (modify-syntax-entry ?\[ "(]")
+ (modify-syntax-entry ?\] ")[")
+ (condition-case nil
+ (progn (backward-sexp) t)
+ (error nil)))
+ (modify-syntax-entry ?\{ "(}")
+ (modify-syntax-entry ?\} "){")
+ (modify-syntax-entry ?\[ ".")
+ (modify-syntax-entry ?\] ".")
+ nil))))
+ (setq pos (point))
+ (and (memq (following-char) '(?\[ ?\{))
+ (re-search-backward "\\\\[*a-zA-Z]+\\=" nil t)
+ (setq cmd (buffer-substring-no-properties
+ (match-beginning 0) (match-end 0)))
+ (member cmd texmathp-macros)
+ (throw 'exit (cons cmd (point))))
+ (goto-char pos))
+ (throw 'exit nil)))
+ (set-syntax-table syntax-table)))))
+
+;;;###autoload
+(defun texmathp-match-switch (bound)
+ "Search backward for any of the math switches.
+Limit searched to BOUND."
+ ;; The return value is like ("\\(" . (point)).
+ (save-excursion
+ (if (re-search-backward texmathp-onoff-regexp bound t)
+ (cons (buffer-substring-no-properties (match-beginning 1) (match-end 1))
+ (match-beginning 1))
+ nil)))
+
+(provide 'texmathp)
+
+;;; texmathp.el ends here
--- /dev/null
+;;; toolbar-x.el --- fancy toolbar handling in Emacs and XEmacs
+
+;; Copyright (C) 2004, 2005, 2008 Free Software Foundation, Inc.
+
+;; This program 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.
+
+;; This program 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 this program; if not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+;; MA 02110-1301 USA
+
+;;; Author: Miguel Vinicius Santini Frasson
+
+;;; Commentary:
+;; This program implements a common interface to display toolbar
+;; buttons in both Emacs and XEmacs. A toolbar should be basicly
+;; defined by a image and a command to run when the button is pressed,
+;; and additional properties could be added. This is the idea of this
+;; program. See the documentation of function
+;; `toolbarx-install-toolbar' for a description of how to specify
+;; toolbars.
+
+;;; Features:
+
+;; * Button properties are given in the toolbar definition (BUTTON
+;; paramenter in `toolbarx-install-toolbar') and/or in an alist with
+;; associates the symbol with properties (MEANING-ALIST paramenter in
+;; `toolbarx-install-toolbar').
+
+;; * Supported properties:
+;; - All editors: `:insert', `:image', `:command', `:help', `:enable',
+;; `:append-command' and `:prepend-command';
+;; - Emacs only: `:visible' and `:button';
+;; - XEmacs only: `:toolbar'.
+;; For the precise value-type for each property, see documentation of
+;; the function `toolbarx-install-toolbar'.
+;; (ps: properties that are particular to an editor are just ignored
+;; the other editor flavour.)
+
+;; * Button properties may depend on the editor flavour, if the value
+;; is a vector; the first element will be used for Emacs and the 2nd
+;; for XEmacs. Example: `:image ["new" toolbar-file-icon]'
+
+;; * Properties can have value specified by function (with no
+;; argument) or variables that evaluate to an object of the correct
+;; type for a particular property. The evaluation is done when the
+;; roolbar is refresh (a call of `toolbarx-refresh'.)
+;; (ps: this is valid only for properties that *not* have \`form\' as
+;; value type.)
+
+;; * On `refresh time' (a call `toolbarx-refresh', necessary when the
+;; toolbar should change), the `:insert' property (if present) is
+;; evaluated to decide if button will be displayed.
+
+;; Properties can be distributed to several buttons, using \`groups\'.
+;; Example: (for (bar baz :toolbar (bottom . top) :insert foo-form)
+;; means that `foo', `bar' and `baz' have `:insert foo-form' and `bar' and
+;; `baz' have the property `:toolbar (bottom . top)'. (ps: this type
+;; of value for the `:toolbar' property (XEmacs only) means that the
+;; buttons will be in the bottom toolbar unless the default toolbar is
+;; in the bottom, and in this case, this buttons go to the top
+;; toolbar).
+
+;; * (Part of) the toolbar definition can be stored in a variable,
+;; evaluated in `installation time'. See `:eval-group' on the
+;; documentation of the function `toolbarx-install-toolbar'.
+
+;; * It is possible to define sets of buttons that appear according to
+;; an option selected in a dropdown menu. See `:dropdown-group' on
+;; the documentation of the function `toolbarx-install-toolbar'.
+
+;;; Rough description of the implementation
+;; There are 3 \`engines\' implemented:
+
+;; == the 1st one (parsing) parses the toolbar definition
+;; independently of editor flavour and store the parsed buttons with
+;; their properties, in the same order that they appear in the
+;; definitions, in a variable `toolbarx-internal-button-switches';
+
+;; == the 2nd one (refresh for Emacs) inserts buttons in the Emacs
+;; toolbar in the same order that they appear in the definitions;
+;; buttons with a `:insert' property value that evaluates to nil are
+;; ignored; if a (real) button does not have at least (valid) image
+;; and command properties, they are silently ignored;
+
+;; == the 3rd engine (refresh for XEmacs) is similar to the 2nd, but
+;; inserts buttons in XEmacs.
+
+;;; History:
+
+;; This program was motivated by the intention of implementation of a
+;; good toolbar for AUCTeX, that would work in both Emacs and XEmacs.
+;; Since toolbars are very different in behaviour and implementation
+;; (for instance, in Emacs one can display as many toolbar buttons as
+;; wanted, because it becomes mult-line, and in XEmacs, there is one
+;; line, but toolbars and all sides of a frame.)
+
+\f
+;;; Code:
+
+;; Note that this just gives a useful default. Icons are expected to
+;; be in subdirectory "images" or "toolbar" relative to the load-path.
+;; Packages loading toolbarx are advised to explicitly add their own
+;; searchpath with add-to-list here even when they fulfill that
+;; criterion: another package might have loaded toolbar-x previously
+;; when load-path was not yet correctly set. The default setting
+;; really caters only for toolbar-x' stock icons.
+
+(defvar toolbarx-image-path
+ (nconc
+ (delq nil (mapcar #'(lambda(x)
+ (and x
+ (member
+ (file-name-nondirectory
+ (directory-file-name x))
+ '("toolbar" "images"))
+ ;;(file-directory-p x)
+ x))
+ load-path))
+ (list data-directory))
+ "List of directories where toolbarx finds its images.")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; First engine: Parsing buttons
+
+;; it obtains button information, process it and stores result in
+;; `toolbarx-internal-button-switches', which is a list with 1st
+;; element the symbol `:switches', the 2nd element as a list of
+;; processed buttons, and the 3rd element is used for Emacs to store
+;; the keys used in ``constant'' buttons.
+
+;; The 2nd element of `toolbarx-internal-button-switches' is a list
+;; where each element is either:
+;; * a button-list, that is, a list with elements to define a button.
+;; * a list where 1st elem is `:insert' and 2nd is a form, and the
+;; following elements are in the same format of the 2nd element of
+;; `toolbarx-internal-button-switches'.
+
+(defun toolbarx-make-string-from-symbol (symbol)
+ "Return a string from the name of a SYMBOL.
+Upcase initials and replace dashes by spaces."
+ (let* ((str (upcase-initials (symbol-name symbol)))
+ (str2))
+ (dolist (i (append str nil))
+ (if (eq i 45) ; if dash, push space
+ (push 32 str2)
+ (push i str2))) ; else push identical
+ (concat (nreverse str2))))
+
+(defun toolbarx-make-symbol-from-string (string)
+ "Return a (intern) symbol from STRING.
+Downcase string and replace spaces by dashes."
+ (let* ((str1 (append (downcase string) nil))
+ (str2))
+ (dolist (i str1)
+ (if (eq i 32) ; if dash, push space
+ (push 45 str2)
+ (push i str2)))
+ (intern (concat (nreverse str2)))))
+
+(defun toolbarx-good-option-list-p (option-list valid-options)
+ "Non-nil means the OPTION-LIST is of form (OPT FORM ... OPT FORM).
+Each OPT is member of VALID-OPTIONS and OPT are pairwise
+different. OPTION-LIST equal to nil is a good option list."
+ (let ((elt-in-valid t)
+ (temp-opt-list option-list)
+ (list-diff)
+ (n (/ (length option-list) 2)))
+ (dotimes (i n)
+ (when (> i 0)
+ (setq temp-opt-list (cddr temp-opt-list)))
+ (add-to-list 'list-diff
+ (car temp-opt-list))
+ (setq elt-in-valid (and elt-in-valid
+ (memq (car temp-opt-list)
+ valid-options))))
+ (and elt-in-valid ; options are on VALID-OPTOPNS
+ ;; OPTION-LIST has all option different from each other
+ (eq (length list-diff) n)
+ ;; OPTION-LIST has even number of elements
+ (eq (% (length option-list) 2) 0))))
+
+(defun toolbarx-separate-options (group-list valid-options &optional check)
+ "Return a cons cell with non-options and options of GROUP-LIST.
+The options-part is the largest tail of the list GROUP-LIST that
+has an element of VALID-OPTIONS (the comparation is made with
+`memq'.) The non-options-part is the beginning of GROUP-LIST
+less its tail. Return a cons cell which `car' is the
+non-options-part and the `cdr' is the options-part.
+
+If CHECK is non-nil, the tail is the largest that yield non-nil
+when applied to `toolbarx-good-option-list-p'."
+ (let ((maximal)
+ (temp))
+ (dolist (i valid-options)
+ (setq temp (memq i group-list))
+ (when (and (> (length temp) (length maximal))
+ (if check
+ (toolbarx-good-option-list-p temp valid-options)
+ t))
+ (setq maximal (memq i group-list))))
+ (cons (butlast group-list (length maximal)) maximal)))
+
+
+(defun toolbarx-merge-props (inner-props outer-props override add)
+ "Merge property lists INNER-PROPS and OUTER-PROPS.
+INNER-PROPS and OUTER-PROPS are two lists in the format
+ (PROP VAL PROP VAL ... PROP VAL).
+Returns a list with properties and values merged.
+
+OVERRIDE and ADD are supposed to be lists of symbols. The value
+of a property in OVERRIDE is the one on OUTER-PROPS or
+INNER-PROPS, but if the property is in both, the value in
+INNER-PROPS is used. The value of a property in ADD will be a
+list with first element the symbol `:add-value-list' and the rest
+are the properties, inner properties first."
+ (let* ((merged)
+ (inner-prop)
+ (outer-prop))
+ (dolist (prop override)
+ (if (memq prop inner-props)
+ (setq merged (append merged
+ (list prop (cadr (memq prop inner-props)))))
+ (when (memq prop outer-props)
+ (setq merged (append merged
+ (list prop (cadr (memq prop outer-props))))))))
+ (dolist (prop add merged)
+ (setq inner-prop (memq prop inner-props))
+ (when inner-prop
+ (if (and (listp (cadr inner-prop))
+ (eq (car (cadr inner-prop)) :add-value-list))
+ (setq inner-prop (cdr (cadr inner-prop)))
+ (setq inner-prop (list (cadr inner-prop)))))
+ (setq outer-prop (memq prop outer-props))
+ (when outer-prop
+ (if (and (listp (cadr outer-prop))
+ (eq (car (cadr outer-prop)) :add-value-list))
+ (setq outer-prop (cdr (cadr outer-prop)))
+ (setq outer-prop (list (cadr outer-prop)))))
+ (when (append inner-prop outer-prop)
+ (setq merged (append merged
+ (list prop (cons :add-value-list
+ (append inner-prop
+ outer-prop)))))))))
+
+(defun toolbarx-make-command (comm prep app)
+ "Return a command made from COMM, PREP and APP.
+COMM is a command or a form. PREP and APP are forms. If PREP or
+APP are non-nil, they are added to the resulting command at the
+beginning and end, respectively. If both are nil and COMM is a
+command, COMM is returned."
+ (let ((comm-is-command (commandp comm)))
+ (if (and (not prep)
+ (not app)
+ comm-is-command)
+ comm
+ (append '(lambda nil (interactive))
+ (when prep (list prep))
+ (when comm
+ (if comm-is-command
+ `((call-interactively (function ,comm)))
+ (list comm)))
+ (when app (list app))))))
+
+;; in Emacs, menus are made of keymaps (vectors are possible, but editors
+;; handle `menu titles' differently) meanwhile in XEmacs, menus are lists of
+;; vectors
+
+(defun toolbarx-emacs-mount-popup-menu
+ (strings var type &optional title save)
+ "Return an interactive `lambda'-expression that shows a popup menu.
+This function is the action of `toolbarx-mount-popup-menu' if
+inside Emacs. See documentation of that function for more."
+ ;; making the menu keymap by adding each menu-item definition
+ ;; see (info "(elisp)Menu keymaps")
+ (let* ((keymap (make-sparse-keymap title))
+ (count 1)
+ (used-symbols '(nil))
+ (key)
+ (real-type (if (eq type 'toggle) 'toggle 'radio))
+ (real-save (when save (if (eq save 'offer) 'offer 'always))))
+ ;; warn if type is not `radio' ot `toggle'; use `radio' if incorrect.
+ (unless (eq type real-type)
+ (display-warning 'toolbarx
+ (format (concat "TYPE should be symbols `radio' or "
+ "`toggle', but %s found; using `radio'")
+ type)))
+ ;; warn if save is not `nil', `offer' or `always'; use nil when incorrect
+ (unless (eq save real-save)
+ (setq real-save nil)
+ (display-warning 'toolbarx
+ (format (concat "SAVE should be symbols `nil', "
+ "`offer' or `always', but %s found; "
+ "using `nil'")
+ save)))
+ (dolist (i strings)
+ ;; finding a new symbol
+ (let* ((aux-count 0)
+ (i-symb (toolbarx-make-symbol-from-string i)))
+ (setq key i-symb)
+ (while (memq key used-symbols)
+ (setq aux-count (1+ aux-count))
+ (setq key (intern (format "%s-%d" i-symb aux-count))))
+ (setq used-symbols (cons key used-symbols)))
+ (define-key-after keymap (vector key)
+ `(menu-item ,i
+ ,(append
+ `(lambda nil (interactive)
+ ,(if (eq real-type 'radio)
+ `(setq ,var ,count)
+ `(if (memq ,count ,var)
+ (setq ,var (delete ,count ,var))
+ (setq ,var (sort (cons ,count ,var) '<))))
+ (toolbarx-refresh))
+ (when (eq real-save 'always)
+ `((customize-save-variable
+ (quote ,var) ,var)))
+ `(,var))
+ :button ,(if (eq real-type 'radio)
+ `(:radio eq ,var ,count)
+ `(:toggle memq ,count ,var))))
+ (setq count (1+ count)))
+ (when (eq real-save 'offer)
+ (define-key-after keymap [sep] '(menu-item "--shadow-etched-in-dash"))
+ (let* ((aux-count 0)
+ (i-symb 'custom-save))
+ (setq key i-symb)
+ (while (memq key used-symbols)
+ (setq aux-count (1+ aux-count))
+ (setq key (intern (format "%s-%d" i-symb aux-count))))
+ (setq used-symbols (cons key used-symbols)))
+ (define-key-after keymap (vector key)
+ `(menu-item "Save state of this menu"
+ (lambda nil (interactive)
+ (customize-save-variable (quote ,var) ,var)))))
+ ;; returns a `lambda'-expression
+ `(lambda nil (interactive) (popup-menu (quote ,keymap)))))
+
+(defun toolbarx-xemacs-mount-popup-menu
+ (strings var type &optional title save)
+ "Return an interactive `lambda'-expression that shows a popup menu.
+This function is the action of `toolbarx-mount-popup-menu' if
+inside XEmacs. See documentation of that function for more."
+ (let* ((menu (if (and title (stringp title))
+ (list title)
+ (setq title nil)
+ (list "Dropdown menu")))
+ (count 0)
+ (menu-item)
+ (menu-callback)
+ (real-type (if (eq type 'toggle) 'toggle 'radio))
+ (real-save (when save (if (eq save 'offer) 'offer 'always))))
+ ;; warn if type is not `radio' ot `toggle'; use `radio' if incorrect.
+ (unless (eq type real-type)
+ (warn (concat "TYPE should be symbols `radio' or `toggle', "
+ "but %s found; using `radio'") type))
+ ;; warn if save is not `nil', `offer' or `always'; use nil when incorrect
+ (unless (eq save real-save)
+ (setq real-save nil)
+ (display-warning 'toolbarx
+ (format (concat "SAVE should be symbols `nil', "
+ "`offer' or `always', but %s found; "
+ "using `nil'")
+ save)))
+ ;; making the menu list of vectors
+ (dolist (str strings)
+ (setq count (1+ count))
+ (setq menu-callback (list 'progn
+ (if (eq real-type 'radio)
+ `(setq ,var ,count)
+ `(if (memq ,count ,var)
+ (setq ,var (delete ,count ,var))
+ (setq ,var (sort (cons ,count ,var) '<))))
+ '(toolbarx-refresh)))
+ (when (eq real-save 'always)
+ (setq menu-callback (append menu-callback
+ (list (list 'customize-save-variable
+ (list 'quote var) var)))))
+ (setq menu-item (vector str menu-callback
+ :style real-type
+ :selected (if (eq real-type 'radio)
+ `(eq ,var ,count)
+ `(memq ,count ,var))))
+ (setq menu (append menu (list menu-item))))
+ (when (eq real-save 'offer)
+ (setq menu (append menu (list "--:shadowEtchedInDash")))
+ (setq menu (append menu (list
+ (vector
+ "Save state of this menu"
+ `(customize-save-variable (quote ,var)
+ ,var))))))
+ ;; returnung the lambda-expression
+ `(lambda nil (interactive)
+ (let ((popup-menu-titles ,(if title t nil)))
+ (popup-menu (quote ,menu))))))
+
+(defun toolbarx-mount-popup-menu (strings var type &optional title save)
+ "Return a command that show a popup menu.
+The return is a `lambda'-expression with a interactive declaration.
+
+STRINGS is a list of strings which will be the itens of the menu.
+
+VAR is a symbol that is set when an item is clicked. TYPE should
+be one of the symbols `radio' or `toggle': `radio' means that the
+nth item is selected if VAR is `n' and this item sets VAR to `n';
+`toggle' means that VAR should be a list of integers and the nth
+item is selected if `n' belongs to VAR. The item inserts or
+deletes `n' from VAR.
+
+TITLE is a string (the title of the popup menu) or nil for no
+title.
+
+SAVE is one of the symbols nil, `offer' or `always'. If value
+is nil, do not try to save anything. If it is `offer', a menu
+item is added offering the user the possibiity to save state of
+that dropdown menu for future sesseions (using `custom'). If it
+is `always', state is saved every time that a item is clicked."
+ (if (featurep 'xemacs)
+ (toolbarx-xemacs-mount-popup-menu strings var type title save)
+ (toolbarx-emacs-mount-popup-menu strings var type title save)))
+
+(defun toolbarx-option-value (opt)
+ "Return option value according to Emacs flavour.
+If OPT is a vector, return first element if in Emacs or
+second if in XEmacs. Otherwise, return OPT.
+If OPT is vector and length is smaller than the necessary (like
+if in XEmacs and vector has length 1), then nil is returned."
+ (if (vectorp opt)
+ (if (featurep 'xemacs)
+ (when (> (length opt) 1)
+ (aref opt 1))
+ (when (> (length opt) 0)
+ (aref opt 0)))
+ opt))
+
+(defun toolbarx-eval-function-or-symbol (object type-test-func)
+ "Return a cons cell (GOOD-OBJ . VAL).
+GOOD-OBJ non-nil means that VAL is a valid value, according to
+the car of the result of TYPE-TEST-FUNCTION, that should return a
+cons cell in the same format as the return of this function.
+
+If OBJECT applied to TYPE-TEST-FUNC return (GOOD-OBJ . VAL), and
+GOOD-OBJ is non-nil, return that. Else, check if OBJECT is a
+function. If so, evaluate and test again with TYPE-TEST-FUNC. If
+not a function or if GOOD-OBJ is again nil, test if OBJECT is a
+bound symbol, evaluate that and return the result of
+TYPE-TEST-FUNC."
+ (let* ((ret (funcall type-test-func object)))
+ (unless (car ret)
+ (if (functionp object)
+ (progn
+ (setq ret (funcall type-test-func (funcall object)))
+ (unless (car ret)
+ (when (and (symbolp object) (boundp object))
+ (setq ret (funcall type-test-func (symbol-value object))))))
+ ;; ok, obj is not function; try symbol
+ (when (and (symbolp object) (boundp object))
+ (setq ret (funcall type-test-func (symbol-value object))))))
+ ret))
+
+(defun toolbarx-test-image-type (obj)
+ "Return a cons cell (GOOD-OBJ . VAL).
+GOOD-OBJ is non-nil if OBJ yields a valid image object VAL (see
+documentation of function `toolbarx-process-symbol')."
+ (let ((toolbarx-test-image-type-simple
+ (lambda (img)
+ (let* ((val (toolbarx-option-value img))
+ (all-obj-ok t)
+ (good-obj
+ (if (featurep 'xemacs)
+ ;; if XEmacs
+ (or (stringp val) ; a string
+ (glyphp val) ; or a glyph
+ (and (symbolp val) ; or a symbol bound to a
+ (boundp val) ; glyph-list
+ (check-toolbar-button-syntax
+ (vector val
+ (lambda nil (interactive))
+ nil nil) t))
+ (and (listp val) ; or a glyph-or-string list
+ (> (length val) 0)
+ (< (length val) 7)
+ (dolist (i val all-obj-ok)
+ (setq all-obj-ok
+ (and all-obj-ok
+ (or (not i)
+ (stringp i)
+ (glyphp i)))))))
+ ;; if Emacs
+ (or (stringp val) ; string
+ (and (consp val) ; or image descriptor
+ (eq (car val) 'image))
+ (and (symbolp val) ; or a symbol bound to a
+ (boundp val) ; image descriptor
+ ; (defined with `defimage')
+ (consp (eval val))
+ (eq (car (eval val)) 'image))
+ (and (listp val) ; or list with 4 strings or
+ ; image descriptors
+ (= (length val) 4)
+ (dolist (i val all-obj-ok)
+ (setq all-obj-ok
+ (and all-obj-ok
+ (or (stringp i)
+ (and (consp i)
+ (eq (car i)
+ 'image)))))))))))
+ (cons good-obj val)))))
+ (toolbarx-eval-function-or-symbol obj toolbarx-test-image-type-simple)))
+
+(defun toolbarx-test-button-type (obj)
+ "Return a cons cell (GOOD-OBJ . VAL).
+GOOD-OBJ is non-nil if OBJ yields a valid button object VAL (see
+documentation of function `toolbarx-process-symbol')."
+ (let ((toolbarx-test-button-type-simple
+ (lambda (but)
+ (let* ((val (toolbarx-option-value but))
+ (good-obj (if (featurep 'xemacs)
+ ;; if XEmacs
+ t
+ ;; if Emacs
+ (and (consp val)
+ (memq (car val) '(:toggle :radio))))))
+ (cons good-obj val)))))
+ (toolbarx-eval-function-or-symbol obj toolbarx-test-button-type-simple)))
+
+(defun toolbarx-test-any-type (obj)
+ "Return a cons cell (t . VAL).
+If OBJ is vector, return VAL according to editor. Else, return
+OBJ, because it is a form anyway."
+ (cons t (toolbarx-option-value obj)))
+
+(defun toolbarx-test-string-or-nil (obj)
+ "Return a cons cell (GOOD-OBJ . VAL).
+GOOD-OBJ is non-nil if OBJ yields a valid help object VAL (see
+documentation of function `toolbarx-process-symbol')."
+ (let ((toolbarx-test-string-or-nil-simple
+ (lambda (obj)
+ (let* ((val (toolbarx-option-value obj))
+ (good-obj (or (stringp val)
+ (not val))))
+ (cons good-obj val)))))
+ (toolbarx-eval-function-or-symbol obj toolbarx-test-string-or-nil-simple)))
+
+(defun toolbarx-test-toolbar-type (obj)
+ "Return a cons cell (GOOD-OBJ . VAL).
+GOOD-OBJ is non-nil if OBJ yields a valid toolbar property object
+VAL (see documentation of function `toolbarx-process-symbol')."
+ (let ((toolbarx-test-toolbar-type-simple
+ (lambda (obj)
+ (let* ((val (toolbarx-option-value obj))
+ (all-but-def-opts '(top bottom left right))
+ (all-opts '(default top bottom left right))
+ (good-obj
+ (if (featurep 'xemacs)
+ ;; if XEmacs
+ (if (symbolp val)
+ (memq val all-opts)
+ (and (consp val)
+ (memq (car val) all-but-def-opts)
+ (memq (cdr val) all-but-def-opts)))
+ ;; if Emacs
+ t)))
+ (cons good-obj val)))))
+ (toolbarx-eval-function-or-symbol obj toolbarx-test-toolbar-type-simple)))
+
+(defun toolbarx-test-dropdown-type (obj)
+ "Return a cons cell (GOOD-OBJ . VAL).
+GOOD-OBJ is non-nil if OBJ yields a valid `:type' property object
+VAL of a dropdown group (see documentation of function
+`toolbarx-process-dropdown-group'."
+ (let ((toolbarx-test-dropdown-type-simple
+ (lambda (obj)
+ (let* ((val (toolbarx-option-value obj))
+ (good-obj (memq val '(radio toggle))))
+ (cons good-obj val)))))
+ (toolbarx-eval-function-or-symbol obj toolbarx-test-dropdown-type-simple)))
+
+(defun toolbarx-test-symbol (obj)
+ "Return a cons cell (GOOD-OBJ . VAL).
+GOOD-OBJ is non-nil if OBJ yields a valid `:variable' property
+object VAL of a dropdown group (see documentation of function
+`toolbarx-process-dropdown-group'."
+ (let ((toolbarx-test-symbol-simple
+ (lambda (obj)
+ (let* ((val (toolbarx-option-value obj))
+ (good-obj (symbolp val)))
+ (cons good-obj val)))))
+ (toolbarx-eval-function-or-symbol obj toolbarx-test-symbol-simple)))
+
+(defun toolbarx-test-dropdown-default (obj)
+ "Return a cons cell (GOOD-OBJ . VAL).
+GOOD-OBJ is non-nil if OBJ yields a valid `:default' property
+object VAL of a dropdown group (see documentation of function
+`toolbarx-process-dropdown-group'."
+ (let ((toolbarx-test-dropdown-default-simple
+ (lambda (obj)
+ (let* ((val (toolbarx-option-value obj))
+ (good-obj (or (integerp val)
+ (and (listp val)
+ (let ((ok t))
+ (dolist (i val ok)
+ (setq ok (and ok (integerp i)))))))))
+ (cons good-obj val)))))
+ (toolbarx-eval-function-or-symbol obj
+ toolbarx-test-dropdown-default-simple)))
+
+(defun toolbarx-test-dropdown-save (obj)
+ "Return a cons cell (GOOD-OBJ . VAL).
+GOOD-OBJ is non-nil if OBJ yields a valid `:save' property
+object VAL of a dropdown group (see documentation of function
+`toolbarx-process-dropdown-group'."
+ (let ((toolbarx-test-dropdown-save-simple
+ (lambda (obj)
+ (let* ((val (toolbarx-option-value obj))
+ (good-obj (memq val '(nil offer always))))
+ (cons good-obj val)))))
+ (toolbarx-eval-function-or-symbol obj toolbarx-test-dropdown-save-simple)))
+
+(defconst toolbarx-button-props
+ (let* ((props-types-alist
+ '((:image toolbarx-test-image-type)
+ (:command toolbarx-test-any-type)
+ (:enable toolbarx-test-any-type)
+ (:visible toolbarx-test-any-type)
+ (:help toolbarx-test-string-or-nil)
+ (:insert toolbarx-test-any-type . and)
+ (:toolbar toolbarx-test-toolbar-type)
+ (:button toolbarx-test-button-type)
+ (:append-command toolbarx-test-any-type . progn)
+ (:prepend-command toolbarx-test-any-type . progn)))
+ (possible-props (nreverse (let* ((props ()))
+ (dolist (p props-types-alist props)
+ (setq props (cons (car p) props))))))
+ (props-override (nreverse (let* ((props ()))
+ (dolist (p props-types-alist props)
+ (unless (cddr p)
+ (setq props (cons (car p) props)))))))
+ (props-add (nreverse (let* ((props ()))
+ (dolist (p props-types-alist props)
+ (when (cddr p)
+ (setq props (cons (car p) props))))))))
+ (list props-types-alist possible-props props-override props-add))
+ "List yielding all encarnations of properties of a button.
+First element: alist, where each element is of form
+ (PROP . (TYPE-TEST-FUNCTION . ADD-OR-NIL))
+Second is a list with all properties.
+Third, a list with properties that override when merging.
+Fourth, a list of lists, each in the format (PROP ADD).")
+
+(defconst toolbarx-dropdown-props
+ ;; for naming dropdown properties see `Convention' in the doc string
+ (let* ((props-types-alist
+ '((:type toolbarx-test-dropdown-type)
+ (:variable toolbarx-test-symbol)
+ (:default toolbarx-test-dropdown-default)
+ (:save toolbarx-test-dropdown-save)
+ (:title toolbarx-test-string-or-nil)
+ (:dropdown-image toolbarx-test-image-type)
+ (:dropdown-enable toolbarx-test-any-type)
+ (:dropdown-visible toolbarx-test-any-type)
+ (:dropdown-insert toolbarx-test-any-type . and)
+ (:dropdown-help toolbarx-test-string-or-nil)
+ (:dropdown-toolbar toolbarx-test-toolbar-type)
+ (:dropdown-append-command toolbarx-test-any-type . progn)
+ (:dropdown-prepend-command toolbarx-test-any-type . progn)))
+ (possible-props (nreverse (let* ((props ()))
+ (dolist (p props-types-alist props)
+ (setq props (cons (car p) props))))))
+ (props-override (nreverse (let* ((props ()))
+ (dolist (p props-types-alist props)
+ (unless (cddr p)
+ (setq props (cons (car p) props)))))))
+ (props-add (nreverse (let* ((props ()))
+ (dolist (p props-types-alist props)
+ (when (cddr p)
+ (setq props (cons (car p) props))))))))
+ (list props-types-alist possible-props props-override props-add))
+ "List yielding all encarnations of properties of a dropdown group.
+First element: alist, where each element is of form
+ (PROP . (TYPE-TEST-FUNCTION . ADD-OR-NIL))
+Second is a list with all properties.
+Third, a list with properties that override when merging.
+Fourth, a list of lists, each in the format (PROP ADD).
+
+Convention: properties for the dropdown button should be formed
+with the strings \":dropdown-\" with the button property name
+without `:'. This is used on the implementation.")
+
+(defun toolbarx-process-group-without-insert (group-without-props
+ merged-props-without-insert
+ meaning-alist switches)
+ "Return an updated version of SWITCHES.
+GROUP-WITHOUT-PROPS and MERGED-PROPS-WITHOUT-INSERT are
+preprocessed variables in `toolbarx-process-group'."
+ (let ((current-switches switches))
+ (dolist (i group-without-props current-switches)
+ (setq i (toolbarx-option-value i))
+ (if (symbolp i)
+ (setq current-switches
+ (toolbarx-process-symbol i meaning-alist
+ merged-props-without-insert
+ current-switches))
+ (when (listp i)
+ (setq current-switches
+ (toolbarx-process-group i meaning-alist
+ merged-props-without-insert
+ current-switches)))))))
+
+(defun toolbarx-process-group (group meaning-alist props switches)
+ "Return an updated version of SWITCHES.
+Append to already processed buttons (stored in SWITCHES) a
+processed version of GROUP. Groups are useful to distribute
+properties. External properties are given in PROPS, and merged
+with the internal properties that are in the end of GROUP. If
+properties (after merge) contain a `:insert' property, return a
+list where the first and second elements are `:insert' and its
+value, and after that a list in the same format as SWITCHES."
+ (cond
+ ;; if DROPDOWN group
+ ((eq (car group) :dropdown-group)
+ (toolbarx-process-dropdown-group group meaning-alist props switches))
+ ;; if EVAL group
+ ((eq (car group) :eval-group)
+ (let ((current-switches switches))
+ (dolist (elt (cdr group) current-switches)
+ (let ((eval-elt (eval elt)))
+ (setq current-switches
+ (toolbarx-process-group (if (listp eval-elt)
+ eval-elt
+ (list eval-elt))
+ meaning-alist props
+ current-switches))))))
+ ;; if normal group
+ (t
+ (let* ((splited-props
+ (toolbarx-separate-options
+ group (append (nth 1 toolbarx-button-props)
+ (nth 1 toolbarx-dropdown-props))))
+ (intern-props (cdr splited-props))
+ (group-without-props (car splited-props))
+ (merged-props
+ (toolbarx-merge-props intern-props props
+ (append (nth 2 toolbarx-button-props)
+ (nth 2 toolbarx-dropdown-props))
+ (append (nth 3 toolbarx-button-props)
+ (nth 3 toolbarx-dropdown-props)))))
+ ;; check whether merged props have an `:insert'
+ (if (memq :insert merged-props)
+ ;; if yes, prepend switches with a (:insert cond elements)
+ (let* ((memq-ins (memq :insert merged-props))
+ (ins-val (if (and (listp (cadr memq-ins))
+ (eq :add-value-list
+ (car (cadr memq-ins))))
+ ;; if property is add-value property
+ (let* ((p (assq
+ :insert
+ (nth 0 toolbarx-button-props)))
+ (add-list (list (cddr p)))
+ (prop-good-val))
+ (dolist (val (cdr (cadr memq-ins)))
+ (setq prop-good-val (funcall (cadr p) val))
+ (when (car prop-good-val)
+ (setq add-list (cons (cdr prop-good-val)
+ add-list))))
+ ;; return: (nreverse add-list)
+ (setq add-list (nreverse add-list))
+ (if (eq 2 (length add-list))
+ (cadr add-list) ; just 1 value, no
+ add-list)) ; add-function
+ ;; if property is not add-value
+ (cadr memq-ins)))
+ (merged-props-without-insert
+ (append (butlast merged-props (length memq-ins))
+ (cddr memq-ins)))
+ (group-switches
+ (toolbarx-process-group-without-insert
+ group-without-props merged-props-without-insert
+ meaning-alist nil)))
+ ;; return
+ (nreverse (cons (append (list :insert ins-val)
+ group-switches)
+ (nreverse switches))))
+ ;; if not, just append what is processed to switches
+ (toolbarx-process-group-without-insert group-without-props
+ merged-props meaning-alist
+ switches))))))
+
+(defun toolbarx-process-symbol (symbol meaning-alist props switches)
+ "Process a button given by SYMBOL in MEANING-ALIST.
+The processed button is appended in SWITCHES, which is returned.
+Look for a association of SYMBOL in MEANING-ALIST for collecting
+properties. Such association is a list that represents either a
+normal button (a description of the button) or an alias
+group (the symbol is an alias for a group of buttons). PROPS is
+a externel list of properties that are merged and then applied to
+the button. Scope is given by GLOBAL-FLAG."
+ ;; there are 3 situations: symbol is :new-line, there is an alias group
+ ;; or a normal button
+ (let ((button-assq (cdr (assq symbol meaning-alist))))
+ (cond
+ ((eq (car button-assq) :alias)
+ ;; button association is ALIAS GROUP is passed to
+ ;; `toolbarx-process-group' as is but without the car.
+ ;; return: (toolbarx-process-group... returns updates switch
+ (toolbarx-process-group (cdr button-assq) meaning-alist props switches))
+ (t
+ ;; NORMAL BUTTON (association is a list of properties)
+ ;;
+ ;; properties need to be processed, that is, merge internal
+ ;; and external (given by PROPS) properties
+ (let* (;; button properties defined in `toolbarx-button-props'
+ (props-override (nth 2 toolbarx-button-props))
+ (props-add (nth 3 toolbarx-button-props))
+ ;; split considering also dropdown-group properties
+ (button-assq-split
+ (toolbarx-separate-options
+ button-assq
+ (append (nth 1 toolbarx-button-props)
+ (nth 1 toolbarx-dropdown-props))))
+ (button-split-no-props (car button-assq-split))
+ (button-split-props (cdr button-assq-split))
+ ;; if there is no :image or :command in the props,
+ ;; try to get them from no-props part
+ (button-image-no-prop
+ (unless (memq :image button-split-props)
+ (when (> (length button-split-no-props) 0)
+ (list :image (nth 0 button-split-no-props)))))
+ (button-command-no-prop
+ (unless (memq :command button-split-props)
+ (when (> (length button-split-no-props) 1)
+ (list :command (nth 1 button-split-no-props)))))
+ (button-props (append button-split-props
+ button-image-no-prop
+ button-command-no-prop))
+ ;; merge props
+ (merged-props (toolbarx-merge-props button-props props
+ props-override
+ props-add)))
+ ;; return:
+ (nreverse (cons (cons symbol merged-props) (nreverse switches))))))))
+
+(defun toolbarx-process-dropdown-group (dropdown meaning-alist props switches)
+ "Process buttons that appear according to dropdown menu.
+Process a dropdown group DROPDOWN with meaning alist
+MEANING-ALIST, external property list PROP and GLOBAL-FLAG
+specifying scope. For a complete description, see documentation
+of `toolbarx-install-toolbar'. The processed buttons are stored
+in the end of SWITCHES, which is returned."
+ (let* ((dropdown-group (if (eq (car dropdown) :dropdown-group)
+ (cdr dropdown)
+ dropdown))
+ (dropdown-list-splited
+ (toolbarx-separate-options dropdown-group
+ (append
+ (nth 1 toolbarx-button-props)
+ (nth 1 toolbarx-dropdown-props))))
+ (dropdown-list (car dropdown-list-splited))
+ (dropdown-props (cdr dropdown-list-splited))
+ (merged-props
+ (toolbarx-merge-props dropdown-props props
+ (append (nth 2 toolbarx-button-props)
+ (nth 2 toolbarx-dropdown-props))
+ (append (nth 3 toolbarx-button-props)
+ (nth 3 toolbarx-dropdown-props))))
+ (merged-props-button-only
+ (let* ((props-button-only)
+ (prop))
+ (dolist (p (nth 1 toolbarx-button-props) props-button-only)
+ (setq prop (memq p merged-props))
+ (when prop
+ (setq props-button-only
+ (append (list p (cadr prop))
+ props-button-only))))))
+ (merged-props-dropdown-only
+ (let* ((props-dropdown-only)
+ (prop))
+ (dolist (p (nth 1 toolbarx-dropdown-props) props-dropdown-only)
+ (setq prop (memq p merged-props))
+ (when prop
+ (setq props-dropdown-only
+ (append (list p (cadr prop))
+ props-dropdown-only))))))
+ ;; get value for each property and check type ONLY for props that do
+ ;; not concern the dropdown button, like `:type', `:save', etc. The
+ ;; props that concern the button are going to be handled in refresh
+ ;; time.
+ (filtered-dropdown-group-props-only
+ (let* ((filtered-props-temp)
+ (prop-good-val)
+ (prop))
+ (save-match-data
+ (dolist (p (nth 0 toolbarx-dropdown-props) filtered-props-temp)
+ (unless (string-match "^:dropdown-.*$"
+ (symbol-name (car p)))
+ ;; property -> (car p)
+ ;; test type function -> (cadr p)
+ (setq prop (memq (car p) merged-props-dropdown-only))
+ ;; if so, check if value is of correct type
+ (when prop
+ (setq prop-good-val (funcall (cadr p) (cadr prop)))
+ (if (car prop-good-val)
+ (setq filtered-props-temp
+ (append filtered-props-temp
+ (list (car p) (cdr prop-good-val))))
+ (display-warning
+ 'toolbarx
+ (format (concat "Wrong type for value in "
+ "property `%s' in dropdown group")
+ (car p))))))))))
+ ;; properties for the dropdown button from dropdown merged properties
+ (dropdown-button-props
+ (let* ((props))
+ (save-match-data
+ (dolist (pr (nth 1 toolbarx-dropdown-props))
+ (when (and (memq pr merged-props-dropdown-only)
+ (string-match "^:dropdown-\\(.*\\)$"
+ (symbol-name pr)))
+ (let* ((new-pr (intern (concat ":"
+ (substring (symbol-name pr)
+ (match-beginning 1)
+ (match-end 1)))))
+ (val (cadr (memq pr merged-props-dropdown-only))))
+ (setq props (append (list new-pr val) props))))))
+ (unless (memq :image props)
+ (setq props (append (list :image "dropdown") props)))
+ props))
+ (dropdown-button-without-command
+ (cons 'dropdown dropdown-button-props))
+ ;; `:type' defaults to `radio'
+ (type (if (memq :type filtered-dropdown-group-props-only)
+ (cadr (memq :type filtered-dropdown-group-props-only))
+ 'radio))
+ ;; `:default' defaults to 1 or nil depending on `type'
+ ;; if type is toggle and default is not a list, but a
+ ;; integer, set as the list with integer
+ (default
+ (let* ((memq-default (memq :default
+ filtered-dropdown-group-props-only))
+ (def-temp (cadr memq-default))
+ (default-temp (if memq-default
+ def-temp
+ (if (eq type 'radio) 1 (list 1)))))
+ default-temp))
+ ;; `:save' defaults to nil and require `:variable'
+ (save (let* ((save-temp
+ (when (memq :save filtered-dropdown-group-props-only)
+ (cadr (memq :save
+ filtered-dropdown-group-props-only)))))
+ (if (and save-temp
+ (not (memq :variable
+ filtered-dropdown-group-props-only)))
+ (progn
+ (display-warning
+ 'toolbarx
+ (concat "`:save' property with non-nil value should "
+ "be used only with the `:variable' property; "
+ "using value nil for `:save'."))
+ nil)
+ save-temp)))
+ ;; `:title' defaults to nil
+ (title (when (memq :title filtered-dropdown-group-props-only)
+ (cadr (memq :title filtered-dropdown-group-props-only))))
+ ;; the menu variable is buildt from the `:variable' option or
+ ;; make a symbol not used
+ (variable (if (memq :variable filtered-dropdown-group-props-only)
+ (cadr (memq :variable
+ filtered-dropdown-group-props-only))
+ (let* ((count 0)
+ (symb (intern (format
+ "toolbarx-internal-menu-var-%d"
+ count))))
+ (while (boundp symb)
+ (setq count (1+ count))
+ (setq symb
+ (intern (format "toolbarx-internal-menu-var-%d"
+ count))))
+ symb)))
+ ;; auxiliary variables
+ (list-strings)
+ (list-buttons))
+ ;; setting `variable'
+ (if save
+ (custom-declare-variable
+ variable default
+ "Used as variable of dropdown menu defined with `toolbarx'.")
+ (when (not (boundp variable))
+ (set variable default)))
+ ;; now check `variable' content
+ (set variable
+ (let ((val (eval variable)))
+ (if (eq type 'toggle)
+ (if (listp val)
+ val
+ (if (integerp val)
+ (list val)
+ (list 1)))
+ ;; then, type is radio
+ (if (integerp val)
+ val
+ (if (and val
+ (listp val)
+ (integerp (car val)))
+ (car val)
+ 1)))))
+ ;; === buiding `list-strings' and `list-buttons' ===
+ ;; if only symbols, build `list-strings' and `list-buttons' from symbols
+ (if (let ((only-symbols-flag t))
+ (dolist (i dropdown-list only-symbols-flag)
+ (setq only-symbols-flag (and only-symbols-flag (symbolp i)))))
+ (let ((count 0))
+ (dolist (i dropdown-list)
+ ;; list-strings and list-buttons are buildt reversed
+ (setq list-strings (cons (toolbarx-make-string-from-symbol i)
+ list-strings))
+ (setq count (1+ count))
+ (setq list-buttons (cons (list i
+ :insert
+ (if (eq type 'radio)
+ (list 'eq count variable)
+ (list 'memq count variable)))
+ list-buttons))))
+ ;; if not, the it must start with string
+ (unless (stringp (car dropdown-list))
+ (error "%s %s %s"
+ "If not all itens on dropdown are symbols, then a string"
+ "must come before each set of buttons; no string found"
+ "in first position."))
+ (let ((count 0)
+ (elem)
+ (temp-list-buttons))
+ (while dropdown-list
+ (setq elem (car dropdown-list))
+ (setq dropdown-list (cdr dropdown-list))
+ (if (stringp elem)
+ ;; if string, output `temp-list-buttons' and prepair it again
+ (progn
+ ;; list-strings and list-buttons are buildt reversed
+ (setq list-strings (cons elem list-strings))
+ (when temp-list-buttons
+ (setq list-buttons (cons (append (nreverse temp-list-buttons)
+ (list :insert
+ (if (eq type 'radio)
+ (list 'eq count
+ variable)
+ (list 'memq count
+ variable))))
+ list-buttons)))
+ (setq temp-list-buttons nil)
+ (setq count (1+ count)))
+ ;; else, if not string, just insert it to `temp-list-buttons'
+ ;; which is also buildt reversed
+ (setq temp-list-buttons (cons elem temp-list-buttons))))
+ ;; output last temp list, left behind
+ (when temp-list-buttons
+ (setq list-buttons (cons (append (nreverse
+ temp-list-buttons)
+ (list
+ :insert (if (eq type 'radio)
+ (list 'eq count
+ variable)
+ (list 'memq count
+ variable))))
+ list-buttons)))))
+ ;; lists were made reversed (elements inserted at the beginning)
+ (setq list-strings (nreverse list-strings))
+ (setq list-buttons (nreverse list-buttons))
+ ;; now, pass `list-buttons' as a group to `toolbarx-process-group'
+ (let ((current-switches switches))
+ (setq current-switches
+ (toolbarx-process-group list-buttons meaning-alist
+ merged-props ; pass non-processed props
+ current-switches))
+ (setq current-switches
+ ;; outputing dropdown button
+ (toolbarx-process-group (append dropdown-button-without-command
+ (list :command
+ (toolbarx-mount-popup-menu
+ list-strings variable type
+ title save)))
+ meaning-alist merged-props-button-only
+ switches))
+ current-switches)))
+
+
+
+;; Still functions `toolbarx-install-toolbar' and `toolbarx-refresh'to
+;; complete the parsing engine. Since they interface with other engines,
+;; they must come in the end.
+
+;;; How a image is made, giving a string as (part of) file name.
+
+;; look at function `image-type-available-p' for Emacs !!!!
+
+(defun toolbarx-find-image (image)
+ "Return image descriptor or glyph for IMAGE.
+In Emacs, return an image descriptor for IMAGE. In XEmacs,
+return a glyph.
+
+IMAGE is string. Usually IMAGE neither contains a directory nor
+an extension. If the extension is omitted, `xpm', `xbm' and
+`pbm' are tried. If the directory is omitted,
+`toolbarx-image-path' is searched."
+ ;; `find-image' in Emacs 21 looks in `load-path' and `data-directory'. In
+ ;; Emacs 22, we have `image-load-path' which includes `load-path' and
+ ;; `data-directory'.
+ ;;
+ ;; If there's some API in XEmacs to find the images, we should use it
+ ;; instead of locate-library.
+ ;;
+ ;; Emacs 22 has locate-file, but the other Emacsen don't. The
+ ;; following should hopefully get us to all images ultimately.
+
+ (let ((file))
+ (dolist (i '("" ".xpm" ".xbm" ".pbm"))
+ (unless file
+ (setq file (locate-library (concat image i) t toolbarx-image-path))))
+ (if (featurep 'xemacs)
+ (and file (make-glyph file))
+ (if file
+ (create-image file)
+ (find-image `((:type xpm :file ,(concat image ".xpm"))
+ (:type xbm :file ,(concat image ".xbm"))
+ (:type pbm :file ,(concat image ".pbm"))))))))
+
+;; next variable interfaces between parsing and display engines
+(defvar toolbarx-internal-button-switches nil
+ "Store the list of processed buttons, used by `toolbarx-refresh'.
+This variable can store different values for the different buffers.")
+
+\f
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Second engine: display parsed buttons in Emacs
+
+(defun toolbarx-emacs-add-button (button used-keys keymap)
+ "Insert a button where BUTTON is its description.
+USED-KEYS should be a list of symbols, where the first element is
+`:used-symbols'. This list should store the symbols of the
+buttons already inserted. This list is changed by side effect.
+KEYMAP is the keymap where the menu-item corresponding to the
+tool-bal button is going to be inserted. Insertion is made in
+the end of KEYMAP.
+
+BUTTON should be a list of form (SYMBOL . PROP-LIST). SYMBOL is
+a symbol that \"names\" this button. PROP-LIST is a list in the
+format (PROP VAL ... PROP VAL). The supported properties are
+`:image', `:command', `:append-command', `:prepend-command',
+`:help', `:enable', `:visible', `:button', `:insert' and
+`:toolbar'. For a description of properties, see documentation of
+function `toolbar-install-toolbar'."
+ (let* ((symbol (nth 0 button))
+ (used-keys-list (when used-keys
+ (cdr used-keys)))
+ (filtered-props
+ (let* ((filtered-props-temp)
+ (prop-good-val)
+ (prop))
+ (dolist (p (nth 0 toolbarx-button-props) filtered-props-temp)
+ ;; property -> (car p)
+ ;; test type function -> (cadr p)
+ ;; add-function -> (cddr p)
+ (setq prop (memq (car p) button))
+ ;; if so, check if value is of correct type
+ (when prop
+ ;; if property is of add-type, them the value is a list
+ ;; (:add-value-list VAL VAL). Each VAL should be checked.
+ (if (and (cddr p) (eq :add-value-list (car (cadr prop))))
+ (let* ((add-list (list (cddr p))))
+ (dolist (val (cdr (cadr prop)))
+ (setq prop-good-val (funcall (cadr p) val))
+ (when (car prop-good-val)
+ (setq add-list (cons (cdr prop-good-val) add-list))))
+ (setq add-list (nreverse add-list))
+ (when (eq 2 (length add-list)) ; just 1 value, no
+ ; add-function
+ (setq add-list (cadr add-list)))
+ (setq filtered-props-temp (append
+ (list (car p) add-list)
+ filtered-props-temp)))
+ ;; if override-property
+ (setq prop-good-val (funcall (cadr p) (cadr prop)))
+ (when (car prop-good-val)
+ (setq filtered-props-temp (append
+ (list (car p)
+ (cdr prop-good-val))
+ filtered-props-temp))))))))
+ (insert (or (not (memq :insert filtered-props))
+ ;; (memq :insert filtered-props)
+ (eval (nth 1 (memq :insert filtered-props))))))
+ (when insert
+ (cond
+ (t
+ ;; symbol is not :new-line, therefore a normal button
+ (let* ((image (cadr (memq :image filtered-props)))
+ (image-descriptor
+ (when (memq :image filtered-props)
+ (cond
+ ((stringp image) ; string
+ (toolbarx-find-image image))
+ ((and (consp image) ; or image descriptor
+ (eq (car image) 'image))
+ image)
+ ((and (symbolp image) ; or a symbol bound to a
+ (boundp image) ; image descriptor (defined
+ ; with `defimage')g
+ (consp (eval image))
+ (eq (car (eval image)) 'image))
+ (eval image))
+ (t ; otherwise, must be a list
+ ; with 4 strings or image
+ ; descriptors
+ (apply 'vector (mapcar (lambda (img)
+ (if (stringp img)
+ (toolbarx-find-image img)
+ img))
+ image))))))
+ (command
+ (let* ((com (nth 1 (memq :command filtered-props)))
+ (app (nth 1 (memq :append-command filtered-props)))
+ (prep (nth 1 (memq :prepend-command filtered-props))))
+ (when (or com app prep)
+ (toolbarx-make-command com prep app))))
+ (help (cons (memq :help filtered-props)
+ (cadr (memq :help filtered-props))))
+ (enable (cons (memq :enable filtered-props)
+ (cadr (memq :enable filtered-props))))
+ (visible (cons (memq :visible filtered-props)
+ (cadr (memq :visible filtered-props))))
+ (button (cons (memq :button filtered-props)
+ (cadr (memq :button filtered-props))))
+ (menuitem (append
+ (list 'menu-item
+ (toolbarx-make-string-from-symbol symbol)
+ command
+ :image image-descriptor)
+ (when (car help)
+ (list :help (cdr help)))
+ (when (car enable)
+ (list :enable (cdr enable)))
+ (when (car visible)
+ (list :visible (cdr visible)))
+ (when (car button)
+ (list :button (cdr button)))))
+ (key-not-used
+ (let* ((count 0)
+ (symb symbol))
+ (while (memq symb used-keys-list)
+ (setq count (1+ count))
+ (setq symb (intern (format "%s-%d" symbol count))))
+ symb)))
+ (when (and image-descriptor command)
+ (setq used-keys-list (cons key-not-used used-keys-list))
+ (define-key-after keymap
+ (vector key-not-used) menuitem))))))
+ (when used-keys (setcdr used-keys used-keys-list))))
+
+
+(defun toolbarx-emacs-refresh-process-button-or-insert-list (switches
+ used-keys
+ keymap)
+ "Process SWITCHES, inserting buttons in `tool-bar-map'.
+If a button is actually a `:insert' clause group (if `car' is
+`:insert') and evaluation of `cdr' yields non-nil, process `cddr'
+recursively as SWITCHES. USED-KEYS is a list which `car' is
+`:used-symbols' and which `cdr' is a list of symbols that have already
+been used as keys in the keymap `tool-bar-map'."
+ (dolist (button switches)
+ (if (eq (car button) :insert)
+ (when (eval (cadr button))
+ (toolbarx-emacs-refresh-process-button-or-insert-list (cddr button)
+ used-keys
+ keymap))
+ (toolbarx-emacs-add-button button used-keys keymap))))
+
+
+
+(defun toolbarx-emacs-refresh (&optional global-flag)
+ "Refresh and redraw the toolbar in Emacs.
+If GLOBAL-FLAG is non-nil, the default value of toolbar switches
+is used and the default value of `toolbarx-map' is changed."
+ (let* ((switches (if global-flag
+ (if (default-boundp 'toolbarx-internal-button-switches)
+ (default-value 'toolbarx-internal-button-switches)
+ toolbarx-internal-button-switches)
+ toolbarx-internal-button-switches))
+ (used-keys (list :used-symbols nil))
+ (tool-bar-map-temp (make-sparse-keymap)))
+ (toolbarx-emacs-refresh-process-button-or-insert-list switches used-keys
+ tool-bar-map-temp)
+ (if global-flag
+ (setq-default tool-bar-map tool-bar-map-temp)
+ (setq tool-bar-map tool-bar-map-temp))))
+
+\f
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Third engine: display parsed buttons in XEmacs
+
+(defun toolbarx-xemacs-image-properties (image)
+ "Return a list of properties of IMAGE.
+IMAGE should be a string or a list of one to six strings or
+glyphs or nil, or a symbol bound to a list of one to six
+glyphs (them must be a valid image list, like one created with
+the function `toolbar-make-button-list'). Return a
+list (GLYPH-LIST HEIGHT WIDTH) where HEIGHT (resp. WIDTH) is the
+maximum of the heights (resp. widths) of all glyphs (or strings
+converted to glyphs) in GLYPH-LIST. If IMAGE is not a list, it
+is treated as a list with IMAGE as only element. Strings are
+converted to glyphs with the function `toolbarx-find-image'. If,
+after possible string-to-glyph convertions, the list of glyphs
+has nil as first element, GLYPH-LIST becomes nil."
+ (let* ((glyph-list
+ (if (symbolp image) ; if symbol, them must be a
+ ; valid image list, like
+ ; created by function
+ ; `toolbar-make-button-list'
+ (eval image)
+ (let ((img-list (if (listp image)
+ image
+ (list image)))
+ (glyph-list-temp))
+ ;; glyph-list-temp
+ (setq glyph-list-temp
+ (dolist (glyph img-list (nreverse glyph-list-temp))
+ (if (stringp glyph)
+ (setq glyph-list-temp
+ (cons (toolbarx-find-image glyph)
+ glyph-list-temp))
+ (setq glyph-list-temp (cons glyph glyph-list-temp)))))
+ (unless (car glyph-list-temp)
+ (setq glyph-list-temp nil))
+ glyph-list-temp)))
+ (usable-buttons
+ ;; computing inheritage
+ (let* ((usable-temp))
+ (if toolbar-captioned-p ; problematic point :-(
+ (progn
+ ;; CAP-UP: cap-up -> up
+ (setq usable-temp (cons (cond
+ ((nth 3 glyph-list))
+ ((nth 0 glyph-list)))
+ usable-temp))
+ ;; CAP-DOWN: cap-down -> cap-up -> down -> up
+ (setq usable-temp (cons (cond
+ ((nth 4 glyph-list))
+ ((nth 3 glyph-list))
+ ((nth 1 glyph-list))
+ ((nth 0 glyph-list)))
+ usable-temp))
+ ;; CAP-DISABLED: cap-disabled -> cap-up -> disabled -> up
+ (setq usable-temp (cons (cond
+ ((nth 5 glyph-list))
+ ((nth 3 glyph-list))
+ ((nth 2 glyph-list))
+ ((nth 0 glyph-list)))
+ usable-temp)))
+ ;; UP: up
+ (setq usable-temp (cons (nth 0 glyph-list) usable-temp))
+ ;; DOWN: down -> up
+ (setq usable-temp (cons (cond
+ ((nth 1 glyph-list))
+ ((nth 0 glyph-list)))
+ usable-temp))
+ ;; DISABLED: disabled -> up
+ (setq usable-temp (cons (cond
+ ((nth 2 glyph-list))
+ ((nth 0 glyph-list)))
+ usable-temp)))
+ usable-temp))
+ (height (apply 'max 0 (mapcar (lambda (glyph)
+ (if glyph
+ (glyph-height glyph)
+ 0))
+ usable-buttons)))
+ (width (apply 'max 0 (mapcar (lambda (glyph)
+ (if glyph
+ (glyph-width glyph)
+ 0))
+ usable-buttons))))
+ (list (if (symbolp image) image glyph-list) height width)))
+
+
+
+(defun toolbarx-xemacs-button-properties (button)
+ "Return a list of properties of BUTTON.
+The result is either nil (if not to be inserted) or a list in the format
+ (TOOLBAR HEIGHT WIDTH BUTTON-DESCRIPTION)
+where
+
+TOOLBAR is one of the symbols `default', `top', `right', `bottom'
+ or `left'.
+
+HEIGHT and WIDTH are the maximal dimentions of all the glyphs
+ involved.
+
+BUTTON-DESCRIPTION is button definition in XEmacs; see the
+ documentation of variable `default-toolbar'."
+ (let* ((filtered-props
+ (let* ((filtered-props-temp)
+ (prop-good-val)
+ (prop))
+ (dolist (p (nth 0 toolbarx-button-props) filtered-props-temp)
+ ;; property -> (car p)
+ ;; test type function -> (cadr p)
+ ;; add-function -> (cddr p)
+ (setq prop (memq (car p) button))
+ ;; if so, check if value is of correct type
+ (when prop
+ ;; if property is of add-type, them the value is a list
+ ;; (:add-value-list VAL VAL). Each VAL should be checked.
+ (if (and (cddr p) (eq :add-value-list (car (cadr prop))))
+ (let* ((add-list (list (cddr p))))
+ (dolist (val (cdr (cadr prop)))
+ (setq prop-good-val (funcall (cadr p) val))
+ (when (car prop-good-val)
+ (setq add-list (cons (cdr prop-good-val) add-list))))
+ (setq add-list (nreverse add-list))
+ (when (eq 2 (length add-list)) ; just 1 value, no
+ ; add-function
+ (setq add-list (cadr add-list)))
+ (setq filtered-props-temp (append
+ (list (car p) add-list)
+ filtered-props-temp)))
+ ;; if override-property
+ (setq prop-good-val (funcall (cadr p) (cadr prop)))
+ (when (car prop-good-val)
+ (setq filtered-props-temp (append
+ (list (car p)
+ (cdr prop-good-val))
+ filtered-props-temp))))))))
+ (insert (or (not (memq :insert filtered-props))
+ ;; (memq :insert filtered-props) holds
+ (eval (nth 1 (memq :insert filtered-props))))))
+ (when insert
+ (let* ((image-props (toolbarx-xemacs-image-properties
+ (cadr (memq :image filtered-props))))
+ (glyph-list (car image-props))
+ (image-height (nth 1 image-props))
+ (image-width (nth 2 image-props))
+ (command
+ (let* ((com (nth 1 (memq :command filtered-props)))
+ (app (nth 1 (memq :append-command filtered-props)))
+ (prep (nth 1 (memq :prepend-command filtered-props))))
+ (when (or com app prep)
+ (toolbarx-make-command com prep app))))
+ ;; enable defaults to `t'
+ (enable (if (memq :enable filtered-props)
+ (cadr (memq :enable filtered-props))
+ t))
+ ;; help defaults to nil
+ (help (when (memq :help filtered-props)
+ (cadr (memq :help filtered-props))))
+ ;; toolbar defaults to `default'
+ (toolbar-prop (cons (memq :toolbar filtered-props)
+ (cadr (memq :toolbar filtered-props))))
+ (toolbar (if (car toolbar-prop)
+ (if (symbolp (cdr toolbar-prop))
+ (cdr toolbar-prop)
+ ;; (cdr toolbar-prop) is cons cell
+ (if (eq (cadr toolbar-prop)
+ (default-toolbar-position))
+ (cddr toolbar-prop)
+ (cadr toolbar-prop)))
+ 'default)))
+ (when glyph-list
+ (list toolbar image-height image-width
+ (vector glyph-list command enable help)))))))
+
+(defun toolbarx-xemacs-refresh-process-button-or-insert-list (switches
+ toolbar-props)
+ "Process SWITCHES, returning an updated version of TOOLBAR-PROPS.
+TOOLBAR-PROPS should be a list with 12 elements, each one representing
+properties (in this order) `locale', `default', `top', `right',
+`bottom', `left', `default-height', `default-width', `top-height',
+`right-width', `bottom-height' and `left-width'. The return is a list
+with the same properties updated.
+
+NB: Buttons (vectors) are inserted in front of the lists
+represented by `default', `top', `right', `bottom' and `left', so
+the lists are built reversed."
+ (let ((locale (nth 0 toolbar-props))
+ (default (nth 1 toolbar-props))
+ (top (nth 2 toolbar-props))
+ (right (nth 3 toolbar-props))
+ (bottom (nth 4 toolbar-props))
+ (left (nth 5 toolbar-props))
+ (default-height (nth 6 toolbar-props))
+ (default-width (nth 7 toolbar-props))
+ (top-height (nth 8 toolbar-props))
+ (right-width (nth 9 toolbar-props))
+ (bottom-height (nth 10 toolbar-props))
+ (left-width (nth 11 toolbar-props))
+ (toolbar-props-temp))
+ (dolist (button switches)
+ (if (eq (car button) :insert)
+ (when (eval (cadr button))
+ ;; if insert group, process `cddr'
+ (progn
+ (setq toolbar-props-temp
+ (toolbarx-xemacs-refresh-process-button-or-insert-list
+ (cddr button)
+ (list locale default top right bottom left
+ default-height default-width top-height
+ right-width bottom-height left-width)))
+ (setq default (nth 1 toolbar-props-temp))
+ (setq top (nth 2 toolbar-props-temp))
+ (setq right (nth 3 toolbar-props-temp))
+ (setq bottom (nth 4 toolbar-props-temp))
+ (setq left (nth 5 toolbar-props-temp))
+ (setq default-height (nth 6 toolbar-props-temp))
+ (setq default-width (nth 7 toolbar-props-temp))
+ (setq top-height (nth 8 toolbar-props-temp))
+ (setq right-width (nth 9 toolbar-props-temp))
+ (setq bottom-height (nth 10 toolbar-props-temp))
+ (setq left-width (nth 11 toolbar-props-temp))))
+ ;; else, if normal button
+ (let* ((button-props (toolbarx-xemacs-button-properties button))
+ (toolbar (nth 0 button-props))
+ (height (nth 1 button-props))
+ (width (nth 2 button-props))
+ (button-description (nth 3 button-props)))
+ (when button-props
+ (cond
+ ;; default
+ ((eq toolbar 'default)
+ (setq default (cons button-description default))
+ (setq default-height (max default-height height))
+ (setq default-width (max default-width width)))
+ ;; top
+ ((eq toolbar 'top)
+ (setq top (cons button-description top))
+ (setq top-height (max top-height height)))
+ ;; right
+ ((eq toolbar 'right)
+ (setq right (cons button-description right))
+ (setq right-width (max right-width width)))
+ ;; bottom
+ ((eq toolbar 'bottom)
+ (setq bottom (cons button-description bottom))
+ (setq bottom-height (max bottom-height height)))
+ ;; left
+ ((eq toolbar 'left)
+ (setq left (cons button-description left))
+ (setq left-width (max left-width width))))))))
+ ;; return a list similar to toolbar-props
+ (list locale default top right bottom left default-height
+ default-width top-height right-width bottom-height left-width)))
+
+
+(defun toolbarx-xemacs-refresh (&optional global-flag)
+ "Refresh the toolbar in XEmacs."
+ (let* ((switches (if global-flag
+ (if (default-boundp 'toolbarx-internal-button-switches)
+ (default-value 'toolbarx-internal-button-switches)
+ toolbarx-internal-button-switches)
+ toolbarx-internal-button-switches))
+ (locale (if global-flag 'global (current-buffer)))
+ (toolbar-init (list locale ; locale
+ nil ; default
+ nil ; top
+ nil ; right
+ nil ; bottom
+ nil ; left
+ 0 ; default-height
+ 0 ; default-width
+ 0 ; top-height
+ 0 ; right-width
+ 0 ; bottom-height
+ 0)) ; left-width
+ (toolbar-props
+ (toolbarx-xemacs-refresh-process-button-or-insert-list switches
+ toolbar-init))
+ ;; NB: Buttons (vectors) are inserted in front of the lists
+ ;; represented by `default', `top', `right', `bottom' and
+ ;; `left', so the lists are built reversed.
+ (default (nreverse (nth 1 toolbar-props)))
+ (top (nreverse (nth 2 toolbar-props)))
+ (right (nreverse (nth 3 toolbar-props)))
+ (bottom (nreverse (nth 4 toolbar-props)))
+ (left (nreverse (nth 5 toolbar-props)))
+ (default-height (nth 6 toolbar-props))
+ (default-width (nth 7 toolbar-props))
+ (top-height (nth 8 toolbar-props))
+ (right-width (nth 9 toolbar-props))
+ (bottom-height (nth 10 toolbar-props))
+ (left-width (nth 11 toolbar-props))
+ (button-raised-border 2)
+ (default-border (specifier-instance default-toolbar-border-width))
+ (top-border (specifier-instance top-toolbar-border-width))
+ (right-border (specifier-instance right-toolbar-border-width))
+ (bottom-border (specifier-instance bottom-toolbar-border-width))
+ (left-border (specifier-instance left-toolbar-border-width)))
+ ;; adding borders
+ (when default
+ (setq default-height (+ (* 2 button-raised-border)
+ (* 2 default-border)
+ default-height))
+ (setq default-width (+ (* 2 button-raised-border)
+ (* 2 default-border)
+ default-width)))
+ (when top
+ (setq top-height (+ (* 2 button-raised-border)
+ (* 2 top-border)
+ top-height)))
+ (when right
+ (setq right-width (+ (* 2 button-raised-border)
+ (* 2 right-border)
+ right-width)))
+ (when bottom
+ (setq bottom-height (+ (* 2 button-raised-border)
+ (* 2 bottom-border)
+ bottom-height)))
+ (when left
+ (setq left-width (+ (* 2 button-raised-border)
+ (* 2 left-border)
+ left-width)))
+ ;; deal with specifiers
+ ;; - remove all specifiers for toolbars witout buttons
+ (if default
+ (progn
+ ;; Only activate the tool bar if it is already visible.
+ (when toolbar-visible-p
+ (set-specifier default-toolbar-visible-p (not (not default)) locale)
+ (if (memq (default-toolbar-position) '(top bottom))
+ (set-specifier default-toolbar-height default-height locale)
+ (set-specifier default-toolbar-width default-width locale)))
+ (set-specifier default-toolbar default locale))
+ (remove-specifier default-toolbar locale)
+ (remove-specifier default-toolbar-visible-p locale)
+ (remove-specifier default-toolbar-height locale)
+ (remove-specifier default-toolbar-width locale))
+ (if top
+ (progn
+ (set-specifier top-toolbar-visible-p (not (not top)) locale)
+ (set-specifier top-toolbar-height top-height locale)
+ (set-specifier top-toolbar top locale))
+ (remove-specifier top-toolbar locale)
+ (remove-specifier top-toolbar-visible-p locale)
+ (remove-specifier top-toolbar-height locale))
+ (if right
+ (progn
+ (set-specifier right-toolbar-visible-p (not (not right))
+ locale)
+ (set-specifier right-toolbar-width right-width locale)
+ (set-specifier right-toolbar right locale))
+ (remove-specifier right-toolbar locale)
+ (remove-specifier right-toolbar-visible-p locale)
+ (remove-specifier right-toolbar-width locale))
+ (if bottom
+ (progn
+ (set-specifier bottom-toolbar-visible-p (not (not bottom)) locale)
+ (set-specifier bottom-toolbar-height bottom-height locale)
+ (set-specifier bottom-toolbar bottom locale))
+ (remove-specifier bottom-toolbar locale)
+ (remove-specifier bottom-toolbar-visible-p locale)
+ (remove-specifier bottom-toolbar-height locale))
+ (if left
+ (progn
+ (set-specifier left-toolbar-visible-p (not (not left)) locale)
+ (set-specifier left-toolbar-width left-width locale)
+ (set-specifier left-toolbar left locale))
+ (remove-specifier left-toolbar locale)
+ (remove-specifier left-toolbar-visible-p locale)
+ (remove-specifier left-toolbar-width locale))))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; finishing parsing engine
+
+(defun toolbarx-refresh (&optional global-flag)
+ "Redraw the toolbar, peviously installed with `toolbarx'.
+Force global refresh if GLOBAL-FLAG is non-nil."
+ (interactive "P")
+ (if (featurep 'xemacs)
+ (toolbarx-xemacs-refresh global-flag)
+ (toolbarx-emacs-refresh global-flag)))
+
+;;;###autoload (autoload 'toolbarx-install-toolbar "toolbar-x")
+
+(defun toolbarx-install-toolbar (buttons &optional meaning-alist global-flag)
+ "Install toolbar buttons given in BUTTONS.
+Button properties are optionally given in MEANING-ALIST. If
+GLOBAL-FLAG is non-nil, toolbar is installed globally (on every
+buffer that does not have a toolbar set locally). BUTTONS is a
+list of format
+ (ELEM ... ELEM . PROPS),
+where each ELEM is either
+
+ - a list in the same format od BUTTONS, which is going to be
+ refered as a *group*; groups are used to distribute properties
+ recursively to its elements; there are groups with special
+ format for special purpose: *dropdown groups* and also *eval
+ groups*.
+
+ - a symbol, which could be associated in MEANING-ALIST with a
+ list of button properties (symbol + properties = a *button*)
+ or associated to a special kind of group (an *alias group*).
+
+ - a vector, which elements are on the previous formats (but not
+ another vector); this is useful to specify different
+ ingredients to the toolbar depending if editor is Emacs or
+ XEmacs; the first element will be used in Emacs; the second
+ element is going to be used in XEmacs.
+
+Meaning alist
+=============
+
+MEANING-ALIST is a list where each element is in one of the
+formats (SYMB . BUTTON-PROPS-LIST) or (SYMB . ALIAS-GROUP).
+BUTTON-PROPS-LIST is a list in one of the formats
+ (IMAGE COMMAND PROP VAL PROP VAL ... PROP VAL) or
+ (PROP VAL PROP VAL ... PROP VAL).
+The IMAGE is going to be used as the `:image' property of the
+button (see button properties bellow), and COMMAND shall be used
+as the `:command' property of the button. Each PROP is one of
+the button properties, and VAL is its respective value.
+ALIAS-GROUP is a list which first element is the symbol `:alias'
+and the cdr shall be processed as a group.
+
+However, a symbol is not required to have an association in
+MEANING-ALIST, which is only a way to specify properties to a
+button. One can use groups to specify properties. Nil is a good
+MEANING-ALIST.
+
+Buttons
+=======
+
+A toolbar button in `toolbarx' is the set with a symbol and
+properties used to display the button, like a image and a command
+to call when the button is pressed (which are the minimal
+elements that a button should have.) The supported properties
+for buttons and their `basic types' (see note on how values of
+properties are obtained!) are:
+
+ :image -- in Emacs, either a string or image descriptor (see
+ info for a definition), or a variable bound to a image
+ descriptor (like those defined with `defimage') or a list of 4
+ strings or image descriptors; in XEmacs, either a string or a
+ glyph, or a symbol bount to a glyph, or a list of at least 1
+ and at most 6 strings or glyphs or nil (not the first element
+ though); defines the image file displayed by the button. If
+ it is a string, the image file found with that name (always
+ using the function `toolbarx-find-image' to make the
+ \`internal\' image descriptor) is used as button image. For
+ the other formats, the button image is handled in the same way
+ as it is treated by the editors; see info nodes bellow for a
+ description of the capabilities of each editor
+ Emacs: info file \"elisp\", node \"Tool Bar\" (see `:image'
+ property);
+ PS: a *vector* of four strings is used in the Emacs
+ Lisp documentation as the `more ellaborated' image
+ property format, but here we reserve vectors to
+ provide editor-dependent values; this motivates our
+ choice for a list instead of vector (however,
+ internally the list becomes a vector when displaying
+ the button).
+ XEmacs: info file \"lispref\", node \"Toolbar Descriptor
+ Format\" (see GLYPH-LIST) or the documentation of
+ the variable `default-toolbar'; check the inheritage
+ in case of a ommited glyph or nil instead of glyph.
+
+ :command -- a form; if the form happens to be a command, it will
+ be called with `call-interactively'.
+
+ :append-command -- a form added to the end of the value of
+ `:command'.
+
+ :prepend-command -- a form added at the beginning of the value
+ of `:command'.
+
+ :help -- either a string or nil; defined the help string of the
+ button;
+
+ :enable -- a form, evaluated constantly by both editors to
+ determine if a button is active (enabled) or not.
+
+ :visible -- in Emacs, a form that is evaluated constantly to
+ determine if a button is visible; in XEmacs, this property is
+ ignored.
+
+ :button -- in Emacs, a cons cell (TYPE . SELECTED) where the
+ TYPE should be `:toggle' or `:radio' and the cdr should be a
+ form. SELECTED is evaluated to determine when the button is
+ selected. This property is ignored in XEmacs.
+
+ :insert -- a form that is evaluated every time that the toolbar
+ is refresh (a call of `toolbarx-refresh') to determine if the
+ button is inserted or just ignored (until next refresh).
+
+ :toolbar -- in XEmacs, either one of the symbols `default',
+ `top', `bottom', `left', `right', or a cons cell
+ (POS . POS-AVOID-DEFAULT) where POS and POS-AVOID-DEFAULT
+ should be one of the symbols `top', `bottom', `left', `right';
+ if a symbol, the button will be inserted in one of these
+ toolbars; if a cons cell, button will be inserted in toolbar
+ POS unless the position of the default toolbar is POS (then,
+ the default toolbar would override the position-specific
+ toolbar), and in this case, button will be inserted in toolbar
+ POS-AVOID-DEFAULT; in Emacs, this property is meaningless, and
+ therefore ignored. Hint of use of this property: in a
+ program, use or everything with `default' and the cons format
+ to avoid the default toolbar, or use only the position
+ specific buttons (symbols that are not `default'), because of
+ the `overriding' system in XEmacs, when a position-specific
+ toolbar overrides the default toolbar; for instance, if you
+ put a button in the default toolbar and another in the top
+ toolbar (and the default toolbar is in the top), then *only*
+ the ones in the top toolbar will be visible!
+
+How to specify a button
+=======================
+
+One can specify a button by its symbol or by a group to specify
+properties. For example,
+ BUTTON =
+ ( foo
+ (bar :image [\"bar-Emacs\" \"bar-XEmacs\"]
+ :command bar-function :help \"Bar help string\")
+ :insert foo-bar )
+ MEANING-ALIST = ( (foo :image \"foo\" :command foo-function) )
+specifiy two buttons `foo' and `bar', each one with its necessary
+:image and :command properties, and both use the :insert property
+specified ate the end of BUTTONS (because groups distribute
+properties to all its elements). `foo' and `bar' will be
+inserted only if `foo-bar' evaluation yields non-nil. `bar' used
+a different :image property depending if editor is Emacs or
+XEmacs.
+
+Note on how values of properties are obtained
+=============================================
+
+For each property PROP, its value should be either:
+ i) a vector of 2 elements; then each element should be of the
+ basic type of PROP.
+ ii) an element on the basic type of PROP.
+ iii) a function (that does not need arguments); it is evaluated
+ and the return should be ot type i) or ii) above
+ iv) a symbol bound to a element of type i) or ii).
+
+The type is cheched in the order i), ii) iii) and iv). This
+evaluations are done every time that the oolbar is refresh.
+
+Ps.: in order to specify a vector as value of a property (like
+the :image in Emacs), it is necessary to provide the vector as
+element of another vector.
+
+Special groups
+==============
+
+Eval groups
+-----------
+
+If the first element of a group is the symbol `:eval-group', each
+element is evaluated (with `eval'), put inside a list and
+processed like a group. Eval groups are useful to store
+definition of buttons in a variable.
+
+Dropdown groups
+---------------
+
+The idea is to specify a set of buttons that appear when a
+determined menu item of a dropdown menu is active. The dropdown
+menu appears when a button (by default with a triangle pointing
+down) is clicked. This button is called `dropdown button'. The
+dropdown button appears on the left of the currently visible
+buttons of the dropdown group.
+
+A dropdown group is a list which first element is the symbol
+`:dropdown-group' and in one of the following formats
+ (:dropdown-group SYMBOL-1 ... SYMBOL-n PROP-1 VAL-1 ... PROP-k VAL-k)
+or
+ (:dropdown-group
+ STRING-1 ITEM-11 ... ITEM-1n
+ STRING-2 ITEM-21 ... ITEM-2m
+ . . .
+ STRING-n ITEM-n1 ... ITEM-np
+ PROP-1 VAL-1 ... PROP-j VAL-j)
+where
+ SYMBOL-* is a symbol that defines a button in MEANING-ALIST;
+ STRING-* is a string that will appear in the dropdown menu;
+ ITEM-* is any format that define buttons or groups.
+
+\(a dropdown group of first format is internally converted to the
+second by making strings from the symbols and each symbol is the
+item)
+
+The same rules for obtaining property values, described above,
+apply here. Properties are also distributed by groups. The
+supported properties and their basic type are:
+
+ :type -- one of the symbols `radio' (default) or `toggle'; if
+ type is radio, only one of the itens may be active, and if
+ type is toggle, any item number of itens can be active.
+
+ :variable -- a symbol; it is the variable that govern the
+ dropdown button; every time the value should be an integer
+ starting from 1 (if type is radio) or a list of integers (if
+ type is toggle). The Nth set of buttons is :insert'ed.
+
+ :default -- determines the default value when the menu is
+ installed; it is ignored if a value was saved with custom; it
+ defaults to 1 if type is radio or nil if type is toggle. If
+ value is a integer and type is `toggle', value used is a list
+ with that integer.
+
+ :save -- one of the symbols nil (default), `offer' or
+ `always'; determined if it is possible for the user to save
+ the which menu itens are active, for a next session. If value
+ is `offer', a item (offering to save) is added to the
+ popup menu. If the value is `always', every time that a item
+ is selected, the variable is saved. If value is nil, variable
+ shall not be saved. If value is non-nil then `:variable' is
+ mandatory.
+
+ :title -- a string or nil; if a string, the popup menu will show
+ is as menu title; if nil, no title is shown.
+
+ :dropdown-help -- a string or nil; the help string of the
+ dropdown button.
+
+ :dropdown-image -- in Emacs, either a string or a vector of 4
+ strings; in XEmacs, either a string or a glyph or a list of at
+ least 1 and at most 6 strings or glyphs; defines the image
+ file displayed by the dropdown button; by default, it is the
+ string \"dropdown\".
+
+ :dropdown-append-command,
+ :dropdownprepend-command -- a form; append or prepend forms to
+ the command that shows the dropdown menu, allowing extra code
+ to run before or after the menu appears (remember that every
+ menu item clicked refresh the toolbar.)
+
+ :dropdown-enable -- a form; evaluated constantly by both editors
+ to determine if the dropdown button is active (enabled) or
+ not.
+
+ :dropdown-visible -- a form; in Emacs, it is evaluated
+ constantly to determine if the dropdown button is visible; in
+ XEmacs, this property is ignored.
+
+ :dropdown-toolbar -- in XEmacs, one of the symbols `default',
+ `opposite', `top', `bottom', `left' or `right'; ignored in
+ Emacs; in XEmacs, the toolbar where the dropdown button will
+ appear.
+
+Also, if the symbol `dropdown' is associted in MEANING-ALIST
+with some properties, these properties override (or add) with
+higher precedence.
+
+Special buttons
+===============
+
+If the symbol of a button is `:new-line', it is inserted
+a (faked) return, and the next button will be displayed a next
+line of buttons. The only property supported for this button is
+`:insert'. This feature is available only in Emacs. In XEmacs,
+this button is ignored."
+ (let ((switches (toolbarx-process-group buttons meaning-alist nil nil)))
+ (if global-flag
+ (setq-default toolbarx-internal-button-switches
+ switches)
+ (set (make-local-variable 'toolbarx-internal-button-switches)
+ switches)
+ (unless (featurep 'xemacs)
+ (make-local-variable 'tool-bar-map))))
+ (toolbarx-refresh global-flag))
+
+
+(defconst toolbarx-default-toolbar-meaning-alist
+ `((separator :image "sep" :command t :enable nil :help "")
+
+ (,(if (and (not (featurep 'xemacs)) (>= emacs-major-version 22))
+ 'new-file
+ 'open-file)
+ :image ["new" toolbar-file-icon]
+ :command [find-file toolbar-open]
+ :enable [(not (window-minibuffer-p
+ (frame-selected-window menu-updating-frame)))
+ t]
+ :help ["Specify a new file's name, to edit the file" "Visit new file"])
+
+ ,(when (and (not (featurep 'xemacs)) (>= emacs-major-version 22))
+ '(open-file :image ["open" toolbar-file-icon]
+ :command [menu-find-file-existing toolbar-open]
+ :enable [(not (window-minibuffer-p
+ (frame-selected-window menu-updating-frame)))
+ t]
+ :help ["Read a file into an Emacs buffer" "Open a file"]))
+
+ (dired :image [,(if (>= emacs-major-version 22)
+ "diropen"
+ "open")
+ toolbar-folder-icon]
+ :command [dired toolbar-dired]
+ :help ["Read a directory, operate on its files" "Edit a directory"])
+
+ (save-buffer :image ["save" toolbar-disk-icon]
+ :command [save-buffer toolbar-save]
+ :enable [(and
+ (buffer-modified-p)
+ (buffer-file-name)
+ (not (window-minibuffer-p
+ (frame-selected-window menu-updating-frame))))
+ t]
+ :help ["Save current buffer to its file" "Save buffer"]
+ :visible (or buffer-file-name
+ (not (eq 'special
+ (get major-mode 'mode-class)))))
+
+ ;; Emacs only
+ (write-file :image "saveas"
+ :command write-file
+ :enable (not
+ (window-minibuffer-p
+ (frame-selected-window menu-updating-frame)))
+ :insert [t nil]
+ :help "Write current buffer to another file"
+ :visible (or buffer-file-name
+ (not (eq 'special (get major-mode 'mode-class)))))
+
+ (undo :image ["undo" toolbar-undo-icon]
+ :command [undo toolbar-undo]
+ :enable [(and (not buffer-read-only)
+ (not (eq t buffer-undo-list))
+ (if (eq last-command 'undo)
+ pending-undo-list
+ (consp buffer-undo-list)))
+ t]
+ :help ["Undo last operation" "Undo edit"]
+ :visible (not (eq 'special (get major-mode 'mode-class))))
+
+ (cut :image ["cut" toolbar-cut-icon]
+ :help ["Delete text in region and copy it to the clipboard"
+ "Kill region"]
+ :command [clipboard-kill-region toolbar-cut]
+ :visible (not (eq 'special (get major-mode 'mode-class))))
+
+ (copy :image ["copy" toolbar-copy-icon]
+ :help ["Copy text in region to the clipboard" "Copy region"]
+ :command [clipboard-kill-ring-save toolbar-copy])
+
+ (paste :image ["paste" toolbar-paste-icon]
+ :help ["Paste text from clipboard" "Paste from clipboard"]
+ :command [clipboard-yank toolbar-paste]
+ :visible (not (eq 'special (get major-mode 'mode-class))))
+
+ ;; Emacs only
+ (search-forward :command nonincremental-search-forward
+ :help "Search forward for a string"
+ :image "search"
+ :insert [t nil])
+
+ (search-replace
+ :image ["search-replace" toolbar-replace-icon]
+ :command [query-replace toolbar-replace]
+ :help ["Replace string interactively, ask about each occurrence"
+ "Search & Replace"])
+
+ (print-buffer :image ["print" toolbar-printer-icon]
+ :command [print-buffer toolbar-print]
+ :help ["Print current buffer with page headings"
+ "Print buffer"])
+
+ ;; Emacs only
+ (customize :image "preferences"
+ :command customize
+ :help "Edit preferences (customize)"
+ :insert [t nil])
+
+ ;; Emacs only
+ (help :image "help"
+ :command (lambda () (interactive) (popup-menu menu-bar-help-menu))
+ :help "Pop up the Help menu"
+ :insert [t nil])
+
+ ;; Emacs only
+ (kill-buffer :command kill-this-buffer
+ :enable (kill-this-buffer-enabled-p)
+ :help "Discard current buffer"
+ :image "close"
+ :insert [t nil])
+
+ ;; Emacs only
+ (exit-emacs :image "exit"
+ :command save-buffers-kill-emacs
+ :help "Offer to save unsaved buffers, then exit Emacs"
+ :insert [t nil])
+
+ (spell-buffer :image ["spell" toolbar-spell-icon]
+ :command [ispell-buffer toolbar-ispell]
+ :help ["Check spelling of selected buffer" "Check spelling"])
+
+ (info :image ["info" toolbar-info-icon]
+ :command [info toolbar-info]
+ :help ["Enter Info, the documentation browser" "Info documentation"])
+
+ ;; XEmacs only
+ (mail :image toolbar-mail-icon
+ :command toolbar-mail
+ :help "Read mail"
+ :insert [nil t])
+
+ ;; XEmacs only
+ (compile :image toolbar-compile-icon
+ :command toolbar-compile
+ :help "Start a compilation"
+ :insert [nil t])
+
+ ;; XEmacs only
+ (debug :image toolbar-debug-icon
+ :command toolbar-debug
+ :help "Start a debugger"
+ :insert [nil t])
+
+ ;; XEmacs only
+ (news :image toolbar-news-icon
+ :command toolbar-news
+ :help "Read news"
+ :insert [nil t]))
+ "A meaning alist with definition of the default buttons.
+The following buttons are available:
+
+* Both Emacs and XEmacs: `open-file', `dired', `save-buffer',
+ `undo', `cut', `copy', `paste', `search-replace', `print-buffer',
+ `spell-buffer', `info'.
+
+* Emacs only: `new-file' (Emacs 22+) `write-file', `search-forward',
+ `customize', `help', `kill-buffer', `exit-emacs'.
+
+* XEmacs only: `mail', `compile', `debug', `news'.
+
+To reproduce the default toolbar in both editors with use as BUTTON
+in `toolbarx-install-toolbar':
+
+\(toolbarx-install-toolbar
+ '([(open-file dired kill-buffer save-buffer write-file undo cut
+ copy paste search-forward print-buffer customize help)
+ (open-file dired save-buffer print-buffer cut copy paste undo
+ spell-buffer search-replace mail info compile debug news)])
+ toolbarx-default-toolbar-meaning-alist)
+
+Ps.: there are more buttons available than suggested in the
+expression above.")
+
+(provide 'toolbar-x)
+
+;;; toolbar-x.el ends here
--- /dev/null
+This is the README file for the AUCTeX distribution.
+
+ Copyright (C) 2008 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without
+ modification, are permitted in any medium without royalty provided
+ the copyright notice and this notice are preserved.
+
+Introduction to AUCTeX
+**********************
+
+This file gives a brief overview of what AUCTeX is. It is *not* an
+attempt to document AUCTeX. Real documentation for AUCTeX is available
+in the manual, which should be available as an info file after
+installation.
+
+AUCTeX is a comprehensive customizable integrated environment for
+writing input files for TeX, LaTeX, ConTeXt, Texinfo, and docTeX using
+Emacs or XEmacs.
+
+It supports you in the insertion of macros, environments, and sectioning
+commands by providing completion alternatives and prompting for
+parameters. It automatically indents your text as you type it and lets
+you format a whole file at once. The outlining and folding facilities
+provide you with a focused and clean view of your text.
+
+AUCTeX lets you process your source files by running TeX and related
+tools (such as output filters, post processors for generating indices
+and bibliographies, and viewers) from inside Emacs. AUCTeX lets you
+browse through the errors TeX reported, while it moves the cursor
+directly to the reported error, and displays some documentation for
+that particular error. This will even work when the document is spread
+over several files.
+
+One component of AUCTeX that LaTeX users will find attractive is
+preview-latex, a combination of folding and in-source previewing that
+provides true "What You See Is What You Get" experience in your
+sourcebuffer, while letting you retain full control. For more
+information, see further below.
+
+More detailed information about the features and usage of AUCTeX can be
+found in the AUCTeX manual. You can access it from within Emacs by
+typing `C-h i d m auctex <RET>'. If you prefer the standalone info
+reader, issue the command `info auctex' in a terminal.
+
+AUCTeX is written entirely in Emacs Lisp, and hence you can easily add
+new features for your own needs. It is a GNU project and distributed
+under the `GNU General Public License Version 3'.
+
+The most recent version is always available at
+`http://ftp.gnu.org/pub/gnu/auctex/'.
+
+WWW users may want to check out the AUCTeX page at
+`http://www.gnu.org/software/auctex/'.
+
+For comprehensive information about how to install AUCTeX read the file
+`INSTALL' or `INSTALL.windows', respectively.
+
+If you are considering upgrading AUCTeX, the recent changes are
+described in the `CHANGES' file.
+
+If you want to discuss AUCTeX with other users or its developers, there
+are several mailing lists you can use.
+
+Send a mail with the subject "subscribe" to <auctex-request@gnu.org> in
+order to join the general discussion list for AUCTeX. Articles should
+be sent to <auctex@gnu.org>. In a similar way, you can subscribe to
+the <info-auctex@gnu.org> list for just getting important announcements
+about AUCTeX. The list <bug-auctex@gnu.org> is for bug reports which
+you should usually file with the `M-x TeX-submit-bug-report <RET>'
+command. If you want to address the developers of AUCTeX themselves
+with technical issues, they can be found on the discussion list
+<auctex-devel@gnu.org>.
+
+preview-latex in a nutshell
+***************************
+
+Does your neck hurt from turning between previewer windows and the
+source too often? This AUCTeX component will render your displayed
+LaTeX equations right into the editing window where they belong.
+
+The purpose of preview-latex is to embed LaTeX environments such as
+display math or figures into the source buffers and switch conveniently
+between source and image representation.
+
+1 What use is it?
+*****************
+
+WYSIWYG (what you see is what you get) sometimes is considered all the
+rage, sometimes frowned upon. Do we really want it? Wrong question.
+The right question is _what_ we want from it. Except when finetuning
+the layout, we don't want to use printer fonts for on-screen text
+editing. The low resolution and contrast of a computer screen render
+all but the coarsest printer fonts (those for low-quality newsprint)
+unappealing, and the margins and pagination of the print are not wanted
+on the screen, either. On the other hand, more complex visual
+compositions like math formulas and tables can't easily be taken in
+when seen only in the source. preview-latex strikes a balance: it only
+uses graphic renditions of the output for certain, configurable
+constructs, does this only when told, and then right in the source code.
+Switching back and forth between the source and preview is easy and
+natural and can be done for each image independently. Behind the scenes
+of preview-latex, a sophisticated framework of other programs like
+`dvipng', Dvips and Ghostscript are employed together with a special
+LaTeX style file for extracting the material of interest in the
+background and providing fast interactive response.
+
+2 Activating preview-latex
+**************************
+
+After installation, the package may need to be activated (and remember
+to activate AUCTeX too). In XEmacs, and in any prepackaged versions
+worth their salt, activation should be automatic upon installation. If
+this seems not the case, complain to your installation provider.
+
+The usual activation (if it is not done automatically) would be
+
+ (load "preview-latex.el" nil t t)
+
+If you still don't get a "Preview" menu in LaTeX mode in spite of
+AUCTeX showing its "Command", your installation is broken. One
+possible cause are duplicate Lisp files that might be detectable with
+`<M-x> list-load-path-shadows <RET>'.
+
+3 Getting started
+*****************
+
+Once activated, preview-latex and its documentation will be accessible
+via its menus (note that preview-latex requires AUCTeX to be loaded).
+When you have loaded a LaTeX document (a sample document `circ.tex' is
+included in the distribution, but most documents including math and/or
+figures should do), you can use its menu or `C-c C-p C-d' (for
+`Preview/Document'). Previews will now be generated for various
+objects in your document. You can use the time to take a short look at
+the other menu entries and key bindings in the `Preview' menu. You'll
+see the previewed objects change into a roadworks sign when
+preview-latex has determined just what it is going to preview. Note
+that you can freely navigate the buffer while this is going on. When
+the process is finished you will see the objects typeset in your buffer.
+
+It is a bad idea, however, to edit the buffer before the roadworks signs
+appear, since that is the moment when the correlation between the
+original text and the buffer locations gets established. If the buffer
+changes before that point of time, the previews will not be placed where
+they belong. If you do want to change some obvious error you just
+spotted, we recommend you stop the background process by pressing `C-c
+C-k'.
+
+To see/edit the LaTeX code for a specific object, put the point (the
+cursor) on it and press `C-c C-p C-p' (for `Preview/at point'). It
+will also do to click with the middle mouse button on the preview. Now
+you can edit the code, and generate a new preview by again pressing
+`C-c C-p C-p' (or by clicking with the middle mouse button on the icon
+before the edited text).
+
+If you are using the `desktop' package, previews will remain from one
+session to the next as long as you don't kill your buffer. If you are
+using XEmacs, you will probably need to upgrade the package to the
+newest one; things are being fixed just as I am writing this.
+
+4 Basic modes of operation
+**************************
+
+preview-latex has a number of methods for generating its graphics. Its
+default operation is equivalent to using the `LaTeX' command from
+AUCTeX. If this happens to be a call of PDFLaTeX generating PDF output
+(you need at least AUCTeX 11.51 for this), then Ghostscript will be
+called directly on the resulting PDF file. If a DVI file gets
+produced, first Dvips and then Ghostscript get called by default.
+
+The image type to be generated by Ghostscript can be configured with
+
+ M-x customize-variable RET preview-image-type RET
+
+The default is `png' (the most efficient image type). A special
+setting is `dvipng' in case you have the `dvipng' program installed.
+In this case, `dvipng' will be used for converting DVI files and
+Ghostscript (with a `PNG' device) for converting PDF files. `dvipng'
+is much faster than the combination of Dvips and Ghostscript. You can
+get downloads, access to its CVS archive and further information from
+its project site (http://savannah.nongnu.org/projects/dvipng).
+
+5 More documentation
+********************
+
+After the installation, documentation in the form of an info manual
+will be available. You can access it with the standalone info reader
+with
+
+ info preview-latex
+
+or by pressing `C-h i d m preview-latex <RET>' in Emacs. Once
+preview-latex is activated, you can instead use `C-c C-p <TAB>' (or the
+menu entry `Preview/Read documentation').
+
+Depending on your installation, a printable manual may also be
+available in the form of `preview-latex.dvi' or `preview-latex.ps'.
+
+Detailed documentation for the LaTeX style used for extracting the
+preview images is placed in `preview.dvi' in a suitable directory
+during installation; on typical teTeX-based systems,
+
+ texdoc preview
+
+will display it.
+
+6 Availability
+**************
+
+The preview-latex project is now part of AUCTeX and accessible as part
+of the AUCTeX project page (http://savannah.gnu.org/projects/auctex).
+You can get its files from the AUCTeX download area
+(ftp://ftp.gnu.org/pub/gnu/auctex). As of AUCTeX 11.81, preview-latex
+should already be integrated into AUCTeX, so no separate download will
+be necessary.
+
+You will also find `.rpm' files there for Fedora and possibly SuSE.
+Anonymous CVS is available as well.
+
+7 Contacts
+**********
+
+Bug reports should be sent by using `M-x preview-report-bug <RET>', as
+this will fill in a lot of information interesting to us. If the
+installation fails (but this should be a rare event), report bugs to
+<bug-auctex@gnu.org>.
+
+There is a general discussion list for AUCTeX which also covers
+preview-latex, look at `http://lists.gnu.org/mailman/listinfo/auctex'.
+For more information on the mailing list, send a message with just the
+word "help" as subject or body to <auctex-request@gnu.org>. For the
+developers, there is the <auctex-devel@gnu.org> list; it would probably
+make sense to direct feature requests and questions about internal
+details there. There is a low-volume read-only announcement list
+available to which you can subscribe by sending a mail with "subscribe"
+in the subject to <info-auctex-request@gnu.org>.
+
+Offers to support further development will be appreciated. If you want
+to show your appreciation with a donation to the main developer, you can
+do so via PayPal to <dak@gnu.org>, and of course you can arrange for
+service contracts or for added functionality. Take a look at the
+`TODO' list for suggestions in that area.
+
--- /dev/null
+Company is an Emacs extension for performing text completion.
+Completion candidates are retrieved from a variety of modular
+back-ends, such as Semantic.
+
+Once installed, enable company-mode with M-x company-mode.
+For further information, see the docstring for `company-mode'.
--- /dev/null
+;;; company-abbrev.el --- a company-mode completion back-end for abbrev
+
+;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'company)
+(eval-when-compile (require 'cl))
+(require 'abbrev)
+
+(defun company-abbrev-insert (match)
+ "Replace MATCH with the expanded abbrev."
+ (expand-abbrev))
+
+;;;###autoload
+(defun company-abbrev (command &optional arg &rest ignored)
+ "A `company-mode' completion back-end for abbrev."
+ (interactive (list 'interactive))
+ (case command
+ ('interactive (company-begin-backend 'company-abbrev
+ 'company-abbrev-insert))
+ ('prefix (company-grab-symbol))
+ ('candidates (nconc
+ (delete "" (all-completions arg global-abbrev-table))
+ (delete "" (all-completions arg local-abbrev-table))))
+ ('meta (abbrev-expansion arg))
+ ('require-match t)))
+
+(provide 'company-abbrev)
+;;; company-abbrev.el ends here
--- /dev/null
+;;; company-clang.el --- a company-mode completion back-end for clang
+
+;; Copyright (C) 2009 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'company)
+(eval-when-compile (require 'cl))
+
+(defcustom company-clang-executable
+ (executable-find "clang")
+ "*Location of clang executable"
+ :group 'company-clang
+ :type 'file)
+
+(defcustom company-clang-auto-save t
+ "*Determines whether to save the buffer when retrieving completions.
+clang can only complete correctly when the buffer has been saved."
+ :group 'company-clang
+ :type '(choice (const :tag "Off" nil)
+ (const :tag "On" t)))
+
+(defcustom company-clang-arguments nil
+ "*Additional arguments to pass to clang when completing.
+Prefix files (-include ...) can be selected with
+`company-clang-set-prefix' or automatically through a custom
+`company-clang-prefix-guesser'."
+ :group 'company-clang
+ :type '(repeat (string :tag "Argument" nil)))
+
+(defcustom company-clang-prefix-guesser 'company-clang-guess-prefix
+ "*A function to determine the prefix file for the current buffer."
+ :group 'company-clang
+ :type '(function :tag "Guesser function" nil))
+
+(defvar company-clang-modes '(c-mode objc-mode)
+ "Major modes which clang may complete.")
+
+;; prefix ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar company-clang--prefix nil)
+
+(defsubst company-clang--guess-pch-file (file)
+ (let ((dir (directory-file-name (file-name-directory file))))
+ (when (equal (file-name-nondirectory dir) "Classes")
+ (setq dir (file-name-directory dir)))
+ (car (directory-files dir t "\\([^.]h\\|[^h]\\).pch\\'" t))))
+
+(defsubst company-clang--file-substring (file beg end)
+ (with-temp-buffer
+ (insert-file-contents-literally file nil beg end)
+ (buffer-string)))
+
+(defun company-clang-guess-prefix ()
+ "Try to guess the prefix file for the current buffer."
+ ;; Prefixes seem to be called .pch. Pre-compiled headers do, too.
+ ;; So we look at the magic number to rule them out.
+ (let* ((file (company-clang--guess-pch-file buffer-file-name))
+ (magic-number (company-clang--file-substring file 0 4)))
+ (unless (member magic-number '("CPCH" "gpch"))
+ file)))
+
+(defun company-clang-set-prefix (&optional prefix)
+ "Use PREFIX as a prefix (-include ...) file for clang completion."
+ (interactive (let ((def (funcall company-clang-prefix-guesser)))
+ (unless (stringp def)
+ (setq def default-directory))
+ (list (read-file-name "Prefix file: "
+ (when def (file-name-directory def))
+ def t (when def (file-name-nondirectory def))))))
+ ;; TODO: pre-compile?
+ (setq company-clang--prefix (and (stringp prefix)
+ (file-regular-p prefix)
+ prefix)))
+
+;; Clean-up on exit.
+(add-hook 'kill-emacs-hook 'company-clang-set-prefix)
+
+;; parsing ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; TODO: How to handle OVERLOAD and Pattern?
+(defconst company-clang--completion-pattern
+ "^COMPLETION: \\_<\\(%s[a-zA-Z0-9_:]*\\)")
+
+(defconst company-clang--error-buffer-name "*clang error*")
+
+(defun company-clang--parse-output (prefix)
+ (goto-char (point-min))
+ (let ((pattern (format company-clang--completion-pattern
+ (regexp-quote prefix)))
+ lines match)
+ (while (re-search-forward pattern nil t)
+ (setq match (match-string-no-properties 1))
+ (unless (equal match "Pattern")
+ (push match lines)))
+ lines))
+
+(defun company-clang--handle-error (res args)
+ (goto-char (point-min))
+ (let* ((buf (get-buffer-create company-clang--error-buffer-name))
+ (cmd (concat company-clang-executable (mapconcat 'identity args " ")))
+ (pattern (format company-clang--completion-pattern ""))
+ (err (if (re-search-forward pattern nil t)
+ (buffer-substring-no-properties (point-min)
+ (1- (match-beginning 0)))
+ ;; Warn the user more agressively if no match was found.
+ (message "clang failed with error %d:\n%s" res cmd)
+ (buffer-string))))
+
+ (with-current-buffer buf
+ (let ((inhibit-read-only t))
+ (erase-buffer)
+ (insert (current-time-string)
+ (format "\nclang failed with error %d:\n" res)
+ cmd "\n\n")
+ (insert err)
+ (setq buffer-read-only t)
+ (goto-char (point-min))))))
+
+(defun company-clang--call-process (prefix &rest args)
+ (with-temp-buffer
+ (let ((res (apply 'call-process company-clang-executable nil t nil args)))
+ (unless (eq 0 res)
+ (company-clang--handle-error res args))
+ ;; Still try to get any useful input.
+ (company-clang--parse-output prefix))))
+
+(defsubst company-clang--build-location (pos)
+ (save-excursion
+ (goto-char pos)
+ (format "%s:%d:%d" buffer-file-name (line-number-at-pos)
+ (1+ (current-column)))))
+
+(defsubst company-clang--build-complete-args (pos)
+ (append '("-cc1" "-fsyntax-only")
+ company-clang-arguments
+ (when (stringp company-clang--prefix)
+ (list "-include" (expand-file-name company-clang--prefix)))
+ '("-code-completion-at")
+ (list (company-clang--build-location pos))
+ (list buffer-file-name)))
+
+(defun company-clang--candidates (prefix)
+ (and company-clang-auto-save
+ (buffer-modified-p)
+ (basic-save-buffer))
+ (when (null company-clang--prefix)
+ (company-clang-set-prefix (or (funcall company-clang-prefix-guesser)
+ 'none)))
+ (apply 'company-clang--call-process
+ prefix
+ (company-clang--build-complete-args (- (point) (length prefix)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defconst company-clang-required-version "1.1")
+
+(defsubst company-clang-version ()
+ "Return the version of `company-clang-executable'."
+ (with-temp-buffer
+ (call-process company-clang-executable nil t nil "--version")
+ (goto-char (point-min))
+ (when (re-search-forward "\\`clang version \\([0-9.]+\\)" nil t)
+ (match-string-no-properties 1))))
+
+(defun company-clang-objc-templatify (selector)
+ (let* ((end (point))
+ (beg (- (point) (length selector)))
+ (templ (company-template-declare-template beg end)))
+ (save-excursion
+ (goto-char beg)
+ (while (search-forward ":" end t)
+ (replace-match ": ")
+ (incf end 2)
+ (company-template-add-field templ (1- (match-end 0)) "<arg>"))
+ (delete-char -1))
+ (company-template-move-to-first templ)))
+
+(defun company-clang (command &optional arg &rest ignored)
+ "A `company-mode' completion back-end for clang.
+Clang is a parser for C and ObjC. The unreleased development version of
+clang (1.1) is required.
+
+Additional command line arguments can be specified in
+`company-clang-arguments'. Prefix files (-include ...) can be selected
+with `company-clang-set-prefix' or automatically through a custom
+`company-clang-prefix-guesser'.
+
+Completions only work correctly when the buffer has been saved.
+`company-clang-auto-save' determines whether to do this automatically."
+ (interactive (list 'interactive))
+ (case command
+ ('interactive (company-begin-backend 'company-clang))
+ ('init (unless company-clang-executable
+ (error "Company found no clang executable"))
+ (when (version< (company-clang-version)
+ company-clang-required-version)
+ (error "Company requires clang version 1.1")))
+ ('prefix (and (memq major-mode company-clang-modes)
+ buffer-file-name
+ company-clang-executable
+ (not (company-in-string-or-comment))
+ (or (company-grab-symbol) 'stop)))
+ ('candidates (company-clang--candidates arg))
+ ('post-completion (and (derived-mode-p 'objc-mode)
+ (string-match ":" arg)
+ (company-clang-objc-templatify arg)))))
+
+(provide 'company-clang)
+;;; company-clang.el ends here
--- /dev/null
+;;; company-css.el --- a company-mode completion back-end for css-mode
+
+;; Copyright (C) 2009 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'company)
+(eval-when-compile (require 'cl))
+
+(defconst company-css-property-alist
+ ;; see http://www.w3.org/TR/CSS21/propidx.html
+ '(("azimuth" angle "left-side" "far-left" "left" "center-left" "center"
+ "center-right" "right" "far-right" "right-side" "behind" "leftwards"
+ "rightwards")
+ ("background" background-color background-image background-repeat
+ background-attachment background-position)
+ ("background-attachment" "scroll" "fixed")
+ ("background-color" color "transparent")
+ ("background-image" uri "none")
+ ("background-position" percentage length "left" "center" "right" percentage
+ length "top" "center" "bottom" "left" "center" "right" "top" "center"
+ "bottom")
+ ("background-repeat" "repeat" "repeat-x" "repeat-y" "no-repeat")
+ ("border" border-width border-style border-color)
+ ("border-bottom" border)
+ ("border-bottom-color" border-color)
+ ("border-bottom-style" border-style)
+ ("border-bottom-width" border-width)
+ ("border-collapse" "collapse" "separate")
+ ("border-color" color "transparent")
+ ("border-left" border)
+ ("border-left-color" border-color)
+ ("border-left-style" border-style)
+ ("border-left-width" border-width)
+ ("border-right" border)
+ ("border-right-color" border-color)
+ ("border-right-style" border-style)
+ ("border-right-width" border-width)
+ ("border-spacing" length length)
+ ("border-style" border-style)
+ ("border-top" border)
+ ("border-top-color" border-color)
+ ("border-top-style" border-style)
+ ("border-top-width" border-width)
+ ("border-width" border-width)
+ ("bottom" length percentage "auto")
+ ("caption-side" "top" "bottom")
+ ("clear" "none" "left" "right" "both")
+ ("clip" shape "auto")
+ ("color" color)
+ ("content" "normal" "none" string uri counter "attr()" "open-quote"
+ "close-quote" "no-open-quote" "no-close-quote")
+ ("counter-increment" identifier integer "none")
+ ("counter-reset" identifier integer "none")
+ ("cue" cue-before cue-after)
+ ("cue-after" uri "none")
+ ("cue-before" uri "none")
+ ("cursor" uri "*" "auto" "crosshair" "default" "pointer" "move" "e-resize"
+ "ne-resize" "nw-resize" "n-resize" "se-resize" "sw-resize" "s-resize"
+ "w-resize" "text" "wait" "help" "progress")
+ ("direction" "ltr" "rtl")
+ ("display" "inline" "block" "list-item" "run-in" "inline-block" "table"
+ "inline-table" "table-row-group" "table-header-group" "table-footer-group"
+ "table-row" "table-column-group" "table-column" "table-cell"
+ "table-caption" "none")
+ ("elevation" angle "below" "level" "above" "higher" "lower")
+ ("empty-cells" "show" "hide")
+ ("float" "left" "right" "none")
+ ("font" font-style font-variant font-weight font-size "/" line-height
+ font-family "caption" "icon" "menu" "message-box" "small-caption"
+ "status-bar")
+ ("font-family" family-name generic-family)
+ ("font-size" absolute-size relative-size length percentage)
+ ("font-style" "normal" "italic" "oblique")
+ ("font-variant" "normal" "small-caps")
+ ("font-weight" "normal" "bold" "bolder" "lighter" "100" "200" "300" "400"
+ "500" "600" "700" "800" "900")
+ ("height" length percentage "auto")
+ ("left" length percentage "auto")
+ ("letter-spacing" "normal" length)
+ ("line-height" "normal" number length percentage)
+ ("list-style" list-style-type list-style-position list-style-image)
+ ("list-style-image" uri "none")
+ ("list-style-position" "inside" "outside")
+ ("list-style-type" "disc" "circle" "square" "decimal" "decimal-leading-zero"
+ "lower-roman" "upper-roman" "lower-greek" "lower-latin" "upper-latin"
+ "armenian" "georgian" "lower-alpha" "upper-alpha" "none")
+ ("margin" margin-width)
+ ("margin-bottom" margin-width)
+ ("margin-left" margin-width)
+ ("margin-right" margin-width)
+ ("margin-top" margin-width)
+ ("max-height" length percentage "none")
+ ("max-width" length percentage "none")
+ ("min-height" length percentage)
+ ("min-width" length percentage)
+ ("orphans" integer)
+ ("outline" outline-color outline-style outline-width)
+ ("outline-color" color "invert")
+ ("outline-style" border-style)
+ ("outline-width" border-width)
+ ("overflow" "visible" "hidden" "scroll" "auto")
+ ("padding" padding-width)
+ ("padding-bottom" padding-width)
+ ("padding-left" padding-width)
+ ("padding-right" padding-width)
+ ("padding-top" padding-width)
+ ("page-break-after" "auto" "always" "avoid" "left" "right")
+ ("page-break-before" "auto" "always" "avoid" "left" "right")
+ ("page-break-inside" "avoid" "auto")
+ ("pause" time percentage)
+ ("pause-after" time percentage)
+ ("pause-before" time percentage)
+ ("pitch" frequency "x-low" "low" "medium" "high" "x-high")
+ ("pitch-range" number)
+ ("play-during" uri "mix" "repeat" "auto" "none")
+ ("position" "static" "relative" "absolute" "fixed")
+ ("quotes" string string "none")
+ ("richness" number)
+ ("right" length percentage "auto")
+ ("speak" "normal" "none" "spell-out")
+ ("speak-header" "once" "always")
+ ("speak-numeral" "digits" "continuous")
+ ("speak-punctuation" "code" "none")
+ ("speech-rate" number "x-slow" "slow" "medium" "fast" "x-fast" "faster"
+ "slower")
+ ("stress" number)
+ ("table-layout" "auto" "fixed")
+ ("text-align" "left" "right" "center" "justify")
+ ("text-decoration" "none" "underline" "overline" "line-through" "blink")
+ ("text-indent" length percentage)
+ ("text-transform" "capitalize" "uppercase" "lowercase" "none")
+ ("top" length percentage "auto")
+ ("unicode-bidi" "normal" "embed" "bidi-override")
+ ("vertical-align" "baseline" "sub" "super" "top" "text-top" "middle"
+ "bottom" "text-bottom" percentage length)
+ ("visibility" "visible" "hidden" "collapse")
+ ("voice-family" specific-voice generic-voice "*" specific-voice
+ generic-voice)
+ ("volume" number percentage "silent" "x-soft" "soft" "medium" "loud"
+ "x-loud")
+ ("white-space" "normal" "pre" "nowrap" "pre-wrap" "pre-line")
+ ("widows" integer)
+ ("width" length percentage "auto")
+ ("word-spacing" "normal" length)
+ ("z-index" "auto" integer))
+ "A list of CSS properties and their possible values.")
+
+(defconst company-css-value-classes
+ '((absolute-size "xx-small" "x-small" "small" "medium" "large" "x-large"
+ "xx-large")
+ (border-style "none" "hidden" "dotted" "dashed" "solid" "double" "groove"
+ "ridge" "inset" "outset")
+ (color "aqua" "black" "blue" "fuchsia" "gray" "green" "lime" "maroon" "navy"
+ "olive" "orange" "purple" "red" "silver" "teal" "white" "yellow")
+ (counter "counter(,)")
+ (family-name "Courier" "Helvetica" "Times")
+ (generic-family "serif" "sans-serif" "cursive" "fantasy" "monospace")
+ (generic-voice "male" "female" "child")
+ (margin-width "auto") ;; length percentage
+ (relative-size "larger" "smaller")
+ (shape "rect(,,,)")
+ (uri "url()"))
+ "A list of CSS property value classes and their contents.")
+;; missing, because not completable
+;; <angle><frequency><identifier><integer><length><number><padding-width>
+;; <percentage><specific-voice><string><time><uri>
+
+(defconst company-css-html-tags
+ '("a" "abbr" "acronym" "address" "applet" "area" "b" "base" "basefont" "bdo"
+ "big" "blockquote" "body" "br" "button" "caption" "center" "cite" "code"
+ "col" "colgroup" "dd" "del" "dfn" "dir" "div" "dl" "dt" "em" "fieldset"
+ "font" "form" "frame" "frameset" "h1" "h2" "h3" "h4" "h5" "h6" "head" "hr"
+ "html" "i" "iframe" "img" "input" "ins" "isindex" "kbd" "label" "legend"
+ "li" "link" "map" "menu" "meta" "noframes" "noscript" "object" "ol"
+ "optgroup" "option" "p" "param" "pre" "q" "s" "samp" "script" "select"
+ "small" "span" "strike" "strong" "style" "sub" "sup" "table" "tbody" "td"
+ "textarea" "tfoot" "th" "thead" "title" "tr" "tt" "u" "ul" "var")
+ "A list of HTML tags for use in CSS completion.")
+
+(defconst company-css-pseudo-classes
+ '("active" "after" "before" "first" "first-child" "first-letter" "first-line"
+ "focus" "hover" "lang" "left" "link" "right" "visited")
+ "Identifiers for CSS pseudo-elements and pseudo-classes.")
+
+(defconst company-css-property-cache (make-hash-table :size 115 :test 'equal))
+
+(defun company-css-property-values (attribute)
+ "Access the `company-css-property-alist' cached and flattened."
+ (or (gethash attribute company-css-property-cache)
+ (let (results)
+ (dolist (value (cdr (assoc attribute company-css-property-alist)))
+ (if (symbolp value)
+ (dolist (child (or (cdr (assoc value company-css-value-classes))
+ (company-css-property-values
+ (symbol-name value))))
+ (add-to-list 'results child))
+ (add-to-list 'results value)))
+ (setq results (sort results 'string<))
+ (puthash attribute results company-css-property-cache)
+ results)))
+
+;;; bracket detection
+
+(defconst company-css-braces-syntax-table
+ (let ((table (make-syntax-table)))
+ (setf (aref table ?{) '(4 . 125))
+ (setf (aref table ?}) '(5 . 123))
+ table)
+ "A syntax table giving { and } paren syntax.")
+
+(defun company-css-inside-braces-p ()
+ "Return non-nil, if point is within matched { and }."
+ (ignore-errors
+ (with-syntax-table company-css-braces-syntax-table
+ (let ((parse-sexp-ignore-comments t))
+ (scan-lists (point) -1 1)))))
+
+;;; tags
+(defconst company-css-tag-regexp
+ (concat "\\(?:\\`\\|}\\)[[:space:]]*"
+ ;; multiple
+ "\\(?:"
+ ;; previous tags:
+ "\\(?:#\\|\\_<[[:alpha:]]\\)[[:alnum:]-#]*\\(?:\\[[^]]*\\]\\)?"
+ ;; space or selectors
+ "\\(?:[[:space:]]+\\|[[:space:]]*[+,>][[:space:]]*\\)"
+ "\\)*"
+ "\\(\\(?:#\\|\\_<[[:alpha:]]\\)\\(?:[[:alnum:]-#]*\\_>\\)?\\_>\\|\\)"
+ "\\=")
+ "A regular expression matching CSS tags")
+
+;;; pseudo id
+(defconst company-css-pseudo-regexp
+ (concat "\\(?:\\`\\|}\\)[[:space:]]*"
+ ;; multiple
+ "\\(?:"
+ ;; previous tags:
+ "\\(?:#\\|\\_<[[:alpha:]]\\)[[:alnum:]-#]*\\(?:\\[[^]]*\\]\\)?"
+ ;; space or delimiters
+ "\\(?:[[:space:]]+\\|[[:space:]]*[+,>][[:space:]]*\\)"
+ "\\)*"
+ "\\(?:\\(?:\\#\\|\\_<[[:alpha:]]\\)[[:alnum:]-#]*\\):"
+ "\\([[:alpha:]-]+\\_>\\|\\)\\_>\\=")
+ "A regular expression matching CSS pseudo classes")
+
+;;; properties
+
+(defun company-css-grab-property ()
+ "Return the CSS property before point, if any.
+Returns \"\" if no property found, but feasible at this position."
+ (when (company-css-inside-braces-p)
+ (company-grab-symbol)))
+
+;;; values
+(defconst company-css-property-value-regexp
+ "\\_<\\([[:alpha:]-]+\\):\\(?:[^};]*[[:space:]]+\\)?\\([^};]*\\_>\\|\\)\\="
+ "A regular expression matching CSS tags")
+
+;;;###autoload
+(defun company-css (command &optional arg &rest ignored)
+ "A `company-mode' completion back-end for `css-mode'."
+ (interactive (list 'interactive))
+ (case command
+ ('interactive (company-begin-backend 'company-css))
+ ('prefix (and (derived-mode-p 'css-mode)
+ (or (company-grab company-css-tag-regexp 1)
+ (company-grab company-css-pseudo-regexp 1)
+ (company-grab company-css-property-value-regexp 2)
+ (company-css-grab-property))))
+ ('candidates
+ (cond
+ ((company-grab company-css-tag-regexp 1)
+ (all-completions arg company-css-html-tags))
+ ((company-grab company-css-pseudo-regexp 1)
+ (all-completions arg company-css-pseudo-classes))
+ ((company-grab company-css-property-value-regexp 2)
+ (all-completions arg
+ (company-css-property-values
+ (company-grab company-css-property-value-regexp 1))))
+ ((company-css-grab-property)
+ (all-completions arg company-css-property-alist))))
+ ('sorted t)))
+
+(provide 'company-css)
+;;; company-css.el ends here
--- /dev/null
+;;; company-dabbrev-code.el --- a dabbrev-like company-mode back-end for code
+
+;; Copyright (C) 2009 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'company)
+(require 'company-dabbrev)
+(eval-when-compile (require 'cl))
+
+(defcustom company-dabbrev-code-modes
+ '(asm-mode batch-file-mode c++-mode c-mode cperl-mode csharp-mode css-mode
+ emacs-lisp-mode erlang-mode espresso-mode f90-mode fortran-mode
+ haskell-mode java-mode javascript-mode jde-mode js2-mode lisp-mode
+ lua-mode objc-mode perl-mode php-mode python-mode ruby-mode scheme-mode
+ shell-script-mode)
+ "*Modes that use `company-dabbrev-code'.
+In all these modes `company-dabbrev-code' will complete only symbols, not text
+in comments or strings. In other modes `company-dabbrev-code' will pass control
+to other back-ends \(e.g. `company-dabbrev'\).
+Value t means complete in all modes."
+ :group 'company
+ :type '(choice (repeat (symbol :tag "Major mode"))
+ (const tag "All modes" t)))
+
+(defcustom company-dabbrev-code-other-buffers t
+ "*Determines whether `company-dabbrev-code' should search other buffers.
+If 'all, search all other buffers. If t, search buffers with the same
+major-mode.
+See also `company-dabbrev-code-time-limit'."
+ :group 'company
+ :type '(choice (const :tag "Off" nil)
+ (const :tag "Same major mode" t)
+ (const :tag "All" all)))
+
+(defcustom company-dabbrev-code-time-limit .5
+ "*Determines how long `company-dabbrev-code' should look for matches."
+ :group 'company
+ :type '(choice (const :tag "Off" nil)
+ (number :tag "Seconds")))
+
+(defsubst company-dabbrev-code--make-regexp (prefix)
+ (concat "\\_<" (if (equal prefix "")
+ "\\([a-zA-Z]\\|\\s_\\)"
+ (regexp-quote prefix))
+ "\\(\\sw\\|\\s_\\)*\\_>"))
+
+;;;###autoload
+(defun company-dabbrev-code (command &optional arg &rest ignored)
+ "A dabbrev-like `company-mode' back-end for code.
+The back-end looks for all symbols in the current buffer that aren't in
+comments or strings."
+ (interactive (list 'interactive))
+ (case command
+ ('interactive (company-begin-backend 'company-dabbrev-code))
+ ('prefix (and (or (eq t company-dabbrev-code-modes)
+ (apply 'derived-mode-p company-dabbrev-code-modes))
+ (not (company-in-string-or-comment))
+ (or (company-grab-symbol) 'stop)))
+ ('candidates (let ((completion-ignore-case nil))
+ (company-dabbrev--search
+ (company-dabbrev-code--make-regexp arg)
+ company-dabbrev-code-time-limit
+ company-dabbrev-code-other-buffers t)))
+ ('duplicates t)))
+
+(provide 'company-dabbrev-code)
+;;; company-dabbrev-code.el ends here
--- /dev/null
+;;; company-dabbrev.el --- a dabbrev-like company-mode completion back-end
+
+;; Copyright (C) 2009 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'company)
+(eval-when-compile (require 'cl))
+
+(defcustom company-dabbrev-other-buffers 'all
+ "*Determines whether `company-dabbrev' should search other buffers.
+If 'all, search all other buffers. If t, search buffers with the same
+major-mode.
+See also `company-dabbrev-time-limit'."
+ :group 'company
+ :type '(choice (const :tag "Off" nil)
+ (const :tag "Same major mode" t)
+ (const :tag "All" all)))
+
+(defcustom company-dabbrev-time-limit .5
+ "*Determines how many seconds `company-dabbrev' should look for matches."
+ :group 'company
+ :type '(choice (const :tag "Off" nil)
+ (number :tag "Seconds")))
+
+(defcustom company-dabbrev-char-regexp "\\sw"
+ "*A regular expression matching the characters `company-dabbrev' looks for."
+ :group 'company
+ :type 'regexp)
+
+(defmacro company-dabrev--time-limit-while (test start limit &rest body)
+ (declare (indent 3) (debug t))
+ `(let ((company-time-limit-while-counter 0))
+ (catch 'done
+ (while ,test
+ ,@body
+ (and ,limit
+ (eq (incf company-time-limit-while-counter) 25)
+ (setq company-time-limit-while-counter 0)
+ (> (float-time (time-since ,start)) ,limit)
+ (throw 'done 'company-time-out))))))
+
+(defsubst company-dabbrev--make-regexp (prefix)
+ (concat "\\<" (if (equal prefix "")
+ company-dabbrev-char-regexp
+ (regexp-quote prefix))
+ "\\(" company-dabbrev-char-regexp "\\)*\\>"))
+
+(defun company-dabbrev--search-buffer (regexp pos symbols start limit
+ ignore-comments)
+ (save-excursion
+ (let (match)
+ (goto-char (if pos (1- pos) (point-min)))
+ ;; search before pos
+ (company-dabrev--time-limit-while (re-search-backward regexp nil t)
+ start limit
+ (setq match (match-string-no-properties 0))
+ (if (and ignore-comments (company-in-string-or-comment))
+ (re-search-backward "\\s<\\|\\s!\\|\\s\"\\|\\s|" nil t)
+ (push match symbols)))
+ (goto-char (or pos (point-min)))
+ ;; search after pos
+ (company-dabrev--time-limit-while (re-search-forward regexp nil t)
+ start limit
+ (setq match (match-string-no-properties 0))
+ (if (and ignore-comments (company-in-string-or-comment))
+ (re-search-forward "\\s>\\|\\s!\\|\\s\"" nil t)
+ (push match symbols)))
+ symbols)))
+
+(defun company-dabbrev--search (regexp &optional limit other-buffers
+ ignore-comments)
+ (let* ((start (current-time))
+ (symbols (company-dabbrev--search-buffer regexp (point) nil start limit
+ ignore-comments)))
+ (when other-buffers
+ (dolist (buffer (delq (current-buffer) (buffer-list)))
+ (and (or (eq other-buffers 'all)
+ (eq (buffer-local-value 'major-mode buffer) major-mode))
+ (with-current-buffer buffer
+ (setq symbols
+ (company-dabbrev--search-buffer regexp nil symbols start
+ limit ignore-comments))))
+ (and limit
+ (> (float-time (time-since start)) limit)
+ (return))))
+ symbols))
+
+;;;###autoload
+(defun company-dabbrev (command &optional arg &rest ignored)
+ "A dabbrev-like `company-mode' completion back-end."
+ (interactive (list 'interactive))
+ (case command
+ ('interactive (company-begin-backend 'company-dabbrev))
+ ('prefix (company-grab-word))
+ ('candidates
+ (mapcar 'downcase
+ (company-dabbrev--search (company-dabbrev--make-regexp arg)
+ company-dabbrev-time-limit
+ company-dabbrev-other-buffers)))
+ ('ignore-case t)
+ ('duplicates t)))
+
+(provide 'company-dabbrev)
+;;; company-dabbrev.el ends here
--- /dev/null
+;;; company-eclim.el --- a company-mode completion back-end for eclim.
+
+;; Copyright (C) 2009 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'company)
+(eval-when-compile (require 'cl))
+
+(defun company-eclim-executable-find ()
+ (let (file)
+ (dolist (eclipse-root '("/Applications/eclipse" "/usr/lib/eclipse"
+ "/usr/local/lib/eclipse"))
+ (and (file-exists-p (setq file (expand-file-name "plugins" eclipse-root)))
+ (setq file (car (last (directory-files file t "^org.eclim_"))))
+ (file-exists-p (setq file (expand-file-name "bin/eclim" file)))
+ (return file)))))
+
+(defcustom company-eclim-executable
+ (or (executable-find "eclim") (company-eclim-executable-find))
+ "*Location of eclim executable"
+ :group 'company
+ :type 'file)
+
+(defcustom company-eclim-auto-save t
+ "*Determines whether to save the buffer when retrieving completions.
+eclim can only complete correctly when the buffer has been saved."
+ :group 'company
+ :type '(choice (const :tag "Off" nil)
+ (const :tag "On" t)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar company-eclim--project-dir 'unknown)
+(make-variable-buffer-local 'company-eclim--project-dir)
+
+(defvar company-eclim--project-name 'unknown)
+(make-variable-buffer-local 'company-eclim--project-name)
+
+(defvar company-eclim--doc nil)
+(make-variable-buffer-local 'company-eclim--doc)
+
+(defun company-eclim--buffer-lines ()
+ (goto-char (point-max))
+ (let (lines)
+ (while (= 0 (forward-line -1))
+ (push (buffer-substring-no-properties (point-at-bol) (point-at-eol))
+ lines))
+ lines))
+
+(defun company-eclim--call-process (&rest args)
+ (let ((coding-system-for-read 'utf-8)
+ res)
+ (with-temp-buffer
+ (if (= 0 (setq res (apply 'call-process company-eclim-executable nil t nil
+ "-command" args)))
+ (company-eclim--buffer-lines)
+ (message "Company-eclim command failed with error %d:\n%s" res
+ (buffer-substring (point-min) (point-max)))
+ nil))))
+
+(defun company-eclim--project-list ()
+ (mapcar (lambda (line) (nreverse (split-string line " *- *" nil)))
+ (company-eclim--call-process "project_list")))
+
+(defun company-eclim--project-dir ()
+ (if (eq company-eclim--project-dir 'unknown)
+ (setq company-eclim--project-dir
+ (directory-file-name
+ (expand-file-name
+ (company-locate-dominating-file buffer-file-name ".project"))))
+ company-eclim--project-dir))
+
+(defun company-eclim--project-name ()
+ (if (eq company-eclim--project-name 'unknown)
+ (setq company-eclim--project-name
+ (car (cddr (assoc (company-eclim--project-dir)
+ (company-eclim--project-list)))))
+ company-eclim--project-name))
+
+(defun company-eclim--candidates (prefix)
+ (interactive "d")
+ (let ((project-file (file-relative-name buffer-file-name
+ (company-eclim--project-dir)))
+ (project-name (company-eclim--project-name)))
+ (when company-eclim-auto-save
+ (when (buffer-modified-p)
+ (basic-save-buffer))
+ ;; FIXME: Sometimes this isn't finished when we complete.
+ (company-eclim--call-process "java_src_update"
+ "-p" (company-eclim--project-name)
+ "-f" project-file))
+ (setq company-eclim--doc
+ (mapcar (lambda (line)
+ (cdr (split-string line "|" nil)))
+ (company-eclim--call-process
+ "java_complete" "-p" (company-eclim--project-name)
+ "-f" project-file
+ "-o" (number-to-string (1- (point)))
+ "-e" "utf-8"
+ "-l" "standard"))))
+ (let ((completion-ignore-case nil))
+ (all-completions prefix (mapcar 'car company-eclim--doc))))
+
+(defun company-eclim (command &optional arg &rest ignored)
+ "A `company-mode' completion back-end for eclim.
+eclim provides access to Eclipse Java IDE features for other editors.
+
+Completions only work correctly when the buffer has been saved.
+`company-eclim-auto-save' determines whether to do this automatically."
+ (interactive (list 'interactive))
+ (case command
+ ('interactive (company-begin-backend 'company-eclim))
+ ('prefix (and (derived-mode-p 'java-mode 'jde-mode)
+ buffer-file-name
+ company-eclim-executable
+ (company-eclim--project-name)
+ (not (company-in-string-or-comment))
+ (or (company-grab-symbol) 'stop)))
+ ('candidates (company-eclim--candidates arg))
+ ('meta (cadr (assoc arg company-eclim--doc)))
+ ;; because "" doesn't return everything
+ ('no-cache (equal arg ""))))
+
+(provide 'company-eclim)
+;;; company-eclim.el ends here
--- /dev/null
+;;; company-elisp.el --- a company-mode completion back-end for emacs-lisp-mode
+
+;; Copyright (C) 2009 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'company)
+(eval-when-compile (require 'cl))
+(require 'help-mode)
+
+(defcustom company-elisp-detect-function-context t
+ "*If enabled, offer lisp functions only in appropriate contexts.
+Functions are offered for completion only after ' and \(."
+ :group 'company
+ :type '(choice (const :tag "Off" nil)
+ (const :tag "On" t)))
+
+(defun company-grab-lisp-symbol ()
+ (let ((prefix (company-grab-symbol)))
+ (if prefix
+ (unless (and (company-in-string-or-comment)
+ (/= (char-before (- (point) (length prefix))) ?`))
+ prefix)
+ 'stop)))
+
+(defun company-elisp-predicate (symbol)
+ (or (boundp symbol)
+ (fboundp symbol)))
+
+(defvar company-elisp-parse-limit 30)
+(defvar company-elisp-parse-depth 100)
+
+(defvar company-elisp-binding-regexp
+ (concat "([ \t\n]*\\_<" (regexp-opt '("let" "defun" "defmacro" "defsubst"
+ "lambda" "lexical-let" "flet" "labels"))
+ "\\*?")
+ "Regular expression matching sexps containing variable bindings.")
+
+(defvar company-elisp-binding-regexp-1
+ (concat "([ \t\n]*\\_<" (regexp-opt '("dolist" "dotimes")))
+ "Regular expression matching sexps containing one variable binding.")
+
+(defun company-elisp-parse-local (prefix vars)
+ (let ((regexp (concat "[ \t\n]*\\(\\_<" (regexp-quote prefix)
+ "\\(?:\\sw\\|\\s_\\)*\\_>\\)"))
+ (pos (point)))
+ (ignore-errors
+ (save-excursion
+ (dotimes (i company-elisp-parse-depth)
+ (up-list -1)
+ (save-excursion
+ (cond
+ ((looking-at company-elisp-binding-regexp)
+ (down-list 2)
+ (ignore-errors
+ (dotimes (i company-elisp-parse-limit)
+ (save-excursion
+ (when (looking-at "[ \t\n]*(")
+ (down-list 1))
+ (and (looking-at regexp)
+ ;; Don't add incomplete text as candidate.
+ (not (eq (match-end 0) pos))
+ (add-to-list 'vars (match-string-no-properties 1))))
+ (forward-sexp))))
+ ((looking-at company-elisp-binding-regexp-1)
+ (down-list 2)
+ (and (looking-at regexp)
+ ;; Don't add incomplete text as candidate.
+ (not (eq (match-end 0) pos))
+ (add-to-list 'vars (match-string-no-properties 1)))))))))
+ vars))
+
+(defun company-elisp-candidates (prefix)
+ (let* ((completion-ignore-case nil)
+ (before (char-before (- (point) (length prefix))))
+ (predicate (if (and company-elisp-detect-function-context
+ (not (eq before ?')))
+ (if (eq before ?\()
+ 'fboundp
+ 'boundp)
+ 'company-elisp-predicate))
+ (candidates (all-completions prefix obarray predicate)))
+ (company-elisp-parse-local prefix candidates)))
+
+(defun company-elisp-doc (symbol)
+ (let* ((symbol (intern symbol))
+ (doc (if (fboundp symbol)
+ (documentation symbol t)
+ (documentation-property symbol 'variable-documentation t))))
+ (and (stringp doc)
+ (string-match ".*$" doc)
+ (match-string 0 doc))))
+
+;;;###autoload
+(defun company-elisp (command &optional arg &rest ignored)
+ "A `company-mode' completion back-end for `emacs-lisp-mode'."
+ (interactive (list 'interactive))
+ (case command
+ ('interactive (company-begin-backend 'company-elisp))
+ ('prefix (and (eq (derived-mode-p 'emacs-lisp-mode) 'emacs-lisp-mode)
+ (company-grab-lisp-symbol)))
+ ('candidates (company-elisp-candidates arg))
+ ('meta (company-elisp-doc arg))
+ ('doc-buffer (let ((symbol (intern arg)))
+ (save-window-excursion
+ (when (or (ignore-errors (describe-function symbol))
+ (ignore-errors (describe-variable symbol)))
+ (help-buffer)))))
+ ('location (let ((sym (intern arg)))
+ (or (ignore-errors (find-definition-noselect sym nil))
+ (ignore-errors (find-definition-noselect sym 'defvar))
+ (ignore-errors (find-definition-noselect sym t)))))))
+
+(provide 'company-elisp)
+;;; company-elisp.el ends here
--- /dev/null
+;;; company-etags.el --- a company-mode completion back-end for etags
+
+;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'company)
+(eval-when-compile (require 'etags))
+(eval-when-compile (require 'cl))
+
+(defcustom company-etags-use-main-table-list t
+ "*Always search `tags-table-list' if set.
+If this is disabled, `company-etags' will try to find the one table for each
+buffer automatically."
+ :group 'company-mode
+ :type '(choice (const :tag "off" nil)
+ (const :tag "on" t)))
+
+(defvar company-etags-modes '(c-mode objc-mode c++-mode java-mode jde-mode
+ pascal-mode perl-mode python-mode))
+
+(defvar company-etags-buffer-table 'unknown)
+(make-variable-buffer-local 'company-etags-buffer-table)
+
+(defun company-etags-find-table ()
+ (let ((file (company-locate-dominating-file (or buffer-file-name
+ default-directory)
+ "TAGS")))
+ (when file
+ (list (expand-file-name file)))))
+
+(defun company-etags-buffer-table ()
+ (or (and company-etags-use-main-table-list tags-table-list)
+ (if (eq company-etags-buffer-table 'unknown)
+ (setq company-etags-buffer-table (company-etags-find-table))
+ company-etags-buffer-table)))
+
+;;;###autoload
+(defun company-etags (command &optional arg &rest ignored)
+ "A `company-mode' completion back-end for etags."
+ (interactive (list 'interactive))
+ (case command
+ ('interactive (company-begin-backend 'company-etags))
+ ('prefix (and (memq major-mode company-etags-modes)
+ (not (company-in-string-or-comment))
+ (require 'etags nil t)
+ (company-etags-buffer-table)
+ (or (company-grab-symbol) 'stop)))
+ ('candidates (let ((tags-table-list (company-etags-buffer-table))
+ (completion-ignore-case nil))
+ (and (or tags-file-name tags-table-list)
+ (fboundp 'tags-completion-table)
+ tags-table-list
+ (all-completions arg (tags-completion-table)))))
+ ('location (let ((tags-table-list (company-etags-buffer-table)))
+ (when (fboundp 'find-tag-noselect)
+ (save-excursion
+ (let ((buffer (find-tag-noselect arg)))
+ (cons buffer (with-current-buffer buffer (point))))))))
+ ('sorted t)))
+
+(provide 'company-etags)
+;;; company-etags.el ends here
--- /dev/null
+;;; company-files.el --- a company-mode completion back-end for file names
+
+;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'company)
+(eval-when-compile (require 'cl))
+
+(defun company-files-directory-files (dir prefix)
+ (ignore-errors
+ (if (equal prefix "")
+ (directory-files dir nil "\\`[^.]\\|\\`.[^.]")
+ (file-name-all-completions prefix dir))))
+
+(defvar company-files-regexps
+ (let ((begin (if (eq system-type 'windows-nt)
+ "[a-z][A-Z]\\"
+ "~?/")))
+ (list (concat "\"\\(" begin "[^\"\n]*\\)")
+ (concat "\'\\(" begin "[^\'\n]*\\)")
+ (concat "\\(?:[ \t]\\|^\\)\\(" begin "[^ \t\n]*\\)"))))
+
+(defun company-files-grab-existing-name ()
+ ;; Grab file names with spaces, only when they include quotes.
+ (let (file dir)
+ (and (dolist (regexp company-files-regexps)
+ (when (setq file (company-grab-line regexp 1))
+ (return file)))
+ (setq dir (file-name-directory file))
+ (not (string-match "//" dir))
+ (file-exists-p dir)
+ (file-name-all-completions (file-name-nondirectory file) dir)
+ file)))
+
+(defvar company-files-completion-cache nil)
+
+(defun company-files-complete (prefix)
+ (let* ((dir (file-name-directory prefix))
+ (file (file-name-nondirectory prefix))
+ candidates)
+ (unless (equal dir (car company-files-completion-cache))
+ (dolist (file (company-files-directory-files dir file))
+ (setq file (concat dir file))
+ (push file candidates)
+ (when (file-directory-p file)
+ ;; Add one level of children.
+ (dolist (child (company-files-directory-files file ""))
+ (push (concat file child) candidates))))
+ (setq company-files-completion-cache (cons dir (nreverse candidates))))
+ (cdr company-files-completion-cache)))
+
+;;;###autoload
+(defun company-files (command &optional arg &rest ignored)
+ "a `company-mode' completion back-end existing file names."
+ (interactive (list 'interactive))
+ (case command
+ ('interactive (company-begin-backend 'company-files))
+ ('prefix (company-files-grab-existing-name))
+ ('candidates (company-files-complete arg))
+ ('location (cons (dired-noselect
+ (file-name-directory (directory-file-name arg))) 1))
+ ('sorted t)
+ ('no-cache t)))
+
+(provide 'company-files)
+;;; company-files.el ends here
--- /dev/null
+;;; company-gtags.el --- a company-mode completion back-end for GNU Global
+
+;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'company)
+(eval-when-compile (require 'cl))
+
+(defcustom company-gtags-executable
+ (executable-find "global")
+ "*Location of GNU global executable"
+ :type 'string
+ :group 'company)
+
+(define-obsolete-variable-alias
+ 'company-gtags-gnu-global-program-name
+ 'company-gtags-executable)
+
+(defvar company-gtags--tags-available-p 'unknown)
+(make-variable-buffer-local 'company-gtags--tags-available-p)
+
+(defvar company-gtags-modes '(c-mode c++-mode jde-mode java-mode php-mode))
+
+(defun company-gtags--tags-available-p ()
+ (if (eq company-gtags--tags-available-p 'unknown)
+ (setq company-gtags--tags-available-p
+ (company-locate-dominating-file buffer-file-name "GTAGS"))
+ company-gtags--tags-available-p))
+
+(defun company-gtags-fetch-tags (prefix)
+ (with-temp-buffer
+ (let (tags)
+ (when (= 0 (call-process company-gtags-executable nil
+ (list (current-buffer) nil) nil "-c" prefix))
+ (goto-char (point-min))
+ (split-string (buffer-string) "\n" t)))))
+
+(defun company-gtags-location (tag)
+ (with-temp-buffer
+ (when (= 0 (call-process company-gtags-executable nil
+ (list (current-buffer) nil) nil "-x" tag))
+ (goto-char (point-min))
+ (when (looking-at (concat (regexp-quote tag)
+ "[ \t]+\\([[:digit:]]+\\)"
+ "[ \t]+\\([^ \t]+\\)"))
+ (cons (expand-file-name (match-string 2))
+ (string-to-number (match-string 1)))))))
+
+;;;###autoload
+(defun company-gtags (command &optional arg &rest ignored)
+ "A `company-mode' completion back-end for GNU Global."
+ (interactive (list 'interactive))
+ (case command
+ ('interactive (company-begin-backend 'company-gtags))
+ ('prefix (and company-gtags-executable
+ (memq major-mode company-gtags-modes)
+ (not (company-in-string-or-comment))
+ (company-gtags--tags-available-p)
+ (or (company-grab-symbol) 'stop)))
+ ('candidates (company-gtags-fetch-tags arg))
+ ('sorted t)
+ ('location (company-gtags-location arg))))
+
+(provide 'company-gtags)
+;;; company-gtags.el ends here
--- /dev/null
+;;; company-ispell.el --- a company-mode completion back-end using ispell
+
+;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'company)
+(require 'ispell)
+(eval-when-compile (require 'cl))
+
+(defcustom company-ispell-dictionary nil
+ "*Dictionary to use for `company-ispell'.
+If nil, use `ispell-complete-word-dict'."
+ :group 'company
+ :type '(choice (const :tag "default (nil)" nil)
+ (file :tag "dictionary" t)))
+
+(defvar company-ispell-available 'unknown)
+
+(defun company-ispell-available ()
+ (when (eq company-ispell-available 'unknown)
+ (condition-case err
+ (progn
+ (lookup-words "WHATEVER")
+ (setq company-ispell-available t))
+ (error
+ (message "Company: ispell-look-command not found")
+ (setq company-ispell-available nil))))
+ company-ispell-available)
+
+;;;###autoload
+(defun company-ispell (command &optional arg &rest ignored)
+ "A `company-mode' completion back-end using ispell."
+ (interactive (list 'interactive))
+ (case command
+ ('interactive (company-begin-backend 'company-ispell))
+ ('prefix (when (company-ispell-available)
+ (company-grab-word)))
+ ('candidates (lookup-words arg (or company-ispell-dictionary
+ ispell-complete-word-dict)))
+ ('sorted t)
+ ('ignore-case t)))
+
+(provide 'company-ispell)
+;;; company-ispell.el ends here
--- /dev/null
+;;; company-keywords.el --- a company back-end for programming language keywords
+
+;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'company)
+(eval-when-compile (require 'cl))
+
+(defun company-keywords-upper-lower (&rest lst)
+ ;; Upcase order is different for _.
+ (nconc (sort (mapcar 'upcase lst) 'string<) lst))
+
+(defvar company-keywords-alist
+ ;; Please contribute corrections or additions.
+ `((c++-mode
+ "asm" "auto" "bool" "break" "case" "catch" "char" "class" "const"
+ "const_cast" "continue" "default" "delete" "do" "double" "dynamic_cast"
+ "else" "enum" "explicit" "export" "extern" "false" "float" "for" "friend"
+ "goto" "if" "inline" "int" "long" "mutable" "namespace" "new"
+ "operator" "private" "protected" "public" "register" "reinterpret_cast"
+ "return" "short" "signed" "sizeof" "static" "static_cast" "struct" "switch"
+ "template" "this" "throw" "true" "try" "typedef" "typeid" "typename"
+ "union" "unsigned" "using" "virtual" "void" "volatile" "wchar_t" "while")
+ (c-mode
+ "auto" "break" "case" "char" "const" "continue" "default" "do"
+ "double" "else" "enum" "extern" "float" "for" "goto" "if" "int" "long"
+ "register" "return" "short" "signed" "sizeof" "static" "struct"
+ "switch" "typedef" "union" "unsigned" "void" "volatile" "while")
+ (csharp-mode
+ "abstract" "add" "alias" "as" "base" "bool" "break" "byte" "case"
+ "catch" "char" "checked" "class" "const" "continue" "decimal" "default"
+ "delegate" "do" "double" "else" "enum" "event" "explicit" "extern"
+ "false" "finally" "fixed" "float" "for" "foreach" "get" "global" "goto"
+ "if" "implicit" "in" "int" "interface" "internal" "is" "lock" "long"
+ "namespace" "new" "null" "object" "operator" "out" "override" "params"
+ "partial" "private" "protected" "public" "readonly" "ref" "remove"
+ "return" "sbyte" "sealed" "set" "short" "sizeof" "stackalloc" "static"
+ "string" "struct" "switch" "this" "throw" "true" "try" "typeof" "uint"
+ "ulong" "unchecked" "unsafe" "ushort" "using" "value" "var" "virtual"
+ "void" "volatile" "where" "while" "yield")
+ (d-mode
+ ;; from http://www.digitalmars.com/d/2.0/lex.html
+ "abstract" "alias" "align" "asm"
+ "assert" "auto" "body" "bool" "break" "byte" "case" "cast" "catch"
+ "cdouble" "cent" "cfloat" "char" "class" "const" "continue" "creal"
+ "dchar" "debug" "default" "delegate" "delete" "deprecated" "do"
+ "double" "else" "enum" "export" "extern" "false" "final" "finally"
+ "float" "for" "foreach" "foreach_reverse" "function" "goto" "idouble"
+ "if" "ifloat" "import" "in" "inout" "int" "interface" "invariant"
+ "ireal" "is" "lazy" "long" "macro" "mixin" "module" "new" "nothrow"
+ "null" "out" "override" "package" "pragma" "private" "protected"
+ "public" "pure" "real" "ref" "return" "scope" "short" "static" "struct"
+ "super" "switch" "synchronized" "template" "this" "throw" "true" "try"
+ "typedef" "typeid" "typeof" "ubyte" "ucent" "uint" "ulong" "union"
+ "unittest" "ushort" "version" "void" "volatile" "wchar" "while" "with")
+ (f90-mode .
+ ;; from f90.el
+ ;; ".AND." ".GE." ".GT." ".LT." ".LE." ".NE." ".OR." ".TRUE." ".FALSE."
+ ,(company-keywords-upper-lower
+ "abs" "abstract" "achar" "acos" "adjustl" "adjustr" "aimag" "aint"
+ "align" "all" "all_prefix" "all_scatter" "all_suffix" "allocatable"
+ "allocate" "allocated" "and" "anint" "any" "any_prefix" "any_scatter"
+ "any_suffix" "asin" "assign" "assignment" "associate" "associated"
+ "asynchronous" "atan" "atan2" "backspace" "bind" "bit_size" "block"
+ "btest" "c_alert" "c_associated" "c_backspace" "c_bool"
+ "c_carriage_return" "c_char" "c_double" "c_double_complex" "c_f_pointer"
+ "c_f_procpointer" "c_float" "c_float_complex" "c_form_feed" "c_funloc"
+ "c_funptr" "c_horizontal_tab" "c_int" "c_int16_t" "c_int32_t" "c_int64_t"
+ "c_int8_t" "c_int_fast16_t" "c_int_fast32_t" "c_int_fast64_t"
+ "c_int_fast8_t" "c_int_least16_t" "c_int_least32_t" "c_int_least64_t"
+ "c_int_least8_t" "c_intmax_t" "c_intptr_t" "c_loc" "c_long"
+ "c_long_double" "c_long_double_complex" "c_long_long" "c_new_line"
+ "c_null_char" "c_null_funptr" "c_null_ptr" "c_ptr" "c_short"
+ "c_signed_char" "c_size_t" "c_vertical_tab" "call" "case" "ceiling"
+ "char" "character" "character_storage_size" "class" "close" "cmplx"
+ "command_argument_count" "common" "complex" "conjg" "contains" "continue"
+ "copy_prefix" "copy_scatter" "copy_suffix" "cos" "cosh" "count"
+ "count_prefix" "count_scatter" "count_suffix" "cpu_time" "cshift"
+ "cycle" "cyclic" "data" "date_and_time" "dble" "deallocate" "deferred"
+ "digits" "dim" "dimension" "distribute" "do" "dot_product" "double"
+ "dprod" "dynamic" "elemental" "else" "elseif" "elsewhere" "end" "enddo"
+ "endfile" "endif" "entry" "enum" "enumerator" "eoshift" "epsilon" "eq"
+ "equivalence" "eqv" "error_unit" "exit" "exp" "exponent" "extends"
+ "extends_type_of" "external" "extrinsic" "false" "file_storage_size"
+ "final" "floor" "flush" "forall" "format" "fraction" "function" "ge"
+ "generic" "get_command" "get_command_argument" "get_environment_variable"
+ "goto" "grade_down" "grade_up" "gt" "hpf_alignment" "hpf_distribution"
+ "hpf_template" "huge" "iachar" "iall" "iall_prefix" "iall_scatter"
+ "iall_suffix" "iand" "iany" "iany_prefix" "iany_scatter" "iany_suffix"
+ "ibclr" "ibits" "ibset" "ichar" "ieee_arithmetic" "ieee_exceptions"
+ "ieee_features" "ieee_get_underflow_mode" "ieee_set_underflow_mode"
+ "ieee_support_underflow_control" "ieor" "if" "ilen" "implicit"
+ "import" "include" "independent" "index" "inherit" "input_unit"
+ "inquire" "int" "integer" "intent" "interface" "intrinsic" "ior"
+ "iostat_end" "iostat_eor" "iparity" "iparity_prefix" "iparity_scatter"
+ "iparity_suffix" "ishft" "ishftc" "iso_c_binding" "iso_fortran_env"
+ "kind" "lbound" "le" "leadz" "len" "len_trim" "lge" "lgt" "lle" "llt"
+ "log" "log10" "logical" "lt" "matmul" "max" "maxexponent" "maxloc"
+ "maxval" "maxval_prefix" "maxval_scatter" "maxval_suffix" "merge"
+ "min" "minexponent" "minloc" "minval" "minval_prefix" "minval_scatter"
+ "minval_suffix" "mod" "module" "modulo" "move_alloc" "mvbits" "namelist"
+ "ne" "nearest" "neqv" "new" "new_line" "nint" "non_intrinsic"
+ "non_overridable" "none" "nopass" "not" "null" "nullify"
+ "number_of_processors" "numeric_storage_size" "only" "onto" "open"
+ "operator" "optional" "or" "output_unit" "pack" "parameter" "parity"
+ "parity_prefix" "parity_scatter" "parity_suffix" "pass" "pause"
+ "pointer" "popcnt" "poppar" "precision" "present" "print" "private"
+ "procedure" "processors" "processors_shape" "product" "product_prefix"
+ "product_scatter" "product_suffix" "program" "protected" "public"
+ "pure" "radix" "random_number" "random_seed" "range" "read" "real"
+ "realign" "recursive" "redistribute" "repeat" "reshape" "result"
+ "return" "rewind" "rrspacing" "same_type_as" "save" "scale" "scan"
+ "select" "selected_char_kind" "selected_int_kind" "selected_real_kind"
+ "sequence" "set_exponent" "shape" "sign" "sin" "sinh" "size" "spacing"
+ "spread" "sqrt" "stop" "subroutine" "sum" "sum_prefix" "sum_scatter"
+ "sum_suffix" "system_clock" "tan" "tanh" "target" "template" "then"
+ "tiny" "transfer" "transpose" "trim" "true" "type" "ubound" "unpack"
+ "use" "value" "verify" "volatile" "wait" "where" "while" "with" "write"))
+ (java-mode
+ "abstract" "assert" "boolean" "break" "byte" "case" "catch" "char" "class"
+ "continue" "default" "do" "double" "else" "enum" "extends" "final"
+ "finally" "float" "for" "if" "implements" "import" "instanceof" "int"
+ "interface" "long" "native" "new" "package" "private" "protected" "public"
+ "return" "short" "static" "strictfp" "super" "switch" "synchronized"
+ "this" "throw" "throws" "transient" "try" "void" "volatile" "while")
+ (javascript-mode
+ "break" "catch" "const" "continue" "delete" "do" "else" "export" "for"
+ "function" "if" "import" "in" "instanceOf" "label" "let" "new" "return"
+ "switch" "this" "throw" "try" "typeof" "var" "void" "while" "with" "yield")
+ (objc-mode
+ "@catch" "@class" "@encode" "@end" "@finally" "@implementation"
+ "@interface" "@private" "@protected" "@protocol" "@public"
+ "@selector" "@synchronized" "@throw" "@try" "alloc" "autorelease"
+ "bycopy" "byref" "in" "inout" "oneway" "out" "release" "retain")
+ (perl-mode
+ ;; from cperl.el
+ "AUTOLOAD" "BEGIN" "CHECK" "CORE" "DESTROY" "END" "INIT" "__END__"
+ "__FILE__" "__LINE__" "abs" "accept" "alarm" "and" "atan2" "bind"
+ "binmode" "bless" "caller" "chdir" "chmod" "chomp" "chop" "chown" "chr"
+ "chroot" "close" "closedir" "cmp" "connect" "continue" "cos"
+ "crypt" "dbmclose" "dbmopen" "defined" "delete" "die" "do" "dump" "each"
+ "else" "elsif" "endgrent" "endhostent" "endnetent" "endprotoent"
+ "endpwent" "endservent" "eof" "eq" "eval" "exec" "exists" "exit" "exp"
+ "fcntl" "fileno" "flock" "for" "foreach" "fork" "format" "formline"
+ "ge" "getc" "getgrent" "getgrgid" "getgrnam" "gethostbyaddr"
+ "gethostbyname" "gethostent" "getlogin" "getnetbyaddr" "getnetbyname"
+ "getnetent" "getpeername" "getpgrp" "getppid" "getpriority"
+ "getprotobyname" "getprotobynumber" "getprotoent" "getpwent" "getpwnam"
+ "getpwuid" "getservbyname" "getservbyport" "getservent" "getsockname"
+ "getsockopt" "glob" "gmtime" "goto" "grep" "gt" "hex" "if" "index" "int"
+ "ioctl" "join" "keys" "kill" "last" "lc" "lcfirst" "le" "length"
+ "link" "listen" "local" "localtime" "lock" "log" "lstat" "lt" "map"
+ "mkdir" "msgctl" "msgget" "msgrcv" "msgsnd" "my" "ne" "next" "no"
+ "not" "oct" "open" "opendir" "or" "ord" "our" "pack" "package" "pipe"
+ "pop" "pos" "print" "printf" "push" "q" "qq" "quotemeta" "qw" "qx"
+ "rand" "read" "readdir" "readline" "readlink" "readpipe" "recv" "redo"
+ "ref" "rename" "require" "reset" "return" "reverse" "rewinddir" "rindex"
+ "rmdir" "scalar" "seek" "seekdir" "select" "semctl" "semget" "semop"
+ "send" "setgrent" "sethostent" "setnetent" "setpgrp" "setpriority"
+ "setprotoent" "setpwent" "setservent" "setsockopt" "shift" "shmctl"
+ "shmget" "shmread" "shmwrite" "shutdown" "sin" "sleep" "socket"
+ "socketpair" "sort" "splice" "split" "sprintf" "sqrt" "srand" "stat"
+ "study" "sub" "substr" "symlink" "syscall" "sysopen" "sysread" "system"
+ "syswrite" "tell" "telldir" "tie" "time" "times" "tr" "truncate" "uc"
+ "ucfirst" "umask" "undef" "unless" "unlink" "unpack" "unshift" "untie"
+ "until" "use" "utime" "values" "vec" "wait" "waitpid"
+ "wantarray" "warn" "while" "write" "x" "xor" "y")
+ (php-mode
+ "__CLASS__" "__DIR__" "__FILE__" "__FUNCTION__" "__LINE__" "__METHOD__"
+ "__NAMESPACE__" "_once" "abstract" "and" "array" "as" "break" "case"
+ "catch" "cfunction" "class" "clone" "const" "continue" "declare"
+ "default" "die" "do" "echo" "else" "elseif" "empty" "enddeclare"
+ "endfor" "endforeach" "endif" "endswitch" "endwhile" "eval" "exception"
+ "exit" "extends" "final" "for" "foreach" "function" "global"
+ "goto" "if" "implements" "include" "instanceof" "interface"
+ "isset" "list" "namespace" "new" "old_function" "or" "php_user_filter"
+ "print" "private" "protected" "public" "require" "require_once" "return"
+ "static" "switch" "this" "throw" "try" "unset" "use" "var" "while" "xor")
+ (python-mode
+ "and" "assert" "break" "class" "continue" "def" "del" "elif" "else"
+ "except" "exec" "finally" "for" "from" "global" "if" "import" "in" "is"
+ "lambda" "not" "or" "pass" "print" "raise" "return" "try" "while" "yield")
+ (ruby-mode
+ "BEGIN" "END" "alias" "and" "begin" "break" "case" "class" "def" "defined"
+ "do" "else" "elsif" "end" "ensure" "false" "for" "if" "in" "module"
+ "next" "nil" "not" "or" "redo" "rescue" "retry" "return" "self" "super"
+ "then" "true" "undef" "unless" "until" "when" "while" "yield")
+ ;; aliases
+ (js2-mode . javascript-mode)
+ (espresso-mode . javascript-mode)
+ (cperl-mode . perl-mode)
+ (jde-mode . java-mode))
+ "*Alist mapping major-modes to sorted keywords for `company-keywords'.")
+
+;;;###autoload
+(defun company-keywords (command &optional arg &rest ignored)
+ "A `company-mode' back-end for programming language keywords."
+ (interactive (list 'interactive))
+ (case command
+ ('interactive (company-begin-backend 'company-))
+ ('prefix (and (assq major-mode company-keywords-alist)
+ (not (company-in-string-or-comment))
+ (or (company-grab-symbol) 'stop)))
+ ('candidates
+ (let ((completion-ignore-case nil)
+ (symbols (cdr (assq major-mode company-keywords-alist))))
+ (all-completions arg (if (consp symbols)
+ symbols
+ (cdr (assq symbols company-keywords-alist))))))
+ ('sorted t)))
+
+(provide 'company-keywords)
+;;; company-keywords.el ends here
+
+
--- /dev/null
+;;; company-nxml.el --- a company-mode completion back-end for nxml-mode
+
+;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'company)
+(require 'nxml-mode)
+(require 'rng-nxml)
+(eval-when-compile (require 'cl))
+
+(defconst company-nxml-token-regexp
+ "\\(?:[_[:alpha:]][-._[:alnum:]]*\\_>\\)")
+
+(defvar company-nxml-in-attribute-value-regexp
+ (replace-regexp-in-string "w" company-nxml-token-regexp
+ "<w\\(?::w\\)?\
+\\(?:[ \t\r\n]+w\\(?::w\\)?[ \t\r\n]*=\
+[ \t\r\n]*\\(?:\"[^\"]*\"\\|'[^']*'\\)\\)*\
+[ \t\r\n]+\\(w\\(:w\\)?\\)[ \t\r\n]*=[ \t\r\n]*\
+\\(\"\\([^\"]*\\>\\)\\|'\\([^']*\\>\\)\\)\\="
+ t t))
+
+(defvar company-nxml-in-tag-name-regexp
+ (replace-regexp-in-string "w" company-nxml-token-regexp
+ "<\\(/?w\\(?::w?\\)?\\)?\\=" t t))
+
+(defun company-nxml-all-completions (prefix alist)
+ (let ((candidates (mapcar 'cdr alist))
+ (case-fold-search nil)
+ filtered)
+ (when (cdar rng-open-elements)
+ (push (concat "/" (cdar rng-open-elements)) candidates))
+ (setq candidates (sort (all-completions prefix candidates) 'string<))
+ (while candidates
+ (unless (equal (car candidates) (car filtered))
+ (push (car candidates) filtered))
+ (pop candidates))
+ (nreverse filtered)))
+
+(defmacro company-nxml-prepared (&rest body)
+ (declare (indent 0) (debug t))
+ `(let ((lt-pos (save-excursion (search-backward "<" nil t)))
+ xmltok-dtd)
+ (when (and lt-pos (= (rng-set-state-after lt-pos) lt-pos))
+ ,@body)))
+
+(defun company-nxml-tag (command &optional arg &rest ignored)
+ (case command
+ ('prefix (and (derived-mode-p 'nxml-mode)
+ rng-validate-mode
+ (company-grab company-nxml-in-tag-name-regexp 1)))
+ ('candidates (company-nxml-prepared
+ (company-nxml-all-completions arg
+ (rng-match-possible-start-tag-names))))
+ ('sorted t)))
+
+(defun company-nxml-attribute (command &optional arg &rest ignored)
+ (case command
+ ('prefix (and (derived-mode-p 'nxml-mode)
+ rng-validate-mode
+ (memq (char-after) '(?\ ?\t ?\n)) ;; outside word
+ (company-grab rng-in-attribute-regex 1)))
+ ('candidates (company-nxml-prepared
+ (and (rng-adjust-state-for-attribute
+ lt-pos (- (point) (length arg)))
+ (company-nxml-all-completions arg
+ (rng-match-possible-attribute-names)))))
+ ('sorted t)))
+
+(defun company-nxml-attribute-value (command &optional arg &rest ignored)
+ (case command
+ ('prefix (and (derived-mode-p 'nxml-mode)
+ rng-validate-mode
+ (and (memq (char-after) '(?' ?\" ?\ ?\t ?\n)) ;; outside word
+ (looking-back company-nxml-in-attribute-value-regexp)
+ (or (match-string-no-properties 4)
+ (match-string-no-properties 5)
+ ""))))
+ ('candidates (company-nxml-prepared
+ (let (attr-start attr-end colon)
+ (and (looking-back rng-in-attribute-value-regex lt-pos)
+ (setq colon (match-beginning 2)
+ attr-start (match-beginning 1)
+ attr-end (match-end 1))
+ (rng-adjust-state-for-attribute lt-pos attr-start)
+ (rng-adjust-state-for-attribute-value
+ attr-start colon attr-end)
+ (all-completions arg
+ (rng-match-possible-value-strings))))))))
+
+;;;###autoload
+(defun company-nxml (command &optional arg &rest ignored)
+ "A `company-mode' completion back-end for `nxml-mode'."
+ (interactive (list 'interactive))
+ (case command
+ ('interactive (company-begin-backend 'company-nxml))
+ ('prefix (or (company-nxml-tag 'prefix)
+ (company-nxml-attribute 'prefix)
+ (company-nxml-attribute-value 'prefix)))
+ ('candidates (cond
+ ((company-nxml-tag 'prefix)
+ (company-nxml-tag 'candidates arg))
+ ((company-nxml-attribute 'prefix)
+ (company-nxml-attribute 'candidates arg))
+ ((company-nxml-attribute-value 'prefix)
+ (sort (company-nxml-attribute-value 'candidates arg)
+ 'string<))))
+ ('sorted t)))
+
+(provide 'company-nxml)
+;;; company-nxml.el ends here
--- /dev/null
+;;; company-oddmuse.el --- a company-mode completion back-end for oddmuse-mode
+
+;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'company)
+(eval-when 'compile (require 'yaooddmuse nil t))
+(eval-when 'compile (require 'oddmuse nil t))
+(eval-when-compile (require 'cl))
+
+(defvar company-oddmuse-link-regexp
+ "\\(\\<[A-Z][[:alnum:]]*\\>\\)\\|\\[\\[\\([[:alnum:]]+\\>\\|\\)")
+
+(defun company-oddmuse-get-page-table ()
+ (case major-mode
+ ('yaoddmuse-mode (with-no-warnings
+ (yaoddmuse-get-pagename-table yaoddmuse-wikiname)))
+ ('oddmuse-mode (with-no-warnings
+ (oddmuse-make-completion-table oddmuse-wiki)))))
+
+;;;###autoload
+(defun company-oddmuse (command &optional arg &rest ignored)
+ "A `company-mode' completion back-end for `oddmuse-mode'."
+ (interactive (list 'interactive))
+ (case command
+ ('interactive (company-begin-backend 'company-oddmuse))
+ ('prefix (let ((case-fold-search nil))
+ (and (memq major-mode '(oddmuse-mode yaoddmuse-mode))
+ (looking-back company-oddmuse-link-regexp (point-at-bol))
+ (or (match-string 1)
+ (match-string 2)))))
+ ('candidates (all-completions arg (company-oddmuse-get-page-table)))))
+
+(provide 'company-oddmuse)
+;;; company-oddmuse.el ends here
--- /dev/null
+(define-package "company" "0.5" "Flexible inline text and code completion")
--- /dev/null
+;;; company-pysmell.el --- a company-mode completion back-end for pysmell.el
+
+;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+(require 'pysmell)
+
+(defvar company-pysmell--available-p 'unknown)
+(make-variable-buffer-local 'company-pysmell--available-p)
+
+(defun company-pysmell--available-p ()
+ (if (eq company-pysmell--available-p 'unknown)
+ (setq company-pysmell--available-p
+ (company-locate-dominating-file buffer-file-name "PYSMELLTAGS"))
+ company-pysmell--available-p))
+
+(defun company-pysmell--grab-symbol ()
+ (let ((symbol (company-grab-symbol)))
+ (when symbol
+ (cons symbol
+ (save-excursion
+ (let ((pos (point)))
+ (goto-char (- (point) (length symbol)))
+ (while (eq (char-before) ?.)
+ (goto-char (1- (point)))
+ (skip-syntax-backward "w_"))
+ (- pos (point))))))))
+
+;;;###autoload
+(defun company-pysmell (command &optional arg &rest ignored)
+ "A `company-mode' completion back-end for pysmell.
+This requires pysmell.el and pymacs.el."
+ (interactive (list 'interactive))
+ (case command
+ ('interactive (company-begin-backend 'company-pysmell))
+ ('prefix (and (derived-mode-p 'python-mode)
+ buffer-file-name
+ (not (company-in-string-or-comment))
+ (company-pysmell--available-p)
+ (company-pysmell--grab-symbol)))
+ ('candidates (delete "" (pysmell-get-all-completions)))))
+
+(provide 'company-pysmell)
+;;; company-pysmell.el ends here
--- /dev/null
+;;; company-ropemacs.el --- a company-mode completion back-end for pysmell.el
+
+;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+(require 'pymacs)
+
+(unless (fboundp 'rope-completions)
+ (pymacs-load "ropemacs" "rope-"))
+
+(unless (fboundp 'rope-completions)
+ (error "rope-completions not found, try development version of ropemacs"))
+
+(defun company-ropemacs--grab-symbol ()
+ (let ((symbol (company-grab-symbol)))
+ (when symbol
+ (cons symbol
+ (save-excursion
+ (let ((pos (point)))
+ (goto-char (- (point) (length symbol)))
+ (while (eq (char-before) ?.)
+ (goto-char (1- (point)))
+ (skip-syntax-backward "w_"))
+ (- pos (point))))))))
+
+(defun company-ropemacs-doc-buffer (candidate)
+ "Return buffer with docstring of CANDIDATE if it is available."
+ (let ((doc (company-with-candidate-inserted candidate (rope-get-doc))))
+ (when doc
+ (with-current-buffer (company-doc-buffer)
+ (insert doc)
+ (current-buffer)))))
+
+(defun company-ropemacs-location (candidate)
+ "Return location of CANDIDATE in cons form (FILE . LINE) if it is available."
+ (let ((location (company-with-candidate-inserted candidate
+ (rope-definition-location))))
+ (when location
+ (cons (elt location 0) (elt location 1)))))
+
+(defun company-ropemacs (command &optional arg &rest ignored)
+ "A `company-mode' completion back-end for ropemacs."
+ (interactive (list 'interactive))
+ (case command
+ ('interactive (company-begin-backend 'company-ropemacs))
+ ('prefix (and (derived-mode-p 'python-mode)
+ (not (company-in-string-or-comment))
+ (company-ropemacs--grab-symbol)))
+ ('candidates (mapcar (lambda (element) (concat arg element))
+ (rope-completions)))
+ ('doc-buffer (company-ropemacs-doc-buffer arg))
+ ('location (company-ropemacs-location arg))))
+
+(provide 'company-ropemacs)
+;;; company-ropemacs.el ends here
--- /dev/null
+;;; company-semantic.el --- a company-mode back-end using CEDET Semantic
+
+;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'company)
+(or (require 'semantic-analyze nil t)
+ (require 'semantic/analyze))
+(eval-when-compile (require 'cl))
+
+(defcustom company-semantic-metadata-function 'company-semantic-summary-and-doc
+ "*The function turning a semantic tag into doc information."
+ :group 'company
+ :type 'function)
+
+(defvar company-semantic-modes '(c-mode c++-mode jde-mode java-mode))
+
+(defvar company-semantic--current-tags nil
+ "Tags for the current context")
+
+(defun company-semantic-doc-or-summary (tag)
+ (or (semantic-documentation-for-tag tag)
+ (and (require 'semantic-idle nil t)
+ (require 'semantic/idle nil t)
+ (funcall semantic-idle-summary-function tag nil t))))
+
+(defun company-semantic-summary-and-doc (tag)
+ (let ((doc (semantic-documentation-for-tag tag))
+ (summary (funcall semantic-idle-summary-function tag nil t)))
+ (and (stringp doc)
+ (string-match "\n*\\(.*\\)$" doc)
+ (setq doc (match-string 1 doc)))
+ (concat (funcall semantic-idle-summary-function tag nil t)
+ (when doc
+ (if (< (+ (length doc) (length summary) 4) (window-width))
+ " -- "
+ "\n"))
+ doc)))
+
+(defun company-semantic-doc-buffer (tag)
+ (let ((doc (semantic-documentation-for-tag tag)))
+ (when doc
+ (with-current-buffer (company-doc-buffer)
+ (insert (funcall semantic-idle-summary-function tag nil t)
+ "\n"
+ doc)
+ (current-buffer)))))
+
+(defsubst company-semantic-completions (prefix)
+ (ignore-errors
+ (let ((completion-ignore-case nil)
+ (context (semantic-analyze-current-context)))
+ (setq company-semantic--current-tags
+ (semantic-analyze-possible-completions context))
+ (all-completions prefix company-semantic--current-tags))))
+
+(defun company-semantic-completions-raw (prefix)
+ (setq company-semantic--current-tags nil)
+ (dolist (tag (semantic-analyze-find-tags-by-prefix prefix))
+ (unless (eq (semantic-tag-class tag) 'include)
+ (push tag company-semantic--current-tags)))
+ (delete "" (mapcar 'semantic-tag-name company-semantic--current-tags)))
+
+(defun company-semantic--pre-prefix-length (prefix-length)
+ "Sum up the length of all chained symbols before POS.
+Symbols are chained by \".\" or \"->\"."
+ (save-excursion
+ (let ((pos (point)))
+ (goto-char (- (point) prefix-length))
+ (while (looking-back "->\\|\\.")
+ (goto-char (match-beginning 0))
+ (skip-syntax-backward "w_"))
+ (- pos (point)))))
+
+(defun company-semantic--grab ()
+ "Grab the semantic prefix, but return everything before -> or . as length."
+ (let ((symbol (company-grab-symbol)))
+ (when symbol
+ (cons symbol (company-semantic--pre-prefix-length (length symbol))))))
+
+;;;###autoload
+(defun company-semantic (command &optional arg &rest ignored)
+ "A `company-mode' completion back-end using CEDET Semantic."
+ (interactive (list 'interactive))
+ (case command
+ ('interactive (company-begin-backend 'company-semantic))
+ ('prefix (and (memq major-mode company-semantic-modes)
+ (semantic-active-p)
+ (not (company-in-string-or-comment))
+ (or (company-semantic--grab) 'stop)))
+ ('candidates (if (and (equal arg "")
+ (not (looking-back "->\\|\\.")))
+ (company-semantic-completions-raw arg)
+ (company-semantic-completions arg)))
+ ('meta (funcall company-semantic-metadata-function
+ (assoc arg company-semantic--current-tags)))
+ ('doc-buffer (company-semantic-doc-buffer
+ (assoc arg company-semantic--current-tags)))
+ ;; because "" is an empty context and doesn't return local variables
+ ('no-cache (equal arg ""))
+ ('location (let ((tag (assoc arg company-semantic--current-tags)))
+ (when (buffer-live-p (semantic-tag-buffer tag))
+ (cons (semantic-tag-buffer tag)
+ (semantic-tag-start tag)))))))
+
+(provide 'company-semantic)
+;;; company-semantic.el ends here
--- /dev/null
+;;; company-template.el
+
+;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+
+(defface company-template-field
+ '((((background dark)) (:background "yellow" :foreground "black"))
+ (((background light)) (:background "orange" :foreground "black")))
+ "*Face used for editable text in template fields."
+ :group 'company)
+
+(defvar company-template-nav-map
+ (let ((keymap (make-sparse-keymap)))
+ (define-key keymap [remap forward-word] 'company-template-forward-field)
+ (define-key keymap [remap subword-forward] 'company-template-forward-field)
+ ;; M-n
+ keymap))
+
+;; interactive ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defsubst company-template-templates-at (pos)
+ (let (os)
+ (dolist (o (overlays-at pos))
+ (when (overlay-get o 'company-template-fields)
+ (push o os)))
+ os))
+
+(defun company-template-move-to-first (templ)
+ (interactive)
+ (let ((fields (overlay-get templ 'company-template-fields)))
+ (push-mark)
+ (goto-char (apply 'min (mapcar 'overlay-start fields)))))
+
+(defun company-template-forward-field ()
+ (interactive)
+ (let* ((templates (company-template-templates-at (point)))
+ (minimum (apply 'max (mapcar 'overlay-end templates)))
+ (fields (apply 'append
+ (mapcar (lambda (templ)
+ (overlay-get templ 'company-template-fields))
+ templates))))
+ (dolist (pos (mapcar 'overlay-start fields))
+ (and pos
+ (> pos (point))
+ (< pos minimum)
+ (setq minimum pos)))
+ (push-mark)
+ (goto-char minimum)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar company-template--buffer-templates nil)
+(make-variable-buffer-local 'company-template--buffer-templates)
+
+(defun company-template-declare-template (beg end)
+ (let ((ov (make-overlay beg end)))
+ ;; (overlay-put ov 'face 'highlight)
+ (overlay-put ov 'keymap company-template-nav-map)
+ (overlay-put ov 'evaporate t)
+ (push ov company-template--buffer-templates)
+ (add-hook 'post-command-hook 'company-template-post-command nil t)
+ ov))
+
+(defun company-template-remove-template (templ)
+ (mapc 'company-template-remove-field
+ (overlay-get templ 'company-template-fields))
+ (setq company-template--buffer-templates
+ (delq templ company-template--buffer-templates))
+ (delete-overlay templ))
+
+(defun company-template-add-field (templ pos text)
+ (assert templ)
+ (save-excursion
+ ;; (goto-char pos)
+ (let ((ov (make-overlay pos pos))
+ (siblings (overlay-get templ 'company-template-fields))
+ (label (propertize text 'face 'company-template-field
+ 'company-template-parent templ)))
+ (overlay-put ov 'face 'highlight)
+ (add-text-properties 0 1 '(cursor t) label)
+ (overlay-put ov 'after-string label)
+ ;; (overlay-put ov 'evaporate t)
+ (overlay-put ov 'intangible t)
+ (overlay-put ov 'company-template-parent templ)
+ (overlay-put ov 'insert-in-front-hooks '(company-template-remove))
+ (push ov siblings)
+ (overlay-put templ 'company-template-fields siblings))))
+
+(defun company-template-remove-field (field)
+ (when (overlayp field)
+ ;; (delete-region (overlay-start field) (overlay-end field))
+ (delete-overlay field))
+ ;; TODO: unlink
+ )
+
+(defun company-template-clean-up (&optional pos)
+ "Clean up all templates that don't contain POS."
+ (unless pos (setq pos (point)))
+ (let ((local-ovs (overlays-in (- pos 2) pos)))
+ (dolist (templ company-template--buffer-templates)
+ (unless (memq templ local-ovs)
+ (company-template-remove-template templ)))))
+
+;; hooks ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun company-template-remove (overlay after-p beg end &optional r)
+ "Called when a snippet input prompt is modified."
+ (when after-p
+ (delete-overlay overlay)))
+
+(defun company-template-post-command ()
+ (company-template-clean-up)
+ (unless company-template--buffer-templates
+ (remove-hook 'post-command-hook 'company-template-post-command t)))
+
+(provide 'company-template)
+
+;;; company-template.el ends here
--- /dev/null
+;;; company-tempo.el --- a company-mode completion back-end for tempo
+
+;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'company)
+(eval-when-compile (require 'cl))
+(require 'tempo)
+
+(defsubst company-tempo-lookup (match)
+ (cdr (assoc match (tempo-build-collection))))
+
+(defun company-tempo-insert (match)
+ "Replace MATCH with the expanded tempo template."
+ (search-backward match)
+ (goto-char (match-beginning 0))
+ (replace-match "")
+ (call-interactively (company-tempo-lookup match)))
+
+(defsubst company-tempo-meta (match)
+ (let ((templ (company-tempo-lookup match))
+ doc)
+ (and templ
+ (setq doc (documentation templ t))
+ (car (split-string doc "\n" t)))))
+
+;;;###autoload
+(defun company-tempo (command &optional arg &rest ignored)
+ "A `company-mode' completion back-end for tempo."
+ (interactive (list 'interactive))
+ (case command
+ ('interactive (company-begin-backend 'company-tempo
+ 'company-tempo-insert))
+ ('prefix (or (car (tempo-find-match-string tempo-match-finder)) ""))
+ ('candidates (all-completions arg (tempo-build-collection)))
+ ('meta (company-tempo-meta arg))
+ ('require-match t)
+ ('sorted t)))
+
+(provide 'company-tempo)
+;;; company-tempo.el ends here
--- /dev/null
+;;; company-xcode.el --- a company-mode completion back-end for Xcode projects
+
+;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'company)
+(eval-when-compile (require 'cl))
+
+(defcustom company-xcode-xcodeindex-executable (executable-find "xcodeindex")
+ "*Location of xcodeindex executable"
+ :group 'company-xcode
+ :type 'file)
+
+(defvar company-xcode-tags nil)
+
+(defun company-xcode-reset ()
+ "Reset the cached tags."
+ (interactive)
+ (setq company-xcode-tags nil))
+
+(defcustom company-xcode-types
+ '("Class" "Constant" "Enum" "Macro" "Modeled Class" "Structure"
+ "Type" "Union" "Function")
+ "*The types of symbols offered by `company-xcode'
+No context-enabled completion is available. Types like methods will be
+offered regardless of whether the class supports them. The defaults should be
+valid in most contexts."
+ :set (lambda (variable value)
+ (set variable value)
+ (company-xcode-reset))
+ :group 'company-xcode
+ :type '(set (const "Category") (const "Class") (const "Class Method")
+ (const "Class Variable") (const "Constant") (const "Enum")
+ (const "Field") (const "Instance Method")
+ (const "Instance Variable") (const "Macro")
+ (const "Modeled Class") (const "Modeled Method")
+ (const "Modeled Property") (const "Property") (const "Protocol")
+ (const "Structure") (const "Type") (const "Union")
+ (const "Variable") (const "Function")))
+
+(defvar company-xcode-project 'unknown)
+(make-variable-buffer-local 'company-xcode-project)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun company-xcode-fetch (project-bundle)
+ (setq project-bundle (directory-file-name project-bundle))
+ (message "Retrieving dump from %s..." project-bundle)
+ (with-temp-buffer
+ (let ((default-directory (file-name-directory project-bundle)))
+ (call-process company-xcode-xcodeindex-executable nil (current-buffer)
+ nil "dump" "-project"
+ (file-name-nondirectory project-bundle) "-quiet")
+ (goto-char (point-min))
+ (let ((regexp (concat "^\\([^\t\n]*\\)\t[^\t\n]*\t"
+ (regexp-opt company-xcode-types)
+ "\t[^\t\n]*\t[^\t\n]*"))
+ candidates)
+ (while (re-search-forward regexp nil t)
+ (add-to-list 'candidates (match-string 1)))
+ (message "Retrieving dump from %s...done" project-bundle)
+ candidates))))
+
+(defun company-xcode-find-project ()
+ (let ((dir (if buffer-file-name
+ (file-name-directory buffer-file-name)
+ (expand-file-name default-directory)))
+ (prev-dir nil)
+ file)
+ (while (not (or file (equal dir prev-dir)))
+ (setq file (car (directory-files dir t ".xcodeproj\\'" t))
+ prev-dir dir
+ dir (file-name-directory (directory-file-name dir))))
+ file))
+
+(defun company-xcode-tags ()
+ (when (eq company-xcode-project 'unknown)
+ (setq company-xcode-project (company-xcode-find-project)))
+ (when company-xcode-project
+ (cdr (or (assoc company-xcode-project company-xcode-tags)
+ (car (push (cons company-xcode-project
+ (company-xcode-fetch company-xcode-project))
+ company-xcode-tags))))))
+;;;###autoload
+(defun company-xcode (command &optional arg &rest ignored)
+ "A `company-mode' completion back-end for Xcode projects."
+ (interactive (list 'interactive))
+ (case command
+ ('interactive (company-begin-backend 'company-xcode))
+ ('prefix (and company-xcode-xcodeindex-executable
+ (company-xcode-tags)
+ (not (company-in-string-or-comment))
+ (or (company-grab-symbol) 'stop)))
+ ('candidates (let ((completion-ignore-case nil))
+ (company-xcode-tags)
+ (all-completions arg (company-xcode-tags))))))
+
+
+(provide 'company-xcode)
+;;; company-xcode.el ends here
--- /dev/null
+;;; company.el --- extensible inline text completion mechanism
+
+;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+;; Version: 0.5
+;; Keywords: abbrev, convenience, matching
+;; URL: http://nschum.de/src/emacs/company/
+;; Compatibility: GNU Emacs 22.x, GNU Emacs 23.x
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; Company is a modular completion mechanism. Modules for retrieving completion
+;; candidates are called back-ends, modules for displaying them are front-ends.
+;;
+;; Company comes with many back-ends, e.g. `company-elisp'. These are
+;; distributed in individual files and can be used individually.
+;;
+;; Place company.el and the back-ends you want to use in a directory and add the
+;; following to your .emacs:
+;; (add-to-list 'load-path "/path/to/company")
+;; (autoload 'company-mode "company" nil t)
+;;
+;; Enable company-mode with M-x company-mode. For further information look at
+;; the documentation for `company-mode' (C-h f company-mode RET)
+;;
+;; If you want to start a specific back-end, call it interactively or use
+;; `company-begin-backend'. For example:
+;; M-x company-abbrev will prompt for and insert an abbrev.
+;;
+;; To write your own back-end, look at the documentation for `company-backends'.
+;; Here is a simple example completing "foo":
+;;
+;; (defun company-my-backend (command &optional arg &rest ignored)
+;; (case command
+;; ('prefix (when (looking-back "foo\\>")
+;; (match-string 0)))
+;; ('candidates (list "foobar" "foobaz" "foobarbaz"))
+;; ('meta (format "This value is named %s" arg))))
+;;
+;; Sometimes it is a good idea to mix two back-ends together, for example to
+;; enrich gtags with dabbrev-code results (to emulate local variables):
+;; To do this, add a list with the merged back-ends as an element in
+;; company-backends.
+;;
+;; Known Issues:
+;; When point is at the very end of the buffer, the pseudo-tooltip appears very
+;; wrong, unless company is allowed to temporarily insert a fake newline.
+;; This behavior is enabled by `company-end-of-buffer-workaround'.
+;;
+;;; Change Log:
+;;
+;; 2010-02-24 (0.5)
+;; `company-ropemacs' now provides location and docs. (Fernando H. Silva)
+;; Added `company-with-candidate-inserted' macro.
+;; Added `company-clang' back-end.
+;; Added new mechanism for non-consecutive insertion.
+;; (So far only used by clang for ObjC.)
+;; The semantic back-end now shows meta information for local symbols.
+;; Added compatibility for CEDET in Emacs 23.2 and from CVS. (Oleg Andreev)
+;;
+;; 2009-05-07 (0.4.3)
+;; Added `company-other-backend'.
+;; Idle completion no longer interrupts multi-key command input.
+;; Added `company-ropemacs' and `company-pysmell' back-ends.
+;;
+;; 2009-04-25 (0.4.2)
+;; In C modes . and -> now count towards `company-minimum-prefix-length'.
+;; Reverted default front-end back to `company-preview-if-just-one-frontend'.
+;; The pseudo tooltip will no longer be clipped at the right window edge.
+;; Added `company-tooltip-minimum'.
+;; Windows compatibility fixes.
+;;
+;; 2009-04-19 (0.4.1)
+;; Added `global-company-mode'.
+;; Performance enhancements.
+;; Added `company-eclim' back-end.
+;; Added safer workaround for Emacs `posn-col-row' bug.
+;;
+;; 2009-04-18 (0.4)
+;; Automatic completion is now aborted if the prefix gets too short.
+;; Added option `company-dabbrev-time-limit'.
+;; `company-backends' now supports merging back-ends.
+;; Added back-end `company-dabbrev-code' for generic code.
+;; Fixed `company-begin-with'.
+;;
+;; 2009-04-15 (0.3.1)
+;; Added 'stop prefix to prevent dabbrev from completing inside of symbols.
+;; Fixed issues with tabbar-mode and line-spacing.
+;; Performance enhancements.
+;;
+;; 2009-04-12 (0.3)
+;; Added `company-begin-commands' option.
+;; Added abbrev, tempo and Xcode back-ends.
+;; Back-ends are now interactive. You can start them with M-x backend-name.
+;; Added `company-begin-with' for starting company from elisp-code.
+;; Added hooks.
+;; Added `company-require-match' and `company-auto-complete' options.
+;;
+;; 2009-04-05 (0.2.1)
+;; Improved Emacs Lisp back-end behavior for local variables.
+;; Added `company-elisp-detect-function-context' option.
+;; The mouse can now be used for selection.
+;;
+;; 2009-03-22 (0.2)
+;; Added `company-show-location'.
+;; Added etags back-end.
+;; Added work-around for end-of-buffer bug.
+;; Added `company-filter-candidates'.
+;; More local Lisp variables are now included in the candidates.
+;;
+;; 2009-03-21 (0.1.5)
+;; Fixed elisp documentation buffer always showing the same doc.
+;; Added `company-echo-strip-common-frontend'.
+;; Added `company-show-numbers' option and M-0 ... M-9 default bindings.
+;; Don't hide the echo message if it isn't shown.
+;;
+;; 2009-03-20 (0.1)
+;; Initial release.
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+
+(add-to-list 'debug-ignored-errors "^.* frontend cannot be used twice$")
+(add-to-list 'debug-ignored-errors "^Echo area cannot be used twice$")
+(add-to-list 'debug-ignored-errors "^No \\(document\\|loc\\)ation available$")
+(add-to-list 'debug-ignored-errors "^Company not ")
+(add-to-list 'debug-ignored-errors "^No candidate number ")
+(add-to-list 'debug-ignored-errors "^Cannot complete at point$")
+(add-to-list 'debug-ignored-errors "^No other back-end$")
+
+(defgroup company nil
+ "Extensible inline text completion mechanism"
+ :group 'abbrev
+ :group 'convenience
+ :group 'matching)
+
+(defface company-tooltip
+ '((t :background "yellow"
+ :foreground "black"))
+ "*Face used for the tool tip."
+ :group 'company)
+
+(defface company-tooltip-selection
+ '((default :inherit company-tooltip)
+ (((class color) (min-colors 88)) (:background "orange1"))
+ (t (:background "green")))
+ "*Face used for the selection in the tool tip."
+ :group 'company)
+
+(defface company-tooltip-mouse
+ '((default :inherit highlight))
+ "*Face used for the tool tip item under the mouse."
+ :group 'company)
+
+(defface company-tooltip-common
+ '((t :inherit company-tooltip
+ :foreground "red"))
+ "*Face used for the common completion in the tool tip."
+ :group 'company)
+
+(defface company-tooltip-common-selection
+ '((t :inherit company-tooltip-selection
+ :foreground "red"))
+ "*Face used for the selected common completion in the tool tip."
+ :group 'company)
+
+(defface company-preview
+ '((t :background "blue4"
+ :foreground "wheat"))
+ "*Face used for the completion preview."
+ :group 'company)
+
+(defface company-preview-common
+ '((t :inherit company-preview
+ :foreground "red"))
+ "*Face used for the common part of the completion preview."
+ :group 'company)
+
+(defface company-preview-search
+ '((t :inherit company-preview
+ :background "blue1"))
+ "*Face used for the search string in the completion preview."
+ :group 'company)
+
+(defface company-echo nil
+ "*Face used for completions in the echo area."
+ :group 'company)
+
+(defface company-echo-common
+ '((((background dark)) (:foreground "firebrick1"))
+ (((background light)) (:background "firebrick4")))
+ "*Face used for the common part of completions in the echo area."
+ :group 'company)
+
+(defun company-frontends-set (variable value)
+ ;; uniquify
+ (let ((remainder value))
+ (setcdr remainder (delq (car remainder) (cdr remainder))))
+ (and (memq 'company-pseudo-tooltip-unless-just-one-frontend value)
+ (memq 'company-pseudo-tooltip-frontend value)
+ (error "Pseudo tooltip frontend cannot be used twice"))
+ (and (memq 'company-preview-if-just-one-frontend value)
+ (memq 'company-preview-frontend value)
+ (error "Preview frontend cannot be used twice"))
+ (and (memq 'company-echo value)
+ (memq 'company-echo-metadata-frontend value)
+ (error "Echo area cannot be used twice"))
+ ;; preview must come last
+ (dolist (f '(company-preview-if-just-one-frontend company-preview-frontend))
+ (when (memq f value)
+ (setq value (append (delq f value) (list f)))))
+ (set variable value))
+
+(defcustom company-frontends '(company-pseudo-tooltip-unless-just-one-frontend
+ company-preview-if-just-one-frontend
+ company-echo-metadata-frontend)
+ "*The list of active front-ends (visualizations).
+Each front-end is a function that takes one argument. It is called with
+one of the following arguments:
+
+'show: When the visualization should start.
+
+'hide: When the visualization should end.
+
+'update: When the data has been updated.
+
+'pre-command: Before every command that is executed while the
+visualization is active.
+
+'post-command: After every command that is executed while the
+visualization is active.
+
+The visualized data is stored in `company-prefix', `company-candidates',
+`company-common', `company-selection', `company-point' and
+`company-search-string'."
+ :set 'company-frontends-set
+ :group 'company
+ :type '(repeat (choice (const :tag "echo" company-echo-frontend)
+ (const :tag "echo, strip common"
+ company-echo-strip-common-frontend)
+ (const :tag "show echo meta-data in echo"
+ company-echo-metadata-frontend)
+ (const :tag "pseudo tooltip"
+ company-pseudo-tooltip-frontend)
+ (const :tag "pseudo tooltip, multiple only"
+ company-pseudo-tooltip-unless-just-one-frontend)
+ (const :tag "preview" company-preview-frontend)
+ (const :tag "preview, unique only"
+ company-preview-if-just-one-frontend)
+ (function :tag "custom function" nil))))
+
+(defcustom company-tooltip-limit 10
+ "*The maximum number of candidates in the tool tip"
+ :group 'company
+ :type 'integer)
+
+(defcustom company-tooltip-minimum 6
+ "*The minimum height of the tool tip.
+If this many lines are not available, prefer to display the tooltip above."
+ :group 'company
+ :type 'integer)
+
+(defvar company-safe-backends
+ '((company-abbrev . "Abbrev")
+ (company-clang . "clang")
+ (company-css . "CSS")
+ (company-dabbrev . "dabbrev for plain text")
+ (company-dabbrev-code . "dabbrev for code")
+ (company-eclim . "eclim (an Eclipse interace)")
+ (company-elisp . "Emacs Lisp")
+ (company-etags . "etags")
+ (company-files . "Files")
+ (company-gtags . "GNU Global")
+ (company-ispell . "ispell")
+ (company-keywords . "Programming language keywords")
+ (company-nxml . "nxml")
+ (company-oddmuse . "Oddmuse")
+ (company-pysmell . "PySmell")
+ (company-ropemacs . "ropemacs")
+ (company-semantic . "CEDET Semantic")
+ (company-tempo . "Tempo templates")
+ (company-xcode . "Xcode")))
+(put 'company-safe-backends 'risky-local-variable t)
+
+(defun company-safe-backends-p (backends)
+ (and (consp backends)
+ (not (dolist (backend backends)
+ (unless (if (consp backend)
+ (company-safe-backends-p backend)
+ (assq backend company-safe-backends))
+ (return t))))))
+
+(defcustom company-backends '(company-elisp company-nxml company-css
+ company-eclim company-semantic company-clang
+ company-xcode company-ropemacs
+ (company-gtags company-etags company-dabbrev-code
+ company-pysmell company-keywords)
+ company-oddmuse company-files company-dabbrev)
+ "*The list of active back-ends (completion engines).
+Each list elements can itself be a list of back-ends. In that case their
+completions are merged. Otherwise only the first matching back-end returns
+results.
+
+`company-begin-backend' can be used to start a specific back-end,
+`company-other-backend' will skip to the next matching back-end in the list.
+
+Each back-end is a function that takes a variable number of arguments.
+The first argument is the command requested from the back-end. It is one
+of the following:
+
+'prefix: The back-end should return the text to be completed. It must be
+text immediately before `point'. Returning nil passes control to the next
+back-end. The function should return 'stop if it should complete but cannot
+\(e.g. if it is in the middle of a string\). If the returned value is only
+part of the prefix (e.g. the part after \"->\" in C), the back-end may return a
+cons of prefix and prefix length, which is then used in the
+`company-minimum-prefix-length' test.
+
+'candidates: The second argument is the prefix to be completed. The
+return value should be a list of candidates that start with the prefix.
+
+Optional commands:
+
+'sorted: The back-end may return t here to indicate that the candidates
+are sorted and will not need to be sorted again.
+
+'duplicates: If non-nil, company will take care of removing duplicates
+from the list.
+
+'no-cache: Usually company doesn't ask for candidates again as completion
+progresses, unless the back-end returns t for this command. The second
+argument is the latest prefix.
+
+'meta: The second argument is a completion candidate. The back-end should
+return a (short) documentation string for it.
+
+'doc-buffer: The second argument is a completion candidate. The back-end should
+create a buffer (preferably with `company-doc-buffer'), fill it with
+documentation and return it.
+
+'location: The second argument is a completion candidate. The back-end can
+return the cons of buffer and buffer location, or of file and line
+number where the completion candidate was defined.
+
+'require-match: If this value is t, the user is not allowed to enter anything
+not offering as a candidate. Use with care! The default value nil gives the
+user that choice with `company-require-match'. Return value 'never overrides
+that option the other way around.
+
+The back-end should return nil for all commands it does not support or
+does not know about. It should also be callable interactively and use
+`company-begin-backend' to start itself in that case."
+ :group 'company
+ :type `(repeat
+ (choice
+ :tag "Back-end"
+ ,@(mapcar (lambda (b) `(const :tag ,(cdr b) ,(car b)))
+ company-safe-backends)
+ (symbol :tag "User defined")
+ (repeat :tag "Merged Back-ends"
+ (choice :tag "Back-end"
+ ,@(mapcar (lambda (b)
+ `(const :tag ,(cdr b) ,(car b)))
+ company-safe-backends)
+ (symbol :tag "User defined"))))))
+
+(put 'company-backends 'safe-local-variable 'company-safe-backends-p)
+
+(defcustom company-completion-started-hook nil
+ "*Hook run when company starts completing.
+The hook is called with one argument that is non-nil if the completion was
+started manually."
+ :group 'company
+ :type 'hook)
+
+(defcustom company-completion-cancelled-hook nil
+ "*Hook run when company cancels completing.
+The hook is called with one argument that is non-nil if the completion was
+aborted manually."
+ :group 'company
+ :type 'hook)
+
+(defcustom company-completion-finished-hook nil
+ "*Hook run when company successfully completes.
+The hook is called with the selected candidate as an argument."
+ :group 'company
+ :type 'hook)
+
+(defcustom company-minimum-prefix-length 3
+ "*The minimum prefix length for automatic completion."
+ :group 'company
+ :type '(integer :tag "prefix length"))
+
+(defcustom company-require-match 'company-explicit-action-p
+ "*If enabled, disallow non-matching input.
+This can be a function do determine if a match is required.
+
+This can be overridden by the back-end, if it returns t or 'never to
+'require-match. `company-auto-complete' also takes precedence over this."
+ :group 'company
+ :type '(choice (const :tag "Off" nil)
+ (function :tag "Predicate function")
+ (const :tag "On, if user interaction took place"
+ 'company-explicit-action-p)
+ (const :tag "On" t)))
+
+(defcustom company-auto-complete 'company-explicit-action-p
+ "Determines when to auto-complete.
+If this is enabled, all characters from `company-auto-complete-chars' complete
+the selected completion. This can also be a function."
+ :group 'company
+ :type '(choice (const :tag "Off" nil)
+ (function :tag "Predicate function")
+ (const :tag "On, if user interaction took place"
+ 'company-explicit-action-p)
+ (const :tag "On" t)))
+
+(defcustom company-auto-complete-chars '(?\ ?\( ?\) ?. ?\" ?$ ?\' ?< ?| ?!)
+ "Determines which characters trigger an automatic completion.
+See `company-auto-complete'. If this is a string, each string character causes
+completion. If it is a list of syntax description characters (see
+`modify-syntax-entry'), all characters with that syntax auto-complete.
+
+This can also be a function, which is called with the new input and should
+return non-nil if company should auto-complete.
+
+A character that is part of a valid candidate never starts auto-completion."
+ :group 'company
+ :type '(choice (string :tag "Characters")
+ (set :tag "Syntax"
+ (const :tag "Whitespace" ?\ )
+ (const :tag "Symbol" ?_)
+ (const :tag "Opening parentheses" ?\()
+ (const :tag "Closing parentheses" ?\))
+ (const :tag "Word constituent" ?w)
+ (const :tag "Punctuation." ?.)
+ (const :tag "String quote." ?\")
+ (const :tag "Paired delimiter." ?$)
+ (const :tag "Expression quote or prefix operator." ?\')
+ (const :tag "Comment starter." ?<)
+ (const :tag "Comment ender." ?>)
+ (const :tag "Character-quote." ?/)
+ (const :tag "Generic string fence." ?|)
+ (const :tag "Generic comment fence." ?!))
+ (function :tag "Predicate function")))
+
+(defcustom company-idle-delay .7
+ "*The idle delay in seconds until automatic completions starts.
+A value of nil means never complete automatically, t means complete
+immediately when a prefix of `company-minimum-prefix-length' is reached."
+ :group 'company
+ :type '(choice (const :tag "never (nil)" nil)
+ (const :tag "immediate (t)" t)
+ (number :tag "seconds")))
+
+(defcustom company-begin-commands t
+ "*A list of commands following which company will start completing.
+If this is t, it will complete after any command. See `company-idle-delay'.
+
+Alternatively any command with a non-nil 'company-begin property is treated as
+if it was on this list."
+ :group 'company
+ :type '(choice (const :tag "Any command" t)
+ (const :tag "Self insert command" '(self-insert-command))
+ (repeat :tag "Commands" function)))
+
+(defcustom company-show-numbers nil
+ "*If enabled, show quick-access numbers for the first ten candidates."
+ :group 'company
+ :type '(choice (const :tag "off" nil)
+ (const :tag "on" t)))
+
+(defvar company-end-of-buffer-workaround t
+ "*Work around a visualization bug when completing at the end of the buffer.
+The work-around consists of adding a newline.")
+
+;;; mode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar company-mode-map (make-sparse-keymap)
+ "Keymap used by `company-mode'.")
+
+(defvar company-active-map
+ (let ((keymap (make-sparse-keymap)))
+ (define-key keymap "\e\e\e" 'company-abort)
+ (define-key keymap "\C-g" 'company-abort)
+ (define-key keymap (kbd "M-n") 'company-select-next)
+ (define-key keymap (kbd "M-p") 'company-select-previous)
+ (define-key keymap (kbd "<down>") 'company-select-next)
+ (define-key keymap (kbd "<up>") 'company-select-previous)
+ (define-key keymap [down-mouse-1] 'ignore)
+ (define-key keymap [down-mouse-3] 'ignore)
+ (define-key keymap [mouse-1] 'company-complete-mouse)
+ (define-key keymap [mouse-3] 'company-select-mouse)
+ (define-key keymap [up-mouse-1] 'ignore)
+ (define-key keymap [up-mouse-3] 'ignore)
+ (define-key keymap "\C-m" 'company-complete-selection)
+ (define-key keymap "\t" 'company-complete-common)
+ (define-key keymap (kbd "<f1>") 'company-show-doc-buffer)
+ (define-key keymap "\C-w" 'company-show-location)
+ (define-key keymap "\C-s" 'company-search-candidates)
+ (define-key keymap "\C-\M-s" 'company-filter-candidates)
+ (dotimes (i 10)
+ (define-key keymap (vector (+ (aref (kbd "M-0") 0) i))
+ `(lambda () (interactive) (company-complete-number ,i))))
+
+ keymap)
+ "Keymap that is enabled during an active completion.")
+
+(defvar company--disabled-backends nil)
+
+(defun company-init-backend (backend)
+ (and (symbolp backend)
+ (not (fboundp backend))
+ (ignore-errors (require backend nil t)))
+
+ (if (or (symbolp backend)
+ (functionp backend))
+ (condition-case err
+ (progn
+ (funcall backend 'init)
+ (put backend 'company-init t))
+ (error
+ (put backend 'company-init 'failed)
+ (unless (memq backend company--disabled-backends)
+ (message "Company back-end '%s' could not be initialized:\n%s"
+ backend (error-message-string err)))
+ (push backend company--disabled-backends)
+ nil))
+ (mapc 'company-init-backend backend)))
+
+(defvar company-default-lighter " company")
+
+(defvar company-lighter company-default-lighter)
+(make-variable-buffer-local 'company-lighter)
+
+;;;###autoload
+(define-minor-mode company-mode
+ "\"complete anything\"; in in-buffer completion framework.
+Completion starts automatically, depending on the values
+`company-idle-delay' and `company-minimum-prefix-length'.
+
+Completion can be controlled with the commands:
+`company-complete-common', `company-complete-selection', `company-complete',
+`company-select-next', `company-select-previous'. If these commands are
+called before `company-idle-delay', completion will also start.
+
+Completions can be searched with `company-search-candidates' or
+`company-filter-candidates'. These can be used while completion is
+inactive, as well.
+
+The completion data is retrieved using `company-backends' and displayed using
+`company-frontends'. If you want to start a specific back-end, call it
+interactively or use `company-begin-backend'.
+
+regular keymap (`company-mode-map'):
+
+\\{company-mode-map}
+keymap during active completions (`company-active-map'):
+
+\\{company-active-map}"
+ nil company-lighter company-mode-map
+ (if company-mode
+ (progn
+ (add-hook 'pre-command-hook 'company-pre-command nil t)
+ (add-hook 'post-command-hook 'company-post-command nil t)
+ (mapc 'company-init-backend company-backends))
+ (remove-hook 'pre-command-hook 'company-pre-command t)
+ (remove-hook 'post-command-hook 'company-post-command t)
+ (company-cancel)
+ (kill-local-variable 'company-point)))
+
+(define-globalized-minor-mode global-company-mode company-mode
+ (lambda () (company-mode 1)))
+
+(defsubst company-assert-enabled ()
+ (unless company-mode
+ (company-uninstall-map)
+ (error "Company not enabled")))
+
+;;; keymaps ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar company-overriding-keymap-bound nil)
+(make-variable-buffer-local 'company-overriding-keymap-bound)
+
+(defvar company-old-keymap nil)
+(make-variable-buffer-local 'company-old-keymap)
+
+(defvar company-my-keymap nil)
+(make-variable-buffer-local 'company-my-keymap)
+
+(defsubst company-enable-overriding-keymap (keymap)
+ (setq company-my-keymap keymap)
+ (when company-overriding-keymap-bound
+ (company-uninstall-map)))
+
+(defun company-install-map ()
+ (unless (or company-overriding-keymap-bound
+ (null company-my-keymap))
+ (setq company-old-keymap overriding-terminal-local-map
+ overriding-terminal-local-map company-my-keymap
+ company-overriding-keymap-bound t)))
+
+(defun company-uninstall-map ()
+ (when (eq overriding-terminal-local-map company-my-keymap)
+ (setq overriding-terminal-local-map company-old-keymap
+ company-overriding-keymap-bound nil)))
+
+;; Hack:
+;; Emacs calculates the active keymaps before reading the event. That means we
+;; cannot change the keymap from a timer. So we send a bogus command.
+(defun company-ignore ()
+ (interactive)
+ (setq this-command last-command))
+
+(global-set-key '[31415926] 'company-ignore)
+
+(defun company-input-noop ()
+ (push 31415926 unread-command-events))
+
+;; Hack:
+;; posn-col-row is incorrect in older Emacsen when line-spacing is set
+(defun company--col-row (&optional pos)
+ (let ((posn (posn-at-point pos)))
+ (cons (car (posn-col-row posn)) (cdr (posn-actual-col-row posn)))))
+
+(defsubst company--column (&optional pos)
+ (car (posn-col-row (posn-at-point pos))))
+
+(defsubst company--row (&optional pos)
+ (cdr (posn-actual-col-row (posn-at-point pos))))
+
+;;; backends ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun company-grab (regexp &optional expression limit)
+ (when (looking-back regexp limit)
+ (or (match-string-no-properties (or expression 0)) "")))
+
+(defun company-grab-line (regexp &optional expression)
+ (company-grab regexp expression (point-at-bol)))
+
+(defun company-grab-symbol ()
+ (if (looking-at "\\_>")
+ (buffer-substring (point) (save-excursion (skip-syntax-backward "w_")
+ (point)))
+ (unless (and (char-after) (memq (char-syntax (char-after)) '(?w ?_)))
+ "")))
+
+(defun company-grab-word ()
+ (if (looking-at "\\>")
+ (buffer-substring (point) (save-excursion (skip-syntax-backward "w")
+ (point)))
+ (unless (and (char-after) (eq (char-syntax (char-after)) ?w))
+ "")))
+
+(defun company-in-string-or-comment ()
+ (let ((ppss (syntax-ppss)))
+ (or (car (setq ppss (nthcdr 3 ppss)))
+ (car (setq ppss (cdr ppss)))
+ (nth 3 ppss))))
+
+(if (fboundp 'locate-dominating-file)
+ (defalias 'company-locate-dominating-file 'locate-dominating-file)
+ (defun company-locate-dominating-file (file name)
+ (catch 'root
+ (let ((dir (file-name-directory file))
+ (prev-dir nil))
+ (while (not (equal dir prev-dir))
+ (when (file-exists-p (expand-file-name name dir))
+ (throw 'root dir))
+ (setq prev-dir dir
+ dir (file-name-directory (directory-file-name dir))))))))
+
+(defun company-call-backend (&rest args)
+ (if (functionp company-backend)
+ (apply company-backend args)
+ (apply 'company--multi-backend-adapter company-backend args)))
+
+(defun company--multi-backend-adapter (backends command &rest args)
+ (case command
+ ('candidates
+ (apply 'append (mapcar (lambda (backend) (apply backend command args))
+ backends)))
+ ('sorted nil)
+ ('duplicates t)
+ (otherwise
+ (let (value)
+ (dolist (backend backends)
+ (when (setq value (apply backend command args))
+ (return value)))))))
+
+;;; completion mechanism ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar company-backend nil)
+(make-variable-buffer-local 'company-backend)
+
+(defvar company-prefix nil)
+(make-variable-buffer-local 'company-prefix)
+
+(defvar company-candidates nil)
+(make-variable-buffer-local 'company-candidates)
+
+(defvar company-candidates-length nil)
+(make-variable-buffer-local 'company-candidates-length)
+
+(defvar company-candidates-cache nil)
+(make-variable-buffer-local 'company-candidates-cache)
+
+(defvar company-candidates-predicate nil)
+(make-variable-buffer-local 'company-candidates-predicate)
+
+(defvar company-common nil)
+(make-variable-buffer-local 'company-common)
+
+(defvar company-selection 0)
+(make-variable-buffer-local 'company-selection)
+
+(defvar company-selection-changed nil)
+(make-variable-buffer-local 'company-selection-changed)
+
+(defvar company--explicit-action nil
+ "Non-nil, if explicit completion took place.")
+(make-variable-buffer-local 'company--explicit-action)
+
+(defvar company--point-max nil)
+(make-variable-buffer-local 'company--point-max)
+
+(defvar company-point nil)
+(make-variable-buffer-local 'company-point)
+
+(defvar company-timer nil)
+
+(defvar company-added-newline nil)
+(make-variable-buffer-local 'company-added-newline)
+
+(defsubst company-strip-prefix (str)
+ (substring str (length company-prefix)))
+
+(defmacro company-with-candidate-inserted (candidate &rest body)
+ "Evaluate BODY with CANDIDATE temporarily inserted.
+This is a tool for back-ends that need candidates inserted before they
+can retrieve meta-data for them."
+ (declare (indent 1))
+ `(let ((inhibit-modification-hooks t)
+ (inhibit-point-motion-hooks t)
+ (modified-p (buffer-modified-p)))
+ (insert (company-strip-prefix ,candidate))
+ (unwind-protect
+ (progn ,@body)
+ (delete-region company-point (point)))))
+
+(defun company-explicit-action-p ()
+ "Return whether explicit completion action was taken by the user."
+ (or company--explicit-action
+ company-selection-changed))
+
+(defsubst company-reformat (candidate)
+ ;; company-ispell needs this, because the results are always lower-case
+ ;; It's mory efficient to fix it only when they are displayed.
+ (concat company-prefix (substring candidate (length company-prefix))))
+
+(defun company--should-complete ()
+ (and (not (or buffer-read-only overriding-terminal-local-map
+ overriding-local-map))
+ ;; Check if in the middle of entering a key combination.
+ (or (equal (this-command-keys-vector) [])
+ (not (keymapp (key-binding (this-command-keys-vector)))))
+ (eq company-idle-delay t)
+ (or (eq t company-begin-commands)
+ (memq this-command company-begin-commands)
+ (and (symbolp this-command) (get this-command 'company-begin)))
+ (not (and transient-mark-mode mark-active))))
+
+(defsubst company-call-frontends (command)
+ (dolist (frontend company-frontends)
+ (condition-case err
+ (funcall frontend command)
+ (error (error "Company: Front-end %s error \"%s\" on command %s"
+ frontend (error-message-string err) command)))))
+
+(defsubst company-set-selection (selection &optional force-update)
+ (setq selection (max 0 (min (1- company-candidates-length) selection)))
+ (when (or force-update (not (equal selection company-selection)))
+ (setq company-selection selection
+ company-selection-changed t)
+ (company-call-frontends 'update)))
+
+(defun company-apply-predicate (candidates predicate)
+ (let (new)
+ (dolist (c candidates)
+ (when (funcall predicate c)
+ (push c new)))
+ (nreverse new)))
+
+(defun company-update-candidates (candidates)
+ (setq company-candidates-length (length candidates))
+ (if (> company-selection 0)
+ ;; Try to restore the selection
+ (let ((selected (nth company-selection company-candidates)))
+ (setq company-selection 0
+ company-candidates candidates)
+ (when selected
+ (while (and candidates (string< (pop candidates) selected))
+ (incf company-selection))
+ (unless candidates
+ ;; Make sure selection isn't out of bounds.
+ (setq company-selection (min (1- company-candidates-length)
+ company-selection)))))
+ (setq company-selection 0
+ company-candidates candidates))
+ ;; Save in cache:
+ (push (cons company-prefix company-candidates) company-candidates-cache)
+ ;; Calculate common.
+ (let ((completion-ignore-case (company-call-backend 'ignore-case)))
+ (setq company-common (try-completion company-prefix company-candidates)))
+ (when (eq company-common t)
+ (setq company-candidates nil)))
+
+(defun company-calculate-candidates (prefix)
+ (let ((candidates (cdr (assoc prefix company-candidates-cache))))
+ (or candidates
+ (when company-candidates-cache
+ (let ((len (length prefix))
+ (completion-ignore-case (company-call-backend 'ignore-case))
+ prev)
+ (dotimes (i (1+ len))
+ (when (setq prev (cdr (assoc (substring prefix 0 (- len i))
+ company-candidates-cache)))
+ (setq candidates (all-completions prefix prev))
+ (return t)))))
+ ;; no cache match, call back-end
+ (progn
+ (setq candidates (company-call-backend 'candidates prefix))
+ (when company-candidates-predicate
+ (setq candidates
+ (company-apply-predicate candidates
+ company-candidates-predicate)))
+ (unless (company-call-backend 'sorted)
+ (setq candidates (sort candidates 'string<)))
+ (when (company-call-backend 'duplicates)
+ ;; strip duplicates
+ (let ((c2 candidates))
+ (while c2
+ (setcdr c2 (progn (while (equal (pop c2) (car c2)))
+ c2)))))))
+ (if (or (cdr candidates)
+ (not (equal (car candidates) prefix)))
+ ;; Don't start when already completed and unique.
+ candidates
+ ;; Not the right place? maybe when setting?
+ (and company-candidates t))))
+
+(defun company-idle-begin (buf win tick pos)
+ (and company-mode
+ (eq buf (current-buffer))
+ (eq win (selected-window))
+ (eq tick (buffer-chars-modified-tick))
+ (eq pos (point))
+ (not company-candidates)
+ (not (equal (point) company-point))
+ (let ((company-idle-delay t)
+ (company-begin-commands t))
+ (company-begin)
+ (when company-candidates
+ (company-input-noop)
+ (company-post-command)))))
+
+(defun company-auto-begin ()
+ (company-assert-enabled)
+ (and company-mode
+ (not company-candidates)
+ (let ((company-idle-delay t)
+ (company-minimum-prefix-length 0)
+ (company-begin-commands t))
+ (company-begin)))
+ ;; Return non-nil if active.
+ company-candidates)
+
+(defun company-manual-begin ()
+ (interactive)
+ (setq company--explicit-action t)
+ (company-auto-begin))
+
+(defun company-other-backend (&optional backward)
+ (interactive (list current-prefix-arg))
+ (company-assert-enabled)
+ (if company-backend
+ (let* ((after (cdr (member company-backend company-backends)))
+ (before (cdr (member company-backend (reverse company-backends))))
+ (next (if backward
+ (append before (reverse after))
+ (append after (reverse before)))))
+ (company-cancel)
+ (dolist (backend next)
+ (when (ignore-errors (company-begin-backend backend))
+ (return t))))
+ (company-manual-begin))
+ (unless company-candidates
+ (error "No other back-end")))
+
+(defun company-require-match-p ()
+ (let ((backend-value (company-call-backend 'require-match)))
+ (or (eq backend-value t)
+ (and (if (functionp company-require-match)
+ (funcall company-require-match)
+ (eq company-require-match t))
+ (not (eq backend-value 'never))))))
+
+(defun company-punctuation-p (input)
+ "Return non-nil, if input starts with punctuation or parentheses."
+ (memq (char-syntax (string-to-char input)) '(?. ?\( ?\))))
+
+(defun company-auto-complete-p (input)
+ "Return non-nil, if input starts with punctuation or parentheses."
+ (and (if (functionp company-auto-complete)
+ (funcall company-auto-complete)
+ company-auto-complete)
+ (if (functionp company-auto-complete-chars)
+ (funcall company-auto-complete-chars input)
+ (if (consp company-auto-complete-chars)
+ (memq (char-syntax (string-to-char input))
+ company-auto-complete-chars)
+ (string-match (substring input 0 1) company-auto-complete-chars)))))
+
+(defun company--incremental-p ()
+ (and (> (point) company-point)
+ (> (point-max) company--point-max)
+ (not (eq this-command 'backward-delete-char-untabify))
+ (equal (buffer-substring (- company-point (length company-prefix))
+ company-point)
+ company-prefix)))
+
+(defsubst company--string-incremental-p (old-prefix new-prefix)
+ (and (> (length new-prefix) (length old-prefix))
+ (equal old-prefix (substring new-prefix 0 (length old-prefix)))))
+
+(defun company--continue-failed (new-prefix)
+ (when (company--incremental-p)
+ (let ((input (buffer-substring-no-properties (point) company-point)))
+ (cond
+ ((company-auto-complete-p input)
+ ;; auto-complete
+ (save-excursion
+ (goto-char company-point)
+ (company-complete-selection)
+ nil))
+ ((and (company--string-incremental-p company-prefix new-prefix)
+ (company-require-match-p))
+ ;; wrong incremental input, but required match
+ (backward-delete-char (length input))
+ (ding)
+ (message "Matching input is required")
+ company-candidates)
+ ((equal company-prefix (car company-candidates))
+ ;; last input was actually success
+ (company-cancel company-prefix)
+ nil)))))
+
+(defun company--good-prefix-p (prefix)
+ (and (or (company-explicit-action-p)
+ (>= (or (cdr-safe prefix) (length prefix))
+ company-minimum-prefix-length))
+ (stringp (or (car-safe prefix) prefix))))
+
+(defun company--continue ()
+ (when (company-call-backend 'no-cache company-prefix)
+ ;; Don't complete existing candidates, fetch new ones.
+ (setq company-candidates-cache nil))
+ (let* ((new-prefix (company-call-backend 'prefix))
+ (c (when (and (company--good-prefix-p new-prefix)
+ (setq new-prefix (or (car-safe new-prefix) new-prefix))
+ (= (- (point) (length new-prefix))
+ (- company-point (length company-prefix))))
+ (setq new-prefix (or (car-safe new-prefix) new-prefix))
+ (company-calculate-candidates new-prefix))))
+ (or (cond
+ ((eq c t)
+ ;; t means complete/unique.
+ (company-cancel new-prefix)
+ nil)
+ ((consp c)
+ ;; incremental match
+ (setq company-prefix new-prefix)
+ (company-update-candidates c)
+ c)
+ (t (company--continue-failed new-prefix)))
+ (company-cancel))))
+
+(defun company--begin-new ()
+ (let (prefix c)
+ (dolist (backend (if company-backend
+ ;; prefer manual override
+ (list company-backend)
+ company-backends))
+ (setq prefix
+ (if (or (symbolp backend)
+ (functionp backend))
+ (when (or (not (symbolp backend))
+ (eq t (get backend 'company-init))
+ (unless (get backend 'company-init)
+ (company-init-backend backend)))
+ (funcall backend 'prefix))
+ (company--multi-backend-adapter backend 'prefix)))
+ (when prefix
+ (when (company--good-prefix-p prefix)
+ (setq prefix (or (car-safe prefix) prefix)
+ company-backend backend
+ c (company-calculate-candidates prefix))
+ ;; t means complete/unique. We don't start, so no hooks.
+ (if (not (consp c))
+ (when company--explicit-action
+ (message "No completion found"))
+ (setq company-prefix prefix)
+ (when (symbolp backend)
+ (setq company-lighter (concat " " (symbol-name backend))))
+ (company-update-candidates c)
+ (run-hook-with-args 'company-completion-started-hook
+ (company-explicit-action-p))
+ (company-call-frontends 'show)))
+ (return c)))))
+
+(defun company-begin ()
+ (setq company-candidates
+ (or (and company-candidates (company--continue))
+ (and (company--should-complete) (company--begin-new))))
+ (when company-candidates
+ (when (and company-end-of-buffer-workaround (eobp))
+ (save-excursion (insert "\n"))
+ (setq company-added-newline (buffer-chars-modified-tick)))
+ (setq company-point (point)
+ company--point-max (point-max))
+ (company-enable-overriding-keymap company-active-map)
+ (company-call-frontends 'update)))
+
+(defun company-cancel (&optional result)
+ (and company-added-newline
+ (> (point-max) (point-min))
+ (let ((tick (buffer-chars-modified-tick)))
+ (delete-region (1- (point-max)) (point-max))
+ (equal tick company-added-newline))
+ ;; Only set unmodified when tick remained the same since insert.
+ (set-buffer-modified-p nil))
+ (when company-prefix
+ (if (stringp result)
+ (progn
+ (company-call-backend 'pre-completion result)
+ (run-hook-with-args 'company-completion-finished-hook result)
+ (company-call-backend 'post-completion result))
+ (run-hook-with-args 'company-completion-cancelled-hook result)))
+ (setq company-added-newline nil
+ company-backend nil
+ company-prefix nil
+ company-candidates nil
+ company-candidates-length nil
+ company-candidates-cache nil
+ company-candidates-predicate nil
+ company-common nil
+ company-selection 0
+ company-selection-changed nil
+ company--explicit-action nil
+ company-lighter company-default-lighter
+ company--point-max nil
+ company-point nil)
+ (when company-timer
+ (cancel-timer company-timer))
+ (company-search-mode 0)
+ (company-call-frontends 'hide)
+ (company-enable-overriding-keymap nil))
+
+(defun company-abort ()
+ (interactive)
+ (company-cancel t)
+ ;; Don't start again, unless started manually.
+ (setq company-point (point)))
+
+(defun company-finish (result)
+ (insert (company-strip-prefix result))
+ (company-cancel result)
+ ;; Don't start again, unless started manually.
+ (setq company-point (point)))
+
+(defsubst company-keep (command)
+ (and (symbolp command) (get command 'company-keep)))
+
+(defun company-pre-command ()
+ (unless (company-keep this-command)
+ (condition-case err
+ (when company-candidates
+ (company-call-frontends 'pre-command))
+ (error (message "Company: An error occurred in pre-command")
+ (message "%s" (error-message-string err))
+ (company-cancel))))
+ (when company-timer
+ (cancel-timer company-timer)
+ (setq company-timer nil))
+ (company-uninstall-map))
+
+(defun company-post-command ()
+ (unless (company-keep this-command)
+ (condition-case err
+ (progn
+ (unless (equal (point) company-point)
+ (company-begin))
+ (if company-candidates
+ (company-call-frontends 'post-command)
+ (and (numberp company-idle-delay)
+ (or (eq t company-begin-commands)
+ (memq this-command company-begin-commands))
+ (setq company-timer
+ (run-with-timer company-idle-delay nil
+ 'company-idle-begin
+ (current-buffer) (selected-window)
+ (buffer-chars-modified-tick) (point))))))
+ (error (message "Company: An error occurred in post-command")
+ (message "%s" (error-message-string err))
+ (company-cancel))))
+ (company-install-map))
+
+;;; search ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar company-search-string nil)
+(make-variable-buffer-local 'company-search-string)
+
+(defvar company-search-lighter " Search: \"\"")
+(make-variable-buffer-local 'company-search-lighter)
+
+(defvar company-search-old-map nil)
+(make-variable-buffer-local 'company-search-old-map)
+
+(defvar company-search-old-selection 0)
+(make-variable-buffer-local 'company-search-old-selection)
+
+(defun company-search (text lines)
+ (let ((quoted (regexp-quote text))
+ (i 0))
+ (dolist (line lines)
+ (when (string-match quoted line (length company-prefix))
+ (return i))
+ (incf i))))
+
+(defun company-search-printing-char ()
+ (interactive)
+ (company-search-assert-enabled)
+ (setq company-search-string
+ (concat (or company-search-string "") (string last-command-event))
+ company-search-lighter (concat " Search: \"" company-search-string
+ "\""))
+ (let ((pos (company-search company-search-string
+ (nthcdr company-selection company-candidates))))
+ (if (null pos)
+ (ding)
+ (company-set-selection (+ company-selection pos) t))))
+
+(defun company-search-repeat-forward ()
+ "Repeat the incremental search in completion candidates forward."
+ (interactive)
+ (company-search-assert-enabled)
+ (let ((pos (company-search company-search-string
+ (cdr (nthcdr company-selection
+ company-candidates)))))
+ (if (null pos)
+ (ding)
+ (company-set-selection (+ company-selection pos 1) t))))
+
+(defun company-search-repeat-backward ()
+ "Repeat the incremental search in completion candidates backwards."
+ (interactive)
+ (company-search-assert-enabled)
+ (let ((pos (company-search company-search-string
+ (nthcdr (- company-candidates-length
+ company-selection)
+ (reverse company-candidates)))))
+ (if (null pos)
+ (ding)
+ (company-set-selection (- company-selection pos 1) t))))
+
+(defun company-create-match-predicate ()
+ (setq company-candidates-predicate
+ `(lambda (candidate)
+ ,(if company-candidates-predicate
+ `(and (string-match ,company-search-string candidate)
+ (funcall ,company-candidates-predicate
+ candidate))
+ `(string-match ,company-search-string candidate))))
+ (company-update-candidates
+ (company-apply-predicate company-candidates company-candidates-predicate))
+ ;; Invalidate cache.
+ (setq company-candidates-cache (cons company-prefix company-candidates)))
+
+(defun company-filter-printing-char ()
+ (interactive)
+ (company-search-assert-enabled)
+ (company-search-printing-char)
+ (company-create-match-predicate)
+ (company-call-frontends 'update))
+
+(defun company-search-kill-others ()
+ "Limit the completion candidates to the ones matching the search string."
+ (interactive)
+ (company-search-assert-enabled)
+ (company-create-match-predicate)
+ (company-search-mode 0)
+ (company-call-frontends 'update))
+
+(defun company-search-abort ()
+ "Abort searching the completion candidates."
+ (interactive)
+ (company-search-assert-enabled)
+ (company-set-selection company-search-old-selection t)
+ (company-search-mode 0))
+
+(defun company-search-other-char ()
+ (interactive)
+ (company-search-assert-enabled)
+ (company-search-mode 0)
+ (when last-input-event
+ (clear-this-command-keys t)
+ (setq unread-command-events (list last-input-event))))
+
+(defvar company-search-map
+ (let ((i 0)
+ (keymap (make-keymap)))
+ (if (fboundp 'max-char)
+ (set-char-table-range (nth 1 keymap) (cons #x100 (max-char))
+ 'company-search-printing-char)
+ (with-no-warnings
+ ;; obselete in Emacs 23
+ (let ((l (generic-character-list))
+ (table (nth 1 keymap)))
+ (while l
+ (set-char-table-default table (car l) 'company-search-printing-char)
+ (setq l (cdr l))))))
+ (define-key keymap [t] 'company-search-other-char)
+ (while (< i ?\s)
+ (define-key keymap (make-string 1 i) 'company-search-other-char)
+ (incf i))
+ (while (< i 256)
+ (define-key keymap (vector i) 'company-search-printing-char)
+ (incf i))
+ (let ((meta-map (make-sparse-keymap)))
+ (define-key keymap (char-to-string meta-prefix-char) meta-map)
+ (define-key keymap [escape] meta-map))
+ (define-key keymap (vector meta-prefix-char t) 'company-search-other-char)
+ (define-key keymap "\e\e\e" 'company-search-other-char)
+ (define-key keymap [escape escape escape] 'company-search-other-char)
+
+ (define-key keymap "\C-g" 'company-search-abort)
+ (define-key keymap "\C-s" 'company-search-repeat-forward)
+ (define-key keymap "\C-r" 'company-search-repeat-backward)
+ (define-key keymap "\C-o" 'company-search-kill-others)
+ keymap)
+ "Keymap used for incrementally searching the completion candidates.")
+
+(define-minor-mode company-search-mode
+ "Search mode for completion candidates.
+Don't start this directly, use `company-search-candidates' or
+`company-filter-candidates'."
+ nil company-search-lighter nil
+ (if company-search-mode
+ (if (company-manual-begin)
+ (progn
+ (setq company-search-old-selection company-selection)
+ (company-call-frontends 'update))
+ (setq company-search-mode nil))
+ (kill-local-variable 'company-search-string)
+ (kill-local-variable 'company-search-lighter)
+ (kill-local-variable 'company-search-old-selection)
+ (company-enable-overriding-keymap company-active-map)))
+
+(defsubst company-search-assert-enabled ()
+ (company-assert-enabled)
+ (unless company-search-mode
+ (company-uninstall-map)
+ (error "Company not in search mode")))
+
+(defun company-search-candidates ()
+ "Start searching the completion candidates incrementally.
+
+\\<company-search-map>Search can be controlled with the commands:
+- `company-search-repeat-forward' (\\[company-search-repeat-forward])
+- `company-search-repeat-backward' (\\[company-search-repeat-backward])
+- `company-search-abort' (\\[company-search-abort])
+
+Regular characters are appended to the search string.
+
+The command `company-search-kill-others' (\\[company-search-kill-others]) uses
+ the search string to limit the completion candidates."
+ (interactive)
+ (company-search-mode 1)
+ (company-enable-overriding-keymap company-search-map))
+
+(defvar company-filter-map
+ (let ((keymap (make-keymap)))
+ (define-key keymap [remap company-search-printing-char]
+ 'company-filter-printing-char)
+ (set-keymap-parent keymap company-search-map)
+ keymap)
+ "Keymap used for incrementally searching the completion candidates.")
+
+(defun company-filter-candidates ()
+ "Start filtering the completion candidates incrementally.
+This works the same way as `company-search-candidates' immediately
+followed by `company-search-kill-others' after each input."
+ (interactive)
+ (company-search-mode 1)
+ (company-enable-overriding-keymap company-filter-map))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun company-select-next ()
+ "Select the next candidate in the list."
+ (interactive)
+ (when (company-manual-begin)
+ (company-set-selection (1+ company-selection))))
+
+(defun company-select-previous ()
+ "Select the previous candidate in the list."
+ (interactive)
+ (when (company-manual-begin)
+ (company-set-selection (1- company-selection))))
+
+(defun company-select-mouse (event)
+ "Select the candidate picked by the mouse."
+ (interactive "e")
+ (when (nth 4 (event-start event))
+ (company-set-selection (- (cdr (posn-actual-col-row (event-start event)))
+ (company--row)
+ 1))
+ t))
+
+(defun company-complete-mouse (event)
+ "Complete the candidate picked by the mouse."
+ (interactive "e")
+ (when (company-select-mouse event)
+ (company-complete-selection)))
+
+(defun company-complete-selection ()
+ "Complete the selected candidate."
+ (interactive)
+ (when (company-manual-begin)
+ (company-finish (nth company-selection company-candidates))))
+
+(defun company-complete-common ()
+ "Complete the common part of all candidates."
+ (interactive)
+ (when (company-manual-begin)
+ (if (and (not (cdr company-candidates))
+ (equal company-common (car company-candidates)))
+ (company-complete-selection)
+ (insert (company-strip-prefix company-common)))))
+
+(defun company-complete ()
+ "Complete the common part of all candidates or the current selection.
+The first time this is called, the common part is completed, the second time, or
+when the selection has been changed, the selected candidate is completed."
+ (interactive)
+ (when (company-manual-begin)
+ (if (or company-selection-changed
+ (eq last-command 'company-complete-common))
+ (call-interactively 'company-complete-selection)
+ (call-interactively 'company-complete-common)
+ (setq this-command 'company-complete-common))))
+
+(defun company-complete-number (n)
+ "Complete the Nth candidate.
+To show the number next to the candidates in some back-ends, enable
+`company-show-numbers'."
+ (when (company-manual-begin)
+ (and (< n 1) (> n company-candidates-length)
+ (error "No candidate number %d" n))
+ (decf n)
+ (company-finish (nth n company-candidates))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defconst company-space-strings-limit 100)
+
+(defconst company-space-strings
+ (let (lst)
+ (dotimes (i company-space-strings-limit)
+ (push (make-string (- company-space-strings-limit 1 i) ?\ ) lst))
+ (apply 'vector lst)))
+
+(defsubst company-space-string (len)
+ (if (< len company-space-strings-limit)
+ (aref company-space-strings len)
+ (make-string len ?\ )))
+
+(defsubst company-safe-substring (str from &optional to)
+ (let ((len (length str)))
+ (if (> from len)
+ ""
+ (if (and to (> to len))
+ (concat (substring str from)
+ (company-space-string (- to len)))
+ (substring str from to)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar company-last-metadata nil)
+(make-variable-buffer-local 'company-last-metadata)
+
+(defun company-fetch-metadata ()
+ (let ((selected (nth company-selection company-candidates)))
+ (unless (equal selected (car company-last-metadata))
+ (setq company-last-metadata
+ (cons selected (company-call-backend 'meta selected))))
+ (cdr company-last-metadata)))
+
+(defun company-doc-buffer (&optional string)
+ (with-current-buffer (get-buffer-create "*Company meta-data*")
+ (erase-buffer)
+ (current-buffer)))
+
+(defvar company--electric-commands
+ '(scroll-other-window scroll-other-window-down)
+ "List of Commands that won't break out of electric commands.")
+
+(defmacro company--electric-do (&rest body)
+ (declare (indent 0) (debug t))
+ `(when (company-manual-begin)
+ (save-window-excursion
+ (let ((height (window-height))
+ (row (company--row))
+ cmd)
+ ,@body
+ (and (< (window-height) height)
+ (< (- (window-height) row 2) company-tooltip-limit)
+ (recenter (- (window-height) row 2)))
+ (while (memq (setq cmd (key-binding (vector (list (read-event)))))
+ company--electric-commands)
+ (call-interactively cmd))
+ (when last-input-event
+ (clear-this-command-keys t)
+ (setq unread-command-events (list last-input-event)))))))
+
+(defun company-show-doc-buffer ()
+ "Temporarily show a buffer with the complete documentation for the selection."
+ (interactive)
+ (company--electric-do
+ (let* ((selected (nth company-selection company-candidates))
+ (doc-buffer (or (company-call-backend 'doc-buffer selected)
+ (error "No documentation available"))))
+ (with-current-buffer doc-buffer
+ (goto-char (point-min)))
+ (display-buffer doc-buffer t))))
+(put 'company-show-doc-buffer 'company-keep t)
+
+(defun company-show-location ()
+ "Temporarily display a buffer showing the selected candidate in context."
+ (interactive)
+ (company--electric-do
+ (let* ((selected (nth company-selection company-candidates))
+ (location (company-call-backend 'location selected))
+ (pos (or (cdr location) (error "No location available")))
+ (buffer (or (and (bufferp (car location)) (car location))
+ (find-file-noselect (car location) t))))
+ (with-selected-window (display-buffer buffer t)
+ (save-restriction
+ (widen)
+ (if (bufferp (car location))
+ (goto-char pos)
+ (goto-char (point-min))
+ (forward-line (1- pos))))
+ (set-window-start nil (point))))))
+(put 'company-show-location 'company-keep t)
+
+;;; package functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar company-callback nil)
+(make-variable-buffer-local 'company-callback)
+
+(defvar company-begin-with-marker nil)
+(make-variable-buffer-local 'company-begin-with-marker)
+
+(defun company-remove-callback (&optional ignored)
+ (remove-hook 'company-completion-finished-hook company-callback t)
+ (remove-hook 'company-completion-cancelled-hook 'company-remove-callback t)
+ (remove-hook 'company-completion-finished-hook 'company-remove-callback t)
+ (when company-begin-with-marker
+ (set-marker company-begin-with-marker nil)))
+
+(defun company-begin-backend (backend &optional callback)
+ "Start a completion at point using BACKEND."
+ (interactive (let ((val (completing-read "Company back-end: "
+ obarray
+ 'functionp nil "company-")))
+ (when val
+ (list (intern val)))))
+ (when (setq company-callback callback)
+ (add-hook 'company-completion-finished-hook company-callback nil t))
+ (add-hook 'company-completion-cancelled-hook 'company-remove-callback nil t)
+ (add-hook 'company-completion-finished-hook 'company-remove-callback nil t)
+ (setq company-backend backend)
+ ;; Return non-nil if active.
+ (or (company-manual-begin)
+ (error "Cannot complete at point")))
+
+(defun company-begin-with (candidates
+ &optional prefix-length require-match callback)
+ "Start a completion at point.
+CANDIDATES is the list of candidates to use and PREFIX-LENGTH is the length of
+the prefix that already is in the buffer before point. It defaults to 0.
+
+CALLBACK is a function called with the selected result if the user successfully
+completes the input.
+
+Example:
+\(company-begin-with '\(\"foo\" \"foobar\" \"foobarbaz\"\)\)"
+ (setq company-begin-with-marker (copy-marker (point) t))
+ (company-begin-backend
+ `(lambda (command &optional arg &rest ignored)
+ (cond
+ ((eq command 'prefix)
+ (when (equal (point) (marker-position company-begin-with-marker))
+ (buffer-substring ,(- (point) (or prefix-length 0)) (point))))
+ ((eq command 'candidates)
+ (all-completions arg ',candidates))
+ ((eq command 'require-match)
+ ,require-match)))
+ callback))
+
+;;; pseudo-tooltip ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar company-pseudo-tooltip-overlay nil)
+(make-variable-buffer-local 'company-pseudo-tooltip-overlay)
+
+(defvar company-tooltip-offset 0)
+(make-variable-buffer-local 'company-tooltip-offset)
+
+(defun company-pseudo-tooltip-update-offset (selection num-lines limit)
+
+ (decf limit 2)
+ (setq company-tooltip-offset
+ (max (min selection company-tooltip-offset)
+ (- selection -1 limit)))
+
+ (when (<= company-tooltip-offset 1)
+ (incf limit)
+ (setq company-tooltip-offset 0))
+
+ (when (>= company-tooltip-offset (- num-lines limit 1))
+ (incf limit)
+ (when (= selection (1- num-lines))
+ (decf company-tooltip-offset)
+ (when (<= company-tooltip-offset 1)
+ (setq company-tooltip-offset 0)
+ (incf limit))))
+
+ limit)
+
+;;; propertize
+
+(defsubst company-round-tab (arg)
+ (* (/ (+ arg tab-width) tab-width) tab-width))
+
+(defun company-untabify (str)
+ (let* ((pieces (split-string str "\t"))
+ (copy pieces))
+ (while (cdr copy)
+ (setcar copy (company-safe-substring
+ (car copy) 0 (company-round-tab (string-width (car copy)))))
+ (pop copy))
+ (apply 'concat pieces)))
+
+(defun company-fill-propertize (line width selected)
+ (setq line (company-safe-substring line 0 width))
+ (add-text-properties 0 width '(face company-tooltip
+ mouse-face company-tooltip-mouse)
+ line)
+ (add-text-properties 0 (length company-common)
+ '(face company-tooltip-common
+ mouse-face company-tooltip-mouse)
+ line)
+ (when selected
+ (if (and company-search-string
+ (string-match (regexp-quote company-search-string) line
+ (length company-prefix)))
+ (progn
+ (add-text-properties (match-beginning 0) (match-end 0)
+ '(face company-tooltip-selection)
+ line)
+ (when (< (match-beginning 0) (length company-common))
+ (add-text-properties (match-beginning 0) (length company-common)
+ '(face company-tooltip-common-selection)
+ line)))
+ (add-text-properties 0 width '(face company-tooltip-selection
+ mouse-face company-tooltip-selection)
+ line)
+ (add-text-properties 0 (length company-common)
+ '(face company-tooltip-common-selection
+ mouse-face company-tooltip-selection)
+ line)))
+ line)
+
+;;; replace
+
+(defun company-buffer-lines (beg end)
+ (goto-char beg)
+ (let ((row (company--row))
+ lines)
+ (while (and (equal (move-to-window-line (incf row)) row)
+ (<= (point) end))
+ (push (buffer-substring beg (min end (1- (point)))) lines)
+ (setq beg (point)))
+ (unless (eq beg end)
+ (push (buffer-substring beg end) lines))
+ (nreverse lines)))
+
+(defsubst company-modify-line (old new offset)
+ (concat (company-safe-substring old 0 offset)
+ new
+ (company-safe-substring old (+ offset (length new)))))
+
+(defsubst company--length-limit (lst limit)
+ (if (nthcdr limit lst)
+ limit
+ (length lst)))
+
+(defun company--replacement-string (lines old column nl &optional align-top)
+
+ (let ((width (length (car lines))))
+ (when (> width (- (window-width) column))
+ (setq column (max 0 (- (window-width) width)))))
+
+ (let (new)
+ (when align-top
+ ;; untouched lines first
+ (dotimes (i (- (length old) (length lines)))
+ (push (pop old) new)))
+ ;; length into old lines.
+ (while old
+ (push (company-modify-line (pop old) (pop lines) column) new))
+ ;; Append whole new lines.
+ (while lines
+ (push (concat (company-space-string column) (pop lines)) new))
+ (concat (when nl "\n")
+ (mapconcat 'identity (nreverse new) "\n")
+ "\n")))
+
+(defun company--create-lines (selection limit)
+
+ (let ((len company-candidates-length)
+ (numbered 99999)
+ lines
+ width
+ lines-copy
+ previous
+ remainder
+ new)
+
+ ;; Scroll to offset.
+ (setq limit (company-pseudo-tooltip-update-offset selection len limit))
+
+ (when (> company-tooltip-offset 0)
+ (setq previous (format "...(%d)" company-tooltip-offset)))
+
+ (setq remainder (- len limit company-tooltip-offset)
+ remainder (when (> remainder 0)
+ (setq remainder (format "...(%d)" remainder))))
+
+ (decf selection company-tooltip-offset)
+ (setq width (max (length previous) (length remainder))
+ lines (nthcdr company-tooltip-offset company-candidates)
+ len (min limit len)
+ lines-copy lines)
+
+ (dotimes (i len)
+ (setq width (max (length (pop lines-copy)) width)))
+ (setq width (min width (window-width)))
+
+ (setq lines-copy lines)
+
+ ;; number can make tooltip too long
+ (when company-show-numbers
+ (setq numbered company-tooltip-offset))
+
+ (when previous
+ (push (propertize (company-safe-substring previous 0 width)
+ 'face 'company-tooltip)
+ new))
+
+ (dotimes (i len)
+ (push (company-fill-propertize
+ (if (>= numbered 10)
+ (company-reformat (pop lines))
+ (incf numbered)
+ (format "%s %d"
+ (company-safe-substring (company-reformat (pop lines))
+ 0 (- width 2))
+ (mod numbered 10)))
+ width (equal i selection))
+ new))
+
+ (when remainder
+ (push (propertize (company-safe-substring remainder 0 width)
+ 'face 'company-tooltip)
+ new))
+
+ (setq lines (nreverse new))))
+
+;; show
+
+(defsubst company--window-inner-height ()
+ (let ((edges (window-inside-edges (selected-window))))
+ (- (nth 3 edges) (nth 1 edges))))
+
+(defsubst company--pseudo-tooltip-height ()
+ "Calculate the appropriate tooltip height.
+Returns a negative number if the tooltip should be displayed above point."
+ (let* ((lines (count-lines (window-start) (point-at-bol)))
+ (below (- (company--window-inner-height) 1 lines)))
+ (if (and (< below (min company-tooltip-minimum company-candidates-length))
+ (> lines below))
+ (- (max 3 (min company-tooltip-limit lines)))
+ (max 3 (min company-tooltip-limit below)))))
+
+(defun company-pseudo-tooltip-show (row column selection)
+ (company-pseudo-tooltip-hide)
+ (save-excursion
+
+ (move-to-column 0)
+
+ (let* ((height (company--pseudo-tooltip-height))
+ above)
+
+ (when (< height 0)
+ (setq row (+ row height -1)
+ above t))
+
+ (let* ((nl (< (move-to-window-line row) row))
+ (beg (point))
+ (end (save-excursion
+ (move-to-window-line (+ row (abs height)))
+ (point)))
+ (ov (make-overlay beg end))
+ (args (list (mapcar 'company-untabify
+ (company-buffer-lines beg end))
+ column nl above)))
+
+ (setq company-pseudo-tooltip-overlay ov)
+ (overlay-put ov 'company-replacement-args args)
+ (overlay-put ov 'company-before
+ (apply 'company--replacement-string
+ (company--create-lines selection (abs height))
+ args))
+
+ (overlay-put ov 'company-column column)
+ (overlay-put ov 'company-height (abs height))
+ (overlay-put ov 'window (selected-window))))))
+
+(defun company-pseudo-tooltip-show-at-point (pos)
+ (let ((col-row (company--col-row pos)))
+ (when col-row
+ (company-pseudo-tooltip-show (1+ (cdr col-row)) (car col-row)
+ company-selection))))
+
+(defun company-pseudo-tooltip-edit (lines selection)
+ (let ((column (overlay-get company-pseudo-tooltip-overlay 'company-column))
+ (height (overlay-get company-pseudo-tooltip-overlay 'company-height)))
+ (overlay-put company-pseudo-tooltip-overlay 'company-before
+ (apply 'company--replacement-string
+ (company--create-lines selection height)
+ (overlay-get company-pseudo-tooltip-overlay
+ 'company-replacement-args)))))
+
+(defun company-pseudo-tooltip-hide ()
+ (when company-pseudo-tooltip-overlay
+ (delete-overlay company-pseudo-tooltip-overlay)
+ (setq company-pseudo-tooltip-overlay nil)))
+
+(defun company-pseudo-tooltip-hide-temporarily ()
+ (when (overlayp company-pseudo-tooltip-overlay)
+ (overlay-put company-pseudo-tooltip-overlay 'invisible nil)
+ (overlay-put company-pseudo-tooltip-overlay 'before-string nil)))
+
+(defun company-pseudo-tooltip-unhide ()
+ (when company-pseudo-tooltip-overlay
+ (overlay-put company-pseudo-tooltip-overlay 'invisible t)
+ (overlay-put company-pseudo-tooltip-overlay 'before-string
+ (overlay-get company-pseudo-tooltip-overlay 'company-before))
+ (overlay-put company-pseudo-tooltip-overlay 'window (selected-window))))
+
+(defun company-pseudo-tooltip-frontend (command)
+ "A `company-mode' front-end similar to a tool-tip but based on overlays."
+ (case command
+ ('pre-command (company-pseudo-tooltip-hide-temporarily))
+ ('post-command
+ (let ((old-height (if (overlayp company-pseudo-tooltip-overlay)
+ (overlay-get company-pseudo-tooltip-overlay
+ 'company-height)
+ 0))
+ (new-height (company--pseudo-tooltip-height)))
+ (unless (and (>= (* old-height new-height) 0)
+ (>= (abs old-height) (abs new-height)))
+ ;; Redraw needed.
+ (company-pseudo-tooltip-show-at-point (- (point)
+ (length company-prefix)))))
+ (company-pseudo-tooltip-unhide))
+ ('hide (company-pseudo-tooltip-hide)
+ (setq company-tooltip-offset 0))
+ ('update (when (overlayp company-pseudo-tooltip-overlay)
+ (company-pseudo-tooltip-edit company-candidates
+ company-selection)))))
+
+(defun company-pseudo-tooltip-unless-just-one-frontend (command)
+ "`company-pseudo-tooltip-frontend', but not shown for single candidates."
+ (unless (and (eq command 'post-command)
+ (not (cdr company-candidates)))
+ (company-pseudo-tooltip-frontend command)))
+
+;;; overlay ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar company-preview-overlay nil)
+(make-variable-buffer-local 'company-preview-overlay)
+
+(defun company-preview-show-at-point (pos)
+ (company-preview-hide)
+
+ (setq company-preview-overlay (make-overlay pos pos))
+
+ (let ((completion(nth company-selection company-candidates)))
+ (setq completion (propertize completion 'face 'company-preview))
+ (add-text-properties 0 (length company-common)
+ '(face company-preview-common) completion)
+
+ ;; Add search string
+ (and company-search-string
+ (string-match (regexp-quote company-search-string) completion)
+ (add-text-properties (match-beginning 0)
+ (match-end 0)
+ '(face company-preview-search)
+ completion))
+
+ (setq completion (company-strip-prefix completion))
+
+ (and (equal pos (point))
+ (not (equal completion ""))
+ (add-text-properties 0 1 '(cursor t) completion))
+
+ (overlay-put company-preview-overlay 'after-string completion)
+ (overlay-put company-preview-overlay 'window (selected-window))))
+
+(defun company-preview-hide ()
+ (when company-preview-overlay
+ (delete-overlay company-preview-overlay)
+ (setq company-preview-overlay nil)))
+
+(defun company-preview-frontend (command)
+ "A `company-mode' front-end showing the selection as if it had been inserted."
+ (case command
+ ('pre-command (company-preview-hide))
+ ('post-command (company-preview-show-at-point (point)))
+ ('hide (company-preview-hide))))
+
+(defun company-preview-if-just-one-frontend (command)
+ "`company-preview-frontend', but only shown for single candidates."
+ (unless (and (eq command 'post-command)
+ (cdr company-candidates))
+ (company-preview-frontend command)))
+
+;;; echo ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar company-echo-last-msg nil)
+(make-variable-buffer-local 'company-echo-last-msg)
+
+(defvar company-echo-timer nil)
+
+(defvar company-echo-delay .01)
+
+(defun company-echo-show (&optional getter)
+ (when getter
+ (setq company-echo-last-msg (funcall getter)))
+ (let ((message-log-max nil))
+ (if company-echo-last-msg
+ (message "%s" company-echo-last-msg)
+ (message ""))))
+
+(defsubst company-echo-show-soon (&optional getter)
+ (when company-echo-timer
+ (cancel-timer company-echo-timer))
+ (setq company-echo-timer (run-with-timer company-echo-delay nil
+ 'company-echo-show getter)))
+
+(defun company-echo-format ()
+
+ (let ((limit (window-width (minibuffer-window)))
+ (len -1)
+ ;; Roll to selection.
+ (candidates (nthcdr company-selection company-candidates))
+ (i (if company-show-numbers company-selection 99999))
+ comp msg)
+
+ (while candidates
+ (setq comp (company-reformat (pop candidates))
+ len (+ len 1 (length comp)))
+ (if (< i 10)
+ ;; Add number.
+ (progn
+ (setq comp (propertize (format "%d: %s" i comp)
+ 'face 'company-echo))
+ (incf len 3)
+ (incf i)
+ (add-text-properties 3 (+ 3 (length company-common))
+ '(face company-echo-common) comp))
+ (setq comp (propertize comp 'face 'company-echo))
+ (add-text-properties 0 (length company-common)
+ '(face company-echo-common) comp))
+ (if (>= len limit)
+ (setq candidates nil)
+ (push comp msg)))
+
+ (mapconcat 'identity (nreverse msg) " ")))
+
+(defun company-echo-strip-common-format ()
+
+ (let ((limit (window-width (minibuffer-window)))
+ (len (+ (length company-prefix) 2))
+ ;; Roll to selection.
+ (candidates (nthcdr company-selection company-candidates))
+ (i (if company-show-numbers company-selection 99999))
+ msg comp)
+
+ (while candidates
+ (setq comp (company-strip-prefix (pop candidates))
+ len (+ len 2 (length comp)))
+ (when (< i 10)
+ ;; Add number.
+ (setq comp (format "%s (%d)" comp i))
+ (incf len 4)
+ (incf i))
+ (if (>= len limit)
+ (setq candidates nil)
+ (push (propertize comp 'face 'company-echo) msg)))
+
+ (concat (propertize company-prefix 'face 'company-echo-common) "{"
+ (mapconcat 'identity (nreverse msg) ", ")
+ "}")))
+
+(defun company-echo-hide ()
+ (when company-echo-timer
+ (cancel-timer company-echo-timer))
+ (unless (equal company-echo-last-msg "")
+ (setq company-echo-last-msg "")
+ (company-echo-show)))
+
+(defun company-echo-frontend (command)
+ "A `company-mode' front-end showing the candidates in the echo area."
+ (case command
+ ('pre-command (company-echo-show-soon))
+ ('post-command (company-echo-show-soon 'company-echo-format))
+ ('hide (company-echo-hide))))
+
+(defun company-echo-strip-common-frontend (command)
+ "A `company-mode' front-end showing the candidates in the echo area."
+ (case command
+ ('pre-command (company-echo-show-soon))
+ ('post-command (company-echo-show-soon 'company-echo-strip-common-format))
+ ('hide (company-echo-hide))))
+
+(defun company-echo-metadata-frontend (command)
+ "A `company-mode' front-end showing the documentation in the echo area."
+ (case command
+ ('pre-command (company-echo-show-soon))
+ ('post-command (company-echo-show-soon 'company-fetch-metadata))
+ ('hide (company-echo-hide))))
+
+;; templates ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(autoload 'company-template-declare-template "company-template")
+
+(provide 'company)
+;;; company.el ends here
--- /dev/null
+Company is an Emacs extension for performing text completion.
+Completion candidates are retrieved from a variety of modular
+back-ends, such as Semantic.
+
+Once installed, enable company-mode with M-x company-mode.
+For further information, see the docstring for `company-mode'.
--- /dev/null
+<rss version="2.0">
+ <channel>
+ <title>ELPA News</title>
+ <link>http://elpa.gnu.org/packages/</link>
+ <language>en</language>
+ <description>News for the Emacs Lisp Package Archive</description>
+<item>
+<title>auctex.tar version 11.86</title>
+<link>http://elpa.gnu.org/packages/news.html</link>
+<description>integrated environment for *TeX*</description>
+<pubDate>Wed, 20 October 2010 16:32:11 -0400</pubDate>
+</item>
+<item>
+<title>muse.tar version 3.20</title>
+<link>http://elpa.gnu.org/packages/news.html</link>
+<description>Authoring and publishing tool</description>
+<pubDate>Thu, 26 August 2010 14:14:46 -0400</pubDate>
+</item>
+<item>
+<title>company.tar version 0.5</title>
+<link>http://elpa.gnu.org/packages/news.html</link>
+<description>Flexible inline text and code completion</description>
+<pubDate>Wed, 25 August 2010 21:30:45 -0400</pubDate>
+</item>
+<item>
+<title>company.tar version 0.5</title>
+<link>http://elpa.gnu.org/packages/news.html</link>
+<description>Flexible inline text and code completion</description>
+<pubDate>Sat, 31 July 2010 20:57:40 -0400</pubDate>
+</item>
+ </channel>
+</rss>
--- /dev/null
+;;; js2-mode.el --- improved JavaScript editing mode
+
+;; Copyright (C) 2009 Free Software Foundation, Inc.
+
+;; Author: Steve Yegge <steve.yegge@gmail.com>
+;; Version: 20090814
+;; Keywords: languages, javascript
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This JavaScript editing mode supports:
+
+;; - strict recognition of the Ecma-262 language standard
+;; - support for most Rhino and SpiderMonkey extensions from 1.5 to 1.8
+;; - parsing support for ECMAScript for XML (E4X, ECMA-357)
+;; - accurate syntax highlighting using a recursive-descent parser
+;; - on-the-fly reporting of syntax errors and strict-mode warnings
+;; - undeclared-variable warnings using a configurable externs framework
+;; - "bouncing" line indentation to choose among alternate indentation points
+;; - smart line-wrapping within comments and strings
+;; - code folding:
+;; - show some or all function bodies as {...}
+;; - show some or all block comments as /*...*/
+;; - context-sensitive menu bar and popup menus
+;; - code browsing using the `imenu' package
+;; - typing helpers such as automatic insertion of matching braces/parens
+;; - many customization options
+
+;; To customize how it works:
+;; M-x customize-group RET js2-mode RET
+
+;; Notes:
+
+;; This mode includes a port of Mozilla Rhino's scanner, parser and
+;; symbol table. Ideally it should stay in sync with Rhino, keeping
+;; `js2-mode' current as the EcmaScript language standard evolves.
+
+;; Unlike cc-engine based language modes, js2-mode's line-indentation is not
+;; customizable. It is a surprising amount of work to support customizable
+;; indentation. The current compromise is that the tab key lets you cycle among
+;; various likely indentation points, similar to the behavior of python-mode.
+
+;; This mode does not yet work with "multi-mode" modes such as `mmm-mode'
+;; and `mumamo', although it could be made to do so with some effort.
+;; This means that `js2-mode' is currently only useful for editing JavaScript
+;; files, and not for editing JavaScript within <script> tags or templates.
+
+;;; Code:
+
+(eval-when-compile
+ (require 'cl))
+
+(require 'imenu)
+(require 'cc-cmds) ; for `c-fill-paragraph'
+
+(eval-and-compile
+ (require 'cc-mode) ; (only) for `c-populate-syntax-table'
+ (require 'cc-langs) ; it's here in Emacs 21...
+ (require 'cc-engine)) ; for `c-paragraph-start' et. al.
+
+;;; Externs (variables presumed to be defined by the host system)
+
+(defvar js2-ecma-262-externs
+ (mapcar 'symbol-name
+ '(Array Boolean Date Error EvalError Function Infinity
+ Math NaN Number Object RangeError ReferenceError RegExp
+ String SyntaxError TypeError URIError arguments
+ decodeURI decodeURIComponent encodeURI
+ encodeURIComponent escape eval isFinite isNaN
+ parseFloat parseInt undefined unescape))
+"Ecma-262 externs. Included in `js2-externs' by default.")
+
+(defvar js2-browser-externs
+ (mapcar 'symbol-name
+ '(;; DOM level 1
+ Attr CDATASection CharacterData Comment DOMException
+ DOMImplementation Document DocumentFragment
+ DocumentType Element Entity EntityReference
+ ExceptionCode NamedNodeMap Node NodeList Notation
+ ProcessingInstruction Text
+
+ ;; DOM level 2
+ HTMLAnchorElement HTMLAppletElement HTMLAreaElement
+ HTMLBRElement HTMLBaseElement HTMLBaseFontElement
+ HTMLBodyElement HTMLButtonElement HTMLCollection
+ HTMLDListElement HTMLDirectoryElement HTMLDivElement
+ HTMLDocument HTMLElement HTMLFieldSetElement
+ HTMLFontElement HTMLFormElement HTMLFrameElement
+ HTMLFrameSetElement HTMLHRElement HTMLHeadElement
+ HTMLHeadingElement HTMLHtmlElement HTMLIFrameElement
+ HTMLImageElement HTMLInputElement HTMLIsIndexElement
+ HTMLLIElement HTMLLabelElement HTMLLegendElement
+ HTMLLinkElement HTMLMapElement HTMLMenuElement
+ HTMLMetaElement HTMLModElement HTMLOListElement
+ HTMLObjectElement HTMLOptGroupElement
+ HTMLOptionElement HTMLOptionsCollection
+ HTMLParagraphElement HTMLParamElement HTMLPreElement
+ HTMLQuoteElement HTMLScriptElement HTMLSelectElement
+ HTMLStyleElement HTMLTableCaptionElement
+ HTMLTableCellElement HTMLTableColElement
+ HTMLTableElement HTMLTableRowElement
+ HTMLTableSectionElement HTMLTextAreaElement
+ HTMLTitleElement HTMLUListElement
+
+ ;; DOM level 3
+ DOMConfiguration DOMError DOMException
+ DOMImplementationList DOMImplementationSource
+ DOMLocator DOMStringList NameList TypeInfo
+ UserDataHandler
+
+ ;; Window
+ alert confirm document java navigator prompt screen
+ self top
+
+ ;; W3C CSS
+ CSSCharsetRule CSSFontFace CSSFontFaceRule
+ CSSImportRule CSSMediaRule CSSPageRule
+ CSSPrimitiveValue CSSProperties CSSRule CSSRuleList
+ CSSStyleDeclaration CSSStyleRule CSSStyleSheet
+ CSSValue CSSValueList Counter DOMImplementationCSS
+ DocumentCSS DocumentStyle ElementCSSInlineStyle
+ LinkStyle MediaList RGBColor Rect StyleSheet
+ StyleSheetList ViewCSS
+
+ ;; W3C Event
+ EventListener EventTarget Event DocumentEvent UIEvent
+ MouseEvent MutationEvent KeyboardEvent
+
+ ;; W3C Range
+ DocumentRange Range RangeException
+
+ ;; W3C XML
+ XPathResult XMLHttpRequest))
+ "Browser externs.
+You can cause these to be included or excluded with the custom
+variable `js2-include-browser-externs'.")
+
+(defvar js2-rhino-externs
+ (mapcar 'symbol-name
+ '(Packages importClass importPackage com org java
+ ;; Global object (shell) externs
+ defineClass deserialize doctest gc help load
+ loadClass print quit readFile readUrl runCommand seal
+ serialize spawn sync toint32 version))
+ "Mozilla Rhino externs.
+Set `js2-include-rhino-externs' to t to include them.")
+
+(defvar js2-gears-externs
+ (mapcar 'symbol-name
+ '(
+ ;; TODO(stevey): add these
+ ))
+ "Google Gears externs.
+Set `js2-include-gears-externs' to t to include them.")
+
+;;; Variables
+
+(defvar js2-emacs22 (>= emacs-major-version 22))
+
+(defcustom js2-highlight-level 2
+ "Amount of syntax highlighting to perform.
+nil, zero or negative means none.
+1 adds basic syntax highlighting.
+2 adds highlighting of some Ecma built-in properties.
+3 adds highlighting of many Ecma built-in functions."
+ :group 'js2-mode
+ :type '(choice (const :tag "None" nil)
+ (const :tag "Basic" 1)
+ (const :tag "Include Properties" 2)
+ (const :tag "Include Functions" 3)))
+
+(defvar js2-mode-dev-mode-p nil
+ "Non-nil if running in development mode. Normally nil.")
+
+(defgroup js2-mode nil
+ "An improved JavaScript mode."
+ :group 'languages)
+
+(defcustom js2-basic-offset (if (and (boundp 'c-basic-offset)
+ (numberp c-basic-offset))
+ c-basic-offset
+ 4)
+ "Number of spaces to indent nested statements.
+Similar to `c-basic-offset'."
+ :group 'js2-mode
+ :type 'integer)
+(make-variable-buffer-local 'js2-basic-offset)
+
+(defcustom js2-mirror-mode t
+ "Non-nil to insert closing brackets, parens, etc. automatically."
+ :group 'js2-mode
+ :type 'boolean)
+
+(defcustom js2-auto-indent-p nil
+ "Automatic indentation with punctuation characters.
+If non-nil, the current line is indented when certain punctuations
+are inserted."
+ :group 'js2-mode
+ :type 'boolean)
+
+(defcustom js2-bounce-indent-p nil
+ "Non-nil to have indent-line function choose among alternatives.
+If nil, the indent-line function will indent to a predetermined column
+based on heuristic guessing. If non-nil, then if the current line is
+already indented to that predetermined column, indenting will choose
+another likely column and indent to that spot. Repeated invocation of
+the indent-line function will cycle among the computed alternatives.
+See the function `js2-bounce-indent' for details."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-indent-on-enter-key nil
+ "Non-nil to have Enter/Return key indent the line.
+This is unusual for Emacs modes but common in IDEs like Eclipse."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-enter-indents-newline nil
+ "Non-nil to have Enter/Return key indent the newly-inserted line.
+This is unusual for Emacs modes but common in IDEs like Eclipse."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-rebind-eol-bol-keys t
+ "Non-nil to rebind `beginning-of-line' and `end-of-line' keys.
+If non-nil, bounce between bol/eol and first/last non-whitespace char."
+ :group 'js2-mode
+ :type 'boolean)
+
+(defcustom js2-electric-keys '("{" "}" "(" ")" "[" "]" ":" ";" "," "*")
+ "Keys that auto-indent when `js2-auto-indent-p' is non-nil.
+Each value in the list is passed to `define-key'."
+ :type 'list
+ :group 'js2-mode)
+
+(defcustom js2-idle-timer-delay 0.2
+ "Delay in secs before re-parsing after user makes changes.
+Multiplied by `js2-dynamic-idle-timer-adjust', which see."
+ :type 'number
+ :group 'js2-mode)
+(make-variable-buffer-local 'js2-idle-timer-delay)
+
+(defcustom js2-dynamic-idle-timer-adjust 0
+ "Positive to adjust `js2-idle-timer-delay' based on file size.
+The idea is that for short files, parsing is faster so we can be
+more responsive to user edits without interfering with editing.
+The buffer length in characters (typically bytes) is divided by
+this value and used to multiply `js2-idle-timer-delay' for the
+buffer. For example, a 21k file and 10k adjust yields 21k/10k
+== 2, so js2-idle-timer-delay is multiplied by 2.
+If `js2-dynamic-idle-timer-adjust' is 0 or negative,
+`js2-idle-timer-delay' is not dependent on the file size."
+ :type 'number
+ :group 'js2-mode)
+
+(defcustom js2-mode-escape-quotes t
+ "Non-nil to disable automatic quote-escaping inside strings."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-mode-squeeze-spaces t
+ "Non-nil to normalize whitespace when filling in comments.
+Multiple runs of spaces are converted to a single space."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-mode-show-parse-errors t
+ "True to highlight parse errors."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-mode-show-strict-warnings t
+ "Non-nil to emit Ecma strict-mode warnings.
+Some of the warnings can be individually disabled by other flags,
+even if this flag is non-nil."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-strict-trailing-comma-warning t
+ "Non-nil to warn about trailing commas in array literals.
+Ecma-262 forbids them, but many browsers permit them. IE is the
+big exception, and can produce bugs if you have trailing commas."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-strict-missing-semi-warning t
+ "Non-nil to warn about semicolon auto-insertion after statement.
+Technically this is legal per Ecma-262, but some style guides disallow
+depending on it."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-missing-semi-one-line-override nil
+ "Non-nil to permit missing semicolons in one-line functions.
+In one-liner functions such as `function identity(x) {return x}'
+people often omit the semicolon for a cleaner look. If you are
+such a person, you can suppress the missing-semicolon warning
+by setting this variable to t."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-strict-inconsistent-return-warning t
+ "Non-nil to warn about mixing returns with value-returns.
+It's perfectly legal to have a `return' and a `return foo' in the
+same function, but it's often an indicator of a bug, and it also
+interferes with type inference (in systems that support it.)"
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-strict-cond-assign-warning t
+ "Non-nil to warn about expressions like if (a = b).
+This often should have been '==' instead of '='. If the warning
+is enabled, you can suppress it on a per-expression basis by
+parenthesizing the expression, e.g. if ((a = b)) ..."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-strict-cond-assign-warning t
+ "Non-nil to warn about expressions like if (a = b).
+This often should have been '==' instead of '='. If the warning
+is enabled, you can suppress it on a per-expression basis by
+parenthesizing the expression, e.g. if ((a = b)) ..."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-strict-var-redeclaration-warning t
+ "Non-nil to warn about redeclaring variables in a script or function."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-strict-var-hides-function-arg-warning t
+ "Non-nil to warn about a var decl hiding a function argument."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-skip-preprocessor-directives nil
+ "Non-nil to treat lines beginning with # as comments.
+Useful for viewing Mozilla JavaScript source code."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-language-version 180
+ "Configures what JavaScript language version to recognize.
+Currently versions 150, 160, 170 and 180 are supported, corresponding
+to JavaScript 1.5, 1.6, 1.7 and 1.8, respectively. In a nutshell,
+1.6 adds E4X support, 1.7 adds let, yield, and Array comprehensions,
+and 1.8 adds function closures."
+ :type 'integer
+ :group 'js2-mode)
+
+(defcustom js2-allow-keywords-as-property-names t
+ "If non-nil, you can use JavaScript keywords as object property names.
+Examples:
+
+ var foo = {int: 5, while: 6, continue: 7};
+ foo.return = 8;
+
+Ecma-262 forbids this syntax, but many browsers support it."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-instanceof-has-side-effects nil
+ "If non-nil, treats the instanceof operator as having side effects.
+This is useful for xulrunner apps."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-cleanup-whitespace nil
+ "Non-nil to invoke `delete-trailing-whitespace' before saves."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-move-point-on-right-click t
+ "Non-nil to move insertion point when you right-click.
+This makes right-click context menu behavior a bit more intuitive,
+since menu operations generally apply to the point. The exception
+is if there is a region selection, in which case the point does -not-
+move, so cut/copy/paste etc. can work properly.
+
+Note that IntelliJ moves the point, and Eclipse leaves it alone,
+so this behavior is customizable."
+ :group 'js2-mode
+ :type 'boolean)
+
+(defcustom js2-allow-rhino-new-expr-initializer t
+ "Non-nil to support a Rhino's experimental syntactic construct.
+
+Rhino supports the ability to follow a `new' expression with an object
+literal, which is used to set additional properties on the new object
+after calling its constructor. Syntax:
+
+ new <expr> [ ( arglist ) ] [initializer]
+
+Hence, this expression:
+
+ new Object {a: 1, b: 2}
+
+results in an Object with properties a=1 and b=2. This syntax is
+apparently not configurable in Rhino - it's currently always enabled,
+as of Rhino version 1.7R2."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-allow-member-expr-as-function-name nil
+ "Non-nil to support experimental Rhino syntax for function names.
+
+Rhino supports an experimental syntax configured via the Rhino Context
+setting `allowMemberExprAsFunctionName'. The experimental syntax is:
+
+ function <member-expr> ( [ arg-list ] ) { <body> }
+
+Where member-expr is a non-parenthesized 'member expression', which
+is anything at the grammar level of a new-expression or lower, meaning
+any expression that does not involve infix or unary operators.
+
+When <member-expr> is not a simple identifier, then it is syntactic
+sugar for assigning the anonymous function to the <member-expr>. Hence,
+this code:
+
+ function a.b().c[2] (x, y) { ... }
+
+is rewritten as:
+
+ a.b().c[2] = function(x, y) {...}
+
+which doesn't seem particularly useful, but Rhino permits it."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defvar js2-mode-version 20090727
+ "Release number for `js2-mode'.")
+
+;; scanner variables
+
+(defmacro js2-deflocal (name value &optional comment)
+ "Define a buffer-local variable NAME with VALUE and COMMENT."
+ `(progn
+ (defvar ,name ,value ,comment)
+ (make-variable-buffer-local ',name)))
+
+;; We record the start and end position of each token.
+(js2-deflocal js2-token-beg 1)
+(js2-deflocal js2-token-end -1)
+
+(defvar js2-EOF_CHAR -1
+ "Represents end of stream. Distinct from js2-EOF token type.")
+
+;; I originally used symbols to represent tokens, but Rhino uses
+;; ints and then sets various flag bits in them, so ints it is.
+;; The upshot is that we need a `js2-' prefix in front of each name.
+(defvar js2-ERROR -1)
+(defvar js2-EOF 0)
+(defvar js2-EOL 1)
+(defvar js2-ENTERWITH 2) ; begin interpreter bytecodes
+(defvar js2-LEAVEWITH 3)
+(defvar js2-RETURN 4)
+(defvar js2-GOTO 5)
+(defvar js2-IFEQ 6)
+(defvar js2-IFNE 7)
+(defvar js2-SETNAME 8)
+(defvar js2-BITOR 9)
+(defvar js2-BITXOR 10)
+(defvar js2-BITAND 11)
+(defvar js2-EQ 12)
+(defvar js2-NE 13)
+(defvar js2-LT 14)
+(defvar js2-LE 15)
+(defvar js2-GT 16)
+(defvar js2-GE 17)
+(defvar js2-LSH 18)
+(defvar js2-RSH 19)
+(defvar js2-URSH 20)
+(defvar js2-ADD 21) ; infix plus
+(defvar js2-SUB 22) ; infix minus
+(defvar js2-MUL 23)
+(defvar js2-DIV 24)
+(defvar js2-MOD 25)
+(defvar js2-NOT 26)
+(defvar js2-BITNOT 27)
+(defvar js2-POS 28) ; unary plus
+(defvar js2-NEG 29) ; unary minus
+(defvar js2-NEW 30)
+(defvar js2-DELPROP 31)
+(defvar js2-TYPEOF 32)
+(defvar js2-GETPROP 33)
+(defvar js2-GETPROPNOWARN 34)
+(defvar js2-SETPROP 35)
+(defvar js2-GETELEM 36)
+(defvar js2-SETELEM 37)
+(defvar js2-CALL 38)
+(defvar js2-NAME 39) ; an identifier
+(defvar js2-NUMBER 40)
+(defvar js2-STRING 41)
+(defvar js2-NULL 42)
+(defvar js2-THIS 43)
+(defvar js2-FALSE 44)
+(defvar js2-TRUE 45)
+(defvar js2-SHEQ 46) ; shallow equality (===)
+(defvar js2-SHNE 47) ; shallow inequality (!==)
+(defvar js2-REGEXP 48)
+(defvar js2-BINDNAME 49)
+(defvar js2-THROW 50)
+(defvar js2-RETHROW 51) ; rethrow caught exception: catch (e if ) uses it
+(defvar js2-IN 52)
+(defvar js2-INSTANCEOF 53)
+(defvar js2-LOCAL_LOAD 54)
+(defvar js2-GETVAR 55)
+(defvar js2-SETVAR 56)
+(defvar js2-CATCH_SCOPE 57)
+(defvar js2-ENUM_INIT_KEYS 58)
+(defvar js2-ENUM_INIT_VALUES 59)
+(defvar js2-ENUM_INIT_ARRAY 60)
+(defvar js2-ENUM_NEXT 61)
+(defvar js2-ENUM_ID 62)
+(defvar js2-THISFN 63)
+(defvar js2-RETURN_RESULT 64) ; to return previously stored return result
+(defvar js2-ARRAYLIT 65) ; array literal
+(defvar js2-OBJECTLIT 66) ; object literal
+(defvar js2-GET_REF 67) ; *reference
+(defvar js2-SET_REF 68) ; *reference = something
+(defvar js2-DEL_REF 69) ; delete reference
+(defvar js2-REF_CALL 70) ; f(args) = something or f(args)++
+(defvar js2-REF_SPECIAL 71) ; reference for special properties like __proto
+(defvar js2-YIELD 72) ; JS 1.7 yield pseudo keyword
+
+;; XML support
+(defvar js2-DEFAULTNAMESPACE 73)
+(defvar js2-ESCXMLATTR 74)
+(defvar js2-ESCXMLTEXT 75)
+(defvar js2-REF_MEMBER 76) ; Reference for x.@y, x..y etc.
+(defvar js2-REF_NS_MEMBER 77) ; Reference for x.ns::y, x..ns::y etc.
+(defvar js2-REF_NAME 78) ; Reference for @y, @[y] etc.
+(defvar js2-REF_NS_NAME 79) ; Reference for ns::y, @ns::y@[y] etc.
+
+(defvar js2-first-bytecode js2-ENTERWITH)
+(defvar js2-last-bytecode js2-REF_NS_NAME)
+
+(defvar js2-TRY 80)
+(defvar js2-SEMI 81) ; semicolon
+(defvar js2-LB 82) ; left and right brackets
+(defvar js2-RB 83)
+(defvar js2-LC 84) ; left and right curly-braces
+(defvar js2-RC 85)
+(defvar js2-LP 86) ; left and right parens
+(defvar js2-RP 87)
+(defvar js2-COMMA 88) ; comma operator
+
+(defvar js2-ASSIGN 89) ; simple assignment (=)
+(defvar js2-ASSIGN_BITOR 90) ; |=
+(defvar js2-ASSIGN_BITXOR 91) ; ^=
+(defvar js2-ASSIGN_BITAND 92) ; &=
+(defvar js2-ASSIGN_LSH 93) ; <<=
+(defvar js2-ASSIGN_RSH 94) ; >>=
+(defvar js2-ASSIGN_URSH 95) ; >>>=
+(defvar js2-ASSIGN_ADD 96) ; +=
+(defvar js2-ASSIGN_SUB 97) ; -=
+(defvar js2-ASSIGN_MUL 98) ; *=
+(defvar js2-ASSIGN_DIV 99) ; /=
+(defvar js2-ASSIGN_MOD 100) ; %=
+
+(defvar js2-first-assign js2-ASSIGN)
+(defvar js2-last-assign js2-ASSIGN_MOD)
+
+(defvar js2-HOOK 101) ; conditional (?:)
+(defvar js2-COLON 102)
+(defvar js2-OR 103) ; logical or (||)
+(defvar js2-AND 104) ; logical and (&&)
+(defvar js2-INC 105) ; increment/decrement (++ --)
+(defvar js2-DEC 106)
+(defvar js2-DOT 107) ; member operator (.)
+(defvar js2-FUNCTION 108) ; function keyword
+(defvar js2-EXPORT 109) ; export keyword
+(defvar js2-IMPORT 110) ; import keyword
+(defvar js2-IF 111) ; if keyword
+(defvar js2-ELSE 112) ; else keyword
+(defvar js2-SWITCH 113) ; switch keyword
+(defvar js2-CASE 114) ; case keyword
+(defvar js2-DEFAULT 115) ; default keyword
+(defvar js2-WHILE 116) ; while keyword
+(defvar js2-DO 117) ; do keyword
+(defvar js2-FOR 118) ; for keyword
+(defvar js2-BREAK 119) ; break keyword
+(defvar js2-CONTINUE 120) ; continue keyword
+(defvar js2-VAR 121) ; var keyword
+(defvar js2-WITH 122) ; with keyword
+(defvar js2-CATCH 123) ; catch keyword
+(defvar js2-FINALLY 124) ; finally keyword
+(defvar js2-VOID 125) ; void keyword
+(defvar js2-RESERVED 126) ; reserved keywords
+
+(defvar js2-EMPTY 127)
+
+;; Types used for the parse tree - never returned by scanner.
+
+(defvar js2-BLOCK 128) ; statement block
+(defvar js2-LABEL 129) ; label
+(defvar js2-TARGET 130)
+(defvar js2-LOOP 131)
+(defvar js2-EXPR_VOID 132) ; expression statement in functions
+(defvar js2-EXPR_RESULT 133) ; expression statement in scripts
+(defvar js2-JSR 134)
+(defvar js2-SCRIPT 135) ; top-level node for entire script
+(defvar js2-TYPEOFNAME 136) ; for typeof(simple-name)
+(defvar js2-USE_STACK 137)
+(defvar js2-SETPROP_OP 138) ; x.y op= something
+(defvar js2-SETELEM_OP 139) ; x[y] op= something
+(defvar js2-LOCAL_BLOCK 140)
+(defvar js2-SET_REF_OP 141) ; *reference op= something
+
+;; For XML support:
+(defvar js2-DOTDOT 142) ; member operator (..)
+(defvar js2-COLONCOLON 143) ; namespace::name
+(defvar js2-XML 144) ; XML type
+(defvar js2-DOTQUERY 145) ; .() -- e.g., x.emps.emp.(name == "terry")
+(defvar js2-XMLATTR 146) ; @
+(defvar js2-XMLEND 147)
+
+;; Optimizer-only tokens
+(defvar js2-TO_OBJECT 148)
+(defvar js2-TO_DOUBLE 149)
+
+(defvar js2-GET 150) ; JS 1.5 get pseudo keyword
+(defvar js2-SET 151) ; JS 1.5 set pseudo keyword
+(defvar js2-LET 152) ; JS 1.7 let pseudo keyword
+(defvar js2-CONST 153)
+(defvar js2-SETCONST 154)
+(defvar js2-SETCONSTVAR 155)
+(defvar js2-ARRAYCOMP 156)
+(defvar js2-LETEXPR 157)
+(defvar js2-WITHEXPR 158)
+(defvar js2-DEBUGGER 159)
+
+(defvar js2-COMMENT 160)
+(defvar js2-ENUM 161) ; for "enum" reserved word
+
+(defconst js2-num-tokens (1+ js2-ENUM))
+
+(defconst js2-debug-print-trees nil)
+
+;; Rhino accepts any string or stream as input. Emacs character
+;; processing works best in buffers, so we'll assume the input is a
+;; buffer. JavaScript strings can be copied into temp buffers before
+;; scanning them.
+
+;; Buffer-local variables yield much cleaner code than using `defstruct'.
+;; They're the Emacs equivalent of instance variables, more or less.
+
+(js2-deflocal js2-ts-dirty-line nil
+ "Token stream buffer-local variable.
+Indicates stuff other than whitespace since start of line.")
+
+(js2-deflocal js2-ts-regexp-flags nil
+ "Token stream buffer-local variable.")
+
+(js2-deflocal js2-ts-string ""
+ "Token stream buffer-local variable.
+Last string scanned.")
+
+(js2-deflocal js2-ts-number nil
+ "Token stream buffer-local variable.
+Last literal number scanned.")
+
+(js2-deflocal js2-ts-hit-eof nil
+ "Token stream buffer-local variable.")
+
+(js2-deflocal js2-ts-line-start 0
+ "Token stream buffer-local variable.")
+
+(js2-deflocal js2-ts-lineno 1
+ "Token stream buffer-local variable.")
+
+(js2-deflocal js2-ts-line-end-char -1
+ "Token stream buffer-local variable.")
+
+(js2-deflocal js2-ts-cursor 1 ; emacs buffers are 1-indexed
+ "Token stream buffer-local variable.
+Current scan position.")
+
+(js2-deflocal js2-ts-is-xml-attribute nil
+ "Token stream buffer-local variable.")
+
+(js2-deflocal js2-ts-xml-is-tag-content nil
+ "Token stream buffer-local variable.")
+
+(js2-deflocal js2-ts-xml-open-tags-count 0
+ "Token stream buffer-local variable.")
+
+(js2-deflocal js2-ts-string-buffer nil
+ "Token stream buffer-local variable.
+List of chars built up while scanning various tokens.")
+
+(js2-deflocal js2-ts-comment-type nil
+ "Token stream buffer-local variable.")
+
+;;; Parser variables
+
+(js2-deflocal js2-parsed-errors nil
+ "List of errors produced during scanning/parsing.")
+
+(js2-deflocal js2-parsed-warnings nil
+ "List of warnings produced during scanning/parsing.")
+
+(js2-deflocal js2-recover-from-parse-errors t
+ "Non-nil to continue parsing after a syntax error.
+
+In recovery mode, the AST will be built in full, and any error
+nodes will be flagged with appropriate error information. If
+this flag is nil, a syntax error will result in an error being
+signaled.
+
+The variable is automatically buffer-local, because different
+modes that use the parser will need different settings.")
+
+(js2-deflocal js2-parse-hook nil
+ "List of callbacks for receiving parsing progress.")
+
+(defvar js2-parse-finished-hook nil
+ "List of callbacks to notify when parsing finishes.
+Not called if parsing was interrupted.")
+
+(js2-deflocal js2-is-eval-code nil
+ "True if we're evaluating code in a string.
+If non-nil, the tokenizer will record the token text, and the AST nodes
+will record their source text. Off by default for IDE modes, since the
+text is available in the buffer.")
+
+(defvar js2-parse-ide-mode t
+ "Non-nil if the parser is being used for `js2-mode'.
+If non-nil, the parser will set text properties for fontification
+and the syntax table. The value should be nil when using the
+parser as a frontend to an interpreter or byte compiler.")
+
+;;; Parser instance variables (buffer-local vars for js2-parse)
+
+(defconst js2-clear-ti-mask #xFFFF
+ "Mask to clear token information bits.")
+
+(defconst js2-ti-after-eol (lsh 1 16)
+ "Flag: first token of the source line.")
+
+(defconst js2-ti-check-label (lsh 1 17)
+ "Flag: indicates to check for label.")
+
+;; Inline Rhino's CompilerEnvirons vars as buffer-locals.
+
+(js2-deflocal js2-compiler-generate-debug-info t)
+(js2-deflocal js2-compiler-use-dynamic-scope nil)
+(js2-deflocal js2-compiler-reserved-keywords-as-identifier nil)
+(js2-deflocal js2-compiler-xml-available t)
+(js2-deflocal js2-compiler-optimization-level 0)
+(js2-deflocal js2-compiler-generating-source t)
+(js2-deflocal js2-compiler-strict-mode nil)
+(js2-deflocal js2-compiler-report-warning-as-error nil)
+(js2-deflocal js2-compiler-generate-observer-count nil)
+(js2-deflocal js2-compiler-activation-names nil)
+
+;; SKIP: sourceURI
+
+;; There's a compileFunction method in Context.java - may need it.
+(js2-deflocal js2-called-by-compile-function nil
+ "True if `js2-parse' was called by `js2-compile-function'.
+Will only be used when we finish implementing the interpreter.")
+
+;; SKIP: ts (we just call `js2-init-scanner' and use its vars)
+
+(js2-deflocal js2-current-flagged-token js2-EOF)
+(js2-deflocal js2-current-token js2-EOF)
+
+;; SKIP: node factory - we're going to just call functions directly,
+;; and eventually go to a unified AST format.
+
+(js2-deflocal js2-nesting-of-function 0)
+
+(js2-deflocal js2-recorded-assignments nil
+ "Tracks assignments found during parsing.")
+
+(defcustom js2-global-externs nil
+ "A list of any extern names you'd like to consider always declared.
+This list is global and is used by all js2-mode files.
+You can create buffer-local externs list using `js2-additional-externs'.
+
+There is also a buffer-local variable `js2-default-externs',
+which is initialized by default to include the Ecma-262 externs
+and the standard browser externs. The three lists are all
+checked during highlighting."
+ :type 'list
+ :group 'js2-mode)
+
+(js2-deflocal js2-default-externs nil
+ "Default external declarations.
+
+These are currently only used for highlighting undeclared variables,
+which only worries about top-level (unqualified) references.
+As js2-mode's processing improves, we will flesh out this list.
+
+The initial value is set to `js2-ecma-262-externs', unless you
+have set `js2-include-browser-externs', in which case the browser
+externs are also included.
+
+See `js2-additional-externs' for more information.")
+
+(defcustom js2-include-browser-externs t
+ "Non-nil to include browser externs in the master externs list.
+If you work on JavaScript files that are not intended for browsers,
+such as Mozilla Rhino server-side JavaScript, set this to nil.
+You can always include them on a per-file basis by calling
+`js2-add-browser-externs' from a function on `js2-mode-hook'.
+
+See `js2-additional-externs' for more information about externs."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-include-rhino-externs t
+ "Non-nil to include Mozilla Rhino externs in the master externs list.
+See `js2-additional-externs' for more information about externs."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-include-gears-externs t
+ "Non-nil to include Google Gears externs in the master externs list.
+See `js2-additional-externs' for more information about externs."
+ :type 'boolean
+ :group 'js2-mode)
+
+(js2-deflocal js2-additional-externs nil
+ "A buffer-local list of additional external declarations.
+It is used to decide whether variables are considered undeclared
+for purposes of highlighting.
+
+Each entry is a lisp string. The string should be the fully qualified
+name of an external entity. All externs should be added to this list,
+so that as js2-mode's processing improves it can take advantage of them.
+
+You may want to declare your externs in three ways.
+First, you can add externs that are valid for all your JavaScript files.
+You should probably do this by adding them to `js2-global-externs', which
+is a global list used for all js2-mode files.
+
+Next, you can add a function to `js2-mode-hook' that adds additional
+externs appropriate for the specific file, perhaps based on its path.
+These should go in `js2-additional-externs', which is buffer-local.
+
+Finally, you can add a function to `js2-post-parse-callbacks',
+which is called after parsing completes, and `root' is bound to
+the root of the parse tree. At this stage you can set up an AST
+node visitor using `js2-visit-ast' and examine the parse tree
+for specific import patterns that may imply the existence of
+other externs, possibly tied to your build system. These should also
+be added to `js2-additional-externs'.
+
+Your post-parse callback may of course also use the simpler and
+faster (but perhaps less robust) approach of simply scanning the
+buffer text for your imports, using regular expressions.")
+
+;; SKIP: decompiler
+;; SKIP: encoded-source
+
+;;; The following variables are per-function and should be saved/restored
+;;; during function parsing...
+
+(js2-deflocal js2-current-script-or-fn nil)
+(js2-deflocal js2-current-scope nil)
+(js2-deflocal js2-nesting-of-with 0)
+(js2-deflocal js2-label-set nil
+ "An alist mapping label names to nodes.")
+
+(js2-deflocal js2-loop-set nil)
+(js2-deflocal js2-loop-and-switch-set nil)
+(js2-deflocal js2-has-return-value nil)
+(js2-deflocal js2-end-flags 0)
+
+;;; ...end of per function variables
+
+;; Without 2-token lookahead, labels are a problem.
+;; These vars store the token info of the last matched name,
+;; iff it wasn't the last matched token. Only valid in some contexts.
+(defvar js2-prev-name-token-start nil)
+(defvar js2-prev-name-token-string nil)
+
+(defsubst js2-save-name-token-data (pos name)
+ (setq js2-prev-name-token-start pos
+ js2-prev-name-token-string name))
+
+;; These flags enumerate the possible ways a statement/function can
+;; terminate. These flags are used by endCheck() and by the Parser to
+;; detect inconsistent return usage.
+;;
+;; END_UNREACHED is reserved for code paths that are assumed to always be
+;; able to execute (example: throw, continue)
+;;
+;; END_DROPS_OFF indicates if the statement can transfer control to the
+;; next one. Statement such as return dont. A compound statement may have
+;; some branch that drops off control to the next statement.
+;;
+;; END_RETURNS indicates that the statement can return (without arguments)
+;; END_RETURNS_VALUE indicates that the statement can return a value.
+;;
+;; A compound statement such as
+;; if (condition) {
+;; return value;
+;; }
+;; Will be detected as (END_DROPS_OFF | END_RETURN_VALUE) by endCheck()
+
+(defconst js2-end-unreached #x0)
+(defconst js2-end-drops-off #x1)
+(defconst js2-end-returns #x2)
+(defconst js2-end-returns-value #x4)
+(defconst js2-end-yields #x8)
+
+;; Rhino awkwardly passes a statementLabel parameter to the
+;; statementHelper() function, the main statement parser, which
+;; is then used by quite a few of the sub-parsers. We just make
+;; it a buffer-local variable and make sure it's cleaned up properly.
+(js2-deflocal js2-labeled-stmt nil) ; type `js2-labeled-stmt-node'
+
+;; Similarly, Rhino passes an inForInit boolean through about half
+;; the expression parsers. We use a dynamically-scoped variable,
+;; which makes it easier to funcall the parsers individually without
+;; worrying about whether they take the parameter or not.
+(js2-deflocal js2-in-for-init nil)
+(js2-deflocal js2-temp-name-counter 0)
+(js2-deflocal js2-parse-stmt-count 0)
+
+(defsubst js2-get-next-temp-name ()
+ (format "$%d" (incf js2-temp-name-counter)))
+
+(defvar js2-parse-interruptable-p t
+ "Set this to nil to force parse to continue until finished.
+This will mostly be useful for interpreters.")
+
+(defvar js2-statements-per-pause 50
+ "Pause after this many statements to check for user input.
+If user input is pending, stop the parse and discard the tree.
+This makes for a smoother user experience for large files.
+You may have to wait a second or two before the highlighting
+and error-reporting appear, but you can always type ahead if
+you wish. This appears to be more or less how Eclipse, IntelliJ
+and other editors work.")
+
+(js2-deflocal js2-record-comments t
+ "Instructs the scanner to record comments in `js2-scanned-comments'.")
+
+(js2-deflocal js2-scanned-comments nil
+ "List of all comments from the current parse.")
+
+(defcustom js2-mode-indent-inhibit-undo nil
+ "Non-nil to disable collection of Undo information when indenting lines.
+Some users have requested this behavior. It's nil by default because
+other Emacs modes don't work this way."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-mode-indent-ignore-first-tab nil
+ "If non-nil, ignore first TAB keypress if we look indented properly.
+It's fairly common for users to navigate to an already-indented line
+and press TAB for reassurance that it's been indented. For this class
+of users, we want the first TAB press on a line to be ignored if the
+line is already indented to one of the precomputed alternatives.
+
+This behavior is only partly implemented. If you TAB-indent a line,
+navigate to another line, and then navigate back, it fails to clear
+the last-indented variable, so it thinks you've already hit TAB once,
+and performs the indent. A full solution would involve getting on the
+point-motion hooks for the entire buffer. If we come across another
+use cases that requires watching point motion, I'll consider doing it.
+
+If you set this variable to nil, then the TAB key will always change
+the indentation of the current line, if more than one alternative
+indentation spot exists."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defvar js2-indent-hook nil
+ "A hook for user-defined indentation rules.
+
+Functions on this hook should expect two arguments: (LIST INDEX)
+The LIST argument is the list of computed indentation points for
+the current line. INDEX is the list index of the indentation point
+that `js2-bounce-indent' plans to use. If INDEX is nil, then the
+indent function is not going to change the current line indentation.
+
+If a hook function on this list returns a non-nil value, then
+`js2-bounce-indent' assumes the hook function has performed its own
+indentation, and will do nothing. If all hook functions on the list
+return nil, then `js2-bounce-indent' will use its computed indentation
+and reindent the line.
+
+When hook functions on this hook list are called, the variable
+`js2-mode-ast' may or may not be set, depending on whether the
+parse tree is available. If the variable is nil, you can pass a
+callback to `js2-mode-wait-for-parse', and your callback will be
+called after the new parse tree is built. This can take some time
+in large files.")
+
+(defface js2-warning
+ `((((class color) (background light))
+ (:underline "orange"))
+ (((class color) (background dark))
+ (:underline "orange"))
+ (t (:underline t)))
+ "Face for JavaScript warnings."
+ :group 'js2-mode)
+
+(defface js2-error
+ `((((class color) (background light))
+ (:foreground "red"))
+ (((class color) (background dark))
+ (:foreground "red"))
+ (t (:foreground "red")))
+ "Face for JavaScript errors."
+ :group 'js2-mode)
+
+(defface js2-jsdoc-tag
+ '((t :foreground "SlateGray"))
+ "Face used to highlight @whatever tags in jsdoc comments."
+ :group 'js2-mode)
+
+(defface js2-jsdoc-type
+ '((t :foreground "SteelBlue"))
+ "Face used to highlight {FooBar} types in jsdoc comments."
+ :group 'js2-mode)
+
+(defface js2-jsdoc-value
+ '((t :foreground "PeachPuff3"))
+ "Face used to highlight tag values in jsdoc comments."
+ :group 'js2-mode)
+
+(defface js2-function-param
+ '((t :foreground "SeaGreen"))
+ "Face used to highlight function parameters in javascript."
+ :group 'js2-mode)
+
+(defface js2-instance-member
+ '((t :foreground "DarkOrchid"))
+ "Face used to highlight instance variables in javascript.
+Not currently used."
+ :group 'js2-mode)
+
+(defface js2-private-member
+ '((t :foreground "PeachPuff3"))
+ "Face used to highlight calls to private methods in javascript.
+Not currently used."
+ :group 'js2-mode)
+
+(defface js2-private-function-call
+ '((t :foreground "goldenrod"))
+ "Face used to highlight calls to private functions in javascript.
+Not currently used."
+ :group 'js2-mode)
+
+(defface js2-jsdoc-html-tag-name
+ (if js2-emacs22
+ '((((class color) (min-colors 88) (background light))
+ (:foreground "rosybrown"))
+ (((class color) (min-colors 8) (background dark))
+ (:foreground "yellow"))
+ (((class color) (min-colors 8) (background light))
+ (:foreground "magenta")))
+ '((((type tty pc) (class color) (background light))
+ (:foreground "magenta"))
+ (((type tty pc) (class color) (background dark))
+ (:foreground "yellow"))
+ (t (:foreground "RosyBrown"))))
+ "Face used to highlight jsdoc html tag names"
+ :group 'js2-mode)
+
+(defface js2-jsdoc-html-tag-delimiter
+ (if js2-emacs22
+ '((((class color) (min-colors 88) (background light))
+ (:foreground "dark khaki"))
+ (((class color) (min-colors 8) (background dark))
+ (:foreground "green"))
+ (((class color) (min-colors 8) (background light))
+ (:foreground "green")))
+ '((((type tty pc) (class color) (background light))
+ (:foreground "green"))
+ (((type tty pc) (class color) (background dark))
+ (:foreground "green"))
+ (t (:foreground "dark khaki"))))
+ "Face used to highlight brackets in jsdoc html tags."
+ :group 'js2-mode)
+
+(defface js2-magic-paren
+ '((t :underline t))
+ "Face used to color parens that will be auto-overwritten."
+ :group 'js2-mode)
+
+(defcustom js2-post-parse-callbacks nil
+ "A list of callback functions invoked after parsing finishes.
+Currently, the main use for this function is to add synthetic
+declarations to `js2-recorded-assignments', which see."
+ :type 'list
+ :group 'js2-mode)
+
+(defface js2-external-variable
+ '((t :foreground "orange"))
+ "Face used to highlight assignments to undeclared variables.
+An undeclared variable is any variable not declared with var or let
+in the current scope or any lexically enclosing scope. If you assign
+to such a variable, then you are either expecting it to originate from
+another file, or you've got a potential bug."
+ :group 'js2-mode)
+
+(defcustom js2-highlight-external-variables t
+ "Non-nil to higlight assignments to undeclared variables."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defcustom js2-auto-insert-catch-block t
+ "Non-nil to insert matching catch block on open-curly after `try'."
+ :type 'boolean
+ :group 'js2-mode)
+
+(defvar js2-mode-map
+ (let ((map (make-sparse-keymap))
+ keys)
+ (define-key map [mouse-1] #'js2-mode-show-node)
+ (define-key map (kbd "C-m") #'js2-enter-key)
+ (when js2-rebind-eol-bol-keys
+ (define-key map (kbd "C-a") #'js2-beginning-of-line)
+ (define-key map (kbd "C-e") #'js2-end-of-line))
+ (define-key map (kbd "C-c C-e") #'js2-mode-hide-element)
+ (define-key map (kbd "C-c C-s") #'js2-mode-show-element)
+ (define-key map (kbd "C-c C-a") #'js2-mode-show-all)
+ (define-key map (kbd "C-c C-f") #'js2-mode-toggle-hide-functions)
+ (define-key map (kbd "C-c C-t") #'js2-mode-toggle-hide-comments)
+ (define-key map (kbd "C-c C-o") #'js2-mode-toggle-element)
+ (define-key map (kbd "C-c C-w") #'js2-mode-toggle-warnings-and-errors)
+ (define-key map (kbd "C-c C-`") #'js2-next-error)
+ ;; also define user's preference for next-error, if available
+ (if (setq keys (where-is-internal #'next-error))
+ (define-key map (car keys) #'js2-next-error))
+ (define-key map (or (car (where-is-internal #'mark-defun))
+ (kbd "M-C-h"))
+ #'js2-mark-defun)
+ (define-key map (or (car (where-is-internal #'narrow-to-defun))
+ (kbd "C-x nd"))
+ #'js2-narrow-to-defun)
+ (define-key map [down-mouse-3] #'js2-down-mouse-3)
+ (when js2-auto-indent-p
+ (mapc (lambda (key)
+ (define-key map key #'js2-insert-and-indent))
+ js2-electric-keys))
+
+ (define-key map [menu-bar javascript]
+ (cons "JavaScript" (make-sparse-keymap "JavaScript")))
+
+ (define-key map [menu-bar javascript customize-js2-mode]
+ '(menu-item "Customize js2-mode" js2-mode-customize
+ :help "Customize the behavior of this mode"))
+
+ (define-key map [menu-bar javascript js2-force-refresh]
+ '(menu-item "Force buffer refresh" js2-mode-reset
+ :help "Re-parse the buffer from scratch"))
+
+ (define-key map [menu-bar javascript separator-2]
+ '("--"))
+
+ (define-key map [menu-bar javascript next-error]
+ '(menu-item "Next warning or error" js2-next-error
+ :enabled (and js2-mode-ast
+ (or (js2-ast-root-errors js2-mode-ast)
+ (js2-ast-root-warnings js2-mode-ast)))
+ :help "Move to next warning or error"))
+
+ (define-key map [menu-bar javascript display-errors]
+ '(menu-item "Show errors and warnings" js2-mode-display-warnings-and-errors
+ :visible (not js2-mode-show-parse-errors)
+ :help "Turn on display of warnings and errors"))
+
+ (define-key map [menu-bar javascript hide-errors]
+ '(menu-item "Hide errors and warnings" js2-mode-hide-warnings-and-errors
+ :visible js2-mode-show-parse-errors
+ :help "Turn off display of warnings and errors"))
+
+ (define-key map [menu-bar javascript separator-1]
+ '("--"))
+
+ (define-key map [menu-bar javascript js2-toggle-function]
+ '(menu-item "Show/collapse element" js2-mode-toggle-element
+ :help "Hide or show function body or comment"))
+
+ (define-key map [menu-bar javascript show-comments]
+ '(menu-item "Show block comments" js2-mode-toggle-hide-comments
+ :visible js2-mode-comments-hidden
+ :help "Expand all hidden block comments"))
+
+ (define-key map [menu-bar javascript hide-comments]
+ '(menu-item "Hide block comments" js2-mode-toggle-hide-comments
+ :visible (not js2-mode-comments-hidden)
+ :help "Show block comments as /*...*/"))
+
+ (define-key map [menu-bar javascript show-all-functions]
+ '(menu-item "Show function bodies" js2-mode-toggle-hide-functions
+ :visible js2-mode-functions-hidden
+ :help "Expand all hidden function bodies"))
+
+ (define-key map [menu-bar javascript hide-all-functions]
+ '(menu-item "Hide function bodies" js2-mode-toggle-hide-functions
+ :visible (not js2-mode-functions-hidden)
+ :help "Show {...} for all top-level function bodies"))
+
+ map)
+ "Keymap used in `js2-mode' buffers.")
+
+(defconst js2-mode-identifier-re "[a-zA-Z_$][a-zA-Z0-9_$]*")
+
+(defvar js2-mode-//-comment-re "^\\(\\s-*\\)//.+"
+ "Matches a //-comment line. Must be first non-whitespace on line.
+First match-group is the leading whitespace.")
+
+(defvar js2-mode-hook nil)
+
+(js2-deflocal js2-mode-ast nil "Private variable.")
+(js2-deflocal js2-mode-parse-timer nil "Private variable.")
+(js2-deflocal js2-mode-buffer-dirty-p nil "Private variable.")
+(js2-deflocal js2-mode-parsing nil "Private variable.")
+(js2-deflocal js2-mode-node-overlay nil)
+
+(defvar js2-mode-show-overlay js2-mode-dev-mode-p
+ "Debug: Non-nil to highlight AST nodes on mouse-down.")
+
+(js2-deflocal js2-mode-fontifications nil "Private variable")
+(js2-deflocal js2-mode-deferred-properties nil "Private variable")
+(js2-deflocal js2-imenu-recorder nil "Private variable")
+(js2-deflocal js2-imenu-function-map nil "Private variable")
+
+(defvar js2-paragraph-start
+ "\\(@[a-zA-Z]+\\>\\|$\\)")
+
+;; Note that we also set a 'c-in-sws text property in html comments,
+;; so that `c-forward-sws' and `c-backward-sws' work properly.
+(defvar js2-syntactic-ws-start
+ "\\s \\|/[*/]\\|[\n\r]\\|\\\\[\n\r]\\|\\s!\\|<!--\\|^\\s-*-->")
+
+(defvar js2-syntactic-ws-end
+ "\\s \\|[\n\r/]\\|\\s!")
+
+(defvar js2-syntactic-eol
+ (concat "\\s *\\(/\\*[^*\n\r]*"
+ "\\(\\*+[^*\n\r/][^*\n\r]*\\)*"
+ "\\*+/\\s *\\)*"
+ "\\(//\\|/\\*[^*\n\r]*"
+ "\\(\\*+[^*\n\r/][^*\n\r]*\\)*$"
+ "\\|\\\\$\\|$\\)")
+ "Copied from `java-mode'. Needed for some cc-engine functions.")
+
+(defvar js2-comment-prefix-regexp
+ "//+\\|\\**")
+
+(defvar js2-comment-start-skip
+ "\\(//+\\|/\\*+\\)\\s *")
+
+(defvar js2-mode-verbose-parse-p js2-mode-dev-mode-p
+ "Non-nil to emit status messages during parsing.")
+
+(defvar js2-mode-functions-hidden nil "private variable")
+(defvar js2-mode-comments-hidden nil "private variable")
+
+(defvar js2-mode-syntax-table
+ (let ((table (make-syntax-table)))
+ (c-populate-syntax-table table)
+ table)
+ "Syntax table used in js2-mode buffers.")
+
+(defvar js2-mode-abbrev-table nil
+ "Abbrev table in use in `js2-mode' buffers.")
+(define-abbrev-table 'js2-mode-abbrev-table ())
+
+(defvar js2-mode-pending-parse-callbacks nil
+ "List of functions waiting to be notified that parse is finished.")
+
+(defvar js2-mode-last-indented-line -1)
+
+;;; Localizable error and warning messages
+
+;; Messages are copied from Rhino's Messages.properties.
+;; Many of the Java-specific messages have been elided.
+;; Add any js2-specific ones at the end, so we can keep
+;; this file synced with changes to Rhino's.
+
+(defvar js2-message-table
+ (make-hash-table :test 'equal :size 250)
+ "Contains localized messages for js2-mode.")
+
+;; TODO(stevey): construct this table at compile-time.
+(defmacro js2-msg (key &rest strings)
+ `(puthash ,key (funcall #'concat ,@strings)
+ js2-message-table))
+
+(defun js2-get-msg (msg-key)
+ "Look up a localized message.
+MSG-KEY is a list of (MSG ARGS). If the message takes parameters,
+the correct number of ARGS must be provided."
+ (let* ((key (if (listp msg-key) (car msg-key) msg-key))
+ (args (if (listp msg-key) (cdr msg-key)))
+ (msg (gethash key js2-message-table)))
+ (if msg
+ (apply #'format msg args)
+ key))) ; default to showing the key
+
+(js2-msg "msg.dup.parms"
+ "Duplicate parameter name '%s'.")
+
+(js2-msg "msg.too.big.jump"
+ "Program too complex: jump offset too big.")
+
+(js2-msg "msg.too.big.index"
+ "Program too complex: internal index exceeds 64K limit.")
+
+(js2-msg "msg.while.compiling.fn"
+ "Encountered code generation error while compiling function '%s': %s")
+
+(js2-msg "msg.while.compiling.script"
+ "Encountered code generation error while compiling script: %s")
+
+;; Context
+(js2-msg "msg.ctor.not.found"
+ "Constructor for '%s' not found.")
+
+(js2-msg "msg.not.ctor"
+ "'%s' is not a constructor.")
+
+;; FunctionObject
+(js2-msg "msg.varargs.ctor"
+ "Method or constructor '%s' must be static "
+ "with the signature (Context cx, Object[] args, "
+ "Function ctorObj, boolean inNewExpr) "
+ "to define a variable arguments constructor.")
+
+(js2-msg "msg.varargs.fun"
+ "Method '%s' must be static with the signature "
+ "(Context cx, Scriptable thisObj, Object[] args, Function funObj) "
+ "to define a variable arguments function.")
+
+(js2-msg "msg.incompat.call"
+ "Method '%s' called on incompatible object.")
+
+(js2-msg "msg.bad.parms"
+ "Unsupported parameter type '%s' in method '%s'.")
+
+(js2-msg "msg.bad.method.return"
+ "Unsupported return type '%s' in method '%s'.")
+
+(js2-msg "msg.bad.ctor.return"
+ "Construction of objects of type '%s' is not supported.")
+
+(js2-msg "msg.no.overload"
+ "Method '%s' occurs multiple times in class '%s'.")
+
+(js2-msg "msg.method.not.found"
+ "Method '%s' not found in '%s'.")
+
+;; IRFactory
+
+(js2-msg "msg.bad.for.in.lhs"
+ "Invalid left-hand side of for..in loop.")
+
+(js2-msg "msg.mult.index"
+ "Only one variable allowed in for..in loop.")
+
+(js2-msg "msg.bad.for.in.destruct"
+ "Left hand side of for..in loop must be an array of "
+ "length 2 to accept key/value pair.")
+
+(js2-msg "msg.cant.convert"
+ "Can't convert to type '%s'.")
+
+(js2-msg "msg.bad.assign.left"
+ "Invalid assignment left-hand side.")
+
+(js2-msg "msg.bad.decr"
+ "Invalid decerement operand.")
+
+(js2-msg "msg.bad.incr"
+ "Invalid increment operand.")
+
+(js2-msg "msg.bad.yield"
+ "yield must be in a function.")
+
+(js2-msg "msg.yield.parenthesized"
+ "yield expression must be parenthesized.")
+
+;; NativeGlobal
+(js2-msg "msg.cant.call.indirect"
+ "Function '%s' must be called directly, and not by way of a "
+ "function of another name.")
+
+(js2-msg "msg.eval.nonstring"
+ "Calling eval() with anything other than a primitive "
+ "string value will simply return the value. "
+ "Is this what you intended?")
+
+(js2-msg "msg.eval.nonstring.strict"
+ "Calling eval() with anything other than a primitive "
+ "string value is not allowed in strict mode.")
+
+(js2-msg "msg.bad.destruct.op"
+ "Invalid destructuring assignment operator")
+
+;; NativeCall
+(js2-msg "msg.only.from.new"
+ "'%s' may only be invoked from a `new' expression.")
+
+(js2-msg "msg.deprec.ctor"
+ "The '%s' constructor is deprecated.")
+
+;; NativeFunction
+(js2-msg "msg.no.function.ref.found"
+ "no source found to decompile function reference %s")
+
+(js2-msg "msg.arg.isnt.array"
+ "second argument to Function.prototype.apply must be an array")
+
+;; NativeGlobal
+(js2-msg "msg.bad.esc.mask"
+ "invalid string escape mask")
+
+;; NativeRegExp
+(js2-msg "msg.bad.quant"
+ "Invalid quantifier %s")
+
+(js2-msg "msg.overlarge.backref"
+ "Overly large back reference %s")
+
+(js2-msg "msg.overlarge.min"
+ "Overly large minimum %s")
+
+(js2-msg "msg.overlarge.max"
+ "Overly large maximum %s")
+
+(js2-msg "msg.zero.quant"
+ "Zero quantifier %s")
+
+(js2-msg "msg.max.lt.min"
+ "Maximum %s less than minimum")
+
+(js2-msg "msg.unterm.quant"
+ "Unterminated quantifier %s")
+
+(js2-msg "msg.unterm.paren"
+ "Unterminated parenthetical %s")
+
+(js2-msg "msg.unterm.class"
+ "Unterminated character class %s")
+
+(js2-msg "msg.bad.range"
+ "Invalid range in character class.")
+
+(js2-msg "msg.trail.backslash"
+ "Trailing \\ in regular expression.")
+
+(js2-msg "msg.re.unmatched.right.paren"
+ "unmatched ) in regular expression.")
+
+(js2-msg "msg.no.regexp"
+ "Regular expressions are not available.")
+
+(js2-msg "msg.bad.backref"
+ "back-reference exceeds number of capturing parentheses.")
+
+(js2-msg "msg.bad.regexp.compile"
+ "Only one argument may be specified if the first "
+ "argument to RegExp.prototype.compile is a RegExp object.")
+
+;; Parser
+(js2-msg "msg.got.syntax.errors"
+ "Compilation produced %s syntax errors.")
+
+(js2-msg "msg.var.redecl"
+ "TypeError: redeclaration of var %s.")
+
+(js2-msg "msg.const.redecl"
+ "TypeError: redeclaration of const %s.")
+
+(js2-msg "msg.let.redecl"
+ "TypeError: redeclaration of variable %s.")
+
+(js2-msg "msg.parm.redecl"
+ "TypeError: redeclaration of formal parameter %s.")
+
+(js2-msg "msg.fn.redecl"
+ "TypeError: redeclaration of function %s.")
+
+(js2-msg "msg.let.decl.not.in.block"
+ "SyntaxError: let declaration not directly within block")
+
+;; NodeTransformer
+(js2-msg "msg.dup.label"
+ "duplicated label")
+
+(js2-msg "msg.undef.label"
+ "undefined label")
+
+(js2-msg "msg.bad.break"
+ "unlabelled break must be inside loop or switch")
+
+(js2-msg "msg.continue.outside"
+ "continue must be inside loop")
+
+(js2-msg "msg.continue.nonloop"
+ "continue can only use labels of iteration statements")
+
+(js2-msg "msg.bad.throw.eol"
+ "Line terminator is not allowed between the throw "
+ "keyword and throw expression.")
+
+(js2-msg "msg.no.paren.parms"
+ "missing ( before function parameters.")
+
+(js2-msg "msg.no.parm"
+ "missing formal parameter")
+
+(js2-msg "msg.no.paren.after.parms"
+ "missing ) after formal parameters")
+
+(js2-msg "msg.no.brace.body"
+ "missing '{' before function body")
+
+(js2-msg "msg.no.brace.after.body"
+ "missing } after function body")
+
+(js2-msg "msg.no.paren.cond"
+ "missing ( before condition")
+
+(js2-msg "msg.no.paren.after.cond"
+ "missing ) after condition")
+
+(js2-msg "msg.no.semi.stmt"
+ "missing ; before statement")
+
+(js2-msg "msg.missing.semi"
+ "missing ; after statement")
+
+(js2-msg "msg.no.name.after.dot"
+ "missing name after . operator")
+
+(js2-msg "msg.no.name.after.coloncolon"
+ "missing name after :: operator")
+
+(js2-msg "msg.no.name.after.dotdot"
+ "missing name after .. operator")
+
+(js2-msg "msg.no.name.after.xmlAttr"
+ "missing name after .@")
+
+(js2-msg "msg.no.bracket.index"
+ "missing ] in index expression")
+
+(js2-msg "msg.no.paren.switch"
+ "missing ( before switch expression")
+
+(js2-msg "msg.no.paren.after.switch"
+ "missing ) after switch expression")
+
+(js2-msg "msg.no.brace.switch"
+ "missing '{' before switch body")
+
+(js2-msg "msg.bad.switch"
+ "invalid switch statement")
+
+(js2-msg "msg.no.colon.case"
+ "missing : after case expression")
+
+(js2-msg "msg.double.switch.default"
+ "double default label in the switch statement")
+
+(js2-msg "msg.no.while.do"
+ "missing while after do-loop body")
+
+(js2-msg "msg.no.paren.for"
+ "missing ( after for")
+
+(js2-msg "msg.no.semi.for"
+ "missing ; after for-loop initializer")
+
+(js2-msg "msg.no.semi.for.cond"
+ "missing ; after for-loop condition")
+
+(js2-msg "msg.in.after.for.name"
+ "missing in after for")
+
+(js2-msg "msg.no.paren.for.ctrl"
+ "missing ) after for-loop control")
+
+(js2-msg "msg.no.paren.with"
+ "missing ( before with-statement object")
+
+(js2-msg "msg.no.paren.after.with"
+ "missing ) after with-statement object")
+
+(js2-msg "msg.no.paren.after.let"
+ "missing ( after let")
+
+(js2-msg "msg.no.paren.let"
+ "missing ) after variable list")
+
+(js2-msg "msg.no.curly.let"
+ "missing } after let statement")
+
+(js2-msg "msg.bad.return"
+ "invalid return")
+
+(js2-msg "msg.no.brace.block"
+ "missing } in compound statement")
+
+(js2-msg "msg.bad.label"
+ "invalid label")
+
+(js2-msg "msg.bad.var"
+ "missing variable name")
+
+(js2-msg "msg.bad.var.init"
+ "invalid variable initialization")
+
+(js2-msg "msg.no.colon.cond"
+ "missing : in conditional expression")
+
+(js2-msg "msg.no.paren.arg"
+ "missing ) after argument list")
+
+(js2-msg "msg.no.bracket.arg"
+ "missing ] after element list")
+
+(js2-msg "msg.bad.prop"
+ "invalid property id")
+
+(js2-msg "msg.no.colon.prop"
+ "missing : after property id")
+
+(js2-msg "msg.no.brace.prop"
+ "missing } after property list")
+
+(js2-msg "msg.no.paren"
+ "missing ) in parenthetical")
+
+(js2-msg "msg.reserved.id"
+ "identifier is a reserved word")
+
+(js2-msg "msg.no.paren.catch"
+ "missing ( before catch-block condition")
+
+(js2-msg "msg.bad.catchcond"
+ "invalid catch block condition")
+
+(js2-msg "msg.catch.unreachable"
+ "any catch clauses following an unqualified catch are unreachable")
+
+(js2-msg "msg.no.brace.try"
+ "missing '{' before try block")
+
+(js2-msg "msg.no.brace.catchblock"
+ "missing '{' before catch-block body")
+
+(js2-msg "msg.try.no.catchfinally"
+ "'try' without 'catch' or 'finally'")
+
+(js2-msg "msg.no.return.value"
+ "function %s does not always return a value")
+
+(js2-msg "msg.anon.no.return.value"
+ "anonymous function does not always return a value")
+
+(js2-msg "msg.return.inconsistent"
+ "return statement is inconsistent with previous usage")
+
+(js2-msg "msg.generator.returns"
+ "TypeError: generator function '%s' returns a value")
+
+(js2-msg "msg.anon.generator.returns"
+ "TypeError: anonymous generator function returns a value")
+
+(js2-msg "msg.syntax"
+ "syntax error")
+
+(js2-msg "msg.unexpected.eof"
+ "Unexpected end of file")
+
+(js2-msg "msg.XML.bad.form"
+ "illegally formed XML syntax")
+
+(js2-msg "msg.XML.not.available"
+ "XML runtime not available")
+
+(js2-msg "msg.too.deep.parser.recursion"
+ "Too deep recursion while parsing")
+
+(js2-msg "msg.no.side.effects"
+ "Code has no side effects")
+
+(js2-msg "msg.extra.trailing.comma"
+ "Trailing comma is not legal in an ECMA-262 object initializer")
+
+(js2-msg "msg.array.trailing.comma"
+ "Trailing comma yields different behavior across browsers")
+
+(js2-msg "msg.equal.as.assign"
+ (concat "Test for equality (==) mistyped as assignment (=)?"
+ " (parenthesize to suppress warning)"))
+
+(js2-msg "msg.var.hides.arg"
+ "Variable %s hides argument")
+
+(js2-msg "msg.destruct.assign.no.init"
+ "Missing = in destructuring declaration")
+
+;; ScriptRuntime
+(js2-msg "msg.no.properties"
+ "%s has no properties.")
+
+(js2-msg "msg.invalid.iterator"
+ "Invalid iterator value")
+
+(js2-msg "msg.iterator.primitive"
+ "__iterator__ returned a primitive value")
+
+(js2-msg "msg.assn.create.strict"
+ "Assignment to undeclared variable %s")
+
+(js2-msg "msg.ref.undefined.prop"
+ "Reference to undefined property '%s'")
+
+(js2-msg "msg.prop.not.found"
+ "Property %s not found.")
+
+(js2-msg "msg.invalid.type"
+ "Invalid JavaScript value of type %s")
+
+(js2-msg "msg.primitive.expected"
+ "Primitive type expected (had %s instead)")
+
+(js2-msg "msg.namespace.expected"
+ "Namespace object expected to left of :: (found %s instead)")
+
+(js2-msg "msg.null.to.object"
+ "Cannot convert null to an object.")
+
+(js2-msg "msg.undef.to.object"
+ "Cannot convert undefined to an object.")
+
+(js2-msg "msg.cyclic.value"
+ "Cyclic %s value not allowed.")
+
+(js2-msg "msg.is.not.defined"
+ "'%s' is not defined.")
+
+(js2-msg "msg.undef.prop.read"
+ "Cannot read property '%s' from %s")
+
+(js2-msg "msg.undef.prop.write"
+ "Cannot set property '%s' of %s to '%s'")
+
+(js2-msg "msg.undef.prop.delete"
+ "Cannot delete property '%s' of %s")
+
+(js2-msg "msg.undef.method.call"
+ "Cannot call method '%s' of %s")
+
+(js2-msg "msg.undef.with"
+ "Cannot apply 'with' to %s")
+
+(js2-msg "msg.isnt.function"
+ "%s is not a function, it is %s.")
+
+(js2-msg "msg.isnt.function.in"
+ "Cannot call property %s in object %s. "
+ "It is not a function, it is '%s'.")
+
+(js2-msg "msg.function.not.found"
+ "Cannot find function %s.")
+
+(js2-msg "msg.function.not.found.in"
+ "Cannot find function %s in object %s.")
+
+(js2-msg "msg.isnt.xml.object"
+ "%s is not an xml object.")
+
+(js2-msg "msg.no.ref.to.get"
+ "%s is not a reference to read reference value.")
+
+(js2-msg "msg.no.ref.to.set"
+ "%s is not a reference to set reference value to %s.")
+
+(js2-msg "msg.no.ref.from.function"
+ "Function %s can not be used as the left-hand "
+ "side of assignment or as an operand of ++ or -- operator.")
+
+(js2-msg "msg.bad.default.value"
+ "Object's getDefaultValue() method returned an object.")
+
+(js2-msg "msg.instanceof.not.object"
+ "Can't use instanceof on a non-object.")
+
+(js2-msg "msg.instanceof.bad.prototype"
+ "'prototype' property of %s is not an object.")
+
+(js2-msg "msg.bad.radix"
+ "illegal radix %s.")
+
+;; ScriptableObject
+(js2-msg "msg.default.value"
+ "Cannot find default value for object.")
+
+(js2-msg "msg.zero.arg.ctor"
+ "Cannot load class '%s' which has no zero-parameter constructor.")
+
+(js2-msg "msg.ctor.multiple.parms"
+ "Can't define constructor or class %s since more than "
+ "one constructor has multiple parameters.")
+
+(js2-msg "msg.extend.scriptable"
+ "%s must extend ScriptableObject in order to define property %s.")
+
+(js2-msg "msg.bad.getter.parms"
+ "In order to define a property, getter %s must have zero "
+ "parameters or a single ScriptableObject parameter.")
+
+(js2-msg "msg.obj.getter.parms"
+ "Expected static or delegated getter %s to take "
+ "a ScriptableObject parameter.")
+
+(js2-msg "msg.getter.static"
+ "Getter and setter must both be static or neither be static.")
+
+(js2-msg "msg.setter.return"
+ "Setter must have void return type: %s")
+
+(js2-msg "msg.setter2.parms"
+ "Two-parameter setter must take a ScriptableObject as "
+ "its first parameter.")
+
+(js2-msg "msg.setter1.parms"
+ "Expected single parameter setter for %s")
+
+(js2-msg "msg.setter2.expected"
+ "Expected static or delegated setter %s to take two parameters.")
+
+(js2-msg "msg.setter.parms"
+ "Expected either one or two parameters for setter.")
+
+(js2-msg "msg.setter.bad.type"
+ "Unsupported parameter type '%s' in setter '%s'.")
+
+(js2-msg "msg.add.sealed"
+ "Cannot add a property to a sealed object: %s.")
+
+(js2-msg "msg.remove.sealed"
+ "Cannot remove a property from a sealed object: %s.")
+
+(js2-msg "msg.modify.sealed"
+ "Cannot modify a property of a sealed object: %s.")
+
+(js2-msg "msg.modify.readonly"
+ "Cannot modify readonly property: %s.")
+
+;; TokenStream
+(js2-msg "msg.missing.exponent"
+ "missing exponent")
+
+(js2-msg "msg.caught.nfe"
+ "number format error")
+
+(js2-msg "msg.unterminated.string.lit"
+ "unterminated string literal")
+
+(js2-msg "msg.unterminated.comment"
+ "unterminated comment")
+
+(js2-msg "msg.unterminated.re.lit"
+ "unterminated regular expression literal")
+
+(js2-msg "msg.invalid.re.flag"
+ "invalid flag after regular expression")
+
+(js2-msg "msg.no.re.input.for"
+ "no input for %s")
+
+(js2-msg "msg.illegal.character"
+ "illegal character")
+
+(js2-msg "msg.invalid.escape"
+ "invalid Unicode escape sequence")
+
+(js2-msg "msg.bad.namespace"
+ "not a valid default namespace statement. "
+ "Syntax is: default xml namespace = EXPRESSION;")
+
+;; TokensStream warnings
+(js2-msg "msg.bad.octal.literal"
+ "illegal octal literal digit %s; "
+ "interpreting it as a decimal digit")
+
+(js2-msg "msg.reserved.keyword"
+ "illegal usage of future reserved keyword %s; "
+ "interpreting it as ordinary identifier")
+
+(js2-msg "msg.script.is.not.constructor"
+ "Script objects are not constructors.")
+
+;; Arrays
+(js2-msg "msg.arraylength.bad"
+ "Inappropriate array length.")
+
+;; Arrays
+(js2-msg "msg.arraylength.too.big"
+ "Array length %s exceeds supported capacity limit.")
+
+;; URI
+(js2-msg "msg.bad.uri"
+ "Malformed URI sequence.")
+
+;; Number
+(js2-msg "msg.bad.precision"
+ "Precision %s out of range.")
+
+;; NativeGenerator
+(js2-msg "msg.send.newborn"
+ "Attempt to send value to newborn generator")
+
+(js2-msg "msg.already.exec.gen"
+ "Already executing generator")
+
+(js2-msg "msg.StopIteration.invalid"
+ "StopIteration may not be changed to an arbitrary object.")
+
+;; Interpreter
+(js2-msg "msg.yield.closing"
+ "Yield from closing generator")
+
+;;; Utilities
+
+(defun js2-delete-if (predicate list)
+ "Remove all items satisfying PREDICATE in LIST."
+ (loop for item in list
+ if (not (funcall predicate item))
+ collect item))
+
+(defun js2-position (element list)
+ "Find 0-indexed position of ELEMENT in LIST comparing with `eq'.
+Returns nil if element is not found in the list."
+ (let ((count 0)
+ found)
+ (while (and list (not found))
+ (if (eq element (car list))
+ (setq found t)
+ (setq count (1+ count)
+ list (cdr list))))
+ (if found count)))
+
+(defun js2-find-if (predicate list)
+ "Find first item satisfying PREDICATE in LIST."
+ (let (result)
+ (while (and list (not result))
+ (if (funcall predicate (car list))
+ (setq result (car list)))
+ (setq list (cdr list)))
+ result))
+
+(defmacro js2-time (form)
+ "Evaluate FORM, discard result, and return elapsed time in sec"
+ (declare (debug t))
+ (let ((beg (make-symbol "--js2-time-beg--"))
+ (delta (make-symbol "--js2-time-end--")))
+ `(let ((,beg (current-time))
+ ,delta)
+ ,form
+ (/ (truncate (* (- (float-time (current-time))
+ (float-time ,beg)))
+ 10000)
+ 10000.0))))
+
+(defsubst js2-same-line (pos)
+ "Return t if POS is on the same line as current point."
+ (and (>= pos (point-at-bol))
+ (<= pos (point-at-eol))))
+
+(defsubst js2-same-line-2 (p1 p2)
+ "Return t if p1 is on the same line as p2."
+ (save-excursion
+ (goto-char p1)
+ (js2-same-line p2)))
+
+(defun js2-code-bug ()
+ "Signal an error when we encounter an unexpected code path."
+ (error "failed assertion"))
+
+;; I'd like to associate errors with nodes, but for now the
+;; easiest thing to do is get the context info from the last token.
+(defsubst js2-record-parse-error (msg &optional arg pos len)
+ (push (list (list msg arg)
+ (or pos js2-token-beg)
+ (or len (- js2-token-end js2-token-beg)))
+ js2-parsed-errors))
+
+(defsubst js2-report-error (msg &optional msg-arg pos len)
+ "Signal a syntax error or record a parse error."
+ (if js2-recover-from-parse-errors
+ (js2-record-parse-error msg msg-arg pos len)
+ (signal 'js2-syntax-error
+ (list msg
+ js2-ts-lineno
+ (save-excursion
+ (goto-char js2-ts-cursor)
+ (current-column))
+ js2-ts-hit-eof))))
+
+(defsubst js2-report-warning (msg &optional msg-arg pos len)
+ (if js2-compiler-report-warning-as-error
+ (js2-report-error msg msg-arg pos len)
+ (push (list (list msg msg-arg)
+ (or pos js2-token-beg)
+ (or len (- js2-token-end js2-token-beg)))
+ js2-parsed-warnings)))
+
+(defsubst js2-add-strict-warning (msg-id &optional msg-arg beg end)
+ (if js2-compiler-strict-mode
+ (js2-report-warning msg-id msg-arg beg
+ (and beg end (- end beg)))))
+
+(put 'js2-syntax-error 'error-conditions
+ '(error syntax-error js2-syntax-error))
+(put 'js2-syntax-error 'error-message "Syntax error")
+
+(put 'js2-parse-error 'error-conditions
+ '(error parse-error js2-parse-error))
+(put 'js2-parse-error 'error-message "Parse error")
+
+(defmacro js2-clear-flag (flags flag)
+ `(setq ,flags (logand ,flags (lognot ,flag))))
+
+(defmacro js2-set-flag (flags flag)
+ "Logical-or FLAG into FLAGS."
+ `(setq ,flags (logior ,flags ,flag)))
+
+(defsubst js2-flag-set-p (flags flag)
+ (/= 0 (logand flags flag)))
+
+(defsubst js2-flag-not-set-p (flags flag)
+ (zerop (logand flags flag)))
+
+;; Stolen shamelessly from James Clark's nxml-mode.
+(defmacro js2-with-unmodifying-text-property-changes (&rest body)
+ "Evaluate BODY without any text property changes modifying the buffer.
+Any text properties changes happen as usual but the changes are not treated as
+modifications to the buffer."
+ (declare (indent 0) (debug t))
+ (let ((modified (make-symbol "modified")))
+ `(let ((,modified (buffer-modified-p))
+ (inhibit-read-only t)
+ (inhibit-modification-hooks t)
+ (buffer-undo-list t)
+ (deactivate-mark nil)
+ ;; Apparently these avoid file locking problems.
+ (buffer-file-name nil)
+ (buffer-file-truename nil))
+ (unwind-protect
+ (progn ,@body)
+ (unless ,modified
+ (restore-buffer-modified-p nil))))))
+
+(defmacro js2-with-underscore-as-word-syntax (&rest body)
+ "Evaluate BODY with the _ character set to be word-syntax."
+ (declare (indent 0) (debug t))
+ (let ((old-syntax (make-symbol "old-syntax")))
+ `(let ((,old-syntax (string (char-syntax ?_))))
+ (unwind-protect
+ (progn
+ (modify-syntax-entry ?_ "w" js2-mode-syntax-table)
+ ,@body)
+ (modify-syntax-entry ?_ ,old-syntax js2-mode-syntax-table)))))
+
+(defsubst js2-char-uppercase-p (c)
+ "Return t if C is an uppercase character.
+Handles unicode and latin chars properly."
+ (/= c (downcase c)))
+
+(defsubst js2-char-lowercase-p (c)
+ "Return t if C is an uppercase character.
+Handles unicode and latin chars properly."
+ (/= c (upcase c)))
+
+;;; AST struct and function definitions
+
+;; flags for ast node property 'member-type (used for e4x operators)
+(defvar js2-property-flag #x1 "property access: element is valid name")
+(defvar js2-attribute-flag #x2 "x.@y or x..@y")
+(defvar js2-descendants-flag #x4 "x..y or x..@i")
+
+(defsubst js2-relpos (pos anchor)
+ "Convert POS to be relative to ANCHOR.
+If POS is nil, returns nil."
+ (and pos (- pos anchor)))
+
+(defsubst js2-make-pad (indent)
+ (if (zerop indent)
+ ""
+ (make-string (* indent js2-basic-offset) ? )))
+
+(defsubst js2-visit-ast (node callback)
+ "Visit every node in ast NODE with visitor CALLBACK.
+
+CALLBACK is a function that takes two arguments: (NODE END-P). It is
+called twice: once to visit the node, and again after all the node's
+children have been processed. The END-P argument is nil on the first
+call and non-nil on the second call. The return value of the callback
+affects the traversal: if non-nil, the children of NODE are processed.
+If the callback returns nil, or if the node has no children, then the
+callback is called immediately with a non-nil END-P argument.
+
+The node traversal is approximately lexical-order, although there
+are currently no guarantees around this."
+ (let ((vfunc (get (aref node 0) 'js2-visitor)))
+ ;; visit the node
+ (when (funcall callback node nil)
+ ;; visit the kids
+ (cond
+ ((eq vfunc 'js2-visit-none)
+ nil) ; don't even bother calling it
+ ;; Each AST node type has to define a `js2-visitor' function
+ ;; that takes a node and a callback, and calls `js2-visit-ast'
+ ;; on each child of the node.
+ (vfunc
+ (funcall vfunc node callback))
+ (t
+ (error "%s does not define a visitor-traversal function"
+ (aref node 0)))))
+ ;; call the end-visit
+ (funcall callback node t)))
+
+(defstruct (js2-node
+ (:constructor nil)) ; abstract
+ "Base AST node type."
+ (type -1) ; token type
+ (pos -1) ; start position of this AST node in parsed input
+ (len 1) ; num characters spanned by the node
+ props ; optional node property list (an alist)
+ parent) ; link to parent node; null for root
+
+(defsubst js2-node-get-prop (node prop &optional default)
+ (or (cadr (assoc prop (js2-node-props node))) default))
+
+(defsubst js2-node-set-prop (node prop value)
+ (setf (js2-node-props node)
+ (cons (list prop value) (js2-node-props node))))
+
+(defsubst js2-fixup-starts (n nodes)
+ "Adjust the start positions of NODES to be relative to N.
+Any node in the list may be nil, for convenience."
+ (dolist (node nodes)
+ (when node
+ (setf (js2-node-pos node) (- (js2-node-pos node)
+ (js2-node-pos n))))))
+
+(defsubst js2-node-add-children (parent &rest nodes)
+ "Set parent node of NODES to PARENT, and return PARENT.
+Does nothing if we're not recording parent links.
+If any given node in NODES is nil, doesn't record that link."
+ (js2-fixup-starts parent nodes)
+ (dolist (node nodes)
+ (and node
+ (setf (js2-node-parent node) parent))))
+
+;; Non-recursive since it's called a frightening number of times.
+(defsubst js2-node-abs-pos (n)
+ (let ((pos (js2-node-pos n)))
+ (while (setq n (js2-node-parent n))
+ (setq pos (+ pos (js2-node-pos n))))
+ pos))
+
+(defsubst js2-node-abs-end (n)
+ "Return absolute buffer position of end of N."
+ (+ (js2-node-abs-pos n) (js2-node-len n)))
+
+;; It's important to make sure block nodes have a lisp list for the
+;; child nodes, to limit printing recursion depth in an AST that
+;; otherwise consists of defstruct vectors. Emacs will crash printing
+;; a sufficiently large vector tree.
+
+(defstruct (js2-block-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-block-node (&key (type js2-BLOCK)
+ (pos js2-token-beg)
+ len
+ props
+ kids)))
+ "A block of statements."
+ kids) ; a lisp list of the child statement nodes
+
+(put 'cl-struct-js2-block-node 'js2-visitor 'js2-visit-block)
+(put 'cl-struct-js2-block-node 'js2-printer 'js2-print-block)
+
+(defsubst js2-visit-block (ast callback)
+ "Visit the `js2-block-node' children of AST."
+ (dolist (kid (js2-block-node-kids ast))
+ (js2-visit-ast kid callback)))
+
+(defun js2-print-block (n i)
+ (let ((pad (js2-make-pad i)))
+ (insert pad "{\n")
+ (dolist (kid (js2-block-node-kids n))
+ (js2-print-ast kid (1+ i)))
+ (insert pad "}")))
+
+(defstruct (js2-scope
+ (:include js2-block-node)
+ (:constructor nil)
+ (:constructor make-js2-scope (&key (type js2-BLOCK)
+ (pos js2-token-beg)
+ len
+ kids)))
+ ;; The symbol-table is a LinkedHashMap<String,Symbol> in Rhino.
+ ;; I don't have one of those handy, so I'll use an alist for now.
+ ;; It's as fast as an emacs hashtable for up to about 50 elements,
+ ;; and is much lighter-weight to construct (both CPU and mem).
+ ;; The keys are interned strings (symbols) for faster lookup.
+ ;; Should switch to hybrid alist/hashtable eventually.
+ symbol-table ; an alist of (symbol . js2-symbol)
+ parent-scope ; a `js2-scope'
+ top) ; top-level `js2-scope' (script/function)
+
+(put 'cl-struct-js2-scope 'js2-visitor 'js2-visit-none)
+(put 'cl-struct-js2-scope 'js2-printer 'js2-print-none)
+
+(defun js2-scope-set-parent-scope (scope parent)
+ (setf (js2-scope-parent-scope scope) parent
+ (js2-scope-top scope) (if (null parent)
+ scope
+ (js2-scope-top parent))))
+
+(defun js2-node-get-enclosing-scope (node)
+ "Return the innermost `js2-scope' node surrounding NODE.
+Returns nil if there is no enclosing scope node."
+ (let ((parent (js2-node-parent node)))
+ (while (not (js2-scope-p parent))
+ (setq parent (js2-node-parent parent)))
+ parent))
+
+(defun js2-get-defining-scope (scope name)
+ "Search up scope chain from SCOPE looking for NAME, a string or symbol.
+Returns `js2-scope' in which NAME is defined, or nil if not found."
+ (let ((sym (if (symbolp name)
+ name
+ (intern name)))
+ table
+ result
+ (continue t))
+ (while (and scope continue)
+ (if (and (setq table (js2-scope-symbol-table scope))
+ (assq sym table))
+ (setq continue nil
+ result scope)
+ (setq scope (js2-scope-parent-scope scope))))
+ result))
+
+(defsubst js2-scope-get-symbol (scope name)
+ "Return symbol table entry for NAME in SCOPE.
+NAME can be a string or symbol. Returns a `js2-symbol' or nil if not found."
+ (and (js2-scope-symbol-table scope)
+ (cdr (assq (if (symbolp name)
+ name
+ (intern name))
+ (js2-scope-symbol-table scope)))))
+
+(defsubst js2-scope-put-symbol (scope name symbol)
+ "Enter SYMBOL into symbol-table for SCOPE under NAME.
+NAME can be a lisp symbol or string. SYMBOL is a `js2-symbol'."
+ (let* ((table (js2-scope-symbol-table scope))
+ (sym (if (symbolp name) name (intern name)))
+ (entry (assq sym table)))
+ (if entry
+ (setcdr entry symbol)
+ (push (cons sym symbol)
+ (js2-scope-symbol-table scope)))))
+
+(defstruct (js2-symbol
+ (:constructor nil)
+ (:constructor make-js2-symbol (decl-type name &optional ast-node)))
+ "A symbol table entry."
+ ;; One of js2-FUNCTION, js2-LP (for parameters), js2-VAR,
+ ;; js2-LET, or js2-CONST
+ decl-type
+ name ; string
+ ast-node) ; a `js2-node'
+
+(defstruct (js2-error-node
+ (:include js2-node)
+ (:constructor nil) ; silence emacs21 byte-compiler
+ (:constructor make-js2-error-node (&key (type js2-ERROR)
+ (pos js2-token-beg)
+ len)))
+ "AST node representing a parse error.")
+
+(put 'cl-struct-js2-error-node 'js2-visitor 'js2-visit-none)
+(put 'cl-struct-js2-error-node 'js2-printer 'js2-print-none)
+
+(defstruct (js2-script-node
+ (:include js2-scope)
+ (:constructor nil)
+ (:constructor make-js2-script-node (&key (type js2-SCRIPT)
+ (pos js2-token-beg)
+ len
+ var-decls
+ fun-decls)))
+ functions ; lisp list of nested functions
+ regexps ; lisp list of (string . flags)
+ symbols ; alist (every symbol gets unique index)
+ (param-count 0)
+ var-names ; vector of string names
+ consts ; bool-vector matching var-decls
+ (temp-number 0)) ; for generating temp variables
+
+(put 'cl-struct-js2-script-node 'js2-visitor 'js2-visit-block)
+(put 'cl-struct-js2-script-node 'js2-printer 'js2-print-script)
+
+(defun js2-print-script (node indent)
+ (dolist (kid (js2-block-node-kids node))
+ (js2-print-ast kid indent)))
+
+(defstruct (js2-ast-root
+ (:include js2-script-node)
+ (:constructor nil)
+ (:constructor make-js2-ast-root (&key (type js2-SCRIPT)
+ (pos js2-token-beg)
+ len
+ buffer)))
+ "The root node of a js2 AST."
+ buffer ; the source buffer from which the code was parsed
+ comments ; a lisp list of comments, ordered by start position
+ errors ; a lisp list of errors found during parsing
+ warnings ; a lisp list of warnings found during parsing
+ node-count) ; number of nodes in the tree, including the root
+
+(put 'cl-struct-js2-ast-root 'js2-visitor 'js2-visit-ast-root)
+(put 'cl-struct-js2-ast-root 'js2-printer 'js2-print-script)
+
+(defun js2-visit-ast-root (ast callback)
+ (dolist (kid (js2-ast-root-kids ast))
+ (js2-visit-ast kid callback))
+ (dolist (comment (js2-ast-root-comments ast))
+ (js2-visit-ast comment callback)))
+
+(defstruct (js2-comment-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-comment-node (&key (type js2-COMMENT)
+ (pos js2-token-beg)
+ len
+ (format js2-ts-comment-type))))
+ format) ; 'line, 'block, 'jsdoc or 'html
+
+(put 'cl-struct-js2-comment-node 'js2-visitor 'js2-visit-none)
+(put 'cl-struct-js2-comment-node 'js2-printer 'js2-print-comment)
+
+(defun js2-print-comment (n i)
+ ;; We really ought to link end-of-line comments to their nodes.
+ ;; Or maybe we could add a new comment type, 'endline.
+ (insert (js2-make-pad i)
+ (js2-node-string n)))
+
+(defstruct (js2-expr-stmt-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-expr-stmt-node (&key (type js2-EXPR_VOID)
+ (pos js2-ts-cursor)
+ len
+ expr)))
+ "An expression statement."
+ expr)
+
+(defsubst js2-expr-stmt-node-set-has-result (node)
+ "Change the node type to `js2-EXPR_RESULT'. Used for code generation."
+ (setf (js2-node-type node) js2-EXPR_RESULT))
+
+(put 'cl-struct-js2-expr-stmt-node 'js2-visitor 'js2-visit-expr-stmt-node)
+(put 'cl-struct-js2-expr-stmt-node 'js2-printer 'js2-print-expr-stmt-node)
+
+(defun js2-visit-expr-stmt-node (n v)
+ (js2-visit-ast (js2-expr-stmt-node-expr n) v))
+
+(defun js2-print-expr-stmt-node (n indent)
+ (js2-print-ast (js2-expr-stmt-node-expr n) indent)
+ (insert ";\n"))
+
+(defstruct (js2-loop-node
+ (:include js2-scope)
+ (:constructor nil))
+ "Abstract supertype of loop nodes."
+ body ; a `js2-block-node'
+ lp ; position of left-paren, nil if omitted
+ rp) ; position of right-paren, nil if omitted
+
+(defstruct (js2-do-node
+ (:include js2-loop-node)
+ (:constructor nil)
+ (:constructor make-js2-do-node (&key (type js2-DO)
+ (pos js2-token-beg)
+ len
+ body
+ condition
+ while-pos
+ lp
+ rp)))
+ "AST node for do-loop."
+ condition ; while (expression)
+ while-pos) ; buffer position of 'while' keyword
+
+(put 'cl-struct-js2-do-node 'js2-visitor 'js2-visit-do-node)
+(put 'cl-struct-js2-do-node 'js2-printer 'js2-print-do-node)
+
+(defun js2-visit-do-node (n v)
+ (js2-visit-ast (js2-do-node-body n) v)
+ (js2-visit-ast (js2-do-node-condition n) v))
+
+(defun js2-print-do-node (n i)
+ (let ((pad (js2-make-pad i)))
+ (insert pad "do {\n")
+ (dolist (kid (js2-block-node-kids (js2-do-node-body n)))
+ (js2-print-ast kid (1+ i)))
+ (insert pad "} while (")
+ (js2-print-ast (js2-do-node-condition n) 0)
+ (insert ");\n")))
+
+(defstruct (js2-while-node
+ (:include js2-loop-node)
+ (:constructor nil)
+ (:constructor make-js2-while-node (&key (type js2-WHILE)
+ (pos js2-token-beg)
+ len
+ body
+ condition
+ lp
+ rp)))
+ "AST node for while-loop."
+ condition) ; while-condition
+
+(put 'cl-struct-js2-while-node 'js2-visitor 'js2-visit-while-node)
+(put 'cl-struct-js2-while-node 'js2-printer 'js2-print-while-node)
+
+(defun js2-visit-while-node (n v)
+ (js2-visit-ast (js2-while-node-condition n) v)
+ (js2-visit-ast (js2-while-node-body n) v))
+
+(defun js2-print-while-node (n i)
+ (let ((pad (js2-make-pad i)))
+ (insert pad "while (")
+ (js2-print-ast (js2-while-node-condition n) 0)
+ (insert ") {\n")
+ (js2-print-body (js2-while-node-body n) (1+ i))
+ (insert pad "}\n")))
+
+(defstruct (js2-for-node
+ (:include js2-loop-node)
+ (:constructor nil)
+ (:constructor make-js2-for-node (&key (type js2-FOR)
+ (pos js2-ts-cursor)
+ len
+ body
+ init
+ condition
+ update
+ lp
+ rp)))
+ "AST node for a C-style for-loop."
+ init ; initialization expression
+ condition ; loop condition
+ update) ; update clause
+
+(put 'cl-struct-js2-for-node 'js2-visitor 'js2-visit-for-node)
+(put 'cl-struct-js2-for-node 'js2-printer 'js2-print-for-node)
+
+(defun js2-visit-for-node (n v)
+ (js2-visit-ast (js2-for-node-init n) v)
+ (js2-visit-ast (js2-for-node-condition n) v)
+ (js2-visit-ast (js2-for-node-update n) v)
+ (js2-visit-ast (js2-for-node-body n) v))
+
+(defun js2-print-for-node (n i)
+ (let ((pad (js2-make-pad i)))
+ (insert pad "for (")
+ (js2-print-ast (js2-for-node-init n) 0)
+ (insert "; ")
+ (js2-print-ast (js2-for-node-condition n) 0)
+ (insert "; ")
+ (js2-print-ast (js2-for-node-update n) 0)
+ (insert ") {\n")
+ (js2-print-body (js2-for-node-body n) (1+ i))
+ (insert pad "}\n")))
+
+(defstruct (js2-for-in-node
+ (:include js2-loop-node)
+ (:constructor nil)
+ (:constructor make-js2-for-in-node (&key (type js2-FOR)
+ (pos js2-ts-cursor)
+ len
+ body
+ iterator
+ object
+ in-pos
+ each-pos
+ foreach-p
+ lp
+ rp)))
+ "AST node for a for..in loop."
+ iterator ; [var] foo in ...
+ object ; object over which we're iterating
+ in-pos ; buffer position of 'in' keyword
+ each-pos ; buffer position of 'each' keyword, if foreach-p
+ foreach-p) ; t if it's a for-each loop
+
+(put 'cl-struct-js2-for-in-node 'js2-visitor 'js2-visit-for-in-node)
+(put 'cl-struct-js2-for-in-node 'js2-printer 'js2-print-for-in-node)
+
+(defun js2-visit-for-in-node (n v)
+ (js2-visit-ast (js2-for-in-node-iterator n) v)
+ (js2-visit-ast (js2-for-in-node-object n) v)
+ (js2-visit-ast (js2-for-in-node-body n) v))
+
+(defun js2-print-for-in-node (n i)
+ (let ((pad (js2-make-pad i))
+ (foreach (js2-for-in-node-foreach-p n)))
+ (insert pad "for ")
+ (if foreach
+ (insert "each "))
+ (insert "(")
+ (js2-print-ast (js2-for-in-node-iterator n) 0)
+ (insert " in ")
+ (js2-print-ast (js2-for-in-node-object n) 0)
+ (insert ") {\n")
+ (js2-print-body (js2-for-in-node-body n) (1+ i))
+ (insert pad "}\n")))
+
+(defstruct (js2-return-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-return-node (&key (type js2-RETURN)
+ (pos js2-ts-cursor)
+ len
+ retval)))
+ "AST node for a return statement."
+ retval) ; expression to return, or 'undefined
+
+(put 'cl-struct-js2-return-node 'js2-visitor 'js2-visit-return-node)
+(put 'cl-struct-js2-return-node 'js2-printer 'js2-print-return-node)
+
+(defun js2-visit-return-node (n v)
+ (if (js2-return-node-retval n)
+ (js2-visit-ast (js2-return-node-retval n) v)))
+
+(defun js2-print-return-node (n i)
+ (insert (js2-make-pad i) "return")
+ (when (js2-return-node-retval n)
+ (insert " ")
+ (js2-print-ast (js2-return-node-retval n) 0))
+ (insert ";\n"))
+
+(defstruct (js2-if-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-if-node (&key (type js2-IF)
+ (pos js2-ts-cursor)
+ len
+ condition
+ then-part
+ else-pos
+ else-part
+ lp
+ rp)))
+ "AST node for an if-statement."
+ condition ; expression
+ then-part ; statement or block
+ else-pos ; optional buffer position of 'else' keyword
+ else-part ; optional statement or block
+ lp ; position of left-paren, nil if omitted
+ rp) ; position of right-paren, nil if omitted
+
+(put 'cl-struct-js2-if-node 'js2-visitor 'js2-visit-if-node)
+(put 'cl-struct-js2-if-node 'js2-printer 'js2-print-if-node)
+
+(defun js2-visit-if-node (n v)
+ (js2-visit-ast (js2-if-node-condition n) v)
+ (js2-visit-ast (js2-if-node-then-part n) v)
+ (if (js2-if-node-else-part n)
+ (js2-visit-ast (js2-if-node-else-part n) v)))
+
+(defun js2-print-if-node (n i)
+ (let ((pad (js2-make-pad i))
+ (then-part (js2-if-node-then-part n))
+ (else-part (js2-if-node-else-part n)))
+ (insert pad "if (")
+ (js2-print-ast (js2-if-node-condition n) 0)
+ (insert ") {\n")
+ (js2-print-body then-part (1+ i))
+ (insert pad "}")
+ (cond
+ ((not else-part)
+ (insert "\n"))
+ ((js2-if-node-p else-part)
+ (insert " else ")
+ (js2-print-body else-part i))
+ (t
+ (insert " else {\n")
+ (js2-print-body else-part (1+ i))
+ (insert pad "}\n")))))
+
+(defstruct (js2-try-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-try-node (&key (type js2-TRY)
+ (pos js2-ts-cursor)
+ len
+ try-block
+ catch-clauses
+ finally-block)))
+ "AST node for a try-statement."
+ try-block
+ catch-clauses ; a lisp list of `js2-catch-node'
+ finally-block) ; a `js2-finally-node'
+
+(put 'cl-struct-js2-try-node 'js2-visitor 'js2-visit-try-node)
+(put 'cl-struct-js2-try-node 'js2-printer 'js2-print-try-node)
+
+(defun js2-visit-try-node (n v)
+ (js2-visit-ast (js2-try-node-try-block n) v)
+ (dolist (clause (js2-try-node-catch-clauses n))
+ (js2-visit-ast clause v))
+ (if (js2-try-node-finally-block n)
+ (js2-visit-ast (js2-try-node-finally-block n) v)))
+
+(defun js2-print-try-node (n i)
+ (let ((pad (js2-make-pad i))
+ (catches (js2-try-node-catch-clauses n))
+ (finally (js2-try-node-finally-block n)))
+ (insert pad "try {\n")
+ (js2-print-body (js2-try-node-try-block n) (1+ i))
+ (insert pad "}")
+ (when catches
+ (dolist (catch catches)
+ (js2-print-ast catch i)))
+ (if finally
+ (js2-print-ast finally i)
+ (insert "\n"))))
+
+(defstruct (js2-catch-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-catch-node (&key (type js2-CATCH)
+ (pos js2-ts-cursor)
+ len
+ var-name
+ guard-kwd
+ guard-expr
+ block
+ lp
+ rp)))
+ "AST node for a catch clause."
+ var-name ; a `js2-name-node'
+ guard-kwd ; relative buffer position of "if" in "catch (x if ...)"
+ guard-expr ; catch condition, a `js2-node'
+ block ; statements, a `js2-block-node'
+ lp ; buffer position of left-paren, nil if omitted
+ rp) ; buffer position of right-paren, nil if omitted
+
+(put 'cl-struct-js2-catch-node 'js2-visitor 'js2-visit-catch-node)
+(put 'cl-struct-js2-catch-node 'js2-printer 'js2-print-catch-node)
+
+(defun js2-visit-catch-node (n v)
+ (js2-visit-ast (js2-catch-node-var-name n) v)
+ (when (js2-catch-node-guard-kwd n)
+ (js2-visit-ast (js2-catch-node-guard-expr n) v))
+ (js2-visit-ast (js2-catch-node-block n) v))
+
+(defun js2-print-catch-node (n i)
+ (let ((pad (js2-make-pad i))
+ (guard-kwd (js2-catch-node-guard-kwd n))
+ (guard-expr (js2-catch-node-guard-expr n)))
+ (insert " catch (")
+ (js2-print-ast (js2-catch-node-var-name n) 0)
+ (when guard-kwd
+ (insert " if ")
+ (js2-print-ast guard-expr 0))
+ (insert ") {\n")
+ (js2-print-body (js2-catch-node-block n) (1+ i))
+ (insert pad "}")))
+
+(defstruct (js2-finally-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-finally-node (&key (type js2-FINALLY)
+ (pos js2-ts-cursor)
+ len
+ body)))
+ "AST node for a finally clause."
+ body) ; a `js2-node', often but not always a block node
+
+(put 'cl-struct-js2-finally-node 'js2-visitor 'js2-visit-finally-node)
+(put 'cl-struct-js2-finally-node 'js2-printer 'js2-print-finally-node)
+
+(defun js2-visit-finally-node (n v)
+ (js2-visit-ast (js2-finally-node-body n) v))
+
+(defun js2-print-finally-node (n i)
+ (let ((pad (js2-make-pad i)))
+ (insert " finally {\n")
+ (js2-print-body (js2-finally-node-body n) (1+ i))
+ (insert pad "}\n")))
+
+(defstruct (js2-switch-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-switch-node (&key (type js2-SWITCH)
+ (pos js2-ts-cursor)
+ len
+ discriminant
+ cases
+ lp
+ rp)))
+ "AST node for a switch statement."
+ discriminant ; a `js2-node' (switch expression)
+ cases ; a lisp list of `js2-case-node'
+ lp ; position of open-paren for discriminant, nil if omitted
+ rp) ; position of close-paren for discriminant, nil if omitted
+
+(put 'cl-struct-js2-switch-node 'js2-visitor 'js2-visit-switch-node)
+(put 'cl-struct-js2-switch-node 'js2-printer 'js2-print-switch-node)
+
+(defun js2-visit-switch-node (n v)
+ (js2-visit-ast (js2-switch-node-discriminant n) v)
+ (dolist (c (js2-switch-node-cases n))
+ (js2-visit-ast c v)))
+
+(defun js2-print-switch-node (n i)
+ (let ((pad (js2-make-pad i))
+ (cases (js2-switch-node-cases n)))
+ (insert pad "switch (")
+ (js2-print-ast (js2-switch-node-discriminant n) 0)
+ (insert ") {\n")
+ (dolist (case cases)
+ (js2-print-ast case i))
+ (insert pad "}\n")))
+
+(defstruct (js2-case-node
+ (:include js2-block-node)
+ (:constructor nil)
+ (:constructor make-js2-case-node (&key (type js2-CASE)
+ (pos js2-ts-cursor)
+ len
+ kids
+ expr)))
+ "AST node for a case clause of a switch statement."
+ expr) ; the case expression (nil for default)
+
+(put 'cl-struct-js2-case-node 'js2-visitor 'js2-visit-case-node)
+(put 'cl-struct-js2-case-node 'js2-printer 'js2-print-case-node)
+
+(defun js2-visit-case-node (n v)
+ (if (js2-case-node-expr n) ; nil for default: case
+ (js2-visit-ast (js2-case-node-expr n) v))
+ (js2-visit-block n v))
+
+(defun js2-print-case-node (n i)
+ (let ((pad (js2-make-pad i))
+ (expr (js2-case-node-expr n)))
+ (insert pad)
+ (if (null expr)
+ (insert "default:\n")
+ (insert "case ")
+ (js2-print-ast expr 0)
+ (insert ":\n"))
+ (dolist (kid (js2-case-node-kids n))
+ (js2-print-ast kid (1+ i)))))
+
+(defstruct (js2-throw-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-throw-node (&key (type js2-THROW)
+ (pos js2-ts-cursor)
+ len
+ expr)))
+ "AST node for a throw statement."
+ expr) ; the expression to throw
+
+(put 'cl-struct-js2-throw-node 'js2-visitor 'js2-visit-throw-node)
+(put 'cl-struct-js2-throw-node 'js2-printer 'js2-print-throw-node)
+
+(defun js2-visit-throw-node (n v)
+ (js2-visit-ast (js2-throw-node-expr n) v))
+
+(defun js2-print-throw-node (n i)
+ (insert (js2-make-pad i) "throw ")
+ (js2-print-ast (js2-throw-node-expr n) 0)
+ (insert ";\n"))
+
+(defstruct (js2-with-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-with-node (&key (type js2-WITH)
+ (pos js2-ts-cursor)
+ len
+ object
+ body
+ lp
+ rp)))
+ "AST node for a with-statement."
+ object
+ body
+ lp ; buffer position of left-paren around object, nil if omitted
+ rp) ; buffer position of right-paren around object, nil if omitted
+
+(put 'cl-struct-js2-with-node 'js2-visitor 'js2-visit-with-node)
+(put 'cl-struct-js2-with-node 'js2-printer 'js2-print-with-node)
+
+(defun js2-visit-with-node (n v)
+ (js2-visit-ast (js2-with-node-object n) v)
+ (js2-visit-ast (js2-with-node-body n) v))
+
+(defun js2-print-with-node (n i)
+ (let ((pad (js2-make-pad i)))
+ (insert pad "with (")
+ (js2-print-ast (js2-with-node-object n) 0)
+ (insert ") {\n")
+ (js2-print-body (js2-with-node-body n) (1+ i))
+ (insert pad "}\n")))
+
+(defstruct (js2-label-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-label-node (&key (type js2-LABEL)
+ (pos js2-ts-cursor)
+ len
+ name)))
+ "AST node for a statement label or case label."
+ name ; a string
+ loop) ; for validating and code-generating continue-to-label
+
+(put 'cl-struct-js2-label-node 'js2-visitor 'js2-visit-none)
+(put 'cl-struct-js2-label-node 'js2-printer 'js2-print-label)
+
+(defun js2-print-label (n i)
+ (insert (js2-make-pad i)
+ (js2-label-node-name n)
+ ":\n"))
+
+(defstruct (js2-labeled-stmt-node
+ (:include js2-node)
+ (:constructor nil)
+ ;; type needs to be in `js2-side-effecting-tokens' to avoid spurious
+ ;; no-side-effects warnings, hence js2-EXPR_RESULT.
+ (:constructor make-js2-labeled-stmt-node (&key (type js2-EXPR_RESULT)
+ (pos js2-ts-cursor)
+ len
+ labels
+ stmt)))
+ "AST node for a statement with one or more labels.
+Multiple labels for a statement are collapsed into the labels field."
+ labels ; lisp list of `js2-label-node'
+ stmt) ; the statement these labels are for
+
+(put 'cl-struct-js2-labeled-stmt-node 'js2-visitor 'js2-visit-labeled-stmt)
+(put 'cl-struct-js2-labeled-stmt-node 'js2-printer 'js2-print-labeled-stmt)
+
+(defun js2-get-label-by-name (lbl-stmt name)
+ "Return a `js2-label-node' by NAME from LBL-STMT's labels list.
+Returns nil if no such label is in the list."
+ (let ((label-list (js2-labeled-stmt-node-labels lbl-stmt))
+ result)
+ (while (and label-list (not result))
+ (if (string= (js2-label-node-name (car label-list)) name)
+ (setq result (car label-list))
+ (setq label-list (cdr label-list))))
+ result))
+
+(defun js2-visit-labeled-stmt (n v)
+ (dolist (label (js2-labeled-stmt-node-labels n))
+ (js2-visit-ast label v))
+ (js2-visit-ast (js2-labeled-stmt-node-stmt n) v))
+
+(defun js2-print-labeled-stmt (n i)
+ (dolist (label (js2-labeled-stmt-node-labels n))
+ (js2-print-ast label i))
+ (js2-print-ast (js2-labeled-stmt-node-stmt n) (1+ i)))
+
+(defun js2-labeled-stmt-node-contains (node label)
+ "Return t if NODE contains LABEL in its label set.
+NODE is a `js2-labels-node'. LABEL is an identifier."
+ (loop for nl in (js2-labeled-stmt-node-labels node)
+ if (string= label (js2-label-node-name nl))
+ return t
+ finally return nil))
+
+(defsubst js2-labeled-stmt-node-add-label (node label)
+ "Add a `js2-label-node' to the label set for this statement."
+ (setf (js2-labeled-stmt-node-labels node)
+ (nconc (js2-labeled-stmt-node-labels node) (list label))))
+
+(defstruct (js2-jump-node
+ (:include js2-node)
+ (:constructor nil))
+ "Abstract supertype of break and continue nodes."
+ label ; `js2-name-node' for location of label identifier, if present
+ target) ; target js2-labels-node or loop/switch statement
+
+(defun js2-visit-jump-node (n v)
+ ;; we don't visit the target, since it's a back-link
+ (if (js2-jump-node-label n)
+ (js2-visit-ast (js2-jump-node-label n) v)))
+
+(defstruct (js2-break-node
+ (:include js2-jump-node)
+ (:constructor nil)
+ (:constructor make-js2-break-node (&key (type js2-BREAK)
+ (pos js2-ts-cursor)
+ len
+ label
+ target)))
+ "AST node for a break statement.
+The label field is a `js2-name-node', possibly nil, for the named label
+if provided. E.g. in 'break foo', it represents 'foo'. The target field
+is the target of the break - a label node or enclosing loop/switch statement.")
+
+(put 'cl-struct-js2-break-node 'js2-visitor 'js2-visit-jump-node)
+(put 'cl-struct-js2-break-node 'js2-printer 'js2-print-break-node)
+
+(defun js2-print-break-node (n i)
+ (insert (js2-make-pad i) "break")
+ (when (js2-break-node-label n)
+ (insert " ")
+ (js2-print-ast (js2-break-node-label n) 0))
+ (insert ";\n"))
+
+(defstruct (js2-continue-node
+ (:include js2-jump-node)
+ (:constructor nil)
+ (:constructor make-js2-continue-node (&key (type js2-CONTINUE)
+ (pos js2-ts-cursor)
+ len
+ label
+ target)))
+ "AST node for a continue statement.
+The label field is the user-supplied enclosing label name, a `js2-name-node'.
+It is nil if continue specifies no label. The target field is the jump target:
+a `js2-label-node' or the innermost enclosing loop.")
+
+(put 'cl-struct-js2-continue-node 'js2-visitor 'js2-visit-jump-node)
+(put 'cl-struct-js2-continue-node 'js2-printer 'js2-print-continue-node)
+
+(defun js2-print-continue-node (n i)
+ (insert (js2-make-pad i) "continue")
+ (when (js2-continue-node-label n)
+ (insert " ")
+ (js2-print-ast (js2-continue-node-label n) 0))
+ (insert ";\n"))
+
+(defstruct (js2-function-node
+ (:include js2-script-node)
+ (:constructor nil)
+ (:constructor make-js2-function-node (&key (type js2-FUNCTION)
+ (pos js2-ts-cursor)
+ len
+ (ftype 'FUNCTION)
+ (form 'FUNCTION_STATEMENT)
+ (name "")
+ params
+ body
+ lp
+ rp)))
+ "AST node for a function declaration.
+The `params' field is a lisp list of nodes. Each node is either a simple
+`js2-name-node', or if it's a destructuring-assignment parameter, a
+`js2-array-node' or `js2-object-node'."
+ ftype ; FUNCTION, GETTER or SETTER
+ form ; FUNCTION_{STATEMENT|EXPRESSION|EXPRESSION_STATEMENT}
+ name ; function name (a `js2-name-node', or nil if anonymous)
+ params ; a lisp list of destructuring forms or simple name nodes
+ body ; a `js2-block-node' or expression node (1.8 only)
+ lp ; position of arg-list open-paren, or nil if omitted
+ rp ; position of arg-list close-paren, or nil if omitted
+ ignore-dynamic ; ignore value of the dynamic-scope flag (interpreter only)
+ needs-activation ; t if we need an activation object for this frame
+ is-generator ; t if this function contains a yield
+ member-expr) ; nonstandard Ecma extension from Rhino
+
+(put 'cl-struct-js2-function-node 'js2-visitor 'js2-visit-function-node)
+(put 'cl-struct-js2-function-node 'js2-printer 'js2-print-function-node)
+
+(defun js2-visit-function-node (n v)
+ (if (js2-function-node-name n)
+ (js2-visit-ast (js2-function-node-name n) v))
+ (dolist (p (js2-function-node-params n))
+ (js2-visit-ast p v))
+ (js2-visit-ast (js2-function-node-body n) v))
+
+(defun js2-print-function-node (n i)
+ (let ((pad (js2-make-pad i))
+ (getter (js2-node-get-prop n 'GETTER_SETTER))
+ (name (js2-function-node-name n))
+ (params (js2-function-node-params n))
+ (body (js2-function-node-body n))
+ (expr (eq (js2-function-node-form n) 'FUNCTION_EXPRESSION)))
+ (unless getter
+ (insert pad "function"))
+ (when name
+ (insert " ")
+ (js2-print-ast name 0))
+ (insert "(")
+ (loop with len = (length params)
+ for param in params
+ for count from 1
+ do
+ (js2-print-ast param 0)
+ (if (< count len)
+ (insert ", ")))
+ (insert ") {")
+ (unless expr
+ (insert "\n"))
+ ;; TODO: fix this to be smarter about indenting, etc.
+ (js2-print-body body (1+ i))
+ (insert pad "}")
+ (unless expr
+ (insert "\n"))))
+
+(defsubst js2-function-name (node)
+ "Return function name for NODE, a `js2-function-node', or nil if anonymous."
+ (and (js2-function-node-name node)
+ (js2-name-node-name (js2-function-node-name node))))
+
+;; Having this be an expression node makes it more flexible.
+;; There are IDE contexts, such as indentation in a for-loop initializer,
+;; that work better if you assume it's an expression. Whenever we have
+;; a standalone var/const declaration, we just wrap with an expr stmt.
+;; Eclipse apparently screwed this up and now has two versions, expr and stmt.
+(defstruct (js2-var-decl-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-var-decl-node (&key (type js2-VAR)
+ (pos js2-token-beg)
+ len
+ kids
+ decl-type)))
+ "AST node for a variable declaration list (VAR, CONST or LET).
+The node bounds differ depending on the declaration type. For VAR or
+CONST declarations, the bounds include the var/const keyword. For LET
+declarations, the node begins at the position of the first child."
+ kids ; a lisp list of `js2-var-init-node' structs.
+ decl-type) ; js2-VAR, js2-CONST or js2-LET
+
+(put 'cl-struct-js2-var-decl-node 'js2-visitor 'js2-visit-var-decl)
+(put 'cl-struct-js2-var-decl-node 'js2-printer 'js2-print-var-decl)
+
+(defun js2-visit-var-decl (n v)
+ (dolist (kid (js2-var-decl-node-kids n))
+ (js2-visit-ast kid v)))
+
+(defun js2-print-var-decl (n i)
+ (let ((pad (js2-make-pad i))
+ (tt (js2-var-decl-node-decl-type n)))
+ (insert pad)
+ (insert (cond
+ ((= tt js2-VAR) "var ")
+ ((= tt js2-LET) "") ; handled by parent let-{expr/stmt}
+ ((= tt js2-CONST) "const ")
+ (t
+ (error "malformed var-decl node"))))
+ (loop with kids = (js2-var-decl-node-kids n)
+ with len = (length kids)
+ for kid in kids
+ for count from 1
+ do
+ (js2-print-ast kid 0)
+ (if (< count len)
+ (insert ", ")))))
+
+(defstruct (js2-var-init-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-var-init-node (&key (type js2-VAR)
+ (pos js2-ts-cursor)
+ len
+ target
+ initializer)))
+ "AST node for a variable declaration.
+The type field will be js2-CONST for a const decl."
+ target ; `js2-name-node', `js2-object-node', or `js2-array-node'
+ initializer) ; initializer expression, a `js2-node'
+
+(put 'cl-struct-js2-var-init-node 'js2-visitor 'js2-visit-var-init-node)
+(put 'cl-struct-js2-var-init-node 'js2-printer 'js2-print-var-init-node)
+
+(defun js2-visit-var-init-node (n v)
+ (js2-visit-ast (js2-var-init-node-target n) v)
+ (if (js2-var-init-node-initializer n)
+ (js2-visit-ast (js2-var-init-node-initializer n) v)))
+
+(defun js2-print-var-init-node (n i)
+ (let ((pad (js2-make-pad i))
+ (name (js2-var-init-node-target n))
+ (init (js2-var-init-node-initializer n)))
+ (insert pad)
+ (js2-print-ast name 0)
+ (when init
+ (insert " = ")
+ (js2-print-ast init 0))))
+
+(defstruct (js2-cond-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-cond-node (&key (type js2-HOOK)
+ (pos js2-ts-cursor)
+ len
+ test-expr
+ true-expr
+ false-expr
+ q-pos
+ c-pos)))
+ "AST node for the ternary operator"
+ test-expr
+ true-expr
+ false-expr
+ q-pos ; buffer position of ?
+ c-pos) ; buffer position of :
+
+(put 'cl-struct-js2-cond-node 'js2-visitor 'js2-visit-cond-node)
+(put 'cl-struct-js2-cond-node 'js2-printer 'js2-print-cond-node)
+
+(defun js2-visit-cond-node (n v)
+ (js2-visit-ast (js2-cond-node-test-expr n) v)
+ (js2-visit-ast (js2-cond-node-true-expr n) v)
+ (js2-visit-ast (js2-cond-node-false-expr n) v))
+
+(defun js2-print-cond-node (n i)
+ (let ((pad (js2-make-pad i)))
+ (insert pad)
+ (js2-print-ast (js2-cond-node-test-expr n) 0)
+ (insert " ? ")
+ (js2-print-ast (js2-cond-node-true-expr n) 0)
+ (insert " : ")
+ (js2-print-ast (js2-cond-node-false-expr n) 0)))
+
+(defstruct (js2-infix-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-infix-node (&key type
+ (pos js2-ts-cursor)
+ len
+ op-pos
+ left
+ right)))
+ "Represents infix expressions.
+Includes assignment ops like `|=', and the comma operator.
+The type field inherited from `js2-node' holds the operator."
+ op-pos ; buffer position where operator begins
+ left ; any `js2-node'
+ right) ; any `js2-node'
+
+(put 'cl-struct-js2-infix-node 'js2-visitor 'js2-visit-infix-node)
+(put 'cl-struct-js2-infix-node 'js2-printer 'js2-print-infix-node)
+
+(defun js2-visit-infix-node (n v)
+ (when (js2-infix-node-left n)
+ (js2-visit-ast (js2-infix-node-left n) v))
+ (when (js2-infix-node-right n)
+ (js2-visit-ast (js2-infix-node-right n) v)))
+
+(defconst js2-operator-tokens
+ (let ((table (make-hash-table :test 'eq))
+ (tokens
+ (list (cons js2-IN "in")
+ (cons js2-TYPEOF "typeof")
+ (cons js2-INSTANCEOF "instanceof")
+ (cons js2-DELPROP "delete")
+ (cons js2-COMMA ",")
+ (cons js2-COLON ":")
+ (cons js2-OR "||")
+ (cons js2-AND "&&")
+ (cons js2-INC "++")
+ (cons js2-DEC "--")
+ (cons js2-BITOR "|")
+ (cons js2-BITXOR "^")
+ (cons js2-BITAND "&")
+ (cons js2-EQ "==")
+ (cons js2-NE "!=")
+ (cons js2-LT "<")
+ (cons js2-LE "<=")
+ (cons js2-GT ">")
+ (cons js2-GE ">=")
+ (cons js2-LSH "<<")
+ (cons js2-RSH ">>")
+ (cons js2-URSH ">>>")
+ (cons js2-ADD "+") ; infix plus
+ (cons js2-SUB "-") ; infix minus
+ (cons js2-MUL "*")
+ (cons js2-DIV "/")
+ (cons js2-MOD "%")
+ (cons js2-NOT "!")
+ (cons js2-BITNOT "~")
+ (cons js2-POS "+") ; unary plus
+ (cons js2-NEG "-") ; unary minus
+ (cons js2-SHEQ "===") ; shallow equality
+ (cons js2-SHNE "!==") ; shallow inequality
+ (cons js2-ASSIGN "=")
+ (cons js2-ASSIGN_BITOR "|=")
+ (cons js2-ASSIGN_BITXOR "^=")
+ (cons js2-ASSIGN_BITAND "&=")
+ (cons js2-ASSIGN_LSH "<<=")
+ (cons js2-ASSIGN_RSH ">>=")
+ (cons js2-ASSIGN_URSH ">>>=")
+ (cons js2-ASSIGN_ADD "+=")
+ (cons js2-ASSIGN_SUB "-=")
+ (cons js2-ASSIGN_MUL "*=")
+ (cons js2-ASSIGN_DIV "/=")
+ (cons js2-ASSIGN_MOD "%="))))
+ (loop for (k . v) in tokens do
+ (puthash k v table))
+ table))
+
+(defun js2-print-infix-node (n i)
+ (let* ((tt (js2-node-type n))
+ (op (gethash tt js2-operator-tokens)))
+ (unless op
+ (error "unrecognized infix operator %s" (js2-node-type n)))
+ (insert (js2-make-pad i))
+ (js2-print-ast (js2-infix-node-left n) 0)
+ (unless (= tt js2-COMMA)
+ (insert " "))
+ (insert op)
+ (insert " ")
+ (js2-print-ast (js2-infix-node-right n) 0)))
+
+(defstruct (js2-assign-node
+ (:include js2-infix-node)
+ (:constructor nil)
+ (:constructor make-js2-assign-node (&key type
+ (pos js2-ts-cursor)
+ len
+ op-pos
+ left
+ right)))
+ "Represents any assignment.
+The type field holds the actual assignment operator.")
+
+(put 'cl-struct-js2-assign-node 'js2-visitor 'js2-visit-infix-node)
+(put 'cl-struct-js2-assign-node 'js2-printer 'js2-print-infix-node)
+
+(defstruct (js2-unary-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-unary-node (&key type ; required
+ (pos js2-ts-cursor)
+ len
+ operand)))
+ "AST node type for unary operator nodes.
+The type field can be NOT, BITNOT, POS, NEG, INC, DEC,
+TYPEOF, or DELPROP. For INC or DEC, a 'postfix node
+property is added if the operator follows the operand."
+ operand) ; a `js2-node' expression
+
+(put 'cl-struct-js2-unary-node 'js2-visitor 'js2-visit-unary-node)
+(put 'cl-struct-js2-unary-node 'js2-printer 'js2-print-unary-node)
+
+(defun js2-visit-unary-node (n v)
+ (js2-visit-ast (js2-unary-node-operand n) v))
+
+(defun js2-print-unary-node (n i)
+ (let* ((tt (js2-node-type n))
+ (op (gethash tt js2-operator-tokens))
+ (postfix (js2-node-get-prop n 'postfix)))
+ (unless op
+ (error "unrecognized unary operator %s" tt))
+ (insert (js2-make-pad i))
+ (unless postfix
+ (insert op))
+ (if (or (= tt js2-TYPEOF)
+ (= tt js2-DELPROP))
+ (insert " "))
+ (js2-print-ast (js2-unary-node-operand n) 0)
+ (when postfix
+ (insert op))))
+
+(defstruct (js2-let-node
+ (:include js2-scope)
+ (:constructor nil)
+ (:constructor make-js2-let-node (&key (type js2-LETEXPR)
+ (pos js2-token-beg)
+ len
+ vars
+ body
+ lp
+ rp)))
+ "AST node for a let expression or a let statement.
+Note that a let declaration such as let x=6, y=7 is a `js2-var-decl-node'."
+ vars ; a `js2-var-decl-node'
+ body ; a `js2-node' representing the expression or body block
+ lp
+ rp)
+
+(put 'cl-struct-js2-let-node 'js2-visitor 'js2-visit-let-node)
+(put 'cl-struct-js2-let-node 'js2-printer 'js2-print-let-node)
+
+(defun js2-visit-let-node (n v)
+ (when (js2-let-node-vars n)
+ (js2-visit-ast (js2-let-node-vars n) v))
+ (when (js2-let-node-body n)
+ (js2-visit-ast (js2-let-node-body n) v)))
+
+(defun js2-print-let-node (n i)
+ (insert (js2-make-pad i) "let (")
+ (js2-print-ast (js2-let-node-vars n) 0)
+ (insert ") ")
+ (js2-print-ast (js2-let-node-body n) i))
+
+(defstruct (js2-keyword-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-keyword-node (&key type
+ (pos js2-token-beg)
+ (len (- js2-ts-cursor pos)))))
+ "AST node representing a literal keyword such as `null'.
+Used for `null', `this', `true', `false' and `debugger'.
+The node type is set to js2-NULL, js2-THIS, etc.")
+
+(put 'cl-struct-js2-keyword-node 'js2-visitor 'js2-visit-none)
+(put 'cl-struct-js2-keyword-node 'js2-printer 'js2-print-keyword-node)
+
+(defun js2-print-keyword-node (n i)
+ (insert (js2-make-pad i)
+ (let ((tt (js2-node-type n)))
+ (cond
+ ((= tt 'js2-THIS) "this")
+ ((= tt 'js2-NULL) "null")
+ ((= tt 'js2-TRUE) "true")
+ ((= tt 'js2-FALSE) "false")
+ ((= tt 'js2-DEBUGGER) "debugger")
+ (t (error "Invalid keyword literal type: %d" tt))))))
+
+(defsubst js2-this-node-p (node)
+ "Return t if this node is a `js2-literal-node' of type js2-THIS."
+ (eq (js2-node-type node) js2-THIS))
+
+(defstruct (js2-new-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-new-node (&key (type js2-NEW)
+ (pos js2-token-beg)
+ len
+ target
+ args
+ initializer
+ lp
+ rp)))
+ "AST node for new-expression such as new Foo()."
+ target ; an identifier or reference
+ args ; a lisp list of argument nodes
+ lp ; position of left-paren, nil if omitted
+ rp ; position of right-paren, nil if omitted
+ initializer) ; experimental Rhino syntax: optional `js2-object-node'
+
+(put 'cl-struct-js2-new-node 'js2-visitor 'js2-visit-new-node)
+(put 'cl-struct-js2-new-node 'js2-printer 'js2-print-new-node)
+
+(defun js2-visit-new-node (n v)
+ (js2-visit-ast (js2-new-node-target n) v)
+ (dolist (arg (js2-new-node-args n))
+ (js2-visit-ast arg v))
+ (when (js2-new-node-initializer n)
+ (js2-visit-ast (js2-new-node-initializer n) v)))
+
+(defun js2-print-new-node (n i)
+ (insert (js2-make-pad i) "new ")
+ (js2-print-ast (js2-new-node-target n))
+ (insert "(")
+ (js2-print-list (js2-new-node-args n))
+ (insert ")")
+ (when (js2-new-node-initializer n)
+ (insert " ")
+ (js2-print-ast (js2-new-node-initializer n))))
+
+(defstruct (js2-name-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-name-node (&key (type js2-NAME)
+ (pos js2-token-beg)
+ (len (- js2-ts-cursor
+ js2-token-beg))
+ (name js2-ts-string))))
+ "AST node for a JavaScript identifier"
+ name ; a string
+ scope) ; a `js2-scope' (optional, used for codegen)
+
+(put 'cl-struct-js2-name-node 'js2-visitor 'js2-visit-none)
+(put 'cl-struct-js2-name-node 'js2-printer 'js2-print-name-node)
+
+(defun js2-print-name-node (n i)
+ (insert (js2-make-pad i)
+ (js2-name-node-name n)))
+
+(defsubst js2-name-node-length (node)
+ "Return identifier length of NODE, a `js2-name-node'.
+Returns 0 if NODE is nil or its identifier field is nil."
+ (if node
+ (length (js2-name-node-name node))
+ 0))
+
+(defstruct (js2-number-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-number-node (&key (type js2-NUMBER)
+ (pos js2-token-beg)
+ (len (- js2-ts-cursor
+ js2-token-beg))
+ (value js2-ts-string)
+ (num-value js2-ts-number))))
+ "AST node for a number literal."
+ value ; the original string, e.g. "6.02e23"
+ num-value) ; the parsed number value
+
+(put 'cl-struct-js2-number-node 'js2-visitor 'js2-visit-none)
+(put 'cl-struct-js2-number-node 'js2-printer 'js2-print-number-node)
+
+(defun js2-print-number-node (n i)
+ (insert (js2-make-pad i)
+ (number-to-string (js2-number-node-value n))))
+
+(defstruct (js2-regexp-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-regexp-node (&key (type js2-REGEXP)
+ (pos js2-token-beg)
+ (len (- js2-ts-cursor
+ js2-token-beg))
+ value
+ flags)))
+ "AST node for a regular expression literal."
+ value ; the regexp string, without // delimiters
+ flags) ; a string of flags, e.g. `mi'.
+
+(put 'cl-struct-js2-regexp-node 'js2-visitor 'js2-visit-none)
+(put 'cl-struct-js2-regexp-node 'js2-printer 'js2-print-regexp)
+
+(defun js2-print-regexp (n i)
+ (insert (js2-make-pad i)
+ "/"
+ (js2-regexp-node-value n)
+ "/")
+ (if (js2-regexp-node-flags n)
+ (insert (js2-regexp-node-flags n))))
+
+(defstruct (js2-string-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-string-node (&key (type js2-STRING)
+ (pos js2-token-beg)
+ (len (- js2-ts-cursor
+ js2-token-beg))
+ (value js2-ts-string))))
+ "String literal.
+Escape characters are not evaluated; e.g. \n is 2 chars in value field.
+You can tell the quote type by looking at the first character."
+ value) ; the characters of the string, including the quotes
+
+(put 'cl-struct-js2-string-node 'js2-visitor 'js2-visit-none)
+(put 'cl-struct-js2-string-node 'js2-printer 'js2-print-string-node)
+
+(defun js2-print-string-node (n i)
+ (insert (js2-make-pad i)
+ (js2-node-string n)))
+
+(defstruct (js2-array-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-array-node (&key (type js2-ARRAYLIT)
+ (pos js2-ts-cursor)
+ len
+ elems)))
+ "AST node for an array literal."
+ elems) ; list of expressions. [foo,,bar] yields a nil middle element.
+
+(put 'cl-struct-js2-array-node 'js2-visitor 'js2-visit-array-node)
+(put 'cl-struct-js2-array-node 'js2-printer 'js2-print-array-node)
+
+(defun js2-visit-array-node (n v)
+ (dolist (e (js2-array-node-elems n))
+ (when e ; can be nil, e.g. [a, ,b]
+ (js2-visit-ast e v))))
+
+(defun js2-print-array-node (n i)
+ (insert (js2-make-pad i) "[")
+ (js2-print-list (js2-array-node-elems n))
+ (insert "]"))
+
+(defstruct (js2-object-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-object-node (&key (type js2-OBJECTLIT)
+ (pos js2-ts-cursor)
+ len
+ elems)))
+ "AST node for an object literal expression."
+ elems) ; a lisp list of `js2-object-prop-node'
+
+(put 'cl-struct-js2-object-node 'js2-visitor 'js2-visit-object-node)
+(put 'cl-struct-js2-object-node 'js2-printer 'js2-print-object-node)
+
+(defun js2-visit-object-node (n v)
+ (dolist (e (js2-object-node-elems n))
+ (js2-visit-ast e v)))
+
+(defun js2-print-object-node (n i)
+ (insert (js2-make-pad i) "{")
+ (js2-print-list (js2-object-node-elems n))
+ (insert "}"))
+
+(defstruct (js2-object-prop-node
+ (:include js2-infix-node)
+ (:constructor nil)
+ (:constructor make-js2-object-prop-node (&key (type js2-COLON)
+ (pos js2-ts-cursor)
+ len
+ left
+ right
+ op-pos)))
+ "AST node for an object literal prop:value entry.
+The `left' field is the property: a name node, string node or number node.
+The `right' field is a `js2-node' representing the initializer value.")
+
+(put 'cl-struct-js2-object-prop-node 'js2-visitor 'js2-visit-infix-node)
+(put 'cl-struct-js2-object-prop-node 'js2-printer 'js2-print-object-prop-node)
+
+(defun js2-print-object-prop-node (n i)
+ (insert (js2-make-pad i))
+ (js2-print-ast (js2-object-prop-node-left n) 0)
+ (insert ":")
+ (js2-print-ast (js2-object-prop-node-right n) 0))
+
+(defstruct (js2-getter-setter-node
+ (:include js2-infix-node)
+ (:constructor nil)
+ (:constructor make-js2-getter-setter-node (&key type ; GET or SET
+ (pos js2-ts-cursor)
+ len
+ left
+ right)))
+ "AST node for a getter/setter property in an object literal.
+The `left' field is the `js2-name-node' naming the getter/setter prop.
+The `right' field is always an anonymous `js2-function-node' with a node
+property `GETTER_SETTER' set to js2-GET or js2-SET. ")
+
+(put 'cl-struct-js2-getter-setter-node 'js2-visitor 'js2-visit-infix-node)
+(put 'cl-struct-js2-getter-setter-node 'js2-printer 'js2-print-getter-setter)
+
+(defun js2-print-getter-setter (n i)
+ (let ((pad (js2-make-pad i))
+ (left (js2-getter-setter-node-left n))
+ (right (js2-getter-setter-node-right n)))
+ (insert pad)
+ (insert (if (= (js2-node-type n) js2-GET) "get " "set "))
+ (js2-print-ast left 0)
+ (js2-print-ast right 0)))
+
+(defstruct (js2-prop-get-node
+ (:include js2-infix-node)
+ (:constructor nil)
+ (:constructor make-js2-prop-get-node (&key (type js2-GETPROP)
+ (pos js2-ts-cursor)
+ len
+ left
+ right)))
+ "AST node for a dotted property reference, e.g. foo.bar or foo().bar")
+
+(put 'cl-struct-js2-prop-get-node 'js2-visitor 'js2-visit-prop-get-node)
+(put 'cl-struct-js2-prop-get-node 'js2-printer 'js2-print-prop-get-node)
+
+(defun js2-visit-prop-get-node (n v)
+ (when (js2-prop-get-node-left n)
+ (js2-visit-ast (js2-prop-get-node-left n) v))
+ (when (js2-prop-get-node-right n)
+ (js2-visit-ast (js2-prop-get-node-right n) v)))
+
+(defun js2-print-prop-get-node (n i)
+ (insert (js2-make-pad i))
+ (js2-print-ast (js2-prop-get-node-left n) 0)
+ (insert ".")
+ (js2-print-ast (js2-prop-get-node-right n) 0))
+
+(defstruct (js2-elem-get-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-elem-get-node (&key (type js2-GETELEM)
+ (pos js2-ts-cursor)
+ len
+ target
+ element
+ lb
+ rb)))
+ "AST node for an array index expression such as foo[bar]."
+ target ; a `js2-node' - the expression preceding the "."
+ element ; a `js2-node' - the expression in brackets
+ lb ; position of left-bracket, nil if omitted
+ rb) ; position of right-bracket, nil if omitted
+
+(put 'cl-struct-js2-elem-get-node 'js2-visitor 'js2-visit-elem-get-node)
+(put 'cl-struct-js2-elem-get-node 'js2-printer 'js2-print-elem-get-node)
+
+(defun js2-visit-elem-get-node (n v)
+ (when (js2-elem-get-node-target n)
+ (js2-visit-ast (js2-elem-get-node-target n) v))
+ (when (js2-elem-get-node-element n)
+ (js2-visit-ast (js2-elem-get-node-element n) v)))
+
+(defun js2-print-elem-get-node (n i)
+ (insert (js2-make-pad i))
+ (js2-print-ast (js2-elem-get-node-target n) 0)
+ (insert "[")
+ (js2-print-ast (js2-elem-get-node-element n) 0)
+ (insert "]"))
+
+(defstruct (js2-call-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-call-node (&key (type js2-CALL)
+ (pos js2-ts-cursor)
+ len
+ target
+ args
+ lp
+ rp)))
+ "AST node for a JavaScript function call."
+ target ; a `js2-node' evaluating to the function to call
+ args ; a lisp list of `js2-node' arguments
+ lp ; position of open-paren, or nil if missing
+ rp) ; position of close-paren, or nil if missing
+
+(put 'cl-struct-js2-call-node 'js2-visitor 'js2-visit-call-node)
+(put 'cl-struct-js2-call-node 'js2-printer 'js2-print-call-node)
+
+(defun js2-visit-call-node (n v)
+ (js2-visit-ast (js2-call-node-target n) v)
+ (dolist (arg (js2-call-node-args n))
+ (js2-visit-ast arg v)))
+
+(defun js2-print-call-node (n i)
+ (insert (js2-make-pad i))
+ (js2-print-ast (js2-call-node-target n) 0)
+ (insert "(")
+ (js2-print-list (js2-call-node-args n))
+ (insert ")"))
+
+(defstruct (js2-yield-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-yield-node (&key (type js2-YIELD)
+ (pos js2-ts-cursor)
+ len
+ value)))
+ "AST node for yield statement or expression."
+ value) ; optional: value to be yielded
+
+(put 'cl-struct-js2-yield-node 'js2-visitor 'js2-visit-yield-node)
+(put 'cl-struct-js2-yield-node 'js2-printer 'js2-print-yield-node)
+
+(defun js2-visit-yield-node (n v)
+ (js2-visit-ast (js2-yield-node-value n) v))
+
+(defun js2-print-yield-node (n i)
+ (insert (js2-make-pad i))
+ (insert "yield")
+ (when (js2-yield-node-value n)
+ (insert " ")
+ (js2-print-ast (js2-yield-node-value n) 0)))
+
+(defstruct (js2-paren-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-paren-node (&key (type js2-LP)
+ (pos js2-ts-cursor)
+ len
+ expr)))
+ "AST node for a parenthesized expression.
+In particular, used when the parens are syntactically optional,
+as opposed to required parens such as those enclosing an if-conditional."
+ expr) ; `js2-node'
+
+(put 'cl-struct-js2-paren-node 'js2-visitor 'js2-visit-paren-node)
+(put 'cl-struct-js2-paren-node 'js2-printer 'js2-print-paren-node)
+
+(defun js2-visit-paren-node (n v)
+ (js2-visit-ast (js2-paren-node-expr n) v))
+
+(defun js2-print-paren-node (n i)
+ (insert (js2-make-pad i))
+ (insert "(")
+ (js2-print-ast (js2-paren-node-expr n) 0)
+ (insert ")"))
+
+(defstruct (js2-array-comp-node
+ (:include js2-scope)
+ (:constructor nil)
+ (:constructor make-js2-array-comp-node (&key (type js2-ARRAYCOMP)
+ (pos js2-ts-cursor)
+ len
+ result
+ loops
+ filter
+ if-pos
+ lp
+ rp)))
+ "AST node for an Array comprehension such as [[x,y] for (x in foo) for (y in bar)]."
+ result ; result expression (just after left-bracket)
+ loops ; a lisp list of `js2-array-comp-loop-node'
+ filter ; guard/filter expression
+ if-pos ; buffer pos of 'if' keyword, if present, else nil
+ lp ; buffer position of if-guard left-paren, or nil if not present
+ rp) ; buffer position of if-guard right-paren, or nil if not present
+
+(put 'cl-struct-js2-array-comp-node 'js2-visitor 'js2-visit-array-comp-node)
+(put 'cl-struct-js2-array-comp-node 'js2-printer 'js2-print-array-comp-node)
+
+(defun js2-visit-array-comp-node (n v)
+ (js2-visit-ast (js2-array-comp-node-result n) v)
+ (dolist (l (js2-array-comp-node-loops n))
+ (js2-visit-ast l v))
+ (if (js2-array-comp-node-filter n)
+ (js2-visit-ast (js2-array-comp-node-filter n) v)))
+
+(defun js2-print-array-comp-node (n i)
+ (let ((pad (js2-make-pad i))
+ (result (js2-array-comp-node-result n))
+ (loops (js2-array-comp-node-loops n))
+ (filter (js2-array-comp-node-filter n)))
+ (insert pad "[")
+ (js2-print-ast result 0)
+ (dolist (l loops)
+ (insert " ")
+ (js2-print-ast l 0))
+ (when filter
+ (insert " if (")
+ (js2-print-ast filter 0))
+ (insert ")]")))
+
+(defstruct (js2-array-comp-loop-node
+ (:include js2-for-in-node)
+ (:constructor nil)
+ (:constructor make-js2-array-comp-loop-node (&key (type js2-FOR)
+ (pos js2-ts-cursor)
+ len
+ iterator
+ object
+ in-pos
+ foreach-p
+ each-pos
+ lp
+ rp)))
+ "AST subtree for each 'for (foo in bar)' loop in an array comprehension.")
+
+(put 'cl-struct-js2-array-comp-loop-node 'js2-visitor 'js2-visit-array-comp-loop)
+(put 'cl-struct-js2-array-comp-loop-node 'js2-printer 'js2-print-array-comp-loop)
+
+(defun js2-visit-array-comp-loop (n v)
+ (js2-visit-ast (js2-array-comp-loop-node-iterator n) v)
+ (js2-visit-ast (js2-array-comp-loop-node-object n) v))
+
+(defun js2-print-array-comp-loop (n i)
+ (insert "for (")
+ (js2-print-ast (js2-array-comp-loop-node-iterator n) 0)
+ (insert " in ")
+ (js2-print-ast (js2-array-comp-loop-node-object n) 0)
+ (insert ")"))
+
+(defstruct (js2-empty-expr-node
+ (:include js2-node)
+ (:constructor nil)
+ (:constructor make-js2-empty-expr-node (&key (type js2-EMPTY)
+ (pos js2-token-beg)
+ len)))
+ "AST node for an empty expression.")
+
+(put 'cl-struct-js2-empty-expr-node 'js2-visitor 'js2-visit-none)
+(put 'cl-struct-js2-empty-expr-node 'js2-printer 'js2-print-none)
+
+(defstruct (js2-xml-node
+ (:include js2-block-node)
+ (:constructor nil)
+ (:constructor make-js2-xml-node (&key (type js2-XML)
+ (pos js2-token-beg)
+ len
+ kids)))
+ "AST node for initial parse of E4X literals.
+The kids field is a list of XML fragments, each a `js2-string-node' or
+a `js2-xml-js-expr-node'. Equivalent to Rhino's XmlLiteral node.")
+
+(put 'cl-struct-js2-xml-node 'js2-visitor 'js2-visit-block)
+(put 'cl-struct-js2-xml-node 'js2-printer 'js2-print-xml-node)
+
+(defun js2-print-xml-node (n i)
+ (dolist (kid (js2-xml-node-kids n))
+ (js2-print-ast kid i)))
+
+(defstruct (js2-xml-js-expr-node
+ (:include js2-xml-node)
+ (:constructor nil)
+ (:constructor make-js2-xml-js-expr-node (&key (type js2-XML)
+ (pos js2-ts-cursor)
+ len
+ expr)))
+ "AST node for an embedded JavaScript {expression} in an E4X literal.
+The start and end fields correspond to the curly-braces."
+ expr) ; a `js2-expr-node' of some sort
+
+(put 'cl-struct-js2-xml-js-expr-node 'js2-visitor 'js2-visit-xml-js-expr)
+(put 'cl-struct-js2-xml-js-expr-node 'js2-printer 'js2-print-xml-js-expr)
+
+(defun js2-visit-xml-js-expr (n v)
+ (js2-visit-ast (js2-xml-js-expr-node-expr n) v))
+
+(defun js2-print-xml-js-expr (n i)
+ (insert (js2-make-pad i))
+ (insert "{")
+ (js2-print-ast (js2-xml-js-expr-node-expr n) 0)
+ (insert "}"))
+
+(defstruct (js2-xml-dot-query-node
+ (:include js2-infix-node)
+ (:constructor nil)
+ (:constructor make-js2-xml-dot-query-node (&key (type js2-DOTQUERY)
+ (pos js2-ts-cursor)
+ op-pos
+ len
+ left
+ right
+ rp)))
+ "AST node for an E4X foo.(bar) filter expression.
+Note that the left-paren is automatically the character immediately
+following the dot (.) in the operator. No whitespace is permitted
+between the dot and the lp by the scanner."
+ rp)
+
+(put 'cl-struct-js2-xml-dot-query-node 'js2-visitor 'js2-visit-infix-node)
+(put 'cl-struct-js2-xml-dot-query-node 'js2-printer 'js2-print-xml-dot-query)
+
+(defun js2-print-xml-dot-query (n i)
+ (insert (js2-make-pad i))
+ (js2-print-ast (js2-xml-dot-query-node-left n) 0)
+ (insert ".(")
+ (js2-print-ast (js2-xml-dot-query-node-right n) 0)
+ (insert ")"))
+
+(defstruct (js2-xml-ref-node
+ (:include js2-node)
+ (:constructor nil)) ; abstract
+ "Base type for E4X XML attribute-access or property-get expressions.
+Such expressions can take a variety of forms. The general syntax has
+three parts:
+
+ - (optional) an @ (specifying an attribute access)
+ - (optional) a namespace (a `js2-name-node') and double-colon
+ - (required) either a `js2-name-node' or a bracketed [expression]
+
+The property-name expressions (examples: ns::name, @name) are
+represented as `js2-xml-prop-ref' nodes. The bracketed-expression
+versions (examples: ns::[name], @[name]) become `js2-xml-elem-ref' nodes.
+
+This node type (or more specifically, its subclasses) will sometimes
+be the right-hand child of a `js2-prop-get-node' or a
+`js2-infix-node' of type `js2-DOTDOT', the .. xml-descendants operator.
+The `js2-xml-ref-node' may also be a standalone primary expression with
+no explicit target, which is valid in certain expression contexts such as
+
+ company..employee.(@id < 100)
+
+in this case, the @id is a `js2-xml-ref' that is part of an infix '<'
+expression whose parent is a `js2-xml-dot-query-node'."
+ namespace
+ at-pos
+ colon-pos)
+
+(defsubst js2-xml-ref-node-attr-access-p (node)
+ "Return non-nil if this expression began with an @-token."
+ (and (numberp (js2-xml-ref-node-at-pos node))
+ (plusp (js2-xml-ref-node-at-pos node))))
+
+(defstruct (js2-xml-prop-ref-node
+ (:include js2-xml-ref-node)
+ (:constructor nil)
+ (:constructor make-js2-xml-prop-ref-node (&key (type js2-REF_NAME)
+ (pos js2-token-beg)
+ len
+ propname
+ namespace
+ at-pos
+ colon-pos)))
+ "AST node for an E4X XML [expr] property-ref expression.
+The JavaScript syntax is an optional @, an optional ns::, and a name.
+
+ [ '@' ] [ name '::' ] name
+
+Examples include name, ns::name, ns::*, *::name, *::*, @attr, @ns::attr,
+@ns::*, @*::attr, @*::*, and @*.
+
+The node starts at the @ token, if present. Otherwise it starts at the
+namespace name. The node bounds extend through the closing right-bracket,
+or if it is missing due to a syntax error, through the end of the index
+expression."
+ propname)
+
+(put 'cl-struct-js2-xml-prop-ref-node 'js2-visitor 'js2-visit-xml-prop-ref-node)
+(put 'cl-struct-js2-xml-prop-ref-node 'js2-printer 'js2-print-xml-prop-ref-node)
+
+(defun js2-visit-xml-prop-ref-node (n v)
+ (if (js2-xml-prop-ref-node-namespace n)
+ (js2-visit-ast (js2-xml-prop-ref-node-namespace n) v))
+ (if (js2-xml-prop-ref-node-propname n)
+ (js2-visit-ast (js2-xml-prop-ref-node-propname n) v)))
+
+(defun js2-print-xml-prop-ref-node (n i)
+ (insert (js2-make-pad i))
+ (if (js2-xml-ref-node-attr-access-p n)
+ (insert "@"))
+ (when (js2-xml-prop-ref-node-namespace n)
+ (js2-print-ast (js2-xml-prop-ref-node-namespace n) 0)
+ (insert "::"))
+ (if (js2-xml-prop-ref-node-propname n)
+ (js2-print-ast (js2-xml-prop-ref-node-propname n) 0)))
+
+(defstruct (js2-xml-elem-ref-node
+ (:include js2-xml-ref-node)
+ (:constructor nil)
+ (:constructor make-js2-xml-elem-ref-node (&key (type js2-REF_MEMBER)
+ (pos js2-token-beg)
+ len
+ expr
+ lb
+ rb
+ namespace
+ at-pos
+ colon-pos)))
+ "AST node for an E4X XML [expr] member-ref expression.
+Syntax:
+
+ [ '@' ] [ name '::' ] '[' expr ']'
+
+Examples include ns::[expr], @ns::[expr], @[expr], *::[expr] and @*::[expr].
+
+Note that the form [expr] (i.e. no namespace or attribute-qualifier)
+is not a legal E4X XML element-ref expression, since it's already used
+for standard JavaScript element-get array indexing. Hence, a
+`js2-xml-elem-ref-node' always has either the attribute-qualifier, a
+non-nil namespace node, or both.
+
+The node starts at the @ token, if present. Otherwise it starts
+at the namespace name. The node bounds extend through the closing
+right-bracket, or if it is missing due to a syntax error, through the
+end of the index expression."
+ expr ; the bracketed index expression
+ lb
+ rb)
+
+(put 'cl-struct-js2-xml-elem-ref-node 'js2-visitor 'js2-visit-xml-elem-ref-node)
+(put 'cl-struct-js2-xml-elem-ref-node 'js2-printer 'js2-print-xml-elem-ref-node)
+
+(defun js2-visit-xml-elem-ref-node (n v)
+ (if (js2-xml-elem-ref-node-namespace n)
+ (js2-visit-ast (js2-xml-elem-ref-node-namespace n) v))
+ (if (js2-xml-elem-ref-node-expr n)
+ (js2-visit-ast (js2-xml-elem-ref-node-expr n) v)))
+
+(defun js2-print-xml-elem-ref-node (n i)
+ (insert (js2-make-pad i))
+ (if (js2-xml-ref-node-attr-access-p n)
+ (insert "@"))
+ (when (js2-xml-elem-ref-node-namespace n)
+ (js2-print-ast (js2-xml-elem-ref-node-namespace n) 0)
+ (insert "::"))
+ (insert "[")
+ (if (js2-xml-elem-ref-node-expr n)
+ (js2-print-ast (js2-xml-elem-ref-node-expr n) 0))
+ (insert "]"))
+
+;;; Placeholder nodes for when we try parsing the XML literals structurally.
+
+(defstruct (js2-xml-start-tag-node
+ (:include js2-xml-node)
+ (:constructor nil)
+ (:constructor make-js2-xml-start-tag-node (&key (type js2-XML)
+ (pos js2-ts-cursor)
+ len
+ name
+ attrs
+ kids
+ empty-p)))
+ "AST node for an XML start-tag. Not currently used.
+The `kids' field is a lisp list of child content nodes."
+ name ; a `js2-xml-name-node'
+ attrs ; a lisp list of `js2-xml-attr-node'
+ empty-p) ; t if this is an empty element such as <foo bar="baz"/>
+
+(put 'cl-struct-js2-xml-start-tag-node 'js2-visitor 'js2-visit-xml-start-tag)
+(put 'cl-struct-js2-xml-start-tag-node 'js2-printer 'js2-print-xml-start-tag)
+
+(defun js2-visit-xml-start-tag (n v)
+ (js2-visit-ast (js2-xml-start-tag-node-name n) v)
+ (dolist (attr (js2-xml-start-tag-node-attrs n))
+ (js2-visit-ast attr v))
+ (js2-visit-block n v))
+
+(defun js2-print-xml-start-tag (n i)
+ (insert (js2-make-pad i) "<")
+ (js2-print-ast (js2-xml-start-tag-node-name n) 0)
+ (when (js2-xml-start-tag-node-attrs n)
+ (insert " ")
+ (js2-print-list (js2-xml-start-tag-node-attrs n) " "))
+ (insert ">"))
+
+;; I -think- I'm going to make the parent node the corresponding start-tag,
+;; and add the end-tag to the kids list of the parent as well.
+(defstruct (js2-xml-end-tag-node
+ (:include js2-xml-node)
+ (:constructor nil)
+ (:constructor make-js2-xml-end-tag-node (&key (type js2-XML)
+ (pos js2-ts-cursor)
+ len
+ name)))
+ "AST node for an XML end-tag. Not currently used."
+ name) ; a `js2-xml-name-node'
+
+(put 'cl-struct-js2-xml-end-tag-node 'js2-visitor 'js2-visit-xml-end-tag)
+(put 'cl-struct-js2-xml-end-tag-node 'js2-printer 'js2-print-xml-end-tag)
+
+(defun js2-visit-xml-end-tag (n v)
+ (js2-visit-ast (js2-xml-end-tag-node-name n) v))
+
+(defun js2-print-xml-end-tag (n i)
+ (insert (js2-make-pad i))
+ (insert "</")
+ (js2-print-ast (js2-xml-end-tag-node-name n) 0)
+ (insert ">"))
+
+(defstruct (js2-xml-name-node
+ (:include js2-xml-node)
+ (:constructor nil)
+ (:constructor make-js2-xml-name-node (&key (type js2-XML)
+ (pos js2-ts-cursor)
+ len
+ namespace
+ kids)))
+ "AST node for an E4X XML name. Not currently used.
+Any XML name can be qualified with a namespace, hence the namespace field.
+Further, any E4X name can be comprised of arbitrary JavaScript {} expressions.
+The kids field is a list of `js2-name-node' and `js2-xml-js-expr-node'.
+For a simple name, the kids list has exactly one node, a `js2-name-node'."
+ namespace) ; a `js2-string-node'
+
+(put 'cl-struct-js2-xml-name-node 'js2-visitor 'js2-visit-xml-name-node)
+(put 'cl-struct-js2-xml-name-node 'js2-printer 'js2-print-xml-name-node)
+
+(defun js2-visit-xml-name-node (n v)
+ (js2-visit-ast (js2-xml-name-node-namespace n) v))
+
+(defun js2-print-xml-name-node (n i)
+ (insert (js2-make-pad i))
+ (when (js2-xml-name-node-namespace n)
+ (js2-print-ast (js2-xml-name-node-namespace n) 0)
+ (insert "::"))
+ (dolist (kid (js2-xml-name-node-kids n))
+ (js2-print-ast kid 0)))
+
+(defstruct (js2-xml-pi-node
+ (:include js2-xml-node)
+ (:constructor nil)
+ (:constructor make-js2-xml-pi-node (&key (type js2-XML)
+ (pos js2-ts-cursor)
+ len
+ name
+ attrs)))
+ "AST node for an E4X XML processing instruction. Not currently used."
+ name ; a `js2-xml-name-node'
+ attrs) ; a list of `js2-xml-attr-node'
+
+(put 'cl-struct-js2-xml-pi-node 'js2-visitor 'js2-visit-xml-pi-node)
+(put 'cl-struct-js2-xml-pi-node 'js2-printer 'js2-print-xml-pi-node)
+
+(defun js2-visit-xml-pi-node (n v)
+ (js2-visit-ast (js2-xml-pi-node-name n) v)
+ (dolist (attr (js2-xml-pi-node-attrs n))
+ (js2-visit-ast attr v)))
+
+(defun js2-print-xml-pi-node (n i)
+ (insert (js2-make-pad i) "<?")
+ (js2-print-ast (js2-xml-pi-node-name n))
+ (when (js2-xml-pi-node-attrs n)
+ (insert " ")
+ (js2-print-list (js2-xml-pi-node-attrs n)))
+ (insert "?>"))
+
+(defstruct (js2-xml-cdata-node
+ (:include js2-xml-node)
+ (:constructor nil)
+ (:constructor make-js2-xml-cdata-node (&key (type js2-XML)
+ (pos js2-ts-cursor)
+ len
+ content)))
+ "AST node for a CDATA escape section. Not currently used."
+ content) ; a `js2-string-node' with node-property 'quote-type 'cdata
+
+(put 'cl-struct-js2-xml-cdata-node 'js2-visitor 'js2-visit-xml-cdata-node)
+(put 'cl-struct-js2-xml-cdata-node 'js2-printer 'js2-print-xml-cdata-node)
+
+(defun js2-visit-xml-cdata-node (n v)
+ (js2-visit-ast (js2-xml-cdata-node-content n) v))
+
+(defun js2-print-xml-cdata-node (n i)
+ (insert (js2-make-pad i))
+ (js2-print-ast (js2-xml-cdata-node-content n)))
+
+(defstruct (js2-xml-attr-node
+ (:include js2-xml-node)
+ (:constructor nil)
+ (:constructor make-js2-attr-node (&key (type js2-XML)
+ (pos js2-ts-cursor)
+ len
+ name
+ value
+ eq-pos
+ quote-type)))
+ "AST node representing a foo='bar' XML attribute value. Not yet used."
+ name ; a `js2-xml-name-node'
+ value ; a `js2-xml-name-node'
+ eq-pos ; buffer position of "=" sign
+ quote-type) ; 'single or 'double
+
+(put 'cl-struct-js2-xml-attr-node 'js2-visitor 'js2-visit-xml-attr-node)
+(put 'cl-struct-js2-xml-attr-node 'js2-printer 'js2-print-xml-attr-node)
+
+(defun js2-visit-xml-attr-node (n v)
+ (js2-visit-ast (js2-xml-attr-node-name n) v)
+ (js2-visit-ast (js2-xml-attr-node-value n) v))
+
+(defun js2-print-xml-attr-node (n i)
+ (let ((quote (if (eq (js2-xml-attr-node-quote-type n) 'single)
+ "'"
+ "\"")))
+ (insert (js2-make-pad i))
+ (js2-print-ast (js2-xml-attr-node-name n) 0)
+ (insert "=" quote)
+ (js2-print-ast (js2-xml-attr-node-value n) 0)
+ (insert quote)))
+
+(defstruct (js2-xml-text-node
+ (:include js2-xml-node)
+ (:constructor nil)
+ (:constructor make-js2-text-node (&key (type js2-XML)
+ (pos js2-ts-cursor)
+ len
+ content)))
+ "AST node for an E4X XML text node. Not currently used."
+ content) ; a lisp list of `js2-string-node' and `js2-xml-js-expr-node'
+
+(put 'cl-struct-js2-xml-text-node 'js2-visitor 'js2-visit-xml-text-node)
+(put 'cl-struct-js2-xml-text-node 'js2-printer 'js2-print-xml-text-node)
+
+(defun js2-visit-xml-text-node (n v)
+ (js2-visit-ast (js2-xml-text-node-content n) v))
+
+(defun js2-print-xml-text-node (n i)
+ (insert (js2-make-pad i))
+ (dolist (kid (js2-xml-text-node-content n))
+ (js2-print-ast kid)))
+
+(defstruct (js2-xml-comment-node
+ (:include js2-xml-node)
+ (:constructor nil)
+ (:constructor make-js2-xml-comment-node (&key (type js2-XML)
+ (pos js2-ts-cursor)
+ len)))
+ "AST node for E4X XML comment. Not currently used.")
+
+(put 'cl-struct-js2-xml-comment-node 'js2-visitor 'js2-visit-none)
+(put 'cl-struct-js2-xml-comment-node 'js2-printer 'js2-print-xml-comment)
+
+(defun js2-print-xml-comment (n i)
+ (insert (js2-make-pad i)
+ (js2-node-string n)))
+
+;;; Node utilities
+
+(defsubst js2-node-line (n)
+ "Fetch the source line number at the start of node N.
+This is O(n) in the length of the source buffer; use prudently."
+ (1+ (count-lines (point-min) (js2-node-abs-pos n))))
+
+(defsubst js2-block-node-kid (n i)
+ "Return child I of node N, or nil if there aren't that many."
+ (nth i (js2-block-node-kids n)))
+
+(defsubst js2-block-node-first (n)
+ "Return first child of block node N, or nil if there is none."
+ (first (js2-block-node-kids n)))
+
+(defun js2-node-root (n)
+ "Return the root of the AST containing N.
+If N has no parent pointer, returns N."
+ (let ((parent (js2-node-parent n)))
+ (if parent
+ (js2-node-root parent)
+ n)))
+
+(defun js2-node-position-in-parent (node &optional parent)
+ "Return the position of NODE in parent's block-kids list.
+PARENT can be supplied if known. Positioned returned is zero-indexed.
+Returns 0 if NODE is not a child of a block statement, or if NODE
+is not a statement node."
+ (let ((p (or parent (js2-node-parent node)))
+ (i 0))
+ (if (not (js2-block-node-p p))
+ i
+ (or (js2-position node (js2-block-node-kids p))
+ 0))))
+
+(defsubst js2-node-short-name (n)
+ "Return the short name of node N as a string, e.g. `js2-if-node'."
+ (substring (symbol-name (aref n 0))
+ (length "cl-struct-")))
+
+(defsubst js2-node-child-list (node)
+ "Return the child list for NODE, a lisp list of nodes.
+Works for block nodes, array nodes, obj literals, funarg lists,
+var decls and try nodes (for catch clauses). Note that you should call
+`js2-block-node-kids' on the function body for the body statements.
+Returns nil for zero-length child lists or unsupported nodes."
+ (cond
+ ((js2-function-node-p node)
+ (js2-function-node-params node))
+ ((js2-block-node-p node)
+ (js2-block-node-kids node))
+ ((js2-try-node-p node)
+ (js2-try-node-catch-clauses node))
+ ((js2-array-node-p node)
+ (js2-array-node-elems node))
+ ((js2-object-node-p node)
+ (js2-object-node-elems node))
+ ((js2-call-node-p node)
+ (js2-call-node-args node))
+ ((js2-new-node-p node)
+ (js2-new-node-args node))
+ ((js2-var-decl-node-p node)
+ (js2-var-decl-node-kids node))
+ (t
+ nil)))
+
+(defsubst js2-node-set-child-list (node kids)
+ "Set the child list for NODE to KIDS."
+ (cond
+ ((js2-function-node-p node)
+ (setf (js2-function-node-params node) kids))
+ ((js2-block-node-p node)
+ (setf (js2-block-node-kids node) kids))
+ ((js2-try-node-p node)
+ (setf (js2-try-node-catch-clauses node) kids))
+ ((js2-array-node-p node)
+ (setf (js2-array-node-elems node) kids))
+ ((js2-object-node-p node)
+ (setf (js2-object-node-elems node) kids))
+ ((js2-call-node-p node)
+ (setf (js2-call-node-args node) kids))
+ ((js2-new-node-p node)
+ (setf (js2-new-node-args node) kids))
+ ((js2-var-decl-node-p node)
+ (setf (js2-var-decl-node-kids node) kids))
+ (t
+ (error "Unsupported node type: %s" (js2-node-short-name node))))
+ kids)
+
+;; All because Common Lisp doesn't support multiple inheritance for defstructs.
+(defconst js2-paren-expr-nodes
+ '(cl-struct-js2-array-comp-loop-node
+ cl-struct-js2-array-comp-node
+ cl-struct-js2-call-node
+ cl-struct-js2-catch-node
+ cl-struct-js2-do-node
+ cl-struct-js2-elem-get-node
+ cl-struct-js2-for-in-node
+ cl-struct-js2-for-node
+ cl-struct-js2-function-node
+ cl-struct-js2-if-node
+ cl-struct-js2-let-node
+ cl-struct-js2-new-node
+ cl-struct-js2-paren-node
+ cl-struct-js2-switch-node
+ cl-struct-js2-while-node
+ cl-struct-js2-with-node
+ cl-struct-js2-xml-dot-query-node)
+ "Node types that can have a parenthesized child expression.
+In particular, nodes that respond to `js2-node-lp' and `js2-node-rp'.")
+
+(defsubst js2-paren-expr-node-p (node)
+ "Return t for nodes that typically have a parenthesized child expression.
+Useful for computing the indentation anchors for arg-lists and conditions.
+Note that it may return a false positive, for instance when NODE is
+a `js2-new-node' and there are no arguments or parentheses."
+ (memq (aref node 0) js2-paren-expr-nodes))
+
+;; Fake polymorphism... yech.
+(defsubst js2-node-lp (node)
+ "Return relative left-paren position for NODE, if applicable.
+For `js2-elem-get-node' structs, returns left-bracket position.
+Note that the position may be nil in the case of a parse error."
+ (cond
+ ((js2-elem-get-node-p node)
+ (js2-elem-get-node-lb node))
+ ((js2-loop-node-p node)
+ (js2-loop-node-lp node))
+ ((js2-function-node-p node)
+ (js2-function-node-lp node))
+ ((js2-if-node-p node)
+ (js2-if-node-lp node))
+ ((js2-new-node-p node)
+ (js2-new-node-lp node))
+ ((js2-call-node-p node)
+ (js2-call-node-lp node))
+ ((js2-paren-node-p node)
+ (js2-node-pos node))
+ ((js2-switch-node-p node)
+ (js2-switch-node-lp node))
+ ((js2-catch-node-p node)
+ (js2-catch-node-lp node))
+ ((js2-let-node-p node)
+ (js2-let-node-lp node))
+ ((js2-array-comp-node-p node)
+ (js2-array-comp-node-lp node))
+ ((js2-with-node-p node)
+ (js2-with-node-lp node))
+ ((js2-xml-dot-query-node-p node)
+ (1+ (js2-infix-node-op-pos node)))
+ (t
+ (error "Unsupported node type: %s" (js2-node-short-name node)))))
+
+;; Fake polymorphism... blech.
+(defsubst js2-node-rp (node)
+ "Return relative right-paren position for NODE, if applicable.
+For `js2-elem-get-node' structs, returns right-bracket position.
+Note that the position may be nil in the case of a parse error."
+ (cond
+ ((js2-elem-get-node-p node)
+ (js2-elem-get-node-lb node))
+ ((js2-loop-node-p node)
+ (js2-loop-node-rp node))
+ ((js2-function-node-p node)
+ (js2-function-node-rp node))
+ ((js2-if-node-p node)
+ (js2-if-node-rp node))
+ ((js2-new-node-p node)
+ (js2-new-node-rp node))
+ ((js2-call-node-p node)
+ (js2-call-node-rp node))
+ ((js2-paren-node-p node)
+ (+ (js2-node-pos node) (js2-node-len node)))
+ ((js2-switch-node-p node)
+ (js2-switch-node-rp node))
+ ((js2-catch-node-p node)
+ (js2-catch-node-rp node))
+ ((js2-let-node-p node)
+ (js2-let-node-rp node))
+ ((js2-array-comp-node-p node)
+ (js2-array-comp-node-rp node))
+ ((js2-with-node-p node)
+ (js2-with-node-rp node))
+ ((js2-xml-dot-query-node-p node)
+ (1+ (js2-xml-dot-query-node-rp node)))
+ (t
+ (error "Unsupported node type: %s" (js2-node-short-name node)))))
+
+(defsubst js2-node-first-child (node)
+ "Returns the first element of `js2-node-child-list' for NODE."
+ (car (js2-node-child-list node)))
+
+(defsubst js2-node-last-child (node)
+ "Returns the last element of `js2-node-last-child' for NODE."
+ (car (last (js2-node-child-list node))))
+
+(defun js2-node-prev-sibling (node)
+ "Return the previous statement in parent.
+Works for parents supported by `js2-node-child-list'.
+Returns nil if NODE is not in the parent, or PARENT is
+not a supported node, or if NODE is the first child."
+ (let* ((p (js2-node-parent node))
+ (kids (js2-node-child-list p))
+ (sib (car kids)))
+ (while (and kids
+ (not (eq node (cadr kids))))
+ (setq kids (cdr kids)
+ sib (car kids)))
+ sib))
+
+(defun js2-node-next-sibling (node)
+ "Return the next statement in parent block.
+Returns nil if NODE is not in the block, or PARENT is not
+a block node, or if NODE is the last statement."
+ (let* ((p (js2-node-parent node))
+ (kids (js2-node-child-list p)))
+ (while (and kids
+ (not (eq node (car kids))))
+ (setq kids (cdr kids)))
+ (cadr kids)))
+
+(defun js2-node-find-child-before (pos parent &optional after)
+ "Find the last child that starts before POS in parent.
+If AFTER is non-nil, returns first child starting after POS.
+POS is an absolute buffer position. PARENT is any node
+supported by `js2-node-child-list'.
+Returns nil if no applicable child is found."
+ (let ((kids (if (js2-function-node-p parent)
+ (js2-block-node-kids (js2-function-node-body parent))
+ (js2-node-child-list parent)))
+ (beg (if (js2-function-node-p parent)
+ (js2-node-abs-pos (js2-function-node-body parent))
+ (js2-node-abs-pos parent)))
+ kid
+ result
+ fn
+ (continue t))
+ (setq fn (if after '> '<))
+ (while (and kids continue)
+ (setq kid (car kids))
+ (if (funcall fn (+ beg (js2-node-pos kid)) pos)
+ (setq result kid
+ continue (if after nil t))
+ (setq continue (if after t nil)))
+ (setq kids (cdr kids)))
+ result))
+
+(defun js2-node-find-child-after (pos parent)
+ "Find first child that starts after POS in parent.
+POS is an absolute buffer position. PARENT is any node
+supported by `js2-node-child-list'.
+Returns nil if no applicable child is found."
+ (js2-node-find-child-before pos parent 'after))
+
+(defun js2-node-replace-child (pos parent new-node)
+ "Replace node at index POS in PARENT with NEW-NODE.
+Only works for parents supported by `js2-node-child-list'."
+ (let ((kids (js2-node-child-list parent))
+ (i 0))
+ (while (< i pos)
+ (setq kids (cdr kids)
+ i (1+ i)))
+ (setcar kids new-node)
+ (js2-node-add-children parent new-node)))
+
+(defun js2-node-buffer (n)
+ "Return the buffer associated with AST N.
+Returns nil if the buffer is not set as a property on the root
+node, or if parent links were not recorded during parsing."
+ (let ((root (js2-node-root n)))
+ (and root
+ (js2-ast-root-p root)
+ (js2-ast-root-buffer root))))
+
+(defsubst js2-block-node-push (n kid)
+ "Push js2-node KID onto the end of js2-block-node N's child list.
+KID is always added to the -end- of the kids list.
+Function also calls `js2-node-add-children' to add the parent link."
+ (let ((kids (js2-node-child-list n)))
+ (if kids
+ (setcdr kids (nconc (cdr kids) (list kid)))
+ (js2-node-set-child-list n (list kid)))
+ (js2-node-add-children n kid)))
+
+(defun js2-node-string (node)
+ (let ((buf (js2-node-buffer node))
+ pos)
+ (unless buf
+ (error "No buffer available for node %s" node))
+ (save-excursion
+ (set-buffer buf)
+ (buffer-substring-no-properties (setq pos (js2-node-abs-pos node))
+ (+ pos (js2-node-len node))))))
+
+;; Container for storing the node we're looking for in a traversal.
+(js2-deflocal js2-discovered-node nil)
+
+;; Keep track of absolute node position during traversals.
+(js2-deflocal js2-visitor-offset nil)
+
+(js2-deflocal js2-node-search-point nil)
+
+(when js2-mode-dev-mode-p
+ (defun js2-find-node-at-point ()
+ (interactive)
+ (let ((node (js2-node-at-point)))
+ (message "%s" (or node "No node found at point"))))
+ (defun js2-node-name-at-point ()
+ (interactive)
+ (let ((node (js2-node-at-point)))
+ (message "%s" (if node
+ (js2-node-short-name node)
+ "No node found at point.")))))
+
+(defun js2-node-at-point (&optional pos skip-comments)
+ "Return AST node at POS, a buffer position, defaulting to current point.
+The `js2-mode-ast' variable must be set to the current parse tree.
+Signals an error if the AST (`js2-mode-ast') is nil.
+Always returns a node - if it can't find one, it returns the root.
+If SKIP-COMMENTS is non-nil, comment nodes are ignored."
+ (let ((ast js2-mode-ast)
+ result)
+ (unless ast
+ (error "No JavaScript AST available"))
+ ;; Look through comments first, since they may be inside nodes that
+ ;; would otherwise report a match.
+ (setq pos (or pos (point))
+ result (if (> pos (js2-node-abs-end ast))
+ ast
+ (if (not skip-comments)
+ (js2-comment-at-point pos))))
+ (unless result
+ (setq js2-discovered-node nil
+ js2-visitor-offset 0
+ js2-node-search-point pos)
+ (unwind-protect
+ (catch 'js2-visit-done
+ (js2-visit-ast ast #'js2-node-at-point-visitor))
+ (setq js2-visitor-offset nil
+ js2-node-search-point nil))
+ (setq result js2-discovered-node))
+ ;; may have found a comment beyond end of last child node,
+ ;; since visiting the ast-root looks at the comment-list last.
+ (if (and skip-comments
+ (js2-comment-node-p result))
+ (setq result nil))
+ (or result js2-mode-ast)))
+
+(defun js2-node-at-point-visitor (node end-p)
+ (let ((rel-pos (js2-node-pos node))
+ abs-pos
+ abs-end
+ (point js2-node-search-point))
+ (cond
+ (end-p
+ ;; this evaluates to a non-nil return value, even if it's zero
+ (decf js2-visitor-offset rel-pos))
+ ;; we already looked for comments before visiting, and don't want them now
+ ((js2-comment-node-p node)
+ nil)
+ (t
+ (setq abs-pos (incf js2-visitor-offset rel-pos)
+ ;; we only want to use the node if the point is before
+ ;; the last character position in the node, so we decrement
+ ;; the absolute end by 1.
+ abs-end (+ abs-pos (js2-node-len node) -1))
+ (cond
+ ;; If this node starts after search-point, stop the search.
+ ((> abs-pos point)
+ (throw 'js2-visit-done nil))
+ ;; If this node ends before the search-point, don't check kids.
+ ((> point abs-end)
+ nil)
+ (t
+ ;; Otherwise point is within this node, possibly in a child.
+ (setq js2-discovered-node node)
+ t)))))) ; keep processing kids to look for more specific match
+
+(defsubst js2-block-comment-p (node)
+ "Return non-nil if NODE is a comment node of format `jsdoc' or `block'."
+ (and (js2-comment-node-p node)
+ (memq (js2-comment-node-format node) '(jsdoc block))))
+
+;; TODO: put the comments in a vector and binary-search them instead
+(defun js2-comment-at-point (&optional pos)
+ "Look through scanned comment nodes for one containing POS.
+POS is a buffer position that defaults to current point.
+Function returns nil if POS was not in any comment node."
+ (let ((ast js2-mode-ast)
+ (x (or pos (point)))
+ beg
+ end)
+ (unless ast
+ (error "No JavaScript AST available"))
+ (catch 'done
+ ;; Comments are stored in lexical order.
+ (dolist (comment (js2-ast-root-comments ast) nil)
+ (setq beg (js2-node-abs-pos comment)
+ end (+ beg (js2-node-len comment)))
+ (if (and (>= x beg)
+ (<= x end))
+ (throw 'done comment))))))
+
+(defun js2-mode-find-parent-fn (node)
+ "Find function enclosing NODE.
+Returns nil if NODE is not inside a function."
+ (setq node (js2-node-parent node))
+ (while (and node (not (js2-function-node-p node)))
+ (setq node (js2-node-parent node)))
+ (and (js2-function-node-p node) node))
+
+(defun js2-mode-find-enclosing-fn (node)
+ "Find function or root enclosing NODE."
+ (if (js2-ast-root-p node)
+ node
+ (setq node (js2-node-parent node))
+ (while (not (or (js2-ast-root-p node)
+ (js2-function-node-p node)))
+ (setq node (js2-node-parent node)))
+ node))
+
+(defun js2-mode-find-enclosing-node (beg end)
+ "Find script or function fully enclosing BEG and END."
+ (let ((node (js2-node-at-point beg))
+ pos
+ (continue t))
+ (while continue
+ (if (or (js2-ast-root-p node)
+ (and (js2-function-node-p node)
+ (<= (setq pos (js2-node-abs-pos node)) beg)
+ (>= (+ pos (js2-node-len node)) end)))
+ (setq continue nil)
+ (setq node (js2-node-parent node))))
+ node))
+
+(defun js2-node-parent-script-or-fn (node)
+ "Find script or function immediately enclosing NODE.
+If NODE is the ast-root, returns nil."
+ (if (js2-ast-root-p node)
+ nil
+ (setq node (js2-node-parent node))
+ (while (and node (not (or (js2-function-node-p node)
+ (js2-script-node-p node))))
+ (setq node (js2-node-parent node)))
+ node))
+
+(defsubst js2-nested-function-p (node)
+ "Return t if NODE is a nested function, or is inside a nested function."
+ (js2-function-node-p (if (js2-function-node-p node)
+ (js2-node-parent-script-or-fn node)
+ (js2-node-parent-script-or-fn
+ (js2-node-parent-script-or-fn node)))))
+
+(defsubst js2-mode-shift-kids (kids start offset)
+ (dolist (kid kids)
+ (if (> (js2-node-pos kid) start)
+ (incf (js2-node-pos kid) offset))))
+
+(defsubst js2-mode-shift-children (parent start offset)
+ "Update start-positions of all children of PARENT beyond START."
+ (let ((root (js2-node-root parent)))
+ (js2-mode-shift-kids (js2-node-child-list parent) start offset)
+ (js2-mode-shift-kids (js2-ast-root-comments root) start offset)))
+
+(defsubst js2-node-is-descendant (node ancestor)
+ "Return t if NODE is a descendant of ANCESTOR."
+ (while (and node
+ (not (eq node ancestor)))
+ (setq node (js2-node-parent node)))
+ node)
+
+;;; visitor infrastructure
+
+(defun js2-visit-none (node callback)
+ "Visitor for AST node that have no node children."
+ nil)
+
+(defun js2-print-none (node indent)
+ "Visitor for AST node with no printed representation.")
+
+(defun js2-print-body (node indent)
+ "Print a statement, or a block without braces."
+ (if (js2-block-node-p node)
+ (dolist (kid (js2-block-node-kids node))
+ (js2-print-ast kid indent))
+ (js2-print-ast node indent)))
+
+(defun js2-print-list (args &optional delimiter)
+ (loop with len = (length args)
+ for arg in args
+ for count from 1
+ do
+ (js2-print-ast arg 0)
+ (if (< count len)
+ (insert (or delimiter ", ")))))
+
+(defun js2-print-tree (ast)
+ "Prints an AST to the current buffer.
+Makes `js2-ast-parent-nodes' available to the printer functions."
+ (let ((max-lisp-eval-depth (max max-lisp-eval-depth 1500)))
+ (js2-print-ast ast)))
+
+(defun js2-print-ast (node &optional indent)
+ "Helper function for printing AST nodes.
+Requires `js2-ast-parent-nodes' to be non-nil.
+You should use `js2-print-tree' instead of this function."
+ (let ((printer (get (aref node 0) 'js2-printer))
+ (i (or indent 0))
+ (pos (js2-node-abs-pos node)))
+ ;; TODO: wedge comments in here somewhere
+ (if printer
+ (funcall printer node i))))
+
+(defconst js2-side-effecting-tokens
+ (let ((tokens (make-bool-vector js2-num-tokens nil)))
+ (dolist (tt (list js2-ASSIGN
+ js2-ASSIGN_ADD
+ js2-ASSIGN_BITAND
+ js2-ASSIGN_BITOR
+ js2-ASSIGN_BITXOR
+ js2-ASSIGN_DIV
+ js2-ASSIGN_LSH
+ js2-ASSIGN_MOD
+ js2-ASSIGN_MUL
+ js2-ASSIGN_RSH
+ js2-ASSIGN_SUB
+ js2-ASSIGN_URSH
+ js2-BLOCK
+ js2-BREAK
+ js2-CALL
+ js2-CATCH
+ js2-CATCH_SCOPE
+ js2-CONST
+ js2-CONTINUE
+ js2-DEBUGGER
+ js2-DEC
+ js2-DELPROP
+ js2-DEL_REF
+ js2-DO
+ js2-ELSE
+ js2-EMPTY
+ js2-ENTERWITH
+ js2-EXPORT
+ js2-EXPR_RESULT
+ js2-FINALLY
+ js2-FOR
+ js2-FUNCTION
+ js2-GOTO
+ js2-IF
+ js2-IFEQ
+ js2-IFNE
+ js2-IMPORT
+ js2-INC
+ js2-JSR
+ js2-LABEL
+ js2-LEAVEWITH
+ js2-LET
+ js2-LETEXPR
+ js2-LOCAL_BLOCK
+ js2-LOOP
+ js2-NEW
+ js2-REF_CALL
+ js2-RETHROW
+ js2-RETURN
+ js2-RETURN_RESULT
+ js2-SEMI
+ js2-SETELEM
+ js2-SETELEM_OP
+ js2-SETNAME
+ js2-SETPROP
+ js2-SETPROP_OP
+ js2-SETVAR
+ js2-SET_REF
+ js2-SET_REF_OP
+ js2-SWITCH
+ js2-TARGET
+ js2-THROW
+ js2-TRY
+ js2-VAR
+ js2-WHILE
+ js2-WITH
+ js2-WITHEXPR
+ js2-YIELD))
+ (aset tokens tt t))
+ (if js2-instanceof-has-side-effects
+ (aset tokens js2-INSTANCEOF t))
+ tokens))
+
+(defun js2-node-has-side-effects (node)
+ "Return t if NODE has side effects."
+ (when node ; makes it easier to handle malformed expressions
+ (let ((tt (js2-node-type node)))
+ (cond
+ ;; This doubtless needs some work, since EXPR_VOID is used
+ ;; in several ways in Rhino, and I may not have caught them all.
+ ;; I'll wait for people to notice incorrect warnings.
+ ((and (= tt js2-EXPR_VOID)
+ (js2-expr-stmt-node-p node)) ; but not if EXPR_RESULT
+ (js2-node-has-side-effects (js2-expr-stmt-node-expr node)))
+ ((= tt js2-COMMA)
+ (js2-node-has-side-effects (js2-infix-node-right node)))
+ ((or (= tt js2-AND)
+ (= tt js2-OR))
+ (or (js2-node-has-side-effects (js2-infix-node-right node))
+ (js2-node-has-side-effects (js2-infix-node-left node))))
+ ((= tt js2-HOOK)
+ (and (js2-node-has-side-effects (js2-cond-node-true-expr node))
+ (js2-node-has-side-effects (js2-cond-node-false-expr node))))
+ ((js2-paren-node-p node)
+ (js2-node-has-side-effects (js2-paren-node-expr node)))
+ ((= tt js2-ERROR) ; avoid cascaded error messages
+ nil)
+ (t
+ (aref js2-side-effecting-tokens tt))))))
+
+(defun js2-member-expr-leftmost-name (node)
+ "For an expr such as foo.bar.baz, return leftmost node foo.
+NODE is any `js2-node' object. If it represents a member expression,
+which is any sequence of property gets, element-gets, function calls,
+or xml descendants/filter operators, then we look at the lexically
+leftmost (first) node in the chain. If it is a name-node we return it.
+Note that NODE can be a raw name-node and it will be returned as well.
+If NODE is not a name-node or member expression, or if it is a member
+expression whose leftmost target is not a name node, returns nil."
+ (let ((continue t)
+ result)
+ (while (and continue (not result))
+ (cond
+ ((js2-name-node-p node)
+ (setq result node))
+ ((js2-prop-get-node-p node)
+ (setq node (js2-prop-get-node-left node)))
+ ;; TODO: handle call-nodes, xml-nodes, others?
+ (t
+ (setq continue nil))))
+ result))
+
+(defconst js2-stmt-node-types
+ (list js2-BLOCK
+ js2-BREAK
+ js2-CONTINUE
+ js2-DEFAULT ; e4x "default xml namespace" statement
+ js2-DO
+ js2-EXPR_RESULT
+ js2-EXPR_VOID
+ js2-FOR
+ js2-IF
+ js2-RETURN
+ js2-SWITCH
+ js2-THROW
+ js2-TRY
+ js2-WHILE
+ js2-WITH)
+ "Node types that only appear in statement contexts.
+The list does not include nodes that always appear as the child
+of another specific statement type, such as switch-cases,
+catch and finally blocks, and else-clauses. The list also excludes
+nodes like yield, let and var, which may appear in either expression
+or statement context, and in the latter context always have a
+`js2-expr-stmt-node' parent. Finally, the list does not include
+functions or scripts, which are treated separately from statements
+by the JavaScript parser and runtime.")
+
+(defun js2-stmt-node-p (node)
+ "Heuristic for figuring out if NODE is a statement.
+Some node types can appear in either an expression context or a
+statement context, e.g. let-nodes, yield-nodes, and var-decl nodes.
+For these node types in a statement context, the parent will be a
+`js2-expr-stmt-node'.
+Functions aren't included in the check."
+ (memq (js2-node-type node) js2-stmt-node-types))
+
+(defsubst js2-mode-find-first-stmt (node)
+ "Search upward starting from NODE looking for a statement.
+For purposes of this function, a `js2-function-node' counts."
+ (while (not (or (js2-stmt-node-p node)
+ (js2-function-node-p node)))
+ (setq node (js2-node-parent node)))
+ node)
+
+(defun js2-node-parent-stmt (node)
+ "Return the node's first ancestor that is a statement.
+Returns nil if NODE is a `js2-ast-root'. Note that any expression
+appearing in a statement context will have a parent that is a
+`js2-expr-stmt-node' that will be returned by this function."
+ (let ((parent (js2-node-parent node)))
+ (if (or (null parent)
+ (js2-stmt-node-p parent)
+ (and (js2-function-node-p parent)
+ (not (eq (js2-function-node-form parent)
+ 'FUNCTION_EXPRESSION))))
+ parent
+ (js2-node-parent-stmt parent))))
+
+;; In the Mozilla Rhino sources, Roshan James writes:
+;; Does consistent-return analysis on the function body when strict mode is
+;; enabled.
+;;
+;; function (x) { return (x+1) }
+;;
+;; is ok, but
+;;
+;; function (x) { if (x < 0) return (x+1); }
+;;
+;; is not because the function can potentially return a value when the
+;; condition is satisfied and if not, the function does not explicitly
+;; return a value.
+;;
+;; This extends to checking mismatches such as "return" and "return <value>"
+;; used in the same function. Warnings are not emitted if inconsistent
+;; returns exist in code that can be statically shown to be unreachable.
+;; Ex.
+;; function (x) { while (true) { ... if (..) { return value } ... } }
+;;
+;; emits no warning. However if the loop had a break statement, then a
+;; warning would be emitted.
+;;
+;; The consistency analysis looks at control structures such as loops, ifs,
+;; switch, try-catch-finally blocks, examines the reachable code paths and
+;; warns the user about an inconsistent set of termination possibilities.
+;;
+;; These flags enumerate the possible ways a statement/function can
+;; terminate. These flags are used by endCheck() and by the Parser to
+;; detect inconsistent return usage.
+;;
+;; END_UNREACHED is reserved for code paths that are assumed to always be
+;; able to execute (example: throw, continue)
+;;
+;; END_DROPS_OFF indicates if the statement can transfer control to the
+;; next one. Statement such as return dont. A compound statement may have
+;; some branch that drops off control to the next statement.
+;;
+;; END_RETURNS indicates that the statement can return with no value.
+;; END_RETURNS_VALUE indicates that the statement can return a value.
+;;
+;; A compound statement such as
+;; if (condition) {
+;; return value;
+;; }
+;; Will be detected as (END_DROPS_OFF | END_RETURN_VALUE) by endCheck()
+
+(defconst js2-END_UNREACHED 0)
+(defconst js2-END_DROPS_OFF 1)
+(defconst js2-END_RETURNS 2)
+(defconst js2-END_RETURNS_VALUE 4)
+(defconst js2-END_YIELDS 8)
+
+(defun js2-has-consistent-return-usage (node)
+ "Check that every return usage in a function body is consistent.
+Returns t if the function satisfies strict mode requirement."
+ (let ((n (js2-end-check node)))
+ ;; either it doesn't return a value in any branch...
+ (or (js2-flag-not-set-p n js2-END_RETURNS_VALUE)
+ ;; or it returns a value (or is unreached) at every branch
+ (js2-flag-not-set-p n (logior js2-END_DROPS_OFF
+ js2-END_RETURNS
+ js2-END_YIELDS)))))
+
+(defun js2-end-check-if (node)
+ "Returns in the then and else blocks must be consistent with each other.
+If there is no else block, then the return statement can fall through.
+Returns logical OR of END_* flags"
+ (let ((th (js2-if-node-then-part node))
+ (el (js2-if-node-else-part node)))
+ (if (null th)
+ js2-END_UNREACHED
+ (logior (js2-end-check th) (if el
+ (js2-end-check el)
+ js2-END_DROPS_OFF)))))
+
+(defun js2-end-check-switch (node)
+ "Consistency of return statements is checked between the case statements.
+If there is no default, then the switch can fall through. If there is a
+default, we check to see if all code paths in the default return or if
+there is a code path that can fall through.
+Returns logical OR of END_* flags."
+ (let ((rv js2-END_UNREACHED)
+ default-case)
+ ;; examine the cases
+ (catch 'break
+ (dolist (c (js2-switch-node-cases node))
+ (if (js2-case-node-expr c)
+ (js2-set-flag rv (js2-end-check-block c))
+ (setq default-case c)
+ (throw 'break nil))))
+ ;; we don't care how the cases drop into each other
+ (js2-clear-flag rv js2-END_DROPS_OFF)
+ ;; examine the default
+ (js2-set-flag rv (if default-case
+ (js2-end-check default-case)
+ js2-END_DROPS_OFF))
+ rv))
+
+(defun js2-end-check-try (node)
+ "If the block has a finally, return consistency is checked in the
+finally block. If all code paths in the finally return, then the
+returns in the try-catch blocks don't matter. If there is a code path
+that does not return or if there is no finally block, the returns
+of the try and catch blocks are checked for mismatch.
+Returns logical OR of END_* flags."
+ (let ((finally (js2-try-node-finally-block node))
+ rv)
+ ;; check the finally if it exists
+ (setq rv (if finally
+ (js2-end-check (js2-finally-node-body finally))
+ js2-END_DROPS_OFF))
+ ;; If the finally block always returns, then none of the returns
+ ;; in the try or catch blocks matter.
+ (when (js2-flag-set-p rv js2-END_DROPS_OFF)
+ (js2-clear-flag rv js2-END_DROPS_OFF)
+ ;; examine the try block
+ (js2-set-flag rv (js2-end-check (js2-try-node-try-block node)))
+ ;; check each catch block
+ (dolist (cb (js2-try-node-catch-clauses node))
+ (js2-set-flag rv (js2-end-check (js2-catch-node-block cb)))))
+ rv))
+
+(defun js2-end-check-loop (node)
+ "Return statement in the loop body must be consistent. The default
+assumption for any kind of a loop is that it will eventually terminate.
+The only exception is a loop with a constant true condition. Code that
+follows such a loop is examined only if one can statically determine
+that there is a break out of the loop.
+
+ for(... ; ... ; ...) {}
+ for(... in ... ) {}
+ while(...) { }
+ do { } while(...)
+
+Returns logical OR of END_* flags."
+ (let ((rv (js2-end-check (js2-loop-node-body node)))
+ (condition (cond
+ ((js2-while-node-p node)
+ (js2-while-node-condition node))
+ ((js2-do-node-p node)
+ (js2-do-node-condition node))
+ ((js2-for-node-p node)
+ (js2-for-node-condition node)))))
+
+ ;; check to see if the loop condition is always true
+ (if (and condition
+ (eq (js2-always-defined-boolean-p condition) 'ALWAYS_TRUE))
+ (js2-clear-flag rv js2-END_DROPS_OFF))
+
+ ;; look for effect of breaks
+ (js2-set-flag rv (js2-node-get-prop node
+ 'CONTROL_BLOCK_PROP
+ js2-END_UNREACHED))
+ rv))
+
+(defun js2-end-check-block (node)
+ "A general block of code is examined statement by statement.
+If any statement (even a compound one) returns in all branches, then
+subsequent statements are not examined.
+Returns logical OR of END_* flags."
+ (let* ((rv js2-END_DROPS_OFF)
+ (kids (js2-block-node-kids node))
+ (n (car kids)))
+ ;; Check each statment. If the statement can continue onto the next
+ ;; one (i.e. END_DROPS_OFF is set), then check the next statement.
+ (while (and n (js2-flag-set-p rv js2-END_DROPS_OFF))
+ (js2-clear-flag rv js2-END_DROPS_OFF)
+ (js2-set-flag rv (js2-end-check n))
+ (setq kids (cdr kids)
+ n (car kids)))
+ rv))
+
+(defun js2-end-check-label (node)
+ "A labeled statement implies that there may be a break to the label.
+The function processes the labeled statement and then checks the
+CONTROL_BLOCK_PROP property to see if there is ever a break to the
+particular label.
+Returns logical OR of END_* flags."
+ (let ((rv (js2-end-check (js2-labeled-stmt-node-stmt node))))
+ (logior rv (js2-node-get-prop node
+ 'CONTROL_BLOCK_PROP
+ js2-END_UNREACHED))))
+
+(defun js2-end-check-break (node)
+ "When a break is encountered annotate the statement being broken
+out of by setting its CONTROL_BLOCK_PROP property.
+Returns logical OR of END_* flags."
+ (and (js2-break-node-target node)
+ (js2-node-set-prop (js2-break-node-target node)
+ 'CONTROL_BLOCK_PROP
+ js2-END_DROPS_OFF))
+ js2-END_UNREACHED)
+
+(defun js2-end-check (node)
+ "Examine the body of a function, doing a basic reachability analysis.
+Returns a combination of flags END_* flags that indicate
+how the function execution can terminate. These constitute only the
+pessimistic set of termination conditions. It is possible that at
+runtime certain code paths will never be actually taken. Hence this
+analysis will flag errors in cases where there may not be errors.
+Returns logical OR of END_* flags"
+ (let (kid)
+ (cond
+ ((js2-break-node-p node)
+ (js2-end-check-break node))
+ ((js2-expr-stmt-node-p node)
+ (if (setq kid (js2-expr-stmt-node-expr node))
+ (js2-end-check kid)
+ js2-END_DROPS_OFF))
+ ((or (js2-continue-node-p node)
+ (js2-throw-node-p node))
+ js2-END_UNREACHED)
+ ((js2-return-node-p node)
+ (if (setq kid (js2-return-node-retval node))
+ js2-END_RETURNS_VALUE
+ js2-END_RETURNS))
+ ((js2-loop-node-p node)
+ (js2-end-check-loop node))
+ ((js2-switch-node-p node)
+ (js2-end-check-switch node))
+ ((js2-labeled-stmt-node-p node)
+ (js2-end-check-label node))
+ ((js2-if-node-p node)
+ (js2-end-check-if node))
+ ((js2-try-node-p node)
+ (js2-end-check-try node))
+ ((js2-block-node-p node)
+ (if (null (js2-block-node-kids node))
+ js2-END_DROPS_OFF
+ (js2-end-check-block node)))
+ ((js2-yield-node-p node)
+ js2-END_YIELDS)
+ (t
+ js2-END_DROPS_OFF))))
+
+(defun js2-always-defined-boolean-p (node)
+ "Check if NODE always evaluates to true or false in boolean context.
+Returns 'ALWAYS_TRUE, 'ALWAYS_FALSE, or nil if it's neither always true
+nor always false."
+ (let ((tt (js2-node-type node))
+ num)
+ (cond
+ ((or (= tt js2-FALSE) (= tt js2-NULL))
+ 'ALWAYS_FALSE)
+ ((= tt js2-TRUE)
+ 'ALWAYS_TRUE)
+ ((= tt js2-NUMBER)
+ (setq num (js2-number-node-num-value node))
+ (if (and (not (eq num 0.0e+NaN))
+ (not (zerop num)))
+ 'ALWAYS_TRUE
+ 'ALWAYS_FALSE))
+ (t
+ nil))))
+
+;;; Scanner -- a port of Mozilla Rhino's lexer.
+;; Corresponds to Rhino files Token.java and TokenStream.java.
+
+(defvar js2-tokens nil
+ "List of all defined token names.") ; initialized in `js2-token-names'
+
+(defconst js2-token-names
+ (let* ((names (make-vector js2-num-tokens -1))
+ (case-fold-search nil) ; only match js2-UPPER_CASE
+ (syms (apropos-internal "^js2-\\(?:[A-Z_]+\\)")))
+ (loop for sym in syms
+ for i from 0
+ do
+ (unless (or (memq sym '(js2-EOF_CHAR js2-ERROR))
+ (not (boundp sym)))
+ (aset names (symbol-value sym) ; code, e.g. 152
+ (substring (symbol-name sym) 4)) ; name, e.g. "LET"
+ (push sym js2-tokens)))
+ names)
+ "Vector mapping int values to token string names, sans `js2-' prefix.")
+
+(defun js2-token-name (tok)
+ "Return a string name for TOK, a token symbol or code.
+Signals an error if it's not a recognized token."
+ (let ((code tok))
+ (if (symbolp tok)
+ (setq code (symbol-value tok)))
+ (if (eq code -1)
+ "ERROR"
+ (if (and (numberp code)
+ (not (minusp code))
+ (< code js2-num-tokens))
+ (aref js2-token-names code)
+ (error "Invalid token: %s" code)))))
+
+(defsubst js2-token-sym (tok)
+ "Return symbol for TOK given its code, e.g. 'js2-LP for code 86."
+ (intern (js2-token-name tok)))
+
+(defconst js2-token-codes
+ (let ((table (make-hash-table :test 'eq :size 256)))
+ (loop for name across js2-token-names
+ for sym = (intern (concat "js2-" name))
+ do
+ (puthash sym (symbol-value sym) table))
+ ;; clean up a few that are "wrong" in Rhino's token codes
+ (puthash 'js2-DELETE js2-DELPROP table)
+ table)
+ "Hashtable mapping token symbols to their bytecodes.")
+
+(defsubst js2-token-code (sym)
+ "Return code for token symbol SYM, e.g. 86 for 'js2-LP."
+ (or (gethash sym js2-token-codes)
+ (error "Invalid token symbol: %s " sym))) ; signal code bug
+
+(defsubst js2-report-scan-error (msg &optional no-throw beg len)
+ (setq js2-token-end js2-ts-cursor)
+ (js2-report-error msg nil
+ (or beg js2-token-beg)
+ (or len (- js2-token-end js2-token-beg)))
+ (unless no-throw
+ (throw 'return js2-ERROR)))
+
+(defsubst js2-get-string-from-buffer ()
+ "Reverse the char accumulator and return it as a string."
+ (setq js2-token-end js2-ts-cursor)
+ (if js2-ts-string-buffer
+ (apply #'string (nreverse js2-ts-string-buffer))
+ ""))
+
+;; TODO: could potentially avoid a lot of consing by allocating a
+;; char buffer the way Rhino does.
+(defsubst js2-add-to-string (c)
+ (push c js2-ts-string-buffer))
+
+;; Note that when we "read" the end-of-file, we advance js2-ts-cursor
+;; to (1+ (point-max)), which lets the scanner treat end-of-file like
+;; any other character: when it's not part of the current token, we
+;; unget it, allowing it to be read again by the following call.
+(defsubst js2-unget-char ()
+ (decf js2-ts-cursor))
+
+;; Rhino distinguishes \r and \n line endings. We don't need to
+;; because we only scan from Emacs buffers, which always use \n.
+(defsubst js2-get-char ()
+ "Read and return the next character from the input buffer.
+Increments `js2-ts-lineno' if the return value is a newline char.
+Updates `js2-ts-cursor' to the point after the returned char.
+Returns `js2-EOF_CHAR' if we hit the end of the buffer.
+Also updates `js2-ts-hit-eof' and `js2-ts-line-start' as needed."
+ (let (c)
+ ;; check for end of buffer
+ (if (>= js2-ts-cursor (point-max))
+ (setq js2-ts-hit-eof t
+ js2-ts-cursor (1+ js2-ts-cursor)
+ c js2-EOF_CHAR) ; return value
+ ;; otherwise read next char
+ (setq c (char-before (incf js2-ts-cursor)))
+ ;; if we read a newline, update counters
+ (if (= c ?\n)
+ (setq js2-ts-line-start js2-ts-cursor
+ js2-ts-lineno (1+ js2-ts-lineno)))
+ ;; TODO: skip over format characters
+ c)))
+
+(defsubst js2-read-unicode-escape ()
+ "Read a \\uNNNN sequence from the input.
+Assumes the ?\ and ?u have already been read.
+Returns the unicode character, or nil if it wasn't a valid character.
+Doesn't change the values of any scanner variables."
+ ;; I really wish I knew a better way to do this, but I can't
+ ;; find the Emacs function that takes a 16-bit int and converts
+ ;; it to a Unicode/utf-8 character. So I basically eval it with (read).
+ ;; Have to first check that it's 4 hex characters or it may stop
+ ;; the read early.
+ (ignore-errors
+ (let ((s (buffer-substring-no-properties js2-ts-cursor
+ (+ 4 js2-ts-cursor))))
+ (if (string-match "[a-zA-Z0-9]\\{4\\}" s)
+ (read (concat "?\\u" s))))))
+
+(defsubst js2-match-char (test)
+ "Consume and return next character if it matches TEST, a character.
+Returns nil and consumes nothing if TEST is not the next character."
+ (let ((c (js2-get-char)))
+ (if (eq c test)
+ t
+ (js2-unget-char)
+ nil)))
+
+(defsubst js2-peek-char ()
+ (prog1
+ (js2-get-char)
+ (js2-unget-char)))
+
+(defsubst js2-java-identifier-start-p (c)
+ (or
+ (memq c '(?$ ?_))
+ (js2-char-uppercase-p c)
+ (js2-char-lowercase-p c)))
+
+(defsubst js2-java-identifier-part-p (c)
+ "Implementation of java.lang.Character.isJavaIdentifierPart()"
+ ;; TODO: make me Unicode-friendly. See comments above.
+ (or
+ (memq c '(?$ ?_))
+ (js2-char-uppercase-p c)
+ (js2-char-lowercase-p c)
+ (and (>= c ?0) (<= c ?9))))
+
+(defsubst js2-alpha-p (c)
+ (cond ((and (<= ?A c) (<= c ?Z)) t)
+ ((and (<= ?a c) (<= c ?z)) t)
+ (t nil)))
+
+(defsubst js2-digit-p (c)
+ (and (<= ?0 c) (<= c ?9)))
+
+(defsubst js2-js-space-p (c)
+ (if (<= c 127)
+ (memq c '(#x20 #x9 #xB #xC #xD))
+ (or
+ (eq c #xA0)
+ ;; TODO: change this nil to check for Unicode space character
+ nil)))
+
+(defconst js2-eol-chars (list js2-EOF_CHAR ?\n ?\r))
+
+(defsubst js2-skip-line ()
+ "Skip to end of line"
+ (let (c)
+ (while (not (memq (setq c (js2-get-char)) js2-eol-chars)))
+ (js2-unget-char)
+ (setq js2-token-end js2-ts-cursor)))
+
+(defun js2-init-scanner (&optional buf line)
+ "Create token stream for BUF starting on LINE.
+BUF defaults to current-buffer and line defaults to 1.
+
+A buffer can only have one scanner active at a time, which yields
+dramatically simpler code than using a defstruct. If you need to
+have simultaneous scanners in a buffer, copy the regions to scan
+into temp buffers."
+ (save-excursion
+ (when buf
+ (set-buffer buf))
+ (setq js2-ts-dirty-line nil
+ js2-ts-regexp-flags nil
+ js2-ts-string ""
+ js2-ts-number nil
+ js2-ts-hit-eof nil
+ js2-ts-line-start 0
+ js2-ts-lineno (or line 1)
+ js2-ts-line-end-char -1
+ js2-ts-cursor (point-min)
+ js2-ts-is-xml-attribute nil
+ js2-ts-xml-is-tag-content nil
+ js2-ts-xml-open-tags-count 0
+ js2-ts-string-buffer nil)))
+
+;; This function uses the cached op, string and number fields in
+;; TokenStream; if getToken has been called since the passed token
+;; was scanned, the op or string printed may be incorrect.
+(defun js2-token-to-string (token)
+ ;; Not sure where this function is used in Rhino. Not tested.
+ (if (not js2-debug-print-trees)
+ ""
+ (let ((name (js2-token-name token)))
+ (cond
+ ((memq token (list js2-STRING js2-REGEXP js2-NAME))
+ (concat name " `" js2-ts-string "'"))
+ ((eq token js2-NUMBER)
+ (format "NUMBER %g" js2-ts-number))
+ (t
+ name)))))
+
+(defconst js2-keywords
+ '(break
+ case catch const continue
+ debugger default delete do
+ else enum
+ false finally for function
+ if in instanceof import
+ let
+ new null
+ return
+ switch
+ this throw true try typeof
+ var void
+ while with
+ yield))
+
+;; Token names aren't exactly the same as the keywords, unfortunately.
+;; E.g. enum isn't in the tokens, and delete is js2-DELPROP.
+(defconst js2-kwd-tokens
+ (let ((table (make-vector js2-num-tokens nil))
+ (tokens
+ (list js2-BREAK
+ js2-CASE js2-CATCH js2-CONST js2-CONTINUE
+ js2-DEBUGGER js2-DEFAULT js2-DELPROP js2-DO
+ js2-ELSE
+ js2-FALSE js2-FINALLY js2-FOR js2-FUNCTION
+ js2-IF js2-IN js2-INSTANCEOF js2-IMPORT
+ js2-LET
+ js2-NEW js2-NULL
+ js2-RETURN
+ js2-SWITCH
+ js2-THIS js2-THROW js2-TRUE js2-TRY js2-TYPEOF
+ js2-VAR
+ js2-WHILE js2-WITH
+ js2-YIELD)))
+ (dolist (i tokens)
+ (aset table i 'font-lock-keyword-face))
+ (aset table js2-STRING 'font-lock-string-face)
+ (aset table js2-REGEXP 'font-lock-string-face)
+ (aset table js2-COMMENT 'font-lock-comment-face)
+ (aset table js2-THIS 'font-lock-builtin-face)
+ (aset table js2-VOID 'font-lock-constant-face)
+ (aset table js2-NULL 'font-lock-constant-face)
+ (aset table js2-TRUE 'font-lock-constant-face)
+ (aset table js2-FALSE 'font-lock-constant-face)
+ table)
+ "Vector whose values are non-nil for tokens that are keywords.
+The values are default faces to use for highlighting the keywords.")
+
+(defconst js2-reserved-words
+ '(abstract
+ boolean byte
+ char class
+ double
+ enum export extends
+ final float
+ goto
+ implements import int interface
+ long
+ native
+ package private protected public
+ short static super synchronized
+ throws transient
+ volatile))
+
+(defconst js2-keyword-names
+ (let ((table (make-hash-table :test 'equal)))
+ (loop for k in js2-keywords
+ do (puthash
+ (symbol-name k) ; instanceof
+ (intern (concat "js2-"
+ (upcase (symbol-name k)))) ; js2-INSTANCEOF
+ table))
+ table)
+ "JavaScript keywords by name, mapped to their symbols.")
+
+(defconst js2-reserved-word-names
+ (let ((table (make-hash-table :test 'equal)))
+ (loop for k in js2-reserved-words
+ do
+ (puthash (symbol-name k) 'js2-RESERVED table))
+ table)
+ "JavaScript reserved words by name, mapped to 'js2-RESERVED.")
+
+(defsubst js2-collect-string (buf)
+ "Convert BUF, a list of chars, to a string.
+Reverses BUF before converting."
+ (cond
+ ((stringp buf)
+ buf)
+ ((null buf) ; for emacs21 compat
+ "")
+ (t
+ (if buf
+ (apply #'string (nreverse buf))
+ ""))))
+
+(defun js2-string-to-keyword (s)
+ "Return token for S, a string, if S is a keyword or reserved word.
+Returns a symbol such as 'js2-BREAK, or nil if not keyword/reserved."
+ (or (gethash s js2-keyword-names)
+ (gethash s js2-reserved-word-names)))
+
+(defsubst js2-ts-set-char-token-bounds ()
+ "Used when next token is one character."
+ (setq js2-token-beg (1- js2-ts-cursor)
+ js2-token-end js2-ts-cursor))
+
+(defsubst js2-ts-return (token)
+ "Return an N-character TOKEN from `js2-get-token'.
+Updates `js2-token-end' accordingly."
+ (setq js2-token-end js2-ts-cursor)
+ (throw 'return token))
+
+(defsubst js2-x-digit-to-int (c accumulator)
+ "Build up a hex number.
+If C is a hexadecimal digit, return ACCUMULATOR * 16 plus
+corresponding number. Otherwise return -1."
+ (catch 'return
+ (catch 'check
+ ;; Use 0..9 < A..Z < a..z
+ (cond
+ ((<= c ?9)
+ (decf c ?0)
+ (if (<= 0 c)
+ (throw 'check nil)))
+ ((<= c ?F)
+ (when (<= ?A c)
+ (decf c (- ?A 10))
+ (throw 'check nil)))
+ ((<= c ?f)
+ (when (<= ?a c)
+ (decf c (- ?a 10))
+ (throw 'check nil))))
+ (throw 'return -1))
+ (logior c (lsh accumulator 4))))
+
+(defun js2-get-token ()
+ "Return next JavaScript token, an int such as js2-RETURN."
+ (let (c
+ c1
+ identifier-start
+ is-unicode-escape-start
+ contains-escape
+ escape-val
+ escape-start
+ str
+ result
+ base
+ is-integer
+ quote-char
+ val
+ look-for-slash
+ continue)
+ (catch 'return
+ (while t
+ ;; Eat whitespace, possibly sensitive to newlines.
+ (setq continue t)
+ (while continue
+ (setq c (js2-get-char))
+ (cond
+ ((eq c js2-EOF_CHAR)
+ (js2-ts-set-char-token-bounds)
+ (throw 'return js2-EOF))
+ ((eq c ?\n)
+ (js2-ts-set-char-token-bounds)
+ (setq js2-ts-dirty-line nil)
+ (throw 'return js2-EOL))
+ ((not (js2-js-space-p c))
+ (if (/= c ?-) ; in case end of HTML comment
+ (setq js2-ts-dirty-line t))
+ (setq continue nil))))
+ ;; Assume the token will be 1 char - fixed up below.
+ (js2-ts-set-char-token-bounds)
+ (when (eq c ?@)
+ (throw 'return js2-XMLATTR))
+ ;; identifier/keyword/instanceof?
+ ;; watch out for starting with a <backslash>
+ (cond
+ ((eq c ?\\)
+ (setq c (js2-get-char))
+ (if (eq c ?u)
+ (setq identifier-start t
+ is-unicode-escape-start t
+ js2-ts-string-buffer nil)
+ (setq identifier-start nil)
+ (js2-unget-char)
+ (setq c ?\\)))
+ (t
+ (when (setq identifier-start (js2-java-identifier-start-p c))
+ (setq js2-ts-string-buffer nil)
+ (js2-add-to-string c))))
+ (when identifier-start
+ (setq contains-escape is-unicode-escape-start)
+ (catch 'break
+ (while t
+ (if is-unicode-escape-start
+ ;; strictly speaking we should probably push-back
+ ;; all the bad characters if the <backslash>uXXXX
+ ;; sequence is malformed. But since there isn't a
+ ;; correct context(is there?) for a bad Unicode
+ ;; escape sequence in an identifier, we can report
+ ;; an error here.
+ (progn
+ (setq escape-val 0)
+ (dotimes (i 4)
+ (setq c (js2-get-char)
+ escape-val (js2-x-digit-to-int c escape-val))
+ ;; Next check takes care of c < 0 and bad escape
+ (if (minusp escape-val)
+ (throw 'break nil)))
+ (if (minusp escape-val)
+ (js2-report-scan-error "msg.invalid.escape" t))
+ (js2-add-to-string escape-val)
+ (setq is-unicode-escape-start nil))
+ (setq c (js2-get-char))
+ (cond
+ ((eq c ?\\)
+ (setq c (js2-get-char))
+ (if (eq c ?u)
+ (setq is-unicode-escape-start t
+ contains-escape t)
+ (js2-report-scan-error "msg.illegal.character" t)))
+ (t
+ (if (or (eq c js2-EOF_CHAR)
+ (not (js2-java-identifier-part-p c)))
+ (throw 'break nil))
+ (js2-add-to-string c))))))
+ (js2-unget-char)
+ (setq str (js2-get-string-from-buffer))
+ (unless contains-escape
+ ;; OPT we shouldn't have to make a string (object!) to
+ ;; check if it's a keyword.
+ ;; Return the corresponding token if it's a keyword
+ (when (setq result (js2-string-to-keyword str))
+ (if (and (< js2-language-version 170)
+ (memq result '(js2-LET js2-YIELD)))
+ ;; LET and YIELD are tokens only in 1.7 and later
+ (setq result 'js2-NAME))
+ (if (not (eq result js2-RESERVED))
+ (throw 'return (js2-token-code result)))
+ (js2-report-warning "msg.reserved.keyword" str)))
+ ;; If we want to intern these as Rhino does, just use (intern str)
+ (setq js2-ts-string str)
+ (throw 'return js2-NAME)) ; end identifier/kwd check
+ ;; is it a number?
+ (when (or (js2-digit-p c)
+ (and (eq c ?.) (js2-digit-p (js2-peek-char))))
+ (setq js2-ts-string-buffer nil
+ base 10)
+ (when (eq c ?0)
+ (setq c (js2-get-char))
+ (cond
+ ((or (eq c ?x) (eq c ?X))
+ (setq base 16)
+ (setq c (js2-get-char)))
+ ((js2-digit-p c)
+ (setq base 8))
+ (t
+ (js2-add-to-string ?0))))
+ (if (eq base 16)
+ (while (<= 0 (js2-x-digit-to-int c 0))
+ (js2-add-to-string c)
+ (setq c (js2-get-char)))
+ (while (and (<= ?0 c) (<= c ?9))
+ ;; We permit 08 and 09 as decimal numbers, which
+ ;; makes our behavior a superset of the ECMA
+ ;; numeric grammar. We might not always be so
+ ;; permissive, so we warn about it.
+ (when (and (eq base 8) (>= c ?8))
+ (js2-report-warning "msg.bad.octal.literal"
+ (if (eq c ?8) "8" "9"))
+ (setq base 10))
+ (js2-add-to-string c)
+ (setq c (js2-get-char))))
+ (setq is-integer t)
+ (when (and (eq base 10) (memq c '(?. ?e ?E)))
+ (setq is-integer nil)
+ (when (eq c ?.)
+ (loop do
+ (js2-add-to-string c)
+ (setq c (js2-get-char))
+ while (js2-digit-p c)))
+ (when (memq c '(?e ?E))
+ (js2-add-to-string c)
+ (setq c (js2-get-char))
+ (when (memq c '(?+ ?-))
+ (js2-add-to-string c)
+ (setq c (js2-get-char)))
+ (unless (js2-digit-p c)
+ (js2-report-scan-error "msg.missing.exponent" t))
+ (loop do
+ (js2-add-to-string c)
+ (setq c (js2-get-char))
+ while (js2-digit-p c))))
+ (js2-unget-char)
+ (setq js2-ts-string (js2-get-string-from-buffer)
+ js2-ts-number
+ (if (and (eq base 10) (not is-integer))
+ (string-to-number js2-ts-string)
+ ;; TODO: call runtime number-parser. Some of it is in
+ ;; js2-util.el, but I need to port ScriptRuntime.stringToNumber.
+ (string-to-number js2-ts-string)))
+ (throw 'return js2-NUMBER))
+ ;; is it a string?
+ (when (memq c '(?\" ?\'))
+ ;; We attempt to accumulate a string the fast way, by
+ ;; building it directly out of the reader. But if there
+ ;; are any escaped characters in the string, we revert to
+ ;; building it out of a string buffer.
+ (setq quote-char c
+ js2-ts-string-buffer nil
+ c (js2-get-char))
+ (catch 'break
+ (while (/= c quote-char)
+ (catch 'continue
+ (when (or (eq c ?\n) (eq c js2-EOF_CHAR))
+ (js2-unget-char)
+ (setq js2-token-end js2-ts-cursor)
+ (js2-report-error "msg.unterminated.string.lit")
+ (throw 'return js2-STRING))
+ (when (eq c ?\\)
+ ;; We've hit an escaped character
+ (setq c (js2-get-char))
+ (case c
+ (?b (setq c ?\b))
+ (?f (setq c ?\f))
+ (?n (setq c ?\n))
+ (?r (setq c ?\r))
+ (?t (setq c ?\t))
+ (?v (setq c ?\v))
+ (?u
+ (setq c1 (js2-read-unicode-escape))
+ (if js2-parse-ide-mode
+ (if c1
+ (progn
+ ;; just copy the string in IDE-mode
+ (js2-add-to-string ?\\)
+ (js2-add-to-string ?u)
+ (dotimes (i 3)
+ (js2-add-to-string (js2-get-char)))
+ (setq c (js2-get-char))) ; added at end of loop
+ ;; flag it as an invalid escape
+ (js2-report-warning "msg.invalid.escape"
+ nil (- js2-ts-cursor 2) 6))
+ ;; Get 4 hex digits; if the u escape is not
+ ;; followed by 4 hex digits, use 'u' + the
+ ;; literal character sequence that follows.
+ (js2-add-to-string ?u)
+ (setq escape-val 0)
+ (dotimes (i 4)
+ (setq c (js2-get-char)
+ escape-val (js2-x-digit-to-int c escape-val))
+ (if (minusp escape-val)
+ (throw 'continue nil))
+ (js2-add-to-string c))
+ ;; prepare for replace of stored 'u' sequence by escape value
+ (setq js2-ts-string-buffer (nthcdr 5 js2-ts-string-buffer)
+ c escape-val)))
+ (?x
+ ;; Get 2 hex digits, defaulting to 'x'+literal
+ ;; sequence, as above.
+ (setq c (js2-get-char)
+ escape-val (js2-x-digit-to-int c 0))
+ (if (minusp escape-val)
+ (progn
+ (js2-add-to-string ?x)
+ (throw 'continue nil))
+ (setq c1 c
+ c (js2-get-char)
+ escape-val (js2-x-digit-to-int c escape-val))
+ (if (minusp escape-val)
+ (progn
+ (js2-add-to-string ?x)
+ (js2-add-to-string c1)
+ (throw 'continue nil))
+ ;; got 2 hex digits
+ (setq c escape-val))))
+ (?\n
+ ;; Remove line terminator after escape to follow
+ ;; SpiderMonkey and C/C++
+ (setq c (js2-get-char))
+ (throw 'continue nil))
+ (t
+ (when (and (<= ?0 c) (< c ?8))
+ (setq val (- c ?0)
+ c (js2-get-char))
+ (when (and (<= ?0 c) (< c ?8))
+ (setq val (- (+ (* 8 val) c) ?0)
+ c (js2-get-char))
+ (when (and (<= ?0 c)
+ (< c ?8)
+ (< val #o37))
+ ;; c is 3rd char of octal sequence only
+ ;; if the resulting val <= 0377
+ (setq val (- (+ (* 8 val) c) ?0)
+ c (js2-get-char))))
+ (js2-unget-char)
+ (setq c val)))))
+ (js2-add-to-string c)
+ (setq c (js2-get-char)))))
+ (setq js2-ts-string (js2-get-string-from-buffer))
+ (throw 'return js2-STRING))
+ (case c
+ (?\;
+ (throw 'return js2-SEMI))
+ (?\[
+ (throw 'return js2-LB))
+ (?\]
+ (throw 'return js2-RB))
+ (?{
+ (throw 'return js2-LC))
+ (?}
+ (throw 'return js2-RC))
+ (?\(
+ (throw 'return js2-LP))
+ (?\)
+ (throw 'return js2-RP))
+ (?,
+ (throw 'return js2-COMMA))
+ (??
+ (throw 'return js2-HOOK))
+ (?:
+ (if (js2-match-char ?:)
+ (js2-ts-return js2-COLONCOLON)
+ (throw 'return js2-COLON)))
+ (?.
+ (if (js2-match-char ?.)
+ (js2-ts-return js2-DOTDOT)
+ (if (js2-match-char ?\()
+ (js2-ts-return js2-DOTQUERY)
+ (throw 'return js2-DOT))))
+ (?|
+ (if (js2-match-char ?|)
+ (throw 'return js2-OR)
+ (if (js2-match-char ?=)
+ (js2-ts-return js2-ASSIGN_BITOR)
+ (throw 'return js2-BITOR))))
+ (?^
+ (if (js2-match-char ?=)
+ (js2-ts-return js2-ASSIGN_BITOR)
+ (throw 'return js2-BITXOR)))
+ (?&
+ (if (js2-match-char ?&)
+ (throw 'return js2-AND)
+ (if (js2-match-char ?=)
+ (js2-ts-return js2-ASSIGN_BITAND)
+ (throw 'return js2-BITAND))))
+ (?=
+ (if (js2-match-char ?=)
+ (if (js2-match-char ?=)
+ (js2-ts-return js2-SHEQ)
+ (throw 'return js2-EQ))
+ (throw 'return js2-ASSIGN)))
+ (?!
+ (if (js2-match-char ?=)
+ (if (js2-match-char ?=)
+ (js2-ts-return js2-SHNE)
+ (js2-ts-return js2-NE))
+ (throw 'return js2-NOT)))
+ (?<
+ ;; NB:treat HTML begin-comment as comment-till-eol
+ (when (js2-match-char ?!)
+ (when (js2-match-char ?-)
+ (when (js2-match-char ?-)
+ (js2-skip-line)
+ (setq js2-ts-comment-type 'html)
+ (throw 'return js2-COMMENT)))
+ (js2-unget-char))
+ (if (js2-match-char ?<)
+ (if (js2-match-char ?=)
+ (js2-ts-return js2-ASSIGN_LSH)
+ (js2-ts-return js2-LSH))
+ (if (js2-match-char ?=)
+ (js2-ts-return js2-LE)
+ (throw 'return js2-LT))))
+ (?>
+ (if (js2-match-char ?>)
+ (if (js2-match-char ?>)
+ (if (js2-match-char ?=)
+ (js2-ts-return js2-ASSIGN_URSH)
+ (js2-ts-return js2-URSH))
+ (if (js2-match-char ?=)
+ (js2-ts-return js2-ASSIGN_RSH)
+ (js2-ts-return js2-RSH)))
+ (if (js2-match-char ?=)
+ (js2-ts-return js2-GE)
+ (throw 'return js2-GT))))
+ (?*
+ (if (js2-match-char ?=)
+ (js2-ts-return js2-ASSIGN_MUL)
+ (throw 'return js2-MUL)))
+ (?/
+ ;; is it a // comment?
+ (when (js2-match-char ?/)
+ (setq js2-token-beg (- js2-ts-cursor 2))
+ (js2-skip-line)
+ (setq js2-ts-comment-type 'line)
+ ;; include newline so highlighting goes to end of window
+ (incf js2-token-end)
+ (throw 'return js2-COMMENT))
+ ;; is it a /* comment?
+ (when (js2-match-char ?*)
+ (setq look-for-slash nil
+ js2-token-beg (- js2-ts-cursor 2)
+ js2-ts-comment-type
+ (if (js2-match-char ?*)
+ (progn
+ (setq look-for-slash t)
+ 'jsdoc)
+ 'block))
+ (while t
+ (setq c (js2-get-char))
+ (cond
+ ((eq c js2-EOF_CHAR)
+ (setq js2-token-end (1- js2-ts-cursor))
+ (js2-report-error "msg.unterminated.comment")
+ (throw 'return js2-COMMENT))
+ ((eq c ?*)
+ (setq look-for-slash t))
+ ((eq c ?/)
+ (if look-for-slash
+ (js2-ts-return js2-COMMENT)))
+ (t
+ (setq look-for-slash nil
+ js2-token-end js2-ts-cursor)))))
+ (if (js2-match-char ?=)
+ (js2-ts-return js2-ASSIGN_DIV)
+ (throw 'return js2-DIV)))
+ (?#
+ (when js2-skip-preprocessor-directives
+ (js2-skip-line)
+ (setq js2-ts-comment-type 'preprocessor
+ js2-token-end js2-ts-cursor)
+ (throw 'return js2-COMMENT))
+ (throw 'return js2-ERROR))
+ (?%
+ (if (js2-match-char ?=)
+ (js2-ts-return js2-ASSIGN_MOD)
+ (throw 'return js2-MOD)))
+ (?~
+ (throw 'return js2-BITNOT))
+ (?+
+ (if (js2-match-char ?=)
+ (js2-ts-return js2-ASSIGN_ADD)
+ (if (js2-match-char ?+)
+ (js2-ts-return js2-INC)
+ (throw 'return js2-ADD))))
+ (?-
+ (cond
+ ((js2-match-char ?=)
+ (setq c js2-ASSIGN_SUB))
+ ((js2-match-char ?-)
+ (unless js2-ts-dirty-line
+ ;; treat HTML end-comment after possible whitespace
+ ;; after line start as comment-until-eol
+ (when (js2-match-char ?>)
+ (js2-skip-line)
+ (setq js2-ts-comment-type 'html)
+ (throw 'return js2-COMMENT)))
+ (setq c js2-DEC))
+ (t
+ (setq c js2-SUB)))
+ (setq js2-ts-dirty-line t)
+ (js2-ts-return c))
+ (otherwise
+ (js2-report-scan-error "msg.illegal.character")))))))
+
+(defun js2-read-regexp (start-token)
+ "Called by parser when it gets / or /= in literal context."
+ (let (c
+ err
+ in-class ; inside a '[' .. ']' character-class
+ flags
+ (continue t))
+ (setq js2-token-beg js2-ts-cursor
+ js2-ts-string-buffer nil
+ js2-ts-regexp-flags nil)
+ (if (eq start-token js2-ASSIGN_DIV)
+ ;; mis-scanned /=
+ (js2-add-to-string ?=)
+ (if (not (eq start-token js2-DIV))
+ (error "failed assertion")))
+ (while (and (not err)
+ (or (/= (setq c (js2-get-char)) ?/)
+ in-class))
+ (cond
+ ((or (= c ?\n)
+ (= c js2-EOF_CHAR))
+ (setq js2-token-end (1- js2-ts-cursor)
+ err t
+ js2-ts-string (js2-collect-string js2-ts-string-buffer))
+ (js2-report-error "msg.unterminated.re.lit"))
+ (t (cond
+ ((= c ?\\)
+ (js2-add-to-string c)
+ (setq c (js2-get-char)))
+ ((= c ?\[)
+ (setq in-class t))
+ ((= c ?\])
+ (setq in-class nil)))
+ (js2-add-to-string c))))
+ (unless err
+ (while continue
+ (cond
+ ((js2-match-char ?g)
+ (push ?g flags))
+ ((js2-match-char ?i)
+ (push ?i flags))
+ ((js2-match-char ?m)
+ (push ?m flags))
+ (t
+ (setq continue nil))))
+ (if (js2-alpha-p (js2-peek-char))
+ (js2-report-scan-error "msg.invalid.re.flag" t
+ js2-ts-cursor 1))
+ (setq js2-ts-string (js2-collect-string js2-ts-string-buffer)
+ js2-ts-regexp-flags (js2-collect-string flags)
+ js2-token-end js2-ts-cursor)
+ ;; tell `parse-partial-sexp' to ignore this range of chars
+ (put-text-property js2-token-beg js2-token-end 'syntax-class '(2)))))
+
+(defun js2-get-first-xml-token ()
+ (setq js2-ts-xml-open-tags-count 0
+ js2-ts-is-xml-attribute nil
+ js2-ts-xml-is-tag-content nil)
+ (js2-unget-char)
+ (js2-get-next-xml-token))
+
+(defsubst js2-xml-discard-string ()
+ "Throw away the string in progress and flag an XML parse error."
+ (setq js2-ts-string-buffer nil
+ js2-ts-string nil)
+ (js2-report-scan-error "msg.XML.bad.form" t))
+
+(defun js2-get-next-xml-token ()
+ (setq js2-ts-string-buffer nil ; for recording the XML
+ js2-token-beg js2-ts-cursor)
+ (let (c result)
+ (setq result
+ (catch 'return
+ (while t
+ (setq c (js2-get-char))
+ (cond
+ ((= c js2-EOF_CHAR)
+ (throw 'return js2-ERROR))
+ (js2-ts-xml-is-tag-content
+ (case c
+ (?>
+ (js2-add-to-string c)
+ (setq js2-ts-xml-is-tag-content nil
+ js2-ts-is-xml-attribute nil))
+ (?/
+ (js2-add-to-string c)
+ (when (eq ?> (js2-peek-char))
+ (setq c (js2-get-char))
+ (js2-add-to-string c)
+ (setq js2-ts-xml-is-tag-content nil)
+ (decf js2-ts-xml-open-tags-count)))
+ (?{
+ (js2-unget-char)
+ (setq js2-ts-string (js2-get-string-from-buffer))
+ (throw 'return js2-XML))
+ ((?\' ?\")
+ (js2-add-to-string c)
+ (unless (js2-read-quoted-string c)
+ (throw 'return js2-ERROR)))
+ (?=
+ (js2-add-to-string c)
+ (setq js2-ts-is-xml-attribute t))
+ ((? ?\t ?\r ?\n)
+ (js2-add-to-string c))
+ (t
+ (js2-add-to-string c)
+ (setq js2-ts-is-xml-attribute nil)))
+ (when (and (not js2-ts-xml-is-tag-content)
+ (zerop js2-ts-xml-open-tags-count))
+ (setq js2-ts-string (js2-get-string-from-buffer))
+ (throw 'return js2-XMLEND)))
+ (t
+ ;; else not tag content
+ (case c
+ (?<
+ (js2-add-to-string c)
+ (setq c (js2-peek-char))
+ (case c
+ (?!
+ (setq c (js2-get-char)) ;; skip !
+ (js2-add-to-string c)
+ (setq c (js2-peek-char))
+ (case c
+ (?-
+ (setq c (js2-get-char)) ;; skip -
+ (js2-add-to-string c)
+ (if (eq c ?-)
+ (progn
+ (js2-add-to-string c)
+ (unless (js2-read-xml-comment)
+ (throw 'return js2-ERROR)))
+ (js2-xml-discard-string)
+ (throw 'return js2-ERROR)))
+ (?\[
+ (setq c (js2-get-char)) ;; skip [
+ (js2-add-to-string c)
+ (if (and (= (js2-get-char) ?C)
+ (= (js2-get-char) ?D)
+ (= (js2-get-char) ?A)
+ (= (js2-get-char) ?T)
+ (= (js2-get-char) ?A)
+ (= (js2-get-char) ?\[))
+ (progn
+ (js2-add-to-string ?C)
+ (js2-add-to-string ?D)
+ (js2-add-to-string ?A)
+ (js2-add-to-string ?T)
+ (js2-add-to-string ?A)
+ (js2-add-to-string ?\[)
+ (unless (js2-read-cdata)
+ (throw 'return js2-ERROR)))
+ (js2-xml-discard-string)
+ (throw 'return js2-ERROR)))
+ (t
+ (unless (js2-read-entity)
+ (throw 'return js2-ERROR)))))
+ (??
+ (setq c (js2-get-char)) ;; skip ?
+ (js2-add-to-string c)
+ (unless (js2-read-PI)
+ (throw 'return js2-ERROR)))
+ (?/
+ ;; end tag
+ (setq c (js2-get-char)) ;; skip /
+ (js2-add-to-string c)
+ (when (zerop js2-ts-xml-open-tags-count)
+ (js2-xml-discard-string)
+ (throw 'return js2-ERROR))
+ (setq js2-ts-xml-is-tag-content t)
+ (decf js2-ts-xml-open-tags-count))
+ (t
+ ;; start tag
+ (setq js2-ts-xml-is-tag-content t)
+ (incf js2-ts-xml-open-tags-count))))
+ (?{
+ (js2-unget-char)
+ (setq js2-ts-string (js2-get-string-from-buffer))
+ (throw 'return js2-XML))
+ (t
+ (js2-add-to-string c))))))))
+ (setq js2-token-end js2-ts-cursor)
+ result))
+
+(defun js2-read-quoted-string (quote)
+ (let (c)
+ (catch 'return
+ (while (/= (setq c (js2-get-char)) js2-EOF_CHAR)
+ (js2-add-to-string c)
+ (if (eq c quote)
+ (throw 'return t)))
+ (js2-xml-discard-string) ;; throw away string in progress
+ nil)))
+
+(defun js2-read-xml-comment ()
+ (let ((c (js2-get-char)))
+ (catch 'return
+ (while (/= c js2-EOF_CHAR)
+ (catch 'continue
+ (js2-add-to-string c)
+ (when (and (eq c ?-) (eq ?- (js2-peek-char)))
+ (setq c (js2-get-char))
+ (js2-add-to-string c)
+ (if (eq (js2-peek-char) ?>)
+ (progn
+ (setq c (js2-get-char)) ;; skip >
+ (js2-add-to-string c)
+ (throw 'return t))
+ (throw 'continue nil)))
+ (setq c (js2-get-char))))
+ (js2-xml-discard-string)
+ nil)))
+
+(defun js2-read-cdata ()
+ (let ((c (js2-get-char)))
+ (catch 'return
+ (while (/= c js2-EOF_CHAR)
+ (catch 'continue
+ (js2-add-to-string c)
+ (when (and (eq c ?\]) (eq (js2-peek-char) ?\]))
+ (setq c (js2-get-char))
+ (js2-add-to-string c)
+ (if (eq (js2-peek-char) ?>)
+ (progn
+ (setq c (js2-get-char)) ;; Skip >
+ (js2-add-to-string c)
+ (throw 'return t))
+ (throw 'continue nil)))
+ (setq c (js2-get-char))))
+ (js2-xml-discard-string)
+ nil)))
+
+(defun js2-read-entity ()
+ (let ((decl-tags 1)
+ c)
+ (catch 'return
+ (while (/= js2-EOF_CHAR (setq c (js2-get-char)))
+ (js2-add-to-string c)
+ (case c
+ (?<
+ (incf decl-tags))
+ (?>
+ (decf decl-tags)
+ (if (zerop decl-tags)
+ (throw 'return t)))))
+ (js2-xml-discard-string)
+ nil)))
+
+(defun js2-read-PI ()
+ "Scan an XML processing instruction."
+ (let (c)
+ (catch 'return
+ (while (/= js2-EOF_CHAR (setq c (js2-get-char)))
+ (js2-add-to-string c)
+ (when (and (eq c ??) (eq (js2-peek-char) ?>))
+ (setq c (js2-get-char)) ;; Skip >
+ (js2-add-to-string c)
+ (throw 'return t)))
+ (js2-xml-discard-string)
+ nil)))
+
+(defun js2-scanner-get-line ()
+ "Return the text of the current scan line."
+ (buffer-substring (point-at-bol) (point-at-eol)))
+
+;;; Highlighting
+
+(defsubst js2-set-face (beg end face &optional record)
+ "Fontify a region. If RECORD is non-nil, record for later."
+ (when (plusp js2-highlight-level)
+ (setq beg (min (point-max) beg)
+ beg (max (point-min) beg)
+ end (min (point-max) end)
+ end (max (point-min) end))
+ (if record
+ (push (list beg end face) js2-mode-fontifications)
+ (put-text-property beg end 'face face))))
+
+(defsubst js2-set-kid-face (pos kid len face)
+ "Set-face on a child node.
+POS is absolute buffer position of parent.
+KID is the child node.
+LEN is the length to fontify.
+FACE is the face to fontify with."
+ (js2-set-face (+ pos (js2-node-pos kid))
+ (+ pos (js2-node-pos kid) (js2-node-len kid))
+ face))
+
+(defsubst js2-fontify-kwd (start length)
+ (js2-set-face start (+ start length) 'font-lock-keyword-face))
+
+(defsubst js2-clear-face (beg end)
+ (remove-text-properties beg end '(face nil
+ help-echo nil
+ point-entered nil
+ c-in-sws nil)))
+
+(defsubst js2-record-text-property (beg end prop value)
+ "Record a text property to set when parsing finishes."
+ (push (list beg end prop value) js2-mode-deferred-properties))
+
+(defconst js2-ecma-global-props
+ (concat "^"
+ (regexp-opt
+ '("Infinity" "NaN" "undefined" "arguments") t)
+ "$")
+ "Value properties of the Ecma-262 Global Object.
+Shown at or above `js2-highlight-level' 2.")
+
+;; might want to add the name "arguments" to this list?
+(defconst js2-ecma-object-props
+ (concat "^"
+ (regexp-opt
+ '("prototype" "__proto__" "__parent__") t)
+ "$")
+ "Value properties of the Ecma-262 Object constructor.
+Shown at or above `js2-highlight-level' 2.")
+
+(defconst js2-ecma-global-funcs
+ (concat
+ "^"
+ (regexp-opt
+ '("decodeURI" "decodeURIComponent" "encodeURI" "encodeURIComponent"
+ "eval" "isFinite" "isNaN" "parseFloat" "parseInt") t)
+ "$")
+ "Function properties of the Ecma-262 Global object.
+Shown at or above `js2-highlight-level' 2.")
+
+(defconst js2-ecma-number-props
+ (concat "^"
+ (regexp-opt '("MAX_VALUE" "MIN_VALUE" "NaN"
+ "NEGATIVE_INFINITY"
+ "POSITIVE_INFINITY") t)
+ "$")
+ "Properties of the Ecma-262 Number constructor.
+Shown at or above `js2-highlight-level' 2.")
+
+(defconst js2-ecma-date-props "^\\(parse\\|UTC\\)$"
+ "Properties of the Ecma-262 Date constructor.
+Shown at or above `js2-highlight-level' 2.")
+
+(defconst js2-ecma-math-props
+ (concat "^"
+ (regexp-opt
+ '("E" "LN10" "LN2" "LOG2E" "LOG10E" "PI" "SQRT1_2" "SQRT2")
+ t)
+ "$")
+ "Properties of the Ecma-262 Math object.
+Shown at or above `js2-highlight-level' 2.")
+
+(defconst js2-ecma-math-funcs
+ (concat "^"
+ (regexp-opt
+ '("abs" "acos" "asin" "atan" "atan2" "ceil" "cos" "exp" "floor"
+ "log" "max" "min" "pow" "random" "round" "sin" "sqrt" "tan") t)
+ "$")
+ "Function properties of the Ecma-262 Math object.
+Shown at or above `js2-highlight-level' 2.")
+
+(defconst js2-ecma-function-props
+ (concat
+ "^"
+ (regexp-opt
+ '(;; properties of the Object prototype object
+ "hasOwnProperty" "isPrototypeOf" "propertyIsEnumerable"
+ "toLocaleString" "toString" "valueOf"
+ ;; properties of the Function prototype object
+ "apply" "call"
+ ;; properties of the Array prototype object
+ "concat" "join" "pop" "push" "reverse" "shift" "slice" "sort"
+ "splice" "unshift"
+ ;; properties of the String prototype object
+ "charAt" "charCodeAt" "fromCharCode" "indexOf" "lastIndexOf"
+ "localeCompare" "match" "replace" "search" "split" "substring"
+ "toLocaleLowerCase" "toLocaleUpperCase" "toLowerCase"
+ "toUpperCase"
+ ;; properties of the Number prototype object
+ "toExponential" "toFixed" "toPrecision"
+ ;; properties of the Date prototype object
+ "getDate" "getDay" "getFullYear" "getHours" "getMilliseconds"
+ "getMinutes" "getMonth" "getSeconds" "getTime"
+ "getTimezoneOffset" "getUTCDate" "getUTCDay" "getUTCFullYear"
+ "getUTCHours" "getUTCMilliseconds" "getUTCMinutes" "getUTCMonth"
+ "getUTCSeconds" "setDate" "setFullYear" "setHours"
+ "setMilliseconds" "setMinutes" "setMonth" "setSeconds" "setTime"
+ "setUTCDate" "setUTCFullYear" "setUTCHours" "setUTCMilliseconds"
+ "setUTCMinutes" "setUTCMonth" "setUTCSeconds" "toDateString"
+ "toLocaleDateString" "toLocaleString" "toLocaleTimeString"
+ "toTimeString" "toUTCString"
+ ;; properties of the RegExp prototype object
+ "exec" "test"
+ ;; SpiderMonkey/Rhino extensions, versions 1.5+
+ "toSource" "__defineGetter__" "__defineSetter__"
+ "__lookupGetter__" "__lookupSetter__" "__noSuchMethod__"
+ "every" "filter" "forEach" "lastIndexOf" "map" "some")
+ t)
+ "$")
+ "Built-in functions defined by Ecma-262 and SpiderMonkey extensions.
+Shown at or above `js2-highlight-level' 3.")
+
+(defsubst js2-parse-highlight-prop-get (parent target prop call-p)
+ (let ((target-name (and target
+ (js2-name-node-p target)
+ (js2-name-node-name target)))
+ (prop-name (if prop (js2-name-node-name prop)))
+ (level1 (>= js2-highlight-level 1))
+ (level2 (>= js2-highlight-level 2))
+ (level3 (>= js2-highlight-level 3))
+ pos
+ face)
+ (when level2
+ (if call-p
+ (cond
+ ((and target prop)
+ (cond
+ ((and level3 (string-match js2-ecma-function-props prop-name))
+ (setq face 'font-lock-builtin-face))
+ ((and target-name prop)
+ (cond
+ ((string= target-name "Date")
+ (if (string-match js2-ecma-date-props prop-name)
+ (setq face 'font-lock-builtin-face)))
+ ((string= target-name "Math")
+ (if (string-match js2-ecma-math-funcs prop-name)
+ (setq face 'font-lock-builtin-face)))))))
+ (prop
+ (if (string-match js2-ecma-global-funcs prop-name)
+ (setq face 'font-lock-builtin-face))))
+ (cond
+ ((and target prop)
+ (cond
+ ((string= target-name "Number")
+ (if (string-match js2-ecma-number-props prop-name)
+ (setq face 'font-lock-constant-face)))
+ ((string= target-name "Math")
+ (if (string-match js2-ecma-math-props prop-name)
+ (setq face 'font-lock-constant-face)))))
+ (prop
+ (if (string-match js2-ecma-object-props prop-name)
+ (setq face 'font-lock-constant-face)))))
+ (when face
+ (js2-set-face (setq pos (+ (js2-node-pos parent) ; absolute
+ (js2-node-pos prop))) ; relative
+ (+ pos (js2-node-len prop))
+ face)))))
+
+(defun js2-parse-highlight-member-expr-node (node)
+ "Perform syntax highlighting of EcmaScript built-in properties.
+The variable `js2-highlight-level' governs this highighting."
+ (let (face target prop name pos end parent call-p callee)
+ (cond
+ ;; case 1: simple name, e.g. foo
+ ((js2-name-node-p node)
+ (setq name (js2-name-node-name node))
+ ;; possible for name to be nil in rare cases - saw it when
+ ;; running js2-mode on an elisp buffer. Might as well try to
+ ;; make it so js2-mode never barfs.
+ (when name
+ (setq face (if (string-match js2-ecma-global-props name)
+ 'font-lock-constant-face))
+ (when face
+ (setq pos (js2-node-pos node)
+ end (+ pos (js2-node-len node)))
+ (js2-set-face pos end face))))
+ ;; case 2: property access or function call
+ ((or (js2-prop-get-node-p node)
+ ;; highlight function call if expr is a prop-get node
+ ;; or a plain name (i.e. unqualified function call)
+ (and (setq call-p (js2-call-node-p node))
+ (setq callee (js2-call-node-target node)) ; separate setq!
+ (or (js2-prop-get-node-p callee)
+ (js2-name-node-p callee))))
+ (setq parent node
+ node (if call-p callee node))
+ (if (and call-p (js2-name-node-p callee))
+ (setq prop callee)
+ (setq target (js2-prop-get-node-left node)
+ prop (js2-prop-get-node-right node)))
+ (cond
+ ((js2-name-node-p target)
+ (if (js2-name-node-p prop)
+ ;; case 2a: simple target, simple prop name, e.g. foo.bar
+ (js2-parse-highlight-prop-get parent target prop call-p)
+ ;; case 2b: simple target, complex name, e.g. foo.x[y]
+ (js2-parse-highlight-prop-get parent target nil call-p)))
+ ((js2-name-node-p prop)
+ ;; case 2c: complex target, simple name, e.g. x[y].bar
+ (js2-parse-highlight-prop-get parent target prop call-p)))))))
+
+(defun js2-parse-highlight-member-expr-fn-name (expr)
+ "Highlight the `baz' in function foo.bar.baz(args) {...}.
+This is experimental Rhino syntax. EXPR is the foo.bar.baz member expr.
+We currently only handle the case where the last component is a prop-get
+of a simple name. Called before EXPR has a parent node."
+ (let (pos
+ (name (and (js2-prop-get-node-p expr)
+ (js2-prop-get-node-right expr))))
+ (when (js2-name-node-p name)
+ (js2-set-face (setq pos (+ (js2-node-pos expr) ; parent is absolute
+ (js2-node-pos name)))
+ (+ pos (js2-node-len name))
+ 'font-lock-function-name-face
+ 'record))))
+
+;; source: http://jsdoc.sourceforge.net/
+;; Note - this syntax is for Google's enhanced jsdoc parser that
+;; allows type specifications, and needs work before entering the wild.
+
+(defconst js2-jsdoc-param-tag-regexp
+ (concat "^\\s-*\\*+\\s-*\\(@"
+ "\\(?:param\\|argument\\)"
+ "\\)"
+ "\\s-*\\({[^}]+}\\)?" ; optional type
+ "\\s-*\\([a-zA-Z0-9_$]+\\)?" ; name
+ "\\>")
+ "Matches jsdoc tags with optional type and optional param name.")
+
+(defconst js2-jsdoc-typed-tag-regexp
+ (concat "^\\s-*\\*+\\s-*\\(@\\(?:"
+ (regexp-opt
+ '("enum"
+ "extends"
+ "field"
+ "id"
+ "implements"
+ "lends"
+ "mods"
+ "requires"
+ "return"
+ "returns"
+ "throw"
+ "throws"))
+ "\\)\\)\\s-*\\({[^}]+}\\)?")
+ "Matches jsdoc tags with optional type.")
+
+(defconst js2-jsdoc-arg-tag-regexp
+ (concat "^\\s-*\\*+\\s-*\\(@\\(?:"
+ (regexp-opt
+ '("alias"
+ "augments"
+ "borrows"
+ "bug"
+ "base"
+ "config"
+ "default"
+ "define"
+ "exception"
+ "function"
+ "member"
+ "memberOf"
+ "name"
+ "namespace"
+ "property"
+ "since"
+ "suppress"
+ "this"
+ "throws"
+ "type"
+ "version"))
+ "\\)\\)\\s-+\\([^ \t]+\\)")
+ "Matches jsdoc tags with a single argument.")
+
+(defconst js2-jsdoc-empty-tag-regexp
+ (concat "^\\s-*\\*+\\s-*\\(@\\(?:"
+ (regexp-opt
+ '("addon"
+ "author"
+ "class"
+ "const"
+ "constant"
+ "constructor"
+ "constructs"
+ "deprecated"
+ "desc"
+ "description"
+ "event"
+ "example"
+ "exec"
+ "export"
+ "fileoverview"
+ "final"
+ "function"
+ "hidden"
+ "ignore"
+ "implicitCast"
+ "inheritDoc"
+ "inner"
+ "interface"
+ "license"
+ "noalias"
+ "noshadow"
+ "notypecheck"
+ "override"
+ "owner"
+ "preserve"
+ "preserveTry"
+ "private"
+ "protected"
+ "public"
+ "static"
+ "supported"
+ ))
+ "\\)\\)\\s-*")
+ "Matches empty jsdoc tags.")
+
+(defconst js2-jsdoc-link-tag-regexp
+ "{\\(@\\(?:link\\|code\\)\\)\\s-+\\([^#}\n]+\\)\\(#.+\\)?}"
+ "Matches a jsdoc link or code tag.")
+
+(defconst js2-jsdoc-see-tag-regexp
+ "^\\s-*\\*+\\s-*\\(@see\\)\\s-+\\([^#}\n]+\\)\\(#.+\\)?"
+ "Matches a jsdoc @see tag.")
+
+(defconst js2-jsdoc-html-tag-regexp
+ "\\(</?\\)\\([a-zA-Z]+\\)\\s-*\\(/?>\\)"
+ "Matches a simple (no attributes) html start- or end-tag.")
+
+(defsubst js2-jsdoc-highlight-helper ()
+ (js2-set-face (match-beginning 1)
+ (match-end 1)
+ 'js2-jsdoc-tag)
+ (if (match-beginning 2)
+ (if (save-excursion
+ (goto-char (match-beginning 2))
+ (= (char-after) ?{))
+ (js2-set-face (1+ (match-beginning 2))
+ (1- (match-end 2))
+ 'js2-jsdoc-type)
+ (js2-set-face (match-beginning 2)
+ (match-end 2)
+ 'js2-jsdoc-value)))
+ (if (match-beginning 3)
+ (js2-set-face (match-beginning 3)
+ (match-end 3)
+ 'js2-jsdoc-value)))
+
+(defun js2-highlight-jsdoc (ast)
+ "Highlight doc comment tags."
+ (let ((comments (js2-ast-root-comments ast))
+ beg end)
+ (save-excursion
+ (dolist (node comments)
+ (when (eq (js2-comment-node-format node) 'jsdoc)
+ (setq beg (js2-node-abs-pos node)
+ end (+ beg (js2-node-len node)))
+ (save-restriction
+ (narrow-to-region beg end)
+ (dolist (re (list js2-jsdoc-param-tag-regexp
+ js2-jsdoc-typed-tag-regexp
+ js2-jsdoc-arg-tag-regexp
+ js2-jsdoc-link-tag-regexp
+ js2-jsdoc-see-tag-regexp
+ js2-jsdoc-empty-tag-regexp))
+ (goto-char beg)
+ (while (re-search-forward re nil t)
+ (js2-jsdoc-highlight-helper)))
+ ;; simple highlighting for html tags
+ (goto-char beg)
+ (while (re-search-forward js2-jsdoc-html-tag-regexp nil t)
+ (js2-set-face (match-beginning 1)
+ (match-end 1)
+ 'js2-jsdoc-html-tag-delimiter)
+ (js2-set-face (match-beginning 2)
+ (match-end 2)
+ 'js2-jsdoc-html-tag-name)
+ (js2-set-face (match-beginning 3)
+ (match-end 3)
+ 'js2-jsdoc-html-tag-delimiter))))))))
+
+(defun js2-highlight-assign-targets (node left right)
+ "Highlight function properties and external variables."
+ (let (leftpos end name)
+ ;; highlight vars and props assigned function values
+ (when (js2-function-node-p right)
+ (cond
+ ;; var foo = function() {...}
+ ((js2-name-node-p left)
+ (setq name left))
+ ;; foo.bar.baz = function() {...}
+ ((and (js2-prop-get-node-p left)
+ (js2-name-node-p (js2-prop-get-node-right left)))
+ (setq name (js2-prop-get-node-right left))))
+ (when name
+ (js2-set-face (setq leftpos (js2-node-abs-pos name))
+ (+ leftpos (js2-node-len name))
+ 'font-lock-function-name-face
+ 'record)))
+ ;; save variable assignments so we can check for undeclared later
+ ;; (can't do it here since var decls can come at end of script)
+ (when (and js2-highlight-external-variables
+ (setq name (js2-member-expr-leftmost-name left)))
+ (push (list name js2-current-scope
+ (setq leftpos (js2-node-abs-pos name))
+ (setq end (+ leftpos (js2-node-len name))))
+ js2-recorded-assignments))))
+
+(defun js2-highlight-undeclared-vars ()
+ "After entire parse is finished, look for undeclared variable assignments.
+We have to wait until entire buffer is parsed, since JavaScript permits var
+decls to occur after they're used.
+
+If any undeclared var name is in `js2-externs' or `js2-additional-externs',
+it is considered declared."
+ (let (name)
+ (dolist (entry js2-recorded-assignments)
+ (destructuring-bind (name-node scope pos end) entry
+ (setq name (js2-name-node-name name-node))
+ (unless (or (member name js2-global-externs)
+ (member name js2-default-externs)
+ (member name js2-additional-externs)
+ (js2-get-defining-scope scope name))
+ (js2-set-face pos end 'js2-external-variable 'record)
+ (js2-record-text-property pos end 'help-echo "Undeclared variable")
+ (js2-record-text-property pos end 'point-entered #'js2-echo-help))))
+ (setq js2-recorded-assignments nil)))
+
+;;; IMenu support
+
+;; We currently only support imenu, but eventually should support speedbar and
+;; possibly other browsing mechanisms.
+
+;; The basic strategy is to identify function assignment targets of the form
+;; `foo.bar.baz', convert them to (list foo bar baz <position>), and push the
+;; list into `js2-imenu-recorder'. The lists are merged into a trie-like tree
+;; for imenu after parsing is finished.
+
+;; A `foo.bar.baz' assignment target may be expressed in many ways in
+;; JavaScript, and the general problem is undecidable. However, several forms
+;; are readily recognizable at parse-time; the forms we attempt to recognize
+;; include:
+
+;; function foo() -- function declaration
+;; foo = function() -- function expression assigned to variable
+;; foo.bar.baz = function() -- function expr assigned to nested property-get
+;; foo = {bar: function()} -- fun prop in object literal assigned to var
+;; foo = {bar: {baz: function()}} -- inside nested object literal
+;; foo.bar = {baz: function()}} -- obj lit assigned to nested prop get
+;; a.b = {c: {d: function()}} -- nested obj lit assigned to nested prop get
+;; foo = {get bar() {...}} -- getter/setter in obj literal
+;; function foo() {function bar() {...}} -- nested function
+;; foo['a'] = function() -- fun expr assigned to deterministic element-get
+
+;; This list boils down to a few forms that can be combined recursively.
+;; Top-level named function declarations include both the left-hand (name)
+;; and the right-hand (function value) expressions needed to produce an imenu
+;; entry. The other "right-hand" forms we need to look for are:
+;; - functions declared as props/getters/setters in object literals
+;; - nested named function declarations
+;; The "left-hand" expressions that functions can be assigned to include:
+;; - local/global variables
+;; - nested property-get expressions like a.b.c.d
+;; - element gets like foo[10] or foo['bar'] where the index
+;; expression can be trivially converted to a property name. They
+;; effectively then become property gets.
+
+;; All the different definition types are canonicalized into the form
+;; foo.bar.baz = position-of-function-keyword
+
+;; We need to build a trie-like structure for imenu. As an example,
+;; consider the following JavaScript code:
+
+;; a = function() {...} // function at position 5
+;; b = function() {...} // function at position 25
+;; foo = function() {...} // function at position 100
+;; foo.bar = function() {...} // function at position 200
+;; foo.bar.baz = function() {...} // function at position 300
+;; foo.bar.zab = function() {...} // function at position 400
+
+;; During parsing we accumulate an entry for each definition in
+;; the variable `js2-imenu-recorder', like so:
+
+;; '((a 5)
+;; (b 25)
+;; (foo 100)
+;; (foo bar 200)
+;; (foo bar baz 300)
+;; (foo bar zab 400))
+
+;; After parsing these entries are merged into this alist-trie:
+
+;; '((a . 1)
+;; (b . 2)
+;; (foo (<definition> . 3)
+;; (bar (<definition> . 6)
+;; (baz . 100)
+;; (zab . 200))))
+
+;; Note the wacky need for a <definition> name. The token can be anything
+;; that isn't a valid JavaScript identifier, because you might make foo
+;; a function and then start setting properties on it that are also functions.
+
+(defsubst js2-prop-node-name (node)
+ "Return the name of a node that may be a property-get/property-name.
+If NODE is not a valid name-node, string-node or integral number-node,
+returns nil. Otherwise returns the string name/value of the node."
+ (cond
+ ((js2-name-node-p node)
+ (js2-name-node-name node))
+ ((js2-string-node-p node)
+ (js2-string-node-value node))
+ ((and (js2-number-node-p node)
+ (string-match "^[0-9]+$" (js2-number-node-value node)))
+ (js2-number-node-value node))
+ ((js2-this-node-p node)
+ "this")))
+
+(defsubst js2-node-qname-component (node)
+ "Test function: return the name of this node, if it contributes to a qname.
+Returns nil if the node doesn't contribute."
+ (copy-sequence
+ (or (js2-prop-node-name node)
+ (if (and (js2-function-node-p node)
+ (js2-function-node-name node))
+ (js2-name-node-name (js2-function-node-name node))))))
+
+(defsubst js2-record-function-qname (fn-node qname)
+ "Associate FN-NODE with its QNAME for later lookup.
+This is used in postprocessing the chain list. When we find a chain
+whose first element is a js2-THIS keyword node, we look up the parent
+function and see (using this map) whether it is the tail of a chain.
+If so, we replace the this-node with a copy of the parent's qname."
+ (unless js2-imenu-function-map
+ (setq js2-imenu-function-map (make-hash-table :test 'eq)))
+ (puthash fn-node qname js2-imenu-function-map))
+
+(defun js2-record-imenu-functions (node &optional var)
+ "Record function definitions for imenu.
+NODE is a function node or an object literal.
+VAR, if non-nil, is the expression that NODE is being assigned to."
+ (when js2-parse-ide-mode
+ (let ((fun-p (js2-function-node-p node))
+ qname left fname-node pos)
+ (cond
+ ;; non-anonymous function declaration?
+ ((and fun-p
+ (not var)
+ (setq fname-node (js2-function-node-name node)))
+ (push (setq qname (list fname-node (js2-node-pos node)))
+ js2-imenu-recorder)
+ (js2-record-function-qname node qname))
+ ;; for remaining forms, compute left-side tree branch first
+ ((and var (setq qname (js2-compute-nested-prop-get var)))
+ (cond
+ ;; foo.bar.baz = function
+ (fun-p
+ (push (nconc qname (list (js2-node-pos node)))
+ js2-imenu-recorder)
+ (js2-record-function-qname node qname))
+ ;; foo.bar.baz = object-literal
+ ;; look for nested functions: {a: {b: function() {...} }}
+ ((js2-object-node-p node)
+ (js2-record-object-literal node qname))))))))
+
+(defun js2-compute-nested-prop-get (node)
+ "If NODE is of form foo.bar.baz, return component nodes as a list.
+Otherwise returns nil. Element-gets can be treated as property-gets
+if the index expression is a name, a string, or a positive integer."
+ (let (left right head)
+ (cond
+ ((or (js2-name-node-p node)
+ (js2-this-node-p node))
+ (list node))
+ ;; foo.bar.baz is parenthesized as (foo.bar).baz => right operand is a leaf
+ ((js2-prop-get-node-p node) ; includes elem-get nodes
+ (setq left (js2-prop-get-node-left node)
+ right (js2-prop-get-node-right node))
+ (if (and (or (js2-prop-get-node-p left) ; left == foo.bar
+ (js2-name-node-p left)
+ (js2-this-node-p left)) ; or left == foo
+ (or (js2-name-node-p right) ; .bar
+ (js2-string-node-p right) ; ['bar']
+ (and (js2-number-node-p right) ; [10]
+ (string-match "^[0-9]+$"
+ (js2-number-node-value right)))))
+ (if (setq head (js2-compute-nested-prop-get left))
+ (nconc head (list right))))))))
+
+(defun js2-record-object-literal (node qname)
+ "Recursively process an object literal looking for functions.
+NODE is an object literal that is the right-hand child of an assignment
+expression. QNAME is a list of nodes representing the assignment target,
+e.g. for foo.bar.baz = {...}, QNAME is (foo-node bar-node baz-node).
+We do a depth-first traversal of NODE. Any functions we find are prefixed
+with QNAME plus the property name of the function and appended to the
+variable `js2-imenu-recorder'."
+ ;; Elements are relative to parent position, which is still absolute,
+ ;; since the parser passes the assignment target and value expressions
+ ;; to us before they are added as children of the assignment node.
+ (let ((pos (js2-node-pos node))
+ left right)
+ (dolist (e (js2-object-node-elems node)) ; e is a `js2-object-prop-node'
+ (setq left (js2-infix-node-left e))
+ (cond
+ ;; foo: function() {...}
+ ((js2-function-node-p (setq right (js2-infix-node-right e)))
+ (when (js2-prop-node-name left)
+ ;; As a policy decision, we record the position of the property,
+ ;; not the position of the `function' keyword, since the property
+ ;; is effectively the name of the function.
+ (push (append qname (list left) (list (+ pos (js2-node-pos e))))
+ js2-imenu-recorder)
+ (js2-record-function-qname right qname)))
+ ;; foo: {object-literal} -- add foo to qname and recurse
+ ((js2-object-node-p right)
+ (js2-record-object-literal right
+ (append qname (list (js2-infix-node-left e)))))))))
+
+(defsubst js2-node-top-level-decl-p (node)
+ "Return t if NODE's name is defined in the top-level scope.
+Also returns t if NODE's name is not defined in any scope, since it implies
+that it's an external variable, which must also be in the top-level scope."
+ (let* ((name (js2-prop-node-name node))
+ (this-scope (js2-node-get-enclosing-scope node))
+ defining-scope)
+ (cond
+ ((js2-this-node-p node)
+ nil)
+ ((null this-scope)
+ t)
+ ((setq defining-scope (js2-get-defining-scope this-scope name))
+ (js2-ast-root-p defining-scope))
+ (t t))))
+
+(defun js2-browse-postprocess-chains (chains)
+ "Modify function-declaration name chains after parsing finishes.
+Some of the information is only available after the parse tree is complete.
+For instance, following a 'this' reference requires a parent function node."
+ (let (result head fn parent-chain p elem)
+ (dolist (chain chains)
+ ;; examine the head of each node to get its defining scope
+ (setq head (car chain))
+ (cond
+ ;; if top-level/external, keep as-is
+ ((js2-node-top-level-decl-p head)
+ (push chain result))
+ ;; check for a this-reference
+ ((eq (js2-node-type head) js2-THIS)
+ (setq fn (js2-node-parent-script-or-fn head))
+ ;; if there is no parent function, or if the parent function
+ ;; is nested, discard the head node and keep the rest of the chain.
+ (if (or (null fn) (js2-nested-function-p fn))
+ (push (cdr chain) result)
+ ;; else look up parent in function-map. If not found, discard chain.
+ (when (setq parent-chain (and js2-imenu-function-map
+ (gethash fn js2-imenu-function-map)))
+ ;; else discard head node and prefix parent fn qname, which is
+ ;; the parent-chain sans tail, to this chain.
+ (push (append (butlast parent-chain) (cdr chain)) result))))))
+ ;; finally replace each node in each chain with its name.
+ (dolist (chain result)
+ (setq p chain)
+ (while p
+ (if (js2-node-p (setq elem (car p)))
+ (setcar p (js2-node-qname-component elem)))
+ (setq p (cdr p))))
+ result))
+
+;; Merge name chains into a trie-like tree structure of nested lists.
+;; To simplify construction of the trie, we first build it out using the rule
+;; that the trie consists of lists of pairs. Each pair is a 2-element array:
+;; [key, num-or-list]. The second element can be a number; if so, this key
+;; is a leaf-node with only one value. (I.e. there is only one declaration
+;; associated with the key at this level.) Otherwise the second element is
+;; a list of pairs, with the rule applied recursively. This symmetry permits
+;; a simple recursive formulation.
+;;
+;; js2-mode is building the data structure for imenu. The imenu documentation
+;; claims that it's the structure above, but in practice it wants the children
+;; at the same list level as the key for that level, which is how I've drawn
+;; the "Expected final result" above. We'll postprocess the trie to remove the
+;; list wrapper around the children at each level.
+;;
+;; A completed nested imenu-alist entry looks like this:
+;; '(("foo"
+;; ("<definition>" . 7)
+;; ("bar"
+;; ("a" . 40)
+;; ("b" . 60))))
+;;
+;; In particular, the documentation for `imenu--index-alist' says that
+;; a nested sub-alist element looks like (INDEX-NAME SUB-ALIST).
+;; The sub-alist entries immediately follow INDEX-NAME, the head of the list.
+
+(defsubst js2-treeify (lst)
+ "Convert (a b c d) to (a ((b ((c d)))))"
+ (if (null (cddr lst)) ; list length <= 2
+ lst
+ (list (car lst) (list (js2-treeify (cdr lst))))))
+
+(defun js2-build-alist-trie (chains trie)
+ "Merge declaration name chains into a trie-like alist structure for imenu.
+CHAINS is the qname chain list produced during parsing. TRIE is a
+list of elements built up so far."
+ (let (head tail pos branch kids)
+ (dolist (chain chains)
+ (setq head (car chain)
+ tail (cdr chain)
+ pos (if (numberp (car tail)) (car tail))
+ branch (js2-find-if (lambda (n)
+ (string= (car n) head))
+ trie)
+ kids (second branch))
+ (cond
+ ;; case 1: this key isn't in the trie yet
+ ((null branch)
+ (if trie
+ (setcdr (last trie) (list (js2-treeify chain)))
+ (setq trie (list (js2-treeify chain)))))
+ ;; case 2: key is present with a single number entry: replace w/ list
+ ;; ("a1" 10) + ("a1" 20) => ("a1" (("<definition>" 10)
+ ;; ("<definition>" 20)))
+ ((numberp kids)
+ (setcar (cdr branch)
+ (list (list "<definition-1>" kids)
+ (if pos
+ (list "<definition-2>" pos)
+ (js2-treeify tail)))))
+ ;; case 3: key is there (with kids), and we're a number entry
+ (pos
+ (setcdr (last kids)
+ (list
+ (list (format "<definition-%d>"
+ (1+ (loop for kid in kids
+ count (eq ?< (aref (car kid) 0)))))
+ pos))))
+
+ ;; case 4: key is there with kids, need to merge in our chain
+ (t
+ (js2-build-alist-trie (list tail) kids))))
+ trie))
+
+(defun js2-flatten-trie (trie)
+ "Convert TRIE to imenu-format.
+Recurses through nodes, and for each one whose second element is a list,
+appends the list's flattened elements to the current element. Also
+changes the tails into conses. For instance, this pre-flattened trie
+
+'(a ((b 20)
+ (c ((d 30)
+ (e 40)))))
+
+becomes
+
+'(a (b . 20)
+ (c (d . 30)
+ (e . 40)))
+
+Note that the root of the trie has no key, just a list of chains.
+This is also true for the value of any key with multiple children,
+e.g. key 'c' in the example above."
+ (cond
+ ((listp (car trie))
+ (mapcar #'js2-flatten-trie trie))
+ (t
+ (if (numberp (second trie))
+ (cons (car trie) (second trie))
+ ;; else pop list and append its kids
+ (apply #'append (list (car trie)) (js2-flatten-trie (cdr trie)))))))
+
+(defun js2-build-imenu-index ()
+ "Turn `js2-imenu-recorder' into an imenu data structure."
+ (unless (eq js2-imenu-recorder 'empty)
+ (let* ((chains (js2-browse-postprocess-chains js2-imenu-recorder))
+ (result (js2-build-alist-trie chains nil)))
+ (js2-flatten-trie result))))
+
+(defun js2-test-print-chains (chains)
+ "Print a list of qname chains.
+Each element of CHAINS is a list of the form (NODE [NODE *] pos);
+i.e. one or more nodes, and an integer position as the list tail."
+ (mapconcat (lambda (chain)
+ (concat "("
+ (mapconcat (lambda (elem)
+ (if (js2-node-p elem)
+ (or (js2-node-qname-component elem)
+ "nil")
+ (number-to-string elem)))
+ chain
+ " ")
+ ")"))
+ chains
+ "\n"))
+
+;;; Parser
+
+(defconst js2-version "1.8.0"
+ "Version of JavaScript supported, plus minor js2 version.")
+
+(defmacro js2-record-face (face)
+ "Record a style run of FACE for the current token."
+ `(js2-set-face js2-token-beg js2-token-end ,face 'record))
+
+(defsubst js2-node-end (n)
+ "Computes the absolute end of node N.
+Use with caution! Assumes `js2-node-pos' is -absolute-, which
+is only true until the node is added to its parent; i.e., while parsing."
+ (+ (js2-node-pos n)
+ (js2-node-len n)))
+
+(defsubst js2-record-comment ()
+ "Record a comment in `js2-scanned-comments'."
+ (push (make-js2-comment-node :len (- js2-token-end js2-token-beg)
+ :format js2-ts-comment-type)
+ js2-scanned-comments)
+ (when js2-parse-ide-mode
+ (js2-record-face (if (eq js2-ts-comment-type 'jsdoc)
+ 'font-lock-doc-face
+ 'font-lock-comment-face))
+ (when (memq js2-ts-comment-type '(html preprocessor))
+ ;; Tell cc-engine the bounds of the comment.
+ (put-text-property js2-token-beg (1- js2-token-end) 'c-in-sws t))))
+
+;; This function is called depressingly often, so it should be fast.
+;; Most of the time it's looking at the same token it peeked before.
+(defsubst js2-peek-token ()
+ "Returns the next token without consuming it.
+If previous token was consumed, calls scanner to get new token.
+If previous token was -not- consumed, returns it (idempotent).
+
+This function will not return a newline (js2-EOL) - instead, it
+gobbles newlines until it finds a non-newline token, and flags
+that token as appearing just after a newline.
+
+This function will also not return a js2-COMMENT. Instead, it
+records comments found in `js2-scanned-comments'. If the token
+returned by this function immediately follows a jsdoc comment,
+the token is flagged as such.
+
+Note that this function always returned the un-flagged token!
+The flags, if any, are saved in `js2-current-flagged-token'."
+ (if (/= js2-current-flagged-token js2-EOF) ; last token not consumed
+ js2-current-token ; most common case - return already-peeked token
+ (let ((tt (js2-get-token)) ; call scanner
+ saw-eol
+ face)
+ ;; process comments and whitespace
+ (while (or (= tt js2-EOL)
+ (= tt js2-COMMENT))
+ (if (= tt js2-EOL)
+ (setq saw-eol t)
+ (setq saw-eol nil)
+ (if js2-record-comments
+ (js2-record-comment)))
+ (setq tt (js2-get-token))) ; call scanner
+ (setq js2-current-token tt
+ js2-current-flagged-token (if saw-eol
+ (logior tt js2-ti-after-eol)
+ tt))
+ ;; perform lexical fontification as soon as token is scanned
+ (when js2-parse-ide-mode
+ (cond
+ ((minusp tt)
+ (js2-record-face 'js2-error))
+ ((setq face (aref js2-kwd-tokens tt))
+ (js2-record-face face))
+ ((and (= tt js2-NAME)
+ (equal js2-ts-string "undefined"))
+ (js2-record-face 'font-lock-constant-face))))
+ tt))) ; return unflagged token
+
+(defsubst js2-peek-flagged-token ()
+ "Returns the current token along with any flags set for it."
+ (js2-peek-token)
+ js2-current-flagged-token)
+
+(defsubst js2-consume-token ()
+ (setq js2-current-flagged-token js2-EOF))
+
+(defsubst js2-next-token ()
+ (prog1
+ (js2-peek-token)
+ (js2-consume-token)))
+
+(defsubst js2-next-flagged-token ()
+ (js2-peek-token)
+ (prog1 js2-current-flagged-token
+ (js2-consume-token)))
+
+(defsubst js2-match-token (match)
+ "Consume and return t if next token matches MATCH, a bytecode.
+Returns nil and consumes nothing if MATCH is not the next token."
+ (if (/= (js2-peek-token) match)
+ nil
+ (js2-consume-token)
+ t))
+
+(defsubst js2-valid-prop-name-token (tt)
+ (or (= tt js2-NAME)
+ (and js2-allow-keywords-as-property-names
+ (plusp tt)
+ (aref js2-kwd-tokens tt))))
+
+(defsubst js2-match-prop-name ()
+ "Consume token and return t if next token is a valid property name.
+It's valid if it's a js2-NAME, or `js2-allow-keywords-as-property-names'
+is non-nil and it's a keyword token."
+ (if (js2-valid-prop-name-token (js2-peek-token))
+ (progn
+ (js2-consume-token)
+ t)
+ nil))
+
+(defsubst js2-must-match-prop-name (msg-id &optional pos len)
+ (if (js2-match-prop-name)
+ t
+ (js2-report-error msg-id nil pos len)
+ nil))
+
+(defsubst js2-peek-token-or-eol ()
+ "Return js2-EOL if the current token immediately follows a newline.
+Else returns the current token. Used in situations where we don't
+consider certain token types valid if they are preceded by a newline.
+One example is the postfix ++ or -- operator, which has to be on the
+same line as its operand."
+ (let ((tt (js2-peek-token)))
+ ;; Check for last peeked token flags
+ (if (js2-flag-set-p js2-current-flagged-token js2-ti-after-eol)
+ js2-EOL
+ tt)))
+
+(defsubst js2-set-check-for-label ()
+ (assert (= (logand js2-current-flagged-token js2-clear-ti-mask) js2-NAME))
+ (js2-set-flag js2-current-flagged-token js2-ti-check-label))
+
+(defsubst js2-must-match (token msg-id &optional pos len)
+ "Match next token to token code TOKEN, or record a syntax error.
+MSG-ID is the error message to report if the match fails.
+Returns t on match, nil if no match."
+ (if (js2-match-token token)
+ t
+ (js2-report-error msg-id nil pos len)
+ nil))
+
+(defsubst js2-inside-function ()
+ (plusp js2-nesting-of-function))
+
+(defsubst js2-set-requires-activation ()
+ (if (js2-function-node-p js2-current-script-or-fn)
+ (setf (js2-function-node-needs-activation js2-current-script-or-fn) t)))
+
+(defsubst js2-check-activation-name (name token)
+ (when (js2-inside-function)
+ ;; skip language-version 1.2 check from Rhino
+ (if (or (string= "arguments" name)
+ (and js2-compiler-activation-names ; only used in codegen
+ (gethash name js2-compiler-activation-names)))
+ (js2-set-requires-activation))))
+
+(defsubst js2-set-is-generator ()
+ (if (js2-function-node-p js2-current-script-or-fn)
+ (setf (js2-function-node-is-generator js2-current-script-or-fn) t)))
+
+(defsubst js2-must-have-xml ()
+ (unless js2-compiler-xml-available
+ (js2-report-error "msg.XML.not.available")))
+
+(defsubst js2-push-scope (scope)
+ "Push SCOPE, a `js2-scope', onto the lexical scope chain."
+ (assert (js2-scope-p scope))
+ (assert (null (js2-scope-parent-scope scope)))
+ (assert (not (eq js2-current-scope scope)))
+ (setf (js2-scope-parent-scope scope) js2-current-scope
+ js2-current-scope scope))
+
+(defsubst js2-pop-scope ()
+ (setq js2-current-scope
+ (js2-scope-parent-scope js2-current-scope)))
+
+(defsubst js2-enter-loop (loop-node)
+ (push loop-node js2-loop-set)
+ (push loop-node js2-loop-and-switch-set)
+ (js2-push-scope loop-node)
+ ;; Tell the current labeled statement (if any) its statement,
+ ;; and set the jump target of the first label to the loop.
+ ;; These are used in `js2-parse-continue' to verify that the
+ ;; continue target is an actual labeled loop. (And for codegen.)
+ (when js2-labeled-stmt
+ (setf (js2-labeled-stmt-node-stmt js2-labeled-stmt) loop-node
+ (js2-label-node-loop (car (js2-labeled-stmt-node-labels
+ js2-labeled-stmt))) loop-node)))
+
+(defsubst js2-exit-loop ()
+ (pop js2-loop-set)
+ (pop js2-loop-and-switch-set)
+ (js2-pop-scope))
+
+(defsubst js2-enter-switch (switch-node)
+ (push switch-node js2-loop-and-switch-set))
+
+(defsubst js2-exit-switch ()
+ (pop js2-loop-and-switch-set))
+
+(defun js2-parse (&optional buf cb)
+ "Tells the js2 parser to parse a region of JavaScript.
+
+BUF is a buffer or buffer name containing the code to parse.
+Call `narrow-to-region' first to parse only part of the buffer.
+
+The returned AST root node is given some additional properties:
+ `node-count' - total number of nodes in the AST
+ `buffer' - BUF. The buffer it refers to may change or be killed,
+ so the value is not necessarily reliable.
+
+An optional callback CB can be specified to report parsing
+progress. If `(functionp CB)' returns t, it will be called with
+the current line number once before parsing begins, then again
+each time the lexer reaches a new line number.
+
+CB can also be a list of the form `(symbol cb ...)' to specify
+multiple callbacks with different criteria. Each symbol is a
+criterion keyword, and the following element is the callback to
+call
+
+ :line - called whenever the line number changes
+ :token - called for each new token consumed
+
+The list of criteria could be extended to include entering or
+leaving a statement, an expression, or a function definition."
+ (if (and cb (not (functionp cb)))
+ (error "criteria callbacks not yet implemented"))
+ (let ((inhibit-point-motion-hooks t)
+ (js2-compiler-xml-available (>= js2-language-version 160))
+ ;; This is a recursive-descent parser, so give it a big stack.
+ (max-lisp-eval-depth (max max-lisp-eval-depth 3000))
+ (max-specpdl-size (max max-specpdl-size 3000))
+ (case-fold-search nil)
+ ast)
+ (or buf (setq buf (current-buffer)))
+ (message nil) ; clear any error message from previous parse
+ (save-excursion
+ (set-buffer buf)
+ (setq js2-scanned-comments nil
+ js2-parsed-errors nil
+ js2-parsed-warnings nil
+ js2-imenu-recorder nil
+ js2-imenu-function-map nil
+ js2-label-set nil)
+ (js2-init-scanner)
+ (setq ast (js2-with-unmodifying-text-property-changes
+ (js2-do-parse)))
+ (unless js2-ts-hit-eof
+ (js2-report-error "msg.got.syntax.errors" (length js2-parsed-errors)))
+ (setf (js2-ast-root-errors ast) js2-parsed-errors
+ (js2-ast-root-warnings ast) js2-parsed-warnings)
+ ;; if we didn't find any declarations, put a dummy in this list so we
+ ;; don't end up re-parsing the buffer in `js2-mode-create-imenu-index'
+ (unless js2-imenu-recorder
+ (setq js2-imenu-recorder 'empty))
+ (run-hooks 'js2-parse-finished-hook)
+ ast)))
+
+;; Corresponds to Rhino's Parser.parse() method.
+(defun js2-do-parse ()
+ "Parse current buffer starting from current point.
+Scanner should be initialized."
+ (let ((pos js2-ts-cursor)
+ (end js2-ts-cursor) ; in case file is empty
+ root n tt)
+ ;; initialize buffer-local parsing vars
+ (setf root (make-js2-ast-root :buffer (buffer-name) :pos pos)
+ js2-current-script-or-fn root
+ js2-current-scope root
+ js2-current-flagged-token js2-EOF
+ js2-nesting-of-function 0
+ js2-labeled-stmt nil
+ js2-recorded-assignments nil) ; for js2-highlight
+ (while (/= (setq tt (js2-peek-token)) js2-EOF)
+ (if (= tt js2-FUNCTION)
+ (progn
+ (js2-consume-token)
+ (setq n (js2-parse-function (if js2-called-by-compile-function
+ 'FUNCTION_EXPRESSION
+ 'FUNCTION_STATEMENT)))
+ (js2-record-imenu-functions n))
+ ;; not a function - parse a statement
+ (setq n (js2-parse-statement)))
+ ;; add function or statement to script
+ (setq end (js2-node-end n))
+ (js2-block-node-push root n))
+ ;; add comments to root in lexical order
+ (when js2-scanned-comments
+ ;; if we find a comment beyond end of normal kids, use its end
+ (setq end (max end (js2-node-end (first js2-scanned-comments))))
+ (dolist (comment js2-scanned-comments)
+ (push comment (js2-ast-root-comments root))
+ (js2-node-add-children root comment)))
+ (setf (js2-node-len root) (- end pos))
+ ;; Give extensions a chance to muck with things before highlighting starts.
+ (dolist (callback js2-post-parse-callbacks)
+ (funcall callback))
+ (js2-highlight-undeclared-vars)
+ root))
+
+(defun js2-function-parser ()
+ (js2-consume-token)
+ (js2-parse-function 'FUNCTION_EXPRESSION_STATEMENT))
+
+(defun js2-parse-function-closure-body (fn-node)
+ "Parse a JavaScript 1.8 function closure body."
+ (let ((js2-nesting-of-function (1+ js2-nesting-of-function)))
+ (if js2-ts-hit-eof
+ (js2-report-error "msg.no.brace.body" nil
+ (js2-node-pos fn-node)
+ (- js2-ts-cursor (js2-node-pos fn-node)))
+ (js2-node-add-children fn-node
+ (setf (js2-function-node-body fn-node)
+ (js2-parse-expr))))))
+
+(defun js2-parse-function-body (fn-node)
+ (js2-must-match js2-LC "msg.no.brace.body"
+ (js2-node-pos fn-node)
+ (- js2-ts-cursor (js2-node-pos fn-node)))
+ (let ((pos js2-token-beg) ; LC position
+ (pn (make-js2-block-node)) ; starts at LC position
+ tt
+ end)
+ (incf js2-nesting-of-function)
+ (unwind-protect
+ (while (not (or (= (setq tt (js2-peek-token)) js2-ERROR)
+ (= tt js2-EOF)
+ (= tt js2-RC)))
+ (js2-block-node-push pn (if (/= tt js2-FUNCTION)
+ (js2-parse-statement)
+ (js2-consume-token)
+ (js2-parse-function 'FUNCTION_STATEMENT))))
+ (decf js2-nesting-of-function))
+ (setq end js2-token-end) ; assume no curly and leave at current token
+ (if (js2-must-match js2-RC "msg.no.brace.after.body" pos)
+ (setq end js2-token-end))
+ (setf (js2-node-pos pn) pos
+ (js2-node-len pn) (- end pos))
+ (setf (js2-function-node-body fn-node) pn)
+ (js2-node-add-children fn-node pn)
+ pn))
+
+(defun js2-parse-function-params (fn-node pos)
+ (if (js2-match-token js2-RP)
+ (setf (js2-function-node-rp fn-node) (- js2-token-beg pos))
+ (let (params len param)
+ (loop for tt = (js2-peek-token)
+ do
+ (cond
+ ;; destructuring param
+ ((or (= tt js2-LB) (= tt js2-LC))
+ (push (js2-parse-primary-expr) params))
+ ;; simple name
+ (t
+ (js2-must-match js2-NAME "msg.no.parm")
+ (js2-record-face 'js2-function-param)
+ (setq param (js2-create-name-node))
+ (js2-define-symbol js2-LP js2-ts-string param)
+ (push param params)))
+ while
+ (js2-match-token js2-COMMA))
+ (if (js2-must-match js2-RP "msg.no.paren.after.parms")
+ (setf (js2-function-node-rp fn-node) (- js2-token-beg pos)))
+ (dolist (p params)
+ (js2-node-add-children fn-node p)
+ (push p (js2-function-node-params fn-node))))))
+
+(defsubst js2-check-inconsistent-return-warning (fn-node name)
+ "Possibly show inconsistent-return warning.
+Last token scanned is the close-curly for the function body."
+ (when (and js2-mode-show-strict-warnings
+ js2-strict-inconsistent-return-warning
+ (not (js2-has-consistent-return-usage
+ (js2-function-node-body fn-node))))
+ ;; Have it extend from close-curly to bol or beginning of block.
+ (let ((pos (save-excursion
+ (goto-char js2-token-end)
+ (max (js2-node-abs-pos (js2-function-node-body fn-node))
+ (point-at-bol))))
+ (end js2-token-end))
+ (if (plusp (js2-name-node-length name))
+ (js2-add-strict-warning "msg.no.return.value"
+ (js2-name-node-name name) pos end)
+ (js2-add-strict-warning "msg.anon.no.return.value" nil pos end)))))
+
+(defun js2-parse-function (function-type)
+ "Function parser. FUNCTION-TYPE is a symbol."
+ (let ((pos js2-token-beg) ; start of 'function' keyword
+ name
+ name-beg
+ name-end
+ fn-node
+ lp
+ (synthetic-type function-type)
+ member-expr-node)
+ ;; parse function name, expression, or non-name (anonymous)
+ (cond
+ ;; function foo(...)
+ ((js2-match-token js2-NAME)
+ (setq name (js2-create-name-node t)
+ name-beg js2-token-beg
+ name-end js2-token-end)
+ (unless (js2-match-token js2-LP)
+ (when js2-allow-member-expr-as-function-name
+ ;; function foo.bar(...)
+ (setq member-expr-node name
+ name nil
+ member-expr-node (js2-parse-member-expr-tail
+ nil member-expr-node)))
+ (js2-must-match js2-LP "msg.no.paren.parms")))
+ ((js2-match-token js2-LP)
+ nil) ; anonymous function: leave name as null
+ (t
+ ;; function random-member-expr(...)
+ (when js2-allow-member-expr-as-function-name
+ ;; Note that memberExpr can not start with '(' like
+ ;; in function (1+2).toString(), because 'function (' already
+ ;; processed as anonymous function
+ (setq member-expr-node (js2-parse-member-expr)))
+ (js2-must-match js2-LP "msg.no.paren.parms")))
+ (if (= js2-current-token js2-LP) ; eventually matched LP?
+ (setq lp js2-token-beg))
+ (if member-expr-node
+ (progn
+ (setq synthetic-type 'FUNCTION_EXPRESSION)
+ (js2-parse-highlight-member-expr-fn-name member-expr-node))
+ (if name
+ (js2-set-face name-beg name-end
+ 'font-lock-function-name-face 'record)))
+ (if (and (not (eq synthetic-type 'FUNCTION_EXPRESSION))
+ (plusp (js2-name-node-length name)))
+ ;; Function statements define a symbol in the enclosing scope
+ (js2-define-symbol js2-FUNCTION (js2-name-node-name name) fn-node))
+ (setf fn-node (make-js2-function-node :pos pos
+ :name name
+ :form function-type
+ :lp (if lp (- lp pos))))
+ (if (or (js2-inside-function) (plusp js2-nesting-of-with))
+ ;; 1. Nested functions are not affected by the dynamic scope flag
+ ;; as dynamic scope is already a parent of their scope.
+ ;; 2. Functions defined under the with statement also immune to
+ ;; this setup, in which case dynamic scope is ignored in favor
+ ;; of the with object.
+ (setf (js2-function-node-ignore-dynamic fn-node) t))
+ ;; dynamically bind all the per-function variables
+ (let ((js2-current-script-or-fn fn-node)
+ (js2-current-scope fn-node)
+ (js2-nesting-of-with 0)
+ (js2-end-flags 0)
+ js2-label-set
+ js2-loop-set
+ js2-loop-and-switch-set)
+ (js2-parse-function-params fn-node pos)
+ (if (and (>= js2-language-version 180)
+ (/= (js2-peek-token) js2-LC))
+ (js2-parse-function-closure-body fn-node)
+ (js2-parse-function-body fn-node))
+ (if name
+ (js2-node-add-children fn-node name))
+ (js2-check-inconsistent-return-warning fn-node name)
+ ;; Function expressions define a name only in the body of the
+ ;; function, and only if not hidden by a parameter name
+ (if (and name
+ (eq synthetic-type 'FUNCTION_EXPRESSION)
+ (null (js2-scope-get-symbol js2-current-scope
+ (js2-name-node-name name))))
+ (js2-define-symbol js2-FUNCTION
+ (js2-name-node-name name)
+ fn-node))
+ (if (and name
+ (eq function-type 'FUNCTION_EXPRESSION_STATEMENT))
+ (js2-record-imenu-functions fn-node)))
+ (setf (js2-node-len fn-node) (- js2-ts-cursor pos)
+ (js2-function-node-member-expr fn-node) member-expr-node) ; may be nil
+ ;; Rhino doesn't do this, but we need it for finding undeclared vars.
+ ;; We wait until after parsing the function to set its parent scope,
+ ;; since `js2-define-symbol' needs the defining-scope check to stop
+ ;; at the function boundary when checking for redeclarations.
+ (setf (js2-scope-parent-scope fn-node) js2-current-scope)
+ fn-node))
+
+(defun js2-parse-statements (&optional parent)
+ "Parse a statement list. Last token consumed must be js2-LC.
+
+PARENT can be a `js2-block-node', in which case the statements are
+appended to PARENT. Otherwise a new `js2-block-node' is created
+and returned.
+
+This function does not match the closing js2-RC: the caller
+matches the RC so it can provide a suitable error message if not
+matched. This means it's up to the caller to set the length of
+the node to include the closing RC. The node start pos is set to
+the absolute buffer start position, and the caller should fix it
+up to be relative to the parent node. All children of this block
+node are given relative start positions and correct lengths."
+ (let ((pn (or parent (make-js2-block-node)))
+ tt)
+ (setf (js2-node-pos pn) js2-token-beg)
+ (while (and (> (setq tt (js2-peek-token)) js2-EOF)
+ (/= tt js2-RC))
+ (js2-block-node-push pn (js2-parse-statement)))
+ pn))
+
+(defun js2-parse-statement ()
+ (let (tt pn beg end)
+ ;; coarse-grained user-interrupt check - needs work
+ (and js2-parse-interruptable-p
+ (zerop (% (incf js2-parse-stmt-count)
+ js2-statements-per-pause))
+ (input-pending-p)
+ (throw 'interrupted t))
+ (setq pn (js2-statement-helper))
+ ;; no-side-effects warning check
+ (unless (js2-node-has-side-effects pn)
+ (setq end (js2-node-end pn))
+ (save-excursion
+ (goto-char end)
+ (setq beg (max (js2-node-pos pn) (point-at-bol))))
+ (js2-add-strict-warning "msg.no.side.effects" nil beg end))
+ pn))
+
+;; These correspond to the switch cases in Parser.statementHelper
+(defconst js2-parsers
+ (let ((parsers (make-vector js2-num-tokens
+ #'js2-parse-expr-stmt)))
+ (aset parsers js2-BREAK #'js2-parse-break)
+ (aset parsers js2-CONST #'js2-parse-const-var)
+ (aset parsers js2-CONTINUE #'js2-parse-continue)
+ (aset parsers js2-DEBUGGER #'js2-parse-debugger)
+ (aset parsers js2-DEFAULT #'js2-parse-default-xml-namespace)
+ (aset parsers js2-DO #'js2-parse-do)
+ (aset parsers js2-FOR #'js2-parse-for)
+ (aset parsers js2-FUNCTION #'js2-function-parser)
+ (aset parsers js2-IF #'js2-parse-if)
+ (aset parsers js2-LC #'js2-parse-block)
+ (aset parsers js2-LET #'js2-parse-let-stmt)
+ (aset parsers js2-NAME #'js2-parse-name-or-label)
+ (aset parsers js2-RETURN #'js2-parse-ret-yield)
+ (aset parsers js2-SEMI #'js2-parse-semi)
+ (aset parsers js2-SWITCH #'js2-parse-switch)
+ (aset parsers js2-THROW #'js2-parse-throw)
+ (aset parsers js2-TRY #'js2-parse-try)
+ (aset parsers js2-VAR #'js2-parse-const-var)
+ (aset parsers js2-WHILE #'js2-parse-while)
+ (aset parsers js2-WITH #'js2-parse-with)
+ (aset parsers js2-YIELD #'js2-parse-ret-yield)
+ parsers)
+ "A vector mapping token types to parser functions.")
+
+(defsubst js2-parse-warn-missing-semi (beg end)
+ (and js2-mode-show-strict-warnings
+ js2-strict-missing-semi-warning
+ (js2-add-strict-warning
+ "msg.missing.semi" nil
+ ;; back up to beginning of statement or line
+ (max beg (save-excursion
+ (goto-char end)
+ (point-at-bol)))
+ end)))
+
+(defconst js2-no-semi-insertion
+ (list js2-IF
+ js2-SWITCH
+ js2-WHILE
+ js2-DO
+ js2-FOR
+ js2-TRY
+ js2-WITH
+ js2-LC
+ js2-ERROR
+ js2-SEMI
+ js2-FUNCTION)
+ "List of tokens that don't do automatic semicolon insertion.")
+
+(defconst js2-autoinsert-semi-and-warn
+ (list js2-ERROR js2-EOF js2-RC))
+
+(defun js2-statement-helper ()
+ (let* ((tt (js2-peek-token))
+ (first-tt tt)
+ (beg js2-token-beg)
+ (parser (if (= tt js2-ERROR)
+ #'js2-parse-semi
+ (aref js2-parsers tt)))
+ pn
+ tt-flagged)
+ ;; If the statement is set, then it's been told its label by now.
+ (and js2-labeled-stmt
+ (js2-labeled-stmt-node-stmt js2-labeled-stmt)
+ (setq js2-labeled-stmt nil))
+ (setq pn (funcall parser))
+ ;; Don't do auto semi insertion for certain statement types.
+ (unless (or (memq first-tt js2-no-semi-insertion)
+ (js2-labeled-stmt-node-p pn))
+ (js2-auto-insert-semicolon pn))
+ pn))
+
+(defun js2-auto-insert-semicolon (pn)
+ (let* ((tt-flagged (js2-peek-flagged-token))
+ (tt (logand tt-flagged js2-clear-ti-mask))
+ (pos (js2-node-pos pn)))
+ (cond
+ ((= tt js2-SEMI)
+ ;; Consume ';' as a part of expression
+ (js2-consume-token)
+ ;; extend the node bounds to include the semicolon.
+ (setf (js2-node-len pn) (- js2-token-end pos)))
+ ((memq tt js2-autoinsert-semi-and-warn)
+ ;; Autoinsert ;
+ (js2-parse-warn-missing-semi pos (js2-node-end pn)))
+ (t
+ (if (js2-flag-not-set-p tt-flagged js2-ti-after-eol)
+ ;; Report error if no EOL or autoinsert ';' otherwise
+ (js2-report-error "msg.no.semi.stmt")
+ (js2-parse-warn-missing-semi pos (js2-node-end pn)))))))
+
+(defun js2-parse-condition ()
+ "Parse a parenthesized boolean expression, e.g. in an if- or while-stmt.
+The parens are discarded and the expression node is returned.
+The `pos' field of the return value is set to an absolute position
+that must be fixed up by the caller.
+Return value is a list (EXPR LP RP), with absolute paren positions."
+ (let (pn lp rp)
+ (if (js2-must-match js2-LP "msg.no.paren.cond")
+ (setq lp js2-token-beg))
+ (setq pn (js2-parse-expr))
+ (if (js2-must-match js2-RP "msg.no.paren.after.cond")
+ (setq rp js2-token-beg))
+ ;; Report strict warning on code like "if (a = 7) ..."
+ (if (and js2-strict-cond-assign-warning
+ (js2-assign-node-p pn))
+ (js2-add-strict-warning "msg.equal.as.assign" nil
+ (js2-node-pos pn)
+ (+ (js2-node-pos pn)
+ (js2-node-len pn))))
+ (list pn lp rp)))
+
+(defun js2-parse-if ()
+ "Parser for if-statement. Last matched token must be js2-IF."
+ (let ((pos js2-token-beg)
+ cond
+ if-true
+ if-false
+ else-pos
+ end
+ pn)
+ (js2-consume-token)
+ (setq cond (js2-parse-condition)
+ if-true (js2-parse-statement)
+ if-false (if (js2-match-token js2-ELSE)
+ (progn
+ (setq else-pos (- js2-token-beg pos))
+ (js2-parse-statement)))
+ end (js2-node-end (or if-false if-true))
+ pn (make-js2-if-node :pos pos
+ :len (- end pos)
+ :condition (car cond)
+ :then-part if-true
+ :else-part if-false
+ :else-pos else-pos
+ :lp (js2-relpos (second cond) pos)
+ :rp (js2-relpos (third cond) pos)))
+ (js2-node-add-children pn (car cond) if-true if-false)
+ pn))
+
+(defun js2-parse-switch ()
+ "Parser for if-statement. Last matched token must be js2-SWITCH."
+ (let ((pos js2-token-beg)
+ tt
+ pn
+ discriminant
+ has-default
+ case-expr
+ case-node
+ case-pos
+ cases
+ stmt
+ lp
+ rp)
+ (js2-consume-token)
+ (if (js2-must-match js2-LP "msg.no.paren.switch")
+ (setq lp js2-token-beg))
+ (setq discriminant (js2-parse-expr)
+ pn (make-js2-switch-node :discriminant discriminant
+ :pos pos
+ :lp (js2-relpos lp pos)))
+ (js2-node-add-children pn discriminant)
+ (js2-enter-switch pn)
+ (unwind-protect
+ (progn
+ (if (js2-must-match js2-RP "msg.no.paren.after.switch")
+ (setf (js2-switch-node-rp pn) (- js2-token-beg pos)))
+ (js2-must-match js2-LC "msg.no.brace.switch")
+ (catch 'break
+ (while t
+ (setq tt (js2-next-token)
+ case-pos js2-token-beg)
+ (cond
+ ((= tt js2-RC)
+ (setf (js2-node-len pn) (- js2-token-end pos))
+ (throw 'break nil)) ; done
+ ((= tt js2-CASE)
+ (setq case-expr (js2-parse-expr))
+ (js2-must-match js2-COLON "msg.no.colon.case"))
+ ((= tt js2-DEFAULT)
+ (if has-default
+ (js2-report-error "msg.double.switch.default"))
+ (setq has-default t
+ case-expr nil)
+ (js2-must-match js2-COLON "msg.no.colon.case"))
+ (t
+ (js2-report-error "msg.bad.switch")
+ (throw 'break nil)))
+ (setq case-node (make-js2-case-node :pos case-pos
+ :len (- js2-token-end case-pos)
+ :expr case-expr))
+ (js2-node-add-children case-node case-expr)
+ (while (and (/= (setq tt (js2-peek-token)) js2-RC)
+ (/= tt js2-CASE)
+ (/= tt js2-DEFAULT)
+ (/= tt js2-EOF))
+ (setf stmt (js2-parse-statement)
+ (js2-node-len case-node) (- (js2-node-end stmt) case-pos))
+ (js2-block-node-push case-node stmt))
+ (push case-node cases)))
+ ;; add cases last, as pushing reverses the order to be correct
+ (dolist (kid cases)
+ (js2-node-add-children pn kid)
+ (push kid (js2-switch-node-cases pn)))
+ pn) ; return value
+ (js2-exit-switch))))
+
+(defun js2-parse-while ()
+ "Parser for while-statement. Last matched token must be js2-WHILE."
+ (let ((pos js2-token-beg)
+ (pn (make-js2-while-node))
+ cond
+ body)
+ (js2-consume-token)
+ (js2-enter-loop pn)
+ (unwind-protect
+ (progn
+ (setf cond (js2-parse-condition)
+ (js2-while-node-condition pn) (car cond)
+ body (js2-parse-statement)
+ (js2-while-node-body pn) body
+ (js2-node-len pn) (- (js2-node-end body) pos)
+ (js2-while-node-lp pn) (js2-relpos (second cond) pos)
+ (js2-while-node-rp pn) (js2-relpos (third cond) pos))
+ (js2-node-add-children pn body (car cond)))
+ (js2-exit-loop))
+ pn))
+
+(defun js2-parse-do ()
+ "Parser for do-statement. Last matched token must be js2-DO."
+ (let ((pos js2-token-beg)
+ (pn (make-js2-do-node))
+ cond
+ body
+ end)
+ (js2-consume-token)
+ (js2-enter-loop pn)
+ (unwind-protect
+ (progn
+ (setq body (js2-parse-statement))
+ (js2-must-match js2-WHILE "msg.no.while.do")
+ (setf (js2-do-node-while-pos pn) (- js2-token-beg pos)
+ cond (js2-parse-condition)
+ (js2-do-node-condition pn) (car cond)
+ (js2-do-node-body pn) body
+ end js2-ts-cursor
+ (js2-do-node-lp pn) (js2-relpos (second cond) pos)
+ (js2-do-node-rp pn) (js2-relpos (third cond) pos))
+ (js2-node-add-children pn (car cond) body))
+ (js2-exit-loop))
+ ;; Always auto-insert semicolon to follow SpiderMonkey:
+ ;; It is required by ECMAScript but is ignored by the rest of
+ ;; world; see bug 238945
+ (if (js2-match-token js2-SEMI)
+ (setq end js2-ts-cursor))
+ (setf (js2-node-len pn) (- end pos))
+ pn))
+
+(defun js2-parse-for ()
+ "Parser for for-statement. Last matched token must be js2-FOR.
+Parses for, for-in, and for each-in statements."
+ (let ((for-pos js2-token-beg)
+ pn
+ is-for-each
+ is-for-in
+ in-pos
+ each-pos
+ tmp-pos
+ init ; Node init is also foo in 'foo in object'
+ cond ; Node cond is also object in 'foo in object'
+ incr ; 3rd section of for-loop initializer
+ body
+ tt
+ lp
+ rp)
+ (js2-consume-token)
+ ;; See if this is a for each () instead of just a for ()
+ (when (js2-match-token js2-NAME)
+ (if (string= "each" js2-ts-string)
+ (progn
+ (setq is-for-each t
+ each-pos (- js2-token-beg for-pos)) ; relative
+ (js2-record-face 'font-lock-keyword-face))
+ (js2-report-error "msg.no.paren.for")))
+ (if (js2-must-match js2-LP "msg.no.paren.for")
+ (setq lp (- js2-token-beg for-pos)))
+ (setq tt (js2-peek-token))
+ ;; parse init clause
+ (let ((js2-in-for-init t)) ; set as dynamic variable
+ (cond
+ ((= tt js2-SEMI)
+ (setq init (make-js2-empty-expr-node)))
+ ((or (= tt js2-VAR) (= tt js2-LET))
+ (js2-consume-token)
+ (setq init (js2-parse-variables tt js2-token-beg)))
+ (t
+ (setq init (js2-parse-expr)))))
+ (if (js2-match-token js2-IN)
+ (setq is-for-in t
+ in-pos (- js2-token-beg for-pos)
+ cond (js2-parse-expr)) ; object over which we're iterating
+ ;; else ordinary for loop - parse cond and incr
+ (js2-must-match js2-SEMI "msg.no.semi.for")
+ (setq cond (if (= (js2-peek-token) js2-SEMI)
+ (make-js2-empty-expr-node) ; no loop condition
+ (js2-parse-expr)))
+ (js2-must-match js2-SEMI "msg.no.semi.for.cond")
+ (setq tmp-pos js2-token-end
+ incr (if (= (js2-peek-token) js2-RP)
+ (make-js2-empty-expr-node :pos tmp-pos)
+ (js2-parse-expr))))
+ (if (js2-must-match js2-RP "msg.no.paren.for.ctrl")
+ (setq rp (- js2-token-beg for-pos)))
+ (if (not is-for-in)
+ (setq pn (make-js2-for-node :init init
+ :condition cond
+ :update incr
+ :lp lp
+ :rp rp))
+ ;; cond could be null if 'in obj' got eaten by the init node.
+ (if (js2-infix-node-p init)
+ ;; it was (foo in bar) instead of (var foo in bar)
+ (setq cond (js2-infix-node-right init)
+ init (js2-infix-node-left init))
+ (if (and (js2-var-decl-node-p init)
+ (> (length (js2-var-decl-node-kids init)) 1))
+ (js2-report-error "msg.mult.index")))
+ (setq pn (make-js2-for-in-node :iterator init
+ :object cond
+ :in-pos in-pos
+ :foreach-p is-for-each
+ :each-pos each-pos
+ :lp lp
+ :rp rp)))
+ (unwind-protect
+ (progn
+ (js2-enter-loop pn)
+ ;; We have to parse the body -after- creating the loop node,
+ ;; so that the loop node appears in the js2-loop-set, allowing
+ ;; break/continue statements to find the enclosing loop.
+ (setf body (js2-parse-statement)
+ (js2-loop-node-body pn) body
+ (js2-node-pos pn) for-pos
+ (js2-node-len pn) (- (js2-node-end body) for-pos))
+ (js2-node-add-children pn init cond incr body))
+ ;; finally
+ (js2-exit-loop))
+ pn))
+
+(defun js2-parse-try ()
+ "Parser for try-statement. Last matched token must be js2-TRY."
+ (let ((try-pos js2-token-beg)
+ try-end
+ try-block
+ catch-blocks
+ finally-block
+ saw-default-catch
+ peek
+ var-name
+ catch-cond
+ catch-node
+ guard-kwd
+ catch-pos
+ finally-pos
+ pn
+ block
+ lp
+ rp)
+ (js2-consume-token)
+ (if (/= (js2-peek-token) js2-LC)
+ (js2-report-error "msg.no.brace.try"))
+ (setq try-block (js2-parse-statement)
+ try-end (js2-node-end try-block)
+ peek (js2-peek-token))
+ (cond
+ ((= peek js2-CATCH)
+ (while (js2-match-token js2-CATCH)
+ (setq catch-pos js2-token-beg
+ guard-kwd nil
+ catch-cond nil
+ lp nil
+ rp nil)
+ (if saw-default-catch
+ (js2-report-error "msg.catch.unreachable"))
+ (if (js2-must-match js2-LP "msg.no.paren.catch")
+ (setq lp (- js2-token-beg catch-pos)))
+ (js2-must-match js2-NAME "msg.bad.catchcond")
+ (setq var-name (js2-create-name-node))
+ (if (js2-match-token js2-IF)
+ (setq guard-kwd (- js2-token-beg catch-pos)
+ catch-cond (js2-parse-expr))
+ (setq saw-default-catch t))
+ (if (js2-must-match js2-RP "msg.bad.catchcond")
+ (setq rp (- js2-token-beg catch-pos)))
+ (js2-must-match js2-LC "msg.no.brace.catchblock")
+ (setq block (js2-parse-statements)
+ try-end (js2-node-end block)
+ catch-node (make-js2-catch-node :pos catch-pos
+ :var-name var-name
+ :guard-expr catch-cond
+ :guard-kwd guard-kwd
+ :block block
+ :lp lp
+ :rp rp))
+ (if (js2-must-match js2-RC "msg.no.brace.after.body")
+ (setq try-end js2-token-beg))
+ (setf (js2-node-len block) (- try-end (js2-node-pos block))
+ (js2-node-len catch-node) (- try-end catch-pos))
+ (js2-node-add-children catch-node var-name catch-cond block)
+ (push catch-node catch-blocks)))
+ ((/= peek js2-FINALLY)
+ (js2-must-match js2-FINALLY "msg.try.no.catchfinally"
+ (js2-node-pos try-block)
+ (- (setq try-end (js2-node-end try-block))
+ (js2-node-pos try-block)))))
+ (when (js2-match-token js2-FINALLY)
+ (setq finally-pos js2-token-beg
+ block (js2-parse-statement)
+ try-end (js2-node-end block)
+ finally-block (make-js2-finally-node :pos finally-pos
+ :len (- try-end finally-pos)
+ :body block))
+ (js2-node-add-children finally-block block))
+ (setq pn (make-js2-try-node :pos try-pos
+ :len (- try-end try-pos)
+ :try-block try-block
+ :finally-block finally-block))
+ (js2-node-add-children pn try-block finally-block)
+ ;; push them onto the try-node, which reverses and corrects their order
+ (dolist (cb catch-blocks)
+ (js2-node-add-children pn cb)
+ (push cb (js2-try-node-catch-clauses pn)))
+ pn))
+
+(defun js2-parse-throw ()
+ "Parser for throw-statement. Last matched token must be js2-THROW."
+ (let ((pos js2-token-beg)
+ expr
+ pn)
+ (js2-consume-token)
+ (if (= (js2-peek-token-or-eol) js2-EOL)
+ ;; ECMAScript does not allow new lines before throw expression,
+ ;; see bug 256617
+ (js2-report-error "msg.bad.throw.eol"))
+ (setq expr (js2-parse-expr)
+ pn (make-js2-throw-node :pos pos
+ :len (- (js2-node-end expr) pos)
+ :expr expr))
+ (js2-node-add-children pn expr)
+ pn))
+
+(defsubst js2-match-jump-label-name (label-name)
+ "If break/continue specified a label, return that label's labeled stmt.
+Returns the corresponding `js2-labeled-stmt-node', or if LABEL-NAME
+does not match an existing label, reports an error and returns nil."
+ (let ((bundle (cdr (assoc label-name js2-label-set))))
+ (if (null bundle)
+ (js2-report-error "msg.undef.label"))
+ bundle))
+
+(defun js2-parse-break ()
+ "Parser for break-statement. Last matched token must be js2-BREAK."
+ (let ((pos js2-token-beg)
+ (end js2-token-end)
+ break-target ; statement to break from
+ break-label ; in "break foo", name-node representing the foo
+ labels ; matching labeled statement to break to
+ pn)
+ (js2-consume-token) ; `break'
+ (when (eq (js2-peek-token-or-eol) js2-NAME)
+ (js2-consume-token)
+ (setq break-label (js2-create-name-node)
+ end (js2-node-end break-label)
+ ;; matchJumpLabelName only matches if there is one
+ labels (js2-match-jump-label-name js2-ts-string)
+ break-target (if labels (car (js2-labeled-stmt-node-labels labels)))))
+ (unless (or break-target break-label)
+ ;; no break target specified - try for innermost enclosing loop/switch
+ (if (null js2-loop-and-switch-set)
+ (unless break-label
+ (js2-report-error "msg.bad.break" nil pos (length "break")))
+ (setq break-target (car js2-loop-and-switch-set))))
+ (setq pn (make-js2-break-node :pos pos
+ :len (- end pos)
+ :label break-label
+ :target break-target))
+ (js2-node-add-children pn break-label) ; but not break-target
+ pn))
+
+(defun js2-parse-continue ()
+ "Parser for continue-statement. Last matched token must be js2-CONTINUE."
+ (let ((pos js2-token-beg)
+ (end js2-token-end)
+ label ; optional user-specified label, a `js2-name-node'
+ labels ; current matching labeled stmt, if any
+ target ; the `js2-loop-node' target of this continue stmt
+ pn)
+ (js2-consume-token) ; `continue'
+ (when (= (js2-peek-token-or-eol) js2-NAME)
+ (js2-consume-token)
+ (setq label (js2-create-name-node)
+ end (js2-node-end label)
+ ;; matchJumpLabelName only matches if there is one
+ labels (js2-match-jump-label-name js2-ts-string)))
+ (cond
+ ((null labels) ; no current label to go to
+ (if (null js2-loop-set) ; no loop to continue to
+ (js2-report-error "msg.continue.outside" nil pos
+ (length "continue"))
+ (setq target (car js2-loop-set)))) ; innermost enclosing loop
+ (t
+ (if (js2-loop-node-p (js2-labeled-stmt-node-stmt labels))
+ (setq target (js2-labeled-stmt-node-stmt labels))
+ (js2-report-error "msg.continue.nonloop" nil pos (- end pos)))))
+ (setq pn (make-js2-continue-node :pos pos
+ :len (- end pos)
+ :label label
+ :target target))
+ (js2-node-add-children pn label) ; but not target - it's not our child
+ pn))
+
+(defun js2-parse-with ()
+ "Parser for with-statement. Last matched token must be js2-WITH."
+ (js2-consume-token)
+ (let ((pos js2-token-beg)
+ obj body pn lp rp)
+ (if (js2-must-match js2-LP "msg.no.paren.with")
+ (setq lp js2-token-beg))
+ (setq obj (js2-parse-expr))
+ (if (js2-must-match js2-RP "msg.no.paren.after.with")
+ (setq rp js2-token-beg))
+ (let ((js2-nesting-of-with (1+ js2-nesting-of-with)))
+ (setq body (js2-parse-statement)))
+ (setq pn (make-js2-with-node :pos pos
+ :len (- (js2-node-end body) pos)
+ :object obj
+ :body body
+ :lp (js2-relpos lp pos)
+ :rp (js2-relpos rp pos)))
+ (js2-node-add-children pn obj body)
+ pn))
+
+(defun js2-parse-const-var ()
+ "Parser for var- or const-statement.
+Last matched token must be js2-CONST or js2-VAR."
+ (let ((tt (js2-peek-token))
+ (pos js2-token-beg)
+ expr
+ pn)
+ (js2-consume-token)
+ (setq expr (js2-parse-variables tt js2-token-beg)
+ pn (make-js2-expr-stmt-node :pos pos
+ :len (- (js2-node-end expr) pos)
+ :expr expr))
+ (js2-node-add-children pn expr)
+ pn))
+
+(defsubst js2-wrap-with-expr-stmt (pos expr &optional add-child)
+ (let ((pn (make-js2-expr-stmt-node :pos pos
+ :len (js2-node-len expr)
+ :type (if (js2-inside-function)
+ js2-EXPR_VOID
+ js2-EXPR_RESULT)
+ :expr expr)))
+ (if add-child
+ (js2-node-add-children pn expr))
+ pn))
+
+(defun js2-parse-let-stmt ()
+ "Parser for let-statement. Last matched token must be js2-LET."
+ (js2-consume-token)
+ (let ((pos js2-token-beg)
+ expr
+ pn)
+ (if (= (js2-peek-token) js2-LP)
+ ;; let expression in statement context
+ (setq expr (js2-parse-let pos 'statement)
+ pn (js2-wrap-with-expr-stmt pos expr t))
+ ;; else we're looking at a statement like let x=6, y=7;
+ (setf expr (js2-parse-variables js2-LET pos)
+ pn (js2-wrap-with-expr-stmt pos expr t)
+ (js2-node-type pn) js2-EXPR_RESULT))
+ pn))
+
+(defun js2-parse-ret-yield ()
+ (js2-parse-return-or-yield (js2-peek-token) nil))
+
+(defconst js2-parse-return-stmt-enders
+ (list js2-SEMI js2-RC js2-EOF js2-EOL js2-ERROR js2-RB js2-RP js2-YIELD))
+
+(defsubst js2-now-all-set (before after mask)
+ "Return whether or not the bits in the mask have changed to all set.
+BEFORE is bits before change, AFTER is bits after change, and MASK is
+the mask for bits. Returns t if all the bits in the mask are set in AFTER
+but not BEFORE."
+ (and (/= (logand before mask) mask)
+ (= (logand after mask) mask)))
+
+(defun js2-parse-return-or-yield (tt expr-context)
+ (let ((pos js2-token-beg)
+ (end js2-token-end)
+ (before js2-end-flags)
+ (inside-function (js2-inside-function))
+ e
+ ret
+ name)
+ (unless inside-function
+ (js2-report-error (if (eq tt js2-RETURN)
+ "msg.bad.return"
+ "msg.bad.yield")))
+ (js2-consume-token)
+ ;; This is ugly, but we don't want to require a semicolon.
+ (unless (memq (js2-peek-token-or-eol) js2-parse-return-stmt-enders)
+ (setq e (js2-parse-expr)
+ end (js2-node-end e)))
+ (cond
+ ((eq tt js2-RETURN)
+ (js2-set-flag js2-end-flags (if (null e)
+ js2-end-returns
+ js2-end-returns-value))
+ (setq ret (make-js2-return-node :pos pos
+ :len (- end pos)
+ :retval e))
+ (js2-node-add-children ret e)
+ ;; See if we need a strict mode warning.
+ ;; TODO: The analysis done by `js2-has-consistent-return-usage' is
+ ;; more thorough and accurate than this before/after flag check.
+ ;; E.g. if there's a finally-block that always returns, we shouldn't
+ ;; show a warning generated by inconsistent returns in the catch blocks.
+ ;; Basically `js2-has-consistent-return-usage' needs to keep more state,
+ ;; so we know which returns/yields to highlight, and we should get rid of
+ ;; all the checking in `js2-parse-return-or-yield'.
+ (if (and js2-strict-inconsistent-return-warning
+ (js2-now-all-set before js2-end-flags
+ (logior js2-end-returns js2-end-returns-value)))
+ (js2-add-strict-warning "msg.return.inconsistent" nil pos end)))
+ (t
+ (unless (js2-inside-function)
+ (js2-report-error "msg.bad.yield"))
+ (js2-set-flag js2-end-flags js2-end-yields)
+ (setq ret (make-js2-yield-node :pos pos
+ :len (- end pos)
+ :value e))
+ (js2-node-add-children ret e)
+ (unless expr-context
+ (setq e ret
+ ret (js2-wrap-with-expr-stmt pos e t))
+ (js2-set-requires-activation)
+ (js2-set-is-generator))))
+ ;; see if we are mixing yields and value returns.
+ (when (and inside-function
+ (js2-now-all-set before js2-end-flags
+ (logior js2-end-yields js2-end-returns-value)))
+ (setq name (js2-function-name js2-current-script-or-fn))
+ (if (zerop (length name))
+ (js2-report-error "msg.anon.generator.returns" nil pos (- end pos))
+ (js2-report-error "msg.generator.returns" name pos (- end pos))))
+ ret))
+
+(defun js2-parse-debugger ()
+ (js2-consume-token)
+ (make-js2-keyword-node :type js2-DEBUGGER))
+
+(defun js2-parse-block ()
+ "Parser for a curly-delimited statement block.
+Last token matched must be js2-LC."
+ (let ((pos js2-token-beg)
+ (pn (make-js2-scope)))
+ (js2-consume-token)
+ (js2-push-scope pn)
+ (unwind-protect
+ (progn
+ (js2-parse-statements pn)
+ (js2-must-match js2-RC "msg.no.brace.block")
+ (setf (js2-node-len pn) (- js2-token-end pos)))
+ (js2-pop-scope))
+ pn))
+
+;; for js2-ERROR too, to have a node for error recovery to work on
+(defun js2-parse-semi ()
+ "Parse a statement or handle an error.
+Last matched token is js-SEMI or js-ERROR."
+ (let ((tt (js2-peek-token)) pos len)
+ (js2-consume-token)
+ (if (eq tt js2-SEMI)
+ (make-js2-empty-expr-node :len 1)
+ (setq pos js2-token-beg
+ len (- js2-token-beg pos))
+ (js2-report-error "msg.syntax" nil pos len)
+ (make-js2-error-node :pos pos :len len))))
+
+(defun js2-parse-default-xml-namespace ()
+ "Parse a `default xml namespace = <expr>' e4x statement."
+ (let ((pos js2-token-beg)
+ end len expr unary es)
+ (js2-consume-token)
+ (js2-must-have-xml)
+ (js2-set-requires-activation)
+ (setq len (- js2-ts-cursor pos))
+ (unless (and (js2-match-token js2-NAME)
+ (string= js2-ts-string "xml"))
+ (js2-report-error "msg.bad.namespace" nil pos len))
+ (unless (and (js2-match-token js2-NAME)
+ (string= js2-ts-string "namespace"))
+ (js2-report-error "msg.bad.namespace" nil pos len))
+ (unless (js2-match-token js2-ASSIGN)
+ (js2-report-error "msg.bad.namespace" nil pos len))
+ (setq expr (js2-parse-expr)
+ end (js2-node-end expr)
+ unary (make-js2-unary-node :type js2-DEFAULTNAMESPACE
+ :pos pos
+ :len (- end pos)
+ :operand expr))
+ (js2-node-add-children unary expr)
+ (make-js2-expr-stmt-node :pos pos
+ :len (- end pos)
+ :expr unary)))
+
+(defun js2-record-label (label bundle)
+ ;; current token should be colon that `js2-parse-primary-expr' left untouched
+ (js2-consume-token)
+ (let ((name (js2-label-node-name label))
+ labeled-stmt
+ dup)
+ (when (setq labeled-stmt (cdr (assoc name js2-label-set)))
+ ;; flag both labels if possible when used in editing mode
+ (if (and js2-parse-ide-mode
+ (setq dup (js2-get-label-by-name labeled-stmt name)))
+ (js2-report-error "msg.dup.label" nil
+ (js2-node-abs-pos dup) (js2-node-len dup)))
+ (js2-report-error "msg.dup.label" nil
+ (js2-node-pos label) (js2-node-len label)))
+ (js2-labeled-stmt-node-add-label bundle label)
+ (js2-node-add-children bundle label)
+ ;; Add one reference to the bundle per label in `js2-label-set'
+ (push (cons name bundle) js2-label-set)))
+
+(defun js2-parse-name-or-label ()
+ "Parser for identifier or label. Last token matched must be js2-NAME.
+Called when we found a name in a statement context. If it's a label, we gather
+up any following labels and the next non-label statement into a
+`js2-labeled-stmt-node' bundle and return that. Otherwise we parse an
+expression and return it wrapped in a `js2-expr-stmt-node'."
+ (let ((pos js2-token-beg)
+ (end js2-token-end)
+ expr
+ stmt
+ pn
+ bundle
+ (continue t))
+ ;; set check for label and call down to `js2-parse-primary-expr'
+ (js2-set-check-for-label)
+ (setq expr (js2-parse-expr))
+ (if (/= (js2-node-type expr) js2-LABEL)
+ ;; Parsed non-label expression - wrap with expression stmt.
+ (setq pn (js2-wrap-with-expr-stmt pos expr t))
+ ;; else parsed a label
+ (setq bundle (make-js2-labeled-stmt-node :pos pos))
+ (js2-record-label expr bundle)
+ ;; look for more labels
+ (while (and continue (= (js2-peek-token) js2-NAME))
+ (js2-set-check-for-label)
+ (setq expr (js2-parse-expr))
+ (if (/= (js2-node-type expr) js2-LABEL)
+ (progn
+ (setq stmt (js2-wrap-with-expr-stmt (js2-node-pos expr) expr t)
+ continue nil)
+ (js2-auto-insert-semicolon stmt))
+ (js2-record-label expr bundle)))
+ ;; no more labels; now parse the labeled statement
+ (unwind-protect
+ (unless stmt
+ (let ((js2-labeled-stmt bundle)) ; bind dynamically
+ (setq stmt (js2-statement-helper))))
+ ;; remove the labels for this statement from the global set
+ (dolist (label (js2-labeled-stmt-node-labels bundle))
+ (setq js2-label-set (remove label js2-label-set))))
+ (setf (js2-labeled-stmt-node-stmt bundle) stmt
+ (js2-node-len bundle) (- (js2-node-end stmt) pos))
+ (js2-node-add-children bundle stmt)
+ bundle)))
+
+(defun js2-parse-expr-stmt ()
+ "Default parser in statement context, if no recognized statement found."
+ (js2-wrap-with-expr-stmt js2-token-beg (js2-parse-expr) t))
+
+(defun js2-parse-variables (decl-type pos)
+ "Parse a comma-separated list of variable declarations.
+Could be a 'var', 'const' or 'let' expression, possibly in a for-loop initializer.
+
+DECL-TYPE is a token value: either VAR, CONST, or LET depending on context.
+For 'var' or 'const', the keyword should be the token last scanned.
+
+POS is the position where the node should start. It's sometimes the
+var/const/let keyword, and other times the beginning of the first token
+in the first variable declaration.
+
+Returns the parsed `js2-var-decl-node' expression node."
+ (let* ((result (make-js2-var-decl-node :decl-type decl-type
+ :pos pos))
+ destructuring
+ kid-pos
+ tt
+ init
+ name
+ end
+ nbeg nend
+ vi
+ (continue t))
+ ;; Example:
+ ;; var foo = {a: 1, b: 2}, bar = [3, 4];
+ ;; var {b: s2, a: s1} = foo, x = 6, y, [s3, s4] = bar;
+ (while continue
+ (setq destructuring nil
+ name nil
+ tt (js2-peek-token)
+ kid-pos js2-token-beg
+ end js2-token-end
+ init nil)
+ (if (or (= tt js2-LB) (= tt js2-LC))
+ ;; Destructuring assignment, e.g., var [a, b] = ...
+ (setq destructuring (js2-parse-primary-expr)
+ end (js2-node-end destructuring))
+ ;; Simple variable name
+ (when (js2-must-match js2-NAME "msg.bad.var")
+ (setq name (js2-create-name-node)
+ nbeg js2-token-beg
+ nend js2-token-end
+ end nend)
+ (js2-define-symbol decl-type js2-ts-string name js2-in-for-init)))
+ (when (js2-match-token js2-ASSIGN)
+ (setq init (js2-parse-assign-expr)
+ end (js2-node-end init))
+ (if (and js2-parse-ide-mode
+ (or (js2-object-node-p init)
+ (js2-function-node-p init)))
+ (js2-record-imenu-functions init name)))
+ (when name
+ (js2-set-face nbeg nend (if (js2-function-node-p init)
+ 'font-lock-function-name-face
+ 'font-lock-variable-name-face)
+ 'record))
+ (setq vi (make-js2-var-init-node :pos kid-pos
+ :len (- end kid-pos)
+ :type decl-type))
+ (if destructuring
+ (progn
+ (if (and (null init) (not js2-in-for-init))
+ (js2-report-error "msg.destruct.assign.no.init"))
+ (setf (js2-var-init-node-target vi) destructuring))
+ (setf (js2-var-init-node-target vi) name))
+ (setf (js2-var-init-node-initializer vi) init)
+ (js2-node-add-children vi name destructuring init)
+ (js2-block-node-push result vi)
+ (unless (js2-match-token js2-COMMA)
+ (setq continue nil)))
+ (setf (js2-node-len result) (- end pos))
+ result))
+
+(defun js2-parse-let (pos &optional stmt-p)
+ "Parse a let expression or statement.
+A let-expression is of the form `let (vars) expr'.
+A let-statment is of the form `let (vars) {statements}'.
+The third form of let is a variable declaration list, handled
+by `js2-parse-variables'."
+ (let ((pn (make-js2-let-node :pos pos))
+ beg vars body)
+ (if (js2-must-match js2-LP "msg.no.paren.after.let")
+ (setf (js2-let-node-lp pn) (- js2-token-beg pos)))
+ (js2-push-scope pn)
+ (unwind-protect
+ (progn
+ (setq vars (js2-parse-variables js2-LET js2-token-beg))
+ (if (js2-must-match js2-RP "msg.no.paren.let")
+ (setf (js2-let-node-rp pn) (- js2-token-beg pos)))
+ (if (and stmt-p (eq (js2-peek-token) js2-LC))
+ ;; let statement
+ (progn
+ (js2-consume-token)
+ (setf beg js2-token-beg ; position stmt at LC
+ body (js2-parse-statements))
+ (js2-must-match js2-RC "msg.no.curly.let")
+ (setf (js2-node-len body) (- js2-token-end beg)
+ (js2-node-len pn) (- js2-token-end pos)
+ (js2-let-node-body pn) body
+ (js2-node-type pn) js2-LET))
+ ;; let expression
+ (setf body (js2-parse-expr)
+ (js2-node-len pn) (- (js2-node-end body) pos)
+ (js2-let-node-body pn) body))
+ (js2-node-add-children pn vars body))
+ (js2-pop-scope))
+ pn))
+
+(defsubst js2-define-new-symbol (decl-type name node)
+ (js2-scope-put-symbol js2-current-scope
+ name
+ (make-js2-symbol decl-type name node)))
+
+(defun js2-define-symbol (decl-type name &optional node ignore-not-in-block)
+ "Define a symbol in the current scope.
+If NODE is non-nil, it is the AST node associated with the symbol."
+ (let* ((defining-scope (js2-get-defining-scope js2-current-scope name))
+ (symbol (if defining-scope
+ (js2-scope-get-symbol defining-scope name)))
+ (sdt (if symbol (js2-symbol-decl-type symbol) -1)))
+ (cond
+ ((and symbol ; already defined
+ (or (= sdt js2-CONST) ; old version is const
+ (= decl-type js2-CONST) ; new version is const
+ ;; two let-bound vars in this block have same name
+ (and (= sdt js2-LET)
+ (eq defining-scope js2-current-scope))))
+ (js2-report-error
+ (cond
+ ((= sdt js2-CONST) "msg.const.redecl")
+ ((= sdt js2-LET) "msg.let.redecl")
+ ((= sdt js2-VAR) "msg.var.redecl")
+ ((= sdt js2-FUNCTION) "msg.function.redecl")
+ (t "msg.parm.redecl"))
+ name))
+ ((= decl-type js2-LET)
+ (if (and (not ignore-not-in-block)
+ (or (= (js2-node-type js2-current-scope) js2-IF)
+ (js2-loop-node-p js2-current-scope)))
+ (js2-report-error "msg.let.decl.not.in.block")
+ (js2-define-new-symbol decl-type name node)))
+ ((or (= decl-type js2-VAR)
+ (= decl-type js2-CONST)
+ (= decl-type js2-FUNCTION))
+ (if symbol
+ (if (and js2-strict-var-redeclaration-warning (= sdt js2-VAR))
+ (js2-add-strict-warning "msg.var.redecl" name)
+ (if (and js2-strict-var-hides-function-arg-warning (= sdt js2-LP))
+ (js2-add-strict-warning "msg.var.hides.arg" name)))
+ (js2-define-new-symbol decl-type name node)))
+ ((= decl-type js2-LP)
+ (if symbol
+ ;; must be duplicate parameter. Second parameter hides the
+ ;; first, so go ahead and add the second pararameter
+ (js2-report-warning "msg.dup.parms" name))
+ (js2-define-new-symbol decl-type name node))
+ (t (js2-code-bug)))))
+
+(defun js2-parse-expr ()
+ (let* ((pn (js2-parse-assign-expr))
+ (pos (js2-node-pos pn))
+ left
+ right
+ op-pos)
+ (while (js2-match-token js2-COMMA)
+ (setq op-pos (- js2-token-beg pos)) ; relative
+ (if (= (js2-peek-token) js2-YIELD)
+ (js2-report-error "msg.yield.parenthesized"))
+ (setq right (js2-parse-assign-expr)
+ left pn
+ pn (make-js2-infix-node :type js2-COMMA
+ :pos pos
+ :len (- js2-ts-cursor pos)
+ :op-pos op-pos
+ :left left
+ :right right))
+ (js2-node-add-children pn left right))
+ pn))
+
+(defun js2-parse-assign-expr ()
+ (let ((tt (js2-peek-token))
+ (pos js2-token-beg)
+ pn
+ left
+ right
+ op-pos)
+ (if (= tt js2-YIELD)
+ (js2-parse-return-or-yield tt t)
+ ;; not yield - parse assignment expression
+ (setq pn (js2-parse-cond-expr)
+ tt (js2-peek-token))
+ (when (and (<= js2-first-assign tt)
+ (<= tt js2-last-assign))
+ (js2-consume-token)
+ (setq op-pos (- js2-token-beg pos) ; relative
+ left pn
+ right (js2-parse-assign-expr)
+ pn (make-js2-assign-node :type tt
+ :pos pos
+ :len (- (js2-node-end right) pos)
+ :op-pos op-pos
+ :left left
+ :right right))
+ (when js2-parse-ide-mode
+ (js2-highlight-assign-targets pn left right)
+ (if (or (js2-function-node-p right)
+ (js2-object-node-p right))
+ (js2-record-imenu-functions right left)))
+ ;; do this last so ide checks above can use absolute positions
+ (js2-node-add-children pn left right))
+ pn)))
+
+(defun js2-parse-cond-expr ()
+ (let ((pos js2-token-beg)
+ (pn (js2-parse-or-expr))
+ test-expr
+ if-true
+ if-false
+ q-pos
+ c-pos)
+ (when (js2-match-token js2-HOOK)
+ (setq q-pos (- js2-token-beg pos)
+ if-true (js2-parse-assign-expr))
+ (js2-must-match js2-COLON "msg.no.colon.cond")
+ (setq c-pos (- js2-token-beg pos)
+ if-false (js2-parse-assign-expr)
+ test-expr pn
+ pn (make-js2-cond-node :pos pos
+ :len (- (js2-node-end if-false) pos)
+ :test-expr test-expr
+ :true-expr if-true
+ :false-expr if-false
+ :q-pos q-pos
+ :c-pos c-pos))
+ (js2-node-add-children pn test-expr if-true if-false))
+ pn))
+
+(defun js2-make-binary (type left parser)
+ "Helper for constructing a binary-operator AST node.
+LEFT is the left-side-expression, already parsed, and the
+binary operator should have just been matched.
+PARSER is a function to call to parse the right operand,
+or a `js2-node' struct if it has already been parsed."
+ (let* ((pos (js2-node-pos left))
+ (op-pos (- js2-token-beg pos))
+ (right (if (js2-node-p parser)
+ parser
+ (funcall parser)))
+ (pn (make-js2-infix-node :type type
+ :pos pos
+ :len (- (js2-node-end right) pos)
+ :op-pos op-pos
+ :left left
+ :right right)))
+ (js2-node-add-children pn left right)
+ pn))
+
+(defun js2-parse-or-expr ()
+ (let ((pn (js2-parse-and-expr)))
+ (when (js2-match-token js2-OR)
+ (setq pn (js2-make-binary js2-OR
+ pn
+ 'js2-parse-or-expr)))
+ pn))
+
+(defun js2-parse-and-expr ()
+ (let ((pn (js2-parse-bit-or-expr)))
+ (when (js2-match-token js2-AND)
+ (setq pn (js2-make-binary js2-AND
+ pn
+ 'js2-parse-and-expr)))
+ pn))
+
+(defun js2-parse-bit-or-expr ()
+ (let ((pn (js2-parse-bit-xor-expr)))
+ (while (js2-match-token js2-BITOR)
+ (setq pn (js2-make-binary js2-BITOR
+ pn
+ 'js2-parse-bit-xor-expr)))
+ pn))
+
+(defun js2-parse-bit-xor-expr ()
+ (let ((pn (js2-parse-bit-and-expr)))
+ (while (js2-match-token js2-BITXOR)
+ (setq pn (js2-make-binary js2-BITXOR
+ pn
+ 'js2-parse-bit-and-expr)))
+ pn))
+
+(defun js2-parse-bit-and-expr ()
+ (let ((pn (js2-parse-eq-expr)))
+ (while (js2-match-token js2-BITAND)
+ (setq pn (js2-make-binary js2-BITAND
+ pn
+ 'js2-parse-eq-expr)))
+ pn))
+
+(defconst js2-parse-eq-ops
+ (list js2-EQ js2-NE js2-SHEQ js2-SHNE))
+
+(defun js2-parse-eq-expr ()
+ (let ((pn (js2-parse-rel-expr))
+ tt)
+ (while (memq (setq tt (js2-peek-token)) js2-parse-eq-ops)
+ (js2-consume-token)
+ (setq pn (js2-make-binary tt
+ pn
+ 'js2-parse-rel-expr)))
+ pn))
+
+(defconst js2-parse-rel-ops
+ (list js2-IN js2-INSTANCEOF js2-LE js2-LT js2-GE js2-GT))
+
+(defun js2-parse-rel-expr ()
+ (let ((pn (js2-parse-shift-expr))
+ (continue t)
+ tt)
+ (while continue
+ (setq tt (js2-peek-token))
+ (cond
+ ((and js2-in-for-init (= tt js2-IN))
+ (setq continue nil))
+ ((memq tt js2-parse-rel-ops)
+ (js2-consume-token)
+ (setq pn (js2-make-binary tt pn 'js2-parse-shift-expr)))
+ (t
+ (setq continue nil))))
+ pn))
+
+(defconst js2-parse-shift-ops
+ (list js2-LSH js2-URSH js2-RSH))
+
+(defun js2-parse-shift-expr ()
+ (let ((pn (js2-parse-add-expr))
+ tt
+ (continue t))
+ (while continue
+ (setq tt (js2-peek-token))
+ (if (memq tt js2-parse-shift-ops)
+ (progn
+ (js2-consume-token)
+ (setq pn (js2-make-binary tt pn 'js2-parse-add-expr)))
+ (setq continue nil)))
+ pn))
+
+(defun js2-parse-add-expr ()
+ (let ((pn (js2-parse-mul-expr))
+ tt
+ (continue t))
+ (while continue
+ (setq tt (js2-peek-token))
+ (if (or (= tt js2-ADD) (= tt js2-SUB))
+ (progn
+ (js2-consume-token)
+ (setq pn (js2-make-binary tt pn 'js2-parse-mul-expr)))
+ (setq continue nil)))
+ pn))
+
+(defconst js2-parse-mul-ops
+ (list js2-MUL js2-DIV js2-MOD))
+
+(defun js2-parse-mul-expr ()
+ (let ((pn (js2-parse-unary-expr))
+ tt
+ (continue t))
+ (while continue
+ (setq tt (js2-peek-token))
+ (if (memq tt js2-parse-mul-ops)
+ (progn
+ (js2-consume-token)
+ (setq pn (js2-make-binary tt pn 'js2-parse-unary-expr)))
+ (setq continue nil)))
+ pn))
+
+(defsubst js2-make-unary (type parser &rest args)
+ "Make a unary node of type TYPE.
+PARSER is either a node (for postfix operators) or a function to call
+to parse the operand (for prefix operators)."
+ (let* ((pos js2-token-beg)
+ (postfix (js2-node-p parser))
+ (expr (if postfix
+ parser
+ (apply parser args)))
+ end
+ pn)
+ (if postfix ; e.g. i++
+ (setq pos (js2-node-pos expr)
+ end js2-token-end)
+ (setq end (js2-node-end expr)))
+ (setq pn (make-js2-unary-node :type type
+ :pos pos
+ :len (- end pos)
+ :operand expr))
+ (js2-node-add-children pn expr)
+ pn))
+
+(defconst js2-incrementable-node-types
+ (list js2-NAME js2-GETPROP js2-GETELEM js2-GET_REF js2-CALL)
+ "Node types that can be the operand of a ++ or -- operator.")
+
+(defsubst js2-check-bad-inc-dec (tt beg end unary)
+ (unless (memq (js2-node-type (js2-unary-node-operand unary))
+ js2-incrementable-node-types)
+ (js2-report-error (if (= tt js2-INC)
+ "msg.bad.incr"
+ "msg.bad.decr")
+ nil beg (- end beg))))
+
+(defun js2-parse-unary-expr ()
+ (let ((tt (js2-peek-token))
+ pn expr beg end)
+ (cond
+ ((or (= tt js2-VOID)
+ (= tt js2-NOT)
+ (= tt js2-BITNOT)
+ (= tt js2-TYPEOF))
+ (js2-consume-token)
+ (js2-make-unary tt 'js2-parse-unary-expr))
+ ((= tt js2-ADD)
+ (js2-consume-token)
+ ;; Convert to special POS token in decompiler and parse tree
+ (js2-make-unary js2-POS 'js2-parse-unary-expr))
+ ((= tt js2-SUB)
+ (js2-consume-token)
+ ;; Convert to special NEG token in decompiler and parse tree
+ (js2-make-unary js2-NEG 'js2-parse-unary-expr))
+ ((or (= tt js2-INC)
+ (= tt js2-DEC))
+ (js2-consume-token)
+ (prog1
+ (setq beg js2-token-beg
+ end js2-token-end
+ expr (js2-make-unary tt 'js2-parse-member-expr t))
+ (js2-check-bad-inc-dec tt beg end expr)))
+ ((= tt js2-DELPROP)
+ (js2-consume-token)
+ (js2-make-unary js2-DELPROP 'js2-parse-unary-expr))
+ ((= tt js2-ERROR)
+ (js2-consume-token)
+ (make-js2-error-node)) ; try to continue
+ ((and (= tt js2-LT)
+ js2-compiler-xml-available)
+ ;; XML stream encountered in expression.
+ (js2-consume-token)
+ (js2-parse-member-expr-tail t (js2-parse-xml-initializer)))
+ (t
+ (setq pn (js2-parse-member-expr t)
+ ;; Don't look across a newline boundary for a postfix incop.
+ tt (js2-peek-token-or-eol))
+ (when (or (= tt js2-INC) (= tt js2-DEC))
+ (js2-consume-token)
+ (setf expr pn
+ pn (js2-make-unary tt expr))
+ (js2-node-set-prop pn 'postfix t)
+ (js2-check-bad-inc-dec tt js2-token-beg js2-token-end pn))
+ pn))))
+
+(defun js2-parse-xml-initializer ()
+ "Parse an E4X XML initializer.
+I'm parsing it the way Rhino parses it, but without the tree-rewriting.
+Then I'll postprocess the result, depending on whether we're in IDE
+mode or codegen mode, and generate the appropriate rewritten AST.
+IDE mode uses a rich AST that models the XML structure. Codegen mode
+just concatenates everything and makes a new XML or XMLList out of it."
+ (let ((tt (js2-get-first-xml-token))
+ pn-xml
+ pn
+ expr
+ kids
+ expr-pos
+ (continue t)
+ (first-token t))
+ (when (not (or (= tt js2-XML) (= tt js2-XMLEND)))
+ (js2-report-error "msg.syntax"))
+ (setq pn-xml (make-js2-xml-node))
+ (while continue
+ (if first-token
+ (setq first-token nil)
+ (setq tt (js2-get-next-xml-token)))
+ (cond
+ ;; js2-XML means we found a {expr} in the XML stream.
+ ;; The js2-ts-string is the XML up to the left-curly.
+ ((= tt js2-XML)
+ (push (make-js2-string-node :pos js2-token-beg
+ :len (- js2-ts-cursor js2-token-beg))
+ kids)
+ (js2-must-match js2-LC "msg.syntax")
+ (setq expr-pos js2-ts-cursor
+ expr (if (eq (js2-peek-token) js2-RC)
+ (make-js2-empty-expr-node :pos expr-pos)
+ (js2-parse-expr)))
+ (js2-must-match js2-RC "msg.syntax")
+ (setq pn (make-js2-xml-js-expr-node :pos (js2-node-pos expr)
+ :len (js2-node-len expr)
+ :expr expr))
+ (js2-node-add-children pn expr)
+ (push pn kids))
+ ;; a js2-XMLEND token means we hit the final close-tag.
+ ((= tt js2-XMLEND)
+ (push (make-js2-string-node :pos js2-token-beg
+ :len (- js2-ts-cursor js2-token-beg))
+ kids)
+ (dolist (kid (nreverse kids))
+ (js2-block-node-push pn-xml kid))
+ (setf (js2-node-len pn-xml) (- js2-ts-cursor
+ (js2-node-pos pn-xml))
+ continue nil))
+ (t
+ (js2-report-error "msg.syntax")
+ (setq continue nil))))
+ pn-xml))
+
+
+(defun js2-parse-argument-list ()
+ "Parse an argument list and return it as a lisp list of nodes.
+Returns the list in reverse order. Consumes the right-paren token."
+ (let (result)
+ (unless (js2-match-token js2-RP)
+ (loop do
+ (if (= (js2-peek-token) js2-YIELD)
+ (js2-report-error "msg.yield.parenthesized"))
+ (push (js2-parse-assign-expr) result)
+ while
+ (js2-match-token js2-COMMA))
+ (js2-must-match js2-RP "msg.no.paren.arg")
+ result)))
+
+(defun js2-parse-member-expr (&optional allow-call-syntax)
+ (let ((tt (js2-peek-token))
+ pn
+ pos
+ target
+ args
+ beg
+ end
+ init
+ tail)
+ (if (/= tt js2-NEW)
+ (setq pn (js2-parse-primary-expr))
+ ;; parse a 'new' expression
+ (js2-consume-token)
+ (setq pos js2-token-beg
+ beg pos
+ target (js2-parse-member-expr)
+ end (js2-node-end target)
+ pn (make-js2-new-node :pos pos
+ :target target
+ :len (- end pos)))
+ (js2-node-add-children pn target)
+ (when (js2-match-token js2-LP)
+ ;; Add the arguments to pn, if any are supplied.
+ (setf beg pos ; start of "new" keyword
+ pos js2-token-beg
+ args (nreverse (js2-parse-argument-list))
+ (js2-new-node-args pn) args
+ end js2-token-end
+ (js2-new-node-lp pn) (- pos beg)
+ (js2-new-node-rp pn) (- end 1 beg))
+ (apply #'js2-node-add-children pn args))
+ (when (and js2-allow-rhino-new-expr-initializer
+ (js2-match-token js2-LC))
+ (setf init (js2-parse-object-literal)
+ end (js2-node-end init)
+ (js2-new-node-initializer pn) init)
+ (js2-node-add-children pn init))
+ (setf (js2-node-len pn) (- beg pos))) ; end outer if
+ (js2-parse-member-expr-tail allow-call-syntax pn)))
+
+(defun js2-parse-member-expr-tail (allow-call-syntax pn)
+ "Parse a chain of property/array accesses or function calls.
+Includes parsing for E4X operators like `..' and `.@'.
+If ALLOW-CALL-SYNTAX is nil, stops when we encounter a left-paren.
+Returns an expression tree that includes PN, the parent node."
+ (let ((beg (js2-node-pos pn))
+ tt
+ (continue t))
+ (while continue
+ (setq tt (js2-peek-token))
+ (cond
+ ((or (= tt js2-DOT) (= tt js2-DOTDOT))
+ (setq pn (js2-parse-property-access tt pn)))
+ ((= tt js2-DOTQUERY)
+ (setq pn (js2-parse-dot-query pn)))
+ ((= tt js2-LB)
+ (setq pn (js2-parse-element-get pn)))
+ ((= tt js2-LP)
+ (if allow-call-syntax
+ (setq pn (js2-parse-function-call pn))
+ (setq continue nil)))
+ (t
+ (setq continue nil))))
+ (if (>= js2-highlight-level 2)
+ (js2-parse-highlight-member-expr-node pn))
+ pn))
+
+(defun js2-parse-dot-query (pn)
+ "Parse a dot-query expression, e.g. foo.bar.(@name == 2)
+Last token parsed must be `js2-DOTQUERY'."
+ (let ((pos (js2-node-pos pn))
+ op-pos
+ expr
+ end)
+ (js2-consume-token)
+ (js2-must-have-xml)
+ (js2-set-requires-activation)
+ (setq op-pos js2-token-beg
+ expr (js2-parse-expr)
+ end (js2-node-end expr)
+ pn (make-js2-xml-dot-query-node :left pn
+ :pos pos
+ :op-pos op-pos
+ :right expr))
+ (js2-node-add-children pn
+ (js2-xml-dot-query-node-left pn)
+ (js2-xml-dot-query-node-right pn))
+ (if (js2-must-match js2-RP "msg.no.paren")
+ (setf (js2-xml-dot-query-node-rp pn) js2-token-beg
+ end js2-token-end))
+ (setf (js2-node-len pn) (- end pos))
+ pn))
+
+(defun js2-parse-element-get (pn)
+ "Parse an element-get expression, e.g. foo[bar].
+Last token parsed must be `js2-RB'."
+ (let ((lb js2-token-beg)
+ (pos (js2-node-pos pn))
+ rb
+ expr)
+ (js2-consume-token)
+ (setq expr (js2-parse-expr))
+ (if (js2-must-match js2-RB "msg.no.bracket.index")
+ (setq rb js2-token-beg))
+ (setq pn (make-js2-elem-get-node :target pn
+ :pos pos
+ :element expr
+ :lb (js2-relpos lb pos)
+ :rb (js2-relpos rb pos)
+ :len (- js2-token-end pos)))
+ (js2-node-add-children pn
+ (js2-elem-get-node-target pn)
+ (js2-elem-get-node-element pn))
+ pn))
+
+(defun js2-parse-function-call (pn)
+ (let (args
+ (pos (js2-node-pos pn)))
+ (js2-consume-token)
+ (setq pn (make-js2-call-node :pos pos
+ :target pn
+ :lp (- js2-token-beg pos)))
+ (js2-node-add-children pn (js2-call-node-target pn))
+ ;; Add the arguments to pn, if any are supplied.
+ (setf args (nreverse (js2-parse-argument-list))
+ (js2-call-node-rp pn) (- js2-token-beg pos)
+ (js2-call-node-args pn) args)
+ (apply #'js2-node-add-children pn args)
+ (setf (js2-node-len pn) (- js2-ts-cursor pos))
+ pn))
+
+(defun js2-parse-property-access (tt pn)
+ "Parse a property access, XML descendants access, or XML attr access."
+ (let ((member-type-flags 0)
+ (dot-pos js2-token-beg)
+ (dot-len (if (= tt js2-DOTDOT) 2 1))
+ name
+ ref ; right side of . or .. operator
+ result)
+ (js2-consume-token)
+ (when (= tt js2-DOTDOT)
+ (js2-must-have-xml)
+ (setq member-type-flags js2-descendants-flag))
+ (if (not js2-compiler-xml-available)
+ (progn
+ (js2-must-match-prop-name "msg.no.name.after.dot")
+ (setq name (js2-create-name-node t js2-GETPROP)
+ result (make-js2-prop-get-node :left pn
+ :pos js2-token-beg
+ :right name
+ :len (- js2-token-end
+ js2-token-beg)))
+ (js2-node-add-children result pn name)
+ result)
+ ;; otherwise look for XML operators
+ (setf result (if (= tt js2-DOT)
+ (make-js2-prop-get-node)
+ (make-js2-infix-node :type js2-DOTDOT))
+ (js2-node-pos result) (js2-node-pos pn)
+ (js2-infix-node-op-pos result) dot-pos
+ (js2-infix-node-left result) pn ; do this after setting position
+ tt (js2-next-token))
+ (cond
+ ;; needed for generator.throw()
+ ((= tt js2-THROW)
+ (js2-save-name-token-data js2-token-beg "throw")
+ (setq ref (js2-parse-property-name nil js2-ts-string member-type-flags)))
+ ;; handles: name, ns::name, ns::*, ns::[expr]
+ ((js2-valid-prop-name-token tt)
+ (setq ref (js2-parse-property-name -1 js2-ts-string member-type-flags)))
+ ;; handles: *, *::name, *::*, *::[expr]
+ ((= tt js2-MUL)
+ (js2-save-name-token-data js2-token-beg "*")
+ (setq ref (js2-parse-property-name nil "*" member-type-flags)))
+ ;; handles: '@attr', '@ns::attr', '@ns::*', '@ns::[expr]', etc.
+ ((= tt js2-XMLATTR)
+ (setq result (js2-parse-attribute-access)))
+ (t
+ (js2-report-error "msg.no.name.after.dot" nil dot-pos dot-len)))
+ (if ref
+ (setf (js2-node-len result) (- (js2-node-end ref)
+ (js2-node-pos result))
+ (js2-infix-node-right result) ref))
+ (if (js2-infix-node-p result)
+ (js2-node-add-children result
+ (js2-infix-node-left result)
+ (js2-infix-node-right result)))
+ result)))
+
+(defun js2-parse-attribute-access ()
+ "Parse an E4X XML attribute expression.
+This includes expressions of the forms:
+
+ @attr @ns::attr @ns::*
+ @* @*::attr @*::*
+ @[expr] @*::[expr] @ns::[expr]
+
+Called if we peeked an '@' token."
+ (let ((tt (js2-next-token))
+ (at-pos js2-token-beg))
+ (cond
+ ;; handles: @name, @ns::name, @ns::*, @ns::[expr]
+ ((js2-valid-prop-name-token tt)
+ (js2-parse-property-name at-pos js2-ts-string 0))
+ ;; handles: @*, @*::name, @*::*, @*::[expr]
+ ((= tt js2-MUL)
+ (js2-save-name-token-data js2-token-beg "*")
+ (js2-parse-property-name js2-token-beg "*" 0))
+ ;; handles @[expr]
+ ((= tt js2-LB)
+ (js2-parse-xml-elem-ref at-pos))
+ (t
+ (js2-report-error "msg.no.name.after.xmlAttr")
+ ;; Avoid cascaded errors that happen if we make an error node here.
+ (js2-save-name-token-data js2-token-beg "")
+ (js2-parse-property-name js2-token-beg "" 0)))))
+
+(defun js2-parse-property-name (at-pos s member-type-flags)
+ "Check if :: follows name in which case it becomes qualified name.
+
+AT-POS is a natural number if we just read an '@' token, else nil.
+S is the name or string that was matched: an identifier, 'throw' or '*'.
+MEMBER-TYPE-FLAGS is a bit set tracking whether we're a '.' or '..' child.
+
+Returns a `js2-xml-ref-node' if it's an attribute access, a child of a '..'
+operator, or the name is followed by ::. For a plain name, returns a
+`js2-name-node'. Returns a `js2-error-node' for malformed XML expressions."
+ (let ((pos (or at-pos js2-token-beg))
+ colon-pos
+ (name (js2-create-name-node t js2-current-token))
+ ns
+ tt
+ ref
+ pn)
+ (catch 'return
+ (when (js2-match-token js2-COLONCOLON)
+ (setq ns name
+ colon-pos js2-token-beg
+ tt (js2-next-token))
+ (cond
+ ;; handles name::name
+ ((js2-valid-prop-name-token tt)
+ (setq name (js2-create-name-node)))
+ ;; handles name::*
+ ((= tt js2-MUL)
+ (js2-save-name-token-data js2-token-beg "*")
+ (setq name (js2-create-name-node)))
+ ;; handles name::[expr]
+ ((= tt js2-LB)
+ (throw 'return (js2-parse-xml-elem-ref at-pos ns colon-pos)))
+ (t
+ (js2-report-error "msg.no.name.after.coloncolon"))))
+ (if (and (null ns) (zerop member-type-flags))
+ name
+ (prog1
+ (setq pn
+ (make-js2-xml-prop-ref-node :pos pos
+ :len (- (js2-node-end name) pos)
+ :at-pos at-pos
+ :colon-pos colon-pos
+ :propname name))
+ (js2-node-add-children pn name))))))
+
+(defun js2-parse-xml-elem-ref (at-pos &optional namespace colon-pos)
+ "Parse the [expr] portion of an xml element reference.
+For instance, @[expr], @*::[expr], or ns::[expr]."
+ (let* ((lb js2-token-beg)
+ (pos (or at-pos lb))
+ rb
+ (expr (js2-parse-expr))
+ (end (js2-node-end expr))
+ pn)
+ (if (js2-must-match js2-RB "msg.no.bracket.index")
+ (setq rb js2-token-beg
+ end js2-token-end))
+ (prog1
+ (setq pn
+ (make-js2-xml-elem-ref-node :pos pos
+ :len (- end pos)
+ :namespace namespace
+ :colon-pos colon-pos
+ :at-pos at-pos
+ :expr expr
+ :lb (js2-relpos lb pos)
+ :rb (js2-relpos rb pos)))
+ (js2-node-add-children pn namespace expr))))
+
+(defun js2-parse-primary-expr ()
+ "Parses a literal (leaf) expression of some sort.
+Includes complex literals such as functions, object-literals,
+array-literals, array comprehensions and regular expressions."
+ (let ((tt-flagged (js2-next-flagged-token))
+ pn ; parent node (usually return value)
+ tt
+ px-pos ; paren-expr pos
+ len
+ flags ; regexp flags
+ expr)
+ (setq tt js2-current-token)
+ (cond
+ ((= tt js2-FUNCTION)
+ (js2-parse-function 'FUNCTION_EXPRESSION))
+ ((= tt js2-LB)
+ (js2-parse-array-literal))
+ ((= tt js2-LC)
+ (js2-parse-object-literal))
+ ((= tt js2-LET)
+ (js2-parse-let js2-token-beg))
+ ((= tt js2-LP)
+ (setq px-pos js2-token-beg
+ expr (js2-parse-expr))
+ (js2-must-match js2-RP "msg.no.paren")
+ (setq pn (make-js2-paren-node :pos px-pos
+ :expr expr
+ :len (- js2-token-end px-pos)))
+ (js2-node-add-children pn (js2-paren-node-expr pn))
+ pn)
+ ((= tt js2-XMLATTR)
+ (js2-must-have-xml)
+ (js2-parse-attribute-access))
+ ((= tt js2-NAME)
+ (js2-parse-name tt-flagged tt))
+ ((= tt js2-NUMBER)
+ (make-js2-number-node))
+ ((= tt js2-STRING)
+ (prog1
+ (make-js2-string-node)
+ (js2-record-face 'font-lock-string-face)))
+ ((or (= tt js2-DIV) (= tt js2-ASSIGN_DIV))
+ ;; Got / or /= which in this context means a regexp literal
+ (setq px-pos js2-token-beg)
+ (js2-read-regexp tt)
+ (setq flags js2-ts-regexp-flags
+ js2-ts-regexp-flags nil)
+ (prog1
+ (make-js2-regexp-node :pos px-pos
+ :len (- js2-ts-cursor px-pos)
+ :value js2-ts-string
+ :flags flags)
+ (js2-set-face px-pos js2-ts-cursor 'font-lock-string-face 'record)
+ (put-text-property px-pos js2-ts-cursor 'syntax-table '(2))))
+ ((or (= tt js2-NULL)
+ (= tt js2-THIS)
+ (= tt js2-FALSE)
+ (= tt js2-TRUE))
+ (make-js2-keyword-node :type tt))
+ ((= tt js2-RESERVED)
+ (js2-report-error "msg.reserved.id")
+ (make-js2-name-node))
+ ((= tt js2-ERROR)
+ ;; the scanner or one of its subroutines reported the error.
+ (make-js2-error-node))
+ ((= tt js2-EOF)
+ (setq px-pos (point-at-bol)
+ len (- js2-ts-cursor px-pos))
+ (js2-report-error "msg.unexpected.eof" nil px-pos len)
+ (make-js2-error-node :pos px-pos :len len))
+ (t
+ (js2-report-error "msg.syntax")
+ (make-js2-error-node)))))
+
+(defun js2-parse-name (tt-flagged tt)
+ (let ((name js2-ts-string)
+ (name-pos js2-token-beg))
+ (if (and (js2-flag-set-p tt-flagged js2-ti-check-label)
+ (= (js2-peek-token) js2-COLON))
+ (prog1
+ ;; Do not consume colon, it is used as unwind indicator
+ ;; to return to statementHelper.
+ (make-js2-label-node :pos name-pos
+ :len (- js2-token-end name-pos)
+ :name name)
+ (js2-set-face name-pos
+ js2-token-end
+ 'font-lock-variable-name-face 'record))
+ ;; Otherwise not a label, just a name. Unfortunately peeking
+ ;; the next token to check for a colon has biffed js2-token-beg
+ ;; and js2-token-end. We store the name's bounds in buffer vars
+ ;; and `js2-create-name-node' uses them.
+ (js2-save-name-token-data name-pos name)
+ (if js2-compiler-xml-available
+ (js2-parse-property-name nil name 0)
+ (js2-create-name-node 'check-activation)))))
+
+(defsubst js2-parse-warn-trailing-comma (msg pos elems comma-pos)
+ (js2-add-strict-warning
+ msg nil
+ ;; back up from comma to beginning of line or array/objlit
+ (max (if elems
+ (js2-node-pos (car elems))
+ pos)
+ (save-excursion
+ (goto-char comma-pos)
+ (back-to-indentation)
+ (point)))
+ comma-pos))
+
+(defun js2-parse-array-literal ()
+ (let ((pos js2-token-beg)
+ (end js2-token-end)
+ (after-lb-or-comma t)
+ after-comma
+ tt
+ elems
+ pn
+ (continue t))
+ (while continue
+ (setq tt (js2-peek-token))
+ (cond
+ ;; comma
+ ((= tt js2-COMMA)
+ (js2-consume-token)
+ (setq after-comma js2-token-end)
+ (if (not after-lb-or-comma)
+ (setq after-lb-or-comma t)
+ (push nil elems)))
+ ;; end of array
+ ((or (= tt js2-RB)
+ (= tt js2-EOF)) ; prevent infinite loop
+ (if (= tt js2-EOF)
+ (js2-report-error "msg.no.bracket.arg" nil pos)
+ (js2-consume-token))
+ (setq continue nil
+ end js2-token-end
+ pn (make-js2-array-node :pos pos
+ :len (- js2-ts-cursor pos)
+ :elems (nreverse elems)))
+ (apply #'js2-node-add-children pn (js2-array-node-elems pn))
+ (when after-comma
+ (js2-parse-warn-trailing-comma "msg.array.trailing.comma"
+ pos elems after-comma)))
+ ;; array comp
+ ((and (>= js2-language-version 170)
+ (= tt js2-FOR) ; check for array comprehension
+ (not after-lb-or-comma) ; "for" can't follow a comma
+ elems ; must have at least 1 element
+ (not (cdr elems))) ; but no 2nd element
+ (setf continue nil
+ pn (js2-parse-array-comprehension (car elems) pos)))
+ ;; another element
+ (t
+ (unless after-lb-or-comma
+ (js2-report-error "msg.no.bracket.arg"))
+ (push (js2-parse-assign-expr) elems)
+ (setq after-lb-or-comma nil
+ after-comma nil))))
+ pn))
+
+(defun js2-parse-array-comprehension (expr pos)
+ "Parse a JavaScript 1.7 Array Comprehension.
+EXPR is the first expression after the opening left-bracket.
+POS is the beginning of the LB token preceding EXPR.
+We should have just parsed the 'for' keyword before calling this function."
+ (let (loops
+ filter
+ if-pos
+ result)
+ (while (= (js2-peek-token) js2-FOR)
+ (push (js2-parse-array-comp-loop) loops))
+ (when (= (js2-peek-token) js2-IF)
+ (js2-consume-token)
+ (setq if-pos (- js2-token-beg pos) ; relative
+ filter (js2-parse-condition)))
+ (js2-must-match js2-RB "msg.no.bracket.arg" pos)
+ (setq result (make-js2-array-comp-node :pos pos
+ :len (- js2-ts-cursor pos)
+ :result expr
+ :loops (nreverse loops)
+ :filter (car filter)
+ :lp (js2-relpos (second filter) pos)
+ :rp (js2-relpos (third filter) pos)
+ :if-pos if-pos))
+ (apply #'js2-node-add-children result expr (car filter)
+ (js2-array-comp-node-loops result))
+ result))
+
+(defun js2-parse-array-comp-loop ()
+ "Parse a 'for [each] (foo in bar)' expression in an Array comprehension.
+Last token peeked should be the initial FOR."
+ (let ((pos js2-token-beg)
+ (pn (make-js2-array-comp-loop-node))
+ tt
+ iter
+ obj
+ foreach-p
+ in-pos
+ each-pos
+ lp
+ rp)
+ (assert (= (js2-next-token) js2-FOR)) ; consumes token
+ (js2-push-scope pn)
+ (unwind-protect
+ (progn
+ (when (js2-match-token js2-NAME)
+ (if (string= js2-ts-string "each")
+ (progn
+ (setq foreach-p t
+ each-pos (- js2-token-beg pos)) ; relative
+ (js2-record-face 'font-lock-keyword-face))
+ (js2-report-error "msg.no.paren.for")))
+ (if (js2-must-match js2-LP "msg.no.paren.for")
+ (setq lp (- js2-token-beg pos)))
+ (setq tt (js2-peek-token))
+ (cond
+ ((or (= tt js2-LB)
+ (= tt js2-LC))
+ ;; handle destructuring assignment
+ (setq iter (js2-parse-primary-expr)))
+ ((js2-valid-prop-name-token tt)
+ (js2-consume-token)
+ (setq iter (js2-create-name-node)))
+ (t
+ (js2-report-error "msg.bad.var")))
+ ;; Define as a let since we want the scope of the variable to
+ ;; be restricted to the array comprehension
+ (if (js2-name-node-p iter)
+ (js2-define-symbol js2-LET (js2-name-node-name iter) pn t))
+ (if (js2-must-match js2-IN "msg.in.after.for.name")
+ (setq in-pos (- js2-token-beg pos)))
+ (setq obj (js2-parse-expr))
+ (if (js2-must-match js2-RP "msg.no.paren.for.ctrl")
+ (setq rp (- js2-token-beg pos)))
+ (setf (js2-node-pos pn) pos
+ (js2-node-len pn) (- js2-ts-cursor pos)
+ (js2-array-comp-loop-node-iterator pn) iter
+ (js2-array-comp-loop-node-object pn) obj
+ (js2-array-comp-loop-node-in-pos pn) in-pos
+ (js2-array-comp-loop-node-each-pos pn) each-pos
+ (js2-array-comp-loop-node-foreach-p pn) foreach-p
+ (js2-array-comp-loop-node-lp pn) lp
+ (js2-array-comp-loop-node-rp pn) rp)
+ (js2-node-add-children pn iter obj))
+ (js2-pop-scope))
+ pn))
+
+(defun js2-parse-object-literal ()
+ (let ((pos js2-token-beg)
+ tt
+ elems
+ result
+ after-comma
+ (continue t))
+ (while continue
+ (setq tt (js2-peek-token))
+ (cond
+ ;; {foo: ...}, {'foo': ...}, {get foo() {...}}, or {set foo(x) {...}}
+ ((or (js2-valid-prop-name-token tt)
+ (= tt js2-STRING))
+ (setq after-comma nil
+ result (js2-parse-named-prop tt))
+ (if (and (null result)
+ (not js2-recover-from-parse-errors))
+ (setq continue nil)
+ (push result elems)))
+ ;; {12: x} or {10.7: x}
+ ((= tt js2-NUMBER)
+ (js2-consume-token)
+ (setq after-comma nil)
+ (push (js2-parse-plain-property (make-js2-number-node)) elems))
+ ;; trailing comma
+ ((= tt js2-RC)
+ (setq continue nil)
+ (if after-comma
+ (js2-parse-warn-trailing-comma "msg.extra.trailing.comma"
+ pos elems after-comma)))
+ (t
+ (js2-report-error "msg.bad.prop")
+ (unless js2-recover-from-parse-errors
+ (setq continue nil)))) ; end switch
+ (if (js2-match-token js2-COMMA)
+ (setq after-comma js2-token-end)
+ (setq continue nil))) ; end loop
+ (js2-must-match js2-RC "msg.no.brace.prop")
+ (setq result (make-js2-object-node :pos pos
+ :len (- js2-ts-cursor pos)
+ :elems (nreverse elems)))
+ (apply #'js2-node-add-children result (js2-object-node-elems result))
+ result))
+
+(defun js2-parse-named-prop (tt)
+ "Parse a name, string, or getter/setter object property."
+ (js2-consume-token)
+ (let ((string-prop (and (= tt js2-STRING)
+ (make-js2-string-node)))
+ expr
+ (ppos js2-token-beg)
+ (pend js2-token-end)
+ (name (js2-create-name-node))
+ (prop js2-ts-string))
+ (if (and (= tt js2-NAME)
+ (= (js2-peek-token) js2-NAME)
+ (or (string= prop "get")
+ (string= prop "set")))
+ (progn
+ ;; getter/setter prop
+ (js2-consume-token)
+ (js2-set-face ppos pend 'font-lock-keyword-face 'record) ; get/set
+ (js2-record-face 'font-lock-function-name-face) ; for peeked name
+ (setq name (js2-create-name-node)) ; discard get/set & use peeked name
+ (js2-parse-getter-setter-prop ppos name (string= prop "get")))
+ ;; regular prop
+ (prog1
+ (setq expr (js2-parse-plain-property (or string-prop name)))
+ (js2-set-face ppos pend
+ (if (js2-function-node-p
+ (js2-object-prop-node-right expr))
+ 'font-lock-function-name-face
+ 'font-lock-variable-name-face)
+ 'record)))))
+
+(defun js2-parse-plain-property (prop)
+ "Parse a non-getter/setter property in an object literal.
+PROP is the node representing the property: a number, name or string."
+ (js2-must-match js2-COLON "msg.no.colon.prop")
+ (let* ((pos (js2-node-pos prop))
+ (colon (- js2-token-beg pos))
+ (expr (js2-parse-assign-expr))
+ (result (make-js2-object-prop-node
+ :pos pos
+ ;; don't include last consumed token in length
+ :len (- (+ (js2-node-pos expr)
+ (js2-node-len expr))
+ pos)
+ :left prop
+ :right expr
+ :op-pos colon)))
+ (js2-node-add-children result prop expr)
+ result))
+
+(defun js2-parse-getter-setter-prop (pos prop get-p)
+ "Parse getter or setter property in an object literal.
+JavaScript syntax is:
+
+ { get foo() {...}, set foo(x) {...} }
+
+POS is the start position of the `get' or `set' keyword.
+PROP is the `js2-name-node' representing the property name.
+GET-P is non-nil if the keyword was `get'."
+ (let ((type (if get-p js2-GET js2-SET))
+ result
+ end
+ (fn (js2-parse-function 'FUNCTION_EXPRESSION)))
+ ;; it has to be an anonymous function, as we already parsed the name
+ (if (/= (js2-node-type fn) js2-FUNCTION)
+ (js2-report-error "msg.bad.prop")
+ (if (plusp (length (js2-function-name fn)))
+ (js2-report-error "msg.bad.prop")))
+ (js2-node-set-prop fn 'GETTER_SETTER type) ; for codegen
+ (setq end (js2-node-end fn)
+ result (make-js2-getter-setter-node :type type
+ :pos pos
+ :len (- end pos)
+ :left prop
+ :right fn))
+ (js2-node-add-children result prop fn)
+ result))
+
+(defun js2-create-name-node (&optional check-activation-p token)
+ "Create a name node using the token info from last scanned name.
+In some cases we need to either synthesize a name node, or we lost
+the name token information by peeking. If the TOKEN parameter is
+not `js2-NAME', then we use the token info saved in instance vars."
+ (let ((beg js2-token-beg)
+ (s js2-ts-string)
+ name)
+ (when (/= js2-current-token js2-NAME)
+ (setq beg (or js2-prev-name-token-start js2-ts-cursor)
+ s js2-prev-name-token-string
+ js2-prev-name-token-start nil
+ js2-prev-name-token-string nil))
+ (setq name (make-js2-name-node :pos beg
+ :name s
+ :len (length s)))
+ (if check-activation-p
+ (js2-check-activation-name s (or token js2-NAME)))
+ name))
+
+;;; Indentation support
+
+;; This indenter is based on Karl Landström's "javascript.el" indenter.
+;; Karl cleverly deduces that the desired indentation level is often a
+;; function of paren/bracket/brace nesting depth, which can be determined
+;; quickly via the built-in `parse-partial-sexp' function. His indenter
+;; then does some equally clever checks to see if we're in the context of a
+;; substatement of a possibly braceless statement keyword such as if, while,
+;; or finally. This approach yields pretty good results.
+
+;; The indenter is often "wrong", however, and needs to be overridden.
+;; The right long-term solution is probably to emulate (or integrate
+;; with) cc-engine, but it's a nontrivial amount of coding. Even when a
+;; parse tree from `js2-parse' is present, which is not true at the
+;; moment the user is typing, computing indentation is still thousands
+;; of lines of code to handle every possible syntactic edge case.
+
+;; In the meantime, the compromise solution is that we offer a "bounce
+;; indenter", configured with `js2-bounce-indent-p', which cycles the
+;; current line indent among various likely guess points. This approach
+;; is far from perfect, but should at least make it slightly easier to
+;; move the line towards its desired indentation when manually
+;; overriding Karl's heuristic nesting guesser.
+
+;; I've made miscellaneous tweaks to Karl's code to handle some Ecma
+;; extensions such as `let' and Array comprehensions. Major kudos to
+;; Karl for coming up with the initial approach, which packs a lot of
+;; punch for so little code.
+
+(defconst js-possibly-braceless-keyword-re
+ (regexp-opt
+ '("catch" "do" "else" "finally" "for" "if" "try" "while" "with" "let")
+ 'words)
+ "Regular expression matching keywords that are optionally
+followed by an opening brace.")
+
+(defconst js-indent-operator-re
+ (concat "[-+*/%<>=&^|?:.]\\([^-+*/]\\|$\\)\\|"
+ (regexp-opt '("in" "instanceof") 'words))
+ "Regular expression matching operators that affect indentation
+of continued expressions.")
+
+;; This function has horrible results if you're typing an array
+;; such as [[1, 2], [3, 4], [5, 6]]. Bounce indenting -really- sucks
+;; in conjunction with electric-indent, so just disabling it.
+(defsubst js2-code-at-bol-p ()
+ "Return t if the first character on line is non-whitespace."
+ nil)
+
+(defun js2-insert-and-indent (key)
+ "Run command bound to key and indent current line. Runs the command
+bound to KEY in the global keymap and indents the current line."
+ (interactive (list (this-command-keys)))
+ (let ((cmd (lookup-key (current-global-map) key)))
+ (if (commandp cmd)
+ (call-interactively cmd)))
+ ;; don't do the electric keys inside comments or strings,
+ ;; and don't do bounce-indent with them.
+ (let ((parse-state (parse-partial-sexp (point-min) (point)))
+ (js2-bounce-indent-p (js2-code-at-bol-p)))
+ (unless (or (nth 3 parse-state)
+ (nth 4 parse-state))
+ (indent-according-to-mode))))
+
+(defun js-re-search-forward-inner (regexp &optional bound count)
+ "Auxiliary function for `js-re-search-forward'."
+ (let ((parse)
+ (saved-point (point-min)))
+ (while (> count 0)
+ (re-search-forward regexp bound)
+ (setq parse (parse-partial-sexp saved-point (point)))
+ (cond ((nth 3 parse)
+ (re-search-forward
+ (concat "\\([^\\]\\|^\\)" (string (nth 3 parse)))
+ (save-excursion (end-of-line) (point)) t))
+ ((nth 7 parse)
+ (forward-line))
+ ((or (nth 4 parse)
+ (and (eq (char-before) ?\/) (eq (char-after) ?\*)))
+ (re-search-forward "\\*/"))
+ (t
+ (setq count (1- count))))
+ (setq saved-point (point))))
+ (point))
+
+(defun js-re-search-forward (regexp &optional bound noerror count)
+ "Search forward but ignore strings and comments. Invokes
+`re-search-forward' but treats the buffer as if strings and
+comments have been removed."
+ (let ((saved-point (point))
+ (search-expr
+ (cond ((null count)
+ '(js-re-search-forward-inner regexp bound 1))
+ ((< count 0)
+ '(js-re-search-backward-inner regexp bound (- count)))
+ ((> count 0)
+ '(js-re-search-forward-inner regexp bound count)))))
+ (condition-case err
+ (eval search-expr)
+ (search-failed
+ (goto-char saved-point)
+ (unless noerror
+ (error (error-message-string err)))))))
+
+(defun js-re-search-backward-inner (regexp &optional bound count)
+ "Auxiliary function for `js-re-search-backward'."
+ (let ((parse)
+ (saved-point (point-min)))
+ (while (> count 0)
+ (re-search-backward regexp bound)
+ (setq parse (parse-partial-sexp saved-point (point)))
+ (cond ((nth 3 parse)
+ (re-search-backward
+ (concat "\\([^\\]\\|^\\)" (string (nth 3 parse)))
+ (save-excursion (beginning-of-line) (point)) t))
+ ((nth 7 parse)
+ (goto-char (nth 8 parse)))
+ ((or (nth 4 parse)
+ (and (eq (char-before) ?/) (eq (char-after) ?*)))
+ (re-search-backward "/\\*"))
+ (t
+ (setq count (1- count))))))
+ (point))
+
+(defun js-re-search-backward (regexp &optional bound noerror count)
+ "Search backward but ignore strings and comments. Invokes
+`re-search-backward' but treats the buffer as if strings and
+comments have been removed."
+ (let ((saved-point (point))
+ (search-expr
+ (cond ((null count)
+ '(js-re-search-backward-inner regexp bound 1))
+ ((< count 0)
+ '(js-re-search-forward-inner regexp bound (- count)))
+ ((> count 0)
+ '(js-re-search-backward-inner regexp bound count)))))
+ (condition-case err
+ (eval search-expr)
+ (search-failed
+ (goto-char saved-point)
+ (unless noerror
+ (error (error-message-string err)))))))
+
+(defun js-looking-at-operator-p ()
+ "Return non-nil if text after point is an operator (that is not
+a comma)."
+ (save-match-data
+ (and (looking-at js-indent-operator-re)
+ (or (not (looking-at ":"))
+ (save-excursion
+ (and (js-re-search-backward "[?:{]\\|\\<case\\>" nil t)
+ (looking-at "?")))))))
+
+(defun js-continued-expression-p ()
+ "Returns non-nil if the current line continues an expression."
+ (save-excursion
+ (back-to-indentation)
+ (or (js-looking-at-operator-p)
+ (and (js-re-search-backward "\n" nil t)
+ (progn
+ (skip-chars-backward " \t")
+ (backward-char)
+ (and (js-looking-at-operator-p)
+ (and (progn (backward-char)
+ (not (looking-at "\\*\\|++\\|--\\|/[/*]"))))))))))
+
+(defun js-end-of-do-while-loop-p ()
+ "Returns non-nil if word after point is `while' of a do-while
+statement, else returns nil. A braceless do-while statement
+spanning several lines requires that the start of the loop is
+indented to the same column as the current line."
+ (interactive)
+ (save-excursion
+ (save-match-data
+ (when (looking-at "\\s-*\\<while\\>")
+ (if (save-excursion
+ (skip-chars-backward "[ \t\n]*}")
+ (looking-at "[ \t\n]*}"))
+ (save-excursion
+ (backward-list) (backward-word 1) (looking-at "\\<do\\>"))
+ (js-re-search-backward "\\<do\\>" (point-at-bol) t)
+ (or (looking-at "\\<do\\>")
+ (let ((saved-indent (current-indentation)))
+ (while (and (js-re-search-backward "^[ \t]*\\<" nil t)
+ (/= (current-indentation) saved-indent)))
+ (and (looking-at "[ \t]*\\<do\\>")
+ (not (js-re-search-forward
+ "\\<while\\>" (point-at-eol) t))
+ (= (current-indentation) saved-indent)))))))))
+
+(defun js-ctrl-statement-indentation ()
+ "Returns the proper indentation of the current line if it
+starts the body of a control statement without braces, else
+returns nil."
+ (let (forward-sexp-function) ; temporarily unbind it
+ (save-excursion
+ (back-to-indentation)
+ (when (save-excursion
+ (and (not (js2-same-line (point-min)))
+ (not (looking-at "{"))
+ (js-re-search-backward "[[:graph:]]" nil t)
+ (not (looking-at "[{([]"))
+ (progn
+ (forward-char)
+ ;; scan-sexps sometimes throws an error
+ (ignore-errors (backward-sexp))
+ (when (looking-at "(") (backward-word 1))
+ (and (save-excursion
+ (skip-chars-backward " \t}" (point-at-bol))
+ (bolp))
+ (looking-at js-possibly-braceless-keyword-re)
+ (not (js-end-of-do-while-loop-p))))))
+ (save-excursion
+ (goto-char (match-beginning 0))
+ (+ (current-indentation) js2-basic-offset))))))
+
+(defun js2-indent-in-array-comp (parse-status)
+ "Return non-nil if we think we're in an array comprehension.
+In particular, return the buffer position of the first `for' kwd."
+ (let ((end (point)))
+ (when (nth 1 parse-status)
+ (save-excursion
+ (goto-char (nth 1 parse-status))
+ (when (looking-at "\\[")
+ (forward-char 1)
+ (js2-forward-sws)
+ (if (looking-at "[[{]")
+ (let (forward-sexp-function) ; use lisp version
+ (forward-sexp) ; skip destructuring form
+ (js2-forward-sws)
+ (if (and (/= (char-after) ?,) ; regular array
+ (looking-at "for"))
+ (match-beginning 0)))
+ ;; to skip arbitrary expressions we need the parser,
+ ;; so we'll just guess at it.
+ (if (re-search-forward "[^,]* \\(for\\) " end t)
+ (match-beginning 1))))))))
+
+(defun js2-array-comp-indentation (parse-status for-kwd)
+ (if (js2-same-line for-kwd)
+ ;; first continuation line
+ (save-excursion
+ (goto-char (nth 1 parse-status))
+ (forward-char 1)
+ (skip-chars-forward " \t")
+ (current-column))
+ (save-excursion
+ (goto-char for-kwd)
+ (current-column))))
+
+(defun js-proper-indentation (parse-status)
+ "Return the proper indentation for the current line."
+ (save-excursion
+ (back-to-indentation)
+ (let ((ctrl-stmt-indent (js-ctrl-statement-indentation))
+ (same-indent-p (looking-at "[]})]\\|\\<case\\>\\|\\<default\\>"))
+ (continued-expr-p (js-continued-expression-p))
+ (bracket (nth 1 parse-status))
+ beg)
+ (cond
+ ;; indent array comprehension continuation lines specially
+ ((and bracket
+ (not (js2-same-line bracket))
+ (setq beg (js2-indent-in-array-comp parse-status))
+ (>= (point) (save-excursion
+ (goto-char beg)
+ (point-at-bol)))) ; at or after first loop?
+ (js2-array-comp-indentation parse-status beg))
+
+ (ctrl-stmt-indent)
+
+ (bracket
+ (goto-char bracket)
+ (cond
+ ((looking-at "[({[][ \t]*\\(/[/*]\\|$\\)")
+ (let ((p (parse-partial-sexp (point-at-bol) (point))))
+ (when (save-excursion (skip-chars-backward " \t)")
+ (looking-at ")"))
+ (backward-list))
+ (if (nth 1 p)
+ (progn (goto-char (1+ (nth 1 p)))
+ (skip-chars-forward " \t"))
+ (back-to-indentation))
+ (cond (same-indent-p
+ (current-column))
+ (continued-expr-p
+ (+ (current-column) (* 2 js2-basic-offset)))
+ (t
+ (+ (current-column) js2-basic-offset)))))
+ (t
+ (unless same-indent-p
+ (forward-char)
+ (skip-chars-forward " \t"))
+ (current-column))))
+
+ (continued-expr-p js2-basic-offset)
+ (t 0)))))
+
+(defun js2-lineup-comment (parse-status)
+ "Indent a multi-line block comment continuation line."
+ (let* ((beg (nth 8 parse-status))
+ (first-line (js2-same-line beg))
+ (offset (save-excursion
+ (goto-char beg)
+ (if (looking-at "/\\*")
+ (+ 1 (current-column))
+ 0))))
+ (unless first-line
+ (indent-line-to offset))))
+
+(defun js2-backward-sws ()
+ "Move backward through whitespace and comments."
+ (interactive)
+ (while (forward-comment -1)))
+
+(defun js2-forward-sws ()
+ "Move forward through whitespace and comments."
+ (interactive)
+ (while (forward-comment 1)))
+
+(defsubst js2-current-indent (&optional pos)
+ "Return column of indentation on current line.
+If POS is non-nil, go to that point and return indentation for that line."
+ (save-excursion
+ (if pos
+ (goto-char pos))
+ (back-to-indentation)
+ (current-column)))
+
+(defsubst js2-arglist-close ()
+ "Return non-nil if we're on a line beginning with a close-paren/brace."
+ (save-match-data
+ (save-excursion
+ (goto-char (point-at-bol))
+ (js2-forward-sws)
+ (looking-at "[])}]"))))
+
+(defsubst js2-indent-looks-like-label-p ()
+ (goto-char (point-at-bol))
+ (js2-forward-sws)
+ (looking-at (concat js2-mode-identifier-re ":")))
+
+(defun js2-indent-in-objlit-p (parse-status)
+ "Return non-nil if this looks like an object-literal entry."
+ (let ((start (nth 1 parse-status)))
+ (and
+ start
+ (save-excursion
+ (and (zerop (forward-line -1))
+ (not (< (point) start)) ; crossed a {} boundary
+ (js2-indent-looks-like-label-p)))
+ (save-excursion
+ (js2-indent-looks-like-label-p)))))
+
+;; if prev line looks like foobar({ then we're passing an object
+;; literal to a function call, and people pretty much always want to
+;; de-dent back to the previous line, so move the 'basic-offset'
+;; position to the front.
+(defsubst js2-indent-objlit-arg-p (parse-status)
+ (save-excursion
+ (back-to-indentation)
+ (js2-backward-sws)
+ (and (eq (1- (point)) (nth 1 parse-status))
+ (eq (char-before) ?{)
+ (progn
+ (forward-char -1)
+ (skip-chars-backward " \t")
+ (eq (char-before) ?\()))))
+
+(defsubst js2-indent-case-block-p ()
+ (save-excursion
+ (back-to-indentation)
+ (js2-backward-sws)
+ (goto-char (point-at-bol))
+ (skip-chars-forward " \t")
+ (save-match-data
+ (looking-at "case\\s-.+:"))))
+
+(defsubst js2-syntax-bol ()
+ "Return the point at the first non-whitespace char on the line.
+Returns `point-at-bol' if the line is empty."
+ (save-excursion
+ (beginning-of-line)
+ (skip-chars-forward " \t")
+ (point)))
+
+(defun js2-bounce-indent (normal-col parse-status)
+ "Cycle among alternate computed indentation positions.
+PARSE-STATUS is the result of `parse-partial-sexp' from the beginning
+of the buffer to the current point. NORMAL-COL is the indentation
+column computed by the heuristic guesser based on current paren,
+bracket, brace and statement nesting."
+ (let ((cur-indent (js2-current-indent))
+ (old-buffer-undo-list buffer-undo-list)
+ ;; Emacs 21 only has `count-lines', not `line-number-at-pos'
+ (current-line (save-excursion
+ (forward-line 0) ; move to bol
+ (1+ (count-lines (point-min) (point)))))
+ positions
+ pos
+ anchor
+ arglist-cont
+ same-indent
+ prev-line-col
+ basic-offset
+ computed-pos)
+ ;; temporarily don't record undo info, if user requested this
+ (if js2-mode-indent-inhibit-undo
+ (setq buffer-undo-list t))
+ (unwind-protect
+ (progn
+ ;; first likely point: indent from beginning of previous code line
+ (push (setq basic-offset
+ (+ (save-excursion
+ (back-to-indentation)
+ (js2-backward-sws)
+ (back-to-indentation)
+ (setq prev-line-col (current-column)))
+ js2-basic-offset))
+ positions)
+
+ ;; (first + epsilon) likely point: indent 2x from beginning of
+ ;; previous code line. Some companies like this approach. Ahem.
+ ;; Seriously, though -- 4-space indent for expression continuation
+ ;; lines isn't a bad idea. We should eventually implement it
+ ;; that way.
+ (push (setq basic-offset
+ (+ (save-excursion
+ (back-to-indentation)
+ (js2-backward-sws)
+ (back-to-indentation)
+ (setq prev-line-col (current-column)))
+ (* 2 js2-basic-offset)))
+ positions)
+
+ ;; second likely point: indent from assign-expr RHS. This
+ ;; is just a crude guess based on finding " = " on the previous
+ ;; line containing actual code.
+ (setq pos (save-excursion
+ (save-match-data
+ (forward-line -1)
+ (goto-char (point-at-bol))
+ (when (re-search-forward "\\s-+\\(=\\)\\s-+"
+ (point-at-eol) t)
+ (goto-char (match-end 1))
+ (skip-chars-forward " \t\r\n")
+ (current-column)))))
+ (when pos
+ (incf pos js2-basic-offset)
+ (unless (member pos positions)
+ (push pos positions)))
+
+ ;; third likely point: same indent as previous line of code.
+ ;; Make it the first likely point if we're not on an
+ ;; arglist-close line and previous line ends in a comma, or
+ ;; both this line and prev line look like object-literal
+ ;; elements.
+ (setq pos (save-excursion
+ (goto-char (point-at-bol))
+ (js2-backward-sws)
+ (back-to-indentation)
+ (prog1
+ (current-column)
+ ;; while we're here, look for trailing comma
+ (if (save-excursion
+ (goto-char (point-at-eol))
+ (js2-backward-sws)
+ (eq (char-before) ?,))
+ (setq arglist-cont (1- (point)))))))
+ (when pos
+ (if (and (or arglist-cont
+ (js2-indent-in-objlit-p parse-status))
+ (not (js2-arglist-close)))
+ (setq same-indent pos))
+ (unless (member pos positions)
+ (push pos positions)))
+
+ ;; fourth likely point: first preceding code with less indentation
+ ;; than the immediately preceding code line.
+ (setq pos (save-excursion
+ (js2-backward-sws)
+ (back-to-indentation)
+ (setq anchor (current-column))
+ (while (and (zerop (forward-line -1))
+ (>= (progn
+ (back-to-indentation)
+ (current-column))
+ anchor)))
+ (setq pos (current-column))))
+ (unless (member pos positions)
+ (push pos positions))
+
+ ;; put nesting-heuristic position first in list, sort rest
+ (setq positions (nreverse (sort positions '<)))
+ (setq positions (cons normal-col (delete normal-col positions)))
+
+ ;; comma-list continuation lines: prev line indent takes precedence
+ (if same-indent
+ (setq positions
+ (cons same-indent
+ (sort (delete same-indent positions) '<))))
+
+ ;; common special cases where we want to indent in from previous line
+ (if (or (js2-indent-case-block-p)
+ (js2-indent-objlit-arg-p parse-status))
+ (setq positions
+ (cons basic-offset
+ (delete basic-offset positions))))
+
+ ;; record whether we're already sitting on one of the alternatives
+ (setq pos (member cur-indent positions))
+ (cond
+ ;; case 0: we're one one of the alternatives and this is the
+ ;; first time they've pressed TAB on this line (best-guess).
+ ((and js2-mode-indent-ignore-first-tab
+ pos
+ ;; first time pressing TAB on this line?
+ (not (eq js2-mode-last-indented-line current-line)))
+ ;; do nothing
+ (setq computed-pos nil))
+ ;; case 1: only one computed position => use it
+ ((null (cdr positions))
+ (setq computed-pos 0))
+ ;; case 2: not on any of the computed spots => use main spot
+ ((not pos)
+ (setq computed-pos 0))
+ ;; case 3: on last position: cycle to first position
+ ((null (cdr pos))
+ (setq computed-pos 0))
+ ;; case 4: on intermediate position: cycle to next position
+ (t
+ (setq computed-pos (js2-position (second pos) positions))))
+
+ ;; see if any hooks want to indent; otherwise we do it
+ (loop with result = nil
+ for hook in js2-indent-hook
+ while (null result)
+ do
+ (setq result (funcall hook positions computed-pos))
+ finally do
+ (unless (or result (null computed-pos))
+ (indent-line-to (nth computed-pos positions)))))
+
+ ;; finally
+ (if js2-mode-indent-inhibit-undo
+ (setq buffer-undo-list old-buffer-undo-list))
+ ;; see commentary for `js2-mode-last-indented-line'
+ (setq js2-mode-last-indented-line current-line))))
+
+(defsubst js2-1-line-comment-continuation-p ()
+ "Return t if we're in a 1-line comment continuation.
+If so, we don't ever want to use bounce-indent."
+ (save-excursion
+ (save-match-data
+ (and (progn
+ (forward-line 0)
+ (looking-at "\\s-*//"))
+ (progn
+ (forward-line -1)
+ (forward-line 0)
+ (when (looking-at "\\s-*$")
+ (js2-backward-sws)
+ (forward-line 0))
+ (looking-at "\\s-*//"))))))
+
+(defun js2-indent-line ()
+ "Indent the current line as JavaScript source text."
+ (interactive)
+ (let (parse-status
+ current-indent
+ offset
+ indent-col
+ moved
+ ;; don't whine about errors/warnings when we're indenting.
+ ;; This has to be set before calling parse-partial-sexp below.
+ (inhibit-point-motion-hooks t))
+ (setq parse-status (save-excursion
+ (parse-partial-sexp (point-min)
+ (point-at-bol)))
+ offset (- (point) (save-excursion
+ (back-to-indentation)
+ (setq current-indent (current-column))
+ (point))))
+ (js2-with-underscore-as-word-syntax
+ (if (nth 4 parse-status)
+ (js2-lineup-comment parse-status)
+ (setq indent-col (js-proper-indentation parse-status))
+ ;; see comments below about js2-mode-last-indented-line
+ (when
+ (cond
+ ;; bounce-indenting is disabled during electric-key indent.
+ ;; It doesn't work well on first line of buffer.
+ ((and js2-bounce-indent-p
+ (not (js2-same-line (point-min)))
+ (not (js2-1-line-comment-continuation-p)))
+ (js2-bounce-indent indent-col parse-status)
+ (setq moved t))
+ ;; just indent to the guesser's likely spot
+ ((/= current-indent indent-col)
+ (indent-line-to indent-col)
+ (setq moved t)))
+ (when (and moved (plusp offset))
+ (forward-char offset)))))))
+
+(defun js2-indent-region (start end)
+ "Indent the region, but don't use bounce indenting."
+ (let ((js2-bounce-indent-p nil)
+ (indent-region-function nil))
+ (indent-region start end nil))) ; nil for byte-compiler
+
+;;;###autoload (add-to-list 'auto-mode-alist '("\\.js$" . js2-mode))
+
+;;;###autoload
+(defun js2-mode ()
+ "Major mode for editing JavaScript code."
+ (interactive)
+ (kill-all-local-variables)
+ (set-syntax-table js2-mode-syntax-table)
+ (use-local-map js2-mode-map)
+ (setq major-mode 'js2-mode
+ mode-name "JavaScript-IDE"
+ comment-start "//" ; used by comment-region; don't change it
+ comment-end "")
+ (setq local-abbrev-table js2-mode-abbrev-table)
+ (set (make-local-variable 'max-lisp-eval-depth)
+ (max max-lisp-eval-depth 3000))
+ (set (make-local-variable 'indent-line-function) #'js2-indent-line)
+ (set (make-local-variable 'indent-region-function) #'js2-indent-region)
+
+ ;; I tried an "improvement" to `c-fill-paragraph' that worked out badly
+ ;; on most platforms other than the one I originally wrote it on. So it's
+ ;; back to `c-fill-paragraph'. Still not perfect, though -- something to do
+ ;; with our binding of the RET key inside comments: short lines stay short.
+ (set (make-local-variable 'fill-paragraph-function) #'c-fill-paragraph)
+
+ (set (make-local-variable 'before-save-hook) #'js2-before-save)
+ (set (make-local-variable 'next-error-function) #'js2-next-error)
+ (set (make-local-variable 'beginning-of-defun-function) #'js2-beginning-of-defun)
+ (set (make-local-variable 'end-of-defun-function) #'js2-end-of-defun)
+ ;; we un-confuse `parse-partial-sexp' by setting syntax-table properties
+ ;; for characters inside regexp literals.
+ (set (make-local-variable 'parse-sexp-lookup-properties) t)
+ ;; this is necessary to make `show-paren-function' work properly
+ (set (make-local-variable 'parse-sexp-ignore-comments) t)
+ ;; needed for M-x rgrep, among other things
+ (put 'js2-mode 'find-tag-default-function #'js2-mode-find-tag)
+
+ ;; some variables needed by cc-engine for paragraph-fill, etc.
+ (setq c-buffer-is-cc-mode t
+ c-comment-prefix-regexp js2-comment-prefix-regexp
+ c-comment-start-regexp "/[*/]\\|\\s|"
+ c-paragraph-start js2-paragraph-start
+ c-paragraph-separate "$"
+ comment-start-skip js2-comment-start-skip
+ c-syntactic-ws-start js2-syntactic-ws-start
+ c-syntactic-ws-end js2-syntactic-ws-end
+ c-syntactic-eol js2-syntactic-eol)
+
+ (setq js2-default-externs
+ (append js2-ecma-262-externs
+ (if js2-include-browser-externs
+ js2-browser-externs)
+ (if js2-include-gears-externs
+ js2-gears-externs)
+ (if js2-include-rhino-externs
+ js2-rhino-externs)))
+
+ ;; We do our own syntax highlighting based on the parse tree.
+ ;; However, we want minor modes that add keywords to highlight properly
+ ;; (examples: doxymacs, column-marker). We do this by not letting
+ ;; font-lock unfontify anything, and telling it to fontify after we
+ ;; re-parse and re-highlight the buffer. (We currently don't do any
+ ;; work with regions other than the whole buffer.)
+ (dolist (var '(font-lock-unfontify-buffer-function
+ font-lock-unfontify-region-function))
+ (set (make-local-variable var) (lambda (&rest args) t)))
+
+ ;; Don't let font-lock do syntactic (string/comment) fontification.
+ (set (make-local-variable #'font-lock-syntactic-face-function)
+ (lambda (state) nil))
+
+ ;; Experiment: make reparse-delay longer for longer files.
+ (if (plusp js2-dynamic-idle-timer-adjust)
+ (setq js2-idle-timer-delay
+ (* js2-idle-timer-delay
+ (/ (point-max) js2-dynamic-idle-timer-adjust))))
+
+ (add-hook 'change-major-mode-hook #'js2-mode-exit nil t)
+ (add-hook 'after-change-functions #'js2-mode-edit nil t)
+ (setq imenu-create-index-function #'js2-mode-create-imenu-index)
+ (imenu-add-to-menubar (concat "IM-" mode-name))
+ (when js2-mirror-mode
+ (js2-enter-mirror-mode))
+ (add-to-invisibility-spec '(js2-outline . t))
+ (set (make-local-variable 'line-move-ignore-invisible) t)
+ (set (make-local-variable 'forward-sexp-function) #'js2-mode-forward-sexp)
+ (setq js2-mode-functions-hidden nil
+ js2-mode-comments-hidden nil
+ js2-mode-buffer-dirty-p t
+ js2-mode-parsing nil)
+ (js2-reparse)
+ (run-hooks 'js2-mode-hook))
+
+(defun js2-mode-exit ()
+ "Exit `js2-mode' and clean up."
+ (interactive)
+ (when js2-mode-node-overlay
+ (delete-overlay js2-mode-node-overlay)
+ (setq js2-mode-node-overlay nil))
+ (js2-remove-overlays)
+ (setq js2-mode-ast nil)
+ (remove-hook 'change-major-mode-hook #'js2-mode-exit t)
+ (remove-from-invisibility-spec '(js2-outline . t))
+ (js2-mode-show-all)
+ (js2-with-unmodifying-text-property-changes
+ (js2-clear-face (point-min) (point-max))))
+
+(defun js2-before-save ()
+ "Clean up whitespace before saving file.
+You can disable this by customizing `js2-cleanup-whitespace'."
+ (when js2-cleanup-whitespace
+ (let ((col (current-column)))
+ (delete-trailing-whitespace)
+ ;; don't change trailing whitespace on current line
+ (unless (eq (current-column) col)
+ (indent-to col)))))
+
+(defsubst js2-mode-reset-timer ()
+ "Cancel any existing parse timer and schedule a new one."
+ (if js2-mode-parse-timer
+ (cancel-timer js2-mode-parse-timer))
+ (setq js2-mode-parsing nil)
+ (setq js2-mode-parse-timer
+ (run-with-idle-timer js2-idle-timer-delay nil #'js2-reparse)))
+
+(defun js2-mode-edit (beg end len)
+ "Schedule a new parse after buffer is edited.
+Buffer edit spans from BEG to END and is of length LEN.
+Also clears the `js2-magic' bit on autoinserted parens/brackets
+if the edit occurred on a line different from the magic paren."
+ (let* ((magic-pos (next-single-property-change (point-min) 'js2-magic))
+ (line (if magic-pos (line-number-at-pos magic-pos))))
+ (and line
+ (or (/= (line-number-at-pos beg) line)
+ (and (> 0 len)
+ (/= (line-number-at-pos end) line)))
+ (js2-mode-mundanify-parens)))
+ (setq js2-mode-buffer-dirty-p t)
+ (js2-mode-hide-overlay)
+ (js2-mode-reset-timer))
+
+(defun js2-mode-run-font-lock ()
+ "Run `font-lock-fontify-buffer' after parsing/highlighting.
+This is intended to allow modes that install their own font-lock keywords
+to work with js2-mode. In practice it never seems to work for long.
+Hopefully the Emacs maintainers can help figure out a way to make it work."
+ (when (and (boundp 'font-lock-keywords)
+ font-lock-keywords
+ (boundp 'font-lock-mode)
+ font-lock-mode)
+ ;; TODO: font-lock and jit-lock really really REALLY don't want to
+ ;; play nicely with js2-mode. They go out of their way to fail to
+ ;; provide any option for saying "look, fontify the farging buffer
+ ;; with just the keywords already". Argh.
+ (setq font-lock-defaults (list font-lock-keywords 'keywords-only))
+ (let (font-lock-verbose)
+ (font-lock-default-fontify-buffer))))
+
+(defun js2-reparse (&optional force)
+ "Re-parse current buffer after user finishes some data entry.
+If we get any user input while parsing, including cursor motion,
+we discard the parse and reschedule it. If FORCE is nil, then the
+buffer will only rebuild its `js2-mode-ast' if the buffer is dirty."
+ (let (time
+ interrupted-p
+ (js2-compiler-strict-mode js2-mode-show-strict-warnings))
+ (unless js2-mode-parsing
+ (setq js2-mode-parsing t)
+ (unwind-protect
+ (when (or js2-mode-buffer-dirty-p force)
+ (js2-remove-overlays)
+ (js2-with-unmodifying-text-property-changes
+ (remove-text-properties (point-min) (point-max) '(syntax-table))
+ (setq js2-mode-buffer-dirty-p nil
+ js2-mode-fontifications nil
+ js2-mode-deferred-properties nil
+ js2-additional-externs nil)
+ (if js2-mode-verbose-parse-p
+ (message "parsing..."))
+ (setq time
+ (js2-time
+ (setq interrupted-p
+ (catch 'interrupted
+ (setq js2-mode-ast (js2-parse))
+ (js2-mode-fontify-regions)
+ (js2-mode-remove-suppressed-warnings)
+ (js2-mode-show-warnings)
+ (js2-mode-show-errors)
+ (js2-mode-run-font-lock) ; note: doesn't work
+ (js2-mode-highlight-magic-parens)
+ (if (>= js2-highlight-level 1)
+ (js2-highlight-jsdoc js2-mode-ast))
+ nil))))
+ (if interrupted-p
+ (progn
+ ;; unfinished parse => try again
+ (setq js2-mode-buffer-dirty-p t)
+ (js2-mode-reset-timer))
+ (if js2-mode-verbose-parse-p
+ (message "Parse time: %s" time)))))
+ (setq js2-mode-parsing nil)
+ (unless interrupted-p
+ (setq js2-mode-parse-timer nil))))))
+
+(defun js2-mode-show-node ()
+ "Debugging aid: highlight selected AST node on mouse click."
+ (interactive)
+ (let ((node (js2-node-at-point))
+ beg
+ end)
+ (when js2-mode-show-overlay
+ (if (null node)
+ (message "No node found at location %s" (point))
+ (setq beg (js2-node-abs-pos node)
+ end (+ beg (js2-node-len node)))
+ (if js2-mode-node-overlay
+ (move-overlay js2-mode-node-overlay beg end)
+ (setq js2-mode-node-overlay (make-overlay beg end))
+ (overlay-put js2-mode-node-overlay 'face 'highlight))
+ (js2-with-unmodifying-text-property-changes
+ (put-text-property beg end 'point-left #'js2-mode-hide-overlay))
+ (message "%s, parent: %s"
+ (js2-node-short-name node)
+ (if (js2-node-parent node)
+ (js2-node-short-name (js2-node-parent node))
+ "nil"))))))
+
+(defun js2-mode-hide-overlay (&optional p1 p2)
+ "Remove the debugging overlay when the point moves.
+P1 and P2 are the old and new values of point, respectively."
+ (when js2-mode-node-overlay
+ (let ((beg (overlay-start js2-mode-node-overlay))
+ (end (overlay-end js2-mode-node-overlay)))
+ ;; Sometimes we're called spuriously.
+ (unless (and p2
+ (>= p2 beg)
+ (<= p2 end))
+ (js2-with-unmodifying-text-property-changes
+ (remove-text-properties beg end '(point-left nil)))
+ (delete-overlay js2-mode-node-overlay)
+ (setq js2-mode-node-overlay nil)))))
+
+(defun js2-mode-reset ()
+ "Debugging helper: reset everything."
+ (interactive)
+ (js2-mode-exit)
+ (js2-mode))
+
+(defsubst js2-mode-show-warn-or-err (e face)
+ "Highlight a warning or error E with FACE.
+E is a list of ((MSG-KEY MSG-ARG) BEG END)."
+ (let* ((key (first e))
+ (beg (second e))
+ (end (+ beg (third e)))
+ ;; Don't inadvertently go out of bounds.
+ (beg (max (point-min) (min beg (point-max))))
+ (end (max (point-min) (min end (point-max))))
+ (js2-highlight-level 3) ; so js2-set-face is sure to fire
+ (ovl (make-overlay beg end)))
+ (overlay-put ovl 'face face)
+ (overlay-put ovl 'js2-error t)
+ (put-text-property beg end 'help-echo (js2-get-msg key))
+ (put-text-property beg end 'point-entered #'js2-echo-error)))
+
+(defun js2-remove-overlays ()
+ "Remove overlays from buffer that have a `js2-error' property."
+ (let ((beg (point-min))
+ (end (point-max)))
+ (save-excursion
+ (dolist (o (overlays-in beg end))
+ (when (overlay-get o 'js2-error)
+ (delete-overlay o))))))
+
+(defun js2-error-at-point (&optional pos)
+ "Return non-nil if there's an error overlay at POS.
+Defaults to point."
+ (loop with pos = (or pos (point))
+ for o in (overlays-at pos)
+ thereis (overlay-get o 'js2-error)))
+
+(defun js2-mode-fontify-regions ()
+ "Apply fontifications recorded during parsing."
+ ;; We defer clearing faces as long as possible to eliminate flashing.
+ (js2-clear-face (point-min) (point-max))
+ ;; have to reverse the recorded fontifications so that errors and
+ ;; warnings overwrite the normal fontifications
+ (dolist (f (nreverse js2-mode-fontifications))
+ (put-text-property (first f) (second f) 'face (third f)))
+ (setq js2-mode-fontifications nil)
+ (dolist (p js2-mode-deferred-properties)
+ (apply #'put-text-property p))
+ (setq js2-mode-deferred-properties nil))
+
+(defun js2-mode-show-errors ()
+ "Highlight syntax errors."
+ (when js2-mode-show-parse-errors
+ (dolist (e (js2-ast-root-errors js2-mode-ast))
+ (js2-mode-show-warn-or-err e 'js2-error))))
+
+(defun js2-mode-remove-suppressed-warnings ()
+ "Take suppressed warnings out of the AST warnings list.
+This ensures that the counts and `next-error' are correct."
+ (setf (js2-ast-root-warnings js2-mode-ast)
+ (js2-delete-if
+ (lambda (e)
+ (let ((key (caar e)))
+ (or
+ (and (not js2-strict-trailing-comma-warning)
+ (string-match "trailing\\.comma" key))
+ (and (not js2-strict-cond-assign-warning)
+ (string= key "msg.equal.as.assign"))
+ (and js2-missing-semi-one-line-override
+ (string= key "msg.missing.semi")
+ (let* ((beg (second e))
+ (node (js2-node-at-point beg))
+ (fn (js2-mode-find-parent-fn node))
+ (body (and fn (js2-function-node-body fn)))
+ (lc (and body (js2-node-abs-pos body)))
+ (rc (and lc (+ lc (js2-node-len body)))))
+ (and fn
+ (or (null body)
+ (save-excursion
+ (goto-char beg)
+ (and (js2-same-line lc)
+ (js2-same-line rc))))))))))
+ (js2-ast-root-warnings js2-mode-ast))))
+
+(defun js2-mode-show-warnings ()
+ "Highlight strict-mode warnings."
+ (when js2-mode-show-strict-warnings
+ (dolist (e (js2-ast-root-warnings js2-mode-ast))
+ (js2-mode-show-warn-or-err e 'js2-warning))))
+
+(defun js2-echo-error (old-point new-point)
+ "Called by point-motion hooks."
+ (let ((msg (get-text-property new-point 'help-echo)))
+ (if msg
+ (message msg))))
+
+(defalias #'js2-echo-help #'js2-echo-error)
+
+(defun js2-enter-key ()
+ "Handle user pressing the Enter key."
+ (interactive)
+ (let ((parse-status (save-excursion
+ (parse-partial-sexp (point-min) (point)))))
+ (cond
+ ;; check if we're inside a string
+ ((nth 3 parse-status)
+ (js2-mode-split-string parse-status))
+ ;; check if inside a block comment
+ ((nth 4 parse-status)
+ (js2-mode-extend-comment))
+ (t
+ ;; should probably figure out what the mode-map says we should do
+ (if js2-indent-on-enter-key
+ (let ((js2-bounce-indent-p nil))
+ (js2-indent-line)))
+ (insert "\n")
+ (if js2-enter-indents-newline
+ (let ((js2-bounce-indent-p nil))
+ (js2-indent-line)))))))
+
+(defun js2-mode-split-string (parse-status)
+ "Turn a newline in mid-string into a string concatenation.
+PARSE-STATUS is as documented in `parse-partial-sexp'."
+ (let* ((col (current-column))
+ (quote-char (nth 3 parse-status))
+ (quote-string (string quote-char))
+ (string-beg (nth 8 parse-status))
+ (indent (save-match-data
+ (or
+ (save-excursion
+ (back-to-indentation)
+ (if (looking-at "\\+")
+ (current-column)))
+ (save-excursion
+ (goto-char string-beg)
+ (if (looking-back "\\+\\s-+")
+ (goto-char (match-beginning 0)))
+ (current-column))))))
+ (insert quote-char "\n")
+ (indent-to indent)
+ (insert "+ " quote-string)
+ (when (eolp)
+ (insert quote-string)
+ (backward-char 1))))
+
+(defun js2-mode-extend-comment ()
+ "When inside a comment block, add comment prefix."
+ (let (star single col first-line needs-close)
+ (save-excursion
+ (back-to-indentation)
+ (cond
+ ((looking-at "\\*[^/]")
+ (setq star t
+ col (current-column)))
+ ((looking-at "/\\*")
+ (setq star t
+ first-line t
+ col (1+ (current-column))))
+ ((looking-at "//")
+ (setq single t
+ col (current-column)))))
+ ;; Heuristic for whether we need to close the comment:
+ ;; if we've got a parse error here, assume it's an unterminated
+ ;; comment.
+ (setq needs-close
+ (or
+ (eq (get-text-property (1- (point)) 'point-entered)
+ 'js2-echo-error)
+ ;; The heuristic above doesn't work well when we're
+ ;; creating a comment and there's another one downstream,
+ ;; as our parser thinks this one ends at the end of the
+ ;; next one. (You can have a /* inside a js block comment.)
+ ;; So just close it if the next non-ws char isn't a *.
+ (and first-line
+ (eolp)
+ (save-excursion
+ (skip-chars-forward " \t\r\n")
+ (not (eq (char-after) ?*))))))
+ (insert "\n")
+ (cond
+ (star
+ (indent-to col)
+ (insert "* ")
+ (if (and first-line needs-close)
+ (save-excursion
+ (insert "\n")
+ (indent-to col)
+ (insert "*/"))))
+ (single
+ (when (save-excursion
+ (and (zerop (forward-line 1))
+ (looking-at "\\s-*//")))
+ (indent-to col)
+ (insert "// "))))))
+
+(defun js2-beginning-of-line ()
+ "Toggles point between bol and first non-whitespace char in line.
+Also moves past comment delimiters when inside comments."
+ (interactive)
+ (let (node beg)
+ (cond
+ ((bolp)
+ (back-to-indentation))
+ ((looking-at "//")
+ (skip-chars-forward "/ \t"))
+ ((and (eq (char-after) ?*)
+ (setq node (js2-comment-at-point))
+ (memq (js2-comment-node-format node) '(jsdoc block))
+ (save-excursion
+ (skip-chars-backward " \t")
+ (bolp)))
+ (skip-chars-forward "\* \t"))
+ (t
+ (goto-char (point-at-bol))))))
+
+(defun js2-end-of-line ()
+ "Toggles point between eol and last non-whitespace char in line."
+ (interactive)
+ (if (eolp)
+ (skip-chars-backward " \t")
+ (goto-char (point-at-eol))))
+
+(defun js2-enter-mirror-mode()
+ "Turns on mirror mode, where quotes, brackets etc are mirrored automatically
+ on insertion."
+ (interactive)
+ (define-key js2-mode-map (read-kbd-macro "{") 'js2-mode-match-curly)
+ (define-key js2-mode-map (read-kbd-macro "}") 'js2-mode-magic-close-paren)
+ (define-key js2-mode-map (read-kbd-macro "\"") 'js2-mode-match-double-quote)
+ (define-key js2-mode-map (read-kbd-macro "'") 'js2-mode-match-single-quote)
+ (define-key js2-mode-map (read-kbd-macro "(") 'js2-mode-match-paren)
+ (define-key js2-mode-map (read-kbd-macro ")") 'js2-mode-magic-close-paren)
+ (define-key js2-mode-map (read-kbd-macro "[") 'js2-mode-match-bracket)
+ (define-key js2-mode-map (read-kbd-macro "]") 'js2-mode-magic-close-paren))
+
+(defun js2-leave-mirror-mode()
+ "Turns off mirror mode."
+ (interactive)
+ (dolist (key '("{" "\"" "'" "(" ")" "[" "]"))
+ (define-key js2-mode-map (read-kbd-macro key) 'self-insert-command)))
+
+(defsubst js2-mode-inside-string ()
+ "Return non-nil if inside a string.
+Actually returns the quote character that begins the string."
+ (let ((parse-state (save-excursion
+ (parse-partial-sexp (point-min) (point)))))
+ (nth 3 parse-state)))
+
+(defsubst js2-mode-inside-comment-or-string ()
+ "Return non-nil if inside a comment or string."
+ (or
+ (let ((comment-start
+ (save-excursion
+ (goto-char (point-at-bol))
+ (if (re-search-forward "//" (point-at-eol) t)
+ (match-beginning 0)))))
+ (and comment-start
+ (<= comment-start (point))))
+ (let ((parse-state (save-excursion
+ (parse-partial-sexp (point-min) (point)))))
+ (or (nth 3 parse-state)
+ (nth 4 parse-state)))))
+
+(defsubst js2-make-magic-delimiter (delim &optional pos)
+ "Add `js2-magic' and `js2-magic-paren' to DELIM, a string.
+Sets value of `js2-magic' text property to line number at POS."
+ (propertize delim
+ 'js2-magic (line-number-at-pos pos)
+ 'face 'js2-magic-paren))
+
+(defun js2-mode-match-delimiter (open close)
+ "Insert OPEN (a string) and possibly matching delimiter CLOSE.
+The rule we use, which as far as we can tell is how Eclipse works,
+is that we insert the match if we're not in a comment or string,
+and the next non-whitespace character is either punctuation or
+occurs on another line."
+ (insert open)
+ (when (and (looking-at "\\s-*\\([[:punct:]]\\|$\\)")
+ (not (js2-mode-inside-comment-or-string)))
+ (save-excursion
+ (insert (js2-make-magic-delimiter close)))
+ (when js2-auto-indent-p
+ (let ((js2-bounce-indent-p (js2-code-at-bol-p)))
+ (js2-indent-line)))))
+
+(defun js2-mode-match-bracket ()
+ "Insert matching bracket."
+ (interactive)
+ (js2-mode-match-delimiter "[" "]"))
+
+(defun js2-mode-match-paren ()
+ "Insert matching paren unless already inserted."
+ (interactive)
+ (js2-mode-match-delimiter "(" ")"))
+
+(defun js2-mode-match-curly (arg)
+ "Insert matching curly-brace.
+With prefix arg, no formatting or indentation will occur -- the close-brace
+is simply inserted directly at the point."
+ (interactive "p")
+ (let (try-pos)
+ (cond
+ (current-prefix-arg
+ (js2-mode-match-delimiter "{" "}"))
+ ((and js2-auto-insert-catch-block
+ (setq try-pos (if (looking-back "\\s-*\\(try\\)\\s-*"
+ (point-at-bol))
+ (match-beginning 1))))
+ (js2-insert-catch-skel try-pos))
+ (t
+ ;; Otherwise try to do something smarter.
+ (insert "{")
+ (unless (or (not (looking-at "\\s-*$"))
+ (save-excursion
+ (skip-chars-forward " \t\r\n")
+ (and (looking-at "}")
+ (js2-error-at-point)))
+ (js2-mode-inside-comment-or-string))
+ (undo-boundary)
+ ;; absolutely mystifying bug: when inserting the next "\n",
+ ;; the buffer-undo-list is given two new entries: the inserted range,
+ ;; and the incorrect position of the point. It's recorded incorrectly
+ ;; as being before the opening "{", not after it. But it's recorded
+ ;; as the correct value if you're debugging `js2-mode-match-curly'
+ ;; in edebug. I have no idea why it's doing this, but incrementing
+ ;; the inserted position fixes the problem, so that the undo takes us
+ ;; back to just after the user-inserted "{".
+ (insert "\n")
+ (ignore-errors
+ (incf (cadr buffer-undo-list)))
+ (js2-indent-line)
+ (save-excursion
+ (insert "\n}")
+ (let ((js2-bounce-indent-p (js2-code-at-bol-p)))
+ (js2-indent-line))))))))
+
+(defun js2-insert-catch-skel (try-pos)
+ "Complete a try/catch block after inserting a { following a try keyword.
+Rationale is that a try always needs a catch or a finally, and the catch is
+the more likely of the two.
+
+TRY-POS is the buffer position of the try keyword. The open-curly should
+already have been inserted."
+ (insert "{")
+ (let ((try-col (save-excursion
+ (goto-char try-pos)
+ (current-column))))
+ (insert "\n")
+ (undo-boundary)
+ (js2-indent-line) ;; indent the blank line where cursor will end up
+ (save-excursion
+ (insert "\n")
+ (indent-to try-col)
+ (insert "} catch (x) {\n\n")
+ (indent-to try-col)
+ (insert "}"))))
+
+(defun js2-mode-highlight-magic-parens ()
+ "Re-highlight magic parens after parsing nukes the 'face prop."
+ (let ((beg (point-min))
+ end)
+ (while (setq beg (next-single-property-change beg 'js2-magic))
+ (setq end (next-single-property-change (1+ beg) 'js2-magic))
+ (if (get-text-property beg 'js2-magic)
+ (js2-with-unmodifying-text-property-changes
+ (put-text-property beg (or end (1+ beg))
+ 'face 'js2-magic-paren))))))
+
+(defun js2-mode-mundanify-parens ()
+ "Clear all magic parens and brackets."
+ (let ((beg (point-min))
+ end)
+ (while (setq beg (next-single-property-change beg 'js2-magic))
+ (setq end (next-single-property-change (1+ beg) 'js2-magic))
+ (remove-text-properties beg (or end (1+ beg))
+ '(js2-magic face)))))
+
+(defsubst js2-match-quote (quote-string)
+ (let ((start-quote (js2-mode-inside-string)))
+ (cond
+ ;; inside a comment - don't do quote-matching, since we can't
+ ;; reliably figure out if we're in a string inside the comment
+ ((js2-comment-at-point)
+ (insert quote-string))
+ ((not start-quote)
+ ;; not in string => insert matched quotes
+ (insert quote-string)
+ ;; exception: if we're just before a word, don't double it.
+ (unless (looking-at "[^ \t\r\n]")
+ (save-excursion
+ (insert quote-string))))
+ ((looking-at quote-string)
+ (if (looking-back "[^\\]\\\\")
+ (insert quote-string)
+ (forward-char 1)))
+ ((and js2-mode-escape-quotes
+ (save-excursion
+ (save-match-data
+ (re-search-forward quote-string (point-at-eol) t))))
+ ;; inside terminated string, escape quote (unless already escaped)
+ (insert (if (looking-back "[^\\]\\\\")
+ quote-string
+ (concat "\\" quote-string))))
+ (t
+ (insert quote-string))))) ; else terminate the string
+
+(defun js2-mode-match-single-quote ()
+ "Insert matching single-quote."
+ (interactive)
+ (let ((parse-status (parse-partial-sexp (point-min) (point))))
+ ;; don't match inside comments, since apostrophe is more common
+ (if (nth 4 parse-status)
+ (insert "'")
+ (js2-match-quote "'"))))
+
+(defun js2-mode-match-double-quote ()
+ "Insert matching double-quote."
+ (interactive)
+ (js2-match-quote "\""))
+
+;; Eclipse works as follows:
+;; * type an open-paren and it auto-inserts close-paren
+;; - auto-inserted paren gets a green bracket
+;; - green bracket means typing close-paren there will skip it
+;; * if you insert any text on a different line, it turns off
+(defun js2-mode-magic-close-paren ()
+ "Skip over close-paren rather than inserting, where appropriate."
+ (interactive)
+ (let* ((here (point))
+ (parse-status (parse-partial-sexp (point-min) here))
+ (open-pos (nth 1 parse-status))
+ (close last-input-event)
+ (open (cond
+ ((eq close ?\))
+ ?\()
+ ((eq close ?\])
+ ?\[)
+ ((eq close ?})
+ ?{)
+ (t nil))))
+ (if (and (eq (char-after) close)
+ (eq open (char-after open-pos))
+ (js2-same-line open-pos)
+ (get-text-property here 'js2-magic))
+ (progn
+ (remove-text-properties here (1+ here) '(js2-magic face))
+ (forward-char 1))
+ (insert-char close 1))
+ (blink-matching-open)))
+
+(defun js2-mode-wait-for-parse (callback)
+ "Invoke CALLBACK when parsing is finished.
+If parsing is already finished, calls CALLBACK immediately."
+ (if (not js2-mode-buffer-dirty-p)
+ (funcall callback)
+ (push callback js2-mode-pending-parse-callbacks)
+ (add-hook 'js2-parse-finished-hook #'js2-mode-parse-finished)))
+
+(defun js2-mode-parse-finished ()
+ "Invoke callbacks in `js2-mode-pending-parse-callbacks'."
+ ;; We can't let errors propagate up, since it prevents the
+ ;; `js2-parse' method from completing normally and returning
+ ;; the ast, which makes things mysteriously not work right.
+ (unwind-protect
+ (dolist (cb js2-mode-pending-parse-callbacks)
+ (condition-case err
+ (funcall cb)
+ (error (message "%s" err))))
+ (setq js2-mode-pending-parse-callbacks nil)))
+
+(defun js2-mode-flag-region (from to flag)
+ "Hide or show text from FROM to TO, according to FLAG.
+If FLAG is nil then text is shown, while if FLAG is t the text is hidden.
+Returns the created overlay if FLAG is non-nil."
+ (remove-overlays from to 'invisible 'js2-outline)
+ (when flag
+ (let ((o (make-overlay from to)))
+ (overlay-put o 'invisible 'js2-outline)
+ (overlay-put o 'isearch-open-invisible
+ 'js2-isearch-open-invisible)
+ o)))
+
+;; Function to be set as an outline-isearch-open-invisible' property
+;; to the overlay that makes the outline invisible (see
+;; `js2-mode-flag-region').
+(defun js2-isearch-open-invisible (overlay)
+ ;; We rely on the fact that isearch places point on the matched text.
+ (js2-mode-show-element))
+
+(defun js2-mode-invisible-overlay-bounds (&optional pos)
+ "Return cons cell of bounds of folding overlay at POS.
+Returns nil if not found."
+ (let ((overlays (overlays-at (or pos (point))))
+ o)
+ (while (and overlays
+ (not o))
+ (if (overlay-get (car overlays) 'invisible)
+ (setq o (car overlays))
+ (setq overlays (cdr overlays))))
+ (if o
+ (cons (overlay-start o) (overlay-end o)))))
+
+(defun js2-mode-function-at-point (&optional pos)
+ "Return the innermost function node enclosing current point.
+Returns nil if point is not in a function."
+ (let ((node (js2-node-at-point pos)))
+ (while (and node (not (js2-function-node-p node)))
+ (setq node (js2-node-parent node)))
+ (if (js2-function-node-p node)
+ node)))
+
+(defun js2-mode-toggle-element ()
+ "Hide or show the foldable element at the point."
+ (interactive)
+ (let (comment fn pos)
+ (save-excursion
+ (save-match-data
+ (cond
+ ;; /* ... */ comment?
+ ((js2-block-comment-p (setq comment (js2-comment-at-point)))
+ (if (js2-mode-invisible-overlay-bounds
+ (setq pos (+ 3 (js2-node-abs-pos comment))))
+ (progn
+ (goto-char pos)
+ (js2-mode-show-element))
+ (js2-mode-hide-element)))
+ ;; //-comment?
+ ((save-excursion
+ (back-to-indentation)
+ (looking-at js2-mode-//-comment-re))
+ (js2-mode-toggle-//-comment))
+ ;; function?
+ ((setq fn (js2-mode-function-at-point))
+ (setq pos (and (js2-function-node-body fn)
+ (js2-node-abs-pos (js2-function-node-body fn))))
+ (goto-char (1+ pos))
+ (if (js2-mode-invisible-overlay-bounds)
+ (js2-mode-show-element)
+ (js2-mode-hide-element)))
+ (t
+ (message "Nothing at point to hide or show")))))))
+
+(defun js2-mode-hide-element ()
+ "Fold/hide contents of a block, showing ellipses.
+Show the hidden text with \\[js2-mode-show-element]."
+ (interactive)
+ (if js2-mode-buffer-dirty-p
+ (js2-mode-wait-for-parse #'js2-mode-hide-element))
+ (let (node body beg end)
+ (cond
+ ((js2-mode-invisible-overlay-bounds)
+ (message "already hidden"))
+ (t
+ (setq node (js2-node-at-point))
+ (cond
+ ((js2-block-comment-p node)
+ (js2-mode-hide-comment node))
+ (t
+ (while (and node (not (js2-function-node-p node)))
+ (setq node (js2-node-parent node)))
+ (if (and node
+ (setq body (js2-function-node-body node)))
+ (progn
+ (setq beg (js2-node-abs-pos body)
+ end (+ beg (js2-node-len body)))
+ (js2-mode-flag-region (1+ beg) (1- end) 'hide))
+ (message "No collapsable element found at point"))))))))
+
+(defun js2-mode-show-element ()
+ "Show the hidden element at current point."
+ (interactive)
+ (let ((bounds (js2-mode-invisible-overlay-bounds)))
+ (if bounds
+ (js2-mode-flag-region (car bounds) (cdr bounds) nil)
+ (message "Nothing to un-hide"))))
+
+(defun js2-mode-show-all ()
+ "Show all of the text in the buffer."
+ (interactive)
+ (js2-mode-flag-region (point-min) (point-max) nil))
+
+(defun js2-mode-toggle-hide-functions ()
+ (interactive)
+ (if js2-mode-functions-hidden
+ (js2-mode-show-functions)
+ (js2-mode-hide-functions)))
+
+(defun js2-mode-hide-functions ()
+ "Hides all non-nested function bodies in the buffer.
+Use \\[js2-mode-show-all] to reveal them, or \\[js2-mode-show-element]
+to open an individual entry."
+ (interactive)
+ (if js2-mode-buffer-dirty-p
+ (js2-mode-wait-for-parse #'js2-mode-hide-functions))
+ (if (null js2-mode-ast)
+ (message "Oops - parsing failed")
+ (setq js2-mode-functions-hidden t)
+ (js2-visit-ast js2-mode-ast #'js2-mode-function-hider)))
+
+(defun js2-mode-function-hider (n endp)
+ (when (not endp)
+ (let ((tt (js2-node-type n))
+ body beg end)
+ (cond
+ ((and (= tt js2-FUNCTION)
+ (setq body (js2-function-node-body n)))
+ (setq beg (js2-node-abs-pos body)
+ end (+ beg (js2-node-len body)))
+ (js2-mode-flag-region (1+ beg) (1- end) 'hide)
+ nil) ; don't process children of function
+ (t
+ t))))) ; keep processing other AST nodes
+
+(defun js2-mode-show-functions ()
+ "Un-hide any folded function bodies in the buffer."
+ (interactive)
+ (setq js2-mode-functions-hidden nil)
+ (save-excursion
+ (goto-char (point-min))
+ (while (/= (goto-char (next-overlay-change (point)))
+ (point-max))
+ (dolist (o (overlays-at (point)))
+ (when (and (overlay-get o 'invisible)
+ (not (overlay-get o 'comment)))
+ (js2-mode-flag-region (overlay-start o) (overlay-end o) nil))))))
+
+(defun js2-mode-hide-comment (n)
+ (let* ((head (if (eq (js2-comment-node-format n) 'jsdoc)
+ 3 ; /**
+ 2)) ; /*
+ (beg (+ (js2-node-abs-pos n) head))
+ (end (- (+ beg (js2-node-len n)) head 2))
+ (o (js2-mode-flag-region beg end 'hide)))
+ (overlay-put o 'comment t)))
+
+(defun js2-mode-toggle-hide-comments ()
+ "Folds all block comments in the buffer.
+Use \\[js2-mode-show-all] to reveal them, or \\[js2-mode-show-element]
+to open an individual entry."
+ (interactive)
+ (if js2-mode-comments-hidden
+ (js2-mode-show-comments)
+ (js2-mode-hide-comments)))
+
+(defun js2-mode-hide-comments ()
+ (interactive)
+ (if js2-mode-buffer-dirty-p
+ (js2-mode-wait-for-parse #'js2-mode-hide-comments))
+ (if (null js2-mode-ast)
+ (message "Oops - parsing failed")
+ (setq js2-mode-comments-hidden t)
+ (dolist (n (js2-ast-root-comments js2-mode-ast))
+ (let ((format (js2-comment-node-format n)))
+ (when (js2-block-comment-p n)
+ (js2-mode-hide-comment n))))
+ (js2-mode-hide-//-comments)))
+
+(defsubst js2-mode-extend-//-comment (direction)
+ "Find start or end of a block of similar //-comment lines.
+DIRECTION is -1 to look back, 1 to look forward.
+INDENT is the indentation level to match.
+Returns the end-of-line position of the furthest adjacent
+//-comment line with the same indentation as the current line.
+If there is no such matching line, returns current end of line."
+ (let ((pos (point-at-eol))
+ (indent (current-indentation)))
+ (save-excursion
+ (save-match-data
+ (while (and (zerop (forward-line direction))
+ (looking-at js2-mode-//-comment-re)
+ (eq indent (length (match-string 1))))
+ (setq pos (point-at-eol)))
+ pos))))
+
+(defun js2-mode-hide-//-comments ()
+ "Fold adjacent 1-line comments, showing only snippet of first one."
+ (let (beg end)
+ (save-excursion
+ (save-match-data
+ (goto-char (point-min))
+ (while (re-search-forward js2-mode-//-comment-re nil t)
+ (setq beg (point)
+ end (js2-mode-extend-//-comment 1))
+ (unless (eq beg end)
+ (overlay-put (js2-mode-flag-region beg end 'hide)
+ 'comment t))
+ (goto-char end)
+ (forward-char 1))))))
+
+(defun js2-mode-toggle-//-comment ()
+ "Fold or un-fold any multi-line //-comment at point.
+Caller should have determined that this line starts with a //-comment."
+ (let* ((beg (point-at-eol))
+ (end beg))
+ (save-excursion
+ (goto-char end)
+ (if (js2-mode-invisible-overlay-bounds)
+ (js2-mode-show-element)
+ ;; else hide the comment
+ (setq beg (js2-mode-extend-//-comment -1)
+ end (js2-mode-extend-//-comment 1))
+ (unless (eq beg end)
+ (overlay-put (js2-mode-flag-region beg end 'hide)
+ 'comment t))))))
+
+(defun js2-mode-show-comments ()
+ "Un-hide any hidden comments, leaving other hidden elements alone."
+ (interactive)
+ (setq js2-mode-comments-hidden nil)
+ (save-excursion
+ (goto-char (point-min))
+ (while (/= (goto-char (next-overlay-change (point)))
+ (point-max))
+ (dolist (o (overlays-at (point)))
+ (when (overlay-get o 'comment)
+ (js2-mode-flag-region (overlay-start o) (overlay-end o) nil))))))
+
+(defun js2-mode-display-warnings-and-errors ()
+ "Turn on display of warnings and errors."
+ (interactive)
+ (setq js2-mode-show-parse-errors t
+ js2-mode-show-strict-warnings t)
+ (js2-reparse 'force))
+
+(defun js2-mode-hide-warnings-and-errors ()
+ "Turn off display of warnings and errors."
+ (interactive)
+ (setq js2-mode-show-parse-errors nil
+ js2-mode-show-strict-warnings nil)
+ (js2-reparse 'force))
+
+(defun js2-mode-toggle-warnings-and-errors ()
+ "Toggle the display of warnings and errors.
+Some users don't like having warnings/errors reported while they type."
+ (interactive)
+ (setq js2-mode-show-parse-errors (not js2-mode-show-parse-errors)
+ js2-mode-show-strict-warnings (not js2-mode-show-strict-warnings))
+ (if (interactive-p)
+ (message "warnings and errors %s"
+ (if js2-mode-show-parse-errors
+ "enabled"
+ "disabled")))
+ (js2-reparse 'force))
+
+(defun js2-mode-customize ()
+ (interactive)
+ (customize-group 'js2-mode))
+
+(defun js2-mode-forward-sexp (&optional arg)
+ "Move forward across one statement or balanced expression.
+With ARG, do it that many times. Negative arg -N means
+move backward across N balanced expressions."
+ (interactive "p")
+ (setq arg (or arg 1))
+ (if js2-mode-buffer-dirty-p
+ (js2-mode-wait-for-parse #'js2-mode-forward-sexp))
+ (let (node end (start (point)))
+ (cond
+ ;; backward-sexp
+ ;; could probably make this better for some cases:
+ ;; - if in statement block (e.g. function body), go to parent
+ ;; - infix exprs like (foo in bar) - maybe go to beginning
+ ;; of infix expr if in the right-side expression?
+ ((and arg (minusp arg))
+ (dotimes (i (- arg))
+ (js2-backward-sws)
+ (forward-char -1) ; enter the node we backed up to
+ (setq node (js2-node-at-point (point) t))
+ (goto-char (if node
+ (js2-node-abs-pos node)
+ (point-min)))))
+ (t
+ ;; forward-sexp
+ (js2-forward-sws)
+ (dotimes (i arg)
+ (js2-forward-sws)
+ (setq node (js2-node-at-point (point) t)
+ end (if node (+ (js2-node-abs-pos node)
+ (js2-node-len node))))
+ (goto-char (or end (point-max))))))))
+
+(defun js2-next-error (&optional arg reset)
+ "Move to next parse error.
+Typically invoked via \\[next-error].
+ARG is the number of errors, forward or backward, to move.
+RESET means start over from the beginning."
+ (interactive "p")
+ (if (or (null js2-mode-ast)
+ (and (null (js2-ast-root-errors js2-mode-ast))
+ (null (js2-ast-root-warnings js2-mode-ast))))
+ (message "No errors")
+ (when reset
+ (goto-char (point-min)))
+ (let* ((errs (copy-sequence
+ (append (js2-ast-root-errors js2-mode-ast)
+ (js2-ast-root-warnings js2-mode-ast))))
+ (continue t)
+ (start (point))
+ (count (or arg 1))
+ (backward (minusp count))
+ (sorter (if backward '> '<))
+ (stopper (if backward '< '>))
+ (count (abs count))
+ all-errs
+ err)
+ ;; sort by start position
+ (setq errs (sort errs (lambda (e1 e2)
+ (funcall sorter (second e1) (second e2))))
+ all-errs errs)
+ ;; find nth error with pos > start
+ (while (and errs continue)
+ (when (funcall stopper (cadar errs) start)
+ (setq err (car errs))
+ (if (zerop (decf count))
+ (setq continue nil)))
+ (setq errs (cdr errs)))
+ (if err
+ (goto-char (second err))
+ ;; wrap around to first error
+ (goto-char (second (car all-errs)))
+ ;; if we were already on it, echo msg again
+ (if (= (point) start)
+ (js2-echo-error (point) (point)))))))
+
+(defun js2-down-mouse-3 ()
+ "Make right-click move the point to the click location.
+This makes right-click context menu operations a bit more intuitive.
+The point will not move if the region is active, however, to avoid
+destroying the region selection."
+ (interactive)
+ (when (and js2-move-point-on-right-click
+ (not mark-active))
+ (let ((e last-input-event))
+ (ignore-errors
+ (goto-char (cadadr e))))))
+
+(defun js2-mode-create-imenu-index ()
+ "Return an alist for `imenu--index-alist'."
+ ;; This is built up in `js2-parse-record-imenu' during parsing.
+ (when js2-mode-ast
+ ;; if we have an ast but no recorder, they're requesting a rescan
+ (unless js2-imenu-recorder
+ (js2-reparse 'force))
+ (prog1
+ (js2-build-imenu-index)
+ (setq js2-imenu-recorder nil
+ js2-imenu-function-map nil))))
+
+(defun js2-mode-find-tag ()
+ "Replacement for `find-tag-default'.
+`find-tag-default' returns a ridiculous answer inside comments."
+ (let (beg end)
+ (js2-with-underscore-as-word-syntax
+ (save-excursion
+ (if (and (not (looking-at "[A-Za-z0-9_$]"))
+ (looking-back "[A-Za-z0-9_$]"))
+ (setq beg (progn (forward-word -1) (point))
+ end (progn (forward-word 1) (point)))
+ (setq beg (progn (forward-word 1) (point))
+ end (progn (forward-word -1) (point))))
+ (replace-regexp-in-string
+ "[\"']" ""
+ (buffer-substring-no-properties beg end))))))
+
+(defun js2-mode-forward-sibling ()
+ "Move to the end of the sibling following point in parent.
+Returns non-nil if successful, or nil if there was no following sibling."
+ (let* ((node (js2-node-at-point))
+ (parent (js2-mode-find-enclosing-fn node))
+ sib)
+ (when (setq sib (js2-node-find-child-after (point) parent))
+ (goto-char (+ (js2-node-abs-pos sib)
+ (js2-node-len sib))))))
+
+(defun js2-mode-backward-sibling ()
+ "Move to the beginning of the sibling node preceding point in parent.
+Parent is defined as the enclosing script or function."
+ (let* ((node (js2-node-at-point))
+ (parent (js2-mode-find-enclosing-fn node))
+ sib)
+ (when (setq sib (js2-node-find-child-before (point) parent))
+ (goto-char (js2-node-abs-pos sib)))))
+
+(defun js2-beginning-of-defun ()
+ "Go to line on which current function starts, and return non-nil.
+If we're not in a function, go to beginning of previous script-level element."
+ (interactive)
+ (let ((parent (js2-node-parent-script-or-fn (js2-node-at-point)))
+ pos sib)
+ (cond
+ ((and (js2-function-node-p parent)
+ (not (eq (point) (setq pos (js2-node-abs-pos parent)))))
+ (goto-char pos))
+ (t
+ (js2-mode-backward-sibling)))))
+
+(defun js2-end-of-defun ()
+ "Go to the char after the last position of the current function.
+If we're not in a function, skips over the next script-level element."
+ (interactive)
+ (let ((parent (js2-node-parent-script-or-fn (js2-node-at-point))))
+ (if (not (js2-function-node-p parent))
+ ;; punt: skip over next script-level element beyond point
+ (js2-mode-forward-sibling)
+ (goto-char (+ 1 (+ (js2-node-abs-pos parent)
+ (js2-node-len parent)))))))
+
+(defun js2-mark-defun (&optional allow-extend)
+ "Put mark at end of this function, point at beginning.
+The function marked is the one that contains point.
+
+Interactively, if this command is repeated,
+or (in Transient Mark mode) if the mark is active,
+it marks the next defun after the ones already marked."
+ (interactive "p")
+ (let (extended)
+ (when (and allow-extend
+ (or (and (eq last-command this-command) (mark t))
+ (and transient-mark-mode mark-active)))
+ (let ((sib (save-excursion
+ (goto-char (mark))
+ (if (js2-mode-forward-sibling)
+ (point))))
+ node)
+ (if sib
+ (progn
+ (set-mark sib)
+ (setq extended t))
+ ;; no more siblings - try extending to enclosing node
+ (goto-char (mark t)))))
+ (when (not extended)
+ (let ((node (js2-node-at-point (point) t)) ; skip comments
+ ast fn stmt parent beg end)
+ (when (js2-ast-root-p node)
+ (setq ast node
+ node (or (js2-node-find-child-after (point) node)
+ (js2-node-find-child-before (point) node))))
+ ;; only mark whole buffer if we can't find any children
+ (if (null node)
+ (setq node ast))
+ (if (js2-function-node-p node)
+ (setq parent node)
+ (setq fn (js2-mode-find-enclosing-fn node)
+ stmt (if (or (null fn)
+ (js2-ast-root-p fn))
+ (js2-mode-find-first-stmt node))
+ parent (or stmt fn)))
+ (setq beg (js2-node-abs-pos parent)
+ end (+ beg (js2-node-len parent)))
+ (push-mark beg)
+ (goto-char end)
+ (exchange-point-and-mark)))))
+
+(defun js2-narrow-to-defun ()
+ "Narrow to the function enclosing point."
+ (interactive)
+ (let* ((node (js2-node-at-point (point) t)) ; skip comments
+ (fn (if (js2-script-node-p node)
+ node
+ (js2-mode-find-enclosing-fn node)))
+ (beg (js2-node-abs-pos fn)))
+ (unless (js2-ast-root-p fn)
+ (narrow-to-region beg (+ beg (js2-node-len fn))))))
+
+(provide 'js2-mode)
+
+;; arch-tag: 1dd56864-a3ef-4682-a63f-6341f6a42738
+;;; js2-mode.el ends here
--- /dev/null
+This JavaScript editing mode supports:
+
+ - strict recognition of the Ecma-262 language standard
+ - support for most Rhino and SpiderMonkey extensions from 1.5 to 1.8
+ - parsing support for ECMAScript for XML (E4X, ECMA-357)
+ - accurate syntax highlighting using a recursive-descent parser
+ - on-the-fly reporting of syntax errors and strict-mode warnings
+ - undeclared-variable warnings using a configurable externs framework
+ - "bouncing" line indentation to choose among alternate indentation points
+ - smart line-wrapping within comments and strings
+ - code folding:
+ - show some or all function bodies as {...}
+ - show some or all block comments as /*...*/
+ - context-sensitive menu bar and popup menus
+ - code browsing using the `imenu' package
+ - typing helpers such as automatic insertion of matching braces/parens
+ - many customization options
+
+The mode includes a port of Mozilla Rhino's scanner, parser and symbol
+table. Ideally it should stay in sync with Rhino, keeping `js2-mode'
+current as the EcmaScript language standard evolves.
+
+Unlike cc-engine based language modes, js2-mode's line-indentation is
+not customizable. It is a surprising amount of work to support
+customizable indentation. The current compromise is that the tab key
+lets you cycle among various likely indentation points, similar to the
+behavior of python-mode.
+
+This mode does not yet work with "multi-mode" modes such as `mmm-mode'
+and `mumamo', although it could be made to do so with some effort.
+This means that `js2-mode' is currently only useful for editing
+JavaScript files, and not for editing JavaScript within <script> tags
+or templates.
+
--- /dev/null
+Muse is a tool for easily authoring and publishing documents. It
+allows for rapid prototyping of hyperlinked text, which may then be
+exported to multiple output formats, such as HTML, LaTeX, and Texinfo.
+
+The markup rules used by Muse are intended to be very friendly to
+people familiar with Emacs. See the included manual for more
+information.
--- /dev/null
+;;; cgi.el -- using Emacs for CGI scripting
+;;;
+;;; Author: Eric Marsden <emarsden@laas.fr>
+;;; Michael Olson <mwolson@gnu.org> (slight modifications)
+;;; Keywords: CGI web scripting slow
+;;; Version: 0.3
+;;; Time-stamp: <2001-08-24 emarsden>
+;;; Copyright: (C) 2000 Eric Marsden
+;;; Parts copyright (C) 2006 Free Software Foundation, Inc.
+;;
+;; This program 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.
+;;
+;; This program 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 this program; if not, write to the Free
+;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+;;
+;;
+;;; Commentary:
+;;
+;; People who like this sort of thing will find this the sort of
+;; thing they like. -- Abraham Lincoln
+;;
+;;
+;; Overview ==========================================================
+;;
+;; A simple library for the Common Gateway Interface for Emacs,
+;; allowing you to service requests for non static web pages in elisp.
+;; Provides routines for decoding arguments to GET- and POST-type CGI
+;; requests.
+;;
+;; Usage: place a shell script such as the following in your web
+;; server's CGI directory (typically called something like
+;; /var/www/cgi-bin/):
+;;
+;; ,-------------------------------------------------------------------
+;; | #!/bin/sh
+;; |
+;; | emacs -batch -l cgi.el -f cgi-calendar
+;; `-------------------------------------------------------------------
+;;
+;; (`cgi-calendar' is a sample elisp CGI script provided at the end of
+;; this file).
+;;
+;; Alternatively, if you're running version 2.x of the linux kernel
+;; you could make .elc files directly executable via the binfmt_misc
+;; mechanism and run them straight from the cgi-bin directory.
+;;
+;; Efficiency would be improved by having Emacs bind to the http
+;; service port and spawn a thread per connection. Extending Emacs to
+;; support server sockets and multithreading is left as an exercise
+;; for the reader.
+;;
+;; References:
+;; * rfc1738 "Uniform Resource Locators"
+;; * rfc1630 "Universal Resource Identifiers in WWW"
+;;
+;; Thanks to Christoph Conrad <christoph.conrad@gmx.de> for pointing
+;; out a bug in the URI-decoding.
+
+;;; Code:
+
+(eval-when-compile
+ (require 'cl)
+ (require 'calendar))
+
+(defconst cgi-url-unreserved-chars '(
+ ?a ?b ?c ?d ?e ?f ?g ?h ?i ?j ?k ?l ?m
+ ?n ?o ?p ?q ?r ?s ?t ?u ?v ?w ?x ?y ?z
+ ?A ?B ?C ?D ?E ?F ?G ?H ?I ?J ?K ?L ?M
+ ?N ?O ?P ?Q ?R ?S ?T ?U ?V ?W ?X ?Y ?Z
+ ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9
+ ?\$ ?\- ?\_ ?\. ?\! ?\~ ?\* ?\' ?\( ?\) ?\,))
+
+(defun cgi-int-char (i)
+ (if (fboundp 'int-char) (int-char i) i))
+
+(defun cgi-hex-char-p (ch)
+ (declare (character ch))
+ (let ((hexchars '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9
+ ?A ?B ?C ?D ?E ?F)))
+ (member (upcase ch) hexchars)))
+
+;; decode %xx to the corresponding character and + to ' '
+(defun cgi-decode-string (str)
+ (do ((i 0)
+ (len (length str))
+ (decoded '()))
+ ((>= i len) (concat (nreverse decoded)))
+ (let ((ch (aref str i)))
+ (cond ((eq ?+ ch)
+ (push ?\ decoded)
+ (incf i))
+ ((and (eq ?% ch)
+ (< (+ i 2) len)
+ (cgi-hex-char-p (aref str (+ i 1)))
+ (cgi-hex-char-p (aref str (+ i 2))))
+ (let ((hex (string-to-number (substring str (+ i 1) (+ i 3)) 16)))
+ (push (cgi-int-char hex) decoded)
+ (incf i 3)))
+ (t (push ch decoded)
+ (incf i))))))
+
+(defun cgi-position (item seq &optional start end)
+ (or start (setq start 0))
+ (or end (setq end (length seq)))
+ (while (and (< start end)
+ (not (equal item (aref seq start))))
+ (setq start (1+ start)))
+ (and (< start end) start))
+
+;; Parse "foo=x&bar=y+re" into (("foo" . "x") ("bar" . "y re"))
+;; Substrings are plus-decoded and then URI-decoded.
+(defun cgi-decode (q)
+ (when q
+ (flet ((split-= (str)
+ (let ((pos (or (cgi-position ?= str) 0)))
+ (cons (cgi-decode-string (substring str 0 pos))
+ (cgi-decode-string (substring str (+ pos 1)))))))
+ (mapcar #'split-= (split-string q "&")))))
+
+(defun cgi-lose (fmt &rest args)
+ (let ((why (apply #'format fmt args)))
+ (message "Script error: %s" why) ; to error_log
+ (princ "Content-type: text/html\n\n") ; to browser
+ (princ "<html><head><title>Script error</title></head>\r\n")
+ (princ "<body><h1>Script error</h1>\r\n<p>\r\n")
+ (princ why)
+ (princ "\r\n</body></html>\r\n")
+ (kill-emacs 0)))
+
+(defmacro cgi-evaluate (&rest forms)
+ `(condition-case why
+ (princ (with-output-to-string ,@forms))
+ (error (cgi-lose "Emacs Lisp error: %s" why))))
+
+(defun cgi-arguments ()
+ (let ((method (getenv "REQUEST_METHOD"))
+ req buf)
+ (cond ((null method)
+ (cgi-lose "No request method specified"))
+ ((string= "GET" method)
+ (unless (getenv "QUERY_STRING")
+ (cgi-lose "No query string for GET request"))
+ (cgi-decode (getenv "QUERY_STRING")))
+ ((string= "POST" method)
+ (setq req (getenv "CONTENT_LENGTH"))
+ (unless req
+ (cgi-lose "No content-length for POST request"))
+ (setq buf (get-buffer-create " *cgi*"))
+ (set-buffer buf)
+ (erase-buffer)
+ (loop for i from 1 to (string-to-number req)
+ do (insert (read-event)))
+ (cgi-decode (buffer-string)))
+ (t
+ (cgi-lose "Can't handle request method %s" method)))))
+
+;; ====================================================================
+;; a sample application: calendar via the web. If invoked without
+;; arguments, presents a calendar for the three months around the
+;; current date. You can request a calendar for a specific period by
+;; specifying the year and the month in the query string:
+;;
+;; ~$ lynx -dump 'http://localhost/cgi-bin/cal?year=1975&month=6'
+;;
+;; When run in batch mode, text normally displayed in the echo area
+;; (via `princ' for example) goes to stdout, and thus to the browser.
+;; Text output using `message' goes to stderr, and thus normally to
+;; your web server's error_log.
+;; ====================================================================
+
+(eval-and-compile
+ (if (fboundp 'calendar-extract-month)
+ (defalias 'cgi-calendar-extract-month 'calendar-extract-month)
+ (defalias 'cgi-calendar-extract-month 'extract-calendar-month))
+
+ (if (fboundp 'calendar-extract-year)
+ (defalias 'cgi-calendar-extract-year 'calendar-extract-year)
+ (defalias 'cgi-calendar-extract-year 'extract-calendar-year))
+
+ (if (fboundp 'calendar-generate)
+ (defalias 'cgi-calendar-generate 'calendar-generate)
+ (defalias 'cgi-calendar-generate 'generate-calendar)))
+
+(defun cgi-calendar-string ()
+ (require 'calendar)
+ (let* ((args (cgi-arguments))
+ (now (calendar-current-date))
+ (mnth (cdr (assoc "month" args)))
+ (month (if mnth (string-to-number mnth)
+ (cgi-calendar-extract-month now)))
+ (yr (cdr (assoc "year" args)))
+ (year (if yr (string-to-number yr)
+ (cgi-calendar-extract-year now))))
+ (with-temp-buffer
+ (cgi-calendar-generate month year)
+ (buffer-string))))
+
+(defun cgi-calendar ()
+ (cgi-evaluate
+ (princ "Content-type: text/html\n\n")
+ (princ "<html><head><title>Emacs calendar</title></head>\r\n")
+ (princ "<body> <h1>Emacs calendar</h1>\r\n")
+ (princ "<pre>\r\n")
+ (princ (cgi-calendar-string))
+ (princ "\r\n</pre></body></html>\r\n")))
+
+(provide 'cgi)
+
+;; cgi.el ends here
--- /dev/null
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+\1f
+File: dir, Node: Top This is the top of the INFO tree
+
+ This (the Directory node) gives a menu of major topics.
+ Typing "q" exits, "?" lists all Info commands, "d" returns here,
+ "h" gives a primer for first-timers,
+ "mEmacs<Return>" visits the Emacs manual, etc.
+
+ In Emacs, you can click mouse button 2 on a menu item or cross reference
+ to select it.
+
+* Menu:
+
+Emacs
+* Muse: (muse). Authoring and publishing environment for Emacs.
--- /dev/null
+;; This file provides a fix for htmlize.el and Emacs 23.
+;; To use it, add the path to this directory to your load path and
+;; add (require 'htmlize-hack) to your Emacs init file.
+
+(require 'htmlize)
+
+(when (equal htmlize-version "1.34")
+ (defun htmlize-face-size (face)
+ ;; The size (height) of FACE, taking inheritance into account.
+ ;; Only works in Emacs 21 and later.
+ (let ((size-list
+ (loop
+ for f = face then (face-attribute f :inherit)
+ until (or (null f) (eq f 'unspecified))
+ for h = (face-attribute f :height)
+ collect (if (eq h 'unspecified) nil h))))
+ (reduce 'htmlize-merge-size (cons nil size-list)))))
+
+(provide 'htmlize-hack)
--- /dev/null
+;;; httpd.el -- a web server in Emacs Lisp
+;;;
+;;; Author: Eric Marsden <emarsden@laas.fr>
+;;; John Wiegley <johnw@gnu.org>
+;;; Michael Olson <mwolson@gnu.org> (slight modifications)
+;;; Version: 1.1
+;;; Keywords: games
+;;; Copyright (C) 2001, 2003 Eric Marsden
+;;; Parts copyright (C) 2006 Free Software Foundation, Inc.
+;;
+;; This program 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.
+;;
+;; This program 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 this program; if not, write to the Free
+;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+;;
+;; The latest version of this package should be available from
+;;
+;; <URL:http://purl.org/net/emarsden/home/downloads/>
+
+;;; Commentary:
+;;
+;; httpd.el is an HTTP server embedded in the Emacs. It can handle GET
+;; and HEAD requests; adding support for POST should not be too
+;; difficult. By default, httpd.el will listen on server side Emacs
+;; sockets for HTTP requests.
+;;
+;; I have only tested this code with Emacs; it may need modifications
+;; to work with XEmacs.
+;;
+;; This version has been modified to work with GNU Emacs 21 and 22.
+;;
+;;; Acknowledgements:
+;;
+;; httpd.el was inspired by pshttpd, an HTTP server written in
+;; Postscript by Anders Karlsson <URL:http://www.pugo.org:8080/>.
+;;
+;; Thanks to John Wiegley and Cyprian Adam Laskowski.
+
+;;; Code
+
+(defvar httpd-document-root "/var/www")
+
+(defvar httpd-path-handlers '()
+ "Alist of (path-regexp . handler) forms.
+If a GET request is made for an URL whose path component matches
+a PATH-REGEXP, the corresponding handler is called to generate
+content.")
+
+(defvar httpd-mime-types-alist
+ '(("html" . "text/html; charset=iso-8859-1")
+ ("txt" . "text/plain; charset=iso-8859-1")
+ ("jpg" . "image/jpeg")
+ ("jpeg" . "image/jpeg")
+ ("gif" . "image/gif")
+ ("png" . "image/png")
+ ("tif" . "image/tiff")
+ ("tiff" . "image/tiff")
+ ("css" . "text/css")
+ ("gz" . "application/octet-stream")
+ ("ps" . "application/postscript")
+ ("pdf" . "application/pdf")
+ ("eps" . "application/postscript")
+ ("tar" . "application/x-tar")
+ ("rpm" . "application/x-rpm")
+ ("zip" . "application/zip")
+ ("mp3" . "audio/mpeg")
+ ("mp2" . "audio/mpeg")
+ ("mid" . "audio/midi")
+ ("midi" . "audio/midi")
+ ("wav" . "audio/x-wav")
+ ("au" . "audio/basic")
+ ("ram" . "audio/pn-realaudio")
+ ("ra" . "audio/x-realaudio")
+ ("mpg" . "video/mpeg")
+ ("mpeg" . "video/mpeg")
+ ("qt" . "video/quicktime")
+ ("mov" . "video/quicktime")
+ ("avi" . "video/x-msvideo")))
+
+(defun httpd-mime-type (filename)
+ (or (cdr (assoc (file-name-extension filename) httpd-mime-types-alist))
+ "text/plain"))
+
+(put 'httpd-exception 'error-conditions '(httpd-exception error))
+
+(defun defhttpd-exception (name code msg)
+ (put name 'error-conditions (list name 'httpd-exception 'error))
+ (put name 'httpd-code code)
+ (put name 'httpd-msg msg))
+
+(defhttpd-exception 'httpd-moved/perm 301 "Moved permanently")
+(defhttpd-exception 'httpd-moved/temp 302 "Moved temporarily")
+(defhttpd-exception 'httpd-bad-request 400 "Bad request")
+(defhttpd-exception 'httpd-forbidden 403 "Forbidden")
+(defhttpd-exception 'httpd-file-not-found 404 "Not found")
+(defhttpd-exception 'httpd-method-forbidden 405 "Method not allowed")
+(defhttpd-exception 'httpd-unimplemented 500 "Internal server error")
+(defhttpd-exception 'httpd-unimplemented 501 "Not implemented")
+(defhttpd-exception 'httpd-unimplemented 503 "Service unavailable")
+
+(defvar httpd-endl "\r\n")
+
+(defvar httpd-process nil)
+(defvar httpd-bytes-sent nil) ; only used with `httpd-process'
+(defvar httpd-log-accesses t)
+
+(defun httpd-add-handler (path-regexp handler)
+ (push (cons path-regexp handler) httpd-path-handlers))
+
+(defun httpd-try-internal-handler (path &optional cont)
+ (catch 'result
+ (dolist (elem httpd-path-handlers)
+ (let ((regexp (car elem))
+ (handler (cdr elem)))
+ (if (string-match regexp path)
+ (throw 'result (funcall handler path cont)))))))
+
+(defun httpd-date-stamp ()
+ (format-time-string "[%d/%b/%Y %H:%M:%S %z]"))
+
+(defun httpd-log (&rest strings)
+ (if httpd-log-accesses
+ (save-excursion
+ (goto-char (point-max))
+ (with-current-buffer (get-buffer-create "*httpd access_log*")
+ (mapc 'insert strings)))))
+
+(defun httpd-send-data (&rest strings)
+ (dolist (s strings)
+ (send-string httpd-process s)
+ (if httpd-bytes-sent
+ (setq httpd-bytes-sent (+ httpd-bytes-sent (length s))))))
+
+(defun httpd-send (code msg &rest strings)
+ (httpd-log (number-to-string code) " ")
+ (apply 'httpd-send-data
+ "HTTP/1.0 " (number-to-string code) " " msg httpd-endl
+ strings))
+
+(defun httpd-send-eof ()
+ (httpd-log (number-to-string httpd-bytes-sent) "\n")
+ (process-send-eof httpd-process))
+
+(defun httpd-send-file (filename)
+ (with-temp-buffer
+ (insert-file-contents filename)
+ (httpd-send-data (buffer-string))))
+
+(defun httpd-lose (code msg)
+ (httpd-send code msg
+ "Content-Type: text/html" httpd-endl
+ "Connection: close" httpd-endl
+ httpd-endl
+ "<html><head><title>Error</title></head>" httpd-endl
+ "<body><h1>" msg "</h1>" httpd-endl
+ "<p>" msg httpd-endl
+ "</body></html>" httpd-endl)
+ (httpd-send-eof))
+
+(defun httpd-handle-redirect (req where)
+ "Redirect the client to new location WHERE."
+ (httpd-send 301 "Moved permanently"
+ "Location: " where httpd-endl
+ "URI: " where httpd-endl
+ "Connection: close" httpd-endl
+ httpd-endl)
+ (httpd-send-eof))
+
+(defun httpd-handle-GET+HEAD (path &optional want-data req)
+ (if (zerop (length path))
+ (setq path "index.html"))
+
+ ;; could use `expand-file-name' here instead of `concat', but we
+ ;; don't want tilde expansion, etc.
+ (let ((filename (concat httpd-document-root "/" path))
+ modified-since)
+ (cond ((httpd-try-internal-handler path) t)
+ ((file-directory-p filename)
+ (httpd-handle-redirect path (concat "http://" (system-name) "/"
+ path "/")))
+ ((file-readable-p filename)
+ (let ((attrs (file-attributes filename)))
+ (if (and (string-match "^If-Modified-Since:\\s-+\\(.+\\)" req)
+ (setq modified-since
+ (apply 'encode-time
+ (parse-time-string (match-string 1 req))))
+ (time-less-p (nth 5 attrs) modified-since))
+ (httpd-send 304 "Not modified"
+ "Server: Emacs/httpd.el" httpd-endl
+ "Connection: close" httpd-endl
+ httpd-endl)
+ (httpd-send 200 "OK"
+ "Server: Emacs/httpd.el" httpd-endl
+ "Connection: close" httpd-endl
+ "MIME-Version: 1.0" httpd-endl
+ "Content-Type: "
+ (httpd-mime-type filename) httpd-endl
+ "Content-Length: "
+ (number-to-string (nth 7 attrs)) httpd-endl
+ httpd-endl)
+ (if want-data
+ (httpd-send-file filename)))
+ (httpd-send-eof)))
+
+ (t (signal 'httpd-file-not-found path)))))
+
+(defun httpd-handle-request (req &optional cont)
+ (httpd-log (car (process-contact httpd-process)) " - - "
+ (httpd-date-stamp) " \"")
+ (if (not (string-match ".+" req))
+ (progn
+ (httpd-log "\"")
+ (error "HTTP request was empty"))
+ (let ((request (match-string 0 req)))
+ (httpd-log request "\" ")
+ (cond
+ ((string-match "\\.\\." request)
+ ;; reject requests containing ".." in the path. Should really
+ ;; URI-decode first.
+ (signal 'httpd-forbidden request))
+
+ ((string-match "\\`\\(GET\\|HEAD\\|POST\\)\\s-/\\(\\S-*\\)" request)
+ (let ((kind (match-string 1 request))
+ (arg (match-string 2 request)))
+ (if (string= kind "POST")
+ (unless (httpd-try-internal-handler arg cont)
+ (signal 'httpd-unimplemented arg))
+ (httpd-handle-GET+HEAD arg (string= kind "GET") req))))
+
+ (t (signal 'httpd-bad-request request))))))
+
+(defun httpd-serve (proc string)
+ (let ((httpd-process proc)
+ (httpd-bytes-sent 0))
+ (condition-case why
+ (httpd-handle-request string)
+ (httpd-exception
+ (httpd-lose (get (car why) 'httpd-code)
+ (get (car why) 'httpd-msg)))
+ ;; Comment out these two lines if you want to catch errors
+ ;; inside Emacs itself.
+ (error
+ (httpd-lose 500 (format "Emacs Lisp error: %s" why)))
+ )))
+
+(defun httpd-start (&optional port)
+ (interactive (list (read-string "Serve Web requests on port: " "8080")))
+ (if (null port)
+ (setq port 8080)
+ (if (stringp port)
+ (setq port (string-to-number port))))
+ (if httpd-process
+ (delete-process httpd-process))
+ (setq httpd-process
+ (if (fboundp 'make-network-process)
+ (make-network-process :name "httpd"
+ :buffer (generate-new-buffer "httpd")
+ :host 'local :service port
+ :server t :noquery t
+ :filter 'httpd-serve)
+ (and (fboundp 'open-network-stream-server)
+ (open-network-stream-server "httpd"
+ (generate-new-buffer "httpd")
+ port nil 'httpd-serve))))
+ (if (and (processp httpd-process)
+ (eq (process-status httpd-process) 'listen))
+ (message "httpd.el is listening on port %d" port)))
+
+(defun httpd-stop ()
+ (interactive)
+ (when httpd-process
+ (message "httpd.el server on port %d has stopped"
+ (cadr (process-contact httpd-process)))
+ (delete-process httpd-process)
+ (setq httpd-process nil)))
+
+(provide 'httpd)
+
+;; httpd.el ends here
--- /dev/null
+;;; muse-backlink.el --- backlinks for Muse
+
+;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; Author: Jim Ottaway <j.ottaway@lse.ac.uk>
+;; Keywords:
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Hierarchical backlink insertion into new muse pages.
+;;
+;; To add:
+;;
+;; (require 'muse-backlink)
+;; (muse-backlink-install)
+;;
+;; To control what gets backlinked, modify
+;; `muse-backlink-exclude-backlink-regexp' and
+;; `muse-backlink-exclude-backlink-parent-regexp'.
+;;
+;; To stop backlinking temporarily:
+;; (setq muse-backlink-create-backlinks nil)
+;;
+;; To remove the backlink functionality completely:
+;;
+;; (muse-backlink-remove)
+
+;;; Contributors:
+
+;;; Code:
+
+(require 'muse)
+(require 'muse-project)
+
+(eval-when-compile (require 'muse-mode))
+
+(eval-and-compile
+ (if (< emacs-major-version 22)
+ (progn
+ ;; Swiped from Emacs 22.0.50.4
+ (defvar muse-backlink-split-string-default-separators "[ \f\t\n\r\v]+"
+ "The default value of separators for `split-string'.
+
+A regexp matching strings of whitespace. May be locale-dependent
+\(as yet unimplemented). Should not match non-breaking spaces.
+
+Warning: binding this to a different value and using it as default is
+likely to have undesired semantics.")
+
+ (defun muse-backlink-split-string (string &optional separators omit-nulls)
+ "Split STRING into substrings bounded by matches for SEPARATORS.
+
+The beginning and end of STRING, and each match for SEPARATORS, are
+splitting points. The substrings matching SEPARATORS are removed, and
+the substrings between the splitting points are collected as a list,
+which is returned.
+
+If SEPARATORS is non-nil, it should be a regular expression matching text
+which separates, but is not part of, the substrings. If nil it defaults to
+`split-string-default-separators', normally \"[ \\f\\t\\n\\r\\v]+\", and
+OMIT-NULLS is forced to t.
+
+If OMIT-NULLS is t, zero-length substrings are omitted from the list \(so
+that for the default value of SEPARATORS leading and trailing whitespace
+are effectively trimmed). If nil, all zero-length substrings are retained,
+which correctly parses CSV format, for example.
+
+Note that the effect of `(split-string STRING)' is the same as
+`(split-string STRING split-string-default-separators t)'). In the rare
+case that you wish to retain zero-length substrings when splitting on
+whitespace, use `(split-string STRING split-string-default-separators)'.
+
+Modifies the match data; use `save-match-data' if necessary."
+ (let ((keep-nulls (not (if separators omit-nulls t)))
+ (rexp (or separators muse-backlink-split-string-default-separators))
+ (start 0)
+ notfirst
+ (list nil))
+ (while (and (string-match rexp string
+ (if (and notfirst
+ (= start (match-beginning 0))
+ (< start (length string)))
+ (1+ start) start))
+ (< start (length string)))
+ (setq notfirst t)
+ (if (or keep-nulls (< start (match-beginning 0)))
+ (setq list
+ (cons (substring string start (match-beginning 0))
+ list)))
+ (setq start (match-end 0)))
+ (if (or keep-nulls (< start (length string)))
+ (setq list
+ (cons (substring string start)
+ list)))
+ (nreverse list))))
+ (defalias 'muse-backlink-split-string 'split-string)))
+
+(defgroup muse-backlink nil
+ "Hierarchical backlinking for Muse."
+ :group 'muse)
+
+(defcustom muse-backlink-create-backlinks t
+ "When non-nil, create hierarchical backlinks in new Muse pages.
+For control over which pages will receive backlinks, see
+`muse-backlink-exclude-backlink-parent-regexp' and
+`muse-backlink-exclude-backlink-regexp'."
+ :type 'boolean
+ :group 'muse-backlink)
+
+(defcustom muse-backlink-avoid-bad-links t
+ "When non-nil, avoid bad links when backlinking."
+ :type 'boolean
+ :group 'muse-backlink)
+
+;; The default for exclusion stops backlinks from being added to and
+;; from planner day pages.
+(defcustom muse-backlink-exclude-backlink-parent-regexp
+ "^[0-9][0-9][0-9][0-9]\\.[0-9][0-9]\\.[0-9][0-9]$"
+ "Regular expression matching pages whose children should not have backlinks."
+ :type 'regexp
+ :group 'muse-backlink)
+
+(defcustom muse-backlink-exclude-backlink-regexp
+ "^[0-9][0-9][0-9][0-9]\\.[0-9][0-9]\\.[0-9][0-9]$"
+ "Regular expression matching pages that should not have backlinks."
+ :type 'regexp
+ :group 'muse-backlink)
+
+(defcustom muse-backlink-separator "/"
+ "String that separates backlinks.
+Should be something that will not appear as a substring in an explicit
+link that has no description."
+ :type 'string
+ :group 'muse-backlink)
+
+(defcustom muse-backlink-before-string "backlinks: "
+ "String to come before the backlink list."
+ :type 'string
+ :group 'muse-backlink)
+
+(defcustom muse-backlink-after-string ""
+ "String to come after the backlink list."
+ :type 'string
+ :group 'muse-backlink)
+
+(defcustom muse-backlink-separator "/"
+ "String that separates backlinks.
+Should be something that will not appear as a substring in an explicit
+link that has no description."
+ :type 'string
+ :group 'muse-backlink)
+
+(defcustom muse-backlink-regexp
+ (concat "^"
+ (regexp-quote muse-backlink-before-string)
+ "\\("
+ (regexp-quote muse-backlink-separator)
+ ".+\\)"
+ (regexp-quote muse-backlink-after-string))
+ ;; Really, I want something like this, but I can't make it work:
+ ;; (concat "^\\("
+ ;; (regexp-quote muse-backlink-separator)
+ ;; "\\(?:"
+ ;; muse-explicit-link-regexp
+ ;; "\\)\\)+")
+ "Regular expression to match backlinks in a buffer.
+Match 1 is the list of backlinks without `muse-backlink-before-string'
+and `muse-backlink-after-string'."
+ :type 'regexp
+ :group 'muse-backlink)
+
+(defun muse-backlink-goto-insertion-point ()
+ "Find the right place to add backlinks."
+ (goto-char (point-min))
+ (when (looking-at "\\(?:^#.+[ \t]*\n\\)+")
+ (goto-char (match-end 0))))
+
+(defun muse-backlink-get-current ()
+ "Return a list of backlinks in the current buffer."
+ (save-excursion
+ (goto-char (point-min))
+ (when (re-search-forward muse-backlink-regexp nil t)
+ (muse-backlink-split-string
+ (match-string 1)
+ (regexp-quote muse-backlink-separator) t))))
+
+(defun muse-backlink-format-link-list (links)
+ "Format the list of LINKS as backlinks."
+ (concat muse-backlink-separator
+ (mapconcat #'identity links muse-backlink-separator)))
+
+(defun muse-backlink-insert-links (links)
+ "Insert backlinks to LINKS into the current page.
+LINKS is a list of links ordered by ancestry, with the parent as the
+last element."
+ (muse-backlink-goto-insertion-point)
+ (insert muse-backlink-before-string
+ (muse-backlink-format-link-list links)
+ muse-backlink-after-string
+ ;; Could have this in the after string, but they might get
+ ;; deleted.
+ "\n\n"))
+
+(defun muse-backlink-unsaved-page-p (page project)
+ "Return non-nil if PAGE is in PROJECT but has not been saved."
+ (member
+ page
+ (mapcar
+ #'(lambda (b)
+ (with-current-buffer b
+ (and (derived-mode-p 'muse-mode)
+ (equal muse-current-project project)
+ (not (muse-project-page-file
+ (muse-page-name)
+ muse-current-project))
+ (muse-page-name))))
+ (buffer-list))))
+
+(defvar muse-backlink-links nil
+ "Internal variable.
+The links to insert in the forthcomingly visited muse page.")
+
+(defvar muse-backlink-pending nil
+ "Internal variable.")
+
+(defvar muse-backlink-parent-buffer nil
+ "Internal variable.
+The parent buffer of the forthcomingly visited muse page.")
+
+
+;;; Attach hook to the derived mode hook, to avoid problems such as
+;;; planner-prepare-file thinking that the buffer needs no template.
+(defun muse-backlink-get-mode-hook ()
+ (derived-mode-hook-name major-mode))
+
+(defun muse-backlink-insert-hook-func ()
+ "Insert backlinks into the current buffer and clean up."
+ (when (and muse-backlink-links
+ muse-backlink-pending
+ (string= (car muse-backlink-links) (muse-page-name)))
+ (muse-backlink-insert-links (cdr muse-backlink-links))
+ (when muse-backlink-avoid-bad-links
+ (save-buffer)
+ (when muse-backlink-parent-buffer
+ (with-current-buffer muse-backlink-parent-buffer
+ (font-lock-fontify-buffer))))
+ (setq muse-backlink-links nil
+ muse-backlink-parent-buffer nil
+ muse-backlink-pending nil)
+ (remove-hook (muse-backlink-get-mode-hook) #'muse-backlink-insert-hook-func)))
+
+(defun muse-backlink-handle-link (link)
+ "When appropriate, arrange for backlinks on visiting LINK."
+ (when (and muse-backlink-create-backlinks
+ (not muse-backlink-pending)
+ (memq this-command
+ '(muse-follow-name-at-point muse-follow-name-at-mouse))
+ (not muse-publishing-p)
+ (not (and (boundp 'muse-colors-fontifying-p)
+ muse-colors-fontifying-p)))
+ (require 'muse-mode)
+ (setq
+ muse-backlink-links
+ (save-match-data
+ (let* ((orig-link (or link (match-string 1)))
+ (link (if (string-match "#" orig-link)
+ (substring orig-link 0 (match-beginning 0))
+ orig-link)))
+ (unless
+ (or (not muse-current-project)
+ (string-match muse-url-regexp orig-link)
+ (string-match muse-image-regexp orig-link)
+ (and (boundp 'muse-wiki-interwiki-regexp)
+ (string-match muse-wiki-interwiki-regexp
+ orig-link))
+ ;; Don't add a backlink if the page already
+ ;; exists, whether it has been saved or not.
+ (or (muse-project-page-file link muse-current-project)
+ (muse-backlink-unsaved-page-p link muse-current-project))
+ (string-match muse-backlink-exclude-backlink-parent-regexp
+ (muse-page-name))
+ (string-match muse-backlink-exclude-backlink-regexp link))
+ ;; todo: Hmm. This will only work if the child page is the
+ ;; same mode as the parent page.
+ (add-hook (muse-backlink-get-mode-hook) #'muse-backlink-insert-hook-func)
+ (setq muse-backlink-pending t)
+ (when muse-backlink-avoid-bad-links
+ (setq muse-backlink-parent-buffer (current-buffer))
+ (unless (muse-project-page-file
+ (muse-page-name) muse-current-project)
+ ;; It must be modified...
+ (save-buffer)))
+ (cons link
+ (append (muse-backlink-get-current)
+ (list (muse-make-link (muse-page-name))))))))))
+ ;; Make sure we always return nil
+ nil)
+
+(defun muse-backlink-install ()
+ "Add backlinking functionality to muse-mode."
+ (add-to-list 'muse-explicit-link-functions #'muse-backlink-handle-link))
+
+(defun muse-backlink-remove ()
+ "Remove backlinking functionality from muse-mode."
+ (setq muse-explicit-link-functions
+ (delq #'muse-backlink-handle-link muse-explicit-link-functions)))
+
+(provide 'muse-backlink)
+;;; muse-backlink.el ends here
--- /dev/null
+;;; muse-blosxom.el --- publish a document tree for serving by (py)Blosxom
+
+;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; Author: Michael Olson <mwolson@gnu.org>
+;; Date: Wed, 23 March 2005
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; The Blosxom publishing style publishes a tree of categorised files
+;; to a mirrored tree of stories to be served by blosxom.cgi or
+;; pyblosxom.cgi.
+;;
+;; Serving entries with (py)blosxom
+;; --------------------------------
+;;
+;; Each Blosxom file must include `#date yyyy-mm-dd', or optionally
+;; the longer `#date yyyy-mm-dd-hh-mm', a title (using the `#title'
+;; directive) plus whatever normal content is desired.
+;;
+;; The date directive is not used directly by (py)blosxom or this
+;; program. You need to find two additional items to make use of this
+;; feature.
+;;
+;; 1. A script to gather date directives from the entire blog tree
+;; into a single file. The file must associate a blog entry with
+;; a date.
+;;
+;; 2. A plugin for (py)blosxom that reads this file.
+;;
+;; These 2 things are provided for pyblosxom in the contrib/pyblosxom
+;; subdirectory. `getstamps.py' provides the 1st service, while
+;; `hardcodedates.py' provides the second service. Eventually it is
+;; hoped that a blosxom plugin and script will be found/written.
+;;
+;; Alternately, the pyblosxom metadate plugin may be used. On the
+;; plus side, there is no need to run a script to gather the date. On
+;; the downside, each entry is read twice rather than once when the
+;; page is rendered. Set the value of muse-blosxom-use-metadate to
+;; non-nil to enable adding a #postdate directive to all published
+;; files. You can do this by:
+;;
+;; M-x customize-variable RET muse-blosxom-use-metadate RET
+;;
+;; With the metadate plugin installed in pyblosxom, the date set in
+;; this directive will be used instead of the file's modification
+;; time. The plugin is included with Muse at
+;; contrib/pyblosxom/metadate.py.
+;;
+;; Generating a Muse project entry
+;; -------------------------------
+;;
+;; Muse-blosxom has some helper functions to make specifying
+;; muse-blosxom projects a lot easier. An example follows.
+;;
+;; (setq muse-project-alist
+;; `(("blog"
+;; (,@(muse-project-alist-dirs "~/path/to/blog-entries")
+;; :default "index")
+;; ,@(muse-project-alist-styles "~/path/to/blog-entries"
+;; "~/public_html/blog"
+;; "blosxom-xhtml")
+;; )))
+;;
+;; Note that we need a backtick instead of a single quote on the
+;; second line of this example.
+;;
+;; Creating new blog entries
+;; -------------------------
+;;
+;; There is a function called `muse-blosxom-new-entry' that will
+;; automate the process of making a new blog entry. To make use of
+;; it, do the following.
+;;
+;; - Customize `muse-blosxom-base-directory' to the location that
+;; your blog entries are stored.
+;;
+;; - Assign the `muse-blosxom-new-entry' function to a key sequence.
+;; I use the following code to assign this function to `C-c p l'.
+;;
+;; (global-set-key "\C-cpl" 'muse-blosxom-new-entry)
+;;
+;; - You should create your directory structure ahead of time under
+;; your base directory. These directories, which correspond with
+;; category names, may be nested.
+;;
+;; - When you enter this key sequence, you will be prompted for the
+;; category of your entry and its title. Upon entering this
+;; information, a new file will be created that corresponds with
+;; the title, but in lowercase letters and having special
+;; characters converted to underscores. The title and date
+;; directives will be inserted automatically.
+;;
+;; Using tags
+;; ----------
+;;
+;; If you wish to keep all of your blog entries in one directory and
+;; use tags to classify your entries, set `muse-blosxom-use-tags' to
+;; non-nil.
+;;
+;; For this to work, you will need to be using the PyBlosxom plugin at
+;; http://pyblosxom.sourceforge.net/blog/registry/meta/Tags.
+
+;;; Contributors:
+
+;; Gary Vaughan (gary AT gnu DOT org) is the original author of
+;; `emacs-wiki-blosxom.el', which is the ancestor of this file.
+
+;; Brad Collins (brad AT chenla DOT org) ported this file to Muse.
+
+;; Björn Lindström (bkhl AT elektrubadur DOT se) made many valuable
+;; suggestions.
+
+;; Sasha Kovar (sasha AT arcocene DOT org) fixed
+;; muse-blosxom-new-entry when using tags and also implemented support
+;; for the #postdate directive.
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Muse Blosxom Publishing
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(require 'muse-project)
+(require 'muse-publish)
+(require 'muse-html)
+
+(defgroup muse-blosxom nil
+ "Options controlling the behavior of Muse Blosxom publishing.
+See `muse-blosxom' for more information."
+ :group 'muse-publish)
+
+(defcustom muse-blosxom-extension ".txt"
+ "Default file extension for publishing Blosxom files."
+ :type 'string
+ :group 'muse-blosxom)
+
+(defcustom muse-blosxom-header
+ "<lisp>(concat (muse-publishing-directive \"title\") \"\\n\"
+ (when muse-blosxom-use-metadate
+ (let ((date (muse-publishing-directive \"date\")))
+ (when date (concat \"#postdate \"
+ (muse-blosxom-format-date date) \"\\n\"))))
+ (when muse-blosxom-use-tags
+ (let ((tags (muse-publishing-directive \"tags\")))
+ (when tags (concat \"#tags \" tags \"\\n\")))))</lisp>"
+ "Header used for publishing Blosxom files. This may be text or a filename."
+ :type 'string
+ :group 'muse-blosxom)
+
+(defcustom muse-blosxom-footer ""
+ "Footer used for publishing Blosxom files. This may be text or a filename."
+ :type 'string
+ :group 'muse-blosxom)
+
+(defcustom muse-blosxom-base-directory "~/Blog"
+ "Base directory of blog entries.
+This is the top-level directory where your Muse blog entries may be found."
+ :type 'directory
+ :group 'muse-blosxom)
+
+(defcustom muse-blosxom-use-tags nil
+ "Determine whether or not to enable use of the #tags directive.
+
+If you wish to keep all of your blog entries in one directory and
+use tags to classify your entries, set `muse-blosxom-use-tags' to
+non-nil.
+
+For this to work, you will need to be using the PyBlosxom plugin
+at http://pyblosxom.sourceforge.net/blog/registry/meta/Tags."
+ :type 'boolean
+ :group 'muse-blosxom)
+
+(defcustom muse-blosxom-use-metadate nil
+ "Determine whether or not to use the #postdate directive.
+
+If non-nil, published entries include the original date (as specified
+in the muse #date line) which can be read by the metadate PyBlosxom
+plugin.
+
+For this to work, you will need to be using the PyBlosxom plugin
+at http://pyblosxom.sourceforge.net/blog/registry/date/metadate."
+ :type 'boolean
+ :group 'muse-blosxom)
+
+;; Maintain (published-file . date) alist, which will later be written
+;; to a timestamps file; not implemented yet.
+
+(defvar muse-blosxom-page-date-alist nil)
+
+(defun muse-blosxom-update-page-date-alist ()
+ "Add a date entry to `muse-blosxom-page-date-alist' for this page."
+ (when muse-publishing-current-file
+ ;; Make current file be relative to base directory
+ (let ((rel-file
+ (concat
+ (file-name-as-directory
+ (or (muse-publishing-directive "category")
+ (file-relative-name
+ (file-name-directory
+ (expand-file-name muse-publishing-current-file))
+ (file-truename muse-blosxom-base-directory))))
+ (file-name-nondirectory muse-publishing-current-file))))
+ ;; Strip the file extension
+ (when muse-ignored-extensions-regexp
+ (setq rel-file (save-match-data
+ (and (string-match muse-ignored-extensions-regexp
+ rel-file)
+ (replace-match "" t t rel-file)))))
+ ;; Add to page-date alist
+ (add-to-list
+ 'muse-blosxom-page-date-alist
+ `(,rel-file . ,(muse-publishing-directive "date"))))))
+
+;; Enter a new blog entry
+
+(defun muse-blosxom-title-to-file (title)
+ "Derive a file name from the given TITLE.
+
+Feel free to overwrite this if you have a different concept of what
+should be allowed in a filename."
+ (muse-replace-regexp-in-string (concat "[^-." muse-regexp-alnum "]")
+ "_" (downcase title)))
+
+(defun muse-blosxom-format-date (date)
+ "Convert a date string to PyBlosxom metadate plugin format."
+ (apply #'format "%s-%s-%s %s:%s" (split-string date "-")))
+
+;;;###autoload
+(defun muse-blosxom-new-entry (category title)
+ "Start a new blog entry with given CATEGORY.
+The filename of the blog entry is derived from TITLE.
+The page will be initialized with the current date and TITLE."
+ (interactive
+ (list
+ (if muse-blosxom-use-tags
+ (let ((tag "foo")
+ (tags nil))
+ (while (progn (setq tag (read-string "Tag (RET to continue): "))
+ (not (string= tag "")))
+ (add-to-list 'tags tag t))
+ tags)
+ (funcall muse-completing-read-function
+ "Category: "
+ (mapcar 'list (muse-project-recurse-directory
+ muse-blosxom-base-directory))))
+ (read-string "Title: ")))
+ (let ((file (muse-blosxom-title-to-file title)))
+ (muse-project-find-file
+ file "blosxom" nil
+ (if muse-blosxom-use-tags
+ (directory-file-name muse-blosxom-base-directory)
+ (concat (directory-file-name muse-blosxom-base-directory)
+ "/" category))))
+ (goto-char (point-min))
+ (insert "#date " (format-time-string "%Y-%m-%d-%H-%M")
+ "\n#title " title)
+ (if muse-blosxom-use-tags
+ (if (> (length category) 0)
+ (insert (concat "\n#tags " (mapconcat #'identity category ","))))
+ (unless (string= category "")
+ (insert (concat "\n#category " category))))
+ (insert "\n\n")
+ (forward-line 2))
+
+;;; Register the Muse Blosxom Publisher
+
+(muse-derive-style "blosxom-html" "html"
+ :suffix 'muse-blosxom-extension
+ :link-suffix 'muse-html-extension
+ :header 'muse-blosxom-header
+ :footer 'muse-blosxom-footer
+ :after 'muse-blosxom-update-page-date-alist
+ :browser 'find-file)
+
+(muse-derive-style "blosxom-xhtml" "xhtml"
+ :suffix 'muse-blosxom-extension
+ :link-suffix 'muse-xhtml-extension
+ :header 'muse-blosxom-header
+ :footer 'muse-blosxom-footer
+ :after 'muse-blosxom-update-page-date-alist
+ :browser 'find-file)
+
+(provide 'muse-blosxom)
+
+;;; muse-blosxom.el ends here
--- /dev/null
+;;; muse-book.el --- publish entries into a compilation
+
+;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Contributors:
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Muse Book Publishing
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(require 'muse-publish)
+(require 'muse-project)
+(require 'muse-latex)
+(require 'muse-regexps)
+
+(defgroup muse-book nil
+ "Module for publishing a series of Muse pages as a complete book.
+Each page will become a separate chapter in the book, unless the
+style keyword :nochapters is used, in which case they are all run
+together as if one giant chapter."
+ :group 'muse-publish)
+
+(defcustom muse-book-before-publish-hook nil
+ "A hook run in the book buffer before it is marked up."
+ :type 'hook
+ :group 'muse-book)
+
+(defcustom muse-book-after-publish-hook nil
+ "A hook run in the book buffer after it is marked up."
+ :type 'hook
+ :group 'muse-book)
+
+(defcustom muse-book-latex-header
+ "\\documentclass{book}
+
+\\usepackage[english]{babel}
+\\usepackage[latin1]{inputenc}
+\\usepackage[T1]{fontenc}
+
+\\begin{document}
+
+\\title{<lisp>(muse-publishing-directive \"title\")</lisp>}
+\\author{<lisp>(muse-publishing-directive \"author\")</lisp>}
+\\date{<lisp>(muse-publishing-directive \"date\")</lisp>}
+
+\\maketitle
+
+\\tableofcontents\n"
+ "Header used for publishing books to LaTeX. This may be text or a filename."
+ :type 'string
+ :group 'muse-book)
+
+(defcustom muse-book-latex-footer
+ "<lisp>(muse-latex-bibliography)</lisp>
+\\end{document}"
+ "Footer used for publishing books to LaTeX. This may be text or a filename."
+ :type 'string
+ :group 'muse-book)
+
+(defun muse-book-publish-chapter (title entry style &optional nochapters)
+ "Publish the chapter TITLE for the file ENTRY using STYLE.
+TITLE is a string, ENTRY is a cons of the form (PAGE-NAME .
+FILE), and STYLE is a Muse style list.
+
+This routine does the same basic work as `muse-publish-markup-buffer',
+but treating the page as if it were a single chapter within a book."
+ (let ((muse-publishing-directives (list (cons "title" title)))
+ (muse-publishing-current-file (cdr entry))
+ (beg (point)) end)
+ (muse-insert-file-contents (cdr entry))
+ (setq end (copy-marker (point-max) t))
+ (muse-publish-markup-region beg end (car entry) style)
+ (goto-char beg)
+ (unless (or nochapters
+ (muse-style-element :nochapters style))
+ (insert "\n")
+ (muse-insert-markup (muse-markup-text 'chapter))
+ (insert (let ((chap (muse-publishing-directive "title")))
+ (if (string= chap title)
+ (car entry)
+ chap)))
+ (muse-insert-markup (muse-markup-text 'chapter-end))
+ (insert "\n\n"))
+ (save-restriction
+ (narrow-to-region beg end)
+ (muse-publish-markup (or title "")
+ '((100 "<\\(lisp\\)>" 0
+ muse-publish-markup-tag)))
+ (muse-style-run-hooks :after style))
+ (goto-char end)))
+
+(defun muse-book-publish-p (project target)
+ "Determine whether the book in PROJECT is out-of-date."
+ (let ((pats (cadr project)))
+ (catch 'publish
+ (while pats
+ (if (symbolp (car pats))
+ (if (eq :book-end (car pats))
+ (throw 'publish nil)
+ ;; skip past symbol-value pair
+ (setq pats (cddr pats)))
+ (dolist (entry (muse-project-file-entries (car pats)))
+ (when (and (not (muse-project-private-p (cdr entry)))
+ (file-newer-than-file-p (cdr entry) target))
+ (throw 'publish t)))
+ (setq pats (cdr pats)))))))
+
+(defun muse-book-get-directives (file)
+ "Interpret any publishing directives contained in FILE.
+This is meant to be called in a temp buffer that will later be
+used for publishing."
+ (save-restriction
+ (narrow-to-region (point) (point))
+ (unwind-protect
+ (progn
+ (muse-insert-file-contents file)
+ (muse-publish-markup
+ "attributes"
+ `(;; Remove leading and trailing whitespace from the file
+ (100 "\\(\\`\n+\\|\n+\\'\\)" 0 "")
+ ;; Remove trailing whitespace from all lines
+ (200 ,(concat "[" muse-regexp-blank "]+$") 0 "")
+ ;; Handle any leading #directives
+ (300 "\\`#\\([a-zA-Z-]+\\)\\s-+\\(.+\\)\n+"
+ 0 muse-publish-markup-directive))))
+ (delete-region (point-min) (point-max)))))
+
+(defun muse-book-publish-project
+ (project book title style &optional output-dir force)
+ "Publish PROJECT under the name BOOK with the given TITLE and STYLE.
+BOOK should be a page name, i.e., letting the style determine the
+prefix and/or suffix. The book is published to OUTPUT-DIR. If FORCE
+is nil, the book is only published if at least one of its component
+pages has changed since it was last published."
+ (interactive
+ (let ((project (muse-read-project "Publish project as book: " nil t)))
+ (append (list project
+ (read-string "Basename of book (without extension): ")
+ (read-string "Title of book: "))
+ (muse-publish-get-info))))
+ (setq project (muse-project project))
+ (let ((muse-current-project project))
+ ;; See if any of the project's files need saving first
+ (muse-project-save-buffers project)
+ ;; Publish the book
+ (muse-book-publish book style output-dir force title)))
+
+(defun muse-book-publish (file style &optional output-dir force title)
+ "Publish FILE as a book with the given TITLE and STYLE.
+The book is published to OUTPUT-DIR. If FORCE is nil, the book
+is only published if at least one of its component pages has
+changed since it was last published."
+ ;; Cleanup some of the arguments
+ (let ((style-name style))
+ (setq style (muse-style style))
+ (unless style
+ (error "There is no style '%s' defined" style-name)))
+ ;; Publish each page in the project as a chapter in one large book
+ (let* ((output-path (muse-publish-output-file file output-dir style))
+ (output-suffix (muse-style-element :osuffix style))
+ (target output-path)
+ (project muse-current-project)
+ (published nil))
+ (when output-suffix
+ (setq target (concat (muse-path-sans-extension target)
+ output-suffix)))
+ ;; Unless force is non-nil, determine if the book needs publishing
+ (if (and (not force)
+ (not (muse-book-publish-p project target)))
+ (message "The book \"%s\" is up-to-date." file)
+ ;; Create the book from all its component parts
+ (muse-with-temp-buffer
+ (let ((style-final (muse-style-element :final style t))
+ (style-header (muse-style-element :header style))
+ (style-footer (muse-style-element :footer style))
+ (muse-publishing-current-style style)
+ (muse-publishing-directives
+ (list (cons "title" (or title (muse-page-name file)))
+ (cons "date" (format-time-string "%B %e, %Y"))))
+ (muse-publishing-p t)
+ (muse-current-project project)
+ (pats (cadr project))
+ (nochapters nil))
+ (run-hooks 'muse-before-book-publish-hook)
+ (let ((style-final style-final)
+ (style-header style-header)
+ (style-footer style-footer))
+ (unless title
+ (muse-book-get-directives file)
+ (setq title (muse-publishing-directive "title")))
+ (while pats
+ (if (symbolp (car pats))
+ (cond
+ ((eq :book-part (car pats))
+ (insert "\n")
+ (muse-insert-markup (muse-markup-text 'part))
+ (insert (cadr pats))
+ (muse-insert-markup (muse-markup-text 'part-end))
+ (insert "\n")
+ (setq pats (cddr pats)))
+ ((eq :book-chapter (car pats))
+ (insert "\n")
+ (muse-insert-markup (muse-markup-text 'chapter))
+ (insert (cadr pats))
+ (muse-insert-markup (muse-markup-text 'chapter-end))
+ (insert "\n")
+ (setq pats (cddr pats)))
+ ((eq :nochapters (car pats))
+ (setq nochapters t
+ pats (cddr pats)))
+ ((eq :book-style (car pats))
+ (setq style (muse-style (cadr pats)))
+ (setq style-final (muse-style-element :final style t)
+ style-header (muse-style-element :header style)
+ style-footer (muse-style-element :footer style)
+ muse-publishing-current-style style)
+ (setq pats (cddr pats)))
+ ((eq :book-funcall (car pats))
+ (funcall (cadr pats))
+ (setq pats (cddr pats)))
+ ((eq :book-end (car pats))
+ (setq pats nil))
+ (t
+ (setq pats (cddr pats))))
+ (let ((entries (muse-project-file-entries (car pats))))
+ (while (and entries (car entries) (caar entries))
+ (unless (muse-project-private-p (cdar entries))
+ (muse-book-publish-chapter title (car entries)
+ style nochapters)
+ (setq published t))
+ (setq entries (cdr entries))))
+ (setq pats (cdr pats)))))
+ (goto-char (point-min))
+ (if style-header (muse-insert-file-or-string style-header file))
+ (goto-char (point-max))
+ (if style-footer (muse-insert-file-or-string style-footer file))
+ (run-hooks 'muse-after-book-publish-hook)
+ (if (muse-write-file output-path)
+ (if style-final
+ (funcall style-final file output-path target))
+ (setq published nil)))))
+ (if published
+ (message "The book \"%s\" has been published." file))
+ published))
+
+;;; Register the Muse BOOK Publishers
+
+(muse-derive-style "book-latex" "latex"
+ :header 'muse-book-latex-header
+ :footer 'muse-book-latex-footer
+ :publish 'muse-book-publish)
+
+(muse-derive-style "book-pdf" "pdf"
+ :header 'muse-book-latex-header
+ :footer 'muse-book-latex-footer
+ :publish 'muse-book-publish)
+
+(provide 'muse-book)
+
+;;; muse-book.el ends here
--- /dev/null
+;;; muse-colors.el --- coloring and highlighting used by Muse
+
+;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; Author: John Wiegley (johnw AT gnu DOT org)
+;; Keywords: hypermedia
+;; Date: Thu 11-Mar-2004
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Contributors:
+
+;; Lan Yufeng (nlany DOT web AT gmail DOT com) found an error where
+;; headings were being given the wrong face, contributing a patch to
+;; fix this.
+
+;; Sergey Vlasov (vsu AT altlinux DOT ru) fixed an issue with coloring
+;; links that are in consecutive lines.
+
+;; Jim Ottaway ported the <lisp> tag from emacs-wiki.
+
+;; Per B. Sederberg (per AT med DOT upenn DOT edu) contributed the
+;; viewing of inline images.
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Emacs Muse Highlighting
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(require 'muse-mode)
+(require 'muse-regexps)
+(require 'font-lock)
+
+(defgroup muse-colors nil
+ "Options controlling the behavior of Emacs Muse highlighting.
+See `muse-colors-buffer' for more information."
+ :group 'muse-mode)
+
+(defcustom muse-colors-autogen-headings t
+ "Specify whether the heading faces should be auto-generated.
+The default is to scale them.
+
+Choosing 'outline will copy the colors from the outline-mode
+headings.
+
+If you want to customize each of the headings individually, set
+this to nil."
+ :type '(choice (const :tag "Default (scaled) headings" t)
+ (const :tag "Use outline-mode headings" outline)
+ (const :tag "Don't touch the headings" nil))
+ :group 'muse-colors)
+
+(defcustom muse-colors-evaluate-lisp-tags t
+ "Specify whether to evaluate the contents of <lisp> tags at
+display time. If nil, don't evaluate them. If non-nil, evaluate
+them.
+
+The actual contents of the buffer are not changed, only the
+displayed text."
+ :type 'boolean
+ :group 'muse-colors)
+
+(defcustom muse-colors-inline-images t
+ "Specify whether to inline images inside the Emacs buffer. If
+nil, don't inline them. If non-nil, an image link will be
+replaced by the image.
+
+The actual contents of the buffer are not changed, only whether
+an image is displayed."
+ :type 'boolean
+ :group 'muse-colors)
+
+(defcustom muse-colors-inline-image-method 'default-directory
+ "Determine how to locate inline images.
+Setting this to 'default-directory uses the current directory of
+the current Muse buffer.
+
+Setting this to a function calls that function with the filename
+of the image to be inlined. The value that is returned will be
+used as the filename of the image."
+ :type '(choice (const :tag "Current directory" default-directory)
+ (const :tag "Publishing directory"
+ muse-colors-use-publishing-directory)
+ (function :tag "Custom function"))
+ :group 'muse-colors)
+
+(defvar muse-colors-region-end nil
+ "Indicate the end of the region that is currently being font-locked.")
+(make-variable-buffer-local 'muse-colors-region-end)
+
+;;;###autoload
+(defun muse-colors-toggle-inline-images ()
+ "Toggle display of inlined images on/off."
+ (interactive)
+ ;; toggle the custom setting
+ (if (not muse-colors-inline-images)
+ (setq muse-colors-inline-images t)
+ (setq muse-colors-inline-images nil))
+ ;; reprocess the buffer
+ (muse-colors-buffer)
+ ;; display informative message
+ (if muse-colors-inline-images
+ (message "Images are now displayed inline")
+ (message "Images are now displayed as links")))
+
+(defvar muse-colors-outline-faces-list
+ (if (facep 'outline-1)
+ '(outline-1 outline-2 outline-3 outline-4 outline-5)
+ ;; these are equivalent in coloring to the outline faces
+ '(font-lock-function-name-face
+ font-lock-variable-name-face
+ font-lock-keyword-face
+ font-lock-builtin-face
+ font-lock-comment-face))
+ "Outline faces to use when assigning Muse header faces.")
+
+(defun muse-make-faces-default (&optional later)
+ "Generate the default face definitions for headers."
+ (dolist (num '(1 2 3 4 5))
+ (let ((newsym (intern (concat "muse-header-" (int-to-string num))))
+ (docstring (concat
+ "Muse header face. See "
+ "`muse-colors-autogen-headings' before changing it.")))
+ ;; put in the proper group and give documentation
+ (if later
+ (unless (featurep 'xemacs)
+ (muse-copy-face 'variable-pitch newsym)
+ (set-face-attribute newsym nil :height (1+ (* 0.1 (- 5 num)))
+ :weight 'bold))
+ (if (featurep 'xemacs)
+ (eval `(defface ,newsym
+ '((t (:size
+ ,(nth (1- num)
+ '("24pt" "18pt" "14pt" "12pt" "11pt"))
+ :bold t)))
+ ,docstring
+ :group 'muse-colors))
+ (eval `(defface ,newsym
+ '((t (:height ,(1+ (* 0.1 (- 5 num)))
+ :inherit variable-pitch
+ :weight bold)))
+ ,docstring
+ :group 'muse-colors)))))))
+
+(progn (muse-make-faces-default))
+
+(defun muse-make-faces (&optional frame)
+ "Generate face definitions for headers based the user's preferences."
+ (cond
+ ((not muse-colors-autogen-headings)
+ nil)
+ ((eq muse-colors-autogen-headings t)
+ (muse-make-faces-default t))
+ (t
+ (dolist (num '(1 2 3 4 5))
+ (let ((newsym (intern (concat "muse-header-" (int-to-string num)))))
+ ;; copy the desired face definition
+ (muse-copy-face (nth (1- num) muse-colors-outline-faces-list)
+ newsym))))))
+
+;; after displaying the Emacs splash screen, the faces are wiped out,
+;; so recover from that
+(add-hook 'window-setup-hook #'muse-make-faces)
+;; ditto for when a new frame is created
+(when (boundp 'after-make-frame-functions)
+ (add-hook 'after-make-frame-functions #'muse-make-faces))
+
+(defface muse-link
+ '((((class color) (background light))
+ (:foreground "blue" :underline "blue" :bold t))
+ (((class color) (background dark))
+ (:foreground "cyan" :underline "cyan" :bold t))
+ (t (:bold t)))
+ "Face for Muse cross-references."
+ :group 'muse-colors)
+
+(defface muse-bad-link
+ '((((class color) (background light))
+ (:foreground "red" :underline "red" :bold t))
+ (((class color) (background dark))
+ (:foreground "coral" :underline "coral" :bold t))
+ (t (:bold t)))
+ "Face for bad Muse cross-references."
+ :group 'muse-colors)
+
+(defface muse-verbatim
+ '((((class color) (background light))
+ (:foreground "slate gray"))
+ (((class color) (background dark))
+ (:foreground "gray")))
+ "Face for verbatim text."
+ :group 'muse-colors)
+
+(defface muse-emphasis-1
+ '((t (:italic t)))
+ "Face for italic emphasized text."
+ :group 'muse-colors)
+
+(defface muse-emphasis-2
+ '((t (:bold t)))
+ "Face for bold emphasized text."
+ :group 'muse-colors)
+
+(defface muse-emphasis-3
+ '((t (:bold t :italic t)))
+ "Face for bold italic emphasized text."
+ :group 'muse-colors)
+
+(muse-copy-face 'italic 'muse-emphasis-1)
+(muse-copy-face 'bold 'muse-emphasis-2)
+(muse-copy-face 'bold-italic 'muse-emphasis-3)
+
+(defcustom muse-colors-buffer-hook nil
+ "A hook run after a region is highlighted.
+Each function receives three arguments: BEG END VERBOSE.
+BEG and END mark the range being highlighted, and VERBOSE specifies
+whether progress messages should be displayed to the user."
+ :type 'hook
+ :group 'muse-colors)
+
+(defvar muse-colors-highlighting-registry nil
+ "The rules for highlighting Muse and Muse-derived buffers.
+This is automatically generated when using font-lock in Muse buffers.
+
+This an alist of major-mode symbols to `muse-colors-rule' objects.")
+
+(defun muse-colors-make-highlighting-struct ()
+ (list nil nil nil))
+(defconst muse-colors-highlighting.regexp 0
+ "Regexp matching each car of the markup of the current rule.")
+(defconst muse-colors-highlighting.vector 1
+ "Vector of all characters that are part of the markup of the current rule.
+This is composed of the 2nd element of each markup entry.")
+(defconst muse-colors-highlighting.remaining 2
+ "Expressions for highlighting a buffer which have no corresponding
+entry in the vector.")
+
+(defsubst muse-colors-highlighting-entry (mode)
+ "Return the highlighting rules for MODE."
+ (assq mode muse-colors-highlighting-registry))
+
+(defun muse-colors-find-highlighting (mode)
+ "Return the highlighting rules to be used for MODE.
+If MODE does not have highlighting rules, check its parent modes."
+ (let ((seen nil))
+ (catch 'rules
+ (while (and mode (not (memq mode seen)))
+ (let ((entry (muse-colors-highlighting-entry mode)))
+ (when entry (throw 'rules (cdr entry))))
+ (setq seen (cons mode seen))
+ (setq mode (get mode 'derived-mode-parent)))
+ nil)))
+
+(defun muse-colors-define-highlighting (mode markup)
+ "Create or update the markup rules for MODE, using MARKUP.
+
+See `muse-colors-markup' for an explanation of the format that MARKUP
+should take."
+ (unless (and (symbolp mode) mode (consp markup))
+ (error "Invalid arguments"))
+ (let* ((highlighting-entry (muse-colors-highlighting-entry mode))
+ (struct (cdr highlighting-entry))
+ (regexp nil)
+ (vector nil)
+ (remaining nil))
+ ;; Initialize struct
+ (if struct
+ (setq vector (nth muse-colors-highlighting.vector struct))
+ (setq struct (muse-colors-make-highlighting-struct)))
+ ;; Initialize vector
+ (if vector
+ (let ((i 0))
+ (while (< i 128)
+ (aset vector i nil)
+ (setq i (1+ i))))
+ (setq vector (make-vector 128 nil)))
+ ;; Determine vector, regexp, remaining
+ (let ((regexps nil)
+ (rules nil))
+ (dolist (rule markup)
+ (let ((value (cond ((symbolp (car rule))
+ (symbol-value (car rule)))
+ ((stringp (car rule))
+ (car rule))
+ (t nil))))
+ (when value
+ (setq rules (cons rule rules))
+ (setq regexps (cons value regexps)))))
+ (setq regexps (nreverse regexps))
+ (setq regexp (concat "\\(" (mapconcat #'identity regexps "\\|") "\\)"))
+ (dolist (rule rules)
+ (if (eq (nth 1 rule) t)
+ (setq remaining (cons (cons (nth 0 rule) (nth 2 rule))
+ remaining))
+ (aset vector (nth 1 rule)
+ (cons (cons (nth 0 rule) (nth 2 rule))
+ (aref vector (nth 1 rule)))))))
+ ;; Update the struct
+ (setcar (nthcdr muse-colors-highlighting.regexp struct) regexp)
+ (setcar (nthcdr muse-colors-highlighting.vector struct) vector)
+ (setcar (nthcdr muse-colors-highlighting.remaining struct) remaining)
+ ;; Update entry for mode in muse-colors-highlighting-registry
+ (if highlighting-entry
+ (setcdr highlighting-entry struct)
+ (setq muse-colors-highlighting-registry
+ (cons (cons mode struct)
+ muse-colors-highlighting-registry)))))
+
+(defun muse-configure-highlighting (sym val)
+ "Extract color markup information from VAL and set to SYM.
+This is usually called with `muse-colors-markup' as both arguments."
+ (muse-colors-define-highlighting 'muse-mode val)
+ (set sym val))
+
+(defun muse-colors-emphasized ()
+ "Color emphasized text and headings."
+ ;; Here we need to check four different points - the start and end
+ ;; of the leading *s, and the start and end of the trailing *s. We
+ ;; allow the outsides to be surrounded by whitespace or punctuation,
+ ;; but no word characters, and the insides must not be surrounded by
+ ;; whitespace or punctuation. Thus the following are valid:
+ ;;
+ ;; " *foo bar* "
+ ;; "**foo**,"
+ ;; and the following is invalid:
+ ;; "** testing **"
+ (let* ((beg (match-beginning 0))
+ (e1 (match-end 0))
+ (leader (- e1 beg))
+ b2 e2 multiline)
+ (unless (or (eq (get-text-property beg 'invisible) 'muse)
+ (get-text-property beg 'muse-comment)
+ (get-text-property beg 'muse-directive))
+ ;; check if it's a header
+ (if (eq (char-after e1) ?\ )
+ (when (or (= beg (point-min))
+ (eq (char-before beg) ?\n))
+ (add-text-properties
+ (muse-line-beginning-position) (muse-line-end-position)
+ (list 'face (intern (concat "muse-header-"
+ (int-to-string leader))))))
+ ;; beginning of line or space or symbol
+ (when (or (= beg (point-min))
+ (eq (char-syntax (char-before beg)) ?\ )
+ (memq (char-before beg)
+ '(?\- ?\[ ?\< ?\( ?\' ?\` ?\" ?\n)))
+ (save-excursion
+ (skip-chars-forward "^*<>\n" muse-colors-region-end)
+ (when (eq (char-after) ?\n)
+ (setq multiline t)
+ (skip-chars-forward "^*<>" muse-colors-region-end))
+ (setq b2 (point))
+ (skip-chars-forward "*" muse-colors-region-end)
+ (setq e2 (point))
+ ;; Abort if space exists just before end
+ ;; or bad leader
+ ;; or no '*' at end
+ ;; or word constituent follows
+ (unless (or (> leader 5)
+ (not (eq leader (- e2 b2)))
+ (eq (char-syntax (char-before b2)) ?\ )
+ (not (eq (char-after b2) ?*))
+ (and (not (eobp))
+ (eq (char-syntax (char-after (1+ b2))) ?w)))
+ (add-text-properties beg e1 '(invisible muse))
+ (add-text-properties
+ e1 b2 (list 'face (cond ((= leader 1) 'muse-emphasis-1)
+ ((= leader 2) 'muse-emphasis-2)
+ ((= leader 3) 'muse-emphasis-3))))
+ (add-text-properties b2 e2 '(invisible muse))
+ (when multiline
+ (add-text-properties
+ beg e2 '(font-lock-multiline t))))))))))
+
+(defun muse-colors-underlined ()
+ "Color underlined text."
+ (let ((start (match-beginning 0))
+ multiline)
+ (unless (or (eq (get-text-property start 'invisible) 'muse)
+ (get-text-property start 'muse-comment)
+ (get-text-property start 'muse-directive))
+ ;; beginning of line or space or symbol
+ (when (or (= start (point-min))
+ (eq (char-syntax (char-before start)) ?\ )
+ (memq (char-before start)
+ '(?\- ?\[ ?\< ?\( ?\' ?\` ?\" ?\n)))
+ (save-excursion
+ (skip-chars-forward "^_<>\n" muse-colors-region-end)
+ (when (eq (char-after) ?\n)
+ (setq multiline t)
+ (skip-chars-forward "^_<>" muse-colors-region-end))
+ ;; Abort if space exists just before end
+ ;; or no '_' at end
+ ;; or word constituent follows
+ (unless (or (eq (char-syntax (char-before (point))) ?\ )
+ (not (eq (char-after (point)) ?_))
+ (and (not (eobp))
+ (eq (char-syntax (char-after (1+ (point)))) ?w)))
+ (add-text-properties start (1+ start) '(invisible muse))
+ (add-text-properties (1+ start) (point) '(face underline))
+ (add-text-properties (point)
+ (min (1+ (point)) (point-max))
+ '(invisible muse))
+ (when multiline
+ (add-text-properties
+ start (min (1+ (point)) (point-max))
+ '(font-lock-multiline t)))))))))
+
+(defun muse-colors-verbatim ()
+ "Render in teletype and suppress further parsing."
+ (let ((start (match-beginning 0))
+ multiline)
+ (unless (or (eq (get-text-property start 'invisible) 'muse)
+ (get-text-property start 'muse-comment)
+ (get-text-property start 'muse-directive))
+ ;; beginning of line or space or symbol
+ (when (or (= start (point-min))
+ (eq (char-syntax (char-before start)) ?\ )
+ (memq (char-before start)
+ '(?\- ?\[ ?\< ?\( ?\' ?\` ?\" ?\n)))
+ (let ((pos (point)))
+ (skip-chars-forward "^=\n" muse-colors-region-end)
+ (when (eq (char-after) ?\n)
+ (setq multiline t)
+ (skip-chars-forward "^=" muse-colors-region-end))
+ ;; Abort if space exists just before end
+ ;; or no '=' at end
+ ;; or word constituent follows
+ (unless (or (eq (char-syntax (char-before (point))) ?\ )
+ (not (eq (char-after (point)) ?=))
+ (and (not (eobp))
+ (eq (char-syntax (char-after (1+ (point)))) ?w)))
+ (setq pos (min (1+ (point)) (point-max)))
+ (add-text-properties start (1+ start) '(invisible muse))
+ (add-text-properties (1+ start) (point) '(face muse-verbatim))
+ (add-text-properties (point)
+ (min (1+ (point)) (point-max))
+ '(invisible muse))
+ (when multiline
+ (add-text-properties
+ start (min (1+ (point)) (point-max))
+ '(font-lock-multiline t))))
+ (goto-char pos))))))
+
+(defcustom muse-colors-markup
+ `(;; make emphasized text appear emphasized
+ ("\\*\\{1,5\\}" ?* muse-colors-emphasized)
+
+ ;; make underlined text appear underlined
+ (,(concat "_[^" muse-regexp-blank "_\n]")
+ ?_ muse-colors-underlined)
+
+ ("^#title " ?\# muse-colors-title)
+
+ (muse-explicit-link-regexp ?\[ muse-colors-explicit-link)
+
+ ;; render in teletype and suppress further parsing
+ (,(concat "=[^" muse-regexp-blank "=\n]") ?= muse-colors-verbatim)
+
+ ;; highlight any markup tags encountered
+ (muse-tag-regexp ?\< muse-colors-custom-tags)
+
+ ;; display comments
+ (,(concat "^;[" muse-regexp-blank "]") ?\; muse-colors-comment)
+
+ ;; this has to come later since it doesn't have a special
+ ;; character in the second cell
+ (muse-url-regexp t muse-colors-implicit-link)
+ )
+ "Expressions to highlight an Emacs Muse buffer.
+These are arranged in a rather special fashion, so as to be as quick as
+possible.
+
+Each element of the list is itself a list, of the form:
+
+ (LOCATE-REGEXP TEST-CHAR MATCH-FUNCTION)
+
+LOCATE-REGEXP is a partial regexp, and should be the smallest possible
+regexp to differentiate this rule from other rules. It may also be a
+symbol containing such a regexp. The buffer region is scanned only
+once, and LOCATE-REGEXP indicates where the scanner should stop to
+look for highlighting possibilities.
+
+TEST-CHAR is a char or t. The character should match the beginning
+text matched by LOCATE-REGEXP. These chars are used to build a vector
+for fast MATCH-FUNCTION calling.
+
+MATCH-FUNCTION is the function called when a region has been
+identified. It is responsible for adding the appropriate text
+properties to change the appearance of the buffer.
+
+This markup is used to modify the appearance of the original text to
+make it look more like the published HTML would look (like making some
+markup text invisible, inlining images, etc).
+
+font-lock is used to apply the markup rules, so that they can happen
+on a deferred basis. They are not always accurate, but you can use
+\\[font-lock-fontifty-block] near the point of error to force
+fontification in that area."
+ :type '(repeat
+ (list :tag "Highlight rule"
+ (choice (regexp :tag "Locate regexp")
+ (symbol :tag "Regexp symbol"))
+ (choice (character :tag "Confirm character")
+ (const :tag "Default rule" t))
+ function))
+ :set 'muse-configure-highlighting
+ :group 'muse-colors)
+
+;; XEmacs users don't have `font-lock-multiline'.
+(unless (boundp 'font-lock-multiline)
+ (defvar font-lock-multiline nil))
+
+(defun muse-use-font-lock ()
+ "Set up font-locking for Muse."
+ (muse-add-to-invisibility-spec 'muse)
+ (set (make-local-variable 'font-lock-multiline) 'undecided)
+ (set (make-local-variable 'font-lock-defaults)
+ `(nil t nil nil beginning-of-line
+ (font-lock-fontify-region-function . muse-colors-region)
+ (font-lock-unfontify-region-function
+ . muse-unhighlight-region)))
+ (set (make-local-variable 'font-lock-fontify-region-function)
+ 'muse-colors-region)
+ (set (make-local-variable 'font-lock-unfontify-region-function)
+ 'muse-unhighlight-region)
+ (muse-make-faces)
+ (muse-colors-define-highlighting 'muse-mode muse-colors-markup)
+ (font-lock-mode t))
+
+(defun muse-colors-buffer ()
+ "Re-highlight the entire Muse buffer."
+ (interactive)
+ (muse-colors-region (point-min) (point-max) t))
+
+(defvar muse-colors-fontifying-p nil
+ "Indicate whether Muse is fontifying the current buffer.")
+(make-variable-buffer-local 'muse-colors-fontifying-p)
+
+(defvar muse-colors-delayed-commands nil
+ "Commands to be run immediately after highlighting a region.
+
+This is meant to accommodate highlighting <lisp> in #title
+directives after everything else.
+
+It may be modified by Muse functions during highlighting, but not
+the user.")
+(make-variable-buffer-local 'muse-colors-delayed-commands)
+
+(defun muse-colors-region (beg end &optional verbose)
+ "Apply highlighting according to `muse-colors-markup'.
+Note that this function should NOT change the buffer, nor should any
+of the functions listed in `muse-colors-markup'."
+ (let ((buffer-undo-list t)
+ (inhibit-read-only t)
+ (inhibit-point-motion-hooks t)
+ (inhibit-modification-hooks t)
+ (modified-p (buffer-modified-p))
+ (muse-colors-fontifying-p t)
+ (muse-colors-region-end (muse-line-end-position end))
+ (muse-colors-delayed-commands nil)
+ (highlighting (muse-colors-find-highlighting major-mode))
+ regexp vector remaining
+ deactivate-mark)
+ (unless highlighting
+ (error "No highlighting found for this mode"))
+ (setq regexp (nth muse-colors-highlighting.regexp highlighting)
+ vector (nth muse-colors-highlighting.vector highlighting)
+ remaining (nth muse-colors-highlighting.remaining highlighting))
+ (unwind-protect
+ (save-excursion
+ (save-restriction
+ (widen)
+ ;; check to see if we should expand the beg/end area for
+ ;; proper multiline matches
+ (when (and font-lock-multiline
+ (> beg (point-min))
+ (get-text-property (1- beg) 'font-lock-multiline))
+ ;; We are just after or in a multiline match.
+ (setq beg (or (previous-single-property-change
+ beg 'font-lock-multiline)
+ (point-min)))
+ (goto-char beg)
+ (setq beg (muse-line-beginning-position)))
+ (when font-lock-multiline
+ (setq end (or (text-property-any end (point-max)
+ 'font-lock-multiline nil)
+ (point-max))))
+ (goto-char end)
+ (setq end (muse-line-beginning-position 2))
+ ;; Undo any fontification in the area.
+ (font-lock-unfontify-region beg end)
+ ;; And apply fontification based on `muse-colors-markup'
+ (let ((len (float (- end beg)))
+ (case-fold-search nil)
+ markup-list)
+ (goto-char beg)
+ (while (and (< (point) end)
+ (re-search-forward regexp end t))
+ (if verbose
+ (message "Highlighting buffer...%d%%"
+ (* (/ (float (- (point) beg)) len) 100)))
+ (let ((ch (char-after (match-beginning 0))))
+ (when (< ch 128)
+ (setq markup-list (aref vector ch))))
+ (unless markup-list
+ (setq markup-list remaining))
+ (let ((prev (point)))
+ ;; backtrack and figure out which rule matched
+ (goto-char (match-beginning 0))
+ (catch 'done
+ (dolist (entry markup-list)
+ (let ((value (cond ((symbolp (car entry))
+ (symbol-value (car entry)))
+ ((stringp (car entry))
+ (car entry))
+ (t nil))))
+ (when (and (stringp value) (looking-at value))
+ (goto-char (match-end 0))
+ (when (cdr entry)
+ (funcall (cdr entry)))
+ (throw 'done t))))
+ ;; if no rule matched, which should never happen,
+ ;; return to previous position so that forward
+ ;; progress is ensured
+ (goto-char prev))))
+ (dolist (command muse-colors-delayed-commands)
+ (apply (car command) (cdr command)))
+ (run-hook-with-args 'muse-colors-buffer-hook
+ beg end verbose)
+ (if verbose (message "Highlighting buffer...done")))))
+ (set-buffer-modified-p modified-p))))
+
+(defcustom muse-colors-tags
+ '(("example" t nil nil muse-colors-example-tag)
+ ("code" t nil nil muse-colors-example-tag)
+ ("verbatim" t nil nil muse-colors-literal-tag)
+ ("lisp" t t nil muse-colors-lisp-tag)
+ ("literal" t nil nil muse-colors-literal-tag))
+ "A list of tag specifications for specially highlighting text.
+XML-style tags are the best way to add custom highlighting to Muse.
+This is easily accomplished by customizing this list of markup tags.
+
+For each entry, the name of the tag is given, whether it expects
+a closing tag and/or an optional set of attributes, whether it is
+nestable, and a function that performs whatever action is desired
+within the delimited region.
+
+The function is called with three arguments, the beginning and
+end of the region surrounded by the tags. If properties are
+allowed, they are passed as a third argument in the form of an
+alist. The `end' argument to the function is the last character
+of the enclosed tag or region.
+
+Functions should not modify the contents of the buffer."
+ :type '(repeat (list (string :tag "Markup tag")
+ (boolean :tag "Expect closing tag" :value t)
+ (boolean :tag "Parse attributes" :value nil)
+ (boolean :tag "Nestable" :value nil)
+ function))
+ :group 'muse-colors)
+
+(defvar muse-colors-inhibit-tags-in-directives t
+ "If non-nil, don't allow tags to be interpreted in directives.
+This is used to delay highlighting of <lisp> tags in #title until later.")
+(make-variable-buffer-local 'muse-colors-inhibit-tags-in-directives)
+
+(defsubst muse-colors-tag-info (tagname &rest args)
+ "Get tag info associated with TAGNAME, ignoring ARGS."
+ (assoc tagname muse-colors-tags))
+
+(defun muse-colors-custom-tags ()
+ "Highlight `muse-colors-tags'."
+ (let ((tag-info (muse-colors-tag-info (match-string 1))))
+ (unless (or (not tag-info)
+ (get-text-property (match-beginning 0) 'muse-comment)
+ (and muse-colors-inhibit-tags-in-directives
+ (get-text-property (match-beginning 0) 'muse-directive)))
+ (let ((closed-tag (match-string 3))
+ (start (match-beginning 0))
+ end attrs)
+ (when (nth 2 tag-info)
+ (let ((attrstr (match-string 2)))
+ (while (and attrstr
+ (string-match (concat "\\([^"
+ muse-regexp-blank
+ "=\n]+\\)\\(=\""
+ "\\([^\"]+\\)\"\\)?")
+ attrstr))
+ (let ((attr (cons (downcase
+ (muse-match-string-no-properties 1 attrstr))
+ (muse-match-string-no-properties 3 attrstr))))
+ (setq attrstr (replace-match "" t t attrstr))
+ (if attrs
+ (nconc attrs (list attr))
+ (setq attrs (list attr)))))))
+ (if (and (cadr tag-info) (not closed-tag))
+ (if (muse-goto-tag-end (car tag-info) (nth 3 tag-info))
+ (setq end (match-end 0))
+ (setq tag-info nil)))
+ (when tag-info
+ (let ((args (list start end)))
+ (if (nth 2 tag-info)
+ (nconc args (list attrs)))
+ (apply (nth 4 tag-info) args)))))))
+
+(defun muse-unhighlight-region (begin end &optional verbose)
+ "Remove all visual highlights in the buffer (except font-lock)."
+ (let ((buffer-undo-list t)
+ (inhibit-read-only t)
+ (inhibit-point-motion-hooks t)
+ (inhibit-modification-hooks t)
+ (modified-p (buffer-modified-p))
+ deactivate-mark)
+ (unwind-protect
+ (remove-text-properties
+ begin end '(face nil font-lock-multiline nil end-glyph nil
+ invisible nil intangible nil display nil
+ mouse-face nil keymap nil help-echo nil
+ muse-link nil muse-directive nil muse-comment nil
+ muse-no-implicit-link nil muse-no-flyspell nil))
+ (set-buffer-modified-p modified-p))))
+
+(defun muse-colors-example-tag (beg end)
+ "Strip properties and colorize with `muse-verbatim'."
+ (muse-unhighlight-region beg end)
+ (let ((multi (save-excursion
+ (goto-char beg)
+ (forward-line 1)
+ (> end (point)))))
+ (add-text-properties beg end `(face muse-verbatim
+ font-lock-multiline ,multi))))
+
+(defun muse-colors-literal-tag (beg end)
+ "Strip properties and mark as literal."
+ (muse-unhighlight-region beg end)
+ (let ((multi (save-excursion
+ (goto-char beg)
+ (forward-line 1)
+ (> end (point)))))
+ (add-text-properties beg end `(font-lock-multiline ,multi))))
+
+(defun muse-colors-lisp-tag (beg end attrs)
+ "Color the region enclosed by a <lisp> tag."
+ (if (not muse-colors-evaluate-lisp-tags)
+ (muse-colors-literal-tag beg end)
+ (muse-unhighlight-region beg end)
+ (let (beg-lisp end-lisp)
+ (save-match-data
+ (goto-char beg)
+ (setq beg-lisp (and (looking-at "<[^>]+>")
+ (match-end 0)))
+ (goto-char end)
+ (setq end-lisp (and (muse-looking-back "</[^>]+>")
+ (match-beginning 0))))
+ (add-text-properties
+ beg end
+ (list 'font-lock-multiline t
+ 'display (muse-eval-lisp
+ (concat
+ "(progn "
+ (buffer-substring-no-properties beg-lisp end-lisp)
+ ")"))
+ 'intangible t)))))
+
+(defvar muse-mode-local-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [return] 'muse-follow-name-at-point)
+ (define-key map [(control ?m)] 'muse-follow-name-at-point)
+ (define-key map [(shift return)] 'muse-follow-name-at-point-other-window)
+ (if (featurep 'xemacs)
+ (progn
+ (define-key map [(button2)] 'muse-follow-name-at-mouse)
+ (define-key map [(shift button2)]
+ 'muse-follow-name-at-mouse-other-window))
+ (define-key map [(shift control ?m)]
+ 'muse-follow-name-at-point-other-window)
+ (define-key map [mouse-2] 'muse-follow-name-at-mouse)
+ (define-key map [(shift mouse-2)]
+ 'muse-follow-name-at-mouse-other-window)
+ (unless (eq emacs-major-version 21)
+ (set-keymap-parent map muse-mode-map)))
+ map)
+ "Local keymap used by Muse while on a link.")
+
+(defvar muse-keymap-property
+ (if (or (featurep 'xemacs)
+ (>= emacs-major-version 21))
+ 'keymap
+ 'local-map)
+ "The name of the keymap or local-map property.")
+
+(defsubst muse-link-properties (help-str &optional face)
+ "Determine text properties to use for a link."
+ (append (if face
+ (list 'face face 'mouse-face 'highlight 'muse-link t)
+ (list 'invisible 'muse 'intangible t))
+ (list 'help-echo help-str 'rear-nonsticky t
+ muse-keymap-property muse-mode-local-map)))
+
+(defun muse-link-face (link-name &optional explicit)
+ "Return the type of LINK-NAME as a face symbol.
+For EXPLICIT links, this is either a normal link or a bad-link
+face. For implicit links, it is either colored normally or
+ignored."
+ (save-match-data
+ (let ((link (if explicit
+ (muse-handle-explicit-link link-name)
+ (muse-handle-implicit-link link-name))))
+ (when link
+ (cond ((string-match muse-url-regexp link)
+ 'muse-link)
+ ((muse-file-remote-p link)
+ 'muse-link)
+ ((string-match muse-file-regexp link)
+ (when (string-match "/[^/]+#[^#./]+\\'" link)
+ ;; strip anchor from the end of a path
+ (setq link (substring link 0 (match-beginning 0))))
+ (if (file-exists-p link)
+ 'muse-link
+ 'muse-bad-link))
+ ((not (featurep 'muse-project))
+ 'muse-link)
+ (t
+ (if (string-match "#" link)
+ (setq link (substring link 0 (match-beginning 0))))
+ (if (or (and (muse-project-of-file)
+ (muse-project-page-file
+ link muse-current-project t))
+ (file-exists-p link))
+ 'muse-link
+ 'muse-bad-link)))))))
+
+(defun muse-colors-use-publishing-directory (link)
+ "Make LINK relative to the directory where we will publish the
+current file."
+ (let ((style (car (muse-project-applicable-styles
+ link (cddr (muse-project)))))
+ path)
+ (when (and style
+ (setq path (muse-style-element :path style)))
+ (expand-file-name link path))))
+
+(defun muse-colors-resolve-image-file (link)
+ "Determine if we can create images and see if the link is an image
+file."
+ (save-match-data
+ (and (or (fboundp 'create-image)
+ (fboundp 'make-glyph))
+ (not (string-match "\\`[uU][rR][lL]:" link))
+ (string-match muse-image-regexp link))))
+
+(defun muse-make-file-glyph (filename)
+ "Given a file name, return a newly-created image glyph.
+This is a hack for supporting inline images in XEmacs."
+ (let ((case-fold-search nil))
+ ;; Scan filename to determine image type
+ (when (fboundp 'make-glyph)
+ (save-match-data
+ (cond ((string-match "jpe?g" filename)
+ (make-glyph (vector 'jpeg :file filename) 'buffer))
+ ((string-match "gif" filename)
+ (make-glyph (vector 'gif :file filename) 'buffer))
+ ((string-match "png" filename)
+ (make-glyph (vector 'png :file filename) 'buffer)))))))
+
+(defun muse-colors-insert-image (link beg end invis-props)
+ "Create an image using create-image or make-glyph and insert it
+in place of an image link defined by BEG and END."
+ (setq link (expand-file-name link))
+ (let ((image-file (cond
+ ((eq muse-colors-inline-image-method 'default-directory)
+ link)
+ ((functionp muse-colors-inline-image-method)
+ (funcall muse-colors-inline-image-method link))))
+ glyph)
+ (when (stringp image-file)
+ (if (fboundp 'create-image)
+ ;; use create-image and display property
+ (let ((display-stuff (condition-case nil
+ (create-image image-file)
+ (error nil))))
+ (when display-stuff
+ (add-text-properties beg end (list 'display display-stuff))))
+ ;; use make-glyph and invisible property
+ (and (setq glyph (muse-make-file-glyph image-file))
+ (progn
+ (add-text-properties beg end invis-props)
+ (add-text-properties beg end (list
+ 'end-glyph glyph
+ 'help-echo link))))))))
+
+(defun muse-colors-explicit-link ()
+ "Color explicit links."
+ (when (and (eq ?\[ (char-after (match-beginning 0)))
+ (not (get-text-property (match-beginning 0) 'muse-comment))
+ (not (get-text-property (match-beginning 0) 'muse-directive)))
+ ;; remove flyspell overlays
+ (when (fboundp 'flyspell-unhighlight-at)
+ (let ((cur (match-beginning 0)))
+ (while (> (match-end 0) cur)
+ (flyspell-unhighlight-at cur)
+ (setq cur (1+ cur)))))
+ (let* ((unesc-link (muse-get-link))
+ (unesc-desc (muse-get-link-desc))
+ (link (muse-link-unescape unesc-link))
+ (desc (muse-link-unescape unesc-desc))
+ (props (muse-link-properties desc (muse-link-face link t)))
+ (invis-props (append props (muse-link-properties desc))))
+ ;; see if we should try and inline an image
+ (if (and muse-colors-inline-images
+ (or (muse-colors-resolve-image-file link)
+ (and desc
+ (muse-colors-resolve-image-file desc)
+ (setq link desc))))
+ ;; we found an image, so inline it
+ (muse-colors-insert-image
+ link
+ (match-beginning 0) (match-end 0) invis-props)
+ (if desc
+ (progn
+ ;; we put the normal face properties on the invisible
+ ;; portion too, since emacs sometimes will position
+ ;; the cursor on an intangible character
+ (add-text-properties (match-beginning 0)
+ (match-beginning 2) invis-props)
+ (add-text-properties (match-beginning 2) (match-end 2) props)
+ (add-text-properties (match-end 2) (match-end 0) invis-props)
+ ;; in case specials were escaped, cause the unescaped
+ ;; text to be displayed
+ (unless (string= desc unesc-desc)
+ (add-text-properties (match-beginning 2) (match-end 2)
+ (list 'display desc))))
+ (add-text-properties (match-beginning 0)
+ (match-beginning 1) invis-props)
+ (add-text-properties (match-beginning 1) (match-end 0) props)
+ (add-text-properties (match-end 1) (match-end 0) invis-props)
+ (unless (string= link unesc-link)
+ (add-text-properties (match-beginning 1) (match-end 1)
+ (list 'display link))))
+ (goto-char (match-end 0))
+ (add-text-properties
+ (match-beginning 0) (match-end 0)
+ (muse-link-properties (muse-match-string-no-properties 0)
+ (muse-link-face link t)))))))
+
+(defun muse-colors-implicit-link ()
+ "Color implicit links."
+ (unless (or (eq (get-text-property (match-beginning 0) 'invisible) 'muse)
+ (get-text-property (match-beginning 0) 'muse-comment)
+ (get-text-property (match-beginning 0) 'muse-directive)
+ (get-text-property (match-beginning 0) 'muse-no-implicit-link)
+ (eq (char-before (match-beginning 0)) ?\")
+ (eq (char-after (match-end 0)) ?\"))
+ ;; remove flyspell overlays
+ (when (fboundp 'flyspell-unhighlight-at)
+ (let ((cur (match-beginning 0)))
+ (while (> (match-end 0) cur)
+ (flyspell-unhighlight-at cur)
+ (setq cur (1+ cur)))))
+ ;; colorize link
+ (let ((link (muse-match-string-no-properties 0))
+ (face (muse-link-face (match-string 0))))
+ (when face
+ (add-text-properties (match-beginning 0) (match-end 0)
+ (muse-link-properties
+ (muse-match-string-no-properties 0) face))))))
+
+(defun muse-colors-title ()
+ "Color #title directives."
+ (let ((beg (+ 7 (match-beginning 0))))
+ (add-text-properties beg (muse-line-end-position) '(muse-directive t))
+ ;; colorize <lisp> tags in #title after other <lisp> tags have had a
+ ;; chance to run, so that we can have behavior that is consistent
+ ;; with how the document is published
+ (setq muse-colors-delayed-commands
+ (cons (list 'muse-colors-title-lisp beg (muse-line-end-position))
+ muse-colors-delayed-commands))))
+
+(defun muse-colors-title-lisp (beg end)
+ "Called after other highlighting is done for a region in order to handle
+<lisp> tags that exist in #title directives."
+ (save-restriction
+ (narrow-to-region beg end)
+ (goto-char (point-min))
+ (let ((muse-colors-inhibit-tags-in-directives nil)
+ (muse-colors-tags '(("lisp" t t nil muse-colors-lisp-tag))))
+ (while (re-search-forward muse-tag-regexp nil t)
+ (muse-colors-custom-tags))))
+ (add-text-properties beg end '(face muse-header-1)))
+
+(defun muse-colors-comment ()
+ "Color comments."
+ (add-text-properties (match-beginning 0) (muse-line-end-position)
+ (list 'face 'font-lock-comment-face
+ 'muse-comment t)))
+
+
+(provide 'muse-colors)
+
+;;; muse-colors.el ends here
--- /dev/null
+;;; muse-context.el --- publish entries in ConTeXt or PDF format
+
+;; Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+;; Author: Jean Magnan de Bornier (jean@bornier.net)
+;; Created: 16-Apr-2007
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; This file when loaded allows you to publish .muse files as ConTeXt
+;; files or as pdf files, using respectively the "context" and
+;; "context-pdf" styles. It is far from being perfect, so any feedback
+;; will be welcome and any mistake hopefully fixed.
+
+;;; Author:
+
+;; Jean Magnan de Bornier, who based this file on muse-latex.el and
+;; made the context, context-pdf, context-slides, and
+;; context-slides-pdf Muse publishing styles.
+
+;; 16 Avril 2007
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Muse ConTeXt Publishing
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(require 'muse-publish)
+
+(defgroup muse-context nil
+ "Rules for marking up a Muse file as a ConTeXt article."
+ :group 'muse-publish)
+
+(defcustom muse-context-extension ".tex"
+ "Default file extension for publishing ConTeXt files."
+ :type 'string
+ :group 'muse-context)
+
+(defcustom muse-context-pdf-extension ".pdf"
+ "Default file extension for publishing ConTeXt files to PDF."
+ :type 'string
+ :group 'muse-context)
+
+(defcustom muse-context-pdf-program "texexec --pdf"
+ "The program that is called to generate PDF content from ConTeXt content."
+ :type 'string
+ :group 'muse-context)
+
+(defcustom muse-context-pdf-cruft '(".pgf" ".tmp" ".tui" ".tuo" ".toc" ".log")
+ "Extensions of files to remove after generating PDF output successfully."
+ :type 'string
+ :group 'muse-context)
+
+(defcustom muse-context-header
+ "\\setupinteraction [state=start]
+\\usemodule[tikz]
+\\usemodule[bib]\n
+<lisp>(muse-context-setup-bibliography)</lisp>
+ \\setuppublications[]\n
+\\setuppublicationlist[]\n\\setupcite[]\n
+\\starttext
+\\startalignment[center]
+ \\blank[2*big]
+ {\\tfd <lisp>(muse-publishing-directive \"title\")</lisp>}
+ \\blank[3*medium]
+ {\\tfa <lisp>(muse-publishing-directive \"author\")</lisp>}
+ \\blank[2*medium]
+ {\\tfa <lisp>(muse-publishing-directive \"date\")</lisp>}
+ \\blank[3*medium]
+\\stopalignment
+
+<lisp>(and muse-publish-generate-contents
+ (not muse-context-permit-contents-tag)
+ \"\\\\placecontent\n\\\\page[yes]\")</lisp>\n\n"
+ "Header used for publishing ConTeXt files. This may be text or a filename."
+ :type 'string
+ :group 'muse-context)
+
+(defcustom muse-context-footer "<lisp>(muse-context-bibliography)</lisp>
+\\stoptext\n"
+ "Footer used for publishing ConTeXt files. This may be text or a filename."
+ :type 'string
+ :group 'muse-context)
+
+(defcustom muse-context-markup-regexps
+ `(;; numeric ranges
+ (10000 "\\([0-9]+\\)-\\([0-9]+\\)" 0 "\\1--\\2")
+
+ ;; be careful of closing quote pairs
+ (10100 "\"'" 0 "\"\\\\-'"))
+ "List of markup regexps for identifying regions in a Muse page.
+For more on the structure of this list, see `muse-publish-markup-regexps'."
+ :type '(repeat (choice
+ (list :tag "Markup rule"
+ integer
+ (choice regexp symbol)
+ integer
+ (choice string function symbol))
+ function))
+ :group 'muse-context)
+
+(defcustom muse-context-markup-functions
+ '((table . muse-context-markup-table))
+ "An alist of style types to custom functions for that kind of text.
+For more on the structure of this list, see
+`muse-publish-markup-functions'."
+ :type '(alist :key-type symbol :value-type function)
+ :group 'muse-context)
+
+(defcustom muse-context-markup-strings
+ '((image-with-desc . "\\placefigure[][]{%3%}{\\externalfigure[%1%.%2%]}")
+ (image . "\\placefigure[][]{}{\\externalfigure[%s.%s]}")
+ (image-link . "\\useURL[aa][%s][][%1%] \\from[aa]")
+ (anchor-ref . "\\goto{%2%}{}[%1%]")
+ (url . "\\useURL[aa][%s][][%s] \\from[aa]")
+ (url-and-desc . "\\useURL[bb][%s][][%s]\\from[bb]\\footnote{%1%}")
+ (link . "\\goto{%2%}[program(%1%)]\\footnote{%1%}")
+ (link-and-anchor . "\\useexternaldocument[%4%][%4%][] \\at{%3%, page}{}[%4%::%2%]\\footnote{%1%}")
+ (email-addr . "\\useURL[mail][mailto:%s][][%s]\\from[mail]")
+ (anchor . "\\reference[%s] ")
+ (emdash . "---")
+ (comment-begin . "\\doifmode{comment}{")
+ (comment-end . "}")
+ (rule . "\\blank[medium]\\hrule\\blank[medium]")
+ (no-break-space . "~")
+ (enddots . "\\ldots ")
+ (dots . "\\dots ")
+ (part . "\\part{")
+ (part-end . "}")
+ (chapter . "\\chapter{")
+ (chapter-end . "}")
+ (section . "\\section{")
+ (section-end . "}")
+ (subsection . "\\subsection{")
+ (subsection-end . "}")
+ (subsubsection . "\\subsubsection{")
+ (subsubsection-end . "}")
+ (section-other . "\\subsubsubject{")
+ (section-other-end . "}")
+ (footnote . "\\footnote{")
+ (footnote-end . "}")
+ (footnotetext . "\\footnotetext[%d]{")
+ (begin-underline . "\\underbar{")
+ (end-underline . "}")
+ (begin-literal . "\\type{")
+ (end-literal . "}")
+ (begin-emph . "{\\em ")
+ (end-emph . "}")
+ (begin-more-emph . "{\\bf ")
+ (end-more-emph . "}")
+ (begin-most-emph . "{\\bf {\\em ")
+ (end-most-emph . "}}")
+ (begin-example . "\\starttyping")
+ (end-example . "\\stoptyping")
+ (begin-center . "\\startalignment[center]\n")
+ (end-center . "\n\\stopalignment")
+ (begin-quote . "\\startquotation\n")
+ (end-quote . "\n\\stopquotation")
+ (begin-cite . "\\cite[authoryear][")
+ (begin-cite-author . "\\cite[author][")
+ (begin-cite-year . "\\cite[year][")
+ (end-cite . "]")
+ (begin-uli . "\\startitemize\n")
+ (end-uli . "\n\\stopitemize")
+ (begin-uli-item . "\\item ")
+ (begin-oli . "\\startitemize[n]\n")
+ (end-oli . "\n\\stopitemize")
+ (begin-oli-item . "\\item ")
+ (begin-dl . "\\startitemize\n")
+ (end-dl . "\n\\stopitemize")
+ (begin-ddt . "\\head ")
+ (end-ddt . "\n")
+ (begin-verse . "\\blank[big]")
+ (end-verse-line . "\\par")
+ (verse-space . "\\fixedspaces ~~")
+ (end-verse . "\\blank[big]"))
+ "Strings used for marking up text.
+These cover the most basic kinds of markup, the handling of which
+differs little between the various styles."
+ :type '(alist :key-type symbol :value-type string)
+ :group 'muse-context)
+
+(defcustom muse-context-slides-header
+ "\\usemodule[<lisp>(if (string-equal (muse-publishing-directive \"module\") nil) \"pre-01\" (muse-publishing-directive \"module\"))</lisp>]
+\\usemodule[tikz]
+\\usemodule[newmat]
+\\setupinteraction [state=start]
+\\starttext
+\\TitlePage { <lisp>(muse-publishing-directive \"title\")</lisp>
+\\blank[3*medium]
+\\tfa <lisp>(muse-publishing-directive \"author\")</lisp>
+ \\blank[2*medium]
+ \\tfa <lisp>(muse-publishing-directive \"date\")</lisp>}"
+ "Header for publishing a presentation (slides) using ConTeXt.
+Any of the predefined modules, which are available in the
+tex/context/base directory, can be used by writing a \"module\"
+directive at the top of the muse file; if no such directive is
+provided, module pre-01 is used. Alternatively, you can use your
+own style (\"mystyle\", in this example) by replacing
+\"\\usemodule[]\" with \"\\input mystyle\".
+
+This may be text or a filename."
+ :type 'string
+ :group 'muse-context)
+
+(defcustom muse-context-slides-markup-strings
+ '((section . "\\Topic {")
+ (subsection . "\\page \n{\\bf ")
+ (subsubsection . "{\\em "))
+ "Strings used for marking up text in ConTeXt slides."
+ :type '(alist :key-type symbol :value-type string)
+ :group 'muse-context)
+
+(defcustom muse-context-markup-specials-document
+ '((?\\ . "\\textbackslash{}")
+ (?\_ . "\\textunderscore{}")
+ (?\< . "\\switchtobodyfont[small]")
+ (?\> . "\\switchtobodyfont[big]")
+ (?^ . "\\^")
+ (?\~ . "\\~")
+ (?\@ . "\\@")
+ (?\$ . "\\$")
+ (?\% . "\\%")
+ (?\{ . "\\{")
+ (?\} . "\\}")
+ (?\& . "\\&")
+ (?\# . "\\#"))
+ "A table of characters which must be represented specially.
+These are applied to the entire document, sans already-escaped
+regions."
+ :type '(alist :key-type character :value-type string)
+ :group 'muse-context)
+
+(defcustom muse-context-markup-specials-example
+ '()
+ "A table of characters which must be represented specially.
+These are applied to <example> regions.
+
+With the default interpretation of <example> regions, no specials
+need to be escaped."
+ :type '(alist :key-type character :value-type string)
+ :group 'muse-context)
+
+(defcustom muse-context-markup-specials-literal
+ '()
+ "A table of characters which must be represented specially.
+This applies to =monospaced text= and <code> regions."
+ :type '(alist :key-type character :value-type string)
+ :group 'muse-context)
+
+(defcustom muse-context-markup-specials-url
+ '((?\\ . "\\textbackslash")
+ (?\_ . "\\_")
+ (?\< . "\\<")
+ (?\> . "\\>")
+ (?\$ . "\\$")
+ (?\% . "\\%")
+ (?\{ . "\\{")
+ (?\} . "\\}")
+ (?\& . "\\&")
+ (?\# . "\\#"))
+ "A table of characters which must be represented specially.
+These are applied to URLs."
+ :type '(alist :key-type character :value-type string)
+ :group 'muse-context)
+
+(defcustom muse-context-markup-specials-image
+ '((?\\ . "\\textbackslash") ; cannot find suitable replacement
+ (?\< . "\\<")
+ (?\> . "\\>")
+ (?\$ . "\\$")
+ (?\% . "\\%")
+ (?\{ . "\\{")
+ (?\} . "\\}")
+ (?\& . "\\&")
+ (?\# . "\\#") ; cannot find suitable replacement
+ )
+ "A table of characters which must be represented specially.
+These are applied to image filenames."
+ :type '(alist :key-type character :value-type string)
+ :group 'muse-context)
+
+(defun muse-context-decide-specials (context)
+ "Determine the specials to escape, depending on the CONTEXT argument."
+ (cond ((memq context '(underline emphasis document url-desc verbatim
+ footnote))
+ muse-context-markup-specials-document)
+ ((eq context 'image)
+ muse-context-markup-specials-image)
+ ((memq context '(email url))
+ muse-context-markup-specials-url)
+ ((eq context 'literal)
+ muse-context-markup-specials-literal)
+ ((eq context 'example)
+ muse-context-markup-specials-example)
+ (t (error "Invalid context argument '%s' in muse-context" context))))
+
+(defun muse-context-markup-table ()
+ (let* ((table-info (muse-publish-table-fields (match-beginning 0)
+ (match-end 0)))
+ (row-len (car table-info))
+ (field-list (cdr table-info)))
+ (when table-info
+ (muse-insert-markup "\\starttable[|"
+ (mapconcat 'symbol-name (make-vector row-len 'l)
+ "|") "|]\n \\HL\n \\VL ")
+ (dolist (fields field-list)
+ (let ((type (car fields)))
+ (setq fields (cdr fields))
+ (when (= type 3)
+ (muse-insert-markup ""))
+ (insert (car fields))
+ (setq fields (cdr fields))
+ (dolist (field fields)
+ (muse-insert-markup " \\VL ")
+ (insert field))
+ (muse-insert-markup "\\VL\\NR\n \\HL\n \\VL ")
+ (when (= type 2)
+ (muse-insert-markup " "))))
+ (muse-insert-markup "\\stoptable\n")
+ (while (search-backward "VL \\stoptable" nil t)
+ (replace-match "stoptable" nil t)))))
+
+(defun muse-context-fixup-dquotes ()
+ "Fixup double quotes."
+ (goto-char (point-min))
+ (let ((open t))
+ (while (search-forward "\"" nil t)
+ (unless (get-text-property (match-beginning 0) 'read-only)
+ (when (or (bobp)
+ (eq (char-before) ?\n))
+ (setq open t))
+ (if open
+ (progn
+ (replace-match "``")
+ (setq open nil))
+ (replace-match "''")
+ (setq open t))))))
+
+(defcustom muse-context-permit-contents-tag nil
+ "If nil, ignore <contents> tags. Otherwise, insert table of contents.
+
+Most of the time, it is best to have a table of contents on the
+first page, with a new page immediately following. To make this
+work with documents published in both HTML and ConTeXt, we need to
+ignore the <contents> tag.
+
+If you don't agree with this, then set this option to non-nil,
+and it will do what you expect."
+ :type 'boolean
+ :group 'muse-context)
+
+(defun muse-context-fixup-citations ()
+ "Replace semicolons in multi-head citations with colons."
+ (goto-char (point-min))
+ (while (re-search-forward "\\\\cite.?\\[" nil t)
+ (let ((start (point))
+ (end (re-search-forward "]")))
+ (save-restriction
+ (narrow-to-region start end)
+ (goto-char (point-min))
+ (while (re-search-forward ";" nil t)
+ (replace-match ","))))))
+
+(defun muse-context-munge-buffer ()
+ (muse-context-fixup-dquotes)
+ (muse-context-fixup-citations)
+ (when (and muse-context-permit-contents-tag
+ muse-publish-generate-contents)
+ (goto-char (car muse-publish-generate-contents))
+ (muse-insert-markup "\\placecontent")))
+
+(defun muse-context-bibliography ()
+ (save-excursion
+ (goto-char (point-min))
+ (if (re-search-forward "\\\\cite.?\\[" nil t)
+ "\\completepublications[criterium=all]"
+ "")))
+
+(defun muse-context-setup-bibliography ()
+ (save-excursion
+ (goto-char (point-min))
+ (if (re-search-forward "\\\\cite.?\\[" nil t)
+ (concat
+ "\\usemodule[bibltx]\n\\setupbibtex [database="
+ (muse-publishing-directive "bibsource") "]")
+ "")))
+
+(defun muse-context-pdf-browse-file (file)
+ (shell-command (concat "open " file)))
+
+(defun muse-context-pdf-generate (file output-path final-target)
+ (apply
+ #'muse-publish-transform-output
+ file output-path final-target "PDF"
+ (function
+ (lambda (file output-path)
+ (let* ((fnd (file-name-directory output-path))
+ (command (format "%s \"%s\""
+ muse-context-pdf-program
+ (file-relative-name file fnd)))
+ (times 0)
+ (default-directory fnd)
+ result)
+ ;; XEmacs can sometimes return a non-number result. We'll err
+ ;; on the side of caution by continuing to attempt to generate
+ ;; the PDF if this happens and treat the final result as
+ ;; successful.
+ (while (and (< times 2)
+ (or (not (numberp result))
+ (not (eq result 0))
+ ;; table of contents takes 2 passes
+;; (file-readable-p
+;; (muse-replace-regexp-in-string
+;; "\\.tex\\'" ".toc" file t t))
+ ))
+ (setq result (shell-command command)
+ times (1+ times)))
+ (if (or (not (numberp result))
+ (eq result 0))
+ t
+ nil))))
+ muse-context-pdf-cruft))
+
+(muse-define-style "context"
+ :suffix 'muse-context-extension
+ :regexps 'muse-context-markup-regexps
+ :functions 'muse-context-markup-functions
+ :strings 'muse-context-markup-strings
+ :specials 'muse-context-decide-specials
+ :after 'muse-context-munge-buffer
+ :header 'muse-context-header
+ :footer 'muse-context-footer
+ :browser 'find-file)
+
+(muse-derive-style "context-pdf" "context"
+ :final 'muse-context-pdf-generate
+ :browser 'muse-context-pdf-browse-file
+ :link-suffix 'muse-context-pdf-extension
+ :osuffix 'muse-context-pdf-extension)
+
+(muse-derive-style "context-slides" "context"
+ :header 'muse-context-slides-header
+ :strings 'muse-context-slides-markup-strings)
+
+(muse-derive-style "context-slides-pdf" "context-pdf"
+ :header 'muse-context-slides-header
+ :strings 'muse-context-slides-markup-strings)
+
+(provide 'muse-context)
+
+;;; muse-context.el ends here
--- /dev/null
+;;; muse-docbook.el --- publish DocBook files
+
+;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Contributors:
+
+;; Dale P. Smith (dpsm AT en DOT com) improved the markup
+;; significantly and made many valuable suggestions.
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Muse DocBook XML Publishing
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(require 'muse-publish)
+(require 'muse-regexps)
+(require 'muse-xml-common)
+
+(defgroup muse-docbook nil
+ "Options controlling the behavior of Muse DocBook XML publishing.
+See `muse-docbook' for more information."
+ :group 'muse-publish)
+
+(defcustom muse-docbook-extension ".xml"
+ "Default file extension for publishing DocBook XML files."
+ :type 'string
+ :group 'muse-docbook)
+
+(defcustom muse-docbook-header
+ "<?xml version=\"1.0\" encoding=\"<lisp>
+ (muse-docbook-encoding)</lisp>\"?>
+<!DOCTYPE article PUBLIC \"-//OASIS//DTD DocBook V4.2//EN\"
+ \"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd\"<lisp>(muse-docbook-entities)</lisp>>
+<article>
+ <articleinfo>
+ <title><lisp>(muse-publishing-directive \"title\")</lisp></title>
+ <author><lisp>(muse-docbook-get-author
+ (muse-publishing-directive \"author\"))</lisp></author>
+ <pubdate><lisp>(muse-publishing-directive \"date\")</lisp></pubdate>
+ </articleinfo>
+ <!-- Page published by Emacs Muse begins here -->\n"
+ "Header used for publishing DocBook XML files.
+This may be text or a filename."
+ :type 'string
+ :group 'muse-docbook)
+
+(defcustom muse-docbook-footer "
+ <!-- Page published by Emacs Muse ends here -->
+<lisp>(muse-docbook-bibliography)</lisp></article>\n"
+ "Footer used for publishing DocBook XML files.
+This may be text or a filename."
+ :type 'string
+ :group 'muse-docbook)
+
+(defcustom muse-docbook-markup-regexps
+ `(;; Beginning of doc, end of doc, or plain paragraph separator
+ (10000 ,(concat "\\(\\(\n\\(?:[" muse-regexp-blank "]*\n\\)*"
+ "\\([" muse-regexp-blank "]*\n\\)\\)"
+ "\\|\\`\\s-*\\|\\s-*\\'\\)")
+ 3 muse-docbook-markup-paragraph))
+ "List of markup rules for publishing a Muse page to DocBook XML.
+For more on the structure of this list, see `muse-publish-markup-regexps'."
+ :type '(repeat (choice
+ (list :tag "Markup rule"
+ integer
+ (choice regexp symbol)
+ integer
+ (choice string function symbol))
+ function))
+ :group 'muse-docbook)
+
+(defcustom muse-docbook-markup-functions
+ '((anchor . muse-xml-markup-anchor)
+ (table . muse-xml-markup-table))
+ "An alist of style types to custom functions for that kind of text.
+For more on the structure of this list, see
+`muse-publish-markup-functions'."
+ :type '(alist :key-type symbol :value-type function)
+ :group 'muse-docbook)
+
+(defcustom muse-docbook-markup-strings
+ '((image-with-desc . "<mediaobject>
+<imageobject>
+<imagedata fileref=\"%1%.%2%\" format=\"%2%\" />
+</imageobject>
+<caption><para>%3%</para></caption>
+</mediaobject>")
+ (image . "<inlinemediaobject><imageobject>
+<imagedata fileref=\"%1%.%2%\" format=\"%2%\" />
+</imageobject></inlinemediaobject>")
+ (image-link . "<ulink url=\"%1%\"><inlinemediaobject><imageobject>
+<imagedata fileref=\"%2%.%3%\" format=\"%3%\" />
+</imageobject></inlinemediaobject></ulink>")
+ (anchor-ref . "<link linkend=\"%s\">%s</link>")
+ (url . "<ulink url=\"%s\">%s</ulink>")
+ (link . "<ulink url=\"%s\">%s</ulink>")
+ (link-and-anchor . "<ulink url=\"%s#%s\">%s</ulink>")
+ (email-addr . "<email>%s</email>")
+ (anchor . "<anchor id=\"%s\" />\n")
+ (emdash . "%s—%s")
+ (comment-begin . "<!-- ")
+ (comment-end . " -->")
+ (rule . "")
+ (no-break-space . " ")
+ (enddots . "....")
+ (dots . "...")
+ (section . "<section><title>")
+ (section-end . "</title>")
+ (subsection . "<section><title>")
+ (subsection-end . "</title>")
+ (subsubsection . "<section><title>")
+ (subsubsection-end . "</title>")
+ (section-other . "<section><title>")
+ (section-other-end . "</title>")
+ (section-close . "</section>")
+ (footnote . "<footnote><para>")
+ (footnote-end . "</para></footnote>")
+ (begin-underline . "")
+ (end-underline . "")
+ (begin-literal . "<systemitem>")
+ (end-literal . "</systemitem>")
+ (begin-emph . "<emphasis>")
+ (end-emph . "</emphasis>")
+ (begin-more-emph . "<emphasis role=\"strong\">")
+ (end-more-emph . "</emphasis>")
+ (begin-most-emph . "<emphasis role=\"strong\"><emphasis>")
+ (end-most-emph . "</emphasis></emphasis>")
+ (begin-verse . "<literallayout>\n")
+ (verse-space . " ")
+ (end-verse . "</literallayout>")
+ (begin-example . "<programlisting>")
+ (end-example . "</programlisting>")
+ (begin-center . "<para role=\"centered\">\n")
+ (end-center . "\n</para>")
+ (begin-quote . "<blockquote>\n")
+ (end-quote . "\n</blockquote>")
+ (begin-cite . "<citation role=\"%s\">")
+ (begin-cite-author . "<citation role=\"%s\">A:")
+ (begin-cite-year . "<citation role=\"%s\">Y:")
+ (end-cite . "</citation>")
+ (begin-quote-item . "<para>")
+ (end-quote-item . "</para>")
+ (begin-uli . "<itemizedlist mark=\"bullet\">\n")
+ (end-uli . "\n</itemizedlist>")
+ (begin-uli-item . "<listitem><para>")
+ (end-uli-item . "</para></listitem>")
+ (begin-oli . "<orderedlist>\n")
+ (end-oli . "\n</orderedlist>")
+ (begin-oli-item . "<listitem><para>")
+ (end-oli-item . "</para></listitem>")
+ (begin-dl . "<variablelist>\n")
+ (end-dl . "\n</variablelist>")
+ (begin-dl-item . "<varlistentry>\n")
+ (end-dl-item . "\n</varlistentry>")
+ (begin-ddt . "<term>")
+ (end-ddt . "</term>")
+ (begin-dde . "<listitem><para>")
+ (end-dde . "</para></listitem>")
+ (begin-table . "<informaltable>\n")
+ (end-table . "</informaltable>")
+ (begin-table-group . " <tgroup cols='%s'>\n")
+ (end-table-group . " </tgroup>\n")
+ (begin-table-row . " <row>\n")
+ (end-table-row . " </row>\n")
+ (begin-table-entry . " <entry>")
+ (end-table-entry . "</entry>\n"))
+ "Strings used for marking up text.
+These cover the most basic kinds of markup, the handling of which
+differs little between the various styles."
+ :type '(alist :key-type symbol :value-type string)
+ :group 'muse-docbook)
+
+(defcustom muse-docbook-encoding-default 'utf-8
+ "The default Emacs buffer encoding to use in published files.
+This will be used if no special characters are found."
+ :type 'symbol
+ :group 'muse-docbook)
+
+(defcustom muse-docbook-charset-default "utf-8"
+ "The default DocBook XML charset to use if no translation is
+found in `muse-docbook-encoding-map'."
+ :type 'string
+ :group 'muse-docbook)
+
+(defun muse-docbook-encoding ()
+ (muse-xml-transform-content-type
+ (or (and (boundp 'buffer-file-coding-system)
+ buffer-file-coding-system)
+ muse-docbook-encoding-default)
+ muse-docbook-charset-default))
+
+(defun muse-docbook-markup-paragraph ()
+ (catch 'bail-out
+ (let ((end (copy-marker (match-end 0) t)))
+ (goto-char (match-beginning 0))
+ (when (save-excursion
+ (save-match-data
+ (and (not (get-text-property (max (point-min) (1- (point)))
+ 'muse-no-paragraph))
+ (re-search-backward
+ "<\\(/?\\)\\(para\\|footnote\\|literallayout\\)[ >]"
+ nil t)
+ (cond ((string= (match-string 2) "literallayout")
+ (and (not (string= (match-string 1) "/"))
+ (throw 'bail-out t)))
+ ((string= (match-string 2) "para")
+ (and
+ (not (string= (match-string 1) "/"))
+ ;; don't mess up nested lists
+ (not (and (muse-looking-back "<listitem>")
+ (throw 'bail-out t)))))
+ ((string= (match-string 2) "footnote")
+ (string= (match-string 1) "/"))
+ (t nil)))))
+ (when (get-text-property (1- (point)) 'muse-end-list)
+ (goto-char (previous-single-property-change (1- (point))
+ 'muse-end-list)))
+ (muse-insert-markup "</para>"))
+ (goto-char end))
+ (cond
+ ((eobp)
+ (unless (bolp)
+ (insert "\n")))
+ ((get-text-property (point) 'muse-no-paragraph)
+ (forward-char 1)
+ nil)
+ ((eq (char-after) ?\<)
+ (when (looking-at (concat "<\\(emphasis\\|systemitem\\|inlinemediaobject"
+ "\\|u?link\\|anchor\\|email\\)[ >]"))
+ (muse-insert-markup "<para>")))
+ (t
+ (muse-insert-markup "<para>")))))
+
+(defun muse-docbook-get-author (&optional author)
+ "Split the AUTHOR directive into separate fields.
+AUTHOR should be of the form: \"Firstname Other Names Lastname\",
+and anything after `Firstname' is optional."
+ (setq author (save-match-data (split-string author)))
+ (let ((num-el (length author)))
+ (cond ((eq num-el 1)
+ (concat "<firstname>" (car author) "</firstname>"))
+ ((eq num-el 2)
+ (concat "<firstname>" (nth 0 author) "</firstname>"
+ "<surname>" (nth 1 author) "</surname>"))
+ ((eq num-el 3)
+ (concat "<firstname>" (nth 0 author) "</firstname>"
+ "<othername>" (nth 1 author) "</othername>"
+ "<surname>" (nth 2 author) "</surname>"))
+ (t
+ (let (first last)
+ (setq first (car author))
+ (setq author (nreverse (cdr author)))
+ (setq last (car author))
+ (setq author (nreverse (cdr author)))
+ (concat "<firstname>" first "</firstname>"
+ "<othername>"
+ (mapconcat 'identity author " ")
+ "</othername>"
+ "<surname>" last "</surname>"))))))
+
+(defun muse-docbook-fixup-images ()
+ (goto-char (point-min))
+ (while (re-search-forward (concat "<imagedata fileref=\"[^\"]+\""
+ " format=\"\\([^\"]+\\)\" />$")
+ nil t)
+ (replace-match (upcase (match-string 1)) t t nil 1)))
+
+(defun muse-docbook-fixup-citations ()
+ ;; remove the role attribute if there is no role
+ (goto-char (point-min))
+ (while (re-search-forward "<\\(citation role=\"nil\"\\)>" nil t)
+ (replace-match "citation" t t nil 1))
+ ;; replace colons in multi-head citations with semicolons
+ (goto-char (point-min))
+ (while (re-search-forward "<citation.*>" nil t)
+ (let ((start (point))
+ (end (re-search-forward "</citation>")))
+ (save-restriction
+ (narrow-to-region start end)
+ (goto-char (point-min))
+ (while (re-search-forward "," nil t)
+ (replace-match ";"))))))
+
+(defun muse-docbook-munge-buffer ()
+ (muse-docbook-fixup-images)
+ (muse-docbook-fixup-citations))
+
+(defun muse-docbook-entities ()
+ (save-excursion
+ (goto-char (point-min))
+ (if (re-search-forward "<citation" nil t)
+ (concat
+ " [\n<!ENTITY bibliography SYSTEM \""
+ (if (string-match ".short$" (muse-page-name))
+ (substring (muse-page-name) 0 -6)
+ (muse-page-name))
+ ".bib.xml\">\n]")
+ "")))
+
+(defun muse-docbook-bibliography ()
+ (save-excursion
+ (goto-char (point-min))
+ (if (re-search-forward "<citation" nil t)
+ "&bibliography;\n"
+ "")))
+
+(defun muse-docbook-finalize-buffer ()
+ (when (boundp 'buffer-file-coding-system)
+ (when (memq buffer-file-coding-system '(no-conversion undecided-unix))
+ ;; make it agree with the default charset
+ (setq buffer-file-coding-system muse-docbook-encoding-default))))
+
+;;; Register the Muse DocBook XML Publisher
+
+(muse-define-style "docbook"
+ :suffix 'muse-docbook-extension
+ :regexps 'muse-docbook-markup-regexps
+ :functions 'muse-docbook-markup-functions
+ :strings 'muse-docbook-markup-strings
+ :specials 'muse-xml-decide-specials
+ :before-end 'muse-docbook-munge-buffer
+ :after 'muse-docbook-finalize-buffer
+ :header 'muse-docbook-header
+ :footer 'muse-docbook-footer
+ :browser 'find-file)
+
+(provide 'muse-docbook)
+
+;;; muse-docbook.el ends here
--- /dev/null
+;;; muse-groff.el --- publish groff -mom -mwww files
+
+;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; Author: Andrew J. Korty (ajk AT iu DOT edu)
+;; Date: Tue 5-Jul-2005
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Contributors:
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Muse Publishing Using groff -mom -mwww
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(require 'muse-publish)
+
+(defgroup muse-groff nil
+ "Rules for marking up a Muse file with groff -mom -mwww macros."
+ :group 'muse-publish)
+
+(defcustom muse-groff-extension ".groff"
+ "Default file extension for publishing groff -mom -mwww files."
+ :type 'string
+ :group 'muse-groff)
+
+(defcustom muse-groff-pdf-extension ".pdf"
+ "Default file extension for publishing groff -mom -mwww files to PDF."
+ :type 'string
+ :group 'muse-groff)
+
+(defcustom muse-groff-header
+ ".TITLE \"<lisp>(muse-publishing-directive \"title\")</lisp>\"
+.SUBTITLE \"<lisp>(muse-publishing-directive \"date\")</lisp>\"
+.AUTHOR \"<lisp>(muse-publishing-directive \"author\")</lisp>\"
+.PRINTSTYLE TYPESET
+.de list
+. LIST \\$1
+. SHIFT_LIST \\$2
+..
+.PARA_INDENT 0
+.START
+<lisp>(and muse-publish-generate-contents \".TOC\n\")</lisp>\n"
+ "Header used for publishing groff -mom -mwww files."
+ :type '(choice string file)
+ :group 'muse-groff)
+
+(defcustom muse-groff-footer " "
+ "Footer used for publishing groff -mom -mwww files."
+ :type '(choice string file)
+ :group 'muse-groff)
+
+(defcustom muse-groff-markup-regexps
+ `((10400 ,(concat "\\(\n</\\(blockquote\\|center\\)>\\)?\n"
+ "\\(["
+ muse-regexp-blank
+ "]*\n\\)+\\(<\\(blockquote\\|center\\)>\n\\)?")
+ 0 muse-groff-markup-paragraph))
+"List of markup regexps for identifying regions in a Muse page.
+For more on the structure of this list, see `muse-publish-markup-regexps'."
+ :type '(repeat (choice
+ (list :tag "Markup rule"
+ integer
+ (choice regexp symbol)
+ integer
+ (choice string function symbol))
+ function))
+ :group 'muse-groff)
+
+(defcustom muse-groff-markup-functions
+ '((table . muse-groff-markup-table))
+ "An alist of style types to custom functions for that kind of text.
+For more on the structure of this list, see
+`muse-publish-markup-functions'."
+ :type '(alist :key-type symbol :value-type function)
+ :group 'muse-groff)
+
+(defcustom muse-groff-markup-tags
+ '()
+ "A list of tag specifications, for specially marking up GROFF."
+ :type '(repeat (list (string :tag "Markup tag")
+ (boolean :tag "Expect closing tag" :value t)
+ (boolean :tag "Parse attributes" :value nil)
+ (boolean :tag "Nestable" :value nil)
+ function))
+ :group 'muse-groff)
+
+(defcustom muse-groff-markup-strings
+ `((image-with-desc . "\n.MPIMG -R %s.%s\n")
+ (image . "\n.MPIMG -R %s.%s\n")
+ (image-link . "\n.\\\" %s\n.MPIMG -R %s.%s")
+ (url . "\n.URL %s %s\n\\z")
+ (link . "\n.URL %s %s\n\\z")
+ (email-addr . "\f[C]%s\f[]")
+ (emdash . "\\(em")
+ (rule . "\n.RULE\n")
+ (no-break-space . "\\h")
+ (line-break . "\\p")
+ (enddots . "....")
+ (dots . "...")
+;; (part . "\\part{")
+;; (part-end . "}")
+;; (chapter . "\\chapter{")
+;; (chapter-end . "}")
+ (section . ".HEAD \"")
+ (section-end . "\"")
+ (subsection . ".SUBHEAD \"")
+ (subsection-end . "\"")
+ (subsubsection . ".PARAHEAD \"")
+ (subsubsection-end . "\"")
+;; (footnote . "\\c\n.FOOTNOTE\n")
+;; (footnote-end . "\n.FOOTNOTE OFF\n")
+;; (footnotemark . "\\footnotemark[%d]")
+;; (footnotetext . "\\footnotetext[%d]{")
+;; (footnotetext-end . "}")
+ (begin-underline . "\n.UNDERSCORE \"")
+ (end-underline . "\"\n")
+ (begin-literal . "\\fC")
+ (end-literal . "\\fP")
+ (begin-emph . "\\fI")
+ (end-emph . "\\fP")
+ (begin-more-emph . "\\fB")
+ (end-more-emph . "\\fP")
+ (begin-most-emph . "\\f(BI")
+ (end-most-emph . "\\fP")
+ (begin-verse . ".QUOTE")
+ (end-verse . ".QUOTE OFF")
+ (begin-center . "\n.CENTER\n")
+ (end-center . "\n.QUAD L\n")
+ (begin-example . ,(concat
+ ".QUOTE_FONT CR\n.QUOTE_INDENT 1\n"".QUOTE_SIZE -2\n"
+ ".UNDERLINE_QUOTES OFF\n.QUOTE"))
+ (end-example . ".QUOTE OFF")
+ (begin-quote . ".BLOCKQUOTE")
+ (end-quote . ".BLOCKQUOTE OFF")
+ (begin-cite . "")
+ (begin-cite-author . "")
+ (begin-cite-year . "")
+ (end-cite . "")
+ (begin-uli . ".list BULLET\n.SHIFT_LIST 2m\n.ITEM\n")
+ (end-uli . "\n.LIST OFF")
+ (begin-oli . ".list DIGIT\n.SHIFT_LIST 2m\n.ITEM\n")
+ (end-oli . "\n.LIST OFF")
+ (begin-ddt . "\\fB")
+ (begin-dde . "\\fP\n.IR 4P\n")
+ (end-ddt . ".IRX CLEAR"))
+ "Strings used for marking up text.
+These cover the most basic kinds of markup, the handling of which
+differs little between the various styles."
+ :type '(alist :key-type symbol :value-type string)
+ :group 'muse-groff)
+
+(defcustom muse-groff-markup-specials
+ '((?\\ . "\\e"))
+ "A table of characters which must be represented specially."
+ :type '(alist :key-type character :value-type string)
+ :group 'muse-groff)
+
+(defun muse-groff-markup-paragraph ()
+ (let ((end (copy-marker (match-end 0) t)))
+ (goto-char (1+ (match-beginning 0)))
+ (delete-region (point) end)
+ (unless (looking-at "\.\\(\\(\\(SUB\\|PARA\\)?HEAD \\)\\|RULE$\\)")
+ (muse-insert-markup ".ALD .5v\n.PP\n.ne 2\n"))))
+
+(defun muse-groff-protect-leading-chars ()
+ "Protect leading periods and apostrophes from being interpreted as
+command characters."
+ (while (re-search-forward "^[.']" nil t)
+ (replace-match "\\\\&\\&" t)))
+
+(defun muse-groff-concat-lists ()
+ "Join like lists."
+ (let ((type "")
+ arg begin)
+ (while (re-search-forward "^\.LIST[ \t]+\\(.*\\)\n" nil t)
+ (setq arg (match-string 1))
+ (if (string= arg "OFF")
+ (setq begin (match-beginning 0))
+ (if (and begin (string= type arg))
+ (delete-region begin (match-end 0))
+ (setq type arg
+ begin 0))))))
+
+(defun muse-groff-fixup-dquotes ()
+ "Fixup double quotes."
+ (let ((open t))
+ (while (search-forward "\"" nil t)
+ (unless (get-text-property (match-beginning 0) 'read-only)
+ (if (and (bolp) (eq (char-before) ?\n))
+ (setq open t))
+ (if open
+ (progn
+ (replace-match "``")
+ (setq open nil))
+ (replace-match "''")
+ (setq open t))))))
+
+(defun muse-groff-prepare-buffer ()
+ (goto-char (point-min))
+ (muse-groff-protect-leading-chars))
+
+(defun muse-groff-munge-buffer ()
+ (goto-char (point-min))
+ (muse-groff-concat-lists))
+
+(defun muse-groff-pdf-browse-file (file)
+ (shell-command (concat "open " file)))
+
+(defun muse-groff-pdf-generate (file output-path final-target)
+ (muse-publish-transform-output
+ file output-path final-target "PDF"
+ (function
+ (lambda (file output-path)
+ (let ((command
+ (format
+ (concat "file=%s; ext=%s; cd %s && cp $file$ext $file.ref && "
+ "groff -mom -mwww -t $file$ext > $file.ps && "
+ "pstopdf $file.ps")
+ (file-name-sans-extension file)
+ muse-groff-extension
+ (file-name-directory output-path))))
+ (shell-command command))))
+ ".ps"))
+
+;;; Register the Muse GROFF Publisher
+
+(muse-define-style "groff"
+ :suffix 'muse-groff-extension
+ :regexps 'muse-groff-markup-regexps
+;;; :functions 'muse-groff-markup-functions
+ :strings 'muse-groff-markup-strings
+ :tags 'muse-groff-markup-tags
+ :specials 'muse-groff-markup-specials
+ :before 'muse-groff-prepare-buffer
+ :before-end 'muse-groff-munge-buffer
+ :header 'muse-groff-header
+ :footer 'muse-groff-footer
+ :browser 'find-file)
+
+(muse-derive-style "groff-pdf" "groff"
+ :final 'muse-groff-pdf-generate
+ :browser 'muse-groff-pdf-browse-file
+ :osuffix 'muse-groff-pdf-extension)
+
+(provide 'muse-groff)
+
+;;; muse-groff.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
--- /dev/null
+;;; muse-html.el --- publish to HTML and XHTML
+
+;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Contributors:
+
+;; Zhiqiang Ye (yezq AT mail DOT cbi DOT pku DOT edu DOT cn) suggested
+;; appending an 'encoding="..."' fragment to the first line of the
+;; sample publishing header so that when editing the resulting XHTML
+;; file, Emacs would use the proper encoding.
+
+;; Sun Jiyang (sunyijiang AT gmail DOT com) came up with the idea for
+;; the <src> tag and provided an implementation for emacs-wiki.
+
+;; Charles Wang (wcy123 AT gmail DOT com) provided an initial
+;; implementation of the <src> tag for Muse.
+
+;; Clinton Ebadi (clinton AT unknownlamer DOT org) provided further
+;; ideas for the implementation of the <src> tag.
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Muse HTML Publishing
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(require 'muse-publish)
+(require 'muse-regexps)
+(require 'muse-xml-common)
+
+(defgroup muse-html nil
+ "Options controlling the behavior of Muse HTML publishing."
+ :group 'muse-publish)
+
+(defcustom muse-html-extension ".html"
+ "Default file extension for publishing HTML files."
+ :type 'string
+ :group 'muse-html)
+
+(defcustom muse-xhtml-extension ".html"
+ "Default file extension for publishing XHTML files."
+ :type 'string
+ :group 'muse-html)
+
+(defcustom muse-html-style-sheet
+ "<style type=\"text/css\">
+body {
+ background: white; color: black;
+ margin-left: 3%; margin-right: 7%;
+}
+
+p { margin-top: 1% }
+p.verse { margin-left: 3% }
+
+.example { margin-left: 3% }
+
+h2 {
+ margin-top: 25px;
+ margin-bottom: 0px;
+}
+h3 { margin-bottom: 0px; }
+ </style>"
+ "Store your stylesheet definitions here.
+This is used in `muse-html-header'.
+You can put raw CSS in here or a <link> tag to an external stylesheet.
+This text may contain <lisp> markup tags.
+
+An example of using <link> is as follows.
+
+<link rel=\"stylesheet\" type=\"text/css\" charset=\"utf-8\" media=\"all\" href=\"/default.css\">"
+ :type 'string
+ :group 'muse-html)
+
+(defcustom muse-xhtml-style-sheet
+ "<style type=\"text/css\">
+body {
+ background: white; color: black;
+ margin-left: 3%; margin-right: 7%;
+}
+
+p { margin-top: 1% }
+p.verse { margin-left: 3% }
+
+.example { margin-left: 3% }
+
+h2 {
+ margin-top: 25px;
+ margin-bottom: 0px;
+}
+h3 { margin-bottom: 0px; }
+ </style>"
+ "Store your stylesheet definitions here.
+This is used in `muse-xhtml-header'.
+You can put raw CSS in here or a <link> tag to an external stylesheet.
+This text may contain <lisp> markup tags.
+
+An example of using <link> is as follows.
+
+<link rel=\"stylesheet\" type=\"text/css\" charset=\"utf-8\" media=\"all\" href=\"/default.css\" />"
+ :type 'string
+ :group 'muse-html)
+
+(defcustom muse-html-header
+ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">
+<html>
+ <head>
+ <title><lisp>
+ (concat (muse-publishing-directive \"title\")
+ (let ((author (muse-publishing-directive \"author\")))
+ (if (not (string= author (user-full-name)))
+ (concat \" (by \" author \")\"))))</lisp></title>
+ <meta name=\"generator\" content=\"muse.el\">
+ <meta http-equiv=\"<lisp>muse-html-meta-http-equiv</lisp>\"
+ content=\"<lisp>muse-html-meta-content-type</lisp>\">
+ <lisp>
+ (let ((maintainer (muse-style-element :maintainer)))
+ (when maintainer
+ (concat \"<link rev=\\\"made\\\" href=\\\"\" maintainer \"\\\">\")))
+ </lisp><lisp>
+ (muse-style-element :style-sheet muse-publishing-current-style)
+ </lisp>
+ </head>
+ <body>
+ <h1><lisp>
+ (concat (muse-publishing-directive \"title\")
+ (let ((author (muse-publishing-directive \"author\")))
+ (if (not (string= author (user-full-name)))
+ (concat \" (by \" author \")\"))))</lisp></h1>
+ <!-- Page published by Emacs Muse begins here -->\n"
+ "Header used for publishing HTML files. This may be text or a filename."
+ :type 'string
+ :group 'muse-html)
+
+(defcustom muse-html-footer "
+<!-- Page published by Emacs Muse ends here -->
+ </body>
+</html>\n"
+ "Footer used for publishing HTML files. This may be text or a filename."
+ :type 'string
+ :group 'muse-html)
+
+(defcustom muse-xhtml-header
+ "<?xml version=\"1.0\" encoding=\"<lisp>
+ (muse-html-encoding)</lisp>\"?>
+<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"
+ \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
+<html xmlns=\"http://www.w3.org/1999/xhtml\">
+ <head>
+ <title><lisp>
+ (concat (muse-publishing-directive \"title\")
+ (let ((author (muse-publishing-directive \"author\")))
+ (if (not (string= author (user-full-name)))
+ (concat \" (by \" author \")\"))))</lisp></title>
+ <meta name=\"generator\" content=\"muse.el\" />
+ <meta http-equiv=\"<lisp>muse-html-meta-http-equiv</lisp>\"
+ content=\"<lisp>muse-html-meta-content-type</lisp>\" />
+ <lisp>
+ (let ((maintainer (muse-style-element :maintainer)))
+ (when maintainer
+ (concat \"<link rev=\\\"made\\\" href=\\\"\" maintainer \"\\\" />\")))
+ </lisp><lisp>
+ (muse-style-element :style-sheet muse-publishing-current-style)
+ </lisp>
+ </head>
+ <body>
+ <h1><lisp>
+ (concat (muse-publishing-directive \"title\")
+ (let ((author (muse-publishing-directive \"author\")))
+ (if (not (string= author (user-full-name)))
+ (concat \" (by \" author \")\"))))</lisp></h1>
+ <!-- Page published by Emacs Muse begins here -->\n"
+ "Header used for publishing XHTML files. This may be text or a filename."
+ :type 'string
+ :group 'muse-html)
+
+(defcustom muse-xhtml-footer "
+<!-- Page published by Emacs Muse ends here -->
+ </body>
+</html>\n"
+ "Footer used for publishing XHTML files. This may be text or a filename."
+ :type 'string
+ :group 'muse-html)
+
+(defcustom muse-html-anchor-on-word nil
+ "When true, anchors surround the closest word. This allows you
+to select them in a browser (i.e. for pasting), but has the
+side-effect of marking up headers in multiple colors if your
+header style is different from your link style."
+ :type 'boolean
+ :group 'muse-html)
+
+(defcustom muse-html-table-attributes
+ " class=\"muse-table\" border=\"2\" cellpadding=\"5\""
+ "The attribute to be used with HTML <table> tags.
+Note that Muse supports insertion of raw HTML tags, as long
+as you wrap the region in <literal></literal>."
+ :type 'string
+ :group 'muse-html)
+
+(defcustom muse-html-markup-regexps
+ `(;; Beginning of doc, end of doc, or plain paragraph separator
+ (10000 ,(concat "\\(\\(\n\\(?:[" muse-regexp-blank "]*\n\\)*"
+ "\\([" muse-regexp-blank "]*\n\\)\\)"
+ "\\|\\`\\s-*\\|\\s-*\\'\\)")
+ ;; this is somewhat repetitive because we only require the
+ ;; line just before the paragraph beginning to be not
+ ;; read-only
+ 3 muse-html-markup-paragraph))
+ "List of markup rules for publishing a Muse page to HTML.
+For more on the structure of this list, see `muse-publish-markup-regexps'."
+ :type '(repeat (choice
+ (list :tag "Markup rule"
+ integer
+ (choice regexp symbol)
+ integer
+ (choice string function symbol))
+ function))
+ :group 'muse-html)
+
+(defcustom muse-html-markup-functions
+ '((anchor . muse-html-markup-anchor)
+ (table . muse-html-markup-table)
+ (footnote . muse-html-markup-footnote))
+ "An alist of style types to custom functions for that kind of text.
+For more on the structure of this list, see
+`muse-publish-markup-functions'."
+ :type '(alist :key-type symbol :value-type function)
+ :group 'muse-html)
+
+(defcustom muse-html-markup-strings
+ '((image-with-desc . "<table class=\"image\" width=\"100%%\">
+ <tr><td align=\"center\"><img src=\"%1%.%2%\" alt=\"%3%\"></td></tr>
+ <tr><td align=\"center\" class=\"image-caption\">%3%</td></tr>
+</table>")
+ (image . "<img src=\"%s.%s\" alt=\"\">")
+ (image-link . "<a class=\"image-link\" href=\"%s\">
+<img src=\"%s.%s\"></a>")
+ (anchor-ref . "<a href=\"#%s\">%s</a>")
+ (url . "<a href=\"%s\">%s</a>")
+ (link . "<a href=\"%s\">%s</a>")
+ (link-and-anchor . "<a href=\"%s#%s\">%s</a>")
+ (email-addr . "<a href=\"mailto:%s\">%s</a>")
+ (anchor . "<a name=\"%1%\" id=\"%1%\">")
+ (emdash . "%s—%s")
+ (comment-begin . "<!-- ")
+ (comment-end . " -->")
+ (rule . "<hr>")
+ (fn-sep . "<hr>\n")
+ (no-break-space . " ")
+ (line-break . "<br>")
+ (enddots . "....")
+ (dots . "...")
+ (section . "<h2>")
+ (section-end . "</h2>")
+ (subsection . "<h3>")
+ (subsection-end . "</h3>")
+ (subsubsection . "<h4>")
+ (subsubsection-end . "</h4>")
+ (section-other . "<h5>")
+ (section-other-end . "</h5>")
+ (begin-underline . "<u>")
+ (end-underline . "</u>")
+ (begin-literal . "<code>")
+ (end-literal . "</code>")
+ (begin-cite . "<span class=\"citation\">")
+ (begin-cite-author . "<span class=\"citation-author\">")
+ (begin-cite-year . "<span class=\"citation-year\">")
+ (end-cite . "</span>")
+ (begin-emph . "<em>")
+ (end-emph . "</em>")
+ (begin-more-emph . "<strong>")
+ (end-more-emph . "</strong>")
+ (begin-most-emph . "<strong><em>")
+ (end-most-emph . "</em></strong>")
+ (begin-verse . "<p class=\"verse\">\n")
+ (verse-space . " ")
+ (end-verse-line . "<br>")
+ (end-last-stanza-line . "<br>")
+ (empty-verse-line . "<br>")
+ (end-verse . "</p>")
+ (begin-example . "<pre class=\"example\">")
+ (end-example . "</pre>")
+ (begin-center . "<center>\n<p>")
+ (end-center . "</p>\n</center>")
+ (begin-quote . "<blockquote>\n")
+ (end-quote . "\n</blockquote>")
+ (begin-quote-item . "<p class=\"quoted\">")
+ (end-quote-item . "</p>")
+ (begin-uli . "<ul>\n")
+ (end-uli . "\n</ul>")
+ (begin-uli-item . "<li>")
+ (end-uli-item . "</li>")
+ (begin-oli . "<ol>\n")
+ (end-oli . "\n</ol>")
+ (begin-oli-item . "<li>")
+ (end-oli-item . "</li>")
+ (begin-dl . "<dl>\n")
+ (end-dl . "\n</dl>")
+ (begin-ddt . "<dt><strong>")
+ (end-ddt . "</strong></dt>")
+ (begin-dde . "<dd>")
+ (end-dde . "</dd>")
+ (begin-table . "<table%s>\n")
+ (end-table . "</table>")
+ (begin-table-row . " <tr>\n")
+ (end-table-row . " </tr>\n")
+ (begin-table-entry . " <%s>")
+ (end-table-entry . "</%s>\n"))
+ "Strings used for marking up text as HTML.
+These cover the most basic kinds of markup, the handling of which
+differs little between the various styles."
+ :type '(alist :key-type symbol :value-type string)
+ :group 'muse-html)
+
+(defcustom muse-xhtml-markup-strings
+ '((image-with-desc . "<table class=\"image\" width=\"100%%\">
+ <tr><td align=\"center\"><img src=\"%1%.%2%\" alt=\"%3%\" /></td></tr>
+ <tr><td align=\"center\" class=\"image-caption\">%3%</td></tr>
+</table>")
+ (image . "<img src=\"%s.%s\" alt=\"\" />")
+ (image-link . "<a class=\"image-link\" href=\"%s\">
+<img src=\"%s.%s\" alt=\"\" /></a>")
+ (rule . "<hr />")
+ (fn-sep . "<hr />\n")
+ (line-break . "<br />")
+ (begin-underline . "<span style=\"text-decoration: underline;\">")
+ (end-underline . "</span>")
+ (begin-center . "<p style=\"text-align: center;\">\n")
+ (end-center . "\n</p>")
+ (end-verse-line . "<br />")
+ (end-last-stanza-line . "<br />")
+ (empty-verse-line . "<br />"))
+ "Strings used for marking up text as XHTML.
+These cover the most basic kinds of markup, the handling of which
+differs little between the various styles.
+
+If a markup rule is not found here, `muse-html-markup-strings' is
+searched."
+ :type '(alist :key-type symbol :value-type string)
+ :group 'muse-html)
+
+(defcustom muse-xhtml1.1-markup-strings
+ '((anchor . "<a id=\"%s\">"))
+ "Strings used for marking up text as XHTML 1.1.
+These cover the most basic kinds of markup, the handling of which
+differs little between the various styles.
+
+If a markup rule is not found here, `muse-xhtml-markup-strings'
+and `muse-html-markup-strings' are searched."
+ :type '(alist :key-type symbol :value-type string)
+ :group 'muse-html)
+
+(defcustom muse-html-markup-tags
+ '(("class" t t t muse-html-class-tag)
+ ("div" t t t muse-html-div-tag)
+ ("src" t t nil muse-html-src-tag))
+ "A list of tag specifications, for specially marking up HTML."
+ :type '(repeat (list (string :tag "Markup tag")
+ (boolean :tag "Expect closing tag" :value t)
+ (boolean :tag "Parse attributes" :value nil)
+ (boolean :tag "Nestable" :value nil)
+ function))
+ :group 'muse-html)
+
+(defcustom muse-html-meta-http-equiv "Content-Type"
+ "The http-equiv attribute used for the HTML <meta> tag."
+ :type 'string
+ :group 'muse-html)
+
+(defcustom muse-html-meta-content-type "text/html"
+ "The content type used for the HTML <meta> tag.
+If you are striving for XHTML 1.1 compliance, you may want to
+change this to \"application/xhtml+xml\"."
+ :type 'string
+ :group 'muse-html)
+
+(defcustom muse-html-meta-content-encoding (if (featurep 'mule)
+ 'detect
+ "iso-8859-1")
+ "The charset to append to the HTML <meta> tag.
+If set to the symbol 'detect, use `muse-html-encoding-map' to try
+and determine the HTML charset from emacs's coding. If set to a
+string, this string will be used to force a particular charset"
+ :type '(choice string symbol)
+ :group 'muse-html)
+
+(defcustom muse-html-encoding-default 'iso-8859-1
+ "The default Emacs buffer encoding to use in published files.
+This will be used if no special characters are found."
+ :type 'symbol
+ :group 'muse-html)
+
+(defcustom muse-html-charset-default "iso-8859-1"
+ "The default HTML meta charset to use if no translation is found in
+`muse-html-encoding-map'."
+ :type 'string
+ :group 'muse-html)
+
+(defcustom muse-html-src-allowed-modes t
+ "Modes that we allow the <src> tag to colorize.
+If t, permit the <src> tag to colorize any mode.
+
+If a list of mode names, such as '(\"html\" \"latex\"), and the
+lang argument to <src> is not in the list, then use fundamental
+mode instead."
+ :type '(choice (const :tag "Any" t)
+ (repeat (string :tag "Mode")))
+ :group 'muse-html)
+
+(defun muse-html-insert-anchor (anchor)
+ "Insert an anchor, either around the word at point, or within a tag."
+ (skip-chars-forward (concat muse-regexp-blank "\n"))
+ (if (looking-at (concat "<\\([^" muse-regexp-blank "/>\n]+\\)>"))
+ (let ((tag (match-string 1)))
+ (goto-char (match-end 0))
+ (muse-insert-markup (muse-markup-text 'anchor anchor))
+ (when muse-html-anchor-on-word
+ (or (and (search-forward (format "</%s>" tag)
+ (muse-line-end-position) t)
+ (goto-char (match-beginning 0)))
+ (forward-word 1)))
+ (muse-insert-markup "</a>"))
+ (muse-insert-markup (muse-markup-text 'anchor anchor))
+ (when muse-html-anchor-on-word
+ (forward-word 1))
+ (muse-insert-markup "</a>\n")))
+
+(defun muse-html-markup-anchor ()
+ (unless (get-text-property (match-end 1) 'muse-link)
+ (save-match-data
+ (muse-html-insert-anchor (match-string 2)))
+ (match-string 1)))
+
+(defun muse-html-markup-paragraph ()
+ (let ((end (copy-marker (match-end 0) t)))
+ (goto-char (match-beginning 0))
+ (when (save-excursion
+ (save-match-data
+ (and (not (get-text-property (max (point-min) (1- (point)))
+ 'muse-no-paragraph))
+ (re-search-backward "<\\(/?\\)p[ >]" nil t)
+ (not (string-equal (match-string 1) "/")))))
+ (when (get-text-property (1- (point)) 'muse-end-list)
+ (goto-char (previous-single-property-change (1- (point))
+ 'muse-end-list)))
+ (muse-insert-markup "</p>"))
+ (goto-char end))
+ (cond
+ ((eobp)
+ (unless (bolp)
+ (insert "\n")))
+ ((get-text-property (point) 'muse-no-paragraph)
+ (forward-char 1)
+ nil)
+ ((eq (char-after) ?\<)
+ (cond
+ ((looking-at "<\\(em\\|strong\\|code\\|span\\)[ >]")
+ (muse-insert-markup "<p>"))
+ ((looking-at "<a ")
+ (if (looking-at "<a[^>\n]+><img")
+ (muse-insert-markup "<p class=\"image-link\">")
+ (muse-insert-markup "<p>")))
+ ((looking-at "<img[ >]")
+ (muse-insert-markup "<p class=\"image\">"))
+ (t
+ (forward-char 1)
+ nil)))
+ ((muse-looking-back "\\(</h[1-4]>\\|<hr>\\)\n\n")
+ (muse-insert-markup "<p class=\"first\">"))
+ (t
+ (muse-insert-markup "<p>"))))
+
+(defun muse-html-markup-footnote ()
+ (cond
+ ((get-text-property (match-beginning 0) 'muse-link)
+ nil)
+ ((= (muse-line-beginning-position) (match-beginning 0))
+ (prog1
+ (let ((text (match-string 1)))
+ (muse-insert-markup
+ (concat "<p class=\"footnote\">"
+ "<a class=\"footnum\" name=\"fn." text
+ "\" href=\"#fnr." text "\">"
+ text ".</a>")))
+ (save-excursion
+ (save-match-data
+ (let* ((beg (goto-char (match-end 0)))
+ (end (and (search-forward "\n\n" nil t)
+ (prog1
+ (copy-marker (match-beginning 0))
+ (goto-char beg)))))
+ (while (re-search-forward (concat "^["
+ muse-regexp-blank
+ "]+\\([^\n]\\)")
+ end t)
+ (replace-match "\\1" t)))))
+ (replace-match "")))
+ (t (let ((text (match-string 1)))
+ (muse-insert-markup
+ (concat "<sup><a class=\"footref\" name=\"fnr." text
+ "\" href=\"#fn." text "\">"
+ text "</a></sup>")))
+ (replace-match ""))))
+
+(defun muse-html-markup-table ()
+ (muse-xml-markup-table muse-html-table-attributes))
+
+;; Handling of tags for HTML
+
+(defun muse-html-strip-links (string)
+ "Remove all HTML links from STRING."
+ (muse-replace-regexp-in-string "\\(<a .*?>\\|</a>\\)" "" string nil t))
+
+(defun muse-html-insert-contents (depth)
+ "Scan the current document and generate a table of contents at point.
+DEPTH indicates how many levels of headings to include. The default is 2."
+ (let ((max-depth (or depth 2))
+ (index 1)
+ base contents l end)
+ (save-excursion
+ (goto-char (point-min))
+ (search-forward "Page published by Emacs Muse begins here" nil t)
+ (catch 'done
+ (while (re-search-forward "<h\\([0-9]+\\)>\\(.+?\\)</h\\1>$" nil t)
+ (unless (and (get-text-property (point) 'read-only)
+ (not (get-text-property (match-beginning 0)
+ 'muse-contents)))
+ (remove-text-properties (match-beginning 0) (match-end 0)
+ '(muse-contents nil))
+ (setq l (1- (string-to-number (match-string 1))))
+ (if (null base)
+ (setq base l)
+ (if (< l base)
+ (throw 'done t)))
+ (when (<= l max-depth)
+ ;; escape specials now before copying the text, so that we
+ ;; can deal sanely with both emphasis in titles and
+ ;; special characters
+ (goto-char (match-end 2))
+ (setq end (point-marker))
+ (muse-publish-escape-specials (match-beginning 2) end
+ nil 'document)
+ (muse-publish-mark-read-only (match-beginning 2) end)
+ (setq contents (cons (cons l (buffer-substring-no-properties
+ (match-beginning 2) end))
+ contents))
+ (set-marker end nil)
+ (goto-char (match-beginning 2))
+ (muse-html-insert-anchor (concat "sec" (int-to-string index)))
+ (setq index (1+ index)))))))
+ (setq index 1 contents (nreverse contents))
+ (let ((depth 1) (sub-open 0) (p (point)))
+ (muse-insert-markup "<div class=\"contents\">\n<dl>\n")
+ (while contents
+ (muse-insert-markup "<dt>\n"
+ "<a href=\"#sec" (int-to-string index) "\">"
+ (muse-html-strip-links (cdar contents))
+ "</a>\n"
+ "</dt>\n")
+ (setq index (1+ index)
+ depth (caar contents)
+ contents (cdr contents))
+ (when contents
+ (cond
+ ((< (caar contents) depth)
+ (let ((idx (caar contents)))
+ (while (< idx depth)
+ (muse-insert-markup "</dl>\n</dd>\n")
+ (setq sub-open (1- sub-open)
+ idx (1+ idx)))))
+ ((> (caar contents) depth) ; can't jump more than one ahead
+ (muse-insert-markup "<dd>\n<dl>\n")
+ (setq sub-open (1+ sub-open))))))
+ (while (> sub-open 0)
+ (muse-insert-markup "</dl>\n</dd>\n")
+ (setq sub-open (1- sub-open)))
+ (muse-insert-markup "</dl>\n</div>\n")
+ (muse-publish-mark-read-only p (point)))))
+
+(defun muse-html-denote-headings ()
+ "Place a text property on any headings in the current buffer.
+This allows the headings to be picked up later on if publishing a
+table of contents."
+ (save-excursion
+ (goto-char (point-min))
+ (search-forward "Page published by Emacs Muse begins here" nil t)
+ (while (re-search-forward "<h\\([0-9]+\\)>\\(.+?\\)</h\\1>$" nil t)
+ (unless (get-text-property (point) 'read-only)
+ (add-text-properties (match-beginning 0) (match-end 0)
+ '(muse-contents t))))))
+
+(defun muse-html-class-tag (beg end attrs)
+ (let ((name (cdr (assoc "name" attrs))))
+ (when name
+ (goto-char beg)
+ (muse-insert-markup "<span class=\"" name "\">")
+ (save-excursion
+ (goto-char end)
+ (muse-insert-markup "</span>")))))
+
+(defun muse-html-div-tag (beg end attrs)
+ "Publish a <div> tag for HTML."
+ (let ((id (cdr (assoc "id" attrs)))
+ (style (cdr (assoc "style" attrs))))
+ (when (or id style)
+ (goto-char beg)
+ (if (null id)
+ (muse-insert-markup "<div style=\"" style "\">")
+ (muse-insert-markup "<div id=\"" id "\">"))
+ (save-excursion
+ (goto-char end)
+ (muse-insert-markup "</div>")))))
+
+(defun muse-html-src-tag (beg end attrs)
+ "Publish the region using htmlize.
+The language to use may be specified by the \"lang\" attribute.
+
+Muse will look for a function named LANG-mode, where LANG is the
+value of the \"lang\" attribute.
+
+This tag requires htmlize 1.34 or later in order to work."
+ (if (condition-case nil
+ (progn
+ (require 'htmlize)
+ (if (fboundp 'htmlize-region-for-paste)
+ nil
+ (muse-display-warning
+ (concat "The `htmlize-region-for-paste' function was not"
+ " found.\nThis is available in htmlize.el 1.34"
+ " or later."))
+ t))
+ (error nil t))
+ ;; if htmlize.el was not found, treat this like an example tag
+ (muse-publish-example-tag beg end)
+ (muse-publish-ensure-block beg end)
+ (let* ((lang (cdr (assoc "lang" attrs)))
+ (mode (or (and (not (eq muse-html-src-allowed-modes t))
+ (not (member lang muse-html-src-allowed-modes))
+ 'fundamental-mode)
+ (intern-soft (concat lang "-mode"))))
+ (text (muse-delete-and-extract-region beg end))
+ (htmltext
+ (with-temp-buffer
+ (insert text)
+ (if (functionp mode)
+ (funcall mode)
+ (fundamental-mode))
+ (font-lock-fontify-buffer)
+ ;; silence the byte-compiler
+ (when (fboundp 'htmlize-region-for-paste)
+ ;; transform the region to HTML
+ (htmlize-region-for-paste (point-min) (point-max))))))
+ (save-restriction
+ (narrow-to-region (point) (point))
+ (insert htmltext)
+ (goto-char (point-min))
+ (re-search-forward "<pre\\([^>]*\\)>\n?" nil t)
+ (replace-match "<pre class=\"src\">")
+ (goto-char (point-max))
+ (muse-publish-mark-read-only (point-min) (point-max))))))
+
+;; Register the Muse HTML Publisher
+
+(defun muse-html-browse-file (file)
+ (browse-url (concat "file:" file)))
+
+(defun muse-html-encoding ()
+ (if (stringp muse-html-meta-content-encoding)
+ muse-html-meta-content-encoding
+ (muse-xml-transform-content-type
+ (or (and (boundp 'buffer-file-coding-system)
+ buffer-file-coding-system)
+ muse-html-encoding-default)
+ muse-html-charset-default)))
+
+(defun muse-html-prepare-buffer ()
+ (make-local-variable 'muse-html-meta-http-equiv)
+ (set (make-local-variable 'muse-html-meta-content-type)
+ (if (save-match-data
+ (string-match "charset=" muse-html-meta-content-type))
+ muse-html-meta-content-type
+ (concat muse-html-meta-content-type "; charset="
+ (muse-html-encoding)))))
+
+(defun muse-html-munge-buffer ()
+ (if muse-publish-generate-contents
+ (progn
+ (goto-char (car muse-publish-generate-contents))
+ (muse-html-insert-contents (cdr muse-publish-generate-contents))
+ (setq muse-publish-generate-contents nil))
+ (muse-html-denote-headings)))
+
+(defun muse-html-finalize-buffer ()
+ (when (and (boundp 'buffer-file-coding-system)
+ (memq buffer-file-coding-system '(no-conversion undecided-unix)))
+ ;; make it agree with the default charset
+ (setq buffer-file-coding-system muse-html-encoding-default)))
+
+;;; Register the Muse HTML and XHTML Publishers
+
+(muse-define-style "html"
+ :suffix 'muse-html-extension
+ :regexps 'muse-html-markup-regexps
+ :functions 'muse-html-markup-functions
+ :strings 'muse-html-markup-strings
+ :tags 'muse-html-markup-tags
+ :specials 'muse-xml-decide-specials
+ :before 'muse-html-prepare-buffer
+ :before-end 'muse-html-munge-buffer
+ :after 'muse-html-finalize-buffer
+ :header 'muse-html-header
+ :footer 'muse-html-footer
+ :style-sheet 'muse-html-style-sheet
+ :browser 'muse-html-browse-file)
+
+(muse-derive-style "xhtml" "html"
+ :suffix 'muse-xhtml-extension
+ :strings 'muse-xhtml-markup-strings
+ :header 'muse-xhtml-header
+ :footer 'muse-xhtml-footer
+ :style-sheet 'muse-xhtml-style-sheet)
+
+;; xhtml1.0 is an alias for xhtml
+(muse-derive-style "xhtml1.0" "xhtml")
+
+;; xhtml1.1 has some quirks that need attention from us
+(muse-derive-style "xhtml1.1" "xhtml"
+ :strings 'muse-xhtml1.1-markup-strings)
+
+(provide 'muse-html)
+
+;;; muse-html.el ends here
--- /dev/null
+;;; muse-http.el --- publish HTML files over HTTP
+
+;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Contributors:
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Publishing HTML over HTTP (using httpd.el)
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(require 'muse-html)
+(require 'muse-project)
+(require 'httpd)
+(require 'cgi)
+
+(defgroup muse-http nil
+ "Options controlling the behavior of Emacs Muse over HTTP."
+ :group 'press)
+
+(defcustom muse-http-maintainer (concat "webmaster@" (system-name))
+ "The maintainer address to use for the HTTP 'From' field."
+ :type 'string
+ :group 'muse-http)
+
+(defcustom muse-http-publishing-style "html"
+ "The style to use when publishing projects over http."
+ :type 'string
+ :group 'muse-http)
+
+(defcustom muse-http-max-cache-size 64
+ "The number of pages to cache when serving over HTTP.
+This only applies if set while running the persisted invocation
+server. See main documentation for the `muse-http'
+customization group."
+ :type 'integer
+ :group 'muse-http)
+
+(defvar muse-buffer-mtime nil)
+(make-variable-buffer-local 'muse-buffer-mtime)
+
+(defun muse-sort-buffers (l r)
+ (let ((l-mtime (with-current-buffer l muse-buffer-mtime))
+ (r-mtime (with-current-buffer r muse-buffer-mtime)))
+ (cond
+ ((and (null l-mtime) (null r-mtime)) l)
+ ((null l-mtime) r)
+ ((null r-mtime) l)
+ (t (muse-time-less-p r-mtime l-mtime)))))
+
+(defun muse-winnow-list (entries &optional predicate)
+ "Return only those ENTRIES for which PREDICATE returns non-nil."
+ (let ((flist (list t)))
+ (let ((entry entries))
+ (while entry
+ (if (funcall predicate (car entry))
+ (nconc flist (list (car entry))))
+ (setq entry (cdr entry))))
+ (cdr flist)))
+
+(defun muse-http-prune-cache ()
+ "If the page cache has become too large, prune it."
+ (let* ((buflist
+ (sort (muse-winnow-list (buffer-list)
+ (function
+ (lambda (buf)
+ (with-current-buffer buf
+ muse-buffer-mtime))))
+ 'muse-sort-buffers))
+ (len (length buflist)))
+ (while (> len muse-http-max-cache-size)
+ (kill-buffer (car buflist))
+ (setq len (1- len)))))
+
+(defvar muse-http-serving-p nil)
+
+(defun muse-http-send-buffer (&optional modified code msg)
+ "Markup and send the contents of the current buffer via HTTP."
+ (httpd-send (or code 200) (or msg "OK")
+ "Server: muse.el/" muse-version httpd-endl
+ "Connection: close" httpd-endl
+ "MIME-Version: 1.0" httpd-endl
+ "Date: " (format-time-string "%a, %e %b %Y %T %Z")
+ httpd-endl
+ "From: " muse-http-maintainer httpd-endl)
+ (when modified
+ (httpd-send-data "Last-Modified: "
+ (format-time-string "%a, %e %b %Y %T %Z" modified)
+ httpd-endl))
+ (httpd-send-data "Content-Type: text/html; charset=iso-8859-1" httpd-endl
+ "Content-Length: " (number-to-string (1- (point-max)))
+ httpd-endl httpd-endl
+ (buffer-string))
+ (httpd-send-eof))
+
+(defun muse-http-reject (title msg &optional annotation)
+ (muse-with-temp-buffer
+ (insert msg ".\n")
+ (if annotation
+ (insert annotation "\n"))
+ (muse-publish-markup-buffer title muse-http-publishing-style)
+ (muse-http-send-buffer nil 404 msg)))
+
+(defun muse-http-prepare-url (target explicit)
+ (save-match-data
+ (unless (or (not explicit)
+ (string-match muse-url-regexp target)
+ (string-match muse-image-regexp target)
+ (string-match muse-file-regexp target))
+ (setq target (concat "page?" target
+ "&project=" muse-http-serving-p))))
+ (muse-publish-read-only target))
+
+(defun muse-http-render-page (name)
+ "Render the Muse page identified by NAME.
+When serving from a dedicated Emacs process (see the httpd-serve
+script), a maximum of `muse-http-max-cache-size' pages will be
+cached in memory to speed up serving time."
+ (let ((file (muse-project-page-file name muse-http-serving-p))
+ (muse-publish-url-transforms
+ (cons 'muse-http-prepare-url muse-publish-url-transforms))
+ (inhibit-read-only t))
+ (when file
+ (with-current-buffer (get-buffer-create file)
+ (let ((modified-time (nth 5 (file-attributes file)))
+ (muse-publishing-current-file file)
+ muse-publishing-current-style)
+ (when (or (null muse-buffer-mtime)
+ (muse-time-less-p muse-buffer-mtime modified-time))
+ (erase-buffer)
+ (setq muse-buffer-mtime modified-time))
+ (goto-char (point-max))
+ (when (bobp)
+ (muse-insert-file-contents file t)
+ (let ((styles (cddr (muse-project muse-http-serving-p)))
+ style)
+ (while (and styles (null style))
+ (let ((include-regexp
+ (muse-style-element :include (car styles)))
+ (exclude-regexp
+ (muse-style-element :exclude (car styles))))
+ (when (and (or (and (null include-regexp)
+ (null exclude-regexp))
+ (if include-regexp
+ (string-match include-regexp file)
+ (not (string-match exclude-regexp file))))
+ (not (muse-project-private-p file)))
+ (setq style (car styles))
+ (while (muse-style-element :base style)
+ (setq style
+ (muse-style (muse-style-element :base style))))
+ (if (string= (car style) muse-http-publishing-style)
+ (setq style (car styles))
+ (setq style nil))))
+ (setq styles (cdr styles)))
+ (muse-publish-markup-buffer
+ name (or style muse-http-publishing-style))))
+ (set-buffer-modified-p nil)
+ (muse-http-prune-cache)
+ (current-buffer))))))
+
+(defun muse-http-transmit-page (name)
+ "Render the Muse page identified by NAME.
+When serving from a dedicated Emacs process (see the httpd-serve
+script), a maximum of `muse-http-max-cache-size' pages will be
+cached in memory to speed up serving time."
+ (let ((inhibit-read-only t)
+ (buffer (muse-http-render-page name)))
+ (if buffer
+ (with-current-buffer buffer
+ (muse-http-send-buffer muse-buffer-mtime)))))
+
+(defvar httpd-vars nil)
+
+(defsubst httpd-var (var)
+ "Return value of VAR as a URL variable. If VAR doesn't exist, nil."
+ (cdr (assoc var httpd-vars)))
+
+(defsubst httpd-var-p (var)
+ "Return non-nil if VAR was passed as a URL variable."
+ (not (null (assoc var httpd-vars))))
+
+(defun muse-http-serve (page &optional content)
+ "Serve the given PAGE from this press server."
+ ;; index.html is really a reference to the project home page
+ (if (and muse-project-alist
+ (string-match "\\`index.html?\\'" page))
+ (setq page (concat "page?"
+ (muse-get-keyword :default
+ (cadr (car muse-project-alist))))))
+ ;; handle the actual request
+ (let ((vc-follow-symlinks t)
+ (muse-publish-report-threshhold nil)
+ muse-http-serving-p
+ httpd-vars)
+ (save-excursion
+ ;; process any CGI variables, if cgi.el is available
+ (if (string-match "\\`\\([^&]+\\)&" page)
+ (setq httpd-vars (cgi-decode (substring page (match-end 0)))
+ page (match-string 1 page)))
+ (unless (setq muse-http-serving-p (httpd-var "project"))
+ (let ((project (car muse-project-alist)))
+ (setq muse-http-serving-p (car project))
+ (setq httpd-vars (cons (cons "project" (car project))
+ httpd-vars))))
+ (if (and muse-http-serving-p
+ (string-match "\\`page\\?\\(.+\\)" page))
+ (muse-http-transmit-page (match-string 1 page))))))
+
+(if (featurep 'httpd)
+ (httpd-add-handler "\\`\\(index\\.html?\\|page\\(\\?\\|\\'\\)\\)"
+ 'muse-http-serve))
+
+(provide 'muse-http)
+
+;;; muse-http.el ends here
--- /dev/null
+;;; muse-ikiwiki.el --- integrate with Ikiwiki
+
+;; Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Contributors:
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Muse Ikiwiki Integration
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(require 'muse)
+(require 'muse-html)
+(require 'muse-ipc)
+(require 'muse-publish)
+
+(eval-when-compile
+ (require 'muse-colors))
+
+(defgroup muse-ikiwiki nil
+ "Options controlling the behavior of Muse integration with Ikiwiki."
+ :group 'muse-publish)
+
+(defcustom muse-ikiwiki-header ""
+ "Header used for publishing Ikiwiki output files.
+This may be text or a filename."
+ :type 'string
+ :group 'muse-ikiwiki)
+
+(defcustom muse-ikiwiki-footer ""
+ "Footer used for publishing Ikiwiki output files.
+This may be text or a filename."
+ :type 'string
+ :group 'muse-ikiwiki)
+
+(defcustom muse-ikiwiki-markup-regexps
+ `(;; Ikiwiki directives
+ (1350 ,(concat "\\(\\\\?\\)\\[\\[!""\\(?:-\\|\\w\\)+"
+ "\\([" muse-regexp-blank "\n]+"
+ "\\(?:\\(?:\\(?:-\\|\\w\\)+=\\)?"
+ "\\(?:\"\"\".*?\"\"\"\\|\"[^\"]+\""
+ "\\|[^]" muse-regexp-blank "\n]+\\)"
+ "[" muse-regexp-blank "\n]*\\)*\\)?\\]\\]")
+ 0 muse-ikiwiki-markup-directive))
+ "List of markup rules for publishing Ikiwiki markup on Muse pages.
+For more on the structure of this list, see `muse-publish-markup-regexps'."
+ :type '(repeat (choice
+ (list :tag "Markup rule"
+ integer
+ (choice regexp symbol)
+ integer
+ (choice string function symbol))
+ function))
+ :group 'muse-ikiwiki)
+
+;;; Publishing
+
+(defun muse-ikiwiki-markup-directive ()
+ "Handle publishing of an Ikiwiki directive."
+ (unless (get-text-property (match-beginning 0) 'read-only)
+ (add-text-properties (match-beginning 0) (match-end 0)
+ '(muse-no-paragraph t))
+ (muse-publish-mark-read-only (match-beginning 0) (match-end 0))))
+
+(defun muse-ikiwiki-publish-buffer (name title &optional style)
+ "Publish a buffer for Ikiwki.
+The name of the corresponding file is NAME.
+The name of the style is given by STYLE. It defaults to \"ikiwiki\"."
+ (unless style (setq style "ikiwiki"))
+ (unless title (setq title (muse-page-name name)))
+ (let ((muse-batch-publishing-p t)
+ (muse-publishing-current-file name)
+ (muse-publishing-current-output-path name)
+ (muse-publishing-current-style style)
+ (font-lock-verbose nil)
+ (vc-handled-backends nil)) ; don't activate VC when publishing files
+ (run-hooks 'muse-before-publish-hook)
+ (let ((muse-inhibit-before-publish-hook t))
+ (muse-publish-markup-buffer title style))))
+
+(defun muse-ikiwiki-publish-file (file name &optional style)
+ "Publish a single file for Ikiwiki.
+The name of the real file is NAME, and the name of the temporary
+file containing the content is FILE.
+The name of the style is given by STYLE. It defaults to \"ikiwiki\"."
+ (if (not (stringp file))
+ (message "Error: No file given to publish")
+ (unless style
+ (setq style "ikiwiki"))
+ (let ((output-path file)
+ (target file)
+ (vc-handled-backends nil) ; don't activate VC when publishing files
+ auto-mode-alist
+ muse-current-output-style)
+ (setq auto-mode-alist
+ (delete (cons (concat "\\." muse-file-extension "\\'")
+ 'muse-mode-choose-mode)
+ auto-mode-alist))
+ (setq muse-current-output-style (list :base style :path file))
+ (muse-with-temp-buffer
+ (muse-insert-file-contents file)
+ (muse-ikiwiki-publish-buffer name nil style)
+ (when (muse-write-file output-path t)
+ (muse-style-run-hooks :final style file output-path target))))))
+
+(defun muse-ikiwiki-start-server (port)
+ "Start Muse IPC server, initializing with the client on PORT."
+ (muse-ipc-start "foo" #'muse-ikiwiki-publish-buffer port))
+
+;;; Colors
+
+(defface muse-ikiwiki-directive
+ '((((class color) (background light))
+ (:foreground "dark green"))
+ (((class color) (background dark))
+ (:foreground "green")))
+ "Face for Ikiwiki directives."
+ :group 'muse-ikiwiki)
+
+(defun muse-colors-ikiwiki-directive ()
+ "Color ikiwiki directives."
+ (let ((start (match-beginning 0)))
+ (unless (or (eq (get-text-property start 'invisible) 'muse)
+ (get-text-property start 'muse-comment)
+ (get-text-property start 'muse-directive))
+ ;; beginning of line or space or symbol
+ (save-excursion
+ (and
+ (catch 'valid
+ (while t
+ (skip-chars-forward "^\"]" muse-colors-region-end)
+ (cond ((eq (point) (point-max))
+ (throw 'valid nil))
+ ((> (point) muse-colors-region-end)
+ (throw 'valid nil))
+ ((eq (char-after) ?\")
+ (if (and (< (1+ (point)) muse-colors-region-end)
+ (eq (char-after (1+ (point))) ?\"))
+ (if (and (< (+ 2 (point)) muse-colors-region-end)
+ (eq (char-after (+ 2 (point))) ?\"))
+ ;; triple-quote
+ (progn
+ (forward-char 3)
+ (or (and (looking-at "\"\"\"")
+ (goto-char (match-end 0)))
+ (re-search-forward
+ "\"\"\"" muse-colors-region-end t)
+ (throw 'valid nil)))
+ ;; empty quotes (""), which are invalid
+ (throw 'valid nil))
+ ;; quote with content
+ (forward-char 1)
+ (skip-chars-forward "^\"" muse-colors-region-end)
+ (when (eq (char-after) ?\")
+ (forward-char 1))))
+ ((eq (char-after) ?\])
+ (forward-char 1)
+ (when (and (< (point) muse-colors-region-end)
+ (eq (char-after (point)) ?\]))
+ (forward-char 1)
+ (throw 'valid t)))
+ (t (throw 'valid nil)))))
+ ;; found a valid directive
+ (let ((end (point)))
+ ;; remove flyspell overlays
+ (when (fboundp 'flyspell-unhighlight-at)
+ (let ((cur start))
+ (while (> end cur)
+ (flyspell-unhighlight-at cur)
+ (setq cur (1+ cur)))))
+ (add-text-properties start end
+ '(face muse-ikiwiki-directive
+ muse-directive t muse-no-flyspell t))
+ (when (progn
+ (goto-char start)
+ (skip-chars-forward "^\n" end)
+ (and (eq (char-after) ?\n)
+ (not (= (point) end))))
+ (add-text-properties start end
+ '(font-lock-multiline t)))))))))
+
+(defun muse-ikiwiki-insinuate-colors ()
+ (add-to-list 'muse-colors-markup
+ '("\\[\\[!" ?\[ muse-colors-ikiwiki-directive)
+ nil))
+
+(eval-after-load "muse-colors" '(muse-ikiwiki-insinuate-colors))
+
+;; Styles
+(muse-derive-style "ikiwiki" "xhtml"
+ :header 'muse-ikiwiki-header
+ :footer 'muse-ikiwiki-footer
+ :regexps 'muse-ikiwiki-markup-regexps)
+
+(provide 'muse-ikiwiki)
+
+;;; muse-ikiwiki.el ends here
--- /dev/null
+;;; muse-import-docbook.el --- convert Docbook XML into Muse format
+
+;; Copyright (C) 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; Author: Elena Pomohaci <e.pomohaci@gmail.com>
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; It works only for article type docbook docs and recognize
+;; followings elements: article, sect1, sect2, sect3, title,
+
+;;; Contributors:
+
+;;; Code:
+
+(require 'muse-import-xml)
+
+(defvar muse-import-docbook-prefix "muse-import-docbook-"
+ "The name prefix for tag functions")
+
+(defvar muse-import-docbook-para-indent "\n\n"
+ "Para elements indentation (0, less than 6 spaces, more than 6 spaces)")
+
+(defun muse-import-docbook-reset-para-indent ()
+ (setq muse-import-docbook-para-indent "\n\n"))
+
+
+;;;###autoload
+(defun muse-import-docbook (src dest)
+ "Convert the Docbook buffer SRC to Muse, writing output in the DEST buffer."
+ (interactive "bDocbook buffer:\nBMuse buffer:")
+ (setq muse-import-xml-prefix muse-import-docbook-prefix)
+ (setq muse-import-xml-generic-function-name "muse-import-xml-node")
+ (muse-import-xml src dest))
+
+;;;###autoload
+(defun muse-import-docbook-files (src dest)
+ "Convert the Docbook file SRC to Muse, writing output to the DEST file."
+ (interactive "fDocbook file:\nFMuse file:")
+ (with-temp-file dest
+ (muse-import-docbook (find-file-noselect src) (current-buffer))))
+
+
+;;; element specific functions
+
+(defun muse-import-docbook-get-title (node)
+ (let ((tit (car (xml-get-children node 'title))))
+ (insert (car (cddr tit)) ?\n ?\n)
+ (muse-import-xml-parse-tree (xml-node-children (remove tit node)))))
+
+
+(defun muse-import-docbook-article (node)
+ "Article conversion function"
+ (muse-import-xml-node node))
+
+(defun muse-import-docbook-articleinfo (node)
+ "Article conversion function"
+ (insert "#title ")
+ (muse-import-docbook-get-title node)
+ (insert ?\n))
+
+
+(defalias 'muse-import-docbook-appendix 'muse-import-docbook-article)
+
+(defalias 'muse-import-docbook-appendixinfo 'muse-import-docbook-articleinfo)
+
+
+(defun muse-import-docbook-sect1 (node)
+ "Section 1 conversion function"
+ (insert ?\n "* ")
+ (muse-import-docbook-get-title node))
+
+(defun muse-import-docbook-sect2 (node)
+ "Section 2 conversion function"
+ (insert ?\n "** ")
+ (muse-import-docbook-get-title node))
+
+(defun muse-import-docbook-sect3 (node)
+ "Section 3 conversion function"
+ (insert ?\n "*** ")
+ (muse-import-docbook-get-title node))
+
+
+(defun muse-import-docbook-graphic (node)
+ "Graphic conversion function. Image format is forced to PNG"
+ (let ((name (xml-get-attribute node 'fileref)))
+ (insert "\n[[img/" name ".png][" name "]]")))
+
+(defun muse-import-docbook-para (node)
+ (insert muse-import-docbook-para-indent)
+ (muse-import-xml-node node))
+
+
+(defun muse-import-docbook-emphasis (node)
+ (insert "*")
+ (muse-import-xml-node node)
+ (insert "*"))
+
+(defun muse-import-docbook-quote (node)
+ (insert "\"")
+ (muse-import-xml-node node)
+ (insert "\""))
+
+(defun muse-import-docbook-blockquote (node)
+ (setq muse-import-docbook-para-indent "\n\n ")
+ (muse-import-xml-node node)
+ (muse-import-docbook-reset-para-indent))
+
+(defun muse-import-docbook-member (node)
+ (insert "\n> ")
+ (muse-import-xml-node node))
+
+(defun muse-import-docbook-bridgehead (node)
+ (insert "\n* ")
+ (muse-import-xml-node node))
+
+(provide 'muse-import-docbook)
+
+;;; muse-import-docbook.el ends here
--- /dev/null
+;;; muse-import-latex.el --- convert a LaTex file into a Muse file
+
+;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Helper commands for converting a LaTeX file into a Muse file.
+
+;;; Contributors:
+
+;;; Code:
+
+(require 'muse)
+(require 'muse-regexps)
+
+(defun muse-i-l-write-citation (note author citation pages)
+ (save-excursion
+ (goto-char (point-max))
+ (if (= note 1)
+ (insert "\nFootnotes:\n\n"))
+ (let ((beg (point)))
+ (insert "\n[" (number-to-string note) "] " author)
+ (if (and citation pages)
+ (insert ", " citation ", " pages))
+ (insert "\n")
+ (goto-char beg)
+ (while (re-search-forward (concat "p.\\\\[" muse-regexp-blank "\n]+")
+ nil t)
+ (replace-match "p."))
+ (goto-char beg)
+ (while (re-search-forward "--" nil t)
+ (replace-match "-")))))
+
+(defun muse-i-l-write-footnote (note text)
+ (save-excursion
+ (goto-char (point-max))
+ (if (= note 1)
+ (insert "\nFootnotes:\n\n"))
+ (insert "\n[" (number-to-string note) "] " text ?\n)))
+
+;;;###autoload
+(defun muse-import-latex ()
+ (interactive)
+ (goto-char (point-min))
+ (while (not (eobp))
+ (cond
+ ((or (looking-at "^\\\\documentclass")
+ (looking-at "^\\\\input")
+ (looking-at "^\\\\begin{document}")
+ (looking-at "^\\\\end{document}")
+ (looking-at "^\\\\author")
+ (looking-at "^\\\\\\(med\\|big\\|small\\)skip")
+ (looking-at "^\\\\maketitle"))
+ (delete-region (point) (muse-line-end-position)))
+ ((looking-at "^\\\\title{\\(.+\\)}")
+ (delete-region (match-end 1) (muse-line-end-position))
+ (delete-region (point) (match-beginning 1))
+ (insert "#title ")))
+ (forward-line))
+ (goto-char (point-min))
+ (while (re-search-forward "\\\\\\(l\\)?dots{}" nil t)
+ (replace-match (concat (and (string= (match-string 1) "l") ".")
+ "...")))
+ (goto-char (point-min))
+ (while (re-search-forward "\\(``\\|''\\)" nil t)
+ (replace-match "\""))
+ (goto-char (point-min))
+ (while (re-search-forward "---" nil t)
+ (replace-match " -- "))
+ (goto-char (point-min))
+ (while (re-search-forward "\\\\tableofcontents" nil t)
+ (replace-match "<contents>"))
+ (goto-char (point-min))
+ (while (re-search-forward "\\\\\\\\" nil t)
+ (replace-match ""))
+ (goto-char (point-min))
+ (while (re-search-forward "\\\\\\(sub\\)?section{\\([^}]+\\)}" nil t)
+ (replace-match (concat (if (string= (match-string 1) "sub")
+ "**" "*")
+ " " (match-string 2))))
+ (goto-char (point-min))
+ (while (re-search-forward "\\\\\\(begin\\|end\\){verse}" nil t)
+ (replace-match (concat "<" (if (string= (match-string 1) "end") "/")
+ "verse>")))
+ (goto-char (point-min))
+ (while (re-search-forward "\\\\\\(begin\\|end\\){quote}\n" nil t)
+ (replace-match ""))
+ (goto-char (point-min))
+ (while (re-search-forward
+ "\\\\\\(emph\\|textbf\\){\\([^}]+?\\)\\(\\\\/\\)?}" nil t)
+ (replace-match
+ (if (string= (match-string 1) "emph") "*\\2*" "**\\2**")))
+ (let ((footnote-index 1))
+ (goto-char (point-min))
+ (while (re-search-forward
+ (concat "\\\\\\(q\\)?\\(footnote\\|excerpt\\)\\(np\\)?"
+ "\\({\\([^}]+\\)}\\)?"
+ "\\({\\([^}]+\\)}{\\([^}]+\\)}\\)?{\\([^}]+\\)}") nil t)
+ (let ((beg (match-beginning 0))
+ (end (match-end 0)))
+ (unless (string= (match-string 2) "footnote")
+ (if (null (match-string 1))
+ (insert " " (match-string 9))
+ (let ((b (point)) e)
+ (insert "\"" (match-string 9) "\"")
+ (setq e (point-marker))
+ (save-match-data
+ (save-excursion
+ (goto-char b)
+ (while (< (point) e)
+ (if (looking-at "\\s-+")
+ (delete-region (match-beginning 0)
+ (match-end 0)))
+ (forward-line))))
+ (set-marker e nil))))
+ (insert "[" (number-to-string footnote-index) "]")
+ (if (string= (match-string 2) "footnote")
+ (muse-i-l-write-footnote footnote-index (match-string 9))
+ (muse-i-l-write-citation footnote-index (match-string 5)
+ (match-string 7) (match-string 8)))
+ (setq footnote-index (1+ footnote-index))
+ (delete-region beg end))))
+ (goto-char (point-min))
+ (while (looking-at "\n") (delete-char 1))
+ (goto-char (point-min))
+ (while (re-search-forward "\n\n+" nil t)
+ (replace-match "\n\n")))
+
+(provide 'muse-import-latex)
+
+;;; muse-import-latex.el ends here
--- /dev/null
+;;; muse-import-xml.el --- common to all from-xml converters
+
+;; Copyright (C) 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; Author: Elena Pomohaci <e.pomohaci@gmail.com>
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Contributors:
+
+;;; Code:
+
+(provide 'muse-import-xml)
+
+(require 'xml)
+(require 'muse)
+
+(defvar muse-import-xml-prefix ""
+ "The name prefix for tag functions")
+
+(defvar muse-import-xml-generic-function-name "muse-import-xml-generic"
+ "The generic function name")
+
+(defun muse-import-xml-convert-to-list (buf)
+ "Convert xml BUF in a xml-list"
+ (with-temp-buffer
+ (insert-buffer-substring buf)
+ (goto-char (point-min))
+ (while (re-search-forward ">[ \n\t]*<" nil t)
+ (replace-match "><" nil nil)) ; clean all superfluous blank characters
+ (xml-parse-region (point-min)
+ (point-max)
+ (current-buffer))))
+
+
+(defun muse-import-xml-generic (node)
+ "The generic function called when there is no node specific function."
+ (let ((name (xml-node-name node)))
+ (insert "<" (symbol-name name) ">")
+ (muse-import-xml-node node)
+ (insert "</" (symbol-name name) ">")))
+
+(defun muse-import-xml-parse-tree (lst)
+ "Parse an xml tree list"
+ (mapc #'muse-import-xml-parse-node lst))
+
+(defun muse-import-xml-parse-node (node)
+ "Parse a xml tree node"
+ (if (stringp node)
+ (insert (muse-replace-regexp-in-string "^[ \t]+" "" node))
+ (let ((fname (intern-soft (concat muse-import-xml-prefix
+ (symbol-name (xml-node-name node))))))
+ (if (functionp fname)
+ (funcall fname node)
+ (funcall (intern muse-import-xml-generic-function-name) node)))))
+
+
+(defun muse-import-xml-node (node)
+ "Default node function"
+ (muse-import-xml-parse-tree (xml-node-children node)))
+
+
+(defun muse-import-xml (src dest)
+ "Convert the xml SRC buffer in a muse DEST buffer"
+ (set-buffer (get-buffer-create dest))
+ (when (fboundp 'muse-mode)
+ (muse-mode))
+ (muse-import-xml-parse-tree (muse-import-xml-convert-to-list src)))
+
+;;; muse-import-xml.el ends here
--- /dev/null
+;;; muse-ipc.el --- publish Muse documents from other processes
+
+;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file is still in alpha state. Not for production use!
+
+;;; Contributors:
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Muse Inter-Process Communication
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(eval-when-compile (require 'cl))
+
+(require 'muse)
+(require 'muse-publish)
+
+(defgroup muse-ipc nil
+ "Options controlling the behavior of Muse's IPC module."
+ :group 'muse-publish)
+
+(defcustom muse-ipc-timeout 60
+ "Maximum time to wait for a client to respond."
+ :group 'muse-ipc
+ :type 'number)
+
+(defcustom muse-ipc-ignore-done nil
+ "If non-nil, ignore any 'done' messages that we get from clients."
+ :group 'muse-ipc
+ :type 'boolean)
+
+(defvar muse-ipc-server-port nil
+ "Port of the Emacs server.")
+
+(defvar muse-ipc-server-process nil
+ "Process of the Emacs server.")
+
+(defvar muse-ipc-server-registered nil
+ "Whether we have successfully registered our port with the client.")
+
+(defun muse-ipc-init-filter (proc string)
+ "Handle data from client while initiating a connection."
+ (unless muse-ipc-server-registered
+ (when (string-match "\\`ok$" string)
+ (setq muse-ipc-server-registered t))))
+
+(defun muse-ipc-delete-client (proc)
+ "Delete a client."
+ (let ((buffer (process-get proc :buffer)))
+ (when (and buffer (buffer-live-p buffer))
+ (with-current-buffer buffer
+ (set-buffer-modified-p nil))
+ (kill-buffer buffer)))
+ (when (eq (process-status proc) 'open)
+ (delete-process proc)))
+
+(defun* muse-ipc-server-filter (proc string)
+ "Handle data from a client after it connects."
+ ;; Authenticate
+ (unless (process-get proc :authenticated)
+ (if (and (string-match "\\`begin \\(.+\\)$" string)
+ (equal (match-string 1 string)
+ (process-get proc :shared-secret)))
+ (progn
+ (setq string (substring string (match-end 0)))
+ (process-put proc :authenticated t)
+ (process-send-string proc "ok\n"))
+ (process-send-string proc "nok\n")
+ (delete-process proc))
+ (return-from muse-ipc-server-filter))
+
+ ;; Handle case where the client is sending data to be published
+ (when (process-get proc :sending-data)
+ (with-current-buffer (process-get proc :buffer)
+ (insert string)
+ (let ((buf-len (1- (point)))
+ (expected-len (process-get proc :data-bytes)))
+ (cond ((= buf-len expected-len)
+ (process-put proc :sending-data nil))
+ ((> buf-len expected-len)
+ (process-send-string proc "nok\n")
+ (muse-ipc-delete-client proc)))))
+ (return-from muse-ipc-server-filter))
+
+ ;; Dispatch commands
+ (cond
+ ((string-match "\\`done$" string)
+ ;; done, close the server
+ (unless muse-ipc-ignore-done
+ (muse-ipc-stop-server)))
+
+ ((string-match "\\`name \\(.+\\)$" string)
+ ;; set name
+ (process-put proc :file-name (match-string 1 string))
+ (process-send-string proc "ok\n"))
+
+ ((string-match "\\`title \\(.+\\)$" string)
+ ;; set title
+ (process-put proc :title (match-string 1 string))
+ (process-send-string proc "ok\n"))
+
+ (t
+ ;; unrecognized command
+ (process-send-string proc "nok\n"))))
+
+(defun muse-ipc-stop-server ()
+ "Stop Muse IPC server and reset connection data."
+ (stop-process muse-ipc-server-process)
+ (delete-process muse-ipc-server-process)
+ (setq muse-ipc-server-port nil)
+ (setq muse-ipc-server-process nil))
+
+(defun muse-ipc-start (shared-secret publish-fn client-port &optional server-port)
+ "Start an IPC connection and send a response to CLIENT-PORT.
+If SERVER-PORT is provided, start the IPC server on that port, otherwise
+choose a random port.
+
+SHARED-SECRET is used as a very minimal security measure to
+authenticate the Muse IPC server during initialization, and also
+any incoming clients once the server is started.
+
+PUBLISH-FN is the function which should be called in buffer of
+the received contents. It should transform the buffer into a
+published state. It must take at least two arguments. The first
+argument is the full path of the file that the contents
+correspond with. The second argument is the title to use when
+publishing the file."
+ (when (stringp client-port)
+ (setq client-port (string-to-number client-port)))
+ (when (stringp server-port)
+ (setq server-port (string-to-number server-port)))
+ (setq muse-ipc-server-process
+ (make-network-process
+ :name "muse-ipc"
+ :buffer nil
+ :host 'local :service (or server-port t)
+ :server t :noquery t :nowait t
+ :plist (list :authenticated nil :shared-secret shared-secret
+ :publish-fn publish-fn)
+ :filter 'muse-ipc-server-filter))
+ (unless muse-ipc-server-process
+ (error "Error: Could not start Muse IPC Server process"))
+ (set-process-coding-system muse-ipc-server-process
+ 'raw-text-unix 'raw-text-unix)
+ (setq muse-ipc-server-port
+ (number-to-string
+ (cadr (process-contact muse-ipc-server-process))))
+ (let ((client-proc
+ (make-network-process
+ :name "muse-ipc-client"
+ :buffer nil
+ :host 'local :service client-port
+ :noquery t
+ :filter 'muse-ipc-init-filter)))
+ (setq muse-ipc-server-registered nil)
+ (process-send-string client-proc
+ (concat "begin " shared-secret "\n"))
+ (accept-process-output client-proc muse-ipc-timeout nil t)
+ (unless muse-ipc-server-registered
+ (error "Error: Did not register listener"))
+ (process-send-string client-proc
+ (concat "port " muse-ipc-server-port "\n"))
+ (stop-process client-proc)
+ (delete-process client-proc))
+
+ ;; Accept process output until the server dies
+ (while muse-ipc-server-process (accept-process-output nil 1)))
+
+(provide 'muse-ipc)
+
+;;; muse-ipc.el ends here
--- /dev/null
+;;; muse-journal.el --- keep and publish a journal
+
+;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; The module facilitates the keeping and publication of a journal.
+;; When publishing to HTML, it assumes the form of a web log, or blog.
+;;
+;; The input format for each entry is as follows:
+;;
+;; * 20040317: Title of entry
+;;
+;; Text for the entry.
+;;
+;; <qotd>
+;; "You know who you are. It comes down to a simple gut check: You
+;; either love what you do or you don't. Period." -- P. Bronson
+;; </qotd>
+;;
+;; The "qotd", or Quote of the Day, is entirely optional. When
+;; generated to HTML, this entry is rendered as:
+;;
+;; <div class="entry">
+;; <div class="entry-qotd">
+;; <h3>Quote of the Day:</h3>
+;; <p>"You know who you are. It comes down to a simple gut
+;; check: You either love what you do or you don't. Period."
+;; -- P. Bronson</p>
+;; </div>
+;; <div class="entry-body">
+;; <div class="entry-head">
+;; <div class="entry-date">
+;; <span class="date">March 17, 2004</span>
+;; </div>
+;; <div class="entry-title">
+;; <h2>Title of entry</h2>
+;; </div>
+;; </div>
+;; <div class="entry-text">
+;; <p>Text for the entry.</p>
+;; </div>
+;; </div>
+;; </div>
+;;
+;; The plurality of "div" tags makes it possible to display the
+;; entries in any form you wish, using a CSS style.
+;;
+;; Also, an .RDF file can be generated from your journal by publishing
+;; it with the "rdf" style. It uses the first two sentences of the
+;; first paragraph of each entry as its "description", and
+;; autogenerates tags for linking to the various entries.
+
+;;; Contributors:
+
+;; René Stadler (mail AT renestadler DOT de) provided a patch that
+;; causes dates in RSS feeds to be generated in a format that RSS
+;; readers can parse.
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Muse Journal Publishing
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(require 'muse-publish)
+(require 'muse-html)
+(require 'muse-latex)
+(require 'muse-book)
+
+(defgroup muse-journal nil
+ "Rules for transforming a journal into its final form."
+ :group 'muse-publish)
+
+(defcustom muse-journal-heading-regexp
+ "\\(?:\\([0-9]+\\)\\(?:: \\)?\\)?\\(.+?\\)?"
+ "A regexp that matches a journal heading.
+Paren group 1 is the ISO date, group 2 is the optional category,
+and group 3 is the optional heading for the entry."
+ :type 'regexp
+ :group 'muse-journal)
+
+(defcustom muse-journal-date-format "%a, %e %b %Y"
+ "Date format to use for journal entries."
+ :type 'string
+ :group 'muse-journal)
+
+(defcustom muse-journal-html-heading-regexp
+ (concat "^<h2[^>\n]*>" muse-journal-heading-regexp "</h2>$")
+ "A regexp that matches a journal heading from an HTML document.
+Paren group 1 is the ISO date, group 2 is the optional category,
+and group 3 is the optional heading for the entry."
+ :type 'regexp
+ :group 'muse-journal)
+
+(defcustom muse-journal-rss-heading-regexp
+ (concat "^\\* " muse-journal-heading-regexp "$")
+ "A regexp that matches a journal heading from an HTML document.
+Paren group 1 is the ISO date, group 2 is the optional category,
+and group 3 is the optional heading for the entry."
+ :type 'regexp
+ :group 'muse-journal)
+
+(defcustom muse-journal-html-entry-template
+ "<div class=\"entry\">
+ <a name=\"%anchor%\" style=\"text-decoration: none\"> </a>
+ <div class=\"entry-body\">
+ <div class=\"entry-head\">
+ <div class=\"entry-date\">
+ <span class=\"date\">%date%</span>
+ </div>
+ <div class=\"entry-title\">
+ <h2>%title%</h2>
+ </div>
+ </div>
+ <div class=\"entry-text\">
+ <div class=\"entry-qotd\">
+ <p>%qotd%</p>
+ </div>
+%text%
+ </div>
+ </div>
+</div>\n\n"
+ "Template used to publish individual journal entries as HTML.
+This may be text or a filename."
+ :type 'string
+ :group 'muse-journal)
+
+(defcustom muse-journal-latex-section
+ "\\section*{%title% \\hfill {\\normalsize %date%}}
+\\addcontentsline{toc}{chapter}{%title%}"
+ "Template used to publish a LaTeX section."
+ :type 'string
+ :group 'muse-journal)
+
+(defcustom muse-journal-latex-subsection
+ "\\subsection*{%title%}
+\\addcontentsline{toc}{section}{%title%}"
+ "Template used to publish a LaTeX subsection."
+ :type 'string
+ :group 'muse-journal)
+
+(defcustom muse-journal-markup-tags
+ '(("qotd" t nil nil muse-journal-qotd-tag))
+ "A list of tag specifications, for specially marking up Journal entries.
+See `muse-publish-markup-tags' for more info.
+
+This is used by journal-latex and its related styles, as well as
+the journal-rss-entry style, which both journal-rdf and
+journal-rss use."
+ :type '(repeat (list (string :tag "Markup tag")
+ (boolean :tag "Expect closing tag" :value t)
+ (boolean :tag "Parse attributes" :value nil)
+ (boolean :tag "Nestable" :value nil)
+ function))
+ :group 'muse-journal)
+
+;; FIXME: This doesn't appear to be used.
+(defun muse-journal-generate-pages ()
+ (let ((output-dir (muse-style-element :path)))
+ (goto-char (point-min))
+ (while (re-search-forward muse-journal-heading-regexp nil t)
+ (let* ((date (match-string 1))
+ (category (match-string 1))
+ (category-file (concat output-dir category "/index.html"))
+ (heading (match-string 1)))
+ t))))
+
+(defcustom muse-journal-rdf-extension ".rdf"
+ "Default file extension for publishing RDF (RSS 1.0) files."
+ :type 'string
+ :group 'muse-journal)
+
+(defcustom muse-journal-rdf-base-url ""
+ "The base URL of the website referenced by the RDF file."
+ :type 'string
+ :group 'muse-journal)
+
+(defcustom muse-journal-rdf-header
+ "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"
+ xmlns=\"http://purl.org/rss/1.0/\"
+ xmlns:dc=\"http://purl.org/dc/elements/1.1/\">
+ <channel rdf:about=\"<lisp>(concat (muse-style-element :base-url)
+ (muse-publish-link-name))</lisp>\">
+ <title><lisp>(muse-publishing-directive \"title\")</lisp></title>
+ <link><lisp>(concat (muse-style-element :base-url)
+ (concat (muse-page-name)
+ muse-html-extension))</lisp></link>
+ <description><lisp>(muse-publishing-directive \"desc\")</lisp></description>
+ <items>
+ <rdf:Seq>
+ <rdf:li resource=\"<lisp>
+ (concat (muse-style-element :base-url)
+ (concat (muse-page-name)
+ muse-html-extension))</lisp>\"/>
+ </rdf:Seq>
+ </items>
+ </channel>\n"
+ "Header used for publishing RDF (RSS 1.0) files.
+This may be text or a filename."
+ :type 'string
+ :group 'muse-journal)
+
+(defcustom muse-journal-rdf-footer
+ "</rdf:RDF>\n"
+ "Footer used for publishing RDF (RSS 1.0) files.
+This may be text or a filename."
+ :type 'string
+ :group 'muse-journal)
+
+(defcustom muse-journal-rdf-date-format
+ "%Y-%m-%dT%H:%M:%S"
+ "Date format to use for RDF entries."
+ :type 'string
+ :group 'muse-journal)
+
+(defcustom muse-journal-rdf-entry-template
+ "\n <item rdf:about=\"%link%#%anchor%\">
+ <title>%title%</title>
+ <description>
+ %desc%
+ </description>
+ <link>%link%#%anchor%</link>
+ <dc:date>%date%</dc:date>
+ <dc:creator>%maintainer%</dc:creator>
+ </item>\n"
+ "Template used to publish individual journal entries as RDF.
+This may be text or a filename."
+ :type 'string
+ :group 'muse-journal)
+
+(defcustom muse-journal-rdf-summarize-entries nil
+ "If non-nil, include only summaries in the RDF file, not the full data.
+
+The default is nil, because this annoys some subscribers."
+ :type 'boolean
+ :group 'muse-journal)
+
+(defcustom muse-journal-rss-extension ".xml"
+ "Default file extension for publishing RSS 2.0 files."
+ :type 'string
+ :group 'muse-journal)
+
+(defcustom muse-journal-rss-base-url ""
+ "The base URL of the website referenced by the RSS file."
+ :type 'string
+ :group 'muse-journal)
+
+(defcustom muse-journal-rss-header
+ "<\?xml version=\"1.0\" encoding=\"<lisp>
+ (muse-html-encoding)</lisp>\"?>
+<rss version=\"2.0\">
+ <channel>
+ <title><lisp>(muse-publishing-directive \"title\")</lisp></title>
+ <link><lisp>(concat (muse-style-element :base-url)
+ (concat (muse-page-name)
+ muse-html-extension))</lisp></link>
+ <description><lisp>(muse-publishing-directive \"desc\")</lisp></description>
+ <language>en-us</language>
+ <generator>Emacs Muse</generator>\n\n"
+ "Header used for publishing RSS 2.0 files. This may be text or a filename."
+ :type 'string
+ :group 'muse-journal)
+
+(defcustom muse-journal-rss-footer
+ "\n\n </channel>
+</rss>\n"
+ "Footer used for publishing RSS 2.0 files. This may be text or a filename."
+ :type 'string
+ :group 'muse-journal)
+
+(defcustom muse-journal-rss-date-format
+ "%a, %d %b %Y %H:%M:%S %Z"
+ "Date format to use for RSS 2.0 entries."
+ :type 'string
+ :group 'muse-journal)
+
+(defcustom muse-journal-rss-entry-template
+ "\n <item>
+ <title>%title%</title>
+ <link>%link%#%anchor%</link>
+ <description>%desc%</description>
+ <author><lisp>(muse-publishing-directive \"author\")</lisp></author>
+ <pubDate>%date%</pubDate>
+ <guid>%link%#%anchor%</guid>
+ %enclosure%
+ </item>\n"
+ "Template used to publish individual journal entries as RSS 2.0.
+This may be text or a filename."
+ :type 'string
+ :group 'muse-journal)
+
+(defcustom muse-journal-rss-enclosure-types-alist
+ '(("mp3" . "audio/mpeg"))
+ "File types that are accepted as RSS enclosures.
+This is an alist that maps file extension to content type.
+Useful for podcasting."
+ :type '(alist :key-type string :value-type string)
+ :group 'muse-journal)
+
+(defcustom muse-journal-rss-summarize-entries nil
+ "If non-nil, include only summaries in the RSS file, not the full data.
+
+The default is nil, because this annoys some subscribers."
+ :type 'boolean
+ :group 'muse-journal)
+
+(defcustom muse-journal-rss-markup-regexps
+ '((10000 muse-explicit-link-regexp 0 "\\2"))
+ "List of markup rules for publishing a Muse journal page to RSS 2.0.
+For more information on the structure of this list, see
+`muse-publish-markup-regexps'."
+ :type '(repeat (choice
+ (list :tag "Markup rule"
+ integer
+ (choice regexp symbol)
+ integer
+ (choice string function symbol))
+ function))
+ :group 'muse-journal)
+
+(defcustom muse-journal-rss-markup-functions
+ '((email . ignore)
+ (link . ignore)
+ (url . ignore))
+ "An alist of style types to custom functions for that kind of text.
+For more on the structure of this list, see
+`muse-publish-markup-functions'."
+ :type '(alist :key-type symbol :value-type function)
+ :group 'muse-journal)
+
+(defun muse-journal-anchorize-title (title)
+ "This strips tags from TITLE, truncates TITLE at begin parenthesis,
+and escapes any remaining non-alphanumeric characters."
+ (save-match-data
+ (if (string-match "(" title)
+ (setq title (substring title 0 (match-beginning 0))))
+ (if (string-match "<[^>]+>" title)
+ (setq title (replace-match "" nil nil title)))
+ (let (pos code len ch)
+ (while (setq pos (string-match (concat "[^" muse-regexp-alnum "_]")
+ title pos))
+ (setq ch (aref title pos)
+ code (format "%%%02X" (cond ((fboundp 'char-to-ucs)
+ (char-to-ucs ch))
+ ((fboundp 'char-to-int)
+ (char-to-int ch))
+ (t ch)))
+ len (length code)
+ title (concat (substring title 0 pos)
+ code
+ (when (< pos (length title))
+ (substring title (1+ pos) nil)))
+ pos (+ len pos)))
+ title)))
+
+(defun muse-journal-sort-entries (&optional direction)
+ (interactive "P")
+ (sort-subr
+ direction
+ (function
+ (lambda ()
+ (if (re-search-forward "^\\* [0-9]+" nil t)
+ (goto-char (match-beginning 0))
+ (goto-char (point-max)))))
+ (function
+ (lambda ()
+ (if (re-search-forward "^\\* [0-9]+" nil t)
+ (goto-char (1- (match-beginning 0)))
+ (goto-char (point-max)))))
+ (function
+ (lambda ()
+ (forward-char 2)))
+ (function
+ (lambda ()
+ (end-of-line)))))
+
+(defun muse-journal-qotd-tag (beg end)
+ (muse-publish-ensure-block beg end)
+ (muse-insert-markup (muse-markup-text 'begin-quote))
+ (muse-insert-markup (muse-markup-text 'begin-quote-item))
+ (goto-char end)
+ (muse-insert-markup (muse-markup-text 'end-quote-item))
+ (muse-insert-markup (muse-markup-text 'end-quote)))
+
+(defun muse-journal-html-munge-buffer ()
+ (goto-char (point-min))
+ (let ((heading-regexp muse-journal-html-heading-regexp)
+ (inhibit-read-only t))
+ (while (re-search-forward heading-regexp nil t)
+ (let* ((date (match-string 1))
+ (orig-date date)
+ (title (match-string 2))
+ (clean-title title)
+ datestamp qotd text)
+ (delete-region (match-beginning 0) (match-end 0))
+ (if clean-title
+ (save-match-data
+ (while (string-match "\\(^<[^>]+>\\|<[^>]+>$\\)" clean-title)
+ (setq clean-title (replace-match "" nil nil clean-title)))))
+ (save-match-data
+ (when (and date
+ (string-match
+ (concat "\\`\\([1-9][0-9][0-9][0-9]\\)[./]?"
+ "\\([0-1][0-9]\\)[./]?\\([0-3][0-9]\\)") date))
+ (setq datestamp
+ (encode-time
+ 0 0 0
+ (string-to-number (match-string 3 date))
+ (string-to-number (match-string 2 date))
+ (string-to-number (match-string 1 date))
+ nil)
+ date (concat (format-time-string
+ muse-journal-date-format datestamp)
+ (substring date (match-end 0))))))
+ (save-restriction
+ (narrow-to-region
+ (point) (if (re-search-forward
+ (concat "\\(^<hr>$\\|"
+ heading-regexp "\\)") nil t)
+ (match-beginning 0)
+ (point-max)))
+ (goto-char (point-max))
+ (while (and (not (bobp))
+ (eq ?\ (char-syntax (char-before))))
+ (delete-char -1))
+ (goto-char (point-min))
+ (while (and (not (eobp))
+ (eq ?\ (char-syntax (char-after))))
+ (delete-char 1))
+ (save-excursion
+ (when (search-forward "<qotd>" nil t)
+ (let ((tag-beg (match-beginning 0))
+ (beg (match-end 0))
+ end)
+ (re-search-forward "</qotd>\n*")
+ (setq end (point-marker))
+ (save-restriction
+ (narrow-to-region beg (match-beginning 0))
+ (muse-publish-escape-specials (point-min) (point-max)
+ nil 'document)
+ (setq qotd (buffer-substring-no-properties
+ (point-min) (point-max))))
+ (delete-region tag-beg end)
+ (set-marker end nil))))
+ (setq text (buffer-string))
+ (delete-region (point-min) (point-max))
+ (let ((entry muse-journal-html-entry-template))
+ (muse-insert-file-or-string entry)
+ (muse-publish-mark-read-only (point-min) (point-max))
+ (goto-char (point-min))
+ (while (search-forward "%date%" nil t)
+ (remove-text-properties (match-beginning 0) (match-end 0)
+ '(read-only nil rear-nonsticky nil))
+ (replace-match (or date "") nil t))
+ (goto-char (point-min))
+ (while (search-forward "%title%" nil t)
+ (remove-text-properties (match-beginning 0) (match-end 0)
+ '(read-only nil rear-nonsticky nil))
+ (replace-match (or title " ") nil t))
+ (goto-char (point-min))
+ (while (search-forward "%anchor%" nil t)
+ (replace-match (muse-journal-anchorize-title
+ (or clean-title orig-date))
+ nil t))
+ (goto-char (point-min))
+ (while (search-forward "%qotd%" nil t)
+ (save-restriction
+ (narrow-to-region (match-beginning 0) (match-end 0))
+ (delete-region (point-min) (point-max))
+ (when qotd (muse-insert-markup qotd))))
+ (goto-char (point-min))
+ (while (search-forward "%text%" nil t)
+ (remove-text-properties (match-beginning 0) (match-end 0)
+ '(read-only nil rear-nonsticky nil))
+ (replace-match text nil t))
+ (when (null qotd)
+ (goto-char (point-min))
+ (when (search-forward "<div class=\"entry-qotd\">" nil t)
+ (let ((beg (match-beginning 0)))
+ (re-search-forward "</div>\n*" nil t)
+ (delete-region beg (point))))))))))
+ ;; indicate that we are to continue the :before-end processing
+ nil)
+
+(defun muse-journal-latex-munge-buffer ()
+ (goto-char (point-min))
+ (let ((heading-regexp
+ (concat "^" (regexp-quote (muse-markup-text 'section))
+ muse-journal-heading-regexp
+ (regexp-quote (muse-markup-text 'section-end)) "$"))
+ (inhibit-read-only t))
+ (when (re-search-forward heading-regexp nil t)
+ (goto-char (match-beginning 0))
+ (sort-subr nil
+ (function
+ (lambda ()
+ (if (re-search-forward heading-regexp nil t)
+ (goto-char (match-beginning 0))
+ (goto-char (point-max)))))
+ (function
+ (lambda ()
+ (if (re-search-forward heading-regexp nil t)
+ (goto-char (1- (match-beginning 0)))
+ (goto-char (point-max)))))
+ (function
+ (lambda ()
+ (forward-char 2)))
+ (function
+ (lambda ()
+ (end-of-line)))))
+ (while (re-search-forward heading-regexp nil t)
+ (let ((date (match-string 1))
+ (title (match-string 2))
+ ;; FIXME: Nothing is done with qotd
+ qotd section)
+ (save-match-data
+ (when (and date
+ (string-match
+ (concat "\\([1-9][0-9][0-9][0-9]\\)[./]?"
+ "\\([0-1][0-9]\\)[./]?\\([0-3][0-9]\\)") date))
+ (setq date (encode-time
+ 0 0 0
+ (string-to-number (match-string 3 date))
+ (string-to-number (match-string 2 date))
+ (string-to-number (match-string 1 date))
+ nil)
+ date (format-time-string
+ muse-journal-date-format date))))
+ (save-restriction
+ (narrow-to-region (match-beginning 0) (match-end 0))
+ (delete-region (point-min) (point-max))
+ (muse-insert-markup muse-journal-latex-section)
+ (goto-char (point-min))
+ (while (search-forward "%title%" nil t)
+ (replace-match (or title "Untitled") nil t))
+ (goto-char (point-min))
+ (while (search-forward "%date%" nil t)
+ (replace-match (or date "") nil t))))))
+ (goto-char (point-min))
+ (let ((subheading-regexp
+ (concat "^" (regexp-quote (muse-markup-text 'subsection))
+ "\\([^\n}]+\\)"
+ (regexp-quote (muse-markup-text 'subsection-end)) "$"))
+ (inhibit-read-only t))
+ (while (re-search-forward subheading-regexp nil t)
+ (let ((title (match-string 1)))
+ (save-restriction
+ (narrow-to-region (match-beginning 0) (match-end 0))
+ (delete-region (point-min) (point-max))
+ (muse-insert-markup muse-journal-latex-subsection)
+ (goto-char (point-min))
+ (while (search-forward "%title%" nil t)
+ (replace-match title nil t))))))
+ ;; indicate that we are to continue the :before-end processing
+ nil)
+
+(defun muse-journal-rss-munge-buffer ()
+ (goto-char (point-min))
+ (let ((heading-regexp muse-journal-rss-heading-regexp)
+ (inhibit-read-only t))
+ (while (re-search-forward heading-regexp nil t)
+ (let* ((date (match-string 1))
+ (orig-date date)
+ (title (match-string 2))
+ ;; FIXME: Nothing is done with qotd
+ enclosure qotd desc)
+ (if title
+ (save-match-data
+ (if (string-match muse-explicit-link-regexp title)
+ (setq enclosure (muse-get-link title)
+ title (muse-get-link-desc title)))))
+ (save-match-data
+ (when (and date
+ (string-match
+ (concat "\\([1-9][0-9][0-9][0-9]\\)[./]?"
+ "\\([0-1][0-9]\\)[./]?\\([0-3][0-9]\\)") date))
+ (setq date (encode-time 0 0 0
+ (string-to-number (match-string 3 date))
+ (string-to-number (match-string 2 date))
+ (string-to-number (match-string 1 date))
+ nil)
+ ;; make sure that date is in a format that RSS
+ ;; readers can handle
+ date (let ((system-time-locale "C"))
+ (format-time-string
+ (muse-style-element :date-format) date)))))
+ (save-restriction
+ (narrow-to-region
+ (match-beginning 0)
+ (if (re-search-forward heading-regexp nil t)
+ (match-beginning 0)
+ (if (re-search-forward "^Footnotes:" nil t)
+ (match-beginning 0)
+ (point-max))))
+ (goto-char (point-min))
+ (delete-region (point) (muse-line-end-position))
+ (re-search-forward "</qotd>\n+" nil t)
+ (while (and (char-after)
+ (eq ?\ (char-syntax (char-after))))
+ (delete-char 1))
+ (let ((beg (point)))
+ (if (muse-style-element :summarize)
+ (progn
+ (forward-sentence 2)
+ (setq desc (concat (buffer-substring beg (point)) "...")))
+ (save-restriction
+ (muse-publish-markup-buffer "rss-entry" "journal-rss-entry")
+ (goto-char (point-min))
+ (if (re-search-forward "Page published by Emacs Muse" nil t)
+ (goto-char (muse-line-end-position))
+ (muse-display-warning
+ (concat
+ "Cannot find 'Page published by Emacs Muse begins here'.\n"
+ "You will probably need this text in your header."))
+ (goto-char (point-min)))
+ (setq beg (point))
+ (if (re-search-forward "Page published by Emacs Muse" nil t)
+ (goto-char (muse-line-beginning-position))
+ (muse-display-warning
+ (concat
+ "Cannot find 'Page published by Emacs Muse ends here'.\n"
+ "You will probably need this text in your footer."))
+ (goto-char (point-max)))
+ (setq desc (buffer-substring beg (point))))))
+ (unless (string= desc "")
+ (setq desc (concat "<![CDATA[" desc "]]>")))
+ (delete-region (point-min) (point-max))
+ (let ((entry (muse-style-element :entry-template)))
+ (muse-insert-file-or-string entry)
+ (goto-char (point-min))
+ (while (search-forward "%date%" nil t)
+ (replace-match (or date "") nil t))
+ (goto-char (point-min))
+ (while (search-forward "%title%" nil t)
+ (replace-match "")
+ (save-restriction
+ (narrow-to-region (point) (point))
+ (insert (or title "Untitled"))
+ (remove-text-properties (match-beginning 0) (match-end 0)
+ '(read-only nil rear-nonsticky nil))
+ (let ((muse-publishing-current-style (muse-style "html")))
+ (muse-publish-escape-specials (point-min) (point-max)
+ nil 'document))))
+ (goto-char (point-min))
+ (while (search-forward "%desc%" nil t)
+ (replace-match desc nil t))
+ (goto-char (point-min))
+ (while (search-forward "%enclosure%" nil t)
+ (replace-match
+ (if (null enclosure)
+ ""
+ (save-match-data
+ (format
+ "<enclosure url=\"%s\" %stype=\"%s\"/>"
+ (if (string-match "//" enclosure)
+ enclosure
+ (concat (muse-style-element :base-url)
+ enclosure))
+ (let ((file
+ (expand-file-name enclosure
+ (muse-style-element :path))))
+ (if (file-readable-p file)
+ (format "length=\"%d\" "
+ (nth 7 (file-attributes file)))
+ ""))
+ (if (string-match "\\.\\([^.]+\\)$" enclosure)
+ (let* ((ext (match-string 1 enclosure))
+ (type
+ (assoc
+ ext muse-journal-rss-enclosure-types-alist)))
+ (if type
+ (cdr type)
+ "application/octet-stream"))))))
+ nil t))
+ (goto-char (point-min))
+ (while (search-forward "%link%" nil t)
+ (replace-match
+ (concat (muse-style-element :base-url)
+ (concat (muse-page-name)
+ muse-html-extension))
+ nil t))
+ (goto-char (point-min))
+ (while (search-forward "%anchor%" nil t)
+ (replace-match
+ (muse-journal-anchorize-title (or title orig-date))
+ nil t))
+ (goto-char (point-min))
+ (while (search-forward "%maintainer%" nil t)
+ (replace-match
+ (or (muse-style-element :maintainer)
+ (concat "webmaster@" (system-name)))
+ nil t)))))))
+ ;; indicate that we are to continue the :before-end processing
+ nil)
+
+
+;;; Register the Muse Journal Publishers
+
+(muse-derive-style "journal-html" "html"
+ :before-end 'muse-journal-html-munge-buffer)
+
+(muse-derive-style "journal-xhtml" "xhtml"
+ :before-end 'muse-journal-html-munge-buffer)
+
+(muse-derive-style "journal-latex" "latex"
+ :tags 'muse-journal-markup-tags
+ :before-end 'muse-journal-latex-munge-buffer)
+
+(muse-derive-style "journal-pdf" "pdf"
+ :tags 'muse-journal-markup-tags
+ :before-end 'muse-journal-latex-munge-buffer)
+
+(muse-derive-style "journal-book-latex" "book-latex"
+ ;;:nochapters
+ :tags 'muse-journal-markup-tags
+ :before-end 'muse-journal-latex-munge-buffer)
+
+(muse-derive-style "journal-book-pdf" "book-pdf"
+ ;;:nochapters
+ :tags 'muse-journal-markup-tags
+ :before-end 'muse-journal-latex-munge-buffer)
+
+(muse-define-style "journal-rdf"
+ :suffix 'muse-journal-rdf-extension
+ :regexps 'muse-journal-rss-markup-regexps
+ :functions 'muse-journal-rss-markup-functions
+ :before 'muse-journal-rss-munge-buffer
+ :header 'muse-journal-rdf-header
+ :footer 'muse-journal-rdf-footer
+ :date-format 'muse-journal-rdf-date-format
+ :entry-template 'muse-journal-rdf-entry-template
+ :base-url 'muse-journal-rdf-base-url
+ :summarize 'muse-journal-rdf-summarize-entries)
+
+(muse-define-style "journal-rss"
+ :suffix 'muse-journal-rss-extension
+ :regexps 'muse-journal-rss-markup-regexps
+ :functions 'muse-journal-rss-markup-functions
+ :before 'muse-journal-rss-munge-buffer
+ :header 'muse-journal-rss-header
+ :footer 'muse-journal-rss-footer
+ :date-format 'muse-journal-rss-date-format
+ :entry-template 'muse-journal-rss-entry-template
+ :base-url 'muse-journal-rss-base-url
+ :summarize 'muse-journal-rss-summarize-entries)
+
+;; Used by `muse-journal-rss-munge-buffer' to mark up individual entries
+(muse-derive-style "journal-rss-entry" "html"
+ :tags 'muse-journal-markup-tags)
+
+(provide 'muse-journal)
+
+;;; muse-journal.el ends here
--- /dev/null
+;;; muse-latex.el --- publish entries in LaTex or PDF format
+
+;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Contributors:
+
+;; Li Daobing (lidaobing AT gmail DOT com) provided CJK support.
+
+;; Trent Buck (trentbuck AT gmail DOT com) gave valuable advice for
+;; how to treat LaTeX specials and the like.
+
+;; Matthias Kegelmann (mathias DOT kegelmann AT sdm DOT de) provided a
+;; scenario where we would need to respect the <contents> tag.
+
+;; Jean Magnan de Bornier (jean AT bornier DOT net) provided the
+;; markup string for link-and-anchor.
+
+;; Jim Ottaway (j DOT ottaway AT lse DOT ac DOT uk) implemented slides
+;; and lecture notes.
+
+;; Karl Berry (karl AT freefriends DOT org) suggested how to escape
+;; additional special characters in image filenames.
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Muse LaTeX Publishing
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(require 'muse-publish)
+
+(defgroup muse-latex nil
+ "Rules for marking up a Muse file as a LaTeX article."
+ :group 'muse-publish)
+
+(defcustom muse-latex-extension ".tex"
+ "Default file extension for publishing LaTeX files."
+ :type 'string
+ :group 'muse-latex)
+
+(defcustom muse-latex-pdf-extension ".pdf"
+ "Default file extension for publishing LaTeX files to PDF."
+ :type 'string
+ :group 'muse-latex)
+
+(defcustom muse-latex-pdf-browser "open %s"
+ "The program to use when browsing a published PDF file.
+This should be a format string."
+ :type 'string
+ :group 'muse-latex)
+
+(defcustom muse-latex-pdf-program "pdflatex"
+ "The program that is called to generate PDF content from LaTeX content."
+ :type 'string
+ :group 'muse-latex)
+
+(defcustom muse-latex-pdf-cruft
+ '(".aux" ".log" ".nav" ".out" ".snm" ".toc" ".vrb")
+ "Extensions of files to remove after generating PDF output successfully."
+ :type 'string
+ :group 'muse-latex)
+
+(defcustom muse-latex-header
+ "\\documentclass{article}
+
+\\usepackage[english]{babel}
+\\usepackage{ucs}
+\\usepackage[utf8x]{inputenc}
+\\usepackage[T1]{fontenc}
+\\usepackage{hyperref}
+\\usepackage[pdftex]{graphicx}
+
+\\def\\museincludegraphics{%
+ \\begingroup
+ \\catcode`\\|=0
+ \\catcode`\\\\=12
+ \\catcode`\\#=12
+ \\includegraphics[width=0.75\\textwidth]
+}
+
+\\begin{document}
+
+\\title{<lisp>(muse-publish-escape-specials-in-string
+ (muse-publishing-directive \"title\") 'document)</lisp>}
+\\author{<lisp>(muse-publishing-directive \"author\")</lisp>}
+\\date{<lisp>(muse-publishing-directive \"date\")</lisp>}
+
+\\maketitle
+
+<lisp>(and muse-publish-generate-contents
+ (not muse-latex-permit-contents-tag)
+ \"\\\\tableofcontents\n\\\\newpage\")</lisp>\n\n"
+ "Header used for publishing LaTeX files. This may be text or a filename."
+ :type 'string
+ :group 'muse-latex)
+
+(defcustom muse-latex-footer "<lisp>(muse-latex-bibliography)</lisp>
+\\end{document}\n"
+ "Footer used for publishing LaTeX files. This may be text or a filename."
+ :type 'string
+ :group 'muse-latex)
+
+(defcustom muse-latexcjk-header
+ "\\documentclass{article}
+
+\\usepackage{CJK}
+\\usepackage{indentfirst}
+\\usepackage[CJKbookmarks=true]{hyperref}
+\\usepackage[pdftex]{graphicx}
+
+\\begin{document}
+\\begin{CJK*}<lisp>(muse-latexcjk-encoding)</lisp>
+
+\\title{<lisp>(muse-publish-escape-specials-in-string
+ (muse-publishing-directive \"title\") 'document)</lisp>}
+\\author{<lisp>(muse-publishing-directive \"author\")</lisp>}
+\\date{<lisp>(muse-publishing-directive \"date\")</lisp>}
+
+\\maketitle
+
+<lisp>(and muse-publish-generate-contents
+ (not muse-latex-permit-contents-tag)
+ \"\\\\tableofcontents\n\\\\newpage\")</lisp>\n\n"
+ "Header used for publishing LaTeX files (CJK). This may be text or a
+filename."
+ :type 'string
+ :group 'muse-latex)
+
+(defcustom muse-latexcjk-footer
+ "\n\\end{CJK*}
+\\end{document}\n"
+ "Footer used for publishing LaTeX files (CJK). This may be text or a
+filename."
+ :type 'string
+ :group 'muse-latex)
+
+(defcustom muse-latex-slides-header
+ "\\documentclass[ignorenonframetext]{beamer}
+
+\\usepackage[english]{babel}
+\\usepackage{ucs}
+\\usepackage[utf8x]{inputenc}
+\\usepackage[T1]{fontenc}
+\\usepackage{hyperref}
+
+\\def\\museincludegraphics{%
+ \\begingroup
+ \\catcode`\\|=0
+ \\catcode`\\\\=12
+ \\catcode`\\#=12
+ \\includegraphics[width=0.50\\textwidth]
+}
+
+\\title{<lisp>(muse-publish-escape-specials-in-string
+ (muse-publishing-directive \"title\") 'document)</lisp>}
+\\author{<lisp>(muse-publishing-directive \"author\")</lisp>}
+\\date{<lisp>(muse-publishing-directive \"date\")</lisp>}
+
+\\begin{document}
+
+\\frame{\\titlepage}
+
+<lisp>(and muse-publish-generate-contents
+ \"\\\\frame{\\\\tableofcontents}\")</lisp>\n\n"
+ "Header for publishing of slides using LaTeX.
+This may be text or a filename.
+
+You must have the Beamer extension for LaTeX installed for this to work."
+ :type 'string
+ :group 'muse-latex)
+
+(defcustom muse-latex-lecture-notes-header
+ "\\documentclass{article}
+\\usepackage{beamerarticle}
+
+\\usepackage[english]{babel}
+\\usepackage{ucs}
+\\usepackage[utf8x]{inputenc}
+\\usepackage[T1]{fontenc}
+\\usepackage{hyperref}
+\\usepackage[pdftex]{graphicx}
+
+\\def\\museincludegraphics{%
+ \\begingroup
+ \\catcode`\\|=0
+ \\catcode`\\\\=12
+ \\catcode`\\#=12
+ \\includegraphics[width=0.50\\textwidth]
+}
+
+\\title{<lisp>(muse-publish-escape-specials-in-string
+ (muse-publishing-directive \"title\") 'document)</lisp>}
+\\author{<lisp>(muse-publishing-directive \"author\")</lisp>}
+\\date{<lisp>(muse-publishing-directive \"date\")</lisp>}
+
+\\begin{document}
+
+\\frame{\\titlepage}
+
+<lisp>(and muse-publish-generate-contents
+ \"\\\\frame{\\\\tableofcontents}\")</lisp>\n\n"
+ "Header for publishing of lecture notes using LaTeX.
+This may be text or a filename.
+
+You must have the Beamer extension for LaTeX installed for this to work."
+ :type 'string
+ :group 'muse-latex)
+
+(defcustom muse-latex-markup-regexps
+ `(;; numeric ranges
+ (10000 "\\([0-9]+\\)-\\([0-9]+\\)" 0 "\\1--\\2")
+
+ ;; be careful of closing quote pairs
+ (10100 "\"'" 0 "\"\\\\-'"))
+ "List of markup regexps for identifying regions in a Muse page.
+For more on the structure of this list, see `muse-publish-markup-regexps'."
+ :type '(repeat (choice
+ (list :tag "Markup rule"
+ integer
+ (choice regexp symbol)
+ integer
+ (choice string function symbol))
+ function))
+ :group 'muse-latex)
+
+(defcustom muse-latex-markup-functions
+ '((table . muse-latex-markup-table))
+ "An alist of style types to custom functions for that kind of text.
+For more on the structure of this list, see
+`muse-publish-markup-functions'."
+ :type '(alist :key-type symbol :value-type function)
+ :group 'muse-latex)
+
+(defcustom muse-latex-markup-strings
+ '((image-with-desc . "\\begin{figure}[h]
+\\centering\\museincludegraphics{%s.%s}|endgroup
+\\caption{%s}
+\\end{figure}")
+ (image . "\\begin{figure}[h]
+\\centering\\museincludegraphics{%s.%s}|endgroup
+\\end{figure}")
+ (image-link . "%% %s
+\\museincludegraphics{%s.%s}|endgroup")
+ (anchor-ref . "\\ref{%s}")
+ (url . "\\url{%s}")
+ (url-and-desc . "\\href{%s}{%s}\\footnote{%1%}")
+ (link . "\\href{%s}{%s}\\footnote{%1%}")
+ (link-and-anchor . "\\href{%1%}{%3%}\\footnote{%1%}")
+ (email-addr . "\\verb|%s|")
+ (anchor . "\\label{%s}")
+ (emdash . "---")
+ (comment-begin . "% ")
+ (rule . "\\vspace{.5cm}\\hrule\\vspace{.5cm}")
+ (no-break-space . "~")
+ (line-break . "\\\\")
+ (enddots . "\\ldots{}")
+ (dots . "\\dots{}")
+ (part . "\\part{")
+ (part-end . "}")
+ (chapter . "\\chapter{")
+ (chapter-end . "}")
+ (section . "\\section{")
+ (section-end . "}")
+ (subsection . "\\subsection{")
+ (subsection-end . "}")
+ (subsubsection . "\\subsubsection{")
+ (subsubsection-end . "}")
+ (section-other . "\\paragraph{")
+ (section-other-end . "}")
+ (footnote . "\\footnote{")
+ (footnote-end . "}")
+ (footnotetext . "\\footnotetext[%d]{")
+ (begin-underline . "\\underline{")
+ (end-underline . "}")
+ (begin-literal . "\\texttt{")
+ (end-literal . "}")
+ (begin-emph . "\\emph{")
+ (end-emph . "}")
+ (begin-more-emph . "\\textbf{")
+ (end-more-emph . "}")
+ (begin-most-emph . "\\textbf{\\emph{")
+ (end-most-emph . "}}")
+ (begin-verse . "\\begin{verse}\n")
+ (end-verse-line . " \\\\")
+ (verse-space . "~~~~")
+ (end-verse . "\n\\end{verse}")
+ (begin-example . "\\begin{quote}\n\\begin{verbatim}")
+ (end-example . "\\end{verbatim}\n\\end{quote}")
+ (begin-center . "\\begin{center}\n")
+ (end-center . "\n\\end{center}")
+ (begin-quote . "\\begin{quote}\n")
+ (end-quote . "\n\\end{quote}")
+ (begin-cite . "\\cite{")
+ (begin-cite-author . "\\citet{")
+ (begin-cite-year . "\\citet{")
+ (end-cite . "}")
+ (begin-uli . "\\begin{itemize}\n")
+ (end-uli . "\n\\end{itemize}")
+ (begin-uli-item . "\\item ")
+ (begin-oli . "\\begin{enumerate}\n")
+ (end-oli . "\n\\end{enumerate}")
+ (begin-oli-item . "\\item ")
+ (begin-dl . "\\begin{description}\n")
+ (end-dl . "\n\\end{description}")
+ (begin-ddt . "\\item[")
+ (end-ddt . "] \\mbox{}\n"))
+ "Strings used for marking up text.
+These cover the most basic kinds of markup, the handling of which
+differs little between the various styles."
+ :type '(alist :key-type symbol :value-type string)
+ :group 'muse-latex)
+
+(defcustom muse-latex-slides-markup-tags
+ '(("slide" t t nil muse-latex-slide-tag))
+ "A list of tag specifications, for specially marking up LaTeX slides."
+ :type '(repeat (list (string :tag "Markup tag")
+ (boolean :tag "Expect closing tag" :value t)
+ (boolean :tag "Parse attributes" :value nil)
+ (boolean :tag "Nestable" :value nil)
+ function))
+ :group 'muse-latex)
+
+(defcustom muse-latexcjk-encoding-map
+ '((utf-8 . "{UTF8}{song}")
+ (japanese-iso-8bit . "[dnp]{JIS}{min}")
+ (chinese-big5 . "{Bg5}{bsmi}")
+ (mule-utf-8 . "{UTF8}{song}")
+ (chinese-iso-8bit . "{GB}{song}")
+ (chinese-gbk . "{GBK}{song}"))
+ "An alist mapping emacs coding systems to appropriate CJK codings.
+Use the base name of the coding system (ie, without the -unix)."
+ :type '(alist :key-type coding-system :value-type string)
+ :group 'muse-latex)
+
+(defcustom muse-latexcjk-encoding-default "{GB}{song}"
+ "The default Emacs buffer encoding to use in published files.
+This will be used if no special characters are found."
+ :type 'string
+ :group 'muse-latex)
+
+(defun muse-latexcjk-encoding ()
+ (when (boundp 'buffer-file-coding-system)
+ (muse-latexcjk-transform-content-type buffer-file-coding-system)))
+
+(defun muse-latexcjk-transform-content-type (content-type)
+ "Using `muse-cjklatex-encoding-map', try and resolve an emacs coding
+system to an associated CJK coding system."
+ (let ((match (and (fboundp 'coding-system-base)
+ (assoc (coding-system-base content-type)
+ muse-latexcjk-encoding-map))))
+ (if match
+ (cdr match)
+ muse-latexcjk-encoding-default)))
+
+(defcustom muse-latex-markup-specials-document
+ '((?\\ . "\\textbackslash{}")
+ (?\_ . "\\textunderscore{}")
+ (?\< . "\\textless{}")
+ (?\> . "\\textgreater{}")
+ (?^ . "\\^{}")
+ (?\~ . "\\~{}")
+ (?\@ . "\\@")
+ (?\$ . "\\$")
+ (?\% . "\\%")
+ (?\{ . "\\{")
+ (?\} . "\\}")
+ (?\& . "\\&")
+ (?\# . "\\#"))
+ "A table of characters which must be represented specially.
+These are applied to the entire document, sans already-escaped
+regions."
+ :type '(alist :key-type character :value-type string)
+ :group 'muse-latex)
+
+(defcustom muse-latex-markup-specials-example
+ '()
+ "A table of characters which must be represented specially.
+These are applied to <example> regions.
+
+With the default interpretation of <example> regions, no specials
+need to be escaped."
+ :type '(alist :key-type character :value-type string)
+ :group 'muse-latex)
+
+(defcustom muse-latex-markup-specials-literal
+ '((?\n . "\\\n")
+ (?\\ . "\\textbackslash{}")
+ (?_ . "\\textunderscore{}")
+ (?\< . "\\textless{}")
+ (?\> . "\\textgreater{}")
+ (?^ . "\\^{}")
+ (?\~ . "\\~{}")
+ (?\$ . "\\$")
+ (?\% . "\\%")
+ (?\{ . "\\{")
+ (?\} . "\\}")
+ (?\& . "\\&")
+ (?\# . "\\#"))
+ "A table of characters which must be represented specially.
+This applies to =monospaced text= and <code> regions."
+ :type '(alist :key-type character :value-type string)
+ :group 'muse-latex)
+
+(defcustom muse-latex-markup-specials-url
+ '((?\\ . "\\textbackslash{}")
+ (?\_ . "\\_")
+ (?\< . "\\<")
+ (?\> . "\\>")
+ (?\$ . "\\$")
+ (?\% . "\\%")
+ (?\{ . "\\{")
+ (?\} . "\\}")
+ (?\& . "\\&")
+ (?\# . "\\#"))
+ "A table of characters which must be represented specially.
+These are applied to URLs."
+ :type '(alist :key-type character :value-type string)
+ :group 'muse-latex)
+
+(defcustom muse-latex-markup-specials-image
+ '((?\\ . "\\\\")
+ (?\< . "\\<")
+ (?\> . "\\>")
+ (?\$ . "\\$")
+ (?\% . "\\%")
+ (?\{ . "\\{")
+ (?\} . "\\}")
+ (?\& . "\\&")
+ (?\# . "\\#")
+ (?\| . "\\|"))
+ "A table of characters which must be represented specially.
+These are applied to image filenames."
+ :type '(alist :key-type character :value-type string)
+ :group 'muse-latex)
+
+(defun muse-latex-decide-specials (context)
+ "Determine the specials to escape, depending on CONTEXT."
+ (cond ((memq context '(underline emphasis document url-desc verbatim
+ footnote))
+ muse-latex-markup-specials-document)
+ ((eq context 'image)
+ muse-latex-markup-specials-image)
+ ((memq context '(email url))
+ muse-latex-markup-specials-url)
+ ((eq context 'literal)
+ muse-latex-markup-specials-literal)
+ ((eq context 'example)
+ muse-latex-markup-specials-example)
+ (t (error "Invalid context '%s' in muse-latex" context))))
+
+(defcustom muse-latex-permit-contents-tag nil
+ "If nil, ignore <contents> tags. Otherwise, insert table of contents.
+
+Most of the time, it is best to have a table of contents on the
+first page, with a new page immediately following. To make this
+work with documents published in both HTML and LaTeX, we need to
+ignore the <contents> tag.
+
+If you don't agree with this, then set this option to non-nil,
+and it will do what you expect."
+ :type 'boolean
+ :group 'muse-latex)
+
+(defun muse-latex-markup-table ()
+ (let* ((table-info (muse-publish-table-fields (match-beginning 0)
+ (match-end 0)))
+ (row-len (car table-info))
+ (field-list (cdr table-info)))
+ (when table-info
+ (muse-insert-markup "\\begin{tabular}{" (make-string row-len ?l) "}\n")
+ (dolist (fields field-list)
+ (let ((type (car fields)))
+ (setq fields (cdr fields))
+ (if (eq type 'hline)
+ (muse-insert-markup "\\hline\n")
+ (when (= type 3)
+ (muse-insert-markup "\\hline\n"))
+ (insert (car fields))
+ (setq fields (cdr fields))
+ (dolist (field fields)
+ (muse-insert-markup " & ")
+ (insert field))
+ (muse-insert-markup " \\\\\n")
+ (when (= type 2)
+ (muse-insert-markup "\\hline\n")))))
+ (muse-insert-markup "\\end{tabular}"))))
+
+;;; Tags for LaTeX
+
+(defun muse-latex-slide-tag (beg end attrs)
+ "Publish the <slide> tag in LaTeX.
+This is used by the slides and lecture-notes publishing styles."
+ (let ((title (cdr (assoc "title" attrs))))
+ (goto-char beg)
+ (muse-insert-markup "\\begin{frame}[fragile]\n")
+ (when title
+ (muse-insert-markup "\\frametitle{")
+ (insert title)
+ (muse-insert-markup "}\n"))
+ (save-excursion
+ (goto-char end)
+ (muse-insert-markup "\n\\end{frame}"))))
+
+;;; Post-publishing functions
+
+(defun muse-latex-fixup-dquotes ()
+ "Fixup double quotes."
+ (goto-char (point-min))
+ (let ((open t))
+ (while (search-forward "\"" nil t)
+ (unless (get-text-property (match-beginning 0) 'read-only)
+ (when (or (bobp)
+ (eq (char-before) ?\n))
+ (setq open t))
+ (if open
+ (progn
+ (replace-match "``")
+ (setq open nil))
+ (replace-match "''")
+ (setq open t))))))
+
+(defun muse-latex-fixup-citations ()
+ "Replace semicolons in multi-head citations with colons."
+ (goto-char (point-min))
+ (while (re-search-forward "\\\\cite.?{" nil t)
+ (let ((start (point))
+ (end (re-search-forward "}")))
+ (save-restriction
+ (narrow-to-region start end)
+ (goto-char (point-min))
+ (while (re-search-forward ";" nil t)
+ (replace-match ","))))))
+
+(defun muse-latex-fixup-headings ()
+ "Remove footnotes in headings, since LaTeX does not permit them to exist.
+
+This can happen if there is a link in a heading, because by
+default Muse will add a footnote for each link."
+ (goto-char (point-min))
+ (while (re-search-forward "^\\\\section.?{" nil t)
+ (save-restriction
+ (narrow-to-region (match-beginning 0) (muse-line-end-position))
+ (goto-char (point-min))
+ (while (re-search-forward "\\\\footnote{[^}\n]+}" nil t)
+ (replace-match ""))
+ (forward-line 1))))
+
+(defun muse-latex-munge-buffer ()
+ (muse-latex-fixup-dquotes)
+ (muse-latex-fixup-citations)
+ (muse-latex-fixup-headings)
+ (when (and muse-latex-permit-contents-tag
+ muse-publish-generate-contents)
+ (goto-char (car muse-publish-generate-contents))
+ (muse-insert-markup "\\tableofcontents")))
+
+(defun muse-latex-bibliography ()
+ (save-excursion
+ (goto-char (point-min))
+ (if (re-search-forward "\\\\cite.?{" nil t)
+ (concat
+ "\\bibliography{"
+ (muse-publishing-directive "bibsource")
+ "}\n")
+ "")))
+
+(defun muse-latex-pdf-browse-file (file)
+ (shell-command (format muse-latex-pdf-browser file)))
+
+(defun muse-latex-pdf-generate (file output-path final-target)
+ (apply
+ #'muse-publish-transform-output
+ file output-path final-target "PDF"
+ (function
+ (lambda (file output-path)
+ (let* ((fnd (file-name-directory output-path))
+ (command (format "%s \"%s\""
+ muse-latex-pdf-program
+ (file-relative-name file fnd)))
+ (times 0)
+ (default-directory fnd)
+ result)
+ ;; XEmacs can sometimes return a non-number result. We'll err
+ ;; on the side of caution by continuing to attempt to generate
+ ;; the PDF if this happens and treat the final result as
+ ;; successful.
+ (while (and (< times 2)
+ (or (not (numberp result))
+ (not (eq result 0))
+ ;; table of contents takes 2 passes
+ (file-readable-p
+ (muse-replace-regexp-in-string
+ "\\.tex\\'" ".toc" file t t))))
+ (setq result (shell-command command)
+ times (1+ times)))
+ (if (or (not (numberp result))
+ (eq result 0))
+ t
+ nil))))
+ muse-latex-pdf-cruft))
+
+;;; Register the Muse LATEX Publishers
+
+(muse-define-style "latex"
+ :suffix 'muse-latex-extension
+ :regexps 'muse-latex-markup-regexps
+ :functions 'muse-latex-markup-functions
+ :strings 'muse-latex-markup-strings
+ :specials 'muse-latex-decide-specials
+ :before-end 'muse-latex-munge-buffer
+ :header 'muse-latex-header
+ :footer 'muse-latex-footer
+ :browser 'find-file)
+
+(muse-derive-style "pdf" "latex"
+ :final 'muse-latex-pdf-generate
+ :browser 'muse-latex-pdf-browse-file
+ :link-suffix 'muse-latex-pdf-extension
+ :osuffix 'muse-latex-pdf-extension)
+
+(muse-derive-style "latexcjk" "latex"
+ :header 'muse-latexcjk-header
+ :footer 'muse-latexcjk-footer)
+
+(muse-derive-style "pdfcjk" "latexcjk"
+ :final 'muse-latex-pdf-generate
+ :browser 'muse-latex-pdf-browse-file
+ :link-suffix 'muse-latex-pdf-extension
+ :osuffix 'muse-latex-pdf-extension)
+
+(muse-derive-style "slides" "latex"
+ :header 'muse-latex-slides-header
+ :tags 'muse-latex-slides-markup-tags)
+
+(muse-derive-style "slides-pdf" "pdf"
+ :header 'muse-latex-slides-header
+ :tags 'muse-latex-slides-markup-tags)
+
+(muse-derive-style "lecture-notes" "slides"
+ :header 'muse-latex-lecture-notes-header)
+
+(muse-derive-style "lecture-notes-pdf" "slides-pdf"
+ :header 'muse-latex-lecture-notes-header)
+
+(provide 'muse-latex)
+
+;;; muse-latex.el ends here
--- /dev/null
+;; muse-latex2png.el --- generate PNG images from inline LaTeX code
+
+;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; Author: Michael Olson <mwolson@gnu.org>
+;; Created: 12-Oct-2005
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This was taken from latex2png.el, by Ganesh Swami <ganesh AT
+;; iamganesh DOT com>, which was made for emacs-wiki. It has since
+;; been extensively rewritten for Muse.
+
+;;; To do
+
+;; Remove stale image files. This could be done by making a function
+;; for `muse-before-publish-hook' that deletes according to
+;; (muse-page-name).
+
+;;; Code
+
+(require 'muse-publish)
+
+(defgroup muse-latex2png nil
+ "Publishing LaTeX formulas as PNG files."
+ :group 'muse-publish)
+
+(defcustom muse-latex2png-img-dest "./latex"
+ "The folder where the generated images will be placed.
+This is relative to the current publishing directory."
+ :type 'string
+ :group 'muse-latex2png)
+
+(defcustom muse-latex2png-scale-factor 2.5
+ "The scale factor to be used for sizing the resulting LaTeX output."
+ :type 'number
+ :group 'muse-latex2png)
+
+(defcustom muse-latex2png-fg "Black"
+ "The foreground color."
+ :type 'string
+ :group 'muse-latex2png)
+
+(defcustom muse-latex2png-bg "Transparent"
+ "The background color."
+ :type 'string
+ :group 'muse-latex2png)
+
+(defcustom muse-latex2png-template
+ "\\documentclass{article}
+\\usepackage{fullpage}
+\\usepackage{amssymb}
+\\usepackage[usenames]{color}
+\\usepackage{amsmath}
+\\usepackage{latexsym}
+\\usepackage[mathscr]{eucal}
+%preamble%
+\\pagestyle{empty}
+\\begin{document}
+{%code%}
+\\end{document}\n"
+ "The LaTeX template to use."
+ :type 'string
+ :group 'muse-latex2png)
+
+(defun muse-latex2png-move2pubdir (file prefix pubdir)
+ "Move FILE to the PUBDIR folder.
+
+This is done so that the resulting images do not clutter your
+main publishing directory.
+
+Old files with PREFIX in the name are deleted."
+ (when file
+ (if (file-exists-p file)
+ (progn
+ (unless (file-directory-p pubdir)
+ (message "Creating latex directory %s" pubdir)
+ (make-directory pubdir))
+ (copy-file file (expand-file-name (file-name-nondirectory file)
+ pubdir)
+ t)
+ (delete-file file)
+ (concat muse-latex2png-img-dest "/" (file-name-nondirectory file)))
+ (message "Cannot find %s!" file))))
+
+(defun muse-latex2png (code prefix preamble)
+ "Convert the LaTeX CODE into a png file beginning with PREFIX.
+PREAMBLE indicates extra packages and definitions to include."
+ (unless preamble
+ (setq preamble ""))
+ (unless prefix
+ (setq prefix "muse-latex2png"))
+ (let* ((tmpdir (cond ((boundp 'temporary-file-directory)
+ temporary-file-directory)
+ ((fboundp 'temp-directory)
+ (temp-directory))
+ (t "/tmp")))
+ (texfile (expand-file-name
+ (concat prefix "__" (format "%d" (abs (sxhash code))))
+ tmpdir))
+ (defalt-directory default-directory))
+ (with-temp-file (concat texfile ".tex")
+ (insert muse-latex2png-template)
+ (goto-char (point-min))
+ (while (search-forward "%preamble%" nil t)
+ (replace-match preamble nil t))
+ (goto-char (point-min))
+ (while (search-forward "%code%" nil t)
+ (replace-match code nil t)))
+ (setq default-directory tmpdir)
+ (call-process "latex" nil nil nil texfile)
+ (if (file-exists-p (concat texfile ".dvi"))
+ (progn
+ (call-process
+ "dvipng" nil nil nil
+ "-E"
+ "-fg" muse-latex2png-fg
+ "-bg" muse-latex2png-bg
+ "-T" "tight"
+ "-x" (format "%s" (* muse-latex2png-scale-factor 1000))
+ "-y" (format "%s" (* muse-latex2png-scale-factor 1000))
+ "-o" (concat texfile ".png")
+ (concat texfile ".dvi"))
+ (if (file-exists-p (concat texfile ".png"))
+ (progn
+ (delete-file (concat texfile ".dvi"))
+ (delete-file (concat texfile ".tex"))
+ (delete-file (concat texfile ".aux"))
+ (delete-file (concat texfile ".log"))
+ (concat texfile ".png"))
+ (message "Failed to create png file")
+ nil))
+ (message (concat "Failed to create dvi file " texfile))
+ nil)))
+
+(defun muse-latex2png-region (beg end attrs)
+ "Generate an image for the Latex code between BEG and END.
+If a Muse page is currently being published, replace the given
+region with the appropriate markup that displays the image.
+Otherwise, just return the path of the generated image.
+
+Valid keys for the ATTRS alist are as follows.
+
+prefix: The prefix given to the image file.
+preamble: Extra text to add to the Latex preamble.
+inline: Display image as inline, instead of a block."
+ (let ((end-marker (set-marker (make-marker) (1+ end)))
+ (pubdir (expand-file-name
+ muse-latex2png-img-dest
+ (file-name-directory muse-publishing-current-output-path))))
+ (save-restriction
+ (narrow-to-region beg end)
+ (let* ((text (buffer-substring-no-properties beg end))
+ ;; the prefix given to the image file.
+ (prefix (cdr (assoc "prefix" attrs)))
+ ;; preamble (for extra options)
+ (preamble (cdr (assoc "preamble" attrs)))
+ ;; display inline or as a block
+ (display (car (assoc "inline" attrs))))
+ (when muse-publishing-p
+ (delete-region beg end)
+ (goto-char (point-min)))
+ (unless (file-directory-p pubdir)
+ (make-directory pubdir))
+ (let ((path (muse-latex2png-move2pubdir
+ (muse-latex2png text prefix preamble)
+ prefix pubdir)))
+ (when path
+ (when muse-publishing-p
+ (muse-insert-markup
+ (if (muse-style-derived-p "html")
+ (concat "<img src=\"" path
+ "\" alt=\"latex2png equation\" "
+ (if display (concat "class=\"latex-inline\"")
+ (concat "class=\"latex-display\""))
+ (if (muse-style-derived-p "xhtml")
+ " />"
+ ">")
+ (muse-insert-markup "<!-- " text "-->"))
+ (let ((ext (or (file-name-extension path) ""))
+ (path (muse-path-sans-extension path)))
+ (muse-markup-text 'image path ext))))
+ (goto-char (point-max)))
+ path))))))
+
+(defun muse-publish-latex-tag (beg end attrs)
+ "If the current style is not Latex-based, generate an image for the
+given Latex code. Otherwise, don't do anything to the region.
+See `muse-latex2png-region' for valid keys for ATTRS."
+ (unless (assoc "prefix" attrs)
+ (setq attrs (cons (cons "prefix"
+ (concat "latex2png-" (muse-page-name)))
+ attrs)))
+ (if (or (muse-style-derived-p "latex") (muse-style-derived-p "context"))
+ (muse-publish-mark-read-only beg end)
+ (muse-latex2png-region beg end attrs)))
+
+(put 'muse-publish-latex-tag 'muse-dangerous-tag t)
+
+(defun muse-publish-math-tag (beg end)
+ "Surround the given region with \"$\" characters. Then, if the
+current style is not Latex-based, generate an image for the given
+Latex math code.
+
+If 6 or more spaces come before the tag, and the end of the tag
+is at the end of a line, then surround the region with the
+equivalent of \"$$\" instead. This causes the region to be
+centered in the published output, among other things."
+ (let* ((centered (and (re-search-backward
+ (concat "^[" muse-regexp-blank "]\\{6,\\}\\=")
+ nil t)
+ (save-excursion
+ (save-match-data
+ (goto-char end)
+ (looking-at (concat "[" muse-regexp-blank "]*$"))))
+ (prog1 t
+ (replace-match "")
+ (when (and (or (muse-style-derived-p "latex")
+ (muse-style-derived-p "context"))
+ (not (bobp)))
+ (backward-char 1)
+ (if (bolp)
+ (delete-char 1)
+ (forward-char 1)))
+ (setq beg (point)))))
+ (tag-beg (if centered
+ (if (muse-style-derived-p "context")
+ "\\startformula " "\\[ ")
+ "$"))
+ (tag-end (if centered
+ (if (muse-style-derived-p "context")
+ " \\stopformula" " \\]")
+ "$"))
+ (attrs (nconc (list (cons "prefix"
+ (concat "latex2png-" (muse-page-name))))
+ (if centered nil
+ '(("inline" . t))))))
+ (goto-char beg)
+ (muse-insert-markup tag-beg)
+ (goto-char end)
+ (muse-insert-markup tag-end)
+ (if (or (muse-style-derived-p "latex") (muse-style-derived-p "context"))
+ (muse-publish-mark-read-only beg (point))
+ (muse-latex2png-region beg (point) attrs))))
+
+(put 'muse-publish-math-tag 'muse-dangerous-tag t)
+
+;;; Insinuate with muse-publish
+
+(add-to-list 'muse-publish-markup-tags
+ '("latex" t t nil muse-publish-latex-tag)
+ t)
+
+(add-to-list 'muse-publish-markup-tags
+ '("math" t nil nil muse-publish-math-tag)
+ t)
+
+(provide 'muse-latex2png)
+;;; muse-latex2png.el ends here
--- /dev/null
+;;; muse-mode.el --- mode for editing Muse files; has font-lock support
+
+;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; The Emacs Muse major mode is basically a hyped-up text-mode which
+;; knows a lot more about the apparent structure of the document.
+
+;;; Contributors:
+
+;; Andrea Riciputi (ariciputi AT pito DOT com) gave an initial
+;; implementation for tag completion by means of the `muse-insert-tag'
+;; function.
+
+;; Per B. Sederberg (per AT med DOT upenn DOT edu) contributed the
+;; insertion of relative links and list items, backlink searching, and
+;; other things as well.
+
+;; Stefan Schlee (stefan_schlee AT yahoo DOT com) fixed a bug in
+;; muse-next-reference and muse-previous-reference involving links
+;; that begin at point 1.
+
+;; Gregory Collins (greg AT gregorycollins DOT net) fixed a bug with
+;; paragraph separation and headings when filling.
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Emacs Muse Major Mode
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'muse-mode)
+
+(require 'muse)
+(require 'muse-regexps)
+(require 'muse-project)
+
+(autoload 'muse-use-font-lock "muse-colors")
+(autoload 'muse-publish-this-file "muse-publish")
+(autoload 'muse-publish-get-style "muse-publish")
+(autoload 'muse-publish-output-file "muse-publish")
+
+(require 'derived)
+(eval-when-compile
+ (condition-case nil
+ (require 'pcomplete) ; load if available
+ (error nil)))
+
+;;; Options:
+
+(defgroup muse-mode nil
+ "Options controlling the behavior of the Muse editing Mode."
+ :group 'muse)
+
+(defcustom muse-mode-highlight-p t
+ "If non-nil, highlight the content of Muse buffers."
+ :type 'boolean
+ :require 'muse-colors
+ :group 'muse-mode)
+
+(defcustom muse-mode-auto-p nil
+ "If non-nil, automagically determine when Muse mode should be activated."
+ :type 'boolean
+ :set (function
+ (lambda (sym value)
+ (if value
+ (add-hook 'find-file-hooks 'muse-mode-maybe)
+ (remove-hook 'find-file-hooks 'muse-mode-maybe))
+ (set sym value)))
+ :group 'muse-mode)
+
+(defun muse-mode-maybe-after-init ()
+ (when muse-mode-auto-p
+ (add-hook 'find-file-hooks 'muse-mode-maybe)))
+
+;; If the user sets this value in their init file, make sure that
+;; it takes effect
+(add-hook 'after-init-hook 'muse-mode-maybe-after-init)
+
+(defcustom muse-mode-intangible-links nil
+ "If non-nil, use the intangible property on links.
+This can cause problems with flyspell (and potentially fill-mode),
+so only enable this if you don't use either of these."
+ :type 'boolean
+ :group 'muse-mode)
+
+(defcustom muse-mode-hook nil
+ "A hook that is run when Muse mode is entered."
+ :type 'hook
+ :options '(flyspell-mode footnote-mode turn-on-auto-fill
+ highlight-changes-mode)
+ :group 'muse-mode)
+
+(defcustom muse-grep-command
+ "find %D -type f ! -name '*~' | xargs -I {} echo \\\"{}\\\" | xargs egrep -n -e \"%W\""
+ "The command to use when grepping for backlinks and other
+searches through the muse projects. The string %D is replaced by
+the directories from muse-project-alist, space-separated. The
+string %W is replaced with the name of the muse page or whatever
+else you are searching for. This command has been modified to
+handle spaces in filenames, which were giving egrep a problem.
+
+Note: We highly recommend using glimpse to search large projects.
+To use glimpse, install and edit a file called .glimpse_exclude
+in your home directory. Put a list of glob patterns in that file
+to exclude Emacs backup files, etc. Then, run the indexer using:
+
+ glimpseindex -o <list of Wiki directories>
+
+Once that's completed, customize this variable to have the
+following value:
+
+ glimpse -nyi \"%W\"
+
+Your searches will go much, much faster, especially for very
+large projects. Don't forget to add a user cronjob to update the
+index at intervals."
+ :type 'string
+ :group 'muse-mode)
+
+(defvar muse-insert-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "l" 'muse-insert-relative-link-to-file)
+ (define-key map "t" 'muse-insert-tag)
+ (define-key map "u" 'muse-insert-url)
+
+ map))
+
+;;; Muse mode
+
+(defvar muse-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [(control ?c) (control ?a)] 'muse-index)
+ (define-key map [(control ?c) (control ?e)] 'muse-edit-link-at-point)
+ (define-key map [(control ?c) (control ?l)] 'font-lock-mode)
+ (define-key map [(control ?c) (control ?t)]
+ 'muse-project-publish-this-file)
+ (define-key map [(control ?c) (control ?T)] 'muse-publish-this-file)
+ (define-key map [(control ?c) (meta control ?t)] 'muse-publish-this-file)
+ (define-key map [(control ?c) (control ?v)] 'muse-browse-result)
+
+ (define-key map [(control ?c) ?=] 'muse-what-changed)
+
+ (define-key map [tab] 'muse-next-reference)
+ (define-key map [(control ?i)] 'muse-next-reference)
+
+ (if (featurep 'xemacs)
+ (progn
+ (define-key map [(button2)] 'muse-follow-name-at-mouse)
+ (define-key map [(shift button2)]
+ 'muse-follow-name-at-mouse-other-window))
+ (define-key map [(shift control ?m)]
+ 'muse-follow-name-at-point-other-window)
+ (define-key map [mouse-2] 'muse-follow-name-at-mouse)
+ (define-key map [(shift mouse-2)]
+ 'muse-follow-name-at-mouse-other-window))
+
+ (define-key map [(shift tab)] 'muse-previous-reference)
+ (unless (featurep 'xemacs)
+ (define-key map [(shift iso-lefttab)] 'muse-previous-reference)
+ (define-key map [(shift control ?i)] 'muse-previous-reference))
+
+ (define-key map [(control ?c) (control ?f)] 'muse-project-find-file)
+ (define-key map [(control ?c) (control ?p)] 'muse-project-publish)
+
+ (define-key map [(control ?c) (control ?i)] 'muse-insert-thing)
+ (define-key map [(control ?c) tab] 'muse-insert-thing)
+
+ ;; Searching functions
+ (define-key map [(control ?c) (control ?b)] 'muse-find-backlinks)
+ (define-key map [(control ?c) (control ?s)] 'muse-search)
+
+ ;; Enhanced list functions
+ (define-key map [(meta return)] 'muse-insert-list-item)
+ (define-key map [(control ?>)] 'muse-increase-list-item-indentation)
+ (define-key map [(control ?<)] 'muse-decrease-list-item-indentation)
+
+ (when (featurep 'pcomplete)
+ (define-key map [(meta tab)] 'pcomplete)
+ (define-key map [(meta control ?i)] 'pcomplete))
+
+ map)
+ "Keymap used by Emacs Muse mode.")
+
+;;;###autoload
+(define-derived-mode muse-mode text-mode "Muse"
+ "Muse is an Emacs mode for authoring and publishing documents.
+\\{muse-mode-map}"
+ ;; Since we're not inheriting from normal-mode, we need to
+ ;; explicitly run file variables.
+ (condition-case err
+ (hack-local-variables)
+ (error (message "File local-variables error: %s"
+ (prin1-to-string err))))
+ ;; Avoid lock-up caused by use of the 'intangible' text property
+ ;; with flyspell.
+ (unless muse-mode-intangible-links
+ (set (make-local-variable 'inhibit-point-motion-hooks) t))
+ (setq muse-current-project (muse-project-of-file))
+ (muse-project-set-variables)
+ ;; Make fill not split up links
+ (when (boundp 'fill-nobreak-predicate)
+ (make-local-variable 'fill-nobreak-predicate)
+ ;; Work around annoying inconsistency in fill handling between
+ ;; Emacs 21 and 22.
+ (if (< emacs-major-version 22)
+ (setq fill-nobreak-predicate 'muse-mode-fill-nobreak-p)
+ (add-to-list 'fill-nobreak-predicate
+ 'muse-mode-fill-nobreak-p)))
+ ;; Make fill work nicely with item lists
+ (let ((regexp (concat "\\s-+\\(-\\|[0-9]+\\.\\)\\s-+"
+ "\\|\\[[0-9]+\\]\\s-*"
+ "\\|.*\\s-*::\\s-+"
+ "\\|\\*+\\s-+")))
+ (set (make-local-variable 'adaptive-fill-regexp)
+ (concat regexp "\\|\\s-*"))
+ (set (make-local-variable 'paragraph-start)
+ (concat paragraph-start "\\|" regexp))
+ (set (make-local-variable 'paragraph-separate)
+ (concat paragraph-separate "\\|\\*+\\s-+")))
+ (set (make-local-variable 'fill-paragraph-function)
+ 'muse-mode-fill-paragraph)
+
+ ;; Comment syntax is `; comment'
+ (set (make-local-variable 'comment-start)
+ "; ")
+ (set (make-local-variable 'comment-start-skip)
+ "^;\\s-+")
+ (set (make-local-variable 'indent-line-function)
+ #'ignore)
+ ;; If we're using Emacs21, this makes flyspell work like it should
+ (when (boundp 'flyspell-generic-check-word-p)
+ (set (make-local-variable 'flyspell-generic-check-word-p)
+ 'muse-mode-flyspell-p))
+ ;; If pcomplete is available, set it up
+ (when (featurep 'pcomplete)
+ (set (make-local-variable 'pcomplete-default-completion-function)
+ 'muse-mode-completions)
+ (set (make-local-variable 'pcomplete-command-completion-function)
+ 'muse-mode-completions)
+ (set (make-local-variable 'pcomplete-parse-arguments-function)
+ 'muse-mode-current-word))
+ ;; Initialize any auto-generated variables
+ (run-hooks 'muse-update-values-hook)
+ (when muse-mode-highlight-p
+ (muse-use-font-lock)))
+
+(put 'muse-mode
+ 'flyspell-mode-predicate
+ 'muse-mode-flyspell-p)
+
+(defun muse-mode-fill-nobreak-p ()
+ "Return nil if we should allow a fill to occur at point.
+Otherwise return non-nil.
+
+This is used to keep long explicit links from being mangled by
+fill mode."
+ (save-excursion
+ (save-match-data
+ (and (re-search-backward "\\[\\[\\|\\]\\]"
+ (line-beginning-position) t)
+ (string= (or (match-string 0) "")
+ "[[")))))
+
+(defun muse-mode-fill-paragraph (arg)
+ "If a definition list is at point, use special filling rules for it.
+Otherwise return nil to let the normal filling function take care
+of things.
+
+ARG is passed to `fill-paragraph'."
+ (let ((count 2))
+ (and (not (muse-mode-fill-nobreak-p))
+ (save-excursion
+ (beginning-of-line)
+ (and (looking-at muse-dl-term-regexp)
+ (prog1 t
+ ;; Take initial whitespace into account
+ (when (looking-at (concat "[" muse-regexp-blank "]+"))
+ (setq count (+ count (length (match-string 0))))))))
+ (let ((fill-prefix (make-string count ?\ ))
+ (fill-paragraph-function nil))
+ (prog1 t
+ (fill-paragraph arg))))))
+
+(defun muse-mode-flyspell-p ()
+ "Return non-nil if we should allow spell-checking to occur at point.
+Otherwise return nil.
+
+This is used to keep links from being improperly colorized by flyspell."
+ (let ((pos (if (bobp) (point) (1- (point)))))
+ (and (not (get-text-property pos 'muse-no-flyspell))
+ (not (get-text-property pos 'muse-link))
+ (save-match-data
+ (null (muse-link-at-point))))))
+
+;;;###autoload
+(defun muse-mode-choose-mode ()
+ "Turn the proper Emacs Muse related mode on for this file."
+ (let ((project (muse-project-of-file)))
+ (funcall (or (and project (muse-get-keyword :major-mode (cadr project) t))
+ 'muse-mode))))
+
+(defun muse-mode-maybe ()
+ "Maybe turn Emacs Muse mode on for this file."
+ (let ((project (muse-project-of-file)))
+ (and project
+ (funcall (or (muse-get-keyword :major-mode (cadr project) t)
+ 'muse-mode)))))
+
+;;; Enhanced list editing
+
+(defun muse-on-blank-line ()
+ "See if point is on a blank line"
+ (save-excursion
+ (beginning-of-line)
+ (looking-at (concat "[" muse-regexp-blank "]*$"))))
+
+(defun muse-get-paragraph-start ()
+ "Return the start of the current paragraph. This function will
+return nil if there are no prior paragraphs and the beginning of
+the line if point is on a blank line."
+ (let ((para-start (concat "^[" muse-regexp-blank "]*$")))
+ ;; search back to start of paragraph
+ (save-excursion
+ (save-match-data
+ (if (not (muse-on-blank-line))
+ (re-search-backward para-start nil t)
+ (line-beginning-position))))))
+
+(defun muse-insert-thing ()
+ "Prompt for something to insert into the current buffer."
+ (interactive)
+ (message "Insert:\nl link\nt Muse tag\nu URL")
+ (let (key cmd)
+ (let ((overriding-local-map muse-insert-map))
+ (setq key (read-key-sequence nil)))
+ (if (commandp (setq cmd (lookup-key muse-insert-map key)))
+ (progn (message "")
+ (call-interactively cmd))
+ (message "Not inserting anything"))))
+
+;;;###autoload
+(defun muse-insert-list-item ()
+ "Insert a list item at the current point, taking into account
+your current list type and indentation level."
+ (interactive)
+ (let ((newitem " - ")
+ (itemno nil)
+ (pstart (muse-get-paragraph-start))
+ (list-item (format muse-list-item-regexp
+ (concat "[" muse-regexp-blank "]*"))))
+ ;; search backwards for start of current item
+ (save-excursion
+ (when (re-search-backward list-item pstart t)
+ ;; save the matching item
+ (setq newitem (match-string 0))
+ ;; see what type it is
+ (if (string-match "::" (match-string 0))
+ ;; is a definition, replace the term
+ (setq newitem (concat " "
+ (read-string "Term: ")
+ " :: "))
+ ;; see if it's a numbered list
+ (when (string-match "[0-9]+" newitem)
+ ;; is numbered, so increment
+ (setq itemno (1+
+ (string-to-number
+ (match-string 0 newitem))))
+ (setq newitem (replace-match
+ (number-to-string itemno)
+ nil nil newitem))))))
+ ;; insert the new item
+ (insert (concat "\n" newitem))))
+
+(defun muse-alter-list-item-indentation (operation)
+ "Alter the indentation of the current list item.
+Valid values of OPERATION are 'increase and 'decrease."
+ (let ((pstart (muse-get-paragraph-start))
+ (list-item (format muse-list-item-regexp
+ (concat "[" muse-regexp-blank "]*")))
+ beg move-func indent)
+ ;; search backwards until start of paragraph to see if we are on a
+ ;; current item
+ (save-excursion
+ (if (or (progn (goto-char (muse-line-beginning-position))
+ ;; we are on an item
+ (looking-at list-item))
+ ;; not on item, so search backwards
+ (re-search-backward list-item pstart t))
+ (let ((beg (point)))
+ ;; we are on an item
+ (setq indent (buffer-substring (match-beginning 0)
+ (match-beginning 1)))
+ (muse-forward-list-item (muse-list-item-type (match-string 1))
+ (concat "[" muse-regexp-blank "]*")
+ t)
+ (save-restriction
+ (narrow-to-region beg (point))
+ (goto-char (point-min))
+ (let ((halt nil))
+ (while (< (point) (point-max))
+ ;; increase or decrease the indentation
+ (unless halt
+ (cond ((eq operation 'increase)
+ (insert " "))
+ ((eq operation 'decrease)
+ (if (looking-at " ")
+ ;; we have enough space, so delete it
+ (delete-region (match-beginning 0)
+ (match-end 0))
+ (setq halt t)))))
+ (forward-line 1)))))
+ ;; we are not on an item, so warn
+ (message "You are not on a list item.")))))
+
+;;;###autoload
+(defun muse-increase-list-item-indentation ()
+ "Increase the indentation of the current list item."
+ (interactive)
+ (muse-alter-list-item-indentation 'increase))
+
+;;;###autoload
+(defun muse-decrease-list-item-indentation ()
+ "Decrease the indentation of the current list item."
+ (interactive)
+ (muse-alter-list-item-indentation 'decrease))
+
+;;; Support page name completion using pcomplete
+
+(defun muse-mode-completions ()
+ "Return a list of possible completions names for this buffer."
+ (let ((project (muse-project-of-file)))
+ (if project
+ (while (pcomplete-here
+ (mapcar 'car (muse-project-file-alist project)))))))
+
+(defun muse-mode-current-word ()
+ (let ((end (point)))
+ (save-excursion
+ (save-restriction
+ (skip-chars-backward (concat "^\\[\n" muse-regexp-blank))
+ (narrow-to-region (point) end))
+ (pcomplete-parse-buffer-arguments))))
+
+;;; Navigate/visit links or URLs. Use TAB, S-TAB and RET (or mouse-2).
+
+(defun muse-link-at-point (&optional pos)
+ "Return link text if a URL or link is at point."
+ (let ((case-fold-search nil)
+ (inhibit-point-motion-hooks t)
+ (here (or pos (point))))
+ ;; if we are using muse-colors, we can just use link properties to
+ ;; determine whether we are on a link
+ (if (featurep 'muse-colors)
+ (when (get-text-property here 'muse-link)
+ (save-excursion
+ (when (and (not (bobp))
+ (get-text-property (1- here) 'muse-link))
+ (goto-char (or (previous-single-property-change here 'muse-link)
+ (point-min))))
+ (if (looking-at muse-explicit-link-regexp)
+ (progn
+ (goto-char (match-beginning 1))
+ (muse-handle-explicit-link))
+ (muse-handle-implicit-link))))
+ ;; use fallback method to find a link
+ (when (or (null pos)
+ (and (char-after pos)
+ (not (eq (char-syntax (char-after pos)) ?\ ))))
+ (save-excursion
+ (goto-char here)
+ ;; check for explicit link here or before point
+ (if (or (looking-at muse-explicit-link-regexp)
+ (and
+ (re-search-backward "\\[\\[\\|\\]\\]"
+ (muse-line-beginning-position)
+ t)
+ (string= (or (match-string 0) "") "[[")
+ (looking-at muse-explicit-link-regexp)))
+ (progn
+ (goto-char (match-beginning 1))
+ (muse-handle-explicit-link))
+ (goto-char here)
+ ;; check for bare URL or other link type
+ (skip-chars-backward (concat "^'\"<>{}(\n" muse-regexp-blank))
+ (and (looking-at muse-implicit-link-regexp)
+ (muse-handle-implicit-link))))))))
+
+(defun muse-make-link (link &optional desc)
+ "Return a link to LINK with DESC as the description."
+ (when (string-match muse-explicit-link-regexp link)
+ (unless desc (setq desc (muse-get-link-desc link)))
+ (setq link (muse-get-link link)))
+ (if (and desc
+ link
+ (not (string= desc ""))
+ (not (string= link desc)))
+ (concat "[[" (muse-link-escape link) "][" (muse-link-escape desc) "]]")
+ (concat "[[" (or (muse-link-escape link) "") "]]")))
+
+;;;###autoload
+(defun muse-insert-relative-link-to-file ()
+ "Insert a relative link to a file, with optional description, at point."
+ ;; Perhaps the relative location should be configurable, so that the
+ ;; file search would start in the publishing directory and then
+ ;; insert the link relative to the publishing directory
+ (interactive)
+ (insert
+ (muse-make-link (file-relative-name (read-file-name "Link: "))
+ (read-string "Text: "))))
+
+(defcustom muse-insert-url-initial-input "http://"
+ "The string to insert before reading a URL interactively.
+This is used by the `muse-insert-url' command."
+ :type 'string
+ :group 'muse-mode)
+
+(defun muse-insert-url ()
+ "Insert a URL, with optional description, at point."
+ (interactive)
+ (insert
+ (muse-make-link (read-string "URL: " muse-insert-url-initial-input)
+ (read-string "Text: "))))
+
+;;;###autoload
+(defun muse-edit-link-at-point ()
+ "Edit the current link.
+Do not rename the page originally referred to."
+ (interactive)
+ (if (muse-link-at-point)
+ (let ((link (muse-link-unescape (muse-get-link)))
+ (desc (muse-link-unescape (muse-get-link-desc))))
+ (replace-match
+ (save-match-data
+ (muse-make-link
+ (read-string "Link: " link)
+ (read-string "Text: " desc)))
+ t t))
+ (error "There is no valid link at point")))
+
+(defun muse-visit-link-default (link &optional other-window)
+ "Visit the URL or link named by LINK.
+If ANCHOR is specified, search for it after opening LINK.
+
+This is the default function to call when visiting links; it is
+used by `muse-visit-link' if you have not specified :visit-link
+in `muse-project-alist'."
+ (if (string-match muse-url-regexp link)
+ (muse-browse-url link)
+ (let (anchor
+ base-buffer)
+ (when (string-match "#" link)
+ (setq anchor (substring link (match-beginning 0))
+ link (if (= (match-beginning 0) 0)
+ ;; If there is an anchor but no link, default
+ ;; to the current page.
+ nil
+ (substring link 0 (match-beginning 0)))))
+ (when link
+ (setq base-buffer (get-buffer link))
+ (if (and base-buffer (not (buffer-file-name base-buffer)))
+ ;; If file is temporary (no associated file), just switch to
+ ;; the buffer
+ (if other-window
+ (switch-to-buffer-other-window base-buffer)
+ (switch-to-buffer base-buffer))
+ (let ((project (muse-project-of-file)))
+ (if project
+ (muse-project-find-file link project
+ (and other-window
+ 'find-file-other-window))
+ (if other-window
+ (find-file-other-window link)
+ (find-file link))))))
+ (when anchor
+ (let ((pos (point))
+ (regexp (concat "^\\W*" (regexp-quote anchor) "\\b"))
+ last)
+ (goto-char (point-min))
+ (while (and (setq last (re-search-forward regexp nil t))
+ (muse-link-at-point)))
+ (unless last
+ (goto-char pos)
+ (message "Could not find anchor `%s'" anchor)))))))
+
+(defun muse-visit-link (link &optional other-window)
+ "Visit the URL or link named by LINK."
+ (let ((visit-link-function
+ (muse-get-keyword :visit-link (cadr (muse-project-of-file)) t)))
+ (if visit-link-function
+ (funcall visit-link-function link other-window)
+ (muse-visit-link-default link other-window))))
+
+;;;###autoload
+(defun muse-browse-result (style &optional other-window)
+ "Visit the current page's published result."
+ (interactive
+ (list (muse-project-get-applicable-style buffer-file-name
+ (cddr muse-current-project))
+ current-prefix-arg))
+ (setq style (muse-style style))
+ (muse-project-publish-this-file nil style)
+ (let* ((output-dir (muse-style-element :path style))
+ (output-suffix (muse-style-element :osuffix style))
+ (output-path (muse-publish-output-file buffer-file-name output-dir
+ style))
+ (target (if output-suffix
+ (concat (muse-path-sans-extension output-path)
+ output-suffix)
+ output-path))
+ (muse-current-output-style (list :base (car style)
+ :path output-dir)))
+ (if (not (file-readable-p target))
+ (error "Cannot open output file '%s'" target)
+ (if other-window
+ (find-file-other-window target)
+ (let ((func (muse-style-element :browser style t)))
+ (if func
+ (funcall func target)
+ (message "The %s publishing style does not support browsing."
+ style)))))))
+
+;;;###autoload
+(defun muse-follow-name-at-point (&optional other-window)
+ "Visit the link at point."
+ (interactive "P")
+ (let ((link (muse-link-at-point)))
+ (if link
+ (muse-visit-link link other-window)
+ (error "There is no valid link at point"))))
+
+;;;###autoload
+(defun muse-follow-name-at-point-other-window ()
+ "Visit the link at point in other window."
+ (interactive)
+ (muse-follow-name-at-point t))
+
+(defun muse-follow-name-at-mouse (event &optional other-window)
+ "Visit the link at point, or yank text if none is found."
+ (interactive "eN")
+ (unless
+ (save-excursion
+ (cond ((fboundp 'event-window) ; XEmacs
+ (set-buffer (window-buffer (event-window event)))
+ (and (funcall (symbol-function 'event-point) event)
+ (goto-char (funcall (symbol-function 'event-point)
+ event))))
+ ((fboundp 'posn-window) ; Emacs
+ (set-buffer (window-buffer (posn-window (event-start event))))
+ (goto-char (posn-point (event-start event)))))
+ (let ((link (muse-link-at-point)))
+ (when link
+ (muse-visit-link link other-window)
+ t)))
+ ;; Fall back to normal binding for this event
+ (call-interactively
+ (lookup-key (current-global-map) (this-command-keys)))))
+
+(defun muse-follow-name-at-mouse-other-window (event)
+ "Visit the link at point"
+ (interactive "e")
+ ;; throw away the old window position, since other-window will
+ ;; change it anyway
+ (select-window (car (cadr event)))
+ (muse-follow-name-at-mouse event t))
+
+;;;###autoload
+(defun muse-next-reference ()
+ "Move forward to next Muse link or URL, cycling if necessary."
+ (interactive)
+ (let ((pos))
+ (save-excursion
+ (when (get-text-property (point) 'muse-link)
+ (goto-char (or (next-single-property-change (point) 'muse-link)
+ (point-max))))
+
+ (setq pos (next-single-property-change (point) 'muse-link))
+
+ (when (not pos)
+ (if (get-text-property (point-min) 'muse-link)
+ (setq pos (point-min))
+ (setq pos (next-single-property-change (point-min) 'muse-link)))))
+
+ (when pos
+ (goto-char pos))))
+
+;;;###autoload
+(defun muse-previous-reference ()
+ "Move backward to the next Muse link or URL, cycling if necessary.
+In case of Emacs x <= 21 and ignoring of intangible properties (see
+`muse-mode-intangible-links').
+
+This function is not entirely accurate, but it's close enough."
+ (interactive)
+ (let ((pos))
+ (save-excursion
+
+ ;; Hack: The user perceives the two cases of point ("|")
+ ;; position (1) "|[[" and (2) "[[|" or "][|" as "point is at
+ ;; start of link". But in the sense of the function
+ ;; "previous-single-property-change" these two cases are
+ ;; different. The following code aligns these two cases. Emacs
+ ;; 21: If the intangible property is ignored case (2) is more
+ ;; complicate and this hack only solves the problem partially.
+ ;;
+ (when (and (get-text-property (point) 'muse-link)
+ (muse-looking-back "\\[\\|\\]"))
+ (goto-char (or (previous-single-property-change (point) 'muse-link)
+ (point-min))))
+
+ (when (eq (point) (point-min))
+ (goto-char (point-max)))
+
+ (setq pos (previous-single-property-change (point) 'muse-link))
+
+ (when (not pos)
+ (if (get-text-property (point-min) 'muse-link)
+ (setq pos (point-min))
+ (setq pos (previous-single-property-change (point-max)
+ 'muse-link)))))
+
+ (when pos
+ (if (get-text-property pos 'muse-link)
+ (goto-char pos)
+ (goto-char (or (previous-single-property-change pos 'muse-link)
+ (point-min)))))))
+
+;;;###autoload
+(defun muse-what-changed ()
+ "Show the unsaved changes that have been made to the current file."
+ (interactive)
+ (diff-backup buffer-file-name))
+
+
+;;; Find text in project pages, or pages referring to the current page
+
+(defvar muse-search-history nil)
+
+(defun muse-grep (string &optional grep-command-no-shadow)
+ "Grep for STRING in the project directories.
+GREP-COMMAND if passed will supplant `muse-grep-command'."
+ ;; careful - grep-command leaks into compile, so we call it
+ ;; -no-shadow instead
+ (require 'compile)
+ (let* ((str (or grep-command-no-shadow muse-grep-command))
+ (muse-directories (mapcar
+ (lambda (thing)
+ (car (cadr thing)))
+ muse-project-alist))
+ (dirs (mapconcat (lambda (dir)
+ (shell-quote-argument
+ (expand-file-name dir)))
+ muse-directories " ")))
+ (if (string= dirs "")
+ (muse-display-warning
+ "No directories were found in the current project; aborting search")
+ (while (string-match "%W" str)
+ (setq str (replace-match string t t str)))
+ (while (string-match "%D" str)
+ (setq str (replace-match dirs t t str)))
+ (if (fboundp 'compilation-start)
+ (compilation-start str nil (lambda (&rest args) "*search*")
+ grep-regexp-alist)
+ (and (fboundp 'compile-internal)
+ (compile-internal str "No more search hits" "search"
+ nil grep-regexp-alist))))))
+
+;;;###autoload
+(defun muse-search-with-command (text)
+ "Search for the given TEXT string in the project directories
+using the specified command."
+ (interactive
+ (list (let ((str (concat muse-grep-command)) pos)
+ (when (string-match "%W" str)
+ (setq pos (match-beginning 0))
+ (unless (featurep 'xemacs)
+ (setq pos (1+ pos)))
+ (setq str (replace-match "" t t str)))
+ (read-from-minibuffer "Search command: "
+ (cons str pos) nil nil
+ 'muse-search-history))))
+ (muse-grep nil text))
+
+;;;###autoload
+(defun muse-search ()
+ "Search for the given TEXT using the default grep command."
+ (interactive)
+ (muse-grep (read-string "Search: ")))
+
+;;;###autoload
+(defun muse-find-backlinks ()
+ "Grep for the current pagename in all the project directories."
+ (interactive)
+ (muse-grep (muse-page-name)))
+
+
+;;; Generate an index of all known Muse pages
+
+(defun muse-generate-index (&optional as-list exclude-private)
+ "Generate an index of all Muse pages."
+ (let ((index (muse-index-as-string as-list exclude-private)))
+ (with-current-buffer (get-buffer-create "*Muse Index*")
+ (erase-buffer)
+ (insert index)
+ (current-buffer))))
+
+;;;###autoload
+(defun muse-index ()
+ "Display an index of all known Muse pages."
+ (interactive)
+ (message "Generating Muse index...")
+ (let ((project (muse-project)))
+ (with-current-buffer (muse-generate-index)
+ (goto-char (point-min))
+ (muse-mode)
+ (setq muse-current-project project)
+ (pop-to-buffer (current-buffer))))
+ (message "Generating Muse index...done"))
+
+(defun muse-index-as-string (&optional as-list exclude-private exclude-current)
+ "Generate an index of all Muse pages.
+If AS-LIST is non-nil, insert a dash and spaces before each item.
+If EXCLUDE-PRIVATE is non-nil, exclude files that have private permissions.
+If EXCLUDE-CURRENT is non-nil, exclude the current file from the output."
+ (let ((files (sort (copy-alist (muse-project-file-alist))
+ (function
+ (lambda (l r)
+ (string-lessp (car l) (car r)))))))
+ (when (and exclude-current (muse-page-name))
+ (setq files (delete (assoc (muse-page-name) files) files)))
+ (with-temp-buffer
+ (while files
+ (unless (and exclude-private
+ (muse-project-private-p (cdar files)))
+ (insert (if as-list " - " "") "[[" (caar files) "]]\n"))
+ (setq files (cdr files)))
+ (buffer-string))))
+
+;;; Insert tags interactively on C-c TAB t
+
+(defvar muse-tag-history nil
+ "List of recently-entered tags; used by `muse-insert-tag'.
+If you want a tag to start as the default, you may manually set
+this variable to a list.")
+
+(defvar muse-custom-tags nil
+ "Keep track of any new tags entered in `muse-insert-tag'.
+If there are (X)HTML tags that you use frequently with that
+function, you might want to set this manually.")
+
+;;;###autoload
+(defun muse-insert-tag (tag)
+ "Insert a tag interactively with a blank line after it."
+ (interactive
+ (list
+ (funcall
+ muse-completing-read-function
+ (concat "Tag: "
+ (when muse-tag-history
+ (concat "(default: " (car muse-tag-history) ") ")))
+ (progn
+ (require 'muse-publish)
+ (mapcar 'list (nconc (mapcar 'car muse-publish-markup-tags)
+ muse-custom-tags)))
+ nil nil nil 'muse-tag-history
+ (car muse-tag-history))))
+ (when (equal tag "")
+ (setq tag (car muse-tag-history)))
+ (unless (interactive-p)
+ (require 'muse-publish))
+ (let ((tag-entry (assoc tag muse-publish-markup-tags))
+ (options ""))
+ ;; Add to custom list if no entry exists
+ (unless tag-entry
+ (add-to-list 'muse-custom-tags tag))
+ ;; Get option
+ (when (nth 2 tag-entry)
+ (setq options (read-string "Option: ")))
+ (unless (equal options "")
+ (setq options (concat " " options)))
+ ;; Insert the tag, closing if necessary
+ (when tag (insert (concat "<" tag options ">")))
+ (when (nth 1 tag-entry)
+ (insert (concat "\n\n</" tag ">\n"))
+ (forward-line -2))))
+
+;;; Muse list edit minor mode
+
+(defvar muse-list-edit-minor-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [(meta return)] 'muse-l-e-m-m-insert-list-item)
+ (define-key map [(control ?>)] 'muse-l-e-m-m-increase-list-item-indent)
+ (define-key map [(control ?<)] 'muse-l-e-m-m-decrease-list-item-indent)
+
+ map)
+ "Keymap used by Muse list edit minor mode.")
+
+(defvar muse-l-e-m-m-list-item-regexp
+ (concat "^%s\\(\\([^\n" muse-regexp-blank "].*?\\)?::"
+ "\\(?:[" muse-regexp-blank "]+\\|$\\)"
+ "\\|[" muse-regexp-blank "]?[-*+][" muse-regexp-blank "]*"
+ "\\|[" muse-regexp-blank "][0-9]+\\.[" muse-regexp-blank "]*\\)")
+ "Regexp used to match the beginning of a list item.
+This is used by `muse-list-edit-minor-mode'.
+The '%s' will be replaced with a whitespace regexp when publishing.")
+
+(defun muse-l-e-m-m-insert-list-item ()
+ "Insert a list item at the current point, taking into account
+your current list type and indentation level."
+ (interactive)
+ (let ((muse-list-item-regexp muse-l-e-m-m-list-item-regexp))
+ (call-interactively 'muse-insert-list-item)))
+
+(defun muse-l-e-m-m-increase-list-item-indent ()
+ "Increase the indentation of the current list item."
+ (interactive)
+ (let ((muse-list-item-regexp muse-l-e-m-m-list-item-regexp))
+ (call-interactively 'muse-increase-list-item-indentation)))
+
+(defun muse-l-e-m-m-decrease-list-item-indent ()
+ "Decrease the indentation of the current list item."
+ (interactive)
+ (let ((muse-list-item-regexp muse-l-e-m-m-list-item-regexp))
+ (call-interactively 'muse-decrease-list-item-indentation)))
+
+(defvar muse-l-e-m-m-data nil
+ "A list of data that was changed by Muse list edit minor mode.")
+(make-variable-buffer-local 'muse-l-e-m-m-data)
+
+;;;###autoload
+(define-minor-mode muse-list-edit-minor-mode
+ "This is a global minor mode for editing files with lists.
+It is meant to be used with other major modes, and not with Muse mode.
+
+Interactively, with no prefix argument, toggle the mode.
+With universal prefix ARG turn mode on.
+With zero or negative ARG turn mode off.
+
+This minor mode provides the Muse keybindings for editing lists,
+and support for filling lists properly.
+
+It recognizes not only Muse-style lists, which use the \"-\"
+character or numbers, but also lists that use asterisks or plus
+signs. This should make the minor mode generally useful.
+
+Definition lists and footnotes are also recognized.
+
+Note that list items may omit leading spaces, for compatibility
+with modes that set `left-margin', such as
+`debian-changelog-mode'.
+
+\\{muse-list-edit-minor-mode-map}"
+ :init-value nil
+ :lighter ""
+ :keymap muse-list-edit-minor-mode-map
+ :global nil
+ :group 'muse-mode
+ (if (not muse-list-edit-minor-mode)
+ ;; deactivate
+ (when muse-l-e-m-m-data
+ (setq adaptive-fill-regexp (cdr (assoc "a-f-r" muse-l-e-m-m-data))
+ paragraph-start (cdr (assoc "p-s" muse-l-e-m-m-data))
+ fill-prefix (cdr (assoc "f-p" muse-l-e-m-m-data)))
+ (setq muse-l-e-m-m-data nil))
+ ;; activate
+ (unless muse-l-e-m-m-data
+ ;; save previous fill-related data so we can restore it later
+ (setq muse-l-e-m-m-data
+ (list (cons "a-f-r" adaptive-fill-regexp)
+ (cons "p-s" paragraph-start)
+ (cons "f-p" fill-prefix))))
+ ;; make fill work nicely with item lists
+ (let ((regexp (concat "\\s-*\\([-*+]\\|[0-9]+\\.\\)\\s-+"
+ "\\|\\[[0-9]+\\]\\s-*"
+ "\\|.*\\s-*::\\s-+")))
+ (set (make-local-variable 'adaptive-fill-regexp)
+ (concat regexp "\\|\\s-*"))
+ (set (make-local-variable 'paragraph-start)
+ (concat paragraph-start "\\|" regexp)))
+ ;; force fill-prefix to be nil, because if it is a string that has
+ ;; initial spaces, it messes up fill-paragraph's algorithm
+ (set (make-local-variable 'fill-prefix) nil)))
+
+(defun turn-on-muse-list-edit-minor-mode ()
+ "Unconditionally turn on Muse list edit minor mode."
+ (muse-list-edit-minor-mode 1))
+
+(defun turn-off-muse-list-edit-minor-mode ()
+ "Unconditionally turn off Muse list edit minor mode."
+ (muse-list-edit-minor-mode -1))
+
+;;; muse-mode.el ends here
--- /dev/null
+(define-package "muse" "3.20"
+ "Authoring and publishing tool")
--- /dev/null
+;;; muse-poem.el --- publish a poem to LaTex or PDF
+
+;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file specifies a form for recording poetry. It is as follows.
+;;
+;; Title
+;;
+;;
+;; Body of poem
+;;
+;;
+;; Annotations, history, notes, etc.
+;;
+;; The `muse-poem' module makes it easy to attractively publish and
+;; reference poems in this format, using the "memoir" module for LaTeX
+;; publishing. It will also markup poems for every other output
+;; style, though none are nearly as pretty.
+;;
+;; Once a poem is written in this format, just publish it to PDF using
+;; the "poem-pdf" style. To make an inlined reference to a poem that
+;; you've written -- for example, from a blog page -- there is a
+;; "poem" tag defined by this module:
+;;
+;; <poem title="name.of.poem.page">
+;;
+;; Let's assume the template above was called "name.of.poem.page";
+;; then the above tag would result in this inclusion:
+;;
+;; ** Title
+;;
+;; > Body of poem
+;;
+;; I use this module for publishing all of the poems on my website,
+;; which are at: http://www.newartisans.com/johnw/poems.html.
+
+;;; Contributors:
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Muse Poem Publishing
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(require 'muse-latex)
+(require 'muse-project)
+
+(defgroup muse-poem nil
+ "Rules for marking up a Muse file as a LaTeX article."
+ :group 'muse-latex)
+
+(defcustom muse-poem-latex-header
+ "\\documentclass[14pt,oneside]{memoir}
+
+\\usepackage[english]{babel}
+\\usepackage[latin1]{inputenc}
+\\usepackage[T1]{fontenc}
+
+\\setlength{\\beforepoemtitleskip}{-5.0ex}
+
+\\begin{document}
+
+\\pagestyle{empty}
+
+\\renewcommand{\\poemtoc}{section}
+\\settocdepth{section}
+
+\\mbox{}
+\\vfill
+
+\\poemtitle{<lisp>(muse-publishing-directive \"title\")</lisp>}
+
+\\settowidth{\\versewidth}{<lisp>muse-poem-longest-line</lisp>}\n\n"
+ "Header used for publishing LaTeX poems. This may be text or a filename."
+ :type 'string
+ :group 'muse-poem)
+
+(defcustom muse-poem-latex-footer "\n\\vfill
+\\mbox{}
+
+\\end{document}"
+ "Footer used for publishing LaTeX files. This may be text or a filename."
+ :type 'string
+ :group 'muse-poem)
+
+(defcustom muse-poem-markup-strings
+ '((begin-verse . "\\begin{verse}[\\versewidth]\n")
+ (verse-space . "\\vin "))
+ "Strings used for marking up poems.
+These cover the most basic kinds of markup, the handling of which
+differs little between the various styles."
+ :type '(alist :key-type symbol :value-type string)
+ :group 'muse-poem)
+
+(defcustom muse-chapbook-latex-header
+ "\\documentclass{book}
+
+\\usepackage[english]{babel}
+\\usepackage[latin1]{inputenc}
+\\usepackage[T1]{fontenc}
+
+\\setlength{\\beforepoemtitleskip}{-5.0ex}
+
+\\begin{document}
+
+\\title{<lisp>(muse-publishing-directive \"title\")</lisp>}
+\\author{<lisp>(muse-publishing-directive \"author\")</lisp>}
+\\date{<lisp>(muse-publishing-directive \"date\")</lisp>}
+
+\\maketitle
+
+\\tableofcontents
+
+\\renewcommand{\\poemtoc}{section}
+\\settocdepth{section}\n"
+ "Header used for publishing a book of poems in LaTeX form.
+This may be text or a filename."
+ :type 'string
+ :group 'muse-poem)
+
+(defcustom muse-chapbook-latex-footer "\n\\end{document}"
+ "Footer used for publishing a book of poems in LaTeX form.
+This may be text or a filename."
+ :type 'string
+ :group 'muse-poem)
+
+(defvar muse-poem-longest-line "")
+
+(defcustom muse-poem-chapbook-strings
+ '((begin-verse . "\\newpage
+\\mbox{}
+\\vfill
+
+\\poemtitle{<lisp>(muse-publishing-directive \"title\")</lisp>}
+
+\\settowidth{\\versewidth}{<lisp>muse-poem-longest-line</lisp>}
+
+\\begin{verse}[\\versewidth]\n")
+ (end-verse . "\n\\end{verse}\n\\vfill\n\\mbox{}")
+ (verse-space . "\\vin "))
+ "Strings used for marking up books of poems.
+These cover the most basic kinds of markup, the handling of which
+differs little between the various styles."
+ :type '(alist :key-type symbol :value-type string)
+ :group 'muse-poem)
+
+(defun muse-poem-prepare-buffer ()
+ (goto-char (point-min))
+ (insert "#title ")
+ (forward-line 1)
+ (delete-region (point) (1+ (muse-line-end-position)))
+ (insert "\n<verse>")
+ (let ((beg (point)) end line)
+ (if (search-forward "\n\n\n" nil t)
+ (progn
+ (setq end (copy-marker (match-beginning 0) t))
+ (replace-match "\n</verse>\n")
+ (delete-region (point) (point-max)))
+ (goto-char (point-max))
+ (setq end (point))
+ (insert "</verse>\n"))
+ (goto-char (1+ beg))
+ (set (make-local-variable 'muse-poem-longest-line) "")
+ (while (< (point) end)
+ (setq line (buffer-substring-no-properties (point)
+ (muse-line-end-position)))
+ (if (> (length line) (length muse-poem-longest-line))
+ (setq muse-poem-longest-line line))
+ (forward-line 1))
+ nil))
+
+(defvar muse-poem-tag '("poem" nil t nil muse-poem-markup-tag))
+
+(defun muse-poem-markup-tag (beg end attrs)
+ "This markup tag allows a poem to be included from another project page.
+The form of usage is:
+ <poem title=\"page.name\">"
+ (let ((page (cdr (assoc (cdr (assoc "title" attrs))
+ (muse-project-file-alist))))
+ beg end)
+ (if (null page)
+ (insert " *Reference to\n unknown poem \""
+ (cdr (assoc "title" attrs)) "\".*\n")
+ (setq beg (point))
+ (insert
+ (muse-with-temp-buffer
+ (muse-insert-file-contents page)
+ (goto-char (point-min))
+ (if (assoc "nohead" attrs)
+ (progn
+ (forward-line 3)
+ (delete-region (point-min) (point)))
+ (insert "** ")
+ (search-forward "\n\n\n")
+ (replace-match "\n\n"))
+ (if (search-forward "\n\n\n" nil t)
+ (setq end (match-beginning 0))
+ (setq end (point-max)))
+ (buffer-substring-no-properties (point-min) end)))
+ (setq end (point-marker))
+ (goto-char beg)
+ (unless (assoc "nohead" attrs)
+ (forward-line 2))
+ (while (< (point) end)
+ (insert "> ")
+ (forward-line 1))
+ (set-marker end nil))))
+
+(put 'muse-poem-markup-tag 'muse-dangerous-tag t)
+
+(add-to-list 'muse-publish-markup-tags muse-poem-tag)
+
+;;; Register the Muse POEM Publishers
+
+(muse-derive-style "poem-latex" "latex"
+ :before 'muse-poem-prepare-buffer
+ :strings 'muse-poem-markup-strings
+ :header 'muse-poem-latex-header
+ :footer 'muse-poem-latex-footer)
+
+(muse-derive-style "poem-pdf" "pdf"
+ :before 'muse-poem-prepare-buffer
+ :strings 'muse-poem-markup-strings
+ :header 'muse-poem-latex-header
+ :footer 'muse-poem-latex-footer)
+
+(muse-derive-style "chapbook-latex" "latex"
+ :before 'muse-poem-prepare-buffer
+ :strings 'muse-poem-chapbook-strings
+ :header 'muse-chapbook-latex-header
+ :footer 'muse-chapbook-latex-footer)
+
+(muse-derive-style "chapbook-pdf" "pdf"
+ :before 'muse-poem-prepare-buffer
+ :strings 'muse-poem-chapbook-strings
+ :header 'muse-chapbook-latex-header
+ :footer 'muse-chapbook-latex-footer)
+
+(provide 'muse-poem)
+
+;;; muse-poem.el ends here
--- /dev/null
+;;; muse-project.el --- handle Muse projects
+
+;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Contributors:
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Muse Project Maintainance
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'muse-project)
+
+(require 'muse)
+(require 'muse-publish)
+(require 'cus-edit)
+
+(defgroup muse-project nil
+ "Options controlling the behavior of Muse project handling."
+ :group 'muse)
+
+(defcustom muse-before-project-publish-hook nil
+ "A hook run before a project is published.
+Each function is passed the project object, a cons with the format
+ (PROJNAME . SETTINGS)"
+ :type 'hook
+ :group 'muse-project)
+
+(defcustom muse-after-project-publish-hook nil
+ "A hook run after a project is published.
+Each function is passed the project object, a cons with the format
+ (PROJNAME . SETTINGS)"
+ :type 'hook
+ :group 'muse-project)
+
+(defvar muse-project-alist-using-customize nil
+ "Used internally by Muse to indicate whether `muse-project-alist'
+has been modified via the customize interface.")
+(make-variable-buffer-local 'muse-project-alist-using-customize)
+
+(defmacro with-muse-project (project &rest body)
+ `(progn
+ (unless (muse-project ,project)
+ (error "Can't find project %s" ,project))
+ (with-temp-buffer
+ (muse-mode)
+ (setq muse-current-project (muse-project ,project))
+ (muse-project-set-variables)
+ ,@body)))
+
+(put 'with-muse-project 'lisp-indent-function 0)
+(put 'with-muse-project 'edebug-form-spec '(sexp body))
+
+(defun muse-project-alist-get (sym)
+ "Turn `muse-project-alist' into something we can customize easily."
+ (when (boundp sym)
+ (setq muse-project-alist-using-customize t)
+ (let* ((val (copy-alist (symbol-value sym)))
+ (head val))
+ (while val
+ (let ((head (car (cdar val)))
+ res)
+ ;; Turn settings of first part into cons cells, symbol->string
+ (while head
+ (cond ((stringp (car head))
+ (add-to-list 'res (car head) t)
+ (setq head (cdr head)))
+ ((symbolp (car head))
+ (add-to-list 'res (list (symbol-name (car head))
+ (cadr head)) t)
+ (setq head (cddr head)))
+ (t
+ (setq head (cdr head)))))
+ (setcdr (car val) (cons res (cdr (cdar val)))))
+ (let ((styles (cdar val)))
+ ;; Symbol->string in every style
+ (while (cdr styles)
+ (let ((head (cadr styles))
+ res)
+ (while (consp head)
+ (setq res (plist-put res (symbol-name (car head))
+ (cadr head)))
+ (setq head (cddr head)))
+ (setcdr styles (cons res (cddr styles))))
+ (setq styles (cdr styles))))
+ (setq val (cdr val)))
+ head)))
+
+(defun muse-project-alist-set (sym val)
+ "Turn customized version of `muse-project-alist' into something
+Muse can make use of."
+ (set sym val)
+ (when muse-project-alist-using-customize
+ ;; Make sure the unescaped version is written to .emacs
+ (put sym 'saved-value (list (custom-quote val)))
+ ;; Perform unescaping
+ (while val
+ (let ((head (car (cdar val)))
+ res)
+ ;; Turn cons cells into flat list, string->symbol
+ (while head
+ (cond ((stringp (car head))
+ (add-to-list 'res (car head) t))
+ ((consp (car head))
+ (add-to-list 'res (intern (caar head)) t)
+ (add-to-list 'res (car (cdar head)) t)))
+ (setq head (cdr head)))
+ (setcdr (car val) (cons res (cdr (cdar val)))))
+ (let ((styles (cdar val)))
+ ;; String->symbol in every style
+ (while (cdr styles)
+ (let ((head (cadr styles))
+ res)
+ (while (consp head)
+ (setq res (plist-put res (intern (car head))
+ (cadr head)))
+ (setq head (cddr head)))
+ (setcdr styles (cons res (cddr styles))))
+ (setq styles (cdr styles))))
+ (setq val (cdr val)))))
+
+(define-widget 'muse-project 'default
+ "A widget that defines a Muse project."
+ :format "\n%v"
+ :value-create 'muse-widget-type-value-create
+ :value-get 'muse-widget-child-value-get
+ :value-delete 'ignore
+ :match 'muse-widget-type-match
+ :type '(cons :format " %v"
+ (repeat :tag "Settings" :format "%{%t%}:\n%v%i\n\n"
+ (choice
+ (string :tag "Directory")
+ (list :tag "Book function"
+ (const :tag ":book-funcall" ":book-funcall")
+ (choice (function)
+ (sexp :tag "Unknown")))
+ (list :tag "Book part"
+ (const :tag ":book-part" ":book-part")
+ (string :tag "Name"))
+ (list :tag "Book style"
+ (const :tag ":book-style" ":book-style")
+ (string :tag "Style"))
+ (list :tag "Default file"
+ (const :tag ":default" ":default")
+ (string :tag "File"))
+ (list :tag "End of book"
+ (const :tag ":book-end" ":book-end")
+ (const t))
+ (list :tag "Force publishing"
+ (const :tag ":force-publish" ":force-publish")
+ (repeat (string :tag "File")))
+ (list :tag "Major mode"
+ (const :tag ":major-mode" ":major-mode")
+ (choice (function :tag "Mode")
+ (sexp :tag "Unknown")))
+ (list :tag "New chapter"
+ (const :tag ":book-chapter" ":book-chapter")
+ (string :tag "Name"))
+ (list :tag "No chapters"
+ (const :tag ":nochapters" ":nochapters")
+ (const t))
+ (list :tag "Project-level publishing function"
+ (const :tag ":publish-project"
+ ":publish-project")
+ (choice (function :tag "Function")
+ (sexp :tag "Unknown")))
+ (list :tag "Set variables"
+ (const :tag ":set" ":set")
+ (repeat (list :inline t
+ (symbol :tag "Variable")
+ (sexp :tag "Setting"))))
+ (list :tag "Visit links using"
+ (const :tag ":visit-link" ":visit-link")
+ (choice (function)
+ (sexp :tag "Unknown")))))
+ (repeat :tag "Output styles" :format "%{%t%}:\n%v%i\n\n"
+ (set :tag "Style"
+ (list :inline t
+ :tag "Publishing style"
+ (const :tag ":base" ":base")
+ (string :tag "Style"))
+ (list :inline t
+ :tag "Base URL"
+ (const :tag ":base-url" ":base-url")
+ (string :tag "URL"))
+ (list :inline t
+ :tag "Exclude matching"
+ (const :tag ":exclude" ":exclude")
+ (regexp))
+ (list :inline t
+ :tag "Include matching"
+ (const :tag ":include" ":include")
+ (regexp))
+ (list :inline t
+ :tag "Timestamps file"
+ (const :tag ":timestamps" ":timestamps")
+ (file))
+ (list :inline t
+ :tag "Path"
+ (const :tag ":path" ":path")
+ (string :tag "Path"))))))
+
+(defcustom muse-project-alist nil
+ "An alist of Muse projects.
+A project defines a fileset, and a list of custom attributes for use
+when publishing files in that project."
+ :type '(choice (const :tag "No projects defined." nil)
+ (repeat (cons :format "%{%t%}:\n\n%v"
+ :tag "Project" :indent 4
+ (string :tag "Project name")
+ muse-project))
+ (sexp :tag "Cannot parse expression"))
+ :get 'muse-project-alist-get
+ :set 'muse-project-alist-set
+ :group 'muse-project)
+
+;; Make it easier to specify a muse-project-alist entry
+
+(defcustom muse-project-ignore-regexp
+ (concat "\\`\\(#.*#\\|.*,v\\|.*~\\|\\.\\.?\\|\\.#.*\\|,.*\\)\\'\\|"
+ "/\\(CVS\\|RCS\\|\\.arch-ids\\|{arch}\\|,.*\\|\\.svn\\|"
+ "\\.hg\\|\\.git\\|\\.bzr\\|_darcs\\)\\(/\\|\\'\\)")
+ "A regexp matching files to be ignored in Muse directories.
+
+You should set `case-fold-search' to nil before using this regexp
+in code."
+ :type 'regexp
+ :group 'muse-regexp)
+
+(defcustom muse-project-publish-private-files t
+ "If this is non-nil, files will be published even if their permissions
+are set so that no one else on the filesystem can read them.
+
+Set this to nil if you would like to indicate that some files
+should not be published by manually doing \"chmod o-rwx\" on
+them.
+
+This setting has no effect under Windows (that is, all files are
+published regardless of permissions) because Windows lacks the
+needed filesystem attributes."
+ :type 'boolean
+ :group 'muse-project)
+
+(defun muse-project-recurse-directory (base)
+ "Recusively retrieve all of the directories underneath BASE.
+A list of these directories is returned.
+
+Directories starting with \".\" will be ignored, as well as those
+which match `muse-project-ignore-regexp'."
+ (let ((case-fold-search nil)
+ list dir)
+ (when (and (file-directory-p base)
+ (not (string-match muse-project-ignore-regexp base)))
+ (dolist (file (directory-files base t "^[^.]"))
+ (when (and (file-directory-p file)
+ (not (string-match muse-project-ignore-regexp file)))
+ (setq dir (file-name-nondirectory file))
+ (push dir list)
+ (nconc list (mapcar #'(lambda (item)
+ (concat dir "/" item))
+ (muse-project-recurse-directory file)))))
+ list)))
+
+(defun muse-project-alist-styles (entry-dir output-dir style &rest other)
+ "Return a list of styles to use in a `muse-project-alist' entry.
+ENTRY-DIR is the top-level directory of the project.
+OUTPUT-DIR is where Muse files are published, keeping directory structure.
+STYLE is the publishing style to use.
+
+OTHER contains other definitions to add to each style. It is optional.
+
+For an example of the use of this function, see
+`examples/mwolson/muse-init.el' from the Muse distribution."
+ (let ((fnd (file-name-nondirectory entry-dir)))
+ (when (string= fnd "")
+ ;; deal with cases like "foo/" that have a trailing slash
+ (setq fnd (file-name-nondirectory (substring entry-dir 0 -1))))
+ (cons `(:base ,style :path ,(if (muse-file-remote-p output-dir)
+ output-dir
+ (expand-file-name output-dir))
+ :include ,(concat "/" fnd "/[^/]+$")
+ ,@other)
+ (mapcar (lambda (dir)
+ `(:base ,style
+ :path ,(expand-file-name dir output-dir)
+ :include ,(concat "/" dir "/[^/]+$")
+ ,@other))
+ (muse-project-recurse-directory entry-dir)))))
+
+(defun muse-project-alist-dirs (entry-dir)
+ "Return a list of directories to use in a `muse-project-alist' entry.
+ENTRY-DIR is the top-level directory of the project.
+
+For an example of the use of this function, see
+`examples/mwolson/muse-init.el' from the Muse distribution."
+ (cons (expand-file-name entry-dir)
+ (mapcar (lambda (dir) (expand-file-name dir entry-dir))
+ (muse-project-recurse-directory entry-dir))))
+
+;; Constructing the file-alist
+
+(defvar muse-project-file-alist nil
+ "This variable is automagically constructed as needed.")
+
+(defvar muse-project-file-alist-hook nil
+ "Functions that are to be exectuted immediately after updating
+`muse-project-file-alist'.")
+
+(defvar muse-current-project nil
+ "Project we are currently visiting.")
+(make-variable-buffer-local 'muse-current-project)
+(defvar muse-current-project-global nil
+ "Project we are currently visiting. This is used to propagate the value
+of `muse-current-project' into a new buffer during publishing.")
+
+(defvar muse-current-output-style nil
+ "The output style that we are currently using for publishing files.")
+
+(defsubst muse-project (&optional project)
+ "Resolve the given PROJECT into a full Muse project, if it is a string."
+ (if (null project)
+ (or muse-current-project
+ (muse-project-of-file))
+ (if (stringp project)
+ (assoc project muse-project-alist)
+ (muse-assert (consp project))
+ project)))
+
+(defun muse-project-page-file (page project &optional no-check-p)
+ "Return a filename if PAGE exists within the given Muse PROJECT."
+ (setq project (muse-project project))
+ (if (null page)
+ ;; if not given a page, return the first directory instead
+ (let ((pats (cadr project)))
+ (catch 'done
+ (while pats
+ (if (symbolp (car pats))
+ (setq pats (cddr pats))
+ (throw 'done (file-name-as-directory (car pats)))))))
+ (let ((dir (file-name-directory page))
+ (expanded-path nil))
+ (when dir
+ (setq expanded-path (concat (expand-file-name
+ page
+ (file-name-directory (muse-current-file)))
+ (when muse-file-extension
+ (concat "." muse-file-extension))))
+ (setq page (file-name-nondirectory page)))
+ (let ((files (muse-collect-alist
+ (muse-project-file-alist project no-check-p)
+ page))
+ (matches nil))
+ (if dir
+ (catch 'done
+ (save-match-data
+ (dolist (file files)
+ (if (and expanded-path
+ (string= expanded-path (cdr file)))
+ (throw 'done (cdr file))
+ (let ((pos (string-match (concat (regexp-quote dir) "\\'")
+ (file-name-directory
+ (cdr file)))))
+ (when pos
+ (setq matches (cons (cons pos (cdr file))
+ matches)))))))
+ ;; if we haven't found an exact match, pick a candidate
+ (car (muse-sort-by-rating matches)))
+ (dolist (file files)
+ (setq matches (cons (cons (length (cdr file)) (cdr file))
+ matches)))
+ (car (muse-sort-by-rating matches '<)))))))
+
+(defun muse-project-private-p (file)
+ "Return non-nil if NAME is a private page with PROJECT."
+ (unless (or muse-under-windows-p
+ muse-project-publish-private-files)
+ (setq file (file-truename file))
+ (if (file-attributes file) ; don't publish if no attributes exist
+ (or (when (eq ?- (aref (nth 8 (file-attributes
+ (file-name-directory file))) 7))
+ (message (concat
+ "The " (file-name-directory file)
+ " directory must be readable by others"
+ " in order for its contents to be published.")))
+ (eq ?- (aref (nth 8 (file-attributes file)) 7)))
+ t)))
+
+(defun muse-project-file-entries (path)
+ (let* ((names (list t))
+ (lnames names)
+ (case-fold-search nil))
+ (cond
+ ((file-directory-p path)
+ (dolist (file (directory-files
+ path t (when (and muse-file-extension
+ (not (string= muse-file-extension "")))
+ (concat "." muse-file-extension "\\'"))))
+ (unless (or (string-match muse-project-ignore-regexp file)
+ (string-match muse-project-ignore-regexp
+ (file-name-nondirectory file))
+ (file-directory-p file))
+ (setcdr lnames
+ (cons (cons (muse-page-name file) file) nil))
+ (setq lnames (cdr lnames)))))
+ ((file-readable-p path)
+ (setcdr lnames
+ (cons (cons (muse-page-name path) path) nil))
+ (setq lnames (cdr lnames)))
+ (t ; regexp
+ (muse-assert (file-name-directory path))
+ (dolist (file (directory-files
+ (file-name-directory path) t
+ (file-name-nondirectory path)))
+ (unless (or (string-match muse-project-ignore-regexp file)
+ (string-match muse-project-ignore-regexp
+ (file-name-nondirectory file)))
+ (setcdr lnames
+ (cons (cons (muse-page-name file) file) nil))
+ (setq lnames (cdr lnames))))))
+ (cdr names)))
+
+(defvar muse-updating-file-alist-p nil
+ "Make sure that recursive calls to `muse-project-file-alist' are bounded.")
+
+(defun muse-project-determine-last-mod (project &optional no-check-p)
+ "Return the most recent last-modified timestamp of dirs in PROJECT."
+ (let ((last-mod nil))
+ (unless (or muse-under-windows-p no-check-p)
+ (let ((pats (cadr project)))
+ (while pats
+ (if (symbolp (car pats))
+ (setq pats (cddr pats))
+ (let* ((fnd (file-name-directory (car pats)))
+ (dir (cond ((file-directory-p (car pats))
+ (car pats))
+ ((and (not (file-readable-p (car pats)))
+ fnd
+ (file-directory-p fnd))
+ fnd))))
+ (when dir
+ (let ((mod-time (nth 5 (file-attributes dir))))
+ (when (or (null last-mod)
+ (and mod-time
+ (muse-time-less-p last-mod mod-time)))
+ (setq last-mod mod-time)))))
+ (setq pats (cdr pats))))))
+ last-mod))
+
+(defun muse-project-file-alist (&optional project no-check-p)
+ "Return member filenames for the given Muse PROJECT.
+Also, update the `muse-project-file-alist' variable.
+
+On UNIX, this alist is only updated if one of the directories'
+contents have changed. On Windows, it is always reread from
+disk.
+
+If NO-CHECK-P is non-nil, do not update the alist, just return
+the current one."
+ (setq project (muse-project project))
+ (when (and project muse-project-alist)
+ (let* ((file-alist (assoc (car project) muse-project-file-alist))
+ (last-mod (muse-project-determine-last-mod project no-check-p)))
+ ;; Either return the currently known list, or read it again from
+ ;; disk
+ (if (or (and no-check-p (cadr file-alist))
+ muse-updating-file-alist-p
+ (not (or muse-under-windows-p
+ (null (cddr file-alist))
+ (null last-mod)
+ (muse-time-less-p (cddr file-alist) last-mod))))
+ (cadr file-alist)
+ (if file-alist
+ (setcdr (cdr file-alist) last-mod)
+ (setq file-alist (cons (car project) (cons nil last-mod))
+ muse-project-file-alist
+ (cons file-alist muse-project-file-alist)))
+ ;; Read in all of the file entries
+ (let ((muse-updating-file-alist-p t))
+ (prog1
+ (save-match-data
+ (setcar
+ (cdr file-alist)
+ (let* ((names (list t))
+ (pats (cadr project)))
+ (while pats
+ (if (symbolp (car pats))
+ (setq pats (cddr pats))
+ (nconc names (muse-project-file-entries (car pats)))
+ (setq pats (cdr pats))))
+ (cdr names))))
+ (run-hooks 'muse-project-file-alist-hook)))))))
+
+(defun muse-project-add-to-alist (file &optional project)
+ "Make sure FILE is added to `muse-project-file-alist'.
+
+It works by either calling the `muse-project-file-alist' function
+if a directory has been modified since we last checked, or
+manually forcing the file entry to exist in the alist. This
+works around an issue where if several files being saved at the
+same time, only the first one will make it into the alist. It is
+meant to be called by `muse-project-after-save-hook'.
+
+The project of the file is determined by either the PROJECT
+argument, or `muse-project-of-file' if PROJECT is not specified."
+ (setq project (or (muse-project project) (muse-project-of-file file)))
+ (when (and project muse-project-alist)
+ (let* ((file-alist (assoc (car project) muse-project-file-alist))
+ (last-mod (muse-project-determine-last-mod project)))
+ ;; Determine whether we need to call this
+ (if (or (null (cddr file-alist))
+ (null last-mod)
+ (muse-time-less-p (cddr file-alist) last-mod))
+ ;; The directory will show up as modified, so go ahead and
+ ;; call `muse-project-file-alist'
+ (muse-project-file-alist project)
+ ;; It is not showing as modified, so forcefully add the
+ ;; current file to the project file-alist
+ (let ((muse-updating-file-alist-p t))
+ (prog1
+ (save-match-data
+ (setcar (cdr file-alist)
+ (nconc (muse-project-file-entries file)
+ (cadr file-alist))))
+ (run-hooks 'muse-project-file-alist-hook)))))))
+
+(defun muse-project-of-file (&optional pathname)
+ "Determine which project the given PATHNAME relates to.
+If PATHNAME is nil, the current buffer's filename is used."
+ (if (and (null pathname) muse-current-project)
+ muse-current-project
+ (unless pathname (setq pathname (muse-current-file)))
+ (save-match-data
+ (when (and (stringp pathname)
+ muse-project-alist
+ (not (string= pathname ""))
+ (not (let ((case-fold-search nil))
+ (or (string-match muse-project-ignore-regexp
+ pathname)
+ (string-match muse-project-ignore-regexp
+ (file-name-nondirectory
+ pathname))))))
+ (let* ((file (file-truename pathname))
+ (dir (file-name-directory file))
+ found rating matches)
+ (catch 'found
+ (dolist (project-entry muse-project-alist)
+ (let ((pats (cadr project-entry)))
+ (while pats
+ (if (symbolp (car pats))
+ (setq pats (cddr pats))
+ (let ((tname (file-truename (car pats))))
+ (cond ((or (string= tname file)
+ (string= (file-name-as-directory tname) dir))
+ (throw 'found project-entry))
+ ((string-match (concat "\\`" (regexp-quote tname))
+ file)
+ (setq matches (cons (cons (match-end 0)
+ project-entry)
+ matches)))))
+ (setq pats (cdr pats))))))
+ ;; if we haven't found an exact match, pick a candidate
+ (car (muse-sort-by-rating matches))))))))
+
+(defun muse-project-after-save-hook ()
+ "Update Muse's file-alist if we are saving a Muse file."
+ (let ((project (muse-project-of-file)))
+ (when project
+ (muse-project-add-to-alist (buffer-file-name) project))))
+
+(add-hook 'after-save-hook 'muse-project-after-save-hook)
+
+(defun muse-read-project (prompt &optional no-check-p no-assume)
+ "Read a project name from the minibuffer, if it can't be figured
+ out."
+ (if (null muse-project-alist)
+ (error "There are no Muse projects defined; see `muse-project-alist'")
+ (or (unless no-check-p
+ (muse-project-of-file))
+ (if (and (not no-assume)
+ (= 1 (length muse-project-alist)))
+ (car muse-project-alist)
+ (assoc (funcall muse-completing-read-function
+ prompt muse-project-alist)
+ muse-project-alist)))))
+
+(defvar muse-project-page-history nil)
+
+(defun muse-read-project-file (project prompt &optional default)
+ (let* ((file-list (muse-delete-dups
+ (mapcar #'(lambda (a) (list (car a)))
+ (muse-project-file-alist project))))
+ (name (funcall muse-completing-read-function
+ prompt file-list nil nil nil
+ 'muse-project-page-history default)))
+ (cons name (muse-project-page-file name project))))
+
+;;;###autoload
+(defun muse-project-find-file (name project &optional command directory)
+ "Open the Muse page given by NAME in PROJECT.
+If COMMAND is non-nil, it is the function used to visit the file.
+If DIRECTORY is non-nil, it is the directory in which the page
+will be created if it does not already exist. Otherwise, the
+first directory within the project's fileset is used."
+ (interactive
+ (let* ((project (muse-read-project "Find in project: "
+ current-prefix-arg))
+ (default (muse-get-keyword :default (cadr project)))
+ (entry (muse-read-project-file
+ project (if default
+ (format "Find page: (default: %s) "
+ default)
+ "Find page: ")
+ default)))
+ (list entry project)))
+ (setq project (muse-project project))
+ (let ((project-name (car project)))
+ (unless (interactive-p)
+ (setq project (muse-project project)
+ name (cons name (muse-project-page-file name project))))
+ ;; If we're given a relative or absolute filename, open it as-is
+ (if (and (car name)
+ (save-match-data
+ (or (string-match "\\`\\.+/" (car name))
+ (string-match muse-file-regexp (car name))
+ (string-match muse-image-regexp (car name)))))
+ (setcdr name (car name))
+ ;; At this point, name is (PAGE . FILE).
+ (unless (cdr name)
+ (let ((pats (cadr project)))
+ (while (and pats (null directory))
+ (if (symbolp (car pats))
+ (setq pats (cddr pats))
+ (if (file-directory-p (car pats))
+ (setq directory (car pats) pats nil)
+ (setq pats (cdr pats))))))
+ (when directory
+ (let ((filename (expand-file-name (car name) directory)))
+ (when (and muse-file-extension
+ (not (string= muse-file-extension ""))
+ (not (file-exists-p (car name))))
+ (setq filename (concat filename "." muse-file-extension)))
+ (unless (file-exists-p directory)
+ (make-directory directory t))
+ (setcdr name filename)))))
+ ;; Open the file
+ (if (cdr name)
+ (funcall (or command 'find-file) (cdr name))
+ (error "There is no page %s in project %s"
+ (car name) project-name))))
+
+(defun muse-project-choose-style (closure test styles)
+ "Run TEST on STYLES and return first style where TEST yields non-nil.
+TEST should take two arguments. The first is CLOSURE, which is
+passed verbatim. The second if the current style to consider.
+
+If no style passes TEST, return the first style."
+ (or (catch 'winner
+ (dolist (style styles)
+ (when (funcall test closure style)
+ (throw 'winner style))))
+ (car styles)))
+
+(defun muse-project-choose-style-by-link-suffix (given-suffix style)
+ "If the given STYLE has a link-suffix that equals GIVEN-SUFFIX,
+return non-nil."
+ (let ((link-suffix (or (muse-style-element :link-suffix style)
+ (muse-style-element :suffix style))))
+ (and (stringp link-suffix)
+ (string= given-suffix link-suffix))))
+
+(defun muse-project-applicable-styles (file styles)
+ "Given STYLES, return a list of the ones that are considered for FILE.
+The name of a project may be used for STYLES."
+ (when (stringp styles)
+ (setq styles (cddr (muse-project styles))))
+ (when (and file styles)
+ (let ((used-styles nil))
+ (dolist (style styles)
+ (let ((include-regexp (muse-style-element :include style))
+ (exclude-regexp (muse-style-element :exclude style))
+ (rating nil))
+ (when (and (or (and (null include-regexp)
+ (null exclude-regexp))
+ (if include-regexp
+ (setq rating (string-match include-regexp file))
+ (not (string-match exclude-regexp file))))
+ (file-exists-p file)
+ (not (muse-project-private-p file)))
+ (setq used-styles (cons (cons rating style) used-styles)))))
+ (muse-sort-by-rating (nreverse used-styles)))))
+
+(defun muse-project-get-applicable-style (file styles)
+ "Choose a style from the STYLES that FILE can publish to.
+The user is prompted if several styles are found."
+ (muse-publish-get-style
+ (mapcar (lambda (style)
+ (cons (muse-get-keyword :base style) style))
+ (muse-project-applicable-styles file styles))))
+
+(defun muse-project-resolve-directory (page local-style remote-style)
+ "Figure out the directory part of the path that provides a link to PAGE.
+LOCAL-STYLE is the style of the current Muse file, and
+REMOTE-STYLE is the style associated with PAGE.
+
+If REMOTE-STYLE has a :base-url element, concatenate it and PAGE.
+Otherwise, return a relative link."
+ (let ((prefix (muse-style-element :base-url remote-style)))
+ (if prefix
+ (concat prefix page)
+ (file-relative-name (expand-file-name
+ (file-name-nondirectory page)
+ (muse-style-element :path remote-style))
+ (expand-file-name
+ (muse-style-element :path local-style))))))
+
+(defun muse-project-resolve-link (page local-style remote-styles)
+ "Return a published link from the output path of one file to another file.
+
+The best match for PAGE is determined by comparing the link
+suffix of the given local style and that of the remote styles.
+
+The remote styles are usually populated by
+`muse-project-applicable-styles'.
+
+If no remote style is found, return PAGE verbatim
+
+If PAGE has a :base-url associated with it, return the
+concatenation of the :base-url value and PAGE.
+
+Otherwise, return a relative path from the directory of
+LOCAL-STYLE to the best directory among REMOTE-STYLES."
+ (let ((link-suffix (or (muse-style-element :link-suffix local-style)
+ (muse-style-element :suffix local-style)))
+ remote-style)
+ (if (not (stringp link-suffix))
+ (setq remote-style (car remote-styles))
+ (setq remote-style (muse-project-choose-style
+ link-suffix
+ #'muse-project-choose-style-by-link-suffix
+ remote-styles)))
+ (if (null remote-style)
+ page
+ (setq page (muse-project-resolve-directory
+ page local-style remote-style))
+ (concat (file-name-directory page)
+ (muse-publish-link-name page remote-style)))))
+
+(defun muse-project-current-output-style (&optional file project)
+ (or muse-current-output-style
+ (progn
+ (unless file (setq file (muse-current-file)))
+ (unless project (setq project (muse-project-of-file file)))
+ (car (muse-project-applicable-styles file (cddr project))))))
+
+(defun muse-project-link-page (page)
+ (let ((project (muse-project-of-file)))
+ (muse-project-resolve-link page
+ (muse-project-current-output-style)
+ (muse-project-applicable-styles
+ (muse-project-page-file page project)
+ (cddr project)))))
+
+(defun muse-project-publish-file-default (file style output-dir force)
+ ;; ensure the publishing location is available
+ (unless (file-exists-p output-dir)
+ (message "Creating publishing directory %s" output-dir)
+ (make-directory output-dir t))
+ ;; publish the member file!
+ (muse-publish-file file style output-dir force))
+
+(defun muse-project-publish-file (file styles &optional force)
+ (setq styles (muse-project-applicable-styles file styles))
+ (let (published)
+ (dolist (style styles)
+ (if (or (not (listp style))
+ (not (cdr style)))
+ (muse-display-warning
+ (concat "Skipping malformed muse-project-alist style."
+ "\nPlease double-check your configuration,"))
+ (let ((output-dir (muse-style-element :path style))
+ (muse-current-output-style style)
+ (fun (or (muse-style-element :publish style t)
+ 'muse-project-publish-file-default)))
+ (when (funcall fun file style output-dir force)
+ (setq published t)))))
+ published))
+
+;;;###autoload
+(defun muse-project-publish-this-file (&optional force style)
+ "Publish the currently-visited file according to `muse-project-alist',
+prompting if more than one style applies.
+
+If FORCE is given, publish the file even if it is up-to-date.
+
+If STYLE is given, use that publishing style rather than
+prompting for one."
+ (interactive (list current-prefix-arg))
+ (let ((muse-current-project (muse-project-of-file)))
+ (if (not muse-current-project)
+ ;; file is not part of a project, so fall back to muse-publish
+ (if (interactive-p) (call-interactively 'muse-publish-this-file)
+ (muse-publish-this-file style nil force))
+ (unless style
+ (setq style (muse-project-get-applicable-style
+ buffer-file-name (cddr muse-current-project))))
+ (let* ((output-dir (muse-style-element :path style))
+ (muse-current-project-global muse-current-project)
+ (muse-current-output-style (list :base (car style)
+ :path output-dir))
+ (fun (or (muse-style-element :publish style t)
+ 'muse-project-publish-file-default)))
+ (unless (funcall fun buffer-file-name style output-dir force)
+ (message (concat "The published version is up-to-date; use"
+ " C-u C-c C-t to force an update.")))))))
+
+(defun muse-project-save-buffers (&optional project)
+ (setq project (muse-project project))
+ (when project
+ (save-excursion
+ (map-y-or-n-p
+ (function
+ (lambda (buffer)
+ (and (buffer-modified-p buffer)
+ (not (buffer-base-buffer buffer))
+ (or (buffer-file-name buffer)
+ (progn
+ (set-buffer buffer)
+ (and buffer-offer-save
+ (> (buffer-size) 0))))
+ (with-current-buffer buffer
+ (let ((proj (muse-project-of-file)))
+ (and proj (string= (car proj)
+ (car project)))))
+ (if (buffer-file-name buffer)
+ (format "Save file %s? "
+ (buffer-file-name buffer))
+ (format "Save buffer %s? "
+ (buffer-name buffer))))))
+ (function
+ (lambda (buffer)
+ (set-buffer buffer)
+ (save-buffer)))
+ (buffer-list)
+ '("buffer" "buffers" "save")
+ (if (boundp 'save-some-buffers-action-alist)
+ save-some-buffers-action-alist)))))
+
+(defun muse-project-publish-default (project styles &optional force)
+ "Publish the pages of PROJECT that need publishing."
+ (setq project (muse-project project))
+ (let ((published nil))
+ ;; publish all files in the project, for each style; the actual
+ ;; publishing will only happen if the files are newer than the
+ ;; last published output, or if the file is listed in
+ ;; :force-publish. Files in :force-publish will not trigger the
+ ;; "All pages need to be published" message.
+ (let ((forced-files (muse-get-keyword :force-publish (cadr project)))
+ (file-alist (muse-project-file-alist project)))
+ (dolist (pair file-alist)
+ (when (muse-project-publish-file (cdr pair) styles force)
+ (setq forced-files (delete (car pair) forced-files))
+ (setq published t)))
+ (dolist (file forced-files)
+ (muse-project-publish-file (cdr (assoc file file-alist)) styles t)))
+ ;; run hook after publishing ends
+ (run-hook-with-args 'muse-after-project-publish-hook project)
+ ;; notify the user that everything is now done
+ (if published
+ (message "All pages in %s have been published." (car project))
+ (message "No pages in %s need publishing at this time."
+ (car project)))))
+
+;;;###autoload
+(defun muse-project-publish (project &optional force)
+ "Publish the pages of PROJECT that need publishing."
+ (interactive (list (muse-read-project "Publish project: " nil t)
+ current-prefix-arg))
+ (setq project (muse-project project))
+ (let ((styles (cddr project))
+ (muse-current-project project)
+ (muse-current-project-global project))
+ ;; determine the style from the project, or else ask
+ (unless styles
+ (setq styles (list (muse-publish-get-style))))
+ (unless project
+ (error "Cannot find a project to publish"))
+ ;; prompt to save any buffers related to this project
+ (muse-project-save-buffers project)
+ ;; run hook before publishing begins
+ (run-hook-with-args 'muse-before-project-publish-hook project)
+ ;; run the project-level publisher
+ (let ((fun (or (muse-get-keyword :publish-project (cadr project) t)
+ 'muse-project-publish-default)))
+ (funcall fun project styles force))))
+
+(defun muse-project-batch-publish ()
+ "Publish Muse files in batch mode."
+ (let ((muse-batch-publishing-p t)
+ force)
+ (if (string= "--force" (or (car command-line-args-left) ""))
+ (setq force t
+ command-line-args-left (cdr command-line-args-left)))
+ (if command-line-args-left
+ (dolist (project command-line-args-left)
+ (message "Publishing project %s ..." project)
+ (muse-project-publish project force))
+ (message "No projects specified."))))
+
+(eval-when-compile
+ (put 'make-local-hook 'byte-compile nil))
+
+(defun muse-project-set-variables ()
+ "Load project-specific variables."
+ (when (and muse-current-project-global (null muse-current-project))
+ (setq muse-current-project muse-current-project-global))
+ (let ((vars (muse-get-keyword :set (cadr muse-current-project)))
+ sym custom-set var)
+ (while vars
+ (setq sym (car vars))
+ (setq custom-set (or (get sym 'custom-set) 'set))
+ (setq var (if (eq (get sym 'custom-type) 'hook)
+ (make-local-hook sym)
+ (make-local-variable sym)))
+ (funcall custom-set var (car (cdr vars)))
+ (setq vars (cdr (cdr vars))))))
+
+(custom-add-option 'muse-before-publish-hook 'muse-project-set-variables)
+(add-to-list 'muse-before-publish-hook 'muse-project-set-variables)
+
+(defun muse-project-delete-output-files (project)
+ (interactive
+ (list (muse-read-project "Remove all output files for project: " nil t)))
+ (setq project (muse-project project))
+ (let ((file-alist (muse-project-file-alist project))
+ (styles (cddr project))
+ output-file path)
+ (dolist (entry file-alist)
+ (dolist (style styles)
+ (setq output-file
+ (and (setq path (muse-style-element :path style))
+ (expand-file-name
+ (concat (muse-style-element :prefix style)
+ (car entry)
+ (or (muse-style-element :osuffix style)
+ (muse-style-element :suffix style)))
+ path)))
+ (if output-file
+ (muse-delete-file-if-exists output-file))))))
+
+;;; muse-project.el ends here
--- /dev/null
+;;; muse-protocols.el --- URL protocols that Muse recognizes
+
+;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; Author: Brad Collins (brad AT chenla DOT org)
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Here's an example for adding a protocol for the site yubnub, a Web
+;; Command line service.
+;;
+;; (add-to-list 'muse-url-protocols '("yubnub://" muse-browse-url-yubnub
+;; muse-resolve-url-yubnub))
+;;
+;; (defun muse-resolve-url-yubnub (url)
+;; "Resolve a yubnub URL."
+;; ;; Remove the yubnub://
+;; (when (string-match "\\`yubnub://\\(.+\\)" url)
+;; (match-string 1)))
+;;
+;; (defun muse-browse-url-yubnub (url)
+;; "If this is a yubnub URL-command, jump to it."
+;; (setq url (muse-resolve-url-yubnub url))
+;; (browse-url (concat "http://yubnub.org/parser/parse?command="
+;; url)))
+
+;;; Contributors:
+
+;; Phillip Lord (Phillip.Lord AT newcastle DOT ac DOT uk) provided a
+;; handler for DOI URLs.
+
+;; Stefan Schlee fixed a bug with handling of colons at the end of
+;; URLs.
+
+;; Valery V. Vorotyntsev contribued the woman:// protocol handler and
+;; simplified `muse-browse-url-man'.
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Muse URL Protocols
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(require 'info)
+(require 'muse-regexps)
+
+(defvar muse-url-regexp nil
+ "A regexp used to match URLs within a Muse page.
+This is autogenerated from `muse-url-protocols'.")
+
+(defun muse-update-url-regexp (sym value)
+ (setq muse-url-regexp
+ (concat "\\<\\(" (mapconcat 'car value "\\|") "\\)"
+ "[^][" muse-regexp-blank "\"'()<>^`{}\n]*"
+ "[^][" muse-regexp-blank "\"'()<>^`{}.,;:\n]+"))
+ (set sym value))
+
+(defcustom muse-url-protocols
+ '(("[uU][rR][lL]:" muse-browse-url-url identity)
+ ("info://" muse-browse-url-info nil)
+ ("man://" muse-browse-url-man nil)
+ ("woman://" muse-browse-url-woman nil)
+ ("google://" muse-browse-url-google muse-resolve-url-google)
+ ("http:/?/?" browse-url identity)
+ ("https:/?/?" browse-url identity)
+ ("ftp:/?/?" browse-url identity)
+ ("gopher://" browse-url identity)
+ ("telnet://" browse-url identity)
+ ("wais://" browse-url identity)
+ ("file://?" browse-url identity)
+ ("dict:" muse-browse-url-dict muse-resolve-url-dict)
+ ("doi:" muse-browse-url-doi muse-resolve-url-doi)
+ ("news:" browse-url identity)
+ ("snews:" browse-url identity)
+ ("mailto:" browse-url identity))
+ "A list of (PROTOCOL BROWSE-FUN RESOLVE-FUN) used to match URL protocols.
+PROTOCOL describes the first part of the URL, including the
+\"://\" part. This may be a regexp.
+
+BROWSE-FUN should accept URL as an argument and open the URL in
+the current window.
+
+RESOLVE-FUN should accept URL as an argument and return the final
+URL, or nil if no URL should be included."
+ :type '(repeat (list :tag "Protocol"
+ (string :tag "Regexp")
+ (function :tag "Browse")
+ (choice (function :tag "Resolve")
+ (const :tag "Don't resolve" nil))))
+ :set 'muse-update-url-regexp
+ :group 'muse)
+
+(add-hook 'muse-update-values-hook
+ (lambda ()
+ (muse-update-url-regexp 'muse-url-protocols muse-url-protocols)))
+
+(defcustom muse-wikipedia-country "en"
+ "Indicate the 2-digit country code that we use for Wikipedia
+queries."
+ :type 'string
+ :options '("de" "en" "es" "fr" "it" "pl" "pt" "ja" "nl" "sv")
+ :group 'muse)
+
+(defun muse-protocol-find (proto list)
+ "Return the first element of LIST whose car matches the regexp PROTO."
+ (catch 'found
+ (dolist (item list)
+ (when (string-match (concat "\\`" (car item)) proto)
+ (throw 'found item)))))
+
+;;;###autoload
+(defun muse-browse-url (url &optional other-window)
+ "Handle URL with the function specified in `muse-url-protocols'.
+If OTHER-WINDOW is non-nil, open in a different window."
+ (interactive (list (read-string "URL: ")
+ current-prefix-arg))
+ ;; Strip text properties
+ (when (fboundp 'set-text-properties)
+ (set-text-properties 0 (length url) nil url))
+ (when other-window
+ (switch-to-buffer-other-window (current-buffer)))
+ (when (string-match muse-url-regexp url)
+ (let* ((proto (match-string 1 url))
+ (entry (muse-protocol-find proto muse-url-protocols)))
+ (when entry
+ (funcall (cadr entry) url)))))
+
+(defun muse-resolve-url (url &rest ignored)
+ "Resolve URL with the function specified in `muse-url-protocols'."
+ (when (string-match muse-url-regexp url)
+ (let* ((proto (match-string 1 url))
+ (entry (muse-protocol-find proto muse-url-protocols)))
+ (when entry
+ (let ((func (car (cddr entry))))
+ (if func
+ (setq url (funcall func url))
+ (setq url nil))))))
+ url)
+
+(defun muse-protocol-add (protocol browse-function resolve-function)
+ "Add PROTOCOL to `muse-url-protocols'. PROTOCOL may be a regexp.
+
+BROWSE-FUNCTION should be a function that visits a URL in the
+current buffer.
+
+RESOLVE-FUNCTION should be a function that transforms a URL for
+publishing or returns nil if not linked."
+ (add-to-list 'muse-url-protocols
+ (list protocol browse-function resolve-function))
+ (muse-update-url-regexp 'muse-url-protocols
+ muse-url-protocols))
+
+(defun muse-browse-url-url (url)
+ "Call `muse-protocol-browse-url' to browse URL.
+This is used when we are given something like
+\"URL:http://example.org/\".
+
+If you're looking for a good example for how to make a custom URL
+handler, look at `muse-browse-url-dict' instead."
+ (when (string-match "\\`[uU][rR][lL]:\\(.+\\)" url)
+ (muse-browse-url (match-string 1 url))))
+
+(defun muse-resolve-url-dict (url)
+ "Return the Wikipedia link corresponding with the given URL."
+ (when (string-match "\\`dict:\\(.+\\)" url)
+ (concat "http://" muse-wikipedia-country ".wikipedia.org/"
+ "wiki/Special:Search?search=" (match-string 1 url))))
+
+(defun muse-browse-url-dict (url)
+ "If this is a Wikipedia URL, browse it."
+ (let ((dict-url (muse-resolve-url-dict url)))
+ (when dict-url
+ (browse-url dict-url))))
+
+(defun muse-resolve-url-doi (url)
+ "Return the URL through DOI proxy server."
+ (when (string-match "\\`doi:\\(.+\\)" url)
+ (concat "http://dx.doi.org/"
+ (match-string 1 url))))
+
+(defun muse-browse-url-doi (url)
+ "If this is a DOI URL, browse it.
+
+DOI's (digitial object identifiers) are a standard identifier
+used in the publishing industry."
+ (let ((doi-url (muse-resolve-url-doi url)))
+ (when doi-url
+ (browse-url doi-url))))
+
+(defun muse-resolve-url-google (url)
+ "Return the correct Google search string."
+ (when (string-match "\\`google:/?/?\\(.+\\)" url)
+ (concat "http://www.google.com/search?q="
+ (match-string 1 url))))
+
+(defun muse-browse-url-google (url)
+ "If this is a Google URL, jump to it."
+ (let ((google-url (muse-resolve-url-google url)))
+ (when google-url
+ (browse-url google-url))))
+
+(defun muse-browse-url-info (url)
+ "If this in an Info URL, jump to it."
+ (require 'info)
+ (cond
+ ((string-match "\\`info://\\([^#\n]+\\)#\\(.+\\)" url)
+ (Info-find-node (match-string 1 url)
+ (match-string 2 url)))
+ ((string-match "\\`info://\\([^#\n]+\\)" url)
+ (Info-find-node (match-string 1 url)
+ "Top"))
+ ((string-match "\\`info://(\\([^)\n]+\\))\\(.+\\)" url)
+ (Info-find-node (match-string 1 url) (match-string 2 url)))
+ ((string-match "\\`info://\\(.+\\)" url)
+ (Info-find-node (match-string 1 url) "Top"))))
+
+(defun muse-browse-url-man (url)
+ "If this in a manpage URL, jump to it."
+ (require 'man)
+ (when (string-match "\\`man://\\([^(]+\\(([^)]+)\\)?\\)" url)
+ (man (match-string 1 url))))
+
+(defun muse-browse-url-woman (url)
+ "If this is a WoMan URL, jump to it."
+ (require 'woman)
+ (when (string-match "\\`woman://\\(.+\\)" url)
+ (woman (match-string 1 url))))
+
+(provide 'muse-protocols)
+
+;;; muse-protocols.el ends here
--- /dev/null
+;;; muse-publish.el --- base publishing implementation
+
+;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Contributors:
+
+;; Yann Hodique (yann DOT hodique AT gmail DOT com) fixed an
+;; unnecessary URL description transform in `muse-publish-url'.
+
+;; Peter K. Lee (saint AT corenova DOT com) provided the
+;; `muse-style-elements-list' function.
+
+;; Jim Ottaway (j DOT ottaway AT lse DOT ac DOT uk) provided a
+;; reference implementation for nested lists, as well as some code for
+;; the "style" element of the <literal> tag.
+
+;; Deus Max (deusmax AT gmail DOT com) provided the <php> tag.
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Muse Publishing
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'muse-publish)
+
+(require 'muse)
+(require 'muse-regexps)
+
+(defgroup muse-publish nil
+ "Options controlling the general behavior of Muse publishing."
+ :group 'muse)
+
+(defcustom muse-before-publish-hook nil
+ "A hook run in the buffer to be published, before it is done."
+ :type 'hook
+ :group 'muse-publish)
+
+(defcustom muse-after-publish-hook nil
+ "A hook run in the buffer to be published, after it is done."
+ :type 'hook
+ :group 'muse-publish)
+
+(defcustom muse-publish-url-transforms
+ '(muse-resolve-url)
+ "A list of functions used to prepare URLs for publication.
+Each is passed the URL. The transformed URL should be returned."
+ :type 'hook
+ :options '(muse-resolve-url)
+ :group 'muse-publish)
+
+(defcustom muse-publish-desc-transforms
+ '(muse-publish-strip-URL)
+ "A list of functions used to prepare URL desciptions for publication.
+Each is passed the description. The modified description should
+be returned."
+ :type 'hook
+ :options '(muse-publish-strip-URL)
+ :group 'muse-publish)
+
+(defcustom muse-publish-date-format "%B %e, %Y"
+ "Format string for the date, used by `muse-publish-markup-buffer'.
+See `format-time-string' for details on the format options."
+ :type 'string
+ :group 'muse-publish)
+
+(defcustom muse-publish-comments-p nil
+ "If nil, remove comments before publishing.
+If non-nil, publish comments using the markup of the current style."
+ :type 'boolean
+ :group 'muse-publish)
+
+(defcustom muse-publish-report-threshhold 100000
+ "If a file is this size or larger, report publishing progress."
+ :type 'integer
+ :group 'muse-publish)
+
+(defcustom muse-publish-markup-regexps
+ `(;; Remove leading and trailing whitespace from the file
+ (1000 "\\(\\`\n+\\|\n+\\'\\)" 0 "")
+
+ ;; Remove trailing whitespace from all lines
+ (1100 ,(concat "[" muse-regexp-blank "]+$") 0 "")
+
+ ;; Handle any leading #directives
+ (1200 "\\`#\\([a-zA-Z-]+\\)\\s-+\\(.+\\)\n+" 0 directive)
+
+ ;; commented lines
+ (1250 ,(concat "^;\\(?:[" muse-regexp-blank "]+\\(.+\\)\\|$\\|'\\)")
+ 0 comment)
+
+ ;; markup tags
+ (1300 muse-tag-regexp 0 tag)
+
+ ;; prevent emphasis characters in explicit links from being marked
+ (1400 muse-explicit-link-regexp 0 muse-publish-mark-link)
+
+ ;; emphasized or literal text
+ (1600 ,(concat "\\(^\\|[-[" muse-regexp-blank
+ "<('`\"\n]\\)\\(=[^=" muse-regexp-blank
+ "\n]\\|_[^_" muse-regexp-blank
+ "\n]\\|\\*+[^*" muse-regexp-blank
+ "\n]\\)")
+ 2 word)
+
+ ;; headings, outline-mode style
+ (1700 "^\\(\\*+\\)\\s-+" 0 heading)
+
+ ;; ellipses
+ (1800 "\\.\\.\\.\\." 0 enddots)
+ (1850 "\\.\\.\\." 0 dots)
+
+ ;; horizontal rule, or section separator
+ (1900 "^----+" 0 rule)
+
+ ;; non-breaking space
+ (1950 "~~" 0 no-break-space)
+
+ ;; beginning of footnotes section
+ (2000 "^Footnotes:?\\s-*" 0 fn-sep)
+ ;; footnote definition/reference (def if at beginning of line)
+ (2100 "\\[\\([1-9][0-9]*\\)\\]" 0 footnote)
+
+ ;; unnumbered List items begin with a -. numbered list items
+ ;; begin with number and a period. definition lists have a
+ ;; leading term separated from the body with ::. centered
+ ;; paragraphs begin with at least six columns of whitespace; any
+ ;; other whitespace at the beginning indicates a blockquote. The
+ ;; reason all of these rules are handled here, is so that
+ ;; blockquote detection doesn't interfere with indented list
+ ;; members.
+ (2200 ,(format muse-list-item-regexp (concat "[" muse-regexp-blank "]*"))
+ 0 list)
+
+ ;; support table.el style tables
+ (2300 ,(concat "^" muse-table-el-border-regexp "\n"
+ "\\(\\(" muse-table-el-line-regexp "\n\\)+"
+ "\\(" muse-table-el-border-regexp "\\)"
+ "\\(\n\\|\\'\\)\\)+")
+ 0 table-el)
+
+ ;; simple table markup is supported, nothing fancy. use | to
+ ;; separate cells, || to separate header cells, and ||| for footer
+ ;; cells
+ (2350 ,(concat "\\(\\([" muse-regexp-blank "]*\n\\)?"
+ "\\(\\(?:" muse-table-line-regexp "\\|"
+ muse-table-hline-regexp "\\)\\(?:\n\\|\\'\\)\\)\\)+")
+ 0 table)
+
+ ;; blockquote and centered text
+ (2400 ,(concat "^\\([" muse-regexp-blank "]+\\).+") 0 quote)
+
+ ;; the emdash ("--" or "---")
+ (2500 ,(concat "\\(^\\|[" muse-regexp-blank "]*\\)---?\\($\\|["
+ muse-regexp-blank "]*\\)")
+ 0 emdash)
+
+ ;; "verse" text is indicated the same way as a quoted e-mail
+ ;; response: "> text", where text may contain initial whitespace
+ ;; (see below).
+ (2600 ,(concat "^[" muse-regexp-blank "]*> ") 0 verse)
+
+ ;; define anchor points
+ (2700 "^\\(\\W*\\)#\\(\\S-+\\)\\s-*" 0 anchor)
+
+ ;; replace links in the buffer (links to other pages)
+ (2900 muse-explicit-link-regexp 0 link)
+
+ ;; bare URLs
+ (3000 muse-url-regexp 0 url)
+
+ ;; bare email addresses
+ (3500
+ "\\([^[]\\)[-a-zA-Z0-9._]+@\\([-a-zA-z0-9_]+\\.\\)+[a-zA-Z0-9]+" 0 email)
+ )
+ "List of markup rules for publishing a page with Muse.
+The rules given in this variable are invoked first, followed by
+whatever rules are specified by the current style.
+
+Each member of the list is either a function, or a list of the form:
+
+ (REGEXP/SYMBOL TEXT-BEGIN-GROUP REPLACEMENT-TEXT/FUNCTION/SYMBOL)
+
+REGEXP is a regular expression, or symbol whose value is a regular
+expression, which is searched for using `re-search-forward'.
+TEXT-BEGIN-GROUP is the matching group within that regexp which
+denotes the beginning of the actual text to be marked up.
+REPLACEMENT-TEXT is a string that will be passed to `replace-match'.
+If it is not a string, but a function, it will be called to determine
+what the replacement text should be (it must return a string). If it
+is a symbol, the value of that symbol should be a string.
+
+The replacements are done in order, one rule at a time. Writing
+the regular expressions can be a tricky business. Note that case
+is never ignored. `case-fold-search' is always bound to nil
+while processing the markup rules."
+ :type '(repeat (choice
+ (list :tag "Markup rule"
+ integer
+ (choice regexp symbol)
+ integer
+ (choice string function symbol))
+ function))
+ :group 'muse-publish)
+
+(defcustom muse-publish-markup-functions
+ '((directive . muse-publish-markup-directive)
+ (comment . muse-publish-markup-comment)
+ (anchor . muse-publish-markup-anchor)
+ (tag . muse-publish-markup-tag)
+ (word . muse-publish-markup-word)
+ (emdash . muse-publish-markup-emdash)
+ (enddots . muse-publish-markup-enddots)
+ (dots . muse-publish-markup-dots)
+ (rule . muse-publish-markup-rule)
+ (no-break-space . muse-publish-markup-no-break-space)
+ (heading . muse-publish-markup-heading)
+ (footnote . muse-publish-markup-footnote)
+ (fn-sep . muse-publish-markup-fn-sep)
+ (list . muse-publish-markup-list)
+ (quote . muse-publish-markup-quote)
+ (verse . muse-publish-markup-verse)
+ (table . muse-publish-markup-table)
+ (table-el . muse-publish-markup-table-el)
+ (email . muse-publish-markup-email)
+ (link . muse-publish-markup-link)
+ (url . muse-publish-markup-url))
+ "An alist of style types to custom functions for that kind of text.
+
+Each member of the list is of the form:
+
+ (SYMBOL FUNCTION)
+
+SYMBOL describes the type of text to associate with this rule.
+`muse-publish-markup-regexps' maps regexps to these symbols.
+
+FUNCTION is the function to use to mark up this kind of rule if
+no suitable function is found through the :functions tag of the
+current style."
+ :type '(alist :key-type symbol :value-type function)
+ :group 'muse-publish)
+
+(defcustom muse-publish-markup-tags
+ '(("contents" nil t nil muse-publish-contents-tag)
+ ("verse" t nil nil muse-publish-verse-tag)
+ ("example" t nil nil muse-publish-example-tag)
+ ("src" t t nil muse-publish-src-tag)
+ ("code" t nil nil muse-publish-code-tag)
+ ("quote" t nil t muse-publish-quote-tag)
+ ("literal" t t nil muse-publish-literal-tag)
+ ("verbatim" t nil nil muse-publish-verbatim-tag)
+ ("br" nil nil nil muse-publish-br-tag)
+ ("lisp" t t nil muse-publish-lisp-tag)
+ ("class" t t nil muse-publish-class-tag)
+ ("div" t t nil muse-publish-div-tag)
+ ("command" t t nil muse-publish-command-tag)
+ ("perl" t t nil muse-publish-perl-tag)
+ ("php" t t nil muse-publish-php-tag)
+ ("python" t t nil muse-publish-python-tag)
+ ("ruby" t t nil muse-publish-ruby-tag)
+ ("comment" t nil nil muse-publish-comment-tag)
+ ("include" nil t nil muse-publish-include-tag)
+ ("markup" t t nil muse-publish-mark-up-tag)
+ ("cite" t t nil muse-publish-cite-tag))
+ "A list of tag specifications, for specially marking up text.
+XML-style tags are the best way to add custom markup to Muse.
+This is easily accomplished by customizing this list of markup tags.
+
+For each entry, the name of the tag is given, whether it expects
+a closing tag, whether it takes an optional set of attributes,
+whether it is nestable, and a function that performs whatever
+action is desired within the delimited region.
+
+The tags themselves are deleted during publishing, before the
+function is called. The function is called with three arguments,
+the beginning and end of the region surrounded by the tags. If
+properties are allowed, they are passed as a third argument in
+the form of an alist. The `end' argument to the function is
+always a marker.
+
+Point is always at the beginning of the region within the tags, when
+the function is called. Wherever point is when the function finishes
+is where tag markup will resume.
+
+These tag rules are processed once at the beginning of markup, and
+once at the end, to catch any tags which may have been inserted
+in-between."
+ :type '(repeat (list (string :tag "Markup tag")
+ (boolean :tag "Expect closing tag" :value t)
+ (boolean :tag "Parse attributes" :value nil)
+ (boolean :tag "Nestable" :value nil)
+ function))
+ :group 'muse-publish)
+
+(defcustom muse-publish-markup-header-footer-tags
+ '(("lisp" t t nil muse-publish-lisp-tag)
+ ("markup" t t nil muse-publish-mark-up-tag))
+ "Tags used when publishing headers and footers.
+See `muse-publish-markup-tags' for details."
+ :type '(repeat (list (string :tag "Markup tag")
+ (boolean :tag "Expect closing tag" :value t)
+ (boolean :tag "Parse attributes" :value nil)
+ (boolean :tag "Nestable" :value nil)
+ function))
+ :group 'muse-publish)
+
+(defcustom muse-publish-markup-specials nil
+ "A table of characters which must be represented specially."
+ :type '(alist :key-type character :value-type string)
+ :group 'muse-publish)
+
+(defcustom muse-publish-enable-local-variables nil
+ "If non-nil, interpret local variables in a file when publishing."
+ :type 'boolean
+ :group 'muse-publish)
+
+(defcustom muse-publish-enable-dangerous-tags t
+ "If non-nil, publish tags like <lisp> and <command> that can
+call external programs or expose sensitive information.
+Otherwise, ignore tags like this.
+
+This is useful to set to nil when the file to publish is coming
+from an untrusted source."
+ :type 'boolean
+ :group 'muse-publish)
+
+(defvar muse-publishing-p nil
+ "This is set to t while a page is being published.")
+(defvar muse-batch-publishing-p nil
+ "This is set to t while a page is being batch published.")
+(defvar muse-inhibit-before-publish-hook nil
+ "This is set to t when publishing a file rather than just a buffer.
+It is used by `muse-publish-markup-buffer'.")
+(defvar muse-publishing-styles nil
+ "The publishing styles that Muse recognizes.
+This is automatically generated when loading publishing styles.")
+(defvar muse-publishing-current-file nil
+ "The file that is currently being published.")
+(defvar muse-publishing-current-output-path nil
+ "The path where the current file will be published to.")
+(defvar muse-publishing-current-style nil
+ "The style of the file that is currently being published.")
+(defvar muse-publishing-directives nil
+ "An alist of publishing directives from the top of a file.")
+(defvar muse-publish-generate-contents nil
+ "Non-nil if a table of contents should be generated.
+If non-nil, it is a cons cell specifying (MARKER . DEPTH), to
+tell where the <contents> was seen, and to what depth the
+contents were requested.")
+(defvar muse-publishing-last-position nil
+ "Last position of the point when publishing.
+This is used to make sure that publishing doesn't get stalled.")
+
+(defvar muse-publish-inhibit-style-hooks nil
+ "If non-nil, do not call the :before or :before-end hooks when publishing.")
+
+(defvar muse-publish-use-header-footer-tags nil
+ "If non-nil, use `muse-publish-markup-header-footer-tags' for looking up
+tags. Otherwise, use `muse-publish-markup-tags'.")
+
+(defvar muse-inhibit-style-tags nil
+ "If non-nil, do not search for style-specific tags.
+This is used when publishing headers and footers.")
+
+;; Functions for handling style information
+
+(defsubst muse-style (&optional style)
+ "Resolve the given STYLE into a Muse style, if it is a string."
+ (if (null style)
+ muse-publishing-current-style
+ (if (stringp style)
+ (assoc style muse-publishing-styles)
+ (muse-assert (consp style))
+ style)))
+
+(defun muse-define-style (name &rest elements)
+ (let ((entry (assoc name muse-publishing-styles)))
+ (if entry
+ (setcdr entry elements)
+ (setq muse-publishing-styles
+ (cons (append (list name) elements)
+ muse-publishing-styles)))))
+
+(defun muse-derive-style (new-name base-name &rest elements)
+ (apply 'muse-define-style new-name
+ (append elements (list :base base-name))))
+
+(defsubst muse-get-keyword (keyword list &optional direct)
+ (let ((value (cadr (memq keyword list))))
+ (if (and (not direct) (symbolp value))
+ (symbol-value value)
+ value)))
+
+(defun muse-style-elements-list (elem &optional style)
+ "Return a list all references to ELEM in STYLE, including base styles.
+If STYLE is not specified, use current style."
+ (let (base elements)
+ (while style
+ (setq style (muse-style style))
+ (setq elements (append elements
+ (muse-get-keyword elem style)))
+ (setq style (muse-get-keyword :base style)))
+ elements))
+
+(defun muse-style-element (elem &optional style direct)
+ "Search for ELEM in STYLE, including base styles.
+If STYLE is not specified, use current style."
+ (setq style (muse-style style))
+ (let ((value (muse-get-keyword elem style direct)))
+ (if value
+ value
+ (let ((base (muse-get-keyword :base style)))
+ (if base
+ (muse-style-element elem base direct))))))
+
+(defun muse-style-derived-p-1 (base style)
+ "Internal function used by `muse-style-derived-p'."
+ (if (and (stringp style)
+ (string= style base))
+ t
+ (setq style (muse-style style))
+ (let ((value (muse-get-keyword :base style)))
+ (when value
+ (muse-style-derived-p base value)))))
+
+(defun muse-style-derived-p (base &optional style)
+ "Return non-nil if STYLE is equal to or derived from BASE,
+non-nil otherwise.
+
+BASE should be a string."
+ (unless style
+ (setq style (muse-style)))
+ (when (and (consp style)
+ (stringp (car style)))
+ (setq style (car style)))
+ (muse-style-derived-p-1 base style))
+
+(defun muse-find-markup-element (keyword ident style)
+ (let ((def (assq ident (muse-style-element keyword style))))
+ (if def
+ (cdr def)
+ (let ((base (muse-style-element :base style)))
+ (if base
+ (muse-find-markup-element keyword ident base))))))
+
+(defun muse-markup-text (ident &rest args)
+ "Insert ARGS into the text markup associated with IDENT.
+If the markup text has sections like %N%, this will be replaced
+with the N-1th argument in ARGS. After that, `format' is applied
+to the text with ARGS as parameters."
+ (let ((text (muse-find-markup-element :strings ident (muse-style))))
+ (if (and text args)
+ (progn
+ (let (start repl-text)
+ (while (setq start (string-match "%\\([1-9][0-9]*\\)%" text start))
+ ;; escape '%' in the argument text, since we will be
+ ;; using format on it
+ (setq repl-text (muse-replace-regexp-in-string
+ "%" "%%"
+ (nth (1- (string-to-number
+ (match-string 1 text))) args)
+ t t)
+ start (+ start (length repl-text))
+ text (replace-match repl-text t t text))))
+ (apply 'format text args))
+ (or text ""))))
+
+(defun muse-insert-markup (&rest args)
+ (let ((beg (point)))
+ (apply 'insert args)
+ (muse-publish-mark-read-only beg (point))))
+
+(defun muse-find-markup-tag (keyword tagname style)
+ (let ((def (assoc tagname (muse-style-element keyword style))))
+ (or def
+ (let ((base (muse-style-element :base style)))
+ (if base
+ (muse-find-markup-tag keyword tagname base))))))
+
+(defun muse-markup-tag-info (tagname &rest args)
+ (let ((tag-info (and (not muse-inhibit-style-tags)
+ (muse-find-markup-tag :tags tagname (muse-style)))))
+ (or tag-info
+ (assoc tagname
+ (if muse-publish-use-header-footer-tags
+ muse-publish-markup-header-footer-tags
+ muse-publish-markup-tags)))))
+
+(defsubst muse-markup-function (category)
+ (let ((func (muse-find-markup-element :functions category (muse-style))))
+ (or func
+ (cdr (assq category muse-publish-markup-functions)))))
+
+;; Publishing routines
+
+(defun muse-publish-markup (name rules)
+ (let* ((case-fold-search nil)
+ (inhibit-read-only t)
+ (limit (* (length rules) (point-max)))
+ (verbose (and muse-publish-report-threshhold
+ (> (point-max) muse-publish-report-threshhold)))
+ (base 0))
+ (while rules
+ (goto-char (point-min))
+ (let ((regexp (nth 1 (car rules)))
+ (group (nth 2 (car rules)))
+ (repl (nth 3 (car rules)))
+ pos)
+ (setq muse-publishing-last-position nil)
+ (if (symbolp regexp)
+ (setq regexp (symbol-value regexp)))
+ (if (and verbose (not muse-batch-publishing-p))
+ (message "Publishing %s...%d%%" name
+ (* (/ (float (+ (point) base)) limit) 100)))
+ (while (and regexp (progn
+ (when (and (get-text-property (point) 'read-only)
+ (> (point) (point-min)))
+ (goto-char (or (next-single-property-change
+ (point) 'read-only)
+ (point-max))))
+ (setq pos (re-search-forward regexp nil t))))
+ (if (and verbose (not muse-batch-publishing-p))
+ (message "Publishing %s...%d%%" name
+ (* (/ (float (+ (point) base)) limit) 100)))
+ (unless (and (> (- (match-end 0) (match-beginning 0)) 0)
+ (match-beginning group)
+ (get-text-property (match-beginning group) 'read-only))
+ (let* (func
+ (text (cond
+ ((and (symbolp repl)
+ (setq func (muse-markup-function repl)))
+ (funcall func))
+ ((functionp repl)
+ (funcall repl))
+ ((symbolp repl)
+ (symbol-value repl))
+ (t repl))))
+ (if (stringp text)
+ (replace-match text t))))
+ (if (and muse-publishing-last-position
+ (= pos muse-publishing-last-position))
+ (if (eobp)
+ (setq regexp nil)
+ (forward-char 1)))
+ (setq muse-publishing-last-position pos)))
+ (setq rules (cdr rules)
+ base (+ base (point-max))))
+ (if (and verbose (not muse-batch-publishing-p))
+ (message "Publishing %s...done" name))))
+
+(defun muse-insert-file-or-string (file-or-string &optional title)
+ (let ((beg (point)) end)
+ (if (and (not (string-equal file-or-string ""))
+ (not (string-match "\n" file-or-string))
+ (file-readable-p file-or-string))
+ (setq end (+ beg
+ (cadr (muse-insert-file-contents file-or-string))))
+ (insert file-or-string)
+ (setq end (point)))
+ (save-restriction
+ (narrow-to-region beg end)
+ (remove-text-properties (point-min) (point-max)
+ '(read-only nil rear-nonsticky nil))
+ (goto-char (point-min))
+ (let ((muse-inhibit-style-tags t)
+ (muse-publish-use-header-footer-tags t))
+ (muse-publish-markup (or title "")
+ '((100 muse-tag-regexp 0
+ muse-publish-markup-tag)))))))
+
+(defun muse-style-run-hooks (keyword style &rest args)
+ (catch 'handled
+ (let ((cache nil))
+ (while (and style
+ (setq style (muse-style style)))
+ (let ((func (muse-style-element keyword style t)))
+ (when (and func
+ (not (member func cache)))
+ (setq cache (cons func cache))
+ (when (apply func args)
+ (throw 'handled t))))
+ (setq style (muse-style-element :base style))))))
+
+(defun muse-publish-markup-region (beg end &optional title style)
+ "Apply the given STYLE's markup rules to the given region.
+TITLE is used when indicating the publishing progress; it may be nil.
+
+The point is guaranteed to be at END if the routine terminates
+normally."
+ (unless title (setq title ""))
+ (unless style
+ (or (setq style muse-publishing-current-style)
+ (error "Cannot find any publishing styles to use")))
+ (save-restriction
+ (narrow-to-region beg end)
+ (let ((muse-publish-generate-contents nil))
+ (unless muse-publish-inhibit-style-hooks
+ (muse-style-run-hooks :before style))
+ (muse-publish-markup
+ title
+ (sort (copy-alist (append muse-publish-markup-regexps
+ (muse-style-elements-list :regexps style)))
+ (function
+ (lambda (l r)
+ (< (car l) (car r))))))
+ (unless muse-publish-inhibit-style-hooks
+ (muse-style-run-hooks :before-end style))
+ (muse-publish-escape-specials (point-min) (point-max) nil 'document))
+ (goto-char (point-max))))
+
+(defun muse-publish-markup-buffer (title style)
+ "Apply the given STYLE's markup rules to the current buffer."
+ (setq style (muse-style style))
+ (let ((style-header (muse-style-element :header style))
+ (style-footer (muse-style-element :footer style))
+ (muse-publishing-current-style style)
+ (muse-publishing-directives
+ (list (cons "title" title)
+ (cons "author" (user-full-name))
+ (cons "date" (format-time-string
+ muse-publish-date-format
+ (if muse-publishing-current-file
+ (nth 5 (file-attributes
+ muse-publishing-current-file))
+ (current-time))))))
+ (muse-publishing-p t)
+ (inhibit-read-only t))
+ (run-hooks 'muse-update-values-hook)
+ (unless muse-inhibit-before-publish-hook
+ (run-hooks 'muse-before-publish-hook))
+ (muse-publish-markup-region (point-min) (point-max) title style)
+ (goto-char (point-min))
+ (when style-header
+ (muse-insert-file-or-string style-header title))
+ (goto-char (point-max))
+ (when style-footer
+ (muse-insert-file-or-string style-footer title))
+ (muse-style-run-hooks :after style)
+ (run-hooks 'muse-after-publish-hook)))
+
+(defun muse-publish-markup-string (string &optional style)
+ "Markup STRING using the given STYLE's markup rules."
+ (setq style (muse-style style))
+ (muse-with-temp-buffer
+ (insert string)
+ (let ((muse-publishing-current-style style)
+ (muse-publishing-p t))
+ (muse-publish-markup "*string*" (muse-style-element :rules style)))
+ (buffer-string)))
+
+;; Commands for publishing files
+
+(defun muse-publish-get-style (&optional styles)
+ (unless styles (setq styles muse-publishing-styles))
+ (if (= 1 (length styles))
+ (car styles)
+ (when (catch 'different
+ (let ((first (car (car styles))))
+ (dolist (style (cdr styles))
+ (unless (equal first (car style))
+ (throw 'different t)))))
+ (setq styles (muse-collect-alist
+ styles
+ (funcall muse-completing-read-function
+ "Publish with style: " styles nil t))))
+ (if (or (= 1 (length styles))
+ (not (muse-get-keyword :path (car styles))))
+ (car styles)
+ (setq styles (mapcar (lambda (style)
+ (cons (muse-get-keyword :path style)
+ style))
+ styles))
+ (cdr (assoc (funcall muse-completing-read-function
+ "Publish to directory: " styles nil t)
+ styles)))))
+
+(defsubst muse-publish-get-output-dir (style)
+ (let ((default-directory (or (muse-style-element :path style)
+ default-directory)))
+ (muse-read-directory-name "Publish to directory: " nil default-directory)))
+
+(defsubst muse-publish-get-info ()
+ (let ((style (muse-publish-get-style)))
+ (list style (muse-publish-get-output-dir style)
+ current-prefix-arg)))
+
+(defsubst muse-publish-output-name (&optional file style)
+ (setq style (muse-style style))
+ (concat (muse-style-element :prefix style)
+ (muse-page-name file)
+ (muse-style-element :suffix style)))
+
+(defsubst muse-publish-output-file (file &optional output-dir style)
+ (setq style (muse-style style))
+ (if output-dir
+ (expand-file-name (muse-publish-output-name file style) output-dir)
+ (concat (file-name-directory file)
+ (muse-publish-output-name file style))))
+
+(defsubst muse-publish-link-name (&optional file style)
+ "Take FILE and add :prefix and either :link-suffix or :suffix from STYLE.
+We assume that FILE is a Muse file.
+
+We call `muse-page-name' on FILE to remove the directory part of
+FILE and any extensions that are in `muse-ignored-extensions'."
+ (setq style (muse-style style))
+ (concat (muse-style-element :prefix style)
+ (muse-page-name file)
+ (or (muse-style-element :link-suffix style)
+ (muse-style-element :suffix style))))
+
+(defsubst muse-publish-link-file (file &optional style)
+ "Turn FILE into a URL.
+
+If FILE exists on the system as-is, return it without
+modification. In the case of wanting to link to Muse files when
+`muse-file-extension' is nil, you should load muse-project.el.
+
+Otherwise, assume that it is a Muse file and call
+`muse-publish-link-name' to add :prefix, :link-suffix, :suffix,
+and removing ignored file extensions, but preserving the
+directory part of FILE."
+ (setq style (muse-style style))
+ (if (file-exists-p file)
+ file
+ (concat (file-name-directory file)
+ (muse-publish-link-name file style))))
+
+(defsubst muse-publish-link-page (page)
+ "Turn PAGE into a URL.
+
+This is called by `muse-publish-classify-url' to figure out what
+a link to another file or Muse page should look like.
+
+If muse-project.el is loaded, call `muse-project-link-page' for this.
+Otherwise, call `muse-publish-link-file'."
+ (if (fboundp 'muse-project-link-page)
+ (muse-project-link-page page)
+ (muse-publish-link-file page)))
+
+(defmacro muse-publish-ensure-block (beg &optional end)
+ "Ensure that block-level markup at BEG is published with at least one
+preceding blank line. BEG must be an unquoted symbol that contains a
+position or marker. BEG is modified to be the new position.
+The point is left at the new value of BEG.
+
+Additionally, make sure that BEG is placed on a blank line.
+
+If END is given, make sure that it is placed on a blank line. In
+order to achieve this, END must be an unquoted symbol that
+contains a marker. This is the case with Muse tag functions."
+ `(progn
+ (goto-char ,beg)
+ (cond ((not (bolp)) (insert "\n\n"))
+ ((eq (point) (point-min)) nil)
+ ((prog2 (backward-char) (bolp) (forward-char)) nil)
+ (t (insert "\n")))
+ (unless (and (bolp) (eolp))
+ (insert "\n")
+ (backward-char))
+ (setq ,beg (point))
+ (when (markerp ,end)
+ (goto-char ,end)
+ (unless (and (bolp) (eolp))
+ (insert-before-markers "\n")))
+ (goto-char ,beg)))
+
+;;;###autoload
+(defun muse-publish-region (beg end &optional title style)
+ "Apply the given STYLE's markup rules to the given region.
+The result is placed in a new buffer that includes TITLE in its name."
+ (interactive "r")
+ (when (interactive-p)
+ (unless title (setq title (read-string "Title: ")))
+ (unless style (setq style (muse-publish-get-style))))
+ (let ((text (buffer-substring beg end))
+ (buf (generate-new-buffer (concat "*Muse: " title "*"))))
+ (with-current-buffer buf
+ (insert text)
+ (muse-publish-markup-buffer title style)
+ (goto-char (point-min))
+ (let ((inhibit-read-only t))
+ (remove-text-properties (point-min) (point-max)
+ '(rear-nonsticky nil read-only nil))))
+ (pop-to-buffer buf)))
+
+;;;###autoload
+(defun muse-publish-file (file style &optional output-dir force)
+ "Publish the given FILE in a particular STYLE to OUTPUT-DIR.
+If the argument FORCE is nil, each file is only published if it is
+newer than the published version. If the argument FORCE is non-nil,
+the file is published no matter what."
+ (interactive (cons (read-file-name "Publish file: ")
+ (muse-publish-get-info)))
+ (let ((style-name style))
+ (setq style (muse-style style))
+ (unless style
+ (error "There is no style '%s' defined" style-name)))
+ (let* ((output-path (muse-publish-output-file file output-dir style))
+ (output-suffix (muse-style-element :osuffix style))
+ (muse-publishing-current-file file)
+ (muse-publishing-current-output-path output-path)
+ (target (if output-suffix
+ (concat (muse-path-sans-extension output-path)
+ output-suffix)
+ output-path))
+ (threshhold (nth 7 (file-attributes file))))
+ (if (not threshhold)
+ (message "Please save %s before publishing" file)
+ (when (or force (file-newer-than-file-p file target))
+ (if (and muse-publish-report-threshhold
+ (> threshhold
+ muse-publish-report-threshhold))
+ (message "Publishing %s ..." file))
+ (muse-with-temp-buffer
+ (muse-insert-file-contents file)
+ (run-hooks 'muse-before-publish-hook)
+ (when muse-publish-enable-local-variables
+ (hack-local-variables))
+ (let ((muse-inhibit-before-publish-hook t))
+ (muse-publish-markup-buffer (muse-page-name file) style))
+ (when (muse-write-file output-path)
+ (muse-style-run-hooks :final style file output-path target)))
+ t))))
+
+;;;###autoload
+(defun muse-publish-this-file (style output-dir &optional force)
+ "Publish the currently-visited file.
+Prompt for both the STYLE and OUTPUT-DIR if they are not
+supplied."
+ (interactive (muse-publish-get-info))
+ (setq style (muse-style style))
+ (if buffer-file-name
+ (let ((muse-current-output-style (list :base (car style)
+ :path output-dir)))
+ (unless (muse-publish-file buffer-file-name style output-dir force)
+ (message (concat "The published version is up-to-date; use"
+ " C-u C-c C-T to force an update."))))
+ (message "This buffer is not associated with any file")))
+
+(defun muse-batch-publish-files ()
+ "Publish Muse files in batch mode."
+ (let ((muse-batch-publishing-p t)
+ (font-lock-verbose nil)
+ muse-current-output-style
+ style output-dir)
+ ;; don't activate VC when publishing files
+ (setq vc-handled-backends nil)
+ (setq style (car command-line-args-left)
+ command-line-args-left (cdr command-line-args-left)
+ output-dir (car command-line-args-left)
+ output-dir
+ (if (string-match "\\`--output-dir=" output-dir)
+ (prog1
+ (substring output-dir (match-end 0))
+ (setq command-line-args-left (cdr command-line-args-left))))
+ muse-current-output-style (list :base style :path output-dir))
+ (setq auto-mode-alist
+ (delete (cons (concat "\\." muse-file-extension "\\'")
+ 'muse-mode-choose-mode)
+ auto-mode-alist))
+ (dolist (file command-line-args-left)
+ (muse-publish-file file style output-dir t))))
+
+;; Default publishing rules
+
+(defun muse-publish-section-close (depth)
+ "Seach forward for the closing tag of given DEPTH."
+ (let (not-end)
+ (save-excursion
+ (while (and (setq not-end (re-search-forward
+ (concat "^\\*\\{1," (number-to-string depth)
+ "\\}\\s-+")
+ nil t))
+ (get-text-property (match-beginning 0) 'read-only)))
+ (if not-end
+ (forward-line 0)
+ (goto-char (point-max)))
+ (cond ((not (eq (char-before) ?\n))
+ (insert "\n\n"))
+ ((not (eq (char-before (1- (point))) ?\n))
+ (insert "\n")))
+ (muse-insert-markup (muse-markup-text 'section-close depth))
+ (insert "\n"))))
+
+(defun muse-publish-markup-directive (&optional name value)
+ (unless name (setq name (match-string 1)))
+ (unless value (setq value (match-string 2)))
+ (let ((elem (assoc name muse-publishing-directives)))
+ (if elem
+ (setcdr elem value)
+ (setq muse-publishing-directives
+ (cons (cons name value)
+ muse-publishing-directives))))
+ ;; Make sure we don't ever try to move the point forward (past the
+ ;; beginning of buffer) while we're still searching for directives.
+ (setq muse-publishing-last-position nil)
+ (delete-region (match-beginning 0) (match-end 0)))
+
+(defsubst muse-publishing-directive (name)
+ (cdr (assoc name muse-publishing-directives)))
+
+(defmacro muse-publish-get-and-delete-attr (attr attrs)
+ "Delete attribute ATTR from ATTRS only once, destructively.
+
+This function returns the matching attribute value, if found."
+ (let ((last (make-symbol "last"))
+ (found (make-symbol "found"))
+ (vals (make-symbol "vals")))
+ `(let ((,vals ,attrs))
+ (if (string= (caar ,vals) ,attr)
+ (prog1 (cdar ,vals)
+ (setq ,attrs (cdr ,vals)))
+ (let ((,last ,vals)
+ (,found nil))
+ (while ,vals
+ (setq ,vals (cdr ,vals))
+ (when (string= (caar ,vals) ,attr)
+ (setq ,found (cdar ,vals))
+ (setcdr ,last (cdr ,vals))
+ (setq ,vals nil))
+ (setq ,last ,vals))
+ ,found)))))
+
+(defun muse-publish-markup-anchor ()
+ (unless (get-text-property (match-end 1) 'muse-link)
+ (let ((text (muse-markup-text 'anchor (match-string 2))))
+ (unless (string= text "")
+ (save-match-data
+ (skip-chars-forward (concat muse-regexp-blank "\n"))
+ (muse-insert-markup text)))
+ (match-string 1))))
+
+(defun muse-publish-markup-comment ()
+ (if (null muse-publish-comments-p)
+ ""
+ (goto-char (match-end 0))
+ (muse-insert-markup (muse-markup-text 'comment-end))
+ (if (match-beginning 1)
+ (progn
+ (muse-publish-mark-read-only (match-beginning 1) (match-end 1))
+ (delete-region (match-beginning 0) (match-beginning 1)))
+ (delete-region (match-beginning 0) (match-end 0)))
+ (goto-char (match-beginning 0))
+ (muse-insert-markup (muse-markup-text 'comment-begin))))
+
+(defun muse-publish-markup-tag ()
+ (let ((tag-info (muse-markup-tag-info (match-string 1))))
+ (when (and tag-info
+ (not (get-text-property (match-beginning 0) 'read-only))
+ (nth 4 tag-info)
+ (or muse-publish-enable-dangerous-tags
+ (not (get (nth 4 tag-info) 'muse-dangerous-tag))))
+ (let ((closed-tag (match-string 3))
+ (start (match-beginning 0))
+ (beg (point))
+ end attrs)
+ (when (nth 2 tag-info)
+ (let ((attrstr (match-string 2)))
+ (while (and attrstr
+ (string-match (concat "\\([^"
+ muse-regexp-blank
+ "=\n]+\\)\\(=\"\\"
+ "([^\"]+\\)\"\\)?")
+ attrstr))
+ (let ((attr (cons (downcase
+ (muse-match-string-no-properties 1 attrstr))
+ (muse-match-string-no-properties 3 attrstr))))
+ (setq attrstr (replace-match "" t t attrstr))
+ (if attrs
+ (nconc attrs (list attr))
+ (setq attrs (list attr)))))))
+ (if (and (cadr tag-info) (not closed-tag))
+ (if (muse-goto-tag-end (car tag-info) (nth 3 tag-info))
+ (delete-region (match-beginning 0) (point))
+ (setq tag-info nil)))
+ (when tag-info
+ (setq end (point-marker))
+ (delete-region start beg)
+ (goto-char start)
+ (let ((args (list start end)))
+ (if (nth 2 tag-info)
+ (nconc args (list attrs)))
+ (let ((muse-inhibit-style-tags nil))
+ ;; remove the inhibition
+ (apply (nth 4 tag-info) args)))
+ (set-marker end nil)))))
+ nil)
+
+(defun muse-publish-escape-specials (beg end &optional ignore-read-only context)
+ "Escape specials from BEG to END using style-specific :specials.
+If IGNORE-READ-ONLY is non-nil, ignore the read-only property.
+CONTEXT is used to figure out what kind of specials to escape.
+
+The following contexts exist in Muse.
+'underline _underlined text_
+'literal =monospaced text= or <code> region (monospaced, escaped)
+'emphasis *emphasized text*
+'email email@example.com
+'url http://example.com
+'url-desc [[...][description of an explicit link]]
+'image [[image.png]]
+'example <example> region (monospaced, block context, escaped)
+'verbatim <verbatim> region (escaped)
+'footnote footnote text
+'document normal text"
+ (let ((specials (muse-style-element :specials nil t)))
+ (cond ((functionp specials)
+ (setq specials (funcall specials context)))
+ ((symbolp specials)
+ (setq specials (symbol-value specials))))
+ (if (functionp specials)
+ (funcall specials beg end ignore-read-only)
+ (save-excursion
+ (save-restriction
+ (narrow-to-region beg end)
+ (goto-char (point-min))
+ (while (< (point) (point-max))
+ (if (and (not ignore-read-only)
+ (get-text-property (point) 'read-only))
+ (goto-char (or (next-single-property-change (point) 'read-only)
+ (point-max)))
+ (let ((repl (or (assoc (char-after) specials)
+ (assoc (char-after)
+ muse-publish-markup-specials))))
+ (if (null repl)
+ (forward-char 1)
+ (delete-char 1)
+ (insert-before-markers (cdr repl)))))))))))
+
+(defun muse-publish-markup-word ()
+ (let* ((beg (match-beginning 2))
+ (end (1- (match-end 2)))
+ (leader (buffer-substring-no-properties beg end))
+ open-tag close-tag mark-read-only loc context)
+ (cond
+ ((string= leader "_")
+ (setq context 'underline
+ open-tag (muse-markup-text 'begin-underline)
+ close-tag (muse-markup-text 'end-underline)))
+ ((string= leader "=")
+ (setq context 'literal
+ open-tag (muse-markup-text 'begin-literal)
+ close-tag (muse-markup-text 'end-literal))
+ (setq mark-read-only t))
+ (t
+ (let ((l (length leader)))
+ (setq context 'emphasis)
+ (cond
+ ((= l 1) (setq open-tag (muse-markup-text 'begin-emph)
+ close-tag (muse-markup-text 'end-emph)))
+ ((= l 2) (setq open-tag (muse-markup-text 'begin-more-emph)
+ close-tag (muse-markup-text 'end-more-emph)))
+ ((= l 3) (setq open-tag (muse-markup-text 'begin-most-emph)
+ close-tag (muse-markup-text 'end-most-emph)))
+ (t (setq context nil))))))
+ (if (and context
+ (not (get-text-property beg 'muse-link))
+ (setq loc (search-forward leader nil t))
+ (or (eobp) (not (eq (char-syntax (char-after loc)) ?w)))
+ (not (eq (char-syntax (char-before (point))) ?\ ))
+ (not (get-text-property (point) 'muse-link)))
+ (progn
+ (replace-match "")
+ (delete-region beg end)
+ (setq end (point-marker))
+ (muse-insert-markup close-tag)
+ (goto-char beg)
+ (muse-insert-markup open-tag)
+ (setq beg (point))
+ (when mark-read-only
+ (muse-publish-escape-specials beg end t context)
+ (muse-publish-mark-read-only beg end))
+ (set-marker end nil))
+ (backward-char))
+ nil))
+
+(defun muse-publish-markup-emdash ()
+ (unless (get-text-property (match-beginning 0) 'muse-link)
+ (let ((prespace (match-string 1))
+ (postspace (match-string 2)))
+ (delete-region (match-beginning 0) (match-end 0))
+ (muse-insert-markup (muse-markup-text 'emdash prespace postspace))
+ (when (eq (char-after) ?\<)
+ (insert ?\n)))))
+
+(defun muse-publish-markup-enddots ()
+ (unless (get-text-property (match-beginning 0) 'muse-link)
+ (delete-region (match-beginning 0) (match-end 0))
+ (muse-insert-markup (muse-markup-text 'enddots))))
+
+(defun muse-publish-markup-dots ()
+ (unless (get-text-property (match-beginning 0) 'muse-link)
+ (delete-region (match-beginning 0) (match-end 0))
+ (muse-insert-markup (muse-markup-text 'dots))))
+
+(defun muse-publish-markup-rule ()
+ (unless (get-text-property (match-beginning 0) 'muse-link)
+ (delete-region (match-beginning 0) (match-end 0))
+ (muse-insert-markup (muse-markup-text 'rule))))
+
+(defun muse-publish-markup-no-break-space ()
+ (unless (get-text-property (match-beginning 0) 'muse-link)
+ (delete-region (match-beginning 0) (match-end 0))
+ (muse-insert-markup (muse-markup-text 'no-break-space))))
+
+(defun muse-publish-markup-heading ()
+ (let* ((len (length (match-string 1)))
+ (start (muse-markup-text
+ (cond ((= len 1) 'section)
+ ((= len 2) 'subsection)
+ ((= len 3) 'subsubsection)
+ (t 'section-other))
+ len))
+ (end (muse-markup-text
+ (cond ((= len 1) 'section-end)
+ ((= len 2) 'subsection-end)
+ ((= len 3) 'subsubsection-end)
+ (t 'section-other-end))
+ len)))
+ (delete-region (match-beginning 0) (match-end 0))
+ (muse-insert-markup start)
+ (end-of-line)
+ (when end
+ (muse-insert-markup end))
+ (forward-line 1)
+ (unless (eq (char-after) ?\n)
+ (insert "\n"))
+ (muse-publish-section-close len)))
+
+(defvar muse-publish-footnotes nil)
+
+(defun muse-publish-markup-footnote ()
+ "Scan ahead and snarf up the footnote body."
+ (cond
+ ((get-text-property (match-beginning 0) 'muse-link)
+ nil)
+ ((= (muse-line-beginning-position) (match-beginning 0))
+ "")
+ (t
+ (let ((footnote (save-match-data
+ (string-to-number (match-string 1))))
+ (oldtext (match-string 0))
+ footnotemark)
+ (delete-region (match-beginning 0) (match-end 0))
+ (save-excursion
+ (when (re-search-forward (format "^\\[%d\\]\\s-+" footnote) nil t)
+ (let* ((start (match-beginning 0))
+ (beg (goto-char (match-end 0)))
+ (end (save-excursion
+ (if (search-forward "\n\n" nil t)
+ (copy-marker (match-beginning 0))
+ (goto-char (point-max))
+ (skip-chars-backward "\n")
+ (point-marker)))))
+ (while (re-search-forward
+ (concat "^[" muse-regexp-blank "]+\\([^\n]\\)")
+ end t)
+ (replace-match "\\1" t))
+ (let ((footnotemark-cmd (muse-markup-text 'footnotemark))
+ (footnotemark-end-cmd (muse-markup-text 'footnotemark-end)))
+ (if (string= "" footnotemark-cmd)
+ (setq footnotemark
+ (concat (muse-markup-text 'footnote)
+ (muse-publish-escape-specials-in-string
+ (buffer-substring-no-properties beg end)
+ 'footnote)
+ (muse-markup-text 'footnote-end)))
+ (setq footnotemark (format footnotemark-cmd footnote
+ footnotemark-end-cmd))
+ (unless muse-publish-footnotes
+ (set (make-local-variable 'muse-publish-footnotes)
+ (make-vector 256 nil)))
+ (unless (aref muse-publish-footnotes footnote)
+ (setq footnotemark
+ (concat
+ footnotemark
+ (concat (format (muse-markup-text 'footnotetext)
+ footnote)
+ (buffer-substring-no-properties beg end)
+ (muse-markup-text 'footnotetext-end))))
+ (aset muse-publish-footnotes footnote footnotemark))))
+ (goto-char end)
+ (skip-chars-forward "\n")
+ (delete-region start (point))
+ (set-marker end nil))))
+ (if footnotemark
+ (muse-insert-markup footnotemark)
+ (insert oldtext))))))
+
+(defun muse-publish-markup-fn-sep ()
+ (delete-region (match-beginning 0) (match-end 0))
+ (muse-insert-markup (muse-markup-text 'fn-sep)))
+
+(defun muse-insert-markup-end-list (&rest args)
+ (let ((beg (point)))
+ (apply 'insert args)
+ (add-text-properties beg (point) '(muse-end-list t))
+ (muse-publish-mark-read-only beg (point))))
+
+(defun muse-publish-determine-dl-indent (continue indent-sym determine-sym)
+ ;; If the caller doesn't know how much indentation to use, figure it
+ ;; out ourselves. It is assumed that `muse-forward-list-item' has
+ ;; been called just before this to set the match data.
+ (when (and continue
+ (symbol-value determine-sym))
+ (save-match-data
+ ;; snarf all leading whitespace
+ (let ((indent (and (match-beginning 2)
+ (buffer-substring (match-beginning 1)
+ (match-beginning 2)))))
+ (when (and indent
+ (not (string= indent "")))
+ (set indent-sym indent)
+ (set determine-sym nil))))))
+
+(defun muse-publish-surround-dl (indent post-indent)
+ (let* ((beg-item (muse-markup-text 'begin-dl-item))
+ (end-item (muse-markup-text 'end-dl-item))
+ (beg-ddt (muse-markup-text 'begin-ddt)) ;; term
+ (end-ddt (muse-markup-text 'end-ddt))
+ (beg-dde (muse-markup-text 'begin-dde)) ;; definition
+ (end-dde (muse-markup-text 'end-dde))
+ (continue t)
+ (no-terms t)
+ beg)
+ (while continue
+ ;; envelope this as one term+definitions unit -- HTML does not
+ ;; need this, but DocBook and Muse's custom XML format do
+ (muse-insert-markup beg-item)
+ (when (looking-at muse-dl-term-regexp)
+ ;; find the term and wrap it with published markup
+ (setq beg (point)
+ no-terms nil)
+ (goto-char (match-end 1))
+ (delete-region (point) (match-end 0))
+ (muse-insert-markup-end-list end-ddt)
+ ;; if definition is immediately after term, move to next line
+ (unless (eq (char-after) ?\n)
+ (insert ?\n))
+ (save-excursion
+ (goto-char beg)
+ (delete-region (point) (match-beginning 1))
+ (muse-insert-markup beg-ddt)))
+ ;; handle pathological edge case where there is no term -- I
+ ;; would prefer to just disallow this, but people seem to want
+ ;; this behavior
+ (when (and no-terms
+ (looking-at (concat "[" muse-regexp-blank "]*::"
+ "[" muse-regexp-blank "]*")))
+ (delete-region (point) (match-end 0))
+ ;; but only do this once
+ (setq no-terms nil))
+ (setq beg (point)
+ ;; move past current item
+ continue (muse-forward-list-item 'dl-term indent))
+ (save-restriction
+ (narrow-to-region beg (point))
+ (goto-char (point-min))
+ ;; publish each definition that we find, defaulting to an
+ ;; empty definition if none are found
+ (muse-publish-surround-text beg-dde end-dde
+ (lambda (indent)
+ (muse-forward-list-item 'dl-entry indent))
+ indent post-indent
+ #'muse-publish-determine-dl-indent)
+ (goto-char (point-max))
+ (skip-chars-backward (concat muse-regexp-blank "\n"))
+ (muse-insert-markup-end-list end-item)
+ (when continue
+ (goto-char (point-max)))))))
+
+(defun muse-publish-strip-list-indentation (list-item empty-line indent post-indent)
+ (let ((list-nested nil)
+ (indent-found nil))
+ (while (< (point) (point-max))
+ (when (and (looking-at list-item)
+ (not (or (get-text-property
+ (muse-list-item-critical-point) 'read-only)
+ (get-text-property
+ (muse-list-item-critical-point) 'muse-link))))
+ ;; if we encounter a list item, allow no post-indent space
+ (setq list-nested t))
+ (when (and (not (looking-at empty-line))
+ (looking-at (concat indent "\\("
+ (or (and list-nested "")
+ post-indent)
+ "\\)")))
+ ;; if list is not nested, remove indentation
+ (unless indent-found
+ (setq post-indent (match-string 1)
+ indent-found t))
+ (replace-match ""))
+ (forward-line 1))))
+
+(defun muse-publish-surround-text (beg-tag end-tag move-func &optional indent post-indent determine-indent-func list-item)
+ (unless list-item
+ (setq list-item (format muse-list-item-regexp
+ (concat "[" muse-regexp-blank "]*"))))
+ (let ((continue t)
+ (empty-line (concat "^[" muse-regexp-blank "]*\n"))
+ (determine-indent (if determine-indent-func t nil))
+ (new-indent indent)
+ (first t)
+ beg)
+ (unless indent
+ (setq indent (concat "[" muse-regexp-blank "]+")))
+ (if post-indent
+ (setq post-indent (concat " \\{0," (number-to-string post-indent)
+ "\\}"))
+ (setq post-indent ""))
+ (while continue
+ (if (or (not end-tag) (string= end-tag ""))
+ ;; if no end of list item markup exists, treat the beginning
+ ;; of list item markup as it if it were the end -- this
+ ;; prevents multiple-level lists from being confused
+ (muse-insert-markup-end-list beg-tag)
+ (muse-insert-markup beg-tag))
+ (setq beg (point)
+ ;; move past current item; continue is non-nil if there
+ ;; are more like items to be processed
+ continue (if (and determine-indent-func first)
+ (funcall move-func (concat indent post-indent))
+ (funcall move-func indent)))
+ (when determine-indent-func
+ (funcall determine-indent-func continue 'new-indent 'determine-indent))
+ (when continue
+ ;; remove list markup if we encountered another item of the
+ ;; same type
+ (replace-match "" t t nil 1))
+ (save-restriction
+ ;; narrow to current item
+ (narrow-to-region beg (point))
+ (goto-char (point-min))
+ (if (looking-at empty-line)
+ ;; if initial line is blank, move to first non-blank line
+ (while (progn (forward-line 1)
+ (and (< (point) (point-max))
+ (looking-at empty-line))))
+ ;; otherwise, move to second line of text
+ (forward-line 1))
+ ;; strip list indentation
+ (muse-publish-strip-list-indentation list-item empty-line
+ indent post-indent)
+ (skip-chars-backward (concat muse-regexp-blank "\n"))
+ (muse-insert-markup-end-list end-tag)
+ (when determine-indent-func
+ (setq indent new-indent))
+ (when first
+ (setq first nil))
+ (when continue
+ (goto-char (point-max)))))))
+
+(defun muse-publish-ensure-blank-line ()
+ "Make sure that a blank line exists on the line before point."
+ (let ((pt (point-marker)))
+ (beginning-of-line)
+ (cond ((eq (point) (point-min)) nil)
+ ((prog2 (backward-char) (bolp) (forward-char)) nil)
+ (t (insert-before-markers "\n")))
+ (goto-char pt)
+ (set-marker pt nil)))
+
+(defun muse-publish-markup-list ()
+ "Markup a list entry.
+This function works by marking up items of the same list level
+and type, respecting the end-of-list property."
+ (let* ((str (match-string 1))
+ (type (muse-list-item-type str))
+ (indent (buffer-substring (muse-line-beginning-position)
+ (match-beginning 1)))
+ (post-indent (length str)))
+ (cond
+ ((or (get-text-property (muse-list-item-critical-point) 'read-only)
+ (get-text-property (muse-list-item-critical-point) 'muse-link))
+ nil)
+ ((eq type 'ul)
+ (unless (eq (char-after (match-end 1)) ?-)
+ (delete-region (match-beginning 0) (match-end 0))
+ (muse-publish-ensure-blank-line)
+ (muse-insert-markup (muse-markup-text 'begin-uli))
+ (save-excursion
+ (muse-publish-surround-text
+ (muse-markup-text 'begin-uli-item)
+ (muse-markup-text 'end-uli-item)
+ (lambda (indent)
+ (muse-forward-list-item 'ul indent))
+ indent post-indent)
+ (muse-insert-markup-end-list (muse-markup-text 'end-uli)))
+ (forward-line 1)))
+ ((eq type 'ol)
+ (delete-region (match-beginning 0) (match-end 0))
+ (muse-publish-ensure-blank-line)
+ (muse-insert-markup (muse-markup-text 'begin-oli))
+ (save-excursion
+ (muse-publish-surround-text
+ (muse-markup-text 'begin-oli-item)
+ (muse-markup-text 'end-oli-item)
+ (lambda (indent)
+ (muse-forward-list-item 'ol indent))
+ indent post-indent)
+ (muse-insert-markup-end-list (muse-markup-text 'end-oli)))
+ (forward-line 1))
+ (t
+ (goto-char (match-beginning 0))
+ (muse-publish-ensure-blank-line)
+ (muse-insert-markup (muse-markup-text 'begin-dl))
+ (save-excursion
+ (muse-publish-surround-dl indent post-indent)
+ (muse-insert-markup-end-list (muse-markup-text 'end-dl)))
+ (forward-line 1))))
+ nil)
+
+(defun muse-publish-markup-quote ()
+ "Markup a quoted paragraph.
+The reason this function is so funky, is to prevent text properties
+like read-only from being inadvertently deleted."
+ (let* ((ws (match-string 1))
+ (centered (>= (string-width ws) 6))
+ (begin-elem (if centered 'begin-center 'begin-quote-item))
+ (end-elem (if centered 'end-center 'end-quote-item)))
+ (replace-match "" t t nil 1)
+ (unless centered
+ (muse-insert-markup (muse-markup-text 'begin-quote)))
+ (muse-publish-surround-text (muse-markup-text begin-elem)
+ (muse-markup-text end-elem)
+ (function (lambda (indent)
+ (muse-forward-paragraph)
+ nil)))
+ (unless centered
+ (muse-insert-markup (muse-markup-text 'end-quote)))))
+
+(defun muse-publish-markup-leading-space (markup-space multiple)
+ (let (count)
+ (when (and markup-space
+ (>= (setq count (skip-chars-forward " ")) 0))
+ (delete-region (muse-line-beginning-position) (point))
+ (while (> count 0)
+ (muse-insert-markup markup-space)
+ (setq count (- count multiple))))))
+
+(defun muse-publish-markup-verse ()
+ (let ((leader (match-string 0)))
+ (goto-char (match-beginning 0))
+ (muse-insert-markup (muse-markup-text 'begin-verse))
+ (while (looking-at leader)
+ (replace-match "")
+ (muse-publish-markup-leading-space (muse-markup-text 'verse-space) 2)
+ (let ((beg (point)))
+ (end-of-line)
+ (cond
+ ((bolp)
+ (let ((text (muse-markup-text 'empty-verse-line)))
+ (when text (muse-insert-markup text))))
+ ((save-excursion
+ (save-match-data
+ (forward-line 1)
+ (or (looking-at (concat leader "["
+ muse-regexp-blank
+ "]*$"))
+ (not (looking-at leader)))))
+ (let ((begin-text (muse-markup-text 'begin-last-stanza-line))
+ (end-text (muse-markup-text 'end-last-stanza-line)))
+ (when end-text (muse-insert-markup end-text))
+ (goto-char beg)
+ (when begin-text (muse-insert-markup begin-text))
+ (end-of-line)))
+ (t
+ (let ((begin-text (muse-markup-text 'begin-verse-line))
+ (end-text (muse-markup-text 'end-verse-line)))
+ (when end-text (muse-insert-markup end-text))
+ (goto-char beg)
+ (when begin-text (muse-insert-markup begin-text))
+ (end-of-line))))
+ (forward-line 1))))
+ (muse-insert-markup (muse-markup-text 'end-verse))
+ (insert ?\n))
+
+(defun muse-publish-trim-table (table)
+ "Remove completely blank columns from table, if at start or end of row."
+ ;; remove first
+ (catch 'found
+ (dolist (row (cdr table))
+ (let ((el (cadr row)))
+ (when (and (stringp el) (not (string= el "")))
+ (throw 'found t))))
+ (dolist (row (cdr table))
+ (setcdr row (cddr row)))
+ (setcar table (1- (car table))))
+ ;; remove last
+ (catch 'found
+ (dolist (row (cdr table))
+ (let ((el (car (last row))))
+ (when (and (stringp el) (not (string= el "")))
+ (throw 'found t))))
+ (dolist (row (cdr table))
+ (setcdr (last row 2) nil))
+ (setcar table (1- (car table))))
+ table)
+
+(defun muse-publish-table-fields (beg end)
+ "Parse given region as a table, returning a cons cell.
+The car is the length of the longest row.
+
+The cdr is a list of the fields of the table, with the first
+element indicating the type of the row:
+ 1: body, 2: header, 3: footer, hline: separator.
+
+The existing region will be removed, except for initial blank lines."
+ (unless (muse-publishing-directive "disable-tables")
+ (let ((longest 0)
+ (left 0)
+ (seen-hline nil)
+ fields field-list)
+ (save-restriction
+ (narrow-to-region beg end)
+ (goto-char (point-min))
+ (while (looking-at (concat "^[" muse-regexp-blank "]*$"))
+ (forward-line 1))
+ (setq beg (point))
+ (while (= left 0)
+ (cond
+ ((looking-at muse-table-hline-regexp)
+ (when field-list ; skip if at the beginning of table
+ (if seen-hline
+ (setq field-list (cons (cons 'hline nil) field-list))
+ (dolist (field field-list)
+ ;; the preceding fields are header lines
+ (setcar field 2))
+ (setq seen-hline t))))
+ ((looking-at muse-table-line-regexp)
+ (setq fields (cons (length (match-string 1))
+ (mapcar #'muse-trim-whitespace
+ (split-string (match-string 0)
+ muse-table-field-regexp)))
+ field-list (cons fields field-list)
+ longest (max (length fields) longest))
+ ;; strip initial bars, if they exist
+ (let ((first (cadr fields)))
+ (when (and first (string-match "\\`|+\\s-*" first))
+ (setcar (cdr fields) (replace-match "" t t first))))))
+ (setq left (forward-line 1))))
+ (delete-region beg end)
+ (if (= longest 0)
+ (cons 0 nil)
+ ;; if the last line was an hline, remove it
+ (when (eq (caar field-list) 'hline)
+ (setq field-list (cdr field-list)))
+ (muse-publish-trim-table (cons (1- longest) (nreverse field-list)))))))
+
+(defun muse-publish-markup-table ()
+ "Style does not support tables.\n")
+
+(defun muse-publish-table-el-table (variant)
+ "Publish table.el-style tables in the format given by VARIANT."
+ (when (condition-case nil
+ (progn (require 'table)
+ t)
+ (error nil))
+ (let ((muse-buf (current-buffer)))
+ (save-restriction
+ (narrow-to-region (match-beginning 0) (match-end 0))
+ (goto-char (point-min))
+ (forward-line 1)
+ (when (search-forward "|" nil t)
+ (with-temp-buffer
+ (let ((temp-buf (current-buffer)))
+ (with-current-buffer muse-buf
+ (table-generate-source variant temp-buf))
+ (with-current-buffer muse-buf
+ (delete-region (point-min) (point-max))
+ (insert-buffer-substring temp-buf)
+ (muse-publish-mark-read-only (point-min) (point-max))))))))))
+
+(defun muse-publish-markup-table-el ()
+ "Mark up table.el-style tables."
+ (cond ((muse-style-derived-p 'html)
+ (muse-publish-table-el-table 'html))
+ ((muse-style-derived-p 'latex)
+ (muse-publish-table-el-table 'latex))
+ ((muse-style-derived-p 'docbook)
+ (muse-publish-table-el-table 'cals))
+ (t "Style does not support table.el tables.\n")))
+
+(defun muse-publish-escape-specials-in-string (string &optional context)
+ "Escape specials in STRING using style-specific :specials.
+CONTEXT is used to figure out what kind of specials to escape.
+
+See the documentation of the `muse-publish-escape-specials'
+function for the list of available contexts."
+ (unless string
+ (setq string ""))
+ (let ((specials (muse-style-element :specials nil t)))
+ (cond ((functionp specials)
+ (setq specials (funcall specials context)))
+ ((symbolp specials)
+ (setq specials (symbol-value specials))))
+ (if (functionp specials)
+ (funcall specials string)
+ (apply (function concat)
+ (mapcar
+ (lambda (ch)
+ (let ((repl (or (assoc ch specials)
+ (assoc ch muse-publish-markup-specials))))
+ (if (null repl)
+ (char-to-string ch)
+ (cdr repl))))
+ (append string nil))))))
+
+(defun muse-publish-markup-email ()
+ (let* ((beg (match-end 1))
+ (addr (buffer-substring-no-properties beg (match-end 0))))
+ (setq addr (muse-publish-escape-specials-in-string addr 'email))
+ (goto-char beg)
+ (delete-region beg (match-end 0))
+ (if (or (eq (char-before (match-beginning 0)) ?\")
+ (eq (char-after (match-end 0)) ?\"))
+ (insert addr)
+ (insert (format (muse-markup-text 'email-addr) addr addr)))
+ (muse-publish-mark-read-only beg (point))))
+
+(defun muse-publish-classify-url (target)
+ "Transform anchors and get published name, if TARGET is a page.
+The return value is two linked cons cells. The car is the type
+of link, the cadr is the page name, and the cddr is the anchor."
+ (save-match-data
+ (cond ((or (null target) (string= target ""))
+ nil)
+ ((string-match "\\`[uU][rR][lL]:\\(.+\\)\\'" target)
+ (cons 'url (cons (match-string 1 target) nil)))
+ ((string-match muse-image-regexp target)
+ (cons 'image (cons target nil)))
+ ((string-match muse-url-regexp target)
+ (cons 'url (cons target nil)))
+ ((string-match muse-file-regexp target)
+ (cons 'file (cons target nil)))
+ ((string-match "#" target)
+ (if (eq (aref target 0) ?\#)
+ (cons 'anchor-ref (cons nil (substring target 1)))
+ (cons 'link-and-anchor
+ ;; match-data is changed by
+ ;; `muse-publish-link-page' or descendants.
+ (cons (save-match-data
+ (muse-publish-link-page
+ (substring target 0 (match-beginning 0))))
+ (substring target (match-end 0))))))
+ (t
+ (cons 'link (cons (muse-publish-link-page target) nil))))))
+
+(defun muse-publish-url-desc (desc explicit)
+ (when desc
+ (dolist (transform muse-publish-desc-transforms)
+ (setq desc (save-match-data
+ (when desc (funcall transform desc explicit)))))
+ (setq desc (muse-link-unescape desc))
+ (muse-publish-escape-specials-in-string desc 'url-desc)))
+
+(defun muse-publish-url (url &optional desc orig-url explicit)
+ "Resolve a URL into its final <a href> form."
+ (let ((unesc-url url)
+ (unesc-orig-url orig-url)
+ (unesc-desc desc)
+ type anchor)
+ ;; Transform URL
+ (dolist (transform muse-publish-url-transforms)
+ (setq url (save-match-data (when url (funcall transform url explicit)))))
+ ;; Classify URL
+ (let ((target (muse-publish-classify-url url)))
+ (setq type (car target)
+ url (if (eq type 'image)
+ (muse-publish-escape-specials-in-string (cadr target)
+ 'image)
+ (muse-publish-escape-specials-in-string (cadr target) 'url))
+ anchor (muse-publish-escape-specials-in-string
+ (cddr target) 'url)))
+ ;; Transform description
+ (if desc
+ (setq desc (muse-publish-url-desc desc explicit))
+ (when orig-url
+ (setq orig-url (muse-publish-url-desc orig-url explicit))))
+ ;; Act on URL classification
+ (cond ((eq type 'anchor-ref)
+ (muse-markup-text 'anchor-ref anchor (or desc orig-url)))
+ ((and unesc-desc (string-match muse-image-regexp unesc-desc))
+ (let ((ext (or (file-name-extension desc) "")))
+ (setq desc (muse-publish-escape-specials-in-string unesc-desc
+ 'image))
+ (setq desc (muse-path-sans-extension desc))
+ (muse-markup-text 'image-link url desc ext)))
+ ((string= url "")
+ desc)
+ ((eq type 'image)
+ (let ((ext (or (file-name-extension url) "")))
+ (setq url (muse-path-sans-extension url))
+ (if desc
+ (muse-markup-text 'image-with-desc url ext desc)
+ (muse-markup-text 'image url ext))))
+ ((eq type 'link-and-anchor)
+ (muse-markup-text 'link-and-anchor url anchor
+ (or desc orig-url)
+ (muse-path-sans-extension url)))
+ ((eq type 'link)
+ (muse-markup-text 'link url (or desc orig-url)))
+ (t
+ (or (and (or desc
+ ;; compare the not-escaped versions of url and
+ ;; orig-url
+ (not (string= unesc-url unesc-orig-url)))
+ (let ((text (muse-markup-text 'url-and-desc url
+ (or desc orig-url))))
+ (and (not (string= text ""))
+ text)))
+ (muse-markup-text 'url url (or desc orig-url)))))))
+
+(defun muse-publish-insert-url (url &optional desc orig-url explicit)
+ "Resolve a URL into its final <a href> form."
+ (delete-region (match-beginning 0) (match-end 0))
+ (let ((text (muse-publish-url url desc orig-url explicit)))
+ (when text
+ (muse-insert-markup text))))
+
+(defun muse-publish-markup-link ()
+ (let (desc explicit orig-link link)
+ (setq explicit (save-match-data
+ (if (string-match muse-explicit-link-regexp
+ (match-string 0))
+ t nil)))
+ (setq orig-link (if explicit (match-string 1) (match-string 0)))
+ (setq desc (when explicit (match-string 2)))
+ (setq link (if explicit
+ (muse-handle-explicit-link orig-link)
+ (muse-handle-implicit-link orig-link)))
+ (when (and link
+ (or explicit
+ (not (or (eq (char-before (match-beginning 0)) ?\")
+ (eq (char-after (match-end 0)) ?\")))))
+ ;; if explicit link has no user-provided description, treat it
+ ;; as if it were an implicit link
+ (when (and explicit (not desc))
+ (setq explicit nil))
+ (muse-publish-insert-url link desc orig-link explicit))))
+
+(defun muse-publish-markup-url ()
+ (unless (or (eq (char-before (match-beginning 0)) ?\")
+ (eq (char-after (match-end 0)) ?\"))
+ (let ((url (match-string 0)))
+ (muse-publish-insert-url url nil url))))
+
+;; Default publishing tags
+
+(defcustom muse-publish-contents-depth 2
+ "The number of heading levels to include with <contents> tags."
+ :type 'integer
+ :group 'muse-publish)
+
+(defun muse-publish-contents-tag (beg end attrs)
+ (set (make-local-variable 'muse-publish-generate-contents)
+ (cons (copy-marker (point) t)
+ (let ((depth (cdr (assoc "depth" attrs))))
+ (or (and depth (string-to-number depth))
+ muse-publish-contents-depth)))))
+
+(defun muse-publish-verse-tag (beg end)
+ (muse-publish-ensure-block beg end)
+ (save-excursion
+ (save-restriction
+ (narrow-to-region beg end)
+ (goto-char (point-min))
+ (delete-char 1)
+ (while (< (point) (point-max))
+ (insert "> ")
+ (forward-line))
+ (if (eq ?\ (char-syntax (char-before)))
+ (delete-char -1)))))
+
+(defun muse-publish-mark-read-only (beg end)
+ "Add read-only properties to the given region."
+ (add-text-properties beg end '(rear-nonsticky (read-only) read-only t))
+ nil)
+
+(defun muse-publish-mark-link (&optional beg end)
+ "Indicate that the given region is a Muse link, so that other
+markup elements respect it. If a region is not specified, use
+the 0th match data to determine it.
+
+This is usually applied to explicit links."
+ (unless beg (setq beg (match-beginning 0)))
+ (unless end (setq end (match-end 0)))
+ (add-text-properties beg end '(muse-link t))
+ nil)
+
+(defun muse-publish-quote-tag (beg end)
+ (muse-publish-ensure-block beg)
+ (save-excursion
+ (save-restriction
+ (narrow-to-region beg end)
+ (let ((quote-regexp "^\\(<\\(/?\\)quote>\\)"))
+ (muse-insert-markup (muse-markup-text 'begin-quote))
+ (while (progn
+ (unless (looking-at (concat "[" muse-regexp-blank "\n]*"
+ "<quote>"))
+ (muse-publish-surround-text
+ (muse-markup-text 'begin-quote-item)
+ (muse-markup-text 'end-quote-item)
+ (function
+ (lambda (indent)
+ (muse-forward-paragraph)
+ (goto-char (match-end 0))
+ (and (< (point) (point-max))
+ (not (looking-at quote-regexp)))))
+ nil nil nil
+ quote-regexp))
+ (if (>= (point) (point-max))
+ t
+ (and (search-forward "<quote>" nil t)
+ (muse-goto-tag-end "quote" t)
+ (progn (forward-line 1) t)
+ (< (point) (point-max))))))
+ (goto-char (point-max))
+ (muse-insert-markup (muse-markup-text 'end-quote))))))
+
+(defun muse-publish-code-tag (beg end)
+ (muse-publish-escape-specials beg end nil 'literal)
+ (goto-char beg)
+ (insert (muse-markup-text 'begin-literal))
+ (goto-char end)
+ (insert (muse-markup-text 'end-literal))
+ (muse-publish-mark-read-only beg (point)))
+
+(defun muse-publish-cite-tag (beg end attrs)
+ (let* ((type (muse-publish-get-and-delete-attr "type" attrs))
+ (citetag (cond ((string-equal type "author")
+ 'begin-cite-author)
+ ((string-equal type "year")
+ 'begin-cite-year)
+ (t
+ 'begin-cite))))
+ (goto-char beg)
+ (insert (muse-markup-text citetag (muse-publishing-directive "bibsource")))
+ (goto-char end)
+ (insert (muse-markup-text 'end-cite))
+ (muse-publish-mark-read-only beg (point))))
+
+(defun muse-publish-src-tag (beg end attrs)
+ (muse-publish-example-tag beg end))
+
+(defun muse-publish-example-tag (beg end)
+ (muse-publish-ensure-block beg end)
+ (muse-publish-escape-specials beg end nil 'example)
+ (goto-char beg)
+ (insert (muse-markup-text 'begin-example))
+ (goto-char end)
+ (insert (muse-markup-text 'end-example))
+ (muse-publish-mark-read-only beg (point)))
+
+(defun muse-publish-literal-tag (beg end attrs)
+ "Ensure that the text between BEG and END is not interpreted later on.
+
+ATTRS is an alist of attributes.
+
+If it contains a \"style\" element, delete the region if the
+current style is neither derived from nor equal to this style.
+
+If it contains both a \"style\" element and an \"exact\" element
+with the value \"t\", delete the region only if the current style
+is exactly this style."
+ (let* ((style (cdr (assoc "style" attrs)))
+ (exact (cdr (assoc "exact" attrs)))
+ (exactp (and (stringp exact) (string= exact "t"))))
+ (if (or (not style)
+ (and exactp (equal (muse-style style)
+ muse-publishing-current-style))
+ (and (not exactp) (muse-style-derived-p style)))
+ (muse-publish-mark-read-only beg end)
+ (delete-region beg end)
+ (when (and (bolp) (eolp) (not (eobp)))
+ (delete-char 1)))))
+
+(put 'muse-publish-literal-tag 'muse-dangerous-tag t)
+
+(defun muse-publish-verbatim-tag (beg end)
+ (muse-publish-escape-specials beg end nil 'verbatim)
+ (muse-publish-mark-read-only beg end))
+
+(defun muse-publish-br-tag (beg end)
+ "Insert a line break."
+ (delete-region beg end)
+ (muse-insert-markup (muse-markup-text 'line-break)))
+
+(defalias 'muse-publish-class-tag 'ignore)
+(defalias 'muse-publish-div-tag 'ignore)
+
+(defun muse-publish-call-tag-on-buffer (tag &optional attrs)
+ "Transform the current buffer as if it were surrounded by the tag TAG.
+If attributes ATTRS are given, pass them to the tag function."
+ (let ((tag-info (muse-markup-tag-info tag)))
+ (when tag-info
+ (let* ((end (progn (goto-char (point-max)) (point-marker)))
+ (args (list (point-min) end))
+ (muse-inhibit-style-tags nil))
+ (when (nth 2 tag-info)
+ (nconc args (list attrs)))
+ (apply (nth 4 tag-info) args)
+ (set-marker end nil)))))
+
+(defun muse-publish-examplify-buffer (&optional attrs)
+ "Transform the current buffer as if it were an <example> region."
+ (muse-publish-call-tag-on-buffer "example" attrs))
+
+(defun muse-publish-srcify-buffer (&optional attrs)
+ "Transform the current buffer as if it were a <src> region."
+ (muse-publish-call-tag-on-buffer "src" attrs))
+
+(defun muse-publish-versify-buffer (&optional attrs)
+ "Transform the current buffer as if it were a <verse> region."
+ (muse-publish-call-tag-on-buffer "verse" attrs)
+ (muse-publish-markup ""
+ `((100 ,(concat "^[" muse-regexp-blank "]*> ") 0
+ muse-publish-markup-verse)))
+ (goto-char (point-min)))
+
+(defmacro muse-publish-markup-attribute (beg end attrs reinterp &rest body)
+ "Evaluate BODY within the bounds of BEG and END.
+ATTRS is an alist. Only the \"markup\" element of ATTRS is acted
+on.
+
+If it is omitted, publish the region with the normal Muse rules.
+If RE-INTERP is specified, this is done immediately in a new
+publishing process. Currently, RE-INTERP is specified only by
+the <include> tag.
+
+If \"nil\", do not mark up the region at all, but prevent it from
+being further interpreted by Muse.
+
+If \"example\", treat the region as if it was surrounded by the
+<example> tag.
+
+If \"src\", treat the region as if it was surrounded by the
+<src> tag.
+
+If \"verse\", treat the region as if it was surrounded by the
+<verse> tag, to preserve newlines.
+
+Otherwise, it should be the name of a function to call in the
+narrowed region after evaluating BODY. The function should
+take the ATTRS parameter.
+
+BEG is modified to be the start of the published markup."
+ (let ((attrs-sym (make-symbol "attrs"))
+ (markup (make-symbol "markup"))
+ (markup-function (make-symbol "markup-function")))
+ `(let* ((,attrs-sym ,attrs)
+ (,markup (muse-publish-get-and-delete-attr "markup" ,attrs-sym)))
+ (save-restriction
+ (narrow-to-region ,beg ,end)
+ (goto-char (point-min))
+ ,@body
+ (if (not ,markup)
+ (when ,reinterp
+ (muse-publish-markup-region (point-min) (point-max))
+ (muse-publish-mark-read-only (point-min) (point-max))
+ (goto-char (point-max)))
+ (let ((,markup-function (read ,markup)))
+ (cond ((eq ,markup-function 'example)
+ (setq ,markup-function #'muse-publish-examplify-buffer))
+ ((eq ,markup-function 'src)
+ (setq ,markup-function #'muse-publish-srcify-buffer))
+ ((eq ,markup-function 'verse)
+ (setq ,markup-function #'muse-publish-versify-buffer))
+ ((and ,markup-function (not (functionp ,markup-function)))
+ (error "Invalid markup function `%s'" ,markup))
+ (t nil))
+ (if ,markup-function
+ (funcall ,markup-function ,attrs-sym)
+ (muse-publish-mark-read-only (point-min) (point-max))
+ (goto-char (point-max)))))))))
+
+(put 'muse-publish-markup-attribute 'lisp-indent-function 4)
+(put 'muse-publish-markup-attribute 'edebug-form-spec
+ '(sexp sexp sexp sexp body))
+
+(defun muse-publish-lisp-tag (beg end attrs)
+ (muse-publish-markup-attribute beg end attrs nil
+ (save-excursion
+ (save-restriction
+ (let ((str (muse-eval-lisp
+ (prog1
+ (concat "(progn "
+ (buffer-substring-no-properties (point-min)
+ (point-max))
+ ")")
+ (delete-region (point-min) (point-max))
+ (widen)))))
+ (set-text-properties 0 (length str) nil str)
+ (insert str))))))
+
+(put 'muse-publish-lisp-tag 'muse-dangerous-tag t)
+
+(defun muse-publish-command-tag (beg end attrs)
+ (muse-publish-markup-attribute beg end attrs nil
+ (while (looking-at "\\s-*$")
+ (forward-line))
+ (let ((interp (muse-publish-get-and-delete-attr "interp" attrs)))
+ (if interp
+ (shell-command-on-region (point) (point-max) interp t t)
+ (shell-command
+ (prog1
+ (buffer-substring-no-properties (point) (point-max))
+ (delete-region (point-min) (point-max)))
+ t)))
+ ;; make sure there is a newline at end
+ (goto-char (point-max))
+ (forward-line 0)
+ (unless (looking-at "\\s-*$")
+ (goto-char (point-max))
+ (insert ?\n))
+ (goto-char (point-min))))
+
+(put 'muse-publish-command-tag 'muse-dangerous-tag t)
+
+(defun muse-publish-perl-tag (beg end attrs)
+ (muse-publish-command-tag beg end
+ (cons (cons "interp" (executable-find "perl"))
+ attrs)))
+
+(put 'muse-publish-perl-tag 'muse-dangerous-tag t)
+
+(defun muse-publish-php-tag (beg end attrs)
+ (muse-publish-command-tag beg end
+ (cons (cons "interp" (executable-find "php"))
+ attrs)))
+
+(put 'muse-publish-php-tag 'muse-dangerous-tag t)
+
+(defun muse-publish-python-tag (beg end attrs)
+ (muse-publish-command-tag beg end
+ (cons (cons "interp" (executable-find "python"))
+ attrs)))
+
+(put 'muse-publish-python-tag 'muse-dangerous-tag t)
+
+(defun muse-publish-ruby-tag (beg end attrs)
+ (muse-publish-command-tag beg end
+ (cons (cons "interp" (executable-find "ruby"))
+ attrs)))
+
+(put 'muse-publish-ruby-tag 'muse-dangerous-tag t)
+
+(defun muse-publish-comment-tag (beg end)
+ (if (null muse-publish-comments-p)
+ (delete-region beg end)
+ (goto-char end)
+ (muse-insert-markup (muse-markup-text 'comment-end))
+ (muse-publish-mark-read-only beg end)
+ (goto-char beg)
+ (muse-insert-markup (muse-markup-text 'comment-begin))))
+
+(defun muse-publish-include-tag (beg end attrs)
+ "Include the named file at the current location during publishing.
+
+<include file=\"...\" markup=\"...\">
+
+The `markup' attribute controls how this file is marked up after
+being inserted. See `muse-publish-markup-attribute' for an
+explanation of how it works."
+ (let ((filename (muse-publish-get-and-delete-attr "file" attrs))
+ (muse-publishing-directives (copy-alist muse-publishing-directives)))
+ (if filename
+ (setq filename (expand-file-name
+ filename
+ (file-name-directory muse-publishing-current-file)))
+ (error "No file attribute specified in <include> tag"))
+ (muse-publish-markup-attribute beg end attrs t
+ (muse-insert-file-contents filename))))
+
+(put 'muse-publish-include-tag 'muse-dangerous-tag t)
+
+(defun muse-publish-mark-up-tag (beg end attrs)
+ "Run an Emacs Lisp function on the region delimted by this tag.
+
+<markup function=\"...\" style=\"...\" exact=\"...\">
+
+The optional \"function\" attribute controls how this section is
+marked up. If used, it should be the name of a function to call
+with the buffer narrowed to the delimited region. Note that no
+further marking-up will be performed on this region.
+
+If \"function\" is omitted, use the standard Muse markup function.
+This is useful for marking up content in headers and footers.
+
+The optional \"style\" attribute causes the region to be deleted
+if the current style is neither derived from nor equal to this
+style.
+
+If both a \"style\" attribute and an \"exact\" attribute are
+provided, and \"exact\" is \"t\", delete the region only if the
+current style is exactly this style."
+ (let* ((style (cdr (assoc "style" attrs)))
+ (exact (cdr (assoc "exact" attrs)))
+ (exactp (and (stringp exact) (string= exact "t"))))
+ (if (or (not style)
+ (and exactp (equal (muse-style style)
+ muse-publishing-current-style))
+ (and (not exactp) (muse-style-derived-p style)))
+ (let* ((function (cdr (assoc "function" attrs)))
+ (muse-publish-use-header-footer-tags nil)
+ (markup-function (and function (intern-soft function))))
+ (if (and markup-function (functionp markup-function))
+ (save-restriction
+ (narrow-to-region beg end)
+ (funcall markup-function)
+ (goto-char (point-max)))
+ (let ((muse-publish-inhibit-style-hooks t))
+ (muse-publish-markup-region beg end)))
+ (muse-publish-mark-read-only beg (point)))
+ (delete-region beg end))))
+
+(put 'muse-publish-mark-up-tag 'muse-dangerous-tag t)
+
+;; Miscellaneous helper functions
+
+(defun muse-publish-strip-URL (string &rest ignored)
+ "If the text \"URL:\" exists at the beginning of STRING, remove it.
+The text is removed regardless of whether and part of it is uppercase."
+ (save-match-data
+ (if (string-match "\\`[uU][rR][lL]:\\(.+\\)\\'" string)
+ (match-string 1 string)
+ string)))
+
+(defun muse-publish-markup-type (category default-func)
+ (let ((rule (muse-find-markup-element :overrides category (muse-style))))
+ (funcall (or rule default-func))))
+
+(defun muse-published-buffer-contents (buffer)
+ (with-current-buffer buffer
+ (goto-char (point-min))
+ (let ((beg (and (search-forward "Emacs Muse begins here")
+ (muse-line-end-position)))
+ (end (and (search-forward "Emacs Muse ends here")
+ (muse-line-beginning-position))))
+ (buffer-substring-no-properties beg end))))
+
+(defun muse-published-contents (file)
+ (when (file-readable-p file)
+ (muse-with-temp-buffer
+ (muse-insert-file-contents file)
+ (muse-published-buffer-contents (current-buffer)))))
+
+(defun muse-publish-transform-output
+ (file temp-file output-path name gen-func &rest cleanup-exts)
+ "Transform the given TEMP-FILE into the OUTPUT-PATH, using GEN-FUNC."
+ (setq file (muse-page-name file))
+ (message "Generating %s output for %s..." name file)
+ (if (not (funcall gen-func temp-file output-path))
+ (message "Generating %s from %s...failed" name file)
+ (message "Generating %s output for %s...done" name file)
+ (muse-delete-file-if-exists temp-file)
+ (dolist (ext cleanup-exts)
+ (muse-delete-file-if-exists
+ (expand-file-name (concat file ext)
+ (file-name-directory output-path))))
+ (message "Wrote %s" output-path)))
+
+(defun muse-publish-read-only (string)
+ (let ((end (1- (length string))))
+ (add-text-properties 0 end
+ '(rear-nonsticky (read-only) read-only t)
+ string)
+ string))
+
+;;; muse-publish.el ends here
--- /dev/null
+;;; muse-regexps.el --- define regexps used by Muse
+
+;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file is the part of the Muse project that describes regexps
+;; that are used throughout the project.
+
+;;; Contributors:
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Muse Regular Expressions
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defgroup muse-regexp nil
+ "Regular expressions used in publishing and syntax highlighting."
+ :group 'muse)
+
+;;; Deal with the lack of character classes for regexps in Emacs21 and
+;;; XEmacs
+
+(defcustom muse-regexp-use-character-classes 'undecided
+ "Indicate whether to use extended character classes like [:space:].
+If 'undecided, Muse will use them if your emacs is known to support them.
+
+Emacs 22 and Emacs 21.3.50 are known to support them. XEmacs
+does not support them.
+
+Emacs 21.2 or higher support them, but with enough annoying edge
+cases that the sanest default is to leave them disabled."
+ :type '(choice (const :tag "Yes" t)
+ (const :tag "No" nil)
+ (const :tag "Let Muse decide" undecided))
+ :group 'muse-regexp)
+
+(defvar muse-regexp-emacs-revision
+ (save-match-data
+ (and (string-match "^[0-9]+\\.[0-9]+\\.\\([0-9]+\\)"
+ emacs-version)
+ (match-string 1 emacs-version)
+ (string-to-number (match-string 1 emacs-version))))
+ "The revision number of this version of Emacs.")
+
+(defun muse-extreg-usable-p ()
+ "Return non-nil if extended character classes can be used,
+nil otherwise.
+
+This is used when deciding the initial values of the muse-regexp
+options."
+ (cond
+ ((eq muse-regexp-use-character-classes t)
+ t)
+ ((eq muse-regexp-use-character-classes nil)
+ nil)
+ ((featurep 'xemacs) nil) ; unusable on XEmacs
+ ((> emacs-major-version 21) t) ; usable if > 21
+ ((< emacs-major-version 21) nil)
+ ((< emacs-minor-version 3) nil)
+ ;; don't use if version is of format 21.x
+ ((null muse-regexp-emacs-revision) nil)
+ ;; only trust 21.3.50 or higher
+ ((>= muse-regexp-emacs-revision 50) t)
+ (t nil)))
+
+(defcustom muse-regexp-blank
+ (if (muse-extreg-usable-p)
+ "[:blank:]"
+ " \t")
+ "Regexp to use in place of \"[:blank:]\".
+This should be something that matches spaces and tabs.
+
+It is like a regexp, but should be embeddable inside brackets.
+Muse will detect the appropriate value correctly most of
+the time."
+ :type 'string
+ :options '("[:blank:]" " \t")
+ :group 'muse-regexp)
+
+(defcustom muse-regexp-alnum
+ (if (muse-extreg-usable-p)
+ "[:alnum:]"
+ "A-Za-z0-9")
+ "Regexp to use in place of \"[:alnum:]\".
+This should be something that matches all letters and numbers.
+
+It is like a regexp, but should be embeddable inside brackets.
+muse will detect the appropriate value correctly most of
+the time."
+ :type 'string
+ :options '("[:alnum:]" "A-Za-z0-9")
+ :group 'muse-regexp)
+
+(defcustom muse-regexp-lower
+ (if (muse-extreg-usable-p)
+ "[:lower:]"
+ "a-z")
+ "Regexp to use in place of \"[:lower:]\".
+This should match all lowercase characters.
+
+It is like a regexp, but should be embeddable inside brackets.
+muse will detect the appropriate value correctly most of
+the time."
+ :type 'string
+ :options '("[:lower:]" "a-z")
+ :group 'muse-regexp)
+
+(defcustom muse-regexp-upper
+ (if (muse-extreg-usable-p)
+ "[:upper:]"
+ "A-Z")
+ "Regexp to use in place of \"[:upper:]\".
+This should match all uppercase characters.
+
+It is like a regexp, but should be embeddable inside brackets.
+muse will detect the appropriate value correctly most of
+the time."
+ :type 'string
+ :options '("[:upper:]" "A-Z")
+ :group 'muse-regexp)
+
+;;; Regexps used to define Muse publishing syntax
+
+(defcustom muse-list-item-regexp
+ (concat "^%s\\(\\([^\n" muse-regexp-blank "].*?\\)?::"
+ "\\(?:[" muse-regexp-blank "]+\\|$\\)"
+ "\\|[" muse-regexp-blank "]-[" muse-regexp-blank "]*"
+ "\\|[" muse-regexp-blank "][0-9]+\\.[" muse-regexp-blank "]*\\)")
+ "Regexp used to match the beginning of a list item.
+The '%s' will be replaced with a whitespace regexp when publishing."
+ :type 'regexp
+ :group 'muse-regexp)
+
+(defcustom muse-ol-item-regexp (concat "\\`[" muse-regexp-blank "]+[0-9]+\\.")
+ "Regexp used to match an ordered list item."
+ :type 'regexp
+ :group 'muse-regexp)
+
+(defcustom muse-ul-item-regexp (concat "\\`[" muse-regexp-blank "]+-")
+ "Regexp used to match an unordered list item."
+ :type 'regexp
+ :group 'muse-regexp)
+
+(defcustom muse-dl-term-regexp
+ (concat "[" muse-regexp-blank "]*\\(.+?\\)["
+ muse-regexp-blank "]+::\\(?:[" muse-regexp-blank "]+\\|$\\)")
+ "Regexp used to match a definition list term.
+The first match string must contain the term."
+ :type 'regexp
+ :group 'muse-regexp)
+
+(defcustom muse-dl-entry-regexp (concat "\\`[" muse-regexp-blank "]*::")
+ "Regexp used to match a definition list entry."
+ :type 'regexp
+ :group 'muse-regexp)
+
+(defcustom muse-table-field-regexp
+ (concat "[" muse-regexp-blank "]+\\(|+\\)\\(?:["
+ muse-regexp-blank "]\\|$\\)")
+ "Regexp used to match table separators when publishing."
+ :type 'regexp
+ :group 'muse-regexp)
+
+(defcustom muse-table-line-regexp (concat ".*" muse-table-field-regexp ".*")
+ "Regexp used to match a table line when publishing."
+ :type 'regexp
+ :group 'muse-regexp)
+
+(defcustom muse-table-hline-regexp (concat "[" muse-regexp-blank
+ "]*|[-+]+|[" muse-regexp-blank
+ "]*")
+ "Regexp used to match a horizontal separator line in a table."
+ :type 'regexp
+ :group 'muse-regexp)
+
+(defcustom muse-table-el-border-regexp (concat "[" muse-regexp-blank "]*"
+ "\\+\\(-*\\+\\)+"
+ "[" muse-regexp-blank "]*")
+ "Regexp used to match the beginning and end of a table.el-style table."
+ :type 'regexp
+ :group 'muse-regexp)
+
+(defcustom muse-table-el-line-regexp (concat "[" muse-regexp-blank "]*"
+ "|\\(.*|\\)*"
+ "[" muse-regexp-blank "]*")
+ "Regexp used to match a table line of a table.el-style table."
+ :type 'regexp
+ :group 'muse-regexp)
+
+(defcustom muse-tag-regexp
+ (concat "<\\([^/" muse-regexp-blank "\n][^" muse-regexp-blank
+ "</>\n]*\\)\\(\\s-+[^<>]+[^</>\n]\\)?\\(/\\)?>")
+ "A regexp used to find XML-style tags within a buffer when publishing.
+Group 1 should be the tag name, group 2 the properties, and group
+3 the optional immediate ending slash."
+ :type 'regexp
+ :group 'muse-regexp)
+
+(defcustom muse-explicit-link-regexp
+ "\\[\\[\\([^][\n]+\\)\\]\\(?:\\[\\([^][\n]+\\)\\]\\)?\\]"
+ "Regexp used to match [[target][description]] links.
+Paren group 1 must match the URL, and paren group 2 the description."
+ :type 'regexp
+ :group 'muse-regexp)
+
+(defcustom muse-implicit-link-regexp
+ (concat "\\([^" muse-regexp-blank "\n]+\\)")
+ "Regexp used to match an implicit link.
+An implicit link is the largest block of text to be checked for
+URLs and bare WikiNames by the `muse-link-at-point' function.
+Paren group 1 is the text to be checked.
+
+URLs are checked by default. To get WikiNames, load
+muse-wiki.el.
+
+This is only used when you are using muse-mode.el, but not
+muse-colors.el.
+
+If the above applies, and you want to match things with spaces in
+them, you will have to modify this."
+ :type 'regexp
+ :group 'muse-regexp)
+
+;;; Regexps used to determine file types
+
+(defcustom muse-file-regexp
+ (concat "\\`[~/]\\|\\?\\|/\\'\\|\\."
+ "\\(html?\\|pdf\\|mp3\\|el\\|zip\\|txt\\|tar\\)"
+ "\\(\\.\\(gz\\|bz2\\)\\)?\\'")
+ "A link matching this regexp will be regarded as a link to a file."
+ :type 'regexp
+ :group 'muse-regexp)
+
+(defcustom muse-image-regexp
+ "\\.\\(eps\\|gif\\|jp\\(e?g\\)\\|p\\(bm\\|ng\\)\\|tiff\\|x\\([bp]m\\)\\)\\'"
+ "A link matching this regexp will be published inline as an image.
+For example:
+
+ [[./wife.jpg][A picture of my wife]]
+
+If you omit the description, the alt tag of the resulting HTML
+buffer will be the name of the file."
+ :type 'regexp
+ :group 'muse-regexp)
+
+(provide 'muse-regexps)
+
+;;; muse-regexps.el ends here
--- /dev/null
+;;; muse-texinfo.el --- publish entries to Texinfo format or PDF
+
+;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Contributors:
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Muse Texinfo Publishing
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(require 'muse-publish)
+(require 'muse-latex)
+(require 'texnfo-upd)
+
+(defgroup muse-texinfo nil
+ "Rules for marking up a Muse file as a Texinfo article."
+ :group 'muse-publish)
+
+(defcustom muse-texinfo-process-natively nil
+ "If non-nil, use the Emacs `texinfmt' module to make Info files."
+ :type 'boolean
+ :require 'texinfmt
+ :group 'muse-texinfo)
+
+(defcustom muse-texinfo-extension ".texi"
+ "Default file extension for publishing Texinfo files."
+ :type 'string
+ :group 'muse-texinfo)
+
+(defcustom muse-texinfo-info-extension ".info"
+ "Default file extension for publishing Info files."
+ :type 'string
+ :group 'muse-texinfo)
+
+(defcustom muse-texinfo-pdf-extension ".pdf"
+ "Default file extension for publishing PDF files."
+ :type 'string
+ :group 'muse-texinfo)
+
+(defcustom muse-texinfo-header
+ "\\input texinfo @c -*-texinfo-*-
+
+@setfilename <lisp>(concat (muse-page-name) \".info\")</lisp>
+@settitle <lisp>(muse-publishing-directive \"title\")</lisp>
+
+@documentencoding iso-8859-1
+
+@iftex
+@finalout
+@end iftex
+
+@titlepage
+@title <lisp>(muse-publishing-directive \"title\")</lisp>
+@author <lisp>(muse-publishing-directive \"author\")</lisp>
+@end titlepage
+
+<lisp>(and muse-publish-generate-contents \"@contents\")</lisp>
+
+@node Top, Overview, , (dir)
+@top Overview
+@c Page published by Emacs Muse begins here\n\n"
+ "Text to prepend to a Muse page being published as Texinfo.
+This may be text or a filename.
+It may contain <lisp> markup tags."
+ :type 'string
+ :group 'muse-texinfo)
+
+(defcustom muse-texinfo-footer
+ "\n@c Page published by Emacs Muse ends here
+@bye\n"
+ "Text to append to a Muse page being published as Texinfo.
+This may be text or a filename.
+It may contain <lisp> markup tags."
+ :type 'string
+ :group 'muse-texinfo)
+
+(defcustom muse-texinfo-markup-regexps nil
+ "List of markup rules for publishing a Muse page to Texinfo.
+For more on the structure of this list, see `muse-publish-markup-regexps'."
+ :type '(repeat (choice
+ (list :tag "Markup rule"
+ integer
+ (choice regexp symbol)
+ integer
+ (choice string function symbol))
+ function))
+ :group 'muse-texinfo)
+
+(defcustom muse-texinfo-markup-functions
+ '((table . muse-texinfo-markup-table)
+ (heading . muse-texinfo-markup-heading))
+ "An alist of style types to custom functions for that kind of text.
+For more on the structure of this list, see
+`muse-publish-markup-functions'."
+ :type '(alist :key-type symbol :value-type function)
+ :group 'muse-texinfo)
+
+(defcustom muse-texinfo-markup-strings
+ '((image-with-desc . "@center @image{%1%, , , %3%, %2%}@*\n@center %3%")
+ (image . "@noindent @image{%s, , , , %s}")
+ (image-link . "@uref{%s, %s.%s}")
+ (anchor-ref . "@ref{%s, %s}")
+ (url . "@uref{%s, %s}")
+ (link . "@ref{Top, %2%, , %1%, }")
+ (link-and-anchor . "@ref{%3%, %2%, , %1%, %3%}")
+ (email-addr . "@email{%s}")
+ (anchor . "@anchor{%s} ")
+ (emdash . "---")
+ (comment-begin . "@ignore\n")
+ (comment-end . "\n@end ignore\n")
+ (rule . "@sp 1")
+ (no-break-space . "@w{ }")
+ (line-break . "@*")
+ (enddots . "@enddots{}")
+ (dots . "@dots{}")
+ (section . "@chapter ")
+ (subsection . "@section ")
+ (subsubsection . "@subsection ")
+ (section-other . "@subsubheading ")
+ (footnote . "@footnote{")
+ (footnote-end . "}")
+ (begin-underline . "_")
+ (end-underline . "_")
+ (begin-literal . "@samp{")
+ (end-literal . "}")
+ (begin-emph . "@emph{")
+ (end-emph . "}")
+ (begin-more-emph . "@strong{")
+ (end-more-emph . "}")
+ (begin-most-emph . "@strong{@emph{")
+ (end-most-emph . "}}")
+ (begin-verse . "@display\n")
+ (end-verse-line . "")
+ (verse-space . "@ @ ")
+ (end-verse . "\n@end display")
+ (begin-example . "@example\n")
+ (end-example . "\n@end example")
+ (begin-center . "@quotation\n")
+ (end-center . "\n@end quotation")
+ (begin-quote . "@quotation\n")
+ (end-quote . "\n@end quotation")
+ (begin-cite . "")
+ (begin-cite-author . "")
+ (begin-cite-year . "")
+ (end-cite . "")
+ (begin-uli . "@itemize @bullet\n")
+ (end-uli . "\n@end itemize")
+ (begin-uli-item . "@item\n")
+ (begin-oli . "@enumerate\n")
+ (end-oli . "\n@end enumerate")
+ (begin-oli-item . "@item\n")
+ (begin-dl . "@table @strong\n")
+ (end-dl . "\n@end table")
+ (begin-ddt . "@item "))
+ "Strings used for marking up text.
+These cover the most basic kinds of markup, the handling of which
+differs little between the various styles."
+ :type '(alist :key-type symbol :value-type string)
+ :group 'muse-texinfo)
+
+(defcustom muse-texinfo-markup-specials
+ '((?@ . "@@")
+ (?{ . "@{")
+ (?} . "@}"))
+ "A table of characters which must be represented specially."
+ :type '(alist :key-type character :value-type string)
+ :group 'muse-texinfo)
+
+(defcustom muse-texinfo-markup-specials-url
+ '((?@ . "@@")
+ (?{ . "@{")
+ (?} . "@}")
+ (?, . "@comma{}"))
+ "A table of characters which must be represented specially.
+These are applied to URLs."
+ :type '(alist :key-type character :value-type string)
+ :group 'muse-texinfo)
+
+(defun muse-texinfo-decide-specials (context)
+ "Determine the specials to escape, depending on CONTEXT."
+ (cond ((memq context '(underline literal emphasis email url url-desc image
+ footnote))
+ muse-texinfo-markup-specials-url)
+ (t muse-texinfo-markup-specials)))
+
+(defun muse-texinfo-markup-table ()
+ (let* ((table-info (muse-publish-table-fields (match-beginning 0)
+ (match-end 0)))
+ (row-len (car table-info))
+ (field-list (cdr table-info)))
+ (when table-info
+ (muse-insert-markup "@multitable @columnfractions")
+ (dotimes (field row-len)
+ (muse-insert-markup " " (number-to-string (/ 1.0 row-len))))
+ (dolist (fields field-list)
+ (let ((type (car fields)))
+ (unless (eq type 'hline)
+ (setq fields (cdr fields))
+ (if (= type 2)
+ (muse-insert-markup "\n@headitem ")
+ (muse-insert-markup "\n@item "))
+ (insert (car fields))
+ (setq fields (cdr fields))
+ (dolist (field fields)
+ (muse-insert-markup " @tab ")
+ (insert field)))))
+ (muse-insert-markup "\n@end multitable")
+ (insert ?\n))))
+
+(defun muse-texinfo-remove-links (string)
+ "Remove explicit links from STRING, replacing them with the link
+description.
+
+If no description exists for the link, use the link itself."
+ (let ((start nil))
+ (while (setq start (string-match muse-explicit-link-regexp string
+ start))
+ (setq string
+ (replace-match (or (match-string 2 string)
+ (match-string 1 string))
+ t t string)))
+ string))
+
+(defun muse-texinfo-protect-wikiwords (start end)
+ "Protect all wikiwords from START to END from further processing."
+ (and (boundp 'muse-wiki-wikiword-regexp)
+ (featurep 'muse-wiki)
+ (save-excursion
+ (goto-char start)
+ (while (re-search-forward muse-wiki-wikiword-regexp end t)
+ (muse-publish-mark-read-only (match-beginning 0)
+ (match-end 0))))))
+
+(defun muse-texinfo-markup-heading ()
+ (save-excursion
+ (muse-publish-markup-heading))
+ (let* ((eol (muse-line-end-position))
+ (orig-heading (buffer-substring (point) eol))
+ (beg (point)))
+ (delete-region (point) eol)
+ ;; don't allow links to be published in headings
+ (insert (muse-texinfo-remove-links orig-heading))
+ (muse-texinfo-protect-wikiwords beg (point))))
+
+(defun muse-texinfo-munge-buffer ()
+ (muse-latex-fixup-dquotes)
+ (texinfo-insert-node-lines (point-min) (point-max) t)
+ (texinfo-all-menus-update t))
+
+(defun muse-texinfo-pdf-browse-file (file)
+ (shell-command (concat "open " file)))
+
+(defun muse-texinfo-info-generate (file output-path final-target)
+ ;; The version of `texinfmt.el' that comes with Emacs 21 doesn't
+ ;; support @documentencoding, so hack it in.
+ (when (and (not (featurep 'xemacs))
+ (eq emacs-major-version 21))
+ (put 'documentencoding 'texinfo-format
+ 'texinfo-discard-line-with-args))
+ ;; Most versions of `texinfmt.el' do not support @headitem, so hack
+ ;; it in.
+ (unless (get 'headitem 'texinfo-format)
+ (put 'headitem 'texinfo-format 'texinfo-multitable-item))
+ (muse-publish-transform-output
+ file output-path final-target "Info"
+ (function
+ (lambda (file output-path)
+ (if muse-texinfo-process-natively
+ (save-window-excursion
+ (save-excursion
+ (find-file file)
+ (let ((inhibit-read-only t))
+ (texinfo-format-buffer))
+ (save-buffer)
+ (kill-buffer (current-buffer))
+ (let ((buf (get-file-buffer file)))
+ (with-current-buffer buf
+ (set-buffer-modified-p nil)
+ (kill-buffer (current-buffer))))
+ t))
+ (let ((result (shell-command
+ (concat "makeinfo --enable-encoding --output="
+ output-path " " file))))
+ (if (or (not (numberp result))
+ (eq result 0))
+ t
+ nil)))))))
+
+(defun muse-texinfo-pdf-generate (file output-path final-target)
+ (let ((muse-latex-pdf-program "pdftex")
+ (muse-latex-pdf-cruft '(".aux" ".cp" ".fn" ".ky" ".log" ".pg" ".toc"
+ ".tp" ".vr")))
+ (muse-latex-pdf-generate file output-path final-target)))
+
+;;; Register the Muse TEXINFO Publishers
+
+(muse-define-style "texi"
+ :suffix 'muse-texinfo-extension
+ :regexps 'muse-texinfo-markup-regexps
+ :functions 'muse-texinfo-markup-functions
+ :strings 'muse-texinfo-markup-strings
+ :specials 'muse-texinfo-decide-specials
+ :after 'muse-texinfo-munge-buffer
+ :header 'muse-texinfo-header
+ :footer 'muse-texinfo-footer
+ :browser 'find-file)
+
+(muse-derive-style "info" "texi"
+ :final 'muse-texinfo-info-generate
+ :link-suffix 'muse-texinfo-info-extension
+ :osuffix 'muse-texinfo-info-extension
+ :browser 'info)
+
+(muse-derive-style "info-pdf" "texi"
+ :final 'muse-texinfo-pdf-generate
+ :link-suffix 'muse-texinfo-pdf-extension
+ :osuffix 'muse-texinfo-pdf-extension
+ :browser 'muse-texinfo-pdf-browse-file)
+
+(provide 'muse-texinfo)
+
+;;; muse-texinfo.el ends here
--- /dev/null
+;;; muse-wiki.el --- wiki features for Muse
+
+;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; Author: Yann Hodique <Yann.Hodique@lifl.fr>
+;; Keywords:
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Contributors:
+
+;; Per B. Sederberg (per AT med DOT upenn DOT edu) made it so that all
+;; files in a Muse project can become implicit links.
+
+;;; Code:
+
+(require 'muse-regexps)
+(require 'muse-mode)
+
+(eval-when-compile
+ (require 'muse-colors))
+
+(defgroup muse-wiki nil
+ "Options controlling the behavior of Emacs Muse Wiki features."
+ :group 'muse-mode)
+
+(defcustom muse-wiki-use-wikiword t
+ "Whether to use color and publish bare WikiNames."
+ :type 'boolean
+ :group 'muse-wiki)
+
+(defcustom muse-wiki-allow-nonexistent-wikiword nil
+ "Whether to color bare WikiNames that don't have an existing file."
+ :type 'boolean
+ :group 'muse-wiki)
+
+(defcustom muse-wiki-match-all-project-files nil
+ "If non-nil, Muse will color and publish implicit links to any
+file in your project, regardless of whether its name is a WikiWord."
+ :type 'boolean
+ :group 'muse-wiki)
+
+(defcustom muse-wiki-ignore-implicit-links-to-current-page nil
+ "If non-nil, Muse will not recognize implicit links to the current
+page, both when formatting and publishing."
+ :type 'boolean
+ :group 'muse-wiki)
+
+(defvar muse-wiki-project-file-regexp nil
+ "Regexp used to match the files in the current project.
+
+This is set by `muse-wiki-update-project-file-regexp' automatically
+when `muse-wiki-match-all-project-files' is non-nil.")
+(make-variable-buffer-local 'muse-wiki-project-file-regexp)
+
+(defun muse-wiki-update-project-file-regexp ()
+ "Update a local copy of `muse-wiki-project-file-regexp' to include
+all the files in the project."
+ ;; see if the user wants to match project files
+ (when muse-wiki-match-all-project-files
+ (let ((files (mapcar #'car (muse-project-file-alist (muse-project)))))
+ (setq muse-wiki-project-file-regexp
+ (when files
+ (concat "\\("
+ ;; include all files from the project
+ (regexp-opt files 'words)
+ "\\)"))))
+ ;; update coloring setup
+ (when (featurep 'muse-colors)
+ (muse-colors-define-highlighting 'muse-mode muse-colors-markup))))
+
+(add-hook 'muse-update-values-hook
+ 'muse-wiki-update-project-file-regexp)
+(add-hook 'muse-project-file-alist-hook
+ 'muse-wiki-update-project-file-regexp)
+
+(defcustom muse-wiki-wikiword-regexp
+ (concat "\\<\\(\\(?:[" muse-regexp-upper
+ "]+[" muse-regexp-lower "]+\\)\\(?:["
+ muse-regexp-upper "]+[" muse-regexp-lower "]+\\)+\\)")
+ "Regexp used to match WikiWords."
+ :set (function
+ (lambda (sym value)
+ (set sym value)
+ (when (featurep 'muse-colors)
+ (muse-colors-define-highlighting 'muse-mode muse-colors-markup))))
+ :type 'regexp
+ :group 'muse-wiki)
+
+(defcustom muse-wiki-ignore-bare-project-names nil
+ "Determine whether project names without a page specifer are links.
+
+If non-nil, project names without a page specifier will not be
+considered links.
+
+When nil, project names without a specifier are highlighted and
+they link to the default page of the project that they name."
+ :type 'boolean
+ :group 'muse-wiki)
+
+(defvar muse-wiki-interwiki-regexp nil
+ "Regexp that matches all interwiki links.
+
+This is automatically generated by setting `muse-wiki-interwiki-alist'.
+It can also be set by calling `muse-wiki-update-interwiki-regexp'.")
+
+(defcustom muse-wiki-interwiki-delimiter "#\\|::"
+ "Delimiter regexp used for InterWiki links.
+
+If you use groups, use only shy groups."
+ :type 'regexp
+ :group 'muse-wiki)
+
+(defcustom muse-wiki-interwiki-replacement ": "
+ "Regexp used for replacing `muse-wiki-interwiki-delimiter' in
+InterWiki link descriptions.
+
+If you want this replacement to happen, you must add
+`muse-wiki-publish-pretty-interwiki' to
+`muse-publish-desc-transforms'."
+ :type 'regexp
+ :group 'muse-wiki)
+
+(eval-when-compile
+ (defvar muse-wiki-interwiki-alist))
+
+(defun muse-wiki-project-files-with-spaces (&optional project)
+ "Return a list of files in PROJECT that have spaces."
+ (setq project (muse-project project))
+ (let ((flist nil))
+ (save-match-data
+ (dolist (entry (muse-project-file-alist project))
+ (when (string-match " " (car entry))
+ (setq flist (cons (car entry) flist)))))
+ flist))
+
+(defun muse-wiki-update-interwiki-regexp ()
+ "Update the value of `muse-wiki-interwiki-regexp' based on
+`muse-wiki-interwiki-alist' and `muse-project-alist'."
+ (if (null muse-project-alist)
+ (setq muse-wiki-interwiki-regexp nil)
+ (let ((old-value muse-wiki-interwiki-regexp))
+ (setq muse-wiki-interwiki-regexp
+ (concat "\\<\\(" (regexp-opt (mapcar #'car muse-project-alist))
+ (when muse-wiki-interwiki-alist
+ (let ((interwiki-rules
+ (mapcar #'car muse-wiki-interwiki-alist)))
+ (when interwiki-rules
+ (concat "\\|" (regexp-opt interwiki-rules)))))
+ "\\)\\(?:\\(" muse-wiki-interwiki-delimiter
+ "\\)\\("
+ (when muse-wiki-match-all-project-files
+ ;; append the files from the project
+ (let ((files nil))
+ (dolist (proj muse-project-alist)
+ (setq files
+ (nconc (muse-wiki-project-files-with-spaces
+ (car proj))
+ files)))
+ (when files
+ (concat (regexp-opt files) "\\|"))))
+ "\\sw+\\)\\(#\\S-+\\)?\\)?\\>"))
+ (when (and (featurep 'muse-colors)
+ (not (string= old-value muse-wiki-interwiki-regexp)))
+ (muse-colors-define-highlighting 'muse-mode muse-colors-markup)))))
+
+(defcustom muse-wiki-interwiki-alist
+ '(("EmacsWiki" . "http://www.emacswiki.org/cgi-bin/wiki/"))
+ "A table of WikiNames that refer to external entities.
+
+The format of this table is an alist, or series of cons cells.
+Each cons cell must be of the form:
+
+ (WIKINAME . STRING-OR-FUNCTION)
+
+The second part of the cons cell may either be a STRING, which in most
+cases should be a URL, or a FUNCTION. If a function, it will be
+called with one argument: the tag applied to the Interwiki name, or
+nil if no tag was used. If the cdr was a STRING and a tag is used,
+the tag is simply appended.
+
+Here are some examples:
+
+ (\"JohnWiki\" . \"http://alice.dynodns.net/wiki?\")
+
+Referring to [[JohnWiki::EmacsModules]] then really means:
+
+ http://alice.dynodns.net/wiki?EmacsModules
+
+If a function is used for the replacement text, you can get creative
+depending on what the tag is. Tags may contain any alphabetic
+character, any number, % or _. If you need other special characters,
+use % to specify the hex code, as in %2E. All browsers should support
+this."
+ :type '(repeat (cons (string :tag "WikiName")
+ (choice (string :tag "URL") function)))
+ :set (function
+ (lambda (sym value)
+ (set sym value)
+ (muse-wiki-update-interwiki-regexp)))
+ :group 'muse-wiki)
+
+(add-hook 'muse-update-values-hook
+ 'muse-wiki-update-interwiki-regexp)
+
+(defun muse-wiki-resolve-project-page (&optional project page)
+ "Return the published path from the current page to PAGE of PROJECT.
+
+If PAGE is not specified, use the value of :default in PROJECT.
+
+If PROJECT is not specified, default to the current project. If
+no project is current, use the first project of
+`muse-projects-alist'.
+
+Note that PAGE can have several output directories. If this is
+the case, we will use the first one that matches our current
+style and has the same link suffix, ignoring the others. If no
+style has the same link suffix as the current publishing style,
+use the first style we find."
+ (setq project (or (and project
+ (muse-project project))
+ (muse-project)
+ (car muse-project-alist))
+ page (or page (muse-get-keyword :default (cadr project))))
+ (let* ((page-path (and muse-project-alist
+ (muse-project-page-file page project)))
+ (remote-styles (and page-path (muse-project-applicable-styles
+ page-path (cddr project))))
+ (local-style (muse-project-current-output-style)))
+ (cond ((and remote-styles local-style muse-publishing-p)
+ (muse-project-resolve-link page local-style remote-styles))
+ ((not muse-publishing-p)
+ (if page-path
+ page-path
+ (when muse-wiki-allow-nonexistent-wikiword
+ ;; make a path to a nonexistent file in project
+ (setq page-path (expand-file-name
+ page (car (cadr project))))
+ (if (and muse-file-extension
+ (not (string= muse-file-extension "")))
+ (concat page-path "." muse-file-extension)
+ page-path)))))))
+
+(defun muse-wiki-handle-implicit-interwiki (&optional string)
+ "If STRING or point has an interwiki link, resolve it to a filename.
+
+Match string 0 is set to the link."
+ (when (and muse-wiki-interwiki-regexp
+ (if string (string-match muse-wiki-interwiki-regexp string)
+ (looking-at muse-wiki-interwiki-regexp)))
+ (let* ((project (match-string 1 string))
+ (subst (cdr (assoc project muse-wiki-interwiki-alist)))
+ (word (match-string 3 string))
+ (anchor (if (match-beginning 4)
+ (match-string 4 string)
+ "")))
+ (if subst
+ (if (functionp subst)
+ (and (setq word (funcall subst word))
+ (concat word anchor))
+ (concat subst word anchor))
+ (and (assoc project muse-project-alist)
+ (or word (not muse-wiki-ignore-bare-project-names))
+ (setq word (muse-wiki-resolve-project-page project word))
+ (concat word anchor))))))
+
+(defun muse-wiki-handle-explicit-interwiki (&optional string)
+ "If STRING or point has an interwiki link, resolve it to a filename."
+ (let ((right-pos (if string (length string) (match-end 1))))
+ (when (and muse-wiki-interwiki-regexp
+ (if string (string-match muse-wiki-interwiki-regexp string)
+ (save-restriction
+ (narrow-to-region (point) right-pos)
+ (looking-at muse-wiki-interwiki-regexp))))
+ (let* ((project (match-string 1 string))
+ (subst (cdr (assoc project muse-wiki-interwiki-alist)))
+ (anchor (and (match-beginning 4)
+ (match-string 4 string)))
+ (word (when (match-end 2)
+ (cond (anchor (match-string 3 string))
+ (string (substring string (match-end 2)))
+ (right-pos (buffer-substring (match-end 2)
+ right-pos))
+ (t nil)))))
+ (if (and (null word)
+ right-pos
+ (not (= right-pos (match-end 1))))
+ ;; if only a project name was found, it must take up the
+ ;; entire string or link
+ nil
+ (unless anchor
+ (if (or (null word)
+ (not (string-match "#[^#]+\\'" word)))
+ (setq anchor "")
+ (setq anchor (match-string 0 word))
+ (setq word (substring word 0 (match-beginning 0)))))
+ (if subst
+ (if (functionp subst)
+ (and (setq word (funcall subst word))
+ (concat word anchor))
+ (concat subst word anchor))
+ (and (assoc project muse-project-alist)
+ (or word (not muse-wiki-ignore-bare-project-names))
+ (setq word (muse-wiki-resolve-project-page project word))
+ (concat word anchor))))))))
+
+(defun muse-wiki-handle-wikiword (&optional string)
+ "If STRING or point has a WikiWord, return it.
+
+Match 1 is set to the WikiWord."
+ (when (and (or (and muse-wiki-match-all-project-files
+ muse-wiki-project-file-regexp
+ (if string
+ (string-match muse-wiki-project-file-regexp string)
+ (looking-at muse-wiki-project-file-regexp)))
+ (and muse-wiki-use-wikiword
+ (if string
+ (string-match muse-wiki-wikiword-regexp string)
+ (looking-at muse-wiki-wikiword-regexp))))
+ (cond
+ (muse-wiki-allow-nonexistent-wikiword
+ t)
+ ((and muse-wiki-ignore-implicit-links-to-current-page
+ (string= (match-string 1 string) (muse-page-name)))
+ nil)
+ ((and (muse-project-of-file)
+ (muse-project-page-file
+ (match-string 1 string) muse-current-project t))
+ t)
+ ((file-exists-p (match-string 1 string))
+ t)
+ (t nil)))
+ (match-string 1 string)))
+
+;;; Prettifications
+
+(defcustom muse-wiki-publish-small-title-words
+ '("the" "and" "at" "on" "of" "for" "in" "an" "a")
+ "Strings that should be downcased in a page title.
+
+This is used by `muse-wiki-publish-pretty-title', which must be
+called manually."
+ :type '(repeat string)
+ :group 'muse-wiki)
+
+(defcustom muse-wiki-hide-nop-tag t
+ "If non-nil, hide <nop> tags when coloring a Muse buffer."
+ :type 'boolean
+ :group 'muse-wiki)
+
+(defun muse-wiki-publish-pretty-title (&optional title explicit)
+ "Return a pretty version of the given TITLE.
+
+If EXPLICIT is non-nil, TITLE will be returned unmodified."
+ (unless title (setq title (or (muse-publishing-directive "title") "")))
+ (if (or explicit
+ (save-match-data (string-match muse-url-regexp title)))
+ title
+ (save-match-data
+ (let ((case-fold-search nil))
+ (while (string-match (concat "\\([" muse-regexp-lower
+ "]\\)\\([" muse-regexp-upper
+ "0-9]\\)")
+ title)
+ (setq title (replace-match "\\1 \\2" t nil title)))
+ (let* ((words (split-string title))
+ (w (cdr words)))
+ (while w
+ (if (member (downcase (car w))
+ muse-wiki-publish-small-title-words)
+ (setcar w (downcase (car w))))
+ (setq w (cdr w)))
+ (mapconcat 'identity words " "))))))
+
+(defun muse-wiki-publish-pretty-interwiki (desc &optional explicit)
+ "Replace instances of `muse-wiki-interwiki-delimiter' with
+`muse-wiki-interwiki-replacement'."
+ (if (or explicit
+ (save-match-data (string-match muse-url-regexp desc)))
+ desc
+ (muse-replace-regexp-in-string muse-wiki-interwiki-delimiter
+ muse-wiki-interwiki-replacement
+ desc)))
+
+;;; Coloring setup
+
+(defun muse-wiki-colors-nop-tag (beg end)
+ "Inhibit the colorization of inhibit links just after the tag.
+
+Example: <nop>WikiWord"
+ (when muse-wiki-hide-nop-tag
+ (add-text-properties beg (+ beg 5)
+ '(invisible muse intangible t)))
+ (unless (> (+ beg 6) (point-max))
+ (add-text-properties (+ beg 5) (+ beg 6)
+ '(muse-no-implicit-link t))))
+
+(defun muse-colors-wikiword-separate ()
+ (add-text-properties (match-beginning 0) (match-end 0)
+ '(invisible muse intangible t)))
+
+(defun muse-wiki-insinuate-colors ()
+ (add-to-list 'muse-colors-tags
+ '("nop" nil nil nil muse-wiki-colors-nop-tag)
+ t)
+ (add-to-list 'muse-colors-markup
+ '(muse-wiki-interwiki-regexp t muse-colors-implicit-link)
+ t)
+ (add-to-list 'muse-colors-markup
+ '(muse-wiki-wikiword-regexp t muse-colors-implicit-link)
+ t)
+ (add-to-list 'muse-colors-markup
+ '(muse-wiki-project-file-regexp t muse-colors-implicit-link)
+ t)
+ (add-to-list 'muse-colors-markup
+ '("''''" ?\' muse-colors-wikiword-separate)
+ nil)
+ (muse-colors-define-highlighting 'muse-mode muse-colors-markup))
+
+(eval-after-load "muse-colors" '(muse-wiki-insinuate-colors))
+
+;;; Publishing setup
+
+(defun muse-wiki-publish-nop-tag (beg end)
+ "Inhibit the colorization of inhibit links just after the tag.
+
+Example: <nop>WikiWord"
+ (unless (= (point) (point-max))
+ (muse-publish-mark-read-only (point) (+ (point) 1))))
+
+(defun muse-wiki-insinuate-publish ()
+ (add-to-list 'muse-publish-markup-tags
+ '("nop" nil nil nil muse-wiki-publish-nop-tag)
+ t)
+ (add-to-list 'muse-publish-markup-regexps
+ '(3100 muse-wiki-interwiki-regexp 0 link)
+ t)
+ (add-to-list 'muse-publish-markup-regexps
+ '(3200 muse-wiki-wikiword-regexp 0 link)
+ t)
+ (add-to-list 'muse-publish-markup-regexps
+ '(3250 muse-wiki-project-file-regexp 0 link)
+ t)
+ (add-to-list 'muse-publish-markup-regexps
+ '(3300 "''''" 0 "")
+ t)
+ (custom-add-option 'muse-publish-desc-transforms
+ 'muse-wiki-publish-pretty-interwiki)
+ (custom-add-option 'muse-publish-desc-transforms
+ 'muse-wiki-publish-pretty-title))
+
+(eval-after-load "muse-publish" '(muse-wiki-insinuate-publish))
+
+;;; Insinuate link handling
+
+(custom-add-option 'muse-implicit-link-functions
+ 'muse-wiki-handle-implicit-interwiki)
+(custom-add-option 'muse-implicit-link-functions
+ 'muse-wiki-handle-wikiword)
+
+(custom-add-option 'muse-explicit-link-functions
+ 'muse-wiki-handle-explicit-interwiki)
+
+(add-to-list 'muse-implicit-link-functions
+ 'muse-wiki-handle-implicit-interwiki t)
+(add-to-list 'muse-implicit-link-functions
+ 'muse-wiki-handle-wikiword t)
+
+(add-to-list 'muse-explicit-link-functions
+ 'muse-wiki-handle-explicit-interwiki t)
+
+;;; Obsolete functions
+
+(defun muse-wiki-update-custom-values ()
+ (muse-display-warning
+ (concat "Please remove `muse-wiki-update-custom-values' from"
+ " `muse-mode-hook'. Its use is now deprecated.")))
+
+(provide 'muse-wiki)
+;;; muse-wiki.el ends here
--- /dev/null
+;;; muse-xml-common.el --- common routines for XML-like publishing styles
+
+;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Contributors:
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Muse XML Publishing - Common Elements
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(require 'muse-publish)
+(require 'muse-regexps)
+
+(defcustom muse-xml-encoding-map
+ '((iso-8859-1 . "iso-8859-1")
+ (iso-2022-jp . "iso-2022-jp")
+ (utf-8 . "utf-8")
+ (japanese-iso-8bit . "euc-jp")
+ (chinese-big5 . "big5")
+ (mule-utf-8 . "utf-8")
+ (chinese-iso-8bit . "gb2312")
+ (chinese-gbk . "gbk"))
+ "An alist mapping Emacs coding systems to appropriate XML charsets.
+Use the base name of the coding system (i.e. without the -unix)."
+ :type '(alist :key-type coding-system :value-type string)
+ :group 'muse-xml)
+
+(defun muse-xml-transform-content-type (content-type default)
+ "Using `muse-xml-encoding-map', try and resolve an Emacs coding
+system to an associated XML coding system.
+If no match is found, the DEFAULT charset is used instead."
+ (let ((match (and (fboundp 'coding-system-base)
+ (assoc (coding-system-base content-type)
+ muse-xml-encoding-map))))
+ (if match
+ (cdr match)
+ default)))
+
+(defcustom muse-xml-markup-specials
+ '((?\" . """)
+ (?\< . "<")
+ (?\> . ">")
+ (?\& . "&"))
+ "A table of characters which must be represented specially."
+ :type '(alist :key-type character :value-type string)
+ :group 'muse-xml)
+
+(defcustom muse-xml-markup-specials-url-extra
+ '((?\" . """)
+ (?\< . "<")
+ (?\> . ">")
+ (?\& . "&")
+ (?\ . "%20")
+ (?\n . "%0D%0A"))
+ "A table of characters which must be represented specially.
+These are extra characters that are escaped within URLs."
+ :type '(alist :key-type character :value-type string)
+ :group 'muse-xml)
+
+(defun muse-xml-decide-specials (context)
+ "Determine the specials to escape, depending on CONTEXT."
+ (cond ((memq context '(email url image))
+ 'muse-xml-escape-url)
+ ((eq context 'url-extra)
+ muse-xml-markup-specials-url-extra)
+ (t muse-xml-markup-specials)))
+
+(defun muse-xml-escape-url (str)
+ "Convert to character entities any non-alphanumeric characters
+outside a few punctuation symbols, that risk being misinterpreted
+if not escaped."
+ (when str
+ (setq str (muse-publish-escape-specials-in-string str 'url-extra))
+ (let (pos code len ch)
+ (save-match-data
+ (while (setq pos (string-match (concat "[^-"
+ muse-regexp-alnum
+ "/:._=@\\?~#%\"\\+<>()&;]")
+ str pos))
+ (setq ch (aref str pos)
+ code (concat "&#" (int-to-string
+ (cond ((fboundp 'char-to-ucs)
+ (char-to-ucs ch))
+ ((fboundp 'char-to-int)
+ (char-to-int ch))
+ (t ch)))
+ ";")
+ len (length code)
+ str (concat (substring str 0 pos)
+ code
+ (when (< pos (length str))
+ (substring str (1+ pos) nil)))
+ pos (+ len pos)))
+ str))))
+
+(defun muse-xml-markup-anchor ()
+ (unless (get-text-property (match-end 1) 'muse-link)
+ (let ((text (muse-markup-text 'anchor (match-string 2))))
+ (save-match-data
+ (skip-chars-forward (concat muse-regexp-blank "\n"))
+ (when (looking-at (concat "<\\([^" muse-regexp-blank "/>\n]+\\)>"))
+ (goto-char (match-end 0)))
+ (muse-insert-markup text)))
+ (match-string 1)))
+
+(defun muse-xml-sort-table (table)
+ "Sort the given table structure so that it validates properly."
+ ;; Note that the decision matrix must have a nil diagonal, or else
+ ;; elements with the same type will be reversed with respect to each
+ ;; other.
+ (let ((decisions '((nil nil nil) ; body < header, body < footer
+ (t nil t) ; header stays where it is
+ (t nil nil)))) ; footer < header
+ (sort table #'(lambda (l r)
+ (and (integerp (car l)) (integerp (car r))
+ (nth (1- (car r))
+ (nth (1- (car l)) decisions)))))))
+
+(defun muse-xml-markup-table (&optional attributes)
+ "Publish the matched region into a table.
+If a string ATTRIBUTES is given, pass it to the markup string begin-table."
+ (let* ((table-info (muse-publish-table-fields (match-beginning 0)
+ (match-end 0)))
+ (row-len (car table-info))
+ (supports-group (not (string= (muse-markup-text 'begin-table-group
+ row-len)
+ "")))
+ (field-list (muse-xml-sort-table (cdr table-info)))
+ last-part)
+ (when table-info
+ (let ((beg (point)))
+ (muse-publish-ensure-block beg))
+ (muse-insert-markup (muse-markup-text 'begin-table (or attributes "")))
+ (muse-insert-markup (muse-markup-text 'begin-table-group row-len))
+ (dolist (fields field-list)
+ (let* ((type (car fields))
+ (part (cond ((eq type 'hline) nil)
+ ((= type 1) "tbody")
+ ((= type 2) "thead")
+ ((= type 3) "tfoot")))
+ (col (cond ((eq type 'hline) nil)
+ ((= type 1) "td")
+ ((= type 2) "th")
+ ((= type 3) "td"))))
+ (setq fields (cdr fields))
+ (unless (and part last-part (string= part last-part))
+ (when last-part
+ (muse-insert-markup " </" last-part ">\n")
+ (when (eq type 'hline)
+ ;; horizontal separators are represented by closing
+ ;; the current table group and opening a new one
+ (muse-insert-markup (muse-markup-text 'end-table-group))
+ (muse-insert-markup (muse-markup-text 'begin-table-group
+ row-len))))
+ (when part
+ (muse-insert-markup " <" part ">\n"))
+ (setq last-part part))
+ (unless (eq type 'hline)
+ (muse-insert-markup (muse-markup-text 'begin-table-row))
+ (dolist (field fields)
+ (muse-insert-markup (muse-markup-text 'begin-table-entry col))
+ (insert field)
+ (muse-insert-markup (muse-markup-text 'end-table-entry col)))
+ (muse-insert-markup (muse-markup-text 'end-table-row)))))
+ (when last-part
+ (muse-insert-markup " </" last-part ">\n"))
+ (muse-insert-markup (muse-markup-text 'end-table-group))
+ (muse-insert-markup (muse-markup-text 'end-table))
+ (insert ?\n))))
+
+(defun muse-xml-prepare-buffer ()
+ (set (make-local-variable 'muse-publish-url-transforms)
+ (cons 'muse-xml-escape-string muse-publish-url-transforms)))
+
+(provide 'muse-xml-common)
+
+;;; muse-xml-common.el ends here
--- /dev/null
+;;; muse-xml.el --- publish XML files
+
+;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; Author: Michael Olson <mwolson@gnu.org>
+;; Date: Sat 23-Jul-2005
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; James Clarke's nxml-mode can be used for editing and validating
+;; Muse-generated XML files. If you are in nxml-mode use the command
+;; C-c C-s C-f to point to the schema in `contrib/muse.rnc', which
+;; comes with Muse. Say yes if you are asked if you want to copy the
+;; file to your location. C-c C-s C-a can then be used to reload the
+;; schema if you make changes to the file.
+
+;;; Contributors:
+
+;; Peter K. Lee (saint AT corenova DOT com) made the initial
+;; implementation of planner-publish.el, which was heavily borrowed
+;; from.
+
+;; Brad Collins (brad AT chenla DOT org) provided a Compact RelaxNG
+;; schema.
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Muse XML Publishing
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(require 'muse-publish)
+(require 'muse-regexps)
+(require 'muse-xml-common)
+
+(defgroup muse-xml nil
+ "Options controlling the behavior of Muse XML publishing.
+See `muse-xml' for more information."
+ :group 'muse-publish)
+
+(defcustom muse-xml-extension ".xml"
+ "Default file extension for publishing XML files."
+ :type 'string
+ :group 'muse-xml)
+
+(defcustom muse-xml-header
+ "<?xml version=\"1.0\" encoding=\"<lisp>
+ (muse-xml-encoding)</lisp>\"?>
+<MUSE>
+ <pageinfo>
+ <title><lisp>(muse-publishing-directive \"title\")</lisp></title>
+ <author><lisp>(muse-publishing-directive \"author\")</lisp></author>
+ <maintainer><lisp>(muse-style-element :maintainer)</lisp></maintainer>
+ <pubdate><lisp>(muse-publishing-directive \"date\")</lisp></pubdate>
+ </pageinfo>
+ <!-- Page published by Emacs Muse begins here -->\n"
+ "Header used for publishing XML files.
+This may be text or a filename."
+ :type 'string
+ :group 'muse-xml)
+
+(defcustom muse-xml-footer "
+ <!-- Page published by Emacs Muse ends here -->
+</MUSE>\n"
+ "Footer used for publishing XML files.
+This may be text or a filename."
+ :type 'string
+ :group 'muse-xml)
+
+(defcustom muse-xml-markup-regexps
+ `(;; Beginning of doc, end of doc, or plain paragraph separator
+ (10000 ,(concat "\\(\\(\n\\(?:[" muse-regexp-blank "]*\n\\)*"
+ "\\([" muse-regexp-blank "]*\n\\)\\)"
+ "\\|\\`\\s-*\\|\\s-*\\'\\)")
+ ;; this is somewhat repetitive because we only require the
+ ;; line just before the paragraph beginning to be not
+ ;; read-only
+ 3 muse-xml-markup-paragraph))
+ "List of markup rules for publishing a Muse page to XML.
+For more on the structure of this list, see `muse-publish-markup-regexps'."
+ :type '(repeat (choice
+ (list :tag "Markup rule"
+ integer
+ (choice regexp symbol)
+ integer
+ (choice string function symbol))
+ function))
+ :group 'muse-xml)
+
+(defcustom muse-xml-markup-functions
+ '((anchor . muse-xml-markup-anchor)
+ (table . muse-xml-markup-table))
+ "An alist of style types to custom functions for that kind of text.
+For more on the structure of this list, see
+`muse-publish-markup-functions'."
+ :type '(alist :key-type symbol :value-type function)
+ :group 'muse-xml)
+
+(defcustom muse-xml-markup-strings
+ '((image-with-desc . "<image href=\"%s.%s\">%s</image>")
+ (image . "<image href=\"%s.%s\"></image>")
+ (image-link . "<link type=\"image\" href=\"%s\">%s.%s</link>")
+ (anchor-ref . "<link type=\"url\" href=\"#%s\">%s</link>")
+ (url . "<link type=\"url\" href=\"%s\">%s</link>")
+ (link . "<link type=\"url\" href=\"%s\">%s</link>")
+ (link-and-anchor . "<link type=\"url\" href=\"%s#%s\">%s</link>")
+ (email-addr . "<link type=\"email\" href=\"%s\">%s</link>")
+ (anchor . "<anchor id=\"%s\" />\n")
+ (emdash . "%s--%s")
+ (comment-begin . "<!-- ")
+ (comment-end . " -->")
+ (rule . "<hr />")
+ (fn-sep . "<hr />\n")
+ (no-break-space . " ")
+ (line-break . "<br>")
+ (enddots . "....")
+ (dots . "...")
+ (section . "<section level=\"1\"><title>")
+ (section-end . "</title>")
+ (subsection . "<section level=\"2\"><title>")
+ (subsection-end . "</title>")
+ (subsubsection . "<section level=\"3\"><title>")
+ (subsubsection-end . "</title>")
+ (section-other . "<section level=\"%s\"><title>")
+ (section-other-end . "</title>")
+ (section-close . "</section>")
+ (footnote . "<footnote>")
+ (footnote-end . "</footnote>")
+ (begin-underline . "<format type=\"underline\">")
+ (end-underline . "</format>")
+ (begin-literal . "<code>")
+ (end-literal . "</code>")
+ (begin-emph . "<format type=\"emphasis\" level=\"1\">")
+ (end-emph . "</format>")
+ (begin-more-emph . "<format type=\"emphasis\" level=\"2\">")
+ (end-more-emph . "</format>")
+ (begin-most-emph . "<format type=\"emphasis\" level=\"3\">")
+ (end-most-emph . "</format>")
+ (begin-verse . "<verse>\n")
+ (begin-verse-line . "<line>")
+ (end-verse-line . "</line>")
+ (empty-verse-line . "<line />")
+ (begin-last-stanza-line . "<line>")
+ (end-last-stanza-line . "</line>")
+ (end-verse . "</verse>")
+ (begin-example . "<example>")
+ (end-example . "</example>")
+ (begin-center . "<p><format type=\"center\">\n")
+ (end-center . "\n</format></p>")
+ (begin-quote . "<blockquote>\n")
+ (end-quote . "\n</blockquote>")
+ (begin-cite . "<cite>")
+ (begin-cite-author . "<cite type=\"author\">")
+ (begin-cite-year . "<cite type=\"year\">")
+ (end-cite . "</cite>")
+ (begin-quote-item . "<p>")
+ (end-quote-item . "</p>")
+ (begin-uli . "<list type=\"unordered\">\n")
+ (end-uli . "\n</list>")
+ (begin-uli-item . "<item>")
+ (end-uli-item . "</item>")
+ (begin-oli . "<list type=\"ordered\">\n")
+ (end-oli . "\n</list>")
+ (begin-oli-item . "<item>")
+ (end-oli-item . "</item>")
+ (begin-dl . "<list type=\"definition\">\n")
+ (end-dl . "\n</list>")
+ (begin-dl-item . "<item>\n")
+ (end-dl-item . "\n</item>")
+ (begin-ddt . "<term>")
+ (end-ddt . "</term>")
+ (begin-dde . "<definition>")
+ (end-dde . "</definition>")
+ (begin-table . "<table%s>\n")
+ (end-table . "</table>")
+ (begin-table-row . " <tr>\n")
+ (end-table-row . " </tr>\n")
+ (begin-table-entry . " <%s>")
+ (end-table-entry . "</%s>\n"))
+ "Strings used for marking up text.
+These cover the most basic kinds of markup, the handling of which
+differs little between the various styles."
+ :type '(alist :key-type symbol :value-type string)
+ :group 'muse-xml)
+
+(defcustom muse-xml-encoding-default 'utf-8
+ "The default Emacs buffer encoding to use in published files.
+This will be used if no special characters are found."
+ :type 'symbol
+ :group 'muse-xml)
+
+(defcustom muse-xml-charset-default "utf-8"
+ "The default XML charset to use if no translation is
+found in `muse-xml-encoding-map'."
+ :type 'string
+ :group 'muse-xml)
+
+(defun muse-xml-encoding ()
+ (muse-xml-transform-content-type
+ (or (and (boundp 'buffer-file-coding-system)
+ buffer-file-coding-system)
+ muse-xml-encoding-default)
+ muse-xml-charset-default))
+
+(defun muse-xml-markup-paragraph ()
+ (let ((end (copy-marker (match-end 0) t)))
+ (goto-char (match-beginning 0))
+ (when (save-excursion
+ (save-match-data
+ (and (not (get-text-property (max (point-min) (1- (point)))
+ 'muse-no-paragraph))
+ (re-search-backward "<\\(/?\\)p[ >]" nil t)
+ (not (string-equal (match-string 1) "/")))))
+ (when (get-text-property (1- (point)) 'muse-end-list)
+ (goto-char (previous-single-property-change (1- (point))
+ 'muse-end-list)))
+ (muse-insert-markup "</p>"))
+ (goto-char end))
+ (cond
+ ((eobp)
+ (unless (bolp)
+ (insert "\n")))
+ ((get-text-property (point) 'muse-no-paragraph)
+ (forward-char 1)
+ nil)
+ ((eq (char-after) ?\<)
+ (when (looking-at (concat "<\\(format\\|code\\|link\\|image"
+ "\\|anchor\\|footnote\\)[ >]"))
+ (muse-insert-markup "<p>")))
+ (t
+ (muse-insert-markup "<p>"))))
+
+(defun muse-xml-finalize-buffer ()
+ (when (boundp 'buffer-file-coding-system)
+ (when (memq buffer-file-coding-system '(no-conversion undecided-unix))
+ ;; make it agree with the default charset
+ (setq buffer-file-coding-system muse-xml-encoding-default))))
+
+;;; Register the Muse XML Publisher
+
+(muse-define-style "xml"
+ :suffix 'muse-xml-extension
+ :regexps 'muse-xml-markup-regexps
+ :functions 'muse-xml-markup-functions
+ :strings 'muse-xml-markup-strings
+ :specials 'muse-xml-decide-specials
+ :after 'muse-xml-finalize-buffer
+ :header 'muse-xml-header
+ :footer 'muse-xml-footer
+ :browser 'find-file)
+
+(provide 'muse-xml)
+
+;;; muse-xml.el ends here
--- /dev/null
+;;; muse.el --- an authoring and publishing tool for Emacs
+
+;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
+
+;; Emacs Lisp Archive Entry
+;; Filename: muse.el
+;; Version: 3.20
+;; Date: Sun 31 Jan-2010
+;; Keywords: hypermedia
+;; Author: John Wiegley <johnw@gnu.org>
+;; Maintainer: Michael Olson <mwolson@gnu.org>
+;; Description: An authoring and publishing tool for Emacs
+;; URL: http://mwolson.org/projects/EmacsMuse.html
+;; Compatibility: Emacs21 XEmacs21 Emacs22
+
+;; This file is part of Emacs Muse. It is not part of GNU Emacs.
+
+;; Emacs Muse 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, or (at your
+;; option) any later version.
+
+;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Muse is a tool for easily authoring and publishing documents. It
+;; allows for rapid prototyping of hyperlinked text, which may then be
+;; exported to multiple output formats -- such as HTML, LaTeX,
+;; Texinfo, etc.
+
+;; The markup rules used by Muse are intended to be very friendly to
+;; people familiar with Emacs. See the included manual for more
+;; information.
+
+;;; Contributors:
+
+;;; Code:
+
+;; Indicate that this version of Muse supports nested tags
+(provide 'muse-nested-tags)
+
+(defvar muse-version "3.20"
+ "The version of Muse currently loaded")
+
+(defun muse-version (&optional insert)
+ "Display the version of Muse that is currently loaded.
+If INSERT is non-nil, insert the text instead of displaying it."
+ (interactive "P")
+ (if insert
+ (insert muse-version)
+ (message muse-version)))
+
+(defgroup muse nil
+ "Options controlling the behavior of Muse.
+The markup used by Muse is intended to be very friendly to people
+familiar with Emacs."
+ :group 'hypermedia)
+
+(defvar muse-under-windows-p (memq system-type '(ms-dos windows-nt)))
+
+(provide 'muse)
+
+(condition-case nil
+ (require 'derived)
+ (error nil))
+(require 'wid-edit)
+(require 'muse-regexps)
+
+(defvar muse-update-values-hook nil
+ "Hook for values that are automatically generated.
+This is to be used by add-on modules for Muse.
+It is run just before colorizing or publishing a buffer.")
+
+(defun muse-update-values ()
+ "Update various values that are automatically generated.
+
+Call this after changing `muse-project-alist'."
+ (interactive)
+ (run-hooks 'muse-update-values-hook)
+ (dolist (buffer (buffer-list))
+ (when (buffer-live-p buffer)
+ (with-current-buffer buffer
+ (when (derived-mode-p 'muse-mode)
+ (and (boundp 'muse-current-project)
+ (fboundp 'muse-project-of-file)
+ (setq muse-current-project nil)
+ (setq muse-current-project (muse-project-of-file))))))))
+
+;; Default file extension
+
+;; By default, use the .muse file extension.
+;;;###autoload (add-to-list 'auto-mode-alist '("\\.muse\\'" . muse-mode-choose-mode))
+
+;; We need to have this at top-level, as well, so that any Muse or
+;; Planner documents opened during init will just work.
+(add-to-list 'auto-mode-alist '("\\.muse\\'" . muse-mode-choose-mode))
+
+(eval-when-compile
+ (defvar muse-ignored-extensions))
+
+(defvar muse-ignored-extensions-regexp nil
+ "A regexp of extensions to omit from the ending of a Muse page name.
+This is autogenerated from `muse-ignored-extensions'.")
+
+(defun muse-update-file-extension (sym val)
+ "Update the value of `muse-file-extension'."
+ (let ((old (and (boundp sym) (symbol-value sym))))
+ (set sym val)
+ (when (and (featurep 'muse-mode)
+ (or (not (stringp val))
+ (not (stringp old))
+ (not (string= old val))))
+ ;; remove old auto-mode-alist association
+ (when (and (boundp sym) (stringp old))
+ (setq auto-mode-alist
+ (delete (cons (concat "\\." old "\\'")
+ 'muse-mode-choose-mode)
+ auto-mode-alist)))
+ ;; associate the new file extension with muse-mode
+ (when (stringp val)
+ (add-to-list 'auto-mode-alist
+ (cons (concat "\\." val "\\'")
+ 'muse-mode-choose-mode)))
+ ;; update the ignored extensions regexp
+ (when (fboundp 'muse-update-ignored-extensions-regexp)
+ (muse-update-ignored-extensions-regexp
+ 'muse-ignored-extensions muse-ignored-extensions)))))
+
+(defcustom muse-file-extension "muse"
+ "File extension of Muse files. Omit the period at the beginning.
+If you don't want Muse files to have an extension, set this to nil."
+ :type '(choice
+ (const :tag "None" nil)
+ (string))
+ :set 'muse-update-file-extension
+ :group 'muse)
+
+(defcustom muse-completing-read-function 'completing-read
+ "Function to call when prompting user to choose between a list of options.
+This should take the same arguments as `completing-read'."
+ :type 'function
+ :group 'muse)
+
+(defun muse-update-ignored-extensions-regexp (sym val)
+ "Update the value of `muse-ignored-extensions-regexp'."
+ (set sym val)
+ (if val
+ (setq muse-ignored-extensions-regexp
+ (concat "\\.\\("
+ (regexp-quote (or muse-file-extension "")) "\\|"
+ (mapconcat 'identity val "\\|")
+ "\\)\\'"))
+ (setq muse-ignored-extensions-regexp
+ (if muse-file-extension
+ (concat "\\.\\(" muse-file-extension "\\)\\'")
+ nil))))
+
+(add-hook 'muse-update-values-hook
+ (lambda ()
+ (muse-update-ignored-extensions-regexp
+ 'muse-ignored-extensions muse-ignored-extensions)))
+
+(defcustom muse-ignored-extensions '("bz2" "gz" "[Zz]")
+ "A list of extensions to omit from the ending of a Muse page name.
+These are regexps.
+
+Don't put a period at the beginning of each extension unless you
+understand that it is part of a regexp."
+ :type '(repeat (regexp :tag "Extension"))
+ :set 'muse-update-ignored-extensions-regexp
+ :group 'muse)
+
+(defun muse-update-file-extension-after-init ()
+ ;; This is short, but it has to be a function, otherwise Emacs21
+ ;; does not load it properly when running after-init-hook
+ (unless (string= muse-file-extension "muse")
+ (let ((val muse-file-extension)
+ (muse-file-extension "muse"))
+ (muse-update-file-extension 'muse-file-extension val))))
+
+;; Once the user's init file has been processed, determine whether
+;; they want a file extension
+(add-hook 'after-init-hook 'muse-update-file-extension-after-init)
+
+;; URL protocols
+
+(require 'muse-protocols)
+
+;; Helper functions
+
+(defsubst muse-delete-file-if-exists (file)
+ (when (file-exists-p file)
+ (delete-file file)
+ (message "Removed %s" file)))
+
+(defsubst muse-time-less-p (t1 t2)
+ "Say whether time T1 is less than time T2."
+ (or (< (car t1) (car t2))
+ (and (= (car t1) (car t2))
+ (< (nth 1 t1) (nth 1 t2)))))
+
+(eval-when-compile
+ (defvar muse-publishing-current-file nil))
+
+(defun muse-current-file ()
+ "Return the name of the currently visited or published file."
+ (or (and (boundp 'muse-publishing-current-file)
+ muse-publishing-current-file)
+ (buffer-file-name)
+ (concat default-directory (buffer-name))))
+
+(defun muse-page-name (&optional name)
+ "Return the canonical form of a Muse page name.
+
+What this means is that the directory part of NAME is removed,
+and the file extensions in `muse-ignored-extensions' are also
+removed from NAME."
+ (save-match-data
+ (unless (and name (not (string= name "")))
+ (setq name (muse-current-file)))
+ (if name
+ (let ((page (file-name-nondirectory name)))
+ (if (and muse-ignored-extensions-regexp
+ (string-match muse-ignored-extensions-regexp page))
+ (replace-match "" t t page)
+ page)))))
+
+(defun muse-display-warning (message)
+ "Display the given MESSAGE as a warning."
+ (if (fboundp 'display-warning)
+ (display-warning 'muse message
+ (if (featurep 'xemacs)
+ 'warning
+ :warning))
+ (let ((buf (get-buffer-create "*Muse warnings*")))
+ (with-current-buffer buf
+ (goto-char (point-max))
+ (insert "Warning (muse): " message)
+ (unless (bolp)
+ (newline)))
+ (display-buffer buf)
+ (sit-for 0))))
+
+(defun muse-eval-lisp (form)
+ "Evaluate the given form and return the result as a string."
+ (require 'pp)
+ (save-match-data
+ (condition-case err
+ (let ((object (eval (read form))))
+ (cond
+ ((stringp object) object)
+ ((and (listp object)
+ (not (eq object nil)))
+ (let ((string (pp-to-string object)))
+ (substring string 0 (1- (length string)))))
+ ((numberp object)
+ (number-to-string object))
+ ((eq object nil) "")
+ (t
+ (pp-to-string object))))
+ (error
+ (muse-display-warning (format "%s: Error evaluating %s: %s"
+ (muse-page-name) form err))
+ "; INVALID LISP CODE"))))
+
+(defmacro muse-with-temp-buffer (&rest body)
+ "Create a temporary buffer, and evaluate BODY there like `progn'.
+See also `with-temp-file' and `with-output-to-string'.
+
+Unlike `with-temp-buffer', this will never attempt to save the
+temp buffer. It is meant to be used along with
+`insert-file-contents' or `muse-insert-file-contents'.
+
+The undo feature will be disabled in the new buffer.
+
+If `debug-on-error' is set to t, keep the buffer around for
+debugging purposes rather than removing it."
+ (let ((temp-buffer (make-symbol "temp-buffer")))
+ `(let ((,temp-buffer (generate-new-buffer " *muse-temp*")))
+ (buffer-disable-undo ,temp-buffer)
+ (unwind-protect
+ (if debug-on-error
+ (with-current-buffer ,temp-buffer
+ ,@body)
+ (condition-case err
+ (with-current-buffer ,temp-buffer
+ ,@body)
+ (error
+ (if (and (boundp 'muse-batch-publishing-p)
+ muse-batch-publishing-p)
+ (progn
+ (message "%s: Error occured: %s"
+ (muse-page-name) err)
+ (backtrace))
+ (muse-display-warning
+ (format (concat "An error occurred while publishing"
+ " %s:\n %s\n\nSet debug-on-error to"
+ " `t' if you would like a backtrace.")
+ (muse-page-name) err))))))
+ (when (buffer-live-p ,temp-buffer)
+ (with-current-buffer ,temp-buffer
+ (set-buffer-modified-p nil))
+ (unless debug-on-error (kill-buffer ,temp-buffer)))))))
+
+(put 'muse-with-temp-buffer 'lisp-indent-function 0)
+(put 'muse-with-temp-buffer 'edebug-form-spec '(body))
+
+(defun muse-insert-file-contents (filename &optional visit)
+ "Insert the contents of file FILENAME after point.
+Do character code conversion and end-of-line conversion, but none
+of the other unnecessary things like format decoding or
+`find-file-hook'.
+
+If VISIT is non-nil, the buffer's visited filename
+and last save file modtime are set, and it is marked unmodified.
+If visiting and the file does not exist, visiting is completed
+before the error is signaled."
+ (let ((format-alist nil)
+ (after-insert-file-functions nil)
+ (inhibit-file-name-handlers
+ (append '(jka-compr-handler image-file-handler epa-file-handler)
+ inhibit-file-name-handlers))
+ (inhibit-file-name-operation 'insert-file-contents))
+ (insert-file-contents filename visit)))
+
+(defun muse-write-file (filename &optional nomessage)
+ "Write current buffer into file FILENAME.
+Unlike `write-file', this does not visit the file, try to back it
+up, or interact with vc.el in any way.
+
+If the file was not written successfully, return nil. Otherwise,
+return non-nil.
+
+If the NOMESSAGE argument is non-nil, suppress the \"Wrote file\"
+message."
+ (when nomessage (setq nomessage 'nomessage))
+ (let ((backup-inhibited t)
+ (buffer-file-name filename)
+ (buffer-file-truename (file-truename filename)))
+ (save-current-buffer
+ (save-restriction
+ (widen)
+ (if (not (file-writable-p buffer-file-name))
+ (prog1 nil
+ (muse-display-warning
+ (format "Cannot write file %s:\n %s" buffer-file-name
+ (let ((dir (file-name-directory buffer-file-name)))
+ (if (not (file-directory-p dir))
+ (if (file-exists-p dir)
+ (format "%s is not a directory" dir)
+ (format "No directory named %s exists" dir))
+ (if (not (file-exists-p buffer-file-name))
+ (format "Directory %s write-protected" dir)
+ "File is write-protected"))))))
+ (let ((coding-system-for-write
+ (or (and (boundp 'save-buffer-coding-system)
+ save-buffer-coding-system)
+ coding-system-for-write)))
+ (write-region (point-min) (point-max) buffer-file-name
+ nil nomessage))
+ (when (boundp 'last-file-coding-system-used)
+ (when (boundp 'buffer-file-coding-system-explicit)
+ (setq buffer-file-coding-system-explicit
+ last-coding-system-used))
+ (if save-buffer-coding-system
+ (setq save-buffer-coding-system last-coding-system-used)
+ (setq buffer-file-coding-system last-coding-system-used)))
+ t)))))
+
+(defun muse-collect-alist (list element &optional test)
+ "Collect items from LIST whose car is equal to ELEMENT.
+If TEST is specified, use it to compare ELEMENT."
+ (unless test (setq test 'equal))
+ (let ((items nil))
+ (dolist (item list)
+ (when (funcall test element (car item))
+ (setq items (cons item items))))
+ items))
+
+(defmacro muse-sort-with-closure (list predicate closure)
+ "Sort LIST, stably, comparing elements using PREDICATE.
+Returns the sorted list. LIST is modified by side effects.
+PREDICATE is called with two elements of list and CLOSURE.
+PREDICATE should return non-nil if the first element should sort
+before the second."
+ `(sort ,list (lambda (a b) (funcall ,predicate a b ,closure))))
+
+(put 'muse-sort-with-closure 'lisp-indent-function 0)
+(put 'muse-sort-with-closure 'edebug-form-spec '(form function-form form))
+
+(defun muse-sort-by-rating (rated-list &optional test)
+ "Sort RATED-LIST according to the rating of each element.
+The rating is stripped out in the returned list.
+Default sorting is highest-first.
+
+If TEST if specified, use it to sort the list. The default test is '>."
+ (unless test (setq test '>))
+ (mapcar (function cdr)
+ (muse-sort-with-closure
+ rated-list
+ (lambda (a b closure)
+ (let ((na (numberp (car a)))
+ (nb (numberp (car b))))
+ (cond ((and na nb) (funcall closure (car a) (car b)))
+ (na (not nb))
+ (t nil))))
+ test)))
+
+(defun muse-escape-specials-in-string (specials string &optional reverse)
+ "Apply the transformations in SPECIALS to STRING.
+
+The transforms should form a fully reversible and non-ambiguous
+syntax when STRING is parsed from left to right.
+
+If REVERSE is specified, reverse an already-escaped string."
+ (let ((rules (mapcar (lambda (rule)
+ (cons (regexp-quote (if reverse
+ (cdr rule)
+ (car rule)))
+ (if reverse (car rule) (cdr rule))))
+ specials)))
+ (save-match-data
+ (with-temp-buffer
+ (insert string)
+ (goto-char (point-min))
+ (while (not (eobp))
+ (unless (catch 'found
+ (dolist (rule rules)
+ (when (looking-at (car rule))
+ (replace-match (cdr rule) t t)
+ (throw 'found t))))
+ (forward-char)))
+ (buffer-string)))))
+
+(defun muse-trim-whitespace (string)
+ "Return a version of STRING with no initial nor trailing whitespace."
+ (muse-replace-regexp-in-string
+ (concat "\\`[" muse-regexp-blank "]+\\|[" muse-regexp-blank "]+\\'")
+ "" string))
+
+(defun muse-path-sans-extension (path)
+ "Return PATH sans final \"extension\".
+
+The extension, in a file name, is the part that follows the last `.',
+except that a leading `.', if any, doesn't count.
+
+This differs from `file-name-sans-extension' in that it will
+never modify the directory part of the path."
+ (concat (file-name-directory path)
+ (file-name-nondirectory (file-name-sans-extension path))))
+
+;; The following code was extracted from cl
+
+(defun muse-const-expr-p (x)
+ (cond ((consp x)
+ (or (eq (car x) 'quote)
+ (and (memq (car x) '(function function*))
+ (or (symbolp (nth 1 x))
+ (and (eq (and (consp (nth 1 x))
+ (car (nth 1 x))) 'lambda) 'func)))))
+ ((symbolp x) (and (memq x '(nil t)) t))
+ (t t)))
+
+(put 'muse-assertion-failed 'error-conditions '(error))
+(put 'muse-assertion-failed 'error-message "Assertion failed")
+
+(defun muse-list* (arg &rest rest)
+ "Return a new list with specified args as elements, cons'd to last arg.
+Thus, `(list* A B C D)' is equivalent to `(nconc (list A B C) D)', or to
+`(cons A (cons B (cons C D)))'."
+ (cond ((not rest) arg)
+ ((not (cdr rest)) (cons arg (car rest)))
+ (t (let* ((n (length rest))
+ (copy (copy-sequence rest))
+ (last (nthcdr (- n 2) copy)))
+ (setcdr last (car (cdr last)))
+ (cons arg copy)))))
+
+(defmacro muse-assert (form &optional show-args string &rest args)
+ "Verify that FORM returns non-nil; signal an error if not.
+Second arg SHOW-ARGS means to include arguments of FORM in message.
+Other args STRING and ARGS... are arguments to be passed to `error'.
+They are not evaluated unless the assertion fails. If STRING is
+omitted, a default message listing FORM itself is used."
+ (let ((sargs
+ (and show-args
+ (delq nil (mapcar
+ (function
+ (lambda (x)
+ (and (not (muse-const-expr-p x)) x)))
+ (cdr form))))))
+ (list 'progn
+ (list 'or form
+ (if string
+ (muse-list* 'error string (append sargs args))
+ (list 'signal '(quote muse-assertion-failed)
+ (muse-list* 'list (list 'quote form) sargs))))
+ nil)))
+
+;; Compatibility functions
+
+(if (fboundp 'looking-back)
+ (defalias 'muse-looking-back 'looking-back)
+ (defun muse-looking-back (regexp &optional limit &rest ignored)
+ (save-excursion
+ (re-search-backward (concat "\\(?:" regexp "\\)\\=") limit t))))
+
+(eval-and-compile
+ (if (fboundp 'line-end-position)
+ (defalias 'muse-line-end-position 'line-end-position)
+ (defun muse-line-end-position (&optional n)
+ (save-excursion (end-of-line n) (point))))
+
+ (if (fboundp 'line-beginning-position)
+ (defalias 'muse-line-beginning-position 'line-beginning-position)
+ (defun muse-line-beginning-position (&optional n)
+ (save-excursion (beginning-of-line n) (point))))
+
+ (if (fboundp 'match-string-no-properties)
+ (defalias 'muse-match-string-no-properties 'match-string-no-properties)
+ (defun muse-match-string-no-properties (num &optional string)
+ (match-string num string))))
+
+(defun muse-replace-regexp-in-string (regexp replacement text &optional fixedcase literal)
+ "Replace REGEXP with REPLACEMENT in TEXT.
+
+Return a new string containing the replacements.
+
+If fourth arg FIXEDCASE is non-nil, do not alter case of replacement text.
+If fifth arg LITERAL is non-nil, insert REPLACEMENT literally."
+ (cond
+ ((and (featurep 'xemacs) (fboundp 'replace-in-string))
+ (and (fboundp 'replace-in-string) ; stupid byte-compiler warning
+ (replace-in-string text regexp replacement literal)))
+ ((fboundp 'replace-regexp-in-string)
+ (replace-regexp-in-string regexp replacement text fixedcase literal))
+ (t (error (concat "Neither `replace-in-string' nor "
+ "`replace-regexp-in-string' was found")))))
+
+(if (fboundp 'add-to-invisibility-spec)
+ (defalias 'muse-add-to-invisibility-spec 'add-to-invisibility-spec)
+ (defun muse-add-to-invisibility-spec (element)
+ "Add ELEMENT to `buffer-invisibility-spec'.
+See documentation for `buffer-invisibility-spec' for the kind of elements
+that can be added."
+ (if (eq buffer-invisibility-spec t)
+ (setq buffer-invisibility-spec (list t)))
+ (setq buffer-invisibility-spec
+ (cons element buffer-invisibility-spec))))
+
+(if (fboundp 'read-directory-name)
+ (defalias 'muse-read-directory-name 'read-directory-name)
+ (defun muse-read-directory-name (prompt &optional dir default-dirname mustmatch initial)
+ "Read directory name - see `read-file-name' for details."
+ (unless dir
+ (setq dir default-directory))
+ (read-file-name prompt dir (or default-dirname
+ (if initial (expand-file-name initial dir)
+ dir))
+ mustmatch initial)))
+
+(defun muse-file-remote-p (file)
+ "Test whether FILE specifies a location on a remote system.
+Return non-nil if the location is indeed remote.
+
+For example, the filename \"/user@host:/foo\" specifies a location
+on the system \"/user@host:\"."
+ (cond ((fboundp 'file-remote-p)
+ (file-remote-p file))
+ ((fboundp 'tramp-handle-file-remote-p)
+ (tramp-handle-file-remote-p file))
+ ((and (boundp 'ange-ftp-name-format)
+ (string-match (car ange-ftp-name-format) file))
+ t)
+ (t nil)))
+
+(if (fboundp 'delete-and-extract-region)
+ (defalias 'muse-delete-and-extract-region 'delete-and-extract-region)
+ (defun muse-delete-and-extract-region (start end)
+ "Delete the text between START and END and return it."
+ (prog1 (buffer-substring start end)
+ (delete-region start end))))
+
+(if (fboundp 'delete-dups)
+ (defalias 'muse-delete-dups 'delete-dups)
+ (defun muse-delete-dups (list)
+ "Destructively remove `equal' duplicates from LIST.
+Store the result in LIST and return it. LIST must be a proper list.
+Of several `equal' occurrences of an element in LIST, the first
+one is kept."
+ (let ((tail list))
+ (while tail
+ (setcdr tail (delete (car tail) (cdr tail)))
+ (setq tail (cdr tail))))
+ list))
+
+;; Set face globally in a predictable fashion
+(defun muse-copy-face (old new)
+ "Copy face OLD to NEW."
+ (if (featurep 'xemacs)
+ (copy-face old new 'all)
+ (copy-face old new)))
+
+;; Widget compatibility functions
+
+(defun muse-widget-type-value-create (widget)
+ "Convert and instantiate the value of the :type attribute of WIDGET.
+Store the newly created widget in the :children attribute.
+
+The value of the :type attribute should be an unconverted widget type."
+ (let ((value (widget-get widget :value))
+ (type (widget-get widget :type)))
+ (widget-put widget :children
+ (list (widget-create-child-value widget
+ (widget-convert type)
+ value)))))
+
+(defun muse-widget-child-value-get (widget)
+ "Get the value of the first member of :children in WIDGET."
+ (widget-value (car (widget-get widget :children))))
+
+(defun muse-widget-type-match (widget value)
+ "Non-nil if the :type value of WIDGET matches VALUE.
+
+The value of the :type attribute should be an unconverted widget type."
+ (widget-apply (widget-convert (widget-get widget :type)) :match value))
+
+;; Link-handling functions and variables
+
+(defun muse-get-link (&optional target)
+ "Based on the match data, retrieve the link.
+Use TARGET to get the string, if it is specified."
+ (muse-match-string-no-properties 1 target))
+
+(defun muse-get-link-desc (&optional target)
+ "Based on the match data, retrieve the link description.
+Use TARGET to get the string, if it is specified."
+ (muse-match-string-no-properties 2 target))
+
+(defvar muse-link-specials
+ '(("[" . "%5B")
+ ("]" . "%5D")
+ ("%" . "%%"))
+ "Syntax used for escaping and unescaping links.
+This allows brackets to occur in explicit links as long as you
+use the standard Muse functions to create them.")
+
+(defun muse-link-escape (text)
+ "Escape characters in TEXT that conflict with the explicit link
+regexp."
+ (when (stringp text)
+ (muse-escape-specials-in-string muse-link-specials text)))
+
+(defun muse-link-unescape (text)
+ "Un-escape characters in TEXT that conflict with the explicit
+link regexp."
+ (when (stringp text)
+ (muse-escape-specials-in-string muse-link-specials text t)))
+
+(defun muse-handle-url (&optional string)
+ "If STRING or point has a URL, match and return it."
+ (if (if string (string-match muse-url-regexp string)
+ (looking-at muse-url-regexp))
+ (match-string 0 string)))
+
+(defcustom muse-implicit-link-functions '(muse-handle-url)
+ "A list of functions to handle an implicit link.
+An implicit link is one that is not surrounded by brackets.
+
+By default, Muse handles URLs only.
+If you want to handle WikiWords, load muse-wiki.el."
+ :type 'hook
+ :options '(muse-handle-url)
+ :group 'muse)
+
+(defun muse-handle-implicit-link (&optional link)
+ "Handle implicit links. If LINK is not specified, look at point.
+An implicit link is one that is not surrounded by brackets.
+By default, Muse handles URLs only.
+If you want to handle WikiWords, load muse-wiki.el.
+
+This function modifies the match data so that match 0 is the
+link.
+
+The match data is restored after each unsuccessful handler
+function call. If LINK is specified, only restore at very end.
+
+This behavior is needed because the part of the buffer that
+`muse-implicit-link-regexp' matches must be narrowed to the part
+that is an accepted link."
+ (let ((funcs muse-implicit-link-functions)
+ (res nil)
+ (data (match-data t)))
+ (while funcs
+ (setq res (funcall (car funcs) link))
+ (if res
+ (setq funcs nil)
+ (unless link (set-match-data data))
+ (setq funcs (cdr funcs))))
+ (when link (set-match-data data))
+ res))
+
+(defcustom muse-explicit-link-functions nil
+ "A list of functions to handle an explicit link.
+An explicit link is one [[like][this]] or [[this]]."
+ :type 'hook
+ :group 'muse)
+
+(defun muse-handle-explicit-link (&optional link)
+ "Handle explicit links. If LINK is not specified, look at point.
+An explicit link is one that looks [[like][this]] or [[this]].
+
+The match data is preserved. If no handlers are able to process
+LINK, return LINK (if specified) or the 1st match string. If
+LINK is not specified, it is assumed that Muse has matched
+against `muse-explicit-link-regexp' before calling this
+function."
+ (let ((funcs muse-explicit-link-functions)
+ (res nil))
+ (save-match-data
+ (while funcs
+ (setq res (funcall (car funcs) link))
+ (if res
+ (setq funcs nil)
+ (setq funcs (cdr funcs)))))
+ (muse-link-unescape
+ (if res
+ res
+ (or link (muse-get-link))))))
+
+;; Movement functions
+
+(defun muse-list-item-type (str)
+ "Determine the type of list given STR.
+Returns either 'ul, 'ol, 'dl-term, 'dl-entry, or nil."
+ (save-match-data
+ (cond ((or (string= str "")
+ (< (length str) 2))
+ nil)
+ ((string-match muse-dl-entry-regexp str)
+ 'dl-entry)
+ ((string-match muse-dl-term-regexp str)
+ 'dl-term)
+ ((string-match muse-ol-item-regexp str)
+ 'ol)
+ ((string-match muse-ul-item-regexp str)
+ 'ul)
+ (t nil))))
+
+(defun muse-list-item-critical-point (&optional offset)
+ "Figure out where the important markup character for the
+currently-matched list item is.
+
+If OFFSET is specified, it is the number of groupings outside of
+the contents of `muse-list-item-regexp'."
+ (unless offset (setq offset 0))
+ (if (match-end (+ offset 2))
+ ;; at a definition list
+ (match-end (+ offset 2))
+ ;; at a different kind of list
+ (match-beginning (+ offset 1))))
+
+(defun muse-forward-paragraph (&optional pattern)
+ "Move forward safely by one paragraph, or according to PATTERN."
+ (when (get-text-property (point) 'muse-end-list)
+ (goto-char (next-single-property-change (point) 'muse-end-list)))
+ (setq pattern (if pattern
+ (concat "^\\(?:" pattern "\\|\n\\|\\'\\)")
+ "^\\s-*\\(\n\\|\\'\\)"))
+ (let ((next-list-end (or (next-single-property-change (point) 'muse-end-list)
+ (point-max))))
+ (forward-line 1)
+ (if (re-search-forward pattern nil t)
+ (goto-char (match-beginning 0))
+ (goto-char (point-max)))
+ (when (> (point) next-list-end)
+ (goto-char next-list-end))))
+
+(defun muse-forward-list-item-1 (type empty-line indented-line)
+ "Determine whether a nested list item is after point."
+ (if (match-beginning 1)
+ ;; if we are given a dl entry, skip past everything on the same
+ ;; level, except for other dl entries
+ (and (eq type 'dl-entry)
+ (not (eq (char-after (match-beginning 2)) ?\:)))
+ ;; blank line encountered with no list item on the same
+ ;; level after it
+ (let ((beg (point)))
+ (forward-line 1)
+ (if (save-match-data
+ (and (looking-at indented-line)
+ (not (looking-at empty-line))))
+ ;; found that this blank line is followed by some
+ ;; indentation, plus other text, so we'll keep
+ ;; going
+ t
+ (goto-char beg)
+ nil))))
+
+(defun muse-forward-list-item (type indent &optional no-skip-nested)
+ "Move forward to the next item of TYPE.
+Return non-nil if successful, nil otherwise.
+The beginning indentation is given by INDENT.
+
+If NO-SKIP-NESTED is non-nil, do not skip past nested items.
+Note that if you desire this behavior, you will also need to
+provide a very liberal INDENT value, such as
+\(concat \"[\" muse-regexp-blank \"]*\")."
+ (let* ((list-item (format muse-list-item-regexp indent))
+ (empty-line (concat "^[" muse-regexp-blank "]*\n"))
+ (indented-line (concat "^" indent "[" muse-regexp-blank "]"))
+ (list-pattern (concat "\\(?:" empty-line "\\)?"
+ "\\(" list-item "\\)")))
+ (while (progn
+ (muse-forward-paragraph list-pattern)
+ ;; make sure we don't go past boundary
+ (and (not (or (get-text-property (point) 'muse-end-list)
+ (>= (point) (point-max))))
+ ;; move past markup that is part of another construct
+ (or (and (match-beginning 1)
+ (or (get-text-property
+ (muse-list-item-critical-point 1) 'muse-link)
+ (and (derived-mode-p 'muse-mode)
+ (get-text-property
+ (muse-list-item-critical-point 1)
+ 'face))))
+ ;; skip nested items
+ (and (not no-skip-nested)
+ (muse-forward-list-item-1 type empty-line
+ indented-line))))))
+ (cond ((or (get-text-property (point) 'muse-end-list)
+ (>= (point) (point-max)))
+ ;; at a list boundary, so stop
+ nil)
+ ((let ((str (when (match-beginning 2)
+ ;; get the entire line
+ (save-excursion
+ (goto-char (match-beginning 2))
+ (buffer-substring (muse-line-beginning-position)
+ (muse-line-end-position))))))
+ (and str (eq type (muse-list-item-type str))))
+ ;; same type, so indicate that there are more items to be
+ ;; parsed
+ (goto-char (match-beginning 1)))
+ (t
+ (when (match-beginning 1)
+ (goto-char (match-beginning 1)))
+ ;; move to just before foreign list item markup
+ nil))))
+
+(defun muse-goto-tag-end (tag nested)
+ "Move forward past the end of TAG.
+
+If NESTED is non-nil, look for other instances of this tag that
+may be nested inside of this tag, and skip past them."
+ (if (not nested)
+ (search-forward (concat "</" tag ">") nil t)
+ (let ((nesting 1)
+ (tag-regexp (concat "\\(<\\(/?\\)" tag "\\([ >]\\)\\)"))
+ (match-found nil))
+ (while (and (> nesting 0)
+ (setq match-found (re-search-forward tag-regexp nil t)))
+ ;; for the sake of font-locking code, skip matches in comments
+ (unless (get-text-property (match-beginning 0) 'muse-comment)
+ (if (string-equal (match-string 2) "/")
+ (and (string-equal (match-string 3) ">")
+ (setq nesting (1- nesting)))
+ (setq nesting (1+ nesting)))))
+ match-found)))
+
+;;; muse.el ends here
--- /dev/null
+This is muse.info, produced by makeinfo version 4.13 from muse.texi.
+
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Muse: (muse). Authoring and publishing environment for Emacs.
+END-INFO-DIR-ENTRY
+
+ This manual is for Emacs Muse version 3.20.
+
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
+Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation License,
+ Version 1.2 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" in this manual.
+
+ (a) The FSF's Back-Cover Text is: "You have freedom to copy and
+ modify this GNU Manual, like GNU software. Copies published by
+ the Free Software Foundation raise funds for GNU development."
+
+ This document is part of a collection distributed under the GNU
+ Free Documentation License. If you want to distribute this
+ document separately from the collection, you can do so by adding a
+ copy of the license to the document, as described in section 6 of
+ the license.
+
+ All Emacs Lisp code contained in this document may be used,
+ distributed, and modified without restriction.
+
+\1f
+File: muse.info, Node: Top, Next: Preface, Prev: (dir), Up: (dir)
+
+Muse
+****
+
+This manual is for Emacs Muse version 3.20.
+
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
+Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation License,
+ Version 1.2 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" in this manual.
+
+ (a) The FSF's Back-Cover Text is: "You have freedom to copy and
+ modify this GNU Manual, like GNU software. Copies published by
+ the Free Software Foundation raise funds for GNU development."
+
+ This document is part of a collection distributed under the GNU
+ Free Documentation License. If you want to distribute this
+ document separately from the collection, you can do so by adding a
+ copy of the license to the document, as described in section 6 of
+ the license.
+
+ All Emacs Lisp code contained in this document may be used,
+ distributed, and modified without restriction.
+
+* Menu:
+
+* Preface:: About the documentation.
+* Introduction:: What is Muse?
+* Obtaining Muse:: How to get Muse releases and development
+ changes.
+* Installation:: Compiling and installing Muse.
+* Getting Started:: Setting up Muse and editing files.
+* Projects:: Creating and managing Muse projects.
+* Keystroke Summary:: Keys used in Muse mode.
+* Markup Rules:: Rules for using markup.
+* Publishing Styles:: Publishing various types of documents.
+* Extending Muse:: Making your own publishing styles.
+* Miscellaneous:: Miscellaneous add-ons, like a minor mode.
+* Getting Help and Reporting Bugs::
+* History:: History of this document.
+* Contributors:: Contributors to this documentation.
+* GNU Free Documentation License:: The license for this documentation.
+* Concept Index:: Search for terms.
+
+ --- The Detailed Node Listing ---
+
+How to Get Muse Releases and Development Changes
+
+* Releases:: Released versions of Muse.
+* Development:: Latest unreleased development changes.
+
+Getting Started
+
+* Loading Muse:: How to load Muse.
+* Using Muse Mode:: How to edit files in Muse.
+* Publishing Files Overview:: Publishing a single file or project.
+* File Extensions:: Using a different file extension.
+
+Creating and Managing Muse Projects
+
+* Single Project:: A single-project example.
+* Multiple Projects:: A multiple-project example.
+* Projects and Subdirectories:: Publishing subdirectories in projects.
+* Options for Projects:: Listing of available options for projects.
+
+Rules for Using Markup
+
+* Paragraphs:: Paragraphs: centering and quoting.
+* Headings:: Levels of headings.
+* Directives:: Directives at the beginning of a
+ document.
+* Emphasizing Text:: Bold, italicized, and underlined text.
+* Footnotes:: Making notes to be shown at the end.
+* Verse:: Indicating poetic stanzas.
+* Lists:: Lists of items.
+* Tables:: Generation of data tables.
+* Explicit Links:: Hyperlinks and email addresses with
+ descriptions.
+* Implicit Links:: Bare URLs, WikiNames, and InterWiki
+ links.
+* Images:: Publishing and displaying images.
+* Horizontal Rules and Anchors:: Inserting a horizontal line or anchor.
+* Embedded Lisp:: Evaluating Emacs Lisp code in documents
+ for extensibility.
+* Citations:: Support for citing other resources.
+* Comments:: Lines to omit from published output.
+* Tag Summary:: Tags that Muse recognizes.
+
+Publishing Various Types of Documents
+
+* Blosxom:: Integrating Muse and pyblosxom.cgi.
+* Book:: Publishing entries into a compilation.
+* ConTeXt:: Publishing ConTeXt documents.
+* DocBook:: Publishing in DocBook XML form.
+* HTML:: Publishing in HTML or XHTML form.
+* Ikiwiki:: Integrating with ikiwiki.
+* Journal:: Keeping a journal or blog.
+* LaTeX:: Publishing LaTeX documents.
+* Poem:: Publish a poem to LaTeX or PDF.
+* Texinfo:: Publish entries to Texinfo format or PDF.
+* XML:: Publish entries to XML.
+
+Integrating Muse and pyblosxom.cgi
+
+* Blosxom Requirements:: Other tools needed for the Blosxom style.
+* Blosxom Entries:: Format of a Blosxom entry and automation.
+* Blosxom Options:: Blosxom styles and options provided.
+
+Making your own publishing styles
+
+* Markup Functions:: Specifying functions to mark up text.
+* Markup Regexps:: Markup rules for publishing.
+* Markup Strings:: Strings specific to a publishing style.
+* Markup Tags:: Tag specifications for special markup.
+* Style Elements:: Parameters used for defining styles.
+* Deriving Styles:: Deriving a new style from an existing
+ one.
+
+Miscellaneous add-ons, like a minor mode
+
+* Muse List Edit Minor Mode:: Edit lists easily in other major modes.
+
+\1f
+File: muse.info, Node: Preface, Next: Introduction, Prev: Top, Up: Top
+
+1 About the documentation
+*************************
+
+This document describes Muse, which was written by John Wiegley and is
+now maintained by Michael Olson. Several versions of this manual are
+available on-line.
+
+ * PDF: http://mwolson.org/static/doc/muse.pdf
+
+ * HTML (single file): http://mwolson.org/static/doc/muse.html
+
+ * HTML (multiple files): http://mwolson.org/static/doc/muse/
+
+\1f
+File: muse.info, Node: Introduction, Next: Obtaining Muse, Prev: Preface, Up: Top
+
+2 What is Muse?
+***************
+
+Emacs Muse (also known as "Muse" or "Emacs-Muse") is an authoring and
+publishing environment for Emacs. It simplifies the process of writing
+documents and publishing them to various output formats.
+
+ Muse consists of two main parts: an enhanced text-mode for authoring
+documents and navigating within Muse projects, and a set of publishing
+styles for generating different kinds of output.
+
+ What makes Muse distinct from other text-publishing systems is a
+modular environment, with a rather simple core, in which "styles" are
+derived from to create new styles. Much of Muse's overall
+functionality is optional. For example, you can use the publisher
+without the major-mode, or the mode without doing any publishing; or if
+you don't load the Texinfo or LaTeX modules, those styles won't be
+available.
+
+ The Muse codebase is a departure from emacs-wiki.el version 2.44. The
+code has been restructured and rewritten, especially its publishing
+functions. The focus in this revision is on the authoring and
+publishing aspects, and the "wikiness" has been removed as a default
+behavior (available in the optional `muse-wiki' module). CamelCase
+words are no longer special by default.
+
+ One of the principal aims in the development of Muse is to make it
+very easy to produce good-looking, standards-compliant documents.
+
+\1f
+File: muse.info, Node: Obtaining Muse, Next: Installation, Prev: Introduction, Up: Top
+
+3 How to Get Muse Releases and Development Changes
+**************************************************
+
+* Menu:
+
+* Releases:: Released versions of Muse.
+* Development:: Latest unreleased development changes.
+
+\1f
+File: muse.info, Node: Releases, Next: Development, Prev: Obtaining Muse, Up: Obtaining Muse
+
+3.1 Released versions of Muse
+=============================
+
+Choose to install a release if you want to minimize risk.
+
+ Errors are corrected in development first. User-visible changes
+will be announced on the <muse-el-discuss@gna.org> mailing list. *Note
+Getting Help and Reporting Bugs::.
+
+ Debian users can get Muse via apt-get. The `muse-el' package is
+available both at Michael Olson's APT repository and the official Debian
+repository. To make use of the former, add the following line to your
+`/etc/apt/sources.list' file and run `apt-get install muse'.
+
+ deb http://mwolson.org/debian/ ./
+
+ Ubuntu users can also get Muse via apt-get. The `muse-el' package
+is available both at Michael Olson's APT repository and the official
+Ubuntu repository. To make use of the former, add the following line to
+your `/etc/apt/sources.list' file and run `apt-get install muse'.
+
+ deb http://mwolson.org/ubuntu/ ./
+
+ The reason for making separate Debian and Ubuntu packages is that
+this manual is under the GFDL, and Debian will not allow it to be
+distributed in its main repository. Ubuntu, on the other hand, permits
+this manual to be included with the `muse-el' package.
+
+ Alternatively, you can download the latest release from
+`http://download.gna.org/muse-el/' .
+
+\1f
+File: muse.info, Node: Development, Prev: Releases, Up: Obtaining Muse
+
+3.2 Latest unreleased development changes
+=========================================
+
+Choose the development version if you want to live on the bleeding edge
+of Muse development or try out new features before release.
+
+ The git version control system allows you to keep up-to-date with the
+latest changes to the development version of Muse. It also allows you
+to contribute changes (via commits, if you are have developer access to
+the repository, or via patches, otherwise). If you would like to
+contribute to Muse development, it is highly recommended that you use
+git.
+
+ If you are new to git, you might find this tutorial helpful:
+`http://www.kernel.org/pub/software/scm/git/docs/tutorial.html'.
+
+ Downloading the Muse module with git and staying up-to-date involves
+the following steps.
+
+ 1. Install git.
+
+ * Debian and Ubuntu: `apt-get install git-core'.
+
+ * Windows: `http://git.or.cz/gitwiki/WindowsInstall'.
+
+ * Other operating systems: download, compile, and install the
+ source from `http://www.kernel.org/pub/software/scm/git/', or
+ find a git package for your operating system.
+
+ 2. Download the Muse development branch.
+
+ If you have developer access to Muse, do:
+
+ git clone ssh://repo.or.cz/srv/git/muse-el.git muse
+
+ otherwise, do:
+
+ git clone git://repo.or.cz/muse-el.git muse
+
+ If you are behind a restrictive firewall, and do not have developer
+ access, then do the following instead:
+
+ git clone http://repo.or.cz/r/muse-el.git muse
+
+ 3. List upstream changes that are missing from your local copy. Do
+ this whenever you want to see whether new changes have been
+ committed to Muse. If you wish, you may skip this step and
+ proceed directly to the "update" step.
+
+ # Change to the source directory you are interested in.
+ cd muse
+
+ # Fetch new changes from the repository, but don't apply them yet
+ git fetch origin
+
+ # Display log messages for the new changes
+ git log HEAD..origin
+
+ "origin" is git's name for the location where you originally got
+ Muse from. You can change this location at any time by editing the
+ `.git/config' file in the directory where the Muse source was
+ placed.
+
+ 4. Update to the latest version by pulling in any missing changes.
+
+ cd muse
+ git pull origin
+
+ git will show how many files changed, and will provide a visual
+ display for how many lines were changed in each file.
+
+
+ There are other ways to interact with the Muse repository.
+
+ * Browse git repo: `http://repo.or.cz/w/muse-el.git'
+
+ * Latest development snapshot:
+ `http://mwolson.org/static/dist/muse-latest.tar.gz'
+
+ * Latest development snapshot (zip file):
+ `http://mwolson.org/static/dist/muse-latest.zip'
+
+ The latest development snapshot can lag behind the git repo by as
+much as 20 minutes, but never more than that.
+
+Becoming a Muse developer
+-------------------------
+
+If you want commit access to the shared Muse repository, then register
+an account at `http://repo.or.cz' (be sure to add an SSH key), and
+contact the current maintainer at <mwolson@gnu.org>. It would be best
+to send some patches to the <muse-el-discuss@gna.org> mailing list
+first, so that he knows that you know what you are doing. *Note
+Getting Help and Reporting Bugs::, for instructions on subscribing to
+the mailing list.
+
+ You must also be willing to sign a copyright assignment for your
+changes to Muse, since Muse is a GNU project. The current maintainer
+will assist you in this process if you contact him.
+
+ For information on committing changes to Muse and performing
+development, please consult
+`http://emacswiki.org/cgi-bin/wiki/MuseDevelopment'.
+
+\1f
+File: muse.info, Node: Installation, Next: Getting Started, Prev: Obtaining Muse, Up: Top
+
+4 Compiling and Installing Muse
+*******************************
+
+Muse may be compiled and installed on your machine.
+
+Compilation
+-----------
+
+This is an optional step, since Emacs Lisp source code does not
+necessarily have to be byte-compiled. Byte-compilation may yield a very
+slight speed increase.
+
+ A working copy of Emacs or XEmacs is needed in order to compile Emacs
+Muse. By default, the program that is installed with the name `emacs'
+will be used.
+
+ If you want to use the `xemacs' binary to perform the compilation,
+you must copy `Makefile.defs.default' to `Makefile.defs' in the
+top-level directory, and then edit `Makefile.defs' as follows. You can
+put either a full path to an Emacs or XEmacs binary or just the command
+name, as long as it is in the `PATH'.
+
+ EMACS = xemacs
+ SITEFLAG = -no-site-file
+ # Edit the section as necessary
+ install_info = install-info --section "XEmacs 21.4" $(1).info \
+ $(INFODIR)/dir || :
+
+ Running `make' in the top-level directory should compile the Muse
+source files in the `lisp' directory, and generate an autoloads file in
+`lisp/muse-autoloads.el'.
+
+Installation
+------------
+
+Muse may be installed into your file hierarchy by doing the following.
+
+ Copy `Makefile.defs.default' to `Makefile.defs' in the top-level
+directory, if you haven't done so already. Then edit the
+`Makefile.defs' file so that `ELISPDIR' points to where you want the
+source and compiled Muse files to be installed and `INFODIR' indicates
+where to put the Muse manual. You may use a combination of `DESTDIR'
+and `PREFIX' to further determine where the installed files should be
+placed. As mentioned earlier, you will want to edit `EMACS' and
+`SITEFLAG' as shown in the Compilation section if you are using XEmacs.
+
+ If you are installing Muse on a Debian or Ubuntu system, you might
+want to change the value of `INSTALLINFO' as specified in
+`Makefile.defs'.
+
+ If you wish to install Muse to different locations than the defaults
+specify, edit `Makefile.defs' accordingly.
+
+ Run `make' as a normal user, if you haven't done so already.
+
+ Run `make install' as the root user if you have chosen installation
+locations that require root permissions.
+
+ELPA
+----
+
+For those used to installing software packages, there will be a `muse'
+package available in the Emacs Lisp Package Archive (abbreviated
+"ELPA") as of the 3.10 release of Muse. This package will be compiled
+and installed automatically in a user-specific location. For more
+information on ELPA, see `http://tromey.com/elpa/'.
+
+\1f
+File: muse.info, Node: Getting Started, Next: Projects, Prev: Installation, Up: Top
+
+5 Getting Started
+*****************
+
+* Menu:
+
+* Loading Muse:: How to load Muse.
+* Using Muse Mode:: How to edit files in Muse.
+* Publishing Files Overview:: Publishing a single file or project.
+* File Extensions:: Using a different file extension.
+
+\1f
+File: muse.info, Node: Loading Muse, Next: Using Muse Mode, Prev: Getting Started, Up: Getting Started
+
+5.1 How to Load Muse
+====================
+
+To use Muse, add the directory containing its files to your `load-path'
+variable, in your `.emacs' file. Then, load in the authoring mode, and
+the styles you wish to publish to. An example follows.
+
+ (add-to-list 'load-path "<path to Muse>")
+
+ (require 'muse-mode) ; load authoring mode
+
+ (require 'muse-html) ; load publishing styles I use
+ (require 'muse-latex)
+ (require 'muse-texinfo)
+ (require 'muse-docbook)
+
+ (require 'muse-project) ; publish files in projects
+
+ An easy way of seeing which settings are available and changing
+settings is to use the Muse customization interface. To do this, type
+`M-x customize-group muse RET'. Each of the options has its own
+documentation. Options are grouped logically according to what effect
+they have.
+
+\1f
+File: muse.info, Node: Using Muse Mode, Next: Publishing Files Overview, Prev: Loading Muse, Up: Getting Started
+
+5.2 How to Edit Files in Muse
+=============================
+
+Muse Mode should automatically be activated when you visit a file with a
+".muse" extension. One such file is `QuickStart.muse', which is
+available in the `examples' directory of the Muse distribution. You
+can tell that Muse Mode has been activated by checking for the text
+"Muse" in your mode line. If Muse Mode has not been activated, you may
+activate it by type `M-x muse-mode RET'.
+
+ You will notice that Muse files are highlighted very simply. Links
+are colored blue, headings are large and bold text, and <example> tags
+are colored in grey.
+
+ There are several different ways to edit things like links, which
+hide the underlying Muse markup. One way is to toggle font-locking off
+by hitting `C-c C-l', which is also `M-x font-lock-mode', make changes,
+and then hit `C-c C-l' again to toggle font-locking back on. Another
+way is just to move into the text and edit it. Markup can also be
+removed by normal deletion methods, though some side effects might
+require a second deletion.
+
+ For the particular case of editing links, it is easiest to move to
+the link and do `C-c C-e', which is also `M-x muse-edit-link-at-point'.
+This prompts you for the link and its description, using the previous
+contents of the link as initial values. A link to another Muse file
+may be created by hitting `C-c TAB l'. A link to a URL may be created
+by hitting `C-c TAB u'. Links may be followed by hitting `RET' on them.
+
+ If you want to add a new list item, this may by accomplished by
+hitting `M-RET'. This will put a dash and some spaces on the screen.
+The dash is the Muse markup that indicates a list item. It is also
+possible to created "nested" lists with this command, by adjusting the
+number of spaces in front of the dashes. If you have lists with long
+lines, you can move to a list item and hit `M-q' to wrap it onto
+multiple lines.
+
+\1f
+File: muse.info, Node: Publishing Files Overview, Next: File Extensions, Prev: Using Muse Mode, Up: Getting Started
+
+5.3 Publishing a Single File or Project
+=======================================
+
+The command `M-x muse-project-publish-this-file' will publish the
+current document to any available publishing style (a publishing style
+is an output format, like HTML or Docbook), placing the output in the
+current directory. If you are in Muse Mode, this command will be bound
+to `C-c C-t'. If the file has been published recently, and its
+contents have not changed, running `C-c C-t' again will not publish the
+file. To force publishing in this case, do `C-u C-c C-t'.
+
+ If you have set up projects and are visiting a file that is part of a
+project, then `C-c C-t' will restrict the output formats to those which
+are used by the project, and will automatically publish to the output
+directory defined by the project. If you want to publish to a
+different directory or use a different format, then use `C-c M-C-t',
+which is also `M-x muse-publish-this-file'.
+
+ If the currently opened file is part of a defined project in
+`muse-project-alist', it (and the rest of the changed files in a
+project) may be published using `C-c C-p'.
+
+\1f
+File: muse.info, Node: File Extensions, Prev: Publishing Files Overview, Up: Getting Started
+
+5.4 Using a Different File Extension
+====================================
+
+By default, Muse expects all project files to have the file extension
+`.muse'. Files without this extension will not be associated with Muse
+mode and will not be considered part of any project, even if they are
+within a project directory.
+
+ If you don't want to use `.muse', you can customize the extension by
+setting the value of `muse-file-extension'.
+
+ If you don't want to use any extension at all, and want Muse to
+autodetect project files based on their location, then add the following
+to your Muse settings file.
+
+ (setq muse-file-extension nil
+ muse-mode-auto-p t)
+
+ Note that if you chose to have `muse-file-extension' set to `nil',
+you may have trouble if your `.emacs' file or other init scripts
+attempt to visit a Muse file. (A very common example of this is if you
+use Planner with Muse and run `(plan)' from your `.emacs'.) If you
+wish to visit Muse files from your `.emacs', be sure to also add the
+following additional code before any such visits happen:
+
+ (add-hook 'find-file-hooks 'muse-mode-maybe)
+
+\1f
+File: muse.info, Node: Projects, Next: Keystroke Summary, Prev: Getting Started, Up: Top
+
+6 Creating and Managing Muse Projects
+*************************************
+
+Often you will want to publish all the files within a directory to a
+particular set of output styles automatically. To support, Muse allows
+for the creation of "projects".
+
+* Menu:
+
+* Single Project:: A single-project example.
+* Multiple Projects:: A multiple-project example.
+* Projects and Subdirectories:: Publishing subdirectories in projects.
+* Options for Projects:: Listing of available options for projects.
+
+\1f
+File: muse.info, Node: Single Project, Next: Multiple Projects, Prev: Projects, Up: Projects
+
+6.1 A Single-Project Example
+============================
+
+Here is a sample project, which may be defined in your `.emacs' file.
+
+ (setq muse-project-alist
+ '(("Website" ("~/Pages" :default "index")
+ (:base "html" :path "~/public_html")
+ (:base "pdf" :path "~/public_html/pdf"))))
+
+ The above defines a project named "website", whose files are located
+in the directory `~/Pages'. The default page to visit is `index'.
+When this project is published, each page will be output as HTML to the
+directory `~/public_html', and as PDF to the directory
+`~/public_html/pdf'. Within any project page, you may create a link to
+other pages using the syntax `[[pagename]]'.
+
+ If you would like to include only some files from a directory in a
+Muse project, you may use a regexp in place of `~/Pages' in the example.
+
+\1f
+File: muse.info, Node: Multiple Projects, Next: Projects and Subdirectories, Prev: Single Project, Up: Projects
+
+6.2 A Multiple-Project Example
+==============================
+
+It is possible to specify multiple projects. Here is an example of
+three projects: a generic website, a projects area, and a day-planner
+(the day-planner part requires Planner Mode--see
+`http://wjsullivan.net/PlannerMode.html' to get it).
+
+ (setq muse-project-alist
+ '(("Website" ("~/Pages" :default "index")
+ (:base "html" :path "~/public_html"))
+ (("Projects" ("~/Projects" :default "index")
+ (:base "xhtml"
+ :path "~/public_html/projects"
+ :exclude "/TopSecret")
+ (:base "pdf"
+ :path "~/public_html/projects/pdf"
+ :exclude "/TopSecret")))
+ ("Plans" ("~/Plans"
+ :default "TaskPool"
+ :major-mode planner-mode
+ :visit-link planner-visit-link)
+ (:base "planner-xhtml"
+ :path "~/public_html/plans"))))
+
+ The `:major-mode' attribute specifies which major to use when
+visiting files in this directory.
+
+ The `:visit-link' attribute specifies the function to call when
+visiting links.
+
+ The `:exclude' attribute has a regexp that matches files to never
+publish.
+
+\1f
+File: muse.info, Node: Projects and Subdirectories, Next: Options for Projects, Prev: Multiple Projects, Up: Projects
+
+6.3 Publishing Subdirectories in Projects
+=========================================
+
+If you want to publish a directory and all of its subdirectories, Muse
+provides two convenience functions that together generate the proper
+rules for you. Note that we use the backtick to begin this
+muse-project-alist definition, rather than a single quote.
+
+ (setq muse-project-alist
+ `(("Website" ("~/Pages" :default "index")
+ (:base "html" :path "~/public_html"))
+ ("Blog" (,@(muse-project-alist-dirs "~/Blog")
+ :default "index")
+ ;; Publish this directory and its subdirectories. Arguments
+ ;; are as follows. The above `muse-project-alist-dirs' part
+ ;; is also needed.
+ ;; 1. Source directory
+ ;; 2. Output directory
+ ;; 3. Publishing style
+ ;; remainder: Other things to put in every generated style
+ ,@(muse-project-alist-styles "~/Blog"
+ "~/public_html/blog"
+ "blosxom"))))
+
+ The `muse-project-alist-dirs' function takes a directory and returns
+it and all of its subdirectories in a list.
+
+ The `muse-project-alist-styles' function is explained by the
+comments above.
+
+ The "blosxom" text is the name of another publishing style, much like
+"html". *Note Blosxom::, for further information about it. You can
+use any publishing style you like for the third argument to
+`muse-project-alist-styles'.
+
+\1f
+File: muse.info, Node: Options for Projects, Prev: Projects and Subdirectories, Up: Projects
+
+6.4 Listing of Available Options for Projects
+=============================================
+
+This is a listing of all of the various options (or, more accurately:
+attributes) that may be specified in `muse-project-alist'.
+
+ Each muse-project-alist entry looks like this:
+
+ (PROJECT-NAME (SOURCES)
+ OUTPUTS)
+
+ We refer to these names below.
+
+ "Attributes", which compose SOURCES and OUTPUTS, are a pair of
+values. The first value is a keyword, like `:default'. The second part
+is the value associated with that keyword, such as the text "index".
+If you are familiar with Emacs Lisp property lists, the concept is
+similar to that, except that in the SOURCES section, single directories
+can be interspersed with two-value attributes.
+
+Project Name
+------------
+
+This is a string that indicates the name of the project. It is
+primarily used for publishing interwiki links with the `muse-wiki.el'
+module.
+
+Sources
+-------
+
+This part of a muse-project-alist entry consists of two-value
+attributes, and also directory names. If you are publishing a book, the
+order of directories and attributes is significant.
+
+ The minimal content for the sources section is a list of directories.
+
+`:book-chapter'
+ Indicates a new chapter of a book. The text of the title of the
+ chapter comes immediately after this keyword.
+
+`:book-end'
+ Indicates the end of a book. Directories listed after this one are
+ ignored when publishing a book. The value "t" (without quotes)
+ should come immediately after this keyword.
+
+`:book-funcall'
+ A function to call while publishing a book. This is useful for
+ doing something just after a particular chapter.
+
+`:book-part'
+ Indicates the beginning of a new part of the book. The text of the
+ title should come immediately after this keyword.
+
+`:book-style'
+ Indicate a particular publishing style to use for this part of the
+ book. If this is specified, it should come just after a `:part'
+ attribute.
+
+`:default'
+ The default page to visit when browsing a project. Also, if you
+ are using the `muse-wiki.el' module, publishing a link to just a
+ project's name will cause it to link to this default file.
+
+`:force-publish'
+ This specifies a list of pages which should be published every
+ time a project is published (by using `C-c C-p', for example),
+ regardless of whether their contents have changed. This is useful
+ for updating Index pages, pages that use the <include> tag, and
+ other pages that have dynamically-generated content.
+
+`:major-mode'
+ This specifies the major mode to use when visiting files in this
+ project. The default is `muse-mode'.
+
+`:nochapters'
+ This indicates that while publishing a book, do not automatically
+ create chapters. Values which may follow this are nil (the
+ default, which means that we automatically create chapters), or
+ non-nil, which means that we manually specify chapters with the
+ `:book-chapter' attribute,
+
+`:publish-project'
+ Indicates which function we should call when publishing a project.
+
+`:set'
+ This specifies a list of variables and values to set when
+ publishing a project. The list should be a property list, which
+ is in the form:
+
+ (VAR1 VALUE1 VAR2 VALUE2 ...)
+
+`:visit-link'
+ Specifies the function to call when visiting a link. The default
+ is `muse-visit-link-default'. The arguments for that function
+ should be (1) the link and (2) whether to visit the link in a new
+ window.
+
+
+Outputs
+-------
+
+This part of a muse-project-alist entry is composed of lists of
+attributes. Each list is called an "output style".
+
+ The minimal content for an output style is a `:base' attribute and a
+`:path' attribute.
+
+`:base'
+ Publishing style to use, such as "html", "docbook", or "pdf".
+
+`:base-url'
+ An external URL which can be used to access published files. This
+ is mainly used by the `muse-wiki' module when publishing links
+ between two separate projects, if the projects are served on
+ different domains.
+
+ It is also used by the `muse-journal' module to create the RSS or
+ RDF output.
+
+`:exclude'
+ Exclude items matching a regexp from being published. The regexp
+ should usually begin with "/".
+
+`:include'
+ Only include items matching a regexp when publishing. The regexp
+ should usually begin with "/".
+
+`:path'
+ The directory in which to store published files.
+
+`:timestamps'
+ A file containing the timestamps (that is, time of creation) for
+ files in this project. It might eventually used by the
+ `muse-blosxom' module, but this option is not currently in use by
+ any Muse code.
+
+
+\1f
+File: muse.info, Node: Keystroke Summary, Next: Markup Rules, Prev: Projects, Up: Top
+
+7 Keys Used in Muse Mode
+************************
+
+This is a summary of keystrokes available in every Muse buffer.
+
+`C-c C-a (`muse-index')'
+ Display an index of all known Muse pages.
+
+`C-c C-b (`muse-find-backlinks')'
+ Find all pages that link to this page.
+
+`C-c C-e (`muse-edit-link-at-point')'
+ Edit link at point.
+
+`C-c C-f (`muse-project-find-file')'
+ Open another Muse page. Prompt for the name.
+
+`C-c C-i l, C-c TAB l (`muse-insert-relative-link-to-file')'
+ Insert a link to a file interactively.
+
+`C-c C-i t, C-c TAB t (`muse-insert-tag')'
+ Insert a tag interactively.
+
+`C-c C-i u, C-c TAB u (`muse-insert-url')'
+ Insert a URL interactively.
+
+`C-c C-l (`font-lock-mode')'
+ Toggle font lock / highlighting for the current buffer.
+
+`C-c C-p (`muse-project-publish')'
+ Publish any Muse pages that have changed.
+
+`C-c C-s (`muse-search')'
+ Find text in all files of the current project.
+
+`C-c C-t (`muse-project-publish-this-file')'
+ Publish the currently-visited file. Prompt for the style if the
+ current file can be published using more than one style.
+
+`C-c C-S-t, or C-c C-M-t (`muse-publish-this-file')'
+ Publish the currently-visited file. Prompt for both the style and
+ output directory.
+
+`C-c C-v (`muse-browse-result')'
+ Show the published result of this page.
+
+`C-c = (`muse-what-changed')'
+ Diff this page against the last backup version.
+
+`TAB'
+ Move to the next Wiki reference.
+
+`S-TAB'
+ Move to the previous Wiki reference.
+
+`M-TAB'
+ Complete the name of a page from the current project at point.
+
+`M-RET'
+ Insert a new list item at point, indenting properly.
+
+`C-<'
+ Decrease the indentation of the list item at point.
+
+`C->'
+ Increase the indentation of the list item at point.
+
+`M-x muse-colors-toggle-inline-images RET'
+ Toggle display of inlined images on/off.
+
+`M-x muse-update-values RET'
+ Update various values that are automatically generated.
+
+ Call this after changing `muse-project-alist'.
+
+\1f
+File: muse.info, Node: Markup Rules, Next: Publishing Styles, Prev: Keystroke Summary, Up: Top
+
+8 Rules for Using Markup
+************************
+
+A Muse document uses special, contextual markup rules to determine how
+to format the output result. For example, if a paragraph is indented,
+Muse assumes it should be quoted.
+
+ There are not too many markup rules, and all of them strive to be as
+simple as possible so that you can focus on document creation, rather
+than formatting.
+
+* Menu:
+
+* Paragraphs:: Paragraphs: centering and quoting.
+* Headings:: Levels of headings.
+* Directives:: Directives at the beginning of a
+ document.
+* Emphasizing Text:: Bold, italicized, and underlined text.
+* Footnotes:: Making notes to be shown at the end.
+* Verse:: Indicating poetic stanzas.
+* Lists:: Lists of items.
+* Tables:: Generation of data tables.
+* Explicit Links:: Hyperlinks and email addresses with
+ descriptions.
+* Implicit Links:: Bare URLs, WikiNames, and InterWiki
+ links.
+* Images:: Publishing and displaying images.
+* Horizontal Rules and Anchors:: Inserting a horizontal line or anchor.
+* Embedded Lisp:: Evaluating Emacs Lisp code in documents
+ for extensibility.
+* Citations:: Support for citing other resources.
+* Comments:: Lines to omit from published output.
+* Tag Summary:: Tags that Muse recognizes.
+
+\1f
+File: muse.info, Node: Paragraphs, Next: Headings, Prev: Markup Rules, Up: Markup Rules
+
+8.1 Paragraphs: centering and quoting
+=====================================
+
+Paragraphs in Muse must be separated by a blank line.
+
+Centered paragraphs and quotations
+----------------------------------
+
+A line that begins with six or more columns of whitespace (either tabs
+or spaces) indicates a centered paragraph. Alternatively, you can use
+the <center> tag to surround regions that are to be published as
+centered paragraphs.
+
+ But if a line begins with whitespace, though less than six columns,
+it indicates a quoted paragraph. Alternatively, you can use the
+<quote> tag to surround regions that are to be published as quoted
+paragraphs.
+
+Literal paragraphs
+------------------
+
+The <example> tag is used for examples, where whitespace should be
+preserved, the text rendered in monospace, and any characters special
+to the output style escaped.
+
+ There is also the <literal> tag, which causes a marked block to be
+entirely left alone. This can be used for inserting a hand-coded HTML
+blocks into HTML output, for example.
+
+ If you want some text to only be inserted when publishing to a
+particular publishing style, use the `style' attribute for the
+<literal> tag. An example follows.
+
+ <literal style="latex">
+ A LaTeX-based style was used in the publishing of this document.
+ </literal>
+
+ This will leave the region alone if the current publishing style is
+"latex" or based on "latex", such as "pdf", and delete the region
+otherwise. It is also possible to leave the text alone only for one
+particular style, rather than its derivations, by adding `exact="t"' to
+the tag.
+
+Line breaks
+-----------
+
+If you need a line break, then use the `<br>' tag. Most of the time
+this tag is unnecessary, because Muse will automatically detect
+paragraphs by means of blank lines. If you want to preserve newlines in
+several lines of text, then use verse markup instead (*note Verse::).
+
+\1f
+File: muse.info, Node: Headings, Next: Directives, Prev: Paragraphs, Up: Markup Rules
+
+8.2 Levels of headings
+======================
+
+A heading becomes a chapter or section in printed output - depending on
+the style. To indicate a heading, start a new paragraph with one or
+more asterices, followed by a space and the heading title. Then begin
+another paragraph to enter the text for that section.
+
+ All levels of headings will be published. Most publishing styles
+only distinguish the between the first 4 levels, however.
+
+ * First level
+
+ ** Second level
+
+ *** Third level
+
+ **** Fourth level
+
+\1f
+File: muse.info, Node: Directives, Next: Emphasizing Text, Prev: Headings, Up: Markup Rules
+
+8.3 Directives at the beginning of a document
+=============================================
+
+Directives are lines beginning with the `#' character that come before
+any paragraphs or sections in the document. Directives are of the form
+"#directive content of directive". You can use any combination of
+uppercase and lowercase letters for directives, even if the directive
+is not in the list below.
+
+ The `muse-publishing-directive' function may be used in header and
+footer text to access directives. For example, to access the `#title'
+directive, use `(muse-publishing-directive "title")'.
+
+ The following is a list of directives that Muse uses.
+
+`#author'
+ The author of this document.
+
+ If this is not specified, Muse will attempt to figure it out from
+ the `user-full-name' variable.
+
+`#date'
+ The date that the document was last modified.
+
+ This is used by publishing styles that are able to embed the date
+ information.
+
+`#desc'
+ A short description of this document.
+
+ This is used by the `journal' publishing style to embed information
+ inside of an RSS/RDF feed.
+
+`#title'
+ The title of this document.
+
+ If this is not specified, the name of the file is used.
+
+
+\1f
+File: muse.info, Node: Emphasizing Text, Next: Footnotes, Prev: Directives, Up: Markup Rules
+
+8.4 Bold, italicized, and underlined text
+=========================================
+
+To emphasize text, surround it with certain specially recognized
+characters.
+
+ *emphasis*
+ **strong emphasis**
+ ***very strong emphasis***
+ _underlined_
+ =verbatim and monospace=
+
+ While editing a Muse document in Muse mode, these forms of emphasis
+will be highlighted in a WYSIWYG manner. Each of these forms may span
+multiple lines.
+
+ Verbatim text will be colored as gray by default. To change this,
+customize `muse-verbatim-face'.
+
+ You can also use the <code> tag to indicate verbatim and monospace
+text. This is handy for regions that have an "=" in them.
+
+\1f
+File: muse.info, Node: Footnotes, Next: Verse, Prev: Emphasizing Text, Up: Markup Rules
+
+8.5 Making notes to be shown at the end
+=======================================
+
+A footnote reference is simply a number in square brackets. To define
+the footnote, place this definition at the bottom of your file.
+`footnote-mode' can be used to greatly facilitate the creation of these
+kinds of footnotes.
+
+ Footnotes are defined by the same number in brackets occurring at the
+beginning of a line. Use footnote-mode's `C-c ! a' command, to very
+easily insert footnotes while typing. Use `C-x C-x' to return to the
+point of insertion.
+
+\1f
+File: muse.info, Node: Verse, Next: Lists, Prev: Footnotes, Up: Markup Rules
+
+8.6 Indicating poetic stanzas
+=============================
+
+Poetry requires that whitespace be preserved, but without resorting to
+monospace. To indicate this, use the following markup, reminiscent of
+email quotations.
+
+ > A line of Emacs verse;
+ > forgive its being so terse.
+
+ You can also use the <verse> tag, if you prefer.
+
+ <verse>
+ A line of Emacs verse;
+ forgive its being so terse.
+ </verse>
+
+ Multiple stanzas may be included in one set of <verse> tags, as
+follows.
+
+ <verse>
+ A line of Emacs verse;
+ forgive its being so terse.
+
+ In terms of terse verse,
+ you could do worse.
+ </verse>
+
+\1f
+File: muse.info, Node: Lists, Next: Tables, Prev: Verse, Up: Markup Rules
+
+8.7 Lists of items
+==================
+
+Lists are given using special characters at the beginning of a line.
+Whitespace must occur before bullets or numbered items, to distinguish
+from the possibility of those characters occurring in a real sentence.
+
+ These are rendered as a bullet list.
+
+ Normal text.
+
+ - bullet item one
+ - bullet item two
+
+ An enumerated list follows.
+
+ Normal text.
+
+ 1. Enum item one
+ 2. Enum item two
+
+ Here is a definition list.
+
+ Term1 ::
+ This is a first definition
+ And it has two lines;
+ no, make that three.
+
+ Term2 :: This is a second definition
+
+Nested lists
+------------
+
+It is possible to nest lists of the same or different kinds. The
+"level" of the list is determined by the amount of initial whitespace.
+
+ Normal text.
+
+ - Level 1, bullet item one
+ 1. Level 2, enum item one
+ 2. Level 2, enum item two
+ - Level 1, bullet item two
+ 1. Level 2, enum item three
+ 2. Level 2, enum item four
+ term :: definition
+
+Breaking list items
+-------------------
+
+If you want to break up a line within any list type, just put one blank
+line between the end of the previous line and the beginning of the next
+line, using the same amount of initial indentation.
+
+ - bullet item 1, line 1
+
+ bullet item 1, line 2
+
+ 1. Enum line 1
+
+ Enum line 2
+
+ - bullet item 2, line 1
+
+ bullet item 2, line 2
+
+\1f
+File: muse.info, Node: Tables, Next: Explicit Links, Prev: Lists, Up: Markup Rules
+
+8.8 Generation of data tables
+=============================
+
+Only very simple tables are supported. The syntax is as follows.
+
+ Double bars || Separate header fields
+
+ Single bars | Separate body fields
+ Here are more | body fields
+
+ Triple bars ||| Separate footer fields
+
+ Some publishing styles require header fields to come first, then
+footer fields, and then the body fields. You can use any order for
+these sections that you like, and Muse will re-order them for you at
+publish-time.
+
+ If you wish to disable table generation for one Muse file, add the
+directive `#disable-tables t' to the top of the file.
+
+Other table formats
+-------------------
+
+It is possible to publish very basic Orgtbl-mode style tables.
+
+ | org | style | table |
+ |------+-------+-------|
+ | one | | one |
+ | two | two | |
+ | | three | three |
+ |------+-------+-------|
+ | more | stuff | |
+
+ If you are used to the way that Org Mode publishes these tables, then
+customize `muse-html-table-attributes' to the following, in order to get
+a similar kind of output.
+
+ border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"
+
+ `table.el' style tables are also supported, as long as `table.el'
+itself supports outputting tables for a particular publishing style.
+At the time of this writing, the "html", "latex", and "docbook" styles
+are supported by `table.el'. Styles derived from these styles will
+also work.
+
+ +---+-----+---+
+ | | one | 1 |
+ +---+-----+---+
+ | b | two | |
+ +---+-----+---+
+ | c | | 3 |
+ +---+-----+---+
+
+\1f
+File: muse.info, Node: Explicit Links, Next: Implicit Links, Prev: Tables, Up: Markup Rules
+
+8.9 Hyperlinks and email addresses with descriptions
+====================================================
+
+A hyperlink can reference a URL, or another page within a Muse project.
+In addition, descriptive text can be specified, which should be
+displayed rather than the link text in output styles that supports link
+descriptions. The syntax is as follows.
+
+ [[link target][link description]]
+ [[link target without description]]
+
+ Thus, the current maintainer's homepage for Muse can be found
+`[[http://mwolson.org/projects/EmacsMuse.html][here]]', or at
+`[[http://mwolson.org/projects/EmacsMuse.html]]'.
+
+\1f
+File: muse.info, Node: Implicit Links, Next: Images, Prev: Explicit Links, Up: Markup Rules
+
+8.10 Bare URLs, WikiNames, and InterWiki links
+==============================================
+
+A URL or email address encountered in the input text is published as a
+hyperlink. These kind of links are called "implicit links" because
+they are not separated from the rest of the Muse document in any way.
+
+ Some characters in URLs will prevent Muse from recognizing them as
+implicit links. If you want to link to a URL containing spaces or any of
+the characters "][,"'`()<>^", you will have to make the link explicit.
+The punctuation characters ".,;:" are also not recognized as part of a
+URL when they appear at its end. For information on how to make an
+explicit link, see *note Hyperlinks and email addresses with
+descriptions: Explicit Links.
+
+ If the `muse-wiki' module is loaded, another form of implicit link
+will be made available. WikiNames, which are typed in CamelCase, are
+highlighted and published as links, provided that the file they refer
+to exists.
+
+ Customization of WikiName recognition may be accomplished by editing
+the `muse-wiki-wikiword-regexp' option and subsequently running
+`(muse-configure-highlighting 'muse-colors-markupmuse-colors-markup)'.
+If you use the Customize interface, the latter will be done
+automatically.
+
+ The `muse-wiki' module also allows for InterWiki links. These are
+similar to WikiWords, but they specify both the project and page of a
+file. The names of your project entries in `muse-project-alist' will
+be used as InterWiki names by default. Several examples follow.
+
+ Blog::DocumentingMuse
+ Projects#EmacsMuse
+ Website
+
+ In the first case, the interwiki delimiter is `::', `Blog' is the
+project name, and `DocumentingMuse' is the page name. In the second
+example, `#' is the interwiki delimiter. If the name of a project
+occurs by itself in text, like the third case, it will be colorized and
+published as a link to the default page of the given project.
+
+ Customization of interwiki links may be accomplished by editing the
+`muse-wiki-interwiki-alist' option.
+
+ It is also possible to link to an anchor in an interwiki document.
+This is called a "three-part link". Examples of this follow.
+
+ Blog::DocumentingMuse#anchor1
+ Projects#EmacsMuse#anchor2
+
+\1f
+File: muse.info, Node: Images, Next: Horizontal Rules and Anchors, Prev: Implicit Links, Up: Markup Rules
+
+8.11 Publishing and displaying images
+=====================================
+
+Image links
+-----------
+
+Links to images may be used in either the target or the description, or
+both. Thus, the following code will publish as a clickable image that
+points to `http://mwolson.org/'.
+
+ [[http://mwolson.org/][/static/logos/site-logo.png]]
+
+ Normally, images in the link part will be inlined.
+
+ If you want these images to be published as links instead, place the
+text "URL:" immediately in front of the link text. An example follows.
+
+ [[URL:http://mwolson.org/static/logos/site-logo.png]]
+
+Displaying images in Muse mode
+------------------------------
+
+If a link to a locally-available image is encountered in the link
+description, Muse mode will attempt to display it if your version of
+Emacs permits this.
+
+ This behavior may be toggled with `C-c C-i', or disabled permanently
+by setting the `muse-colors-inline-images' option to `nil'.
+
+ The method for finding images may be altered by customizing the
+`muse-colors-inline-image-method' option. One useful value for this
+option is `muse-colors-use-publishing-directory', which tells Muse mode
+to look in the directory where the current file will be published. The
+default is to look in the current directory. Relative paths like
+`../pics/' should work for either setting.
+
+ Eventually, it is hoped that Muse will be able to copy images from
+the a "source" directory to a publishing directory by customizing
+`muse-project-alist', but this has not been implemented yet.
+
+Publishing simple images
+------------------------
+
+The following example will display correctly and publish correctly if a
+PNG file called `TestLogo.png' exists in the `../pics/' directory. If
+text is on the same line as the picture, it will remain so in the
+output.
+
+ [[../myimage.png]]
+
+Publishing images with captions
+-------------------------------
+
+If you want to add a caption to an image, use the following syntax.
+This will center the image (if the output format supports it) and add a
+centered caption below the picture. Formats that do not support
+centering the image will instead leave it against the left margin.
+
+ [[../pics/mycat.png][My cat Dexter]]
+
+ Images with captions may only occur in their own paragraphs, with no
+text on the same line. Otherwise, the published output will not be
+syntactically correct.
+
+\1f
+File: muse.info, Node: Horizontal Rules and Anchors, Next: Embedded Lisp, Prev: Images, Up: Markup Rules
+
+8.12 Inserting a horizontal line or anchor
+==========================================
+
+Horizontal Rules
+----------------
+
+Four or more dashes indicate a horizontal rule. Be sure to put blank
+lines around it, or it will be considered part of the proceeding or
+following paragraph!
+
+Anchors
+-------
+
+If you begin a line with "#anchor" - where "anchor" can be any word
+that doesn't contain whitespace - it defines an anchor at that point
+into the document. This point can be referenced using "page#anchor" as
+the target in a Muse link.
+
+\1f
+File: muse.info, Node: Embedded Lisp, Next: Citations, Prev: Horizontal Rules and Anchors, Up: Markup Rules
+
+8.13 Evaluating Emacs Lisp code in documents for extensibility
+==============================================================
+
+Arbitrary kinds of markup can be achieved using the <lisp> tag. With
+the <lisp> tag, you may generate whatever output text you wish. The
+inserted output will get marked up if the <lisp> tag appears within the
+main text of the document.
+
+ <lisp>(concat "This form gets " "inserted")</lisp>
+
+ Note that you should not use the `insert' command within a set of
+<lisp> tags, since the return value from the <lisp> tags will be
+automatically inserted into the document.
+
+ It is also possible to treat the output as if it were surrounded by
+the <example>, <src>, or <verse> tags, by specifying "example", "src",
+or "verse" as the `markup' attribute of the <lisp> tag.
+
+ <lisp markup="example">
+ (concat "Insert" " me")
+ </lisp>
+
+ Other languages also have tags that cause source code to be
+evaluated. *Note Tag Summary::, for details.
+
+\1f
+File: muse.info, Node: Citations, Next: Comments, Prev: Embedded Lisp, Up: Markup Rules
+
+8.14 Support for citing other resources
+=======================================
+
+Example
+-------
+
+Here is an example of what citations look like in a Muse document.
+
+ #bibsource REFDB
+
+ * Title
+ ** Subtitle
+
+ Some text before <cite>Miller1999</cite> and after the citation.
+
+ This is an author-only citation <cite type="author">Miller1999</cite>.
+
+ And this is a year-only citation <cite type="year">Miller1999</cite>.
+
+ Finally, this is a multi-head citation
+ <cite>Miller1999,Andrews2005</cite>.
+
+Overview
+--------
+
+The `#bibsource' directive defines the source of the bibliographies.
+The following sources are possible.
+
+ * DocBook + RefDB: the string "REFDB"
+
+ * LaTeX + bibtex: the name of an appropriate bibtex file
+
+ * LaTeX + RefDB: if the input file is called "foo.muse", then set
+ this to "foo.bib"
+
+ Citations are encoded as <cite> elements which enclose the citation
+keys as they are defined in the bibliography file or database. In
+multi-head citations, the citation keys have to be separated by colons
+or semicolons. The `latex' and `docbook' styles translate these to the
+proper separator automatically.
+
+ The <cite> elements take an optional "type" attribute that defines
+how the citation is rendered. If the attribute is missing, you'll get
+a regular citation according to the bibliography style, e.g." (Miller
+et al., 1999)". If the attribute is set to "author", only the name of
+the author(s) will be rendered. Accordingly, "year" will cause the
+year to be printed. This is useful to create citations like this:
+
+ Miller et al. had already shown in a previous publication (1999) that
+ this is not going to work.
+
+ Remember that refdb-mode (the Emacs interface to RefDB) can retrieve
+references by simply marking the citation key and running the
+`refdb-getref-by-field-on-region' command. Later versions of
+`refdb-mode' will also allow to insert references as Muse citations
+(which is already implemented for DocBook, TEI, and LaTeX documents).
+
+ You may have noticed that there is no element to indicate the
+position of the bibliography. The latter is always created at a valid
+position close to the end of the document. The functions
+`muse-docbook-bibliography' and `muse-latex-bibliography' are called in
+the header or footer to generate this content, so it is possible to
+change the exact position.
+
+\1f
+File: muse.info, Node: Comments, Next: Tag Summary, Prev: Citations, Up: Markup Rules
+
+8.15 Lines to omit from published output
+========================================
+
+Use the following syntax to indicate a comment. Comments will not be
+published.
+
+ ; Comment text goes here.
+
+ That is, only a semi-colon at the beginning of a line, followed by a
+literal space, will cause that line to be treated as a comment.
+
+ You can alternatively surround the region with the <comment> tag.
+
+ If you wish the comment to be published, but just commented out using
+the comment syntax of the output format, then set
+`muse-publish-comments-p' to non-nil.
+
+\1f
+File: muse.info, Node: Tag Summary, Prev: Comments, Up: Markup Rules
+
+8.16 Tags that Muse recognizes
+==============================
+
+Muse has several built-in tags that may prove useful during publishing.
+*Note muse-publish-markup-tags::, to see how to customize the tags that
+Muse uses, as well as make your own tags.
+
+ Only a small subset of these tags are available in header and footer
+text. The `muse-publish-markup-header-footer-tags' option lists the
+tags that are allowed in headers and footers.
+
+Syntax
+------
+
+If a tag takes arguments, it will look like this, where "tagname" is
+the name of the tag.
+
+ <tagname arg1="string1" arg2="string2">
+
+ If you want the tag to look like it came straight from an XHTML
+document, you can alternatively do the following.
+
+ <tagname arg1="string1" arg2="string2" />
+
+ If a tag surrounds some text, it will look like this.
+
+ <tagname>Some text</tagname>
+
+ If a tag surrounds a large region, it will look like this.
+
+ <tagname>
+ Some text.
+ Some more text.
+ </tagname>
+
+Tag listing
+-----------
+
+This is the complete list of tags that Muse accepts, including those
+that were mentioned in previous sections.
+
+`<br>'
+ Insert a line break.
+
+ Muse will automatically detect paragraphs when publishing by means
+ of blank lines, so this tag is usually unnecessary.
+
+`<cite>'
+ Insert a citation to another source.
+
+ This takes the argument `type', which indicates the type of
+ citation. The valid types are "author" and "year". If this
+ argument is omitted, include both author and year in the citation.
+
+ The bibliography to use for the citation may be specified by the
+ `#bibsource' directive.
+
+ *Note Citations::, for additional information.
+
+`<class>'
+ If publishing to HTML, surround the given text with a <span> tag.
+ It takes one argument called "name" that specifies the "class"
+ attribute of the <span> tag.
+
+ If publishing to a different format, do nothing extra to the text.
+
+`<code>'
+ Treat the text surrounded by the tag as if they were enclosed in
+ equal signs, that is, make it monospace.
+
+`<command>'
+ Run a command on the region, replacing the region with the result
+ of the command. The command is specified with the "interp"
+ argument. If no value for "interp" is given, pass the entire
+ region to the shell.
+
+ The "markup" argument controls how this section is marked up.
+
+ If it is omitted, publish the region with the normal Muse rules.
+
+ If "nil", do not mark up the region at all, but prevent Muse from
+ further interpreting it.
+
+ If "example", treat the region as if it was surrounded by the
+ <example> tag.
+
+ If "src", treat the included text as if it was surrounded by the
+ <src> tag. You should also specify the "lang" attribute if doing
+ this.
+
+ If "verse", treat the region as if it was surrounded by the
+ <verse> tag, to preserve newlines.
+
+ Otherwise, it should be the name of a function to call, with the
+ buffer narrowed to the region.
+
+`<comment>'
+ Treat the entire region as a comment. If the option
+ MUSE-PUBLISH-COMMENTS-P is nil, delete the region, otherwise
+ publish it using the comment syntax of the current publishing
+ style.
+
+`<contents>'
+ Publish a Table of Contents. This will either be inserted
+ in-place or at the beginning of the document, depending on your
+ publishing style. It does not have a delimiting tag.
+
+ By default, only 2 levels of headings will be included in the
+ generated Table of Contents. To change this globally, customize
+ the MUSE-PUBLISH-CONTENTS-DEPTH option. To change this only for
+ the current tag, use the "depth" argument.
+
+`<div>'
+ Insert a <div> tag into HTML documents, and do not insert anything
+ special for other non-HTML publishing formats.
+
+ If the "style" argument is provided, include it with the published
+ <div> tag. Likewise for the "id" argument.
+
+`<example>'
+ Publish the region in monospace, preserving the newlines in the
+ region. This is useful for snippets of code.
+
+`<include>'
+ Insert the given file at the current location during publishing.
+ The basic use of this tag is as follows, replacing "included_file"
+ with the name of the file that you want to include.
+
+ <include file="included_file">
+
+ The "markup" argument controls how this section is marked up.
+
+ If it is omitted, publish the included text with the normal Muse
+ rules.
+
+ If "nil", do not mark up the included text at all.
+
+ If "example", treat the included text as if it was surrounded by
+ the <example> tag.
+
+ If "src", treat the included text as if it was surrounded by the
+ <src> tag. You should also specify the "lang" attribute if doing
+ this.
+
+ If "verse", treat the included text as if it was surrounded by the
+ <verse> tag, to preserve newlines.
+
+ Otherwise, it should be the name of a function to call after
+ inserting the file with the buffer narrowed to the section
+ inserted.
+
+`<lisp>'
+ Evaluate the Emacs Lisp expressions between the initial and ending
+ tags. The result is then inserted into the document, so you do
+ not need to explicitly call `insert'. All text properties are
+ removed from the resulting text.
+
+ This tag takes the "markup" argument. See the description of
+ <command> for details.
+
+`<literal>'
+ Make sure that the text enclosed by this tag is published without
+ escaping it in any way. This is useful for inserting markup
+ directly into the published document, when Muse does not provide
+ the desired functionality.
+
+`<markup>'
+ Mark up the text between the initial and ending tags. The markup
+ command to use may be specified by the "function" argument. The
+ standard Muse markup routines are used by default if no "function"
+ argument is provided.
+
+ This is useful for marking up regions in headers and footers. One
+ example that comes to mind is generating a published index of all
+ of the files in the current project by doing the following.
+
+ <markup><lisp>(muse-index-as-string t t)</lisp></markup>
+
+`<perl>'
+ Run the `perl' language interpreter on the region, replacing the
+ region with the result of the command.
+
+ This tag takes the "markup" argument. See the description of
+ <command> for details.
+
+`<python>'
+ Run the `python' language interpreter on the region, replacing the
+ region with the result of the command.
+
+ This tag takes the "markup" argument. See the description of
+ <command> for details.
+
+`<quote>'
+ Publish the region as a blockquote. This will either be inserted
+ in-place or at the beginning of the document, depending on your
+ publishing style. It does not have a delimiting tag.
+
+`<ruby>'
+ Run the `ruby' language interpreter on the region, replacing the
+ region with the result of the command.
+
+ This tag takes the "markup" argument. See the description of
+ <command> for details.
+
+`<src>'
+ Publish the region using htmlize. The language to use may be
+ specified by the "lang" attribute.
+
+ Muse will look for a function named LANG-mode, where LANG is the
+ value of the "lang" attribute.
+
+ This tag requires htmlize 1.34 or later in order to work. If this
+ is not satisfied, or the current publishing style is not
+ HTML-based, Muse will publish the region like an <example> tag.
+
+`<verbatim>'
+ This is used when you want to prevent Muse from trying to
+ interpret some markup. Surround the markup in <verbatim> and
+ </verbatim>, and it will not be interpreted.
+
+ This tag was used often in previous versions of Muse because they
+ did not support whole-document escaping of specials. Now, it will
+ only be needed for other tags, and perhaps footnotes as well.
+
+`<verse>'
+ Preserve the newlines in the region. In formats like HTML,
+ newlines are removed by default, hence the need for this tag. In
+ other publishing styles, this tag may cause the text to be
+ indented slightly in a way that looks nice for poetry and prose.
+
+
+\1f
+File: muse.info, Node: Publishing Styles, Next: Extending Muse, Prev: Markup Rules, Up: Top
+
+9 Publishing Various Types of Documents
+***************************************
+
+One of the principle features of Muse is the ability to publish a simple
+input text to a variety of different output styles. Muse also makes it
+easy to create new styles, or derive from an existing style.
+
+* Menu:
+
+* Blosxom:: Integrating Muse and pyblosxom.cgi.
+* Book:: Publishing entries into a compilation.
+* ConTeXt:: Publishing ConTeXt documents.
+* DocBook:: Publishing in DocBook XML form.
+* HTML:: Publishing in HTML or XHTML form.
+* Ikiwiki:: Integrating with ikiwiki.
+* Journal:: Keeping a journal or blog.
+* LaTeX:: Publishing LaTeX documents.
+* Poem:: Publish a poem to LaTeX or PDF.
+* Texinfo:: Publish entries to Texinfo format or PDF.
+* XML:: Publish entries to XML.
+
+\1f
+File: muse.info, Node: Blosxom, Next: Book, Prev: Publishing Styles, Up: Publishing Styles
+
+9.1 Integrating Muse and pyblosxom.cgi
+======================================
+
+The Blosxom publishing style publishes a tree of categorised files to a
+mirrored tree of stories to be served by blosxom.cgi or pyblosxom.cgi.
+In other words, each blog entry corresponds with one file.
+
+* Menu:
+
+* Blosxom Requirements:: Other tools needed for the Blosxom style.
+* Blosxom Entries:: Format of a Blosxom entry and automation.
+* Blosxom Options:: Blosxom styles and options provided.
+
+\1f
+File: muse.info, Node: Blosxom Requirements, Next: Blosxom Entries, Prev: Blosxom, Up: Blosxom
+
+9.1.1 Other tools needed for the Blosxom style
+----------------------------------------------
+
+You will need to have `pyblosxom.cgi' or `blosxom.cgi' installed on a
+machine that you have upload access to.
+
+ The major difficulty in both of these programs is specifying the
+date of the entries. Both programs rely on the file modification time
+rather than any data contained in the entries themselves. A plugin is
+needed in order for these programs to be able to get the correct date.
+
+PyBlosxom
+---------
+
+There are two different ways of accomplishing this in pyblosxom. The
+first way involves gathering the timestamps (as specified by the
+`#date' directive) into one file and then sending that file along with
+published entries to the webserver.
+
+ The second will read each file at render time and parse the
+`#postdate' directive. Muse will translate the `#date' directive into
+`#postdate' at publish time, so you don't have to do any extra work.
+
+Placing timestamps in one file
+..............................
+
+The following additional components are required in order to make the
+date of blog entries display as something sensible.
+
+ 1. A script to gather date directives from the entire blog tree into a
+ single file. The file must associate a blog entry with a date.
+
+ 2. A plugin for (py)blosxom that reads this file.
+
+ These 2 things are provided for `pyblosxom.cgi' in the
+`contrib/pyblosxom' subdirectory. `getstamps.py' provides the former
+service, while `hardcodedates.py' provides the latter service.
+
+ Here is a sample listing from my `timestamps' file, which maps each
+file to a date. This can really be in any format, as long as your
+date-gathering script and your plugin can both understand it.
+
+ 2005-04-01-14-16 personal/paper_cranes
+ 2005-03-21 personal/spring_break_over
+ 2004-10-24 personal/finished_free_culture
+
+ The script `contrib/pyblosxom/make-blog' demonstrates how to call
+`getstamps.py'. Note that you will need to set the current directory
+to where your Muse files are, execute `getstamps.py', and then move the
+generated timestamps file to your publishing directory.
+
+Getting timestamp from entry while rendering
+............................................
+
+Alternately, the pyblosxom metadate plugin may be used. On the plus
+side, there is no need to run a script to gather the date. On the
+downside, each entry is read twice rather than once when the page is
+rendered. Set the value of `muse-blosxom-use-metadate' to non-nil to
+enable adding a `#postdate' directive to all published files. You can
+do this by:
+
+ M-x customize-variable RET muse-blosxom-use-metadate RET
+
+ With the metadate plugin installed in pyblosxom, the date set in this
+directive will be used instead of the file's modification time. The
+plugin is included with Muse at `contrib/pyblosxom/metadate.py'.
+
+Blosxom
+-------
+
+It is also possible to use Blosxom, which is written in Perl, to serve
+blog entries that were published with Muse. The steps are as follows.
+
+ 1. Download and install blosxom from
+ `http://blosxom.sourceforge.net/'.
+
+ 2. Install the metadate plugin. It is available in
+ `contrib/blosxom/metadate_0_0_3'.
+
+ 3. Every time you make a new blog entry, change to the blosxom data
+ directory and execute the `contrib/blosxom/getstamps.pl' script.
+ This script has only recently been made, and may still have some
+ bugs, so use with caution.
+
+
+\1f
+File: muse.info, Node: Blosxom Entries, Next: Blosxom Options, Prev: Blosxom Requirements, Up: Blosxom
+
+9.1.2 Format of a Blosxom entry and automation
+----------------------------------------------
+
+Each Blosxom file must include `#date yyyy-mm-dd', or optionally the
+longer `#date yyyy-mm-dd-hh-mm', a title (using the `#title'
+directive), plus whatever normal content is desired.
+
+ The date directive is not used directly by `pyblosxom.cgi' or this
+program. You need to have the two additional items from the former
+section to make use of this feature.
+
+ There is a function called `muse-blosxom-new-entry' that will
+automate the process of making a new blog entry. To make use of it, do
+the following.
+
+ * Customize `muse-blosxom-base-directory' to the location that your
+ blog entries are stored.
+
+ * Assign the `muse-blosxom-new-entry' function to a key sequence. I
+ use the following code to assign this function to `C-c p l''.
+
+ (global-set-key "\C-cpl" 'muse-blosxom-new-entry)
+
+ * You should create your directory structure ahead of time under
+ your base directory. These directories, which correspond with
+ category names, may be nested.
+
+ * When you enter this key sequence, you will be prompted for the
+ category of your entry and its title. Upon entering this
+ information, a new file will be created that corresponds with the
+ title, but in lowercase letters and having special characters
+ converted to underscores. The title and date directives will be
+ inserted automatically.
+
+\1f
+File: muse.info, Node: Blosxom Options, Prev: Blosxom Entries, Up: Blosxom
+
+9.1.3 Blosxom styles and options provided
+-----------------------------------------
+
+The following styles and options are available in the Blosxom publishing
+style.
+
+Styles provided
+---------------
+
+`blosxom-html'
+ Publish Blosxom entries in HTML form.
+
+`blosxom-xhtml'
+ Publish Blosxom entries in XHTML form.
+
+
+Options provided
+----------------
+
+`muse-blosxom-extension'
+ Default file extension for publishing Blosxom files.
+
+`muse-blosxom-header'
+ Header used for publishing Blosxom files.
+
+ This may be text or a filename.
+
+`muse-blosxom-footer'
+ Footer used for publishing Blosxom files.
+
+ This may be text or a filename.
+
+`muse-blosxom-base-directory'
+ Base directory of blog entries, used by `muse-blosxom-new-entry'.
+
+ This is the top-level directory where your blog entries may be
+ found locally.
+
+
+\1f
+File: muse.info, Node: Book, Next: ConTeXt, Prev: Blosxom, Up: Publishing Styles
+
+9.2 Publishing entries into a compilation
+=========================================
+
+This publishing style is used to output "books" in LaTeX or PDF format.
+
+ Each page will become a separate chapter in the book, unless the
+style keyword `:nochapters' is used, in which case they are all run
+together as if one giant chapter.
+
+ One way of publishing a book is to make a project for it, add the
+project to `muse-project-alist', and use the `book-pdf' style with a
+very specific `:include' value to specify some page whose contents will
+be checked for the values of `#title' and `#date', and whose name will
+be used in the output file. Then to publish the book, visit the
+aforementioned page and use `C-c C-t' or `C-c C-p' to trigger the
+publishing process. An example `muse-project-alist' for this method
+follows.
+
+ (setq muse-project-alist
+ '(("MyNotes" (:nochapters t ; do automatically add chapters
+ :book-chapter "Computer Science"
+ "~/Notes/cs"
+ :book-chapter "Mathematics"
+ "~/Notes/math"
+ :book-chapter "Emacs"
+ "~/Notes/emacs"
+ :book-end t ; the rest will not be placed in the book
+ "~/Notes" ; so we can find the notes-anthology page
+ "~/Notes/private"
+ :force-publish ("index")
+ :default "index")
+ (:base "book-pdf"
+ :include "/notes-anthology[^/]*$"
+ :path "~/public_html/notes")
+ ;; other publishing styles for each directory go here,
+ ;; if desired
+ )))
+
+ In this example, there would be a file called
+`~/Notes/notes-anthology.muse', which would contain just the following.
+The resulting book would be published to
+`~/public_html/notes/notes-anthology.pdf'.
+
+ #title My Technology Ramblings
+
+ Another way is to call the `muse-book-publish-project' function
+manually, with a custom project entry. An example of this may be found
+in John Wiegley's configuration file at `examples/johnw/muse-init.el',
+in the `muse-publish-my-books' function.
+
+Styles provided
+---------------
+
+`book-latex'
+ Publish a book in LaTeX form. The header and footer are different
+ than the normal LaTeX publishing mode.
+
+`book-pdf'
+ Publish a book in PDF form. The header and footer are different
+ than the normal PDF publishing mode.
+
+
+Options provided
+----------------
+
+`muse-book-before-publish-hook'
+ A hook run in the book buffer before it is marked up.
+
+`muse-book-after-publish-hook'
+ A hook run in the book buffer after it is marked up.
+
+`muse-book-latex-header'
+ Header used for publishing books to LaTeX.
+
+ This may be text or a filename.
+
+`muse-book-latex-footer'
+ Footer used for publishing books to LaTeX.
+
+ This may be text or a filename.
+
+
+\1f
+File: muse.info, Node: ConTeXt, Next: DocBook, Prev: Book, Up: Publishing Styles
+
+9.3 Publishing ConTeXt documents
+================================
+
+This publishing style is capable of producing ConTeXt or PDF documents.
+
+ If you wish to publish PDF documents based on ConTeXt, you will need
+to have it installed. For Debian and Ubuntu, this can be accomplished
+by installing the "texlive" package.
+
+Styles provided
+---------------
+
+`context'
+ Publish a ConTeXt document.
+
+`context-pdf'
+ Publish a PDF document, using an external ConTeXt document
+ conversion tool.
+
+`context-slides'
+ Produce slides from a ConTeXt document.
+
+ Here is an example of a slide.
+
+ * First Slide
+
+ [[Some-sort-of-cute-image.png]]
+
+ ** A subheading
+
+ - A bullet point.
+ - Another bullet point.
+
+ * Second Slide
+
+ ... and so on
+
+`context-slides-pdf'
+ Publish a PDF document of ConTeXt slides.
+
+
+Options provided
+----------------
+
+`muse-context-extension'
+ Default file extension for publishing ConTeXt files.
+
+`muse-context-pdf-extension'
+ Default file extension for publishing ConTeXt files to PDF.
+
+`muse-context-pdf-program'
+ The program that is called to generate PDF content from ConTeXt
+ content.
+
+`muse-context-pdf-cruft'
+ Extensions of files to remove after generating PDF output
+ successfully.
+
+`muse-context-header'
+ Header used for publishing ConTeXt files.
+
+ This may be text or a filename.
+
+`muse-context-footer'
+ Footer used for publishing ConTeXt files.
+
+ This may be text or a filename.
+
+`muse-context-markup-regexps'
+ List of markup regexps for identifying regions in a Muse page.
+
+ For more on the structure of this list, *Note
+ muse-publish-markup-regexps::.
+
+`muse-context-markup-functions'
+ An alist of style types to custom functions for that kind of text.
+
+ For more on the structure of this list, *Note
+ muse-publish-markup-functions::.
+
+`muse-context-markup-strings'
+ Strings used for marking up text.
+
+ These cover the most basic kinds of markup, the handling of which
+ differs little between the various styles.
+
+`muse-context-slides-header'
+ Header for publishing a presentation (slides) using ConTeXt.
+
+ Any of the predefined modules, which are available in the
+ tex/context/base directory, can be used by writing a "module"
+ directive at the top of the Muse file; if no such directive is
+ provided, module pre-01 is used. Alternatively, you can use your
+ own style ("mystyle", in this example) by replacing "\usemodule[]"
+ with "\input mystyle".
+
+ This may be text or a filename.
+
+`muse-context-slides-markup-strings'
+ Strings used for marking up text in ConTeXt slides.
+
+`muse-context-markup-specials-document'
+ A table of characters which must be represented specially. These
+ are applied to the entire document, sans already-escaped regions.
+
+`muse-context-markup-specials-example'
+ A table of characters which must be represented specially. These
+ are applied to example> regions.
+
+ With the default interpretation of <example> regions, no specials
+ need to be escaped.
+
+`muse-context-markup-specials-literal'
+ A table of characters which must be represented specially. This
+ applies to =monospaced text= and <code> regions.
+
+`muse-context-markup-specials-url'
+ A table of characters which must be represented specially. These
+ are applied to URLs.
+
+`muse-context-markup-specials-image'
+ A table of characters which must be represented specially. These
+ are applied to image filenames.
+
+`muse-context-permit-contents-tag'
+ If nil, ignore <contents> tags. Otherwise, insert table of
+ contents.
+
+ Most of the time, it is best to have a table of contents on the
+ first page, with a new page immediately following. To make this
+ work with documents published in both HTML and ConTeXt, we need to
+ ignore the <contents> tag.
+
+ If you don't agree with this, then set this option to non-nil, and
+ it will do what you expect.
+
+
+\1f
+File: muse.info, Node: DocBook, Next: HTML, Prev: ConTeXt, Up: Publishing Styles
+
+9.4 Publishing in DocBook XML form
+==================================
+
+This publishing style is used to generate DocBook XML files.
+
+Styles provided
+---------------
+
+`docbook'
+ Publish a file in Docbook form.
+
+
+Options provided
+----------------
+
+This publishing style uses the same options for markup up special
+characters as the "xml" publishing style. *Note XML::, for details.
+
+`muse-docbook-extension'
+ Default file extension for publishing DocBook XML files.
+
+`muse-docbook-header'
+ Header used for publishing DocBook XML files.
+
+ This may be text or a filename.
+
+`muse-docbook-footer'
+ Footer used for publishing DocBook XML files.
+
+ This may be text or a filename.
+
+`muse-docbook-markup-regexps'
+ List of markup rules for publishing a Muse page to DocBook XML.
+
+`muse-docbook-markup-functions'
+ An alist of style types to custom functions for that kind of text.
+
+`muse-docbook-markup-strings'
+ Strings used for marking up text.
+
+ These cover the most basic kinds of markup, the handling of which
+ differs little between the various styles.
+
+`muse-docbook-encoding-default'
+ The default Emacs buffer encoding to use in published files. This
+ will be used if no special characters are found.
+
+`muse-docbook-charset-default'
+ The default DocBook XML charset to use if no translation is found
+ in `muse-xml-encoding-map'.
+
+
+\1f
+File: muse.info, Node: HTML, Next: Ikiwiki, Prev: DocBook, Up: Publishing Styles
+
+9.5 Publishing in HTML or XHTML form
+====================================
+
+This publishing style is capable of producing HTML or XHTML documents.
+
+Styles provided
+---------------
+
+`html'
+ Supports publishing to HTML 4.0 and HTML 4.01, Strict or
+ Transitional.
+
+`xhtml'
+ Supports publishing to XHTML 1.0 and XHTML 1.1, Strict or
+ Transitional.
+
+
+Options provided
+----------------
+
+If an HTML option does not have a corresponding XHTML option, it will
+be used for both of these publishing styles.
+
+ These publishing styles use the same options for markup up special
+characters as the "xml" publishing style. *Note XML::, for details.
+
+`muse-html-extension'
+ Default file extension for publishing HTML files.
+
+`muse-xhtml-extension'
+ Default file extension for publishing XHTML files.
+
+`muse-html-style-sheet'
+ Store your stylesheet definitions here.
+
+ This is used in `muse-html-header'. You can put raw CSS in here or
+ a <link> tag to an external stylesheet. This text may contain
+ <lisp> markup tags.
+
+ If you are publishing to XHTML, then customize the
+ `muse-xhtml-style-sheet' option instead.
+
+`muse-xhtml-style-sheet'
+ Store your stylesheet definitions here.
+
+ This is used in `muse-xhtml-header'. You can put raw CSS in here
+ or a <link> tag to an external stylesheet. This text may contain
+ <lisp> markup tags.
+
+`muse-html-header'
+ Header used for publishing HTML files.
+
+ This may be text or a filename.
+
+`muse-html-footer'
+ Footer used for publishing HTML files.
+
+ This may be text or a filename.
+
+`muse-xhtml-header'
+ Header used for publishing XHTML files.
+
+ This may be text or a filename.
+
+`muse-xhtml-footer'
+ Footer used for publishing XHTML files.
+
+ This may be text or a filename.
+
+`muse-html-anchor-on-word'
+ When true, anchors surround the closest word.
+
+ This allows you to select them in a browser (i.e. for pasting),
+ but has the side-effect of marking up headers in multiple colors
+ if your header style is different from your link style.
+
+`muse-html-table-attributes'
+ The attribute to be used with HTML <table> tags.
+
+ If you want to make more-complicated tables in HTML, surround the
+ HTML with the literal tag, so that it does not get escaped.
+
+`muse-html-markup-regexps'
+ List of markup rules for publishing a Muse page to HTML.
+
+`muse-html-markup-functions'
+ An alist of style types to custom functions for that kind of text.
+
+`muse-html-markup-strings'
+ Strings used for marking up text as HTML.
+
+ These cover the most basic kinds of markup, the handling of which
+ differs little between the various styles.
+
+`muse-xhtml-markup-strings'
+ Strings used for marking up text as XHTML.
+
+ These cover the most basic kinds of markup, the handling of which
+ differs little between the various styles.
+
+`muse-html-markup-tags'
+ A list of tag specifications, for specially marking up HTML.
+ *Note muse-publish-markup-tags::, for more information.
+
+`muse-html-meta-http-equiv'
+ The http-equiv attribute used for the HTML <meta> tag.
+
+`muse-html-meta-content-type'
+ The content type used for the HTML <meta> tag.
+
+ If you are striving for XHTML 1.1 compliance, you may want to
+ change this to "application/xhtml+xml".
+
+`muse-html-meta-content-encoding'
+ The charset to append to the HTML <meta> tag.
+
+ If set to the symbol 'detect, use `muse-xml-encoding-map' to try
+ and determine the HTML charset from emacs's coding. If set to a
+ string, this string will be used to force a particular charset.
+
+`muse-html-charset-default'
+ The default HTML meta charset to use if no translation is found in
+ `muse-xml-encoding-map'.
+
+`muse-html-encoding-default'
+ The default Emacs buffer encoding to use in published files. This
+ will be used if no special characters are found.
+
+
+\1f
+File: muse.info, Node: Ikiwiki, Next: Journal, Prev: HTML, Up: Publishing Styles
+
+9.6 Integrating with ikiwiki
+============================
+
+Note: Support for Ikiwiki is not yet complete. Use at your own risk.
+
+ Ikiwiki is a wiki compiler (`http://ikiwiki.info/'). Emacs Muse can
+(not yet) be used as a source format for Ikiwiki pages with the plugin
+`IkiWiki::Plugin::muse'.
+
+ The `lisp/muse-ikiwiki.el' file provides publishing functions and
+styles for Ikiwiki. The plugin for Ikiwiki to recognize Muse files is
+provided by the `contrib/ikiwiki/IkiWiki/Plugin/muse.pm' file. Two
+sample init files are available in the `examples/ikiwiki' directory.
+Configure your `ikiwiki.setup' file so that the `muse_init' variable
+has the location of your Muse init file.
+
+ If you are using CGI, The directory `contrib/ikiwiki/IkiWiki' must
+be copied to the same directory as the CGI script that Ikiwiki
+generates. When publishing your wiki, the PERL5LIB environment
+variable must contain the path to the `contrib/ikiwiki/IkiWiki'
+directory.
+
+Styles provided
+---------------
+
+`ikiwiki'
+ Supports publishing XHTML output that Ikiwiki can understand.
+
+
+Options provided
+----------------
+
+`muse-ikiwiki-header'
+ Header used for publishing Ikiwiki output files.
+
+ This may be text or a filename.
+
+`muse-ikiwiki-footer'
+ Footer used for publishing Ikiwiki output files.
+
+ This may be text or a filename.
+
+
+Other relevant options
+----------------------
+
+`muse-colors-evaluate-lisp-tags'
+ Specify whether to evaluate the contents of <lisp> tags at display
+ time. If nil, don't evaluate them. If non-nil, evaluate them.
+
+ The actual contents of the buffer are not changed, only the
+ displayed text.
+
+`muse-html-src-allowed-modes'
+ Modes that we allow the <src> tag to colorize. If `t', permit the
+ <src> tag to colorize any mode.
+
+ If a list of mode names, such as `'("html" "latex")', and the lang
+ argument to <src> is not in the list, then use fundamental mode
+ instead.
+
+`muse-publish-enable-dangerous-tags'
+ If non-nil, publish tags like <lisp> and <command> that can call
+ external programs or expose sensitive information. Otherwise,
+ ignore tags like this.
+
+ This is useful to set to `nil' when the file to publish is coming
+ from an untrusted source.
+
+
+\1f
+File: muse.info, Node: Journal, Next: LaTeX, Prev: Ikiwiki, Up: Publishing Styles
+
+9.7 Keeping a journal or blog
+=============================
+
+The module facilitates the keeping and publication of a journal. When
+publishing to HTML, it assumes the form of a web log, or blog.
+
+ The input format for each entry is as follows.
+
+ * 20040317: Title of entry
+
+ text for the entry.
+
+ <qotd>
+ "You know who you are. It comes down to a simple gut check: You
+ either love what you do or you don't. Period." -- P. Bronson
+ </qotd>
+
+ The "qotd", or Quote of the Day, is entirely optional. When
+generated to HTML, this entry is rendered as the following.
+
+ <div class="entry">
+ <div class="entry-qotd">
+ <h3>Quote of the Day:</h3>
+ <p>"You know who you are. It comes down to a simple gut
+ check: You either love what you do or you don't. Period."
+ -- P. Bronson</p>
+ </div>
+ <div class="entry-body">
+ <div class="entry-head">
+ <div class="entry-date">
+ <span class="date">March 17, 2004</span>
+ </div>
+ <div class="entry-title">
+ <h2>Title of entry</h2>
+ </div>
+ </div>
+ <div class="entry-text">
+ <p>Text for the entry.</p>
+ </div>
+ </div>
+ </div>
+
+ The plurality of "div" tags makes it possible to display the entries
+in any form you wish, using a CSS style.
+
+ Also, an .RDF file can be generated from your journal by publishing
+it with the "rdf" style. It uses the first two sentences of the first
+paragraph of each entry as its "description", and auto-generates tags
+for linking to the various entries.
+
+muse-project-alist considerations
+---------------------------------
+
+If you wish to publish an RDF or RSS feed, it is important to include
+the `:base-url' attribute in your `muse-project-alist' entry for your
+Journal projects. An example follows.
+
+ (setq muse-project-alist
+ '(("Journal" ("~/Journal/"
+ :default "journal")
+ (:base "journal-rss"
+ :base-url "http://example.org/journal/"
+ :path "~/public_html/journal"))))
+
+Styles provided
+---------------
+
+`journal-html'
+ Publish journal entries as an HTML document.
+
+`journal-xhtml'
+ Publish journal entries as an XHTML document.
+
+`journal-latex'
+ Publish journal entries as a LaTeX document.
+
+`journal-pdf'
+ Publish journal entries as a PDF document.
+
+`journal-book-latex'
+ Publish journal entries as a LaTeX book.
+
+`journal-book-pdf'
+ Publish journal entries as a PDF book.
+
+`journal-rdf'
+ Publish journal entries as an RDF file (RSS 1.0).
+
+`journal-rss'
+ Publish journal entries as an RSS file (RSS 2.0).
+
+`journal-rss-entry'
+ Used internally by `journal-rss' and `journal-rdf' for publishing
+ individual entries.
+
+
+Options provided
+----------------
+
+`muse-journal-heading-regexp'
+ A regexp that matches a journal heading.
+
+ Paren group 1 is the ISO date, group 2 is the optional category,
+ and group 3 is the optional heading for the entry.
+
+`muse-journal-date-format'
+ Date format to use for journal entries.
+
+`muse-journal-html-heading-regexp'
+ A regexp that matches a journal heading from an HTML document.
+
+ Paren group 1 is the ISO date, group 2 is the optional category,
+ and group 3 is the optional heading for the entry.
+
+`muse-journal-html-entry-template'
+ Template used to publish individual journal entries as HTML.
+
+ This may be text or a filename.
+
+`muse-journal-latex-section'
+ Template used to publish a LaTeX section.
+
+`muse-journal-latex-subsection'
+ Template used to publish a LaTeX subsection.
+
+`muse-journal-markup-tags'
+ A list of tag specifications, for specially marking up Journal
+ entries.
+
+ *Note muse-publish-markup-tags::, for more information.
+
+ This is used by `journal-latex' and its related styles, as well as
+ the `journal-rss-entry' style, which both `journal-rdf' and
+ `journal-rss' use.
+
+`muse-journal-rdf-extension'
+ Default file extension for publishing RDF (RSS 1.0) files.
+
+`muse-journal-rdf-base-url'
+ The base URL of the website referenced by the RDF file.
+
+`muse-journal-rdf-header'
+ Header used for publishing RDF (RSS 1.0) files.
+
+ This may be text or a filename.
+
+`muse-journal-rdf-footer'
+ Footer used for publishing RDF (RSS 1.0) files.
+
+ This may be text or a filename.
+
+`muse-journal-rdf-date-format'
+ Date format to use for RDF entries.
+
+`muse-journal-rdf-entry-template'
+ Template used to publish individual journal entries as RDF.
+
+ This may be text or a filename.
+
+`muse-journal-rdf-summarize-entries'
+ If non-nil, include only summaries in the RDF file, not the full
+ data.
+
+ The default is nil, because this annoys some subscribers.
+
+`muse-journal-rss-heading-regexp'
+ A regexp that matches a journal heading from an HTML document.
+
+ Paren group 1 is the ISO date, group 2 is the optional category,
+ and group 3 is the optional heading for the entry.
+
+`muse-journal-rss-extension'
+ Default file extension for publishing RSS 2.0 files.
+
+`muse-journal-rss-base-url'
+ The base URL of the website referenced by the RSS file.
+
+`muse-journal-rss-header'
+ Header used for publishing RSS 2.0 files.
+
+ This may be text or a filename.
+
+`muse-journal-rss-footer'
+ Footer used for publishing RSS 2.0 files.
+
+ This may be text or a filename.
+
+`muse-journal-rss-date-format'
+ Date format to use for RSS 2.0 entries.
+
+`muse-journal-rss-entry-template'
+ Template used to publish individual journal entries as RSS 2.0.
+
+ This may be text or a filename.
+
+`muse-journal-rss-enclosure-types-alist'
+ File types that are accepted as RSS enclosures.
+
+ This is an alist that maps file extension to content type.
+
+ Useful for podcasting.
+
+`muse-journal-rss-summarize-entries'
+ If non-nil, include only summaries in the RSS file, not the full
+ data.
+
+ The default is nil, because this annoys some subscribers.
+
+`muse-journal-rss-markup-regexps'
+ List of markup rules for publishing a Muse journal page to RSS.
+
+ For more information on the structure of this list, *Note
+ muse-publish-markup-regexps::.
+
+`muse-journal-rss-markup-functions'
+ An alist of style types to custom functions for that kind of text.
+
+ For more on the structure of this list, *Note
+ muse-publish-markup-functions::.
+
+
+\1f
+File: muse.info, Node: LaTeX, Next: Poem, Prev: Journal, Up: Publishing Styles
+
+9.8 Publishing LaTeX documents
+==============================
+
+This publishing style is capable of producing LaTeX or PDF documents.
+
+ If you wish to publish PDF documents, you will need to have a good
+LaTeX installation. For Debian and Ubuntu, this can be accomplished by
+installing the "tetex-bin" and "tetex-extra" packages. TeX fonts are
+also a must.
+
+ If your LaTeX installation has the file `grffile.sty', which may be
+found in the `texlive-latex-recommended' package for Debian and Ubuntu,
+then consider using it by adding the following to your header file.
+This allows spaces in filenames to work.
+
+ \usepackage{grffile}
+
+Styles provided
+---------------
+
+`latex'
+ Publish a LaTeX document.
+
+`pdf'
+ Publish a PDF document, using an external LaTeX document conversion
+ tool.
+
+`latexcjk'
+ Publish a LaTeX document with CJK (Chinese) encodings.
+
+`pdfcjk'
+ Publish a PDF document with CJK (Chinese) encodings, using an
+ external LaTeX document conversion tool.
+
+`slides'
+ Publish a LaTeX document that uses the Beamer extension. This is
+ suitable for producing slides.
+
+ Here is an example of a slide.
+
+ <slide title="First Slide">
+ Everything between the slide tags composes this slide.
+
+ [[Some-sort-of-cute-image.png]]
+
+ - A bullet point.
+ - Another bullet point.
+ </slide>
+
+`slides-pdf'
+ Publish a PDF document of slides, using the Beamer extension.
+
+`lecture-notes'
+ Publish a LaTeX document that uses the Beamer extension. This is
+ suitable for producing lecture notes.
+
+ This can also use the <slide> tag.
+
+`lecture-notes-pdf'
+ Publish a PDF document of lecture notes, using the Beamer
+ extension.
+
+
+Options provided
+----------------
+
+`muse-latex-extension'
+ Default file extension for publishing LaTeX files.
+
+`muse-latex-pdf-extension'
+ Default file extension for publishing LaTeX files to PDF.
+
+`muse-latex-pdf-browser'
+ The program to use when browsing a published PDF file.
+
+ This should be a format string.
+
+`muse-latex-pdf-program'
+ The program that is called to generate PDF content from LaTeX
+ content.
+
+`muse-latex-pdf-cruft'
+ Extensions of files to remove after generating PDF output
+ successfully.
+
+`muse-latex-header'
+ Header used for publishing LaTeX files.
+
+ This may be text or a filename.
+
+`muse-latex-footer'
+ Footer used for publishing LaTeX files.
+
+ This may be text or a filename.
+
+`muse-latexcjk-header'
+ Header used for publishing LaTeX files (CJK).
+
+ This may be text or a filename.
+
+`muse-latexcjk-footer'
+ Footer used for publishing LaTeX files (CJK).
+
+ This may be text or a filename.
+
+`muse-latex-slides-header'
+ Header for publishing of slides using LaTeX.
+
+ This may be text or a filename.
+
+ You must have the Beamer extension for LaTeX installed for this to
+ work.
+
+`muse-latex-lecture-notes-header'
+ Header publishing of lecture notes using LaTeX.
+
+ This may be text or a filename.
+
+ You must have the Beamer extension for LaTeX installed for this to
+ work.
+
+`muse-latex-markup-regexps'
+ List of markup regexps for identifying regions in a Muse page.
+
+ For more on the structure of this list, *Note
+ muse-publish-markup-regexps::.
+
+`muse-latex-markup-functions'
+ An alist of style types to custom functions for that kind of text.
+
+ For more on the structure of this list, *Note
+ muse-publish-markup-functions::.
+
+`muse-latex-markup-strings'
+ Strings used for marking up text.
+
+ These cover the most basic kinds of markup, the handling of which
+ differs little between the various styles.
+
+`muse-latex-slides-markup-tags'
+ A list of tag specifications, for specially marking up LaTeX
+ slides.
+
+`muse-latexcjk-encoding-map'
+ An alist mapping emacs coding systems to appropriate CJK codings.
+ Use the base name of the coding system (ie, without the -unix).
+
+`muse-latexcjk-encoding-default'
+ The default Emacs buffer encoding to use in published files.
+
+ This will be used if no special characters are found.
+
+`muse-latex-markup-specials-document'
+ A table of characters which must be represented specially. These
+ are applied to the entire document, sans already-escaped regions.
+
+`muse-latex-markup-specials-example'
+ A table of characters which must be represented specially. These
+ are applied to example> regions.
+
+ With the default interpretation of <example> regions, no specials
+ need to be escaped.
+
+`muse-latex-markup-specials-literal'
+ A table of characters which must be represented specially. This
+ applies to =monospaced text= and <code> regions.
+
+`muse-latex-markup-specials-url'
+ A table of characters which must be represented specially. These
+ are applied to URLs.
+
+`muse-latex-markup-specials-image'
+ A table of characters which must be represented specially. These
+ are applied to image filenames.
+
+`muse-latex-permit-contents-tag'
+ If nil, ignore <contents> tags. Otherwise, insert table of
+ contents.
+
+ Most of the time, it is best to have a table of contents on the
+ first page, with a new page immediately following. To make this
+ work with documents published in both HTML and LaTeX, we need to
+ ignore the <contents> tag.
+
+ If you don't agree with this, then set this option to non-nil, and
+ it will do what you expect.
+
+
+\1f
+File: muse.info, Node: Poem, Next: Texinfo, Prev: LaTeX, Up: Publishing Styles
+
+9.9 Publish a poem to LaTeX or PDF
+==================================
+
+The `muse-poem' module makes it easy to attractively publish and
+reference poems in the following format, using the "memoir" module for
+LaTeX publishing. It will also markup poems for every other output
+style, though none are nearly as pretty.
+
+ Title
+
+
+ Body of poem
+
+
+ Annotations, history, notes, etc.
+
+ Once a poem is written in this format, just publish it to PDF using
+the `poem-pdf' style. To make an inlined reference to a poem that
+you've written - for example, from a blog page - there is a "poem" tag
+defined by this module.
+
+ <poem title="name.of.poem.page">
+
+ Let's assume the template above was called `name.of.poem.page'; then
+the above tag would result in this inclusion.
+
+ ** Title
+
+ > Body of poem
+
+ John Wiegley uses this module for publishing all of the poems on his
+website, which are at `http://www.newartisans.com/johnw/poems.html'.
+
+Styles provided
+---------------
+
+`poem-latex'
+ Publish a poem in LaTeX form.
+
+`poem-pdf'
+ Publish a poem to a PDF document.
+
+`chapbook-latex'
+ Publish a book of poems in LaTeX form.
+
+`chapbook-pdf'
+ Publish a book of poems to a PDF document.
+
+
+Options provided
+----------------
+
+`muse-poem-latex-header'
+ Header used for publishing LaTeX poems.
+
+ This may be text or a filename.
+
+`muse-poem-latex-footer'
+ Footer used for publishing LaTeX files.
+
+ This may be text or a filename.
+
+`muse-poem-markup-strings'
+ Strings used for marking up poems.
+
+ These cover the most basic kinds of markup, the handling of which
+ differs little between the various styles.
+
+`muse-chapbook-latex-header'
+ Header used for publishing a book of poems in LaTeX form.
+
+ This may be text or a filename.
+
+`muse-chapbook-latex-footer'
+ Footer used for publishing a book of poems in LaTeX form.
+
+ This may be text or a filename.
+
+`muse-poem-chapbook-strings'
+ Strings used for marking up books of poems.
+
+ These cover the most basic kinds of markup, the handling of which
+ differs little between the various styles.
+
+
+\1f
+File: muse.info, Node: Texinfo, Next: XML, Prev: Poem, Up: Publishing Styles
+
+9.10 Publish entries to Texinfo format or PDF
+=============================================
+
+Rules for publishing a Muse file as a Texinfo article.
+
+Styles provided
+---------------
+
+`texi'
+ Publish a file in Texinfo form.
+
+`info'
+ Generate an Info file from a Muse file.
+
+`info-pdf'
+ Publish a file in PDF form.
+
+
+Options provided
+----------------
+
+`muse-texinfo-process-natively'
+ If non-nil, use the Emacs `texinfmt' module to make Info files.
+
+`muse-texinfo-extension'
+ Default file extension for publishing Texinfo files.
+
+`muse-texinfo-info-extension'
+ Default file extension for publishing Info files.
+
+`muse-texinfo-pdf-extension'
+ Default file extension for publishing PDF files.
+
+`muse-texinfo-header'
+ Text to prepend to a Muse page being published as Texinfo.
+
+ This may be text or a filename. It may contain <lisp> markup tags.
+
+`muse-texinfo-footer'
+ Text to append to a Muse page being published as Texinfo.
+
+ This may be text or a filename. It may contain <lisp> markup tags.
+
+`muse-texinfo-markup-regexps'
+ List of markup rules for publishing a Muse page to Texinfo.
+
+ For more on the structure of this list, *Note
+ muse-publish-markup-regexps::.
+
+`muse-texinfo-markup-functions'
+ An alist of style types to custom functions for that kind of text.
+
+ For more on the structure of this list, *Note
+ muse-publish-markup-functions::.
+
+`muse-texinfo-markup-strings'
+ Strings used for marking up text.
+
+ These cover the most basic kinds of markup, the handling of which
+ differs little between the various styles.
+
+`muse-texinfo-markup-specials'
+ A table of characters which must be represented specially.
+
+`muse-texinfo-markup-specials'
+ A table of characters which must be represented specially. These
+ are applied to URLs.
+
+
+\1f
+File: muse.info, Node: XML, Prev: Texinfo, Up: Publishing Styles
+
+9.11 Publish entries to XML
+===========================
+
+Muse is capable of publishing XML documents, with the help of the
+`muse-xml.el' module.
+
+ A RelaxNG schema is available as part of the Muse distribution in the
+`etc/muse.rnc' file.
+
+Styles provided
+---------------
+
+`xml'
+ Publish a file in XML form.
+
+
+Options provided
+----------------
+
+`muse-xml-encoding-map'
+ An alist mapping Emacs coding systems to appropriate XML charsets.
+ Use the base name of the coding system (i.e. without the -unix).
+
+`muse-xml-markup-specials'
+ A table of characters which must be represented specially in all
+ XML-like markup formats.
+
+`muse-xml-markup-specials-url-extra'
+ A table of characters which must be represented specially in all
+ XML-like markup formats.
+
+ These are extra characters that are escaped within URLs.
+
+`muse-xml-extension'
+ Default file extension used for publishing XML files.
+
+`muse-xml-header'
+ Header used for publishing XML files.
+
+ This may be text or a filename.
+
+`muse-xml-footer'
+ Footer used for publishing XML files.
+
+ This may be text or a filename.
+
+`muse-xml-markup-regexps'
+ List of markup rules for publishing a Muse page to XML.
+
+ For more on the structure of this list, *Note
+ muse-publish-markup-regexps::.
+
+`muse-xml-markup-functions'
+ An alist of style types to custom functions for that kind of text.
+
+ For more on the structure of this list, *Note
+ muse-publish-markup-functions::.
+
+`muse-xml-markup-strings'
+ Strings used for marking up text.
+
+ These cover the most basic kinds of markup, the handling of which
+ differs little between the various styles.
+
+`muse-xml-encoding-default'
+ The default Emacs buffer encoding to use in published files.
+
+ This will be used if no special characters are found.
+
+`muse-xml-charset-default'
+ The default XML charset to use if no translation is found in
+ `muse-xml-encoding-map'.
+
+
+\1f
+File: muse.info, Node: Extending Muse, Next: Miscellaneous, Prev: Publishing Styles, Up: Top
+
+10 Making your own publishing styles
+************************************
+
+* Menu:
+
+* Markup Functions:: Specifying functions to mark up text.
+* Markup Regexps:: Markup rules for publishing.
+* Markup Strings:: Strings specific to a publishing style.
+* Markup Tags:: Tag specifications for special markup.
+* Style Elements:: Parameters used for defining styles.
+* Deriving Styles:: Deriving a new style from an existing
+ one.
+
+\1f
+File: muse.info, Node: Markup Functions, Next: Markup Regexps, Up: Extending Muse
+
+10.1 Specifying functions to mark up text
+=========================================
+
+`muse-publish-markup-functions'
+
+ An alist of style types to custom functions for that kind of text.
+
+ This is used by publishing styles to attempt to minimize the amount
+of custom regexps that each has to define. `muse-publish' provides
+rules for the most common types of markup.
+
+ Each member of the list is of the following form.
+
+ (SYMBOL FUNCTION)
+
+ * SYMBOL Describes the type of text to associate with this rule.
+ `muse-publish-markup-regexps' maps regexps to these symbols.
+
+ * FUNCTION Function to use to mark up this kind of rule if no
+ suitable function is found through the `:functions' tag of the
+ current style.
+
+\1f
+File: muse.info, Node: Markup Regexps, Next: Markup Strings, Prev: Markup Functions, Up: Extending Muse
+
+10.2 Markup rules for publishing
+================================
+
+`muse-publish-markup-regexps'
+
+ List of markup rules for publishing a page with Muse.
+
+ The rules given in this variable are invoked first, followed by
+whatever rules are specified by the current style.
+
+ Each member of the list is either a function, or a list of the
+following form.
+
+ (REGEXP/SYMBOL TEXT-BEGIN-GROUP REPLACEMENT-TEXT/FUNCTION/SYMBOL)
+
+ * REGEXP A regular expression, or symbol whose value is a regular
+ expression, which is searched for using `re-search-forward'.
+
+ * TEXT-BEGIN-GROUP The matching group within that regexp which
+ denotes the beginning of the actual text to be marked up.
+
+ * REPLACEMENT-TEXT A string that will be passed to `replace-match'.
+
+ If it is not a string, but a function, it will be called to
+ determine what the replacement text should be (it must return a
+ string). If it is a symbol, the value of that symbol should be a
+ string.
+
+ The replacements are done in order, one rule at a time. Writing the
+regular expressions can be a tricky business. Note that case is never
+ignored. `case-fold-search' is always bound to nil while processing
+the markup rules.
+
+Publishing order
+----------------
+
+This is the order that the publishing rules are consulted, by default.
+This may be changed by customizing `muse-publish-markup-regexps'.
+
+`trailing and leading whitespace'
+ Remove trailing and leading whitespace from a file.
+
+`directive'
+ `#directive'
+
+ This is only recognized at the beginning of a file.
+
+`comment'
+ `; a commented line'
+
+`tag'
+ `<tag>'
+
+`comment'
+ `; comment'
+
+`explicit links'
+ Prevent emphasis characters in explicit links from being marked up.
+
+ Don't actually publish them here, just add a special no-emphasis
+ text property.
+
+`word'
+ Whitespace-delimited word, possibly with emphasis characters
+
+ This function is responsible for marking up emphasis and escaping
+ some specials.
+
+`heading'
+ `** Heading'
+
+ Outline-mode style headings.
+
+`enddots'
+ `....'
+
+ These are ellipses with a dot at end.
+
+`dots'
+ `...'
+
+ Ellipses.
+
+`rule'
+ `----'
+
+ Horizontal rule or section separator.
+
+`no-break-space'
+ `~~'
+
+ Prevent lines from being split before or after these characters.
+
+`line-break'
+ `<br>'
+
+ Break a line at point.
+
+`fn-sep'
+ `Footnotes:'
+
+ Beginning of footnotes section.
+
+`footnote'
+ `[1]'
+
+ Footnote definition or reference. If at beginning of line, it is a
+ definition.
+
+`list'
+ * ` 1. '
+
+ * ` - '
+
+ * `term :: '
+
+ Numbered list, item list, or term definition list.
+
+`table-el'
+ `table.el' style tables
+
+`table'
+ `table | cells'
+
+ Muse tables or orgtbl-mode style tables.
+
+`quote'
+ spaces before beginning of text
+
+ Blockquotes.
+
+`emdash'
+ `--'
+
+ 2-wide dash
+
+`verse'
+ `> verse text'
+
+`anchor'
+ `#anchor'
+
+`link'
+ `[[explicit][links]]'
+
+`url'
+ `http://example.com/'
+
+`email'
+ `bare-email@example.com'
+
+
+\1f
+File: muse.info, Node: Markup Strings, Next: Markup Tags, Prev: Markup Regexps, Up: Extending Muse
+
+10.3 Strings specific to a publishing style
+===========================================
+
+"Markup strings" are strings used for marking up text for a particular
+style.
+
+ These cover the most basic kinds of markup, the handling of which
+differs little between the various styles.
+
+Available markup strings
+------------------------
+
+`image-with-desc'
+ An image and a description.
+
+ Argument 1: image without extension. Argument 2: image extension.
+ Argument 3: description.
+
+`image'
+ An inlined image.
+
+ Argument 1: image without extension. Argument 2: image extension.
+
+`image-link'
+ An image with a link around it.
+
+ Argument 1: link. Argument 2: image without extension. Argument
+ 3: image extension.
+
+`anchor-ref'
+ A reference to an anchor on the current page.
+
+ Argument 1: anchor name. Argument 2: description if one exists,
+ or the original link otherwise.
+
+`url'
+ A URL without a description.
+
+ Argument 1: URL.
+
+`link'
+ A link to a Muse page with a description.
+
+ Argument 1: link. Argument 2: description if one exists, or the
+ original link otherwise.
+
+`link-and-anchor'
+ A link to a Muse page with an anchor, and a description.
+
+ Argument 1: link. Argument 2: anchor name. Argument 3:
+ description if one exists, or the original link otherwise.
+ Argument 4: link without an extension.
+
+`email-addr'
+ A link to an email address.
+
+ Argument 1: email address. Argument 2: email address.
+
+`anchor'
+ An anchor.
+
+ Argument 1: name of anchor.
+
+`emdash'
+ A 2-length dash.
+
+ Argument 1: Initial whitespace. Argument 2: Terminating
+ whitespace.
+
+`comment-begin'
+ Beginning of a comment.
+
+`comment-end'
+ End of a comment.
+
+`rule'
+ A horizontal line or space.
+
+`no-break-space'
+ A space that separates two words which are not to be separated.
+
+`footnote'
+ Beginning of footnote.
+
+`footnote-end'
+ End of footnote.
+
+`footnotemark'
+ Mark a reference for the current footnote.
+
+ Argument 1: number of this footnote.
+
+`footnotemark-end'
+ End of a reference for the current footnote.
+
+`footnotetext'
+ Indicate the text of the current footnote.
+
+ Argument 1: number of this footnote.
+
+`footnotetext-end'
+ End of a footnote text line.
+
+`fn-sep'
+ Text used to replace "Footnotes:" line.
+
+`dots'
+ 3 dots.
+
+`enddots'
+ 4 dots.
+
+`part'
+ Beginning of a part indicator line. This is used by book
+ publishing.
+
+`part-end'
+ End of a part indicator line. This is used by book publishing.
+
+`chapter'
+ Beginning of a chapter indicator line. This is used by book
+ publishing.
+
+`chapter-end'
+ End of a chapter indicator line. This is used by book publishing.
+
+`section'
+ Beginning of level 1 section indicator line.
+
+ Argument 1: level of section; always 1.
+
+`section-end'
+ End of level 1 section indicator line.
+
+ Argument 1: level of section; always 1.
+
+`subsection'
+ Beginning of level 2 section indicator line.
+
+ Argument 1: level of section; always 2.
+
+`subsection-end'
+ End of level 2 section indicator line.
+
+ Argument 1: level of section; always 2.
+
+`subsubsection'
+ Beginning of level 3 section indicator line.
+
+ Argument 1: level of section; always 3.
+
+`subsubsection-end'
+ End of level 3 section indicator line.
+
+ Argument 1: level of section; always 3.
+
+`section-other'
+ Beginning of section indicator line, where level is greater than 3.
+
+ Argument 1: level of section.
+
+`section-other-end'
+ End of section indicator line, where level is greater than 3.
+
+ Argument 1: level of section.
+
+`begin-underline'
+ Beginning of underlined text.
+
+`end-underline'
+ End of underlined text.
+
+`begin-literal'
+ Beginning of verbatim text. This includes <code> tags and
+ =teletype text=.
+
+`end-literal'
+ End of verbatim text. This includes <code> tags and =teletype
+ text=.
+
+`begin-emph'
+ Beginning of the first level of emphasized text.
+
+`end-emph'
+ End of the first level of emphasized text.
+
+`begin-more-emph'
+ Beginning of the second level of emphasized text.
+
+`end-more-emph'
+ End of the second level of emphasized text.
+
+`begin-most-emph'
+ Beginning of the third (and final) level of emphasized text.
+
+`end-most-emph'
+ End of the third (and final) level of emphasized text.
+
+`begin-verse'
+ Beginning of verse text.
+
+`verse-space'
+ String used to each space that is further indented than the
+ beginning of the verse.
+
+`begin-verse-line'
+ Beginning of a line of verse.
+
+`empty-verse-line'
+ End of a line of verse.
+
+`begin-last-stanza-line'
+ Beginning of the last line of a verse stanza.
+
+`end-last-stanza-line'
+ End of the last line of a verse stanza.
+
+`end-verse'
+ End of verse text.
+
+`begin-example'
+ Beginning of an example region. To make use of this, an
+ `<example>' tag is needed.
+
+`end-example'
+ End of an example region. To make use of this, an `</example>' tag
+ is needed.
+
+`begin-center'
+ Begin a centered line.
+
+`end-center'
+ End a centered line.
+
+`begin-quote'
+ Begin a quoted region.
+
+`end-quote'
+ End a quoted region.
+
+`begin-quote-item'
+ Begin a quote paragraph.
+
+`end-quote-item'
+ End a quote paragraph.
+
+`begin-uli'
+ Begin an unordered list.
+
+`end-uli'
+ End an unordered list.
+
+`begin-uli-item'
+ Begin an unordered list item.
+
+`end-uli-item'
+ End an unordered list item.
+
+`begin-oli'
+ Begin an ordered list.
+
+`end-oli'
+ End an ordered list.
+
+`begin-oli-item'
+ Begin an ordered list item.
+
+`end-oli-item'
+ End an ordered list item.
+
+`begin-dl'
+ Begin a definition list.
+
+`end-dl'
+ End a definition list.
+
+`begin-dl-item'
+ Begin a definition list item.
+
+`end-dl-item'
+ End a definition list item.
+
+`begin-ddt'
+ Begin a definition list term.
+
+`end-ddt'
+ End a definition list term.
+
+`begin-dde'
+ Begin a definition list entry.
+
+`end-dde'
+ End a definition list entry.
+
+`begin-table'
+ Begin a table.
+
+`end-table'
+ End a table.
+
+`begin-table-group'
+ Begin a table grouping.
+
+`end-table-group'
+ End a table grouping.
+
+`begin-table-row'
+ Begin a table row.
+
+`end-table-row'
+ End a table row.
+
+`begin-table-entry'
+ Begin a table entry.
+
+`end-table-entry'
+ End a table entry.
+
+
+\1f
+File: muse.info, Node: Markup Tags, Next: Style Elements, Prev: Markup Strings, Up: Extending Muse
+
+10.4 Tag specifications for special markup
+==========================================
+
+`muse-publish-markup-tags'
+
+ A list of tag specifications, for specially marking up text.
+
+ XML-style tags are the best way to add custom markup to Muse. This
+is easily accomplished by customizing this list of markup tags.
+
+ For each entry, the name of the tag is given, whether it expects a
+closing tag and/or an optional set of attributes, whether it is
+nestable, and a function that performs whatever action is desired within
+the delimited region.
+
+ The tags themselves are deleted during publishing, before the
+function is called. The function is called with three arguments, the
+beginning and end of the region surrounded by the tags. If properties
+are allowed, they are passed as a third argument in the form of an
+alist. The `end' argument to the function is always a marker.
+
+ Point is always at the beginning of the region within the tags, when
+the function is called. Wherever point is when the function finishes is
+where tag markup will resume.
+
+ These tag rules are processed once at the beginning of markup, and
+once at the end, to catch any tags which may have been inserted
+in-between.
+
+\1f
+File: muse.info, Node: Style Elements, Next: Deriving Styles, Prev: Markup Tags, Up: Extending Muse
+
+10.5 Parameters used for defining styles
+========================================
+
+Style elements are tags that define a style. Use either
+`muse-define-style' or `muse-derive-style' (*note Deriving Styles::) to
+create a new style.
+
+ -- Function: muse-define-style name &rest elements
+
+Usable elements
+---------------
+
+`:suffix'
+ File extension to use for publishing files with this style.
+
+`:link-suffix'
+ File extension to use for publishing links to Muse files with this
+ style.
+
+`:osuffix'
+ File extension to use for publishing second-stage files with this
+ style.
+
+ For example, PDF publishing generates a LaTeX file first, then a
+ PDF from that LaTeX file.
+
+`:regexps'
+ List of markup rules for publishing a page with Muse. *Note
+ muse-publish-markup-regexps::.
+
+`:functions'
+ An alist of style types to custom functions for that kind of text.
+ *Note muse-publish-markup-functions::.
+
+`:strings'
+ Strings used for marking up text with this style.
+
+ These cover the most basic kinds of markup, the handling of which
+ differs little between the various styles.
+
+`:tags'
+ A list of tag specifications, used for handling extra tags. *Note
+ muse-publish-markup-tags::.
+
+`:specials'
+ A table of characters which must be represented specially.
+
+`:before'
+ A function that is to be executed on the newly-created publishing
+ buffer (or the current region) before any publishing occurs.
+
+ This is used to set extra parameters that direct the publishing
+ process.
+
+`:before-end'
+ A function that is to be executed on the publishing buffer (or the
+ current region) immediately after applying all of the markup
+ regexps.
+
+ This is used to fix the order of table elements (header, footer,
+ body) in XML-ish styles.
+
+`:after'
+ A function that is to be executed on the publishing buffer after
+ :before-end, and immediately after inserting the header and footer.
+
+ This is used for generating the table of contents as well as
+ setting the file coding system.
+
+`:final'
+ A function that is to be executed after saving the published file,
+ but while still in its buffer.
+
+ This is used for generating second-stage documents like PDF files
+ from just-published LaTeX files.
+
+ The function must accept three arguments: the name of the muse
+ source file, the name of the just-published file, and the name of
+ the second-stage target file. The name of the second-stage target
+ file is the same as that of the just-published file if no
+ second-stage publishing is required.
+
+`:header'
+ Header used for publishing files of this style.
+
+ This may be a variable, text, or a filename. It is inserted at the
+ beginning of a file, after evaluating the publishing markup.
+
+`:footer'
+ Footer used for publishing files of this style.
+
+ This may be a variable, text, or a filename. It is inserted at
+ the end of a file, after evaluating the publishing markup.
+
+`:style-sheet'
+ Style sheet used for publishing files of this style.
+
+ This may be a variable or text. It is used in the header of HTML
+ and XHTML based publishing styles.
+
+`:browser'
+ The function used to browse the published result of files of this
+ style.
+
+
+\1f
+File: muse.info, Node: Deriving Styles, Prev: Style Elements, Up: Extending Muse
+
+10.6 Deriving a new style from an existing one
+==============================================
+
+To create a new style from an existing one, use `muse-derive-style' as
+follows. This is a good way to fix something you don't like about a
+particular publishing style, or to personalize it.
+
+ -- Function: muse-derive-style new-name base-name &rest elements
+
+ The derived name is a string defining the new style, such as
+"my-html". The base name must identify an existing style, such as
+"html" - if you have loaded `muse-html'. The style parameters are the
+same as those used to create a style, except that they override whatever
+definitions exist in the base style. However, some definitions only
+partially override. The following parameters support partial
+overriding.
+
+ *Note Style Elements::, for a complete list of all parameters.
+
+`:functions'
+ If a markup function is not found in the derived style's function
+ list, the base style's function list will be queried.
+
+`:regexps'
+ All regexps in the current style and the base style(s) will be
+ used.
+
+`:strings'
+ If a markup string is not found in the derived style's string
+ list, the base style's string list will be queried.
+
+
+\1f
+File: muse.info, Node: Miscellaneous, Next: Getting Help and Reporting Bugs, Prev: Extending Muse, Up: Top
+
+11 Miscellaneous add-ons, like a minor mode
+*******************************************
+
+* Menu:
+
+* Muse List Edit Minor Mode:: Edit lists easily in other major modes.
+
+\1f
+File: muse.info, Node: Muse List Edit Minor Mode, Up: Miscellaneous
+
+11.1 Edit lists easily in other major modes
+===========================================
+
+`muse-list-edit-minor-mode' is meant to be used with other major modes,
+such as Message (for composing email) and debian-changelog-mode (for
+editing debian/changelog files).
+
+ It implements practically perfect support for editing and filling
+lists. It can even handle nested lists. In addition to Muse-specific
+list items ("-", numbers, definition lists, footnotes), it can also
+handle items that begin with "*" or "+". Filling list items behaves in
+the same way that it does in Muse, regardless of whether filladapt is
+also enabled, which is the primary reason to use this tool.
+
+Installation
+------------
+
+To use it, add "(require 'muse-mode)" to your Emacs customization file
+and add the function `turn-on-muse-list-edit-minor-mode' to any mode
+hooks where you wish to enable this minor mode.
+
+Keybindings
+-----------
+
+`muse-list-edit-minor-mode' uses the following keybindings.
+
+`M-RET (`muse-l-e-m-m-insert-list-item')'
+ Insert a new list item at point, using the indentation level of the
+ current list item.
+
+`C-< (`muse-l-e-m-m-decrease-list-item-indent')'
+ Decrease indentation of the current list item.
+
+`C-> (`muse-l-e-m-m-increase-list-item-indent')'
+ Increase indentation of the current list item.
+
+
+Functions
+---------
+
+ -- Function: muse-list-edit-minor-mode
+ This is a global minor mode for editing files with lists. It is
+ meant to be used with other major modes, and not with Muse mode.
+
+ Interactively, with no prefix argument, toggle the mode. With
+ universal prefix ARG turn mode on. With zero or negative ARG turn
+ mode off.
+
+ This minor mode provides the Muse keybindings for editing lists,
+ and support for filling lists properly.
+
+ It recognizes not only Muse-style lists, which use the "-"
+ character or numbers, but also lists that use asterisks or plus
+ signs. This should make the minor mode generally useful.
+
+ Definition lists and footnotes are also recognized.
+
+ Note that list items may omit leading spaces, for compatibility
+ with modes that set `left-margin', such as `debian-changelog-mode'.
+
+ -- Function: turn-on-muse-list-edit-minor-mode
+ Unconditionally turn on Muse list edit minor mode.
+
+ -- Function: turn-off-muse-list-edit-minor-mode
+ Unconditionally turn off Muse list edit minor mode.
+
+\1f
+File: muse.info, Node: Getting Help and Reporting Bugs, Next: History, Prev: Miscellaneous, Up: Top
+
+12 Getting Help and Reporting Bugs
+**********************************
+
+After you have read this guide, if you still have questions about Muse,
+or if you have bugs to report, there are several places you can go.
+
+ * `http://www.emacswiki.org/cgi-bin/wiki/EmacsMuse' is the
+ emacswiki.org page, and anyone may add tips, hints, or bug
+ descriptions to it.
+
+ * `http://mwolson.org/projects/EmacsMuse.html' is the web page that
+ Michael Olson (the current maintainer) made for Muse.
+
+ * Muse has several different mailing lists.
+
+ `muse-el-announce'
+ Low-traffic list for Muse-related announcements.
+
+ You can join this mailing list (<muse-el-announce@gna.org>)
+ using the subscription form at
+ `http://mail.gna.org/listinfo/muse-el-announce/'. This
+ mailing list is also available via Gmane
+ (`http://gmane.org/'). The group is called
+ `gmane.emacs.muse.announce'.
+
+ `muse-el-discuss'
+ Discussion, bugfixes, suggestions, tips, and the like for
+ Muse. This mailing list also includes the content of
+ muse-el-announce.
+
+ You can join this mailing list (<muse-el-discuss@gna.org>)
+ using the subscription form at
+ `http://mail.gna.org/listinfo/muse-el-discuss/'. This mailing
+ list is also available via Gmane with the identifier
+ `gmane.emacs.muse.general'.
+
+ `muse-el-logs'
+ Log messages for commits made to Muse.
+
+ You can join this mailing list (<muse-el-logs@gna.org>) using
+ the subscription form at
+ `http://mail.gna.org/listinfo/muse-el-logs/'. This mailing
+ list is also available via Gmane with the identifier
+ `gmane.emacs.muse.scm'.
+
+ `muse-el-commits'
+ Generated bug reports for Emacs Muse. If you use our
+ bug-tracker at `https://gna.org/bugs/?group=muse-el', the bug
+ reports will be sent to this list automatically.
+
+ You can join this mailing list (<muse-el-commits@gna.org>)
+ using the subscription form at
+ `http://mail.gna.org/listinfo/muse-el-commits/'. This
+ mailing list is also available via Gmane with the identifier
+ `gmane.emacs.muse.cvs'.
+
+ `muse-el-internationalization'
+ Discussion of translation of the Muse website and
+ documentation into many languages.
+
+ You can join this mailing list
+ (<muse-el-internationalization@gna.org>) using the
+ subscription form at
+ `http://mail.gna.org/listinfo/internationalization/'. This
+ mailing list is also available via Gmane with the identifier
+ `gmane.emacs.muse.internationalization'.
+
+
+ * You can visit the IRC Freenode channel `#emacs'. Many of the
+ contributors are frequently around and willing to answer your
+ questions. The `#muse' channel is also available for
+ Muse-specific help, and its current maintainer hangs out there.
+
+ * The maintainer of Emacs Muse, Michael Olson, may be contacted at
+ <mwolson@gnu.org>. He can be rather slow at answering email, so
+ it is often better to use the muse-el-discuss mailing list.
+
+
+\1f
+File: muse.info, Node: History, Next: Contributors, Prev: Getting Help and Reporting Bugs, Up: Top
+
+13 History of This Document
+***************************
+
+ * 2004 John Wiegley started Muse upon realizing that EmacsWiki had
+ some serious limitations. Around February 2004, he started making
+ "emacs-wiki version 3.00 APLHA", which eventually became known as
+ Muse.
+
+ Most of those who frequent the emacs-wiki mailing list continued
+ to use emacs-wiki, mainly because Planner hasn't been ported over
+ to it.
+
+ As of 2004-12-01, Michael Olson became the maintainer of Muse, as
+ per John Wiegley's request.
+
+ * 2005 Michael Olson overhauled this document and added many new
+ sections in preparation for the first release of Muse (3.01).
+
+
+\1f
+File: muse.info, Node: Contributors, Next: GNU Free Documentation License, Prev: History, Up: Top
+
+14 Contributors to This Documentation
+*************************************
+
+The first draft of this document was taken from the emacs-wiki texinfo
+manual. Michael Olson adapted it for Muse and added most of its
+content.
+
+ John Sullivan did a majority of the work on the emacs-wiki texinfo
+manual.
+
+ While Sacha Chua maintained emacs-wiki, she worked quite a bit on the
+emacs-wiki texinfo manual.
+
+\1f
+File: muse.info, Node: GNU Free Documentation License, Next: Concept Index, Prev: Contributors, Up: Top
+
+Appendix A GNU Free Documentation License
+*****************************************
+
+ Version 1.2, November 2002
+
+ Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ 0. PREAMBLE
+
+ The purpose of this License is to make a manual, textbook, or other
+ functional and useful document "free" in the sense of freedom: to
+ assure everyone the effective freedom to copy and redistribute it,
+ with or without modifying it, either commercially or
+ noncommercially. Secondarily, this License preserves for the
+ author and publisher a way to get credit for their work, while not
+ being considered responsible for modifications made by others.
+
+ This License is a kind of "copyleft," which means that derivative
+ works of the document must themselves be free in the same sense.
+ It complements the GNU General Public License, which is a copyleft
+ license designed for free software.
+
+ We have designed this License in order to use it for manuals for
+ free software, because free software needs free documentation: a
+ free program should come with manuals providing the same freedoms
+ that the software does. But this License is not limited to
+ software manuals; it can be used for any textual work, regardless
+ of subject matter or whether it is published as a printed book.
+ We recommend this License principally for works whose purpose is
+ instruction or reference.
+
+
+ 1. APPLICABILITY AND DEFINITIONS
+
+ This License applies to any manual or other work, in any medium,
+ that contains a notice placed by the copyright holder saying it
+ can be distributed under the terms of this License. Such a notice
+ grants a world-wide, royalty-free license, unlimited in duration,
+ to use that work under the conditions stated herein. The
+ "Document," below, refers to any such manual or work. Any member
+ of the public is a licensee, and is addressed as "you." You
+ accept the license if you copy, modify or distribute the work in a
+ way requiring permission under copyright law.
+
+ A "Modified Version" of the Document means any work containing the
+ Document or a portion of it, either copied verbatim, or with
+ modifications and/or translated into another language.
+
+ A "Secondary Section" is a named appendix or a front-matter
+ section of the Document that deals exclusively with the
+ relationship of the publishers or authors of the Document to the
+ Document's overall subject (or to related matters) and contains
+ nothing that could fall directly within that overall subject.
+ (Thus, if the Document is in part a textbook of mathematics, a
+ Secondary Section may not explain any mathematics.) The
+ relationship could be a matter of historical connection with the
+ subject or with related matters, or of legal, commercial,
+ philosophical, ethical or political position regarding them.
+
+ The "Invariant Sections" are certain Secondary Sections whose
+ titles are designated, as being those of Invariant Sections, in
+ the notice that says that the Document is released under this
+ License. If a section does not fit the above definition of
+ Secondary then it is not allowed to be designated as Invariant.
+ The Document may contain zero Invariant Sections. If the Document
+ does not identify any Invariant Sections then there are none.
+
+ The "Cover Texts" are certain short passages of text that are
+ listed, as Front-Cover Texts or Back-Cover Texts, in the notice
+ that says that the Document is released under this License. A
+ Front-Cover Text may be at most 5 words, and a Back-Cover Text may
+ be at most 25 words.
+
+ A "Transparent" copy of the Document means a machine-readable copy,
+ represented in a format whose specification is available to the
+ general public, that is suitable for revising the document
+ straightforwardly with generic text editors or (for images
+ composed of pixels) generic paint programs or (for drawings) some
+ widely available drawing editor, and that is suitable for input to
+ text formatters or for automatic translation to a variety of
+ formats suitable for input to text formatters. A copy made in an
+ otherwise Transparent file format whose markup, or absence of
+ markup, has been arranged to thwart or discourage subsequent
+ modification by readers is not Transparent. An image format is
+ not Transparent if used for any substantial amount of text. A
+ copy that is not "Transparent" is called "Opaque."
+
+ Examples of suitable formats for Transparent copies include plain
+ ASCII without markup, Texinfo input format, LaTeX input format,
+ SGML or XML using a publicly available DTD, and
+ standard-conforming simple HTML, PostScript or PDF designed for
+ human modification. Examples of transparent image formats include
+ PNG, XCF and JPG. Opaque formats include proprietary formats that
+ can be read and edited only by proprietary word processors, SGML
+ or XML for which the DTD and/or processing tools are not generally
+ available, and the machine-generated HTML, PostScript or PDF
+ produced by some word processors for output purposes only.
+
+ The "Title Page" means, for a printed book, the title page itself,
+ plus such following pages as are needed to hold, legibly, the
+ material this License requires to appear in the title page. For
+ works in formats which do not have any title page as such, "Title
+ Page" means the text near the most prominent appearance of the
+ work's title, preceding the beginning of the body of the text.
+
+ A section "Entitled XYZ" means a named subunit of the Document
+ whose title either is precisely XYZ or contains XYZ in parentheses
+ following text that translates XYZ in another language. (Here XYZ
+ stands for a specific section name mentioned below, such as
+ "Acknowledgements," "Dedications," "Endorsements," or "History.")
+ To "Preserve the Title" of such a section when you modify the
+ Document means that it remains a section "Entitled XYZ" according
+ to this definition.
+
+ The Document may include Warranty Disclaimers next to the notice
+ which states that this License applies to the Document. These
+ Warranty Disclaimers are considered to be included by reference in
+ this License, but only as regards disclaiming warranties: any other
+ implication that these Warranty Disclaimers may have is void and
+ has no effect on the meaning of this License.
+
+ 2. VERBATIM COPYING
+
+ You may copy and distribute the Document in any medium, either
+ commercially or noncommercially, provided that this License, the
+ copyright notices, and the license notice saying this License
+ applies to the Document are reproduced in all copies, and that you
+ add no other conditions whatsoever to those of this License. You
+ may not use technical measures to obstruct or control the reading
+ or further copying of the copies you make or distribute. However,
+ you may accept compensation in exchange for copies. If you
+ distribute a large enough number of copies you must also follow
+ the conditions in section 3.
+
+ You may also lend copies, under the same conditions stated above,
+ and you may publicly display copies.
+
+ 3. COPYING IN QUANTITY
+
+ If you publish printed copies (or copies in media that commonly
+ have printed covers) of the Document, numbering more than 100, and
+ the Document's license notice requires Cover Texts, you must
+ enclose the copies in covers that carry, clearly and legibly, all
+ these Cover Texts: Front-Cover Texts on the front cover, and
+ Back-Cover Texts on the back cover. Both covers must also clearly
+ and legibly identify you as the publisher of these copies. The
+ front cover must present the full title with all words of the
+ title equally prominent and visible. You may add other material
+ on the covers in addition. Copying with changes limited to the
+ covers, as long as they preserve the title of the Document and
+ satisfy these conditions, can be treated as verbatim copying in
+ other respects.
+
+ If the required texts for either cover are too voluminous to fit
+ legibly, you should put the first ones listed (as many as fit
+ reasonably) on the actual cover, and continue the rest onto
+ adjacent pages.
+
+ If you publish or distribute Opaque copies of the Document
+ numbering more than 100, you must either include a
+ machine-readable Transparent copy along with each Opaque copy, or
+ state in or with each Opaque copy a computer-network location from
+ which the general network-using public has access to download
+ using public-standard network protocols a complete Transparent
+ copy of the Document, free of added material. If you use the
+ latter option, you must take reasonably prudent steps, when you
+ begin distribution of Opaque copies in quantity, to ensure that
+ this Transparent copy will remain thus accessible at the stated
+ location until at least one year after the last time you
+ distribute an Opaque copy (directly or through your agents or
+ retailers) of that edition to the public.
+
+ It is requested, but not required, that you contact the authors of
+ the Document well before redistributing any large number of
+ copies, to give them a chance to provide you with an updated
+ version of the Document.
+
+ 4. MODIFICATIONS
+
+ You may copy and distribute a Modified Version of the Document
+ under the conditions of sections 2 and 3 above, provided that you
+ release the Modified Version under precisely this License, with
+ the Modified Version filling the role of the Document, thus
+ licensing distribution and modification of the Modified Version to
+ whoever possesses a copy of it. In addition, you must do these
+ things in the Modified Version:
+
+ A. Use in the Title Page (and on the covers, if any) a title
+ distinct from that of the Document, and from those of previous
+ versions (which should, if there were any, be listed in the
+ History section of the Document). You may use the same title
+ as a previous version if the original publisher of that version
+ gives permission.
+ B. List on the Title Page, as authors, one or more persons or
+ entities responsible for authorship of the modifications in the
+ Modified Version, together with at least five of the principal
+ authors of the Document (all of its principal authors, if it
+ has fewer than five), unless they release you from this
+ requirement.
+ C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+ D. Preserve all the copyright notices of the Document.
+ E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+ F. Include, immediately after the copyright notices, a license
+ notice giving the public permission to use the Modified Version
+ under the terms of this License, in the form shown in the
+ Addendum below.
+ G. Preserve in that license notice the full lists of Invariant
+ Sections and required Cover Texts given in the Document's
+ license notice.
+ H. Include an unaltered copy of this License.
+ I. Preserve the section Entitled "History," Preserve its Title,
+ and add to it an item stating at least the title, year, new
+ authors, and publisher of the Modified Version as given on the
+ Title Page. If there is no section Entitled "History" in the
+ Document, create one stating the title, year, authors, and
+ publisher of the Document as given on its Title Page, then add
+ an item describing the Modified Version as stated in the
+ previous sentence.
+ J. Preserve the network location, if any, given in the Document for
+ public access to a Transparent copy of the Document, and likewise
+ the network locations given in the Document for previous versions
+ it was based on. These may be placed in the "History" section.
+ You may omit a network location for a work that was published at
+ least four years before the Document itself, or if the original
+ publisher of the version it refers to gives permission.
+ K. For any section Entitled "Acknowledgements" or "Dedications,"
+ Preserve the Title of the section, and preserve in the section all
+ the substance and tone of each of the contributor
+ acknowledgements and/or dedications given therein.
+ L. Preserve all the Invariant Sections of the Document,
+ unaltered in their text and in their titles. Section numbers
+ or the equivalent are not considered part of the section titles.
+ M. Delete any section Entitled "Endorsements." Such a section
+ may not be included in the Modified Version.
+ N. Do not retitle any existing section to be Entitled
+ "Endorsements" or to conflict in title with any Invariant
+ Section.
+ O. Preserve any Warranty Disclaimers.
+
+ If the Modified Version includes new front-matter sections or
+ appendices that qualify as Secondary Sections and contain no
+ material copied from the Document, you may at your option
+ designate some or all of these sections as invariant. To do this,
+ add their titles to the list of Invariant Sections in the Modified
+ Version's license notice. These titles must be distinct from any
+ other section titles.
+
+ You may add a section Entitled "Endorsements," provided it contains
+ nothing but endorsements of your Modified Version by various
+ parties-for example, statements of peer review or that the text has
+ been approved by an organization as the authoritative definition
+ of a standard.
+
+ You may add a passage of up to five words as a Front-Cover Text,
+ and a passage of up to 25 words as a Back-Cover Text, to the end
+ of the list of Cover Texts in the Modified Version. Only one
+ passage of Front-Cover Text and one of Back-Cover Text may be
+ added by (or through arrangements made by) any one entity. If the
+ Document already includes a cover text for the same cover,
+ previously added by you or by arrangement made by the same entity
+ you are acting on behalf of, you may not add another; but you may
+ replace the old one, on explicit permission from the previous
+ publisher that added the old one.
+
+ The author(s) and publisher(s) of the Document do not by this
+ License give permission to use their names for publicity for or to
+ assert or imply endorsement of any Modified Version.
+
+ 5. COMBINING DOCUMENTS
+
+ You may combine the Document with other documents released under
+ this License, under the terms defined in section 4 above for
+ modified versions, provided that you include in the combination
+ all of the Invariant Sections of all of the original documents,
+ unmodified, and list them all as Invariant Sections of your
+ combined work in its license notice, and that you preserve all
+ their Warranty Disclaimers.
+
+ The combined work need only contain one copy of this License, and
+ multiple identical Invariant Sections may be replaced with a single
+ copy. If there are multiple Invariant Sections with the same name
+ but different contents, make the title of each such section unique
+ by adding at the end of it, in parentheses, the name of the
+ original author or publisher of that section if known, or else a
+ unique number. Make the same adjustment to the section titles in
+ the list of Invariant Sections in the license notice of the
+ combined work.
+
+ In the combination, you must combine any sections Entitled
+ "History" in the various original documents, forming one section
+ Entitled "History"; likewise combine any sections Entitled
+ "Acknowledgements," and any sections Entitled "Dedications." You
+ must delete all sections Entitled "Endorsements."
+
+ 6. COLLECTIONS OF DOCUMENTS
+
+ You may make a collection consisting of the Document and other
+ documents released under this License, and replace the individual
+ copies of this License in the various documents with a single copy
+ that is included in the collection, provided that you follow the
+ rules of this License for verbatim copying of each of the
+ documents in all other respects.
+
+ You may extract a single document from such a collection, and
+ distribute it individually under this License, provided you insert
+ a copy of this License into the extracted document, and follow
+ this License in all other respects regarding verbatim copying of
+ that document.
+
+ 7. AGGREGATION WITH INDEPENDENT WORKS
+
+ A compilation of the Document or its derivatives with other
+ separate and independent documents or works, in or on a volume of
+ a storage or distribution medium, is called an "aggregate" if the
+ copyright resulting from the compilation is not used to limit the
+ legal rights of the compilation's users beyond what the individual
+ works permit. When the Document is included in an aggregate, this
+ License does not apply to the other works in the aggregate which
+ are not themselves derivative works of the Document.
+
+ If the Cover Text requirement of section 3 is applicable to these
+ copies of the Document, then if the Document is less than one half
+ of the entire aggregate, the Document's Cover Texts may be placed
+ on covers that bracket the Document within the aggregate, or the
+ electronic equivalent of covers if the Document is in electronic
+ form. Otherwise they must appear on printed covers that bracket
+ the whole aggregate.
+
+ 8. TRANSLATION
+
+ Translation is considered a kind of modification, so you may
+ distribute translations of the Document under the terms of section
+ 4. Replacing Invariant Sections with translations requires special
+ permission from their copyright holders, but you may include
+ translations of some or all Invariant Sections in addition to the
+ original versions of these Invariant Sections. You may include a
+ translation of this License, and all the license notices in the
+ Document, and any Warranty Disclaimers, provided that you also
+ include the original English version of this License and the
+ original versions of those notices and disclaimers. In case of a
+ disagreement between the translation and the original version of
+ this License or a notice or disclaimer, the original version will
+ prevail.
+
+ If a section in the Document is Entitled "Acknowledgements,"
+ "Dedications," or "History," the requirement (section 4) to
+ Preserve its Title (section 1) will typically require changing the
+ actual title.
+
+ 9. TERMINATION
+
+ You may not copy, modify, sublicense, or distribute the Document
+ except as expressly provided for under this License. Any other
+ attempt to copy, modify, sublicense or distribute the Document is
+ void, and will automatically terminate your rights under this
+ License. However, parties who have received copies, or rights,
+ from you under this License will not have their licenses
+ terminated so long as such parties remain in full compliance.
+
+ 10. FUTURE REVISIONS OF THIS LICENSE
+
+ The Free Software Foundation may publish new, revised versions of
+ the GNU Free Documentation License from time to time. Such new
+ versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns. See
+ http://www.gnu.org/copyleft/.
+
+ Each version of the License is given a distinguishing version
+ number. If the Document specifies that a particular numbered
+ version of this License "or any later version" applies to it, you
+ have the option of following the terms and conditions either of
+ that specified version or of any later version that has been
+ published (not as a draft) by the Free Software Foundation. If
+ the Document does not specify a version number of this License,
+ you may choose any version ever published (not as a draft) by the
+ Free Software Foundation.
+
+
+ADDENDUM: How to use this License for your documents
+====================================================
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and license
+notices just after the title page:
+
+ Copyright (C) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.2
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+ A copy of the license is included in the section entitled ``GNU
+ Free Documentation License.''
+
+ If you have Invariant Sections, Front-Cover Texts and Back-Cover
+Texts, replace the "with...Texts." line with this:
+
+ with the Invariant Sections being LIST THEIR TITLES, with the
+ Front-Cover Texts being LIST, and with the Back-Cover Texts being
+ LIST.
+
+ If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+ If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License, to
+permit their use in free software.
+
+\1f
+File: muse.info, Node: Concept Index, Prev: GNU Free Documentation License, Up: Top
+
+Index
+*****
+
+\0\b[index\0\b]
+* Menu:
+
+* #author: Directives. (line 18)
+* #date: Directives. (line 24)
+* #desc: Directives. (line 30)
+* #title: Directives. (line 36)
+* anchors: Horizontal Rules and Anchors.
+ (line 13)
+* blog, journal style: Journal. (line 6)
+* blog, one-file-per-entry style: Blosxom. (line 6)
+* bugs, reporting: Getting Help and Reporting Bugs.
+ (line 6)
+* citations: Citations. (line 6)
+* comments: Comments. (line 6)
+* compiling Muse: Installation. (line 11)
+* contributors: Contributors. (line 6)
+* dashes: Horizontal Rules and Anchors.
+ (line 6)
+* Debian package for Muse: Releases. (line 12)
+* developer, becoming: Development. (line 91)
+* development: Development. (line 6)
+* directives: Directives. (line 6)
+* editing Muse files <1>: Publishing Files Overview.
+ (line 6)
+* editing Muse files: Using Muse Mode. (line 6)
+* ELPA package for Muse: Installation. (line 64)
+* Email addresses: Implicit Links. (line 6)
+* emphasizing text: Emphasizing Text. (line 6)
+* examples: Paragraphs. (line 21)
+* file extension, specifying: File Extensions. (line 6)
+* footnotes: Footnotes. (line 6)
+* git version control system, using: Development. (line 9)
+* headings: Headings. (line 6)
+* help, getting: Getting Help and Reporting Bugs.
+ (line 6)
+* history, of Muse: History. (line 6)
+* horizontal rules: Horizontal Rules and Anchors.
+ (line 6)
+* HTML, inserting a raw block: Paragraphs. (line 28)
+* HTML, rendering blocks in monospace: Paragraphs. (line 21)
+* images: Images. (line 6)
+* images, captions: Images. (line 53)
+* images, displaying: Images. (line 22)
+* images, inlined: Images. (line 43)
+* images, local: Images. (line 22)
+* images, without descriptions: Images. (line 43)
+* inserting files at publish time: Tag Summary. (line 6)
+* installing Muse: Installation. (line 38)
+* inter-project links: Implicit Links. (line 29)
+* InterWiki links: Implicit Links. (line 29)
+* italicizing text: Emphasizing Text. (line 6)
+* journal: Journal. (line 6)
+* keystrokes: Keystroke Summary. (line 6)
+* line breaks: Paragraphs. (line 46)
+* links, explicit: Explicit Links. (line 6)
+* links, implicit: Implicit Links. (line 6)
+* links, raw: Implicit Links. (line 6)
+* links, with images: Images. (line 6)
+* links, with target on same page: Horizontal Rules and Anchors.
+ (line 13)
+* lisp, and insert command: Embedded Lisp. (line 13)
+* lisp, embedded: Embedded Lisp. (line 6)
+* lists: Lists. (line 6)
+* lists, breaking lines: Lists. (line 52)
+* lists, bullets: Lists. (line 10)
+* lists, definitions: Lists. (line 24)
+* lists, enumerated: Lists. (line 17)
+* lists, nested: Lists. (line 36)
+* literal text: Paragraphs. (line 28)
+* markup: Markup Rules. (line 6)
+* monospace, rendering blocks: Paragraphs. (line 21)
+* monospace, rendering words: Emphasizing Text. (line 6)
+* muse-define-style: Style Elements. (line 11)
+* muse-derive-style: Deriving Styles. (line 11)
+* muse-list-edit-minor-mode: Muse List Edit Minor Mode.
+ (line 44)
+* muse-project-alist, reference: Options for Projects. (line 6)
+* muse-xml-encoding-map: XML. (line 22)
+* paragraphs: Paragraphs. (line 6)
+* paragraphs, centered: Paragraphs. (line 8)
+* paragraphs, quoted: Paragraphs. (line 16)
+* poetry: Verse. (line 6)
+* projects: Projects. (line 6)
+* projects, multiple: Multiple Projects. (line 6)
+* projects, options: Options for Projects. (line 6)
+* projects, single: Single Project. (line 6)
+* projects, subdirectories: Projects and Subdirectories.
+ (line 6)
+* publishing styles: Publishing Styles. (line 6)
+* publishing styles, blosxom-html: Blosxom Options. (line 12)
+* publishing styles, blosxom-xhtml: Blosxom Options. (line 15)
+* publishing styles, book-latex: Book. (line 56)
+* publishing styles, book-pdf: Book. (line 60)
+* publishing styles, chapbook-latex: Poem. (line 45)
+* publishing styles, chapbook-pdf: Poem. (line 48)
+* publishing styles, context: ConTeXt. (line 15)
+* publishing styles, context-pdf: ConTeXt. (line 18)
+* publishing styles, context-slides: ConTeXt. (line 22)
+* publishing styles, context-slides-pdf: ConTeXt. (line 40)
+* publishing styles, deriving: Deriving Styles. (line 6)
+* publishing styles, docbook: DocBook. (line 11)
+* publishing styles, html: HTML. (line 11)
+* publishing styles, ikiwiki: Ikiwiki. (line 28)
+* publishing styles, info-pdf: Texinfo. (line 17)
+* publishing styles, journal-book-latex: Journal. (line 82)
+* publishing styles, journal-book-pdf: Journal. (line 85)
+* publishing styles, journal-html: Journal. (line 70)
+* publishing styles, journal-latex: Journal. (line 76)
+* publishing styles, journal-pdf: Journal. (line 79)
+* publishing styles, journal-rdf: Journal. (line 88)
+* publishing styles, journal-rss: Journal. (line 91)
+* publishing styles, journal-rss-entry: Journal. (line 94)
+* publishing styles, journal-xhtml: Journal. (line 73)
+* publishing styles, latex: LaTeX. (line 23)
+* publishing styles, latexcjk: LaTeX. (line 30)
+* publishing styles, lecture-notes: LaTeX. (line 55)
+* publishing styles, lecture-notes-pdf: LaTeX. (line 61)
+* publishing styles, pdf: LaTeX. (line 26)
+* publishing styles, pdfcjk: LaTeX. (line 33)
+* publishing styles, poem-latex: Poem. (line 39)
+* publishing styles, poem-pdf: Poem. (line 42)
+* publishing styles, RSS 1.0: Journal. (line 88)
+* publishing styles, RSS 2.0: Journal. (line 91)
+* publishing styles, slides: LaTeX. (line 37)
+* publishing styles, slides-pdf: LaTeX. (line 52)
+* publishing styles, texi: Texinfo. (line 14)
+* publishing styles, xml: XML. (line 15)
+* publishing, including markup in headers and footers: Tag Summary.
+ (line 6)
+* publishing, inserting files: Tag Summary. (line 6)
+* publishing, markup functions: Markup Functions. (line 6)
+* publishing, markup regexps: Markup Regexps. (line 6)
+* publishing, markup strings: Markup Strings. (line 6)
+* publishing, markup tags: Markup Tags. (line 6)
+* publishing, omitting lines: Comments. (line 6)
+* publishing, rules: Markup Regexps. (line 6)
+* publishing, style elements: Style Elements. (line 6)
+* quotations: Paragraphs. (line 16)
+* releases, Debian package: Releases. (line 12)
+* releases, from source: Releases. (line 31)
+* releases, Ubuntu package: Releases. (line 19)
+* settings: Getting Started. (line 6)
+* settings, init file: Loading Muse. (line 6)
+* tables: Tables. (line 6)
+* tables, orgtbl-mode style: Tables. (line 26)
+* tables, simple: Tables. (line 6)
+* tables, table.el style: Tables. (line 42)
+* tags: Tag Summary. (line 6)
+* tags, <cite>: Citations. (line 6)
+* turn-off-muse-list-edit-minor-mode: Muse List Edit Minor Mode.
+ (line 67)
+* turn-on-muse-list-edit-minor-mode: Muse List Edit Minor Mode.
+ (line 64)
+* Ubuntu package for Muse: Releases. (line 19)
+* underlining text: Emphasizing Text. (line 6)
+* updating Muse with git: Development. (line 66)
+* URLs: Implicit Links. (line 6)
+* verbatim text: Emphasizing Text. (line 6)
+* verses: Verse. (line 6)
+* verses, multiple stanzas: Verse. (line 20)
+* WikiNames: Implicit Links. (line 18)
+* WYSIWYG: Emphasizing Text. (line 15)
+
+
+\1f
+Tag Table:
+Node: Top\7f1427
+Node: Preface\7f7398
+Node: Introduction\7f7871
+Node: Obtaining Muse\7f9320
+Node: Releases\7f9657
+Node: Development\7f11046
+Node: Installation\7f14905
+Node: Getting Started\7f17564
+Node: Loading Muse\7f17946
+Node: Using Muse Mode\7f18893
+Node: Publishing Files Overview\7f20926
+Node: File Extensions\7f22170
+Node: Projects\7f23390
+Node: Single Project\7f24012
+Node: Multiple Projects\7f24962
+Node: Projects and Subdirectories\7f26365
+Node: Options for Projects\7f28048
+Node: Keystroke Summary\7f32872
+Node: Markup Rules\7f34991
+Node: Paragraphs\7f36710
+Node: Headings\7f38711
+Node: Directives\7f39334
+Node: Emphasizing Text\7f40654
+Node: Footnotes\7f41431
+Node: Verse\7f42068
+Node: Lists\7f42812
+Node: Tables\7f44361
+Node: Explicit Links\7f46095
+Node: Implicit Links\7f46810
+Node: Images\7f49153
+Node: Horizontal Rules and Anchors\7f51643
+Node: Embedded Lisp\7f52291
+Node: Citations\7f53387
+Node: Comments\7f55871
+Node: Tag Summary\7f56530
+Node: Publishing Styles\7f64773
+Node: Blosxom\7f65872
+Node: Blosxom Requirements\7f66479
+Node: Blosxom Entries\7f70014
+Node: Blosxom Options\7f71577
+Node: Book\7f72505
+Node: ConTeXt\7f75564
+Node: DocBook\7f79691
+Node: HTML\7f81168
+Node: Ikiwiki\7f85163
+Node: Journal\7f87502
+Node: LaTeX\7f94029
+Node: Poem\7f99573
+Node: Texinfo\7f101782
+Node: XML\7f103699
+Node: Extending Muse\7f105730
+Node: Markup Functions\7f106367
+Ref: muse-publish-markup-functions\7f106540
+Node: Markup Regexps\7f107194
+Ref: muse-publish-markup-regexps\7f107372
+Node: Markup Strings\7f110379
+Node: Markup Tags\7f116839
+Ref: muse-publish-markup-tags\7f117032
+Node: Style Elements\7f118151
+Node: Deriving Styles\7f121558
+Node: Miscellaneous\7f122857
+Node: Muse List Edit Minor Mode\7f123142
+Node: Getting Help and Reporting Bugs\7f125621
+Node: History\7f128923
+Node: Contributors\7f129706
+Node: GNU Free Documentation License\7f130214
+Node: Concept Index\7f152443
+\1f
+End Tag Table
--- /dev/null
+Muse is a tool for easily authoring and publishing documents. It
+allows for rapid prototyping of hyperlinked text, which may then be
+exported to multiple output formats, such as HTML, LaTeX, and Texinfo.
+
+The markup rules used by Muse are intended to be very friendly to
+people familiar with Emacs. See the included manual for more
+information.
--- /dev/null
+Org-mode is a mode for keeping notes, maintaining ToDo lists, and doing
+project planning with a fast and effective plain-text system.
+
+This package contains a daily build of Org-mode.
+
+Org-mode develops organizational tasks around NOTES files that contain
+information about projects as plain text. Org-mode is implemented on
+top of outline-mode, which makes it possible to keep the content of
+large files well structured. Visibility cycling and structure editing
+help to work with the tree. Tables are easily created with a built-in
+table editor. Org-mode supports ToDo items, deadlines, time stamps,
+and scheduling. It dynamically compiles entries into an agenda that
+utilizes and smoothly integrates much of the Emacs calendar and diary.
+Plain text URL-like links connect to websites, emails, Usenet
+messages, BBDB entries, and any files related to the projects. For
+printing and sharing of notes, an Org-mode file can be exported as a
+structured ASCII file, as HTML, or (todo and agenda items only) as an
+iCalendar file. It can also serve as a publishing tool for a set of
+linked webpages.
--- /dev/null
+;;; rainbow-mode.el --- Colorize color names in buffers
+
+;; Copyright (C) 2010 Free Software Foundation, Inc
+
+;; Author: Julien Danjou <julien@danjou.info>
+;; Keywords: faces
+;; Version: 0.1
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; This minor mode sets background color to strings that match color
+;; names, e.g. #0000ff is displayed in white with a blue background.
+;;
+
+;;; Code:
+
+(eval-when-compile
+ (require 'cl))
+
+(require 'regexp-opt)
+(require 'faces)
+
+(defgroup rainbow nil
+ "Show color strings with a background color."
+ :tag "Rainbow"
+ :group 'help)
+
+;; Hexadecimal colors
+(defvar rainbow-hexadecimal-colors-font-lock-keywords
+ '(("#[0-9a-fA-F]\\{3\\}[0-9a-fA-F]\\{3\\}?"
+ (0 (rainbow-colorize-itself))))
+ "Font-lock keywords to add for hexadecimal colors.")
+
+;; rgb() colors
+(defvar rainbow-html-rgb-colors-font-lock-keywords
+ '(("rgb(\s*\\([0-9]\\{1,3\\}\\(?:\s*%\\)?\\)\s*,\s*\\([0-9]\\{1,3\\}\\(?:\s*%\\)?\\)\s*,\s*\\([0-9]\\{1,3\\}\\(?:\s*%\\)?\\)\s*)"
+ (0 (rainbow-colorize-rgb)))
+ ("rgba(\s*\\([0-9]\\{1,3\\}\\(?:\s*%\\)?\\)\s*,\s*\\([0-9]\\{1,3\\}\\(?:\s*%\\)?\\)\s*,\s*\\([0-9]\\{1,3\\}\\(?:\s*%\\)?\\)\s*,\s*[0-9]\\{1,3\\}\s*%?\s*)"
+ (0 (rainbow-colorize-rgb))))
+ "Font-lock keywords to add for RGB colors.")
+
+;; HTML colors name
+(defvar rainbow-html-colors-font-lock-keywords nil
+ "Font-lock keywords to add for HTML colors.")
+(make-variable-buffer-local 'rainbow-html-colors-font-lock-keywords)
+
+(defcustom rainbow-html-colors-alist
+ '(("black" . "#000000")
+ ("silver" . "#C0C0C0")
+ ("gray" . "#808080")
+ ("white" . "#FFFFFF")
+ ("maroon" . "#800000")
+ ("red" . "#FF0000")
+ ("purple" . "#800080")
+ ("fuchsia" . "#FF00FF")
+ ("green" . "#008000")
+ ("lime" . "#00FF00")
+ ("olive" . "#808000")
+ ("yellow" . "#FFFF00")
+ ("navy" . "#000080")
+ ("blue" . "#0000FF")
+ ("teal" . "#008080")
+ ("aqua" . "#00FFFF"))
+ "Alist of HTML colors.
+Each entry should have the form (COLOR-NAME . HEXADECIMAL-COLOR)."
+ :group 'rainbow)
+
+(defcustom rainbow-html-colors-major-mode-list
+ '(html-mode css-mode php-mode nxml-mode xml-mode)
+ "List of major mode where HTML colors are enabled when
+`rainbow-html-colors' is set to auto."
+ :group 'rainbow)
+
+(defcustom rainbow-html-colors 'auto
+ "When to enable HTML colors.
+If set to t, the HTML colors will be enabled. If set to nil, the
+HTML colors will not be enabled. If set to auto, the HTML colors
+will be enabled if a major mode has been detected from the
+`rainbow-html-colors-major-mode-list'."
+ :group 'rainbow)
+
+;; X colors
+(defvar rainbow-x-colors-font-lock-keywords
+ `((,(regexp-opt (x-defined-colors) 'words)
+ (0 (rainbow-colorize-itself))))
+ "Font-lock keywords to add for X colors.")
+
+(defcustom rainbow-x-colors-major-mode-list
+ '(emacs-lisp-mode lisp-interaction-mode c-mode c++-mode java-mode)
+ "List of major mode where X colors are enabled when
+`rainbow-x-colors' is set to auto."
+ :group 'rainbow)
+
+(defcustom rainbow-x-colors 'auto
+ "When to enable X colors.
+If set to t, the X colors will be enabled. If set to nil, the
+X colors will not be enabled. If set to auto, the X colors
+will be enabled if a major mode has been detected from the
+`rainbow-x-colors-major-mode-list'."
+ :group 'rainbow)
+
+;; LaTeX colors
+(defvar rainbow-latex-rgb-colors-font-lock-keywords
+ '(("{rgb}{\\([0-9.]+\\),\\([0-9.]+\\),\\([0-9.]+\\)}"
+ (0 (rainbow-colorize-rgb-float)))
+ ("{RGB}{\\([0-9]\\{1,3\\}\\),\\([0-9]\\{1,3\\}\\),\\([0-9]\\{1,3\\}\\)}"
+ (0 (rainbow-colorize-rgb)))
+ ("{HTML}{\\([0-9A-Fa-f]\\{6\\}\\)}"
+ (0 (rainbow-colorize-hexadecimal-without-sharp))))
+ "Font-lock keywords to add for X colors.")
+
+(defcustom rainbow-latex-colors-major-mode-list
+ '(latex-mode)
+ "List of major mode where X colors are enabled when
+`rainbow-x-colors' is set to auto."
+ :group 'rainbow)
+
+(defcustom rainbow-latex-colors 'auto
+ "When to enable LaTeX colors.
+If set to t, the LaTeX colors will be enabled. If set to nil, the
+X colors will not be enabled. If set to auto, the LaTeX colors
+will be enabled if a major mode has been detected from the
+`rainbow-latex-colors-major-mode-list'."
+ :group 'rainbow)
+
+;; Functions
+(defun rainbow-colorize-match (color)
+ "Return a matched string propertized with a face whose
+background is COLOR. The foreground is computed using
+`rainbow-color-luminance', and is either white or black."
+ (put-text-property
+ (match-beginning 0) (match-end 0)
+ 'face `((:foreground ,(if (> 128.0 (rainbow-x-color-luminance color))
+ "white" "black"))
+ (:background ,color))))
+
+(defun rainbow-colorize-itself ()
+ "Colorize a match with itself."
+ (rainbow-colorize-match (match-string-no-properties 0)))
+
+(defun rainbow-colorize-hexadecimal-without-sharp ()
+ "Colorize an hexadecimal colors and prepend # to it."
+ (rainbow-colorize-match (concat "#" (match-string-no-properties 1))))
+
+(defun rainbow-colorize-by-assoc (assoc-list)
+ "Colorize a match with its association from ASSOC-LIST."
+ (rainbow-colorize-match (cdr (assoc (match-string-no-properties 0) assoc-list))))
+
+(defun rainbow-rgb-relative-to-absolute (number)
+ "Convert a relative NUMBER to absolute. If NUMBER is absolute, return NUMBER.
+This will convert \"80 %\" to 204, \"100 %\" to 255 but \"123\" to \"123\"."
+ (let ((string-length (- (length number) 1)))
+ ;; Is this a number with %?
+ (if (eq (elt number string-length) ?%)
+ (/ (* (string-to-number (substring number 0 string-length)) 255) 100)
+ (string-to-number number))))
+
+(defun rainbow-colorize-rgb ()
+ "Colorize a match with itself."
+ (let ((r (rainbow-rgb-relative-to-absolute (match-string-no-properties 1)))
+ (g (rainbow-rgb-relative-to-absolute (match-string-no-properties 2)))
+ (b (rainbow-rgb-relative-to-absolute (match-string-no-properties 3))))
+ (rainbow-colorize-match (format "#%02X%02X%02X" r g b))))
+
+(defun rainbow-colorize-rgb-float ()
+ "Colorize a match with itself, with relative value."
+ (let ((r (* (string-to-number (match-string-no-properties 1)) 255.0))
+ (g (* (string-to-number (match-string-no-properties 2)) 255.0))
+ (b (* (string-to-number (match-string-no-properties 3)) 255.0)))
+ (rainbow-colorize-match (format "#%02X%02X%02X" r g b))))
+
+(defun rainbow-color-luminance (red green blue)
+ "Calculate the luminance of color composed of RED, BLUE and GREEN."
+ (floor (+ (* .2126 red) (* .7152 green) (* .0722 blue)) 256))
+
+(defun rainbow-x-color-luminance (color)
+ "Calculate the luminance of a color string (e.g. \"#ffaa00\", \"blue\")."
+ (let* ((values (x-color-values color))
+ (r (car values))
+ (g (cadr values))
+ (b (caddr values)))
+ (rainbow-color-luminance r g b)))
+
+(defun rainbow-turn-on ()
+ "Turn on raibow-mode."
+ (font-lock-add-keywords nil
+ rainbow-hexadecimal-colors-font-lock-keywords)
+ ;; Activate X colors?
+ (when (or (eq rainbow-x-colors t)
+ (and (eq rainbow-x-colors 'auto)
+ (memq major-mode rainbow-x-colors-major-mode-list)))
+ (font-lock-add-keywords nil
+ rainbow-x-colors-font-lock-keywords))
+ ;; Activate LaTeX colors?
+ (when (or (eq rainbow-latex-colors t)
+ (and (eq rainbow-latex-colors 'auto)
+ (memq major-mode rainbow-latex-colors-major-mode-list)))
+ (font-lock-add-keywords nil
+ rainbow-latex-rgb-colors-font-lock-keywords))
+ ;; Activate HTML colors?
+ (when (or (eq rainbow-html-colors t)
+ (and (eq rainbow-html-colors 'auto)
+ (memq major-mode rainbow-html-colors-major-mode-list)))
+ (setq rainbow-html-colors-font-lock-keywords
+ `((,(regexp-opt (mapcar 'car rainbow-html-colors-alist) 'words)
+ (0 (rainbow-colorize-by-assoc rainbow-html-colors-alist)))))
+ (font-lock-add-keywords nil
+ `(,@rainbow-html-colors-font-lock-keywords
+ ,@rainbow-html-rgb-colors-font-lock-keywords))))
+
+(defun rainbow-turn-off ()
+ "Turn off rainbow-mode."
+ (font-lock-remove-keywords
+ nil
+ `(,@rainbow-hexadecimal-colors-font-lock-keywords
+ ,@rainbow-x-colors-font-lock-keywords
+ ,@rainbow-latex-rgb-colors-font-lock-keywords
+ ,@rainbow-html-colors-font-lock-keywords
+ ,@rainbow-html-rgb-colors-font-lock-keywords)))
+
+;;;###autoload
+(define-minor-mode rainbow-mode
+ "Colorize strings that represent colors.
+This will fontify with colors the string like \"#aabbcc\" or \"blue\"."
+ :lighter " Rbow"
+ (progn
+ (if rainbow-mode
+ (rainbow-turn-on)
+ (rainbow-turn-off))
+ ;; Turn on font lock
+ (font-lock-mode 1)))
+
+(provide 'rainbow-mode)
+
+;;; rainbow-mode.el ends here
--- /dev/null
+This minor mode sets background color to strings that match color
+names. For instance, #0000ff is displayed in white with a blue
+background.