diff options
Diffstat (limited to 'support/jed')
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 Binary files differnew file mode 100644 index 0000000000..0d1a88a703 --- /dev/null +++ b/support/jed/jlm/doc/jlm-vortrag.pdf diff --git a/support/jed/jlm/doc/jlm.pdf b/support/jed/jlm/doc/jlm.pdf Binary files differnew file mode 100644 index 0000000000..e613b14b0a --- /dev/null +++ b/support/jed/jlm/doc/jlm.pdf 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, + {"¢er", "&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", ""ation", "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", "\\§ion", "\\s&ubsection", + "\\su&bsubsection", "\\¶graph", "\\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¬e", + "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", ¶graph_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, "¢er", + "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, "\\§ion", "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, "\\¶graph", "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¬e", + "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 Binary files differnew file mode 100644 index 0000000000..7406bb80a6 --- /dev/null +++ b/support/jed/latex4jed/latex4jed.pdf 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 |