Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add user available functions to open a URL in a web browser #4272

Open
fingolfin opened this issue Feb 18, 2021 · 11 comments
Open

Add user available functions to open a URL in a web browser #4272

fingolfin opened this issue Feb 18, 2021 · 11 comments
Labels
gapdays2021-spring Issues and PRs that could be tackled or discussed at https://www.gapdays.de/gapdays2021-spring good first issue Issues that can be understood and addressed by newcomers to GAP development kind: enhancement Label for issues suggesting enhancements; and for pull requests implementing enhancements

Comments

@fingolfin
Copy link
Member

We already go through a lot of effort to set HELP_VIEWER_INFO.browser to a function like this for HTML; but I know that the very least, the numericalsgps package by @pedritomelenas and friends needs such functionality, see https://github.com/gap-packages/numericalsgps/blob/231329432a3e6e651cfc8e719271ccb23ae973a7/gap/dot.gi#L62-L68 -- but I also think other uses might exist.

So, let's expose it through a dedicated function, say OpenURLInBrowser(url). Shouldn't be too hard (most work is a writing a reference manual entry for it)

One could do the same for PDFs, too, I guess...

@fingolfin fingolfin added kind: enhancement Label for issues suggesting enhancements; and for pull requests implementing enhancements good first issue Issues that can be understood and addressed by newcomers to GAP development gapdays2021-spring Issues and PRs that could be tackled or discussed at https://www.gapdays.de/gapdays2021-spring labels Feb 18, 2021
@pedritomelenas
Copy link

Also jupyterviz has this functionality, since I asked @nathancarter to add it and he kindle agreed. Probably francy also has it. I think that both used similar code as the one @fingolfin describes in dot.gi.
There is some "splash" functions in other packages, like in intpic by @ManuelAFDelgado.
One probably wants to splash a pdf or probably something written in graphviz dot language.

@RussWoodroofe
Copy link
Contributor

RussWoodroofe commented Feb 19, 2021

Suggestion: A starting point would be to have OpenURLInBrowser look at the help viewers. Typically, the preferred help viewer would also be the preferred browser for other purposes, and there's already some sometimes-nontrivial code to e.g. bring up a URL in Safari and go to a given anchor.

Of course, one needs to pick out a help viewer that can handle urls (or pdfs, if the passed url appears to be a pdf). It would be good to be able to flag a help viewer as for help only (and unsuitable for use by this function).

@nathancarter
Copy link

It's best to defer opening a file to the operating system, which will use the user's settings for the given file type. The relevant code is just these 7 lines:
https://github.com/nathancarter/jupyterviz/blob/master/lib/main.gi#L79-L85

if ARCH_IS_MAC_OS_X() then
    Exec( "open ", filename );
elif ARCH_IS_WINDOWS() then
    Exec( "start ", filename );
elif ARCH_IS_UNIX() then
    Exec( "xdg-open ", filename );
fi;

Note that since writing them, I now realize that there should probably be another entry in there for WSL, which should use the wslview command, but I'm not sure how to test if we're in a WSL environment...it would probably be a subcase of ARCH_IS_UNIX().

@ChrisJefferson
Copy link
Contributor

I agree with this general aim. Should wrap the filenames in ', but that's a minor issue.

Note that we are going to start distributing xdg-open with our cygwin install, so you won't need the ARCH_IS_WINDOWS() branch.

I've found the best thing to use in WSL is the slightly crazy looking:

Exec(Concatenation("explorer.exe "$(wslpath -a -w "",Filename(dir, "/output/index.html"), "")""));

And GAP now has an ARCH_IS_WSL() ( #4249 )

@fingolfin
Copy link
Member Author

@nathancarter that sounds nice in theory, but is not in practice, at least on macOS, as open does not support HTML anchors, which are important for the GAP help system. We tried to work around this by using AppleScript, and I think this used to work at some points: open location "URL#anchor"; but unfortunately this has the same issue as using open "URL" these days, i.e., it ignores the anchor. But it does work if one specifies the name of the browser: tell application "Safari" to open location "URL#anchor" honors the anchor.

(BTW, we could probably "fix" this on macOS by querying for the name of the user's default browser, see e.g. here and then using the tell application ... pattern I mention above).

Moreover, some users (e.g. me) genuinely prefer to use different browsers for different things (admittedly this is a niche audience).

@pedritomelenas
Copy link

I do not know if this https://apple.stackexchange.com/a/194873 may help. Though I do not know how to recover default's browser from @fingolfin 's comment...

@RussWoodroofe
Copy link
Contributor

@pedritomelenas, GAP does something pretty similar to the method in the post you link if you set the default help browser to "safari" or similar. (But "browser" uses open.)

To be a little clearer about the problem: the open command supports anchors for remote URLs starting with http: or https:, but it does not support for local URLs starting with file: (such as the ones GAP typically uses for help). Btw, a similar problem holds for opening URLs from the API.

@fingolfin
Copy link
Member Author

@pedritomelenas I gave a link with AppleScript code to recover the default browser, though? Based on that, here is a complete AppleScript snippet which opens a given URL with anchor in the user's default browser, with the anchor being honored; one could adapt that for use in GAP (replacing the current, much shorter AppleScript snippet, which however does not handle anchors right):

-- default_browser.applescript
-- https://discussions.apple.com/thread/250137080?answerId=250251688022#250251688022
-- Show currently set default browser. Change this via System Preferences : General panel
-- VikingOSX, 2019-02-03, Apple Support Communities, No warranty expressed or implied.

use framework "Cocoa"
--use AppleScript version "2.4" -- Yosemite 10.10 or later
use scripting additions

property NSURL : a reference to current application's NSURL
property NSWorkspace : a reference to current application's NSWorkspace
property NSFileManager : a reference to current application's NSFileManager

set any_url to "file:///Users/mhorn/Projekte/GAP/repos/pkg/pkg/pkg/genss/doc/chap3_mj.html#X858ADA3B7A684421"

set dsffsdf to my default_browser(any_url)

tell application (my default_browser(any_url))
	open location any_url
end tell
return

on default_browser(a_url)
	set the_url to NSURL's URLWithString:a_url
	set theApp to ((NSWorkspace's sharedWorkspace())'s URLForApplicationToOpenURL:the_url) as text
	return ((NSFileManager's alloc()'s init())'s displayNameAtPath:(POSIX path of theApp)) as text
end default_browser

@pedritomelenas
Copy link

pedritomelenas commented Mar 3, 2021

So @fingolfin, you mean something like this for macos

test := function (url)
    local script;
    script:= Concatenation( "osascript <<ENDSCRIPT\n",
                                  "use framework \"Cocoa\"\n",
                                  "use scripting additions\n",
                                  "property NSURL : a reference to current application's NSURL\n",
                                  "property NSWorkspace : a reference to current application's NSWorkspace\n",
                                  "property NSFileManager : a reference to current application's NSFileManager\n",
                                  "set any_url to \"", url, "\"\n",
                                  "set dsffsdf to my default_browser(any_url)\n",
                                  "tell application (my default_browser(any_url))\n ",
                                  "	open location any_url\n",
                                  "end tell\n",
                                  "return\n",
                                  "on default_browser(a_url)\n",
                                  "set the_url to NSURL's URLWithString:a_url\n",
                                  "	set theApp to ((NSWorkspace's sharedWorkspace())'s URLForApplicationToOpenURL:the_url) as text\n",
                                  "	return ((NSFileManager's alloc()'s init())'s displayNameAtPath:(POSIX path of theApp)) as text\n",
                                  "end default_browser\n",
                                  "ENDSCRIPT\n" );
    Print(script);
    Exec(script);
    return;
end;

It works on my mac. However, it opens a window prompting for the browser. I was not able to make it work for pdfs though; it asks for Preview.App and then shows an error.

@pedritomelenas
Copy link

pedritomelenas commented Mar 6, 2021

Well, I tried a more simpler approach based on https://apple.stackexchange.com/a/194873, and found that

test2 := function (url)
    local script;
    script:= Concatenation( "osascript <<ENDSCRIPT\n",
                                  "open location \"", url, "\"\n",
                                  "ENDSCRIPT\n" );
    Exec(script);
    return;
end;

just works on macOS 10.15.7 (Catalina) for examples with html, png, pdf, and even with html#anchor. Just try test2("https://github.com/nathancarter/jupyterviz/blob/master/lib/main.gi#L79-L85");.

I changed the default browser to chrome, and it worked.

@pedritomelenas
Copy link

pedritomelenas commented Mar 10, 2021

I agree with this general aim. Should wrap the filenames in ', but that's a minor issue.

Note that we are going to start distributing xdg-open with our cygwin install, so you won't need the ARCH_IS_WINDOWS() branch.

I've found the best thing to use in WSL is the slightly crazy looking:

Exec(Concatenation("explorer.exe "$(wslpath -a -w "",Filename(dir, "/output/index.html"), "")""));

And GAP now has an ARCH_IS_WSL() ( #4249 )

I was able to make this work for local files, but not for https.

This seems to work for https urls.

testwsl2 := function (url)
    local script;
    script:= Concatenation("explorer.exe " , url);
    Exec(script);
    return;
end;

and

testwsl2 := function (url)
    local script;
    script:= Concatenation("wsl-open " , url);
    Exec(script);
    return;
end;

in combination with wsl-open works for all files and urls.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
gapdays2021-spring Issues and PRs that could be tackled or discussed at https://www.gapdays.de/gapdays2021-spring good first issue Issues that can be understood and addressed by newcomers to GAP development kind: enhancement Label for issues suggesting enhancements; and for pull requests implementing enhancements
Projects
None yet
Development

No branches or pull requests

5 participants