From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Eli Zaretskii Newsgroups: gmane.emacs.bugs Subject: bug#71162: bug-gnu-emacs@gnu.org Date: Sat, 25 May 2024 09:09:23 +0300 Message-ID: <86msoe1kz0.fsf@gnu.org> References: <86wmnj3fc5.fsf@gnu.org> <9002e131-3466-4a73-a88c-bad260e5b886@ixont.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="16597"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 71162@debbugs.gnu.org To: David McCracken Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sat May 25 08:12:14 2024 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1sAkda-00042X-D0 for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 25 May 2024 08:12:14 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sAkdH-000637-Tp; Sat, 25 May 2024 02:11:55 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sAkdG-00062t-Ii for bug-gnu-emacs@gnu.org; Sat, 25 May 2024 02:11:54 -0400 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sAkdG-0004Yv-9x for bug-gnu-emacs@gnu.org; Sat, 25 May 2024 02:11:54 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1sAkdN-00037a-Jj for bug-gnu-emacs@gnu.org; Sat, 25 May 2024 02:12:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Eli Zaretskii Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 25 May 2024 06:12:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 71162 X-GNU-PR-Package: emacs Original-Received: via spool by 71162-submit@debbugs.gnu.org id=B71162.171661751411992 (code B ref 71162); Sat, 25 May 2024 06:12:01 +0000 Original-Received: (at 71162) by debbugs.gnu.org; 25 May 2024 06:11:54 +0000 Original-Received: from localhost ([127.0.0.1]:41373 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1sAkdF-00037M-Qa for submit@debbugs.gnu.org; Sat, 25 May 2024 02:11:54 -0400 Original-Received: from eggs.gnu.org ([209.51.188.92]:46492) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1sAkdC-00037G-KY for 71162@debbugs.gnu.org; Sat, 25 May 2024 02:11:52 -0400 Original-Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sAkat-0003tJ-6X; Sat, 25 May 2024 02:09:27 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:References:Subject:In-Reply-To:To:From: Date; bh=q3iAjiVuY3PIyf8AY9kbfxbK9ZglUB+CjJvi+Ip75fg=; b=HCV576KNtaQ40s6+Gxxj oASyF1350wthTyoA9U/H0GR8OSp9CiwTfC1spf4MGJDa6LDgwV5I0+IGFUgI99GeYwnHLfDHkncRW ggRbKvq3Y8+P45UJGlvUt3Ajd6THegxnQHALCfxcV8F/2UXY6GcCcfqHQmx9c8/ssRuXEOWFfF1l8 P2N410kNhi/ftW096SWR4KqDJwPsIkyGEUv2YFDL5JcrA6ZvdO6VBJQDeVeVHryP1nfenh5k9f3wG KzvhaVjrDdNVo7IJcRLExfwQOwyJ2xFGP1mlpK/+ydnzMhnXoGBFnC8Lduz0htH3T+zXfDnPVhFA0 17oifoyFPb++dA==; In-Reply-To: <9002e131-3466-4a73-a88c-bad260e5b886@ixont.com> (message from David McCracken on Fri, 24 May 2024 12:29:49 -0700) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:285813 Archived-At: --=-=-= Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable [Please use Reply All to reply, to keep the bug tracker CC'ed.] > Date: Fri, 24 May 2024 12:29:49 -0700 > From: David McCracken >=20 > I use the same icons and emacs code on Windows and Linux. In Windows it=20 > works in Emacs 29.1 and 26.1 (the two I currently use but it worked in=20 > older versions as well). In Ubuntu-Mate (20.54 and 22.04) it works in=20 > Emacs 26.3 but not 27.1. The code I use for this particular example is >=20 > (define-key-after (default-value 'tool-bar-map) > =A0 [separator-4] menu-bar-separator) > ; Linux-Emacs v25 includes pseudo-key name in the toolbar unless it is too > ; long, which is the only way to stop this unwanted behavior. > (tool-bar-add-item "~/icons/lxa-next" > =A0 'lxa-next > =A0 'lxa-next-reference > =A0 :help "LXA next reference") >=20 > In all cases except Emacs 27.1 in Linux the user icons directory is not=20 > a problem. However, it is an additional problem in 27.1 under Linux. The= =20 > same native lock-broken.xpm that works when in the images directory and=20 > referenced simply as "lock-broken" fails when moved to the user icons=20 > directory and referenced as "~/icons/lock-broken". 27.1 also ignores my=20 > lxa-next.xpm when moved to the images directory and referenced simply as= =20 > "lxa-next". Somebody hard-wired all flexibility out of this mechanism=20 > after 26.3 but only in the Linux version. I initially suspected the=20 > changes related to B/W pbm images, which is described in the images=20 > README but I found the same README in 26.3. If you visit (with C-x C-f) the lxa-next.xpm file in Emacs 27.1 on Ubuntu, does it display correctly as an image? If not, your Emacs 27.1 on Ubuntu is for some reason unable to display XPM images. If lxa-next.xpm does display correctly on Ubuntu, then you need to find out why adding a tool-bar button with an XPM image doesn't work for you. I just tried the below in "emacs-Q" (using Emacs 27.1), and it did show the additional tool-bar button: (defun lxa-next () (interactive) (message "lxa-next")) (tool-bar-add-item "~/icons/lxa-next" 'lxa-next 'lxa-next-reference :help "LXA next reference") Does the above work for you in "emacs -Q" on Ubuntu? If it works in "emacs -Q", but not in your regular sessions, then there are some customizations, perhaps site-wide and possibly by the Ubuntu distro, which somehow prevent this. In the upstream sources, I see no changes in this area. tool-bar-add-item still ends up calling tool-bar--image-expression, which calls find-image like this: (let* ((fg (face-attribute 'tool-bar :foreground)) (bg (face-attribute 'tool-bar :background)) (colors (nconc (if (eq fg 'unspecified) nil (list :foreground fg)) (if (eq bg 'unspecified) nil (list :background bg)))) (xpm-spec (list :type 'xpm :file (concat icon ".xpm"))) (xpm-lo-spec (list :type 'xpm :file (concat "low-color/" icon ".xpm"))) (pbm-spec (append (list :type 'pbm :file (concat icon ".pbm")) colors)) (xbm-spec (append (list :type 'xbm :file (concat icon ".xbm")) colors))) `(find-image (cond ((not (display-color-p)) ',(list pbm-spec xbm-spec xpm-lo-spec xpm-spec)) ((< (display-color-cells) 256) ',(list xpm-lo-spec xpm-spec pbm-spec xbm-spec)) (t ',(list xpm-spec pbm-spec xbm-spec)))))) As you see here, if your display can support at least 256 colors, the XPM image gets preference over the other possibilities. And find-image searches for the image file via image-search-load-path, which searches image-load-path, and for absolute file names like "~/images/lxa-next" should find the file immediately regardless of the value of image-load-path. So if your Emacs does not have some customizations, it should find the images without any problem. If the problem is some Ubuntu customizations, you should take that up with the Ubuntu distro maintainers; we here are only responsible for the original Emacs 27.1 tarball. > In case you are interested I have attached my complete code. I attach it below, because you sent the response only to me in private email (please use Reply All or "wide reply" in your future responses to this discussion). --=-=-= Content-Type: application/emacs-lisp Content-Disposition: attachment; filename=linkxall.el Content-Transfer-Encoding: quoted-printable ;;; linkxall.el --- Provides hyperlinking with LibreOffice LinkXall library= =0D ;; Copyright (C) 2022-2024 David McCracken=0D ;; Author: David McCracken=0D ;; Keywords: lisp LibreOffice LinkXall=0D ;; Version: 0.1.0=0D =0D ;; This program is free software; you can redistribute it and/or modify it = =0D ;; under the terms of the GNU General Public License version 3 as published= by =0D ;; the Free Software Foundation=0D =0D ;; This program is distributed in the hope that it will be useful,=0D ;; but WITHOUT ANY WARRANTY; without even the implied warranty of=0D ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the=0D ;; GNU General Public License for more details.=0D =0D ;; You should have received a copy of the GNU General Public License=0D ;; along with this program. If not, see .=0D =0D ;;; Commentary:=0D ;; Updated: 2024.04.10.11.16=0D ;; Purposes: Emacs LinkXall library. This works with the LibreOffice Basic= =0D ;; LinkXall library to implement plain text LinkXall-compliant hyperlinks i= n =0D ;; both Windows and Linux (with X). =0D =0D ;; Extended program comments are in LO doc files referenced here by links.= =0D ;; *LXA-ODF*|LXADOC|LxaUserGuide.odt*^1Emacs* General description in User G= uide.=0D ;; *LXA-ODF*|LXADOC|LxaUserGuide.odt*^2EmacsUserInterface* Menu Help.=0D ;; *LXA-ODF*|LXADOC|LxaDesign.odt*^1Emacs* Program design=0D =0D ;; Place this in Emacs\share\emacs\site-lisp and auto-load it with =0D ;; (load-library "linkxall.el" ) in .emacs. Also, all of the code is wrappe= d in=0D ;; a progn, which can be interactively evaluated to test program changes.=0D ;; Icons for the toolbar are located in ~/icons. In Windows, HOME evironmen= t=0D ;; variable must be defined, as e.g. C:\Home. The icons are lxa-backlink.xp= m,=0D ;; lxa-fwdlink.xpm, lxa-pin.xpm, lxa-prev.xpm, and lxa-next.xpm.=0D =0D ;; When this loads, it creates LXA menu and toolbar and assigns keyboard an= d =0D ;; mouse shortcuts. There are five major UI actions, open/follow, Back, For= ward,=0D ;; Previous, and Next. Open/follow is the only context-sensitive action. It= =0D ;; opens the menu at the caret on M-l (downcase-word is rebound to M-L) or = =0D ;; pointer on C-S-mouse-1 unless the text is a (syntactically) valid LinkXa= ll =0D ;; link, in which case the link is "followed" by passing it to LO LinkXall.= =0D ;; Back and Forward peruse the jump list, which is maintained by LinkXall. = =0D ;; Keyboard shortcuts M-S-left and M-S-right are bound to Back and Forward,= M-S-=0D ;; up and M-S-down to Previous and Next. Previous and Next search for the = =0D ;; previous and next reference, which is either a bookmark or link. =0D =0D ;; By default this asks the LinkXall (Libre BASIC) library to open all link= =0D ;; types. However, it can follow ODT, BSR, and WEB types itself and doing s= o may =0D ;; afford better performance in some circumstances. This "mixed" mode (BAS,= TXT, =0D ;; and SYS require the library) is enabled by replacing the t with nil in=0D ;; (setq lxa-min-follow t).=0D =0D ;**************************************************************************= *****=0D =0D (progn ; Wrapper to invoke all definitions during development.=0D =0D ; =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D UTILITIES =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0D =0D ;------------------------------- #move-mouse-to-point ---------------------= ---=0D (defun move-mouse-to-point()=0D (let ((pos (window-absolute-pixel-position)))=0D (set-mouse-absolute-pixel-position=0D (car pos) (cdr pos))))=0D =0D ; ------------------------------- #lxa-collapse ---------------------------= ----=0D (defun lxa-collapse(beg)=0D "Collapse selection to begin (BEG=3Dt) or end (BEG=3Dnil)"=0D (if (xor (> (point) (mark)) beg) (set-mark (point))=0D (set-window-point nil (mark))))=0D =0D ;------------------------------- #lxa-trim-string -------------------------= ------=0D (defun lxa-trim-string(str)=0D "Create new string from STR with leading and trailing space removed"=0D (replace-regexp-in-string "^\s+" "" =0D (replace-regexp-in-string "\s+$" "" str)))=0D =0D ;----------------------------- #lxa-condense-string -----------------------= ------=0D (defun lxa-condense-string(str)=0D "Return nil if trimmed STR is empty else `lxa-trim-string' STR"=0D (if (not (stringp str)) nil=0D (let ((ns (lxa-trim-string str)))=0D (if (equal ns "") nil ns))))=0D =0D ;----------------------------- #lxa-get-cursor-line -----------------------= ------=0D (defun lxa-get-cursor-line()=0D (save-excursion=0D (beginning-of-line)=0D (setq beg (point))=0D (end-of-line)=0D (lxa-trim-string (buffer-substring-no-properties beg (point)))))=0D =0D ;------------------------------- #lxa-index-list --------------------------= -----=0D (defun lxa-index-list( thing reflist )=0D "Return the 0-based index of THING in REFLIST or -1 if not in REFLIST.\n\=0D Typically, THING is a string and REFLIST is a list of strings"=0D (let ((listlen (length reflist)) (mlist (member thing reflist)))=0D (if mlist (- listlen (length mlist)) -1 )))=0D =0D (defun lxa-show-match (backward)=0D "Highlight the last search match"=0D (if backward ; after backward search=0D (progn=0D (goto-char (match-end 0))=0D (set-mark (point))=0D (goto-char (match-beginning 0)))=0D ; else after forward search=0D (goto-char (match-beginning 0))=0D (set-mark (point))=0D (goto-char (match-end 0))))=0D =0D ;------------------------------- #get-line-number -------------------------= ------=0D ; Emacs version 26 defines line-number-at-pos as optionsl POS ABSOLUTE and= =0D ; version 25 as optional POS. In v26 ABSOLUTE must be t or the line number= =0D ; is based on display. v25 is automatically abs without the argument but=0D ; complains when given two args.=0D (defun get-line-number() (line-number-at-pos nil t))=0D (condition-case nil=0D (get-line-number)=0D (error (defun get-line-number() (line-number-at-pos))))=0D =0D ;------------------------------ #lxa-focus-window -------------------------= -----=0D (defun lxa-focus-window( uri )=0D (if (> lxa-focus 0) =0D (pcase lxa-focus (1 (call-process "wmctrl" nil 1 nil "-a" uri))=0D (2 (call-process "wintop" nil 1 nil uri)))))=0D =0D ; =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D CORE FUNC= TIONS =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0D =0D ;----------------------------- #lxa-xcmd ----------------------------------= -=0D ; External command request. Typically from OO linkxall through wemecs or le= macs.=0D ; Return is irrelevant. =0D ;- cmd integer tells what to do. =0D ;- parm is string to search for or line (as string int) to go to.=0D ; All arguments are quoted strings because the interface program (wemacs or= =0D ; lemacs) doesn't know what they are when it builds the invocation command.= cmd=0D ; is required. parm and parm2 are optional. parm2 is unused but declared to= =0D ; afford the (external) caller more freedom in formulating the command line= . =0D ;=0D ; cmd is bitmap where:=0D ; b3 0 =3D search, 1 =3D go to line. If go to line then b0 =3D 0 means don'= t =0D ; highlight the line and 1 means do highlight it. If search then:=0D ; b2: 0 =3D case-sensitive, 1 =3D case-insensitive. =0D ; b1 =3D start at: 0 =3D current, 1 =3D begin if forward (b0=3D0), end if b= ackward (b0=3D1).=0D ; b0 =3D direction; 0 =3D forward, 1 backward=0D ; Thus:=0D ; 0 =3D search forward from current case-sensitive (4 =3D insensitive)=0D ; 1 =3D search backward from current case-sensitive (5 =3D insensitive)=0D ; 2 =3D search forward from begin case-sensitive (6 =3D insenstive)=0D ; 3 =3D search backward from end case sensitive (7 =3D insenstive)=0D ; 8 =3D go to line number parm and don't highlight the line.=0D ; 9 =3D go to line number parm and highlight the line.=0D ;=0D ; If not from current then go to end if backward or beginning if forward. I= f =0D ; from current then collapse the current selection to begin if backward or= =0D ; to end if forward to avoid repeatly finding the same instance.=0D ; The search function is invoked with limit=3Dnil and noerror=3Dt, which is= very=0D ; important because with default noerror=3Dnil on search failure this funct= ion=0D ; is aborted and an error code returned to the calling program, which will = not=0D ; be able to distinguish it from emacsclient failure.=0D ; *LXA-ODF*|LXADOC|LxaDesign.odt*^3lxa-xcmd*=0D ; *LXA-BAS*LinkXall>LinkXall*#LXAopenEmacs*=0D ; .........................................................................= ....=0D (defun lxa-xcmd(cmd &optional parm parm2)=0D "linkxall external command request"=0D (interactive)=0D (let* =0D ((cnum (string-to-number cmd))=0D (b0 (=3D (logand cnum 1) 1)) ; b0 =3D t if cmd b0 =3D 1=0D (b1 (=3D (logand cnum 2) 2)) ; b1 =3D t if cmd b1 =3D 1=0D (case-fold-search (=3D (logand cnum 4) 4)))=0D (when parm ; parm is required in all of the following cases. =0D (if (< cnum 8) ; Search for parm string=0D (progn =0D (if b1 (if b0 (end-of-buffer) (beginning-of-buffer)) (lxa-collaps= e b0))=0D (if (funcall (if b0 'search-backward 'search-forward) parm nil t)= =0D (progn (lxa-show-match nil) (setq lxa-search parm))=0D ; else not found. Collapse selection to avoid its extension and d= isplay error. =0D (set-window-point nil (mark))(message-box (concat "Unable to fi= nd " parm))))=0D ; else (cnum >=3D 8) goto to parm line number=0D (goto-line (string-to-number parm))=0D (when b0 (set-mark (point)) (end-of-line))) ; eol), when b0, if=0D ))t) ; when parm, let, defun=0D =0D ;------------------------- #lxa-back-fwd ----------------------------------= =0D ; *LXA-ODF*|LXADOC|LxaDesign.odt*^3LXAxrev*=0D (defun lxa-back-fwd(bf)=0D "Shared core of lxa-link-back and lxa-link-forward, used to peruse the \= =0D LXA link trail. BF is 'B' to go backward and 'F' to go forward. These speci= fic \=0D values are required for coordinating with other programs." =0D (let ((linkproc))=0D (setq linkproc=0D (start-process "openlinkproc" nil =0D (if (getenv "ODAPP") (substitute-in-file-name "$ODAPP") "soffice")=0D (concat "macro:///LinkXall.LinkXall.LXAxrev(\"" bf "\")") ))=0D (set-process-query-on-exit-flag linkproc nil)))=0D =0D ;-------------------------------- #lxa-link-back --------------------------= ------=0D (defun lxa-link-back()=0D "Go back to previous link point"=0D (interactive)=0D (lxa-back-fwd "B"))=0D =0D ;------------------------------ #lxa-link-forward -------------------------= -----=0D (defun lxa-link-forward()=0D "Go to next forward link point"=0D (interactive)=0D (lxa-back-fwd "F"))=0D =0D ;----------------------------- #lxa-set-pinpoint --------------------------= --=0D (defun lxa-set-pinpoint()=0D "Record point for revisit in jump list"=0D (interactive)=0D (let ((linkproc))=0D (setq linkproc=0D (start-process "openlinkproc" nil =0D (if (getenv "ODAPP") (substitute-in-file-name "$ODAPP") "soffice")= =0D (concat "macro:///LinkXall.LinkXall.LXAxlink(LXA-PIN;"=0D buffer-file-name ";" (number-to-string (get-line-number)) "*2)"))= )=0D ; *LXA-ODF*|LXADOC|LxaDesign.odt*^3LXAxlink*=0D ; *LXA-BAS*LinkXall>LinkXall*#LXAxlink=0D (set-process-query-on-exit-flag linkproc nil)))=0D =0D ; ---------------------- #lxa-prev-next --------------------------=0D (setq lxa-search nil)=0D =0D (defun lxa-prev-next(pn)=0D "Shared core of lxa-prev and lxa-next functions to search for the most \= =0D recent LXA reference. PN is t for previous (search backward) and nil for \= =0D next (search forward)"=0D (if (equal lxa-search nil) (message-box "There is no reference")=0D (if (use-region-p) (goto-char (if pn (region-beginning) (region-end))))=0D (when (funcall (if pn 'search-backward 'search-forward) lxa-search nil ni= l)=0D (lxa-show-match t) (message lxa-search))))=0D =0D ;---------------------------------- #lxa-prev -----------------------------= -----=0D (defun lxa-prev()=0D "Search backward for the lxa reference"=0D (interactive)=0D (lxa-prev-next t))=0D =0D ;---------------------------------- #lxa-next -----------------------------= -----=0D (defun lxa-next()=0D "Search forward for the lxa reference"=0D (interactive)=0D (lxa-prev-next nil))=0D =0D ;---------------------------------- #lxa-help-ui --------------------------= --------=0D (defun lxa-help-ui()=0D "User interface help"=0D (lxa-open-link "*LXA-ODF*|LXADOC|LxaUserGuide.odt*^2EmacsUserInterface*" = t ))=0D =0D ;---------------------------------- #lxa-help-bind ------------------------= ----------=0D (defun lxa-help-bind()=0D "Bindings help"=0D (lxa-open-link "*LXA-ODF*|LXADOC|LxaUserGuide.odt*^2Bindings*" t ))=0D =0D ;------------------------------ #lxa-open-err -----------------------------= -=0D (defun lxa-open-err()=0D (message-box "what")) ; "There is no LXA link in \"%s\"" (lxa-get-cursor-= line)))=0D =0D ;--------------------- #lxa-open-link -----------------------------------=0D ; Open (follow) an LXA-type link. =0D ; Return 0 if the text doesn't contain an LXA link type, 1 if it does but n= ot a =0D ; completely valid link (syntax error or missing piece), 2 if the link URL = =0D ; includes an undefined environment variable, 3 if the link is completely v= alid =0D ; but the target can't be opened, and 4 on complete success. =0D ; Optional Arguments:=0D ;- txt is the text to be evaluated. If not provided then the line containin= g the=0D ; cursor is evaluated.=0D ;- rpt t tells to report to the user all errors processing the text as a li= nk.=0D ; Missing or nil tells to report only errors trying to follow a syntactica= lly =0D ; valid link.=0D ; *LXA-ODF*|LXADOC|LxaDesign.odt*^3lxa-open-link*=0D ; .........................................................................= ..=0D (defun lxa-open-link(&optional txt rpt) =0D "Open a link to a LibreOffice document or macro library, another text file,= \n\=0D local HTML file, or web URL. This requires LibreOffice with LinkXall librar= y.\n\=0D Optional TXT is a LinkXall text link. If missing then the entire line\n\=0D containing the cursor is processed. Optional RPT if t tells to report\n\=0D all errors to the user. If missing or nil then only interpretation errors\n= \=0D are reported."=0D (interactive)=0D (unless txt (setq txt (lxa-get-cursor-line)))=0D (catch 'fatal=0D (setq lxa-err 0)=0D (let* ( (oswin (equal system-type 'windows-nt)) =0D (oslin (not oswin))=0D (linktype -1) =0D (args (split-string txt "*" nil))=0D beg name uri bm linkproc wcnt outbuf kbqf here nopro )=0D (while =0D (progn=0D (setq name (pop args))=0D (and name=0D (< (setq linktype =0D (lxa-index-list name =0D (list "LXA-BAS" "LXA-ODF" "LXA-TXT" "LXA-BSR" "LXA-SYS" = "LXA-WEB")=0D ))0))))=0D (when (< linktype 0) =0D (when rpt (message-box "No LXA link type in \"%s\"" txt))=0D (throw 'fatal 0))=0D (setq uri (lxa-condense-string (pop args)))=0D (when (not uri)=0D (when rpt (message-box "LXA link missing URI in \"%s\"" txt))=0D (throw 'fatal 1))=0D (setq bm (lxa-condense-string (pop args)))=0D =0D (setq here =0D (concat buffer-file-name ";" =0D (number-to-string (get-line-number))))=0D =0D ; ---------------- minimal form -------------------------------------------= ------=0D ; If configured to use only min form or if linktype is only supported by mi= n=0D ; (0/BAS, 2/TXT, 4/SYS).=0D (if (or lxa-min-follow (> (lxa-index-list linktype (list 0 2 4)) -1))= =0D (progn=0D ;(message (concat "macro:///LinkXall.LinkXall.LXAxlink(" name "*" uri "*" b= m ";" here "*2)")) ; ))))))=0D (setq linkproc =0D (start-process "openlinkproc" nil =0D (if (getenv "ODAPP") (substitute-in-file-name "$ODAPP") "soff= ice")=0D (concat "macro:///LinkXall.LinkXall.LXAxlink(" =0D name "*" uri "*" bm ";" here "*2)")))=0D (set-process-query-on-exit-flag linkproc nil)=0D (if lxa-min-focus =0D (lxa-focus-window (if (=3D linktype 0) "LibreOffice Basic" =0D (file-name-nondirectory uri))))=0D ) ; min form progn=0D =0D ;--------------- else long form ---------------------=0D (setq nopro (not (string-match ":///" uri)))=0D (if nopro ; Expand/test uri unless (WEB) protocol.=0D (progn=0D (setq uri =0D (replace-regexp-in-string "|[^|]+|" =0D ; If the environment variable is not in the dictionary, lxa-getenvar throws= =0D ; 'fatal 3.=0D (lambda(var) (lxa-getenvar (substring var 1 -1)))=0D uri t)) ; Note t fixedcase optional argument to =0D ; replace-regexp-in-string. Otherwise it uses the case of the varname.=0D (setq uri ; If relative convert to absolute.=0D (expand-file-name uri (file-name-directory buffer-file-name))= )=0D (if (not (file-readable-p uri))=0D (progn (message-box (concat uri " does not exist.")) =0D (throw 'fatal 3)))))=0D =0D ; If WEB or BSR when DEFBROWSER is not defined then use browse-url. This =0D ; function always returns nil. Failure will be silent unless the system rep= orts =0D ; it. LinkXall supports both with and w/o protocol but browse-url fails in = Linux=0D ; without file:/// so this is prefixed to uri if it has no protocol. This d= oesn't=0D ; hurt in Windows.=0D (if (or (=3D linktype 5) ; WEB=0D (and (=3D linktype 3) ; BSR=0D (null lxa-browser)))=0D (browse-url (concat (if nopro "file:///") uri =0D (if (and bm oslin)(concat "#" bm))))=0D ;(message-box (concat (if nopro "file:///") uri (if (and bm oslin)(concat "= #" bm))))=0D ; Else LXA-ODF or LXA-BSR with DEFBROWSER defined.=0D (if (=3D linktype 1) ; ........... LXA-ODF ....................=0D (progn=0D ;(message (concat uri " macro:///LinkXall.LinkXall.LXAxlink(" bm ";" here "= *2)")) ; )))))))=0D (setq linkproc =0D (start-process "openlinkproc" nil =0D (if (getenv "ODAPP") =0D (substitute-in-file-name "$ODAPP") "soffice")=0D uri=0D (concat "macro:///LinkXall.LinkXall.LXAxlink(" bm ";" her= e "*2)")))=0D ;(if (equal bm nil) ";" bm) "," here "*2)")))=0D (set-process-query-on-exit-flag linkproc nil)=0D ; lxa-wmctrl is t if wmctrl is installed, which also means this is Linux, i= n =0D ; which case, if soffice is already open, the document window won't be brou= ght =0D ; forward. We can do that with wmctrl. -a tells to make the specified windo= w =0D ; top-most. =0D ;(if lxa-wmctrl (call-process "wmctrl" nil 1 nil "-a" =0D ; (file-name-nondirectory uri)))=0D ) ; ODT progn=0D =0D ; Else ............... LXA-BSR with bm in Windows ..................=0D (setq uri (concat "file:///" uri))=0D (setq outbuf "*openlinkbuf*")=0D (setq wcnt (length (window-list)))=0D (async-shell-command =0D (concat =0D (shell-quote-argument lxa-browser)=0D " " uri "#" bm) outbuf outbuf)=0D (if (bufferp (get-buffer outbuf))=0D (progn=0D (sleep-for 0.5)=0D (setq kbqf kill-buffer-query-functions)=0D (setq kill-buffer-query-functions nil)=0D (kill-buffer outbuf)=0D (setq kill-buffer-query-functions kbqf) ; This is supposed = to=0D ; suppress "active processes" query if closing Emacs with the spawned app s= till=0D ; open but it doesn't work.=0D (if (equal wcnt 1) (delete-other-windows))))=0D ) ; ODT and BSR=0D ) ; If WEB else ODT/BSR=0D (lxa-focus-window uri) ; Unconditionally in long form=0D ) ; End of long form clause and follow-form if.=0D 4 ) ; No problems.=0D ) ; catch=0D ) ; lxa-open-link=0D =0D ; ------------------------ #lxa-lxa --------------------------------------= =0D ; If there is a valid LXA link at the point then open it. Otherwise open th= e =0D ; LinkXall menu at the point. To allow the menu to be opened in a line =0D ; containing a valid link, if a region has been selected then unconditional= ly =0D ; open the menu. The link may still be followed using the menu's Follow lin= k.=0D ; *LXA-ODF*|LXADOC|LxaDesign.odt*^3lxa-lxa*=0D ; .....................................................................=0D (defun lxa-lxa()=0D "Process LXA request at the cursor. If the text contains an LXA link \=0D then open it. Otherwise, or if a region has been selected, open the LinkXal= l \=0D menu at the cursor."=0D (interactive)=0D (when (or (use-region-p)(< (lxa-open-link nil nil) 4))=0D (move-mouse-to-point)=0D (let ((sel (x-popup-menu t lxa-menu)))=0D (pcase (car (split-string (format "%s" (car sel))))=0D ("Back" (lxa-link-back))=0D ("Forward" (lxas-link-forward))=0D ("Set" (lxa-set-pinpoint))=0D ("Previous" (lxa-prev))=0D ("Next" (lxa-next))=0D ("Follow" (lxa-open-link nil t))=0D ("Start" (server-start nil t))=0D ("Help" =0D (pcase (car (split-string (format "%s" (car (cdr sel)))))=0D ("User" (lxa-help-ui))=0D ("Bindings" (lxa-help-bind))))))))=0D =0D ; ------------------------------ #lxa-menu --------------------------------= -=0D (easy-menu-define lxa-menu nil "lxa-menu"=0D '(lxa-menu=0D ["Back link\tC-, (<)" (lxa-link-back)]=0D ["Forward link\tC-. (>)" (lxa-link-forward)]=0D ["Set pinpoint" (lxa-set-pinpoint)]=0D ["Previous reference\tM-S-up" (lxa-prev)]=0D ["Next reference\tM-S-down" (lxa-next)]=0D ["Follow link\tM-l (L) or C-S-leftClick" (lxa-open-link nil t)] ;(lx= a-lxa t)]=0D ["Start server" (server-start nil t)]=0D ("Help" =0D ["User interface" (lxa-help-ui)]=0D ["Bindings" (lxa-help-bind)])))=0D ; At right end (between Tools and Emacs-Lisp)=0D (define-key-after (lookup-key global-map [menu-bar])=0D [lxa-menu]=0D (cons "LinkXall" lxa-menu) t) ; t, 'file, 'edit, etc. or empty.=0D ; At left end=0D ; (define-key (lookup-key global-map [menu-bar])=0D ; [lxa-menu]=0D ; (cons "LinkXall" lxa-menu))=0D =0D ; =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D ENV DICTIONARY =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0D ; These functions are needed only if Emacs follows one or more LXA link typ= es =0D ; itself instead of passing the text to LO LinkXall to do everything.=0D ; *LXA-ODF*|LXADOC|LxaDesign.odt*^2EmacsEnvironmentDictionary*=0D =0D ;--------------------------- #lxa-getenvar --------------------------------= ---=0D (defun lxa-getenvar(str &optional silent)=0D "Get the lxa private or public environment variable value"=0D (let (( val (if lxaenvars (cdr (assoc str lxaenvars)))))=0D (if (not val) (setq val (subst-char-in-string ?\\ ?/ (getenv str))))=0D (if (or (not val) (string=3D val ""))=0D (if silent nil=0D (message-box (concat str " environment variable is undefined"))=0D (throw 'fatal 2)) =0D val)))=0D =0D ;--------------------------- #lxa-read-env --------------------------------= ---=0D (defun lxa-read-env()=0D "Make lxaenvars alist from the envar.txt file in the $LINKXALL_ENV director= y.\n\=0D If the standard environment variable LINKXALL_ENV is undefined or \n\=0D $LINKXALL_ENV/envar.txt does not exist, lxaenvars is nulled and nil is retu= rned.\n\=0D Otherwise, t is returned. This automatically executes when the library load= s but\n\=0D it may also be invoked interactively to update the dictionary after editing= the file."=0D (interactive)=0D ; Verify dictionary creation by C-h V lxaenvars, which shows the list of co= ns cells.=0D (setq lxaenvars nil)=0D (let ((fspec (getenv "LINKXALL_ENV")))=0D (if (not fspec) nil=0D (setq fspec (concat fspec "/envar.txt"))=0D (if (not (file-readable-p fspec)) nil=0D (with-temp-buffer=0D (insert-file-contents fspec)=0D (goto-char (point-min))=0D (while (not (eobp)) =0D (re-search-forward "^ *\\([^=3D]+\\)=3D\\(.+\\)$" nil t)=0D ; The arguments to re-search-forward are RE limit noerror. nil limit means = end =0D ; of buffer. This is just a place-holder enabling noerror t, which means to= =0D ; return nil but not signal an error if the match fails. This is critical f= or =0D ; blank lines, which don't mean anything bad or good.=0D (if (< (aref (match-string 1) 0) ?A) nil=0D (setq lxaenvars =0D (append lxaenvars =0D `(( ,(match-string 1) . =0D ,(subst-char-in-string ?\\ ?/ (match-string 2))))))=0D (forward-line 1))))t)))) ; lxa-read-env=0D =0D ; =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D INITIALIZATION =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0D ;--------------------- #lxa-mouse-open -------------------------=0D (defun lxa-mouse-open()=0D "Move cursor to mouse position and invoke `lxa-lxa'"=0D (interactive) ; Required for binding to mouse button=0D (mouse-set-point last-input-event)=0D (redisplay t)=0D (lxa-lxa)=0D ) ; lxa-mouse-open=0D =0D ;---------------- #hot keys ---------------------------------------=0D (global-set-key "\M-L" 'downcase-word) ; Rebind to free \M-l.=0D (global-set-key "\M-l" 'lxa-lxa) =0D (global-set-key [C-S-mouse-1]#'lxa-mouse-open)=0D =0D (global-unset-key (kbd "C-,")) =0D (global-set-key (kbd "C-,") 'lxa-link-back) =0D =0D (global-unset-key (kbd "C-.")) =0D (global-set-key (kbd "C-.") 'lxa-link-forward)=0D =0D (global-set-key [M-S-up]#'lxa-prev)=0D (global-set-key [M-S-down]#'lxa-next)=0D =0D ; ------------------------ #toolbar --------------------------------=0D (define-key-after (default-value 'tool-bar-map)=0D [separator-4] menu-bar-separator) =0D =0D ; Linux-Emacs v25 includes pseudo-key name in the toolbar unless it is too= =0D ; long, which is the only way to stop this unwanted behavior.=0D =0D (tool-bar-add-item "~/icons/lxa-backlink" =0D 'lxa-link-back ; function=0D 'lxa-external-link-back ; pseudo-key name =0D :help "LXA external link back")=0D =0D (tool-bar-add-item "~/icons/lxa-fwdlink" =0D 'lxa-link-forward =0D 'lxa-external-link-forward=0D :help "LXA external link forward")=0D =0D (tool-bar-add-item "~/icons/lxa-pin" =0D 'lxa-set-pinpoint =0D 'lxa-external-set-pinpoint=0D :help "LXA set pinpoint")=0D =0D (tool-bar-add-item "~/icons/lxa-prev" =0D 'lxa-prev =0D 'lxa-prev-reference =0D :help "LXA previous reference")=0D =0D (tool-bar-add-item "~/icons/lxa-next" =0D 'lxa-next =0D 'lxa-next-reference =0D :help "LXA next reference")=0D =0D ; ------------------------- #Environment ----------------------------------= =0D ; Environment dictionary and focus are related but independent. If Emacs fo= llows=0D ; any link type itself then it must be able to focus the target but even if= it =0D ; asks LO LinkXall to handle all links, window focus may still be more reli= able=0D ; if done here instead of (or in addition to) in LO.=0D ;- lxa-min-follow t means use min follow form for all. If nil then mixed, w= ith =0D ; min form used for BAS, TXT, and SYS and long form for the others.=0D ;- lxa-min-focus t means that min form tries to focus the target window. Th= is=0D ; applies regardless of whether all min or mixed. Focus is always done in l= ong=0D ; form.=0D ; ........................................................................= =0D (setq lxa-min-follow t) ; t =3D use only min form, nil =3D mixed.=0D (unless lxa-min-follow ; Only mixed needs this.=0D (lxa-read-env)=0D (setq lxa-browser (lxa-getenvar "DEFBROWSER" t)))=0D ;(if lxa-browser (message-box lxa-browser))=0D (setq lxa-min-focus nil) ; t =3D focus target window in min form. This is= done=0D ; only because LinkXall does not do it or is unsuccessful in some cases.=0D (setq lxa-focus (if (executable-find "wmctrl") 1 =0D (if (executable-find "wintop") 2 0)))=0D t ) ; End of progn wrapper. Place cursor at close paren and type C-x C-e.=0D ;; =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0D (provide 'linkxall)=0D =0D =0D ;=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0D ; LinkXall uses four public environment variables related to Emacs. =0D ; EMACSEXEPATH is the path to emacs, emacsclient, and (in Windows) runemacs= .=0D ; This must include a trailing delimiter, e.g. "C:/something/emacs/bin/"=0D =0D ; ODAPP is soffice filespec, e.g. "C:/Program Files/LibreOffice/program/sof= fice"=0D =0D ; LINKXALL_ENV tells the location of LinkXall's private environment file =0D ; envar.txt, e.g. "C:/Home/LinkXall/" or "/home/user/linkxall". This needs = to=0D ; be defined only if linkxall.el is configured for mixed form and expands=0D ; environment variables itself. =0D =0D ; DEFBROWSER is the preferred browser filespec, e.g. =0D ; "C:/Program Files/Mozilla Firefox/firefox.exe" or "/usr/bin/firefox". =0D ; If undefined then the system default browser will be used to follow LXA-B= SR =0D ; links (it is always used for LXA-WEB links). DEFBROWSER may alternatively= be =0D ; defined in envar.txt. DEFBROWSER mainly exists to address Windows lack of= =0D ; support for standard bookmark (partial-URL) syntax "#bookmark". It also = =0D ; enables using different browswers for local files vs. Web. This is neede= d =0D ; here only if configured for mixed form. =0D =0D ; EMACSEXEPATH and ODAPP exist mainly exist for Windows, which doesn't =0D ; automatically put these programs in the path. However, they are also acce= pted=0D ; in Linux. If undefined (in either OS) the programs are invoked just by na= me=0D ; and must be in the path. EMACSEXEPATH is used by wemacs.exe, lemacs, and = =0D ; LinkXall library. Only linkxall.el uses ODAPP.=0D =0D ; LINKXALL_ENV is the only variable that exists for a reason other than to = =0D ; correct a Windows problem. It is typically the only one of these variable= s be =0D ; be defined in Linux and then only if linkxall is configured for mixed for= m.=0D ;=0D ; Use the following temporaries for testing. After changing LINKXALL-ENV, e= val =0D ; the all-encompassing progn to build the dictionary.=0D =0D ;(setenv "ODAPP" "C:/Program Files/LibreOffice/program/soffice") ; Windows= =0D ;(setenv "DEFBROWSER" "C:/Program Files/Mozilla Firefox/firefox.exe") ; Win= dows=0D ;(setenv "LINKXALL_ENV" "C:/Home/LinkXall") ; Windows=0D ;(setenv "LINKXALL_ENV" "~/linkxall") ; Linux=0D =0D ; To make these semi-permanent make them user variables in System Propertie= s > =0D ; Advanced > Environment variables. They will appear in any subsequently op= ened =0D ; windows. Linux is more complicated. Ubuntu recommends putting them in a = =0D ; startup script, e.g. /etc/profile.d/linkxall.sh containing export =0D ; LINKXALL_ENV=3D~/linkxall. These take effect on reboot but full system re= boot =0D ; is not required. sudo systemctl restart display-manager works in most sys= tems =0D ; but the x-manager may need to be explicitly named, e.g. sudo systemctl =0D ; restart lightdm. Get the name by cat /etc/X11/default-display-manager =0D =0D ; =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D TEST C= ASES =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0D ; Min form suppports all LXA types BAS, ODT, TXT, BSR, SYS, and WEB. Long f= orm =0D ; supports only ODT, BSR, and WEB. These are tested for both min and long. = BAS,=0D ; TXT, and SYS can only be tested for min form, which is automatically sele= cted =0D ; regardless of lxa-min-follow value.=0D =0D ; Syntax and missing file error tests can be OS-agnostic. Tests that are =0D ; expected to succeed can use environment or relative addressing. Absolute = must =0D ; be OS-specific.=0D =0D ; ..................... Syntax Errors ..................................=0D ; Syntax errors are reported here for all types if open link is invoked fro= m =0D ; the menu. With KB/mouse shortcuts they just cause the context menu to ope= n.=0D ; *LXA-JUNK*someFile** Windows and Linux. No link here.=0D ; *LXA-ODF*** Windows and Linux. No uri.=0D =0D ; ..................... Inaccessible Target ...............................= ..=0D ; Missing file is reported here (long form) or in LinkXall (min form) excep= t=0D ; for LXA-WEB with protocol (even file:///) which may fail silently in Linu= x.=0D ; *LXA-ODF*badFile.odt** Windows and Linx. min and long form.=0D ; *LXA-BSR*badFile.odt** Windows and Linx. min and long form. DEFBROWSER is= =0D ; irrelevant.=0D ; ShellExecute error (in echo area). min form displays system error.=0D ; *LXA-BAS*LinkXall>NoLib*WhoCares* Only min form. LinkXall error message.= =0D ; *LXA-TXT*noFile*NotMe* Only min form. LinkXall error message.=0D ; *LXA-SYS*noFile*NotMe* Only min form. LinkXall error message.=0D ; *LXA-WEB*badFile.odt** Windows and Linux. min and long form.=0D ; *LXA-WEB*file:///badFile.htm** Windows and Linux. In Windows long form re= ports=0D ; in echo line, min in system error box. Fails silently with either form = in=0D ; Linux.=0D =0D ; ...................... Address Forms ...................................= =0D ; These are all done with ODT because that can be tested for both min and=0D ; long forms and the canonical test of all forms with all link types is=0D ; too much since this is not automated.=0D ; *LXA-ODF*test/bm3.odt*bm2* Relative=0D ; *LXA-ODF*|SWDEV|Emacs/test/bm3.odt*bm2* Private environment.=0D ; *LXA-ODF*|HOMEPATH|/linkxall.odt*bm3* Windows public environment.=0D ; *LXA-ODF*|SSH_AUTH_SOCK|/linkxall.odt*bm3* Linux public environment=0D ; *LXA-ODF*c:/SwDev/Emacs/test/bm3.odt*bm2* Absolute Windows=0D ; *LXA-ODF*/home/d/work/SwDev/Emacs/test/bm3.odt*bm2* Absolute Linux=0D ; *LXA-ODF*/SwDev/Emacs/test/bm3.odt*bm2* Root Windows=0D =0D ; ....................... Min form only ..................................= =0D ; BAS, TXT, and SYS can only be processing by min form. The only option her= e=0D ; is whether we try to focus the target window. Since all but simple syntax= =0D ; verification is done in LinkXall, it would be reasonable for LinkXall to= =0D ; focus the window but it may not be able to reliably do this when acting a= s=0D ; hyperlink server.=0D ; *LXA-BAS*LinkXall>LinkXall*#LXAopenLink=0D ; *LXA-TXT*test/linkxall.el*Min form only* Relative addressing.=0D ; *LXA-TXT*|SWDEV|Emacs/test/linkxall.el*Min form only* Env addressing.=0D ; *LXA-SYS*test/getch.py** Relative addressing=0D ; *LXA-SYS*|SWDEV|Emacs/test/getch.py** Env addressing=0D =0D ; .......................... ODT ..........................................= =0D ; *LXA-ODF*|SWDEV|/Libre/LinkXall/linkXall.odt*bm3=0D ; *LXA-ODF*|SWDEV|Libre/LinkXall/bm 4 .odt*bm8=0D ; *LXA-ODF*../Libre/LinkXall/linkxall.odt*bm3*comment=0D ; *LXA-ODF*|HOMEPATH|/work/test/bm3.odt*bm2* Windows public environment.=0D ; *LXA-ODF*C:/home/work/test/bm3.odt*Bm30*Windows absolute=0D ; *LXA-ODF*C:\home\work\test\bm3.odt*Bm30*Windows absolute=0D ; *LXA-ODF*/home/d/work/test/bm3.odt*Bm30*Linux absolute=0D ; Relative with bm w/o comment *LXA-ODF*test/bm3.odt*firstBm*=0D ; Relative with bm w/o comment *LXA-ODF*test/bm3.odt*firstBm=0D ; *LXA-ODF*test/bm3.odt*firstBm *Relative with commebNt after bm=0D ; *LXA-ODF*test/bm3.odt* firstBm * bm in space=0D ; *LXA-ODF*test/bm3.odt** Relative with comment after null bm=0D ; *LXA-ODF*test/bm3.odt* * Comment after blank bm=0D ; *LXA-ODF*~/work/test/bm3.odt*Bm30* Fails. ~ is ordinary.=0D ; *LXA-ODF*|HOME|/work/test/bm3.odt*bm2* Private or public environment var= iable=0D ; *LXA-ODF*|LIBRARY|/bm1test.odt*bm1* Private environment variable=0D ; *LXA-ODF*baddir/LinkXall*=0D ; *LXA-ODF*|SWDEV|/Libre/LinkXall/linkXall.odt*bm3 *Private environment va= riable=0D ; *LXA-ODF*|SWDEV|Libre/LinkXall/linkXall.odt*bm4=0D ; *LXA-ODF*** No recognized link because null uri=0D ; *LXA-ODF*~/work/test/bm3.odt* Opens the file but bm is this comment=0D ; *LXA-ODF*test/icky.odt*Bm30 * Bad file but possibly good bm. Test with/wo= other file open.=0D ; *LXA-ODF*../Libre/LinkXall/linkXall.odt*textOpenLink=0D ; *LXA-ODF*../Libre/LinkXall/linkXall.odt** Placeholder for no bookmark=0D =0D ; .......................... TXT ..........................................= .=0D ; *LXA-TXT*|SWDEV|Emacs/vMixed/linkxallSelf.el*#lxa-read-env=0D ; *LXA-TXT*|SWDEV|Emacs/linkxall.el*#lxa-read-env=0D ; *LXA-TXT*|UNDEFINED|hi.txt*=0D ; *LXA-TXT*|SSH_AUTH_SOCK|/something.txt* Linux public environment=0D ; *LXA-TXT*|LXADOC|link x all.el*End of progn wrapper=0D =0D ; .......................... BSR .......................................=0D ; min and long forms. If DEFBROWSER is not defined the link is treated as W= EB =0D ; with file protocol and, if Windows, any bookmark is dropped. WEB automati= cally=0D ; moves the window to front but this happens with BSR only if the browser i= s =0D ; not already open. This is corrected using wintop.exe or wmctrl.=0D ; *LXA-BSR*test/index.html*patents=0D ; *LXA-BSR*|WEB|portfolio/index.html*patents=0D ; *LXA-BSR*|LXADOC|/this was index.html*patents=0D ; *LXA-BSR*|HOME|/work/test/index.html*experience*=0D ; *LXA-BSR*~/work/test/index.html*experience=0D ; *LXA-BSR*test/index.html*patents* Relative=0D ; *LXA-BSR*c:/Web/portfolio/index.html*patents* Absolute Windows=0D ; *LXA-BSR*/home/d/work/Web/portfolio/index.html*patents* Absolute Linux=0D ; *LXA-BSR*unrealFile** Windows or Linux. Error reported by Emacs or Libre.= =0D ; *LXA-BSR*$HOME/work/test/index.html*patents* This does work in Windows.=0D =0D ; ........................... WEB ......................................=0D ; *LXA-WEB*|HOME|/work/test/index.html*experience*=0D ; *LXA-WEB*c:/home/work/test/index.html*patents* Semi-absolute=0D ; *LXA-WEB*c:/home/work/test/index.html=0D ; *LXA-WEB*~/work/test/index.html*experience=0D ; *LXA-WEB*unrealFile** Windows or Linux. Error reported by Emacs or Libre.= =0D ; *LXA-WEB*file:///c:/Web/portfolio/index.html*experience* Windows abs with= file protocol.=0D ; *LXA-WEB*c:/Web/portfolio/index.html*experience* Windows abs w/o protocol= .=0D ; *LXA-WEB*file:///home/d/work/Web/portfolio/index.html*experience* Linux a= bs with protocol.=0D ; *LXA-WEB*/home/d/work/Web/portfolio/index.html*experience* Linux abs with= out protocol.=0D ; *LXA-WEB*file:///|HOME|/work/test/index.html** Env fails if uri with prot= ocol.=0D ; *LXA-WEB*|HOME|/work/test/index.html** Env ok if uri without protocol.=0D ; *LXA-WEB*file:///test/index.html** Rel fails if uri with protocol.=0D ; *LXA-WEB*test/index.html** Rel ok if uri w/o protocol.=0D ; *LXA-WEB*file:///$HOME/work/test/index.html*patents* Semi-absolute with b= m fails in Windows.=0D ; *LXA-WEB*file:///~/work/test/index.html** Fails (with Emacs warning in Wi= ndows=0D ; but silently in Linux) because ~ is not expanded for LXA-WEB.=0D ; *LXA-WEB*file:///home/d/work/Web/portfolio/index.html** Absolute Linux=0D ; *LXA-WEB*http:///ixont.com/portfolio/index.html* * Opens the file in the = website. =0D ; *LXA-WEB*http:///ixont.com/portfolio/index.html*patents* Opens the file i= n the website at the anchor. =0D --=-=-=--