summaryrefslogtreecommitdiff
path: root/support/jed
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/jed
Initial commit
Diffstat (limited to 'support/jed')
-rw-r--r--support/jed/jlm/COPYING280
-rw-r--r--support/jed/jlm/README14
-rw-r--r--support/jed/jlm/doc/changelog.old956
-rw-r--r--support/jed/jlm/doc/jlm-vortrag.latex207
-rw-r--r--support/jed/jlm/doc/jlm-vortrag.pdfbin0 -> 196490 bytes
-rw-r--r--support/jed/jlm/doc/jlm.pdfbin0 -> 271692 bytes
-rw-r--r--support/jed/jlm/doc/jlm.tex801
-rw-r--r--support/jed/jlm/doc/latex-jed.rc208
-rw-r--r--support/jed/jlm/doc/wrap_failures.ltx57
-rw-r--r--support/jed/jlm/latex-templ/beamer.ltx49
-rw-r--r--support/jed/jlm/latex-templ/foils.ltx28
-rw-r--r--support/jed/jlm/latex-templ/mini.ltx8
-rw-r--r--support/jed/jlm/latex-templ/powerdot.ltx75
-rw-r--r--support/jed/jlm/latex-templ/scrartcl.ltx21
-rw-r--r--support/jed/jlm/latex-templ/scrbook.ltx22
-rw-r--r--support/jed/jlm/latex-templ/scrlttr2.ltx33
-rw-r--r--support/jed/jlm/latex-templ/scrreprt.ltx24
-rw-r--r--support/jed/jlm/latex-templ/uebung.ltx24
-rw-r--r--support/jed/jlm/latex.sl5407
-rw-r--r--support/jed/jlm/latex_cmds.sl983
-rw-r--r--support/jed/jlm/latex_comm.sl122
-rw-r--r--support/jed/jlm/latex_conv.sl241
-rw-r--r--support/jed/jlm/latex_external.sl1551
-rw-r--r--support/jed/jlm/latex_pst.sl307
-rw-r--r--support/jed/jlm/latex_typo.sl580
-rw-r--r--support/jed/jlm/read_with_description.sl244
-rw-r--r--support/jed/jlm/test/test_latex_pst.sl198
-rw-r--r--support/jed/latex4jed/COPYING339
-rw-r--r--support/jed/latex4jed/README10
-rw-r--r--support/jed/latex4jed/TODO3
-rw-r--r--support/jed/latex4jed/elegant.sl39
-rw-r--r--support/jed/latex4jed/latex.hlp54
-rw-r--r--support/jed/latex4jed/latex.sl2927
-rw-r--r--support/jed/latex4jed/latex4jed.pdfbin0 -> 187820 bytes
-rw-r--r--support/jed/latex4jed/latex4jed.tex820
-rw-r--r--support/jed/latex4jed/modern.sl40
-rw-r--r--support/jed/latex4jed/modules/notice.sl50
-rw-r--r--support/jed/latex4jed/modules/prosper.sl181
-rw-r--r--support/jed/latex4jed/modules/textpos.sl41
-rw-r--r--support/jed/latex4jed/night.sl38
40 files changed, 16982 insertions, 0 deletions
diff --git a/support/jed/jlm/COPYING b/support/jed/jlm/COPYING
new file mode 100644
index 0000000000..e37680cf13
--- /dev/null
+++ b/support/jed/jlm/COPYING
@@ -0,0 +1,280 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 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.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, 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 show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program 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.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public 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.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
diff --git a/support/jed/jlm/README b/support/jed/jlm/README
new file mode 100644
index 0000000000..f5fb8bcc97
--- /dev/null
+++ b/support/jed/jlm/README
@@ -0,0 +1,14 @@
+JLM is an advanced LaTeX mode for Jed <http://www.jedsoft.org>. Its aim is to
+help the user by taking over annoying and stupid things they need to be done,
+like add a \usepackage when you add a command or environment from this package
+or put dollar signs around mathematical commands and move the cursor to an
+appropriate point.
+
+JLM does not think for you. If you want a tabular, but insert an itemize, JLM
+doesn't prevent this. So, you should be familiar with LaTeX and know what
+environments and commands are and where to place them in a document—JLM helps
+writing them.
+
+You can get the newest development version via SVN from
+
+ https://svn.lug-jena.de/repos/public/jjm
diff --git a/support/jed/jlm/doc/changelog.old b/support/jed/jlm/doc/changelog.old
new file mode 100644
index 0000000000..6822f6d76a
--- /dev/null
+++ b/support/jed/jlm/doc/changelog.old
@@ -0,0 +1,956 @@
+------------------------------------------------------------------------
+r44 | joerg | 2006-07-04 00:24:22 +0200 (Di, 04 Jul 2006) | 3 lines
+
+* doc latex-jed.rc
+ + Created a directory for documentation and moved latex-jed.rc there.
+
+------------------------------------------------------------------------
+r43 | joerg | 2006-07-03 23:17:22 +0200 (Mo, 03 Jul 2006) | 24 lines
+
+* latex-jed.rc
+ + set_autosave() does not exist. Use the real code.
+
+* latex_cmds.sl latex.sl
+ + Moved label_insert() and bib_cite() to latex_cmds.sl and rewrote them
+ as hooks for the cmd_add() interface.
+
+ + bib_cite_hook() uses the status line to display helping informations
+ about keys.
+
+* latex.sl
+ + Switched some lines and the keymap to cmd_insert() due to the
+ label_insert() was removed.
+
+ + env_name() and is_math() need to be static to be accessable from
+ latex_cmds.sl.
+
+* latex_cmds.sl
+ + Renamed the label_ref_* stuff to ref_* to make it more
+ distinguishable from the label_* stuff.
+
+ + In ref_next(), move the editing point one step to the left if nothing
+ was found, if searching forward.
+
+------------------------------------------------------------------------
+r42 | joerg | 2006-07-02 17:35:05 +0200 (So, 02 Jul 2006) | 3 lines
+
+* Removed the german words from scrlttr2.latex.
+
+------------------------------------------------------------------------
+r41 | joerg | 2006-07-02 17:19:06 +0200 (So, 02 Jul 2006) | 18 lines
+
+* read_with_description.sl
+ + Replaced the autoload() by require() to prevent multiple loading of
+ stkcheck.
+
+ + To use pop2buf everytime in rwd_completion() is not a good idea,
+ because this function refreshes the screen even if nothing changed.
+ This leads to flickering and is really annoying. Introduced a better
+ strategie.
+
+ + Sometimes the current buffer is not the old_buf in rwd_completion()
+ when inserting the completion. Added a check and if it fail raise an
+ error. Otherwise the completion ends up in a completly different
+ buffer. I don't have an explanation for this and I can't reproduce it.
+
+ + If the *Completion* buffer exists when read_with_description() is
+ called many things go wrong. Therefore remove the buffer if it exists
+ on startup.
+
+------------------------------------------------------------------------
+r40 | joerg | 2006-07-02 11:34:44 +0200 (So, 02 Jul 2006) | 5 lines
+
+* debmode.sl
+ + Removed _debug_info. It's obsolated.
+
+ + Small fixed of the DFA highlighting.
+
+------------------------------------------------------------------------
+r39 | joerg | 2006-07-02 01:43:53 +0200 (So, 02 Jul 2006) | 10 lines
+
+* latex.sl
+ + Jens Kubieziel suggested to add automaticly a space after commands
+ without arguments. I don't like it, because it breaks my workflow.
+ But it might be useful for someone else and it was really easy to make it
+ adjustable. The new variable LaTeX_Auto_Space_After_Commands determines
+ if a space is added after a command if the next charater is a letter.
+
+* latex_cmds.sl
+ + Removed the add command. It is a self defined command of me.
+
+------------------------------------------------------------------------
+r38 | joerg | 2006-07-02 01:32:31 +0200 (So, 02 Jul 2006) | 17 lines
+
+* yankpop.sl
+ + Added a copyright notice for a release version.
+
+ + Removed the _debug_info, _traceback and _slangtrace variables. They
+ are not useless or not needed.
+
+ + Renamed Last_pop by Last_Pop for consistency.
+
+ + Added the property svn:keywords with id to the file.
+
+ + Replaced all error() statements by throw statements. SLang2 migration.
+
+ + Improved indentation and statement alignment.
+
+ + Changed the yp_copy_region_as_kill() to not add a region to the
+ buffer if it is still the head element.
+
+------------------------------------------------------------------------
+r37 | joerg | 2006-07-01 14:28:41 +0200 (Sa, 01 Jul 2006) | 4 lines
+
+* latex-jed.rc
+ + Created a file with commands a user can add to its private jed.rc to
+ improve the LaTeX mode.
+
+------------------------------------------------------------------------
+r36 | joerg | 2006-07-01 00:58:30 +0200 (Sa, 01 Jul 2006) | 5 lines
+
+* latex.sl
+ + Rewrote insert_limits_char() to fix some bugs and make a code cleanup.
+
+ + debug_msg() now converts the argument to a string.
+
+------------------------------------------------------------------------
+r35 | joerg | 2006-06-30 22:33:22 +0200 (Fr, 30 Jun 2006) | 4 lines
+
+* latex.sl latex_external.sl
+ + Replaced the autoload("stkcheck") by a require(), because the
+ autload() led to multiple evaluations of stkcheck.sl.
+
+------------------------------------------------------------------------
+r34 | joerg | 2006-06-25 19:47:43 +0200 (So, 25 Jun 2006) | 20 lines
+
+* latex_cmds.sl
+ + Small fixes. Many backslashes in the descriptions were not quoted.
+
+* latex_external.sl
+ + Replaced the wherefirst() != NULL stuff by the any() function and
+ created a fallback function that will become defined if any() is not
+ available (not enabled in Jed).
+
+* latex.sl
+ + requires now read_with_description.sl which is used in cmd_prompt().
+
+ + Made env_close() more "stack clean".
+
+ + Extended the Cmd_Type by the component compl. This makes it easier to
+ use the struct with read_with_description().
+
+ + Rewritten cmd_prompt() to use read_with_description() as prompt
+ function. Now ^cs presents you a list of possible completions and
+ beside every completion a description of what this command does.
+
+------------------------------------------------------------------------
+r33 | joerg | 2006-06-25 19:22:23 +0200 (So, 25 Jun 2006) | 4 lines
+
+* read_with_description.sl
+ + Implemented a new fancy function to prompt the user for a string and
+ give him a description along with the completion proposition.
+
+------------------------------------------------------------------------
+r32 | joerg | 2006-06-24 22:11:43 +0200 (Sa, 24 Jun 2006) | 18 lines
+
+* latex.sl
+ + Added new customization variables LaTeX_Default_Packages and
+ LaTeX_Default_Class_Options. These are used when inserting templates.
+
+ + Extended the templ_insert() function to call insert_pkgs() with the
+ content of LaTeX_Default_Packages if a line "%:default:pkgs:%" is found
+ and replace the string "%:default:classopt:?%" (with ? = , (comma) or
+ ? = [) with the content of LaTeX_Default_Class_Options. The value of ?
+ indicates if a , is prefixed to L_D_C_O or L_D_C_O is surrounded by [].
+
+ + Moved "WRAP_INDENTS = 1" into latex_mode(), because this variable should
+ be set for every file independent of others.
+
+ + Load the abbrev table TeX in latex_mode() if it exists.
+
+* latex-templ/*
+ + Adapted the files to the new templ_insert() function.
+
+------------------------------------------------------------------------
+r31 | joerg | 2006-06-24 18:08:41 +0200 (Sa, 24 Jun 2006) | 63 lines
+
+* latex_cmds.sl
+
+ + Added a new hook goto_mark_hook() that moves the editing point to the
+ place given by the mark argument. This is useful for commands they need a
+ {} by do not take an argument like \TeX.
+
+ + Flipped the description and dependency argument of hyperref.
+
+ + Added the new goto_mark_hook() to LaTeX and TeX.
+
+ + Added texttrademark.
+
+* latex.sl
+ + Removed the _debug_info variable. It's meaningless in SLang 2.
+
+ + Fixed the trim function to not remove a character after a backlash. And it
+ now differentiates between \\ and \ at the end of line.
+
+ + Kicked linsert(). It's not used anymore.
+
+ + Added the matrix environments from AMS math and set their dependencies.
+
+ + The prompt for a latex command now presents the last used command as
+ default. You only have to press return.
+
+ + font_key() now clears the message at end.
+
+ + Fixed the insertion of \ll. It was not placed in mathmode.
+
+ + Extended the insert_limits_char() function to replace \vee by \bigvee and
+ \wedge by \bigwedge (like \cup and \bigcup) if a limit is set.
+
+* latex_external.sl
+ + Removed the _debug_info variable. It's meaningless in SLang 2.
+
+ + If a compose process is running and we must reload or open the logfile,
+ it's not possible anymore to pop up the logfile buffer.
+
+ + pop_log_file() only counts lines they start with "! " as error lines.
+ Watching only at an exclamation mark leads to false positives.
+
+ + Improved the log parser.
+ - A new function next_log_line() takes care of long messages they are
+ wrapped at 80 characters and continued at the next line.
+
+ - Also improved the handling of box messages. A \vbox need to be parsed
+ different from a \hbox message, e.g. a \vbox message has no line
+ information.
+
+ - If a line matches the first character but does not fullfil other
+ requirements the line is parsed as a default line and not skipped. This
+ was a bug in the versions before.
+
+ + Do not move the editing point when jumping to an error line, if the error
+ message does not give an error line. Think of \vbox messages.
+
+ + When jumping to the column in an error line, check if the line has enough
+ characters. If the file was modified and the line has not enough
+ characters, goto_column() adds whitespaces to the end. This is not
+ intended.
+
+ + Forbid the print and view command if a compose process is running.
+
+------------------------------------------------------------------------
+r30 | joerg | 2006-06-17 14:48:03 +0200 (Sa, 17 Jun 2006) | 37 lines
+
+* latex_cmds.sl
+ + New commands and correction/extension of other commands.
+
+* latex.sl
+ + Load and enable stack check if it is available. This prints warnings
+ to *traceback* about expressions they leave values on the stack.
+
+ + Cleaned up the code from stack commands. After a statement of John
+ that defining and assigning to a variable takes not much longer, I
+ decided to not use the stack features of SLang (pop, dup, exch),
+ because stack check complains about such expressions and they tend to
+ be less readable than variable usage.
+
+ + Due to a bug in SLang the statements after a try-catch-finally block
+ are executed even through a return in the try block quit the function.
+ is_math() fixed.
+
+ + A comma after proof was missing in the ENVIRONMENTS list.
+
+ + cmd_insert() does not treat commands with a star (*) at the end like
+ the command without star, e.g. you have to define only the without
+ star version.
+
+* latex_external.sl
+ + Load and enable stack check if it is available. This prints warnings
+ to *traceback* about expressions they leave values on the stack.
+
+ + Cleaned up the code from stack commands. After a statement of John
+ that defining and assigning to a variable takes not much longer, I
+ decided to not use the stack features of SLang (pop, dup, exch),
+ because stack check complains about such expressions and they tend to
+ be less readable than variable usage.
+
+ + Due to a bug in SLang the statements after a try-catch-finally block
+ are executed even through a return in the try block quit the function.
+ get_master_var() fixed.
+
+------------------------------------------------------------------------
+r29 | joerg | 2006-06-04 02:30:58 +0200 (So, 04 Jun 2006) | 25 lines
+
+* latex.sl
+ + Replaced LaTeX_Templates_Dir by a custom_variable() and added a
+ description.
+
+ + Removed the arguments of inputenc and fontenc from
+ LaTeX_Default_Packages and added an entry for fontenc to PACKAGE_OPTIONS[].
+
+ + insert_templ():
+ - Renamed to templ_insert().
+
+ - The LaTeX_Default_Packages is only inserted if the buffer was empty
+ before. This makes it possible to insert text blocks via the
+ templates function without destroying the current package selection.
+
+ + I've renamed the menu_init_helper() before the last commit, but
+ forgot to rename it at the usage points.
+
+ + Fixed the menu entry for thebibliography.
+
+* latex_cmds.sl
+ + New commands.
+
+* latex-templ/mini.latex
+ + Added a minimalistic template of a latex file.
+
+------------------------------------------------------------------------
+r26 | joerg | 2006-06-04 01:20:54 +0200 (So, 04 Jun 2006) | 3 lines
+
+* latex-templ/*
+ + Reworked all templates to make them usable by many peoples.
+
+------------------------------------------------------------------------
+r25 | joerg | 2006-06-03 23:16:54 +0200 (Sa, 03 Jun 2006) | 11 lines
+
+* latex.sl:
+ + Added colorlinks and urlcolor=blue to the default options of hypperref.
+
+ + Created menu_init_helper() for easier adding menu entries of the form
+ menu_append_item(menu, entry, fun, entry)
+
+ + Renamed init_menu() by menu_init().
+
+ + Rewritten a big part of menu_init() to support the new command
+ cmd_insert() and env_insert(). But a big part remains broken.
+
+------------------------------------------------------------------------
+r24 | joerg | 2006-06-03 19:46:30 +0200 (Sa, 03 Jun 2006) | 3 lines
+
+* latex_cmds.sl
+ + new commands
+
+------------------------------------------------------------------------
+r23 | joerg | 2006-06-03 14:16:21 +0200 (Sa, 03 Jun 2006) | 5 lines
+
+* latex.sl, label_cmd.sl:
+ + Moved all label_ref_hook() stuff to label_cmd.sl.
+
+ + This made it necessary to declare MODE in latex.sl static.
+
+------------------------------------------------------------------------
+r22 | joerg | 2006-06-03 14:00:48 +0200 (Sa, 03 Jun 2006) | 33 lines
+
+* latex_cmds.sl:
+ + Set svn:keywords = id.
+
+ + Renamed pop2_hook() by null_hook().
+
+ + Added file_select_hook() that asks the user for a file and insert
+ this filename as argument. Used for input, include, includegraphics,
+ VerbatimInput.
+
+* latex.sl:
+ + Renamed the buffer of debug messages to *traceback*, because we can
+ so set marks between _print_stack() outputs.
+
+ + Added prefix and region support to cmd_insert().
+ - Prefixing the a cmd_insert() means inserting N optional arguments "[]".
+
+ - A region defined before calling cmd_insert() is moved to the first
+ argument. This makes <MARK>some emphasized text<cmd_insert("emph")>
+ is replaced by \emph{some emphasized text} and the cursor after the }.
+
+ - Better prompt for cmd_insert().
+
+ - struct.ref is a "cool festure" of SLang2 to support OOP that pushes
+ the struct on to the stack. This is not intended. Therefor written
+ as (@struct.ref)(args).
+
+ + cmd_prompt(): The read_with_completion() eats up the prefix argument.
+ Therefor it must be saved before and set after read_with_completion().
+
+ + label_ref_hook() has one argument to much.
+
+ + ^cnq included a " to much in the argument.
+
+------------------------------------------------------------------------
+r21 | joerg | 2006-06-02 00:19:38 +0200 (Fr, 02 Jun 2006) | 130 lines
+
+* latex.sl:
+ + Added new default modes.
+
+ + Made the LaTeX_Template_Dir a little more generic.
+
+ + Moved PACKAGE_OPTIONS down in the package section.
+
+ + The argument of inputenc is now utf8 if _slang_utf8_ok is set.
+ Otherwise it is still latin1.
+
+ + Added the font environments (rmfamily, bfseries, scshape,...) to the
+ environment autocompletions.
+
+ + Added a new section for commands with new cool features:
+ - Created a new data type Cmd_Type to be used for the elements in the
+ cmd_list associative array.
+
+ - The array cmd_list saves all the informations about latex commands,
+ e.g. this ones beginning with a backslash. These informations are:
+ # args: the number of argumentens the command has
+ # desc: a description of the command
+ # deps: a colon separated list of package(s) the command is defined
+ in
+ # hook: a reference to a function that is run after the command was
+ inserted. The current editing point is in the first
+ argument or after the command if the command has no
+ arguments. Two arguments are passed to the function: name
+ (name of the command; without \) and a mark (Mark_Type) of
+ the point after the command (e.g. after the $ for math
+ commands)
+ # math: must this command be in math mode?
+
+ - A new function cmd_add() that adds/overwrites entries of cmd_list.
+ It takes 6 arguments:
+ # name: the name of the command without \
+ # the rest of the arguments are the members of the members of
+ cmd_list
+
+ - The new function cmd_insert() is beside the database cmd_list the
+ main part of this feature. It can be called without an or with one
+ argument that is takes as the command. In the othercase (no
+ argument) the user is prompted with read_mini(). It ensures all
+ dependencies of the command are satisfied (e.g. insert the needed
+ packages and switch to (simple) math mode), inserts the command and
+ braces for the arguments and calls a hook if given.
+
+ - A simple function cmd_prompt that prompts the user for a command
+ and give all known commands as completion.
+
+ + Rewritten and renamed font() to font_key() that works as an
+ intelligent splitter for font command. Some of the font commands have
+ equivalents for math mode. If font_key() is called in math mode it
+ inserts the math version otherwise the text version of the command.
+
+ It provides all keys they where in the keymap before and the key p
+ that promps with completion for a font command.
+
+ + Renamed the variable label_ref_f to label_ref_filt to make it more
+ speaking. label_ref_filter is not possible, because a function with
+ this name extists.
+
+ + label_ref() rewritten. It is now only a simple switching tool to
+ select autoref if hyperref is used and ref else. The old semantic of
+ label_ref() is now in label_ref_hook()
+
+ + Changed the indentation and replaced error by throw in
+ label_ref_next(), label_ref_insert() and label_ref_filter()
+
+ + Added label_ref_hook() to be used as an hook of the new command
+ framework. The command \ref, \autoref, \pageref and \eqref are enabled.
+
+ + Improved the codes of insert_dollar() a little bit.
+
+ + Renamed math_watch() to math_hook() and changed it to make it usable as
+ a command hook.
+
+ + Removed the Math_Goto_Math array. This is now handled with the
+ command framework and math_hook() in a more generic way.
+
+ + Reduced math() and made use of the new command framework.
+
+ + Lage keymap changes. All code from Latex4Jed was remoded. I would now
+ call this keymap as the propsed new keymap.
+ - ^cp is insert_package() which asks for a package to insert
+
+ - ^cs is cmd_prompt() which asks for a command to insert
+
+ - ^cf is only enabled if LaTeX_Font_Key is defined (default: f). The
+ supcommands of ^cf are now handled by font().
+
+ - All ^cs and ^cp stuff used before was removed. The main part is now
+ available with cmd_prompt()
+
+ - Added ^clp for \pageref, ^clu for \url and ^cln for \nocite.
+
+ - Added ^cii for \index
+
+ - The math stuff before on ^cM moved to ^cn. This is more handy than
+ a big M.
+
+ - Now all the defined ^ck keys work.
+
+ - Added ^c\n (Return) as newline_with_completion() because
+ shift+alt+return do not work in all terminals.
+
+ + DFA:
+ - Reduced the rules of DFA to a minimal set. I will enable some of
+ them later.
+
+ - Now \begin, \end and the \documentclass line is highlighted as
+ preprocessor commands.
+
+ - Improved the number highlighting rule.
+
+ - Embedded math parts ($...$) isn't highlighted anymore. Only the $
+ signs are. Formulas across lines were not highlighted correctly
+ (the broken highlighting was a nightmare) and highlighting did not
+ improve the readability of formulas longer than two lines.
+
+ - For open quoted strings, e.g. no counterpart on the line, only the
+ three characters after or before the quoting sign are highlighted.
+ Highlighting across lines is not possible.
+
+ - Added a workaround for DFA highlighting of non-ascii charaters in
+ UTF-8 mode.
+
+* latex_cmd.sl:
+ + This file contains only simple statements. To not blow up latex.sl
+ this part was outsourced.
+
+------------------------------------------------------------------------
+r19 | joerg | 2006-05-31 00:43:54 +0200 (Mi, 31 Mai 2006) | 3 lines
+
+* latex_external.sl:
+ + simple code improvements
+
+------------------------------------------------------------------------
+r18 | joerg | 2006-05-26 01:05:11 +0200 (Fr, 26 Mai 2006) | 4 lines
+
+* latex_external.sl:
+ + Mistake in cust_select fixed. The name of the section of a new
+ configuration is new_conf.
+
+------------------------------------------------------------------------
+r17 | joerg | 2006-05-26 00:29:18 +0200 (Fr, 26 Mai 2006) | 97 lines
+
+* latex_comm.sl:
+ + This is a new file to implement a communication server like gnuserv
+ and emacsclient. It is written in pure SLang, e. g. no jed functions
+ are used.
+
+ + You can run this script with the argument "watch" to startup the
+ server part. Upon success to printes a line to standard out:
+ "communicator created: " and a special string appended that describes
+ the device to connect to the server. All data the serve receives it
+ prints to standout.
+
+ The second way you can invoke this script is with the communication
+ device given at server startup and a message. All remaining
+ parameters after the communication device are joined with spaces. The
+ special message "quit" terminates the server.
+
+ Here is an example:
+
+ Shell1% jed-script latex_comm.sl watch
+ communicator created: /tmp/jed.18338
+ I was here.
+ Another message.
+ quit
+
+ Shell2% jed-script latex_comm.sl /tmp/jed.18338 "I was here."
+ Shell2% jed-script latex_comm.sl /tmp/jed.18338 "Another message."
+ Shell2% jed-script latex_comm.sl /tmp/jed.18338 quit
+
+* latex_external.sl:
+ + Added LaTeX_Rerun and LaTeX_Post_Latex_Cmd as customization
+ variables.
+
+ LaTeX_Rerun is an boolean variable that indicates if the latex
+ command should be called again if the logfile contains the string
+ "Rerun to get cross-references right.", 1 = do it, 0 = don't do it.
+
+ LaTeX_Post_Latex_Cmd is the command that is run after a successful
+ run of the command LaTeX_Latex_Cmd. This is done self-acting.
+
+ + The additional customization variables are required changes on the
+ configuration framework:
+ - cust_type upgraded
+ - cust_set upgraded, e. g. the sixth parameter is now the post
+ processing command and the last parameter (11th) is rerun.
+ - all predefined configurations upgraded
+ - added a new configuration latex_ps that uses dvips and gv
+ - cust_view_insert upgraded
+
+ + xdvi must be started with the name of the dvi file %M.dvi not the
+ latex file %m. Fixed.
+
+ + Readjusted the exception types. For some of them UsageError seamed to
+ me a better choise.
+
+ + () appended to all references to functions. This makes more clear
+ what is referenced.
+
+ + Enhanced expand_and_run_cmd() to replace...
+ - %f by the filename of the current buffer
+ - %l by the line of the current buffer
+ - %c by the column of the current buffer
+ - %% by %
+ - % (% and a whitespace) by a whitespace that concatenates the
+ preceding and the following part to one parameter,
+ i.e. "echo foo% bar" is like echo "foo bar" in shell syntax
+
+ - The second parameter must now be a string or a reference.
+ References are passed to set_process(pid, "output", ) and strings
+ are used as buffer names where the output should go to.
+
+ - Now, the buffer is changed to the one given by the second argument
+ and the working directory is set to the one of the master file
+ before SLang commands (starting with @) are evaluated with eval().
+
+ + The keymap stuff is moved to the logfile section. There it belongs to.
+
+ + Now compose_sig_handl() can start commands by bringing them up in a
+ different buffer. This way it is possible to rerun latex and run a
+ post processing command.
+
+ + Installed a framework to interact with xdvi. Therefor a process
+ running the communication server latex_comm.sl is spawned and the
+ viewer is started.
+
+ All this happens iff the special escape sequence %e is found in the
+ LaTeX_View_Cmd. It is replaced by the command the the editor must run
+ to interact with jed.
+
+ Now you can press ^cv and xdvi opens and jumps to the position in the
+ dvi document the was generated from the line where you hit ^cv. And
+ you can click ctrl+button 1 in the xdvi document to move the cursor
+ in the editor to the line that corresponds to this position.
+
+ + Added a new configuration latex_srcspecl that calls latex with the
+ option -src-specials and xdvi with the corresponding arguments to
+ make use of these source specials.
+
+------------------------------------------------------------------------
+r16 | joerg | 2006-05-23 12:34:39 +0200 (Di, 23 Mai 2006) | 59 lines
+
+* latex_external.sl:
+ + converted the file to UTF-8
+
+ + removed LaTeX_Default_Output, it's superseded by the new cust_view()
+ stuff
+
+ + disabled LaTeX_Rerun; this and LaTeX_Post_Latex_Cmd are unsupported
+ till I found a way to start a process from the signal handler of a
+ process
+
+ + all LaTeX_* variables should be strings, e.g. != NULL; fixed the
+ defaults for Bibtex_Cmd and Index_Cmd
+
+ + added new stuff to quickly change the commands used in the build
+ process at runtime:
+ - now if you hit ^co you get a cool buffer where you can walk around
+ and select a configuration you want to use.
+
+ - In the TOC the space bar selects the mode in the line. In a section
+ the space bar selects the mode of this section.
+
+ - The enter key hit in the TOC jumps to the section of this config.
+ In a section the enter key presents the configuration point for
+ editing. (currently not implemented, use cust_set())
+
+ - You can add your own configurations or change one of the predefined
+ ones with latex_external->cust_set(name, desc, bibtex, index,
+ latex, clean, mrproper, print, view) with the following meanings:
+ name: Name of the configuration
+ desc: a description of this configuration
+ bibtex: the command run at ^cI
+ index: the command run at ^cx
+ latex: the command run at ^cc
+ clean: the command run at ^cr
+ mrproper: the command run at ^cR
+ print: the command run at Mode->Print
+ view: the command run at ^cv
+
+ You can use the placeholder %m to refer to the latex source file
+ and %M to refer to the latex source files without extension (i.e.
+ %M.dvi for the output)
+
+ - predefined configurations for latex, pdflatex and rubber
+
+* latex.sl:
+ + converted the file to UTF-8
+
+ + the search direction in insert_pkgs() was the wrong; fixed
+
+ + the argument env of set_nl_completion() must not be NULL; fixed
+
+ + set the key for latex_external->cust_view() to ^co and kicked
+ latex_customize ^cC -- don't know what this was
+
+ + kicked the menu entry "Customize Defaults" and "Select Output", added
+ "Customize Build"
+
+ + lower the access rights of setup_dfa_callback() to private
+
+------------------------------------------------------------------------
+r15 | joerg | 2006-05-12 16:27:46 +0200 (Fr, 12 Mai 2006) | 8 lines
+
+* latex.sl
+ + moved ldeln() into the tools section
+
+ + modified insert_pkgs() in that way it inserts the new packages _after_
+ the last package (not at the begin -- after \documentclass)
+
+ + added cases to the nl_completion array; it is handled like gather
+
+------------------------------------------------------------------------
+r14 | joerg | 2006-05-12 10:22:31 +0200 (Fr, 12 Mai 2006) | 2 lines
+
+* many changes
+
+------------------------------------------------------------------------
+r12 | joerg | 2006-04-13 13:48:22 +0200 (Do, 13 Apr 2006) | 5 lines
+
+debmode.sl
+* corrected the name in #ifexists test;
+
+* removed "mode: fold"
+
+------------------------------------------------------------------------
+r11 | joerg | 2006-04-12 17:58:05 +0200 (Mi, 12 Apr 2006) | 16 lines
+
+debmode.sl
+* set the access attributes of the function
+
+* before_save_hook():
+ + added some code to make the mode SLang1 compatible; in use the shell
+ command "822-date" to create the date string, because strftime() is
+ not available
+
+* added a keymap
+
+* added a function to insert the string "closes: #..."; key ^c^b
+
+* added a function to assist on writing mails to @bugs.debian.org.
+ Currently it does only insert a "Version:" field for messages to
+ XX-done@bugs.debian.org
+
+------------------------------------------------------------------------
+r10 | joerg | 2006-04-10 23:26:07 +0200 (Mo, 10 Apr 2006) | 3 lines
+
+* created a new mode to make editing of Debian changelog files and other
+ Debian maintenance stuff easier.
+
+------------------------------------------------------------------------
+r9 | joerg | 2006-03-21 18:40:05 +0100 (Di, 21 Mär 2006) | 38 lines
+
+[latex_external.sl]
+* Completely rewritten version to cleanup code and make it more SLang 2
+ conform.
+
+* removed "Cleanup_extensions"; use the new Latex_Cleanup_Cmd instead
+
+* Introduced a new scheme to specify external commands. Now the tokens
+ %m, %M and %o in the string get replaced by the name of the master
+ file, the name of the master file without extension or the output
+ format, respectively.
+
+ This way, it is possible to use rubber.
+
+* Dropped support for compressed files. I don't have such files and I
+ don't know how to handle them. Suggestions are welcome.
+
+* find_next()/goto_error_line() rewritten. Now, it parses the whole file
+ from the beginning to find the right file name. This has some nice side
+ effects -- you can hit enter after an opening brace to jump to this
+ file --, but at the main task nothing changed.
+
+ Added support for "Info" messages.
+
+* pop_to_log_file() now opens the .log file. Due this you see more
+ informations and can open the log without running latex.
+
+* Now all commands (bibtex, latex, cleanup) run in background. This way
+ you can still edit the code while the command is running. The
+ technology is not perfect, but it should work in the main cases.
+
+ The output of the command goes to /dev/null, a buffer or get shown in
+ the minibuffer.
+
+* Crude support for bibtex and makeindex exist, but make suggestions.
+
+* Added a new cleanup method "mrproper" to remove all files, except the
+ source files.
+
+------------------------------------------------------------------------
+r8 | joerg | 2005-09-03 01:57:01 +0200 (Sa, 03 Sep 2005) | 8 lines
+
+* added keyword Id to latex.sl and latex_external.sl to makte it later
+ easier to get a diff between the last relased and the current version
+
+* renamed the mode to JLM joerg's latex mode to distinguish between
+ Guido's Latex4Jed
+
+* added $id$ to both latex files
+
+------------------------------------------------------------------------
+r7 | joerg | 2005-09-03 00:44:32 +0200 (Sa, 03 Sep 2005) | 55 lines
+
+* latex_external.sl
+ + goto_error_line()
+ - package warnings may have their line number in the second line; added
+ code to handle this case
+
+ - the message for errors might be clipped; added code to handle this
+ case to find the right column of the error position
+
+ + removed many leading whitespaces in the code
+
+* latex.sl
+ + removed definition of Key_Return. It is now taken from x-keydefs
+
+ + removed require("texquote"...); we have our own function for this
+
+ + insert_quote() now detects the form of quotes, by the existence of
+ the package german or ngerman; LaTeX_German_Quote removed
+
+ + replaced many insert_char(LAST_CHAR) by call("self_insert_cmd") to
+ make abbreviation work better with latex_mode. Before characters like
+ => or $ do not trigger abbreviation.
+
+ + added a new trim function that respects the sequence '\ ' what the
+ jed function trim not do.
+
+ + added a new function insert_label_at_mark() which saves the current
+ position on the first call and inserts a new label on the second call,
+ jumps back to the saved position and insert a \ref to the label there.
+
+ This should be very handy if you want to insert a reference on a
+ point where you must set a label before. Key: ^Clm
+
+ + added = to the math_array. This makes ^Cm= is expanded to \not=.
+
+ + the newline_indent_hook() and newline_with_completion() now trim()s
+ the line before it insert a newline. This helps reducing leading
+ whitespaces.
+
+ + added a missing pop() in wrap_hook() which caused a fast growing stack
+
+ + rewrote linsert() to place the cursor behind the inserted text, if a
+ region was surrounded be the linsert().
+
+ + fixed a tricky issue with abbreviation and insert_dollar(). The mark
+ to the return point must be set after the $ is inserted, because the
+ $ may trigger an abreviation which moves the mark. The result was,
+ the cursor was placed not after the $ when insert $ after an
+ abbreviation. e.g. abbr = XY -> (X,Y), insert $XY$. The cursor was
+ between $$ and not after.
+
+ + fixed a stack filler in insert_dollar()
+
+ + changed the highlighting rule for comments and embedded formulas ($$)
+ to not highlight leading whitespaces
+
+------------------------------------------------------------------------
+r6 | joerg | 2005-08-16 21:00:00 +0200 (Di, 16 Aug 2005) | 83 lines
+
+* lates.sl:
+ + removed all trailing whitespaces
+
+ + removed _debug_info, _traceback, _slangtrace; they should not be set
+ global; a user should set them in its .jedrc
+
+ + switched from keydefs to x-keydefs to have Key_Shift_Return
+
+ + removed tex_blink_dollar; we have it rewritten some times ago
+
+ + new helper function is_comment(); replaced all occurences of parsing
+ for comments with this function
+
+ + new helper function have_package()
+
+ + calc_indention() and newline_with_completion() now support tabularx
+
+ + insert_limits_char():
+ - make the auto completed text is highlighted
+
+ - replace line feed with white space in auto completed text
+
+ + the keys for \textnormal and \underline produced a backslash to much
+
+ + env_insert():
+ - if a math environment with number (name without star) is inserted a
+ label is automaticle added
+
+ - now indents environments around marked text correctly
+
+ - do not move the current line in the new environment anymore, this
+ was a workaround caused by missing mark support
+
+ + removed all occurences of equation; we don't support it any more,
+ because it causes much trouble and gather is the same (without the
+ trouble) <news:d98lqm$qcs$1@news.BelWue.DE>
+
+ + insert_dollar():
+ - start searching for dollars at the begin of the environment,
+ because there can't be open dollars across environment boundaries;
+ speed gain
+
+ - respects BLINK
+
+ + math():
+ - added a new array Math_Goto_Math which indicates for which keys the
+ cursor should be placed inside the math environment after insert;
+ This makes it easier to type $\phi\in S(\R^{n})$.
+
+ + label_insert()
+ - fix misspelling of subsubsection
+
+ - now only eqref and autoref are supported if the relevant packages
+ are present; note: autoref is precedented
+
+ + ldots()
+ - use also + and - as seperator before ...
+
+ - now take the whole word (inclusive backslash) before the limit
+ character (i.e. "\alpha_1 ..." works)
+
+ + removed key ^C^C for latex_customize, because it is used by
+ latex_external->compose
+
+ + dfa highlighting
+ - add a rule for trailing whitespaces
+
+ - make trailing whitespaces are visible in comments
+
+* yankpop-2.0.sl to yankpop.sl renamed
+
+* latex_external.sl
+ + Package warnings may look different as expected; the line numer may
+ be in the same line as the warning
+
+ + added a note on ^Cy to the output of compose message
+
+* latex-templ added
+
+------------------------------------------------------------------------
+r5 | joerg | 2005-06-09 00:51:33 +0200 (Do, 09 Jun 2005) | 14 lines
+
+* latex.sl
+ + added fontenc with T1 to the default packages
+
+* latex_external.sl
+ + replaced key ^M with \n in definekey() for latex output buffer
+
+ + added key \r with the same meaning as \n to latex output buffer
+
+------------------------------------------------------------------------
+r4 | joerg | 2005-05-24 11:07:23 +0200 (Di, 24 Mai 2005) | 3 lines
+
+* debug message in goto_error_line() removed
+* insert_limits_char() has left value on stack; fixed
+
+------------------------------------------------------------------------
+r2 | joerg | 2005-05-21 13:14:00 +0200 (Sa, 21 Mai 2005) | 4 lines
+
+* "LaTeX Warning:" can be longer than a line which makes ffind("line ")
+ fail. Solved with a new way to find the line number
+* If a line break is in the line number, it is not correctly parsed.
+
+------------------------------------------------------------------------
+r1 | joerg | 2005-05-20 21:41:51 +0200 (Fr, 20 Mai 2005) | 3 lines
+
+* imported the current versions of latex and yankpop mode
+
+------------------------------------------------------------------------
diff --git a/support/jed/jlm/doc/jlm-vortrag.latex b/support/jed/jlm/doc/jlm-vortrag.latex
new file mode 100644
index 0000000000..e8c89942b8
--- /dev/null
+++ b/support/jed/jlm/doc/jlm-vortrag.latex
@@ -0,0 +1,207 @@
+\documentclass[titlepage,25pt,Screen4to3]{foils}
+
+\usepackage{soul}
+\usepackage[margin=8mm,bottom=20mm]{geometry}
+\usepackage[bookmarks,bookmarksnumbered,pagebackref,draft=false]{hyperref}
+% \usepackage[display]{texpower}
+\usepackage{ngerman}
+
+\usepackage[utf8]{inputenc}
+\usepackage{lmodern}
+\usepackage[T1]{fontenc}
+\usepackage{textcomp}
+
+\usepackage{ellipsis}
+\usepackage{fixltx2e}
+\usepackage[final]{microtype}
+\usepackage{paralist}
+\usepackage{fancyvrb}
+\usepackage{amssymb}
+
+% \backgroundstyle[stripes=25]{vgradient}
+
+% \pagestyle{empty}
+% \addtolength{\textheight}{\headheight +\headsep +\footskip +.3in}
+% \setlength{\headheight}{0pt}
+% \setlength{\headsep}{0pt}
+% \setlength{\footskip}{0pt}
+% \setlength{\foilheadskip}{-.2in}
+
+\newcommand*{\todo}[1]{\textcolor{red}{todo: #1}}
+\fvset{fontsize=\footnotesize}
+
+\MyLogo{-- Written with Joergs\LaTeX{}Mode -- Typeset by Foil\TeX{} --}
+
+\begin{document}
+
+\title{Joergs\LaTeX{}Mode heute zu Gast bei der
+ \href{http://www.lug-jena.de}{LUG Jena}}
+\author{Jörg Sommer}
+\date{29.\,Juni 2006}
+\maketitle
+
+\foilhead{Jed}
+
+\begin{itemize}
+ \item Emacs-Clone, es existiert auch Vi-Mode
+ \item aktuelle stabile Version 0.99.18
+ \item verwendet SLang als Skriptsprache
+ \item Jed ist „Referenzanwendung“ für SLang
+ \item beides von John E.\,Davis
+ \item \url{http://www.jedsoft.org/jed/}
+\end{itemize}
+
+\foilhead{Joergs\LaTeX{}Mode -- JLM}
+
+\begin{itemize}
+ \item aufbauend auf Jed und SLang; nur mit SLang 2; \textit{sollte} auch
+ unter Windows funktionieren
+ \item entstanden aus Guido Gonzatos \LaTeX{}4Jed
+ \item seit 2003 als eigenes Projekt
+ \item am Anfang war \verb|math_matharrow()|
+ \item aktuelle Version unter
+ {\small\url{http://www.minet.uni-jena.de/~joergs/jed/}}
+ \item Entwicklung ist noch nicht fertig -- a never ending story
+ \item ca.\,5000 lines of code (viel Konfiguration)
+\end{itemize}
+
+\foilhead{Installation}
+
+\begin{itemize}
+ \item benötigt zus. \texttt{x-keydefs.sl} von
+ {\small\url{http://jedmodes.sf.net/mode/x-keydefs/}}
+ \item alle Dateien am Besten in ein eigenes Verzeichnis legen
+ \begin{Verbatim}[gobble=2]
+ % mkdir ~/.jed; cd ~/.jed; base=http://www.minet.uni-jena.de/~joergs/jed
+ % wget -r -np $base/latex_external.sl $base/latex_cmds.sl $base/latex.sl \
+ $base/latex_comm.sl $base/latex-templ $base/read_with_description.sl
+ % wget http://jedmodes.cvs.sourceforge.net/*checkout*/jedmodes/mode \
+ /x-keydefs/x-keydefs.sl?view=checkout&revision=HEAD
+ \end{Verbatim}
+ \item \verb|~/.jedrc| bearbeiten
+ \begin{Verbatim}[gobble=2]
+ variable Jed_Home_Directory = "/home/joerg/.jed";
+ add_mode_for_extension("latex", "tex");
+ add_mode_for_extension("latex", "latex");
+ set_jed_library_path("/home/joerg/.jed/," + get_jed_library_path());
+ Jed_Highlight_Cache_Dir = "/home/joerg/.jed/dfa/";
+ enable_dfa_syntax_for_mode("LaTeX"); % das etwas andere Syntaxhighlighting
+ \end{Verbatim}
+\end{itemize}
+
+\foilhead{Ein neues Dokument}
+
+\begin{itemize}
+ \item \texttt{MenĂĽ$\rightarrow$Mode$\rightarrow$Templates} oder
+ \verb|^Ct| alle Dateien aus \verb|~/.jed/latex-templ/|
+ \item zusätzlich dazu die Pakete aus \verb|LaTeX_Default_Packages|
+ (getrennt mit Doppelpunkt), wenn Datei leer
+ \item bekannte Befehle und Umgebungen fĂĽgen automatisch Pakete hinzu,\\
+ z.\,B. \verb|\includegraphics{}| oder \verb|Verbatim|
+ \item Dokumententeilung; Hauptdatei mit \verb|^Ca| festlegen
+\end{itemize}
+
+\foilhead{Bedienung per Tastatur}
+
+\begin{itemize}
+ % \item Bedienung erfolgt ĂĽber Tastatur. (Fast) Alle Tasten beginnen mit
+ % \verb|^C|
+ \item Umgebungen: \verb|^Ce|, \texttt{e/Return} neue Umgebung,
+ \texttt{r} umbenennen, \texttt{c} schlieĂźen.
+ \item Befehle: \verb|^Cs|
+ \item Schrift: \verb|^Cf|, \texttt{+/-} skalieren, \texttt{t}
+ \verb|\texttt|, \texttt{k} \verb|\mathfrak{}|, \texttt{p} Umgebungen
+ \item Label: \verb|^Cl|, \texttt{b} \verb|\bibcite|, \texttt{l} \verb|\label|,
+ \texttt{r} \verb|\ref|, \texttt{u} \verb|\url|
+ \item Hilfe: \verb|^Ch|, \texttt{s} \verb|texdoc symbols|, \texttt{t/T}
+ \verb|texdoc -l/-s|
+ \item Mathematik: \verb|^Cm| und \verb|^Cn|
+ \item Pakete: \verb|^Cp|
+\end{itemize}
+
+\foilhead{automatischer Mathmode}
+
+\begin{itemize}
+ \item Mathematikbefehle automatisch in \verb|$$| „Für $\alpha\wedge\beta$ gilt“
+ \item \verb|_| und \verb|^| schalten in Mathmode $a_{i}$ oder springt
+ zurĂĽck $\beta^{2}$
+ \item \verb|_| und \verb|^| verändern den Befehl: \verb|$\cap$| $\rightarrow$
+ \verb|$\bigcap_{}$|
+ \item \verb|_| und \verb|^| schlagen alten Wert vor $\sum_{n=1}^{\infty}
+ \ldots = \sum_{n=1}^{\infty} \ldots $
+ \item 3 Punkte durch \verb|\ldots| ersetzt; im Mathmode raten, was sich wiederholt
+ \item \verb|^Cma_1<rechts>,...n|\quad ergibt\quad $\alpha_{1},\ldots,\alpha_{n}$
+ \item nach $\in$ und $\subset$ Cursor im Mathmode; ) springt hinter \}
+ und nimmt \verb|\big| mit
+\end{itemize}
+
+\foilhead{automatische Pfeile}
+
+\begin{itemize}
+ \item \verb|->| wird zu \verb|$\rightarrow$|
+ \item \verb|<->| wird zu \verb|$\leftrightarrow$|
+ \item \verb|<=| wird zu \verb|$\Leftarrow$|
+ \item \verb|<==>| wird zu \verb|$\Longleftrightarrow$|
+ \item \verb+|->+ wird zu \verb|$\mapsto$|
+ \item und sämtliche gültige Variationen der Pfeillinien
+ \item \verb|>>| wird zu \verb|$\gg$| und \verb|<<| zu \verb|$\ll$|
+\end{itemize}
+
+\foilhead{Magisches Return -- \texttt{Shift+Return}/
+ \texttt{\textasciicircum{}C+Return}}
+
+\begin{itemize}
+ \item z.\,B. in \texttt{itemize}-, \texttt{enumerate}- und
+ \texttt{description}-Umgebung neues \verb|\item|,\\
+ in tabular wird eine Zeile \verb|---| durch \verb|\hline| ersetzt oder \verb|\\| eingefĂĽgt
+ \item Steuerbar ĂĽber die Funktion \verb|latex->set_nl_completion|,\\
+ Argumente: \textit{Umgebung}, \textit{letzte Zeile}, \textit{neue Zeile}
+ \item z.\,B.
+ {\small\verb|latex->set_nl_completion("thebibliography", "", "\\bibitem{}")|}
+ oder {\small\verb|latex->set_nl_completion("my_list", "\n", "\\item")|}
+\end{itemize}
+
+\foilhead{Ăśbersetzen, Anzeigen, Index erzeugen, \ldots}
+
+\begin{itemize}
+ \item Ăśbersetzen \verb|^Cc|, Ausgabe anzeigen \verb|^Cv|, Log anzeigen
+ \verb|^Cy|, Index erzeugen \verb|^Cx|, löschen \verb|^Cr|, alles
+ löschen \verb|^CR|
+ \item Übersetzen passiert im Hintergrund -- gefährlich springender Cursor
+ \item gesteuert ĂĽber Variablen \verb|LaTeX_*_Cmd| mit $\mathtt{*}\in\{
+ \mathtt{Bibtex,~Index,~Latex,}\\ \mathtt{Cleanup,~Mrproper,~Print,~View}\}$
+ \item Konfiguration auswählbar mir \verb|^Co|; rubber für dvi, ps und
+ pdf, latex, pdflatex und latex mit Sourcespecials
+ \item Sourcespecials echt praktisch! irgendwo im Dokument
+ \verb|^Cv| und xdvi ist an der richtigen\texttrademark{} Stelle,
+ \verb|Strg+linke Maustaste| Jed ist an der richtigen\texttrademark{} Stelle
+\end{itemize}
+
+\foilhead{Sonstiges}
+
+\begin{itemize}
+ \item Navigieren in der Log-Datei: \texttt{w/W} nächste/letzte
+ Warnung, \texttt{b/B} n/l Box, \texttt{e/E} n/l Fehler,
+ \texttt{n/N} n/l Meldung, \texttt{Return/g} sprint zur Fehlerzeile
+ \item automatisches EinrĂĽcken
+ \item Leerzeichen am Ende von Zeilen werden automatisch weggeräumt
+ \item bei nicht-UTF-8 werden die AnfĂĽhrungszeichen automatisch gesetzt;
+ wenn \texttt{ngerman} oder \texttt{german} eingebunden dann auch die
+ deutschen
+ \item MenĂĽ und Benutzeranpassungen schlecht
+ \item Highlighting in Jed nicht so einfach
+ \item Beim Laden werden automatisch die bekannten Umgebungen aktualisiert
+\end{itemize}
+
+\foilhead{Aufruf}
+
+\begin{center}
+ \huge
+ \vfill
+ Tester gesucht\\
+ \vfill
+ Kommentare und Vorschläge erwünscht
+ \vfill\null\vfill
+\end{center}
+
+\end{document}
diff --git a/support/jed/jlm/doc/jlm-vortrag.pdf b/support/jed/jlm/doc/jlm-vortrag.pdf
new file mode 100644
index 0000000000..0d1a88a703
--- /dev/null
+++ b/support/jed/jlm/doc/jlm-vortrag.pdf
Binary files differ
diff --git a/support/jed/jlm/doc/jlm.pdf b/support/jed/jlm/doc/jlm.pdf
new file mode 100644
index 0000000000..e613b14b0a
--- /dev/null
+++ b/support/jed/jlm/doc/jlm.pdf
Binary files differ
diff --git a/support/jed/jlm/doc/jlm.tex b/support/jed/jlm/doc/jlm.tex
new file mode 100644
index 0000000000..7b0fdeab63
--- /dev/null
+++ b/support/jed/jlm/doc/jlm.tex
@@ -0,0 +1,801 @@
+\IfFileExists{nag.sty}{\RequirePackage[l2tabu,orthodox]{nag}}{}
+
+\documentclass[draft,english]{scrreprt}
+
+\usepackage[utf8]{inputenc}
+\usepackage{lmodern}
+\usepackage[T1]{fontenc}
+\usepackage{textcomp}
+
+\usepackage[ngerman,english]{babel}
+
+\usepackage{fixltx2e}
+\usepackage[draft=false]{microtype}
+\usepackage{paralist}
+\usepackage{color}
+\usepackage[draft=false,colorlinks,urlcolor=blue]{hyperref}
+\usepackage{svn}
+\usepackage{array}
+\usepackage{fancyvrb}
+\usepackage{dtklogos}
+
+\newcommand*{\file}[1]{\nolinkurl{#1}}
+\newcommand*{\func}[1]{\textsf{#1()}}
+\newcommand*{\var}[1]{\textsf{#1}}
+\newcommand*{\key}[1]{\texttt{#1}}
+\newcommand*{\ctrlkey}[1]{\key{\^{}#1}%
+ \texorpdfstring{%
+ \ifnum`#1=\lccode`#1%
+ \PackageWarning{document}{Kleinbuchstaben #1 fuer ctrlkey verwendet}%
+ \fi}{}}
+\newcommand*{\metakey}{\key{ESC\,}}
+\newcommand*{\reskey}{\ctrlkey{C}}
+\newcommand*{\subseckey}{}
+\newcommand*{\keyseq}[1]{\key{\reskey\subseckey#1}}
+
+\newcommand*{\texstring}[1]{\texttt{#1}}
+\newcommand*{\texcmd}[1]{\texstring{\textbackslash{}#1}}
+
+\newcommand*{\editpoint}{\textbullet}
+
+\newcommand*{\help}[1]{\textcolor{green}{help: #1}}
+\newcommand*{\todo}[1]{\textcolor{red}{todo: #1}}
+
+\newlength{\mywidth}
+\newcommand*{\babelHyphExample}[2]{\settowidth{\mywidth}{#1}%
+ \addtolength{\mywidth}{3.65pt}% width of hyphen sign
+ \addtolength{\mywidth}{-\linewidth}%
+ \par\noindent\rule{-\mywidth}{.3mm}\hspace{0pt}#2}
+
+\SVN $LastChangedRevision: 189 $
+\SVN $LastChangedDate: 2007-08-05 18:57:13 +0200 (So, 05 Aug 2007) $
+
+\begin{document}
+
+\title{JLM---Jörg's \LaTeX{} Mode}
+\author{Jörg Sommer
+ \href{mailto:joerg@alea.gnuu.de}{\nolinkurl{<joerg@alea.gnuu.de>}} }
+\date{\SVNDate}
+\maketitle
+
+\begin{abstract}
+ JLM is an advanced \LaTeX{} mode for Jed. Its aim is to help the user by
+ taking over annoying and stupid things they need to be done, like add a
+ \texcmd{usepackage} when you add a command or environment from this package
+ or put dollar signs around mathematical commands and move the cursor to an
+ appropriate point.
+
+ JLM does not think for you. If you want a \texstring{tabular}, but insert an
+ \texstring{itemize}, JLM doesn't prevent this. So, you should be familiar
+ with \LaTeX{} and know what environments and commands are and where to place
+ them in a document---JLM helps writing them.
+\end{abstract}
+
+\tableofcontents
+% \listoftables
+% \listoffigures
+
+\chapter{Installation}
+\section{\ldots{} on Unix-like systems}
+
+Obviously, you need Jed. You can download the current version from
+\url{http://www.jedsoft.org/jed/download.html}, but it is also part of many
+distributions. You need at least version 0.99.18 with SLang~2 support (run
+\verb+jed --version+ to check it).
+
+\begin{enumerate}
+ \setcounter{enumi}{-1}
+ \item Download the archive \file{jjm-rXYZ.tgz}, where XYZ is the version
+ usually the highest available, from
+ \url{http://www.minet.uni-jena.de/~joergs/}.
+
+ \item Create a directory \file{.jed/} in your home directory, if it doesn't
+ exist, and save there the files from the archive. Save in the same directory
+ the file \file{x-keydefs.sl} from
+ \url{http://jedmodes.sf.net/mode/x-keydefs/}---use
+ \url{http://jedmodes.cvs.sourceforge.net/*checkout*/jedmodes/mode/x-keydefs/x-keydefs.sl?view=checkout&revision=HEAD}.
+
+ \item Depending on your system, Jed loads the file \file{~/.jedrc} or
+ \file{~/.jed/jed.rc} (on Debian) as your configuration file. You can copy
+ the whole file \file{.jed/doc/latex-jed.rc} to this location or copy only
+ parts from \file{latex-jed.rc} into your \file{jed.rc}.
+
+ Important are only these lines to tell Jed where he can find JLM and that he
+ should use it for files with the extention \file{.tex} or \file{.latex}.
+ \begin{Verbatim}[gobble=2,fontsize=\small,frame=lines]
+ Jed_Home_Directory = path_concat(getenv("HOME"), ".jed");
+ set_jed_library_path(Jed_Home_Directory + "," + get_jed_library_path());
+ Jed_Highlight_Cache_Dir = path_concat(Jed_Home_Directory, "dfa");
+
+ add_mode_for_extension("latex", "tex");
+ add_mode_for_extension("latex", "latex");
+ \end{Verbatim}
+ (On Debian the first three lines aren't needed.)
+\end{enumerate}
+
+Now you can open a \LaTeX{} file and start using JLM. Have fun.
+
+\section{\ldots{} on Windows}
+
+Obviously, you need Jed. You can download it from
+\url{http://www.paneura.com/~dino/wjed.html}.
+
+\begin{enumerate}
+ \setcounter{enumi}{-1}
+ \item Download the archive \file{jjm-rXYZ.tgz}, where XYZ is the version
+ usually the highest available, from
+ \url{http://www.minet.uni-jena.de/~joergs/}.
+
+ \item Create a directory \file{C:\Dokumente und
+ Einstellungen\USERNAME\Anwendungsdaten\jed} \help{Where are the
+ spaces in this URL?} in your home directory, if it doesn't
+ exist, and save there the files from the archive. Save in the same directory
+ the file \file{x-keydefs.sl} from
+ \url{http://jedmodes.sf.net/mode/x-keydefs/}---use
+ \url{http://jedmodes.cvs.sourceforge.net/*checkout*/jedmodes/mode/x-keydefs/x-keydefs.sl?view=checkout&revision=HEAD}.
+
+ \item Jed loads the file
+ \file{C:\Dokumente und Einstellungen\USERNAME\jed.rc}. \help{Where are the
+ spaces in this URL?} You can copy the
+ whole file \file{doc/latex-jed.rc} from the archive to this location or copy
+ only parts from \file{latex-jed.rc} into your \file{jed.rc}.
+
+ Important are only these lines to tell Jed where he can find JLM and that he
+ should use it for files with the extention \file{.tex} or \file{.latex}.
+ \begin{Verbatim}[gobble=2,fontsize=\small,frame=lines]
+ Jed_Home_Directory = path_concat(getenv("APPDATA"), "jed");
+ set_jed_library_path(Jed_Home_Directory + "," + get_jed_library_path());
+ Jed_Highlight_Cache_Dir = path_concat(Jed_Home_Directory, "dfa");
+
+ add_mode_for_extension("latex", "tex");
+ add_mode_for_extension("latex", "latex");
+ \end{Verbatim}
+\end{enumerate}
+
+Now you can open a \LaTeX{} file and start using JLM. Have fun.
+
+\chapter{\TeX{} environments---\func{env\_insert}}
+
+\chapter{\texstring{array} like environments}
+
+Environments they are organised in columns \texstring{table},
+\texstring{array} or \texstring{cases}.
+
+\chapter{\TeX{} commands---\func{cmd\_insert}}\label{sec:cmds}
+
+The function \func{cmd\_insert} is an important function of the mode. It is
+used for inserting \TeX{} commands like \texcmd{LaTeX} or \texcmd{frac}. With
+a database (created with \func{cmd\_add}) it decides whether a command is a
+math command and how much mandatory arguments it has. If a command must be in
+math mode, e.\,g. \texcmd{frac}, it inserts dollar signs \$ around the
+command.
+
+The prefix of the command (\func{prefix\_argument}) determines the number of
+optional arguments, e.\,g. the exponent of \texcmd{sqrt}.
+
+Many commands are predefined in \file{latex_cmds.sl}.
+
+\todo{packages needed by the command are inserted}
+
+\chapter{Math stuff}
+\section{In text formulas \$\ldots\$}\label{sec:dollar}
+
+If a command is inserted via \func{cmd\_insert} and it is known that this is a
+math command, it is automaticly placed inside \$\ldots\$. See \autoref{sec:cmds}.
+
+If you insert a dollar sign manually and a backslash is before the editing
+point or the dollar sign is a begin of an in text formula, nothing happens. If
+the dollar sign is the end of an in text formula, something more happens:
+\begin{itemize}
+ \item If the variable \var{BLINK} is non-zero the editing point jumps to the
+ begin of the text formula for a short period or until the next key is
+ pressed.
+ \item All open brackets [, \{ and ( in the formula are closed before the
+ dollar sign is inserted or all closing brackets in front of the editing
+ point matching an open bracket are skipped before the dollar sign is
+ inserted. A dollar sign at the point where it should be inserted is skipped
+ and nothing is inserted.
+
+ Some examples:
+ \begin{itemize}
+ \item \$\texcmd{frac}\{1\}\{2\}\editpoint \quad $\rightarrow$\quad
+ \$\texcmd{frac}\{1\}\{2\}\$\editpoint
+ \item \$\texcmd{frac}\{1\}\{2\editpoint \quad $\rightarrow$\quad
+ \$\texcmd{frac}\{1\}\{2\}\$\editpoint
+ \item \$(\texcmd{\{}\texcmd{frac}\{1\}\{2\editpoint \quad $\rightarrow$\quad
+ \$(\texcmd{\{}\texcmd{frac}\{1\}\{2\}\texcmd{\}})\$\editpoint
+ \item \$\texcmd{frac}\{1\}\{2\editpoint\}\$ \quad $\rightarrow$\quad
+ \$\texcmd{frac}\{1\}\{2\}\$\editpoint
+ \end{itemize}
+\end{itemize}
+
+\section{Active characters after math commands}
+
+Some commands defined in \file{latex_cmds.sl} run a hook after insertion. If
+you press one of the characters “=-+<>” after you inserted one these commands
+the editing point is moved before the dollar sign and the character is
+inserted there. All greek letters have this hook.
+
+Example: You want to write “$\alpha$ is the upper angle in a triangle and
+$\alpha+\beta=\gamma$.” Simply type it. Use the math key for the greek
+characters, e.\,g. \key{\reskey ma} for \texstring{\$\texcmd{alpha}\$}. After
+the first \texcmd{alpha} the editing point is after the dollar sign
+(\$\texcmd{alpha}\$\editpoint). There you can type \help{weiterschreiben}.
+After the next \texcmd{alpha} you have the same situation. Press the plus sign
+and you get this: \$\texcmd{alpha}+\editpoint\$. Type on til the
+\texcmd{gamma}. There you must use the right key or use the dollar sign magic
+\autoref{sec:dollar}.
+
+\chapter{Folding}
+\label{cha:folding}
+
+JLM supports folding.
+
+\begin{table}
+ \begin{tabular}{|@{\hspace{1mm}}l}
+ \ttfamily
+ \texcmd{documentclass\{\ldots{}\}}\\
+ \quad%
+ \begin{tabular}{|@{\hspace{1mm}}l}
+ \texcmd{usepackage\{\ldots{}\}}
+ \end{tabular}\\
+ \texcmd{begin\{document\}}\\
+ \quad%
+ \begin{tabular}{|@{\hspace{1mm}}l}
+ \ldots{}\\
+ \texcmd{begin\{\ldots{}\}}\\
+ \quad%
+ \begin{tabular}{|@{\hspace{1mm}}l}
+ \ldots{}\\
+ \texcmd{begin\{\ldots{}\}}\\
+ \quad%
+ \begin{tabular}{|@{\hspace{1mm}}l}
+ \ldots{}
+ \end{tabular}\\
+ \texcmd{end\{\ldots{}\}}\\
+ \ldots{}\\
+ \end{tabular}\\
+ \texcmd{end\{\ldots{}\}}\\
+ \ldots{}\\
+ \texcmd{chapter\{\ldots{}\}}\\
+ \quad%
+ \begin{tabular}{|@{\hspace{1mm}}l}
+ \ldots{}\\
+ \texcmd{section\{\ldots{}\}}\\
+ \quad%
+ \begin{tabular}{|@{\hspace{1mm}}l}
+ \ldots{}\\
+ \texcmd{subsection\{\ldots{}\}}\\
+ \quad%
+ \begin{tabular}{|@{\hspace{1mm}}l}
+ \ldots{}\\
+ \texcmd{subsubsection\{\ldots{}\}}\\
+ \quad%
+ \begin{tabular}{|@{\hspace{1mm}}l}
+ \ldots{}\\
+ \end{tabular}\\
+ \texcmd{subsubsection\{\ldots{}\}}\\
+ \quad%
+ \begin{tabular}{|@{\hspace{1mm}}l}
+ \ldots{}\\
+ \end{tabular}\\
+ \end{tabular}\\
+ \texcmd{subsection\{\ldots{}\}}\\
+ \quad%
+ \begin{tabular}{|@{\hspace{1mm}}l}
+ \ldots{}
+ \end{tabular}
+ \end{tabular}\\
+ \end{tabular}\\
+ \texcmd{chapter\{\ldots{}\}}
+ \end{tabular}\\
+ \texcmd{end\{document\}}\\
+ \makebox[1em][l]{0}\makebox[1em][l]{|1}\makebox[1em][l]{|2}%
+ \makebox[1em][l]{|3}\makebox[1em][l]{|4}\makebox[1em][l]{|5}
+ \end{tabular}
+\end{table}
+
+\chapter{Babel}
+\section{Hyphenation}
+Compound words are common in german. But compounding words with a dash
+(\texttt{-}) has some drawbacks: You loose automatic hyphenation or get bad
+hyphen points; see \autoref{fig:hypen-examples} The package \textsf{babel}
+provides commands to circumvent these problems, but they are difficult to type
+in---they start with a \texstring{\dq} which is bound to quotation mark function
+\todo{add link to this section}---and you must remember that you have to use
+them.
+
+JLM takes care of this and replaces the dash by an suitable command. A dash
+followed by a dollar sign or alphabetical character starts the functions and
+it watches out for alphabetical characters, a slash or a closing brace. So you
+can cancel the operation by moving the editing point or enter a number.
+
+The functions counts the characters on the left side and on the right side. If
+they are more than an internal set threshold the dash is replaced. If on the
+left side are fewer characters than the threshold the dash is replaced by
+\texstring{\dq\~} otherwise by \texstring{\dq=}. If a shash or an closing
+brace follows the dash, it is replaced by \texttt{\dq\~} and \texttt{\dq\dq}
+is written after the slash or brace, respectively.
+
+Some examples:
+\begin{itemize}
+ \item \texstring{primitiv-rekursiv} becomes \texstring{primitiv\dq=rekursiv}
+
+ \item \texstring{t-produktiv} becomes \texstring{t\dq\~{}produktiv}
+
+ \item \texstring{$\alpha$-Teilchen} becomes \texstring{$\alpha$\dq\~{}Teilchen}
+
+ \item \texstring{Ein-/Ausgabe} becomes \texstring{Ein\dq\~{}/\dq\dq{}Ausgabe}
+
+ \item \texstring{(Haupt-)Aufgabe} becomes \texstring{(Haupt\dq\~{})\dq\dq{}Aufgabe}
+\end{itemize}
+
+\begin{figure}
+ \centering
+ \selectlanguage{ngerman}
+ \microtypesetup{protrusion=false} % disable font protrusion, because it
+ % changes the hyphenation
+ \begin{tabular}{*{2}{p{.4\linewidth}@{}|}}
+ \multicolumn{1}{c@{}}{\underline{bad hyphenation}}&
+ \multicolumn{1}{c@{}}{\underline{good hyphenation}}\\
+ % \babelHyphExample{$C$-Vektor}{$C$-Vektorraum}&
+ % \babelHyphExample{$C$-Vektor}{$C$"=Vektorraum}\\
+ \babelHyphExample{HI}{HI-Virus}&
+ \babelHyphExample{HI}{HI"~Virus}\\
+
+ \babelHyphExample{bergauf und }{bergauf und -ab}&
+ \babelHyphExample{bergauf und}{bergauf und "~ab}\\
+
+ \babelHyphExample{primitiv-rekur}{primitiv-rekursiv}&
+ \babelHyphExample{primitiv-rekur}{primitiv"=rekursiv}\\
+
+ \babelHyphExample{Motor}{Motorrad-Handbuch}&
+ \babelHyphExample{Motor}{Motorrad"=Handbuch}\\
+
+ \babelHyphExample{Ein}{Ein-/Ausgabe}&
+ \babelHyphExample{Ein/}{Ein"~/""Ausgabe}\\
+
+ \babelHyphExample{(Haupt}{(Haupt-)Stromkreis}&
+ \babelHyphExample{(Haupt)}{(Haupt"~)""Stromkreis}
+ \end{tabular}
+ \microtypesetup{protrusion=true}
+ \selectlanguage{english}
+ \caption{Examples of good and bad hyphenation of compound words in german
+ caused by using a simple dash}
+ \label{fig:hypen-examples}
+\end{figure}
+
+\chapter{Keys}
+
+% This documentation assumes that the variable
+% `_Reserved_Key_Prefix' == "^C".
+% This is the default in Jed's "emacs" emulation.
+%
+% The "CUA" emulation sets it to "^E", so, e.g., a keybinding "^Ce<"
+% will become "^Ee<".
+
+\section{Newline with completion}
+
+Some environments are structured internally with special commands like
+\texcmd{item} in \texstring{enumerate} or \texcmd{\textbackslash} in
+\texstring{tabular}. \func{newline\_with\_completion} (bound to
+\key{\reskey-Return} and \key{Shift-Return}) inserts a text before and after
+the linebreak.
+
+Like the dollar sign (\autoref{sec:dollar}) it closes open brackets or skipps
+closing brackets before it inserts.
+
+Examples:
+\begin{verbatim}
+\begin{itemize}
+ \item a aa•
+ \item $aaaa•
+ \item \texttt{aa aa•}
+ \item \texttt{$aaa•}
+ \item (•)
+ \item $(\texttt{aaaa•})
+ \item aaa $aa$ •
+\end{itemize}
+
+\begin{gather*}
+ \begin{cases}
+ aaa& aaa•
+ \end{cases}\\
+ aaa aa (a_{•})
+\end{gather*}
+\end{verbatim}
+
+% % templates - ^CT or ^C^T
+% definekey_reserved("menu_select_menu(\"Global.M&ode.&Templates\")", "t", MODE);
+% definekey_reserved("menu_select_menu(\"Global.M&ode.&Templates\")", "^T", MODE);
+
+% % packages - ^CP
+% definekey_reserved("latex->pkg_prompt", "p", MODE);
+
+% % array - ^Ca
+% definekey_reserved("latex->array_edit_column_format", "ae", MODE);
+% definekey_reserved("latex->array_next_cell", "a\t", MODE);
+% definekey_reserved("latex->array_next_cell", "aa", MODE);
+% definekey_reserved("latex->array_new_cell", "an", MODE);
+% definekey_reserved("latex->array_prev_cell", "ap", MODE);
+
+\renewcommand*{\subseckey}{e}
+\subsection{environments---\keyseq{}}
+\begin{center}
+ \begin{tabular}{l|cl}
+ \multicolumn{1}{c|}{Key}& \multicolumn{1}{c}{Function}&
+ \multicolumn{1}{c}{Description}\\
+ \hline
+ \keyseq{<}& \func{boenv}& goes to the \texcmd{begin} of the environment\\
+ \keyseq{c}& \func{env\_close}& goes to the \texcmd{end} of the
+ environment\\
+ \keyseq{\}}& \func{env\_close}& inserts an \texcmd{end} to close the
+ current environment\\
+ \keyseq{e}& \func{env\_prompt}& inserts a new environment with
+ \texcmd{begin} and \texcmd{end}\\
+ \keyseq{Return}& \func{env\_prompt}& inserts a new environment with
+ \texcmd{begin} and \texcmd{end}\\
+ \keyseq{r}& \func{env\_rename}& renames the current environment\\
+ \keyseq{>}& \func{eoenv}& goes to the \texcmd{end} of the environment
+ \end{tabular}
+\end{center}
+
+\renewcommand*{\subseckey}{d}
+\subsection{commands---\keyseq{}}
+
+% definekey_reserved("latex->cmd_prompt", "d", MODE);
+
+\section{Hot keys for \TeX{} commands}
+
+\renewcommand*{\subseckey}{s}
+\subsection{sectioning commands---\keyseq{}}
+
+\begin{center}
+ \begin{tabular}{l|l||l|l}
+ \multicolumn{1}{c|}{\TeX{} command}& \multicolumn{1}{c||}{Key}&
+ \multicolumn{1}{c|}{\TeX{} command}& \multicolumn{1}{c}{Key}\\
+ \hline
+ \texcmd{appendix}& \keyseq{a}&
+ \texcmd{section}& \keyseq{s}\\
+ \texcmd{chapter}& \keyseq{c}&
+ \texcmd{subsubsection}& \keyseq{b}\\
+ \texcmd{minisec}& \keyseq{m}&
+ \texcmd{subsection}& \keyseq{u}\\
+ \texcmd{paragraph}& \keyseq{g}&
+ \texcmd{subparagraph}& \keyseq{h}\\
+ \texcmd{part}& \keyseq{p}
+ \end{tabular}
+\end{center}
+
+\renewcommand*{\subseckey}{f}
+\subsection{font commands---\keyseq{}}
+
+\todo{Klären, was \func{font\_cmd} ist. Liegt auf \keyseq{p}}
+% definekey_reserved("latex->font_resize(1)", "f-", MODE);
+% definekey_reserved("latex->font_resize(0)", "f+", MODE);
+
+\begin{center}
+ \begin{tabular}{l|*{2}{>{\centering\arraybackslash}p{19mm}}||l|*{2}{>{\centering\arraybackslash}p{19mm}}}
+ \multicolumn{1}{c|}{\TeX{} cmd.}& in text mode& in mathe mode&
+ \multicolumn{1}{c|}{\TeX{} cmd.}& in math mode& everywhere\\
+ \hline
+ \texcmd{emph}& \multicolumn{2}{c||}{\keyseq{e}}& &&\\
+ &&&\texcmd{overline}& \multicolumn{2}{c}{\key{\reskey{}m\_}}\\
+ \texcmd{textbf}& \keyseq{b}& ---&\texcmd{mathbf}& \keyseq{b}& \keyseq{B}\\
+ &&&\texcmd{mathcal}& \multicolumn{2}{c}{\keyseq{a}/\key{\reskey{}nc}}\\
+ \texcmd{textit}& \keyseq{i}& ---&\texcmd{mathit}& \keyseq{i}& \keyseq{I}\\
+ &&&\texcmd{mathfrak}& \multicolumn{2}{c}{\keyseq{k}}\\
+ \texcmd{textmd}& \multicolumn{2}{c||}{\keyseq{m}}&&&\\
+ \texcmd{textnormal}& \keyseq{n}& ---&
+ \texcmd{mathnormal}& \keyseq{n}& \keyseq{N}\\
+ \texcmd{textrm}& \keyseq{r}& ---&\texcmd{mathrm}& \keyseq{r}& \keyseq{R}\\
+ \texcmd{textsc}& \multicolumn{2}{c||}{\keyseq{c}}& &&\\
+ \texcmd{textsf}& \keyseq{f}& ---&\texcmd{mathsf}& \keyseq{f}& \keyseq{F}\\
+ \texcmd{textsl}& \multicolumn{2}{c||}{\keyseq{s}}& &&\\
+ \texcmd{texttt}& \keyseq{t}& ---&\texcmd{mathtt}& \keyseq{t}& \keyseq{T}\\
+ \texcmd{textup}& \multicolumn{2}{c||}{\keyseq{u}}& &&\\
+ \texcmd{underline}& \keyseq{d}/\keyseq{\_}& ---&
+ \texcmd{underbar}& \keyseq{d}/\keyseq{\_}& \keyseq{D}\\
+ \texcmd{verb}& \multicolumn{2}{c||}{\keyseq{v}}& &&\\
+ \texcmd{text}& \multicolumn{2}{c||}{\keyseq{x}}& &&
+ \end{tabular}
+\end{center}
+
+\renewcommand*{\subseckey}{m}
+\subsection{math commands---\keyseq{} and \key{\reskey{}n}}
+
+\begin{center}
+ \begin{tabular}[t]{lc||}
+ \TeX{} cmd.& key\\
+ \hline
+ \texcmd{alpha}& \keyseq{a}\\
+ \texcmd{beta}& \keyseq{b}\\
+ \texcmd{cap}& \keyseq{-}\\
+ \texcmd{cdot}& \keyseq{.}\\
+ \texcmd{chi}& \keyseq{c}\\
+ \texcmd{colon}& \keyseq{:}\\
+ \texcmd{cos}& \keyseq{\ctrlkey{C}}\\
+ \texcmd{cup}& \keyseq{+}\\
+ \texcmd{Delta}& \keyseq{D}\\
+ \texcmd{delta}& \keyseq{d}\\
+ \texcmd{det}& \keyseq{\ctrlkey{D}}\\
+ \texcmd{downarrow}& \keyseq{\ctrlkey{N}}/\key{\reskey\textdownarrow}\\
+ \texcmd{emptyset}& \keyseq{0}\\
+ \texcmd{epsilon}& \keyseq{e}\\
+ \texcmd{eta}& \keyseq{h}\\
+ \texcmd{exists}& \keyseq{E}\\
+ \texcmd{exp}& \keyseq{\ctrlkey{E}}\\
+ \texcmd{forall}& \keyseq{A}\\
+ \texcmd{frac}& \key{\reskey{}nf}\\
+ \texcmd{frac\{1\}}& \key{\reskey{}n1}\\
+ \texcmd{frac\{1\}\{2\}}& \key{\reskey{}n2}\\
+ \texcmd{frac\{1\}\{3\}}& \key{\reskey{}n3}\\
+ \texcmd{frac\{1\}\{4\}}& \key{\reskey{}n4}\\
+ \texcmd{frac\{1\}\{5\}}& \key{\reskey{}n5}\\
+ \texcmd{frac\{1\}\{6\}}& \key{\reskey{}n6}\\
+ \texcmd{frac\{1\}\{7\}}& \key{\reskey{}n7}\\
+ \texcmd{frac\{1\}\{8\}}& \key{\reskey{}n8}\\
+ \texcmd{frac\{1\}\{9\}}& \key{\reskey{}n9}\\
+ \texcmd{Gamma}& \keyseq{G}\\
+ \texcmd{gamma}& \keyseq{g}
+ \end{tabular}%
+ \begin{tabular}[t]{lc||}
+ \TeX{} cmd.& key\\
+ \hline
+ \texcmd{geq}& \keyseq{>}\\
+ \texcmd{hat}& \keyseq{\^}\\
+ \texcmd{in}& \keyseq{i}\\
+ \texcmd{inf}& \keyseq{\ctrlkey{\_}}\\
+ \texcmd{infty}& \keyseq{I}/\keyseq{8}\\
+ \texcmd{int}& \key{\reskey{}ni}\\
+ \texcmd{kappa}& \keyseq{k}\\
+ \texcmd{Lambda}& \keyseq{L}\\
+ \texcmd{lambda}& \keyseq{l}\\
+ \texcmd{langle}& \keyseq{(}\\
+ \texcmd{leftarrow}& \keyseq{\ctrlkey{B}}/\key{\reskey\textleftarrow}\\
+ \texcmd{leq}& \keyseq{<}\\
+ \texcmd{lim}& \keyseq{\ctrlkey{L}}\\
+ \texcmd{log}& \key{\reskey{}nl}\\
+ \texcmd{mu}& \keyseq{m}\\
+ \texcmd{nabla}& \keyseq{N}\\
+ \texcmd{ne}& \keyseq{=}\\
+ \texcmd{neg}& \keyseq{!}\\
+ \texcmd{nicefrac}& \key{\reskey{}nF}\\
+ \texcmd{not}& \keyseq{/}\\
+ \texcmd{nu}& \keyseq{n}\\
+ \texcmd{oint}& \key{\reskey{}no}\\
+ \texcmd{Omega}& \keyseq{O}/\keyseq{W}\\
+ \texcmd{omega}& \keyseq{o}/\keyseq{w}\\
+ \texcmd{Phi}& \keyseq{V}/\keyseq{F}\\
+ \texcmd{phi}& \keyseq{f}\\
+ \texcmd{Pi}& \keyseq{P}\\
+ \texcmd{pi}& \keyseq{p}\\
+ \texcmd{pmod}& \key{\reskey{}nm}\\
+ \texcmd{prod}& \key{\reskey{}np}
+ \end{tabular}%
+ \begin{tabular}[t]{lc}
+ \TeX{} cmd.& key\\
+ \hline
+ \texcmd{Psi}& \keyseq{Y}\\
+ \texcmd{psi}& \keyseq{y}\\
+ \texcmd{rangle}& \keyseq{)}\\
+ \texcmd{rho}& \keyseq{r}\\
+ \texcmd{rightarrow}& \keyseq{\ctrlkey{F}}/\key{\reskey\textrightarrow}\\
+ \texcmd{setminus}& \keyseq{\textbackslash{}}\\
+ \texcmd{Sigma}& \keyseq{S}\\
+ \texcmd{sigma}& \keyseq{s}\\
+ \texcmd{sin}& \keyseq{\ctrlkey{S}}\\
+ \texcmd{sqrt}& \key{\reskey{}nq}\\
+ \texcmd{subset}& \keyseq{\{}\\
+ \texcmd{subseteq}& \keyseq{[}\\
+ \texcmd{sum}& \key{\reskey{}ns}\\
+ \texcmd{sup}& \keyseq{\ctrlkey{\^}}\\
+ \texcmd{supset}& \keyseq{\}}\\
+ \texcmd{supseteq}& \keyseq{]}\\
+ \texcmd{tan}& \keyseq{\ctrlkey{T}}\\
+ \texcmd{tau}& \keyseq{t}\\
+ \texcmd{Theta}& \keyseq{Q}\\
+ \texcmd{theta}& \keyseq{q}\\
+ \texcmd{tilde}& \keyseq{\~}\\
+ \texcmd{times}& \keyseq{*}\\
+ \texcmd{uparrow}& \keyseq{\ctrlkey{P}}/\key{\reskey\textuparrow}\\
+ \texcmd{Upsilon}& \keyseq{U}\\
+ \texcmd{upsilon}& \keyseq{u}\\
+ \texcmd{vee}& \keyseq{|}/\keyseq{v}\\
+ \texcmd{wedge}& \keyseq{\&}\\
+ \texcmd{Xi}& \keyseq{X}\\
+ \texcmd{xi}& \keyseq{x}\\
+ \texcmd{zeta}& \keyseq{z}
+ \end{tabular}
+\end{center}
+
+\renewcommand*{\subseckey}{l}
+\subsection{links---\keyseq{}}
+
+% definekey_reserved("latex->label_insert_at_mark", "lm", MODE);
+% definekey_reserved("latex->label_ref", "lr", MODE);
+
+\begin{center}
+ \begin{tabular}{lc}
+ \TeX{} cmd.& key\\
+ \hline
+ \texcmd{cite}& \keyseq{b}\\
+ \texcmd{index}& \key{\reskey{}ii}\\
+ \texcmd{label}& \keyseq{l}\\
+ \texcmd{nocite}& \keyseq{n}\\
+ \texcmd{pageref}& \keyseq{p}\\
+ \texcmd{url}& \keyseq{u}
+ \end{tabular}
+\end{center}
+
+\renewcommand*{\subseckey}{o}
+\subsection{folding---\keyseq{} and \key{return}}
+
+\begin{itemize}
+ \item With the keysequence \keyseq{o} you can fold a region. You can use
+ \key{\metakey1}, \ldots{}, \key{\metakey8} to set the level relative from
+ the current that gets folded. With \key{\metakey9} you get a prompt where
+ you can enter an arbitrary level, e.\,g. -2 to fold the level 2nd levels
+ upstairs.
+
+ \item With the keysequence \keyseq{u} you can unfold a folded region. You
+ can use it from within the region or at the begin (before the three dots).
+
+ With a prefix argument (set with \key{\metakey1}, \ldots{},
+ \key{\metakey9}) you can set the sublevel that should not be unfolded.
+
+ \item The \key{return} key is redefined to unfold a region, if it is inside
+ or before---looking at the three dots---a folded region. Otherwise it acts
+ like everywhere else.
+\end{itemize}
+
+For the definition of levels see \autoref{cha:folding}.
+
+\section{Mathematical arrows}
+
+If you “draw” an arrow it becomes substitured with an corresponding math
+command. The command is inserted with \func{cmd\_insert} (\autoref{sec:cmds})
+so you have all comforts of \func{cmd\_insert}.
+
+\begin{center}
+ \begin{tabular}{lc||lc}
+ Input& Substitution& Input& Substitution\\
+ \hline
+ \key{->}& \texcmd{rightarrow}& \key{-{}->}& \texcmd{longrightarrow}\\
+ \key{<-}& \texcmd{leftarrow}$^{*}$& \key{<-{}-}& \texcmd{longleftarrow}$^{*}$\\
+ \key{<->}& \texcmd{leftrightarrow}& \key{<-{}->}& \texcmd{longleftrightarrow}\\
+ \key{=>}& \texcmd{Rightarrow}& \key{==>}& \texcmd{Longrightarrow}\\
+ \key{<=}& \texcmd{Leftarrow}$^{*}$& \key{<==}& \texcmd{Longleftarrow}$^{*}$\\
+ \key{<=>}& \texcmd{Leftrightarrow}& \key{<==>}& \texcmd{Longleftrightarrow}\\
+ \key{|->}& \texcmd{mapsto}& \key{|-{}->}& \texcmd{longmapsto}\\
+ \key{>>}& \texcmd{gg}& \key{<<}& \texcmd{ll}\\
+ \key{`->}& \texcmd{hookrightarrow}& &
+ \end{tabular}
+\end{center}
+
+Some of the input sequences---marked with $*$ in the table---become not
+substitured immediately, because it's unclear if anything, e.g. a second
+\key{-} or \key{>}, follows. They are substitured after the next key press.
+So don't be confused and write on as if the substitution happend.
+
+Sometimes these substitutions aren't intented. The character that actives the
+substitution is not alway the last character. The emacs mode of Jed offers two
+possibilities to work around this substition: \ctrlkey{Q} to insert one
+character without showing it to the substition function and \key{\ctrlkey{X}q}
+to insert a string.
+
+\section{Mathematical sub- and superscripts}
+
+The keys \key{\_} and \key{\^} are automaticly surround the word (all
+alphanumeric characters and a possible \texcmd{} at the begin) before the
+editing point with \$, if it is not still in math mode. If the word is a
+\TeX{} command it is tried to find a completion from former usages of the
+command. This is very helpful when you write equations with
+\begin{center}
+ \texstring{\texcmd{sum}\_\{foo\}\^{}\{bar\} 12+2 =
+ \texcmd{sum}\_\{foo\}\^{}\{bar\} 10+4}
+\end{center}
+If you don't want the completion type in what you want. If you accept the
+completion than hit \key{Enter} or \key{Return}. If there is also a completion
+for the counterpar, it is also presented and you can accept it with
+\key{Enter} or \key{Return} or you type what you want. The visible mark shows
+you which part is offered and becomes removed if you don't accept.
+
+If you started in text mode, the editing point is placed after accepted
+completion in text mode. This is helpful when you write things like
+\begin{center}
+ \texstring{First, we look at \$\texcmd{alpha}\_\{i\}\$. The formula becomes\\
+ the truth true, iff \$\texcmd{alpha}\_\{i\}\$ is even.}
+\end{center}
+Than you don't have to skip the dollar sign after the subscript was completed.
+
+The sub- and superscript function treats some \TeX{} commands specially. An
+sub- or superscript for an \texcmd{rightarrow} changes the command to
+\texcmd{xrightarrow} from \AMS{}math. The commands \texcmd{cup}, \texcmd{cap},
+\texcmd{vee} and \texcmd{wedge} become \texcmd{bigcup}, \texcmd{bigcap},
+\texcmd{bigvee} and \texcmd{bigwedge}, respectively.
+
+\end{document}
+
+% breaks - ^CK
+definekey_reserved("latex->cmd_insert(\"newline\");newline()", "kl", MODE);
+definekey_reserved("latex->cmd_insert(\"newline\");newline()", "^K^L", MODE);
+definekey_reserved("latex->cmd_insert(\"linebreak[1]\");newline()", "kb", MODE);
+definekey_reserved("latex->cmd_insert(\"linebreak[1]\");newline()", "^K^B", MODE);
+definekey_reserved("latex->cmd_insert(\"newpage\");newline()", "kp", MODE);
+definekey_reserved("latex->cmd_insert(\"newpage\");newline()", "^K^P", MODE);
+definekey_reserved("latex->cmd_insert(\"clearpage\");newline()", "kc", MODE);
+definekey_reserved("latex->cmd_insert(\"clearpage\");newline()", "^K^C", MODE);
+definekey_reserved("latex->cmd_insert(\"cleardoublepage\");newline()", "kd", MODE);
+definekey_reserved("latex->cmd_insert(\"cleardoublepage\");newline()", "^K^D", MODE);
+definekey_reserved("latex->cmd_insert(\"pagebreak\");newline()", "kr", MODE);
+definekey_reserved("latex->cmd_insert(\"pagebreak\");newline()", "^K^R", MODE);
+definekey_reserved("latex->cmd_insert(\"nolinebreak[1]\");newline()", "kn", MODE);
+definekey_reserved("latex->cmd_insert(\"nolinebreak[1]\");newline()", "^K^N", MODE);
+definekey_reserved("latex->cmd_insert(\"nopagebreak\");newline()", "ko", MODE);
+definekey_reserved("latex->cmd_insert(\"nopagebreak\");newline()", "^K^O", MODE);
+definekey_reserved("latex->cmd_insert(\"enlargethispage\")", "ke", MODE);
+definekey_reserved("latex->cmd_insert(\"enlargethispage\")", "^K^E", MODE);
+
+% misc
+definekey("latex->insert_quote", "\"", MODE);
+definekey("latex->insert_quote", "`", MODE);
+definekey("latex->insert_dollar", "$", MODE);
+definekey("latex->dots", ".", MODE);
+
+foreach $1 ([" ", ",", "~"])
+ definekey_textormath("latex->insert_without_spaces", "self_insert_cmd",
+ $1, MODE);
+
+definekey_textormath("self_insert_cmd", "latex->cmd_insert(\"colon\")",
+ ":", MODE);
+definekey_textormath("self_insert_cmd", "latex->math_right_parenthesis",
+ ")", MODE);
+definekey_textormath("self_insert_cmd", "latex->math_right_parenthesis",
+ "]", MODE);
+definekey("latex->insert_limits_char()", "^", MODE);
+definekey("latex->insert_limits_char()", "_", MODE);
+definekey("latex->newline_with_completion", Key_Shift_Return, MODE);
+definekey_reserved("latex->newline_with_completion", Key_Return, MODE);
+
+% special characters
+definekey_reserved(" \\$", "$", MODE);
+definekey_reserved(" \\&", "&", MODE);
+definekey_reserved(" \\%", "%", MODE);
+definekey_reserved(" \\_", "_", MODE);
+definekey_reserved(" \\#", "#", MODE);
+definekey_reserved(" \\{", "(", MODE);
+definekey_reserved(" \\}", ")", MODE);
+definekey_reserved(" \\textless{}", "<", MODE);
+definekey_reserved(" \\textgreater{}", ">", MODE);
+definekey_reserved(" \\textbackslash{}", "\\", MODE);
+definekey_reserved(" \\textbar{}", "|", MODE);
+definekey_reserved(" \\textasciicircum{}", "^", MODE);
+definekey_reserved(" \\textasciitilde{}", "~", MODE);
+
+% stuff from latex_external - ^C r
+definekey_reserved("latex_external->select_master_file", "ra", MODE);
+definekey_reserved("latex_external->bibtex", "rb", MODE);
+definekey_reserved("latex_external->clearup", "rc", MODE);
+definekey_reserved("latex_external->makeindex", "ri", MODE);
+definekey_reserved("latex_external->mrproper", "rm", MODE);
+definekey_reserved("latex_external->cust_view", "ro", MODE);
+
+% often used stuff from latex_external
+definekey_reserved("latex_external->compose", "c", MODE);
+definekey_reserved("latex_external->compose", "^C", MODE);
+definekey_reserved("latex_external->view", "v", MODE);
+definekey_reserved("latex_external->view", "^V", MODE);
+definekey_reserved("latex_external->pop_log_file", "y", MODE);
+definekey_reserved("latex_external->pop_log_file", "^y", MODE);
+
+% help
+definekey_reserved("latex->texdoc_help()", "ht", MODE);
+definekey_reserved("latex->texdoc_search()", "hT", MODE);
+definekey_reserved("latex->texdoc_search()", "^h^T", MODE);
+definekey_reserved("()=system(\"texdoc symbols-a4 &\")", "hs", MODE);
+definekey_reserved("()=system(\"texdoc symbols-a4 &\")", "^h^S", MODE);
+
+definekey_reserved("latex->indent_region", "q", MODE);
+
+\end{document}
diff --git a/support/jed/jlm/doc/latex-jed.rc b/support/jed/jlm/doc/latex-jed.rc
new file mode 100644
index 0000000000..2391d94454
--- /dev/null
+++ b/support/jed/jlm/doc/latex-jed.rc
@@ -0,0 +1,208 @@
+% -*- mode: SLang -*-
+%
+% This file is full with examples of things you can add to your private
+% jed.rc (e. g. ~/.jedrc or ~/.jed/jed.rc) to improve and customize the
+% LaTeX mode.
+%
+
+% Setting these variables produce a more verbose backtrace upon error.
+_traceback = 1;
+_slangtrace = 1;
+
+% These lines should be anywhere in your jed.rc to make the files of the
+% LaTeX mode will be found if you place them in your home directory.
+#ifdef MSWINDOWS
+Jed_Home_Directory = path_concat(getenv("APPDATA"), "jed");
+#else
+Jed_Home_Directory = path_concat(getenv("HOME"), ".jed");
+#endif
+set_jed_library_path(Jed_Home_Directory + "," + get_jed_library_path());
+Jed_Highlight_Cache_Dir = path_concat(Jed_Home_Directory, "dfa");
+
+% If your TeX binaries aren't in the PATH you can use one of these
+% commands to make jed find them:
+% putenv("PATH=/media/cdrom/texlive/bin/i386-linux:$PATH"$); % UNIX
+% putenv("PATH=D:\texlive\bin\win32:$PATH"R$); % WINDOWS
+
+% Add these lines to load the LaTeX mode for files with the extension .tex
+% and .latex.
+add_mode_for_extension("latex", "tex");
+add_mode_for_extension("latex", "ltx");
+add_mode_for_extension("latex", "sty");
+add_mode_for_extension("latex", "cls");
+
+#ifdef HAS_DFA_SYNTAX
+% Enable dfa syntax highlighting for the LaTeX mode.
+enable_dfa_syntax_for_mode("LaTeX");
+#endif
+
+% % This function is run after the file latex_external.sl was loaded. You can
+% % place here commands they should run exaclty one time, but need functions
+% % defined in latex_external.sl
+% define after_latex_external_load_hook()
+% {
+% % Define your own configuration for building and viewing the output file.
+% call_function("latex_external->cust_set",
+% "rubber_srcspcl", "Rubber with source specials",
+% "", "",
+% "rubber --src-specials --inplace %m", "",
+% "", "rubber --clean %m",
+% "",
+% "xdvi -nofork -editor %e -sourceposition %l:%c%f %M.dvi",
+% 0);
+
+% % Redefine the print command and in the second call the makeindex and the
+% % print command of the default configurations.
+% call_function("latex_external->cust_set",
+% "rubber_dvi", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+% "sh -c dvilj4l% -q% -e-% %M.dvi% |% lp% -t% \"%M\"% -",
+% NULL, NULL);
+% call_function("latex_external->cust_set",
+% "latex", "LaTeX with Xindy", NULL,
+% "texindy --language german-din %M.idx", NULL, NULL,
+% NULL, NULL,
+% "sh -c dvilj4l% -e-% \"%M.dvi\"|lp% -t% \"%M\"",
+% NULL, NULL);
+% }
+
+% Select your own configurations
+variable LaTeX_Config = "rubber_dvi";
+
+% Add your own template directory to the search list.
+variable LaTeX_Template_Dir = path_concat(Jed_Home_Directory, "latex-templ");
+#ifdef UNIX
+ LaTeX_Template_Dir += ",/usr/local/share/jjm/latex-templ-public";
+#endif
+
+% Set your prefered packages to be used for templates.
+variable LaTeX_Default_Packages = "babel:inputenc:fontenc:fixltx2e:microtype";
+
+% Set your prefered class options to be used for templates.
+variable LaTeX_Default_Class_Options = "";
+
+% The file where informations about newly known cmds and envs should go
+variable LaTeX_File_New = path_concat(Jed_Home_Directory, "latex_cfg.sl");
+
+% Define an abbreviation table for your LaTeX files
+#if (_slang_utf8_ok)
+create_abbrev_table("TeX", "0-9A-Za-zŔ-ÖŘ-öř-");
+#else
+create_abbrev_table ("TeX", "0-9A-Za-zŔ-ÖŘ-öř-");
+#endif
+define_abbrev ("TeX", "ie", "i.e.\\ "); % that is
+define_abbrev ("TeX", "eg", "e.g.\\ "); % for example
+define_abbrev ("TeX", "latex","\\LaTeX{}");
+define_abbrev ("TeX", "tex", "\\TeX{}");
+
+% german abbreviations
+define_abbrev ("TeX", "dh", "d.\\,h."); % das heißt
+define_abbrev ("TeX", "zB", "z.\\,B."); % zum Beispiel
+define_abbrev ("TeX", "idR", "i.\\,d.\\,R."); % in der Regel
+define_abbrev ("TeX", "obda", "o.\\,B.\\,d.\\,A.");
+
+% This is needed for the symbol Key_Shift_Tab in the latex_mode_hook below
+require("keydefs");
+
+% This function is run after the file latex.sl was loaded. You can place
+% here commands they should run exaclty one time, but need functions
+% defined in latex.sl
+define after_latex_load_hook(mode)
+{
+ % Define a new completion pair for the environment faelle. Nothing is
+ % inserted before the newline and \item after the newline.
+ call_function("latex->set_nl_completion", "faelle", "", "\\item ");
+
+ % Define additional commands for the ^cs completion list.
+ call_function("latex->cmd_register", "bigm", 0, 1, "same as \big but add more horizontal space before and after delimiter"R, "amsmath", NULL);
+ call_function("latex->cmd_register", "biggm", 0, 1, "same as \bigg but add more horizontal space before and after delimiter"R, "amsmath", NULL);
+ call_function("latex->cmd_register", "Bigm", 0, 1, "same as \Big but add more horizontal space before and after delimiter"R, "amsmath", NULL);
+ call_function("latex->cmd_register", "Biggm", 0, 1, "same as \Bigg but add more horizontal space before and after delimiter"R, "amsmath", NULL);
+ call_function("latex->cmd_register", "complement", 0, 1, "Symbol for complement of a set", "amsmath", NULL);
+ call_function("latex->cmd_register", "null", 0, 0, "empty \mbox{}"R, "", NULL);
+
+ % Maybe you use these commands in your documents.
+ call_function("latex->cmd_register", "todo", 1, 0, "If you have to add or rework something, make a note", "", NULL);
+ call_function("latex->cmd_register", "help", 1, 0, "If something is sketchy, write down you question", "", NULL);
+ call_function("latex->cmd_register", "abs", 1, 1, "Absolute value: |x|", "", NULL);
+ call_function("latex->cmd_register", "norm", 1, 1, "Mathematical norm: ||x||", "", NULL);
+
+ % If you want different default options for amsmath ...
+ % call_function("latex->pkg_register", "amsmath", "intlimits,leqno", "The main package for mathematical stuff", "amsldoc", NULL);
+
+ % Redefine local key mapping of german umlauts to use babel commands.
+ definekey(" \"o", "ö", mode);
+ definekey(" \"O", "Ö", mode);
+ definekey(" \"a", "ä", mode);
+ definekey(" \"A", "Ä", mode);
+ definekey(" \"u", "ü", mode);
+ definekey(" \"U", "Ü", mode);
+ definekey(" \"s", "ß", mode);
+ definekey(" \"<", "«", mode);
+ definekey(" \">", "»", mode);
+ definekey(" \\S", "§", mode);
+
+ % Define a new key combination ^cnd (^cn are additional math
+ % commands) to insert the command \vdash.
+ definekey_reserved("latex->cmd_insert(\"vdash\")", "nd", mode);
+ definekey_reserved("latex->cmd_insert(\"abs\")", "na", mode);
+ definekey_reserved("latex->cmd_insert(\"norm\")", "nn", mode);
+ definekey("latex->textormath(\"self_insert_cmd\", \"local_tex_math_pipe\")",
+ "|", mode);
+
+ % Bind array_next_cell to TAB and indent_line to ^X TAB
+ definekey("latex->array_next_cell", "\t", mode);
+ definekey("latex->array_prev_cell", Key_Shift_Tab, mode);
+ definekey("indent_line", "^X\t", mode);
+
+ % Load configuration entered while previous LaTeX sessions
+ if (file_status(LaTeX_File_New) == 1)
+ () = evalfile(LaTeX_File_New);
+}
+
+% This function is loaded by latex_mode() after the LaTeX mode is setup
+% for a file
+define latex_mode_hook ()
+{
+ % In LaTeX documents you can use the whole width of the screen.
+ WRAP=80;
+
+ % Do not ask if this file should be saved before running LaTeX.
+ _set_buffer_flag(0x80);
+
+ % fold the preample
+ if ( bol_fsearch("\\documentclass") )
+ {
+ () = down(1);
+ call_function("latex->fold", 0);
+ bob();
+ }
+
+ % fold the first sublevel in document
+ if ( bol_fsearch("\\begin{document}") )
+ {
+ () = down(1);
+ call_function("latex->fold", 1);
+ bob();
+ }
+}
+
+define local_tex_math_pipe()
+{
+ if ( blooking_at("\\") )
+ {
+ call("self_insert_cmd");
+ return;
+ }
+
+ if ( andelse {left(5)} {looking_at("\\abs{}")} )
+ {
+ () = right(1);
+ () = replace_chars(3, "norm");
+ () = right(1);
+ }
+ else
+ {
+ () = right(5);
+ call_function("latex->cmd_insert", "abs");
+ }
+}
diff --git a/support/jed/jlm/doc/wrap_failures.ltx b/support/jed/jlm/doc/wrap_failures.ltx
new file mode 100644
index 0000000000..7dd215e56d
--- /dev/null
+++ b/support/jed/jlm/doc/wrap_failures.ltx
@@ -0,0 +1,57 @@
+\documentclass[draft]{scrartcl}
+
+\usepackage[ngerman]{babel}
+
+\newlength{\myhyphenwidth}
+\setlength{\myhyphenwidth}{3.65pt} % width of hyphen sign
+
+\newlength{\mywidth}
+\newcommand*{\example}[2]{\settowidth{\mywidth}{#1}%
+ \addtolength{\mywidth}{\myhyphenwidth}
+ \addtolength{\mywidth}{-\linewidth}%
+ \par\rule{-\mywidth}{.3mm}\hspace{0pt}#2}
+
+\setlength{\parindent}{0pt}
+
+\begin{document}
+
+% \example{$C$-Vektor}{$C$-Vektorraum}
+% \example{$C$-Vektor}{$C$"=Vektorraum}
+
+\example{HI}{HI-V}
+\example{HI}{HI-Virus}
+\example{HI}{HI"~Virus}
+
+\example{primitiv-rekur}{primitiv-rekursiv}
+\example{primitiv-rekur}{primitiv"=rekursiv}
+
+\example{Motor}{Motorrad-Handbuch}
+\example{Motor}{Motorrad"=Handbuch}
+
+\example{Ein}{Ein-/Ausgabe}
+\example{Ein/}{Ein"~/""Ausgabe}
+
+\example{(Haupt}{(Haupt-)Stromkreis}
+\example{(Haupt)}{(Haupt"~)""Stromkreis}
+
+\example{bergauf und }{bergauf und -ab}
+\example{bergauf und }{bergauf und "~ab}
+
+\example{M"oglich}{M"oglichkeiten/Varianten}
+\example{M"oglich}{M"oglichkeiten/""Varianten}
+\example{M"oglich}{M"oglichkeiten\slash{}Varianten}
+
+\example{M"oglichkeiten/\hspace{-\myhyphenwidth}}{M"oglichkeiten/Varianten}
+\example{M"oglichkeiten/\hspace{-\myhyphenwidth}}{M"oglichkeiten/""Varianten}
+\example{M"oglichkeiten/\hspace{-\myhyphenwidth}}{M"oglichkeiten\slash{}Varianten}
+
+\example{M"oglichkeiten/Varian}{M"oglichkeiten/Varianten}
+\example{M"oglichkeiten/Varian}{M"oglichkeiten/""Varianten}
+\example{M"oglichkeiten/Varian}{M"oglichkeiten\slash{}Varianten}
+
+\example{Vorlesungsgliederung/}{Vorlesungsgliederung/-struktur}
+\example{Vorlesungsgliederung/\hspace{-\myhyphenwidth}}{Vorlesungsgliederung/"~struktur}
+\example{Vorlesungsgliederung/\hspace{-\myhyphenwidth}}{Vorlesungsgliederung\slash{}"~struktur}
+\example{Vorlesungsgliederung/\hspace{-\myhyphenwidth}}{Vorlesungsgliederung/"""~struktur}
+
+\end{document}
diff --git a/support/jed/jlm/latex-templ/beamer.ltx b/support/jed/jlm/latex-templ/beamer.ltx
new file mode 100644
index 0000000000..322b98ff00
--- /dev/null
+++ b/support/jed/jlm/latex-templ/beamer.ltx
@@ -0,0 +1,49 @@
+\documentclass%:default:classopt:[%{beamer}
+
+%:default:pkgs:%
+
+%\usetheme{Malmoe}
+\usetheme{AnnArbor}
+%\usecolortheme{seahorse}
+%\usecolortheme{rose}
+%\usecolortheme{orchid}
+
+% You must set \author before \begin{document}, because beamer uses it to set
+% the author field in PDF, which fails if \author is set after \begin{document}.
+% But pay attention, babel is not active here so "o (and the like) do not work.
+\author{your name}
+
+\begin{document}
+
+\title{The title of your presentation}
+\subtitle{Maybe, a subtitle}
+\date{1970-01-01}
+
+\begin{frame}
+ \titlepage
+\end{frame}
+
+\begin{frame}
+ \tableofcontents
+\end{frame}
+
+\section{A proof}
+
+\begin{frame}
+ \frametitle{There Is No Largest Prime Number}
+ \framesubtitle{The proof uses \textit{reductio ad absurdum}.}
+ \begin{theorem}
+ There is no largest prime number.
+ \end{theorem}
+ \begin{proof}
+ \begin{enumerate}
+ \item<1-| alert@1> Suppose $p$ were the largest prime number.
+ \item<2-> Let $q$ be the product of the first $p$ numbers.
+ \item<3-> Then $q+1$ is not divisible by any of them.
+ \item<1-> Thus $q+1$ is also prime and greater than $p$.\qedhere
+ \end{enumerate}
+ \end{proof}
+\end{frame}
+
+\end{document}
+
diff --git a/support/jed/jlm/latex-templ/foils.ltx b/support/jed/jlm/latex-templ/foils.ltx
new file mode 100644
index 0000000000..5ce3c3faa0
--- /dev/null
+++ b/support/jed/jlm/latex-templ/foils.ltx
@@ -0,0 +1,28 @@
+\documentclass[titlepage,25pt,Screen4to3%:default:classopt:,%]{foils}
+
+\usepackage{soul}
+\usepackage[margin=8mm,bottom=20mm]{geometry}
+\usepackage[bookmarks,bookmarksnumbered,pagebackref,draft=false]{hyperref}
+\usepackage[display]{texpower}
+%:default:pkgs:%
+
+% \pagestyle{empty}
+% \addtolength{\textheight}{\headheight +\headsep +\footskip +.3in}
+% \setlength{\headheight}{0pt}
+% \setlength{\headsep}{0pt}
+% \setlength{\footskip}{0pt}
+% \setlength{\foilheadskip}{-.2in}
+
+\MyLogo{-- Written with Joergs\LaTeX{}Mode -- Typeset by Foil\TeX{} --
+ Effects by \TeX{}Power --}
+
+\begin{document}
+
+% \title{}
+% \author{your name}
+% \date{}
+% \maketitle
+
+\foilhead{%:start:%}
+
+\end{document}
diff --git a/support/jed/jlm/latex-templ/mini.ltx b/support/jed/jlm/latex-templ/mini.ltx
new file mode 100644
index 0000000000..d382bc1724
--- /dev/null
+++ b/support/jed/jlm/latex-templ/mini.ltx
@@ -0,0 +1,8 @@
+\listfiles
+\documentclass[draft]{minimal}
+
+\begin{document}
+
+%:start:%
+
+\end{document}
diff --git a/support/jed/jlm/latex-templ/powerdot.ltx b/support/jed/jlm/latex-templ/powerdot.ltx
new file mode 100644
index 0000000000..632d9c33c1
--- /dev/null
+++ b/support/jed/jlm/latex-templ/powerdot.ltx
@@ -0,0 +1,75 @@
+% Powerdot creates the .bm file and it's important to watch on it.
+% rubber: clean $base.bm $base.vrb
+% rubber: watch $base.bm $base.toc
+
+\documentclass[mode=present,style=fyma%:default:classopt:,%]{powerdot}
+ % mode=present: generate a presentation
+ % mode=handout: generate a handout (no visual effect)
+ % mode=print: generate a document for printing with the slides
+ % nopagebreak: allow more than two slides per page on handout
+ % display=slidesnotes: include slides + notes in output
+ % display=slides: output only slides
+ % display=notes: output only notes
+ % clock: insert a clock on slides
+ % style: the layout style
+
+%:default:pkgs:%
+
+\pdsetup{lf={-- Created with Jörg's\LaTeX{}mode -- Layout and effects
+ by powerdot and \LaTeX{} --}}
+
+\begin{document}
+
+\title{%:start:%The title}
+\author{Your name
+ \href{mailto:you@example.org}{\nolinkurl{<you@example.org>}}\\
+ \url{http://www.example.org/}}
+\date{1970-01-01}
+
+\maketitle
+
+\section{First section}
+
+\begin{slide}{Title of the slide}
+ \begin{itemize}
+ \item first item
+ \item second item\pause
+ \item this item is on the next ``page''
+ \end{itemize}
+\end{slide}
+
+\begin{slide}[toc={short title for toc}]{A very very long title for this slide}
+ text
+\end{slide}
+
+\section{second section}
+
+\begin{slide}[method=direct]{A slide with verbatim text}
+\begin{verbatim}
+some verbatim text
+\end{verbatim}
+\end{slide}
+
+\begin{note}{Title}
+ A note about the last slide
+\end{note}
+
+\begin{slide}[method=file]{A slide with verbatim text on more than one ``page''}
+ some text\pause
+
+ \begin{verbatim}
+ and verabtim text
+ \end{verbatim}
+\end{slide}
+
+\begin{slide}{title}
+ \centering
+ \Large
+ \vspace{5ex}
+ And now \onslide*{1}{\ldots}\onslide*{2}{\TeX{}}\\
+ \vspace{3ex}
+ \onslide*{2}{Text on slide 2}%
+ \onslide*{3}{Text on slide 3}
+\end{slide}
+
+\end{document}
diff --git a/support/jed/jlm/latex-templ/scrartcl.ltx b/support/jed/jlm/latex-templ/scrartcl.ltx
new file mode 100644
index 0000000000..ff57cb8fa0
--- /dev/null
+++ b/support/jed/jlm/latex-templ/scrartcl.ltx
@@ -0,0 +1,21 @@
+\documentclass%:default:classopt:[%{scrartcl}
+
+%:default:pkgs:%
+\begin{document}
+
+\title{}
+\author{}
+\date{}
+\thanks{}
+\maketitle
+
+\begin{abstract}
+\end{abstract}
+
+\tableofcontents
+\listoftables
+\listoffigures
+
+\section{}
+
+\end{document}
diff --git a/support/jed/jlm/latex-templ/scrbook.ltx b/support/jed/jlm/latex-templ/scrbook.ltx
new file mode 100644
index 0000000000..8899c56c2b
--- /dev/null
+++ b/support/jed/jlm/latex-templ/scrbook.ltx
@@ -0,0 +1,22 @@
+\documentclass%:default:classopt:[%{scrbook}
+
+%:default:pkgs:%
+\begin{document}
+
+\frontmatter
+\title{}
+\author{}
+\date{}
+\maketitle
+
+\tableofcontents
+\listoftables
+\listoffigures
+
+\mainmatter
+
+\part{}
+\chapter{}
+\section{}
+
+\end{document}
diff --git a/support/jed/jlm/latex-templ/scrlttr2.ltx b/support/jed/jlm/latex-templ/scrlttr2.ltx
new file mode 100644
index 0000000000..e46fe57b74
--- /dev/null
+++ b/support/jed/jlm/latex-templ/scrlttr2.ltx
@@ -0,0 +1,33 @@
+\documentclass[fromalign=right,fromphone,fromemail%:default:classopt:,%]{scrlttr2}
+
+%:default:pkgs:%
+\pagestyle{headings}
+
+\begin{document}
+
+% \setkomavar{backaddress}{}
+% \setkomavar{fromaddress}{your street\\in your town}
+% \setkomavar{fromemail}{mail@example.org}
+\setkomavar{fromname}{Your Name}
+% \setkomavar{fromphone}{}
+% \setkomavar{place}{your town}
+
+\renewcommand{\raggedsignature}{\raggedright}
+
+\begin{letter}{%:start:%somebody\\
+ somewhere}
+ % \setkomavar{date}{}
+ % \setkomavar{yourref}{}
+ % \setkomavar{yourmail}{}
+ % \setkomavar{customer}{}
+ % \setkomavar{invoice}{}
+ \setkomavar{subject}{}
+ \opening{To Whom It May Concern,}
+
+ \closing{With kind regards,}
+ % \ps{}
+ % \encl{}
+ % \cc{}
+\end{letter}
+
+\end{document}
diff --git a/support/jed/jlm/latex-templ/scrreprt.ltx b/support/jed/jlm/latex-templ/scrreprt.ltx
new file mode 100644
index 0000000000..f0d10050dc
--- /dev/null
+++ b/support/jed/jlm/latex-templ/scrreprt.ltx
@@ -0,0 +1,24 @@
+\documentclass%:default:classopt:[%{scrreprt}
+
+%:default:pkgs:%
+\begin{document}
+
+\title{}
+\author{}
+\date{}
+\maketitle
+
+\begin{abstract}
+\end{abstract}
+
+\tableofcontents
+\listoftables
+\listoffigures
+
+\part{}
+
+\chapter{}
+
+\section{}
+
+\end{document}
diff --git a/support/jed/jlm/latex-templ/uebung.ltx b/support/jed/jlm/latex-templ/uebung.ltx
new file mode 100644
index 0000000000..c2a932b019
--- /dev/null
+++ b/support/jed/jlm/latex-templ/uebung.ltx
@@ -0,0 +1,24 @@
+\documentclass[parskip=half%:default:classopt:,%]{scrartcl}
+
+%:default:pkgs:%
+\usepackage{ifthen}
+\usepackage{lastpage}
+\usepackage{fancyhdr}
+\usepackage{paralist}
+% \usepackage[lmargin=5cm,rmargin=2cm]{geometry}
+
+\newcommand*{\aufgabe}[1]{\section*{Aufgabe~#1}}
+
+\pagestyle{fancy}
+\lhead{Jörg Sommer, 56002}
+\chead{%:start:%Fach -- Blatt 00}
+\rhead{~Uhr}
+\cfoot{\ifthenelse{\pageref{LastPage}>1}{\thepage~von~\pageref{LastPage}}{}}
+
+\setdefaultenum{(a)}{}{}{}
+
+\begin{document}
+
+\aufgabe{1}
+
+\end{document}
diff --git a/support/jed/jlm/latex.sl b/support/jed/jlm/latex.sl
new file mode 100644
index 0000000000..c397a978ae
--- /dev/null
+++ b/support/jed/jlm/latex.sl
@@ -0,0 +1,5407 @@
+% File: latex.sl -*- mode: SLang; mode: fold -*-
+%
+% Copyright (c)
+% until 2003 Guido Gonzato <guido.gonzato@univr.it> (as Latex4Jed)
+% 2003--2007 Jörg Sommer <joerg@alea.gnuu.de>
+% $Id: latex.sl 205 2007-09-08 13:38:06Z joerg $
+%
+% -*- This file is part of Jörg's LaTeX Mode (JLM) -*-
+%
+% Description: In this file are all functions for composing, viewing,
+% printing and any related problem. All what have to do
+% with an external program and a latex file.
+%
+% License: 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 2 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.
+
+%!Fix me -- TODO:
+% font_resize(n): n variable machen
+% indent line in Verbatim environment like comments
+% use replace_chars()
+% right, left bei |
+% g\bigl( ... )
+% \{ confuses indention
+% auto-sizing of braces, e.g. "( ()" + ")" -> "\big( () \big)"
+% customization stuff
+% move to comment.sl
+% preview of equations with UTF-8
+% dialog for open subfiles (\input, \include)
+
+if (length(where("latex" == _get_namespaces())))
+ use_namespace("latex");
+else
+ implements("latex");
+
+#ifnexists profile_on
+% profiling does not work with stack check enabled.
+autoload("Global->enable_stack_check", "stkcheck");
+try
+{
+ enable_stack_check();
+}
+catch OpenError: {} % stkcheck not found in the path
+#endif
+
+static variable MODE="LaTeX";
+
+define debug_msg(msg)
+{
+#if (BATCH)
+ message(msg);
+#else
+ whatbuf();
+ setbuf("*traceback*");
+ eob();
+ variable x = make_printable_string(string(msg));
+ insert( substr(x, 2, strlen(x) - 2) );
+ newline();
+ setbuf( () );
+#endif
+}
+
+define debug_pos()
+{
+ variable arg;
+ if (_NARGS)
+ arg = string( () );
+ else
+ arg = "";
+ debug_msg("line = $what_line, col = "$ + string(what_column()) + "; $arg"$);
+}
+
+define debug_print_buf()
+{
+ push_spot();
+ bob();
+ push_mark();
+ eob();
+ message( bufsubstr() );
+ pop_spot();
+}
+
+public variable Key_Enter = "\r", Key_Space = " ";
+
+foreach ("latex_external->" +
+ ["bibtex", "clearup", "compose", "makeindex", "mrproper",
+ "pop_log_file", "print", "select_master_file",
+ "cust_view", "view", "jump_to_master_buffer",
+ "show_bibtex_log", "show_mkidx_log"])
+{
+ autoload((), "latex_external.sl");
+}
+
+foreach ("latex_conv->" +
+ ["colon", "german_lat1", "german_utf8", "native_lat1", "native_utf8",
+ "ltx209_ltx2e"])
+{
+ autoload((), "latex_conv.sl");
+}
+
+foreach ("latex->" +
+ ["pst_update_pic_size", "pst_move_points"])
+{
+ autoload((), "latex_pst.sl");
+}
+
+foreach ("latex->typo_" + ["abbrev", "dots", "german_decimal_point", "hyphen",
+ "percent", "slash"])
+{
+ autoload((), "latex_typo.sl");
+}
+
+#if (_jed_version < 9919)
+require("x-keydefs");
+require("read_with_description");
+#else
+require("x-keydefs", "Global");
+require("read_with_description", "Global");
+#endif
+
+%!%+
+%\variable{String_Type LaTeX_Template_Dir}
+%\synopsis{Directories of template files}
+%\description
+% You can insert text blocks via Mode->Templates or ^ct. These blocks
+% are read from a file that is placed in a directory in this comma
+% separated list.
+%
+% The default is Jed_Home_Directory/latex-templ
+%\seealso{templ_insert()}
+%!%-
+custom_variable("LaTeX_Template_Dir",
+ path_concat(Jed_Home_Directory, "latex-templ"));
+
+%!%+
+%\variable{String_Type LaTeX_Default_Packages}
+%\synopsis{List of packages to insert when a template will be inserted}
+%\description
+% You can insert text blocks via Mode->Templates or ^ct. These blocks can
+% include the special sequences %:default:pkgs:% that is replaced by a list
+% of \\usepackage commands with the packages given with this variable.
+%
+% The default is "inputenc:fontenc:babel:fixltx2e:microtype".
+%\seealso{templ_insert(), insert_pkgs()}
+%!%-
+% http://homepage.ruhr-uni-bochum.de/Georg.Verweyen/latexfuerword.html
+custom_variable("LaTeX_Default_Packages",
+ "inputenc:babel:fontenc:fixltx2e:microtype");
+
+%!%+
+%\variable{String_Type LaTeX_Default_Class_Options}
+%\synopsis{Default class options for a template}
+%\description
+% You can insert text blocks via Mode->Templates or ^ct. These blocks can
+% include one of the special sequences %:default:classopt:,% or
+% %:default:classopt:[% that is replaced by the content of this variable.
+%
+% The default is "draft".
+%\seealso{templ_insert()}
+%!%-
+custom_variable("LaTeX_Default_Class_Options", "draft");
+
+%!%+
+%\variable{Integer_Type LaTeX_Auto_Space_After_Commands}
+%\synopsis{Insert a space after a command, if a letter is inserted}
+%\description
+% If this variable is unequal 0 and you insert a command with
+% cmd_insert() which have no arguments the cursor is placed after this
+% command. If you then enter a letter, a space is inserted, because would
+% treat LaTeX this as part of command which is normally an error.
+%
+% The default is 1, which means to insert a space, if necessary.
+%\seealso{templ_insert()}
+%!%-
+custom_variable("LaTeX_Auto_Space_After_Commands", 1);
+
+%!%+
+%\variable{Integer_Type LaTeX_Indent_First}
+%\synopsis{Defines the amount of spaces used for first indention level}
+%\description
+% Defines the default indention in all environments and open braces.
+%
+% \begin{xyz}
+% text indented by LaTeX_Indent_First
+% \cmd{foo% indented by LaTeX_Indent_First
+% bar} indented a second time by LaTeX_Indent_First
+% \end{xyz}
+%
+% The default is 2.
+%\seealso{LaTeX_Indent_Continued}
+%\seealso{LaTeX_Indent_Item}
+%!%-
+custom_variable("LaTeX_Indent_First", 2);
+
+%!%+
+%\variable{Integer_Type LaTeX_Indent_Continued}
+%\synopsis{Defines the amount of spaces added for each deeper indention level}
+%\description
+% Some environments like table, array, align or gather don't allow empty
+% lines to structure the LaTeX code. JLM tries to detect the end of line
+% in the output and helps structuring the code in this way that all text
+% in the same line in the output, but on different lines in the code is
+% indented deeper than the first line.
+%
+% \begin{tabular}{l}
+% text this line is indented by LaTeX_Indent_First spaces
+% continued l. LaTeX_Indent_First + LaTeX_Indent_Continued
+% third line\\ LaTeX_Indent_First + LaTeX_Indent_Continued
+% text LaTeX_Indent_First
+% \end{tabular}
+%
+% The default is 3.
+%\seealso{LaTeX_Indent_First}
+%\seealso{LaTeX_Indent_Item}
+%!%-
+custom_variable("LaTeX_Indent_Continued", 3);
+
+%!%+
+%\variable{Integer_Type LaTeX_Indent_Item}
+%\synopsis{Defines the amount of spaces used to indent \item}
+%\description
+% \begin{itemize}
+% \item indented by LaTeX_Indent_Item
+% text indented by LaTeX_Indent_First
+% \end{itemize}
+%
+% The default is 1.
+%\seealso{LaTeX_Indent_Continued}
+%\seealso{LaTeX_Indent_First}
+%!%-
+custom_variable("LaTeX_Indent_Item", 1);
+
+%!%+
+%\variable{Integer_Type LaTeX_Register_New}
+%\synopsis{Ask the user about informations for new environments/commands}
+%\description
+% When a environment or command is inserted with *_prompt and
+% it is not known, the user is prompted for the missing informations
+% like number of arguments, needed packages and a description.
+%
+% The default is 1.
+%!%-
+custom_variable("LaTeX_Register_New", 1);
+
+%!%+
+%\variable{String_Type LaTeX_File_New}
+%\synopsis{Name of a file, where options of new cmds, envs and pkgs are saved}
+%\description
+% When a command, environment or package is inserted with *_prompt and
+% this variable is a non-empty string, it is used as the name of a file
+% where a command is appended to save the new data. Later, you can load
+% this file, with evalfile(), to import your config.
+%
+% The default is NULL.
+%\seealso{LaTeX_Register_New}
+%!%-
+custom_variable("LaTeX_File_New", NULL);
+
+%!%+
+%\variable{Integer_Type LaTeX_Typo_Active}
+%\synopsis{Enables/Disables typographic functions}
+%\description
+% Setting this variable to 0 disables all typographic functions. They
+% might be work for you language or do silly things, so you don't want
+% to use them. Every value different from 0 enables the functions.
+%
+% The default is 1.
+%!%-
+custom_variable("LaTeX_Typo_Active", 1);
+
+%!%+
+%\variable{Integer_Type LaTeX_Typo_Word_Size}
+%\synopsis{Defines the lowest number of characters in a word}
+%\description
+% Some typographic functions, like typo_slash(), do different things
+% depending on the leading/following number of characters is more or
+% less than \var{LaTeX_Typo_Word_Size}. The typo_slash() function, e.g.,
+% do not replace the / by \slash{} if the number of characters before
+% the / is not at least \var{LaTeX_Typo_Word_Size}.
+%
+% The default is 4.
+%!%-
+custom_variable("LaTeX_Typo_Word_Size", 4);
+
+%%%%%%%%%%
+%
+% Declarations needed somewhere before the definition
+%
+
+static define array_edit_column_format() { throw NotImplementedError; }
+static define boenv() { throw NotImplementedError; }
+static define bsearch_matching_brace() { throw NotImplementedError; }
+static define cmd_insert() { throw NotImplementedError; }
+static define cmd_parse_args() { throw NotImplementedError; }
+static define env_name() { throw NotImplementedError; }
+static define eoenv() { throw NotImplementedError; }
+private define pkg_find() { throw NotImplementedError; }
+static define is_escaped() { throw NotImplementedError; }
+static define texdoc() { throw NotImplementedError; }
+
+%%%%%%%%%%
+%
+% Some constants
+%
+static variable TeX_Command_Chars = "a-zA-Z@*";
+
+%%%%%%%%%%
+%
+% Tools
+%
+static define is_commented()
+{
+ % When parse_to_point() says inside a string we can't trust him. The X in
+ % the following text is not inside of a comment for parse_to_point()
+ % $\alpha % X
+ % \beta$
+ % But parse_to_point() has no informations (define_syntax()) about
+ % strings, so this should not be a problem.
+ return parse_to_point() == -2;
+}
+
+private define bocomment()
+{
+ !if ( is_commented() )
+ return 0;
+
+ while ( andelse {bfind_char('%')} {is_commented()} );
+ return 1;
+}
+
+private define chop_star(str)
+{
+ if (andelse {str != NULL} {str[-1] == '*'})
+ return str[[:-2]];
+ else
+ return str;
+}
+
+static define is_escaped()
+{
+ variable pnt = _get_point();
+ bskip_chars("\\");
+ variable pnt2 = _get_point();
+ _set_point(pnt);
+ return (pnt - pnt2) mod 2 == 1;
+}
+
+private define trim()
+{
+ skip_white();
+ push_mark();
+ bskip_white();
+ if ( looking_at_char(' ') and is_escaped() )
+ () = right(1);
+ del_region();
+}
+
+static variable verbatim_commands = "bibitem,cite,href,include,includegraphics,input,label,nolinkurl,ref,url";
+static variable verbatim_environments = "verbatim,Verbatim";
+
+static define is_verbatim()
+{
+ if ( is_commented() )
+ return 1;
+
+ variable start_mark = create_user_mark();
+ try
+ {
+ bsearch_matching_brace();
+
+ push_mark();
+ bskip_chars(TeX_Command_Chars);
+ if ( blooking_at("\\") )
+ {
+ if ( is_list_element(verbatim_commands, bufsubstr(), ',') )
+ return 1;
+ }
+ else
+ pop_mark(0);
+ }
+ catch DataError;
+ finally
+ goto_user_mark(start_mark);
+
+ try
+ {
+ if ( bfind("\\verb") )
+ {
+ () = right(5);
+ what_char();
+ () = right(1);
+ if ( ffind_char( () ) )
+ () = right(1);
+ else
+ return 1;
+
+ if (create_user_mark() > start_mark)
+ return 1;
+ }
+ }
+ finally
+ goto_user_mark(start_mark);
+
+ variable e_name = env_name();
+ if ( andelse {e_name != NULL}
+ {is_list_element(verbatim_environments, __tmp(e_name), ',')} )
+ return 1;
+
+ return 0;
+}
+
+private variable math_environments = "gather,align,flalign,alignat,multline";
+private variable anti_math_commands = "text,mbox,intertext,label,raisebox,footnote,makebox";
+
+static define is_math()
+{
+ if ( is_verbatim() )
+ return 0;
+
+ push_spot();
+ try
+ {
+ variable math_open = 0, math_seen = 0;
+ forever
+ {
+ bskip_chars("^{}$_^[]");
+ !if ( left(1) ) % bobp() == TRUE
+ return math_open;
+
+ variable is_bracket = what_char() == '[' or what_char() == ']';
+
+ if ( orelse {bocomment()} {is_escaped() != is_bracket} )
+ continue;
+
+ switch ( what_char() )
+ { case '$':
+ math_open = not math_open;
+ math_seen = 1;
+ }
+ { case '^' or case '_': return not math_open; }
+ { case '{':
+ if (math_seen)
+ return math_open;
+
+ % This is for \raisebox, because the text is in the
+ % second argument
+ while ( left(1) and looking_at_char('}') )
+ bsearch_matching_brace();
+ () = right(1);
+
+ push_mark();
+ bskip_chars(TeX_Command_Chars);
+ variable cmd_name = bufsubstr();
+ () = left(1);
+ if ( looking_at_char('\\') and
+ is_list_element(anti_math_commands, cmd_name, ',') )
+ return 0;
+ }
+ { case '}':
+ bsearch_matching_brace();
+ push_mark();
+ bskip_chars(TeX_Command_Chars);
+ variable cmd = chop_star( bufsubstr() );
+
+ () = left(1);
+ if ( looking_at_char('\\') )
+ {
+ switch (cmd)
+ { case "begin":
+ () = right(7);
+ push_mark();
+ () = ffind_char('}');
+ variable e_name = bufsubstr();
+ if (e_name == "document")
+ return math_open;
+
+ if ( is_list_element(math_environments,
+ chop_star(e_name), ',') )
+ return 1;
+
+ if ( is_list_element(verbatim_environments,
+ chop_star(e_name), ',') )
+ return 0;
+
+ if (math_seen)
+ return math_open;
+
+ () = left(strlen(e_name) + 7);
+ }
+ { case "end":
+ () = right(5);
+ push_mark();
+ () = ffind_char('}');
+ if ( is_list_element("document,"+math_environments,
+ chop_star(bufsubstr()), ',') )
+ return math_open;
+
+ () = bfind("\\end");
+ boenv();
+ }
+ { is_list_element("chapter,section,subsection,subsubsection,paragraph",
+ cmd, ','):
+ return math_open;
+ }
+ { is_list_element("frac,overline,underbrace", cmd, ','):
+ % cmd_list[cmd].math
+ return not math_open;
+ }
+ }
+ else
+ () = right(1);
+ }
+ { case '[': return 1; }
+ { case ']': return math_open; }
+ }
+ }
+ finally
+ pop_spot();
+}
+
+private define str_compress_tex(str)
+{
+ variable a_str = bstring_to_array(str), ins = -1, i;
+
+ for (i=0; i < length(a_str); ++i)
+ {
+ switch (a_str[i])
+ { case '%': % "%.*\n[ \t]*" -> ""
+ if (ins < 0)
+ ins = i;
+
+ do
+ ++i;
+ while (andelse {i < length(a_str)} {a_str[i] != '\n'});
+
+ do
+ ++i;
+ while (andelse {i < length(a_str)}
+ {a_str[i] == '\t' or a_str[i] == ' '});
+
+ --i;
+ continue;
+ }
+ { case '\n': % "\n[ \t]*" -> " "
+ if (ins < 0)
+ ins = i;
+
+ do
+ ++i;
+ while (andelse {i < length(a_str)}
+ {a_str[i] == '\t' or a_str[i] == ' '});
+
+ a_str[ins] = ' ';
+ ++ins;
+ --i;
+ continue;
+ }
+ { case '\\': % escape seqences \% and \
+ if (ins >= 0)
+ {
+ a_str[ins] = a_str[i];
+ ++ins;
+ ++i;
+ if (i >= length(a_str))
+ break;
+ }
+ }
+ { case ' ' or case '\t':
+ variable old_i = i;
+ while (andelse {i+1 < length(a_str)}
+ {a_str[i+1] == '\t' or a_str[i+1] == ' '})
+ ++i;
+ if (i - old_i > 0 and ins < 0)
+ ins = old_i;
+ }
+
+ if (ins >= 0)
+ {
+ a_str[ins] = a_str[i];
+ ++ins;
+ }
+ }
+
+ if (ins == -1)
+ return str;
+ else
+ return unpack("s$ins"$, array_to_bstring(a_str));
+}
+
+static define fsearch_matching_brace()
+{
+ if ( is_commented() )
+ throw UsageError, "Starting inside of a comment is not possible";
+
+ variable start_mark = create_user_mark(), open_lbraces = list_new();
+
+ if ( looking_at_char('}') )
+ return;
+
+ forever
+ {
+ () = right(1);
+ skip_chars("^{}");
+ !if ( looking_at_char('{') or looking_at_char('}') )
+ break;
+
+ if ( is_commented() )
+ {
+ eol();
+ continue;
+ }
+ if ( is_escaped() )
+ continue;
+
+ switch ( what_char() )
+ { case '{':
+ list_append(open_lbraces, [what_line, what_column()], -1);
+ }
+ { case '}':
+ if (length(open_lbraces) == 0)
+ return;
+
+ list_delete(open_lbraces, -1);
+ }
+ }
+
+ goto_user_mark(start_mark);
+ if (length(open_lbraces) > 0)
+ throw DataError, "No matching } found for { in line " +
+ string(open_lbraces[-1][0]) + " column " + string(open_lbraces[-1][1]);
+ else
+ throw DataError, "No matching } found";
+}
+
+static define bsearch_matching_brace()
+{
+ if ( is_commented() )
+ throw UsageError, "Starting inside of a comment is not possible";
+
+ variable start_mark = create_user_mark(), open_rbraces = list_new();
+ forever
+ {
+ bskip_chars("^{}");
+ !if ( left(1) ) % bobp() == TRUE
+ break;
+
+ if ( orelse {bocomment()} {is_escaped()} )
+ continue;
+
+ switch ( what_char() )
+ { case '{':
+ if (length(open_rbraces) == 0)
+ return;
+
+ list_delete(open_rbraces, -1);
+
+ push_mark();
+ bskip_chars(TeX_Command_Chars);
+ variable cmd = chop_star(bufsubstr());
+ if ( andelse {strlen(cmd) > 0} {blooking_at("\\")} )
+ {
+ () = left(1);
+ if (cmd == "end")
+ boenv();
+ else if ( is_list_element("begin,section,chapter,subsection,subsubsection,paragraph",
+ cmd, ',') )
+ break;
+ }
+ }
+ { case '}':
+ list_append(open_rbraces, [what_line, what_column()], -1);
+ }
+ }
+
+ goto_user_mark(start_mark);
+ if (length(open_rbraces) > 0)
+ throw DataError, "No matching } found for { in line " +
+ string(open_rbraces[-1][0]) + " column " + string(open_rbraces[-1][1]);
+ else
+ throw DataError, "No matching } found";
+}
+
+static define search_not_commented(func, arg, skip)
+{
+ forever
+ {
+ variable ret = @func(arg);
+ !if ( andelse {ret} {is_commented()} )
+ return ret;
+
+ () = right(skip);
+ }
+}
+
+private define make_sorted_desc_list(list)
+{
+ variable compl = {}, keys = assoc_get_keys(list);
+ foreach ( keys[array_sort(keys)] )
+ {
+ variable key = ();
+ list_append(compl, list[key], -1);
+ }
+ return compl;
+}
+
+%%%%%%%%%%
+%
+% Stuff for \documentclass[]{}
+%
+
+private define doc_find()
+{
+ bob();
+ !if ( search_not_commented(&fsearch, "\\documentclass", 1) )
+ throw DataError, "Your document misses a \\documentclass";
+
+ () = right(14); % skip \documentclass
+}
+
+private define doc_options_class()
+{
+ variable old_buf = whatbuf();
+ latex_external->jump_to_master_buffer();
+ push_spot();
+ try
+ {
+ doc_find();
+ variable args, class;
+ (args,class) = cmd_parse_args(1,1);
+ if (length(args) == 0)
+ return ("", class[0]);
+ else
+ return (str_delete_chars(args[0], "\\s"), class[0]);
+ }
+ finally
+ {
+ pop_spot();
+ setbuf(old_buf);
+ }
+}
+
+%%%%%%%%%%
+%
+% Package stuff
+%
+
+typedef struct {
+ options, desc, texdoc, hook, compl
+} Pkg_Type;
+private variable pkg_list = Assoc_Type[Pkg_Type];
+
+static define pkg_register(name, opt, desc, texdoc, hook)
+{
+ try
+ {
+ % This is a tricky way to check if all variables are strings
+ () = _typeof([name, desc, texdoc, opt, ""]);
+ }
+ catch TypeMismatchError:
+ {
+ throw InvalidParmError, "One of the given arguments has invalid type";
+ }
+ if (strlen(name) == 0)
+ throw InvalidParmError, "name can not be empty";
+
+ if (hook != NULL and typeof(hook) != Ref_Type)
+ throw InvalidParmError, "The argument hook must be a reference or NULL";
+
+ variable tmp;
+ if ( assoc_key_exists(pkg_list, name) )
+ tmp = pkg_list[name];
+ else
+ {
+ tmp = @Pkg_Type;
+ pkg_list[name] = tmp;
+ }
+
+ tmp.compl = name;
+ tmp.options = opt;
+ tmp.desc = desc;
+ tmp.texdoc = texdoc;
+ tmp.hook = hook;
+}
+
+private define pkg_hook_autoloaded_by_powerdot(name)
+{
+ doc_options_class();
+ exch;
+ pop;
+ if ( () == "powerdot" )
+ return 1;
+ return pkg_find(name);
+}
+
+private define pkg_hook_babel(name)
+{
+ if ( pkg_find(name) )
+ return 1;
+
+ variable mark = create_user_mark();
+ doc_find();
+ push_spot();
+ variable class;
+ (,class) = cmd_parse_args(1,1);
+ pop_spot();
+ if ( class[0] == "powerdot" )
+ % babel must be loaded before \documentclass, otherwise hyperref
+ % (loaded by powerdot) didn't know it.
+ () = left(14);
+ else
+ % suggest the point that pkg_find() suggested
+ goto_user_mark(mark);
+
+ return 0;
+}
+
+pkg_register("amsmath", "", "The main package for mathematical stuff", "amsldoc", NULL);
+pkg_register("amssymb", "", "Symbols from AMS-Math", "", NULL);
+pkg_register("avant", "", "Sets Avant Garde as default sans serif font", "psnfss2e", NULL);
+private variable _lang = getenv("LANG"), _babel_opt = "";
+if (_lang != NULL and _lang != "C")
+{
+ switch (_lang[[0:1]])
+ { case "de": _babel_opt = "ngerman"; }
+ { case "it": _babel_opt = "italian"; }
+ { case "en": _babel_opt = "english"; }
+}
+pkg_register("babel", _babel_opt, "Provides local hyphenation", "", &pkg_hook_babel());
+__uninitialize(&_lang);
+__uninitialize(&_babel_opt);
+pkg_register("bookman", "", "Sets Bookman (roman), Avant Garde (sans serif) and Courier (typewriter) as default font", "psnfss2e", NULL);
+pkg_register("chancery", "", "Sets Zapf Chancery as default roman font", "psnfss2e", NULL);
+pkg_register("charter", "", "Sets Charter as default roman font", "psnfss2e", NULL);
+pkg_register("courier", "", "Sets Courier as default typewriter font", "psnfss2e", NULL);
+pkg_register("eulervm", "euler-digits", "Sets Euler fonts as default math font", "", NULL);
+pkg_register("fontenc", "T1", "", "", NULL);
+pkg_register("graphicx", "final", "Package for graphics", "graphics", NULL);
+pkg_register("helvet", "scaled=.92", "Sets Helvetica as default sans serif font", "psnfss2e", NULL);
+pkg_register("hyperref", "draft=false,colorlinks,urlcolor=blue,breaklinks", "", "hyperref/manual", &pkg_hook_autoloaded_by_powerdot());
+#if (_slang_utf8_ok)
+pkg_register("inputenc", "utf8", "Provides direct input of non-ascii characters", "", NULL);
+#else
+pkg_register("inputenc", "latin1", "Provides direct input of non-ascii characters", "", NULL);
+#endif
+pkg_register("lmodern", "", "Sets Latin Modern as default font", "", NULL);
+pkg_register("mathpazo", "osf,slantedGreek", "Sets Adobe Palatino as default roman font", "psnfss2e", NULL);
+pkg_register("mathptmx", "", "Sets Times as default roman font", "psnfss2e", NULL);
+pkg_register("newcent", "", "Sets New Century Schoolbook (roman), Avant Garde (sans serif) and Courier (typewriter) as default font", "psnfss2e", NULL);
+pkg_register("pstricks", "", "Draws PS graphics with LaTeX commands", "pstricks-doc", &pkg_hook_autoloaded_by_powerdot());
+pkg_register("suetterl", "", "Provides Suetterlin kind font (use \textsuetterlin and \suetterlin)", "", NULL);
+pkg_register("type1ec", "", "Sets Computer Modern super as default font", "", NULL);
+pkg_register("xcolor", "", "Colors for LaTeX", "", &pkg_hook_autoloaded_by_powerdot());
+
+private define pkg_find(name)
+{
+ eob();
+ variable after_last_pkg = create_user_mark();
+ bob();
+ while ( re_fsearch("\\[buR][es][geq][ipu]"R) ) % Fixme: PCRE \\(begin|(Require|use)package)
+ {
+ if ( is_commented() )
+ {
+ eol();
+ continue;
+ }
+
+ if ( looking_at("\\begin{document}") )
+ {
+ goto_user_mark(after_last_pkg);
+ return 0;
+ }
+
+ variable is_usepackage = 0;
+ if ( looking_at("\\usepackage") )
+ {
+ is_usepackage = 1;
+ () = right(11);
+ }
+ else if ( looking_at("\\RequirePackage") )
+ () = right(15);
+ else
+ {
+ () = right(1);
+ continue;
+ }
+
+ variable mark_before_args = create_user_mark();
+
+ variable p;
+ (, p) = cmd_parse_args(1, 1);
+ if ( is_list_element(str_delete_chars(p[0], "\\s"), name, ',') )
+ {
+ goto_user_mark(mark_before_args);
+ return 1;
+ }
+
+ if (is_usepackage)
+ % If this wasn't the expected package, move the mark behind the
+ % \usepackage command
+ move_user_mark(after_last_pkg);
+ }
+
+ throw DataError, "no \\begin{document} found";
+}
+
+private define pkg_insert()
+{
+ variable opt;
+ if (_NARGS >= 2)
+ opt = ();
+
+ variable name = ();
+
+ if (name == "")
+ return;
+
+ variable old_buf = whatbuf();
+ latex_external->jump_to_master_buffer();
+ push_spot();
+ try
+ {
+ variable hook = NULL;
+ if ( assoc_key_exists(pkg_list, name) )
+ hook = pkg_list[name].hook;
+
+ if (hook != NULL)
+ {
+ if ( @hook(name) )
+ return;
+ }
+ else if ( pkg_find(name) )
+ return;
+
+ if ( eobp() )
+ % pkg_find() or the hook didn't found any \usepackage
+ {
+ doc_find();
+ (,) = cmd_parse_args(1,1);
+
+ !if ( down(1) )
+ newline();
+ }
+ else
+ {
+ forever
+ {
+ push_spot();
+ skip_white();
+ looking_at_char('%');
+ pop_spot();
+ !if ( () )
+ break;
+ () = down(1);
+ }
+ if ( bolp() )
+ % We are not in the line with the last \usepackage and
+ % skipped a comment
+ () = up(1);
+ }
+
+ push_spot();
+ bsearch("\\documentclass");
+ pop_spot();
+ if ( () )
+ % after \documentclass
+ insert("\n\\usepackage");
+ else
+ % before \documentclass
+ insert("\n\\RequirePackage");
+
+ if ( __is_initialized(&opt) )
+ {
+ if (opt != "")
+ insert("[$opt]"$);
+ }
+ else if ( assoc_key_exists(pkg_list, name) )
+ {
+ opt = pkg_list[name].options;
+ if (opt != "")
+ insert("[$opt]"$);
+ }
+
+ insert("{$name}"$);
+ !if ( eolp() )
+ newline();
+ }
+ finally
+ {
+ pop_spot();
+ setbuf(old_buf);
+ }
+}
+
+private define insert_pkgs(str)
+{
+ if (str == "")
+ return;
+
+ foreach ( strchop(str, ':', 0) )
+ {
+ variable pkg = (), pos = is_substr(pkg, ","), opt;
+
+ if (pos)
+ pkg_insert(substr(pkg, 1, pos-1), substr(pkg, pos+1, strlen(pkg)) );
+ else
+ pkg_insert(pkg);
+ }
+}
+
+static define pkg_prompt()
+{
+ try
+ {
+ variable pkg = read_with_description("Select a package:", "", "",
+ make_sorted_desc_list(pkg_list));
+
+ if (pkg == "")
+ return;
+
+ variable options, new_pkg = not assoc_key_exists(pkg_list, pkg);
+ if (new_pkg)
+ options = "";
+ else
+ options = pkg_list[pkg].options;
+
+ options = read_mini("Options:", "", options);
+
+ pkg_insert(pkg, options);
+ if (andelse {new_pkg} {LaTeX_File_New != NULL} {strlen(LaTeX_File_New) > 0})
+ {
+ variable desc = read_mini("A description for the new package:", "", "");
+ variable fp = fopen(LaTeX_File_New, "a");
+ () = fprintf(fp, "latex->pkg_register(\"%- 21s \"%s\"R, \"%s\"R, \"\", NULL);\n",
+ pkg + "\",", options, desc);
+ () = fclose(fp);
+ }
+ message("\\usepackage{$pkg} inserted."$);
+ }
+ catch UserBreakError;
+}
+
+static define pkg_loaded(pkg)
+{
+ variable old_buf = whatbuf();
+ latex_external->jump_to_master_buffer();
+ push_spot();
+ try
+ {
+ variable hook = NULL;
+ if ( assoc_key_exists(pkg_list, pkg) )
+ hook = pkg_list[pkg].hook;
+
+ if (hook != NULL)
+ return @hook(pkg);
+ else
+ return pkg_find(pkg);
+ }
+ finally
+ {
+ pop_spot();
+ setbuf(old_buf);
+ }
+}
+
+private define pkg_options(pkg)
+{
+ variable old_buf = whatbuf();
+ latex_external->jump_to_master_buffer();
+ push_spot();
+ try
+ {
+ variable hook = NULL;
+ if ( assoc_key_exists(pkg_list, pkg) )
+ hook = pkg_list[pkg].hook;
+
+ if (hook != NULL)
+ {
+ !if ( @hook(pkg) )
+ throw InternalError, "Package $pkg not found"$;
+ }
+ else !if ( pkg_find(pkg) )
+ throw InternalError, "Package $pkg not found"$;
+
+ variable args;
+ (args,) = cmd_parse_args(1, 0);
+ if (length(args) == 0)
+ return "";
+ else
+ return args[0];
+ }
+ finally
+ {
+ pop_spot();
+ setbuf(old_buf);
+ }
+}
+
+static define pkg_help()
+{
+ try
+ {
+ variable pkg;
+ if (_NARGS)
+ {
+ pkg = ();
+ if ( is_substr(pkg, ":") )
+ pkg = strchop(pkg, ':', 0)[0];
+ }
+ else
+ {
+ pkg = read_with_description("Help for which package:", "", "",
+ make_sorted_desc_list(pkg_list));
+ if (pkg == "")
+ return;
+ }
+
+ variable help;
+ if ( assoc_key_exists(pkg_list, pkg) )
+ {
+ help = pkg_list[pkg].texdoc;
+ if (strlen(help) == 0)
+ help = pkg;
+ }
+ else
+ help = pkg;
+
+ texdoc(help);
+ }
+ catch UserBreakError;
+}
+
+%%%%%%%%%%
+%
+% All about indentation
+%
+
+%!%+
+%\function{env_name_indent}
+%\synopsis{Gets the name and the indention of the current environment}
+%\usage{(String_Type name, Integer_type indent) env_name_indent()}
+%\description
+% This function returns the name of the environment the editing point is in
+% and the count of characters before \begin{...} in this line. If it isn't
+% within a environment, name is NULL and the value of indent is undefined.
+%
+%\seealso{boenv(), env_name()}
+%!%-
+%\usage{(String_Type name, Integer_type indent) env_name_indent([Integer_Type])}
+% If the optional parameter is unequal to zero to editing point is moved
+% there.
+private define env_name_indent()
+{
+ push_spot();
+ try
+ {
+ variable name = env_name(1);
+ return (name, what_column()-1);
+ }
+ finally
+ pop_spot();
+}
+
+private define bsearch_command_indent()
+{
+ variable backslash_mark, start_mark = create_user_mark();
+ forever {
+ !if ( bsearch_char('\\') )
+ error("Unknown case: opening brace, but no \\");
+
+ backslash_mark = create_user_mark();
+
+ % fix me!
+ % \framebox[.8\textwidth]{
+ variable found = orelse {find_matching_delimiter('{') != 1}
+ {create_user_mark() > start_mark};
+
+ goto_user_mark(backslash_mark);
+
+ if (found)
+ % start_mark is the opening brace for the command at
+ % backslash_mark
+ break;
+ % else
+ % the found backslash is inside of {} which are closed before
+ % start_mark
+ }
+ return what_column()-1;
+}
+
+private define calc_indention(env_name, line)
+{
+ if (line != NULL)
+ {
+ line = strtrim_beg(line);
+ foreach ( [ {"\\item", LaTeX_Indent_Item},
+ {"\\intertext{", LaTeX_Indent_First},
+ {"\\bibitem{", LaTeX_Indent_Item}, {"\\end{", 0}] )
+ {
+ variable tmp = ();
+ if (strncmp(line, tmp[0], strlen(tmp[0])) == 0)
+ return tmp[1];
+ }
+ }
+
+ switch ( chop_star(env_name) )
+ { case "document" or case "verbatim" or case "Verbatim": return 0; }
+ { case "gather" or case "align" or case "tabular" or case "tabularx":
+ () = up(1);
+
+ variable indent = LaTeX_Indent_First;
+ !if ( orelse {blooking_at("\\\\")}
+ {blooking_at("\\hline")}
+ {bfind("\\intertext{")}
+ {bfind("\\begin{"+env_name+"}")} % first line after \begin
+ )
+ indent += LaTeX_Indent_Continued;
+
+ () = down(1);
+ return indent;
+ }
+ { case NULL: return 0; }
+
+ return LaTeX_Indent_First;
+}
+
+private define newline_indent_hook()
+{
+ variable indent, start_mark = create_user_mark(), name, env_mark;
+
+ () = bocomment();
+
+ name = env_name(1);
+ if (name == NULL) {
+ % we are outside of \begin{document}
+ indent = 0;
+ env_mark = NULL;
+ }
+ else {
+ indent = what_column()-1;
+ env_mark = create_user_mark();
+ goto_user_mark(start_mark);
+ }
+
+ if (andelse {find_matching_delimiter('}') == 1}
+ {orelse {env_mark == NULL}
+ {create_user_mark() > env_mark} }) {
+ % we are inside of braces
+ name = "{";
+ indent = what_column()-1;
+ bskip_white();
+ !if (bolp())
+ indent = bsearch_command_indent();
+ }
+ goto_user_mark(start_mark);
+ trim();
+ newline();
+
+ indent += calc_indention(name, NULL);
+
+ whitespace(indent);
+}
+
+private define indent_hook()
+{
+ variable mark = create_user_mark();
+ bol();
+ trim();
+ if (eolp()) mark = NULL; % catch the case of a line with only whitespaces
+
+ variable start_mark = create_user_mark();
+ variable indent;
+ switch ( what_char() )
+ { case '}':
+ if (find_matching_delimiter('}') != 1)
+ error("No opening '{' found");
+
+ indent = what_column()-1;
+ bskip_white();
+ !if (bolp()) % if opening brace is behind a command \...{
+ indent = bsearch_command_indent();
+ }
+ { case '{' and up(1) and left(1) and looking_at_char('%'):
+ indent = bsearch_command_indent() + LaTeX_Indent_First;
+ ()=right(1);
+ skip_word_chars();
+ skip_chars("%");
+ !if (eolp())
+ % indent to the level of the command end
+ indent = what_column()-1;
+ }
+ % This looks somewhat tricky, but we only handle cases where the
+ % previous line is a comment. But we must move the editing point for
+ % this so we must reset it.
+ { case '%' and up(1) and is_commented() or
+ (goto_user_mark(start_mark),0):
+ ()=up(1);
+ () = bfind_char('%');
+ indent = what_column()-1;
+ }
+ {
+ variable line = line_as_string();
+ bol();
+
+ variable env_mark, e_name, e_indent;
+
+ e_name = env_name(1);
+ if (e_name == NULL) {
+ % we are outside of \begin{document}
+ e_indent = 0;
+ env_mark = NULL;
+ }
+ else {
+ e_indent = what_column()-1;
+ env_mark = create_user_mark();
+ goto_user_mark(start_mark);
+ }
+
+ variable name;
+ if (andelse {find_matching_delimiter('}') == 1}
+ {orelse {env_mark == NULL} {create_user_mark() > env_mark} }) {
+ % we are inside of braces
+ name = "{";
+ %! Fix me!
+ indent = what_column()-1;
+ bskip_white();
+ !if (bolp()) {
+ % { is not the begin of a line
+ indent = bsearch_command_indent();
+ bskip_white();
+ !if (bolp()) {
+ % the command isn't the start of the line
+ indent = e_indent;
+ name = e_name;
+ }
+ }
+ }
+ else {
+ indent = e_indent;
+ name = e_name;
+ }
+
+ goto_user_mark(start_mark);
+ indent += calc_indention(name, line);
+ }
+
+ goto_user_mark(start_mark);
+ whitespace(indent);
+ if (mark != NULL) goto_user_mark(mark);
+}
+
+private define wrap_hook()
+{
+ variable mark = create_user_mark();
+ ()=up(1);
+ !if ( is_commented() ) {
+ goto_user_mark(mark);
+ indent_hook();
+ return;
+ }
+
+ % The wrap happened in a comment, so continue the comment
+ () = bfind_char('%');
+
+ variable indent = what_column()-1;
+ () = right(1);
+ skip_white();
+ variable inner_indent = what_column() - indent - 2;
+ () = down(1);
+
+ whitespace(indent);
+ insert_char('%');
+ whitespace(inner_indent);
+
+ goto_user_mark(mark);
+}
+
+private define wrapok_hook()
+{
+ push_spot();
+ variable e_n;
+ try
+ {
+ () = bocomment();
+ e_n = env_name();
+ }
+ finally
+ pop_spot();
+
+ if ( andelse {e_n != NULL}
+ {is_list_element("verbatim,Verbatim", e_n, ',')} )
+ return 0;
+
+ push_spot();
+ try
+ {
+ bskip_chars("^ \t");
+ bskip_chars(" \t%");
+ return not bolp();
+ }
+ finally
+ pop_spot();
+}
+
+static define indent_region()
+{
+ variable start_mark = create_user_mark();
+ check_region(0);
+
+ variable end_mark = create_user_mark();
+ pop_mark(1);
+ variable beg_mark = create_user_mark();
+
+ variable env_stack = {};
+ variable level;
+ do
+ {
+ level = struct { name, indent };
+ try
+ level.name = env_name(1);
+ catch AnyError:
+ break;
+
+ if (level.name == NULL)
+ level.indent = 0;
+ else
+ level.indent = what_column()-1;
+ list_insert(env_stack, level, 0);
+ }
+ while (level.name != NULL);
+
+ goto_user_mark(beg_mark);
+
+ level = list_pop(env_stack, -1);
+ () = up(1);
+ while (down(1) and create_user_mark() < end_mark)
+ {
+ bol();
+ trim();
+ if ( eolp() )
+ continue;
+
+ variable line = line_as_string();
+ bol();
+ variable this_line_indention = level.indent +
+ calc_indention(level.name, line);
+
+ whitespace(this_line_indention);
+
+ while ( andelse {ffind_char('\\')} {not is_commented()} )
+ {
+ () = right(1);
+ if ( looking_at("begin{") )
+ {
+ () = right(6);
+ list_append(env_stack, level, -1);
+ level = struct { name, indent };
+ push_mark();
+ () = ffind_char('}');
+ level.name = bufsubstr();
+ level.indent = this_line_indention;
+ }
+ else
+ {
+ if ( looking_at("end{") )
+ {
+ () = right(4);
+ if ( looking_at(level.name+"}") )
+ level = list_pop(env_stack, -1);
+ else
+ throw ApplicationError, "Expected \\end{"+level.name+"}";
+ }
+ }
+ }
+ }
+ goto_user_mark(start_mark);
+}
+
+%%%%%%%%%%
+%
+% Completion in environments
+%
+
+typedef struct { pre_nl, post_nl } nl_completion_type;
+private variable nl_completion = Assoc_Type[nl_completion_type];
+
+static define set_nl_completion(env, pre, post)
+{
+ if ( typeof(env) != String_Type )
+ throw InvalidParmError, "env must be a string";
+ if ( pre != NULL and typeof(pre) != String_Type )
+ throw InvalidParmError, "pre must be a string or NULL";
+ if ( post != NULL and typeof(post) != String_Type )
+ throw InvalidParmError, "post must be a string or NULL";
+
+ if ( assoc_key_exists(nl_completion, env) )
+ {
+ if (pre == NULL and post == NULL)
+ assoc_delete_key(nl_completion, env);
+ else
+ {
+ if (pre != NULL)
+ nl_completion[env].pre_nl = pre;
+ if (post != NULL)
+ nl_completion[env].post_nl = post;
+ }
+ }
+ else
+ {
+ if (pre == NULL) pre = "";
+ if (post == NULL) post = "";
+ nl_completion[env] = @nl_completion_type;
+ nl_completion[env].pre_nl = pre;
+ nl_completion[env].post_nl = post;
+ }
+}
+
+set_nl_completion("align", "\\\\", "");
+set_nl_completion("array", "\\\\", "");
+set_nl_completion("cases", "\\\\", "");
+set_nl_completion("compactdesc", "", "\\item[]");
+set_nl_completion("compactenum", "", "\\item ");
+set_nl_completion("compactitem", "", "\\item ");
+set_nl_completion("description", "", "\\item[]");
+set_nl_completion("enumerate", "", "\\item ");
+set_nl_completion("flalign", "\\\\", "");
+set_nl_completion("gather", "\\\\", "");
+set_nl_completion("itemize", "", "\\item ");
+set_nl_completion("pmatrix", "\\\\", "");
+set_nl_completion("tabular", "\\\\", "");
+set_nl_completion("tabularx", "\\\\", "");
+set_nl_completion("thebibliography", "", "\\bibitem{}");
+
+static define newline_with_completion()
+{
+ if ( is_commented() ) {
+ variable mark = create_user_mark();
+ bol();
+ skip_chars(" \t%");
+ % new line become a comment, too
+ bol();
+ ()=ffind_char('%');
+ variable indent = what_column()-1;
+
+ () = right(1);
+ skip_white();
+ variable inner_indent = 0;
+ !if (eolp())
+ inner_indent = what_column() - indent - 2;
+
+ goto_user_mark(mark);
+ newline();
+ trim();
+ whitespace(indent);
+ insert_char('%');
+ whitespace(inner_indent);
+ return;
+ }
+
+ variable name;
+ (name, indent) = env_name_indent();
+ name = chop_star(name);
+
+ variable compl;
+ if ( assoc_key_exists(nl_completion, name) )
+ compl = nl_completion[name];
+ else
+ {
+ compl = @nl_completion_type;
+ compl.pre_nl = "";
+ compl.post_nl = "";
+ }
+
+ switch (name)
+ { andelse {case "tabular" or case "tabularx"} {blooking_at("---")}:
+ () = left(3);
+ () = replace_chars(3, "\\hline");
+ }
+ {
+ push_spot();
+ variable stop_str = strtrim(compl.post_nl);
+ if (stop_str == "")
+ stop_str = strtrim(compl.pre_nl);
+ variable skip_chars = "^$(){}[]" + substr(stop_str, 1, 1);
+ variable close_stack = list_new(), open_stack = list_new();
+ forever
+ {
+ bskip_chars(skip_chars);
+ () = left(1);
+
+ if ( looking_at(stop_str) )
+ break;
+
+ variable ch = what_char(), counterpart, alt_counterpart = "";
+ switch (ch)
+ { case ')' or case ']' or case '}':
+ if ( andelse {ch == '}'} {is_escaped()} )
+ ch = "\\}";
+ else
+ ch = char(ch);
+
+ list_append(close_stack, ch, -1);
+ continue;
+ }
+ { case '\\':
+ if ( looking_at("\\end") )
+ boenv();
+ else if ( looking_at("\\begin") )
+ break;
+
+ continue;
+ }
+ { case '$':
+ if ( is_escaped() )
+ {
+ bskip_chars("\\");
+ continue;
+ }
+ else
+ {
+ if (length(close_stack) == 0)
+ {
+ list_append(close_stack, "$", -1);
+ }
+ else if (close_stack[-1] == "$")
+ list_delete(close_stack, -1);
+
+ continue;
+ }
+ }
+ { case '(': counterpart = ")"; alt_counterpart = "]"; }
+ { case '[': counterpart = "]"; alt_counterpart = ")"; }
+ { case '{':
+ if ( is_escaped() )
+ counterpart = "\\}";
+ else
+ counterpart = "}";
+ }
+
+ if (andelse {length(close_stack) != 0} {close_stack[-1] == "$"})
+ {
+ list_append(open_stack, "$", -1);
+ list_delete(close_stack, -1);
+ }
+
+ if (length(close_stack) == 0)
+ list_append(open_stack, counterpart, -1);
+ else
+ {
+ if (close_stack[-1] == counterpart or
+ close_stack[-1] == alt_counterpart)
+ list_delete(close_stack, -1);
+ else
+ list_append(open_stack, counterpart, -1);
+ }
+ }
+ pop_spot();
+
+ if (andelse {length(close_stack) != 0} {close_stack[-1] == "$"})
+ list_append(open_stack, "$", -1);
+
+ while (length(open_stack) > 0)
+ {
+ variable looking_for = list_pop(open_stack, 0);
+ if ( looking_at(looking_for) )
+ () = right( strlen(looking_for) );
+ else
+ insert(looking_for);
+ }
+
+ insert( compl.pre_nl );
+ }
+
+ trim();
+ newline();
+ whitespace( indent + calc_indention(name, compl.post_nl) );
+ insert( compl.post_nl );
+ if ( andelse {strlen(compl.post_nl) > 0}
+ {is_substr("]}", char(compl.post_nl[-1]))} )
+ () = left(1);
+}
+
+%%%%%%%%%%
+%
+% Environemts -- all between \begin{} and \end{}
+%
+
+typedef struct {
+ args, desc, deps, hook, compl
+} Env_Type;
+private variable env_list = Assoc_Type[Env_Type];
+
+static define env_register(name, args, desc, deps, hook)
+{
+ try
+ {
+ % This is a tricky way to check if all variables are strings
+ () = _typeof([name, desc, ""]);
+ }
+ catch TypeMismatchError:
+ {
+ throw InvalidParmError, "One of the given arguments has invalid type";
+ }
+ if (strlen(name) == 0)
+ throw InvalidParmError, "name can not be empty";
+ if (typeof(args) != Integer_Type)
+ throw InvalidParmError, "The argument args must be an integer";
+
+ if (typeof(deps) != String_Type and typeof(deps) != Ref_Type)
+ throw InvalidParmError, "The argument deps must be a string or a reference";
+
+ if (hook != NULL and typeof(hook) != Ref_Type)
+ throw InvalidParmError, "The argument hook must be a reference or NULL";
+
+ variable tmp;
+ if ( assoc_key_exists(env_list, name) )
+ tmp = env_list[name];
+ else
+ {
+ tmp = @Env_Type;
+ env_list[name] = tmp;
+ }
+
+ tmp.compl = name;
+ tmp.args = args;
+ tmp.deps = deps;
+ tmp.desc = desc;
+ tmp.hook = hook;
+}
+
+private define env_hook_Verbatim(name, mark_after_begin)
+{
+ variable indent = what_column() - 1;
+ if (indent > 0)
+ {
+ push_spot();
+ goto_user_mark(mark_after_begin);
+ insert("[gobble=$indent]"$);
+ pop_spot();
+ }
+}
+
+private define env_hook_star_label(name, mark_after_begin)
+{
+ if (name[-1] != '*')
+ cmd_insert("label");
+}
+
+private define env_hook_array_format(name, mark_after_begin)
+{
+ eoenv();
+ () = left(1);
+ array_edit_column_format();
+}
+
+private define env_hook_gmatrix(name, mark_after_begin)
+{
+ variable type
+ = char(get_mini_response("Which type do you want? (p) {b} [B] |v| ||V|| "));
+ if ( is_substr("pbBvV", type) )
+ {
+ push_spot();
+ goto_user_mark(mark_after_begin);
+ insert("[$type]"$);
+ pop_spot();
+ }
+}
+
+env_register("abstract", 0, "", "", NULL);
+env_register("align", 0, "Math environment with alignment", "amsmath", &env_hook_star_label());
+env_register("array", 1, "", "", &env_hook_array_format());
+env_register("bmatrix", 0, "", "amsmath", NULL);
+env_register("Bmatrix", 0, "", "amsmath", NULL);
+env_register("cases", 0, "", "amsmath", NULL);
+env_register("center", 0, "", "", NULL);
+env_register("compactdesc", 0, "", "paralist", NULL);
+env_register("compactenum", 0, "", "paralist", NULL);
+env_register("compactitem", 0, "", "paralist", NULL);
+env_register("description", 0, "", "paralist", NULL); % fixme: deps as hook
+% env_register("displaymath", 0, "", "", NULL);
+env_register("enumerate", 0, "", "paralist", NULL); % fixme: deps as hook
+env_register("figure", 0, "", "", NULL);
+env_register("flushleft", 0, "", "", NULL);
+env_register("flushright", 0, "", "", NULL);
+env_register("gather", 0, "", "amsmath", &env_hook_star_label());
+env_register("gmatrix", 0, "", "gauss", &env_hook_gmatrix());
+env_register("itemize", 0, "", "paralist", NULL); % fixme: deps as hook
+env_register("list", 0, "", "", NULL);
+env_register("longtable", 1, "", "longtable", &env_hook_array_format());
+env_register("matrix", 0, "", "amsmath", NULL);
+env_register("minipage", 1, "", "", NULL);
+env_register("picture", 0, "", "", NULL);
+env_register("pmatrix", 0, "", "amsmath", NULL);
+env_register("proof", 0, "", "", NULL);
+env_register("pspicture", 0, "A PSTricks picture", "pstricks", NULL);
+env_register("quotation", 0, "", "", NULL);
+env_register("quote", 0, "", "", NULL);
+env_register("smallmatrix", 0, "", "amsmath", NULL);
+env_register("tabbing", 0, "", "", NULL);
+env_register("table", 0, "", "", NULL);
+env_register("tabular", 1, "", "", &env_hook_array_format());
+env_register("tabularx", 2, "", "tabularx", NULL); % Fixme: hook = array_edit_column_format()
+env_register("thebibliography", 1, "", "", NULL);
+env_register("theorem", 0, "", "", NULL);
+env_register("titlepage", 0, "", "", NULL);
+env_register("verbatim", 0, "", "", NULL);
+env_register("Verbatim", 0, "", "fancyvrb", &env_hook_Verbatim());
+env_register("verse", 0, "", "", NULL);
+env_register("vmatrix", 0, "", "amsmath", NULL);
+env_register("Vmatrix", 0, "", "amsmath", NULL);
+
+private define env_lookup()
+{
+ variable default;
+ if (_NARGS >= 2)
+ default = ();
+
+ variable name = ();
+ if (strlen(name) > 0)
+ {
+ if ( assoc_key_exists(env_list, name) )
+ return env_list[name];
+
+ if (name[-1] == '*')
+ name = chop_star(name);
+ else
+ name = name + "*";
+ if ( assoc_key_exists(env_list, name) )
+ return env_list[name];
+ }
+
+ if (_NARGS >= 2)
+ return default;
+ else
+ throw InternalError, "Environment $name not found and no default given"$;
+}
+
+%!%+
+%\function{boenv}
+%\synopsis{Go to the beginning of the environment}
+%\usage{Integer_Type boenv()}
+%\description
+% This function searches for the beginning of the environment the editing
+% point is in. If it finds a "\begin{...}" it moves the editing point to the
+% begin of "\begin{...}" and returns 1. If no environment beginning is
+% found (maybe the editing point is before \begin{document}) the editing
+% point isn't moved and 0 is returned.
+%!%-
+static define boenv()
+{
+ if ( is_commented() )
+ throw UsageError, "Starting inside of a comment is not possible";
+
+ variable start_mark = create_user_mark(), open_ends = list_new();
+
+ while ( re_bsearch("\\[be][en][gd][i{]"R) ) %! Fixme: PCRE: \\(begin|end)\{
+ {
+ if ( bocomment() )
+ continue;
+
+ if ( looking_at("\\begin{" ) )
+ {
+ if (length(open_ends) == 0)
+ return;
+
+ list_delete(open_ends, -1);
+ }
+ else if ( looking_at("\\end{") )
+ list_append(open_ends, [what_line, what_column()], -1);
+ }
+
+ goto_user_mark(start_mark);
+ if (length(open_ends) > 0)
+ throw DataError, "No matching \\begin found for \\end in line " +
+ string(open_ends[-1][0]) + " column " + string(open_ends[-1][1]);
+ else
+ throw DataError, "No matching \\begin found";
+}
+
+%!%+
+%\function{eoenv}
+%\synopsis{Go to the end of the environment}
+%\usage{Integer_Type eoenv()}
+%\description
+% This function searches for the end of the environment the editing
+% point is in. If it finds a "\end{...}" it moves the editing point to the
+% begin of "\end{...}" and returns 1. If no environment end is
+% found (maybe the editing point is before \begin{document}) the editing
+% point isn't moved and 0 is returned.
+%!%-
+static define eoenv()
+{
+ if ( is_commented() )
+ throw UsageError, "Starting inside of a comment is not possible";
+
+ variable start_mark = create_user_mark(), open_begins = list_new();
+
+ if ( looking_at("\\begin{") )
+ () = right(1);
+
+ while ( re_fsearch("\\[be][en][gd][i{]"R) ) %! Fixme: PCRE: \\(begin|end)\{
+ {
+ if ( is_commented() )
+ {
+ eol();
+ continue;
+ }
+
+ if ( looking_at("\\end{" ) )
+ {
+ if (length(open_begins) == 0)
+ return;
+ list_delete(open_begins, -1);
+ }
+ else if ( looking_at("\\begin{") )
+ list_append(open_begins, [what_line, what_column], -1);
+
+ () = right(1);
+ }
+
+ goto_user_mark(start_mark);
+ if (length(open_begins) > 0)
+ throw DataError, "No matching \\end found for \\begin in line " +
+ string(open_begins[-1][0]) + " column " + string(open_begins[-1][1]);
+ else
+ throw DataError, "No matching \\end found";
+}
+
+%!%+
+%\function{env_name}
+%\synopsis{Gets the name of the current environment}
+%\usage{String_Type env_name([Integer_Type])}
+%\description
+% This function returns the name of the environment the editing point is in.
+% If it isn't within an environment, NULL is returned.
+%
+% If the optional parameter is unequal to zero the editing point is placed
+% at the beginning.
+%
+%\seealso{boenv()}
+%!%-
+static define env_name()
+{
+ variable stay_there = 0, spot = create_user_mark();
+ if (_NARGS)
+ stay_there = ();
+
+ try
+ boenv();
+ catch DataError:
+ % No \begin found
+ return NULL;
+
+ () = right(7); % skip \begin{
+ push_mark();
+ if ( ffind_char('}') )
+ {
+ variable name = bufsubstr();
+ () = left(strlen(name) + 7); % \begin{$name}
+ !if (stay_there)
+ goto_user_mark(spot);
+ return name;
+ }
+ else
+ {
+ pop_mark(1);
+ goto_user_mark(spot);
+ throw DataError, "malformed \\begin{}";
+ }
+}
+
+static define env_close ()
+{
+ variable mark = create_user_mark();
+ bskip_white();
+
+ variable e_name;
+ if ( bolp() )
+ {
+ trim();
+ variable e_indent;
+ (e_name, e_indent) = env_name_indent();
+ whitespace(e_indent);
+ }
+ else
+ {
+ goto_user_mark(mark);
+ e_name = env_name();
+ }
+ if (e_name == NULL)
+ throw UsageError, "Not within an environment";
+
+ insert("\\end{$e_name}"$);
+}
+
+static define env_insert()
+{
+ variable def_args;
+ if (_NARGS >= 2)
+ def_args = ();
+ else
+ def_args = String_Type[0];
+
+ variable name = ();
+
+ variable env_data = env_lookup(name, NULL);
+
+ if (env_data == NULL)
+ {
+ env_data = @Env_Type;
+ env_data.args = 0;
+ env_data.deps = "";
+ env_data.hook = NULL;
+ }
+
+ if (typeof(env_data.deps) == String_Type)
+ insert_pkgs(env_data.deps);
+ else
+ (@env_data.deps)(name);
+
+ variable body;
+ if ( dupmark() )
+ {
+ body = bufsubstr();
+ del_region();
+ }
+
+ variable mark = create_user_mark();
+ bskip_white();
+ variable in_one_line = not bolp();
+ if (in_one_line)
+ goto_user_mark(mark);
+ else
+ {
+ indent_line();
+ skip_white();
+ }
+
+ insert("\\begin{$name}"$);
+
+ variable point_after_begin = create_user_mark();
+
+ if (length(def_args) > 0)
+ insert("{" + strjoin(def_args, "}{") + "}");
+
+ variable point_after_insertion;
+ if (env_data.args - length(def_args) > 0)
+ {
+ insert_char('{');
+ point_after_insertion = create_user_mark();
+ loop (env_data.args - length(def_args) - 1)
+ insert("}{");
+ insert_char('}');
+ }
+
+ if (in_one_line)
+ {
+ if ( __is_initialized(&body) )
+ insert(body);
+ !if ( __is_initialized(&point_after_insertion) )
+ point_after_insertion = create_user_mark();
+ }
+ else
+ {
+ newline();
+ if ( __is_initialized(&body) )
+ {
+ push_mark();
+
+ insert(body);
+ !if ( __is_initialized(&point_after_insertion) )
+ point_after_insertion = create_user_mark();
+
+ !if ( bolp() )
+ newline();
+ indent_region();
+ }
+ else
+ {
+ variable compl;
+ if ( assoc_key_exists(nl_completion, chop_star(name)) )
+ {
+ compl = nl_completion[chop_star(name)].post_nl;
+ insert(compl);
+ }
+
+ indent_line();
+
+ !if ( __is_initialized(&point_after_insertion) )
+ {
+ if (andelse {__is_initialized(&compl)} {strlen(compl) != 0})
+ {
+ is_substr("]}", substr(compl, strlen(compl), 1));
+ dup();
+ if ( () )
+ () = left(1);
+ point_after_insertion = create_user_mark();
+ if ( () )
+ () = right(1);
+ }
+ else
+ point_after_insertion = create_user_mark();
+ }
+ newline();
+ }
+ }
+ env_close();
+ !if (in_one_line or eolp())
+ newline();
+
+ goto_user_mark(point_after_insertion);
+ if (env_data.hook != NULL)
+ (@env_data.hook)(name, point_after_begin);
+}
+
+private variable env_last_env = "";
+
+static define env_prompt()
+{
+ try
+ {
+ env_last_env = read_with_description("Select an environment:",
+ env_last_env, "",
+ make_sorted_desc_list(env_list));
+
+ if (env_last_env == "")
+ return;
+
+ variable env_data = env_lookup(env_last_env, NULL), desc;
+ if (env_data != NULL)
+ desc = env_data.desc;
+ else if (LaTeX_Register_New)
+ {
+ variable args, deps;
+ args = integer( read_mini("How much arguments this environment " +
+ "have?", "0", "") );
+ desc = read_mini("A description for the new environment:", "", "");
+ deps = read_mini("Colon separated list of packages needed for " +
+ "this environment:", "", "");
+
+ env_register(env_last_env, args, desc, deps, NULL);
+ if (andelse {LaTeX_File_New != NULL} {strlen(LaTeX_File_New) > 0})
+ {
+ variable fp = fopen(LaTeX_File_New, "a");
+ () = fprintf(fp, "latex->env_register(\"%- 21s %u, \"%s\"R, \"%s\", NULL);\n",
+ env_last_env + "\",", args, desc, deps);
+ () = fclose(fp);
+ }
+ }
+
+ env_insert(env_last_env);
+ message(desc);
+ }
+ catch UserBreakError;
+}
+
+static define env_rename()
+{
+ variable spot = create_user_mark();
+
+ try
+ {
+ variable old_name = env_name(1);
+
+ if (old_name == NULL)
+ throw UsageError, "You aren't within an environment";
+
+ variable new_name = read_with_description("Rename environment:",
+ old_name, "",
+ make_sorted_desc_list(env_list));
+ if (new_name == old_name)
+ return;
+
+ variable env_data = env_lookup(new_name, NULL);
+ if (env_data == NULL and LaTeX_Register_New)
+ {
+ variable args, desc, deps;
+ args = integer( read_mini("How much arguments this environment " +
+ "have?", "0", "") );
+ desc = read_mini("A description for the new environment:", "", "");
+ deps = read_mini("Colon separated list of packages needed for " +
+ "this environment:", "", "");
+
+ env_register(new_name, args, desc, deps, NULL);
+ if (andelse {LaTeX_File_New != NULL} {strlen(LaTeX_File_New) > 0})
+ {
+ variable fp = fopen(LaTeX_File_New, "a");
+ () = fprintf(fp, "latex->env_register(\"%- 21s %u, \"%s\"R, \"%s\", NULL);\n",
+ new_name + "\",", args, desc, deps);
+ () = fclose(fp);
+ }
+ env_data = env_lookup(new_name);
+ }
+
+ if (env_data != NULL)
+ {
+ if (typeof(env_data.deps) == String_Type)
+ insert_pkgs(env_data.deps);
+ else
+ (@env_data.deps)(new_name);
+ }
+
+ () = right(7);
+ () = replace_chars(strlen(old_name), new_name);
+
+ goto_user_mark(spot);
+ eoenv();
+
+ () = right(5);
+ () = replace_chars(strlen(old_name), new_name);
+ }
+ catch UserBreakError;
+ finally
+ goto_user_mark(spot);
+}
+
+static define env_help()
+{
+ try
+ {
+ variable env;
+ if (_NARGS)
+ env = ();
+ else
+ {
+ env = env_name();
+ if (env == NULL)
+ env = "";
+
+ env = read_with_description("Help for which environment:", env,
+ "", make_sorted_desc_list(env_list));
+ if (env == "")
+ return;
+ }
+
+ variable env_data = env_lookup(env, NULL), help;
+ if (env_data != NULL)
+ {
+ help = env_data.deps;
+ if (typeof(help) != String_Type)
+ __uninitialize(&help);
+ }
+
+ if (andelse {__is_initialized(&help)} {strlen(help) != 0})
+ pkg_help(help);
+ else
+ throw UsageError, "No information found about how to get help";
+ }
+ catch UserBreakError;
+}
+
+%%%%%%%%%%
+%
+% Command stuff, e.g. \foo[]{}
+%
+
+typedef struct {
+ args, desc, deps, hook, math, compl
+} Cmd_Type;
+private variable cmd_list = Assoc_Type[Cmd_Type];
+
+% compl: the name of the command, e.g. the string after the backslash; the
+% name compl makes it easier to pass the struct to read_with_description()
+% args: how many arguments the command has?
+% need_math: is it a command for a mathematical environment?
+% desc: a description of the command
+% deps: which packages the command depend on (colon separated list)
+% hook: NULL or a reference to a function that gets called after inserting the
+% command from inside the first brace or after the command if the
+% command has no arguments
+% Call the function with the name of the command and a mark of the
+% point after the command.
+static define cmd_register(name, args, need_math, desc, deps, hook)
+{
+ try
+ {
+ % This is a tricky way to check if all variables are strings
+ () = _typeof([name, desc, deps, ""]);
+ }
+ catch TypeMismatchError:
+ {
+ throw InvalidParmError, "One of the given arguments has invalid type";
+ }
+ if (strlen(name) == 0)
+ throw InvalidParmError, "name can not be empty";
+ if (typeof(args) != Integer_Type or typeof(need_math) != Integer_Type)
+ throw InvalidParmError, "The arguments args and need_math must be integers";
+
+ if (hook != NULL and typeof(hook) != Ref_Type)
+ throw InvalidParmError, "The argument hook must be a reference or NULL";
+
+ variable tmp;
+ if ( assoc_key_exists(cmd_list, name) )
+ tmp = cmd_list[name];
+ else
+ {
+ tmp = @Cmd_Type;
+ cmd_list[name] = tmp;
+ }
+
+ tmp.compl = name;
+ tmp.args = args;
+ tmp.math = need_math;
+ tmp.deps = deps;
+ tmp.desc = desc;
+ tmp.hook = hook;
+}
+
+() = evalfile("latex_cmds", current_namespace());
+
+private define cmd_lookup()
+{
+ variable default;
+ if (_NARGS >= 2)
+ default = ();
+
+ variable name = ();
+ if (strlen(name) > 0)
+ {
+ if ( assoc_key_exists(cmd_list, name) )
+ return cmd_list[name];
+
+ if (name[-1] == '*')
+ name = chop_star(name);
+ else
+ name = name + "*";
+ if ( assoc_key_exists(cmd_list, name) )
+ return cmd_list[name];
+ }
+
+ if (_NARGS >= 2)
+ return default;
+ else
+ throw InternalError, "Command \\$name not found and no default given"$;
+}
+
+private define insert_space_after_cmd_hook(fun);
+private define insert_space_after_cmd_hook(fun)
+{
+ if (andelse {typeof(fun) == String_Type} {fun == "self_insert_cmd"}
+ { ('A' <= LAST_CHAR and LAST_CHAR <= 'Z') or
+ ('a' <= LAST_CHAR and LAST_CHAR <= 'z') })
+ insert_char(' ');
+
+ remove_from_hook("_jed_before_key_hooks", &insert_space_after_cmd_hook());
+}
+
+static define cmd_insert()
+{
+ variable prefix = prefix_argument(0);
+
+ variable def_args, ins_pkg;
+ if (_NARGS >= 3)
+ def_args = ();
+ else
+ def_args = String_Type[0];
+
+ if (_NARGS >= 2)
+ ins_pkg = ();
+ else
+ ins_pkg = 1;
+
+ variable name = ();
+
+ variable cmd_data = cmd_lookup(name, NULL);
+ if (cmd_data == NULL)
+ {
+ insert_char('\\');
+ insert(name);
+
+ loop (prefix)
+ insert("[]");
+
+ if (prefix != 0)
+ () = left(2 * prefix - 1);
+
+ return;
+ }
+
+ if (ins_pkg)
+ insert_pkgs(cmd_data.deps);
+ else
+ !if ( orelse {cmd_data.deps == ""} {pkg_loaded(cmd_data.deps)} )
+ throw ApplicationError, "The depencies \"" + cmd_data.deps +
+ "\" for the command \"$name\" aren't satisfied"$;
+
+ if ( andelse {cmd_data.args != 0} {dupmark()} )
+ {
+ def_args = [def_args, bufsubstr()];
+ del_region();
+ }
+
+ variable behind_insertion;
+
+ if (andelse {cmd_data.math} {not is_math()} )
+ {
+ !if ( blooking_at("$") )
+ insert("$$");
+
+ behind_insertion = create_user_mark();
+ () = left(1);
+ }
+
+ insert_char('\\');
+ insert(name);
+
+ push_spot();
+ variable next_point;
+
+ if (prefix)
+ {
+ insert_char('[');
+ next_point = create_user_mark();
+ loop (prefix - 1)
+ insert("][");
+ insert_char(']');
+ }
+
+ if (length(def_args) > 0)
+ insert("{" + strjoin(def_args, "}{") + "}");
+
+ loop (cmd_data.args - length(def_args))
+ insert("{}");
+
+ !if ( __is_initialized(&behind_insertion) )
+ behind_insertion = create_user_mark();
+
+ !if ( __is_initialized(&next_point) )
+ {
+ if (cmd_data.args - length(def_args) > 0)
+ {
+ () = left(2 * (cmd_data.args - length(def_args)) - 1);
+ next_point = create_user_mark();
+ }
+ else
+ next_point = behind_insertion;
+ }
+
+ pop_spot();
+
+ if (cmd_data.hook == NULL)
+ goto_user_mark(next_point);
+ else
+ (@cmd_data.hook)(name, behind_insertion);
+
+ if (LaTeX_Auto_Space_After_Commands)
+ {
+ () = left(1);
+ variable ch = what_char();
+ () = right(1);
+
+ if ( ('A' <= ch and ch <= 'Z') or ('a' <= ch and ch <= 'z') )
+ add_to_hook("_jed_before_key_hooks", &insert_space_after_cmd_hook());
+ }
+}
+
+private variable cmd_last_cmd = "";
+
+static define cmd_prompt()
+{
+ try
+ {
+ cmd_last_cmd = read_with_description("Select a command:", cmd_last_cmd, "",
+ make_sorted_desc_list(cmd_list));
+
+ if (cmd_last_cmd == "")
+ return;
+
+ variable cmd_data = cmd_lookup(cmd_last_cmd, NULL), desc;
+ if (cmd_data != NULL)
+ desc = cmd_data.desc;
+ else if (LaTeX_Register_New)
+ {
+ variable args, math, deps;
+ args = integer( read_mini("How much arguments this command " +
+ "have?", "0", "") );
+ variable dflt;
+ math = int(is_math());
+ if (math)
+ dflt = "Y/n";
+ else
+ dflt = "y/N";
+
+ switch ( get_mini_response("Is this a mathematic command? (" +
+ dflt + ") ") )
+ { case 7: throw UserBreakError; }
+ { case 'Y' or case 'y': math = 1; }
+ { case 'N' or case 'n': math = 0; }
+
+ % Fixme: This should be read_with_description() with the
+ % SYNOPSIS as description
+ variable hook_as_string =
+ read_string_with_completion("Name of a hook (leave if empty for none)",
+ "", strjoin("latex->" +
+ _apropos("latex",
+ "cmd_hook", 3),
+ ","));
+ variable hook = __get_reference(hook_as_string);
+ if ( __is_callable(hook) )
+ hook_as_string = "&" + hook_as_string + "()";
+ else
+ {
+ hook = NULL;
+ hook_as_string = "NULL";
+ }
+
+ desc = read_mini("A description for the new command:", "", "");
+ deps = read_mini("Colon separated list of packages needed for " +
+ "this command:", "", "");
+
+ cmd_register(cmd_last_cmd, args, math, desc, deps, hook);
+ if (andelse {LaTeX_File_New != NULL} {strlen(LaTeX_File_New) > 0})
+ {
+ variable fp = fopen(LaTeX_File_New, "a");
+ () = fprintf(fp, "latex->cmd_register(\"%- 21s %u, %u, \"%s\"R, \"%s\", %s);\n",
+ cmd_last_cmd + "\",", args, math, desc, deps,
+ hook_as_string);
+ () = fclose(fp);
+ }
+ }
+
+ cmd_insert(cmd_last_cmd);
+ message(desc);
+ }
+ catch UserBreakError;
+}
+
+static define cmd_parse_args(opt_args, req_args)
+{
+ skip_chars(" \n\t");
+ variable o_args = list_new();
+ while ( andelse {opt_args > 0} {looking_at_char('[')} )
+ {
+ push_mark();
+ try
+ {
+ forever
+ {
+ () = right(1);
+ skip_chars("^{]");
+ !if ( looking_at_char('{') or looking_at_char(']') )
+ throw DataError, "No matching ] found";
+
+ if ( is_escaped() )
+ continue;
+
+ if ( looking_at_char(']') )
+ {
+ list_append(o_args,
+ str_compress_tex( substr(bufsubstr(), 2, -1) ),
+ -1);
+ push_mark();
+ break;
+ }
+ else
+ fsearch_matching_brace();
+ }
+ }
+ finally
+ {
+ pop_mark(0);
+ }
+ () = right(1);
+ skip_chars(" \n\t");
+ --opt_args;
+ }
+
+ variable r_args = list_new();
+ while (req_args > 0)
+ {
+ switch ( what_char() )
+ { case '{':
+ () = right(1);
+ push_mark();
+ try
+ {
+ fsearch_matching_brace();
+ list_append(r_args, str_compress_tex(bufsubstr()), -1);
+ --req_args;
+ push_mark();
+ }
+ finally
+ pop_mark(0);
+
+ () = right(1);
+ }
+ { case '\\':
+ push_mark();
+ () = right(1);
+ skip_chars(TeX_Command_Chars);
+ list_append(r_args, bufsubstr(), -1);
+ --req_args;
+ }
+ { case '%':
+ () = down(1);
+ skip_white();
+ }
+ { case ' ' or case '\n' or case '\t':
+ skip_chars(" \n\t");
+ }
+ {
+ list_append(r_args, char( what_char() ), -1);
+ --req_args;
+ () = right(1);
+ }
+ }
+
+ return (o_args, r_args);
+}
+
+static define cmd_help()
+{
+ try
+ {
+ variable cmd;
+ if (_NARGS)
+ cmd = ();
+ else
+ {
+ push_spot();
+ bskip_chars(TeX_Command_Chars);
+ push_mark();
+ skip_chars(TeX_Command_Chars);
+ cmd = bufsubstr();
+ pop_spot();
+
+ cmd = read_with_description("Help for which command:", cmd, "",
+ make_sorted_desc_list(cmd_list));
+ if (cmd == "")
+ return;
+ }
+
+ variable cmd_data = cmd_lookup(cmd, NULL), help;
+ if (cmd_data != NULL)
+ {
+ help = cmd_data.deps;
+ if (typeof(help) != String_Type)
+ __uninitialize(&help);
+ }
+
+ if (andelse {__is_initialized(&help)} {strlen(help) != 0})
+ pkg_help(help);
+ else
+ throw UsageError, "No information found about how to get help";
+ }
+ catch UserBreakError;
+}
+
+%!%+
+% Check if the editing point stays on a command. In this case return the
+% command, otherwise NULL
+%!%-
+static define is_command()
+{
+ !if ( re_looking_at("\\[$TeX_Command_Chars]"R$) )
+ {
+ !if ( re_looking_at("[$TeX_Command_Chars]"$) )
+ return NULL;
+
+ variable mark = create_user_mark();
+
+ bskip_chars(TeX_Command_Chars);
+ !if ( andelse {left(1)} {looking_at_char('\\')} )
+ {
+ goto_user_mark(mark);
+ return NULL;
+ }
+ }
+
+ push_spot();
+ push_mark();
+ () = right(1);
+ skip_chars(TeX_Command_Chars);
+ bufsubstr();
+ pop_spot();
+ return ();
+}
+
+%%%%%%%%%%
+%
+% All about fonts
+%
+
+static define font_resize(decrease)
+{
+ variable sizes="tiny,scriptsize,footnotesize,small,normalsize,large,Large,LARGE,huge,Huge";
+ variable start_mark = create_user_mark(), is_region = markp();
+
+ if (is_region) {
+ check_region(0);
+ exchange_point_and_mark();
+ } else if (orelse {looking_at_char('\\')} {bfind_char('\\')} )
+ ()=right(1);
+
+ variable mark = create_user_mark();
+ push_mark();
+ skip_word_chars();
+ variable pos = is_list_element(sizes, bufsubstr(), ',');
+
+ if ( pos ) {
+ if (decrease)
+ pos -= 2;
+
+ if (pos == -1 or pos == 10) {
+ goto_user_mark(start_mark);
+ error("Font resizing not possible");
+ }
+
+ push_mark();
+ goto_user_mark(mark);
+ del_region();
+ }
+ else {
+ if (is_region)
+ insert_char('{');
+ else
+ % Maybe bfind_char doesn't find the correct \ - don't write there, it
+ % might be wrong
+ goto_user_mark(start_mark);
+
+ insert_char('\\');
+ if (decrease)
+ pos = 3; % small
+ else
+ pos = 5; % large
+ }
+
+ insert( string(extract_element(sizes, pos, ',')) );
+
+ mark = create_user_mark();
+ skip_non_word_chars();
+ if ( mark == create_user_mark() and not eolp() )
+ insert_char(' ');
+
+ goto_user_mark(start_mark);
+
+ if (is_region)
+ insert_char('}');
+}
+
+static define font_cmd()
+{
+ try
+#ifexists jmini_prompt_string
+ cmd_insert( jmini_prompt_string("Select a font command:", "", "",
+ ["bfseries", "emph", "itshape", "mathbf", "mathcal", "mathit",
+ "mathnormal", "mathrm", "mathsf", "mathtt", "mdseries",
+ "normalfont", "rmfamily", "scshape", "sffamily", "slshape",
+ "textbf", "textit", "textmd", "textnormal", "textrm",
+ "textsc", "textsf", "textsl", "texttt", "textup", "ttfamily",
+ "upshape"]) );
+#else
+ cmd_insert( read_with_completion("textrm,rmfamily,textit,"+
+ "itshape,emph,textmd,mdseries,textbf,bfseries,textup,"+
+ "upshape,textsl,slshape,textsf,sffamily,textsc,"+
+ "scshape,texttt,ttfamily,textnormal,normalfont,mathrm"+
+ "mathbf,mathsf,mathtt,mathit,mathnormal,mathcal",
+ "Select a font command:", "", "", 's') );
+#endif
+ catch UserBreakError: {}
+}
+
+static define templ_insert(file)
+{
+ push_mark();
+ narrow_to_region();
+ try
+ {
+ !if ( insert_file(file) )
+ return;
+
+ bob();
+ if ( fsearch("%:default:classopt:") )
+ {
+ push_mark();
+ () = right(19);
+ if ( looking_at(",%") )
+ {
+ () = right(2);
+ del_region();
+ if ( strlen(LaTeX_Default_Class_Options) )
+ insert("," + LaTeX_Default_Class_Options);
+ }
+ else
+ {
+ if ( looking_at("[%") )
+ {
+ () = right(2);
+ del_region();
+ if ( strlen(LaTeX_Default_Class_Options) )
+ insert("[" + LaTeX_Default_Class_Options + "]");
+ }
+ else
+ pop_mark(1);
+ }
+ }
+
+ if ( bol_fsearch("%:default:pkgs:%\n") )
+ {
+ % set a marker for insert_pkgs where it should place the packages
+ % if no other packages are present
+ () = replace_chars(16, "\\usepackage{JLM marker}");
+ bol();
+ insert_pkgs(LaTeX_Default_Packages);
+ deln(24); % delete the marker line (with \n)
+ }
+
+ bob();
+ if ( fsearch("%:start:%") )
+ deln(9);
+ }
+ finally
+ widen_region();
+}
+
+%%%%%%%%%%
+%
+% All about arrays like tabular or matrix
+%
+
+private define array_what_column()
+{
+ variable start = create_user_mark(), num = 1;
+
+ forever
+ {
+ bskip_chars("^&}\\");
+ !if ( left(1) ) % == bobp()
+ break;
+ if ( looking_at_char('&') and not is_escaped() )
+ {
+ ++num;
+ continue;
+ }
+ if ( looking_at_char('}') and not is_escaped() )
+ {
+ bsearch_matching_brace();
+ continue;
+ }
+ if ( looking_at("\\end") )
+ {
+ boenv();
+ continue;
+ }
+ if ( looking_at("\\multicolumn") )
+ {
+ push_spot();
+ () = right(13);
+ push_mark();
+ skip_chars("0-9");
+ num += integer( bufsubstr() );
+ pop_spot();
+ continue;
+ }
+ if ( orelse {looking_at("\\\\")} {looking_at("\\begin")} )
+ % This must be the begin of the array environment
+ break;
+ }
+
+ goto_user_mark(start);
+ return num;
+}
+
+private variable array_columns = Assoc_Type[Integer_Type, 0];
+
+array_columns["align"] = 20;
+array_columns["array"] = -1;
+array_columns["bmatrix"] = 10; % [ matrix ]
+array_columns["Bmatrix"] = 10; % \{ matrix \}
+array_columns["cases"] = 2;
+array_columns["longtable"] = -1;
+array_columns["matrix"] = 10;
+array_columns["pmatrix"] = 10; % ( matrix )
+array_columns["smallmatrix"] = 10; % \footnotesize matrix
+array_columns["tabular"] = -1;
+array_columns["tabular*"] = -2;
+array_columns["tabularx"] = -2;
+array_columns["vmatrix"] = 10; % | matrix |
+array_columns["Vmatrix"] = 10; % || matrix ||
+
+static define array_new_cell()
+{
+ variable start = create_user_mark();
+ variable e_name = env_name(1);
+
+ variable num_cols;
+ if ( assoc_key_exists(array_columns, e_name) )
+ num_cols = array_columns[e_name];
+ else
+ num_cols = array_columns[ chop_star(e_name) ];
+
+ if (num_cols < 0)
+ {
+ () = right(strlen(e_name) + 8); % \begin{$e_name}
+ (,) = cmd_parse_args(1, -num_cols - 1);
+ !if ( looking_at_char('{') )
+ {
+ goto_user_mark(start);
+ throw InternalError;
+ }
+ () = right(1);
+
+ num_cols = 0;
+ variable factor = 1, factors = {};
+ forever
+ {
+ variable point = _get_point();
+ skip_chars("a-zA-Z");
+ num_cols += factor * (_get_point() - point);
+
+ switch ( what_char() )
+ { case '}':
+ if (length(factors) == 0)
+ break;
+ factor = list_pop(factors);
+ }
+ { case '*':
+ list_append(factors, factor, -1);
+ () = right(2);
+ push_mark();
+ skip_chars("0-9");
+ factor *= integer( bufsubstr() );
+ () = right(1);
+ }
+ () = right(1);
+ if ( looking_at_char('{') )
+ {
+ fsearch_matching_brace();
+ () = right(1);
+ }
+ }
+ }
+ goto_user_mark(start);
+
+ if (array_what_column() < num_cols)
+ insert("& ");
+ else
+ {
+ insert("\\\\\n");
+ indent_line();
+ }
+}
+
+static define array_next_cell()
+{
+ forever
+ {
+ skip_chars("^&{\\");
+ if ( eobp() )
+ % This is very curious, better we do nothing
+ return;
+
+ if ( andelse {looking_at_char('&')} {not is_escaped()} )
+ {
+ () = right(1);
+ return;
+ }
+ if ( looking_at("\\\\") )
+ {
+ () = right(2);
+ skip_chars(" \t\n");
+ if ( looking_at("\\hline") )
+ {
+ () = right(6);
+ skip_chars(" \t\n");
+ }
+ if ( looking_at("\\end") )
+ {
+ bskip_chars(" \t");
+ if ( bolp() )
+ () = left(1);
+ }
+ return;
+ }
+ if ( looking_at("\\end") )
+ {
+ bskip_chars(" \t");
+ if ( bolp() )
+ () = left(1);
+ array_new_cell();
+ return;
+ }
+ if ( looking_at("\\begin") )
+ {
+ eoenv();
+ () = ffind_char('}');
+ continue;
+ }
+ if ( andelse {looking_at_char('{')} {not is_escaped()} )
+ {
+ fsearch_matching_brace();
+ continue;
+ }
+
+ % this must be the begin of a command
+ () = right(1);
+ }
+}
+
+static define array_prev_cell()
+{
+ forever
+ {
+ bskip_chars("^&}\\");
+ !if ( left(1) ) % == bobp()
+ break;
+ if ( andelse {looking_at_char('&')} {not is_escaped()} )
+ break;
+ if ( andelse {looking_at_char('}')} {not is_escaped()} )
+ {
+ bsearch_matching_brace();
+ continue;
+ }
+ if ( looking_at("\\end") )
+ {
+ boenv();
+ continue;
+ }
+ if ( looking_at("\\begin") )
+ {
+ % This must be the begin of the array environment
+ () = right(6);
+ do
+ {
+ fsearch_matching_brace();
+ () = right(1);
+ } while ( looking_at_char('{') );
+ break;
+ }
+ if ( looking_at("\\\\") )
+ break;
+ }
+}
+
+static define array_edit_column_format()
+{
+ variable start = create_user_mark();
+ variable e_name = env_name(1);
+
+ variable num_cols;
+ if ( assoc_key_exists(array_columns, e_name) )
+ num_cols = array_columns[e_name];
+ else
+ num_cols = array_columns[ chop_star(e_name) ];
+
+ if (num_cols >= 0)
+ {
+ goto_user_mark(start);
+ throw UsageError, "environment has no column definition";
+ }
+
+ () = right(strlen(e_name) + 8); % \begin{$e_name}
+ variable col;
+ (,col) = cmd_parse_args(1, -num_cols);
+ col = col[-1];
+ try
+ {
+ variable col_len = strlen(col);
+ col = read_mini("Column format:", "", col);
+ if (col == "")
+ return;
+
+ () = left(col_len + 1); % $col}
+ () = replace_chars(col_len, col);
+ }
+ catch UserBreakError;
+ finally
+ {
+ goto_user_mark(start);
+ }
+}
+
+%%%%%%%%%%
+%
+% Label
+%
+
+private variable label_insert_mark = NULL;
+
+static define label_insert_at_mark()
+{
+ if (label_insert_mark == NULL) {
+ label_insert_mark = create_user_mark();
+ message("Now go to the point where you want to set the label and hit ^Clm again");
+ }
+ else {
+ cmd_insert("label");
+ if (andelse {left(1)} {looking_at_char('}')}) {
+ push_mark();
+ ()=bfind_char('{');
+ ()=right(1);
+ variable label = bufsubstr();
+
+ goto_user_mark(label_insert_mark);
+
+ if ( pkg_loaded("hyperref") )
+ "\\autoref{";
+ else if ( andelse {label[[0:1]] == "eq"} {pkg_loaded("amsmath")} )
+ "\\eqref{";
+ else
+ "\\ref{";
+
+ insert(() + label + "}");
+ }
+ label_insert_mark = NULL;
+ }
+}
+
+static define label_ref()
+{
+ if ( pkg_loaded("hyperref") )
+ cmd_insert("autoref");
+ else
+ cmd_insert("ref");
+}
+
+%%%%%%%%%%
+%
+% Folding
+%
+static define fold(f_lvl);
+static define fold(f_lvl)
+{
+ variable start_mark = create_user_mark();
+ try
+ {
+ while (f_lvl < 0)
+ {
+ variable mark = create_user_mark();
+ switch ( env_name(1) )
+ { case NULL:
+ throw UsageError, "There's no level below the file level";
+ }
+ { case "document":
+ goto_user_mark(mark);
+ break;
+ }
+ ++f_lvl;
+ }
+ if (f_lvl < 0)
+ {
+ throw NotImplementedError;
+ forever
+ {
+ !if ( search_not_commented(&re_bsearch,
+ "\\[cs][heu][acb][pts]"R, 0) ) % Fixme: PCRE
+ {
+ break;
+ }
+ if ( looking_at("\\chapter") )
+ f_lvl += 2;
+ else if ( looking_at("\\section") )
+ f_lvl += 3;
+ else if ( looking_at("\\subsection") )
+ f_lvl += 4;
+ else if ( looking_at("\\subsubsection") )
+ f_lvl += 5;
+ else
+ continue;
+ }
+ if (f_lvl < 0)
+ throw UsageError, "There's no level below the file level";
+
+ switch (f_lvl)
+ { case 1: "\\begin{document}"; }
+ { case 2: "\\chapter" or "\\section"; }
+ { case 1: "\\begin{document}"; }
+ }
+
+ variable first_line, level;
+ switch ( env_name(1) )
+ { case "document":
+ variable beg_doc_mark = create_user_mark(), start_level;
+
+ variable level_names = ["chapter", "section", "subsection", "subsubsection"];
+ while (length(level_names) > 0)
+ {
+ if ( fsearch("\\" + level_names[0]) )
+ break;
+
+ level_names = level_names[[1:]];
+ }
+
+ % add the file level (0) and the begin--end{document} level (1)
+#if (_slang_version < 20007)
+ level_names = ["\\file-level", "\\doc-level", level_names];
+#else
+ level_names = [NULL, NULL, level_names];
+#endif
+
+ goto_user_mark(start_mark);
+ forever
+ {
+ if ( not search_not_commented(&re_bsearch,
+ "\\[cs][heu][acb][pts]"R, 0) or % Fixme: PCRE
+ create_user_mark() < beg_doc_mark)
+ {
+ goto_user_mark(beg_doc_mark);
+ start_level = 1;
+ () = right(1);
+ break;
+ }
+ () = right(1);
+ push_mark();
+ skip_chars(TeX_Command_Chars);
+
+ start_level = wherefirst(level_names == chop_star( bufsubstr() ));
+ if (start_level != NULL)
+ {
+ (,) = cmd_parse_args(1,1);
+ break;
+ }
+ }
+ f_lvl += start_level;
+
+ if (f_lvl == 1)
+ % folding level 1 is easy
+ {
+ () = down(1);
+ push_mark();
+ eoenv();
+ () = up(1);
+ set_region_hidden(1);
+ return;
+ }
+
+ if (start_level == f_lvl)
+ % if we start on the fold level, we must start with a mark
+ {
+ () = down(1);
+ push_mark();
+ first_line = what_line;
+ }
+ level = start_level;
+ forever
+ {
+ !if ( search_not_commented(&re_fsearch,
+ "\\[cseb][heun][acbdg][ptsi{]"R, 1) ) % Fixme: PCRE
+ eob();
+
+ variable last_level = level;
+
+ () = right(1);
+ if ( looking_at("begin{") )
+ ++level;
+ else if ( looking_at("end{document}") or eobp() )
+ level = 0;
+ else if ( looking_at("end{") )
+ {
+ --level;
+ if (f_lvl == level)
+ % this is not a barrier like \section that stops
+ % and starts a folding region
+ continue;
+ }
+ else
+ {
+ push_mark();
+ skip_chars(TeX_Command_Chars);
+
+ level = wherefirst(level_names == chop_star( bufsubstr() ));
+ if (level == NULL)
+ {
+ level = last_level;
+ continue;
+ }
+
+ (,) = cmd_parse_args(1,1);
+ }
+
+ % f_lvl <= last_level: we come from a level where folding
+ % is active
+ % level <= f_lvl: level < f_lvl or level == f_lvl
+ % level < f_lvl: we jump to a level where folding is
+ % inactive
+ % level == f_lvl: we jumped across a barrier that is on
+ % f_lvl - 1---it must become visible
+ if (level <= f_lvl and f_lvl <= last_level)
+ {
+ push_spot();
+ () = up(1);
+ if (what_line <= first_line)
+ % there is nothing to fold
+ pop_mark(0);
+ else
+ set_region_hidden(1);
+ pop_spot();
+ }
+
+ if (level < start_level)
+ break;
+
+ % last_level < f_lvl and f_lvl <= level:
+ % we come from a level where folding is inactive and
+ % continue on a level where folding is active
+ % level == f_lvl and f_lvl <= last_level:
+ % we come from a level where folding is active and
+ % jumped across a barrier on f_lvl - 1 that must
+ % become visible
+ if ((last_level < f_lvl and f_lvl <= level) or
+ (level == f_lvl and f_lvl <= last_level))
+ {
+ () = down(1);
+ push_mark();
+ first_line = what_line;
+ }
+ }
+ }
+ { case NULL:
+ doc_find();
+ variable in_preample = create_user_mark() < start_mark;
+
+ if (in_preample)
+ {
+ if (f_lvl != 0)
+ return;
+ }
+ else if (f_lvl == 0)
+ throw InvalidParmError,
+ "Folding the while file is not supported";
+
+ if (f_lvl <= 1)
+ {
+ (,) = cmd_parse_args(1,1);
+ () = down(1);
+ push_mark();
+ first_line = what_line;
+ !if ( search_not_commented(&fsearch, "\\begin{document}", 1) )
+ {
+ % fixme: throw
+ pop_mark(0);
+ return;
+ }
+ push_spot();
+ () = up(1);
+ if (what_line <= first_line)
+ pop_mark(0);
+ else
+ set_region_hidden(1);
+ pop_spot();
+
+ if (in_preample)
+ return;
+ }
+ else !if ( search_not_commented(&fsearch, "\\begin{document}", 1) )
+ {
+ % fixme: throw
+ return;
+ }
+
+ () = right(1);
+ fold(f_lvl - 1);
+ }
+ {
+ level = 0;
+ do
+ {
+ if ( looking_at("\\begin{") )
+ {
+ if (level < f_lvl)
+ ++level;
+ else
+ {
+ () = down(1);
+ push_mark();
+ first_line = what_line;
+ eoenv();
+ push_spot();
+ () = up(1);
+ if (what_line <= first_line)
+ % there is nothing to fold
+ pop_mark(0);
+ else
+ set_region_hidden(1);
+ pop_spot();
+ }
+ }
+ else if ( looking_at("\\end{") )
+ --level;
+ () = right(1);
+ }
+ while ( andelse {level > 0} {re_fsearch("\\[be][en][gd]"R)} );
+ }
+ }
+ finally
+ {
+ goto_user_mark(start_mark);
+ if ( is_line_hidden() )
+ skip_hidden_lines_backward(1);
+ }
+}
+
+%%%%%%%%%%
+%
+% Helping stuff
+%
+
+%!%+
+%\variable{User_Mark line_mark}
+%\synopsis{holds the mark of the current line}
+%\description
+% we need this variable as buffer for the line mark.
+% if the line mark isn't associated with a variable it isn't shown
+%
+%\seealso{update_log_hook()}
+%!%-
+private variable line_mark;
+
+%!%+
+%\function{update_log_hook}
+%\synopsis{Marks the current line}
+%\usage{update_log_hook()}
+%\description
+% This function marks the current line for highlighting.
+%
+% It is used in the buffers with the output of latex and other programms
+% to show better the line the cursor is in.
+%!%-
+private define update_log_hook()
+{
+ line_mark = create_line_mark(color_number("region"));
+}
+
+private variable TEXDOC_KEYMAP = "texdoc-help";
+!if ( keymap_p(TEXDOC_KEYMAP) ) {
+ make_keymap(TEXDOC_KEYMAP);
+
+ definekey("latex->texdoc_show()", "g", TEXDOC_KEYMAP);
+ definekey("latex->texdoc_show()", "\n", TEXDOC_KEYMAP);
+ definekey("latex->texdoc_show()", "\r", TEXDOC_KEYMAP);
+
+ definekey("delbuf(whatbuf());call(\"delete_window\")", "q", TEXDOC_KEYMAP);
+ definekey("delbuf(whatbuf());call(\"delete_window\")", "c", TEXDOC_KEYMAP);
+ definekey("delbuf(whatbuf());call(\"delete_window\")", "^G", TEXDOC_KEYMAP);
+}
+
+static define texdoc_show()
+{
+ variable file = line_as_string();
+ delbuf( whatbuf() );
+ call("delete_window");
+
+ variable file_bn = path_basename(file);
+ variable ext = path_extname(file_bn);
+ if ( is_list_element(".gz,.bz2", ext, ',') )
+ {
+ file_bn = path_sans_extname(file_bn);
+ ext = path_extname(file_bn);
+ }
+
+ if (file_bn == "README" or is_list_element(".tex,.txt", ext, ','))
+ {
+ () = find_file(file);
+ return;
+ }
+
+ () = system("texdoc '$file' &"$);
+}
+
+private define texdoc_run(td_arg)
+{
+ try
+ {
+ variable pattern = read_mini("Search pattern:", "", "");
+ pop2buf("*Texdoc help*");
+ set_readonly(0);
+ erase_buffer();
+ () = run_shell_cmd("texdoc "+td_arg+" '"+pattern+"'");
+
+ use_keymap(TEXDOC_KEYMAP);
+ set_buffer_hook("update_hook", &update_log_hook);
+ set_buffer_modified_flag(0);
+ set_readonly(1);
+ bob();
+ }
+ catch UserBreakError:
+ { }
+}
+
+static define texdoc_help()
+{
+ texdoc_run("-l");
+}
+
+static define texdoc_search()
+{
+ texdoc_run("-s");
+}
+
+static define texdoc(what)
+{
+ () = system("texdoc '$what' &"$);
+}
+
+static define info_page()
+{
+ info_reader();
+ if (_NARGS)
+ {
+ try
+ {
+ "(latex)";
+ exch;
+ info_find_node( () + () );
+ }
+ catch AnyError:
+ info_find_node("(latex)Top");
+ }
+ else
+ info_find_node("(latex)Top");
+}
+
+%%%%%%%%%%
+%
+% Keyboard stuff
+%
+
+static define insert_quote()
+{
+ if ( orelse {is_escaped()} {is_verbatim()}
+ {andelse {LAST_CHAR != '"'} {LAST_CHAR != '`'}} )
+ {
+ call("self_insert_cmd");
+ return;
+ }
+
+ variable lang = NULL;
+ if ( pkg_loaded("babel") )
+ {
+ variable opt = pkg_options("babel");
+ if (opt != "")
+ lang = strchop(opt, ',', '\0')[-1];
+ else
+ {
+ (opt,) = doc_options_class();
+ if (opt != "")
+ {
+ variable array = strchop(opt, ',', '\0');
+#ifexists array_reverse
+ array_reverse(array);
+#endif
+ foreach opt (array)
+ if ( is_list_element("ngerman,german,french,francais,frenchb",
+ opt, ',') )
+ {
+ lang = opt;
+#ifnexists array_reverse
+ break;
+#endif
+ }
+ }
+ }
+ }
+ else if ( orelse {pkg_loaded("ngerman")} {pkg_loaded("german")} )
+ lang = "german";
+
+ variable lquote, rquote;
+ switch (lang)
+ { case "french" or case "francais":
+ switch (LAST_CHAR)
+ { case '"': lquote = "<<~"; rquote = "~>>"; }
+ { case '`': lquote = "<~"; rquote = "~>"; }
+ }
+ { case "frenchb":
+ switch (LAST_CHAR)
+ { case '"': lquote = "\\og"; rquote = "\\fg"; }
+ { case '`': lquote = "`"; rquote = "'"; }
+ }
+ { case "german" or case "ngerman":
+ switch (LAST_CHAR)
+ { case '"': lquote = "\"`"; rquote = "\"'"; }
+ { case '`': lquote = "\\glq"; rquote = "\\grq"; }
+ }
+ { case "russian":
+ switch (LAST_CHAR)
+ { case '"': lquote = "\"`"; rquote = "\"'"; }
+ { case '`': lquote = "`"; rquote = "'"; }
+ }
+ { % case "english":
+ switch (LAST_CHAR)
+ { case '"': lquote = "``"; rquote = "''"; }
+ { case '`': lquote = "`"; rquote = "'"; }
+ }
+
+ variable start_mark = create_user_mark();
+ variable quote_sign = lquote, search = &bsearch();
+ forever
+ {
+ !if ( @search(quote_sign) )
+ break;
+
+ if ( is_commented() )
+ continue;
+
+ if (quote_sign == lquote)
+ {
+ () = left(1);
+ if ( looking_at( substr(quote_sign, 1, 1) ) ) % ` \subset ``, ' \subset ''
+ continue;
+ quote_sign = rquote;
+ search = &fsearch();
+ }
+ else
+ {
+ if ( looking_at( quote_sign + substr(quote_sign, strlen(quote_sign), 1) ) ) % ` \subset ``, ' \subset ''
+ () = right(1);
+ else
+ {
+ if (create_user_mark() < start_mark)
+ quote_sign = lquote;
+ break;
+ }
+ }
+ }
+
+ goto_user_mark(start_mark);
+ if (substr(quote_sign, 1, 1) == "\\")
+ cmd_insert( substr(quote_sign, 2, -1) );
+ else
+ insert(quote_sign);
+}
+
+static define insert_dollar()
+{
+ if ( orelse {is_escaped()} {is_verbatim()} {not is_math()} )
+ {
+ call("self_insert_cmd");
+ return;
+ }
+
+#ifexists abbrev_table_p
+ call("self_insert_cmd"); % expand abbreviations
+ () = left(1);
+ del();
+#endif
+
+ push_spot();
+ variable close_stack = list_new(), open_stack = list_new();
+ forever
+ {
+ bskip_chars("^$(){}[]");
+ () = left(1);
+
+ variable ch = what_char(), counterpart, alt_counterpart = "";
+ switch (ch)
+ { case ')' or case ']' or case '}':
+ if ( andelse {ch == '}'} {is_escaped()} )
+ ch = "\\}";
+ else
+ ch = char(ch);
+
+ list_append(close_stack, ch, -1);
+ continue;
+ }
+ { case '$':
+ if ( is_escaped() )
+ continue;
+ else
+ break;
+ }
+ { case '(': counterpart = ")"; alt_counterpart = "]"; }
+ { case '[': counterpart = "]"; alt_counterpart = ")"; }
+ { case '{':
+ if ( is_escaped() )
+ counterpart = "\\}";
+ else
+ counterpart = "}";
+ }
+
+ if (length(close_stack) == 0)
+ list_append(open_stack, counterpart, -1);
+ else
+ {
+ if (close_stack[-1] == counterpart or
+ close_stack[-1] == alt_counterpart)
+ list_delete(close_stack, -1);
+ else
+ list_append(open_stack, counterpart, -1);
+ }
+ }
+
+ if (BLINK)
+ {
+ update_sans_update_hook(0);
+ () = input_pending(5);
+ }
+
+ pop_spot();
+
+ while (length(open_stack) > 0)
+ {
+ variable looking_for = list_pop(open_stack, 0);
+ if ( looking_at(looking_for) )
+ () = right( strlen(looking_for) );
+ else
+ insert(looking_for);
+ }
+ if ( looking_at_char('$') )
+ () = right(1);
+ else
+ insert_char('$');
+}
+
+static define insert_without_spaces()
+{
+ variable insert_backslash = is_escaped();
+
+ if (insert_backslash xor (LAST_CHAR == ',' or LAST_CHAR == ' '))
+ {
+ call("self_insert_cmd");
+ return;
+ }
+
+ if (insert_backslash)
+ {
+ () = left(1);
+ del();
+ }
+
+ trim();
+ if ( andelse {bolp()} {left(1)} )
+ {
+ del();
+ trim();
+ }
+
+ if (insert_backslash)
+ insert_char('\\');
+
+ call("self_insert_cmd");
+
+ update(1);
+ forever
+ {
+ variable ch = getkey();
+ if (ch != ' ' and ch != '\t' and ch != '\n')
+ {
+ ungetkey(ch);
+ break;
+ }
+ flush("Whitespaces around a special space make it meaningless");
+ }
+}
+
+#ifnexists isalpha
+define isalpha(ch)
+{
+ % Fixme! fails for Ăź
+ return orelse {ch != toupper(ch)} {ch != tolower(ch)};
+}
+#endif
+
+static define math_arrow(); % declare it for recursion
+static define math_arrow()
+{
+ if ( orelse {is_escaped()} {is_verbatim()} )
+ {
+ call("self_insert_cmd");
+ return;
+ }
+
+ variable arrow_str;
+
+ switch (LAST_CHAR)
+ { case '>':
+ () = left(1);
+ switch ( what_char() )
+ { case '-':
+ () = left(1);
+ switch (what_char())
+ { case '-':
+ () = left(1);
+ switch (what_char)
+ { case '<':
+ deln(3);
+ arrow_str = "longleftrightarrow";
+ }
+ { case '|':
+ deln(3);
+ arrow_str = "longmapsto";
+ }
+ {
+ () = right(1);
+ deln(2);
+ arrow_str = "longrightarrow";
+ }
+ }
+ { case '|':
+ deln(2);
+ arrow_str = "mapsto";
+ }
+ { case '<':
+ deln(2);
+ arrow_str = "leftrightarrow";
+ }
+ { case '`':
+ deln(2);
+ arrow_str = "hookrightarrow";
+ }
+ {
+ () = right(1);
+ del();
+ arrow_str = "rightarrow";
+ }
+ }
+ { case '=':
+ () = left(1);
+ switch (what_char())
+ { case '=':
+ () = left(1);
+ if (what_char() == '<')
+ {
+ deln(3);
+ arrow_str = "Longleftrightarrow";
+ }
+ else
+ {
+ () = right(1);
+ deln(2);
+ arrow_str = "Longrightarrow";
+ }
+ }
+ { case '<':
+ deln(2);
+ arrow_str = "Leftrightarrow";
+ }
+ {
+ () = right(1);
+ del();
+ arrow_str = "Rightarrow";
+ }
+ }
+ { case '>':
+ del();
+ arrow_str = "gg";
+ }
+ {
+ () = right(1);
+ call("self_insert_cmd");
+ return;
+ }
+ }
+ { case '-' or case '=':
+ () = left(1);
+ switch ( what_char() )
+ { case LAST_CHAR:
+ () = left(1);
+ switch ( what_char() )
+ { case '<':
+ () = right(2);
+ insert_char(LAST_CHAR);
+ update_sans_update_hook(1);
+
+ variable new_char = getkey();
+ if (new_char == '>')
+ {
+ LAST_CHAR = '>';
+ math_arrow();
+ return;
+ }
+ else
+ {
+ ungetkey(new_char);
+
+ () = left(3);
+ deln(3);
+ if (LAST_CHAR == '-')
+ arrow_str = "longleftarrow";
+ else
+ arrow_str = "Longleftarrow";
+ }
+ }
+ {
+ () = right(2);
+ call("self_insert_cmd");
+ return;
+ }
+ }
+ { case '<':
+ () = right(1);
+ insert_char(LAST_CHAR);
+ update_sans_update_hook(1);
+
+ new_char = getkey();
+
+ switch (new_char)
+ { case '>' or case '-' or case '=':
+ LAST_CHAR = new_char;
+ math_arrow();
+ return;
+ }
+ {
+ ungetkey(new_char);
+
+ () = left(2);
+ deln(2);
+ if ( LAST_CHAR == '-' )
+ arrow_str = "leftarrow";
+ else
+ arrow_str = "Leftarrow";
+ }
+ }
+ {
+ () = right(1);
+ if (LAST_CHAR == '-')
+ typo_hyphen();
+ else
+ call("self_insert_cmd");
+ return;
+ }
+ }
+ {
+ throw UsageError, "unknow character: $LAST_CHAR"$;
+ }
+
+ cmd_insert(arrow_str);
+}
+
+static define math_ll()
+{
+ if ( left(1) ) {
+ if ( what_char() == '<' )
+ {
+ del();
+ cmd_insert("ll");
+ }
+ else {
+ ()=right(1);
+ call("self_insert_cmd");
+ }
+ }
+ else
+ call("self_insert_cmd");
+}
+
+static define math_right_parenthesis()
+{
+ if (what_char() == '}')
+ {
+ push_spot();
+ find_matching_delimiter(LAST_CHAR) != 1;
+ pop_spot();
+ if ( () )
+ () = right(1);
+ }
+ push_spot();
+ if (find_matching_delimiter(LAST_CHAR) == 1)
+ {
+ push_mark();
+ bskip_chars("leftbigB\\");
+
+ variable size = bufsubstr(), delim;
+ switch ( strlow(size) )
+ { case "\\left": delim = "\\right"; }
+ { case "\\big" or case "\\bigg": delim = size; }
+ { case "\\bigl" or case "\\biggl": delim = size[[:-2]] + "r"; }
+ { delim = ""; }
+
+ pop_spot();
+ insert(delim);
+ }
+ else
+ pop_spot();
+
+ call("self_insert_cmd");
+}
+
+static define insert_limits_char()
+{
+ if ( orelse {is_escaped()} {is_verbatim()} )
+ {
+ call("self_insert_cmd");
+ return;
+ }
+
+ variable skip_dollar_after_compl = 0;
+ if ( blooking_at("$") )
+ {
+ skip_dollar_after_compl = 1;
+ () = left(1);
+ }
+
+ push_spot();
+ bskip_chars(TeX_Command_Chars + "0-9");
+ () = left(1);
+ !if ( looking_at_char('\\') )
+ () = right(1);
+
+ variable insert_dollar = 0;
+ !if ( is_math() )
+ {
+ insert_dollar = 1;
+ skip_dollar_after_compl = 1;
+ insert_char('$');
+ }
+ push_mark();
+ pop_spot();
+ variable last_cmd = bufsubstr();
+
+ if (insert_dollar)
+ {
+ insert_char('$');
+ if (last_cmd != "$")
+ % if no text was enclosed in $ $, the arrangement of spot and
+ % mark is difficult and leads to ^{}$$. This deals with this.
+ () = left(1);
+ }
+
+ switch (last_cmd)
+ { case "\\rightarrow" or case "\\leftarrow":
+ () = left( strlen(last_cmd)-1 );
+ insert_char('x');
+ () = right( strlen(last_cmd)-1 );
+
+ if (LAST_CHAR == '_')
+ {
+ insert("[]{}");
+ () = left(3);
+ }
+ else
+ {
+ insert("{}");
+ () = left(1);
+ }
+
+ return;
+ }
+ { case "\\cup" or case "\\cap" or case "\\vee" or case "\\wedge":
+ () = left( strlen(last_cmd)-1 );
+ insert("big");
+ () = right( strlen(last_cmd)-1 );
+ last_cmd = "\\big" + substr(last_cmd, 2, -1);
+ }
+
+ insert(char(LAST_CHAR) + "{}");
+ () = left(1);
+
+ if (last_cmd[0] != '\\')
+ % completion is only supported for TeX commands
+ return;
+
+ push_spot();
+ () = left(strlen(last_cmd) + 2); % $last_cmd$LAST_CHAR{
+ % the \ at the begin is the regexp quote of the \ in the command
+ !if ( re_bsearch("\\$last_cmd[_^]"$) )
+ {
+ pop_spot();
+ return;
+ }
+
+ () = right( strlen(last_cmd) );
+
+ variable counterpart_compl, compl;
+ !if ( looking_at_char(LAST_CHAR) )
+ {
+ () = right(1);
+ (,counterpart_compl) = cmd_parse_args(0,1);
+ }
+
+ if ( looking_at_char(LAST_CHAR) )
+ {
+ () = right(1);
+ (,compl) = cmd_parse_args(0,1);
+ }
+
+ if (not __is_initialized(&counterpart_compl) and
+ (looking_at_char('^') or looking_at_char('_')) )
+ {
+ () = right(1);
+ (,counterpart_compl) = cmd_parse_args(0,1);
+ }
+
+ pop_spot();
+
+ !if ( __is_initialized(&compl) )
+ return;
+
+ push_visible_mark();
+ insert( str_compress_tex(compl[0]) );
+ update(1);
+ variable k = getkey();
+ switch ( char(k) )
+ { case Key_Return or case Key_Enter:
+ pop_mark(0);
+ () = right(1);
+
+ !if ( __is_initialized(&counterpart_compl) )
+ {
+ if (skip_dollar_after_compl)
+ () = right(1);
+ return;
+ }
+ }
+ {
+ del_region();
+ ungetkey(k);
+ return;
+ }
+
+ push_visible_mark();
+ if (LAST_CHAR == '_')
+ "^{";
+ else
+ "_{";
+ insert(() + str_compress_tex(counterpart_compl[0]) + "}");
+ update(1);
+ k = getkey();
+ switch ( char(k) )
+ { case Key_Return or case Key_Enter:
+ pop_mark(0);
+
+ if (skip_dollar_after_compl)
+ () = right(1);
+ }
+ {
+ del_region();
+ ungetkey(k);
+ }
+}
+
+static define key_fold()
+{
+ variable arg = prefix_argument();
+ try
+ {
+ switch (arg)
+ { case NULL: arg = 0; } % default: fold this level
+ { case 9: % Fixme: This should be 0 digit_arg doesn't support it
+ arg = integer( read_mini("Level to fold:", "9", "") );
+ }
+ fold(arg);
+ }
+ catch UserBreakError;
+}
+
+static define key_unfold()
+{
+ try
+ {
+ variable arg = prefix_argument(0);
+
+ push_spot();
+ skip_hidden_lines_backward(1);
+ () = down(1);
+ push_mark();
+ skip_hidden_lines_forward(1);
+ () = up(1);
+ set_region_hidden(0);
+ pop_spot();
+
+ if (arg > 0)
+ fold(arg);
+ }
+ catch UserBreakError;
+}
+
+static define textormath(text, math)
+{
+ variable cmd;
+ if ( is_math() )
+ cmd = math;
+ else
+ cmd = text;
+
+ if (cmd[0] == ' ')
+ insert( substr(cmd, 2, strlen(cmd)) );
+ else
+ {
+ if ( is_internal(cmd) )
+ call(cmd);
+ else
+ eval(cmd);
+ }
+}
+
+private define defkeyr_textormath_cmd(text, math, key, mode)
+{
+ text = make_printable_string("latex->cmd_insert(\"$text\")"$);
+ math = make_printable_string("latex->cmd_insert(\"$math\")"$);
+ definekey_reserved("latex->textormath($text, $math)"$, key, mode);
+}
+
+private variable SIMPLE_KEYMAP = MODE + "-simple";
+
+!if ( keymap_p(SIMPLE_KEYMAP) )
+{
+ make_keymap(SIMPLE_KEYMAP);
+
+ % templates - ^CT or ^C^T
+ definekey_reserved("menu_select_menu(\"Global.M&ode.&Templates\")", "t", SIMPLE_KEYMAP);
+ definekey_reserved("menu_select_menu(\"Global.M&ode.&Templates\")", "^T", SIMPLE_KEYMAP);
+
+ % packages - ^CP
+ definekey_reserved("latex->pkg_prompt", "p", SIMPLE_KEYMAP);
+
+ % array - ^Ca
+ definekey_reserved("latex->array_edit_column_format", "ae", SIMPLE_KEYMAP);
+ definekey_reserved("latex->array_next_cell", "a\t", SIMPLE_KEYMAP);
+ definekey_reserved("latex->array_next_cell", "aa", SIMPLE_KEYMAP);
+ definekey_reserved("latex->array_new_cell", "an", SIMPLE_KEYMAP);
+ definekey_reserved("latex->array_prev_cell", "ap", SIMPLE_KEYMAP);
+
+ % environments - ^CE
+ definekey_reserved("latex->boenv", "e<", SIMPLE_KEYMAP);
+ definekey_reserved("latex->env_close", "ec", SIMPLE_KEYMAP);
+ definekey_reserved("latex->env_close", "}", SIMPLE_KEYMAP);
+ definekey_reserved("latex->env_prompt", "ee", SIMPLE_KEYMAP);
+ definekey_reserved("latex->env_prompt", "e\r", SIMPLE_KEYMAP);
+ definekey_reserved("latex->env_rename", "er", SIMPLE_KEYMAP);
+ definekey_reserved("latex->eoenv", "e>", SIMPLE_KEYMAP);
+
+ % sections - ^Cs
+ definekey_reserved("latex->cmd_insert(\"appendix\")", "sa", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"chapter\")", "sc", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"part\")", "sp", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"section\")", "ss", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"subsection\")", "su", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"subsubsection\")", "sb", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"paragraph\")", "sg", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"subparagraph\")", "sh", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"minisec\")", "sm", SIMPLE_KEYMAP);
+
+ % commands - ^Cd
+ definekey_reserved("latex->cmd_prompt", "d", SIMPLE_KEYMAP);
+
+ % fonts - ^CF
+ definekey_reserved("latex->font_resize(1)", "f-", SIMPLE_KEYMAP);
+ definekey_reserved("latex->font_resize(0)", "f+", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"mathcal\")", "fa", SIMPLE_KEYMAP);
+ defkeyr_textormath_cmd("textbf", "mathbf", "fb", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"mathbf\")", "fB", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"textsc\")", "fc", SIMPLE_KEYMAP);
+ defkeyr_textormath_cmd("underline", "underbar", "fd", SIMPLE_KEYMAP);
+ defkeyr_textormath_cmd("underline", "underbar", "f_", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"underbar\")", "fD", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"emph\")", "fe", SIMPLE_KEYMAP);
+ defkeyr_textormath_cmd("textsf", "mathsf", "ff", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"mathsf\")", "fF", SIMPLE_KEYMAP);
+ defkeyr_textormath_cmd("textit", "mathit", "fi", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"mathit\")", "fI", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"mathfrak\")", "fk", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"textmd\")", "fm", SIMPLE_KEYMAP);
+ defkeyr_textormath_cmd("textnormal", "mathnormal", "fn", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"mathnormal\")", "fN", SIMPLE_KEYMAP);
+ definekey_reserved("latex->font_cmd", "fp", SIMPLE_KEYMAP);
+ defkeyr_textormath_cmd("textrm", "mathrm", "fr", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"mathrm\")", "fR", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"textsl\")", "fs", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"textup\")", "fu", SIMPLE_KEYMAP);
+ defkeyr_textormath_cmd("texttt", "mathtt", "ft", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"mathtt\")", "fT", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"verb\")", "fv", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"text\")", "fx", SIMPLE_KEYMAP);
+ % definekey_reserved("latex_modify_font(\"\")", "fD", SIMPLE_KEYMAP);
+ % definekey_reserved("latex_rename_font", "fN", SIMPLE_KEYMAP);
+
+ % links - ^CL
+ definekey_reserved("latex->cmd_insert(\"label\")", "ll", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"label\")", "^L^L", SIMPLE_KEYMAP);
+ definekey_reserved("latex->label_insert_at_mark", "lm", SIMPLE_KEYMAP);
+ definekey_reserved("latex->label_insert_at_mark", "^L^M", SIMPLE_KEYMAP);
+ definekey_reserved("latex->label_ref", "lr", SIMPLE_KEYMAP);
+ definekey_reserved("latex->label_ref", "^L^R", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"pageref\")", "lp", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"pageref\")", "^L^P", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"cite\")", "lb", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"cite\")", "^l^b", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"url\")", "lu", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"url\")", "^L^U", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"nocite\")", "ln", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"nocite\")", "^L^N", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"index\")", "li", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"index\")", "^L^I", SIMPLE_KEYMAP);
+
+ % PSTricks - ^Ci
+ definekey_reserved("latex->pst_move_points", "im", SIMPLE_KEYMAP);
+ definekey_reserved("latex->pst_update_pic_size", "iu", SIMPLE_KEYMAP);
+
+ % math symbols - ^C m
+ definekey_reserved("latex->cmd_insert(\"alpha\")", "ma", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"beta\")", "mb", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"chi\")", "mc", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"delta\")", "md", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"epsilon\")", "me", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"phi\")", "mf", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"gamma\")", "mg", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"eta\")", "mh", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"kappa\")", "mk", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"lambda\")", "ml", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"mu\")", "mm", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"nabla\")", "mN", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"nu\")", "mn", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"omega\")", "mo", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"pi\")", "mp", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"theta\")", "mq", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"rho\")", "mr", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"sigma\")", "ms", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"tau\")", "mt", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"upsilon\")", "mu", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"Xi\")", "mX", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"xi\")", "mx", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"psi\")", "my", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"zeta\")", "mz", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"Delta\")", "mD", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"Gamma\")", "mG", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"Theta\")", "mQ", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"Lambda\")", "mL", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"Phi\")", "mV", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"Psi\")", "mY", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"Pi\")", "mP", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"Sigma\")", "mS", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"Upsilon\")", "mU", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"Omega\")", "mO", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"rightarrow\")", "m^f", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"leftarrow\")", "m^b", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"uparrow\")", "m^p", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"downarrow\")", "m^n", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"leq\")", "m<", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"geq\")", "m>", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"tilde\")", "m~", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"infty\")", "mI", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"forall\")", "mA", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"exists\")", "mE", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"neg\")", "m!", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"in\")", "mi", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"times\")", "m*", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"cdot\")", "m.", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"subset\")", "m{", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"supset\")", "m}", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"subseteq\")", "m[", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"supseteq\")", "m]", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"not\")", "m/", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"setminus\")", "m\\", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"cup\")", "m+", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"cap\")", "m-", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"wedge\")", "m&", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"vee\")", "m|", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"langle\")", "m(", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"rangle\")", "m)", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"exp\")", "m^e", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"sin\")", "m^s", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"cos\")", "m^c", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"sup\")", "m^^", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"inf\")", "m^_", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"det\")", "m^d", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"lim\")", "m^l", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"tan\")", "m^t", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"hat\")", "m^", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"vee\")", "mv", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"emptyset\")", "m0", SIMPLE_KEYMAP);
+
+ definekey_reserved("latex->cmd_insert(\"colon\")", "m:", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"infty\")", "m8", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"ne\")", "m=", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"overline\")", "m_", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"Phi\")", "mF", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"omega\")", "mw", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"Omega\")", "mW", SIMPLE_KEYMAP);
+
+ % not so common math stuff - ^C n
+ definekey_reserved("latex->cmd_insert(\"mathcal\")", "nc", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"frac\")", "nf", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"nicefrac\")", "nF", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"int\")", "ni", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"log\")", "nl", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"pmod\")", "nm", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"oint\")", "no", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"prod\")", "np", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"sum\")", "ns", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"sqrt\")", "nq", SIMPLE_KEYMAP);
+
+ definekey_reserved("latex->cmd_insert(\"frac\", 1, [\"1\"])", "n1", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"frac\", 1, [\"1\", \"2\"])", "n2", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"frac\", 1, [\"1\", \"3\"])", "n3", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"frac\", 1, [\"1\", \"4\"])", "n4", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"frac\", 1, [\"1\", \"5\"])", "n5", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"frac\", 1, [\"1\", \"6\"])", "n6", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"frac\", 1, [\"1\", \"7\"])", "n7", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"frac\", 1, [\"1\", \"8\"])", "n8", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"frac\", 1, [\"1\", \"9\"])", "n9", SIMPLE_KEYMAP);
+
+ % breaks - ^CK
+ definekey_reserved("latex->cmd_insert(\"newline\");newline()", "kl", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"newline\");newline()", "^K^L", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"linebreak[1]\");newline()", "kb", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"linebreak[1]\");newline()", "^K^B", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"newpage\");newline()", "kp", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"newpage\");newline()", "^K^P", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"clearpage\");newline()", "kc", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"clearpage\");newline()", "^K^C", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"cleardoublepage\");newline()", "kd", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"cleardoublepage\");newline()", "^K^D", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"pagebreak\");newline()", "kr", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"pagebreak\");newline()", "^K^R", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"nolinebreak[1]\");newline()", "kn", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"nolinebreak[1]\");newline()", "^K^N", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"nopagebreak\");newline()", "ko", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"nopagebreak\");newline()", "^K^O", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"enlargethispage\")", "ke", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"enlargethispage\")", "^K^E", SIMPLE_KEYMAP);
+
+ % math arrows - ^C + arrow
+ definekey_reserved("latex->cmd_insert(\"uparrow\")", Key_Up, SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"downarrow\")", Key_Down, SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"leftarrow\")", Key_Left, SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_insert(\"rightarrow\")", Key_Right, SIMPLE_KEYMAP);
+
+ definekey_reserved("latex->newline_with_completion", Key_Return, SIMPLE_KEYMAP);
+
+ % special characters
+ definekey_reserved(" \\$", "$", SIMPLE_KEYMAP);
+ definekey_reserved(" \\&", "&", SIMPLE_KEYMAP);
+ definekey_reserved(" \\%", "%", SIMPLE_KEYMAP);
+ definekey_reserved(" \\_", "_", SIMPLE_KEYMAP);
+ definekey_reserved(" \\#", "#", SIMPLE_KEYMAP);
+ definekey_reserved(" \\{", "(", SIMPLE_KEYMAP);
+ definekey_reserved(" \\}", ")", SIMPLE_KEYMAP);
+ definekey_reserved(" \\textless{}", "<", SIMPLE_KEYMAP);
+ definekey_reserved(" \\textgreater{}", ">", SIMPLE_KEYMAP);
+ definekey_reserved(" \\textbackslash{}", "\\", SIMPLE_KEYMAP);
+ definekey_reserved(" \\textbar{}", "|", SIMPLE_KEYMAP);
+ definekey_reserved(" \\textasciicircum{}", "^", SIMPLE_KEYMAP);
+ definekey_reserved(" \\textasciitilde{}", "~", SIMPLE_KEYMAP);
+
+ % stuff from latex_external - ^C r
+ definekey_reserved("latex_external->select_master_file", "ra", SIMPLE_KEYMAP);
+ definekey_reserved("latex_external->bibtex", "rb", SIMPLE_KEYMAP);
+ definekey_reserved("latex_external->show_bibtex_log", "rv", SIMPLE_KEYMAP);
+ definekey_reserved("latex_external->clearup", "rc", SIMPLE_KEYMAP);
+ definekey_reserved("latex_external->makeindex", "ri", SIMPLE_KEYMAP);
+ definekey_reserved("latex_external->show_mkidx_log", "ru", SIMPLE_KEYMAP);
+ definekey_reserved("latex_external->mrproper", "rm", SIMPLE_KEYMAP);
+ definekey_reserved("latex_external->cust_view", "ro", SIMPLE_KEYMAP);
+ definekey_reserved("latex_external->print", "rp", SIMPLE_KEYMAP);
+
+ % often used stuff from latex_external
+ definekey_reserved("latex_external->compose", "c", SIMPLE_KEYMAP);
+ definekey_reserved("latex_external->compose", "^C", SIMPLE_KEYMAP);
+ definekey_reserved("latex_external->view", "v", SIMPLE_KEYMAP);
+ definekey_reserved("latex_external->view", "^V", SIMPLE_KEYMAP);
+ definekey_reserved("latex_external->pop_log_file", "y", SIMPLE_KEYMAP);
+ definekey_reserved("latex_external->pop_log_file", "^y", SIMPLE_KEYMAP);
+
+ % help
+ definekey_reserved("latex->texdoc_help()", "ht", SIMPLE_KEYMAP);
+ definekey_reserved("latex->texdoc_search()", "hT", SIMPLE_KEYMAP);
+ definekey_reserved("latex->texdoc_search()", "^h^T", SIMPLE_KEYMAP);
+ definekey_reserved("latex->texdoc(\"symbols-a4\")", "hs", SIMPLE_KEYMAP);
+ definekey_reserved("latex->texdoc(\"symbols-a4\")", "^H^S", SIMPLE_KEYMAP);
+ definekey_reserved("latex->info_page", "hi", SIMPLE_KEYMAP);
+ definekey_reserved("latex->info_page", "^h^I", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_help", "hc", SIMPLE_KEYMAP);
+ definekey_reserved("latex->cmd_help", "^H^C", SIMPLE_KEYMAP);
+ definekey_reserved("latex->env_help", "he", SIMPLE_KEYMAP);
+ definekey_reserved("latex->env_help", "^H^E", SIMPLE_KEYMAP);
+ definekey_reserved("latex->pkg_help", "hp", SIMPLE_KEYMAP);
+ definekey_reserved("latex->pkg_help", "^H^P", SIMPLE_KEYMAP);
+
+ definekey_reserved("latex->indent_region", "q", SIMPLE_KEYMAP);
+
+
+ definekey_reserved("latex->key_fold", "oo", SIMPLE_KEYMAP);
+ definekey_reserved("latex->key_unfold", "ou", SIMPLE_KEYMAP);
+}
+
+private define definekey_textormath(text, math, key, mode)
+{
+ text = make_printable_string(text);
+ math = make_printable_string(math);
+ definekey("latex->textormath($text, $math)"$, key, mode);
+}
+
+static define unfold_or_newline()
+{
+ if (orelse {is_line_hidden()} {andelse {right(1)} {is_line_hidden()}})
+ key_unfold();
+ else
+ {
+ () = left(1);
+ call("newline_and_indent");
+ }
+}
+
+!if ( keymap_p(MODE) )
+{
+ copy_keymap(MODE, SIMPLE_KEYMAP);
+
+ % misc
+ definekey("latex->insert_quote", "\"", MODE);
+ definekey("latex->insert_quote", "`", MODE);
+ definekey("latex->insert_dollar", "$", MODE);
+ definekey("latex->math_ll", "<", MODE);
+ definekey("latex->math_arrow", ">", MODE);
+ definekey("latex->math_arrow", "-", MODE);
+ definekey("latex->math_arrow", "=", MODE);
+
+ foreach $1 ([" ", "~"])
+ definekey_textormath("latex->insert_without_spaces", "self_insert_cmd",
+ $1, MODE);
+
+ % typo stuff
+ definekey_textormath("latex->typo_slash", "self_insert_cmd", "/", MODE);
+ definekey("latex->typo_percent", "%", MODE);
+ definekey_textormath("latex->insert_without_spaces",
+ "latex->typo_german_decimal_point", ",", MODE);
+ definekey("latex->typo_dots", ".", MODE);
+
+ % math stuff
+ definekey_textormath("self_insert_cmd", "latex->cmd_insert(\"colon\")",
+ ":", MODE);
+ definekey_textormath("self_insert_cmd", "latex->math_right_parenthesis",
+ ")", MODE);
+ definekey_textormath("self_insert_cmd", "latex->math_right_parenthesis",
+ "]", MODE);
+ definekey("latex->insert_limits_char()", "^", MODE);
+ definekey("latex->insert_limits_char()", "_", MODE);
+ definekey("latex->newline_with_completion", Key_Shift_Return, MODE);
+
+ definekey("latex->unfold_or_newline", Key_Return, MODE);
+}
+
+%%%%%%%%%%
+%
+% Menu stuff
+%
+
+private define menu_init_helper(menu, list, fun)
+{
+ foreach (list)
+ {
+ variable entry = ();
+ if (typeof(entry) == Array_Type)
+ menu_append_item(menu, entry[0], fun, entry[1]);
+ else
+ menu_append_item(menu, entry,
+ "latex->" + string(fun)[[1:]] +
+ "(\"" + str_delete_chars(entry, "&\\"R) + "\")");
+ }
+}
+
+private define menu_init(menu)
+{
+ % templates
+ menu_append_popup(menu, "&Templates");
+ $1 = menu+".&Templates";
+
+ if (LaTeX_Template_Dir != NULL)
+ {
+ variable templates = Assoc_Type[String_Type];
+ foreach ( strtok(LaTeX_Template_Dir, ",") )
+ {
+ variable tmp = ();
+ foreach ( listdir(tmp) )
+ {
+ variable file = ();
+ if (strlen( path_sans_extname(file) ) != 0)
+ templates[path_sans_extname(file)] = path_concat(tmp, file);
+ }
+ }
+
+ variable keys = assoc_get_keys(templates);
+ foreach ( keys[array_sort(keys)] )
+ {
+ variable templ = ();
+ menu_append_item($1, templ, &templ_insert(), templates[templ]);
+ }
+ }
+
+ % packages
+ menu_append_popup(menu, "&Packages");
+ menu_init_helper(menu+".&Packages",
+ ["alltt", "amsmath", "babel", "booktabs", "calc",
+ "color", "eepic", "fancyhdr", "fancyvrb",
+ "geometry", "graphicx", "hyperref", "isolatin1",
+ "longtable", "makeidx", "moreverb",
+ "psfrag", "pslatex", "rotating", "url"],
+ &pkg_insert() );
+
+ % environments
+ menu_append_popup(menu, "&Environments");
+ $1 = menu+".&Environments";
+ menu_append_item($1, "&array", "latex->env_insert(\"array\", [\"ll\"])");
+ menu_init_helper($1,
+ {"&center", "&description", "&enumerate", "&figure",
+ "flush&left", ["flush&Right", "flushright"], "&itemize",
+ ["&List", "list"]},
+ &env_insert() );
+ menu_append_item($1, "&minipage",
+ "latex->env_insert(\"minipage\", [\"\\linewidth\"R])");
+ menu_init_helper($1,
+ ["&picture", "&quotation", "qu&ote", "ta&bbing", "&table",
+ "tab&ular"],
+ &env_insert() );
+ menu_append_item($1, "thebibliograph&y",
+ "latex->env_insert(\"thebibliography\", [\"99\"])");
+ menu_init_helper($1,
+ {["t&Heorem", "theorem"], "titlepa&ge", "&verbatim",
+ "ver&se"},
+ &env_insert() );
+ menu_append_separator($1);
+ menu_append_item($1, "&Custom...", "latex->env_prompt");
+ menu_append_item($1, "re&Name...", "latex->env_rename");
+ menu_append_item($1, "close...", "latex->env_close");
+ menu_append_item($1, "Goto begin...", "latex->boenv");
+ menu_append_item($1, "Goto end...", "latex->eoenv");
+
+ % font
+ menu_append_popup(menu, "&Font");
+ $1 = menu+".&Font";
+
+ menu_append_popup($1, "&Family");
+ menu_init_helper($1+".&Family",
+ {["&Roman", "textrm"], ["&Sans serif", "textsf"],
+ ["&Typewriter", "texttt"]},
+ &cmd_insert());
+
+ menu_append_popup($1, "&Shape");
+ menu_init_helper($1+".&Shape",
+ {["&Italic", "textit"], ["&Slanted", "textsl"],
+ ["Small &caps", "textsc"],
+ ["&Upright (normal)", "textup"]},
+ &cmd_insert());
+
+ menu_append_popup($1, "S&eries");
+ $2 = $1+".S&eries";
+ menu_append_item($2, "&Boldface", "latex->cmd_insert(\"textbf\")");
+ menu_append_item($2, "&Medium weight (normal)", "latex->cmd_insert(\"textmd\")");
+
+ menu_append_popup($1, "Si&ze");
+ menu_init_helper($1+".Si&ze",
+ ["&tiny", "s&criptsize", "&footnotesize", "&small",
+ "&normalsize", "&large", "&Large", "L&ARGE",
+ "&huge", "&Huge"],
+ &cmd_insert() );
+ menu_append_separator($2);
+ menu_append_item($2, "re&size", "latex_resize_font");
+
+ menu_init_helper($1,
+ {["&Emphasis", "emph"], ["&Underline", "underline"],
+ ["&Normal font", "textnormal"], ["\\&verb", "verb"]},
+ &cmd_insert() );
+
+ menu_append_separator($1);
+ menu_append_item($1, "&Delete last setting", "latex_modify_font(\"\")");
+ menu_append_item($1, "Re&name", "latex_rename_font");
+
+ % font/environment
+ menu_append_popup($1, "As &Environment");
+ menu_init_helper($1+".As &Environment",
+ ["&rmfamily", "&itshape", "&mdseries", "&bfseries",
+ "&upshape", "&slshape", "s&ffamily", "s&cshape",
+ "&ttfamily", "&normalfont"],
+ &env_insert() );
+
+ % font/math
+ menu_append_popup($1, "&Math");
+ menu_init_helper($1+".&Math",
+ ["mathr&m", "math&bf", "math&sf", "math&tt",
+ "math&it", "math&normal"],
+ &cmd_insert() );
+
+ % sections
+ menu_append_popup(menu, "&Sections");
+ menu_init_helper(menu+".&Sections",
+ ["\\p&art", "\\&chapter", "\\&section", "\\s&ubsection",
+ "\\su&bsubsection", "\\&paragraph", "\\subparagrap&h",
+ "\\&minisec"],
+ &cmd_insert() );
+
+ % paragraph
+ menu_append_popup(menu, "&Paragraph");
+ $1 = menu+".&Paragraph";
+ menu_append_item($1, "F&ramed Paragraph", "latex_par_frame");
+ menu_append_item($1, "&background Colour", "latex_par_bgcolour");
+ menu_append_item($1, "&foreground Colour", "latex_par_fgcolour");
+ menu_append_item($1, "\\par&indent",
+ "insert(\"\\\\setlength{\\\\parindent}{0pt}\\n\")");
+ menu_append_item($1, "\\par&skip",
+ "insert(\"\\\\setlength{\\\\parskip}{3pt}\\n\")");
+ menu_append_item($1, "\\&marginpar",
+ "latex_cmd(\"marginpar\", 1)");
+ menu_append_item($1, "\\foot&note",
+ "latex_cmd(\"footnote\", 1)");
+ menu_append_item($1, "\\inc&ludegraphics", "latex_includegraphics");
+
+ % paragraph/margins
+ menu_append_popup($1, "&Margins");
+ $2 = $1+".&Margins";
+ menu_append_item($2, "\\&leftmargin",
+ "latex_cmd(\"setlength{\\\\leftmargin}\", 1)");
+ menu_append_item($2, "\\&rightmargin",
+ "latex_cmd(\"setlength{\\\\rightmargin}\", 1)");
+ menu_append_item($2, "\\&evensidemargin",
+ "latex_cmd(\"setlength{\\\\evensidemargin}\", 1)");
+ menu_append_item($2, "\\&oddsidemargin",
+ "latex_cmd(\"setlength{\\\\oddsidemargin}\", 1)");
+ menu_append_item($2, "\\&topmargin",
+ "latex_cmd(\"setlength{\\\\topmargin}\", 1)");
+ menu_append_item($2, "\\text&width",
+ "latex_cmd(\"setlength{\\\\textwidth}\", 1)");
+ menu_append_item($2, "\\text&height",
+ "latex_cmd(\"setlength{\\\\textheight}\", 1)");
+
+ menu_append_popup($1, "Brea&ks");
+ $2 = $1+".Brea&ks";
+ menu_append_item($2, "\\new&line", "insert(\"\\\\newline\\n\")");
+ menu_append_item($2, "\\\\&*[]", "latex_linebreak");
+ menu_append_item($2, "\\line&break", "insert(\"\\\\linebreak[1]\\n\")");
+ menu_append_item($2, "\\new&page", "insert(\"\\\\newpage\\n\")");
+ menu_append_item($2, "\\&clearpage", "insert(\"\\\\clearpage\\n\")");
+ menu_append_item($2, "\\clear&doublepage",
+ "insert(\"\\\\cleardoublepage\\n\")");
+ menu_append_item($2, "\\pageb&reak", "insert(\"\\\\pagebreak\\n\")");
+ menu_append_item($2, "\\&nolinebreak",
+ "insert(\"\\\\nolinebreak[1]\\n\")");
+ menu_append_item($2, "\\n&opagebreak", "insert(\"\\\\nopagebreak\\n\")");
+ menu_append_item($2, "\\&enlargethispage",
+ "insert(\"\\\\enlargethispage\\n\")");
+
+ % paragraph/spaces
+ menu_append_popup($1, "&Spaces");
+ $2 = $1+".&Spaces";
+ menu_append_item($2, "\\&frenchspacing",
+ "insert(\"\\\\frenchspacing\\n\")");
+ menu_append_item($2, "\\&@.", "insert(\"\\\\@.\\n\")");
+ menu_append_item($2, "\\&dotfill", "insert(\"\\\\dotfill\\n\")");
+ menu_append_item($2, "\\&hfill", "insert(\"\\\\hfill\\n\")");
+ menu_append_item($2, "\\h&rulefill", "insert(\"\\\\hrulefill\\n\")");
+ menu_append_item($2, "\\&smallskip", "insert(\"\\\\smallskip\\n\")");
+ menu_append_item($2, "\\&medskip", "insert(\"\\\\medskip\\n\")");
+ menu_append_item($2, "\\&bigskip", "insert(\"\\\\bigskip\\n\")");
+ menu_append_item($2, "\\&vfill", "insert(\"\\\\vfill\\n\")");
+ menu_append_item($2, "\\hspace", "insert(\"\\\\hspace\\n\")");
+ menu_append_item($2, "\\vs&pace", "insert(\"\\\\vspace\\n\")");
+ menu_append_item($2, "Set \\baselines&kip",
+ "insert(\"\\\\baselineskip 2\\\\baselineskip\\n\")");
+
+ % paragraph/boxes
+ menu_append_popup($1, "Bo&xes");
+ $2 = $1+".Bo&xes";
+ menu_append_item($2, "\\&fbox", "latex_cmd(\"fbox\", 1)");
+ menu_append_item($2, "\\f&ramebox",
+ "latex_cmd(\"framebox[\\\\width][c]\", 1)");
+ menu_append_item($2, "\\&mbox", "latex_cmd(\"mbox\", 1)");
+ menu_append_item($2, "\\ma&kebox",
+ "latex_cmd(\"makebox[\\\\width][c]\", 1)");
+ menu_append_item($2, "\\&newsavebox", "latex_cmd(\"newsavebox\", 1)");
+ menu_append_item($2, "\\ru&le",
+ "latex_cmd(\"rule{\\\\linewidth}\", 1)");
+ menu_append_item($2, "\\save&box",
+ "latex_cmd(\"savebox{}[\\\\linewidth][c]\", 1)");
+ menu_append_item($2, "\\&sbox",
+ "latex_cmd(\"sbox{}\", 1)");
+ menu_append_item($2, "\\&usebox",
+ "latex_cmd(\"usebox\", 1)");
+
+ % links
+ menu_append_popup(menu, "&Links");
+ menu_init_helper(menu+".&Links",
+ ["\\&label", "\\&ref", "\\&cite", "\\&nocite", "\\&url",
+ "\\n&olinkurl", "\\&index"],
+ &cmd_insert() );
+
+ menu_append_popup(menu + ".&Links", "&More index commands");
+ $1 = menu + ".&Links.&More index commands";
+ menu_append_item($1, "\\&index{entry!subentry}",
+ "latex->cmd_insert(\"index\", 1, [\"entry!subentry\"])");
+ menu_append_item($1, "\\&index{entry|(} (begin range)",
+ "latex->cmd_insert(\"index\", 1, [\"entry|(\"])");
+ menu_append_item($1, "\\&index{entry|)} (end range)",
+ "latex->cmd_insert(\"index\", 1, [\"entry|)\"])");
+ menu_append_item($1, "\\&index{sortentry@textentry)}",
+ "latex->cmd_insert(\"index\", 1, [\"sortentry@textentry\"])");
+ menu_append_item($1, "\\&index{entry|format)}",
+ "latex->cmd_insert(\"index\", 1, [\"entry|format\"])");
+
+ % math
+ menu_append_popup(menu, "&Math");
+ $1 = menu+".&Math";
+
+ menu_append_item($1, "&Toggle Math Mode", "toggle_math_mode");
+ menu_append_item($1, "&Greek Letter...", "latex_greek_letter");
+ menu_append_item($1, "&_{} subscript",
+ "latex_insert_tags(\"_{\", \"}\", 1, 1)");
+ menu_append_item($1, "&^{} superscript",
+ "latex_insert_tags(\"^{\", \"}\", 1, 1)");
+ menu_append_item($1, "\\&frac",
+ "latex_insert_tags(\"\\\\frac{\", \"}{}\", 1, 1)");
+ menu_append_item($1, "\\&int",
+ "latex_insert_tags(\"\\\\int_{\", \"}^{}\", 1, 1)");
+ menu_append_item($1, "\\&lim",
+ "latex_insert_tags(\"\\\\lim_{\", \"}\", 1, 1)");
+ menu_append_item($1, "\\&oint",
+ "latex_insert_tags(\"\\\\oint_{\", \"}^{}\", 1, 1)");
+ menu_append_item($1, "\\&prod",
+ "latex_insert_tags(\"\\\\prod_{\", \"}^{}\", 1, 1)");
+ menu_append_item($1, "\\&sum",
+ "latex_insert_tags(\"\\\\sum_{\", \"}^{}\", 1, 1)");
+ menu_append_item($1, "\\s&qrt",
+ "latex_insert_tags(\"\\\\sqrt[]{\", \"}\", 1, 1)");
+
+ % math/accents
+ menu_append_popup($1, "&Accents");
+ menu_init_helper($1+".&Accents",
+ ["hat", "acute", "bar", "dot", "breve", "check",
+ "grave", "vec", "ddot", "tilde", "widetilde",
+ "widehat", "overleftarrow", "overrightarrow",
+ "overline", "underline", "overbrace", "underbrace"],
+ &cmd_insert() );
+
+ menu_append_popup($1, "&Delimiters");
+ menu_append_item($2, "\\left(", "latex_insert(\"left(\")");
+ menu_append_item($2, "\\right)", "latex_insert(\"right)\")");
+ menu_append_item($2, "\\left[", "latex_insert(\"left[\")");
+ menu_append_item($2, "\\right]", "latex_insert(\"right[\")");
+ menu_append_item($2, "\\left{", "latex_insert(\"left\\\\{\")");
+ menu_append_item($2, "\\right}", "latex_insert(\"right\\\\}\")");
+ menu_init_helper($1+".&Delimiters",
+ ["rmoustache", "lmoustache", "rgroup", "lgroup",
+ "arrowvert", "Arrowvert", "bracevert", "lfloor",
+ "rfloor", "lceil", "rceil", "langle", "rangle"],
+ &cmd_insert() );
+ menu_append_item($2, "\\|", "latex_insert(\"\\|\")");
+
+ menu_append_popup($1, "F&unctions");
+ menu_init_helper($1+".F&unctions",
+ ["arccos", "arcsin", "arctan", "arg", "cos",
+ "cosh", "cot", "coth", "csc", "deg", "det",
+ "dim", "exp", "gcd", "hom", "inf", "ker",
+ "lg", "lim", "liminf", "limsup", "ln", "log",
+ "max", "min", "Pr", "sec", "sin", "sinh",
+ "sup", "tan", "tanh"],
+ &cmd_insert() );
+
+ menu_append_popup($1, "Binary &Relations");
+ menu_init_helper($1+".Binary &Relations",
+ ["leq", "geq", "equiv", "models", "prec", "succ",
+ "sim", "perp", "preceq", "succeq", "simeq",
+ "mid", "ll", "gg", "asymp", "parallel", "subset",
+ "supset", "approx", "bowtie", "subseteq",
+ "supseteq", "cong", "Join", "sqsubset", "sqsupset",
+ "neq", "smile", "sqsubseteq", "sqsupseteq", "doteq",
+ "frown", "in", "ni", "propto", "vdash", "dashv",
+ "not"],
+ &cmd_insert() );
+
+ % math/binary operators
+ menu_append_popup($1, "&Binary Operators");
+ menu_init_helper($1+".&Binary Operators",
+ ["pm", "cap", "diamond", "oplus", "mp", "cup",
+ "bigtriangleup", "ominus", "times", "uplus",
+ "bigtriangledown", "otimes", "div", "sqcap",
+ "triangleleft", "oslash", "ast", "sqcup",
+ "triangleright", "odot", "star", "vee", "bigcirc",
+ "circ", "wedge", "dagger", "bullet", "setminus",
+ "ddagger", "cdot", "wr", "analg"],
+ &cmd_insert() );
+
+ % math/spaces
+ menu_append_popup($1, "Spa&ces");
+ $2 = $1+".Spa&ces";
+ menu_append_item($2, "\\! -3/18 quad", "insert(\"\\\\! \")");
+ menu_append_item($2, "\\, 3/18 quad", "insert(\"\\\\, \")");
+ menu_append_item($2, "\\: 4/18 quad", "insert(\"\\\\: \")");
+ menu_append_item($2, "\\; 5/18 quad", "insert(\"\\\\; \")");
+ menu_append_item($2, "\\quad 1em", &cmd_insert(), "quad");
+ menu_append_item($2, "\\qquad 2em", &cmd_insert(), "qquad");
+
+ % math/arrows
+ menu_append_popup($1, "Arro&ws");
+ menu_init_helper($1+".Arro&ws",
+ {["<-", "leftarrow"], ["<--", "longleftarrow"],
+ ["<=", "Leftarrow"], ["<==", "Longleftarrow"],
+ ["->", "rightarrow"], ["-->", "longrightarrow"],
+ ["=>", "Rightarrow"], ["==>", "Longrightarrow"],
+ "uparrow", "Uparrow", "downarrow", "Downarrow",
+ ["<->", "leftrightarrow"],
+ ["<-->", "longleftrightarrow"],
+ ["<=>", "Leftrightarrow"],
+ ["<==>", "Longleftrightarrow"],
+ "updownarrow", "Updownarrow",
+ ["|->", "mapsto"], ["|-->", "longmapsto"],
+ "hookleftarrow", "hookrightarrow", "leftarpoonup",
+ "rightarpoonup", "leftarpoondown", "rightarpoondown",
+ "nearrow", "searrow", "swarrow", "nwarrow"},
+ &cmd_insert() );
+
+ % math/misc
+ menu_append_popup($1, "&Misc");
+ menu_init_helper($1+".&Misc",
+ ["ldots", "cdots", "vdots", "ddots", "aleph",
+ "prime", "forall", "infty", "hbar", "emptyset",
+ "exists", "nabla", "surd", "triangle", "imath",
+ "jmath", "ell", "neg", "top", "flat", "natural",
+ "sharp", "wp", "bot", "clubsuit", "diamondsuit",
+ "heartsuit", "spadesuit", "Re", "Im", "angle",
+ "partial"],
+ &cmd_insert() );
+
+ % bibliography
+ menu_append_popup(menu, "Bibliograph&y");
+ $1 = menu+".Bibliograph&y";
+ menu_append_item($1, "&thebibliography",
+ "latex->env_insert(\"thebibliography\", [\"{99}\"])");
+ menu_init_helper(menu+".Bibliograph&y",
+ ["\\bib&item", "\\&bibliography", "\\bibliography&style"],
+ &cmd_insert() );
+
+ % PSTricks
+ menu_append_popup(menu, "PSTr&icks");
+ $1 = menu + ".PSTr&icks";
+ menu_append_item($1, "&pspicture", "latex->env_insert(\"pspicture\")");
+ menu_init_helper($1,
+ ["\\ps&circle", "\\ps&fram", "\\ps&line", "\\&rput"],
+ &cmd_insert() );
+ menu_append_separator($1);
+ menu_append_item($1, "Move points in region", "latex->pst_move_points");
+ menu_append_item($1, "Update pspicture size", "latex->pst_update_pic_size");
+
+ menu_append_separator(menu);
+
+ menu_append_item(menu, "Select M&aster File",
+ "latex_external->select_master_file");
+ menu_append_item(menu, "Customize Build", "latex_external->cust_view");
+ menu_append_item(menu, "Compose", "latex_external->compose");
+ menu_append_item(menu, "&View", "latex_external->view");
+ menu_append_item(menu, "Show LaTeX lo&g", "latex_external->pop_log_file");
+ menu_append_item(menu, "Pri&nt", "latex_external->print");
+ menu_append_item(menu, "&BibTeX", "latex_external->bibtex");
+ menu_append_item(menu, "Show BibTeX log", "latex_external->show_bibtex_log");
+ menu_append_item(menu, "Makeinde&x", "latex_external->makeindex");
+ menu_append_item(menu, "Show Makeindex log", "latex_external->show_mkidx_log");
+ % menu_append_item(menu, "&Document Outline", "latex_browse_tree");
+ menu_append_item(menu, "&Remove temp files", "latex_external->clearup");
+ menu_append_item(menu, "&Remove all files", "latex_external->mrproper");
+
+ % convert
+ menu_append_popup(menu, "&Convert");
+ $1 = menu+".&Convert";
+ menu_append_item($1, "$:$ -> $\\colon$", "latex_conv->colon");
+ menu_append_item($1, "\"a -> ä (Latin 1)", "latex_conv->german_lat1");
+ menu_append_item($1, "\"a -> ä (UTF-8)", "latex_conv->german_utf8");
+ menu_append_item($1, "\\\"a -> ä (Latin 1)", "latex_conv->native_lat1");
+ menu_append_item($1, "\\\"a -> ä (UTF-8)", "latex_conv->native_utf8");
+ menu_append_item($1, "2.0 (\\bf) -> 2e (\\textbf)", "latex_conv->ltx209_ltx2e");
+
+ % specials
+ menu_append_popup(menu, "Specials");
+ $1 = menu + ".Specials";
+ menu_append_item($1, "Simple keymap", "use_keymap(\"$SIMPLE_KEYMAP\")"$);
+ menu_append_item($1, "Default keymap", "use_keymap(\"$MODE\")"$);
+
+ menu_append_separator(menu);
+ menu_append_item(menu, "Latex info page", "latex->info_page");
+ menu_append_item(menu, "TeXdoxTk", "() = system(\"texdoctk &\")");
+ menu_append_item(menu, "LaTeX Mode &Help", "latex_mode_help");
+ menu_append_popup(menu, "Common &documentations");
+ $1 = menu + ".Common &documentations";
+ menu_init_helper($1, {"&amsldoc", "&de-tex-faq",
+ ["&Hyperref manual", "hyperref/manual"], "&Mathmode",
+ "pst-quickref", "pstricks-doc",
+ "&scrguide", "s&ymbols-a4", "&visualFAQ"},
+ &texdoc());
+}
+mode_set_mode_info(MODE, "init_mode_menu", &menu_init);
+
+create_syntax_table(MODE);
+
+define_syntax("%", "", '%', MODE); % Comment Syntax
+define_syntax('\\', '\\', MODE); % Quote character
+define_syntax("~^_&#", '+', MODE); % operators
+define_syntax("|&{}[]", ',', MODE); % delimiters
+define_syntax(TeX_Command_Chars, 'w', MODE);
+set_syntax_flags(MODE, 8);
+
+#ifdef HAS_DFA_SYNTAX
+private define setup_dfa_callback(name)
+{
+ dfa_enable_highlight_cache("latex.dfa", name);
+
+ % comments:
+ dfa_define_highlight_rule("%(.*[^ \t])?", "comment", name);
+
+ dfa_define_highlight_rule("\\documentclass.*}"R, "Qpreprocess", name);
+ dfa_define_highlight_rule("\\begin{.*}({.*})*"R, "preprocess", name);
+ dfa_define_highlight_rule("\\end{.*}"R, "Qpreprocess", name);
+
+ % % known keywords in curly braces
+ % dfa_define_highlight_rule("{article}", "Qstring", name);
+ % dfa_define_highlight_rule("{book}", "Qstring", name);
+ % dfa_define_highlight_rule("{letter}", "Qstring", name);
+ % dfa_define_highlight_rule("{report}", "Qstring", name);
+ % dfa_define_highlight_rule("{slides}", "Qstring", name);
+ % dfa_define_highlight_rule("{document}", "Qstring", name);
+ % dfa_define_highlight_rule("{scrreport}", "Qstring", name);
+ % % environments
+ % dfa_define_highlight_rule("{abstract}", "Qstring", name);
+ % dfa_define_highlight_rule("{array}", "Qstring", name);
+ % dfa_define_highlight_rule("{center}", "Qstring", name);
+ % dfa_define_highlight_rule("{description}", "Qstring", name);
+ % dfa_define_highlight_rule("{displaymath}", "Qstring", name);
+ % dfa_define_highlight_rule("{enumerate}", "Qstring", name);
+ % dfa_define_highlight_rule("{eqnarray}", "Qstring", name);
+ % dfa_define_highlight_rule("{figure}", "Qstring", name);
+ % dfa_define_highlight_rule("{flushleft}", "Qstring", name);
+ % dfa_define_highlight_rule("{flushright}", "Qstring", name);
+ % dfa_define_highlight_rule("{itemize}", "Qstring", name);
+ % dfa_define_highlight_rule("{list}", "Qstring", name);
+ % dfa_define_highlight_rule("{minipage}", "Qstring", name);
+ % dfa_define_highlight_rule("{picture}", "Qstring", name);
+ % dfa_define_highlight_rule("{quotation}", "Qstring", name);
+ % dfa_define_highlight_rule("{quote}", "Qstring", name);
+ % dfa_define_highlight_rule("{tabbing}", "Qstring", name);
+ % dfa_define_highlight_rule("{table}", "Qstring", name);
+ % dfa_define_highlight_rule("{tabular}", "Qstring", name);
+ % dfa_define_highlight_rule("{thebibliography}", "Qstring", name);
+ % dfa_define_highlight_rule("{theorem}", "Qstring", name);
+ % dfa_define_highlight_rule("{titlepage}", "Qstring", name);
+ % dfa_define_highlight_rule("{verbatim}", "Qstring", name);
+ % dfa_define_highlight_rule("{verse}", "Qstring", name);
+ % % font family
+ % dfa_define_highlight_rule("{rmfamily}", "Qkeyword2", name);
+ % dfa_define_highlight_rule("{itshape}", "Qkeyword2", name);
+ % dfa_define_highlight_rule("{mdseries}", "Qkeyword2", name);
+ % dfa_define_highlight_rule("{bfseries}", "Qkeyword2", name);
+ % dfa_define_highlight_rule("{upshape}", "Qkeyword2", name);
+ % dfa_define_highlight_rule("{slshape}", "Qkeyword2", name);
+ % dfa_define_highlight_rule("{sffamily}", "Qkeyword2", name);
+ % dfa_define_highlight_rule("{scshape}", "Qkeyword2", name);
+ % dfa_define_highlight_rule("{ttfamily}", "Qkeyword2", name);
+ % dfa_define_highlight_rule("{normalfont}", "Qkeyword2", name);
+ % dfa_define_highlight_rule("\\text[^{][^{]"R, "keyword2", name);
+
+ % dfa_define_highlight_rule("{gather\*?}"R, "Qnumber", name);
+ % dfa_define_highlight_rule("{align\*?}"R, "Qnumber", name);
+
+ % % everithing else between curly braces
+ % % !!! doesn't span multiple lines !!!
+ % dfa_define_highlight_rule("{.*}", "Qkeyword1", name);
+ % dfa_define_highlight_rule("^([^{])*}", "Qkeyword1", name);
+ % dfa_define_highlight_rule("{.*", "keyword1", name);
+
+ % % short symbols that delimit math: $ \[ \] \( \)
+ % dfa_define_highlight_rule("\\\\\\[.*\\\\\\]", "Qstring", name);
+ % dfa_define_highlight_rule("\\\\\\(.*\\\\\\)", "Qstring", name);
+ % dfa_define_highlight_rule("^.*\\\\[\\)\\]]", "Qstring", name);
+ % dfa_define_highlight_rule("\\\\[\\(\\[].*", "string", name);
+
+ % dfa_define_highlight_rule("\\$.*\\$", "Qnumber", name);
+ % dfa_define_highlight_rule("\\$.*[^ ]", "number", name);
+ % % dfa_define_highlight_rule("^[^\\$]*\\$", "number", name);
+
+ % % Fundamental delimiters in the TeX language: {}[]
+ % dfa_define_highlight_rule("[{}\\[\\]]", "delimiter", name);
+
+ % % \leftX \rightY constructions where X and Y are
+ % % one of \| \{ \} [ ]( ) / | .
+ % dfa_define_highlight_rule("\\\\(left|right)(\\\\\\||\\\\{|\\\\}|" +
+ % "[\\[\\]\\(\\)/\\|\\.])",
+ % "delimiter", name);
+
+ % % type 2 keywords: font definitions
+ % dfa_define_highlight_rule("\\\\bfseries", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\emph", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\itshape", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\mathbf", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\mathcal", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\mathit", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\mathnormal", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\mathrm", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\mathsf", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\mathtt", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\mdseries", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\normalfont", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\rmfamily", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\scshape", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\sffamily", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\slshape", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\textbf", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\textit", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\textmd", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\textnormal", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\textrm", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\textsc", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\textsf", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\textsl", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\texttt", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\textup", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\ttfamily", "keyword2", name);
+ % dfa_define_highlight_rule("\\\\upshape", "keyword2", name);
+ % % size
+ % dfa_define_highlight_rule("\\tiny"R, "keyword2", name);
+ % dfa_define_highlight_rule("\\scriptsize"R, "keyword2", name);
+ % dfa_define_highlight_rule("\\footnotesize"R, "keyword2", name);
+ % dfa_define_highlight_rule("\\small"R, "keyword2", name);
+ % dfa_define_highlight_rule("\\normalsize"R, "keyword2", name);
+ % dfa_define_highlight_rule("\\large"R, "keyword2", name);
+ % dfa_define_highlight_rule("\\Large"R, "keyword2", name);
+ % dfa_define_highlight_rule("\\LARGE"R, "keyword2", name);
+ % dfa_define_highlight_rule("\\huge"R, "keyword2", name);
+ % dfa_define_highlight_rule("\\Huge"R, "keyword2", name);
+
+ % type 1 keywords: a backslash followed by
+ % one of -,:;!%$#&_ |\/{}~^´'``.=> :
+ dfa_define_highlight_rule("\\[\-,:;!%\$#&_ \|\\/{}~\^'`\.=>]"R,
+ "keyword1", name);
+
+ % type 0 keywords: a backslash followed by alpha characters
+ dfa_define_highlight_rule("\\["R +
+ str_quote_string(TeX_Command_Chars, "*", '\\')
+ + "]+", "keyword", name);
+
+ % % a backslash followed by a single char not covered by one of the
+ % % previous rules is probably an error
+ % dfa_define_highlight_rule("\\.", "error", name);
+
+ % The symbols ~ ^ _
+ dfa_define_highlight_rule("[~\\^_]", "operator", name);
+
+ % numbers
+ dfa_define_highlight_rule("[0-9]([\.,0-9]*[0-9])?"R, "number", name);
+ dfa_define_highlight_rule("\$"R, "number", name);
+
+ % % macro parameters(#1 #2 etc)
+ % dfa_define_highlight_rule("#[1-9]", "operator", name);
+
+ % quoted strings
+ dfa_define_highlight_rule("\"`.*\"'", "Qstring", name); % german
+ dfa_define_highlight_rule("``.*''", "Qstring", name); % english
+
+ % signle quotes
+ dfa_define_highlight_rule("`[^']*'", "string", name); % english
+
+ % quoted strings accross lines; mark the three charaters after and
+ % before the quote characters
+ dfa_define_highlight_rule("[\"`]`.?.?.?", "string", name);
+ dfa_define_highlight_rule(".?.?.?\"'", "string", name);
+ dfa_define_highlight_rule(".?.?.?''", "string", name);
+
+ dfa_define_highlight_rule("[ \t]+$", "trailing_whitespace", name);
+
+ % Workaround to make UTF-8 characters are display correctly, not as
+ % <C3><nn> or <E2><nn><nn>
+ dfa_define_highlight_rule("\xC2.", "normal", name);
+ dfa_define_highlight_rule("\xC3.", "normal", name);
+ dfa_define_highlight_rule("\xE2..", "normal", name);
+ dfa_define_highlight_rule("\xE3..", "normal", name);
+ dfa_define_highlight_rule("\xE4..", "normal", name);
+ dfa_define_highlight_rule("\xE5..", "normal", name);
+ dfa_define_highlight_rule("\xE6..", "normal", name);
+ dfa_define_highlight_rule("\xE7..", "normal", name);
+ dfa_define_highlight_rule("\xE8..", "normal", name);
+ dfa_define_highlight_rule("\xE9..", "normal", name);
+
+ % all the rest
+ % Fixme: Why we need this rule?
+ dfa_define_highlight_rule(".", "normal", name);
+
+ dfa_build_highlight_table(name);
+}
+
+dfa_set_init_callback(&setup_dfa_callback, MODE);
+#endif
+
+%%%%%%%%%%
+%
+% Hooks
+%
+
+% Fix me!
+% we should save the blocal vars on buffer close, but there isn't a hook for
+% this
+private define save_buf_before_hook(filename)
+{
+ % variable buf = latex_external->find_buf_of_file(filename);
+
+ % if (buf == NULL)
+ % buf = whatbuf();
+
+ % setbuf(buf);
+ % push_spot();
+ % eob();
+
+ % variable old_buf_flags;
+ % (,,,old_buf_flags) = getbuf_info();
+ % setbuf_info( getbuf_info() & ~0x20 );
+
+ % % the buf should end with a newline
+ % !if(bolp()) newline();
+
+ % % Fix me!
+ % while ( andelse {up(1)} {bol(), looking_at_char('%')} ) {
+ % skip_chars("% ");
+ % if ( looking_at("LaTeX") ) {
+ % bol();
+ % push_mark();
+ % eol();
+ % ()=right(1);
+ % del_region();
+ % }
+ % }
+ % % ()=down(1);
+ % % !if (eobp()) { eol(); newline(); }
+ % eob();
+
+ % variable error_occured=0;
+ % ERROR_BLOCK {
+ % error_occured = 1;
+ % _clear_error();
+ % }
+
+ % foreach ( ["LaTeX_master_file", "LaTeX_output_format"] ) {
+ % if (error_occured)
+ % break;
+
+ % variable name = ();
+ % if ( latex_external->exists_master_file_var(name) )
+ % insert("% "+name+": "+latex_external->get_master_file_var(name)+"\n");
+ % }
+ % setbuf_info( getbuf_info() | (old_buf_flags&0x20) );
+ % pop_spot();
+}
+
+% Fixme: better define a own format_paragraph
+private define paragraph_separator()
+{
+ bol(); skip_white();
+ return orelse {looking_at_char('\\')} {is_commented()} {eolp()};
+}
+
+%!%+
+%\function{latex_mode}
+%\synopsis{latex_mode}
+%\usage{Void latex_mode()}
+%\description
+% This mode is designed to facilitate the task of editing LaTeX files. It
+% calls the function \var{latex_mode_hook} on startup if it is defined. In
+% addition, if the abbreviation table \var{"TeX"} is defined, that table is
+% used.
+%
+% There are way too many key-bindings for this mode.
+% Please have a look at the menus!
+%!%-
+public define latex_mode()
+{
+ set_mode(MODE, 0x21);
+
+ use_keymap(MODE);
+ use_syntax_table(MODE);
+
+ set_buffer_hook("indent_hook", &indent_hook);
+ set_buffer_hook("newline_indent_hook", &newline_indent_hook);
+ set_buffer_hook("wrap_hook", &wrap_hook);
+ set_buffer_hook("wrapok_hook", &wrapok_hook);
+ append_to_hook("_jed_save_buffer_before_hooks", &save_buf_before_hook);
+ set_buffer_hook("par_sep", &paragraph_separator);
+
+ WRAP_INDENTS = 1;
+ define_blocal_var("info_page", "latex");
+
+ if ( abbrev_table_p("TeX") )
+ {
+ set_abbrev_mode(1);
+ use_abbrev_table("TeX");
+ }
+
+ eob();
+ !if (bobp()) {
+ % file is not empty
+ % Fix me!
+ % Bad Hack: bol() doesn't take an argument, so 1 is left on stack for
+ % and
+ while ( andelse {up(1) and bol(1)} {looking_at_char('%')} ) {
+ skip_chars("% ");
+ push_mark();
+ skip_chars("^:\n");
+ variable name = bufsubstr();
+ switch (name)
+ { case "LaTeX_master_file" or case "LaTeX_output_format":
+ create_blocal_var(name);
+ skip_chars(": ");
+ push_mark();
+ eol();
+ set_blocal_var(bufsubstr(), name);
+ }
+ }
+ bob();
+
+ while ( fsearch("\\begin{") )
+ {
+ () = right(7);
+ if ( is_commented() )
+ continue;
+
+ push_mark();
+ if ( ffind_char('}') )
+ {
+ variable env = chop_star( bufsubstr() );
+ if (orelse {env == "document"} {env_lookup(env, NULL) != NULL})
+ continue;
+
+ variable args = 0;
+ () = right(1);
+ while ( looking_at_char('{') )
+ {
+ ++args;
+ fsearch_matching_brace();
+ () = right(1);
+ }
+ env_register(env, args,
+ "(auto-added on file load, found somewhere in document)",
+ "", NULL);
+ }
+ else
+ pop_mark(0);
+ }
+
+ bob();
+ if ( fsearch("\\documentclass") )
+ while ( re_fsearch("\\[nb]e[wg]"R) )
+ {
+ () = right(1);
+ if ( is_commented() )
+ continue;
+
+ if ( looking_at("begin{document}") )
+ break;
+
+ variable is_newcmd = 0, is_newtheorem = 0;
+ if ( looking_at("newcommand") )
+ {
+ is_newcmd = 1;
+ () = right(10);
+ }
+ else if ( looking_at("newenvironment") )
+ () = right(14);
+ else if ( looking_at("newtheorem") )
+ {
+ is_newtheorem = 1;
+ () = right(10);
+ }
+ else
+ continue;
+
+ if ( looking_at_char('*') )
+ () = right(1);
+
+ variable arg_cnt;
+ (,name) = cmd_parse_args(0, 1);
+ name = name[0];
+ (arg_cnt,) = cmd_parse_args(1, 0);
+
+ if (orelse {is_newtheorem} {length(arg_cnt) == 0})
+ arg_cnt = int(0);
+ else
+ {
+ arg_cnt = integer(arg_cnt[0]);
+ if (is_newcmd)
+ { % \newcommand with default args
+ variable tmp;
+ (tmp,) = cmd_parse_args(arg_cnt, 0);
+ arg_cnt -= length(tmp);
+ }
+ }
+
+ if (is_newcmd)
+ {
+ variable def, is_math = 0;
+ (,def) = cmd_parse_args(0,1);
+ def = def[0];
+ if ( is_substr(def, "\\math") )
+ is_math = 1;
+ else if ( string_match(def, "[^\\][_^]"R, 1) >= 1 )
+ is_math = 1;
+
+ name = name[[1:]]; % remove the \
+ if (cmd_lookup(name, NULL) == NULL)
+ cmd_register(name, arg_cnt[0], int(is_math),
+ "(auto-added on file load, found in preample)",
+ "", NULL);
+ }
+ else
+ { % environments and theorems
+ if (env_lookup(name, NULL) == NULL)
+ env_register(name, arg_cnt,
+ "(auto-added on file load, found in preample)",
+ "", NULL);
+ }
+ }
+
+ bob();
+ }
+
+ run_mode_hooks("latex_mode_hook");
+}
+
+% -----
+
+provide("latex");
+runhooks("after_latex_load_hook", MODE);
+
+% --- End of file latex.sl
diff --git a/support/jed/jlm/latex_cmds.sl b/support/jed/jlm/latex_cmds.sl
new file mode 100644
index 0000000000..1a68264c04
--- /dev/null
+++ b/support/jed/jlm/latex_cmds.sl
@@ -0,0 +1,983 @@
+% File: latex_cmds.sl -*- mode: SLang -*-
+%
+% Copyright (c)
+% 2006--2007 Jörg Sommer <joerg@alea.gnuu.de>
+% $Id: latex_cmds.sl 200 2007-08-23 23:29:21Z joerg $
+%
+% -*- This file is part of Jörg's LaTeX Mode (JLM) -*-
+%
+% Description: Fixme
+%
+% License: 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 2 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.
+
+% Sort the file contents:
+% sed '/^\(% *\)\?cmd_register/!d; /^% /{s/^% //; s/$/%/;}' latex_cmds.sl |sort | sed '/%$/{s/%$//; s/^/% /;}'
+% Find duplicates:
+% sed '/^\(% *\)\?cmd_register/!d; s/^[^"]*"//; s/".*//;' latex_cmds.sl | uniq -d
+% Extract commands from latex files:
+% grep -Eo '\\[a-zA-Z]+(\{[^}]*\})*' skript.latex | sed '/\\begin{/d; s/{[^}]*}/{}/g'
+% Align command:
+% while (down(1)) if (ffind_char(',')) { ()=right(1); trim(); whitespace(37-what_column()); };
+
+static define cmd_hook_null(name, mark)
+{
+ % This is a simple function to remove the arguments from the
+ % stack put by cmd_insert() there
+}
+
+static define cmd_hook_goto_mark(name, mark)
+{
+ % This simple function is used for \LaTeX, \TeX and other
+ % commands they need {} after it to not eat up the space
+ goto_user_mark(mark);
+}
+
+static define cmd_hook_file_select(name, mark)
+{
+ try
+ {
+ variable file = read_with_completion("Which file?", "", "", 'f');
+ if ( path_is_absolute(file) )
+ {
+ variable bufdir;
+ (,bufdir,,) = getbuf_info();
+ variable bufdir_tok = strtok(bufdir, "/");
+ variable file_tok = strtok(file, "/"), x;
+
+ for (x=0; x < length(file_tok) and x < length(bufdir_tok); ++x)
+ if (strcmp(file_tok[x], bufdir_tok[x]) != 0)
+ break;
+
+ % We convert the absolute path into a relative path if the
+ % number of directories we must step downward in bufdir
+ % (=length(bufdir_tok)-x) is less than the number of elements
+ % we must step upward from the root in file (=x)
+ if ( length(bufdir_tok) <= 2*x )
+ {
+ --x;
+ file = "";
+ loop ( length(bufdir_tok)-x-1 )
+ file += "../";
+
+ file += strjoin(file_tok[[x+1:]], "/");
+ }
+ }
+ () = right(1);
+ insert(file);
+ goto_user_mark(mark);
+ }
+ catch UserBreakError: {}
+}
+
+static define cmd_hook_math(name, mark)
+{
+ variable my_mark = create_user_mark();
+ if (mark == my_mark)
+ % we don't need to watch because the jump would go to this position
+ return;
+
+ goto_user_mark(mark); % move behind the $
+ update(0);
+ variable ch = getkey();
+
+ if (is_substr("=-+<>", char(ch)))
+ goto_user_mark(my_mark);
+
+ ungetkey(ch);
+}
+
+private variable not_table = Assoc_Type[String_Type];
+
+not_table["cong"] = "ncong";
+% not_table["equiv"] = "notequiv";
+not_table["exists"] = "nexists";
+% not_table["gg"] = "ngg";
+not_table["in"] = "notin";
+not_table["Leftarrow"] = "nLeftarrow";
+not_table["leftarrow"] = "nleftarrow";
+not_table["Leftrightarrow"] = "nLeftrightarrow";
+not_table["leftrightarrow"] = "nleftrightarrow";
+% not_table["ll"] = "nll";
+not_table["mid"] = "nmid";
+not_table["models"] = "nvDash";
+not_table["ni"] = "notni";
+not_table["parallel"] = "nparallel";
+% not_table["perp"] = "notperp";
+not_table["Rightarrow"] = "nRightarrow";
+not_table["rightarrow"] = "nrightarrow";
+not_table["sim"] = "nsim";
+% not_table["subset"] = "nsubset";
+not_table["subseteq"] = "nsubseteq";
+% not_table["supset"] = "nsupset";
+not_table["supseteq"] = "nsupseteq";
+not_table["vDash"] = "nvDash";
+not_table["vdash"] = "nvdash";
+
+static define cmd_hook_math_not(name, mark)
+{
+ variable len = strlen(name) + 5; % \not\$name
+ () = left(len);
+ if ( looking_at("\\not") )
+ {
+ if ( assoc_key_exists(not_table, name) )
+ {
+ try
+ {
+ cmd_insert(not_table[name], 0);
+ deln(len);
+ }
+ catch ApplicationError;
+ }
+ }
+
+ goto_user_mark(mark);
+}
+
+private variable ref_filt = "";
+private variable ref_mark, ref_line_mark, ref_omark;
+private variable REF_MODE = MODE+"-label";
+
+static define ref_next(dir)
+{
+ if (dir)
+ {
+ % forward
+ !if ( orelse {not right(1)} {fsearch("\\label{" + ref_filt)} )
+ {
+ () = left(1);
+ throw UsageError, "Nothing found";
+ }
+ }
+ else
+ {
+ % search backward
+ !if ( bsearch("\\label{" + ref_filt) )
+ throw UsageError, "Nothing found";
+ }
+ ref_line_mark = create_line_mark(color_number("region"));
+ message("UP/DOWN: label matchs \"" + ref_filt +
+ "\" Q quit ENTER insert SPACE set filter");
+}
+
+static define ref_quit()
+{
+ use_keymap(MODE);
+ set_readonly(0);
+
+ goto_user_mark(ref_mark);
+ __uninitialize(&ref_line_mark); % remove the highlighting
+}
+
+static define ref_insert()
+{
+ !if ( looking_at("\\label{") )
+ throw UsageError, "Did not find \"\\label{\". Do you moved the cursor?";
+
+ () = right(7);
+ push_mark();
+ !if ( ffind_char('}') )
+ eol();
+
+ bufsubstr();
+
+ ref_quit();
+
+ insert( () );
+ goto_user_mark(ref_omark);
+}
+
+static define ref_filter()
+{
+ try
+ ref_filt = read_mini("Label filter:", "", ref_filt);
+ catch UserBreakError;
+ message("UP/DOWN: label matchs \"" + ref_filt +
+ "\" Q quit ENTER insert SPACE set filter");
+}
+
+static define cmd_hook_ref(name, mark)
+{
+ ref_omark = mark;
+ !if ( keymap_p(REF_MODE) )
+ {
+ make_keymap(REF_MODE);
+
+ definekey("latex->ref_next(1)", "n", REF_MODE);
+ definekey("latex->ref_next(1)", Key_Down, REF_MODE);
+ definekey("latex->ref_next(0)", "p", REF_MODE);
+ definekey("latex->ref_next(0)", Key_Up, REF_MODE);
+
+ definekey("latex->ref_insert()", Key_Enter, REF_MODE);
+ definekey("latex->ref_insert()", Key_Return, REF_MODE);
+ definekey("latex->ref_quit()", "q", REF_MODE);
+ definekey("latex->ref_quit()", "\007", REF_MODE); % Ctrl-G
+ definekey("latex->ref_filter()", Key_Space, REF_MODE);
+ }
+ use_keymap(REF_MODE);
+ set_readonly(1);
+ () = right(1);
+ ref_mark = create_user_mark();
+ ref_filt = "";
+ message("UP/DOWN: label matchs \"\" Q quit ENTER insert SPACE set filter");
+}
+
+static define cmd_hook_label(name, mark)
+{
+ variable start_mark = create_user_mark();
+ variable label = "";
+
+ % defaults as proposed in info latex Node label
+ if ( is_math() )
+ label = "eq:";
+ else
+ {
+ % figure -> fig: table -> tab: and so on
+ label = env_name();
+ if (andelse {label == "document"} {re_bsearch("\\[sc][euh][cba]"R)}) % Fixme: PCRE
+ {
+ if ( orelse {looking_at("\\section{")} {looking_at("\\subsection{")}
+ {looking_at("\\subsubsection{")} )
+ label = "sec";
+ else if ( looking_at("\\chapter{") )
+ label = "cha";
+ }
+
+ if (strlen(label) > 4)
+ label = substr(label, 1, 3);
+
+ label += ":";
+ }
+
+ if (label != "")
+ {
+ variable l = "\\$name{$label"$;
+ if ( bsearch(l) )
+ {
+ () = right( strlen(l) );
+ push_mark();
+ () = ffind_char('}');
+ try
+ label += string(integer( bufsubstr() )+1);
+ catch ParseError;
+ }
+ else
+ label += "1";
+ }
+
+ goto_user_mark(start_mark);
+ try
+ {
+ do
+ {
+ label = read_mini("Label:", "", label);
+ bob();
+ }
+ while ( andelse {fsearch("\\$name{$label}"$)}
+ {get_y_or_n("Label already defined. Use it") == 0});
+
+ goto_user_mark(start_mark);
+ () = right(1);
+ insert(label);
+ goto_user_mark(mark);
+ }
+ catch UserBreakError:
+ {
+ goto_user_mark(mark);
+ push_mark();
+ () = bfind("\\" + name + "{");
+ del_region();
+ }
+}
+
+%%%%%%%%%%
+%
+% Stuff for the cmd_hook_bib_cite
+%
+
+private variable BIB_KEYMAP = "latex_bib";
+private variable bib_mark, bib_old_status_line;
+
+!if ( keymap_p(BIB_KEYMAP) )
+{
+ make_keymap (BIB_KEYMAP);
+
+ definekey_reserved("latex->bib_quit", "q", BIB_KEYMAP);
+ definekey_reserved("latex->bib_quit", "^q", BIB_KEYMAP);
+ definekey_reserved("latex->bib_select", "s", BIB_KEYMAP);
+ definekey_reserved("latex->bib_select", "^s", BIB_KEYMAP);
+ definekey("latex->newline_with_completion", Key_Shift_Return, BIB_KEYMAP);
+ definekey_reserved("latex->newline_with_completion", "\n", BIB_KEYMAP);
+}
+
+static define cmd_hook_bib_cite(name, mark)
+{
+ bib_mark = create_user_mark();
+
+ bob();
+ if ( fsearch("\\begin{thebibliography}") )
+ {
+ push_mark();
+ !if ( fsearch("\\end{thebibliography}") )
+ {
+ pop_mark(0);
+ throw ApplicationError, "\\begin{thebibliography} found but no \\end";
+ }
+ }
+ else
+ {
+ !if ( fsearch("\\end{document}") )
+ throw ApplicationError, "No \\end{document} found";
+
+ insert("\\clearpage\n\n");
+ () = up(1);
+ push_spot();
+ env_insert("thebibliography", "{99}");
+ () = fsearch("\\end{thebibliography}");
+ push_mark();
+ pop_spot();
+ }
+
+ narrow();
+ bob();
+ use_keymap(BIB_KEYMAP);
+ bib_old_status_line = Status_Line_String;
+ set_status_line(" "+expand_keystring(_Reserved_Key_Prefix)+
+ "s: select bibitem "+
+ expand_keystring(_Reserved_Key_Prefix)+"q: quit ", 0);
+}
+
+static define bib_quit()
+{
+ widen();
+ goto_user_mark(bib_mark);
+ use_keymap(MODE);
+ set_status_line(bib_old_status_line, 0);
+}
+
+static define bib_select()
+{
+ bol();
+ !if ( ffind("\\bibitem{") )
+ throw UsageError, "No \\bibitem in this line";
+
+ () = right(9);
+ push_mark();
+ !if ( ffind_char('}') )
+ {
+ pop_mark(0);
+ throw ApplicationError, "Malformed \\bibitem: No } found";
+ }
+
+ variable item = bufsubstr();
+ bib_quit();
+ if ( looking_at_char('{') )
+ {
+ () = right(1);
+ insert(item);
+ }
+ else
+ {
+ push_spot();
+ ffind_char('{');
+ () = right(1);
+ insert(item);
+ pop_spot();
+ }
+ () = right(1);
+}
+
+%%%%%%%%%%
+%
+% command definitions
+%
+
+% Fixme: many symbols are in groff_char(7)
+
+cmd_register("acute", 0, 1, "", "", NULL);
+cmd_register("add", 2, 1, "adds row/column n to row/column k in a gmatrix", "gauss", NULL);
+cmd_register("addtocounter", 2, 0, "Increments the counter (1st arg) by 2nd arg", "", NULL);
+cmd_register("addtolength", 2, 0, "Adds #2 to the length register #1", "", NULL);
+#if (_slang_utf8_ok)
+cmd_register("alpha", 0, 1, "Greek character α", "", &cmd_hook_math());
+#else
+cmd_register("alpha", 0, 1, "Greek character", "", &cmd_hook_math());
+#endif
+cmd_register("AMS", 1, 0, "The AMS logo", "dtklogos", &cmd_hook_goto_mark());
+cmd_register("AMSLaTeX", 1, 0, "The AMS-LaTeX logo", "dtklogos", &cmd_hook_goto_mark());
+cmd_register("AMSTeX", 1, 0, "The AMS-TeX logo", "dtklogos", &cmd_hook_goto_mark());
+cmd_register("analg", 0, 1, "binary operator", "", NULL);
+cmd_register("appendix", 0, 0, "Start the appendix", "", NULL);
+#if (_slang_utf8_ok)
+cmd_register("approx", 0, 1, "Mathematical sign for approx â‰", "", NULL);
+#else
+cmd_register("approx", 0, 1, "Mathematical sign for approx", "", NULL);
+#endif
+cmd_register("arccos", 0, 1, "mathematical function", "", NULL);
+cmd_register("arcsin", 0, 1, "mathematical function", "", NULL);
+cmd_register("arctan", 0, 1, "mathematical function", "", NULL);
+cmd_register("arg", 0, 1, "mathematical function", "", NULL);
+cmd_register("arrowvert", 0, 1, "mathematical delimiter", "", NULL);
+cmd_register("Arrowvert", 0, 1, "mathematical delimiter", "", NULL);
+cmd_register("ast", 0, 1, "Asterisk *", "", NULL);
+cmd_register("asymp", 0, 1, "binary relations", "", NULL);
+% cmd_register("atop", 2, 0, "", "", NULL);
+cmd_register("author", 1, 0, "Sets the author of the document", "", NULL);
+cmd_register("autoref", 1, 0, "", "hyperref", &cmd_hook_ref());
+% cmd_register("backslash", 0, 0, "", "", NULL);
+cmd_register("backslashbox", 2, 0, "A big slash in the upper left corner of a tabular", "slashbox", NULL);
+cmd_register("bar", 1, 1, "Draw a line over a math symbol", "", NULL);
+cmd_register("beta", 0, 1, "Greek character", "", &cmd_hook_math());
+cmd_register("bfseries", 0, 0, "Changes the font series to bold face", "", NULL);
+cmd_register("bibitem", 1, 0, "Specify a bibliography item", "", NULL);
+cmd_register("BibTeX", 1, 0, "The BibTeX logo", "dtklogos", &cmd_hook_goto_mark());
+% cmd_register("big", 0, 1, "", "", NULL);
+% cmd_register("Big", 0, 1, "", "", NULL);
+cmd_register("bigcap", 0, 1, "Big intersection sign", "", NULL);
+cmd_register("bigcirc", 0, 1, "binary operator", "", NULL);
+cmd_register("bigcup", 0, 1, "Big union sign", "", NULL);
+% cmd_register("bigg", 0, 0, "", "", NULL);
+% cmd_register("Bigg", 0, 0, "", "", NULL);
+% cmd_register("biggl", 0, 0, "", "", NULL);
+% cmd_register("Biggl", 0, 0, "", "", NULL);
+% cmd_register("biggr", 0, 0, "", "", NULL);
+% cmd_register("Biggr", 0, 0, "", "", NULL);
+% cmd_register("bigl", 0, 0, "", "", NULL);
+% cmd_register("Bigl", 0, 0, "", "", NULL);
+% cmd_register("bigr", 0, 0, "", "", NULL);
+% cmd_register("Bigr", 0, 0, "", "", NULL);
+cmd_register("bigtriangledown", 0, 1, "binary operator", "", NULL);
+cmd_register("bigtriangleup", 0, 1, "binary operator", "", NULL);
+cmd_register("bigvee", 0, 1, "", "", NULL);
+cmd_register("bigwedge", 0, 1, "", "", NULL);
+cmd_register("binom", 2, 1, "binomial expression; \\frac without horizontal line", "amsmath", NULL);
+cmd_register("blacksquare", 0, 1, "A black filled square", "amssymb", NULL);
+cmd_register("blacktriangle", 0, 1, "A black filled triangle", "amssymb", NULL);
+cmd_register("bmod", 1, 1, "The mod operator for binary relation", "amsmath", NULL);
+cmd_register("boolean", 1, 0, "Queries a boolean register defined the \\newboolean", "ifthen", NULL);
+cmd_register("bottomrule", 0, 0, "A horizontal line with better spacing at bottom of a tabular"R, "booktabs", NULL);
+cmd_register("bowtie", 0, 1, "binary relations", "", NULL);
+cmd_register("Box", 0, 1, "an empty box", "amssymb", NULL);
+% cmd_register("boxed", 0, 0, "", "", NULL);
+cmd_register("bracevert", 0, 1, "mathematical delimiter", "", NULL);
+cmd_register("breve", 0, 1, "", "", NULL);
+cmd_register("bullet", 0, 1, "binary operator", "", NULL);
+cmd_register("cap", 0, 1, "Sign of intersection of sets", "", NULL);
+cmd_register("caption", 1, 0, "Caption of a figure or a table", "", NULL);
+cmd_register("carriagereturn", 1, 0, "Symbol for carriage return"R, "dingbat", &cmd_hook_goto_mark());
+cmd_register("cdot", 0, 1, "Centered dot â‹…", "", NULL);
+cmd_register("cdots", 0, 1, "Three centered dots", "", NULL);
+cmd_register("centering", 0, 0, "Switches the text alignment to centering", "", NULL);
+cmd_register("chapter", 1, 0, "Starts a new chapter in a book or report", "", NULL);
+cmd_register("check", 1, 1, "Reverse \\hat", "", NULL);
+cmd_register("chi", 0, 1, "Greek character", "", &cmd_hook_math());
+cmd_register("circ", 0, 1, "binary operator", "", NULL);
+cmd_register("cite", 1, 0, "Refer to a bibliography item", "", &cmd_hook_bib_cite());
+cmd_register("cleardoublepage", 0, 0, "", "", NULL);
+cmd_register("clearpage", 0, 0, "", "", NULL);
+cmd_register("cline", 1, 0, "a horizontal line spanning multiple columns, e.g. 2-5", "", NULL);
+cmd_register("colon", 0, 1, "A colon in math mode; : is the division operator 1:2", "", NULL);
+cmd_register("colops", 0, 1, "switches in a gmatrix into column operation mode", "gauss", NULL);
+cmd_register("color", 0, 0, "", "", NULL);
+#if (_slang_utf8_ok)
+cmd_register("cong", 0, 1, "binary relations ≅", "", &cmd_hook_math_not());
+#else
+cmd_register("cong", 0, 1, "binary relations", "", &cmd_hook_math_not());
+#endif
+cmd_register("cos", 0, 1, "mathematical function", "", NULL);
+cmd_register("cosh", 0, 1, "mathematical function", "", NULL);
+cmd_register("cot", 0, 1, "mathematical function", "", NULL);
+cmd_register("coth", 0, 1, "mathematical function", "", NULL);
+cmd_register("csc", 0, 1, "mathematical function", "", NULL);
+cmd_register("cup", 0, 1, "Sign of union of sets", "", NULL);
+cmd_register("curvearrowright", 0, 1, "", "", NULL);
+cmd_register("dagger", 0, 1, "binary operator", "", NULL);
+cmd_register("dante", 1, 0, "The dante logo", "dtxlogos", &cmd_hook_goto_mark());
+cmd_register("Dante", 1, 0, "The full dante logo", "dtxlogos", &cmd_hook_goto_mark());
+cmd_register("dashv", 0, 1, "binary relations", "", NULL);
+cmd_register("date", 0, 0, "Current date", "", NULL);
+cmd_register("ddagger", 0, 1, "binary operator", "", NULL);
+cmd_register("ddot", 0, 1, "", "", NULL);
+cmd_register("ddots", 0, 1, "Diagonal dots", "", NULL);
+cmd_register("DeclareMathOperator", 2, 0, "declare a string as operator like \log"R, "amsmath", NULL);
+cmd_register("deg", 0, 1, "mathematical function", "", NULL);
+cmd_register("delta", 0, 1, "", "", &cmd_hook_math());
+cmd_register("Delta", 0, 1, "", "", &cmd_hook_math());
+cmd_register("det", 0, 1, "Mathematical function: determinant", "", &cmd_hook_null());
+cmd_register("diamond", 0, 1, "binary operator", "", NULL);
+cmd_register("dim", 0, 1, "Mathematical function: dimension", "", NULL);
+cmd_register("displaybreak", 0, 1, "Defined the point where an equantion can be broken; Place it immedeatly before \\"R, "amsmath", NULL);
+cmd_register("displaystyle", 0, 1, "Switches the style of a formula to display", "", NULL);
+cmd_register("div", 0, 1, "Mathematical operator: divide", "", NULL);
+cmd_register("dot", 0, 1, "", "", NULL);
+cmd_register("doteq", 0, 1, "binary relations", "", NULL);
+cmd_register("dots", 1, 0, "Dots in textmode with special space correction", "ellipsis", &cmd_hook_goto_mark());
+cmd_register("dotsb", 0, 0, "Dots in mathmode for binary operators/relations", "amsmath", NULL);
+cmd_register("dotsc", 0, 0, "Dots in mathmode for commas", "amsmath", NULL);
+cmd_register("dotsi", 0, 0, "Dots in mathmode for integrals", "amsmath", NULL);
+cmd_register("dotsm", 0, 0, "Dots in mathmode for multiplication", "amsmath", NULL);
+cmd_register("dotso", 0, 0, "Dots in mathmode for everything else", "amsmath", NULL);
+cmd_register("downarrow", 0, 1, "", "", NULL);
+cmd_register("dq", 1, 0, "A \" character", "babel,ngerman", &cmd_hook_goto_mark());
+cmd_register("ell", 0, 1, "", "", NULL);
+cmd_register("emph", 1, 0, "Emphasize", "", NULL);
+cmd_register("emptyset", 0, 1, "", "", NULL);
+cmd_register("enlargethispage", 1, 0, "", "", NULL);
+cmd_register("ensuremath", 1, 0, "", "", NULL);
+cmd_register("epsilon", 0, 1, "", "", &cmd_hook_math());
+cmd_register("eqref", 1, 0, "", "amsmath", &cmd_hook_ref());
+#if (_slang_utf8_ok)
+cmd_register("equiv", 0, 1, "Symbol for \"equivalent\" ≡", "", NULL);
+cmd_register("eta", 0, 1, "Grrek character ε", "", &cmd_hook_math());
+cmd_register("EUR", 1, 0, "Typsets a amount with the Euro symbol €; {amount}", "eurosym", NULL);
+cmd_register("euro", 1, 0, "The Euro symbol €", "eurosym", &cmd_hook_goto_mark());
+cmd_register("exists", 0, 1, "Symbol for \"there exists\" â", "", NULL);
+#else
+cmd_register("equiv", 0, 1, "Symbol for \"equivalent\"", "", NULL);
+cmd_register("eta", 0, 1, "Grrek character", "", &cmd_hook_math());
+cmd_register("euro", 1, 0, "The Euro symbol", "eurosym", &cmd_hook_goto_mark());
+cmd_register("exists", 0, 1, "Symbol for \"there exists\"", "", &cmd_hook_math_not());
+#endif
+cmd_register("exp", 0, 1, "exponential function", "", NULL);
+% cmd_register("fbox", 0, 0, "", "", NULL);
+cmd_register("fg", 1, 0, "right french quoting sign >>", "babel,frenchb", &cmd_hook_goto_mark());
+cmd_register("footnote", 1, 0, "", "", NULL);
+cmd_register("footnotemark", 0, 0, "Inserts the next mark for a footnote", "", NULL);
+cmd_register("footnotetext", 1, 0, "Sets a new footnote with the current mark", "", NULL);
+#if (_slang_utf8_ok)
+cmd_register("forall", 0, 1, "Logical \"for all\" â€", "", &cmd_hook_null());
+#else
+cmd_register("forall", 0, 1, "Logical \"for all\"", "", &cmd_hook_null());
+#endif
+cmd_register("foreignlanguage", 2, 0, "Treats #2 as text in language #1", "babel", NULL);
+cmd_register("frac", 2, 1, "Fraction [math]", "", NULL);
+cmd_register("framebox", 1, 0, "Draws a border around the text", "", NULL);
+cmd_register("frown", 0, 1, "binary relations", "", NULL);
+cmd_register("gamma", 0, 1, "", "", &cmd_hook_math());
+cmd_register("Gamma", 0, 1, "", "", &cmd_hook_math());
+cmd_register("gcd", 0, 1, "mathematical function", "", NULL);
+#if (_slang_utf8_ok)
+cmd_register("geq", 0, 1, "Symbol for \"greater or equal than\" ≥", "", NULL);
+#else
+cmd_register("geq", 0, 1, "Symbol for \"greater or equal than\"", "", NULL);
+#endif
+cmd_register("gg", 0, 1, "binary relations", "", NULL);
+cmd_register("glqq", 1, 0, "german left double quote", "babel,ngerman", &cmd_hook_goto_mark());
+cmd_register("glq", 1, 0, "german left single quote", "babel,ngerman", &cmd_hook_goto_mark());
+cmd_register("grave", 0, 1, "", "", NULL);
+cmd_register("grqq", 1, 0, "german right double quote", "babel,ngerman", &cmd_hook_goto_mark());
+cmd_register("grq", 1, 0, "german right single quote", "babel,ngerman", &cmd_hook_goto_mark());
+cmd_register("hat", 1, 1, "", "", NULL);
+cmd_register("hbox", 1, 0, "", "", NULL);
+% cmd_register("hdots", 0, 1, "", "", NULL);
+cmd_register("hfill", 0, 0, "", "", NULL);
+cmd_register("hline", 0, 0, "", "", NULL);
+cmd_register("hom", 0, 1, "mathematical function", "", NULL);
+cmd_register("hookrightarrow", 0, 1, "", "", NULL);
+cmd_register("href", 2, 0, "Reference to an external resources", "hyperref", NULL);
+cmd_register("hspace", 1, 0, "", "", NULL);
+cmd_register("hyperref", 1, 0, "Make the arg. be a reference to the target in the opt. arg.", "", NULL); % &label_ref_hook()
+cmd_register("hyphenation", 1, 0, "Defines hyphenation points for a list of words", "", NULL);
+% cmd_register("id", 0, 0, "", "", NULL);
+cmd_register("ifthenelse", 3, 0, "", "ifthen", NULL);
+cmd_register("iiiint", 0, 1, "", "", NULL);
+cmd_register("iiint", 0, 1, "", "", NULL);
+cmd_register("iint", 0, 1, "", "", NULL);
+% cmd_register("ilimits", 0, 0, "", "", NULL);
+cmd_register("Im", 0, 1, "Imaginary part of a number", "", NULL);
+cmd_register("in", 0, 1, "binary relations", "", &cmd_hook_math_not());
+cmd_register("include", 1, 0, "", "", &cmd_hook_file_select());
+cmd_register("includegraphics", 1, 0, "Inserts a graphic", "graphicx", &cmd_hook_file_select());
+% cmd_register("ind", 0, 0, "", "", NULL);
+cmd_register("index", 1, 0, "Creates an index entry", "makeidx", NULL);
+cmd_register("inf", 0, 1, "mathematical function: infimum", "", NULL);
+cmd_register("infty", 0, 1, "", "", NULL);
+cmd_register("input", 1, 0, "", "", &cmd_hook_file_select());
+cmd_register("int", 0, 1, "", "", NULL);
+cmd_register("intertext", 1, 1, "", "", NULL);
+cmd_register("item", 0, 0, "New item in an enumerate, itemize or list", "", NULL);
+cmd_register("itshape", 0, 0, "", "", NULL);
+cmd_register("Join", 0, 1, "binary relations", "", NULL);
+cmd_register("kappa", 0, 1, "", "", &cmd_hook_math());
+cmd_register("ker", 0, 1, "mathematical function", "", NULL);
+cmd_register("label", 1, 0, "Create an anchor for a reference (\\ref)", "", &cmd_hook_label());
+cmd_register("lambda", 0, 1, "", "", &cmd_hook_math());
+cmd_register("Lambda", 0, 1, "", "", &cmd_hook_math());
+#if (_slang_utf8_ok)
+cmd_register("langle", 0, 1, "mathematical delimiter: 〈", "", NULL);
+#else
+cmd_register("langle", 0, 1, "mathematical delimiter: <", "", NULL);
+#endif
+cmd_register("LaTeX", 1, 0, "", "", &cmd_hook_goto_mark());
+cmd_register("lceil", 0, 1, "mathematical delimiter", "", NULL);
+cmd_register("ldots", 1, 0, "Three dots at the base line", "", &cmd_hook_goto_mark());
+cmd_register("le", 0, 1, "the same as \leq"R, "", NULL);
+cmd_register("leadsto", 0, 1, "", "wasysym", NULL);
+cmd_register("left", 0, 1, "", "", NULL);
+#if (_slang_utf8_ok)
+cmd_register("Leftarrow", 0, 1, "â‡", "", &cmd_hook_math_not());
+cmd_register("leftarrow", 0, 1, "â†", "", &cmd_hook_math_not());
+cmd_register("leftrightarrow", 0, 1, "↔", "", &cmd_hook_math_not());
+cmd_register("Leftrightarrow", 0, 1, "⇔", "", &cmd_hook_math_not());
+cmd_register("leq", 0, 1, "Symbol for \"lower or equal than\" ≤", "", NULL);
+#else
+cmd_register("Leftarrow", 0, 1, "<=", "", &cmd_hook_math_not());
+cmd_register("leftarrow", 0, 1, "<-", "", &cmd_hook_math_not());
+cmd_register("leftrightarrow", 0, 1, "<->", "", &cmd_hook_math_not());
+cmd_register("Leftrightarrow", 0, 1, "<=>", "", &cmd_hook_math_not());
+cmd_register("leq", 0, 1, "Symbol for \"lower or equal than\"", "", NULL);
+#endif
+cmd_register("lfloor", 0, 1, "mathematical delimiter", "", NULL);
+cmd_register("lg", 0, 1, "mathematical function: logarithm base 10", "", NULL);
+cmd_register("lgroup", 0, 1, "mathematical delimiter", "", NULL);
+cmd_register("Lightning", 0, 0, "", "marvosym", NULL);
+cmd_register("lightning", 1, 0, "", "wasysym", &cmd_hook_goto_mark());
+cmd_register("lim", 0, 1, "mathematical function: limit", "", NULL);
+cmd_register("liminf", 0, 1, "mathematical function: lower limit", "", NULL);
+cmd_register("limits", 0, 1, "forces limits to be place under and above", "", NULL);
+cmd_register("limsup", 0, 1, "mathematical function: upper limit", "", NULL);
+cmd_register("linebreak", 0, 0, "", "", NULL);
+cmd_register("lineskip", 0, 0, "Abstand zwischen Zeilen", "", NULL);
+cmd_register("linewidth", 0, 0, "", "", NULL);
+cmd_register("listfiles", 0, 0, "Print list of used files after compilation", "", NULL);
+cmd_register("listtheorems", 0, 0, "", "ntheorem", NULL);
+cmd_register("ll", 0, 1, "binary relations: <<", "", NULL);
+cmd_register("lmoustache", 0, 1, "mathematical delimiter", "", NULL);
+cmd_register("ln", 0, 1, "mathematical function: natural logarithm", "", NULL);
+cmd_register("log", 0, 1, "mathematical function: logarithm", "", NULL);
+cmd_register("longmapsto", 0, 1, "", "", NULL);
+#if (_slang_utf8_ok)
+cmd_register("longleftarrow", 0, 1, "â†âŽŻ", "", NULL);
+cmd_register("Longleftarrow", 0, 1, "â‡â•", "", NULL);
+cmd_register("longleftrightarrow", 0, 1, "â†âŽŻâ†’", "", NULL);
+cmd_register("Longleftrightarrow", 0, 1, "â‡â•â‡’", "", NULL);
+cmd_register("longrightarrow", 0, 1, "⎯→", "", NULL);
+cmd_register("Longrightarrow", 0, 1, "â•â‡’", "", NULL);
+#else
+cmd_register("longleftarrow", 0, 1, "<--", "", NULL);
+cmd_register("Longleftarrow", 0, 1, "<==", "", NULL);
+cmd_register("longleftrightarrow", 0, 1, "<-->", "", NULL);
+cmd_register("Longleftrightarrow", 0, 1, "<==>", "", NULL);
+cmd_register("longrightarrow", 0, 1, "-->", "", NULL);
+cmd_register("Longrightarrow", 0, 1, "==>", "", NULL);
+#endif
+cmd_register("lseil", 0, 1, "", "", NULL);
+cmd_register("lvert", 0, 1, "", "amsmath", NULL);
+cmd_register("lVert", 0, 1, "", "amsmath", NULL);
+cmd_register("makebox", 1, 0, "", "", NULL);
+cmd_register("makeindex", 0, 0, "", "makeidx", NULL);
+cmd_register("maketitle", 0, 0, "", "", NULL);
+cmd_register("mapsto", 0, 1, "", "", NULL);
+cmd_register("marginpar", 1, 0, "", "mparhack", NULL);
+#if (_slang_utf8_ok)
+cmd_register("mathbb", 1, 1, "Characters with double strokes like â„ť", "amssymb", NULL);
+#else
+cmd_register("mathbb", 1, 1, "Characters with double strokes like |R", "amssymb", NULL);
+#endif
+cmd_register("mathbf", 1, 1, "Bold font in math mode", "", NULL);
+cmd_register("mathcal", 1, 1, "Calligraphic letter in math mode", "", NULL);
+cmd_register("mathfrak", 1, 1, "Fraktur font in math mode", "amssymb", NULL);
+cmd_register("mathit", 1, 1, "Italic font in math mode (e.g. variable names, NULL)", "", NULL);
+cmd_register("mathnormal", 1, 1, "Normal font in math mode", "", NULL);
+cmd_register("mathrm", 1, 1, "Roman font in math mode", "", NULL);
+cmd_register("mathscr", 1, 0, "", "mathrsfs", NULL);
+cmd_register("mathsf", 1, 1, "Sans serif font in math mode", "", NULL);
+cmd_register("mathtt", 1, 1, "Typewriter font in math mode", "", NULL);
+cmd_register("max", 0, 1, "mathematical function: maximum", "", NULL);
+cmd_register("mbox", 1, 0, "", "", NULL);
+cmd_register("mdseries", 0, 0, "", "", NULL);
+cmd_register("mid", 0, 1, "binary relations", "", &cmd_hook_math_not());
+cmd_register("midrule", 0, 0, "A horizontal line with better spacing within a tabular"R, "booktabs", NULL);
+cmd_register("min", 0, 1, "mathematical function: minimum", "", NULL);
+cmd_register("minisec", 1, 0, "", "", NULL);
+cmd_register("mod", 0, 1, "", "", NULL);
+cmd_register("models", 0, 1, "binary relations", "", &cmd_hook_math_not());
+cmd_register("mp", 0, 1, "binary operator: minus plus", "", NULL);
+cmd_register("mspace", 1, 1, "Space (like \\hspace) in math; with mu as math units", "amsmath", NULL);
+cmd_register("mu", 0, 1, "", "", &cmd_hook_math());
+cmd_register("mult", 2, 1, "multiply the n-th row/column in a gmatrix by b", "gauss", NULL);
+cmd_register("multicolumn", 3, 0, "", "", NULL);
+cmd_register("nabla", 0, 1, "", "", NULL);
+cmd_register("ncong", 0, 1, "short for \\not\\cong", "amssymb", NULL);
+cmd_register("ne", 0, 1, "short for \\not=", "", NULL);
+#if (_slang_utf8_ok)
+cmd_register("neg", 0, 1, "Logical negation ¬", "", &cmd_hook_null());
+#else
+cmd_register("neg", 0, 1, "Logical negation", "", &cmd_hook_null());
+#endif
+cmd_register("neq", 0, 1, "binary relation: not equal", "", NULL);
+cmd_register("newboolean", 1, 0, "Defines a new boolean register", "ifthen", NULL);
+cmd_register("newcommand*", 2, 0, "", "", NULL);
+cmd_register("newcounter", 1, 0, "", "", NULL);
+cmd_register("newenvironment*", 3, 0, "", "", NULL);
+cmd_register("newlength", 1, 0, "Create a new length register", "", NULL);
+cmd_register("newline", 0, 0, "", "", NULL);
+cmd_register("newpage", 0, 0, "", "", NULL);
+cmd_register("newtheorem", 2, 0, "", "ntheorem", NULL);
+cmd_register("nexists", 0, 1, "short for \\not\\exists", "amsmath", NULL);
+cmd_register("ngg", 0, 1, "short for \\not\\gg", "txfonts", NULL);
+cmd_register("ni", 0, 1, "binary relations: mirrowed \in"R, "", &cmd_hook_math_not());
+cmd_register("nicefrac", 2, 1, "typeset fraction with a slash", "nicefrac", NULL);
+cmd_register("nLeftarrow", 0, 1, "short for \\not\\Leftarrow", "amsmath", NULL);
+cmd_register("nleftarrow", 0, 1, "short for \\not\\leftarrow", "amsmath", NULL);
+cmd_register("nLeftrightarrow", 0, 1, "short for \\not\\Leftrightarrow", "amsmath", NULL);
+cmd_register("nleftrightarrow", 0, 1, "short for \\not\\leftrightarrow", "amsmath", NULL);
+cmd_register("nll", 0, 1, "short for \\not\\ll", "txfonts", NULL);
+cmd_register("nmid", 0, 1, "short for \\not\\mid", "amssymb", NULL);
+cmd_register("nocite", 1, 0, "Include an item in the bibliography", "", &cmd_hook_bib_cite());
+cmd_register("noindent", 0, 0, "", "", NULL);
+cmd_register("nolimits", 0, 1, "", "", NULL);
+cmd_register("nolinebreak", 0, 0, "", "", NULL);
+cmd_register("nolinkurl", 1, 0, "Definition of \url from url.sty if hyperref is loaded"R, "hyperref", NULL);
+cmd_register("nopagebreak", 0, 0, "", "", NULL);
+cmd_register("normalfont", 0, 0, "", "", NULL);
+cmd_register("not", 0, 1, "binary relation", "", &cmd_hook_null());
+cmd_register("notag", 0, 1, "State that an equation should not get a number"R, "", NULL);
+cmd_register("notin", 0, 1, "short for \not\in"R, "", &cmd_hook_null());
+cmd_register("notni", 0, 1, "short for \\not\\ni", "txfonts", NULL);
+cmd_register("nparallel", 0, 1, "short for \\not\\parallel", "amsmath", NULL);
+cmd_register("nRightarrow", 0, 1, "short for \\not\\Rightarrow", "amsmath", NULL);
+cmd_register("nrightarrow", 0, 1, "short for \\not\\rightarrow", "amsmath", NULL);
+cmd_register("nsim", 0, 1, "short for \\not\\sim", "amsmath", NULL);
+cmd_register("nsubseteq", 0, 1, "short for \\not\\subseteq", "amsmath", NULL);
+cmd_register("nsupseteq", 0, 1, "short for \\not\\supseteq", "amsmath", NULL);
+cmd_register("nu", 0, 1, "", "", &cmd_hook_math());
+cmd_register("nvdash", 0, 1, "short for \\not\\vdash", "amsmath", NULL);
+cmd_register("nvDash", 0, 1, "short for \\not\\vDash", "amsmath", NULL);
+cmd_register("odot", 0, 1, "binary operator", "", NULL);
+cmd_register("og", 1, 0, "left french quoting sign <<", "babel,frenchb", &cmd_hook_goto_mark());
+cmd_register("oint", 0, 1, "", "", NULL);
+cmd_register("oldnum", 1, 0, "Old style numbers (Minuskelziffern)", "", NULL);
+cmd_register("omega", 0, 1, "", "", &cmd_hook_math());
+cmd_register("Omega", 0, 1, "", "", &cmd_hook_math());
+cmd_register("ominus", 0, 1, "binary operator", "", NULL);
+cmd_register("operatorname", 1, 1, "typesets a string as operator name", "amsmath", NULL);
+cmd_register("oplus", 0, 1, "binary operator", "", NULL);
+cmd_register("oslash", 0, 1, "binary operator", "", NULL);
+cmd_register("otimes", 0, 1, "binary operator", "", NULL);
+cmd_register("overbrace", 1, 1, "", "", NULL);
+cmd_register("overleftarrow", 0, 1, "", "", NULL);
+cmd_register("overline", 1, 1, "", "", NULL);
+cmd_register("overrightarrow", 0, 1, "", "", NULL);
+cmd_register("overset", 0, 1, "", "", NULL);
+cmd_register("pagebreak", 0, 0, "", "", NULL);
+cmd_register("pageref", 1, 0, "", "", &cmd_hook_ref());
+cmd_register("pagestyle", 1, 0, "", "", NULL);
+cmd_register("paragraph", 1, 0, "Starts a new paragraph", "", NULL);
+cmd_register("parallel", 0, 1, "binary relations: a parallel b", "", &cmd_hook_math_not());
+cmd_register("parbox", 2, 0, "", "", NULL);
+cmd_register("parindent", 0, 0, "", "", NULL);
+cmd_register("part", 1, 0, "Starts a new part of a book or report", "", NULL);
+#if (_slang_utf8_ok)
+cmd_register("partial", 0, 1, "Differentiation character â‚", "", NULL);
+#else
+cmd_register("partial", 0, 1, "Differentiation character", "", NULL);
+#endif
+cmd_register("pdfbookmark", 2, 0, "", "hyperref", NULL);
+cmd_register("pdsetup", 1, 0, "Settings for powerdot presentations", "", NULL);
+cmd_register("perp", 0, 1, "binary relations", "", NULL);
+cmd_register("phantom", 1, 0, "", "", NULL);
+cmd_register("phi", 0, 1, "", "", &cmd_hook_math());
+cmd_register("Phi", 0, 1, "", "", &cmd_hook_math());
+cmd_register("pi", 0, 1, "", "", &cmd_hook_math());
+cmd_register("Pi", 0, 1, "", "", &cmd_hook_math());
+cmd_register("pm", 0, 1, "binary operator: plus minus", "", NULL);
+cmd_register("pmod", 1, 1, "modulo; (mod X)", "", NULL);
+cmd_register("Pr", 0, 1, "mathematical function", "", NULL);
+cmd_register("prec", 0, 1, "binary relations", "", NULL);
+cmd_register("preceq", 0, 1, "binary relations", "", NULL);
+cmd_register("printindex", 0, 0, "", "makeidx", NULL);
+cmd_register("prod", 0, 1, "", "", NULL);
+cmd_register("propto", 0, 1, "binary relations", "", NULL);
+cmd_register("pscircle", 0, 0, "Draws a PSTricks circle", "pstricks", NULL);
+cmd_register("psframe", 0, 0, "Draws a PSTricks box", "pstricks", NULL);
+cmd_register("psi", 0, 1, "", "", &cmd_hook_math());
+cmd_register("psline", 0, 0, "Draws a PSTricks line", "pstricks", NULL);
+cmd_register("rput", 1, 0, "Puts the argument in a PSTricks picture", "pstricks", NULL);
+cmd_register("Psi", 0, 1, "", "", &cmd_hook_math());
+cmd_register("publishers", 1, 0, "Lowermost element in title of KOMA script documents", "", NULL);
+cmd_register("qquad", 0, 0, "", "", NULL);
+cmd_register("quad", 0, 0, "", "", NULL);
+cmd_register("raggedleft", 0, 0, "Switches to right aligned text", "", NULL);
+cmd_register("raggedright", 0, 0, "Switches to left aligned text", "", NULL);
+cmd_register("RaggedRight", 0, 0, "Reimplementation of \raggedright from ragged2e"R, "ragged2e", NULL);
+cmd_register("raisebox", 2, 0, "Moves the text upward -- {distance}{text}", "", NULL);
+#if (_slang_utf8_ok)
+cmd_register("rangle", 0, 1, "mathematical delimiter: 〉", "", NULL);
+#else
+cmd_register("rangle", 0, 1, "mathematical delimiter: >", "", NULL);
+#endif
+cmd_register("rceil", 0, 1, "mathematical delimiter", "", NULL);
+cmd_register("Re", 0, 1, "Real part of a number", "", NULL);
+cmd_register("ref", 1, 0, "", "", &cmd_hook_ref());
+cmd_register("renewcommand*", 2, 0, "", "", NULL);
+cmd_register("rfloor", 0, 1, "mathematical delimiter", "", NULL);
+cmd_register("rgroup", 0, 1, "mathematical delimiter", "", NULL);
+cmd_register("rho", 0, 1, "", "", &cmd_hook_math());
+cmd_register("right", 0, 1, "", "", NULL);
+#if (_slang_utf8_ok)
+cmd_register("rightarrow", 0, 1, "→", "", &cmd_hook_math_not());
+cmd_register("Rightarrow", 0, 1, "⇒", "", &cmd_hook_math_not());
+#else
+cmd_register("rightarrow", 0, 1, "->", "", &cmd_hook_math_not());
+cmd_register("Rightarrow", 0, 1, "=>", "", &cmd_hook_math_not());
+#endif
+cmd_register("rmfamily", 0, 0, "Sets a roman font", "", NULL);
+cmd_register("rmoustache", 0, 1, "mathematical delimiter", "", NULL);
+cmd_register("rowops", 0, 1, "switches in a gmatrix into row operation mode", "gauss", NULL);
+cmd_register("rseil", 0, 1, "", "", NULL);
+cmd_register("rule", 2, 0, "Draws a black rule; {width}{height}", "", NULL);
+cmd_register("rvert", 0, 1, "", "amsmath", NULL);
+cmd_register("rVert", 0, 1, "", "amsmath", NULL);
+cmd_register("scriptstyle", 0, 1, "", "", NULL);
+cmd_register("scriptscriptstyle", 0, 1, "", "", NULL);
+cmd_register("scshape", 0, 0, "", "", NULL);
+cmd_register("searrow", 0, 1, "south east arrow", "", NULL);
+cmd_register("sec", 0, 1, "mathematical function", "", NULL);
+cmd_register("section", 1, 0, "Starts a new section", "", NULL);
+cmd_register("see", 1, 0, "", "", NULL);
+cmd_register("setboolean", 2, 0, "Sets the value of a boolean register {register}{true|false}", "iffthen", NULL);
+cmd_register("setcounter", 2, 0, "Sets the value of the counter 1st arg to 2nd arg", "", NULL);
+cmd_register("setlength", 2, 0, "Sets the value of the length register #1 to #2", "", NULL);
+cmd_register("setminus", 0, 1, "binary operator", "", NULL);
+cmd_register("settowidth", 2, 0, "", "", NULL);
+cmd_register("sffamily", 0, 0, "", "", NULL);
+cmd_register("showhyphens", 1, 0, "Prints the hyphenpoints in the argument to the log file"R, "", NULL);
+cmd_register("sigma", 0, 1, "", "", &cmd_hook_math());
+cmd_register("Sigma", 0, 1, "", "", &cmd_hook_math());
+cmd_register("sim", 0, 1, "binary relations", "", &cmd_hook_math_not());
+cmd_register("simeq", 0, 1, "binary relations", "", NULL);
+cmd_register("sin", 0, 1, "mathematical function", "", NULL);
+cmd_register("sinh", 0, 1, "mathematical function", "", NULL);
+cmd_register("slash", 1, 0, "A / with an hyphenpoint after it", "", &cmd_hook_goto_mark());
+cmd_register("slashbox", 2, 0, "A big slash in the upper left corner of a tabular", "slashbox", NULL);
+cmd_register("slshape", 0, 0, "", "", NULL);
+cmd_register("smile", 0, 1, "binary relations", "", NULL);
+cmd_register("sqcap", 0, 1, "binary operator", "", NULL);
+cmd_register("sqcup", 0, 1, "binary operator", "", NULL);
+cmd_register("sqrt", 1, 1, "", "", NULL);
+cmd_register("sqsubset", 0, 1, "binary relations", "", NULL);
+cmd_register("sqsubseteq", 0, 1, "binary relations", "", NULL);
+cmd_register("sqsupset", 0, 1, "binary relations", "", NULL);
+cmd_register("sqsupseteq", 0, 1, "binary relations", "", NULL);
+cmd_register("stackrel", 2, 1, "Puts the first arg above the second \\stackrel{!}{=}", "", NULL);
+cmd_register("star", 0, 1, "binary operator", "", NULL);
+cmd_register("stepcounter", 1, 0, "Increments the counter by one", "", NULL);
+cmd_register("subject", 1, 0, "Element in title of KOMA script documents", "", NULL);
+cmd_register("subsection", 1, 0, "Starts a new subsection", "", NULL);
+cmd_register("subset", 0, 1, "binary relation", "", &cmd_hook_null());
+cmd_register("subseteq", 0, 1, "binary relation", "", &cmd_hook_math_not());
+cmd_register("subsetneq", 0, 1, "", "", &cmd_hook_null());
+cmd_register("substack", 1, 1, "Produce a multiline sub- or superscript", "amsmath", NULL);
+cmd_register("subsubsection", 1, 0, "Starts a new subsubsection", "", NULL);
+cmd_register("succ", 0, 1, "binary relations", "", NULL);
+cmd_register("succeq", 0, 1, "binary relations", "", NULL);
+cmd_register("suetterlin", 0, 0, "Switches to a suetterlin font", "suetterlin", NULL);
+cmd_register("sum", 0, 1, "", "", NULL);
+cmd_register("sup", 0, 1, "mathematical function", "", NULL);
+cmd_register("supset", 0, 1, "binary relation", "", &cmd_hook_null());
+cmd_register("supseteq", 0, 1, "binary relation", "", &cmd_hook_math_not());
+cmd_register("supsetneq", 0, 1, "", "", &cmd_hook_null());
+cmd_register("SVN", 0, 0, "", "svn", NULL);
+cmd_register("SVNDate", 0, 0, "", "svn", NULL);
+cmd_register("SVNLastChangedRevision", 0, 0, "", "svn", NULL);
+cmd_register("swap", 2, 1, "swap the row/column n and k in a gmatrix", "gauss", NULL);
+cmd_register("tableofcontents", 0, 0, "", "", NULL);
+cmd_register("tan", 0, 1, "mathematical function", "", NULL);
+cmd_register("tanh", 0, 1, "mathematical function", "", NULL);
+cmd_register("tau", 0, 1, "", "", &cmd_hook_math());
+cmd_register("TeX", 1, 0, "", "", &cmd_hook_goto_mark());
+cmd_register("texorpdfstring", 2, 0, "", "hyperref", NULL);
+cmd_register("text", 1, 1, "", "", NULL);
+cmd_register("textasciigrave", 1, 0, "A ` character", "textcomp", &cmd_hook_goto_mark());
+cmd_register("textasteriskcentered", 1, 0, "A * centered", "", &cmd_hook_goto_mark());
+cmd_register("textbackslash", 1, 0, "", "", &cmd_hook_goto_mark());
+cmd_register("textbf", 1, 0, "Boldface font", "", NULL);
+cmd_register("textcolor", 2, 0, "", "xcolor", NULL);
+cmd_register("textdownarrow", 1, 0, "A downarrow for text mode", "textcomp", &cmd_hook_goto_mark());
+cmd_register("textit", 1, 0, "Italic font", "", NULL);
+cmd_register("textleftarrow", 1, 0, "A leftarrow for text mode", "textcomp", &cmd_hook_goto_mark());
+cmd_register("textmd", 1, 0, "Medium weight font (default, NULL)", "", NULL);
+#if (_slang_utf8_ok)
+cmd_register("textmu", 1, 0, "A µ for textmode", "textcomp", &cmd_hook_goto_mark());
+#else
+cmd_register("textmu", 1, 0, "A µ for textmode", "textcomp", &cmd_hook_goto_mark());
+#endif
+cmd_register("textnormal", 1, 0, "Main document font", "", NULL);
+cmd_register("textquotesingle", 1, 0, "A ' character", "textcomp", &cmd_hook_goto_mark());
+cmd_register("textrightarrow", 1, 0, "A rightarrow for text mode", "textcomp", &cmd_hook_goto_mark());
+cmd_register("textrm", 1, 0, "Roman font", "", NULL);
+cmd_register("textsc", 1, 0, "Small caps", "", NULL);
+cmd_register("textsf", 1, 0, "Sans serif", "", NULL);
+cmd_register("textsl", 1, 0, "Slanted font", "", NULL);
+cmd_register("textsuetterlin", 1, 0, "Suetterlin font", "suetterlin", NULL);
+cmd_register("textsuperscript", 1, 0, "Superscript for text (like ^ in math mode)", "", NULL);
+cmd_register("texttrademark", 1, 0, "The trademark symbol", "", &cmd_hook_goto_mark());
+cmd_register("texttt", 1, 0, "Typewriter", "", NULL);
+cmd_register("textup", 1, 0, "Upright font (default, NULL)", "", NULL);
+cmd_register("textuparrow", 1, 0, "A uparrow for text mode", "textcomp", &cmd_hook_goto_mark());
+cmd_register("textvisiblespace", 1, 0, "Sets `-´ at the baseline", "", &cmd_hook_goto_mark());
+% cmd_register("textwidth", 0, 0, "", "", NULL);
+cmd_register("thanks", 1, 0, "Footnote to authors in the title of document", "", NULL);
+% cmd_register("thepage", 0, 0, "", "", NULL);
+cmd_register("theta", 0, 1, "", "", &cmd_hook_math());
+cmd_register("Theta", 0, 1, "", "", &cmd_hook_math());
+cmd_register("tilde", 1, 1, "", "", NULL);
+cmd_register("times", 0, 1, "binary operator", "", NULL);
+cmd_register("title", 1, 0, "", "", NULL);
+cmd_register("titlehead", 1, 0, "Uppermost element in title of KOMA script documents", "", NULL);
+cmd_register("toprule", 0, 0, "A horizontal line with better spacing at top of a tabular"R, "booktabs", NULL);
+cmd_register("triangleleft", 0, 1, "binary operator", "", NULL);
+cmd_register("triangleright", 0, 1, "binary operator", "", NULL);
+cmd_register("ttfamily", 0, 0, "", "", NULL);
+cmd_register("twoheadleftarrow", 0, 1, "", "", NULL);
+cmd_register("twoheadrightarrow", 0, 1, "", "", NULL);
+cmd_register("underbrace", 1, 1, "", "", NULL);
+cmd_register("underline", 1, 0, "", "", NULL);
+cmd_register("unit", 1, 0, "", "units", NULL);
+cmd_register("unitfrac", 2, 0, "", "units", NULL);
+cmd_register("uparrow", 0, 1, "", "", NULL);
+cmd_register("uplus", 0, 1, "binary operator", "", NULL);
+cmd_register("upshape", 0, 0, "", "", NULL);
+cmd_register("upsilon", 0, 1, "", "", &cmd_hook_math());
+cmd_register("Upsilon", 0, 1, "", "", &cmd_hook_math());
+cmd_register("url", 1, 0, "", "hyperref", NULL);
+cmd_register("varepsilon", 0, 0, "", "", &cmd_hook_math());
+cmd_register("varointctrclockwise", 0, 1, "", "esint", NULL);
+cmd_register("varphi", 0, 1, "", "", &cmd_hook_math());
+cmd_register("vDash", 0, 1, "binary relations |=", "", &cmd_hook_math_not());
+cmd_register("vdash", 0, 1, "binary relations |-", "", &cmd_hook_math_not());
+cmd_register("vdots", 0, 1, "Vertical dots", "", NULL);
+cmd_register("vec", 1, 1, "set an arrow above the arguments", "", NULL);
+#if (_slang_utf8_ok)
+cmd_register("vee", 0, 1, "binary operator: Logical or â¨", "", NULL);
+#else
+cmd_register("vee", 0, 1, "binary operator: Logical or", "", NULL);
+#endif
+cmd_register("verb", 0, 0, "", "", NULL);
+cmd_register("VerbatimInput", 1, 0, "Inserts the contents of a file as verbatim text", "fancyvrb", &cmd_hook_file_select());
+cmd_register("vert", 0, 1, "the bar for absolut values: |-1| = 1", "", NULL);
+cmd_register("Vert", 0, 1, "the bar for norm: ||x|| = x_1^2 + x_2^2", "", NULL);
+cmd_register("vfill", 0, 0, "", "", NULL);
+% cmd_register("vol", 0, 0, "", "", NULL);
+cmd_register("vspace", 1, 0, "Insert a vertical space", "", NULL);
+#if (_slang_utf8_ok)
+cmd_register("wedge", 0, 1, "binary operator: Logical and â§", "", NULL);
+#else
+cmd_register("wedge", 0, 1, "binary operator: Logical and", "", NULL);
+#endif
+cmd_register("widehat", 1, 1, "", "", NULL);
+cmd_register("widetilde", 1, 1, "", "", NULL);
+cmd_register("wr", 0, 1, "binary operator", "", NULL);
+cmd_register("xi", 0, 1, "", "", &cmd_hook_math());
+cmd_register("Xi", 0, 1, "", "", &cmd_hook_math());
+cmd_register("xrightarrow", 1, 1, "", "amsmath", NULL);
+cmd_register("xspace", 0, 0, "", "xspace", NULL);
+cmd_register("zeta", 0, 1, "", "", &cmd_hook_math());
diff --git a/support/jed/jlm/latex_comm.sl b/support/jed/jlm/latex_comm.sl
new file mode 100644
index 0000000000..77be207698
--- /dev/null
+++ b/support/jed/jlm/latex_comm.sl
@@ -0,0 +1,122 @@
+% File: latex_comm.sl -*- mode: SLang -*-
+%
+% Copyright (c)
+% 2006--2007 Jörg Sommer <joerg@alea.gnuu.de>
+% $Id: latex_comm.sl 199 2007-08-23 23:28:52Z joerg $
+%
+% -*- This file is part of Jörg's LaTeX Mode (JLM) -*-
+%
+% Description: The dvi viewer Xdvi can communicate with the editor to
+% move the cursor to the possition of the file that is
+% related to the paragraph currently shown.
+%
+% This file implements the communication helper for xdvi.
+%
+% License: 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 2 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.
+
+% Fixme: This is ugly, but
+% jed-script foo -> __argv = ["foo"]
+% jed --script foo -> __argv = ["jed", "--script", "foo"]
+
+_for(0, length(__argv), 1)
+{
+ $0 = ();
+ if ( is_substr(__argv[$0], "latex_comm.sl") )
+ {
+ ++$0;
+ break;
+ }
+}
+
+variable args = __argv[[$0:]];
+
+variable STDIN_FILENO = fileno(stdin);
+variable STDOUT_FILENO = fileno(stdout);
+
+if ( andelse {length(args) == 1} {args[0] == "watch"} )
+{
+ variable fifo_name = "/tmp/jed.latex." + string(getpid());
+
+ if (mkfifo(fifo_name, 0600) != 0)
+ throw ApplicationError, "Could not create FIFO";
+
+ () = write(STDOUT_FILENO, "communicator created: $fifo_name\n"$);
+
+#ifexists SIGHUP
+ variable quit = 0;
+ eval("define sig_handler(sig) { quit = 1; }");
+ signal(SIGHUP, __get_reference("sig_handler") );
+ signal(SIGINT, __get_reference("sig_handler") );
+ signal(SIGTERM, __get_reference("sig_handler") );
+
+# iffalse
+ % slang 2.0 has a bug---signal is set to restart system calls.
+ % However, once a signal is caught, the signal will be set to
+ % interrupt them, which is the correct behavior for the interpreter.
+ % Force that here.
+ () = kill(getpid(), SIGHUP);
+ () = kill(getpid(), SIGINT);
+ () = kill(getpid(), SIGTERM);
+ quit = 0;
+# endif
+#endif
+
+ try
+ {
+ forever
+ {
+ variable fifo = open(fifo_name, O_RDONLY);
+ if (fifo == NULL)
+ break;
+#ifexists quit
+ if (quit)
+ {
+ () = close(fifo);
+ break;
+ }
+#endif
+ try
+ {
+ variable line, last_line;
+ while (read(fifo, &line, 128) > 0)
+ {
+ () = write(STDOUT_FILENO, line);
+ last_line = line;
+ }
+
+ if (andelse {bstrlen(last_line) >= 5}
+ {last_line[[-5:-1]] == "quit\n"B})
+ break;
+ }
+ finally
+ () = close(fifo);
+ }
+ }
+ finally
+ () = remove(fifo_name);
+}
+else
+{
+ if (length(args) < 2)
+ throw NumArgsError, "missing arguments";
+
+ variable stat = stat_file(args[0]);
+ !if ( andelse {stat != NULL} {stat_is("fifo", stat.st_mode)} )
+ throw InvalidParmError, "File "+args[0]+" do not exist or is not a FIFO";
+
+ variable fifo = open(args[0], O_WRONLY);
+ try
+ {
+ () = write(fifo, strjoin(args[[1:]], " ") + "\n");
+ }
+ finally
+ () = close(fifo);
+}
diff --git a/support/jed/jlm/latex_conv.sl b/support/jed/jlm/latex_conv.sl
new file mode 100644
index 0000000000..c378431276
--- /dev/null
+++ b/support/jed/jlm/latex_conv.sl
@@ -0,0 +1,241 @@
+% File: latex_conv.sl -*- mode: SLang -*-
+%
+% Copyright (c)
+% 2006--2007 Jörg Sommer <joerg@alea.gnuu.de>
+% $Id$
+%
+% -*- This file is part of Jörg's LaTeX Mode (JLM) -*-
+%
+% Description: This file include functions to convert LaTeX stuff into
+% each other like "a to ä or : to \colon
+%
+% License: 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 2 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.
+
+if (length(where("latex_conv" == _get_namespaces())))
+ use_namespace("latex_conv");
+else
+ implements("latex_conv");
+
+autoload("Global->enable_stack_check", "stkcheck");
+try
+{
+ enable_stack_check();
+}
+catch OpenError: {} % stkcheck not found in the path
+
+define german_utf8()
+{
+ while ( fsearch_char('"') )
+ {
+ if ( blooking_at("\\") )
+ continue;
+
+ () = right(1);
+ variable new;
+ switch ( what_char() )
+ { case 'a': new = "ä"; }
+ { case 'A': new = "Ă„"; }
+ { case 'o': new = "ö"; }
+ { case 'O': new = "Ă–"; }
+ { case 'u': new = "ĂĽ"; }
+ { case 'U': new = "Ăś"; }
+ { case 's': new = "Ăź"; }
+ { case '`' or case '\'': continue; }
+ { throw ApplicationError, "Unkown sequence: \""+char(what_char()); }
+
+ () = left(1);
+ () = replace_chars(2, new);
+ }
+}
+
+define german_lat1()
+{
+ while ( fsearch_char('"') )
+ {
+ % fixme: latex->is_escaped latex->is_commented
+ if (blooking_at("\\") or parse_to_point() == -2)
+ {
+ () = right(1);
+ continue;
+ }
+
+ () = right(1);
+ variable new;
+ switch ( what_char() )
+ { case 'a': new = "ä"; }
+ { case 'A': new = "Ä"; }
+ { case 'o': new = "ö"; }
+ { case 'O': new = "Ö"; }
+ { case 'u': new = "ü"; }
+ { case 'U': new = "Ü"; }
+ { case 's': new = "ß"; }
+ { case '`' or case '\'': continue; }
+ { throw ApplicationError, "Unkown sequence: \""+char(what_char()); }
+
+ () = left(1);
+ () = replace_chars(2, new);
+ }
+}
+
+define native_lat1()
+{
+ push_spot();
+ try
+ {
+ while ( fsearch("\\\"") )
+ {
+ if ( blooking_at("\\") )
+ continue;
+
+ () = right(2);
+ variable new;
+ switch ( what_char() )
+ { case 'a': new = "ä"; }
+ { case 'A': new = "Ä"; }
+ { case 'o': new = "ö"; }
+ { case 'O': new = "Ö"; }
+ { case 'u': new = "ü"; }
+ { case 'U': new = "Ü"; }
+ { throw ApplicationError, "Unkown sequence"; }
+
+ () = left(2);
+ () = replace_chars(3, new);
+ }
+
+ pop_spot(); push_spot(); replace("\\3", "ß");
+ pop_spot(); push_spot(); replace("\\ss ", "ß");
+ pop_spot(); push_spot(); replace("\\ss{}", "ß");
+ }
+ finally
+ pop_spot();
+}
+
+define native_utf8()
+{
+ push_spot();
+ try
+ {
+ while ( fsearch("\\\"") )
+ {
+ if ( blooking_at("\\") )
+ continue;
+
+ () = right(2);
+ variable new;
+ switch ( what_char() )
+ { case 'a': new = "ä"; }
+ { case 'A': new = "Ă„"; }
+ { case 'o': new = "ö"; }
+ { case 'O': new = "Ă–"; }
+ { case 'u': new = "ĂĽ"; }
+ { case 'U': new = "Ăś"; }
+ { throw ApplicationError, "Unkown sequence"; }
+
+ () = left(2);
+ () = replace_chars(3, new);
+ }
+
+ pop_spot(); push_spot();; replace("\\3", "Ăź");
+ pop_spot(); push_spot();; replace("\\glqq", "„");
+ pop_spot(); push_spot();; replace("\\grqq", "“");
+ pop_spot(); push_spot();; replace("\\glq", "‚");
+ pop_spot(); push_spot();; replace("\\grq", "â€");
+ }
+ finally
+ pop_spot();
+}
+
+define colon()
+{
+ try
+ {
+ while ( fsearch_char(':') )
+ {
+ if ( andelse {not looking_at(":=")} {not blooking_at("=")}
+ {not re_looking_at(": *\\[Ll]eftrightarrow"R)}
+ {not re_looking_at(": *\\[Ll]ongleftrightarrow"R)}
+ {not blooking_at("\\")} {latex->is_math()} )
+ {
+ try
+ {
+ push_visible_mark();
+ () = right(1);
+ switch ( get_y_or_n("Replace this : by \\colon") )
+ { case 1:
+ () = left(1);
+ () = replace_chars(1, "\\colon");
+ variable ch = what_char();
+ if ( ('A' <= ch and ch <= 'Z') or
+ ('a' <= ch and ch <= 'z') )
+ insert_char(' ');
+ }
+ }
+ finally
+ pop_mark(0);
+ }
+ else
+ () = right(1);
+ }
+ }
+ catch UserBreakError;
+}
+
+define ltx209_ltx2e()
+{
+ % Fixme: {\bf \tt } is replaced by \textbf\texttt{}
+ % Fixme: PCRE
+ while ( latex->search_not_commented(&re_fsearch, "\\[beirst][cflmt]"R, 1) )
+ {
+ variable mark = create_user_mark();
+ () = right(1);
+ push_mark();
+ skip_chars(latex->TeX_Command_Chars);
+
+ variable short, long;
+ switch ( bufsubstr() )
+ { case "bf": short = "textbf"; long = "bfseries"; }
+ { case "em": short = "emph"; }
+ { case "it": short = "textit"; long = "itshape"; }
+ { case "rm": short = "textrm"; long = "rmfamily"; }
+ { case "sc": short = "textsc"; long = "scshape"; }
+ { case "sl": short = "textsl"; long = "slshape"; }
+ { case "tt": short = "texttt"; long = "ttfamily"; }
+ { continue; }
+
+ skip_chars(" \t\n{}");
+ push_mark();
+ goto_user_mark(mark);
+ del_region();
+
+ () = left(1);
+ if ( looking_at_char('{') and not latex->is_escaped() )
+ {
+ insert("\\"+ short);
+ push_spot();
+ latex->fsearch_matching_brace();
+ if ( left(1) and looking_at_char('/') and latex->is_escaped() )
+ {
+ () = left(1);
+ deln(2);
+ }
+ pop_spot();
+ }
+ else
+ {
+ () = right(1);
+ % Fixme: Check for \par and use long form
+ % push_mark();
+ % latex->fsearch_matching_brace();
+
+ insert("\\" + long + " ");
+ }
+ }
+}
diff --git a/support/jed/jlm/latex_external.sl b/support/jed/jlm/latex_external.sl
new file mode 100644
index 0000000000..11307401e7
--- /dev/null
+++ b/support/jed/jlm/latex_external.sl
@@ -0,0 +1,1551 @@
+% File: latex_external.sl -*- mode: SLang; mode: fold -*-
+%
+% Copyright (c)
+% until 2003 Guido Gonzato <guido.gonzato@univr.it> (as Latex4Jed)
+% 2003--2007 Jörg Sommer <joerg@alea.gnuu.de>
+% $Id: latex_external.sl 199 2007-08-23 23:28:52Z joerg $
+%
+% -*- This file is part of Jörg's LaTeX Mode (JLM) -*-
+%
+% Description: In this file are all functions for composing, viewing,
+% printing and any related problems. All what have to do
+% with an external program and a latex file.
+%
+% License: 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 2 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.
+
+% Fixme ToDo:
+% + replace all error()s with throw
+
+if (length(where("latex_external" == _get_namespaces())))
+ use_namespace("latex_external");
+else
+ implements("latex_external");
+
+#ifnexists profile_on
+% profiling does not work with stack check enabled.
+autoload("Global->enable_stack_check", "stkcheck");
+try
+{
+ enable_stack_check();
+}
+catch OpenError: {} % stkcheck not found in the path
+#endif
+
+#ifnexists any
+public define any(array)
+{
+ return wherefirst(array) != NULL;
+}
+#endif
+#ifnexists all
+public define all(array)
+{
+ return not any(not array);
+}
+#endif
+
+%%%%%%%%%%
+%
+% Declarations needed somewhere before the definition
+%
+
+static define view() { throw NotImplementedError; }
+
+%%%%%%%%%%
+%
+% Tools
+%
+
+#if (_jed_version < 9919)
+public define buffer_filename ()
+{
+ variable args = __pop_args (_NARGS);
+ variable file, dir;
+ (file, dir, , ) = getbuf_info(__push_args (args));
+ !if (strlen (file)) dir = "";
+ return dir + file;
+}
+#endif
+
+private define path_concat(left, right)
+{
+ if (path_basename(left) == "")
+ % left has a trailing dir separator
+ left = path_dirname(left);
+
+ forever
+ {
+#ifdef UNIX
+ if (strncmp(right, "../", 3) == 0)
+#else
+ if (strncmp(right, "..\\", 3) == 0)
+#endif
+ {
+ left = path_dirname(left);
+ right = substr(right, 4, -1);
+ }
+#ifdef UNIX
+ else if (strncmp(right, "./", 2) == 0)
+#else
+ else if (strncmp(right, ".\\", 2) == 0)
+#endif
+ right = substr(right, 3, -1);
+ else
+ break;
+ }
+
+ return Global->path_concat(left, right);
+}
+
+private define find_buf_of_file(fname)
+{
+ if (fname == NULL)
+ return NULL;
+
+ foreach ( __pop_args( buffer_list() ) )
+ {
+ variable bname = ().value;
+ !if ( strcmp(buffer_filename(bname), fname) )
+ return bname;
+ }
+ return NULL;
+}
+
+private variable MODE="LaTeX-External";
+
+%%%%%%%%%%
+%
+% Customisation stuff
+%
+
+%!%+
+%\variable{String_Type LaTeX_Rerun}
+%\synopsis{rerun composing}
+%\description
+% This variable defines the configuration of the commands used for
+% creating and viewing the document and so on.
+%
+% Default is "latex".
+%\seealso{cust_set()}
+%!%-
+custom_variable("LaTeX_Config", "latex");
+
+% %m Masterfile
+% %M Masterfile without extension
+% \see{expand_and_run_cmd}
+
+typedef struct {
+ name, desc, bibtex, index, latex, post, clean, mrproper, print, view, rerun
+} cust_type;
+private variable cust = Assoc_Type[cust_type];
+
+static define cust_set(name, desc, bibtex, index, latex, post, clean, mrproper,
+ print, view, rerun)
+{
+ variable accept_NULL = assoc_key_exists(cust, name);
+
+ !if ( typeof(rerun) == Integer_Type or (accept_NULL and rerun == NULL) )
+ throw InvalidParmError, "rerun must be an integer";
+
+ variable types = [typeof(desc), typeof(bibtex), typeof(index),
+ typeof(latex), typeof(post), typeof(clean),
+ typeof(mrproper), typeof(print), typeof(view)];
+ !if ( all( (types == String_Type) or
+ (accept_NULL and (types == Null_Type)) ) )
+ throw InvalidParmError, "At least one of the given arguments has a "+
+ "wrong data type";
+
+ variable tmp;
+ if (accept_NULL)
+ {
+ tmp = cust[name];
+ if (desc != NULL)
+ tmp.desc = desc;
+ if (bibtex != NULL)
+ tmp.bibtex = bibtex;
+ if (index != NULL)
+ tmp.index = index;
+ if (latex != NULL)
+ tmp.latex = latex;
+ if (post != NULL)
+ tmp.post = post;
+ if (clean != NULL)
+ tmp.clean = clean;
+ if (mrproper != NULL)
+ tmp.mrproper = mrproper;
+ if (print != NULL)
+ tmp.print = print;
+ if (view != NULL)
+ tmp.view = view;
+ if (rerun != NULL)
+ tmp.rerun = rerun;
+ }
+ else
+ {
+ tmp = @cust_type;
+ cust[name] = tmp;
+
+ tmp.name = name;
+ tmp.desc = desc;
+ tmp.bibtex = bibtex;
+ tmp.index = index;
+ tmp.latex = latex;
+ tmp.post = post;
+ tmp.clean = clean;
+ tmp.mrproper = mrproper;
+ tmp.print = print;
+ tmp.view = view;
+ tmp.rerun = rerun;
+ }
+}
+
+cust_set("rubber_pdf", "Run rubber <http://beffara.org/stuff/rubber.html> to build a PDF",
+ "", "",
+ "rubber --inplace --pdf %m", "",
+ "rubber --clean %m", "rubber --clean --pdf %m",
+ "lp -t \"%M\" %M.pdf", "xpdf %M.pdf", 0);
+
+cust_set("rubber_dvi", "Run rubber <http://beffara.org/stuff/rubber.html> to build a DVI",
+ "", "",
+ "rubber --inplace %m", "",
+ "", "rubber --clean %m",
+ "sh -c dvips% -o-% %M.dvi|lp% -t% \"%M\"", "xdvi %M.dvi", 0);
+
+cust_set("rubber_ps", "Run rubber <http://beffara.org/stuff/rubber.html> to build a PS",
+ "", "",
+ "rubber --inplace --ps %m", "",
+ "rubber --clean %m", "rubber --clean --ps %m",
+ "lp -t %M %M.ps", "gv --watch %M.ps", 0);
+
+cust_set("rubber_ps_pdf", "Run rubber <http://beffara.org/stuff/rubber.html> to build a PDF from PS",
+ "", "",
+ "rubber --inplace --ps --pdf %m", "",
+ "rubber --clean --ps %m", "rubber --clean --ps --pdf %m",
+ "lp -t %M %M.pdf", "xpdf %M.pdf", 0);
+
+cust_set("latex", "Run LaTeX",
+ "bibtex %m",
+ "makeindex %M.idx",
+ "latex -interaction=nonstopmode %m", "",
+#ifdef MSWINDOWS
+ "del %M.aux %M.idx %M.ind %M.log %M.out %M.toc",
+ "del %M.aux %M.idx %M.ind %M.log %M.out %M.toc %M.dvi",
+ "", "yap %M.dvi", 1);
+#else
+ "rm -f %M.aux %M.idx %M.ind %M.log %M.out %M.toc",
+ "rm -f %M.aux %M.idx %M.ind %M.log %M.out %M.toc %M.dvi",
+ "sh -c dvips% -o-% \"%M.dvi\"|lp% -t% \"%M\"",
+ "xdvi %M.dvi", 1);
+#endif
+
+cust_set("pdflatex", "Run PDFLaTeX with Xindy <http://www.xindy.org/>",
+ "bibtex %m",
+ "texindy --quiet --language german-din %M.idx",
+ "pdflatex -interaction=nonstopmode %m", "",
+#ifdef MSWINDOWS
+ "del %M.aux %M.idx %M.ind %M.log %M.out %M.toc",
+ "del %M.aux %M.idx %M.ind %M.log %M.out %M.toc %M.pdf",
+ "",
+#else
+ "rm -f %M.aux %M.idx %M.ind %M.log %M.out %M.toc",
+ "rm -f %M.aux %M.idx %M.ind %M.log %M.out %M.toc %M.pdf",
+ "lp -t %M %M.pdf",
+#endif
+ "xpdf %M.pdf", 1);
+
+cust_set("latex_ps", "Run LaTeX and dvips",
+ "bibtex %m",
+ "makeindex %M.idx",
+ "latex -interaction=nonstopmode %m", "dvips %M.dvi",
+#ifdef MSWINDOWS
+ "del %M.aux %M.idx %M.ind %M.log %M.out %M.toc %M.dvi",
+ "del %M.aux %M.idx %M.ind %M.log %M.out %M.toc %M.dvi %M.ps",
+ "",
+#else
+ "rm -f %M.aux %M.idx %M.ind %M.log %M.out %M.toc %M.dvi",
+ "rm -f %M.aux %M.idx %M.ind %M.log %M.out %M.toc %M.dvi %M.ps",
+ "lp -t %M %M.ps",
+#endif
+ "gv %M.ps", 1);
+
+cust_set("latex_srcspecl",
+ "LaTeX with source specials <http://xdvi.sourceforge.net/inverse-search.html>",
+ "bibtex %m",
+ "makeindex %M.idx",
+#ifdef MSWINDOWS
+ "latex -interaction=nonstopmode --src-specials %m", "",
+ "del %M.aux %M.idx %M.ind %M.log %M.out %M.toc",
+ "del %M.aux %M.idx %M.ind %M.log %M.out %M.toc %M.dvi",
+ "", "yap --find-src-special %l%f %M.dvi", 1);
+#else
+ "latex -interaction=nonstopmode -src-specials %m", "",
+ "rm -f %M.aux %M.idx %M.ind %M.log %M.out %M.toc",
+ "rm -f %M.aux %M.idx %M.ind %M.log %M.out %M.toc %M.dvi",
+ "", "xdvi -nofork -editor %e -sourceposition %l:%c%f %M.dvi", 1);
+#endif
+
+static define cust_jump_or_edit()
+{
+ variable mark = create_user_mark();
+ bol();
+ if ( eolp() or what_line < 3 )
+ % empty line or a line before the TOC -- nothing should happen
+ goto_user_mark(mark);
+ else
+ if ( looking_at_char('*') )
+ % a line in the TOC -- jump to the section
+ {
+ () = right(2);
+ push_mark();
+ !if ( ffind(" -- ") )
+ throw InternalError, "buf structure destroyed";
+ bskip_white();
+
+ !if ( re_fsearch( "^"+bufsubstr()+"$" ) )
+ throw InternalError, "buf structure destroyed";
+ }
+ else
+ if ( ffind_char(':') )
+ % a config line -- edit it
+ {
+ () = right(1);
+ push_spot();
+ bol();
+ push_mark();
+ pop_spot();
+ str_delete_chars(bufsubstr(), " ");
+ % prompt for read_mini() on stack
+ ""; % default for read_mini() on stack
+ () = right(1);
+ push_spot();
+ push_mark();
+ eol();
+ bufsubstr(); % init for read_mini() on stack
+ pop_spot();
+
+ try
+ {
+ read_mini((), (), ());
+
+ set_readonly(0);
+ push_mark();
+ eol();
+ del_region();
+ insert( () ); % from read_mini()
+
+ set_readonly(1);
+ set_buffer_modified_flag(0);
+
+ % Fixme: fill in code
+ throw NotImplementedError;
+ }
+ catch UserBreakError:
+ {}
+ bol();
+ }
+ else
+ % this must be a line with the config name
+ % Fixme: fill in code
+ throw NotImplementedError;
+}
+
+static define cust_select()
+{
+ variable mark = create_user_mark(), name;
+ bol();
+ if ( eolp() or what_line < 3 )
+ {
+ % empty line or a line before the TOC -- nothing should happen
+ goto_user_mark(mark);
+ return;
+ }
+ else
+ if ( looking_at_char('*') )
+ % a line in the TOC
+ {
+ () = right(2);
+ push_mark();
+ !if ( ffind(" -- ") )
+ throw InternalError, "buf structure destroyed";
+ bskip_white();
+
+ name = bufsubstr();
+ }
+ else
+ {
+ % search the last empty line backwards
+ while( not (bol(), eolp()) )
+ () = up(1);
+
+ () = down(1);
+
+ name = line_as_string();
+ }
+
+ if (name == "new_conf")
+ throw UsageError,
+ "This is a pseudo confic. Give it a name and you can load it.";
+ else
+ LaTeX_Config = name;
+
+ delbuf( whatbuf() );
+}
+
+!if ( keymap_p(MODE + "-cust") )
+{
+ variable _mode = MODE + "-cust";
+ make_keymap(_mode);
+
+ definekey("latex_external->cust_jump_or_edit()", "\n", _mode);
+ definekey("latex_external->cust_jump_or_edit()", "\r", _mode);
+ definekey("latex_external->cust_select()", " ", _mode);
+
+ definekey("delbuf(whatbuf());call(\"delete_window\")", "q", _mode);
+ definekey("delbuf(whatbuf());call(\"delete_window\")", "c", _mode);
+}
+
+private define cust_view_insert(name, desc, bibtex, index, latex, post,
+ clean, mrproper, print, view, rerun)
+{
+ insert("* "+name);
+ whitespace(15-strlen(name));
+ % The three spaces after -- are a hack for DFA highlighting
+ insert(" -- "+desc+"\n");
+ push_spot();
+
+ % Fixme: show the keys for the command before the colon;
+ % use which_key to find the key
+ eob();
+ newline();
+ insert(name); newline();
+ insert("Description : "+desc); newline();
+ insert("Bibtex : "+bibtex); newline();
+ insert("Index : "+index); newline();
+ insert("LaTex : "+latex); newline();
+ insert("Post proc. : "+post); newline();
+ insert("Cleanup : "+clean); newline();
+ insert("Mr. Proper : "+mrproper); newline();
+ insert("Print : "+print); newline();
+ insert("View : "+view); newline();
+ insert("Rerun LaTeX : "+rerun); newline();
+ pop_spot();
+}
+
+#ifdef HAS_DFA_SYNTAX
+private define setup_dfa_callback(name)
+{
+ % the header
+ dfa_define_highlight_rule("^Possible configurations", "comment", name);
+ dfa_define_highlight_rule("^-*$", "comment", name);
+ dfa_define_highlight_rule("^Current configuration:.*", "comment", name);
+
+ % in the toc
+ dfa_define_highlight_rule("^\\* ", "preprocess", name);
+ dfa_define_highlight_rule("-- ", "preprocess", name);
+ % this matches the part between * and --
+ dfa_define_highlight_rule("^[^\\*:]*$", "keyword", name);
+ % this matches the part after --
+ dfa_define_highlight_rule(" .*$", "string", name);
+
+ % this matches the configuration name before the section
+ dfa_define_highlight_rule("[a-zA-Z_ ]* ", "keyword", name);
+
+ % this mathes the part before the colon in the section
+ dfa_define_highlight_rule("^[a-zA-Z\\. ]*:", "number", name);
+ % ... and this the part after the colon
+ dfa_define_highlight_rule(" .*$", "normal", name);
+
+ dfa_build_highlight_table(name);
+}
+create_syntax_table(MODE + "-cust");
+dfa_set_init_callback(&setup_dfa_callback(), MODE + "-cust");
+enable_dfa_syntax_for_mode(MODE + "-cust");
+#endif
+
+static define cust_view()
+{
+ sw2buf("LaTeX-cust");
+ set_mode(MODE + "-cust", 0);
+ use_keymap(MODE + "-cust");
+#ifdef HAS_DFA_SYNTAX
+ use_syntax_table(MODE + "-cust");
+#endif
+ set_status_line("Select LaTeX build tools -- Space to select and "+
+ "Enter to edit",
+ 0);
+ erase_buffer();
+
+ insert("Possible configurations\n-----------------------\n");
+ insert("Current configuration: $LaTeX_Config\n\n"$);
+
+ variable tmp = assoc_get_keys(cust);
+ foreach ( tmp[array_sort(tmp)] )
+ {
+ variable conf = ();
+ conf = cust[conf];
+ cust_view_insert(conf.name, conf.desc,
+ conf.bibtex, conf.index,
+ conf.latex, conf.post,
+ conf.clean, conf.mrproper,
+ conf.print, conf.view, string(conf.rerun));
+ }
+
+ cust_view_insert("new_conf", "setup a new configuration",
+ "command to run Bibtex", "command to build the index",
+ "command to generate the output file",
+ "command to run after a successful latex run",
+ "command to remove all temporary files",
+ "command to all files execpt the source file",
+ "command to print the output file",
+ "command to view the output file",
+ "rerun LaTeX?");
+
+ set_readonly(1);
+ set_buffer_modified_flag(0);
+ bob();
+}
+
+%%%%%%%%%%
+%
+% All about the master file stuff
+%
+
+%!%+
+%\function{select_master_file}
+%\synopsis{sets the usage of a master file for compilation}
+%\usage{select_master_file()}
+%\description
+% Asks the user if the file in the current buffer should be used as master
+% file for composing. This is helpful is you use \include in latex. If set
+% everywhere you call compose() latex is called with the file set here.
+%
+%\seealso{mater_file, master_dir, get_compose_dirfile()}
+%!%-
+static define select_master_file()
+{
+ try
+ {
+#ifexists jcomplete_file
+ variable file = jmini_prompt_with_completion("Select master file:", "",
+ "", &jcomplete_file);
+#else
+ variable file = read_with_completion("Select master file:", "", "", 'f');
+#endif
+
+ if (file == "")
+ file = NULL;
+ else
+ !if ( path_is_absolute(file) )
+ file = path_concat(getcwd(), file);
+
+ !if ( blocal_var_exists("LaTeX_master_file") )
+ create_blocal_var("LaTeX_master_file");
+
+ set_blocal_var(file, "LaTeX_master_file");
+ }
+ catch UserBreakError;
+}
+
+%!%+
+%\function{get_master_file}
+%\synopsis{Get file name of the latex file}
+%\usage{String_Type get_master_file()}
+%\description
+% This function returns the full path of the file, which is used by
+% the latex command.
+%
+% This could be used to determine the name of the .dvi or .ps file.
+%!%-
+private define get_master_file()
+{
+ if ( blocal_var_exists("LaTeX_master_file") )
+ {
+ variable file = get_blocal_var("LaTeX_master_file");
+ if ( file != "" and file != NULL )
+ {
+ if ( path_is_absolute(file) )
+ return file;
+ else
+ return path_concat(path_dirname(buffer_filename()), file);
+ }
+ }
+
+ return buffer_filename();
+}
+
+static define jump_to_master_buffer()
+{
+ !if ( blocal_var_exists("LaTeX_master_file") )
+ return;
+
+ variable master_buf = get_blocal_var("LaTeX_master_file");
+ if (master_buf == NULL or master_buf == "")
+ return;
+
+ !if ( path_is_absolute(master_buf) )
+ master_buf = path_concat(path_dirname(buffer_filename()), master_buf);
+
+ variable buf = find_buf_of_file(master_buf);
+ if (buf == NULL)
+ throw InternalError, "Buffer with master file not found";
+
+ setbuf(buf);
+}
+
+private define exists_master_var(name)
+{
+ variable oldbuf = whatbuf();
+ jump_to_master_buffer();
+
+ blocal_var_exists("LaTeX_"+name);
+
+ setbuf(oldbuf);
+ return ();
+}
+
+private define get_master_var() % optional 2nd arg: default
+{
+ variable dflt, name;
+ if (_NARGS == 2)
+ dflt = ();
+ name = ();
+
+ variable oldbuf = whatbuf();
+ jump_to_master_buffer();
+
+ try
+ {
+ if (_NARGS != 2 or blocal_var_exists("LaTeX_"+name))
+ return get_blocal_var("LaTeX_"+name);
+
+ return dflt;
+ }
+ finally
+ {
+ setbuf(oldbuf);
+ }
+}
+
+private define set_master_var(val, name)
+{
+ variable oldbuf = whatbuf();
+ jump_to_master_buffer();
+
+ create_blocal_var("LaTeX_"+name);
+ set_blocal_var(val, "LaTeX_"+name);
+
+ setbuf(oldbuf);
+}
+
+%%%%%%%%%%
+%
+% external command stuff
+%
+
+private variable DUMMY_OUTPUT_BUFFER = " latex-process-output";
+
+private variable outp_buf="";
+
+private define output_to_msg(pid, data)
+{
+ variable outp = strchop(outp_buf + data, '\n', 0);
+
+ % preserve all after the last \n for the next message
+ outp_buf = outp[-1];
+
+ if (length(outp) > 1)
+ {
+ message("(latex) " + outp[-2]);
+ update(0);
+ }
+}
+
+%!%+
+%\variable{User_Mark line_mark}
+%\synopsis{holds the mark of the current line}
+%\description
+% we need this variable as buffer for the line mark.
+% if the line mark isn't associated with a variable it isn't shown
+%
+%\seealso{update_log_hook()}
+%!%-
+private variable line_mark;
+
+%!%+
+%\function{update_log_hook}
+%\synopsis{Marks the current line}
+%\usage{update_log_hook()}
+%\description
+% This function marks the current line for highlighting.
+%
+% It is used in the buffers with the output of latex and other programms
+% to show better the line the cursor is in.
+%!%-
+private define update_log_hook()
+{
+ line_mark = create_line_mark(color_number("region"));
+}
+
+private define expand_and_run_cmd(cmd, buf)
+{
+ variable len = strlen(cmd);
+ if (cmd == NULL or len == 0)
+ return;
+
+ variable master_file = get_master_file();
+ variable rel_master_file = path_basename(master_file);
+
+ variable cmd_list = list_new(), next_arg = "", last_was_percent = 0;
+ foreach (cmd)
+ {
+ variable ch = ();
+ if (last_was_percent)
+ {
+ switch (ch)
+ { case '%': next_arg += "%"; }
+ { case 'c': next_arg += string(what_column()); }
+ { case 'f':
+ if (buffer_filename() == "")
+ throw InternalError, "Buffer without filename: " + whatbuf();
+ % Fixme: this path should be relativ
+ next_arg += buffer_filename();
+ }
+ { case 'l': next_arg += string(what_line()); }
+ { case 'm': next_arg += rel_master_file; }
+ { case 'M': next_arg += path_sans_extname(rel_master_file); }
+ { case ' ': next_arg += " "; }
+ { throw InvalidParmError, "Invalid escape sequence in cmd: %"+ch; }
+ last_was_percent = 0;
+ }
+ else
+ {
+ switch (ch)
+ { case ' ':
+ list_append(cmd_list, next_arg, -1);
+ next_arg = "";
+ }
+ { case '%': last_was_percent = 1; }
+ { next_arg += char(ch); }
+ }
+ }
+ if (last_was_percent)
+ next_arg += "%";
+ if (strlen(next_arg) != 0)
+ list_append(cmd_list, next_arg, -1);
+
+ if ( chdir( path_dirname(master_file) ) )
+ throw IOError, "Could not change directory";
+
+ variable oldbuf = whatbuf();
+
+ if (typeof(buf) == String_Type)
+ {
+ variable buffer_exists = bufferp(buf);
+ setbuf(buf);
+
+ % set it in all cases, maybe we don't compose the same file
+ create_blocal_var("LaTeX_master_file");
+ set_blocal_var(master_file, "LaTeX_master_file");
+
+ if (buffer_exists) {
+ % buffer already exists
+ set_readonly(0);
+ erase_buffer();
+ } else {
+ % buffer is new
+ set_buffer_hook("update_hook", &update_log_hook());
+ }
+ }
+
+ if ( cmd[0] == '@' )
+ {
+ try
+ eval(cmd[[1:]]);
+ finally
+ setbuf(oldbuf);
+ }
+ else
+ {
+ variable pid;
+ try
+ {
+ foreach (cmd_list) ; % push elements on stack
+ pid = open_process_pipe( length(cmd_list)-1 );
+ }
+ finally
+ setbuf(oldbuf);
+
+ process_query_at_exit(pid, 1);
+
+ if (typeof(buf) == Ref_Type)
+ set_process(pid, "output", buf);
+
+ return pid;
+ }
+}
+
+%%%%%%%%%%
+%
+% General log files (bibtex, makeindex, tex)
+%
+private variable SIMPLE_KEYMAP = MODE + "-simple";
+
+!if ( keymap_p(SIMPLE_KEYMAP) ) {
+ make_keymap(SIMPLE_KEYMAP);
+
+ definekey("delbuf(whatbuf());call(\"delete_window\")", "q", SIMPLE_KEYMAP);
+ definekey("delete_window", "c", SIMPLE_KEYMAP);
+}
+
+private define show_log_file(log_file)
+{
+ if (stat_file(log_file) == NULL)
+ throw ApplicationError, "Log file does not exist";
+
+ % moves the current line in the upper half of the window, else the new
+ % window is opened on the upper border
+ if (window_line() >= window_info('r')/2) {
+ recenter( window_info('r')/2-3 );
+ update_sans_update_hook(1);
+ }
+
+ variable buf = find_buf_of_file(log_file);
+ variable open_new_buffer = 1;
+ if (buf != NULL)
+ {
+ setbuf(buf);
+ if ( _test_buffer_flag(0x004) )
+ delbuf(whatbuf());
+ else
+ open_new_buffer = 0;
+ }
+
+ if (open_new_buffer)
+ {
+ if (get_master_var("compose_pid", -1) != -1)
+ throw UsageError, "A compose process is running. I cannot open the log file";
+
+ () = read_file(log_file);
+
+ set_readonly(1);
+ set_buffer_modified_flag(0);
+
+ use_keymap(SIMPLE_KEYMAP);
+ set_status_line(" " + path_basename(log_file) + " ", 0);
+ }
+ pop2buf( whatbuf() );
+
+ window_info('r')-6; % leaves its return code on stack
+ otherwindow();
+ loop( () ) enlargewin(); % shrinks the other window to a size of 6 rows
+ otherwindow();
+
+ return open_new_buffer;
+}
+
+%%%%%%%%%%
+%
+% All about parsing the TeX log file
+%
+
+%!%+
+%\function{find_next_error}
+%\synopsis{Moves the cursor to the line with the next error}
+%\usage{find_next_error}
+%\description
+% This function moves the editing point to the next line, taht contains
+% an error or a warning message of latex.
+%
+% It stops on font warning, undefined references, over and underfull boxes,
+% and all error messages.
+%!%-
+% dir == 1 -> forward, dir != 0 -> backward
+static define find_next(what, dir)
+{
+ variable move;
+ if (dir) move = &down();
+ else move = &up();
+
+ variable found = ' ';
+ variable old_mark = create_user_mark(), old_err_text;
+ if ( looking_at("! ") )
+ {
+ push_mark();
+ () = bol_fsearch("l.");
+ () = down(1);
+ old_err_text = bufsubstr();
+ }
+ do {
+ while (@move(1)) {
+ bol();
+ switch ( what_char() )
+ { case 'L' or case 'P':
+ if ( orelse {looking_at("LaTeX")} {looking_at("Package")} )
+ {
+ if ( ffind("Warning:") )
+ {
+ found = 'w';
+ bol();
+ break;
+ }
+ % else
+ % {
+ % if ( ffind("Info:") )
+ % found = 'i';
+ % else
+ % continue;
+ % }
+ }
+ }
+ { case 'O': if (looking_at("Overfull")) { found = 'b'; break; } }
+ { case 'U': if (looking_at("Underfull")) { found = 'b'; break; } }
+ { case '!':
+ if ( andelse {looking_at("! ")}
+ {not ( andelse {__is_initialized(&old_err_text)}
+ {looking_at(old_err_text)} )
+ } )
+ {
+ found = 'e';
+ break;
+ }
+ }
+ { case 'R':
+ if (looking_at("Runaway argument?"))
+ {
+ found = 'e';
+ break;
+ }
+ }
+ }
+ } while (andelse {what != '*'} {what != found} {not bobp()} {eol(), not eobp()});
+
+ if (bobp() or eobp())
+ {
+ goto_user_mark(old_mark);
+ switch (what)
+ { case 'e': throw UsageError, "No error message left"; }
+ { case 'w': throw UsageError, "No warning message left"; }
+ { case 'b': throw UsageError, "No box message left"; }
+ { case '*': throw UsageError, "No message left"; }
+ { throw InvalidParmError, "unknown search target: "+char(what); }
+ }
+}
+
+!if ( keymap_p(MODE) ) {
+ copy_keymap(MODE, SIMPLE_KEYMAP);
+
+ variable key;
+ foreach key (['e', 'w', 'b'])
+ {
+ definekey("latex_external->find_next('"+char(key)+"', 0)",
+ char(key-0x20), MODE);
+ definekey("latex_external->find_next('"+char(key)+"', 1)",
+ char(key), MODE);
+ }
+ definekey("latex_external->find_next('*', 0)", "N", MODE);
+ definekey("latex_external->find_next('*', 1)", "n", MODE);
+
+ definekey("latex_external->goto_error_line()", "g", MODE);
+ definekey("latex_external->goto_error_line()", "\n", MODE);
+ definekey("latex_external->goto_error_line()", "\r", MODE);
+}
+
+%!%+
+%\function{pop2compose_buf}
+%\synopsis{pops up a new window with the buffer for compiler output}
+%\usage{pop2compose_buf([Integer_Type goto_first_error])}
+%\description
+% If a buffer COMPILE_BUF_NAME exists, a new window is opened with the
+% buffer and this window is shrinked to a size of 6 rows. Therefor the
+% current line of the current window is moved in the upper half, that the
+% new window raises at the bottom.
+%
+% If the optional argument \var{goto_first_error} is given and != 0, the
+% cursor is moved to the first error.
+%
+% After all a short usage message is shown.
+%
+% The buffer is created by compose().
+%\seealso{COMPILE_BUF_NAME, find_next_error(), compose()}
+%!%-
+static define pop_log_file()
+{
+ variable log_file = path_sans_extname( get_master_file() ) + ".log";
+ !if ( show_log_file(log_file) )
+ return;
+
+ use_keymap(MODE);
+ set_buffer_hook("update_hook", &update_log_hook());
+
+ variable box=0, err=0, warn=0;
+ bob();
+ while ( down(1) ) {
+ switch ( what_char() )
+ { case 'L' or case 'P':
+ if ( andelse {orelse {looking_at("LaTeX")}
+ {looking_at("Package")} } {ffind("Warning:")})
+ {
+ bol();
+ ++warn;
+ }
+ }
+ { case 'O': if (looking_at("Overfull")) ++box; }
+ { case 'U': if (looking_at("Underfull")) ++box; }
+ { case '!': if (looking_at("! ")) ++err; }
+ { case 'R': if (looking_at("Runaway argument?")) ++err; }
+ }
+
+ variable str = "";
+ if (err) str += string(err)+" errors, ";
+ if (warn) str += string(warn)+" warnings, ";
+ if (box) str += string(box)+" under-/overfull boxes, ";
+
+ eob();
+ if ( andelse {bol_bsearch("Output written on")}
+ {ffind_char('(')} {right(1)} )
+ {
+ push_mark();
+ skip_chars("0-9");
+ str += bufsubstr() + " pages written";
+ }
+ bob();
+
+ message(str);
+
+ set_status_line(" "+path_basename(log_file) +
+ " -- e: error; w: warning; b: box; g,Enter: go to error line; q: quit",
+ 0);
+}
+
+private define next_log_line()
+{
+ % TeX breakes lines at 80 characters. A line longer than this is more
+ % than one real lines
+ do
+ eol();
+ while ( andelse {what_column() == 80} {down(1)} );
+
+ return down(1);
+}
+
+%!%+
+%\function{goto_error_line}
+%\synopsis{jumps to the error line in the latex code}
+%\usage{goto_error_line}
+%\description
+% If the current editing point is in a line with an error or warning message
+% of latex, this function switches to the buffer of the file wherein the error
+% occured and jumps to the line, named in the output.
+%!%-
+static define goto_error_line()
+{
+ variable start_mark = create_user_mark(), file_stack = {};
+ variable last_msg_type = '\0', last_msg_mark = start_mark;
+
+ bob();
+ while (andelse {next_log_line()} {create_user_mark() <= start_mark} )
+ {
+ switch ( what_char() )
+ { case 'L' or case 'P':
+ push_mark();
+ () = ffind_char(':');
+ variable token = strtok(bufsubstr(), " ");
+ if ( andelse {length(token) >= 2} {length(token) <= 3}
+ {token[0] == "LaTeX" or token[0] == "Package"}
+ {token[-1] == "Warning" or token[-1] == "Info"} )
+ {
+ if (length(token) == 3)
+ {
+ variable pkg = "(" + token[1] + ")";
+ variable last_line_mark = create_user_mark();
+
+ while ( andelse {next_log_line()} {looking_at(pkg)} )
+ last_line_mark = create_user_mark();
+
+ goto_user_mark(last_line_mark);
+ }
+
+ last_msg_type = 'W';
+ last_msg_mark = create_user_mark();
+ continue;
+ }
+ }
+ { case 'O' or case 'U':
+ if (orelse {looking_at("Overfull ")} {looking_at("Underfull ")})
+ {
+ () = ffind_char(' ');
+ if ( looking_at(" \\hbox") )
+ {
+ last_msg_type = 'B';
+ last_msg_mark = create_user_mark();
+
+ () = bol_fsearch(" []\n");
+ }
+ continue;
+ }
+ }
+ { case '!':
+ if ( andelse {looking_at("! ")} {bol_fsearch("l.")} )
+ {
+ last_msg_type = 'E';
+ last_msg_mark = create_user_mark();
+
+ () = bol_fsearch_char('\n');
+ continue;
+ }
+ }
+ { case 'R':
+ if ( looking_at("Runaway argument?") )
+ {
+ last_msg_type = 'R';
+ last_msg_mark = create_user_mark();
+
+ () = bol_fsearch_char('\n');
+ continue;
+ }
+ }
+
+ forever
+ {
+ skip_chars("^()\n");
+ switch ( what_char() )
+ { case '\n':
+ if (what_column() != 80)
+ break;
+ % this is a wrapped line that is continued after the \n
+ () = down(1);
+ }
+ { case ')': list_delete(file_stack, 0); () = right(1); }
+ { case '(':
+ () = right(1);
+ push_mark();
+ skip_chars("^ \n\t(){");
+ while (what_column() == 80 and what_char() == '\n')
+ {
+ () = right(1);
+ skip_chars("^ \n\t(){");
+ }
+ list_insert(file_stack, str_delete_chars(bufsubstr(), "\n"),
+ 0);
+ }
+ { case '\0': break; } % end of file
+ }
+ }
+ goto_user_mark(last_msg_mark);
+
+ variable line = 0, text, detail_text;
+ switch (last_msg_type)
+ { case 'W' or case 'B':
+ variable log_msg = line_as_string();
+ while ( andelse {what_column() == 80} {down(1)} )
+ log_msg += line_as_string();
+
+ variable pos = is_substr(log_msg, "line"), dummy;
+ if (pos != 0)
+ () = sscanf(substr(log_msg, pos, strlen(log_msg)), "%s %d",
+ &dummy, &line);
+ }
+ { case 'E':
+ () = right(2);
+ push_mark();
+ skip_chars("0-9");
+ line = integer( bufsubstr() );
+
+ () = right(1);
+ push_mark();
+ eol();
+ text = bufsubstr();
+
+ bol();
+ if ( bol_bsearch("! ") )
+ {
+ () = down(1);
+ if ( looking_at("<argument>") )
+ {
+ % For somewhat reason LaTeX prints out the text with
+ % additional spaces. This might be the parsed form
+ % (the tokens) of the text.
+ eol();
+ bskip_chars(" ");
+ push_mark();
+ bskip_chars("^ ");
+ detail_text = bufsubstr();
+ }
+ }
+ }
+ { case 'R':
+ () = down(1);
+ push_mark();
+ skip_chars("^\\");
+ text = bufsubstr();
+
+ forever
+ {
+ !if ( re_fsearch("^[<l][*.]") ) % fixme PCRE
+ throw NotImplementedError, "Unexpected message style";
+
+ latex->debug_pos();
+ if ( looking_at("<*> ") )
+ {
+ (text,) = strreplace(text, " ", "[ \n\t]*", strlen(text));
+ if ( ffind("\\input{") )
+ () = right(7);
+ else
+ () = right(4);
+ push_mark();
+ skip_chars("^ \n\t(){}");
+ while (what_column() == 80 and what_char() == '\n')
+ {
+ () = right(1);
+ skip_chars("^ \n\t(){}");
+ }
+ list_insert(file_stack, bufsubstr(), 0);
+ () = bol_fsearch("\n");
+ break;
+ }
+ else if ( looking_at("l.") )
+ {
+ () = right(2);
+ push_mark();
+ skip_chars("0-9");
+ line = integer( bufsubstr() );
+ detail_text = text;
+ __uninitialize(&text);
+ () = bol_fsearch("\n");
+ break;
+ }
+ }
+ }
+ goto_user_mark(start_mark);
+
+ if (length(file_stack) == 0)
+ throw UsageError, "You are not inside the scope of a LaTeX message";
+
+ variable file_name;
+ if ( path_is_absolute(file_stack[0]) )
+ file_name = file_stack[0];
+ else
+ file_name = path_concat(path_dirname(get_master_file()), file_stack[0]);
+
+ call("delete_window");
+ if ( find_file(file_name) )
+ {
+ if (line > 0)
+ goto_line(line);
+ if ( __is_initialized(&text) )
+ {
+ if (line == 0)
+ % This is a "Runaway argument" message
+ {
+ goto_line(1);
+ () = re_fsearch(text);
+ }
+ else if ( strncmp(text, "...", 3) )
+ {
+ variable col = strlen(text)+1;
+ eol();
+ if ( col <= what_column() )
+ goto_column(col);
+ else
+ {
+ % this happens when the file was edited
+ bol();
+ __uninitialize(&detail_text);
+ }
+ }
+ else
+ () = right( ffind(text[[3:]]) );
+ }
+ if ( __is_initialized(&detail_text) )
+ () = right( bsearch(detail_text) );
+ }
+}
+
+%%%%%%%%%%
+%
+% Composing
+%
+
+private define compose_sig_handl(pid, flags, status);
+private define compose_sig_handl(pid, flags, status)
+{
+ if ( pid != get_master_var("compose_pid", -1) )
+ error("Notification for wrong pid got: ("+ string(pid) +","+
+ string(flags) +","+ string(status) + ")");
+
+ switch (flags)
+ { case 1: return; }
+ { case 4 or case 8:
+ set_master_var(-1, "compose_pid");
+
+ if ( get_master_var("is_post_process", 0) )
+ {
+ set_master_var(0, "is_post_process");
+
+ if (status != 0)
+ throw ApplicationError, "(post process) finished with error";
+
+ message("(post process) finished");
+ return;
+ }
+ else
+ {
+ if (status != 0)
+ throw ApplicationError, "(compose) finished with error";
+ flush("(compose) finished");
+ }
+
+ variable master_file = get_master_file(), do_rerun = 0;
+ if (cust[LaTeX_Config].rerun)
+ {
+ variable logfile = fopen(path_sans_extname(master_file)+".log", "r");
+ variable lines = fgetslines(logfile);
+ () = fclose(logfile);
+
+ % if one of the lines contain this string we must rerun latex
+ do_rerun = any( array_map(Integer_Type, &is_substr(), lines,
+ "Rerun to get cross-references right."));
+ % Fixme: "Marginpars may have changed."
+ % "(mparhack) Rerun to get them right."
+ }
+
+ !if ( do_rerun or strlen(cust[LaTeX_Config].post) )
+ return;
+
+ if (whatbuf() == " latex-compose")
+ setbuf( find_buf_of_file(master_file) );
+ else
+ {
+ setbuf(" latex-compose");
+ create_blocal_var("LaTeX_master_file");
+ set_blocal_var(master_file, "LaTeX_master_file");
+ }
+
+ variable cmd;
+ if (do_rerun)
+ {
+ message("(compose) Rerun to get cross-references right...");
+ cmd = cust[LaTeX_Config].latex;
+ }
+ else
+ {
+ set_master_var(1, "is_post_process");
+ message("(compose) postprocessing output file...");
+ cmd = cust[LaTeX_Config].post;
+ }
+
+ pid = expand_and_run_cmd(cmd, DUMMY_OUTPUT_BUFFER);
+ set_master_var(pid, "compose_pid");
+ set_process(pid, "signal", &compose_sig_handl());
+ }
+ {
+ error("Compose process exited abnormal: flag="+ string(flags) +
+ ", status="+string(status));
+ }
+}
+
+static define compose()
+{
+ if (get_master_var("compose_pid", -1) != -1)
+ throw UsageError, "A compose process is already running";
+
+ call("save_some_buffers");
+
+ variable outp;
+ if ( is_substr(cust[LaTeX_Config].latex, "rubber") )
+ outp = &output_to_msg();
+ else
+ outp = DUMMY_OUTPUT_BUFFER;
+
+ variable pid = expand_and_run_cmd(cust[LaTeX_Config].latex, outp);
+ set_master_var(pid, "compose_pid");
+ set_process(pid, "signal", &compose_sig_handl());
+
+ message("Composing...");
+}
+
+%!%+
+%\function{cleanup}
+%\synopsis{removes all temporally files of latex}
+%\usage{cleanup()}
+%\description
+% Removes all temporally files, created by latex while composing. This files
+% are those which have the name of the compose file with a suffix defined
+% in the array Cleanup_extensions.
+%
+%\seealso{Cleanup_extensions}
+%!%-
+static define clearup()
+{
+ message("Deleting temporary files...");
+ () = expand_and_run_cmd(cust[LaTeX_Config].clean, DUMMY_OUTPUT_BUFFER);
+}
+
+%!%+
+%\function{mrproper}
+%\synopsis{removes all temporally files of latex and the output file}
+%\usage{mrproper()}
+%\description
+% Removes all temporally files, created by latex while composing. This files
+% are those which have the name of the compose file with a suffix defined
+% in the array Cleanup_extensions.
+%
+%\seealso{Cleanup_extensions}
+%!%-
+static define mrproper()
+{
+ () = expand_and_run_cmd(cust[LaTeX_Config].mrproper, DUMMY_OUTPUT_BUFFER);
+ message("Deleting temporary files and output file...");
+}
+
+private variable server_comm = NULL, last_buf;
+
+private define view_comm_outp(pid, data)
+{
+ if (strncmp("communicator created: ", data, 22) == 0)
+ {
+ server_comm = substr(data, 23, strlen(data)-23);
+ sw2buf(last_buf);
+ view();
+ return;
+ }
+ if (data == "quit\n")
+ return;
+
+ variable line, col, file;
+ if (sscanf(data, "%d:%d%s", &line, &col, &file) != 3)
+ throw ApplicationError, "View server send unknown string", data;
+
+ () = find_file(file);
+ goto_line(line);
+ goto_column(col);
+#ifexists x_toggle_visibility
+ x_toggle_visibility(0);
+#else
+ tt_send("\e[5t"); % this is the control sequence to raise the
+ % xterm to the front
+#endif
+}
+
+private define view_comm_sig(pid, flags, status)
+{
+ switch (flags)
+ { case 1: return; }
+ { case 4 or case 8: server_comm = NULL; }
+ {
+ throw ApplicationError, "View server exited abnormal";
+ }
+}
+
+private define view_comm_quit()
+{
+ if (server_comm == NULL)
+ return;
+
+ variable fifo = fopen(server_comm, "w");
+ try
+ {
+ () = fputs("quit\n", fifo);
+ }
+ finally
+ () = fclose(fifo);
+
+ % There's bug in SLang before version 2.0.7.91 that discards a system
+ % call like fopen() if a signal arrives at the same time. Because we
+ % use SLang for latex_comm.sl and it gets a SIGHUP when this process
+ % finishes it never gets the quit. Due to this wait a moment and the
+ % finish.
+ sleep(.1);
+}
+add_to_hook("_jed_quit_hooks", &view_comm_quit());
+
+static define view()
+{
+ if (get_master_var("compose_pid", -1) != -1)
+ throw UsageError, "A compose process is running. I cannot open viewer.";
+
+ variable cmd = cust[LaTeX_Config].view;
+ if ( is_substr(cmd, "%e") )
+ {
+ variable latex_comm = expand_jedlib_file("latex_comm.sl");
+ if (server_comm == NULL)
+ {
+ last_buf = whatbuf();
+ variable pid = expand_and_run_cmd("jed-script $latex_comm watch"$,
+ " latex-comm");
+
+ set_process(pid, "output", &view_comm_outp());
+ set_process(pid, "signal", &view_comm_sig());
+ process_query_at_exit(pid, 0);
+
+ return; % the real viewer startup is triggered by view_comm_outp
+ }
+ (cmd,) = strreplace(cmd, "%e", "jed-script% "+ latex_comm
+ +"% "+ server_comm + "% %%l:0%%c%%f", 1);
+ }
+
+ % Fixme: have a better idea than try bad(); catch: do_somthing_others();
+ % How to query is a process is assigned to the buffer?
+ try
+ {
+ () = expand_and_run_cmd(cmd, " latex-view");
+ }
+ catch RunTimeError:
+ () = expand_and_run_cmd(cmd, " latex-view-2");
+
+ % xpdf -q -remote jlm-$PID -raise %M.pdf %p
+ % xpdf -q -remote jlm-$PID -raise -reload
+ % xpdf -q -remote jlm-$PID -quit
+}
+static define print()
+{
+ if (get_master_var("compose_pid", -1) != -1)
+ throw UsageError, "A compose process is running. I cannot start printer.";
+
+ () = expand_and_run_cmd(cust[LaTeX_Config].print, &output_to_msg());
+}
+
+%!%+
+%\function{makeindex}
+%\synopsis{}
+%\usage{makeindex()}
+%\description
+% Don't know what it does.
+%!%-
+static define makeindex()
+{
+ () = expand_and_run_cmd(cust[LaTeX_Config].index, DUMMY_OUTPUT_BUFFER);
+}
+
+static define show_mkidx_log()
+{
+ () = show_log_file(path_sans_extname( get_master_file() ) + ".ilg");
+}
+
+%!%+
+%\function{bibtex}
+%\synopsis{}
+%\usage{bibtex()}
+%\description
+% Don't know what it does.
+%!%-
+static define bibtex()
+{
+ () = expand_and_run_cmd(cust[LaTeX_Config].bibtex, DUMMY_OUTPUT_BUFFER);
+}
+
+static define show_bibtex_log()
+{
+ () = show_log_file(path_sans_extname( get_master_file() ) + ".blg");
+}
+
+provide("latex_external");
+runhooks("after_latex_external_load_hook");
diff --git a/support/jed/jlm/latex_pst.sl b/support/jed/jlm/latex_pst.sl
new file mode 100644
index 0000000000..06897f51a6
--- /dev/null
+++ b/support/jed/jlm/latex_pst.sl
@@ -0,0 +1,307 @@
+% File: latex.sl -*- mode: SLang -*-
+%
+% Copyright (c)
+% 2007 Jörg Sommer <joerg@alea.gnuu.de>
+% $Id: latex_pst.sl 199 2007-08-23 23:28:52Z joerg $
+%
+% -*- This file is part of Jörg's LaTeX Mode (JLM) -*-
+%
+% Description: This file contains all functions related to PSTricks.
+%
+% License: 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 2 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.
+
+%%%%%%%%%%
+%
+% A point in PSTricks
+%
+typedef struct {
+ x, y, mark
+} Pst_Point_Type;
+
+static define pst_point_as_string(pnt)
+{
+ return "(" + string(pnt.x) + "," + string(pnt.y) + ")";
+}
+
+__add_string(Pst_Point_Type, &pst_point_as_string());
+
+static define pst_new_point() % (x, y[, mark])
+{
+ variable pnt = @Pst_Point_Type;
+ if (_NARGS > 2)
+ pnt.mark = ();
+
+ pnt.y = ();
+ pnt.x = ();
+ return pnt;
+}
+
+static define pst_add_points(a, b)
+{
+ return pst_new_point(a.x + b.x, a.y + b.y);
+}
+__add_binary("+", Pst_Point_Type, &pst_add_points(), Pst_Point_Type,
+ Pst_Point_Type);
+
+static define pst_point_min(pnt1, pnt2)
+{
+ return pst_new_point( min([pnt1.x, pnt2.x]), min([pnt1.y, pnt2.y]) );
+}
+
+static define pst_point_max(pnt1, pnt2)
+{
+ return pst_new_point( max([pnt1.x, pnt2.x]), max([pnt1.y, pnt2.y]) );
+}
+
+static define pst_looking_at_point()
+{
+ % return re_looking_at("[ \t\n]*(');
+ return looking_at_char('(');
+}
+
+static define pst_skip_point()
+{
+ return andelse {fsearch_char(')')} {right(1)};
+}
+
+static define pst_update_point(pnt, new_pnt)
+{
+ if (pnt.mark == NULL)
+ throw UsageError, "pnt is not a real point";
+
+ push_spot();
+ EXIT_BLOCK
+ {
+ pop_spot();
+ }
+ goto_user_mark(pnt.mark);
+ % insert before delete to make a spot after the deleted string is left
+ % there
+ insert( pst_point_as_string(new_pnt) );
+ push_mark();
+ () = pst_skip_point();
+ del_region();
+ pnt.x = new_pnt.x;
+ pnt.y = new_pnt.y;
+}
+
+static define pst_read_point()
+{
+ !if ( pst_looking_at_point() )
+ throw UsageError, "No at a point";
+
+ variable mark = create_user_mark();
+
+ () = right(1);
+ push_mark();
+ !if ( pst_skip_point() )
+ {
+ pop_mark(0);
+ goto_user_mark(mark);
+ throw DataError, "This doesn't look like a PSTricks point ($what_line,"$ +
+ string(what_column()) + ")";
+ }
+
+ variable x, y;
+ if ( sscanf(str_delete_chars(bufsubstr(), "\s"R), "%g,%g", &x, &y) != 2 )
+ {
+ goto_user_mark(mark);
+ throw DataError, "This doesn't look like a PSTricks point ($what_line,"$ +
+ string(what_column()) + ")";
+ }
+
+ return pst_new_point(x, y, mark);
+}
+
+private define pst_extract_points_from_region()
+{
+ check_region(1);
+ EXIT_BLOCK
+ {
+ pop_spot();
+ }
+ variable end_mark = create_user_mark();
+ pop_mark(1);
+
+ variable point_list = list_new();
+ while (create_user_mark() < end_mark)
+ {
+ skip_chars("^\\{"R);
+ if ( is_commented() )
+ {
+ eol();
+ continue;
+ }
+ if ( looking_at("\\{") or looking_at("\\\\") )
+ {
+ () = right(2);
+ continue;
+ }
+ if ( looking_at_char('{') )
+ {
+ fsearch_matching_brace();
+ continue;
+ }
+
+ () = right(1);
+ push_mark();
+ skip_chars(TeX_Command_Chars);
+ !if ( is_list_element("rput,psframe,psline,pscircle,psbezier,psdot,psdots,psaxes",
+ bufsubstr(), ',') )
+ continue;
+ (,) = cmd_parse_args(1,0);
+ !if ( pst_looking_at_point() )
+ throw DataError, "Malformed pstricks command in line $what_line"$;
+ do
+ {
+ list_append(point_list, pst_read_point());
+ }
+ while ( pst_looking_at_point() );
+ }
+
+ return point_list;
+}
+
+%%%%%%%%%%
+%
+% PSTricks
+%
+static variable PST_Origin = pst_new_point(0,0);
+
+static define pst_enlarge_pic(point)
+{
+ push_spot();
+ EXIT_BLOCK
+ {
+ pop_spot();
+ }
+
+ boenv();
+ !if ( looking_at("\\begin{pspicture}") )
+ throw UsageError, "This is not a pspicture environment";
+
+ () = right(17);
+ if ( pst_looking_at_point() )
+ {
+ variable old_point = pst_read_point(), tmp_point;
+ if ( pst_looking_at_point() )
+ {
+ tmp_point = pst_point_min(old_point, point);
+ if (tmp_point.x < old_point.x or tmp_point.y < old_point.y)
+ {
+ if (tmp_point.x == PST_Origin.x and tmp_point.y == PST_Origin.y)
+ {
+ push_spot();
+ goto_user_mark(old_point.mark);
+ push_mark();
+ pst_skip_point();
+ del_region();
+ pop_spot();
+ }
+ else
+ pst_update_point(old_point, tmp_point);
+ }
+
+ old_point = pst_read_point();
+ }
+ else if (point.x < PST_Origin.x or point.y < PST_Origin.y)
+ {
+ push_spot();
+ goto_user_mark(old_point.mark);
+ insert( pst_point_as_string(pst_point_min(PST_Origin, point)) );
+ pop_spot();
+ }
+
+ tmp_point = pst_point_max(old_point, point);
+ if (old_point.x < tmp_point.x or old_point.y < tmp_point.y)
+ {
+ if (tmp_point.x == PST_Origin.x and tmp_point.y == PST_Origin.y)
+ {
+ push_spot();
+ goto_user_mark(old_point.mark);
+ push_mark();
+ pst_skip_point();
+ del_region();
+ pop_spot();
+ }
+ else
+ pst_update_point(old_point, tmp_point);
+ }
+ }
+ else
+ {
+ if (point.x < PST_Origin.x or point.y < PST_Origin.y)
+ insert( pst_point_as_string(pst_point_min(point, PST_Origin)) +
+ pst_point_as_string(pst_point_max(point, PST_Origin)) );
+ else if (point.x > PST_Origin.x or point.y > PST_Origin.y)
+ insert( pst_point_as_string(point) );
+ }
+}
+
+static define pst_update_pic_size()
+{
+ push_spot();
+ EXIT_BLOCK
+ {
+ pop_spot();
+ }
+
+ boenv();
+ !if ( looking_at("\\begin{pspicture}") )
+ throw UsageError, "This is not a pspicture environment";
+ () = right(17);
+ while ( pst_looking_at_point() )
+ () = pst_skip_point();
+
+ push_mark();
+ eoenv();
+
+ variable min = PST_Origin, max = PST_Origin;
+ foreach ( pst_extract_points_from_region() )
+ {
+ dup;
+ min = pst_point_min((), min);
+ max = pst_point_max((), max);
+ }
+
+ pst_enlarge_pic(min);
+ pst_enlarge_pic(max);
+}
+
+static define pst_move_points()
+{
+ variable offset;
+ try
+ offset = read_mini("Offset to move points; use X for (X,X) or (X,Y)",
+ "", "");
+ catch UserBreakError:
+ return;
+
+ variable x, y;
+ if ( andelse {sscanf(offset, "%g", &x) != 1}
+ {sscanf(offset, "(%g,%g)", &x, &y) != 2})
+ throw UsageError, "Invalid input for offset";
+
+ !if ( __is_initialized(&y) )
+ y = x;
+
+ offset = pst_new_point(x, y);
+ variable max = PST_Origin, min = PST_Origin, p;
+ foreach p ( pst_extract_points_from_region() )
+ {
+ variable new_p = p + offset;
+ min = pst_point_min(min, new_p);
+ max = pst_point_max(max, new_p);
+ pst_update_point(p, new_p);
+ }
+ pst_enlarge_pic(min);
+ pst_enlarge_pic(max);
+}
diff --git a/support/jed/jlm/latex_typo.sl b/support/jed/jlm/latex_typo.sl
new file mode 100644
index 0000000000..2a8451ee33
--- /dev/null
+++ b/support/jed/jlm/latex_typo.sl
@@ -0,0 +1,580 @@
+% File: latex.sl -*- mode: SLang; mode: fold -*-
+%
+% Copyright (c)
+% 2007 Jörg Sommer <joerg@alea.gnuu.de>
+% $Id: latex_typo.sl 206 2007-09-08 13:38:39Z joerg $
+%
+% -*- This file is part of Jörg's LaTeX Mode (JLM) -*-
+%
+% Description: This file includes all functions related to typography.
+%
+% License: 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 2 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.
+
+if (current_namespace() != "latex")
+ throw UsageError, "You must load this file into the namespace \"latex\"";
+
+private define is_active()
+{
+ return andelse {LaTeX_Typo_Active} {not is_verbatim()};
+}
+
+private variable b_n_c_del;
+private variable b_n_c_insert;
+private variable b_n_c_fun;
+
+private define before_next_char_hook(fun);
+private define before_next_char_hook(fun)
+{
+ debug_msg(sprintf("%s: %c, %S, %s, %s, %S", _function_name(), LAST_CHAR,
+ fun, b_n_c_del, b_n_c_insert, b_n_c_fun) );
+
+ EXIT_BLOCK
+ {
+ remove_from_hook("_jed_before_key_hooks", &before_next_char_hook());
+ __uninitialize(&b_n_c_del);
+ }
+
+ if (andelse {typeof(fun) == String_Type}
+ {orelse {fun == "self_insert_cmd"} {strncmp(fun, "latex->", 7) == 0}}
+ {@b_n_c_fun(LAST_CHAR)} )
+ {
+ variable len = strlen(b_n_c_del);
+ () = left(len);
+ if ( looking_at(b_n_c_del) )
+ () = replace_chars(len, b_n_c_insert);
+ else
+ () = right(len);
+ }
+}
+
+private define enable_before_next_char_hook(del, ins, fun)
+{
+ if ( __is_initialized(&b_n_c_del) )
+ throw UsageError, "before_next_char_hook already active";
+
+ b_n_c_del = del;
+ b_n_c_insert = ins;
+ b_n_c_fun = fun;
+
+ add_to_hook("_jed_before_key_hooks", &before_next_char_hook());
+}
+
+private define is_alpha_or_hyphen(char)
+{
+ return orelse {char == '-'} {isalpha(char)};
+}
+
+%!%+
+%\function{typo_slash()}
+%\synopsis{Replaces a / after a word by \\slash{} or adds ""}
+%\usage{typo_slash()}
+%\description
+% LaTeX does not break words combined with / after the slash, e.g. the
+% text "input/output" is one block and is not wrapped before output.
+%
+% If the number of characters before the / is at least \var{LaTeX_Typo_Word_Size},
+% the / is replaced by \\slash{}, if the package babel is not loaded, or a
+% "" is appended, if the package babel is loaded. \\slash{} is a / with an
+% hyphenpoint after it. Unfortunely, it removes all other hyphenpoints
+% from word after the slash. This does not happen with "" from babel.
+%
+%\notes
+% You can disable this function by setting the variable \var{LaTeX_Typo_Active}
+% to 0. This still inserts the / character as \sfun{self_insert_cmd} would do.
+%
+%\seealso{LaTeX_Typo_Active, LaTeX_Typo_Word_Size}
+%!%-
+static define typo_slash()
+{
+ if (LAST_CHAR != '/')
+ throw UsageError, "typo_slash called for anything else than /";
+
+ % Insert the / and do abbrev expansion
+ call("self_insert_cmd");
+
+ !if ( is_active() )
+ return;
+
+ push_spot();
+ EXIT_BLOCK
+ {
+ pop_spot();
+ }
+
+ () = left(1);
+ if ( blooking_at("-") or blooking_at("\"~") or blooking_at("\"\"") )
+ {
+ EXIT_BLOCK {};
+ pop_spot();
+
+ if ( pkg_loaded("babel") )
+ insert("\"\"");
+ else
+ () = replace_chars(1, "\\slash{}");
+
+ return;
+ }
+
+ _get_point();
+ bskip_word_chars();
+ if ( () - _get_point() < LaTeX_Typo_Word_Size )
+ return;
+
+ if ( pkg_loaded("babel") )
+ enable_before_next_char_hook("", "\"\"", &is_alpha_or_hyphen());
+ else
+ enable_before_next_char_hook("/", "\\slash{}", &isalpha());
+}
+
+%!%+
+%\function{typo_percent()}
+%\synopsis{Inserts a \\, before \\%}
+%\usage{typo_percent()}
+%\description
+% In german typography, a spatium (\\,) should be before a percent sign.
+% This function removes all whitespaces before \\% and insert an \\,.
+%
+%\notes
+% You can disable this function by setting the variable \var{LaTeX_Typo_Active}
+% to 0. This still inserts the % character as \sfun{self_insert_cmd} would do.
+%
+%\seealso{LaTeX_Typo_Active}
+%!%-
+static define typo_percent()
+{
+ if (LAST_CHAR != '%')
+ throw UsageError, "typo_percent called for anything else than %";
+
+ if (andelse {is_active()} {is_escaped()})
+ {
+ () = left(1);
+ trim();
+ !if ( blooking_at("\\,") )
+ insert("\\,");
+ () = right(1);
+ }
+
+ call("self_insert_cmd");
+}
+
+%!%+
+%\function{typo_abbrev()}
+%\synopsis{Inserts a \\, between abbreviations}
+%\usage{typo_abbrev()}
+%\description
+% In german typography, a spatium (\\,) should be after the dot inside of
+% an abbreviation, e.g. z.\\,B. or i.\\,d.\\,R. This functions checks if the
+% number of characters before the first dot and before the current point is
+% less than LaTeX_Typo_Word_Size and inserts a \\, after the previous dot,
+% if it is so.
+%
+%\notes
+% You can disable this function by setting the variable \var{LaTeX_Typo_Active}
+% to 0. This still inserts the % character as \sfun{self_insert_cmd} would do.
+%
+%\seealso{LaTeX_Typo_Active, LaTeX_Typo_Word_Size}
+%!%-
+static define typo_abbrev()
+{
+ if (LAST_CHAR != '.')
+ throw UsageError, "typo_abbrev called for anything else than .";
+
+ call("self_insert_cmd");
+
+ if ( is_active() )
+ {
+ push_spot();
+ EXIT_BLOCK
+ {
+ pop_spot();
+ }
+ () = left(1);
+
+ _get_point();
+ bskip_word_chars();
+ variable len = () - _get_point();
+ if (len == 0 or len >= LaTeX_Typo_Word_Size)
+ return;
+ bskip_white();
+
+ () = left(1);
+ !if ( looking_at_char('.') )
+ return;
+
+ push_spot();
+ EXIT_BLOCK
+ {
+ pop_spot();
+ pop_spot();
+ }
+
+ _get_point();
+ bskip_word_chars();
+ if ( () - _get_point() >= LaTeX_Typo_Word_Size )
+ return;
+
+ pop_spot();
+ () = right(1);
+ trim();
+ insert("\\,");
+ }
+}
+
+%!%+
+%\function{typo_german_decimal_point()}
+%\synopsis{Puts a comma between digits into \\mathord{}}
+%\usage{typo_german_decimal_point()}
+%\description
+% In german, the comma is the separator of the fractional part of
+% numbers. In LaTeX, the default meaning of , in math mode is as a list
+% separator. Due to this it's necessary to tell LaTeX that the , is the
+% decimal point.
+%
+% This functions checks, if the characters before the comma are digits
+% with a leading space and if the characters behind the comma are digits.
+% Then it replaces the comma by \\mathord{,}. In text mode, this functions
+% does nothing special.
+%
+%\notes
+% You can disable this function by setting the variable \var{LaTeX_Typo_Active}
+% to 0. This still inserts the , character as \sfun{self_insert_cmd} would do.
+%
+%\seealso{LaTeX_Typo_Active}
+%!%-
+static define typo_german_decimal_point()
+{
+ if (LAST_CHAR != ',')
+ throw UsageError, "typo_german_decimal_point called for anything else than ,";
+
+ call("self_insert_cmd");
+
+ !if (andelse {is_active()} {is_math()})
+ return;
+
+ push_spot();
+ EXIT_BLOCK
+ {
+ pop_spot();
+ }
+
+ () = left(1);
+ _get_point();
+ bskip_chars("0-9");
+ if ( andelse {() - _get_point() > 0}
+ {orelse {bolp()} {left(1) and is_substr(" \t$", char(what_char()))}} )
+ enable_before_next_char_hook(",", "\\mathord{,}", &isdigit());
+}
+
+private variable word_char_count;
+
+private define hyphen_hook(fun);
+private define hyphen_hook(fun)
+{
+ debug_msg(_function_name() + ": " + char(LAST_CHAR) + ", $fun"$);
+
+ EXIT_BLOCK
+ {
+ remove_from_hook("_jed_before_key_hooks", &hyphen_hook());
+ __uninitialize(&word_char_count);
+ }
+
+ variable replace_str, back = 1;
+
+ if (andelse {typeof(fun) == String_Type} {fun == "self_insert_cmd"}
+ {isalpha(LAST_CHAR)})
+ {
+ if ( __is_initialized(&word_char_count) )
+ % 8.
+ {
+ debug_msg("hyphen_hook: $word_char_count"$);
+ ++word_char_count;
+ if (word_char_count < LaTeX_Typo_Word_Size)
+ {
+ EXIT_BLOCK;
+ return;
+ }
+
+ back = word_char_count;
+ replace_str = "\"=";
+ }
+ else
+ % 7.
+ replace_str = "\"~";
+ }
+ else if (LAST_CHAR == ')')
+ % 6.
+ {
+ replace_str = "\"~";
+ enable_before_next_char_hook("", "\"\"", &isalpha());
+ }
+ else if (LAST_CHAR == '/')
+ % 5.
+ replace_str = "\"~";
+ else
+ return;
+
+ () = left(back);
+ () = replace_chars(1, replace_str);
+ () = right(back - 1);
+}
+
+%!%+
+%\function{typo_hyphen()}
+%\synopsis{Replace a hyphen by a special hyphen}
+%\usage{typo_hyphen()}
+%\description
+% A simple - is not everywhere what you want. Babel defines some special
+% hypens:
+%#v+
+% texdoc gerdoc section 2.2.4 or texdoc babel
+% "" an unvisible hyphen point
+% "~ an hyphen without an hyphen point
+% "= an hyphen that doesn't prevents hyphenation in the
+% rest of the word lik - does
+%#v-
+%
+% \sfun{typo_hyphen} makes the following replacements:
+%#v+
+% w = word character s = space ( \t)
+% W = at least LaTeX_Typo_Word_Size word chars
+%
+% rule | example
+% --------------------+-------------------
+% 1. $-w -> $"~w | $i$-mal, $\alpha$-Teilchen
+% 2. }-w -> }"~w | \LaTeX{}-Aufruf
+% 3. \w-w -> \w"~w | \LaTeX-Aufruf
+% 4. s-w -> s"~w | bergauf und -ab
+% 5. w-/ -> w"~/ | Ein-/Ausgabe
+% 6. w-) -> w"~) | (Haupt-)Aufgabe
+% 7. w-w -> w"~w | I-Punkt, HI-Virus
+% 8. W-W -> W"=W | primitiv-rekursiv
+% 9. /-w -> /"~w | Vorlesungsgliederung/-struktur
+% 10. /""-w -> /"""~w | Vorlesungsgliederung/-struktur
+%#v-
+%\notes
+% You can disable this function by setting the variable \var{LaTeX_Typo_Active}
+% to 0. This still inserts the - character as \sfun{self_insert_cmd} would do.
+%
+%\seealso{LaTeX_Typo_Active}
+%!%-
+static define typo_hyphen()
+{
+ if (LAST_CHAR != '-')
+ throw UsageError, "typo_hyphen called for anything else than -";
+
+ call("self_insert_cmd");
+
+ !if (andelse {is_active()} {pkg_loaded("babel")})
+ return;
+
+ push_spot();
+ EXIT_BLOCK
+ {
+ pop_spot();
+ }
+
+ if ( orelse {left(2) and is_substr("$}/ \t", char(what_char()) )}
+ {left(2) and looking_at("/\"\"")} )
+ % 1. + 2. + 4. + 9. + 10.
+ {
+ enable_before_next_char_hook("-", "\"~", &isalpha());
+ return;
+ }
+
+ () = right(3);
+ _get_point();
+ bskip_word_chars();
+ variable char_cnt = () - _get_point();
+
+ if (char_cnt == 0)
+ return;
+
+ if ( is_escaped() )
+ % 3.
+ enable_before_next_char_hook("-", "\"~", &isalpha());
+ else
+ % 5.--8.
+ {
+ if (char_cnt >= LaTeX_Typo_Word_Size)
+ % 8.
+ word_char_count = 0;
+
+ add_to_hook("_jed_before_key_hooks", &hyphen_hook());
+ }
+}
+
+static define typo_dots()
+{
+ if ( orelse {is_verbatim()} {not blooking_at("..")} )
+ {
+ typo_abbrev();
+ return;
+ }
+
+ () = left(2);
+ push_spot();
+
+ variable text;
+ !if ( is_math() )
+ {
+ push_mark();
+ bskip_chars(" ");
+ () = left(1);
+ !if ( looking_at_char(',') )
+ () = right(1);
+ text = bufsubstr();
+
+ pop_spot();
+ deln(2);
+ try
+ cmd_insert("dots", 0);
+ catch ApplicationError:
+ cmd_insert("ldots");
+
+ insert(text);
+ return;
+ }
+
+ bskip_chars(" ");
+ () = left(1);
+
+ variable ch = what_char();
+ switch (ch)
+ { case ',':
+ if ( pkg_loaded("amsmath") )
+ text = "\\dotsc,";
+ else
+ text = "\\ldots,";
+ }
+ { case '+' or case '-' or case '<' or case '>' or case '=':
+ if ( pkg_loaded("amsmath") )
+ text = "\\dotsb" + char(what_char());
+ else
+ text = "\\cdots" + char( what_char() );
+ }
+ { case '}':
+ if ( pkg_loaded("amsmath") )
+ text = "\\dotso";
+ else
+ text = "\\ldots";
+ }
+ {
+ variable cmd = is_command();
+
+ switch(cmd)
+ { case "\\leq" or case "\\geq" or case "\\pm" or case "\\mp" or
+ case "\\cup" or case "\\cap" or case "\\vee" or case "\\wedge":
+ if ( pkg_loaded("amsmath") )
+ text = "\\dotsb" + cmd;
+ else
+ text = "\\cdots" + cmd;
+ }
+ { case "\\int" or case "\\sum" or case "\\prod":
+ if ( pkg_loaded("amsmath") )
+ text = "\\dotsi";
+ else
+ text = "\\cdots";
+
+ pop_spot();
+ () = replace_chars(2, text+cmd);
+ return;
+ }
+ {
+ if ( pkg_loaded("amsmath") )
+ text = "\\dotso ";
+ else
+ text = "\\ldots ";
+
+ pop_spot();
+ () = replace_chars(2, text);
+ return;
+ }
+ }
+ bskip_chars(" ");
+ () = left(1);
+
+ variable looping = 0;
+ while ( looking_at_char('}') )
+ {
+ variable mark = create_user_mark();
+ if (find_matching_delimiter('}') != 1)
+ {
+ goto_user_mark(mark);
+ break;
+ }
+ () = left(1);
+ switch ( what_char() )
+ { case '_' or case '^':
+ if (looping == 0)
+ {
+ () = right(2);
+ push_mark();
+ () = left(3);
+ }
+ else
+ () = left(1);
+
+ ++looping;
+ }
+ {
+ goto_user_mark(mark);
+ break;
+ }
+ }
+
+ if (looping == 0)
+ {
+ pop_spot();
+ () = replace_chars(2, text);
+ return;
+ }
+
+ if ( re_looking_at("[0-9]") )
+ bskip_chars("0-9");
+ else
+ {
+ variable found_brakets = 0;
+ if ( andelse {looking_at_char('}')} {find_matching_delimiter('}') == 1} )
+ {
+ found_brakets = 1;
+ () = left(1);
+ }
+
+ cmd = is_command();
+ switch (cmd)
+ { case "\\int" or case "\\sum" or case "\\prod":
+ if ( pkg_loaded("amsmath") )
+ text = "\\dotsi";
+ else
+ text = "\\cdots";
+
+ pop_mark(0);
+ pop_spot();
+ () = replace_chars(2, text+cmd);
+ return;
+ }
+ { case NULL:
+ if (found_brakets)
+ () = right(1);
+ else
+ {
+ if ( re_looking_at("[A-Za-z]") )
+ bskip_chars("A-Za-z");
+ text += " ";
+ }
+ }
+ }
+ text += bufsubstr();
+
+ pop_spot();
+ () = replace_chars(2, text+"}");
+ () = left(1);
+}
diff --git a/support/jed/jlm/read_with_description.sl b/support/jed/jlm/read_with_description.sl
new file mode 100644
index 0000000000..b2c740a554
--- /dev/null
+++ b/support/jed/jlm/read_with_description.sl
@@ -0,0 +1,244 @@
+% File: read_with_description.sl -*- mode: SLang -*-
+%
+% Copyright (c)
+% 2006 Jörg Sommer <joerg@alea.gnuu.de>
+% $Id: read_with_description.sl 160 2007-06-28 11:11:34Z joerg $
+%
+% Description: This is an extention of the read_with_completion() function
+% to print a description beside the proposal in the completion
+% buffer to give the user an idea of what he selects.
+%
+% License: 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 2 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.
+
+#ifnexists profile_on
+% profiling does not work with stack check enabled.
+autoload("enable_stack_check", "stkcheck");
+try
+{
+ enable_stack_check();
+}
+catch OpenError: {} % stkcheck not found in the path
+#endif
+
+%!%+
+%\variable{Integer_Type RWD_Match}
+%\synopsis{Defines what and how read_with_description() makes a match}
+%\description
+% This variable defines how a completion should get found for
+% read_with_description().
+% 0 means the matching is case insensitiv and only with the text
+% 1 means the matching is case sensitiv and only with the text
+% 2 means the matching is case insensitiv and with the text and the
+% description
+% 3 means the matching is case sensitiv and with the text and the
+% description
+%
+% The default is 1.
+%\seealso{read_with_completion()}
+%!%-
+custom_variable("RWD_Match", 1);
+
+private variable completion_list, max_compl_width;
+
+private define rwd_complete()
+{
+ variable old_buf = whatbuf();
+
+ variable line = line_as_string(), buffer_new = not bufferp("*Completions*");
+ setbuf("*Completions*");
+
+ if (buffer_new)
+ {
+ if (max_compl_width > SCREEN_WIDTH/2)
+ max_compl_width = SCREEN_WIDTH/2;
+
+ insert("!!! Use Page Up/Down keys to scroll this window. !!!\n");
+ foreach (completion_list)
+ {
+ variable item = ();
+ !if ( strlen(item.compl) )
+ continue;
+
+ insert(item.compl);
+ whitespace(1 + max_compl_width - strlen(item.compl));
+ insert("--");
+ if ( strlen(item.desc) )
+ {
+ insert_char(' ');
+ insert(item.desc);
+ }
+ newline();
+ }
+ set_buffer_modified_flag(0);
+ CASE_SEARCH = RWD_Match & 1;
+ set_status_line(" Completion buffer ", 0);
+
+ __uninitialize(&completion_list);
+ }
+
+ variable possible_completions;
+ if (LAST_KBD_COMMAND == "%rwd_complete%")
+ {
+ pop2buf("*Completions*");
+ if ( eobp() )
+ {
+ bob();
+ () = down(1);
+ }
+
+ if ( is_line_hidden() )
+ skip_hidden_lines_forward(1);
+
+ % if not all lines are hidden, we have a completion
+ possible_completions = not eobp();
+ }
+ else
+ {
+ bob();
+ possible_completions = 0;
+ variable search_fun;
+ if ( (RWD_Match & 2) != 0 )
+ search_fun = &ffind();
+ else
+ search_fun = &looking_at();
+
+ while ( down(1) )
+ {
+ if ( orelse {strlen(line) == 0} {@search_fun(line)} )
+ {
+ set_line_hidden(0);
+ ++possible_completions;
+ }
+ else
+ set_line_hidden(1);
+ }
+ bob();
+ () = down(1);
+
+ if (possible_completions == 1 and is_line_hidden() )
+ skip_hidden_lines_forward(1);
+ }
+
+ variable completion;
+ if (possible_completions == 1)
+ {
+ bol();
+ push_mark();
+ skip_chars("^ \t");
+ completion = bufsubstr();
+ skip_hidden_lines_forward(1);
+ }
+
+ pop2buf(old_buf);
+ setbuf(old_buf);
+
+ switch (possible_completions)
+ { case 0: % no completion error
+ flush("No possible completion!");
+ }
+ { case 1: % excactly on completion
+ if (whatbuf() != old_buf)
+ {
+ % Fixme: find the real reason
+ % this is a hack to see in the *traceback* buffer the buffer name
+ variable buf = whatbuf();
+ throw InternalError;
+ }
+ delete_line();
+ insert(completion);
+ }
+
+ set_current_kbd_command("%rwd_complete%");
+}
+
+%!%+
+%\function{read_with_description}
+%\synopsis{Prompt the user for a string and give him a description of the completion}
+%\usage{String_Type read_with_description(prompt, dflt, init, list)}
+%\description
+% This is an extention of the read_with_completion() function to print a
+% description beside the proposal in the completion buffer to give the user an
+% idea of what he selects.
+%
+% The argument prompt is the prompt for the user, dflt is returned if the user
+% simply hits return, init is th value to use as initialisation of the answer
+% and list is an List_Type of Struct_Type with two componentes "compl" for the
+% completions and "desc" for the description of the completion. The values are
+% presented in the order they are in the list, e. g. you can determine the
+% sorting order.
+%\seealso{read_with_completion()}
+%!%-
+public define read_with_description(prompt, dflt, init, list)
+{
+ max_compl_width = 0;
+ foreach (list)
+ {
+ variable item = (), compl = item.compl, desc = item.desc;
+ if ( strlen(compl) != strlen(str_delete_chars(compl, " \t\n\r")) )
+ throw InvalidParmError, "The completion \"" + compl +
+ "\" contains a whitespace";
+
+ if (strlen(compl) > max_compl_width)
+ max_compl_width = strlen(compl);
+
+ if ( strlen(desc) != strlen(str_delete_chars(desc, "\r\n")) )
+ throw InvalidParmError, "The description \"" + desc +
+ "\" of completion \"" + compl + "\" contains a linebreak";
+ }
+ completion_list = list;
+
+ if ( bufferp("*Completions*") )
+ {
+ variable orig_buf = whatbuf();
+
+ setbuf("*Completions*");
+ set_buffer_modified_flag(0);
+ % jump back that delbuf() does not delete the current buffer and
+ % jump to an arbitrary buffer
+ setbuf(orig_buf);
+
+ delbuf("*Completions*");
+ }
+
+ % mangle the keymap of the mini buffer
+ definekey(&rwd_complete, "\t", "Mini_Map");
+ definekey(&rwd_complete, " ", "Mini_Map");
+
+ % mangle the color of hidden line indicator
+ variable old_fg, old_bg;
+ (old_fg, old_bg) = get_color("...");
+ set_color("...", old_bg, old_bg);
+
+ try
+ return read_with_completion("", prompt, dflt, init, 's');
+ finally
+ {
+ definekey("mini_complete", "\t", "Mini_Map");
+ definekey("mini_complete", " ", "Mini_Map");
+ set_color("...", old_fg, old_bg);
+
+ if ( bufferp("*Completions*") )
+ {
+ variable old_buf = whatbuf();
+
+ if ( buffer_visible("*Completions*") )
+ {
+ pop2buf("*Completions*");
+ call("delete_window");
+ pop2buf(old_buf);
+ }
+
+ delbuf("*Completions*");
+ }
+ }
+}
+
+provide("read_with_description");
diff --git a/support/jed/jlm/test/test_latex_pst.sl b/support/jed/jlm/test/test_latex_pst.sl
new file mode 100644
index 0000000000..85a2578af3
--- /dev/null
+++ b/support/jed/jlm/test/test_latex_pst.sl
@@ -0,0 +1,198 @@
+%%%%%%%%%%
+%
+% Tools
+%
+variable tmp_file = make_tmp_file("");
+
+define exit_hook()
+{
+ set_buffer_modified_flag(0);
+ () = remove(tmp_file);
+ return 1;
+}
+
+define buffer_as_string()
+{
+ push_spot();
+ bob();
+ push_mark();
+ eob();
+ bufsubstr();
+ pop_spot();
+ return ();
+}
+
+define print_buffer()
+{
+ message( buffer_as_string );
+}
+
+define expect_buffer_content(id, str)
+{
+ variable b = buffer_as_string();
+ if (b == str)
+ message("Test $id succeeded"$);
+ else
+ {
+ message("Test $id failed"$);
+ message(__tmp(b));
+ }
+}
+
+%%%%%%%%%%
+%
+% Setup the file
+%
+() = find_file(tmp_file);
+latex_mode();
+() = evalfile("latex_pst", "latex");
+variable test_id;
+
+%%%%%%%%%%
+%
+% Test pst_point_min and pst_point_max
+%
+define test_mm(id, x1, y1, x2, y2, min_x, min_y, max_x, max_y)
+{
+ variable stk_depth = _stkdepth();
+ variable pnt1 = @Pst_Point_Type, pnt2 = @Pst_Point_Type;
+ pnt1.x = x1;
+ pnt1.y = y1;
+ pnt2.x = x2;
+ pnt2.y = y2;
+
+ variable pnt = latex->pst_point_min(pnt1, pnt2);
+ if (pnt.x == min_x and pnt.y == min_y)
+ message("Test mm$id-min succeeded"$);
+ else
+ message("Test mm$id-min failed: "$ + string(pnt.x) + "," + string(pnt.y));
+ stk_depth -= _stkdepth();
+ if (stk_depth != 0)
+ message("Test mm$id-min left $stk_depth values on stack"$);
+
+ stk_depth = _stkdepth();
+ pnt = latex->pst_point_max(pnt1, pnt2);
+ if (pnt.x == max_x and pnt.y == max_y)
+ message("Test mm$id-max succeeded"$);
+ else
+ message("Test mm$id-max failed: "$ + string(pnt.x) + "," + string(pnt.y));
+ stk_depth -= _stkdepth();
+ if (stk_depth != 0)
+ message("Test mm$id-max left $stk_depth values on stack"$);
+}
+
+test_id = 0;
+++test_id; test_mm(test_id, 1, 1, 1, 1, 1, 1, 1, 1);
+++test_id; test_mm(test_id, 1, 0, 0, 1, 0, 0, 1, 1);
+++test_id; test_mm(test_id, 0, 0, 0, 1, 0, 0, 0, 1);
+++test_id; test_mm(test_id, -10, 0, -20, 1, -20, 0, -10, 1);
+++test_id; test_mm(test_id, 10, 10, -20, -1, -20, -1, 10, 10);
+++test_id; test_mm(test_id, -1, -1, 5, -2, -1, -2, 5, -1);
+
+%%%%%%%%%%
+%
+% Test pst_enlarge_pic
+%
+define test_ep(id, pre, x, y, post)
+{
+ variable stk_depth = _stkdepth();
+ erase_buffer();
+ insert("\\begin{pspicture}$pre\n\n\\end{pspicture}\n"$);
+
+ goto_line(2);
+ variable pnt = @Pst_Point_Type;
+ pnt.x = x;
+ pnt.y = y;
+ latex->pst_enlarge_pic(pnt);
+
+ expect_buffer_content("ep$id"$,
+ "\\begin{pspicture}$post\n\n\\end{pspicture}\n"$);
+ stk_depth -= _stkdepth();
+ if (stk_depth != 0)
+ message("Test ep$id left $stk_depth values on stack"$);
+}
+
+test_id = 0;
+++test_id; test_ep(test_id, "", 5, 5, "(5,5)");
+++test_id; test_ep(test_id, "", -5, 5, "(-5,0)(0,5)");
+++test_id; test_ep(test_id, "", -8.8, -2, "(-8.8,-2)(0,0)");
+++test_id; test_ep(test_id, "", 3, -7, "(0,-7)(3,0)");
+
+++test_id; test_ep(test_id, "(10,10)", 3, 7, "(10,10)");
+++test_id; test_ep(test_id, "(10,10)", -1, -2, "(-1,-2)(10,10)");
+++test_id; test_ep(test_id, "(-1,-1)(10,10)", 5, -2, "(-1,-2)(10,10)");
+++test_id; test_ep(test_id, "", 0, 0, "");
+
+%%%%%%%%%%
+%
+% Test pst_update_pic_size
+%
+define test_ups(id, inner, exp)
+{
+ variable stk_depth = _stkdepth();
+ erase_buffer();
+ insert("\\begin{pspicture}\n$inner\n\\end{pspicture}\n"$);
+
+ goto_line(2);
+ latex->pst_update_pic_size();
+ expect_buffer_content("ups$id"$,
+ "\\begin{pspicture}$exp\n$inner\n\\end{pspicture}\n"$);
+ stk_depth -= _stkdepth();
+ if (stk_depth != 0)
+ message("Test ups$id left $stk_depth values on stack"$);
+}
+
+test_id = 0;
+++test_id; test_ups(test_id, "\\psframe(-0.3,-0.2)(5.1,2.2)", "(-0.3,-0.2)(5.1,2.2)");
+++test_id; test_ups(test_id, "\\psframe(3.3,0.2)(5.1,2.2)", "(5.1,2.2)");
+++test_id; test_ups(test_id, "\\psframe(3.3,0.2)(5.1,2.2)\n\\rput[t](6,1)", "(6,2.2)");
+++test_id; test_ups(test_id, "", "");
+
+%%%%%%%%%%
+%
+% Test pst_update_pic_size
+%
+define test_mp(id, inner, input, exp)
+{
+ variable stk_depth = _stkdepth();
+ erase_buffer();
+ insert("\\begin{pspicture}$inner\n\\end{pspicture}\n"$);
+
+ bob(); () = right(17);
+ push_mark();
+ eob(); () = up(1); bol();
+ buffer_keystring(input + "\n");
+ latex->pst_move_points();
+ expect_buffer_content("mp$id"$,
+ "\\begin{pspicture}$exp\n\\end{pspicture}\n"$);
+ stk_depth -= _stkdepth();
+ if (stk_depth != 0)
+ message("Test mp$id left $stk_depth values on stack"$);
+}
+
+test_id = 0;
+++test_id;
+test_mp(test_id,
+ "(4,4)\n\\psframe(1,1)(2,2)\n\\psdots(0.5,3)\n\\psline(0,0)(3,2)",
+ "2",
+ "(5,5)\n\\psframe(3,3)(4,4)\n\\psdots(2.5,5)\n\\psline(2,2)(5,4)");
+++test_id;
+test_mp(test_id,
+ "(4,4)\n\\psframe(1,1)(2,2)\n\\psdots(0.5,3)\n\\psline(0,0)(3,2)",
+ "(-1,2)",
+ "(-1,0)(4,5)\n\\psframe(0,3)(1,4)\n\\psdots(-0.5,5)\n\\psline(-1,2)(2,4)");
+++test_id;
+test_mp(test_id,
+ "(4,4)\n\\psframe(1,1)(2,2)\n\\psdots(0.5,3)\n\\psline(0,0)(3,2)",
+ "0",
+ "(4,4)\n\\psframe(1,1)(2,2)\n\\psdots(0.5,3)\n\\psline(0,0)(3,2)");
+++test_id;
+test_mp(test_id,
+ "(4,4)\n\\psframe(1,1)(2,2)\n\\psdots(0.5,3)\n\\psline(0,0)(3,2)",
+ "(0,0)",
+ "(4,4)\n\\psframe(1,1)(2,2)\n\\psdots(0.5,3)\n\\psline(0,0)(3,2)");
+++test_id;
+test_mp(test_id,
+ "(4,4)\n\\psframe(1,1)(2,2)\n\\psdots(0.5,3)\n\\psline(.7,-.3)(3,2)",
+ "-3.14",
+ "(-2.64,-3.44)(4,4)\n\\psframe(-2.14,-2.14)(-1.14,-1.14)\n\\psdots(-2.64,-0.14)\n\\psline(-2.44,-3.44)(-0.14,-1.14)");
diff --git a/support/jed/latex4jed/COPYING b/support/jed/latex4jed/COPYING
new file mode 100644
index 0000000000..e77696ae8d
--- /dev/null
+++ b/support/jed/latex4jed/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, 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 show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program 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.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public 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.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/support/jed/latex4jed/README b/support/jed/latex4jed/README
new file mode 100644
index 0000000000..4b87ced4da
--- /dev/null
+++ b/support/jed/latex4jed/README
@@ -0,0 +1,10 @@
+------------------------
+latex4jed 1.4.4 README
+------------------------
+
+This S-Lang file for the Jed editor provides a much enhanced LaTeX mode a
+la AUC-TeX: menus, syntax highlighting, shortcuts, templates, plugins,
+document outline, integrated debugging, symbol completion, full
+integration with external programs, and more. It was designed with both
+the beginner and the advanced LaTeX user in mind.
+
diff --git a/support/jed/latex4jed/TODO b/support/jed/latex4jed/TODO
new file mode 100644
index 0000000000..8a6dc63b69
--- /dev/null
+++ b/support/jed/latex4jed/TODO
@@ -0,0 +1,3 @@
+
+Any suggestions?
+
diff --git a/support/jed/latex4jed/elegant.sl b/support/jed/latex4jed/elegant.sl
new file mode 100644
index 0000000000..6659d6e2f7
--- /dev/null
+++ b/support/jed/latex4jed/elegant.sl
@@ -0,0 +1,39 @@
+% elegant.sl
+% By Guido Gonzato, guido dot gonzato at univr dot it
+
+$1 = "black";
+$3 = "white";
+$2 = "#D8D8D8"; % light gray
+$4 = "#606060"; % medium gray
+$5 = "#B4FFB4"; % pale green
+$6 = "#1010A0"; % dark blue
+$7 = "#B40A78"; % dark purple
+$8 = "brightred";
+
+set_color ("normal", $1, $2); % default fg/bg
+set_color ("status", $1, $3); % status line
+set_color ("operator", $1, $2); % +, -, etc...
+set_color ("number", $6, $2); % 10, 2.71, etc..
+set_color ("comment", $1, $5); % /* comment */
+set_color ("region", $3, $4); % region
+set_color ("string", $6, $3); % "string" or 'char'
+set_color ("keyword", $6, $2); % if, while, unsigned, ...
+set_color ("keyword1", "blue", $2); % malloc, exit, etc...
+set_color ("keyword2", "#007000", $2); % other keywords
+set_color ("delimiter", $8, $2); % {}[](),.;...
+set_color ("preprocess", "magenta", $2); % #ifdef etc...
+set_color ("message", $6, $2);
+set_color ("error", $8, $2);
+set_color ("dollar", $8, $2);
+set_color ("...", $8, $2); % folding indicator
+
+set_color ("menu_char", $8, $3);
+set_color ("menu", $1, "white");
+set_color ("menu_popup", $1, $3);
+set_color ("menu_shadow", $1, $4);
+set_color ("menu_selection", $1, "cyan");
+set_color ("menu_selection_char", $8, $3);
+
+set_color ("mouse", "blue", "blue");
+set_color ("cursor", $1, $8);
+set_color ("cursorovr", $1, $8);
diff --git a/support/jed/latex4jed/latex.hlp b/support/jed/latex4jed/latex.hlp
new file mode 100644
index 0000000000..8470f9acc0
--- /dev/null
+++ b/support/jed/latex4jed/latex.hlp
@@ -0,0 +1,54 @@
+LaTeX4Jed 1.4.4 Help
+====================
+
+Keybindings start in Ctrl-C in Emacs mode, Ctrl-Z in IDE mode.
+
+Almost all commands are available from the 'Mode' menu. Most are
+region-or-word aware. Additional keybindings include:
+
+Keybinding Action
+------------------------------------------
+
+Ctrl-C <Left> go to previous paragraph
+Ctrl-C <Right> go to next paragraph
+Ctrl-C& \&
+Ctrl-C$ \$
+Ctrl-C# \#
+Ctrl-C% \%
+Ctrl-C( \{
+Ctrl-C) \}
+Ctrl-C_ \_
+Ctrl-C< \textless{}
+Ctrl-C> \textgreater{}
+Ctrl-C^ \textasciicircum{}
+Ctrl-C~ \textasciitilde{}
+Ctrl-C\ \textbackslash{}
+Ctrl-C| \textbar{}
+Ctrl-C{ {}, region or word aware
+' or " smart quotes
+Ctrl-C' or Ctrl-C" smart quotes, region or word aware
+... {\ldots}
+<- {\leftarrow}
+<= {\Leftarrow}
+< -- {\longleftarrow}
+< == {\Longleftarrow}
+< -> {\leftrightarrow}
+< => {\Leftrightarrow}
+-> {\rightarrow}
+=> {\Rightarrow}
+--> {\longrightarrow}
+==> {\Longrightarrow}
+|-> {\mapsto}
+|--> {\longmapsto}
+Ctrl-Ce insert environment, with completion
+Ctrl-Cf insert font, with completion
+Ctrl-Ch info help on word
+Alt-TAB or Alt-V symbol completion
+TAB indent line
+ESC 1 TAB unindent line
+Ctrl-C[ start environment
+Ctrl-C] close environment
+ESC 1 <cmd> command, long form
+Ctrl-C <RET> new \item line
+F8 preview document
+F9 run (pdf)latex
diff --git a/support/jed/latex4jed/latex.sl b/support/jed/latex4jed/latex.sl
new file mode 100644
index 0000000000..16c2453d44
--- /dev/null
+++ b/support/jed/latex4jed/latex.sl
@@ -0,0 +1,2927 @@
+% File: latex.sl -*- mode: SLang; mode: fold -*-
+%
+% Author: Guido Gonzato, guido.gonzato@univr.it
+% Contributions by G\"unter Milde,
+% Milde@ife.et.tu-dresden.de;
+% J\"org Sommer, joerg@alea.gnuu.de
+%
+% Description: an enhanced latex mode that aims at making the writing
+% of LaTeX documents a breeze.
+%
+% Installation: copy latex.sl to $JED_ROOT/lib (back up the original file
+% latex.sl beforehand), then add these lines to your .jedrc:
+%
+% add_mode_for_extension ("latex", "tex");
+% enable_dfa_syntax_for_mode ("LaTeX");
+%
+% You'll also want to create the DFA cache table. Add
+% "latex.sl" to the list in the file preparse.sl, then
+% (as root) run the command:
+%
+% jed -batch -n -l preparse
+%
+% CAVEAT: this file is incompatible with folding mode,
+% due to clashing ^Cf key binding. See the documentation
+% for details.
+%
+% Version: 1.4.4
+%
+% Last updated: 20 February 2004
+
+% -----
+
+require ("keydefs");
+
+% custom variables
+
+% output profile: "dvi", "ps", "eps", "dvipdf", "pdf"
+custom_variable ("LaTeX_Default_Output", "dvi");
+custom_variable ("LaTeX_Indent", 2);
+custom_variable ("LaTeX_Article_Default_Options", "a4paper,12pt");
+custom_variable ("LaTeX_Book_Default_Options", "twoside,11pt");
+custom_variable ("LaTeX_Letter_Default_Options", "a4paper,12pt");
+custom_variable ("LaTeX_Report_Default_Options", "twoside,12pt");
+custom_variable ("LaTeX_Slides_Default_Options", "a4paper,landscape");
+custom_variable ("LaTeX_Default_Language", "english,italian"); % for Babel
+custom_variable ("LaTeX_Rerun", "y"); % for xrefs
+custom_variable ("LaTeX_Load_Modules", "y");
+% DOS/Windows users: make sure helper programs are in the PATH
+#ifdef WIN32
+custom_variable ("LaTeX_View_Dvi_Cmd", "yap");
+custom_variable ("LaTeX_View_Ps_Cmd", "gsview32");
+custom_variable ("LaTeX_View_Pdf_Cmd", "gsview32");
+custom_variable ("LaTeX_Print_Cmd", "gsview32");
+custom_variable ("LaTeX_Clearup_Cmd",
+ "del *.out *.aux *.lo? *.to?");
+custom_variable ("LaTeX_Modules_Dir", JED_ROOT + "\\lib\\latex\\");
+#else
+custom_variable ("LaTeX_View_Dvi_Cmd", "xdvi");
+custom_variable ("LaTeX_View_Ps_Cmd", "gv -watch");
+custom_variable ("LaTeX_View_Pdf_Cmd", "xpdf -z width");
+custom_variable ("LaTeX_Print_Cmd", "lpr");
+custom_variable ("LaTeX_Clearup_Cmd",
+ "/bin/rm -f *.out *.aux *.lo? *.to?");
+custom_variable ("LaTeX_Modules_Dir", JED_ROOT + "/lib/latex/");
+#endif
+variable custom_variables =
+ "LaTeX_Indent,LaTeX_Article_Default_Options," +
+ "LaTeX_Book_Default_Options,LaTeX_Letter_Default_Options," +
+ "LaTeX_Report_Default_Options,LaTeX_Slides_Default_Options," +
+ "LaTeX_Default_Language,LaTeX_Rerun,LaTeX_View_Dvi_Cmd," +
+ "LaTeX_View_Ps_Cmd,LaTeX_View_Pdf_Cmd,LaTeX_Print_Cmd";
+
+static variable TRUE = 1;
+static variable FALSE = 0;
+static variable NOTFOUND = 0;
+static variable ERROR = 255;
+static variable WARNING = -1;
+static variable RERUN = -2;
+static variable NO_PUSH_SPOT = FALSE;
+static variable PUSH_SPOT = TRUE;
+static variable NO_POP_SPOT = FALSE;
+static variable POP_SPOT = TRUE;
+static variable ITEM_LABEL = FALSE;
+static variable USE_MASTER = FALSE;
+#ifdef UNIX
+static variable devnull = " >/dev/null 2>&1 &";
+#else
+static variable devnull = " >NUL";
+#endif
+static variable LaTeX_Compose_Cmd = "latex" +
+ " -interaction=nonstopmode";
+static variable LaTeX_Compose_Pdf_Cmd = "pdflatex" +
+ " -interaction=nonstopmode";
+static variable LaTeX_Dvips_Cmd = "dvips";
+static variable LaTeX_Eps_Options = " -i -E"; % every page a file, eps output
+static variable LaTeX_Dvipdf_Cmd = "dvipdf";
+static variable LaTeX_Bibtex_Cmd = "bibtex";
+static variable LaTeX_Makeindex_Cmd = "makeindex";
+static variable LaTeX_Buffer;
+static variable Math_Mode = FALSE;
+
+% -----
+
+% this function is sto^H^H^H borrowed from the original latex.sl
+
+define tex_complete_symbol ()
+{
+ variable symbol, completion;
+ variable insertbuf = whatbuf(), searchbuf = "*ltx-comp*";
+
+ !if (bufferp(searchbuf)) {
+ sw2buf(searchbuf);
+ insert_file( expand_jedlib_file("ltx-comp.dat") ); bob();
+ set_buffer_modified_flag(0);
+ sw2buf(insertbuf);
+ bury_buffer(searchbuf);
+ }
+
+ push_spot();
+ push_mark();
+ bskip_word();
+ symbol = bufsubstr();
+ setbuf(searchbuf);
+
+ !if (bol_fsearch(sprintf("\\%s", symbol))) bob(); % wrap to start
+
+ if (bol_fsearch(sprintf("\\%s", symbol))) {
+ go_right_1 ();
+ go_right(strlen(symbol));
+ push_mark_eol();
+ completion = bufsubstr();
+ }
+
+ else {
+ setbuf(insertbuf);
+ pop_mark_0 ();
+ pop_spot();
+ error("No completion found");
+ }
+
+ setbuf(insertbuf);
+ goto_spot ();
+ push_mark();
+ !if (ffind_char (' ')) eol();
+ del_region();
+ insert(completion);
+ pop_spot();
+}
+
+% -----
+
+% this is copied from my context-sensitive help system.
+% Maybe some day it'll be included in the Jed distribution;
+% in that case, I'll remove this duplicated function.
+
+define latex_info_help ()
+{
+ variable str, topic;
+ % get the word under the cursor
+ push_spot ();
+ define_word ("_0-9A-Za-z\\");
+ skip_word ();
+ push_mark ();
+ bskip_word ();
+ topic = bufsubstr ();
+ pop_mark_0 ();
+ pop_spot ();
+ info_mode ();
+ info_find_node ("(latex)");
+ info_find_node ("Command Index");
+ !if (fsearch ("* " + topic))
+ error (sprintf ("%s not found!", topic));
+ skip_word ();
+ () = right (1);
+ skip_word ();
+ bskip_word (); % beginning of node name
+ push_spot ();
+ push_mark ();
+ eol ();
+ () = left (1);
+ str = bufsubstr ();
+ pop_mark_0 ();
+ pop_spot ();
+ info_find_node (str);
+ () = fsearch (topic);
+}
+
+% code to manage compressed files; from compress.sl
+
+static variable
+ Compressed_File_Exts = [".gz", ".Z", ".bz2"],
+ Compress_File_Pgms = ["gzip %s", "compress %s", "bzip2 %s"],
+ Uncompress_File_Pgms = ["gzip -d %s", "uncompress %s", "bzip2 -d %s"],
+ compressed = FALSE,
+ cmp_method,
+ tmpfile;
+
+static define check_is_compressed (file)
+{
+ variable ext = path_extname (file);
+ variable i = where (ext == Compressed_File_Exts);
+
+ if (length (i)) {
+ compressed = TRUE;
+ return i[0];
+ }
+ compressed = FALSE;
+ return -1;
+}
+
+% required stuff and variables
+
+require ("texcom");
+% autoload ("latex_toggle_math_mode", "ltx-math");
+autoload ("latex_insert_math", "ltx-math");
+autoload ("latex_math_mode", "ltx-math");
+
+WRAP_INDENTS = 1; % you really want this
+
+% very simple (but effective!) parsing mechanism of the LaTeX log
+
+static define getline ();
+
+static variable
+ LaTeX_Compile_Buffer = "*LaTeX log*",
+ LaTeX_Dvips_Buffer = "*dvips log*",
+ LaTeX_Bibtex_Buffer = "*bibtex log*",
+ LaTeX_Makeindex_Buffer = "*makeindex log*",
+ LaTeX_Xdvi_Buffer = "*xdvi log*",
+ LaTeX_Xpdf_Buffer = "*xpdf log*",
+ LaTeX_Gv_Buffer = "*gv log*",
+ LaTeX_Tree_Buffer = "*LaTeX Tree*",
+ latex_file,
+ latex_file_dir,
+ line_mark,
+ errors_parsed = FALSE;
+
+define goto_error_line ()
+{
+ variable line, tmp = get_word_chars ();
+ bol ();
+ define_word ("0-9");
+ skip_word ();
+ push_mark ();
+ bskip_word ();
+ line = integer (bufsubstr ());
+ sw2buf (LaTeX_Buffer);
+ call ("one_window");
+ goto_line (line);
+ define_word (tmp);
+}
+
+define find_next_error ()
+{
+ variable str, found;
+
+ if (FALSE == errors_parsed)
+ return;
+ pop2buf (LaTeX_Compile_Buffer);
+ found = fsearch ("! ");
+ % TODO: skip warnings
+ % some LaTeX error messages don't start in "! "
+ if (NOTFOUND == found)
+ found = fsearch ("l.");
+ () = right (2);
+ (str,) = getline ();
+ beep ();
+ flush (str);
+ if (NOTFOUND != found) {
+ eol (); % move over
+ % fix "file not found"
+ found = fsearch ("not found on input");
+ }
+ goto_error_line ();
+}
+
+define latex_parse_errors ()
+{
+ if (TRUE == compressed) {
+ variable cmd;
+ (,latex_file_dir,,) = getbuf_info ();
+ cmd = sprintf (Compress_File_Pgms [cmp_method],
+ dircat (latex_file_dir, tmpfile));
+ run_shell_cmd (cmd);
+ }
+ pop2buf (LaTeX_Compile_Buffer);
+ set_readonly (1);
+ bob ();
+ errors_parsed = TRUE;
+ find_next_error ();
+}
+
+% -----
+
+define latex_compile_and_parse (cmd)
+{
+ variable key, exitcode = TRUE, exit_status;
+ LaTeX_Buffer = whatbuf ();
+ sw2buf (LaTeX_Compile_Buffer);
+ set_readonly (0);
+ erase_buffer ();
+ exit_status = run_shell_cmd (cmd);
+
+ if (FALSE == exit_status) {
+ % handle warnings
+ bob ();
+ if (0 != fsearch ("Font Warning")) {
+ flush ("Font Warning.");
+ beep ();
+ usleep (1000);
+ exitcode = WARNING;
+ }
+ if (0 != fsearch ("Overfull")) {
+ flush ("Warning - Overfulls.");
+ beep ();
+ usleep (1000);
+ exitcode = WARNING;
+ }
+ if (0 != fsearch ("Underfull")) {
+ flush ("Warning - Underfulls.");
+ beep ();
+ usleep (1000);
+ exitcode = WARNING;
+ }
+ % else
+ if (0 != fsearch ("Rerun to get")) {
+ flush ("Rerun to get cross-references right.");
+ beep ();
+ usleep (1000);
+ exitcode = RERUN;
+ }
+ % else
+ % after "Rerun to get" = no hope
+ if (0 != fsearch ("There were undefined")) {
+ flush ("There were undefined references.");
+ beep ();
+ exitcode = WARNING;
+ }
+ % else
+ if ( (WARNING != exitcode) and (RERUN != exitcode)) {
+ flush ("Success!");
+ exitcode = TRUE;
+ }
+ sw2buf (LaTeX_Buffer);
+ return exitcode;
+ }
+ else { % latex returned != 0, errors or warnings found
+ latex_parse_errors ();
+ return ERROR;
+ }
+} % latex_compile_and_parse ()
+
+% -----
+
+% composing
+
+public define latex_select_output ()
+{
+ variable default = LaTeX_Default_Output;
+ LaTeX_Default_Output =
+ read_with_completion ("dvi,ps,eps,pdf,dvipdf",
+ "LaTeX output: dvi,ps,eps,pdf,dvipdf",
+ default, "", 's');
+ if (andelse
+ {strcmp (LaTeX_Default_Output, "dvi")}
+ {strcmp (LaTeX_Default_Output, "ps")}
+ {strcmp (LaTeX_Default_Output, "eps")}
+ {strcmp (LaTeX_Default_Output, "pdf")}
+ {strcmp (LaTeX_Default_Output, "dvipdf")})
+ {
+ beep ();
+ flush ("Unknown output format - defaulting to 'dvi'.");
+ LaTeX_Default_Output = "dvi";
+ }
+}
+
+% -----
+
+public define latex_clearup ()
+{
+ variable bat;
+#ifdef UNIX
+ run_shell_cmd ("cd " + latex_file_dir + "; " + LaTeX_Clearup_Cmd);
+#elifdef WIN32
+ delete_file (bat);
+ write_string_to_file ("cd " + latex_file_dir + "\n", bat);
+ append_string_to_file (LaTeX_Clearup_Cmd + "\n", bat);
+ run_shell_cmd (bat);
+#endif
+ flush ("Temporary files deleted.");
+}
+
+public define latex_compose ()
+{
+ variable tmp, bat, dvi, cmd, cmd2, status;
+
+ !if (USE_MASTER)
+ (latex_file, latex_file_dir,,) = getbuf_info ();
+ % is this a compressed file?
+ cmp_method = check_is_compressed (dircat (latex_file_dir, latex_file));
+ if (-1 != cmp_method) {
+ tmpfile = path_sans_extname (latex_file);
+ cmd = sprintf (Uncompress_File_Pgms [cmp_method],
+ dircat (latex_file_dir, latex_file));
+ flush ("Uncompressing buffer...");
+ run_shell_cmd (cmd);
+ latex_file = path_sans_extname (latex_file);
+ }
+ dvi = path_sans_extname (dircat (latex_file_dir, latex_file)) + ".dvi";
+ bat = path_sans_extname (dircat (latex_file_dir, latex_file)) + ".bat";
+
+ switch (LaTeX_Default_Output)
+ { case "dvi":
+ cmd = LaTeX_Compose_Cmd;
+ cmd2 = "";
+ }
+ { case "ps":
+ cmd = LaTeX_Compose_Cmd;
+ cmd2 = LaTeX_Dvips_Cmd;
+ }
+ { case "eps":
+ cmd = LaTeX_Compose_Cmd;
+ cmd2 = LaTeX_Dvips_Cmd + LaTeX_Eps_Options;
+ }
+ { case "dvipdf":
+ cmd = LaTeX_Compose_Cmd;
+ cmd2 = LaTeX_Dvipdf_Cmd;
+ }
+ { case "pdf":
+ cmd = LaTeX_Compose_Pdf_Cmd;
+ cmd2 = "";
+ }
+
+ % run latex or whatever
+ save_buffers ();
+ flush ("Composing... (output profile: " + LaTeX_Default_Output + ")");
+ % cd to the right directory
+ tmp = "cd " + latex_file_dir + "; " + cmd + " " +
+ dircat (latex_file_dir, latex_file);
+#ifdef UNIX
+ !if (strcmp ("y", LaTeX_Rerun)) {
+ do {
+ status = latex_compile_and_parse (tmp);
+ if (ERROR != status)
+ flush ("Rerunning...");
+ } while (RERUN == status);
+ if (ERROR != status) {
+ flush ("All runs done.");
+ errors_parsed = FALSE;
+ }
+ }
+ else
+ status = latex_compile_and_parse (tmp);
+#elifdef WIN32
+ % build a .bat file, then run it
+ if (TRUE == file_status (bat))
+ delete_file (bat);
+ write_string_to_file ("cd " + latex_file_dir + "\n", bat);
+ append_string_to_file (cmd + " " +
+ dircat (latex_file_dir, latex_file) + "\n", bat);
+ !if (strcmp ("y", LaTeX_Rerun)) {
+ do {
+ status = latex_compile_and_parse (bat);
+ if (ERROR != status)
+ flush ("Rerunning...");
+ } while (RERUN == status);
+ if (ERROR != status) {
+ flush ("All runs done.");
+ errors_parsed = FALSE;
+ }
+ }
+ else
+ status = latex_compile_and_parse (bat);
+ % the .bat file will be deleted later
+#endif
+
+ if (ERROR == status)
+ return;
+
+ % if cmd2 isn't void, run dvips or whatever
+ if (strlen(cmd2)) {
+ flush ("Running: " + cmd2 + " " + dircat (latex_file_dir, dvi));
+ sw2buf (LaTeX_Dvips_Buffer);
+ set_readonly (0);
+ erase_buffer ();
+#ifdef UNIX
+ % cd to the source directory, so that included files can be found
+ if (0 != run_shell_cmd ("cd " + latex_file_dir + "; " +
+ cmd2 + " " + dvi + " 2>&1"))
+#elifdef WIN32
+ delete_file (bat);
+ write_string_to_file ("cd " + latex_file_dir + "\n", bat);
+ append_string_to_file (cmd2 + " " + dvi + "\n", bat);
+ if (0 != run_shell_cmd (bat))
+#endif
+ error ("Could not run " + cmd2 + " " +
+ dircat (latex_file_dir, latex_file));
+ } % if (strlen(cmd2))
+ if (TRUE == compressed) {
+ cmd = sprintf (Compress_File_Pgms [cmp_method],
+ dircat (latex_file_dir, tmpfile));
+ run_shell_cmd (cmd);
+ }
+% if (ERROR != status)
+ flush ("Done.");
+ errors_parsed = FALSE;
+ sw2buf (LaTeX_Buffer);
+}
+
+% customising, viewing, printing, etc.
+
+% -----
+
+public define latex_customise ()
+{
+ variable tmp, var, value;
+ var = read_with_completion (custom_variables,
+ "Variable to change (press TAB to list):",
+ "", "", 's');
+ tmp = sprintf ("New value (now \"%s\"):", string (eval (var)));
+ value = (read_mini (tmp, "", ""));
+ !if (strcmp (var, "LaTeX_Indent"))
+ tmp = string (value);
+ else
+ tmp = "\"" + string (value) + "\"";
+ eval (var + "=" + tmp);
+}
+
+define latex_master_file ()
+{
+ variable mf =
+ read_mini ("Set this buffer as master file (y/n)?",
+ "n", "");
+ if ( (mf [0] == 'y') or (mf [0] == 'Y') ) {
+ USE_MASTER = TRUE;
+ (latex_file, latex_file_dir,,) = getbuf_info ();
+ }
+ else
+ USE_MASTER = FALSE;
+}
+
+public define latex_view ()
+{
+ variable i, dvi, ps, pdf;
+ !if (USE_MASTER)
+ (latex_file, latex_file_dir,,) = getbuf_info ();
+ i = check_is_compressed (dircat (latex_file_dir, latex_file));
+ if (-1 != i) % remove the extension
+ latex_file = path_sans_extname (latex_file);
+ dvi = path_sans_extname (dircat (latex_file_dir, latex_file)) + ".dvi";
+ ps = path_sans_extname (dircat (latex_file_dir, latex_file)) + ".ps";
+ pdf = path_sans_extname (dircat (latex_file_dir, latex_file)) + ".pdf";
+
+ switch (LaTeX_Default_Output)
+
+ { case "dvi":
+ if (1 != file_status (dvi)) {
+ beep ();
+ flush ("No file " + dvi + "! Building it...");
+ usleep (2000);
+ LaTeX_Default_Output = "dvi";
+ latex_compose ();
+ }
+ flush ("Running: " + LaTeX_View_Dvi_Cmd +
+ " " + dvi + " (building fonts...)");
+ sw2buf (LaTeX_Xdvi_Buffer);
+ set_readonly (0);
+ erase_buffer ();
+#ifdef UNIX
+ if (0 != run_shell_cmd ("cd " + latex_file_dir + "; " +
+ LaTeX_View_Dvi_Cmd + " " + dvi + devnull))
+#elifdef WIN32
+ if (0 != run_shell_cmd (LaTeX_View_Dvi_Cmd + " " + dvi))
+#endif
+ error ("Could not run " + LaTeX_View_Dvi_Cmd + " " + dvi);
+ sw2buf (LaTeX_Buffer);
+ }
+
+ { case "ps":
+ if (1 != file_status (dvi)) {
+ beep ();
+ flush ("No file " + dvi + "! Building it...");
+ usleep (2000);
+ LaTeX_Default_Output = "dvi";
+ latex_compose ();
+ }
+ flush ("Running: " + LaTeX_View_Ps_Cmd + " " + ps);
+ sw2buf (LaTeX_Gv_Buffer);
+ set_readonly (0);
+ erase_buffer ();
+ if (0 != run_shell_cmd (LaTeX_View_Ps_Cmd + " " + ps + devnull))
+ error ("Could not run " + LaTeX_View_Ps_Cmd + " " + ps);
+ sw2buf (LaTeX_Buffer);
+ }
+
+ { case "dvipdf" or case "pdf":
+ if (1 != file_status (pdf)) {
+ beep ();
+ flush ("No file " + pdf + "! Building it...");
+ usleep (2000);
+ LaTeX_Default_Output = "pdf";
+ latex_compose ();
+ }
+ flush ("Running: " + LaTeX_View_Pdf_Cmd + " " + pdf);
+ sw2buf (LaTeX_Xpdf_Buffer);
+ set_readonly (0);
+ erase_buffer ();
+ if (0 != run_shell_cmd (LaTeX_View_Pdf_Cmd + " " + pdf + devnull))
+ error ("Could not run " + LaTeX_View_Pdf_Cmd + " " + pdf);
+ sw2buf (LaTeX_Buffer);
+ }
+}
+
+% -----
+
+public define latex_psprint ()
+{
+ variable cmd, ps;
+ !if (USE_MASTER)
+ (latex_file, latex_file_dir,,) = getbuf_info ();
+ % is this a compressed file?
+ % cmp_method = check_is_compressed (dircat (latex_file_dir, latex_file));
+ if (TRUE == compressed)
+ latex_file = path_sans_extname (latex_file);
+ ps = path_sans_extname (dircat (latex_file_dir, latex_file)) + ".ps";
+ if (1 != file_status (ps))
+ error ("No file " + ps + " to print!");
+ cmd = LaTeX_Print_Cmd + " " + ps;
+ cmd = read_mini ("Print command:", "", cmd);
+ () = run_shell_cmd (cmd + devnull);
+ flush ("Done (printing).");
+}
+
+% -----
+
+public define latex_bibtex ()
+{
+ variable bib;
+ !if (USE_MASTER)
+ (latex_file, latex_file_dir,,) = getbuf_info ();
+ if (TRUE == compressed)
+ latex_file = path_sans_extname (latex_file);
+ bib = path_sans_extname (dircat (latex_file_dir, latex_file));
+ flush ("BibTeX'ing " + bib);
+ sw2buf (LaTeX_Bibtex_Buffer);
+ if (0 != run_shell_cmd (LaTeX_Bibtex_Cmd + " " + bib))
+ error ("Error bibTeX'ing " + bib + "!");
+ sw2buf (LaTeX_Buffer);
+ flush ("Done.");
+}
+
+% -----
+
+public define latex_makeindex ()
+{
+ variable idx;
+ !if (USE_MASTER)
+ (latex_file, latex_file_dir,,) = getbuf_info ();
+ if (TRUE == compressed)
+ latex_file = path_sans_extname (latex_file);
+ idx = path_sans_extname (dircat (latex_file_dir, latex_file)) + ".idx";
+ flush ("Processing the index...");
+ sw2buf (LaTeX_Makeindex_Buffer);
+ if (0 != run_shell_cmd (LaTeX_Makeindex_Cmd + " " + idx))
+ error ("Error processing " + idx + "!");
+ sw2buf (LaTeX_Buffer);
+ flush ("Done.");
+}
+
+% -----
+
+define latex_mode_help ()
+{
+ variable file = expand_jedlib_file ("latex.hlp");
+ () = read_file (file);
+ pop2buf (whatbuf ());
+ most_mode ();
+ call ("one_window");
+ set_readonly (1);
+}
+
+% some utility functions
+
+% this function is used to make indented environments
+static define latex_insert_pair_around_lines (left, right)
+{
+ variable col;
+ check_region (1); % spot pushed
+ narrow ();
+ bob ();
+ col = what_column () - 1;
+ insert (left);
+ insert_spaces (col);
+ do {
+ insert_spaces (LaTeX_Indent);
+ bol ();
+ } while (down (1));
+ eob ();
+ insert ("\n");
+ insert_spaces (col);
+ insert (right);
+ widen ();
+ pop_spot ();
+}
+
+static define latex_insert_pair_around_region (left, right)
+{
+ exchange_point_and_mark ();
+ insert (left);
+ exchange_point_and_mark ();
+ insert (right);
+ pop_spot ();
+ pop_mark_0 ();
+}
+
+define latex_insert_tags (tag1, tag2, do_push_spot, do_pop_spot)
+{
+ variable
+ chr = what_char (),
+ tmp = get_word_chars ();
+ if ('\\' == chr)
+ chr = '\0'; % avoid the \ problem
+ % if the current position is within a word, then select it
+ if ( (0 == markp ()) and % no region defined
+ (0 == string_match (" \t\n", char (chr), 1)) ) {
+ % ok, the cursor isn't on a space
+ () = right (1);
+ define_word ("_0-9A-Za-z\\");
+ bskip_word ();
+ push_mark ();
+ skip_word ();
+ define_word (tmp);
+ }
+ % if a region is defined, insert the tags around it
+ if (markp () ) {
+ check_region (0);
+ latex_insert_pair_around_region (tag1, tag2);
+ return;
+ }
+ % the remaining cases
+ insert (tag1);
+ if (do_push_spot)
+ push_spot ();
+ insert (tag2);
+ if (do_pop_spot)
+ pop_spot ();
+}
+
+% -----
+
+define latex_begin_end (param1, param2, do_push_spot, do_pop_spot)
+{
+ variable col = what_column () - 1;
+ variable env1, env2;
+
+ env1 = sprintf ("\\begin{%s}%s\n", param1, param2);
+ env2 = sprintf ("\\end{%s}", param1);
+ if (markp () ) {
+ check_region (0);
+ latex_insert_pair_around_lines (env1, env2);
+ return;
+ }
+ insert (env1);
+ insert_spaces (col + LaTeX_Indent);
+ if (do_push_spot)
+ push_spot ();
+ insert ("\n");
+ insert_spaces (col);
+ insert (env2);
+ if (do_pop_spot)
+ pop_spot ();
+}
+
+% -----
+
+define latex_cmd (cmd, do_push_spot)
+{
+ latex_insert_tags (sprintf ("\\%s{", cmd), "}",
+ do_push_spot, do_push_spot);
+}
+
+define latex_loglike (cmd)
+{
+ latex_insert_tags (sprintf ("\\%s(", cmd), ")",
+ PUSH_SPOT, POP_SPOT);
+}
+
+% -----
+
+define latex_cmd_with_arg (cmd, arg)
+{
+ latex_insert_tags (sprintf ("\\%s{", cmd), "}", PUSH_SPOT, NO_POP_SPOT);
+ insert (sprintf ("{%s}", arg));
+ pop_spot ();
+}
+
+% -----
+
+static variable benv_line, eenv_line; % needed later
+
+define latex_is_within_environment ()
+{
+ variable eline, benv, eenv;
+ push_spot ();
+ if (0 == bsearch ("\\begin{"))
+ return FALSE;
+ () = right (7); % skip \begin{
+ push_mark ();
+ skip_chars ("A-Za-z0-9");
+ benv = bufsubstr ();
+ benv_line = what_line ();
+ pop_mark_0 ();
+ if (0 == fsearch ("\\end{"))
+ return FALSE;
+ eline = what_line;
+ () = right (5);
+ push_mark ();
+ skip_chars ("A-Za-z0-9");
+ eenv = bufsubstr ();
+ eenv_line = what_line ();
+ pop_mark_0 ();
+ pop_spot ();
+ if (eline <= what_line)
+ return FALSE;
+ if (strcmp (benv, eenv))
+ return FALSE;
+ else
+ return TRUE;
+}
+
+% -----
+
+static variable std_env =
+ "abstract,array,center,description,displaymath," +
+ "enumerate,eqnarray,equation,figure,flushleft," +
+ "flushright,itemize,list,minipage,picture," +
+ "quotation,quote,tabbing,table,tabular," +
+ "thebibliography,theorem,titlepage,verbatim,verse";
+
+define latex_rename_environment ()
+{
+ variable newenv;
+ if (FALSE == latex_is_within_environment ())
+ error ("Not within an environment!");
+ newenv =
+ read_with_completion (std_env, "Which environment (TAB to list)?",
+ "", "", 's');
+ push_spot ();
+ () = bsearch ("\\begin{");
+ () = right (7);
+ delete_word ();
+ insert (newenv);
+ () = fsearch ("\\end{");
+ () = right (5);
+ delete_word ();
+ insert (newenv);
+ pop_spot ();
+}
+
+% -----
+
+static variable std_fonts =
+ "textrm,textit,emph,textmd,textbf,textup,textsl," +
+ "textsf,textsc,texttt,verb,textnormal,underline";
+
+static variable std_sizes =
+ "tiny,scriptsize,footnotesize,small," +
+ "normalsize,large,Large,LARGE,huge,Huge";
+
+define latex_modify_font (oldfont, newfont)
+{
+ variable chr = what_char (), font, tmp = get_word_chars ();
+
+ push_spot ();
+ if (0 == bsearch ("\\")) {
+ beep ();
+ flush ("The cursor is not within curly braces.");
+ }
+ () = right (1);
+ define_word ("A-Za-z");
+ push_mark ();
+ skip_word ();
+ font = bufsubstr ();
+ pop_mark_0 ();
+
+ if (is_substr (oldfont, font)) {
+ % delete the font definition
+ if (0 == strlen (newfont)) {
+ define_word ("\\A-Za-z{");
+ bskip_word (); % back to \
+ define_word ("\\A-Za-z");
+ delete_word ();
+ call ("delete_char_cmd"); % delete '}' then its match
+ push_spot ();
+ if (1 != find_matching_delimiter ('{')) {
+ pop_spot ();
+ pop_spot ();
+ error ("Warning - there were unbalanced braces!");
+ }
+ call ("delete_char_cmd"); % delete '{'
+ pop_spot ();
+ }
+ else { % rename the font - no warnings for unbalanced {}
+ define_word ("A-Za-z");
+ bskip_word ();
+ delete_word ();
+ insert (newfont);
+ }
+ }
+ else {
+ beep ();
+ flush ("Could not find a valid font definition.");
+ }
+ define_word (tmp);
+ pop_spot ();
+}
+
+define latex_rename_font ()
+{
+
+ variable newfont =
+ read_with_completion (std_fonts, "Which font (TAB to list)?",
+ "", "", 's');
+ latex_modify_font (std_fonts, newfont);
+}
+
+define latex_insert_font ()
+{
+ variable tmp =
+ read_with_completion (std_fonts, "Which font (TAB to list)?",
+ "", "", 's');
+ !if (strcmp (tmp, "verb"))
+ latex_insert_tags ("\\verb|", "|", TRUE, TRUE);
+ else
+ latex_cmd (tmp, TRUE);
+}
+
+define latex_resize_font ()
+{
+ variable newsize =
+ read_with_completion (std_sizes, "Which size (TAB to list)?",
+ "", "", 's');
+ latex_modify_font (std_sizes, newsize);
+}
+
+% -----
+
+define latex_insert (cmd)
+{ vinsert ("\\%s ", cmd); }
+
+define latex_insert_nospace (cmd)
+{ vinsert ("\\%s", cmd); }
+
+define latex_insert_newline (cmd)
+{ vinsert ("\\%s\n", cmd); }
+
+define latex_open_env ()
+{
+ variable col = what_column (), env =
+ read_with_completion (std_env, "Which environment (TAB to list)?",
+ "", "", 's');
+ vinsert ("\\begin{%s}\n", env);
+ insert_spaces (col + LaTeX_Indent - 1);
+}
+
+% this is J\"org's
+define latex_close_env ()
+{
+ push_spot ();
+
+ ERROR_BLOCK {
+ pop_spot ();
+ }
+
+ % Idea: increase for every \end we found and decrease for ever \begin
+ % we found. If we have 0, the founded \begin is for our \end.
+ variable ends = 1;
+ forever {
+ push_mark ();
+ !if (bsearch("\\begin{")) {
+ pop_mark (1);
+ error ("No \\begin{} found");
+ }
+ --ends;
+ push_spot ();
+
+ variable tmp = bufsubstr(), pos = 0;
+ % see if there are any \ends between our \end and the found \begin
+ do {
+ variable ret = is_substr(tmp[[pos:]], "\\end{");
+ pos += ret;
+ if (ret > 0)
+ ++ends;
+ } while (ret > 0);
+
+ pop_spot();
+ if (ends == 0) {
+ () = right (7);
+ push_mark ();
+ if (ffind_char ('}') == 0) {
+ pop_mark (1);
+ error("Malformed \\begin{}");
+ }
+
+ variable env = bufsubstr();
+ pop_spot ();
+ if (what_column () > LaTeX_Indent)
+ {
+ () = left (LaTeX_Indent);
+ deln (LaTeX_Indent);
+ }
+ insert ("\\end{" + env + "}");
+ return;
+ }
+ }
+}
+
+% -----
+
+% Templates
+
+define latex_article ()
+{
+ vinsert ("\\documentclass[%s]{article}\n\n",
+ LaTeX_Article_Default_Options);
+ insert ("\\begin{document}\n\n");
+ insert ("\\title{");
+ push_spot ();
+ insert ("}\n\n");
+ insert ("\\author{}\n\n");
+ insert ("\\date{}\n\n");
+ insert ("\\thanks{}\n\n");
+ insert ("\\maketitle\n\n");
+ insert ("\\begin{abstract}\n");
+ insert ("\\end{abstract}\n\n");
+ insert ("\\tableofcontents\n");
+ insert ("\\listoftables\n");
+ insert ("\\listoffigures\n\n");
+ insert ("\\section{}\n\n");
+ insert ("\\end{document}");
+ pop_spot ();
+}
+
+define latex_book ()
+{
+ vinsert ("\\documentclass[%s]{book}\n\n",
+ LaTeX_Book_Default_Options);
+ insert ("\\begin{document}\n\n");
+ insert ("\\frontmatter\n");
+ insert ("\\title{");
+ push_spot ();
+ insert ("}\n\n");
+ insert ("\\author{}\n\n");
+ insert ("\\date{}\n\n");
+ insert ("\\maketitle\n\n");
+ insert ("\\tableofcontents\n");
+ insert ("\\listoftables\n");
+ insert ("\\listoffigures\n\n");
+ insert ("\\mainmatter\n\n");
+ insert ("\\part{}\n\n");
+ insert ("\\chapter{}\n\n");
+ insert ("\\section{}\n\n");
+ insert ("\\end{document}");
+ pop_spot ();
+}
+
+define latex_letter ()
+{
+ vinsert ("\\documentclass[%s]{letter}\n\n",
+ LaTeX_Letter_Default_Options);
+ insert ("\\begin{document}\n\n");
+ insert ("\\address\n{\n% return address\n}\n");
+ insert ("\\signature{");
+ push_spot ();
+ insert ("}\n");
+ insert ("\\begin{letter}\n{\n% recipient's address\n}\n");
+ insert ("\\opening{}\n\n");
+ insert ("\\closing{}\n");
+ insert ("\\ps{}\n");
+ insert ("\\cc{}\n");
+ insert ("\\encl{}\n");
+ insert ("\\end{letter}\n");
+ insert ("\\end{document}\n");
+ pop_spot ();
+}
+
+define latex_report ()
+{
+ vinsert ("\\documentclass[%s]{report}\n\n",
+ LaTeX_Report_Default_Options);
+ insert ("\\begin{document}\n\n");
+ insert ("\\title{}\n");
+ push_spot ();
+ insert ("\\author{}\n\n");
+ insert ("\\date{}\n\n");
+ insert ("\\maketitle\n\n");
+ insert ("\\begin{abstract}\n");
+ insert ("\\end{abstract}\n\n");
+ insert ("\\tableofcontents\n");
+ insert ("\\listoftables\n");
+ insert ("\\listoffigures\n\n");
+ insert ("\\part{}\n\n");
+ insert ("\\chapter{}\n\n");
+ insert ("\\section{}\n\n");
+ insert ("\\end{document}");
+ pop_spot ();
+}
+
+define latex_slides ()
+{
+ vinsert ("\\documentclass[%s]{slides}\n\n",
+ LaTeX_Slides_Default_Options);
+ insert ("\\begin{document}\n\n");
+ insert ("\\title{");
+ push_spot ();
+ insert ("}\n\\author{}\n");
+ insert ("\\date{}\n\n");
+ insert ("\\maketitle\n\n");
+ insert ("\\end{document}");
+ pop_spot ();
+}
+
+% Environments
+
+define latex_insert_package (msg)
+{
+ variable spot, tmp;
+ % look for the appropriate package
+ push_spot ();
+ bob ();
+ spot = re_fsearch (sprintf ("\\usepackage.*{%s}", msg));
+ if (0 == spot) { % not found
+ () = fsearch ("\\documentclass");
+ eol ();
+ vinsert ("\n\\usepackage{%s}", msg);
+ flush (sprintf ("Note: \\usepackage{%s} inserted.", msg));
+ }
+ pop_spot ();
+}
+
+define latex_env_item ()
+{
+ variable tmp;
+
+ if (TRUE == ITEM_LABEL)
+ tmp = "item []";
+ else
+ tmp = "item";
+
+ latex_insert (tmp);
+}
+
+define latex_env_itemize (what)
+{
+ variable col = what_column () - 1;
+ !if (strcmp (what, "itemize"))
+ ITEM_LABEL = FALSE;
+ else
+ ITEM_LABEL = TRUE;
+ insert (sprintf ("\\begin{%s}\n", what));
+ insert_spaces (col + LaTeX_Indent);
+ latex_env_item ();
+ push_spot ();
+ insert ("\n");
+ insert_spaces (col);
+ insert (sprintf ("\\end{%s}\n", what));
+ pop_spot ();
+}
+
+define latex_env_description ()
+{
+ latex_begin_end ("description", "", PUSH_SPOT, POP_SPOT);
+ ITEM_LABEL = TRUE;
+}
+
+define latex_env_figure ()
+{
+ % if a prefix argument (e.g. ESC 1) was entered,
+ % then insert the extended form
+ variable
+ col = what_column () - 1,
+ arg = prefix_argument (-1);
+ insert ("\\begin{figure}[htbp]\n");
+ insert_spaces (col + LaTeX_Indent);
+ insert ("\\centering\n");
+ insert_spaces (col + LaTeX_Indent);
+ push_spot ();
+ if (arg == -1)
+ insert ("\\includegraphics[scale=|width=|height=]{file.eps}\n");
+ else
+ insert ("\\includegraphics{}\n");
+ insert_spaces (col + LaTeX_Indent);
+ insert ("\\caption{}\n");
+ insert_spaces (col + LaTeX_Indent);
+ insert ("\\label{fig:}\n");
+ insert_spaces (col);
+ insert ("\\end{figure}");
+ latex_insert_package ("graphicx");
+ pop_spot ();
+}
+
+define latex_env_picture ()
+{ latex_begin_end ("picture", "(width,height)(x offset,y offset)",
+ PUSH_SPOT, POP_SPOT);
+}
+
+define latex_env_custom ()
+{
+ variable custom = read_mini ("What environment?", Null_String, "");
+ latex_begin_end (custom, "", PUSH_SPOT, POP_SPOT);
+}
+
+% tables
+
+static variable table_columns = 3;
+
+define latex_table_row (do_push_spot)
+{
+ variable i, col;
+
+ col = what_column () - 1;
+ if (do_push_spot)
+ push_spot ();
+ loop (table_columns - 1) {
+ insert (" &");
+ }
+ insert (" \\\\");
+ if (do_push_spot)
+ pop_spot ();
+}
+
+define is_integer (str)
+{
+ if (Integer_Type == _slang_guess_type (str))
+ return (integer (str));
+ else
+ return -1;
+}
+
+define latex_table_template (flag_tabular)
+{
+ variable col = what_column () - 1;
+ variable i, align, table_col_str, ok;
+
+ do {
+ table_col_str = read_mini ("Columns?", Null_String, "4");
+ table_columns = is_integer (table_col_str);
+ if (-1 == table_columns) {
+ ok = FALSE;
+ beep ();
+ message ("Wrong value! ");
+ }
+ else
+ ok = TRUE;
+ } while (FALSE == ok);
+
+ align = "{|";
+ loop (table_columns)
+ align = align + "l|";
+ align = align + "}";
+
+ !if (flag_tabular) {
+ insert ("\\begin{table}[htbp]\n");
+ insert_spaces (col + LaTeX_Indent);
+ }
+ insert ("\\centering\n");
+ insert_spaces (col + LaTeX_Indent);
+ vinsert ("\\begin{tabular}%s\n", align);
+ insert_spaces (col + LaTeX_Indent);
+ insert ("\\hline\n");
+ insert_spaces (col + LaTeX_Indent);
+ push_spot ();
+ latex_table_row (NO_PUSH_SPOT);
+ insert ("\n");
+ insert_spaces (col + LaTeX_Indent);
+ insert ("\\hline\n");
+ if (flag_tabular)
+ insert ("\\end{tabular}\n");
+ else {
+ insert_spaces (col + LaTeX_Indent);
+ insert ("\\end{tabular}\n");
+ insert_spaces (col + LaTeX_Indent);
+ latex_cmd ("caption", NO_PUSH_SPOT);
+ insert ("\n");
+ insert_spaces (col + LaTeX_Indent);
+ insert ("\\label{tab:}\n");
+ insert_spaces (col);
+ insert ("\\end{table}");
+ }
+ pop_spot ();
+}
+
+define latex_complete_environment ()
+{
+ variable tmp =
+ read_with_completion (std_env, "Which environment (TAB to list)?",
+ "", "", 's');
+ switch (tmp)
+ { case "description": latex_env_description (); }
+ { case "figure": latex_env_figure (); }
+ { case "minipage": latex_begin_end ("minipage",
+ "[c]{\\linewidth}",
+ TRUE, TRUE);
+ }
+ { case "tabular": latex_table_template (TRUE); }
+ { case "table": latex_table_template (TRUE); }
+ { case "thebibliography": latex_begin_end ("thebibliography",
+ "{99}",
+ TRUE, TRUE);
+ }
+ { latex_begin_end (tmp, "", TRUE, TRUE); }
+}
+
+% -----
+
+% Paragraph
+
+define latex_par_frame ()
+{
+ variable str;
+ str = "\\begin{boxedminipage}[c]{\\linewidth}\n";
+ latex_insert_tags (str, "\\end{boxedminipage}\n", PUSH_SPOT, POP_SPOT);
+ latex_insert_package ("boxedminipage");
+}
+
+define latex_par_bgcolour ()
+{
+ variable str;
+ variable colour = read_mini ("What colour?", Null_String, "");
+ str = sprintf ("\\colorbox{%s}{", colour);
+ latex_insert_tags (str, "}", PUSH_SPOT, POP_SPOT);
+ latex_insert_package ("color");
+}
+
+define latex_par_fgcolour ()
+{
+ variable str;
+ variable colour = read_mini ("What colour?", Null_String, "");
+ str = sprintf ("\\textcolor{%s}{", colour);
+ latex_insert_tags (str, "}", PUSH_SPOT, POP_SPOT);
+ latex_insert_package ("color");
+}
+
+define latex_includegraphics ()
+{
+ % if a prefix argument (e.g. ESC 1) was given, then insert
+ % the extended form
+ variable arg = prefix_argument (-1);
+ if (arg == -1) % no prefix argument
+ latex_cmd ("includegraphics", PUSH_SPOT);
+ else
+ latex_cmd ("includegraphics[scale=|width=|height=]", PUSH_SPOT);
+ latex_insert_package ("graphicx");
+}
+
+define latex_linebreak ()
+{
+ insert ("\\\\*[");
+ push_spot ();
+ insert ("]");
+ pop_spot ();
+}
+
+% misc
+
+define latex_insert_braces ()
+{
+ insert ("{}");
+ go_left_1 ();
+}
+
+define latex_insert_dollar ()
+{
+ insert ("$$");
+ go_left_1 ();
+}
+
+define latex_greek_letter ()
+{
+ variable tmp = expand_keystring (_Reserved_Key_Prefix);
+ flush (sprintf ("Press %sm + letter (e.g. %sma = \\alpha)",
+ tmp, tmp));
+}
+
+define latex_arrow ()
+{
+ % right arrows
+ if (LAST_CHAR == '>') {
+ % 3 chars
+ if (blooking_at ("|--")) {
+ () = left (3);
+ deln (3);
+ insert ("{\\longmapsto}");
+ return;
+ }
+ % 2 chars
+ if (blooking_at ("--")) {
+ go_left (2);
+ deln (2);
+ insert ("{\\longrightarrow}");
+ return;
+ }
+ if (blooking_at ("==")) {
+ go_left (2);
+ deln (2);
+ insert ("{\\Longrightarrow}");
+ return;
+ }
+ if (blooking_at ("|-")) {
+ () = left (2);
+ deln (2);
+ insert ("{\\mapsto}");
+ return;
+ }
+ % left-right
+ if (blooking_at ("< -")) {
+ go_left (3);
+ deln (3);
+ insert ("{\\leftrightarrow}");
+ return;
+ }
+ if (blooking_at ("< =")) {
+ go_left (3);
+ deln (3);
+ insert ("{\\Leftrightarrow}");
+ return;
+ }
+ if (blooking_at ("-")) {
+ go_left (1);
+ deln (1);
+ insert ("{\\rightarrow}");
+ return;
+ }
+ if (blooking_at ("=")) {
+ go_left (1);
+ deln (1);
+ insert ("{\\Rightarrow}");
+ return;
+ }
+ insert (">");
+ }
+ % simple left arrows
+ if (LAST_CHAR == '-') {
+ if (blooking_at ("< -")) {
+ go_left (3);
+ deln (3);
+ insert ("{\\longleftarrow}");
+ return;
+ }
+ if (blooking_at ("<")) {
+ go_left (1);
+ deln (1);
+ insert ("{\\leftarrow}");
+ return;
+ }
+ insert ("-");
+ }
+ % double left arrows
+ if (LAST_CHAR == '=') {
+ if (blooking_at ("< =")) {
+ go_left (3);
+ deln (3);
+ insert ("{\\Longleftarrow}");
+ return;
+ }
+ if (blooking_at ("<")) {
+ go_left (1);
+ deln (1);
+ insert ("{\\Leftarrow}");
+ return;
+ }
+ insert ("=");
+ }
+}
+
+define toggle_math_mode ()
+{
+ $1 = "LaTeX-Mode";
+ if (FALSE == Math_Mode) {
+ Math_Mode = TRUE;
+ definekey ("latex_insert_math", "`", $1);
+ flush ("Math mode enabled.");
+ }
+ else {
+ Math_Mode = FALSE;
+ undefinekey ("`", $1);
+ definekey ("quoted_insert", "`", $1);
+ flush ("Math mode disabled.");
+ }
+}
+
+define latex_url ()
+{
+ latex_insert_tags ("\\url{", "}", PUSH_SPOT, POP_SPOT);
+ latex_insert_package ("url");
+}
+
+define latex_indent_line ()
+{
+ variable arg = prefix_argument (-1);
+ push_spot ();
+ bol ();
+ if (arg == -1) % no prefix argument
+ insert_spaces (LaTeX_Indent);
+ else
+ loop (LaTeX_Indent)
+ if (' ' == what_char ())
+ call ("delete_char_cmd");
+ pop_spot ();
+}
+
+define latex_indent_environment ()
+{
+ if (FALSE == latex_is_within_environment ())
+ error ("Not within an environment!");
+ push_spot ();
+ goto_line (benv_line);
+ down (1);
+ while (what_line () < eenv_line) {
+ latex_indent_line ();
+ () = down (1);
+ }
+ pop_spot ();
+}
+
+% let's finish
+
+% this function is for the Template/Packages menu
+
+define latex_babel ()
+{
+ variable tmp = sprintf ("\\usepackage[%s]{babel}\n",
+ LaTeX_Default_Language);
+ insert (tmp);
+}
+
+define latex_index_word ()
+{
+ variable tmp;
+ if ( (0 == markp ()) and % no region defined
+ (0 == string_match (" \t\n", char (what_char()), 1)) ) {
+ % ok, the cursor isn't on a space
+ () = right (1);
+ bskip_word ();
+ push_mark ();
+ skip_word ();
+ tmp = bufsubstr ();
+ pop_mark_0 ();
+ }
+ else {
+ beep ();
+ flush ("The cursor is not on a word.");
+ return;
+ }
+ bskip_word ();
+ insert ("\\index{" + tmp + "}");
+}
+
+define latex_makeidx ()
+{
+ push_spot ();
+ bob ();
+ if (0 == fsearch ("\\documentclass")) {
+ error ("No \\documentclass definition yet.");
+ return;
+ }
+ () = down (1);
+ insert ("\\usepackage{makeidx}\n");
+ if (0 == fsearch ("\\begin{document}")) {
+ error ("No \\begin{document} definition yet.");
+ return;
+ }
+ insert ("\\makeindex\n\n");
+ eob ();
+ if (0 == bsearch ("\\end{document}")) {
+ error ("No \\end{document} definition yet.");
+ return;
+ }
+ insert ("\\printindex\n\n");
+ pop_spot ();
+}
+
+define latex_index_subentry ()
+{
+ latex_cmd ("index", TRUE);
+ if ('}' != what_char ())
+ () = left (1);
+ insert ("!");
+}
+
+define latex_index_beginrange ()
+{
+ latex_cmd ("index", TRUE);
+ if ('}' != what_char ())
+ () = left (1);
+ insert ("|(");
+}
+
+define latex_index_endrange ()
+{
+ latex_cmd ("index", TRUE);
+ if ('}' != what_char ())
+ () = left (1);
+ insert ("|)");
+}
+
+define latex_index_sortorder ()
+{
+ latex_cmd ("index", TRUE);
+ if ('}' != what_char ())
+ () = left (1);
+ insert ("@");
+}
+
+define latex_index_specialformat ()
+{
+ latex_cmd ("index", TRUE);
+ if ('}' != what_char ())
+ () = left (1);
+ insert ("|");
+}
+
+% -----
+
+% Document structure
+
+static define getline ()
+{
+ variable line, numline;
+ push_mark ();
+ eol ();
+ line = bufsubstr ();
+ pop_mark_0 ();
+ numline = what_line ();
+ return (line, numline);
+}
+
+
+% this one creates the buffer that contains the
+% document tree (structure)
+define latex_build_doc_tree ()
+{
+ variable i, found, line, numline,
+ num_sections = 0,
+ level = -1,
+ case_search = CASE_SEARCH;
+ variable sections = String_Type [8];
+
+ LaTeX_Buffer = whatbuf ();
+ sw2buf (LaTeX_Tree_Buffer);
+ set_readonly (0);
+ erase_buffer ();
+ insert ("Document structure ('q' to quit, <Return> or double click to select):\n\n");
+ sw2buf (LaTeX_Buffer);
+ push_spot ();
+ bob ();
+
+ % let's start with \begin{document}
+ if (0 == fsearch ("\\begin{document}"))
+ error ("No \\begin{document} found!");
+ % get the line
+ (line, numline) = getline ();
+ sw2buf (LaTeX_Tree_Buffer);
+ % TODO: find a better solution
+ vinsert ("%6d%s", numline, " ");
+ insert (line + "\n");
+
+ sections [0] = "\\part{";
+ sections [1] = "\\chapter{";
+ sections [2] = "\\section{";
+ sections [3] = "\\subsection{";
+ sections [4] = "\\subsubsection{";
+ sections [5] = "\\paragraph{";
+ sections [6] = "\\subparagraph{";
+ sections [7] = "\\label{";
+
+ % now, let's search for sectioning commands.
+ % The algorithm is horrible, but it works and is probably more
+ % efficient than the "right" one.
+
+ CASE_SEARCH = 1;
+ for (i = 0; i < 8; i++) {
+ sw2buf (LaTeX_Buffer);
+ bob ();
+ do {
+
+ found = FALSE;
+ sw2buf (LaTeX_Buffer);
+ if (0 != fsearch (sections [i])) {
+ if (-1 == level)
+ level = i; % first level of indentation
+ if (0 == bfind ("%")) { % not in a comment
+ (line, numline) = getline ();
+ num_sections++;
+ sw2buf (LaTeX_Tree_Buffer);
+ vinsert ("%6d%s", numline, " ");
+ insert_spaces ((i - level + 1) * LaTeX_Indent);
+ insert (line + "\n");
+ }
+ found = TRUE;
+ () = down (1);
+ }
+ } while (TRUE == found);
+ }
+ CASE_SEARCH = case_search;
+
+ % ok, now the tree is done; let's sort it
+ sw2buf (LaTeX_Tree_Buffer);
+ bob ();
+ () = down (2);
+ push_mark ();
+ () = down (num_sections);
+ eol ();
+ sort ();
+ pop_mark_0 ();
+ set_readonly (1);
+ latex_mode ();
+ setbuf_info (getbuf_info () & 0xFE); % not modified
+ sw2buf (LaTeX_Buffer);
+ pop_spot ();
+}
+
+static define update_tree_hook ()
+{
+ line_mark = create_line_mark (color_number ("menu_selection"));
+}
+
+define latex_browse_tree ()
+{
+ variable tmode = "tree";
+ !if (keymap_p (tmode))
+ make_keymap (tmode);
+ definekey ("delbuf (whatbuf())", "q", tmode);
+ definekey ("goto_error_line", "\r", tmode);
+ latex_build_doc_tree ();
+ sw2buf (LaTeX_Tree_Buffer);
+ set_buffer_hook ("update_hook", &update_tree_hook);
+ set_readonly (1);
+ use_keymap (tmode);
+ set_mode (tmode, 0);
+ set_buffer_hook ("mouse_2click", "goto_error_line");
+}
+
+% The Menu
+
+% -----
+
+% copied from popups.sl
+static define add_files_popup_with_callback (parent, popup, dir, pattern)
+{
+ variable files, i;
+
+ if (strcmp ("y", LaTeX_Load_Modules))
+ return;
+
+ files = listdir (dir);
+ if (files == NULL)
+ return;
+ i = where (array_map (Int_Type, &string_match, files, pattern, 1));
+ if (length (i) == 0)
+ return;
+ files = files [i];
+ files = files [array_sort (files)];
+ menu_append_popup (parent, popup);
+ popup = parent + "." + popup;
+
+ foreach (files) {
+ variable file = ();
+ file = path_sans_extname (file);
+ menu_append_popup (popup, file);
+ () = evalfile (dircat (LaTeX_Modules_Dir, file));
+ }
+}
+
+% -----
+
+define latex_goto_next_paragraph ()
+{
+ if (0 != re_fsearch ("^$"))
+ () = right (1);
+}
+
+define latex_goto_prev_paragraph ()
+{
+ if (0 != re_bsearch ("^$"))
+ () = left (1);
+}
+
+% -----
+
+define init_menu (menu)
+{
+ variable tmp;
+ % templates
+ menu_append_popup (menu, "&Templates");
+ $1 = sprintf ("%s.&Templates", menu);
+ menu_append_item ($1, "&article", "latex_article");
+ menu_append_item ($1, "&book", "latex_book");
+ menu_append_item ($1, "&letter", "latex_letter");
+ menu_append_item ($1, "&report", "latex_report");
+ menu_append_item ($1, "&slides", "latex_slides");
+ % templates/packages
+ % these aren't bound to any key
+ menu_append_popup ($1, "&Packages");
+ $1 = sprintf ("%s.&Templates.&Packages", menu);
+ menu_append_item ($1, "alltt",
+ "latex_insert_newline (\"usepackage\{alltt\}\")");
+ menu_append_item ($1, "amsmath",
+ "latex_insert_newline (\"usepackage\{amsmath\}\")");
+ menu_append_item ($1, "babel", "latex_babel");
+ menu_append_item ($1, "booktabs",
+ "latex_insert_newline (\"usepackage\{booktabs\}\")");
+ menu_append_item ($1, "calc",
+ "latex_insert_newline (\"usepackage\{calc\}\")");
+ menu_append_item ($1, "color",
+ "latex_insert_newline (\"usepackage\{color\}\")");
+ tmp = "latex_insert_newline (\"usepackage\{epic\}\");";
+ tmp = tmp + "latex_insert_newline (\"usepackage\{eepic\}\")";
+ menu_append_item ($1, "eepic", tmp);
+ tmp = "latex_insert_newline (\"usepackage\{fancyhdr\}\");";
+ tmp = tmp + "latex_insert_newline (\"pagestyle\{fancy\}\")";
+ menu_append_item ($1, "fancyhdr", tmp);
+ menu_append_item ($1, "fancyvrb",
+ "latex_insert_newline (\"usepackage\{fancyvrb\}\")");
+ menu_append_item ($1, "geometry",
+ "latex_insert_newline (\"usepackage\{geometry\}\")");
+ menu_append_item ($1, "graphicx",
+ "latex_insert_newline (\"usepackage\{graphicx\}\")");
+ menu_append_item ($1, "hyperref",
+ "latex_insert_newline (\"usepackage" +
+ "[colorlinks,urlcolor=blue]\{hyperref\}\")");
+ menu_append_item ($1, "inputenc",
+ "latex_insert_newline (\"usepackage[latin1]\{inputenc\}}\")");
+ menu_append_item ($1, "longtable",
+ "latex_insert_newline (\"usepackage\{longtable\}\")");
+ menu_append_item ($1, "makeidx",
+ "latex_insert_newline (\"usepackage\{makeidx\}\")");
+ menu_append_item ($1, "moreverb",
+ "latex_insert_newline (\"usepackage\{moreverb\}\")");
+ menu_append_item ($1, "makeidx",
+ "latex_makeidx");
+ menu_append_item ($1, "psfrag",
+ "latex_insert_newline (\"usepackage\{psfrag\}\")");
+ menu_append_item ($1, "pslatex",
+ "latex_insert_newline (\"usepackage\{pslatex\}\")");
+ menu_append_item ($1, "rotating",
+ "latex_insert_newline (\"usepackage\{rotating\}\")");
+ menu_append_item ($1, "url",
+ "latex_insert_newline (\"usepackage\{url\}\")");
+ % environments
+ menu_append_popup (menu, "&Environments");
+ $1 = sprintf ("%s.&Environments", menu);
+ menu_append_item ($1, "&array",
+ "latex_begin_end (\"array\", \"{ll}\", 1, 1)");
+ menu_append_item ($1, "&center",
+ "latex_begin_end (\"center\", \"\", 1, 1)");
+ menu_append_item ($1, "&description",
+ "latex_env_itemize (\"description\")");
+ menu_append_item ($1, "displaymat&h",
+ "latex_begin_end (\"displaymath\", \"\", 1, 1)");
+ menu_append_item ($1, "&enumerate",
+ "latex_begin_end (\"enumerate\", \"\", 1, 1)");
+ menu_append_item ($1, "eq&narray",
+ "latex_begin_end (\"eqnarray\", \"\", 1, 1)");
+ menu_append_item ($1, "e&quation",
+ "latex_begin_end (\"equation\", \"\", 1, 1)");
+ menu_append_item ($1, "&figure", "latex_env_figure ()");
+ menu_append_item ($1, "flush&left",
+ "latex_begin_end (\"flushleft\", \"\", 1, 1)");
+ menu_append_item ($1, "flush&Right",
+ "latex_begin_end (\"flushright\", \"\", 1, 1)");
+ menu_append_item ($1, "&Itemize", "latex_env_itemize (\"itemize\")");
+ menu_append_item ($1, "\\&item", "latex_env_item");
+% menu_append_item ($1, "&Letter", "latex_env_letter ()");
+ menu_append_item ($1, "&List", "latex_begin_end (\"list\", \"\", 1, 1)");
+ menu_append_item ($1, "&minipage",
+ "latex_begin_end (\"minipage\", \"[c]{\\\\linewidth}\", 1, 1)");
+ menu_append_item ($1, "&picture",
+ "latex_begin_end (\"picture\", \"\", 1, 1)");
+ menu_append_item ($1, "&Quotation",
+ "latex_begin_end (\"quotation\", \"\", 1, 1)");
+ menu_append_item ($1, "qu&ote", "latex_begin_end (\"quote\", \"\", 1, 1)");
+ menu_append_item ($1, "ta&bbing",
+ "latex_begin_end (\"tabbing\", \"\", 1, 1)");
+ menu_append_item ($1, "&table", "latex_table_template (0)");
+ menu_append_item ($1, "table &row", "latex_table_row (1)");
+ menu_append_item ($1, "tab&ular", "latex_table_template (1)");
+ menu_append_item ($1, "thebibliograph&y",
+ "latex_begin_end (\"thebibliography\", \"{99}\", 1, 1)");
+ menu_append_item ($1, "t&Heorem",
+ "latex_begin_end (\"theorem\", \"\", 1, 1)");
+ menu_append_item ($1, "titlepa&ge",
+ "latex_begin_end (\"titlepage\", \"\", 1, 1)");
+ menu_append_item ($1, "&verbatim",
+ "latex_begin_end (\"verbatim\", \"\", 1, 1)");
+ menu_append_item ($1, "ver&se", "latex_begin_end (\"verse\", \"\", 1, 1)");
+ menu_append_item ($1, "&Custom...", "latex_env_custom");
+ menu_append_item ($1, "re&Name...", "latex_rename_environment");
+ menu_append_item ($1, "in&Dent", "latex_indent_environment");
+ % font
+ menu_append_popup (menu, "&Font");
+ $1 = sprintf ("%s.&Font", menu);
+ menu_append_item ($1, "\\text&rm", "latex_cmd (\"textrm\", 1)");
+ menu_append_item ($1, "\\text&it", "latex_cmd (\"textit\", 1)");
+ menu_append_item ($1, "\\&emph", "latex_cmd (\"emph\", 1)");
+ menu_append_item ($1, "\\text&md", "latex_cmd (\"textmd\", 1)");
+ menu_append_item ($1, "\\text&bf", "latex_cmd (\"textmd\", 1)");
+ menu_append_item ($1, "\\text&up", "latex_cmd (\"textup\", 1)");
+ menu_append_item ($1, "\\text&sl", "latex_cmd (\"textsl\", 1)");
+ menu_append_item ($1, "\\texts&f", "latex_cmd (\"textsf\", 1)");
+ menu_append_item ($1, "\\texts&c", "latex_cmd (\"textsc\", 1)");
+ menu_append_item ($1, "\\text&tt", "latex_cmd (\"texttt\", 1)");
+ menu_append_item ($1, "\\&verb",
+ "latex_insert_tags (\"\\\\verb|\", \"|\", 1, 1)");
+ menu_append_item ($1, "\\text&normal", "latex_cmd (\"textnormal\", 1)");
+ menu_append_item ($1, "\\un&derline", "latex_cmd (\"underline\", 1)");
+ menu_append_item ($1, "&Delete", "latex_modify_font (\"\")");
+ menu_append_item ($1, "re&Name", "latex_rename_font");
+ % Font popups:
+ % font/size, font/environment, font/math
+ menu_append_popup ($1, "&Size");
+ menu_append_popup ($1, "As &Environment");
+ menu_append_popup ($1, "&Math");
+ $1 = sprintf ("%s.&Font.&Size", menu);
+ menu_append_item ($1, "\\&tiny", "latex_cmd (\"tiny\", 1)");
+ menu_append_item ($1, "\\s&criptsize",
+ "latex_cmd (\"scriptsize\", 1)");
+ menu_append_item ($1, "\\&footnotesize",
+ "latex_cmd (\"footnotesize\", 1)");
+ menu_append_item ($1, "\\&small", "latex_cmd (\"small\", 1)");
+ menu_append_item ($1, "\\&normalsize", "latex_cmd (\"normalsize\", 1)");
+ menu_append_item ($1, "\\&large", "latex_cmd (\"large\", 1)");
+ menu_append_item ($1, "\\&Large", "latex_cmd (\"Large\", 1)");
+ menu_append_item ($1, "\\L&ARGE", "latex_cmd (\"LARGE\", 1)");
+ menu_append_item ($1, "\\&huge", "latex_cmd (\"huge\", 1)");
+ menu_append_item ($1, "\\&Huge", "latex_cmd (\"Huge\", 1)");
+ menu_append_item ($1, "re&Size", "latex_resize_font");
+ % font/environment
+ $1 = sprintf ("%s.&Font.As &Environment", menu);
+ menu_append_item ($1, "&rmfamily",
+ "latex_begin_end (\"rmfamily\", \"\", 1, 1)");
+ menu_append_item ($1, "&itshape",
+ "latex_begin_end (\"itshape\", \"\", 1, 1)");
+ menu_append_item ($1, "&mdseries",
+ "latex_begin_end (\"mdseries\", \"\", 1, 1)");
+ menu_append_item ($1, "&bfseries",
+ "latex_begin_end (\"bfseries\", \"\", 1, 1)");
+ menu_append_item ($1, "&upshape",
+ "latex_begin_end (\"upshape\", \"\", 1, 1)");
+ menu_append_item ($1, "&slshape",
+ "latex_begin_end (\"slshape\", \"\", 1, 1)");
+ menu_append_item ($1, "s&ffamily",
+ "latex_begin_end (\"sffamily\", \"\", 1, 1)");
+ menu_append_item ($1, "s&cshape",
+ "latex_begin_end (\"scshape\", \"\", 1, 1)");
+ menu_append_item ($1, "&ttfamily",
+ "latex_begin_end (\"ttfamily\", \"\", 1, 1)");
+ menu_append_item ($1, "&normalfont",
+ "latex_begin_end (\"normalfont\", \"\", 1, 1)");
+ % font/math
+ $1 = sprintf ("%s.&Font.&Math", menu);
+ menu_append_item ($1, "\\mathr&m", "latex_cmd (\"mathrm\", 1)");
+ menu_append_item ($1, "\\math&bf", "latex_cmd (\"mathbf\", 1)");
+ menu_append_item ($1, "\\math&sf", "latex_cmd (\"mathsf\", 1)");
+ menu_append_item ($1, "\\math&tt", "latex_cmd (\"mathtt\", 1)");
+ menu_append_item ($1, "\\math&it", "latex_font_mathit");
+ menu_append_item ($1, "\\math&normal", "latex_cmd (\"mathnormal\", 1)");
+ menu_append_item ($1, "\\mathversion{bold}",
+ "latex_cmd (\"mathversion{bold}\", 1)");
+ menu_append_item ($1, "\\mathversion{normal}",
+ "latex_cmd (\"mathversion{normal}\", 1)");
+ % sections
+ menu_append_popup (menu, "&Sections");
+ $1 = sprintf ("%s.&Sections", menu);
+ menu_append_item ($1, "\\p&art", "latex_cmd (\"part\", 1)");
+ menu_append_item ($1, "\\&chapter", "latex_cmd (\"chapter\", 1)");
+ menu_append_item ($1, "\\&section", "latex_cmd (\"section\", 1)");
+ menu_append_item ($1, "\\s&ubsection", "latex_cmd (\"subsection\", 1)");
+ menu_append_item ($1, "\\su&bsubsection",
+ "latex_cmd (\"subsubsection\", 1)");
+ menu_append_item ($1, "\\&paragraph", "latex_cmd (\"paragraph\", 1)");
+ menu_append_item ($1, "\\subparagrap&h",
+ "latex_cmd (\"subparagraph\", 1)");
+ % paragraph
+ menu_append_popup (menu, "&Paragraph");
+ $1 = sprintf ("%s.&Paragraph", menu);
+ menu_append_item ($1, "F&ramed Paragraph", "latex_par_frame");
+ menu_append_item ($1, "&background Colour", "latex_par_bgcolour");
+ menu_append_item ($1, "&foreground Colour", "latex_par_fgcolour");
+ menu_append_item ($1, "\\par&indent",
+ "insert (\"\\\\setlength{\\\\parindent}{0pt}\\n\")");
+ menu_append_item ($1, "\\par&skip",
+ "insert (\"\\\\setlength{\\\\parskip}{3pt}\\n\")");
+ menu_append_item ($1, "\\&marginpar",
+ "latex_cmd (\"marginpar\", 1)");
+ menu_append_item ($1, "\\foot&note",
+ "latex_cmd (\"footnote\", 1)");
+ menu_append_item ($1, "\\inc&ludegraphics", "latex_includegraphics");
+ % paragraph popups:
+ % paragraph/margins, paragraph/breaks, paragraph/boxes, paragraph/spaces
+ menu_append_popup ($1, "&Margins");
+ menu_append_popup ($1, "Brea&ks");
+ menu_append_popup ($1, "&Spaces");
+ menu_append_popup ($1, "Bo&xes");
+ $1 = sprintf ("%s.&Paragraph.&Margins", menu);
+ menu_append_item ($1, "\\&leftmargin",
+ "latex_cmd (\"setlength{\\\\leftmargin}\", 1)");
+ menu_append_item ($1, "\\&rightmargin",
+ "latex_cmd (\"setlength{\\\\rightmargin}\", 1)");
+ menu_append_item ($1, "\\&evensidemargin",
+ "latex_cmd (\"setlength{\\\\evensidemargin}\", 1)");
+ menu_append_item ($1, "\\&oddsidemargin",
+ "latex_cmd (\"setlength{\\\\oddsidemargin}\", 1)");
+ menu_append_item ($1, "\\&topmargin",
+ "latex_cmd (\"setlength{\\\\topmargin}\", 1)");
+ menu_append_item ($1, "\\text&width",
+ "latex_cmd (\"setlength{\\\\textwidth}\", 1)");
+ menu_append_item ($1, "\\text&height",
+ "latex_cmd (\"setlength{\\\\textheight}\", 1)");
+ $1 = sprintf ("%s.&Paragraph.Brea&ks", menu);
+ menu_append_item ($1, "\\new&line", "insert (\"\\\\newline\\n\")");
+ menu_append_item ($1, "\\\\&*[]", "latex_linebreak");
+ menu_append_item ($1, "\\line&break", "insert (\"\\\\linebreak[1]\\n\")");
+ menu_append_item ($1, "\\new&page", "insert (\"\\\\newpage\\n\")");
+ menu_append_item ($1, "\\&clearpage", "insert (\"\\\\clearpage\\n\")");
+ menu_append_item ($1, "\\clear&doublepage",
+ "insert (\"\\\\cleardoublepage\\n\")");
+ menu_append_item ($1, "\\pageb&reak", "insert (\"\\\\pagebreak\\n\")");
+ menu_append_item ($1, "\\&nolinebreak",
+ "insert (\"\\\\nolinebreak[1]\\n\")");
+ menu_append_item ($1, "\\n&opagebreak", "insert (\"\\\\nopagebreak\\n\")");
+ menu_append_item ($1, "\\&enlargethispage",
+ "insert (\"\\\\enlargethispage\\n\")");
+ % paragraph/spaces
+ $1 = sprintf ("%s.&Paragraph.&Spaces", menu);
+ menu_append_item ($1, "\\&frenchspacing",
+ "insert (\"\\\\frenchspacing\\n\")");
+ menu_append_item ($1, "\\&@.", "insert (\"\\\\@.\\n\")");
+ menu_append_item ($1, "\\&dotfill", "insert (\"\\\\dotfill\\n\")");
+ menu_append_item ($1, "\\&hfill", "insert (\"\\\\hfill\\n\")");
+ menu_append_item ($1, "\\h&rulefill", "insert (\"\\\\hrulefill\\n\")");
+ menu_append_item ($1, "\\&smallskip", "insert (\"\\\\smallskip\\n\")");
+ menu_append_item ($1, "\\&medskip", "insert (\"\\\\medskip\\n\")");
+ menu_append_item ($1, "\\&bigskip", "insert (\"\\\\bigskip\\n\")");
+ menu_append_item ($1, "\\&vfill", "insert (\"\\\\vfill\\n\")");
+ menu_append_item ($1, "\\hspace", "insert (\"\\\\hspace\\n\")");
+ menu_append_item ($1, "\\vs&pace", "insert (\"\\\\vspace\\n\")");
+ menu_append_item ($1, "Set \\baselines&kip",
+ "insert (\"\\\\baselineskip 2\\\\baselineskip\\n\")");
+ % paragraph/boxes
+ $1 = sprintf ("%s.&Paragraph.Bo&xes", menu);
+ menu_append_item ($1, "\\&fbox", "latex_cmd (\"fbox\", 1)");
+ menu_append_item ($1, "\\f&ramebox",
+ "latex_cmd (\"framebox[\\\\width][c]\", 1)");
+ menu_append_item ($1, "\\&mbox", "latex_cmd (\"mbox\", 1)");
+ menu_append_item ($1, "\\ma&kebox",
+ "latex_cmd (\"makebox[\\\\width][c]\", 1)");
+ menu_append_item ($1, "\\&newsavebox", "latex_cmd (\"newsavebox\", 1)");
+ menu_append_item ($1, "\\ru&le",
+ "latex_cmd (\"rule{\\\\linewidth}\", 1)");
+ menu_append_item ($1, "\\save&box",
+ "latex_cmd (\"savebox{}[\\\\linewidth][c]\", 1)");
+ menu_append_item ($1, "\\&sbox",
+ "latex_cmd (\"sbox{}\", 1)");
+ menu_append_item ($1, "\\&usebox",
+ "latex_cmd (\"usebox\", 1)");
+ % links
+ menu_append_popup (menu, "&Links");
+ $1 = sprintf ("%s.&Links", menu);
+ menu_append_item ($1, "\\&label", "latex_cmd (\"label\", 1)");
+ menu_append_item ($1, "\\&ref", "latex_cmd (\"ref\", 1)");
+ menu_append_item ($1, "\\&cite", "latex_cmd (\"cite\", 1)");
+ menu_append_item ($1, "\\&nocite", "latex_cmd (\"nocite\", 1)");
+ menu_append_item ($1, "\\&url", "latex_url");
+ % index
+ menu_append_popup (menu, "&Index");
+ $1 = sprintf ("%s.&Index", menu);
+ menu_append_item ($1, "\\&index", "latex_cmd (\"index\", 1)");
+ menu_append_item ($1, "\\&index{entry!subentry}", "latex_index_subentry");
+ menu_append_item ($1, "\\&index{entry|(}", "latex_index_beginrange");
+ menu_append_item ($1, "\\&index{entry|)}", "latex_index_endrange");
+ menu_append_item ($1, "\\&index{sortentry@textentry)}",
+ "latex_index_sortorder");
+ menu_append_item ($1, "\\&index{entry|format)}",
+ "latex_index_specialformat");
+ % math
+ menu_append_popup (menu, "&Math");
+ $1 = sprintf ("%s.&Math", menu);
+ % math popups:
+ % math/greek letter, math/accents, math/binary relations,
+ % math/operators, math/arrows, math/misc
+ menu_append_item ($1, "&Toggle Math Mode", "toggle_math_mode");
+ menu_append_item ($1, "&Greek Letter...", "latex_greek_letter");
+ menu_append_item ($1, "&_{} subscript",
+ "latex_insert_tags (\"_{\", \"}\", 1, 1)");
+ menu_append_item ($1, "&^{} superscript",
+ "latex_insert_tags (\"^{\", \"}\", 1, 1)");
+ menu_append_item ($1, "\\&frac",
+ "latex_insert_tags (\"\\\\frac{\", \"}{}\", 1, 1)");
+ menu_append_item ($1, "\\&int",
+ "latex_insert_tags (\"\\\\int_{\", \"}^{}\", 1, 1)");
+ menu_append_item ($1, "\\&lim",
+ "latex_insert_tags (\"\\\\lim_{\", \"}\", 1, 1)");
+ menu_append_item ($1, "\\&oint",
+ "latex_insert_tags (\"\\\\oint_{\", \"}^{}\", 1, 1)");
+ menu_append_item ($1, "\\&prod",
+ "latex_insert_tags (\"\\\\prod_{\", \"}^{}\", 1, 1)");
+ menu_append_item ($1, "\\&sum",
+ "latex_insert_tags (\"\\\\sum_{\", \"}^{}\", 1, 1)");
+ menu_append_item ($1, "\\s&qrt",
+ "latex_insert_tags (\"\\\\sqrt[]{\", \"}\", 1, 1)");
+ menu_append_popup ($1, "&Accents");
+ menu_append_popup ($1, "&Delimiters");
+ menu_append_popup ($1, "&Functions");
+ menu_append_popup ($1, "Binary &Relations");
+ menu_append_popup ($1, "Binary &Operators");
+ menu_append_popup ($1, "S&paces");
+ menu_append_popup ($1, "Arro&ws");
+ menu_append_popup ($1, "&Misc");
+ % math/accents
+ $1 = sprintf ("%s.&Math.&Accents", menu);
+ menu_append_item ($1, "\\hat", "latex_cmd (\"hat\", 1)");
+ menu_append_item ($1, "\\acute", "latex_cmd (\"acute\", 1)");
+ menu_append_item ($1, "\\bar", "latex_cmd (\"bar\", 1)");
+ menu_append_item ($1, "\\dot", "latex_cmd (\"dot\", 1)");
+ menu_append_item ($1, "\\breve", "latex_cmd (\"breve\", 1)");
+ menu_append_item ($1, "\\check", "latex_cmd (\"check\", 1)");
+ menu_append_item ($1, "\\grave", "latex_cmd (\"grave\", 1)");
+ menu_append_item ($1, "\\vec", "latex_cmd (\"vec\", 1)");
+ menu_append_item ($1, "\\ddot", "latex_cmd (\"ddot\", 1)");
+ menu_append_item ($1, "\\tilde", "latex_cmd (\"tilde\", 1)");
+ % constructs
+ menu_append_item ($1, "\\widetilde", "latex_cmd (\"widetilde\", 1)");
+ menu_append_item ($1, "\\widehat", "latex_cmd (\"widehat\", 1)");
+ menu_append_item ($1, "\\overleftarrow",
+ "latex_cmd (\"overleftarrow\", 1)");
+ menu_append_item ($1, "\\overrightarrow",
+ "latex_cmd (\"overrightarrow\", 1)");
+ menu_append_item ($1, "\\overline", "latex_cmd (\"overline\", 1)");
+ menu_append_item ($1, "\\underline", "latex_cmd (\"underline\", 1)");
+ menu_append_item ($1, "\\overbrace", "latex_cmd (\"overbrace\", 1)");
+ menu_append_item ($1, "\\underbrace", "latex_cmd (\"underbrace\", 1)");
+ % math/delimiters
+ $1 = sprintf ("%s.&Math.&Delimiters", menu);
+ menu_append_item ($1, "\\left (", "latex_insert (\"left(\")");
+ menu_append_item ($1, "\\right)", "latex_insert (\"right)\")");
+ menu_append_item ($1, "\\left[", "latex_insert (\"left[\")");
+ menu_append_item ($1, "\\right]", "latex_insert (\"right[\")");
+ menu_append_item ($1, "\\left{", "latex_insert (\"left\\\\{\")");
+ menu_append_item ($1, "\\right}", "latex_insert (\"right\\\\}\")");
+ menu_append_item ($1, "\\rmoustache", "latex_insert (\"rmoustache\")");
+ menu_append_item ($1, "\\lmoustache", "latex_insert (\"lmoustache\")");
+ menu_append_item ($1, "\\rgroup", "latex_insert (\"rgroup\")");
+ menu_append_item ($1, "\\lgroup", "latex_insert (\"lgroup\")");
+ menu_append_item ($1, "\\arrowvert", "latex_insert (\"arrowvert\")");
+ menu_append_item ($1, "\\Arrowvert", "latex_insert (\"Arrowvert\")");
+ menu_append_item ($1, "\\bracevert", "latex_insert (\"bracevert\")");
+ menu_append_item ($1, "\\lfloor", "latex_insert (\"lfloor\")");
+ menu_append_item ($1, "\\rfloor", "latex_insert (\"rfloor\")");
+ menu_append_item ($1, "\\lceil", "latex_insert (\"lceil\")");
+ menu_append_item ($1, "\\rceil", "latex_insert (\"rceil\")");
+ menu_append_item ($1, "\\langle", "latex_insert (\"langle\")");
+ menu_append_item ($1, "\\rangle", "latex_insert (\"rangle\")");
+ menu_append_item ($1, "\\|", "latex_insert (\"\\|\")");
+ % math/functions
+ $1 = sprintf ("%s.&Math.&Functions", menu);
+ menu_append_item ($1, "\\arccos", "latex_loglike (\"\\arccos\")");
+ menu_append_item ($1, "\\arcsin", "latex_loglike (\"\\arcsin\")");
+ menu_append_item ($1, "\\arctan", "latex_loglike (\"\\arctan\")");
+ menu_append_item ($1, "\\arg", "latex_loglike (\"\\arg\")");
+ menu_append_item ($1, "\\cos", "latex_loglike (\"\\cos\")");
+ menu_append_item ($1, "\\cosh", "latex_loglike (\"\\cosh\")");
+ menu_append_item ($1, "\\cot", "latex_loglike (\"\\cot\")");
+ menu_append_item ($1, "\\coth", "latex_loglike (\"\\coth\")");
+ menu_append_item ($1, "\\csc", "latex_loglike (\"\\csc\")");
+ menu_append_item ($1, "\\deg", "latex_loglike (\"\\deg\")");
+ menu_append_item ($1, "\\det", "latex_loglike (\"\\det\")");
+ menu_append_item ($1, "\\dim", "latex_loglike (\"\\dim\")");
+ menu_append_item ($1, "\\exp", "latex_loglike (\"\\exp\")");
+ menu_append_item ($1, "\\gcd", "latex_loglike (\"\\gcd\")");
+ menu_append_item ($1, "\\hom", "latex_loglike (\"\\hom\")");
+ menu_append_item ($1, "\\inf", "latex_loglike (\"\\inf\")");
+ menu_append_item ($1, "\\ker", "latex_loglike (\"\\ker\")");
+ menu_append_item ($1, "\\lg", "latex_loglike (\"\\lg\")");
+ menu_append_item ($1, "\\lim", "latex_loglike (\"\\lim\")");
+ menu_append_item ($1, "\\liminf", "latex_loglike (\"\\liminf\")");
+ menu_append_item ($1, "\\limsup", "latex_loglike (\"\\limsup\")");
+ menu_append_item ($1, "\\ln", "latex_loglike (\"\\ln\")");
+ menu_append_item ($1, "\\log", "latex_loglike (\"\\log\")");
+ menu_append_item ($1, "\\max", "latex_loglike (\"\\max\")");
+ menu_append_item ($1, "\\min", "latex_loglike (\"\\min\")");
+ menu_append_item ($1, "\\Pr", "latex_loglike (\"\\Pr\")");
+ menu_append_item ($1, "\\sec", "latex_loglike (\"\\sec\")");
+ menu_append_item ($1, "\\sin", "latex_loglike (\"\\sin\")");
+ menu_append_item ($1, "\\sinh", "latex_loglike (\"\\sinh\")");
+ menu_append_item ($1, "\\sup", "latex_loglike (\"\\sup\")");
+ menu_append_item ($1, "\\tan", "latex_loglike (\"\\tan\")");
+ menu_append_item ($1, "\\tanh", "latex_loglike (\"\\tanh\")");
+ % math/binary relations
+ $1 = sprintf ("%s.&Math.Binary &Relations", menu);
+ menu_append_item ($1, "\\leq", "latex_insert (\"leq\")");
+ menu_append_item ($1, "\\geq", "latex_insert (\"geq\")");
+ menu_append_item ($1, "\\equiv", "latex_insert (\"equiv\")");
+ menu_append_item ($1, "\\models", "latex_insert (\"models\")");
+ menu_append_item ($1, "\\prec", "latex_insert (\"prec\")");
+ menu_append_item ($1, "\\succ", "latex_insert (\"succ\")");
+ menu_append_item ($1, "\\sim", "latex_insert (\"sim\")");
+ menu_append_item ($1, "\\perp", "latex_insert (\"perp\")");
+ menu_append_item ($1, "\\preceq", "latex_insert (\"preceq\")");
+ menu_append_item ($1, "\\succeq", "latex_insert (\"succeq\")");
+ menu_append_item ($1, "\\simeq", "latex_insert (\"simeq\")");
+ menu_append_item ($1, "\\mid", "latex_insert (\"mid\")");
+ menu_append_item ($1, "\\ll", "latex_insert (\"ll\")");
+ menu_append_item ($1, "\\gg", "latex_insert (\"gg\")");
+ menu_append_item ($1, "\\asymp", "latex_insert (\"asymp\")");
+ menu_append_item ($1, "\\parallel", "latex_insert (\"parallel\")");
+ menu_append_item ($1, "\\subset", "latex_insert (\"subset\")");
+ menu_append_item ($1, "\\supset", "latex_insert (\"supset\")");
+ menu_append_item ($1, "\\approx", "latex_insert (\"approx\")");
+ menu_append_item ($1, "\\bowtie", "latex_insert (\"bowtie\")");
+ menu_append_item ($1, "\\subseteq", "latex_insert (\"subseteq\")");
+ menu_append_item ($1, "\\supseteq", "latex_insert (\"supseteq\")");
+ menu_append_item ($1, "\\cong", "latex_insert (\"cong\")");
+ menu_append_item ($1, "\\Join", "latex_insert (\"Join\")");
+ menu_append_item ($1, "\\sqsubset", "latex_insert (\"sqsubset\")");
+ menu_append_item ($1, "\\sqsupset", "latex_insert (\"sqsupset\")");
+ menu_append_item ($1, "\\neq", "latex_insert (\"neq\")");
+ menu_append_item ($1, "\\smile", "latex_insert (\"smile\")");
+ menu_append_item ($1, "\\sqsubseteq", "latex_insert (\"sqsubseteq\")");
+ menu_append_item ($1, "\\sqsupseteq", "latex_insert (\"sqsupseteq\")");
+ menu_append_item ($1, "\\doteq", "latex_insert (\"doteq\")");
+ menu_append_item ($1, "\\frown", "latex_insert (\"frown\")");
+ menu_append_item ($1, "\\in", "latex_insert (\"in\")");
+ menu_append_item ($1, "\\ni", "latex_insert (\"ni\")");
+ menu_append_item ($1, "\\propto", "latex_insert (\"propto\")");
+ menu_append_item ($1, "\\vdash", "latex_insert (\"vdash \")");
+ menu_append_item ($1, "\\dashv", "latex_insert (\"dashv \")");
+ menu_append_item ($1, "\\not", "latex_insert (\"not \")");
+ % math/binary operators
+ $1 = sprintf ("%s.&Math.Binary &Operators", menu);
+ menu_append_item ($1, "\\pm", "latex_insert (\"pm\")");
+ menu_append_item ($1, "\\cap", "latex_insert (\"cap\")");
+ menu_append_item ($1, "\\diamond", "latex_insert (\"diamond\")");
+ menu_append_item ($1, "\\oplus", "latex_insert (\"oplus\")");
+ menu_append_item ($1, "\\mp", "latex_insert (\"mp\")");
+ menu_append_item ($1, "\\cup", "latex_insert (\"cup\")");
+ menu_append_item ($1, "\\bigtriangleup",
+ "latex_insert (\"bigtriangleup\")");
+ menu_append_item ($1, "\\ominus", "latex_insert (\"ominus\")");
+ menu_append_item ($1, "\\times", "latex_insert (\"times\")");
+ menu_append_item ($1, "\\uplus", "latex_insert (\"uplus\")");
+ menu_append_item ($1, "\\bigtriangledown",
+ "latex_insert (\"bigtriangledown\")");
+ menu_append_item ($1, "\\otimes", "latex_insert (\"otimes\")");
+ menu_append_item ($1, "\\div", "latex_insert (\"div\")");
+ menu_append_item ($1, "\\sqcap", "latex_insert (\"sqcap\")");
+ menu_append_item ($1, "\\triangleleft",
+ "latex_insert (\"triangleleft\")");
+ menu_append_item ($1, "\\oslash", "latex_insert (\"oslash\")");
+ menu_append_item ($1, "\\ast", "latex_insert (\"ast\")");
+ menu_append_item ($1, "\\sqcup", "latex_insert (\"sqcup\")");
+ menu_append_item ($1, "\\triangleright",
+ "latex_insert (\"triangleright\")");
+ menu_append_item ($1, "\\odot", "latex_insert (\"odot\")");
+ menu_append_item ($1, "\\star", "latex_insert (\"star\")");
+ menu_append_item ($1, "\\vee", "latex_insert (\"vee\")");
+ menu_append_item ($1, "\\bigcirc", "latex_insert (\"bigcirc\")");
+ menu_append_item ($1, "\\circ", "latex_insert (\"circ\")");
+ menu_append_item ($1, "\\wedge", "latex_insert (\"wedge\")");
+ menu_append_item ($1, "\\dagger", "latex_insert (\"dagger\")");
+ menu_append_item ($1, "\\bullet", "latex_insert (\"bullet\")");
+ menu_append_item ($1, "\\setminus", "latex_insert (\"setminus\")");
+ menu_append_item ($1, "\\ddagger", "latex_insert (\"ddagger\")");
+ menu_append_item ($1, "\\cdot", "latex_insert (\"cdot\")");
+ menu_append_item ($1, "\\wr", "latex_insert (\"wr\")");
+ menu_append_item ($1, "\\analg", "latex_insert (\"analg\")");
+ % math/spaces
+ $1 = sprintf ("%s.&Math.S&paces", menu);
+ menu_append_item ($1, "\\;", "insert (\"\\\\; \")");
+ menu_append_item ($1, "\\:", "insert (\"\\\\> \")");
+ menu_append_item ($1, "\\,", "insert (\"\\\\, \")");
+ menu_append_item ($1, "\\!", "insert (\"\\\\! \")");
+ % math/arrows
+ $1 = sprintf ("%s.&Math.Arro&ws", menu);
+ menu_append_item ($1, "\\leftarrow", "latex_insert (\"leftarrow\")");
+ menu_append_item ($1, "\\Leftarrow", "latex_insert (\"Leftarrow\")");
+ menu_append_item ($1, "\\longleftarrow",
+ "latex_insert (\"longleftarrow\")");
+ menu_append_item ($1, "\\Longleftarrow",
+ "latex_insert (\"Longleftarrow\")");
+ menu_append_item ($1, "\\rightarrow", "latex_insert (\"rightarrow\")");
+ menu_append_item ($1, "\\longrightarrow",
+ "latex_insert (\"longrightarrow\")");
+ menu_append_item ($1, "\\Rightarrow", "latex_insert (\"Rightarrow\")");
+ menu_append_item ($1, "\\Longrightarrow",
+ "latex_insert (\"Longrightarrow\")");
+ menu_append_item ($1, "\\uparrow", "latex_insert (\"uparrow\")");
+ menu_append_item ($1, "\\Uparrow", "latex_insert (\"Uparrow\")");
+ menu_append_item ($1, "\\downarrow", "latex_insert (\"downarrow\")");
+ menu_append_item ($1, "\\Downarrow", "latex_insert (\"Downarrow\")");
+ menu_append_item ($1, "\\leftrightarrow",
+ "latex_insert (\"leftrightarrow\")");
+ menu_append_item ($1, "\\Leftrightarrow",
+ "latex_insert (\"Leftrightarrow\")");
+ menu_append_item ($1, "\\longleftrightarrow",
+ "latex_insert (\"longleftrightarrow\")");
+ menu_append_item ($1, "\\Longleftrightarrow",
+ "latex_insert (\"Longleftrightarrow\")");
+ menu_append_item ($1, "\\updownarrow", "latex_insert (\"updownarrow\")");
+ menu_append_item ($1, "\\Updownarrow", "latex_insert (\"Updownarrow\")");
+ menu_append_item ($1, "\\mapsto", "latex_insert (\"mapsto\")");
+ menu_append_item ($1, "\\longmapsto", "latex_insert (\"longmapsto\")");
+ menu_append_item ($1, "\\hookleftarrow",
+ "latex_insert (\"hookleftarrow\")");
+ menu_append_item ($1, "\\hookrightarrow",
+ "latex_insert (\"hookrightarrow\")");
+ menu_append_item ($1, "\\leftarpoonup", "latex_insert (\"leftarpoonup\")");
+ menu_append_item ($1, "\\rightarpoonup",
+ "latex_insert (\"rightarpoonup\")");
+ menu_append_item ($1, "\\leftarpoondown",
+ "latex_insert (\"leftarpoondown\")");
+ menu_append_item ($1, "\\rightarpoondown",
+ "latex_insert (\"rightarpoondown\")");
+ menu_append_item ($1, "\\nearrow", "latex_insert (\"nearrow\")");
+ menu_append_item ($1, "\\searrow", "latex_insert (\"searrow\")");
+ menu_append_item ($1, "\\swarrow", "latex_insert (\"swarrow\")");
+ menu_append_item ($1, "\\nwarrow", "latex_insert (\"nwarrow\")");
+ % math/misc
+ $1 = sprintf ("%s.&Math.&Misc", menu);
+ menu_append_item ($1, "\\ldots", "latex_insert (\"ldots\")");
+ menu_append_item ($1, "\\cdots", "latex_insert (\"cdots\")");
+ menu_append_item ($1, "\\vdots", "latex_insert (\"vdots\")");
+ menu_append_item ($1, "\\ddots", "latex_insert (\"ddots\")");
+ menu_append_item ($1, "\\aleph", "latex_insert (\"aleph\")");
+ menu_append_item ($1, "\\prime", "latex_insert (\"prime\")");
+ menu_append_item ($1, "\\forall", "latex_insert (\"forall\")");
+ menu_append_item ($1, "\\infty", "latex_insert (\"infty\")");
+ menu_append_item ($1, "\\hbar", "latex_insert (\"hbar\")");
+ menu_append_item ($1, "\\emptyset", "latex_insert (\"emptyset\")");
+ menu_append_item ($1, "\\exists", "latex_insert (\"exists\")");
+ menu_append_item ($1, "\\nabla", "latex_insert (\"nabla\")");
+ menu_append_item ($1, "\\surd", "latex_insert (\"surd\")");
+ menu_append_item ($1, "\\triangle", "latex_insert (\"triangle\")");
+ menu_append_item ($1, "\\imath", "latex_insert (\"imath\")");
+ menu_append_item ($1, "\\jmath", "latex_insert (\"jmath\")");
+ menu_append_item ($1, "\\ell", "latex_insert (\"ell\")");
+ menu_append_item ($1, "\\neg", "latex_insert (\"neg\")");
+ menu_append_item ($1, "\\top", "latex_insert (\"top\")");
+ menu_append_item ($1, "\\flat", "latex_insert (\"flat\")");
+ menu_append_item ($1, "\\natural", "latex_insert (\"natural\")");
+ menu_append_item ($1, "\\sharp", "latex_insert (\"sharp\")");
+ menu_append_item ($1, "\\wp", "latex_insert (\"wp\")");
+ menu_append_item ($1, "\\bot", "latex_insert (\"bot\")");
+ menu_append_item ($1, "\\clubsuit", "latex_insert (\"clubsuit\")");
+ menu_append_item ($1, "\\diamondsuit", "latex_insert (\"diamondsuit\")");
+ menu_append_item ($1, "\\heartsuit", "latex_insert (\"heartsuit\")");
+ menu_append_item ($1, "\\spadesuit", "latex_insert (\"spadesuit\")");
+ menu_append_item ($1, "\\Re", "latex_insert (\"Re\")");
+ menu_append_item ($1, "\\Im", "latex_insert (\"Im\")");
+ menu_append_item ($1, "\\angle", "latex_insert (\"angle\")");
+ menu_append_item ($1, "\\partial", "latex_insert (\"partial\")");
+ % bibliography
+ menu_append_popup (menu, "Bibliograph&y");
+ $1 = sprintf ("%s.Bibliograph&y", menu);
+ menu_append_item ($1, "&thebibliography",
+ "latex_begin_end (\"thebibliography\", \"{99}\", 1, 1)");
+ menu_append_item ($1, "\\bib&item",
+ "latex_cmd (\"bibitem\", 1)");
+ menu_append_item ($1, "\\&bibliography",
+ "latex_insert (\"bibliography\")");
+ menu_append_item ($1, "\\bibliography&style",
+ "latex_insert (\"bibliographystyle\")");
+ add_files_popup_with_callback (menu, "Mod&ules",
+ LaTeX_Modules_Dir,
+ "\\C^.*\\.sl$");
+ % separator
+ $1 = sprintf ("%s", menu);
+ menu_append_separator ($1);
+ menu_append_item ($1, "&Customise Defaults", "latex_customise");
+ menu_append_item ($1, "Set M&aster File", "latex_master_file");
+ menu_append_item ($1, "Select &Output", "latex_select_output");
+ menu_append_item ($1, "&Compose", "latex_compose");
+ menu_append_item ($1, "&View", "latex_view");
+#ifndef WIN32
+ menu_append_item ($1, "P&rint", "latex_psprint");
+#endif
+ menu_append_item ($1, "&BibTeX", "latex_bibtex");
+ menu_append_item ($1, "Makeinde&x", "latex_makeindex");
+ menu_append_item ($1, "&Document Structure", "latex_browse_tree");
+ menu_append_item ($1, "&Remove Tmp Files", "latex_clearup");
+ menu_append_separator ($1);
+ menu_append_item(menu, "Latex &Info pages",
+ "info_mode(); info_find_node(\"(latex)\");");
+ menu_append_item ($1, "LaTeX Mode &Help", "latex_mode_help");
+}
+
+% The Keymap
+
+% -----
+
+% normally, folding and latex mode are incompatible because of clashing
+% ^Cf... key bindings. I don't want to give up ^Cf, so this key binding
+% can be customized using the following variable.
+
+custom_variable ("LaTeX_Font_Key", "f"); % suggested alternative: "n"
+
+define latex_keymap ()
+{
+ $1 = "LaTeX-Mode";
+ !if (keymap_p ($1))
+ make_keymap ($1);
+ use_keymap ($1);
+
+ % templates - ^CT or ^C^T
+ definekey_reserved ("latex_article", "ta", $1);
+ definekey_reserved ("latex_article", "^T^A", $1);
+ definekey_reserved ("latex_book", "tb", $1);
+ definekey_reserved ("latex_book", "^T^B", $1);
+ definekey_reserved ("latex_letter", "tl", $1);
+ definekey_reserved ("latex_letter", "^T^L", $1);
+ definekey_reserved ("latex_report", "tr", $1);
+ definekey_reserved ("latex_report", "^T^R", $1);
+ definekey_reserved ("latex_slides", "ts", $1);
+ definekey_reserved ("latex_slides", "^T^S", $1);
+ definekey_reserved ("latex_notice", "tn", $1);
+ definekey_reserved ("latex_notice", "^T^N", $1);
+ % environments - ^CE
+ definekey_reserved ("latex_begin_end (\"array\", \"{ll}\", 1, 1)",
+ "ea", $1);
+ definekey_reserved ("latex_begin_end (\"array\", \"{ll}\", 1, 1)",
+ "^E^A", $1);
+ definekey_reserved ("latex_begin_end (\"center\", \"\", 1, 1)", "ec", $1);
+ definekey_reserved ("latex_begin_end (\"center\", \"\", 1, 1)", "^E^C", $1);
+ definekey_reserved ("latex_env_itemize (\"description\")",
+ "ed", $1);
+ definekey_reserved ("latex_env_itemize (\"description\")",
+ "^E^D", $1);
+ definekey_reserved ("latex_begin_end (\"displaymath\", \"\", 1, 1)",
+ "eh", $1);
+ definekey_reserved ("latex_begin_end (\"displaymath\", \"\", 1, 1)",
+ "^E^H", $1);
+ definekey_reserved ("latex_begin_end (\"enumerate\", \"\", 1, 1)",
+ "ee", $1);
+ definekey_reserved ("latex_begin_end (\"enumerate\", \"\", 1, 1)",
+ "^E^E", $1);
+ definekey_reserved ("latex_begin_end (\"eqnarray\", \"\", 1, 1)",
+ "en", $1);
+ definekey_reserved ("latex_begin_end (\"eqnarray\", \"\", 1, 1)",
+ "^E^N", $1);
+ definekey_reserved ("latex_begin_end (\"equation\", \"\", 1, 1)",
+ "eq", $1);
+ definekey_reserved ("latex_begin_end (\"equation\", \"\", 1, 1)",
+ "^E^Q", $1);
+ definekey_reserved ("latex_env_figure ()", "ef", $1);
+ definekey_reserved ("latex_env_figure ()", "^E^F", $1);
+ definekey_reserved ("latex_begin_end (\"flushleft\", \"\", 1, 1)",
+ "el", $1);
+ definekey_reserved ("latex_begin_end (\"flushright\", \"\", 1, 1)",
+ "eR", $1);
+ definekey_reserved ("latex_env_item", "ei", $1);
+ definekey_reserved ("latex_env_item", "^E^I", $1);
+ definekey_reserved ("latex_env_itemize (\"itemize\")", "eI", $1);
+ % definekey_reserved ("latex_env_letter", "eL", $1);
+ definekey_reserved ("latex_begin_end (\"list\", \"\", 1, 1)", "eL", $1);
+ definekey_reserved ("latex_begin_end (\"list\", \"\", 1, 1)", "^E^L", $1);
+ definekey_reserved ("latex_begin_end (\"minipage\"," +
+ " \"[c]{\\\\linewidth}\", 1, 1)", "em", $1);
+ definekey_reserved ("latex_begin_end (\"minipage\"," +
+ " \"[c]{\\\\linewidth}\", 1, 1)", "^E^M", $1);
+ definekey_reserved ("latex_begin_end (\"picture\", \"\", 1, 1)",
+ "ep", $1);
+ definekey_reserved ("latex_begin_end (\"picture\", \"\", 1, 1)",
+ "^E^P", $1);
+ definekey_reserved ("latex_begin_end (\"quotation\", \"\", 1, 1)",
+ "eQ", $1);
+ definekey_reserved ("latex_begin_end (\"quote\", \"\", 1, 1)", "eo", $1);
+ definekey_reserved ("latex_begin_end (\"quote\", \"\", 1, 1)", "^E^O", $1);
+ definekey_reserved ("latex_begin_end (\"tabbing\", \"\", 1, 1)", "eb", $1);
+ definekey_reserved ("latex_begin_end (\"tabbing\", \"\", 1, 1)",
+ "^E^B", $1);
+ definekey_reserved ("latex_table_template (1)", "eu", $1);
+ definekey_reserved ("latex_table_template (1)", "^E^U", $1);
+ definekey_reserved ("latex_table_template (0)", "et", $1);
+ definekey_reserved ("latex_table_template (0)", "^E^T", $1);
+ definekey_reserved ("latex_table_row (1)", "er", $1);
+ definekey_reserved ("latex_table_row (1)", "^E^R", $1);
+ definekey_reserved ("latex_begin_end (\"thebibliography\", \"{99}\", 1, 1)",
+ "ey", $1);
+ definekey_reserved ("latex_begin_end (\"thebibliography\", \"{99}\", 1, 1)",
+ "^E^Y", $1);
+ definekey_reserved ("latex_begin_end (\"theorem\", \"\", 1, 1)", "eH", $1);
+ definekey_reserved ("latex_begin_end (\"titlepage\", \"\", 1, 1)",
+ "eg", $1);
+ definekey_reserved ("latex_begin_end (\"titlepage\", \"\", 1, 1)",
+ "^E^G", $1);
+ definekey_reserved ("latex_begin_end (\"verbatim\", \"\", 1, 1)",
+ "ev", $1);
+ definekey_reserved ("latex_begin_end (\"verbatim\", \"\", 1, 1)",
+ "^E^V", $1);
+ definekey_reserved ("latex_begin_end (\"verse\", \"\", 1, 1)", "es", $1);
+ definekey_reserved ("latex_begin_end (\"verse\", \"\", 1, 1)", "^E^S", $1);
+ definekey_reserved ("latex_env_custom", "eC", $1);
+ definekey_reserved ("latex_rename_environment", "eN", $1);
+ definekey_reserved ("latex_indent_environment", "eD", $1);
+ definekey_reserved ("latex_complete_environment", "e\t", $1);
+ % fonts - ^CF (normally)
+ definekey_reserved ("latex_cmd (\"textrm\", 1)", LaTeX_Font_Key + "r", $1);
+ definekey_reserved ("latex_cmd (\"textit\", 1)", LaTeX_Font_Key + "i", $1);
+ definekey_reserved ("latex_cmd (\"emph\", 1)", LaTeX_Font_Key + "e", $1);
+ definekey_reserved ("latex_cmd (\"textmd\", 1)", LaTeX_Font_Key + "m", $1);
+ definekey_reserved ("latex_cmd (\"textbf\", 1)", LaTeX_Font_Key + "b", $1);
+ definekey_reserved ("latex_cmd (\"textup\", 1)", LaTeX_Font_Key + "u", $1);
+ definekey_reserved ("latex_cmd (\"textsl\", 1)", LaTeX_Font_Key + "s", $1);
+ definekey_reserved ("latex_cmd (\"textsf\", 1)", LaTeX_Font_Key + "f", $1);
+ definekey_reserved ("latex_cmd (\"textsc\", 1)", LaTeX_Font_Key + "c", $1);
+ definekey_reserved ("latex_cmd (\"texttt\", 1)", LaTeX_Font_Key + "t", $1);
+ definekey_reserved ("latex_insert_tags (\"\\\\verb|\", \"|\", 1, 1)",
+ LaTeX_Font_Key + "v", $1);
+ definekey_reserved ("latex_cmd (\"textnormal\", 1)",
+ LaTeX_Font_Key + "n", $1);
+ definekey_reserved ("latex_cmd (\"underline\", 1)",
+ LaTeX_Font_Key + "d", $1);
+ definekey_reserved ("latex_modify_font (\"\")", LaTeX_Font_Key + "D", $1);
+ definekey_reserved ("latex_rename_font", LaTeX_Font_Key + "N", $1);
+ definekey_reserved ("latex_cmd (\"textrm\", 1)", LaTeX_Font_Key + "^R", $1);
+% definekey_reserved ("latex_cmd (\"textit\", 1)", LaTeX_Font_Key + "^I", $1);
+ definekey_reserved ("latex_cmd (\"emph\", 1)", LaTeX_Font_Key + "^E", $1);
+ definekey_reserved ("latex_cmd (\"textmd\", 1)", LaTeX_Font_Key + "^M", $1);
+ definekey_reserved ("latex_cmd (\"textbf\", 1)", LaTeX_Font_Key + "^B", $1);
+ definekey_reserved ("latex_cmd (\"textup\", 1)", LaTeX_Font_Key + "^U", $1);
+ definekey_reserved ("latex_cmd (\"textsl\", 1)", LaTeX_Font_Key + "^S", $1);
+ definekey_reserved ("latex_cmd (\"textsf\", 1)", LaTeX_Font_Key + "^F", $1);
+ definekey_reserved ("latex_cmd (\"textsc\", 1)", LaTeX_Font_Key + "^C", $1);
+ definekey_reserved ("latex_cmd (\"texttt\", 1)", LaTeX_Font_Key + "^T", $1);
+ definekey_reserved ("latex_insert_tags (\"\\\\verb|\", \"|\", 1, 1)",
+ LaTeX_Font_Key + "^V", $1);
+ definekey_reserved ("latex_cmd (\"textnormal\", 1)",
+ LaTeX_Font_Key + "^N", $1);
+ definekey_reserved ("latex_cmd (\"underline\", 1)",
+ LaTeX_Font_Key + "^D", $1);
+ definekey_reserved ("latex_insert_font", LaTeX_Font_Key + "^I", $1);
+ % font size - ^CZ
+ definekey_reserved ("latex_cmd (\"tiny\", 1)", "zt", $1);
+ definekey_reserved ("latex_cmd (\"tiny\", 1)", "^Z^T", $1);
+ definekey_reserved ("latex_cmd (\"scriptsize\", 1)", "zc", $1);
+ definekey_reserved ("latex_cmd (\"scriptsize\", 1)", "^Z^C", $1);
+ definekey_reserved ("latex_cmd (\"footnotesize\", 1)", "zf", $1);
+ definekey_reserved ("latex_cmd (\"footnotesize\", 1)", "^Z^F", $1);
+ definekey_reserved ("latex_cmd (\"small\", 1)", "zs", $1);
+ definekey_reserved ("latex_cmd (\"small\", 1)", "^Z^S", $1);
+ definekey_reserved ("latex_cmd (\"normalsize\", 1)", "zn", $1);
+ definekey_reserved ("latex_cmd (\"normalsize\", 1)", "^Z^N", $1);
+ definekey_reserved ("latex_cmd (\"large\", 1)", "zl", $1);
+ definekey_reserved ("latex_cmd (\"large\", 1)", "^Z^L", $1);
+ definekey_reserved ("latex_cmd (\"Large\", 1)", "zL", $1);
+ definekey_reserved ("latex_cmd (\"LARGE\", 1)", "zA", $1);
+ definekey_reserved ("latex_cmd (\"LARGE\", 1)", "^Z^A", $1);
+ definekey_reserved ("latex_cmd (\"huge\", 1)", "zh", $1);
+ definekey_reserved ("latex_cmd (\"huge\", 1)", "^Z^H", $1);
+ definekey_reserved ("latex_cmd (\"Huge\", 1)", "zH", $1);
+ definekey_reserved ("latex_resize_font", "zS", $1);
+ % sections - ^CS
+ definekey_reserved ("latex_cmd (\"chapter\", 1)", "sc", $1);
+ definekey_reserved ("latex_cmd (\"chapter\", 1)", "^S^C", $1);
+ definekey_reserved ("latex_cmd (\"section\", 1)", "ss", $1);
+ definekey_reserved ("latex_cmd (\"section\", 1)", "^S^S", $1);
+ definekey_reserved ("latex_cmd (\"subsection\", 1)", "su", $1);
+ definekey_reserved ("latex_cmd (\"subsection\", 1)", "^S^U", $1);
+ definekey_reserved ("latex_cmd (\"subsubsection\", 1)", "sb", $1);
+ definekey_reserved ("latex_cmd (\"subsubsection\", 1)", "^S^B", $1);
+ definekey_reserved ("latex_cmd (\"paragraph\", 1)", "sp", $1);
+ definekey_reserved ("latex_cmd (\"paragraph\", 1)", "^S^P", $1);
+ definekey_reserved ("latex_cmd (\"subparagraph\", 1)", "sh", $1);
+ definekey_reserved ("latex_cmd (\"subparagraph\", 1)", "^S^H", $1);
+ definekey_reserved ("latex_cmd (\"part\", 1)", "sa", $1);
+ definekey_reserved ("latex_cmd (\"part\", 1)", "^S^A", $1);
+ % paragraphs - ^CP
+ definekey_reserved ("latex_par_frame", "pr", $1);
+ definekey_reserved ("latex_par_frame", "^P^R", $1);
+ definekey_reserved ("latex_par_bgcolour", "pb", $1);
+ definekey_reserved ("latex_par_bgcolour", "^P^B", $1);
+ definekey_reserved ("latex_par_fgcolour", "pf", $1);
+ definekey_reserved ("latex_par_fgcolour", "^P^F", $1);
+ definekey_reserved ("insert (\"\\\\setlength{\\\\parindent}{0pt}\\n\")",
+ "pi", $1);
+ definekey_reserved ("insert (\"\\\\setlength{\\\\parindent}{0pt}\\n\")",
+ "^P^I", $1);
+ definekey_reserved ("insert (\"\\\\setlength{\\\\parskip}{3pt}\\n\")",
+ "ps", $1);
+ definekey_reserved ("insert (\"\\\\setlength{\\\\parskip}{3pt}\\n\")",
+ "^P^S", $1);
+ definekey_reserved ("latex_cmd (\"marginpar\", 1)", "pm", $1);
+ definekey_reserved ("latex_cmd (\"marginpar\", 1)", "^P^M", $1);
+ definekey_reserved ("latex_cmd (\"footnote\", 1)", "pn", $1);
+ definekey_reserved ("latex_cmd (\"footnote\", 1)", "^P^N", $1);
+ definekey_reserved ("latex_includegraphics", "pl", $1);
+ definekey_reserved ("latex_includegraphics", "^P^L", $1);
+ % links - ^CL
+ definekey_reserved ("latex_cmd (\"label\", 1)", "ll", $1);
+ definekey_reserved ("latex_cmd (\"label\", 1)", "^L^L", $1);
+ definekey_reserved ("latex_cmd (\"ref\", 1)", "lr", $1);
+ definekey_reserved ("latex_cmd (\"ref\", 1)", "^L^R", $1);
+ definekey_reserved ("latex_cmd (\"cite\", 1)", "lc", $1);
+ definekey_reserved ("latex_cmd (\"cite\", 1)", "^L^C", $1);
+ definekey_reserved ("latex_cmd (\"nocite\", 1)", "ln", $1);
+ definekey_reserved ("latex_cmd (\"nocite\", 1)", "^L^N", $1);
+ definekey_reserved ("latex_cmd (\"pageref\", 1)", "lp", $1);
+ definekey_reserved ("latex_cmd (\"pageref\", 1)", "^L^P", $1);
+ definekey_reserved ("latex_url", "lu", $1);
+ definekey_reserved ("latex_url", "^L^U", $1);
+ definekey_reserved ("latex_index_word", "ii", $1);
+ % math common stuff
+ definekey_reserved ("latex_insert_tags (\"\\\\frac{\", \"}{}\", 1, 1)",
+ "Mf", $1);
+ definekey_reserved ("latex_insert_tags (\"\\\\int_{\", \"}^{}\", 1, 1)",
+ "Mi", $1);
+ definekey_reserved ("latex_insert_tags (\"\\\\lim_{\", \"}\", 1, 1)",
+ "Ml", $1);
+ definekey_reserved ("latex_insert_tags (\"\\\\oint_{\", \"}^{}\", 1, 1)",
+ "Mo", $1);
+ definekey_reserved ("latex_insert_tags (\"\\\\prod_{\", \"}^{}\", 1, 1)",
+ "Mp", $1);
+ definekey_reserved ("latex_insert_tags (\"\\\\sum_{\", \"}^{}\", 1, 1)",
+ "Ms", $1);
+ definekey_reserved ("latex_insert_tags (\"\\\\sqrt[]{\", \"}\", 1, 1)",
+ "Mq", $1);
+ % math arrows - ^C + arrow
+ definekey_reserved ("latex_insert (\"uparrow\")", Key_Up, $1);
+ definekey_reserved ("latex_insert (\"downarrow\")", Key_Down, $1);
+ definekey_reserved ("latex_insert (\"leftarrow\")", Key_Left, $1);
+ definekey_reserved ("latex_insert (\"rightarrow\")", Key_Right, $1);
+ % breaks - ^CK
+ definekey_reserved ("latex_linebreak", "k*", $1);
+ definekey_reserved ("latex_linebreak", "^K^*", $1);
+ definekey_reserved ("insert (\"\\\\newline\\n\")", "kl", $1);
+ definekey_reserved ("insert (\"\\\\newline\\n\")", "^K^L", $1);
+ definekey_reserved ("insert (\"\\\\linebreak[1]\\n\")", "kb", $1);
+ definekey_reserved ("insert (\"\\\\linebreak[1]\\n\")", "^K^B", $1);
+ definekey_reserved ("insert (\"\\\\newpage\\n\")", "kp", $1);
+ definekey_reserved ("insert (\"\\\\newpage\\n\")", "^K^P", $1);
+ definekey_reserved ("insert (\"\\\\clearpage\\n\")", "kc", $1);
+ definekey_reserved ("insert (\"\\\\clearpage\\n\")", "^K^C", $1);
+ definekey_reserved ("insert (\"\\\\cleardoublepage\\n\")", "kd", $1);
+ definekey_reserved ("insert (\"\\\\cleardoublepage\\n\")", "^K^D", $1);
+ definekey_reserved ("insert (\"\\\\pagebreak\\n\")", "kr", $1);
+ definekey_reserved ("insert (\"\\\\pagebreak\\n\")", "^K^R", $1);
+ definekey_reserved ("insert (\"\\\\nolinebreak[1]\\n\")", "kn", $1);
+ definekey_reserved ("insert (\"\\\\nolinebreak[1]\\n\")", "^K^N", $1);
+ definekey_reserved ("insert (\"\\\\nopagebreak\\n\")", "ko", $1);
+ definekey_reserved ("insert (\"\\\\nopagebreak\\n\")", "^K^O", $1);
+ definekey_reserved ("insert (\"\\\\enlargethispage\\n\")", "ke", $1);
+ definekey_reserved ("insert (\"\\\\enlargethispage\\n\")", "^K^E", $1);
+ % misc
+ definekey_reserved ("latex_insert_tags (\"{\", \"}\", 1, 1)", "{", $1);
+ definekey_reserved ("latex_insert_math", "m", $1);
+ % from tex.sl
+ definekey_reserved ("latex_insert_tags (\"``\", \"''\", 1, 1)", "\"", $1);
+ %definekey_reserved ("latex_insert_tags (\"`\", \"'\", 1, 1)", "'", $1);
+ definekey ("tex_insert_quote", "\"", $1);
+ definekey ("tex_insert_quote", "'", $1);
+ definekey ("tex_blink_dollar", "$", $1);
+ definekey ("tex_ldots", ".", $1);
+ definekey ("latex_arrow", ">", $1);
+ definekey ("latex_arrow", "-", $1);
+ definekey ("latex_arrow", "=", $1);
+ definekey ("tex_complete_symbol", "^[^I", $1); % from the old latex.sl
+ definekey ("tex_complete_symbol", "^[v", $1);
+ definekey ("tex_complete_symbol", "^[V", $1);
+ definekey_reserved ("latex_open_env", "[", $1);
+ definekey_reserved ("latex_close_env", "]", $1);
+ definekey_reserved ("call (\"newline_and_indent\"); latex_env_item",
+ "^M", $1);
+ % special characters
+ undefinekey ("^I", $1);
+ definekey ("latex_indent_line", "^I", $1);
+ definekey_reserved (" \\$", "$", $1);
+ definekey_reserved (" \\&", "&", $1);
+ definekey_reserved (" \\%", "%", $1);
+ definekey_reserved (" \\_", "_", $1);
+ definekey_reserved (" \\#", "#", $1);
+ definekey_reserved (" \\{", "(", $1);
+ definekey_reserved (" \\}", ")", $1);
+ definekey_reserved (" \\textless{}", "<", $1);
+ definekey_reserved (" \\textgreater{}", ">", $1);
+ definekey_reserved (" \\textbackslash{}", "\\", $1);
+ definekey_reserved (" \\textbar{}", "|", $1);
+ definekey_reserved (" \\textasciicircum{}", "^", $1);
+ definekey_reserved (" \\textasciitilde{}", "~", $1);
+ % final stuff
+ definekey_reserved ("latex_customise", "C", $1);
+ definekey_reserved ("latex_customise", "^C", $1);
+ definekey_reserved ("latex_master_file", "a", $1);
+ definekey_reserved ("latex_master_file", "^A", $1);
+ definekey_reserved ("latex_select_output", "o", $1);
+ definekey_reserved ("latex_select_output", "^O", $1);
+ definekey_reserved ("latex_compose", "c", $1);
+ definekey_reserved ("latex_compose", "^C", $1);
+ definekey_reserved ("latex_view", "v", $1);
+ definekey_reserved ("latex_view", "^V", $1);
+ definekey_reserved ("latex_psprint", "r", $1);
+ definekey_reserved ("latex_psprint", "^R", $1);
+ definekey_reserved ("latex_bibtex", "I", $1);
+ definekey_reserved ("latex_bibtex", "^I", $1);
+ definekey_reserved ("latex_makeindex", "x", $1);
+ definekey_reserved ("latex_makeindex", "^X", $1);
+ definekey_reserved ("latex_browse_tree", "d", $1);
+ definekey_reserved ("latex_browse_tree", "^D", $1);
+ definekey_reserved ("latex_clearup", "R", $1);
+ % help
+ definekey_reserved ("latex_info_help", "h", $1);
+ definekey_reserved ("latex_info_help", "^H", $1);
+ % compiling + errors
+ local_unsetkey (Key_F9);
+ local_setkey ("latex_compose", Key_F9);
+ local_unsetkey (Key_F8);
+ local_setkey ("latex_view", Key_F8);
+ local_unsetkey (_Reserved_Key_Prefix + "'");
+ definekey_reserved ("find_next_error", "'", $1);
+ % move by paragraphs
+ definekey_reserved ("latex_goto_next_paragraph", Key_Right, $1);
+ definekey_reserved ("latex_goto_prev_paragraph", Key_Left, $1);
+}
+
+% -----
+
+$1 = "LaTeX-Mode";
+create_syntax_table ($1);
+
+define_syntax ("%", "", '%', $1); % Comment Syntax
+define_syntax ('\\', '\\', $1); % Quote character
+define_syntax ('$', '"', $1); % string
+define_syntax ("~^_&#", '+', $1); % operators
+define_syntax ("|&{}[]", ',', $1); % delimiters
+define_syntax ("a-zA-Z@", 'w', $1);
+set_syntax_flags ($1, 8);
+
+% Currently, DFA syntax highlighting doesn't span multiple lines.
+
+#ifdef HAS_DFA_SYNTAX
+%%% DFA_CACHE_BEGIN %%%
+static define setup_dfa_callback (name)
+{
+ dfa_enable_highlight_cache ("latex.dfa", name);
+
+ % comments:
+ dfa_define_highlight_rule ("%.*$", "comment", name);
+
+ % known keywords in curly braces
+ dfa_define_highlight_rule ("{article}", "Qstring", name);
+ dfa_define_highlight_rule ("{book}", "Qstring", name);
+ dfa_define_highlight_rule ("{letter}", "Qstring", name);
+ dfa_define_highlight_rule ("{report}", "Qstring", name);
+ dfa_define_highlight_rule ("{slides}", "Qstring", name);
+ dfa_define_highlight_rule ("{document}", "Qstring", name);
+ % environments
+ dfa_define_highlight_rule ("{abstract}", "Qstring", name);
+ dfa_define_highlight_rule ("{array}", "Qstring", name);
+ dfa_define_highlight_rule ("{center}", "Qstring", name);
+ dfa_define_highlight_rule ("{description}", "Qstring", name);
+ dfa_define_highlight_rule ("{displaymath}", "Qstring", name);
+ dfa_define_highlight_rule ("{enumerate}", "Qstring", name);
+ dfa_define_highlight_rule ("{eqnarray}", "Qstring", name);
+ dfa_define_highlight_rule ("{equation}", "Qstring", name);
+ dfa_define_highlight_rule ("{figure}", "Qstring", name);
+ dfa_define_highlight_rule ("{flushleft}", "Qstring", name);
+ dfa_define_highlight_rule ("{flushright}", "Qstring", name);
+ dfa_define_highlight_rule ("{itemize}", "Qstring", name);
+ dfa_define_highlight_rule ("{list}", "Qstring", name);
+ dfa_define_highlight_rule ("{minipage}", "Qstring", name);
+ dfa_define_highlight_rule ("{picture}", "Qstring", name);
+ dfa_define_highlight_rule ("{quotation}", "Qstring", name);
+ dfa_define_highlight_rule ("{quote}", "Qstring", name);
+ dfa_define_highlight_rule ("{tabbing}", "Qstring", name);
+ dfa_define_highlight_rule ("{table}", "Qstring", name);
+ dfa_define_highlight_rule ("{tabular}", "Qstring", name);
+ dfa_define_highlight_rule ("{thebibliography}", "Qstring", name);
+ dfa_define_highlight_rule ("{theorem}", "Qstring", name);
+ dfa_define_highlight_rule ("{titlepage}", "Qstring", name);
+ dfa_define_highlight_rule ("{verbatim}", "Qstring", name);
+ dfa_define_highlight_rule ("{verse}", "Qstring", name);
+ % font family
+ dfa_define_highlight_rule ("{rmfamily}", "Qkeyword2", name);
+ dfa_define_highlight_rule ("{itshape}", "Qkeyword2", name);
+ dfa_define_highlight_rule ("{mdseries}", "Qkeyword2", name);
+ dfa_define_highlight_rule ("{bfseries}", "Qkeyword2", name);
+ dfa_define_highlight_rule ("{upshape}", "Qkeyword2", name);
+ dfa_define_highlight_rule ("{slshape}", "Qkeyword2", name);
+ dfa_define_highlight_rule ("{sffamily}", "Qkeyword2", name);
+ dfa_define_highlight_rule ("{scshape}", "Qkeyword2", name);
+ dfa_define_highlight_rule ("{ttfamily}", "Qkeyword2", name);
+ dfa_define_highlight_rule ("{normalfont}", "Qkeyword2", name);
+
+ % everithing else between curly braces
+ % !!! doesn't span multiple lines !!!
+ dfa_define_highlight_rule ("{.*}", "Qkeyword1", name);
+ dfa_define_highlight_rule("^([^{])*}", "Qkeyword1", name);
+ dfa_define_highlight_rule("{.*", "keyword1", name);
+
+ % short symbols that delimit math: $ \[ \] \( \)
+ dfa_define_highlight_rule ("\\$|(\\\\[\\[\\]\\(\\)])", "string", name);
+
+ % Fundamental delimiters in the TeX language: {}[]
+ dfa_define_highlight_rule ("[{}\\[\\]]", "delimiter", name);
+
+ % \leftX \rightY constructions where X and Y are
+ % one of \| \{ \} [ ] ( ) / | .
+ dfa_define_highlight_rule ("\\\\(left|right)(\\\\\\||\\\\{|\\\\}|" +
+ "[\\[\\]\\(\\)/\\|\\.])",
+ "delimiter", name);
+
+ % type 2 keywords: font definitions
+ dfa_define_highlight_rule ("\\\\bfseries", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\emph", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\itshape", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\mathbf", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\mathcal", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\mathit", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\mathnormal", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\mathrm", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\mathsf", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\mathtt", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\mdseries", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\normalfont", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\rmfamily", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\scshape", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\sffamily", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\slshape", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\textbf", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\textit", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\textmd", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\textnormal", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\textrm", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\textsc", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\textsf", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\textsl", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\texttt", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\textup", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\ttfamily", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\upshape", "keyword2", name);
+ % size
+ dfa_define_highlight_rule ("\\\\tiny", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\scriptsize", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\footnotesize", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\small", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\normalsize", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\large", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\Large", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\LARGE", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\huge", "keyword2", name);
+ dfa_define_highlight_rule ("\\\\Huge", "keyword2", name);
+
+ % type 1 keywords: a backslash followed by
+ % one of -,:;!%$#&_ |\/{}~^´'``.=> :
+ dfa_define_highlight_rule ("\\\\[\\-,:;!%\\$#&_ \\|\\\\/{}~\\^'`\\.=>]",
+ "keyword1", name);
+
+ % type 0 keywords: a backslash followed by alpha characters
+ dfa_define_highlight_rule ("\\\\[A-Za-z@]+", "keyword", name);
+
+ % a backslash followed by a single char not covered by one of the
+ % previous rules is probably an error
+ dfa_define_highlight_rule ("\\\\.", "error", name);
+
+ % The symbols ~ ^ _
+ dfa_define_highlight_rule ("[~\\^_]", "operator", name);
+
+ % numbers
+ dfa_define_highlight_rule ("[0-9]", "number", name);
+ dfa_define_highlight_rule ("\\.?[0-9]", "number", name);
+
+ % macro parameters (#1 #2 etc)
+ dfa_define_highlight_rule ("#[1-9]", "operator", name);
+
+ % quoted strings
+ dfa_define_highlight_rule ("``.*''", "Qstring", name);
+ dfa_define_highlight_rule("^([^``])*''", "Qstring", name);
+ dfa_define_highlight_rule("``.*", "string", name);
+ % only one case with single quotes
+ dfa_define_highlight_rule ("`.*'", "Qstring", name);
+
+ % all the rest
+ dfa_define_highlight_rule (".", "normal", name);
+
+ dfa_build_highlight_table (name);
+}
+dfa_set_init_callback (&setup_dfa_callback, "LaTeX-Mode");
+%%% DFA_CACHE_END %%%
+#endif
+
+% -----
+
+%!%+
+%\function{latex_mode}
+%\synopsis{latex_mode}
+%\usage{Void latex_mode ();}
+%\description
+% This mode is designed to facilitate the task of editing LaTeX files.
+% It calls the function \var{latex_mode_hook} if it is defined. In addition,
+% if the abbreviation table \var{"TeX"} is defined, that table is used.
+%
+% There are way too many key-bindings for this mode.
+% Please have a look at the menus!
+%!%-
+public define latex_mode ()
+{
+ latex_keymap ();
+ set_mode ("LaTeX", 0x1 | 0x20);
+ set_buffer_hook ("par_sep", "tex_paragraph_separator");
+ set_buffer_hook ("wrap_hook", "tex_wrap_hook");
+
+ % latex math mode will map this to something else.
+ local_unsetkey ("`");
+ local_setkey ("quoted_insert", "`");
+
+ mode_set_mode_info ("LaTeX", "init_mode_menu", &init_menu);
+ use_syntax_table ("LaTeX-Mode");
+ mode_set_mode_info ("LaTeX", "fold_info", "%{{{\r%}}}\r\r");
+ run_mode_hooks ("latex_mode_hook");
+ if (abbrev_table_p ("LaTeX"))
+ use_abbrev_table ("LaTeX");
+}
+
+% -----
+
+provide ("latex");
+
+% --- End of file latex.sl
diff --git a/support/jed/latex4jed/latex4jed.pdf b/support/jed/latex4jed/latex4jed.pdf
new file mode 100644
index 0000000000..7406bb80a6
--- /dev/null
+++ b/support/jed/latex4jed/latex4jed.pdf
Binary files differ
diff --git a/support/jed/latex4jed/latex4jed.tex b/support/jed/latex4jed/latex4jed.tex
new file mode 100644
index 0000000000..d453f7738c
--- /dev/null
+++ b/support/jed/latex4jed/latex4jed.tex
@@ -0,0 +1,820 @@
+% latex4jed.tex -*- LaTeX -*-
+%
+% By Guido Gonzato, guido.gonzato@univr.it
+%
+% Date: 20 February 2004
+
+\documentclass[11pt]{article}
+\usepackage{alltt}
+\usepackage{texnames}
+\usepackage[colorlinks,urlcolor=blue]{hyperref}
+
+% -----
+
+\newcommand{\version}{1.4.4}
+\newcommand{\bl}{\textbackslash{}}
+\newcommand{\key}[1]{\texttt{$\langle$#1$\rangle$}}
+\newcommand{\chr}[1]{\texttt{`#1'}}
+
+% doesn't it deserve its very own logo?
+\def\LJ{\LaTeX\kern-.2em\raise.5ex\hbox%
+{\sc 4}\kern-.2em\textsc{Jed}}
+
+% -----
+
+\begin{document}
+
+\title{\LJ: an enhanced \LaTeX{} mode for Jed}
+
+\author{Version \version\\
+Guido `goccia' Gonzato, Ph.D.\\
+\url{guido, dot, gonzato, at, univr, dot, it}}
+
+\date{Universit\`a di Verona (Italy)\\
+Facolt\`a di Scienze MM. FF. NN.\\
+\today}
+
+\maketitle
+
+\begin{abstract}
+ The Jed editor supports several programming languages and text formats,
+ including \LaTeX. However, the author of this document feels that the
+ default library file \texttt{latex.sl} is too simple, and that it could be
+ improved in many ways.
+
+ This document describes an enhanced \texttt{latex.sl}, which aims at
+ making the process of writing \LaTeX{} documents an easy and pleasant
+ task. Inspired by Emacs' AUC-\TeX, the new \texttt{latex.sl} provides
+ the user with menus, templates, many utilities, and integrated
+ conversion and previewing of \LaTeX{} documents.
+\end{abstract}
+
+\small
+\tableofcontents
+\listoftables
+% \listoffigures
+\normalsize
+
+% -----
+
+\section{Introduction}
+
+Many \TeX{}nicians use \texttt{emacs} or \texttt{vim}. Both are great
+programs with excellent \LaTeX{} support: AUC-\TeX.
+
+However, for several reasons many people prefer other editors. I use a
+fast and compact \texttt{emacs} clone called Jed,
+\url{http://www.jedsoft.org/jed}. It can be customised and extended using
+S-Lang, an easy-to-learn language similar to C. Jed supports a variety of
+programming modes, with syntax highlighting and other facilities; \LaTeX{}
+support is provided by \texttt{latex.sl} and other S-Lang files included
+in the distribution.
+
+I feel that the default implementation of \texttt{latex.sl} is far behind
+AUC-\TeX, and that it could be improved in many ways. When I write code or
+documentation, I discipline myself to follow the so-called `Goccia's
+Rules':
+
+\begin{enumerate}
+
+ \item the program \emph{should} be as helpful as possible, but
+ \item it \emph{must not} stand in the way; therefore,
+ \item it \emph{should} be fully customisable, and
+ \item it \emph{should} be usable by experts and newbies alike.
+
+\end{enumerate}
+
+In my opinion, \texttt{latex.sl} breaks Goccia's Rules 1 and 4. It should
+attempt to be more useful, especially for \LaTeX{} beginners.
+
+J\o rgen Larsen \url{<jl@dirac.ruc.dk>} wrote a much better
+implementation, available from \url{http://dirac.ruc.dk/~jl/jed/}. I
+initially added menus to his mode, but as its development proceeded I lost
+sync with it. Many ideas of my implementation were taken from J\o rgen's;
+I suggest that you check it out.
+
+I eventually decided to roll my own \texttt{latex.sl}: from now on, \LJ.
+It was developed on Linux, but it also works and other Unix systems and
+even Windows. It was tested on a RedHat 7.3 GNU/Linux box with te\TeX, and
+under Windows 98 with MiK\TeX.
+
+The latest version of \LJ{} is \version, it works with Jed 0.99.15
+upwards, and is available from CTAN mirrors; for example,\\
+\url{http://www.ctan.org/tex-archive/support/jed}.
+
+% -----
+
+\section{Installing \LJ}
+
+In the following, I assume that you have a working installation of Jed.
+
+% -----
+
+\subsection{As Superuser}
+
+First of all, make a backup copy of \path{$JED_ROOT/lib/latex.sl}. In the
+event you don't like \LJ{}\footnote{unlikely \texttt{:-)}}, you'll be able to
+restore the original file. However, I'm pretty sure you will not roll
+back{\ldots}
+
+Copy \texttt{latex.sl} and \texttt{latex.hlp} to \path{$JED_ROOT/lib}.
+Optionally, create \path{$JED_ROOT/lib/latex} and copy the modules
+\texttt{prosper.sl} and \texttt{notice.sl} there. More details on modules
+are given in Section~\ref{sec:modules}.
+
+Finally, add these lines to your \texttt{.jedrc}:
+
+{\small
+\begin{verbatim}
+add_mode_for_extension ("latex", "tex");
+enable_dfa_syntax_for_mode ("LaTeX");
+\end{verbatim}
+}
+
+For a system-wide installation, edit the lines above in the file
+\path{$JED_ROOT/lib/jed.rc}.
+
+I \emph{recommend} that you create the DFA\footnote{the regular
+expression-based highlighting scheme.} cache table. If you don't, the DFA
+table will be slowly created each time you start Jed on a \LaTeX{}
+document. It could take \emph{minutes}!
+
+As root, add \texttt{latex.sl} to the list in the file
+\texttt{preparse.sl}, then run the command:
+
+{\small
+\begin{verbatim}
+jed -batch -n -l preparse
+\end{verbatim}
+}
+
+This step may be required each time you update \LJ{} to a new version.
+
+% -----
+
+\subsection{As Normal User}
+
+If you don't have one, create a personal Jed library directory; for
+example,
+
+{\small
+\begin{verbatim}
+$ mkdir /home/myself/myjedlib
+\end{verbatim}
+}
+
+then copy \texttt{latex.sl} to this directory and add these lines to your
+\texttt{.jedrc}:
+
+{\small
+\begin{verbatim}
+variable Jed_Home_Library = "/home/myself/myjedlib";
+set_jed_library_path (Jed_Home_Library + "," +
+ get_jed_library_path());
+Jed_Highlight_Cache_Dir = Jed_Home_Library;
+add_mode_for_extension ("latex", "tex");
+enable_dfa_syntax_for_mode ("LaTeX");
+\end{verbatim}
+}
+
+Jed will now find and use the new \texttt{latex.sl} instead of the default
+library file. The highlight cache will be built automatically the first time
+you use \LJ; a Jed update will not affect your private installation.
+
+% -----
+
+\subsection{Note for Windows Users}
+
+\LJ{} can be used with Jed for the DOS console, but it gives its best with
+\texttt{wjed}. However, as of Jed 0.99.16 \texttt{wjed} will not use
+standard menus unless you modify \path{$JED_ROOT/lib/os.sl}. Lines 33--34
+read:
+
+{\small
+\begin{verbatim}
+%. "menus" evalfile pop % Uncomment to enable text menus
+. "wmenu.sl" evalfile pop % Uncomment to enable GUI menus
+\end{verbatim}
+}
+
+It should be the opposite: uncomment out line 33 to enable text menus, and
+comment out line 34. Wjed will now show the \textsf{Mode} menu.
+
+% -----
+
+\subsection{Caveat}
+
+By default, \LJ{} is incompatible with folding mode because of clashing
+\texttt{Ctrl-Cf} key binding. Unless you're prepared to change the key
+bindings in \texttt{folding.sl}, you can solve the problem setting this
+variable in your \texttt{.jedrc}:
+
+{\small
+\begin{verbatim}
+variable LaTeX_Font_Key = "n";
+\end{verbatim}
+}
+
+which will make all font operations start with \texttt{Ctrl-Cn} instead of
+\texttt{Ctrl-Cf}.
+
+% -----
+
+\subsection{Colours}
+
+Obviously, \LJ{} looks better with \texttt{xjed} and \texttt{wjed}. Three
+nice colour schemes are provided: \texttt{elegant.sl}, \texttt{modern.sl},
+and \texttt{night.sl}. If you wish, copy them to
+\path{JED_ROOT/lib/colors/Xjed/}. If you want or need to use plain console
+\texttt{jed}, add this line to your favourite colour scheme (e.g.
+\path{JED_ROOT/lib/colors/blue2.sl}):
+
+{\small
+\begin{verbatim}
+set_color ("keyword2", "brightgreen", $2); % other keywords
+\end{verbatim}
+}
+
+I suggest that you insert these lines in \texttt{.jedrc}:
+
+{\small
+\begin{verbatim}
+#ifdef WINGUI
+set_color_scheme ("Xjed/night");
+#elifdef XWINDOWS
+set_color_scheme ("Xjed/modern");
+#else
+set_color_scheme ("blue2");
+#endif
+\end{verbatim}
+}
+
+Hereafter, I shall assume that you run Jed in Emacs emulation mode. All
+key bindings will start in \texttt{Ctrl-C}; users who prefer IDE mode will
+use \texttt{Ctrl-Z} instead. I also remind you that all operations can be
+interrupted with \texttt{Ctrl-G}.
+
+% -----
+
+\subsection{Customisation}
+\label{sec:custom}
+
+The user can customise \LJ{} changing the value of its variables. Insert
+lines like the following in your \texttt{.jedrc}. Default values are
+shown:
+
+{\small
+\begin{verbatim}
+variable LaTeX_Default_Output =
+ "dvi"; % or: "ps", "eps", "dvipdf", "pdf"
+variable LaTeX_Indent = 2;
+variable LaTeX_Article_Default_Options = "a4paper,12pt";
+variable LaTeX_Book_Default_Options = "twoside,11pt";
+variable LaTeX_Letter_Default_Options = "a4paper,12pt";
+variable LaTeX_Report_Default_Options = "twoside,12pt";
+variable LaTeX_Slides_Default_Options = "a4paper,landscape";
+variable LaTeX_Default_Language = "italian,english" % for Babel
+custom_variable ("LaTeX_Rerun", "y"); % for xrefs
+#ifdef WIN32
+variable LaTeX_View_Dvi_Command = "yap";
+variable LaTeX_View_Ps_Command = "gsview32";
+variable LaTeX_View_Pdf_Command = "gsview32";
+variable LaTeX_Print_Command = "gsview32";
+variable LaTeX_Clearup_Cmd, "del *.out *.aux *.lo? *.to?";
+variable LaTeX_Modules_Dir, JED_ROOT + "\\lib\\latex\\";
+#else
+variable LaTeX_View_Dvi_Command = "xdvi";
+variable LaTeX_View_Ps_Command = "gv -watch";
+variable LaTeX_View_Pdf_Command = "xpdf -z width";
+variable LaTeX_Print_Command = "lpr";
+variable LaTeX_Clearup_Cmd = "/bin/rm -f *.out *.aux *.lo? *.to?";
+variable LaTeX_Modules_Dir = JED_ROOT + "/lib/latex/";
+#endif
+\end{verbatim}
+}
+
+Windows users must make sure that all auxiliary programs are in the PATH.
+
+The name and purpose of these variables should be self-explanatory. For
+example, \texttt{LaTeX\_Rerun} specifies whether
+(\texttt{pdf})\texttt{latex} should be rerun to resolve all cross
+references. If you don't want to delete temporary files after the
+\texttt{latex} run(s), set \texttt{LaTeX\_Clearup\_Cmd} to ``'' (empty
+string).
+
+You can further customise \LJ{} adding a \texttt{latex\_mode\_hook}
+function to \texttt{.jedrc}. For instance, I want to type accented letters
+on my Italian keyboard, and get the right \TeX{} sequence. So I added this
+function:
+
+{\small
+\begin{alltt}
+define latex_mode_hook ()
+\{
+ set_abbrev_mode (1);
+ if ( () = abbrev_table_p ("LaTeX") )
+ use_abbrev_table ("LaTeX");
+#ifdef WIN32
+ % prevent clash with movement keys
+ undefinekey ("\`a\`a", "LaTeX-Mode");
+ definekey (" \bl\bl`a", "\`a\`a", "LaTeX-Mode");
+#else
+ local_setkey (" \bl\bl`a", "\`a");
+#endif
+ local_setkey (" \bl\bl'e", "\'e");
+ local_setkey (" \bl\bl`e", "\`e");
+ local_setkey (" \bl\bl`\bl\bl{}i\{\}", "\`\i");
+ local_setkey (" \bl\bl`o", "\`o");
+ local_setkey (" \bl\bl`u", "\`u");
+\}
+\end{alltt}
+}
+
+Sometimes, the defaults you set in \texttt{.jedrc} are not appropriate for
+the current editing session. In that case, you can temporarily change the
+values of the variables using the \textsf{Mode/\-Customise Defaults} menu
+entry.
+
+% -----
+
+\section{Editing \LaTeX{} Documents}
+
+% -----
+
+\subsection{Main Features of \LJ{}}
+
+As of version \version, \LJ{} has the following features:
+
+\begin{itemize}
+ \item thoroughly menu-driven
+ \item advanced DFA syntax highlighting
+ \item full integration with external programs
+ \item templates
+ \item modules
+ \item document structure
+ \item integrated debugging
+ \item symbol completion
+ \item many commands to write \LaTeX{} sources in less time.
+\end{itemize}
+
+Available key bindings are shown in the \textsf{Mode} menu entries, and
+were defined in a (hopefully) intuitive and consistent manner. Some examples
+are \texttt{Ctrl-Css} (or \texttt{Ctrl-C Ctrl-S Ctrl-S}) for
+\textsf{Mode/\-Sections/\-\textbackslash{}section}, \texttt{Ctrl-Cec} for
+the \texttt{center} environment, and so on.
+
+Thanks to this arrangement, this guide contains only one table of key
+bindings: Table~\ref{tab:keys}. In most cases, it's much simpler to read
+the menus!
+
+There is another important feature you'll want to use. Most commands are
+\emph{region-or-word aware}. For example, if a region is defined and you
+select \textsf{Mode/\-Environments/\-center}, that region will be included
+in a \texttt{center} environment. If the cursor is positioned on a word
+and you select \textsf{Mode/\-Font/\-\textbackslash{}emph}, the word will
+be included in a \texttt{\textbackslash{}emph} command.
+
+\begin{table}[htbp]
+ \centering
+ \small
+ \begin{tabular}{ll}
+ \hline
+ \textbf{Keybinding} & \textbf{Action} \\
+ \hline
+ \texttt{Ctrl-C\key{Left}} & go to previous paragraph\\
+ \texttt{Ctrl-C\key{Right}} & go to next paragraph\\
+ \texttt{Ctrl-C\&} & \bl\texttt{\&}\\
+ \texttt{Ctrl-C\$} & \bl\texttt{\$}\\
+ \texttt{Ctrl-C\#} & \bl\texttt{\#}\\
+ \texttt{Ctrl-C\%} & \bl\texttt{\%}\\
+ \texttt{Ctrl-C(} & \bl\texttt{\{}\\
+ \texttt{Ctrl-C)} & \bl\texttt{\}}\\
+ \texttt{Ctrl-C\_} & \bl\texttt{\_}\\
+ \texttt{Ctrl-C\textless} & \bl\texttt{textless\{\}}\\
+ \texttt{Ctrl-C\textgreater} & \bl\texttt{textgreater\{\}}\\
+ \texttt{Ctrl-C\textasciicircum} & \bl\texttt{textasciicircum\{\}}\\
+ \texttt{Ctrl-C\textasciitilde} & \bl\texttt{textasciitilde\{\}}\\
+ \texttt{Ctrl-C\textbackslash} & \bl\texttt{textbackslash\{\}}\\
+ \texttt{Ctrl-C\textbar} & \bl\texttt{textbar\{\}}\\
+ \texttt{Ctrl-C\{} & \texttt{\{\}}, region or word aware\\
+ \texttt{'} or \texttt{"} & smart quotes\\
+ \texttt{Ctrl-C'} or \texttt{Ctrl-C"} &
+ smart quotes, region or word aware \\
+ \texttt{...} & \texttt{\{\bl ldots\}}\\
+ % arrows
+ \texttt{<-} & \texttt{\{\bl leftarrow\}}\\
+ \texttt{<=} & \texttt{\{\bl Leftarrow\}}\\
+ \texttt{< --} & \texttt{\{\bl longleftarrow\}}\\
+ \texttt{< ==} & \texttt{\{\bl Longleftarrow\}}\\
+ \texttt{< ->} & \texttt{\{\bl leftrightarrow\}}\\
+ \texttt{< =>} & \texttt{\{\bl Leftrightarrow\}}\\
+ \texttt{->} & \texttt{\{\bl rightarrow\}}\\
+ \texttt{=>} & \texttt{\{\bl Rightarrow\}}\\
+ \texttt{-->} & \texttt{\{\bl longrightarrow\}}\\
+ \texttt{==>} & \texttt{\{\bl Longrightarrow\}}\\
+ \texttt{|->} & \texttt{\{\bl mapsto\}}\\
+ \texttt{|-->} & \texttt{\{\bl longmapsto\}}\\
+ \texttt{Ctrl-Ce}\key{TAB} &
+ insert environment, with completion\\
+ \texttt{Ctrl-Cf}\key{TAB} &
+ insert font, with completion\\
+ \texttt{Ctrl-Ch} & info help on word\\
+ \texttt{Alt-}\key{TAB} or \texttt{Alt-V} & symbol completion\\
+ \texttt{TAB} & indent line\\
+ \texttt{ESC 1}\key{TAB} & unindent line\\
+ \texttt{Ctrl-C[} & start environment\\
+ \texttt{Ctrl-C]} & close environment\\
+ \texttt{ESC 1}\key{cmd} & command, long form\\
+ \texttt{Ctrl-C}\key{RET} & new \texttt{\bl item} line\\
+ \texttt{F8} & preview document\\
+ \texttt{F9} & run (pdf)\texttt{latex}\\
+ \hline
+ \end{tabular}
+ \caption{Key bindings not available in menu entries.}
+ \label{tab:keys}
+\end{table}
+
+% -----
+
+\subsection{Getting Started}
+
+Start a new document, say \texttt{newfile.tex}. The \texttt{.tex}
+extension will automatically invoke \LJ, which can also be started on any
+buffer typing \texttt{Alt-X latex\_mode}. See also the
+\textsf{Buffers/\-Select Mode} menu.
+
+The \textsf{Mode} menu contains many entries and sub-menus, and it also
+indicates the key bindings when available. You'll want to browse through
+the menus, especially if you're not a \LaTeX{} expert.
+
+Now select \textsf{Mode/\-Templates/\-Article} to create an article
+template. Fill it with some text: add a couple of sections, some
+environments, change the fonts, and so on. Let \LJ{} help you:
+use the menus, but try and memorise the key bindings. Note the syntax
+highlighting of keywords and other \LaTeX{} elements.
+
+When you're finished, typeset your document using \textsf{Mode/\-Compose}.
+\texttt{latex} will be run on your document, and if no errors occur the
+file \texttt{newfile\-.dvi} will be created. If errors do occur, please
+read Section~\ref{sec:composing}.
+
+Now select \textsf{Mode/\-View} to preview your document. Et voil\`a, all
+done, without ever using the command line!
+
+% -----
+
+\subsection{Directory Independence}
+
+You don't have to start Jed in the same directory where your \LaTeX{}
+files are kept. When you begin editing a file, \LJ{} takes note of its
+parent directory. All subsequent operations will be performed from
+there. As a result, if your file includes external files of figures,
+everything will work as expected.
+
+% -----
+
+\subsection{Editing Compressed Files}
+
+Jed has the ability to edit compressed files. To enable this feature,
+insert this line in \texttt{.jedrc} or \texttt{jed.rc}:
+
+{\small
+\begin{verbatim}
+auto_compression_mode ();
+\end{verbatim}
+}
+
+\LJ{} works on compressed files with no problems, but obviously it cannot
+deal with compressed external figures or \texttt{\textbackslash{}include}d
+parts. Editing compressed files may be useful on low-resource machines.
+
+
+% -----
+
+\subsection{\LaTeX{} Info Help}
+
+On Linux and other Unix-like systems, the \LaTeX{} Info pages are surely
+installed. Check out typing \texttt{info latex} at the shell prompt.
+
+\LJ{} integrates with the Info pages. If you wish to get some
+help on a \LaTeX{} command or keyword, place the cursor on that word and
+press \texttt{Ctrl-Ch}. If the word is covered in the Info pages, the
+relevant info page will be loaded. Press \key{q} to quit the Info page.
+
+% -----
+
+\subsection{Symbol Completion}
+
+This feature was borrowed by the old \texttt{latex.sl}. If you start
+typing a \LaTeX{} keyword and type \texttt{Alt-}\key{TAB}, the keyword
+will self complete. Type \texttt{Alt-}\key{TAB} again to cycle through
+possible completions. For example, after typing
+\texttt{\textbackslash{}bib} you'll cycle through
+\texttt{\textbackslash{}bib\-item[]\{\}},
+\texttt{\textbackslash{}biblio\-grapy\{\}}, and
+\texttt{\textbackslash{}biblio\-grapy\-style\{\}}.
+
+Under X11, the window manager may reserve \texttt{Alt-}\key{TAB} for
+itself, and MS Windows uses this key binding to switch between tasks. In
+that case, use \texttt{Esc-}\key{TAB}.
+
+% -----
+
+\subsection{Indentation}
+
+\LJ{} uses a kind of `preventive indentation' scheme: it tries to save you
+from hitting the \key{TAB} key to indent the line.
+
+Normally, a new line starts at the same column as the line above, but
+lines within environments are indented. For example, start a
+\texttt{center} environment with \texttt{Ctrl-Cec}: the text will be
+indented by the amount specified by the variable \texttt{LaTeX\_Indent}.
+The default is 2 columns, but it can be changed as seen in
+Section~\ref{sec:custom}.
+
+If you want to force an indented line, press the \key{TAB} key. This will
+simply indent the line by \texttt{LaTeX\_Indent}, regardless of the
+current environment. \texttt{ESC 1}\key{TAB} will unindent a line,
+provided that the line starts with the adequate number of spaces.
+
+Finally, if you're editing messy \LaTeX{} sources\footnote{not written with
+Jed, obviously ;-)}, you can indent environments with \texttt{Ctrl-CeD}.
+
+% -----
+
+\subsection{Environments}
+
+Environments can be entered via the \textsf{Mode/\-Environments} menu.
+This method will provide the right indentation for both the environment
+and the text it encloses.
+
+Another way to start a new environment is typing \texttt{Ctrl-C[}. You'll
+be prompted for the environment name, and the
+\texttt{\textbackslash{}begin{}} line will be inserted. When you're done,
+close the environment with \texttt{Ctrl-C]}.
+
+Environments can be renamed via the \textsf{Mode/\-Environments/\-reName}
+menu entry or its corresponding key binding, provided that the cursor is
+within an environment.
+
+% -----
+
+\subsubsection{Using a Prefix}
+
+Some environments and commands use optional parameters. By default, menu
+entries and key bindings produce the command without the optional part.
+Goccia's rule 1 is obeyed, but what about rule 2?
+
+Using a \emph{prefix} (shortly, pressing \texttt{ESC 1} before any other
+key binding) will insert a more complete form. For example, if you press
+\texttt{Ctrl-Cpl} you will get
+\texttt{\textbackslash{}includegraphics\{\}}, while pressing \texttt{ESC 1
+Ctrl-Cpl} you will get
+\texttt{\textbackslash{}in\-clu\-de\-gra\-phics%
+[scale=\textbar{}width=\textbar{}height=]\{\}}.
+
+% -----
+
+\subsubsection{Itemize}
+
+In \texttt{itemize} or \texttt{enumerate} environments you can use
+\texttt{Ctrl-C}\key{RET} to start a new \texttt{\textbackslash{}item}
+line.
+
+% -----
+
+\subsubsection{Tables}
+
+\LJ{} makes it easier to write tables. When you start a
+\texttt{table} or \texttt{tabular} environment, you'll be prompted for the
+number of columns, then a table template will be inserted.
+
+The \textsf{Mode/\-Environments/\-table row} menu entry will insert a line
+containing the right number of \texttt{\&} delimiters, and terminated by
+\texttt{\textbackslash{}\textbackslash{}}. Just fill in the blanks.
+
+% -----
+
+\subsection{Templates}
+
+Templates for standard \LaTeX{} document classes: \texttt{article},
+\texttt{book}, \texttt{letter}, \texttt{report}, and \texttt{slides}, are
+provided. In addition, templates for notices and for Prosper presentations
+(\url{http://prosper.sourceforge.net}) were added as modules (see
+below) for your convenience. The latter lets you write a presentation in
+minutes!
+
+The most commonly used packages are also listed in the
+\textsf{Mode/\-Templates/\-Packages} sub-menu. The listed packages were
+chosen after some statistics on several \LaTeX{} documents.
+
+% -----
+
+\subsection{Modules}
+\label{sec:modules}
+
+\LJ{} has a modular structure, so that its functionality can be enhanced
+as needed. Additional modules can be written by the user as S-Lang files
+and must reside in \texttt{LaTeX\_Modules\_Dir}. This directory is
+\path{$JED_ROOT/lib/latex} by default, but the user can choose his or her
+directory in \texttt{.jedrc}:
+
+{\small
+\begin{verbatim}
+variable LaTeX_Modules_Dir = "/home/guido/.jedmodules/";
+\end{verbatim}
+}
+
+Writing modules is very simple, even if you are not an S-Lang expert.
+There you are a template:
+
+{\small
+\begin{verbatim}
+% mymodule.sl
+define mymodule_fun1 ()
+{
+ % your code here
+}
+define mymodule_fun2 ()
+{
+ % your code here
+}
+% ... more code...
+$1 = "LaTeX-Mode";
+$2 = "Global.M&ode.Modules.mymodule";
+% optional keybindings
+definekey_reserved ("mymodule_fun1", "t1", $1);
+definekey_reserved ("mymodule_fun2", "t2", $1);
+% optional menus
+menu_append_item ($2, "mymodule fun&1", "mymodule_fun1");
+menu_append_item ($2, "mymodule fun&2", "mymodule_fun2");
+% end of file mymodule.sl
+\end{verbatim}
+}
+
+Version \version{} of \LJ{} ships with these modules:
+
+\begin{description}
+ \item [notice.sl] for writing single-page notices;
+ \item [prosper.sl] for Prosper presentations;
+ \item [textpos.sl] for poster-like material.
+\end{description}
+
+
+% -----
+
+\subsection{Maths}
+
+It's virtually impossible to list all mathematical symbols supported by
+\LaTeX{} in a menu. That said, most symbols are available under
+\textsf{Mode/\-Math}.
+
+Greek letters are obtained typing \texttt{Ctrl-Cm} and a letter; the
+equivalent Greek letter, if available, will be inserted. For instance,
+\texttt{Ctrl-Cma} inserts \texttt{\textbackslash{}alpha}, and
+\texttt{Ctrl-CmG} inserts \texttt{\textbackslash{}Gamma}. An alternative
+way is toggling Math mode, after which you type \texttt{`}-letter
+(backquote-letter) to get the Greek letter. All available symbols are
+provided by the file \texttt{ltx-math.sl}, included in the Jed
+distribution.
+
+Arrows are obtained as shown in Table~\ref{tab:keys}.
+
+% -----
+
+\subsection{Document Structure}
+
+Use this feature to navigate through complex documents. The
+\texttt{*Structure*} buffer shows the document structure, listing all
+\texttt{\textbackslash{}parts}, \texttt{\textbackslash{}sections}, etc.
+and the line where they begin.
+
+Press \key{RET} or double click on a section to move to the relative line
+in the \LaTeX{} buffer, or \key{q} to quit.
+
+% -----
+
+\section{Composing and Debugging}
+\label{sec:composing}
+
+\LJ{} typesets your documents using five output profiles: dvi,
+ps, eps, pdf, and dvipdf. The final output is, respectively: a
+\texttt{.dvi} file, a \texttt{.ps} or \texttt{.eps} file made with
+\texttt{dvips}, a \texttt{.pdf} file made with \texttt{dvipdf}, and a
+\texttt{.pdf} file made with \texttt{pdflatex}. The default output profile
+is dvi.
+
+Select \textsf{Mode/\-Compose} (or press \texttt{F9}) to typeset the
+buffer using the current output profile. A `beep' will notify you of
+warnings, e.g.
+
+{\small
+\begin{verbatim}
+Rerun to get cross-references right.
+\end{verbatim}
+}
+
+If errors are detected, the cursor will be moved to the offending line.
+Press \texttt{Ctrl-C'} to move to the next error. The \texttt{latex} error
+log can be inspected at any moment in the the \texttt{*LaTeX log*} buffer.
+
+If the conversion succeeded, the following \textsf{Mode/\-View} command
+will start the appropriate viewer. If you try to run a viewer but the
+document has not been typeset yet, a single \texttt{latex} run will be
+performed and the viewer will be launched.
+
+% -----
+
+\subsection{Using a Master File}
+
+When you work on complex documents, you can set a buffer as the `master
+file'. That means that although you may be working on several \LaTeX{}
+files at the same time, all operations of conversion, previewing etc. will
+be performed on the master file. This is useful, for example, when you
+have a main file that includes several parts.
+
+If you disable the master file, all operations will be performed on the
+current buffer.
+
+% -----
+
+\section{Notes on \BibTeX}
+
+\LaTeX{} mode doesn't provide any support for writing \BibTeX{} files. Jed
+has an excellent \texttt{bibtex} mode already. Edit a file with
+\texttt{.bib} extension to turn \texttt{bibtex} mode on.
+
+% -----
+
+\section{Known Issues}
+
+\begin{itemize}
+
+ \item The current implementation of syntax highlighting could be
+ improved. The most apparent problem is that text enclosed in curly
+ braces isn't always highlighted correctly. The same problem affects
+ strings that span more than two lines. This is a limitation of the DFA
+ code in Jed.
+
+ \item Auxiliary programs are not launched as separate processes.
+ In other words, you have to wait for a \texttt{latex} run to complete
+ before you can edit the text. Would asyncronous compilation be a better
+ choice?
+
+ \item There is no support for \AMSTeX{} symbols. I'll gladly accept a
+ user-contributed module, which should be straightforward to
+ write---per\-haps just a bit lengthy.
+
+ \item The documentation (this guide) is probably too concise.
+ Please let me know if you think it is.
+
+\end{itemize}
+
+% -----
+
+\section{The End}
+
+\LJ{} was written and is copyrighted \textcopyright{} by Guido
+Gonzato, Ph.D. \url{guido,dot,gonzato,at,univr,dot,it}.
+
+\medskip
+
+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 2 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
+MER\-CHAN\-TA\-BI\-LI\-TY 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.
+
+\medskip
+
+So, in actual fact this program is \emph{copylefted} by me.
+
+Many thanks to G\"unter Milde and J\"org Sommer for their valuable
+contributions, and to all users who helped me with suggestions and bug
+reports. I'm especially indebted with J\o rgen Larsen for showing me how
+to write good S-Lang code. Wait---can I forget to thank John E. Davis for
+his great editor?
+
+I use \LJ{} every day, and I think it's very useful and complete. However,
+I'll be glad to receive suggestions and requests from you. If you find a
+bug or would like me to add new features, please feel free to contact me.
+If you want to send me a module, you're more than welcome!
+
+Enjoy,
+
+\nopagebreak
+\newlength{\enjoy}
+\settowidth{\enjoy}{Enjoy,}
+\hspace{\enjoy}Guido \texttt{=8-)}
+
+% -----
+
+\end{document}
diff --git a/support/jed/latex4jed/modern.sl b/support/jed/latex4jed/modern.sl
new file mode 100644
index 0000000000..4cc02ce8e3
--- /dev/null
+++ b/support/jed/latex4jed/modern.sl
@@ -0,0 +1,40 @@
+% modern.sl
+% By Guido Gonzato <guido.gonzato@univr.it>
+
+$1 = "black";
+$2 = "white";
+$3 = "#E8E8E8"; % light gray
+$4 = "#B0B0B0"; % mid gray
+$5 = "#007000"; % dark green
+$6 = "#1010A0"; % dark blue
+$7 = "#B40A78"; % dark purple
+$8 = "#D717E7"; % purple
+$9 = "#606060"; % dark gray
+
+set_color ("normal", $1, $2); % default fg/bg
+set_color ("status", $1, $3); % status line
+set_color ("operator", $1, $2); % +, -, etc...
+set_color ("number", "brightred", $2); % numbers
+set_color ("comment", $9, $2); % /* comment */
+set_color ("region", $1, $4); % region
+set_color ("string", $6, $3); % "string" or 'char'
+set_color ("keyword", $7, $2); % if, while, unsigned, ...
+set_color ("keyword1", $6, $2); % malloc, exit, etc...
+set_color ("keyword2", $5, $2); % other keywords
+set_color ("delimiter", "red", $2); % {}[](),.;...
+set_color ("preprocess", "magenta", $2); % #ifdef etc...
+set_color ("message", $6, $2);
+set_color ("error", $8, $2);
+set_color ("dollar", $8, $2);
+set_color ("...", $8, $2); % folding indicator
+
+set_color ("menu_char", "red", $3);
+set_color ("menu", $1, $3);
+set_color ("menu_popup", $1, $3);
+set_color ("menu_shadow", $1, $4);
+set_color ("menu_selection", $1, "cyan");
+set_color ("menu_selection_char", "red", $3);
+
+set_color ("mouse", "blue", "blue");
+set_color ("cursor", $1, $8);
+set_color ("cursorovr", $1, $8);
diff --git a/support/jed/latex4jed/modules/notice.sl b/support/jed/latex4jed/modules/notice.sl
new file mode 100644
index 0000000000..4ca50bee03
--- /dev/null
+++ b/support/jed/latex4jed/modules/notice.sl
@@ -0,0 +1,50 @@
+% File: notice.sl -*- mode: SLang -*-
+%
+% Author: Guido Gonzato, guido.gonzato@univr.it
+%
+% Description: this is a module for latex4jed.
+%
+% Installation: copy notice.sl to $JED_ROOT/lib/latex, or to your
+% LaTeX_Modules_Dir.
+%
+% Version: 1.0.0
+%
+% Last updated: 3 May 2003
+
+define notice_template ()
+{
+ vinsert ("\\documentclass[%s]{article}\n\n",
+ LaTeX_Article_Default_Options);
+ insert ("\\usepackage{type1cm}\n");
+ insert ("\\usepackage{times}\n");
+ insert ("\\usepackage{color}\n");
+ insert ("\\usepackage{rotating}\n");
+ insert ("\\pagestyle{empty}\n");
+ insert ("\\begin{document}\n\n");
+
+ insert ("\\begin{sidewaysfigure}\n");
+ push_spot ();
+ insert (" \\fontsize{2.5cm}{2.5cm}\\selectfont\n");
+ insert (" \\centerline{\\textcolor{blue}{\\textbf{Please:}}}\n");
+ insert (" \\vskip 1cm\n\n");
+ insert (" \\fontsize{4cm}{3cm}\\selectfont\n");
+ insert (" \\centerline{\\textcolor{red}{DO NOT}}\n");
+ insert (" \\centerline{\\textcolor{red}{SMOKE}}\n");
+ insert (" \\centerline{\\textcolor{red}{HERE!}}\n");
+ insert (" \\vskip 1cm\n\n");
+ insert (" \\fontsize{2cm}{2cm}\\selectfont\n");
+ insert (" \\centerline{\\textcolor{magenta}{If you do,}}\n");
+ insert (" \\centerline{\\textcolor{magenta}" +
+ "{you'll be \\emph{deboned!}}}\n");
+ insert ("\\end{sidewaysfigure}\n\n");
+ insert ("\\end{document}");
+ pop_spot ();
+}
+
+$1 = "LaTeX-Mode";
+$2 = "Global.M&ode.Mod&ules.notice";
+definekey_reserved ("notice_template", "tn", $1);
+definekey_reserved ("notice_template", "^T^N", $1);
+menu_append_item ($2, "&Template", "notice_template");
+
+% ----- End of file notice.sl
diff --git a/support/jed/latex4jed/modules/prosper.sl b/support/jed/latex4jed/modules/prosper.sl
new file mode 100644
index 0000000000..1163689597
--- /dev/null
+++ b/support/jed/latex4jed/modules/prosper.sl
@@ -0,0 +1,181 @@
+% File: prosper.sl -*- mode: SLang -*-
+%
+% Author: Guido Gonzato, guido.gonzato@univr.it
+%
+% Description: this is a module for latex4jed.
+%
+% Installation: copy prosper.sl to $JED_ROOT/lib/latex, or to your
+% LaTeX_Modules_Dir.
+%
+% Version: 1.0.0
+%
+% Last updated: 3 May 2003
+
+% -----
+
+custom_variable ("Prosper_Default_Style", "azure");
+custom_variable ("Prosper_Default_Options",
+ "pdf,accumulate,slideColor,colorBG," +
+ Prosper_Default_Style);
+custom_variable ("Prosper_Default_Transition", "Glitter");
+
+define prosper_template ()
+{
+ vinsert ("\\documentclass[%s]{prosper}\n", Prosper_Default_Options);
+ insert ("\\hypersetup{pdfpagemode=FullScreen}\n\n");
+ insert ("\\title{");
+ push_spot ();
+ insert ("}\n");
+ insert ("\\subtitle{}\n");
+ insert ("\\author{}\n");
+ insert ("\\email{}\n");
+ insert ("\\institution{}\n");
+ insert ("\\slideCaption{}\n");
+ insert ("\\DefaultTransition{Glitter}\n");
+ insert ("% \\Logo(1,1){\\includegraphics{logo.eps}}\n");
+ insert ("% \\displayVersion\n");
+ insert ("% \\NoFrenchBabelItemize\n\n");
+ insert ("\\begin{document}\n\n");
+ insert ("\\maketitle\n\n");
+ insert ("\\begin{slide}[Split]{slide 1 title}\n");
+ insert (" material for slide 1\n");
+ insert ("\\end{slide}\n%\n");
+ insert ("\\overlays{2}{\n");
+ insert ("\\begin{slide}[Box]{Overlay}\n");
+ insert (" overlay, part 1\\\\\n");
+ insert (" \\onlySlide{2}{\n");
+ insert (" overlay, part 2\n");
+ insert (" } % onlySlide\n");
+ insert ("\\end{slide}\n");
+ insert ("} % overlays\n");
+ insert ("\\overlays{3}{\n");
+ insert ("\\begin{slide}[Wipe]{Overlay + itemstep}\n");
+ insert (" \\begin{itemstep}\n");
+ insert (" \\item one\n");
+ insert (" \\item two\n");
+ insert (" \\item three\n");
+ insert (" \\end{itemstep}\n");
+ insert ("\\end{slide}\n");
+ insert ("} % overlays\n\n");
+ insert ("\\end{document}");
+ pop_spot ();
+ LaTeX_Default_Output = "dvipdf";
+}
+
+% -----
+
+define prosper_choose_option ()
+{
+ variable option =
+ read_with_completion ("draft,final,slideColor,slideBW,total," +
+ "nototal,novolorBG,colorBG,ps,pdf," +
+ "accumulate,noaccumulate,distiller",
+ "Choose transition (pres TAB to list):",
+ "", "", 's');
+ insert (option + ",");
+}
+
+% -----
+
+define prosper_choose_style ()
+{
+ variable style =
+ read_with_completion ("alienglow,autumn,azure,blends,contemporain," +
+ "darkblue,default,frames,lignesbleues," +
+ "nuancegris,troispoints",
+ "Choose style (pres TAB to list):",
+ "", "", 's');
+ insert (style);
+}
+
+% -----
+
+define prosper_choose_transition ()
+{
+ Prosper_Default_Transition =
+ read_with_completion ("Split,Blinds,Box,Wipe,Dissolve,Glitter,Replace",
+ "Choose transition (pres TAB to list):",
+ Prosper_Default_Transition, "", 's');
+ insert (Prosper_Default_Transition);
+}
+
+% -----
+
+define prosper_overlays ()
+{
+ insert ("\\overlays{");
+ push_spot ();
+ insert ("}{\n");
+ latex_begin_end ("slide",
+ sprintf ("[%s]{}", Prosper_Default_Transition),
+ 0, 0);
+ insert ("\n}\n");
+ pop_spot ();
+}
+
+% -----
+
+$1 = "LaTeX-Mode";
+$2 = "Global.M&ode.Mod&ules.prosper";
+
+% reserved keys
+definekey_reserved ("prosper_template", "to", $1);
+definekey_reserved ("prosper_template", "^T^O", $1);
+% menu
+menu_append_item ($2, "&Template", "prosper_template");
+menu_append_item ($2, "Choose &Class Option", "prosper_choose_option");
+menu_append_item ($2, "Choose Class St&yle", "prosper_choose_style");
+menu_append_item ($2, "Choose T&ransition", "prosper_choose_transition");
+menu_append_item ($2, "&Part", sprintf ("latex_cmd (\"part[%s]\", 1)",
+ Prosper_Default_Transition));
+menu_append_item ($2, "&Slide", sprintf
+ ("latex_begin_end (\"slide\", \"[%s]{title}\", 1, 1)",
+ Prosper_Default_Transition));
+menu_append_item ($2, "&Overlays", "prosper_overlays");
+menu_append_item ($2, "&Itemize",
+ "latex_begin_end (\"Itemize\", \"\", 1, 1)");
+menu_append_item ($2, "item&step",
+ "latex_begin_end (\"itemstep\", \"\", 1, 1)");
+% slide macros
+menu_append_popup ($2, "Slide &Macros");
+$3 = sprintf ("%s.Slide &Macros", $2);
+menu_append_item ($3, "\\FontTitle{C}{BW}",
+ "latex_cmd_with_arg (\"FontTitle\", \"\")");
+menu_append_item ($3, "\\FontText{C}{BW}",
+ "latex_cmd_with_arg (\"FontText\", \"\")");
+menu_append_item ($3, "\\fontTitle{}",
+ "latex_cmd (\"fontTitle\", 1)");
+menu_append_item ($3, "\\fontText{}",
+ "latex_cmd (\"fontText\", 1)");
+menu_append_item ($3, "\\ColorFoot{}",
+ "latex_cmd (\"ColorFoot\", 1)");
+menu_append_item ($3, "\\PDFtransition{}",
+ "latex_cmd (\"PDFtransition\", 1)");
+menu_append_item ($3, "\\myitem{lev}{def}",
+ "latex_cmd_with_arg (\"myitem\", \"\")");
+% overlays macros
+menu_append_popup ($2, "O&verlays Macros");
+$3 = sprintf ("%s.O&verlays Macros", $2);
+menu_append_item ($3, "\\fromSlide{p}{mat}",
+ "latex_cmd_with_arg (\"fromSlide\", \"\")");
+menu_append_item ($3, "\\onlySlide{p}{mat}",
+ "latex_cmd_with_arg (\"fromSlide\", \"\")");
+menu_append_item ($3, "\\untilSlide{p}{mat}",
+ "latex_cmd_with_arg (\"untilSlide\", \"\")");
+menu_append_item ($3, "\\FromSlide{p}",
+ "latex_cmd (\"FromSlide\", 1)");
+menu_append_item ($3, "\\OnlySlide{p}",
+ "latex_cmd (\"OnlySlide\", 1)");
+menu_append_item ($3, "\\UntilSlide{p}",
+ "latex_cmd (\"UntilSlide\", 1)");
+% output dependent macros
+menu_append_popup ($2, "P&DF/PS Macros");
+$3 = sprintf ("%s.P&DF/PS Macros", $2);
+menu_append_item ($3, "\\PDForPS{ifpdf}{ifps}",
+ "latex_cmd_with_arg (\"PDForPS\", \"\")");
+menu_append_item ($3, "\\onlyInPS{}",
+ "latex_cmd (\"onlyInPS\", 1)");
+menu_append_item ($3, "\\onlyInPDF{}",
+ "latex_cmd (\"onlyInPDF\", 1)");
+
+% ----- End of file prosper.sl
diff --git a/support/jed/latex4jed/modules/textpos.sl b/support/jed/latex4jed/modules/textpos.sl
new file mode 100644
index 0000000000..cbe3c2ded5
--- /dev/null
+++ b/support/jed/latex4jed/modules/textpos.sl
@@ -0,0 +1,41 @@
+% File: textpos.sl -*- mode: SLang -*-
+%
+% Author: Guido Gonzato, guido.gonzato@univr.it
+%
+% Description: this is a module for latex4jed.
+%
+% Installation: copy textpos.sl to $JED_ROOT/lib/latex, or to your
+% LaTeX_Modules_Dir.
+%
+% Version: 1.0.0
+%
+% Last updated: 7 July 2003
+
+define textpos_template ()
+{
+ vinsert ("\\documentclass[%s]{article}\n",
+ LaTeX_Article_Default_Options);
+ insert ("\\usepackage[absolute]{textpos}\n");
+ insert ("% showboxes,noshowtext,absolute,overlay,quiet,verbose\n\n");
+
+ insert ("\\begin{document}\n\n");
+
+ insert ("\\setlength{\\TPHorizModule}{10mm}\n");
+ insert ("\\setlength{\\TPVertModule}{\\TPHorizModule}\n");
+ insert ("\\textblockorigin{10mm}{10mm}\n\n");
+
+ insert ("\\begin{textblock}{10}[0.5,0.5](6,7)\n");
+ insert_spaces (LaTeX_Indent);
+ push_spot ();
+ insert ("\n\\end{textblock}\n\n");
+ insert ("\\end{document}");
+ pop_spot ();
+}
+
+$1 = "LaTeX-Mode";
+$2 = "Global.M&ode.Mod&ules.textpos";
+definekey_reserved ("textpos_template", "tt", $1);
+definekey_reserved ("textpos_template", "^T^T", $1);
+menu_append_item ($2, "&Template", "textpos_template");
+
+% ----- End of file textpos.sl
diff --git a/support/jed/latex4jed/night.sl b/support/jed/latex4jed/night.sl
new file mode 100644
index 0000000000..f0df257506
--- /dev/null
+++ b/support/jed/latex4jed/night.sl
@@ -0,0 +1,38 @@
+% night.sl
+% By Guido Gonzato <guido.gonzato@univr.it>
+
+$1 = "#EDFF00"; % flash yellow
+$2 = "#000050"; % very dark blue
+$3 = "#FF4242"; % bright red
+$4 = "#90FF90"; % bright green
+$5 = "#4FFF4F"; % green
+$6 = "#D1D1D1"; % whitish
+$7 = "#040FDD"; % blue
+$8 = "#400070"; % dark purple
+$9 = "#20b0f0"; % mid cyan
+
+set_color ("normal", $1, $2); % default fg/bg
+set_color ("status", "black", "white"); % status or mode line
+set_color ("region", "black", "white"); % for marking regions
+set_color ("operator", "white", $2); % +, -, etc..
+set_color ("number", "red", $2); % 10, 2.71,... TeX formulas
+set_color ("comment", $4, $2); % /* comment */
+set_color ("string", "cyan", $7); % "string" or 'char'
+set_color ("keyword", "white", $8); % if, while, unsigned, ...
+set_color ("keyword1", "cyan", $8); % malloc, exit, etc...
+set_color ("keyword2", $3, $8); % other keywords
+set_color ("delimiter", $3, $2); % {}[](),.;...
+set_color ("preprocess", "magenta", $2); % #ifdef ....
+set_color ("message", "white", $2); % color for messages
+set_color ("error", $2, $3); % color for errors
+set_color ("dollar", "white", $2); % color dollar sign continuation
+set_color ("...", "red", $2); % folding indicator
+
+set_color ("menu_char", "red", $6);
+set_color ("menu", "black", $6);
+set_color ("menu_popup", "black", $6);
+set_color ("menu_shadow", $2, "black");
+set_color ("menu_selection", "black", $9);
+set_color ("menu_selection_char", $3, $6);
+
+% End of file night.sl