|
#############################################################################
##
## This file is part of GAP, a system for computational discrete algebra.
## This file's authors include Frank Lübeck.
##
## Copyright of GAP belongs to its developers, whose names are too numerous
## to list here. Please refer to the COPYRIGHT file for details.
##
## SPDX-License-Identifier: GPL-2.0-or-later
##
## The files helpview.g{d,i} contain the configuration mechanism for the
## different help viewer.
##
#############################################################################
##
## the user interface for the help viewer choice
##
#############################################################################
##
#V HELP_VIEWER_INFO
##
## This record contains records for each possible help viewer: each
## stores the `.type' of the output data (currently supported: "text",
## "url", "pdf", "dvi") and a function `.show' for showing the output
## data.
##
## The output data (from handler.HelpData) must have the following
## form:
##
## "text": a format as allowed by `Pager' (usually rec(lines:=text,
## start:=linenr, formatted:=true))
##
## "url": an URL (usually local `file://' URL)
##
## "dvi": a filename or a record rec(file:=filename, page:=pagenr)
## where pagenr is the first page to show
##
## "pdf": same as for "dvi"
##
# The preferred help viewers can be specified via a user preference.
DeclareUserPreference( rec(
name:= [ "HelpViewers", "XpdfOptions", "XdviOptions" ],
description:= [
"Here you can choose your preferred help viewers. See the help for \
<Ref Func=\"SetHelpViewer\"/> for further options.",
"Try <C>HelpViewers:= [ \"screen\", \"firefox\", \"xpdf\" ];</C>.",
"(For <C>\"screen\"</C> we also suggest to set the <C>Pager</C> entry \
to <C>\"less\"</C>.)"
],
default:= [ [ "screen" ], "", "" ],
check:= function( helpviewers, xpdfoptions, xdvioptions )
return IsList( helpviewers ) and ForAll( helpviewers, IsString )
and IsString( xpdfoptions ) and IsString( xdvioptions );
end,
) );
# text on screen
HELP_VIEWER_INFO.screen := rec(
type := "text",
show := PagerAsHelpViewer,
);
if ARCH_IS_WINDOWS() then
# html version on Windows
HELP_VIEWER_INFO.browser := rec(
type := "url",
show := function( filename )
local pos, winfilename;
if not StartsWith(filename, "/cygdrive") and
not StartsWith(filename, "/proc/cygdrive") then
Error( "the name of the help file ", filename , " must start with /cygdrive or /proc/cygdrive" );
else
# Ignoring part of the URL after '#' since we are unable
# to navigate to the precise location on Windows
winfilename:=MakeExternalFilename( SplitString( filename, "#" )[1] );
fi;
Print( "Opening help page ", winfilename, " in default windows browser ... \c" );
Exec( Concatenation("start ", winfilename ) );
Print( "done! \n" );
end
);
elif ARCH_IS_MAC_OS_X() then
# html version using macOS default browser
HELP_VIEWER_INFO.("mac default browser") := rec (
type := "url",
show := function (url)
Exec ( Concatenation( "osascript <<ENDSCRIPT\n",
"open location \"file://", url, "\"\n",
"ENDSCRIPT\n" ) );
return;
end
);
HELP_VIEWER_INFO.browser := HELP_VIEWER_INFO.("mac default browser");
# html version using macOS browser Safari
HELP_VIEWER_INFO.safari := rec (
type := "url",
show := function (url)
Exec ( Concatenation( "osascript <<ENDSCRIPT\n",
"tell application \"Safari\"\n",
"activate\n",
"open location \"file://", url, "\"\n",
"end tell\n",
"ENDSCRIPT\n" ) );
return;
end);
# html version using macOS browser Firefox
HELP_VIEWER_INFO.firefox := rec (
type := "url",
show := function (url)
Exec ( Concatenation( "osascript <<ENDSCRIPT\n",
"tell application \"Firefox\"\n",
"activate\n",
"open location \"file://", url, "\"\n",
"end tell\n",
"ENDSCRIPT\n" ) );
return;
end);
HELP_VIEWER_INFO.preview := rec(
type := "pdf",
show := function(file)
local page;
# unfortunately one cannot (yet?) give a start page to Preview.app
# it is currently ignored
page := 1;
if IsRecord(file) then
if IsBound(file.page) then
page := file.page;
fi;
file := file.file;
fi;
Exec(Concatenation("open -a Preview ", file));
Print("# see page ", page, " in the Preview window.\n");
end
);
HELP_VIEWER_INFO.("adobe reader") := rec(
type := "pdf",
show := function(file)
local page;
# unfortunately one cannot (yet?) give a start page to acroread
# it is currently ignored
page := 1;
if IsRecord(file) then
if IsBound(file.page) then
page := file.page;
fi;
file := file.file;
fi;
Exec(Concatenation("open -a \"Adobe Reader\" ", file));
Print("# see page ", page, " in the Adobe Reader window.\n");
end
);
HELP_VIEWER_INFO.("pdf viewer") := rec(
type := "pdf",
show := function(file)
local page;
# unfortunately one cannot (yet?) give a start page to acroread
# it is currently ignored
page := 1;
if IsRecord(file) then
if IsBound(file.page) then
page := file.page;
fi;
file := file.file;
fi;
Exec(Concatenation("open ", file));
Print("# see page ", page, " in the pdf viewer window.\n");
end
);
HELP_VIEWER_INFO.("skim") := rec(
type := "pdf",
show := function(file)
local page;
page := 1;
if IsRecord(file) then
if IsBound(file.page) then
page := file.page;
fi;
file := file.file;
fi;
Exec( Concatenation(
"osascript <<ENDSCRIPT\n",
"tell application \"Skim\"\n",
"activate\n",
"open \"", file, "\"\n",
"set theDoc to document of front window\n",
"go theDoc to page ",String(page)," of theDoc\n",
"end tell\n",
"ENDSCRIPT\n" ) );
return;
end
);
else # UNIX but not macOS
# Graphical systems handled differently in WSL and standard Linux
if ARCH_IS_WSL() then
HELP_VIEWER_INFO.browser := rec(
type := "url",
show := function( url )
# Ignoring part of the URL after '#' since we are unable
# to navigate to the precise location on Windows
url := SplitString( url, "#" )[1];
Exec(Concatenation("explorer.exe \"$(wslpath -a -w \"",url, "\")\""));
end
);
HELP_VIEWER_INFO.("pdf viewer") := rec(
type := "pdf",
show := function(file)
local page;
# unfortunately one cannot (yet?) give a start page to windows
page := 1;
if IsRecord(file) then
if IsBound(file.page) then
page := file.page;
fi;
file := file.file;
fi;
Exec(Concatenation("explorer.exe \"$(wslpath -a -w \"",file, "\")\""));
Print("# see page ", page, " in PDF.\n");
end
);
else
# html version with netscape
HELP_VIEWER_INFO.netscape := rec(
type := "url",
show := function(url)
Exec(Concatenation("netscape -remote \"openURL(file:", url, ")\""));
end
);
# html version with mozilla
HELP_VIEWER_INFO.mozilla := rec(
type := "url",
show := function(url)
Exec(Concatenation("mozilla -remote \"openURL(file:", url, ")\""));
end
);
# html version with firefox
HELP_VIEWER_INFO.firefox := rec(
type := "url",
show := function(url)
Exec(Concatenation("firefox \"file://", url,"\" >/dev/null 2>&1 &"));
end
);
# html version with chrome
HELP_VIEWER_INFO.chrome := rec(
type := "url",
show := function(url)
Exec(Concatenation("chromium-browser \"file://", url,"\" >/dev/null 2>&1 &"));
end
);
# html version with konqueror - doesn't work with 'file://...#...' URLs
HELP_VIEWER_INFO.konqueror := rec(
type := "url",
show := function(url)
Exec(Concatenation("konqueror \"file://", url,"\" >/dev/null 2>&1 &"));
end
);
fi;
# html version with lynx
HELP_VIEWER_INFO.lynx := rec(
type := "url",
show := function(url)
Exec(Concatenation("lynx \"", url, "\""));
end
);
# html version with w3m
HELP_VIEWER_INFO.w3m := rec(
type := "url",
show := function(url)
Exec(Concatenation("w3m \"", url, "\""));
end
);
HELP_VIEWER_INFO.elinks := rec(
type := "url",
show := function(url)
Exec(Concatenation("elinks \"", url, "\""));
end
);
HELP_VIEWER_INFO.links2ng := rec(
type := "url",
show := function(url)
Exec(Concatenation("links2 \"", url, "\""));
end
);
HELP_VIEWER_INFO.links2 := rec(
type := "url",
show := function(url)
Exec(Concatenation("links2 -g \"", url, "\""));
end
);
fi;
# Function to find the X-windows window ID of a program accessing file
# <bookf>. Used for a hack below: xdvi doesn't provide a -remote control.
# Having compiled GAPHOME/etc/xrmtcmd.c one can reuse running xdvi's for
# each help file. This was provided by Alexander Hulpke.
#
# This may not work if several people on the same machine want to use it.
#
# Set "XLSCLIENTSCMD := fail;" to turn this off.
FWITF:=fail;
XLSCLIENTSCMD:=false;
InstallGlobalFunction(FindWindowId, function(prog,bookf)
local s,l,a,e,n,c;
if FWITF=fail then
FWITF:=Filename(DirectoryTemporary(),"clients");
fi;
if XLSCLIENTSCMD=false then
XLSCLIENTSCMD:=PathSystemProgram("xlsclients");
fi;
if XLSCLIENTSCMD=fail then
return fail;
fi;
Exec(Concatenation(XLSCLIENTSCMD," -l >",FWITF));
s:=InputTextFile(FWITF);
# find the proper jobs
#T also get the right display/user. Probably this has to be done via the
#T `Machine' parameter.
while not IsEndOfStream(s) do
l:=ReadLine(s);
if l<>fail then
e:=Length(l);
if l[e]='\n' then
e:=e-1;
fi;
a:=1;
while l[a]=' ' do
a:=a+1;
od;
if l{[a..a+6]}="Window " then
n:=l{[a+7..e-1]};
elif l{[a..a+7]}="Command:" then
c:=l{[a+10..e]};
a:=PositionSublist(c,prog);
e:=Length(c);
# does the program name occur and is called on the right file?
if a<>fail and e>Length(bookf)
and c{[e-Length(bookf)+1..e]}=bookf then
# now convert n in an integer
e:=0;
a:="0123456789abcdef";
c:=3; # first two characters are 0x
while c<=Length(n) do
e:=e*16+Position(a,n[c])-1;
c:=c+1;
od;
return e;
fi;
fi;
fi;
od;
CloseStream(s);
return fail;
end);
XRMTCMD:=false;
## dvi version with xdvi
## default options, can be adjusted in gap.ini file or by environment
## variables
## longer example:
#SetUserPreference("XdviOptions", " -geometry 739x577 -paper a4 -s 6 -fg \"#111111\" -bg \"#dddddd\" -margins 1cm -gamma 0.8");
HELP_VIEWER_INFO.xdvi := rec(
type := "dvi",
show := function(file)
local page,wnum;
page := 1;
if IsRecord(file) then
if IsBound(file.page) then
page := file.page;
fi;
file := file.file;
fi;
if XRMTCMD=false then
XRMTCMD:=PathSystemProgram("xrmtcmd");
fi;
if XRMTCMD<>fail then
wnum:=FindWindowId("xdvi",file); # get the window ID of a running XDVI
# for the right book
else
wnum:=fail;
fi;
if wnum=fail or XRMTCMD=fail then
Exec(Concatenation("xdvi ", UserPreference("XdviOptions"), " +",
String(page), " ", file, " &"));
else
#Print("Window: ",wnum,"\n");
# command for xdvi: a (to \relax), pagenumber, goto
file:=Concatenation("a",String(page),"g");
Exec(Concatenation(XRMTCMD," ",String(wnum)," ",file));
fi;
end
);
# pdf version with xpdf (very good with well configured fonts!)
HELP_VIEWER_INFO.xpdf := rec(
type := "pdf",
show := function(file)
local page;
page := 1;
if IsRecord(file) then
if IsBound(file.label) then
page := Concatenation("+", file.label);
elif IsBound(file.page) then
page := String(file.page);
else
page := "";
fi;
file := file.file;
fi;
Exec(Concatenation("xpdf -remote gap4 -raise ",
UserPreference("XpdfOptions"),
" ", file, " ", page, " 2>/dev/null &"));
end
);
# pdf version with acroread: less nice since there is no start page argument
# and no remote control.
# When accessing several sections of the same file in a row this viewer
# assumes that acroread is still running and only tells the page number
# to visit.
ACROREAD_OPTIONS := "";
ACROREAD_FILE := "";
HELP_VIEWER_INFO.acroread := rec(
type := "pdf",
show := function(file)
local page;
# unfortunately one cannot (yet?) give a start page to acroread
# it is currently ignored
page := 1;
if IsRecord(file) then
if IsBound(file.page) then
page := file.page;
fi;
file := file.file;
fi;
if file <> ACROREAD_FILE then
Exec(Concatenation("acroread ", ACROREAD_OPTIONS, " ", file, " &"));
ACROREAD_FILE := file;
fi;
Print("# see page ", page, " in acroread window.\n");
end
);
if IsHPCGAP then
MakeReadOnlyObj(HELP_VIEWER_INFO);
fi;
#############################################################################
##
#F SetHelpViewer(<viewer>): Set the viewer used for help
##
# Can give one or more strings for the preferred help viewer;
# the HELP tries to get the data for the viewer in the order given here.
# No argument shows current setting.
InstallGlobalFunction(SetHelpViewer, function(arg)
local view, i, a;
if Length(arg) = 0 then
return UserPreference("HelpViewers");
fi;
view := List(arg, LowercaseString);
for i in [1..Length(view)] do
a := view[i];
# special handling of help viewer `less'
if a = "less" then
Info(InfoWarning, 2,
"Help viewer \"less\": interpreted as ",
"viewer \"screen\" and setting:\n#I ",
"SetUserPreference(\"Pager\",\"less\");\n#I ",
"SetUserPreference(\"PagerOptions\", ",
"[\"-f\",\"-r\",\"-a\",\"-i\",\"-M\",\"-j2\"]);");
SetUserPreference("Pager", "less");
SetUserPreference("PagerOptions", ["-f","-r","-a","-i","-M","-j2"]);
view[i] := "screen";
elif a = "more" then
Info(InfoWarning, 2,
"Help viewer \"more\": interpreted as ",
"viewer \"screen\" and setting:\n#I ",
"SetUserPreferences(\"Pager\", \"more\");\n#I ",
"SetUserPreference(\"PagerOptions\", []);");
SetUserPreference("Pager", "more");
SetUserPreference("PagerOptions", []);
view[i] := "screen";
elif not IsBound(HELP_VIEWER_INFO.(a)) then
Info(InfoWarning, 1, Concatenation(
"GAP's help system has NO support for help viewer ",a,"!\n"));
view[i] := fail;
fi;
od;
if not "screen" in view then
Add(view, "screen");
fi;
SetUserPreference("HelpViewers", Filtered(view, a-> a<>fail));
if Length( UserPreference("HelpViewers") ) > 1 then
Info( InfoWarning, 2, "Trying to use\n#I ",
UserPreference("HelpViewers"),
"\n#I (in this order) as help viewer.");
else
Info(InfoWarning, 2, Concatenation(
"Using ", UserPreference("HelpViewers")[1],
" as help viewer."));
fi;
end);
[ Dauer der Verarbeitung: 0.33 Sekunden
(vorverarbeitet)
]
|