/* ** AREXX $VER:TeXedit.rexx V1.45 (12.11.1995) ** ** This ARexx script is called from virtex (or initex) in case of an ** error or if the 'e' command is used, and it's given the current file ** and line number as arguments. It may be called from the TeX-server too. ** We will successively call CygnusEd (CED) or Micro(GNU)Emacs (MG) to ** load the file and the logfile. Other editors welcome! ** ** INPUTS: ** 1: filename to edit (please no spaces in filename) ** 2: line where error occured ** ** BUGS: ** GETCLIP("TEXFILE") gets precedence over any other information for ** retrieving the logfile, so if you alternately start virtex directly ** from CLI while the server is active, the wrong files may be loaded. ** ** This file tries to cope with the following version (PasTeX 1.2a) ** > This is a PD-Version of Pas-TeX (made Jan 30 1991 [br]/[hes]) ** > This is TeX, C Version 3.1 ** (The logfile is sometimes put at the wrong place.) ** ** Does not handle names relative to the local root correctly (like ":foo/bar") ** ** See each editor relative bugs below. ** ** FILES: ** Rexx:NameStruc ** LIBS:rexxsupport.library ** ** AUTHORS: ** J\"org H\"ohle, since March 91 ** Georg Hessmann, previous version ** ** CHANGES: ** Modifications for personal use by Andreas Scherer, 1993, 1994. ** 12.11.95: Search for `l.NUMBER' in the first column only in order ** to use this script with LaTeX output. */ If ~Show('Libraries','rexxsupport.library') Then If ~AddLib('rexxsupport.library',0,-30,0) Then Do Say "Konnte 'rexxsupport.library' nicht öffnen!" Exit 20 End /* ** The TeX server may want to know that we have been called. */ Call SetClip("TEXTIME",TIME('s')) Parse Arg FILENAME NUMBER . /* ** If the TeX 'e' command was used to call the editor, ** don't ask if files should be loaded. */ If "EDIT" ~= Upper(MyGetEnv("TEXREXX")) Then ASKLOAD = 0 Else ASKLOAD = 1 Parse Value NameStruc(FILENAME) With IVOL IDIRS IBASE . /* ** The idea in the following statements is to get an absolute path ** for . The result will be stored in . For example, ** "CD TeX:bar" "virtex foo" should give =foo, and ** =TeX:bar/foo. This is necessary because the editor doesn't ** know where file foo is located, but will be able to load file ** TeX:bar/foo. */ MAINNAME = GetClip("TEXFILE") If "" = MAINNAME Then Do /* ** TeX has not been started through some Start_TeX.#? script. ** We have a hard time finding the right directories. */ TEXDIR = Pragma('d') /* ** Amiga OS dirnames should end with either `:' or `/'. ** Thus you need just append the filename. */ If Right(TEXDIR,1) ~= ':' & Right(TEXDIR,1) ~= '/' Then TEXDIR = TEXDIR'/' If 0 = IVOL Then Do ERRNFILE = TEXDIR||SubStr(FILENAME,1+IVOL) /* ** The logfile is in the current dir. */ LOGFILE = TEXDIR||SubStr(FILENAME,1+IVOL+IDIRS,IBASE)".log" End; Else Do ERRNFILE = FILENAME If 0 = IDIRS Then /* ** This is a bug in virtex from PasTeX12a (made Jan 30 1991 [br]/[hes]) ** The logfile is *not* in virtex's directory, but rather in the ** source's directory if a device name, but no subsequent directory was ** given. I.e, virtex (CD in RAM) TeX:sample would put the errorfile in ** TeX: and not in RAM: as it should be. */ LOGFILE = Left(FILENAME,IVOL+IDIRS+IBASE)".log" Else LOGFILE = TEXDIR||SubStr(FILENAME,1+IVOL+IDIRS,IBASE)".log" End Drop TEXDIR End; Else Do /* ** TeX was started through Start_TeX.#? scripts. ** "TEXFILE" tells us CD and the main file. */ Parse Value NameStruc(MAINNAME) With MVOL MDIRS MBASE . If 0 ~= IVOL Then ERRNFILE = FILENAME Else ERRNFILE = Left(MAINNAME,MVOL+MDIRS)||SubStr(FILENAME,1+IVOL) LOGFILE = Left(MAINNAME,MVOL+MDIRS+MBASE)".log" Drop MVOL MDIRS MBASE End /* ** 0 = ibase would mean that the call was incorrect, for example when ** TEXREXXEDIT says "TeXedit.rexx" and not "TeXedit.rexx %s %d" */ If 0 = IBASE | ~Exists(ERRNFILE) Then Do Say "TeXedit.rexx: Konnte fehlerhafte Datei nicht finden." Exit 10 End; Else If ~Exists(LOGFILE) Then Do Say "TeXedit.rexx: Konnte Logfile nicht finden." LOGFILE = "" /* ** But we continue. */ End Drop IVOL IDIRS IBASE /* ** Here starts each editor's specific part. */ /* ** Cygnus Ed Professional Version 3.5+ */ If Show('Port','rexx_ced') Then Do Address 'rexx_ced' Options Results CEDtoFront /* ** The following should not be commented out, as this macro is called ** asynchronously, and it would be very bad for the user to have it's ** input mixed with the newly loaded files. Popping up a requester ** ensures that the user does not type in something and waits for the ** files to be loaded. This is the method I use for synchronization. (JCH) */ If ASKLOAD Then Do Okay2 "TeX fand einen Fehler in der Datei"'0A'X"'"ERRNFILE"'. Datei laden?" If 1 ~= RESULT Then Exit 0 End /* ** Make sure the TEX-file is loaded. This works with CED 3.5+ only. ** There was no mechanism to make sure that the errorneous file was ** actually loaded in one of the views. If it wasn't, the next command ** would open a second view for the log file and a *third* for the ** TeX-file, but half of the CED screen was left empty with `Unnamed.' ** You could replace this by `jump to file' for CED 2.12. */ OW ERRNFILE /* ** TODO: We should really delete old logfiles automatically, without letting ** CED open a requester to ask if an old modified file may be ** overwritten or not. */ If "" ~= LOGFILE Then Do 'jump to file "'LOGFILE'"' /* ** Always assume the logfile currently loaded is old, ** because TeX generated a new one. */ If 0 ~= RESULT Then Quit Open new Open '"'LOGFILE'"' /* ** Now it's non-editable. */ Editable file Beg of file /* ** If we don't have the line number: search the number in the logfile. (hes) */ If 0 ~= NUMBER Then 'Search for' "l."NUMBER Else Do /* ** LaTeX mit seinen wilden Meldungen im Logfile müllt alles zu. Es ist ** gar nicht unwahrscheinlich, daß `l.' auftaucht, ohne eine Zeilennummer ** zu markieren. Da ich davon ausgehe, daß bei Aufruf dieses Scripts ein ** Fehler vorliegt, suche ich solange nach `l.', bis es in der ersten ** Spalte steht. Die weitere Verarbeitung bleibt unverändert. ** 12.11.1995 (as) */ Do Until 1 = COLUMN 'Search for' "l." FOUND = RESULT If FOUND Then Do Right Status CursorColumn COLUMN = RESULT End Else COLUMN = 1 End /* ** Take the current line from CED. */ 'Status 55' Parse Var RESULT "l." NUMBER . /* ** Save the current line plus 1 of the log file */ 'Status 57' DUMMY = SetClip("CURRENTLOGLINE",RESULT+2) End End; Else Okay1 "Konnte kein richtiges Logfile finden!" /* ** The following line should really read "jump to file errnfile" and not ** filename, because I have done extra work to get the right directory. But ** this information is only in errnfile, which contains an absolute pathname, ** and not in filename, which is the parameter supplied by virtex or initex, ** usually a relative pathname. CED's current directory is not necessarily ** virtex's one. It also seems that CED is not smart enough as to make the ** difference between foo:tgmoae/myfile and bar:tgmoab/myfile. If I say ** jump to file foo:tgmoae/myfile it may as well jump to bar:tgmoab/myfile, ** whichever window comes first. */ 'jump to file "'ERRNFILE'"' If 0 = RESULT Then Do /* ** Not reached with `OW ERRNFILE' above. */ Open new Open '"'errnfile'"' End /* ** TODO: another editor may have modified the disk file, or the user ** the currently loaded file, while virtex compiled an old version. How ** can I get rid of that stupid filerequester in that case? I said "open ** errnfile", so why does CED pop up a filerequester (and may put the ** user in the wrong directory too)? */ If 0 ~= NUMBER Then JumpTo NUMBER Beg of line Exit 0 End /* ** End of CED part. */ /* ** Micro(Gnu)Emacs (MG), to be found on AmigaLibDisk352. */ If Show('Port','mg') Then Do Address 'mg' Options Results /* ** The following waits until MG is deiconified. */ 'amiga-window-to-top' /* ** We need to prevent the user from continuing to type and thus ** modifying the newly created buffers. I choose the rexx-lock/unlock ** method to synchronise with the user because MG3b4 has some cursor ** position/display bugs: the cursor may erroneously appear in some ** buffer and overwrite it (on the screen only), and not appear in the ** bottom line where it belongs. */ If ASKLOAD Then Do /* ** This is dangerous if this script aborts. */ 'rexx-lock' Address Value RESULT 'rexx-request "TeX fand einen Fehler. Datei laden? "' RETC = RC RETS = RESULT 'rexx-unlock' Address Value RESULT If 1 < RETC | Left(Upper(RETS),1) = 'N' Then Do 'rexx-display ""' Exit 0 End Drop RETC RETS End 'find-file "'ERRNFILE'"' /* ** MG doesn't seem to set the RC value on a find-file. */ 'rexx-buffer' BUF /* ** buf.1 is the buffer name, buf.3 the number of lines. */ If NUMBER < BUF.3 Then Do 'delete-other-windows' If "" ~= LOGFILE Then Do 'split-window-vertically' /* ** Now get rid of old logfiles. Here I make sure that I get rid of ** every suspicious logfile, because multiple pathes may lead to the same ** file, as for example SYS:TeX/sample.log & TeX:sample.log. */ 'rexx-buffer-list' BUFFERS Parse Value NameStruc(LOGFILE) With IVOL IDIRS IBASE LOGNAME = Upper(SubStr(LOGFILE,1+IVOL+IDIRS)) Do I=1 To BUFFERS.0 If 0 < Index(Upper(BUFFERS.I.FILE),LOGNAME) Then Do 'switch-to-buffer "'BUFFERS.I.NAME'"' 'not-modified' 'kill-buffer "'BUFFERS.I.NAME'"' End End 'find-file "'LOGFILE'"' /* ** MG doesn't seem to set the RC value. */ 'beginning-of-buffer' If 0 ~= NUMBER Then 're-search-forward "^l."NUMBER' Else Do /* ** Try to use normal search? */ 're-search-forward "^l."' /* ^ means begin of line */ /* ** If search successfull get current line contents. */ If 0 = RC Then Do 'rexx-line' Parse Var RESULT "l."NUMBER . End End 'other-window' 'rexx-display "Now what''s that error?"' End; Else 'rexx-display "Konnte kein richtiges Logfile finden!"' If 0 ~= NUMBER Then 'goto-line 'NUMBER End; Else Do 'not-modified' 'kill-buffer "'BUF.NAME'"' 'rexx-display "Konnte fehlerhafte Datei nicht finden!"' Exit 5 End Exit 0 End /* ** End of MG part. */ /* ** Write macros for your favorite editor here. */ Say "TeXedit.rexx: Kein unterstützter Editor aktiv." Exit 10 /* ** When will ARexx supply GetEnv/SetEnv? */ MyGetEnv: Procedure Parse Arg NAME If Open(TEMPFILE,"ENV:"NAME,'r') Then Do GIVES = Readln(TEMPFILE) Call Close TEMPFILE End; Else GIVES = "" Return GIVES