summaryrefslogtreecommitdiff
path: root/systems/texlive/tlnet/tlpkg/installer/install-menu-text.pl
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /systems/texlive/tlnet/tlpkg/installer/install-menu-text.pl
Initial commit
Diffstat (limited to 'systems/texlive/tlnet/tlpkg/installer/install-menu-text.pl')
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/install-menu-text.pl1153
1 files changed, 1153 insertions, 0 deletions
diff --git a/systems/texlive/tlnet/tlpkg/installer/install-menu-text.pl b/systems/texlive/tlnet/tlpkg/installer/install-menu-text.pl
new file mode 100644
index 0000000000..3adbb519b9
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/install-menu-text.pl
@@ -0,0 +1,1153 @@
+#!/usr/bin/env perl
+# $Id: install-menu-text.pl 50297 2019-03-08 23:16:36Z karl $
+# install-menu-txt.pl
+#
+# Copyright 2007-2017 Norbert Preining, Karl Berry
+# Copyright 2007-2008 Reinhard Kotucha
+# This file is licensed under the GNU General Public License version 2
+# or any later version.
+#
+# This file implements the text based menu system for the TeX Live installer.
+
+use vars qw(@::end_install_hook $::opt_no_cls);
+
+our %vars;
+our $opt_in_place;
+our $tlpdb;
+our @media_available;
+our $media;
+our $previoustlpdb;
+our @collections_std;
+our $texlive_release;
+
+my $MENU_CONTINUE = -1;
+our $MENU_INSTALL = 0;
+our $MENU_ABORT = 1;
+our $MENU_QUIT = 2;
+
+
+my $RETURN = $MENU_CONTINUE;
+
+my $portable_toggled = 0;
+my $ptoggle_alert = "\n".
+ " !! Portable option changed;\n" .
+ " !! Directories have been reinitialized!\n";
+
+# @fileassocdesc also defined in install-tl
+$::fileassocdesc[0] = "None";
+$::fileassocdesc[1] = "Only new";
+$::fileassocdesc[2] = "All";
+
+$::deskintdesc[0] = "None";
+$::deskintdesc[1] = "Menu shortcuts";
+if (win32() && is_seven()) { $::deskintdesc[2] = "Launcher"; }
+
+sub clear_screen {
+ return 0 if ($::opt_no_cls);
+ system (unix() ? 'clear' : 'cls');
+}
+
+sub string_to_list {
+ my $string=shift;
+ return split(//, $string);
+}
+
+# ___, defined in install-tl, replaces the GUI translating function
+*::__ = \&::___;
+
+sub button { # for main menu: 1 char
+ my $val=shift;
+ my $vals=shift; # array ref to descriptions of possible values
+ if (defined $vals) {
+ return "[$val]";
+ } else { # just yes/no
+ return ($val)? '[X]':'[ ]';
+ }
+}
+
+sub obutton { # for options menu: more chars allowed
+ my $val=shift;
+ my $vals=shift; # array ref to descriptions of possible values
+ $vals = [' ', 'X'] unless defined $vals;
+ return "[$$vals[$val]]";
+}
+
+sub hbar {
+ return '=' x79, "\n";
+}
+
+sub toggle {
+ my $var=shift;
+ my $vals=shift; # array ref to descriptions of possible values
+ $vals = [' ', 'X'] unless defined $vals;
+ my $n_vals = @$vals;
+ $vars{$var} += 1;
+ $vars{$var} = 0 unless $vars{$var} < $n_vals;
+}
+
+sub menu_head {
+ my $text = shift;
+ clear_screen;
+ print hbar(), "$text\n\n";
+}
+
+sub other_options {
+ my @options=@_;
+ my %opts=(
+ '-' => 'deselect all',
+ '+' => 'select all',
+ 'H' => 'help',
+ 'R' => 'return to main menu',
+ 'P' => 'save installation profile to \'texlive.profile\' and exit',
+ 'Q' => 'quit'
+ );
+
+ $opts{'I'}=$vars{'instopt_portable'} ? 'start portable installation' :
+ 'start installation to hard disk';
+
+ print "\nActions:";
+ if ($options[$#options] eq 'diskspace') {
+ pop @options;
+ calc_depends ();
+ print " (disk space required: $vars{'total_size'} MB)";
+ }
+ print "\n";
+
+ for my $option (@options) {
+ if (defined $opts{"$option"}) {
+ printf " <%s> %s\n", $option, $opts{$option};
+ } else {
+ die "other_options: $opts{$option} undefined.\n";
+ }
+ }
+}
+
+sub prompt {
+ my $prompt = shift;
+ print "\n$prompt: ";
+ my $answer = <STDIN>;
+ $answer = "q" if !defined($answer);
+ chomp($answer);
+ return "$answer";
+}
+
+# The menu loop. A menu is a function. Its return value is a
+# reference to another menu or to itself.
+sub run_menu_text {
+ my (@args) = @_;
+ my $default = 0;
+ # select mirror if -select-mirror is given
+ if ($::opt_select_repository) {
+ # network is always available
+ my @mirror_list = TeXLive::TLUtils::create_mirror_list();
+ print "Please select a repository:\n";
+ print "Network repositories:" if ($#media_available >= 0);
+ my @sel_to_index;
+ my $selind = 0;
+ # this is for 0 mirror.ctan.org, but it is printed last!
+ push @sel_to_index, 0;
+ $selind++;
+ for my $i (0..$#mirror_list) {
+ if ($mirror_list[$i] !~ m/^ /) {
+ print "\n$mirror_list[$i]\n";
+ } else {
+ print " " if 1 <= $selind && $selind <= 9; # align
+ print "[$selind] $mirror_list[$i]\n";
+ push @sel_to_index, $i;
+ $selind++;
+ }
+ }
+ print "----\n";
+ print "[0] default mirror http://mirror.ctan.org\n";
+ my $local_ind = "a";
+ if ($#media_available >= 0) {
+ print "Local repositories:\n";
+ # we have some local media present, propose to use it
+ for my $l (@media_available) {
+ my ($a, $b) = split ('#', $l);
+ if ($a eq 'local_compressed') {
+ print "[$local_ind] compressed archive at $b\n";
+ $default = $local_ind;
+ #$local_ind = chr(ord($local_ind)+1);
+ $local_ind++;
+ } elsif ($a eq 'local_uncompressed') {
+ print "[$local_ind] uncompressed archive at $b\n";
+ $default = $local_ind;
+ $local_ind++;
+ } elsif ($a eq 'NET') {
+ print "[$local_ind] cmd line repository: $b\n";
+ $default = $local_ind;
+ $local_ind++;
+ } else {
+ warn "$0: Unknown media $l";
+ }
+ }
+ }
+ print "[q] quit\n";
+ $selind--;
+ my $selstr = "Your selection ";
+ if ($local_ind ne "a") {
+ # we got at least some local repository
+ if ($local_ind eq "b") {
+ $selstr .= "(a,0-$selind,q)";
+ $local_ind = chr(ord($local_ind)-1);
+ } else {
+ # that does not work!!!
+ #$local_ind--;
+ $local_ind = chr(ord($local_ind)-1);
+ $selstr .= "(a-$local_ind,0-$selind,q)";
+ }
+ }
+ $selstr .= " [$default]: ";
+ my $got_answer = 0;
+ my $ans = undef;
+ while (!defined($ans)) {
+ print $selstr;
+ $ans = readline(*STDIN);
+ if (!defined($ans)) {
+ print "Please select `q' to quit the program!\n";
+ } else {
+ chomp($ans);
+ $ans = $default if ($ans eq "");
+ if ($ans =~ m/^[0-9]+$/) {
+ if (0 <= $ans && $ans <= $selind) {
+ my $mfull;
+ if ($ans == 0) {
+ $::init_remote_needed = 'ctan';
+ } else {
+ # only if something else but the predefined mirror is selected
+ # we something here
+ $mfull = TeXLive::TLUtils::extract_mirror_entry($mirror_list[$sel_to_index[$ans]]);
+ print "selected mirror: ", $mfull, "\n";
+ $::init_remote_needed = $mfull;
+ }
+ }
+ } elsif ($ans =~ m/^[a-$local_ind]$/) {
+ my $i = ord($ans) - ord('a');
+ my $t = $media_available[$i];
+ $t =~ s/^[^#]*#//;
+ $::init_remote_needed = $t;
+ } elsif ($ans eq 'q' || $ans eq 'Q') {
+ print "Goodbye.\n";
+ exit 0;
+ } else {
+ print "Not a valid answer: $ans.\n";
+ $ans = undef;
+ }
+ }
+ }
+ }
+
+ # run remote init
+ if (!do_remote_init($::init_remote_needed)) {
+ warn "\n";
+ warn "Please select a different mirror! See info above.\n";
+ print STDERR "Press Enter to exit... ";
+ $ans = readline (*STDIN);
+ exit (1);
+ }
+
+ # the text mode installer does not take look at any argument
+ # except -old-installation-found.
+ while (@args) {
+ my $f = shift @args;
+ if ($f =~ m/^-old-installation-found=(.*)$/) {
+ my $dn = $1;
+ print "\nAn old installation of TeX Live has been found in $dn\n";
+ print "
+If you want the selection of schemes/collections and various options being
+taken over press `y', otherwise anything else.
+
+Import settings from previous TeX Live installation: (y/n): ";
+ chomp(my $yn = <STDIN>);
+ if ($yn =~ m/^y$/i) {
+ import_settings_from_old_tlpdb($dn);
+ }
+ }
+ }
+ my $menu=\&main_menu;
+ while ($RETURN == $MENU_CONTINUE) {
+ $menu=$menu->();
+ }
+ return($RETURN);
+}
+$::run_menu = \&run_menu_text;
+
+sub binary_menu {
+ my %command=(
+ 'self' => \&binary_menu,
+ 'R' => \&main_menu,
+ 'Q' => \&quit
+ );
+
+ my @binaries;
+ my @keys=string_to_list "abcdefghijklmopstuvwxyz";
+ my $index=0;
+ my %keyval;
+ my $selected_platform;
+
+ menu_head "Available platforms:";
+
+ foreach my $key (keys %vars) {
+ if ($key =~ /binary_(.*)/) {
+ push @binaries, $1;
+ }
+ }
+
+ @binaries=sort TeXLive::TLUtils::sort_archs @binaries;
+
+ foreach my $binary (@binaries) {
+ printf " %s %s %s (%s)\n", $keys[$index],
+ button($vars{"binary_$binary"}),
+ platform_desc($binary),
+ "$binary";
+ $keyval{"$keys[$index]"} = "binary_$binary";
+ ++$index;
+ }
+ other_options qw(- + R Q diskspace);
+
+ my $answer = prompt 'Enter letter(s) to (de)select platforms';
+
+ my @keystrokes=string_to_list $answer;
+
+ foreach my $keystroke (@keystrokes) {
+ if ($keystroke eq '-') {
+ for my $binary (@binaries) {
+ $vars{"binary_$binary"}=0 if defined $vars{"binary_$binary"};
+ }
+ }
+ if ($keystroke eq '+') {
+ for my $binary (@binaries) {
+ $vars{"binary_$binary"}=1 if defined $vars{"binary_$binary"};
+ }
+ }
+ if (defined $keyval{$keystroke}) {
+ toggle "$keyval{$keystroke}";
+ } elsif (!defined $command{"\u$answer"}) {
+ print "Unknown command: $answer\n\n";
+ }
+ }
+ if ($vars{"binary_win32"}) {
+ $vars{"collection-wintools"} = 1;
+ } else {
+ $vars{"collection-wintools"} = 0;
+ }
+ if (defined $command{"\u$answer"}) {
+ return $command{"\u$answer"}->();
+ } else {
+ return $command{'self'}->();
+ }
+}
+
+
+sub scheme_menu {
+ my %command=(
+ 'self' => \&scheme_menu,
+ 'R' => \&main_menu,
+ 'Q' => \&quit
+ );
+
+ my @schemes;
+ my @keys=string_to_list "abcdefghijklmnopstuvwxyz";
+ my %keyval;
+ my $index=0;
+
+ menu_head 'Select scheme:';
+
+ @schemes = schemes_ordered_for_presentation();
+ foreach my $pkg (@schemes) {
+ $vars{"$pkg"}=($vars{'selected_scheme'} eq $pkg)? 1:0;
+ }
+ push @schemes, "scheme-custom";
+
+ foreach my $scheme (@schemes) {
+ $keyval{$keys[$index]}="$scheme";
+ if ($scheme ne "scheme-custom") {
+ my $tlpobj = $tlpdb->get_package("$scheme");
+ printf " %s %s %s\n", $keys[$index], button($vars{"$scheme"}),
+ $tlpobj->shortdesc;
+ } else {
+ printf " %s %s custom selection of collections\n",
+ $keys[$index], button($vars{'selected_scheme'} eq "scheme-custom");
+ }
+ ++$index;
+ }
+
+ select_scheme($vars{'selected_scheme'});
+
+ if ($vars{"binary_win32"}) {
+ $vars{"collection-wintools"} = 1;
+ } else {
+ $vars{"collection-wintools"} = 0;
+ }
+
+ other_options qw(R Q diskspace);
+ my $answer = prompt 'Enter letter to select scheme';
+
+ if (defined $keyval{"$answer"}) {
+ $vars{'selected_scheme'}=$keyval{"$answer"};
+ select_scheme($vars{'selected_scheme'});
+ return $command{'self'}->();
+ }
+ if (defined $command{"\u$answer"}) {
+ return $command{"\u$answer"}->();
+ } else {
+ print "Unknown command: $answer\n\n";
+ return $command{'self'}->();
+ }
+}
+
+
+sub collection_menu {
+ my %command=(
+ 'self' => \&collection_menu,
+ 'R' => \&main_menu,
+ 'Q' => \&quit
+ );
+
+ my @collections;
+ my @keys=string_to_list "abcdefghijklmnopstuvwxyzABCDEFGHIJKLMNOPSTUVWXYZ";
+ my %keyval;
+ my $index=0;
+ my @coll_short_desc;
+ my @coll_long_desc;
+
+ menu_head 'Select collections:';
+
+ @collections=sort @collections_std;
+
+ foreach my $collection (@collections) {
+ next if ($collection eq 'collection-perl');
+ my $tlpobj = $tlpdb->get_package("$collection");
+ if (length $tlpobj->shortdesc>30) {
+ push @coll_long_desc, $collection;
+ } else {
+ push @coll_short_desc, $collection;
+ }
+ }
+ my $singlecolumn_index=@coll_short_desc-1;
+
+##<cols=2>
+ my $lines=@coll_short_desc/2;
+ ++$lines if (@coll_short_desc%2);
+ for (0..$lines-1) {
+ $index=$_;
+ my $collection=$coll_short_desc[$index];
+ my $tlpobj = $tlpdb->get_package("$collection");
+ $keyval{$keys[$index]}="$collection";
+ printf " %s %s %-33s", $keys[$index], button($vars{"$collection"}),
+ substr($tlpobj->shortdesc,0,33);
+ if (defined $coll_short_desc[$index+$lines]) {
+ my $collection=$coll_short_desc[$index+$lines];
+ my $tlpobj=$tlpdb->get_package("$collection");
+ $keyval{$keys[$index+$lines]}="$collection";
+ printf " %s %s %-32s\n", $keys[$index+$lines],
+ button($vars{"$collection"}), substr($tlpobj->shortdesc,0,32);
+ } else {
+ print "\n";
+ }
+ }
+##</cols=2>
+ $index=$singlecolumn_index;
+# print "\n$index\n\n";
+ foreach my $collection (@coll_long_desc) {
+ my $tlpobj=$tlpdb->get_package("$collection");
+ $keyval{$keys[$index+1]}="$collection";
+ printf " %s %s %s\n", $keys[$index+1], button($vars{"$collection"}),
+ $tlpobj->shortdesc;
+ ++$index;
+ }
+##</cols=1>
+
+ other_options qw(- + R Q diskspace);
+ my $answer = prompt 'Enter letter(s) to (de)select collection(s)';
+
+ my @keystrokes=string_to_list $answer;
+
+ foreach my $keystroke (@keystrokes) {
+ if ($keystroke eq '-') {
+ for my $collection (@collections) {
+ $vars{"$collection"}=0 if defined $vars{"$collection"};
+ }
+ }
+ if ($keystroke eq '+') {
+ for my $collection (@collections) {
+ $vars{"$collection"}=1 if defined $vars{"$collection"};
+ }
+ }
+ if (defined $keyval{$keystroke}) {
+ toggle "$keyval{$keystroke}";
+ } elsif (!defined $command{"\u$answer"}) {
+ print "Unknown command: $answer\n\n";
+ }
+ }
+
+ if (defined $command{"\u$answer"}) {
+ # if we play around with collections we also select custom-scheme
+ # but we do not switch back to originally afterwards, too complicated
+ # to be done
+ select_scheme("scheme-custom");
+ return $command{"\u$answer"}->();
+ } else {
+ return $command{'self'}->();
+ }
+}
+
+
+sub directories_menu
+{
+ my %command=(
+ 'self' => \&directories_menu,
+ 'R' => \&main_menu,
+ 'Q' => \&quit
+ );
+
+ menu_head "Directories customization:";
+ if (!TeXLive::TLUtils::texdir_check($vars{'TEXDIR'})) {
+ print "!! The default location as given below is forbidden or
+!! can't be written to.
+!! Either change the destination directory using <1> or create it
+!! outside this script.
+";
+ }
+ my $texmfdir = $vars{'TEXDIR'} .
+ ($vars{'TEXDIR'} =~ /\/$/ ? 'texmf-dist' : '/texmf-dist');
+ if (!$opt_in_place) {
+ print <<"EOF";
+ <1> TEXDIR: $vars{'TEXDIR'}
+ main tree: $texmfdir
+EOF
+ } else {
+ print <<"EOF";
+ TEXDIR: $vars{'TEXDIR'}
+ main tree: $texmfdir
+EOF
+ }
+ if (!$vars{'instopt_portable'}) {
+ print <<"EOF";
+
+ <2> TEXMFLOCAL: $vars{'TEXMFLOCAL'}
+ <3> TEXMFSYSVAR: $vars{'TEXMFSYSVAR'}
+ <4> TEXMFSYSCONFIG: $vars{'TEXMFSYSCONFIG'}
+
+ <5> TEXMFVAR: $vars{'TEXMFVAR'}
+ <6> TEXMFCONFIG: $vars{'TEXMFCONFIG'}
+ <7> TEXMFHOME: $vars{'TEXMFHOME'}
+
+EOF
+
+ if (win32) {
+ print " Note: ~ will expand to %USERPROFILE%\n";
+ } else {
+ print " Note: ~ will expand to \$HOME (or to %USERPROFILE% on Windows)\n";
+ }
+ }
+
+ other_options qw(R Q);
+ my $answer = prompt 'Enter command';
+
+ if ("\u$answer" eq '1' and !$opt_in_place) {
+ print "New value for TEXDIR [$vars{'TEXDIR'}]: ";
+ $answer = &input_dirname ();
+ $vars{'TEXDIR'} = $answer if $answer ne "";
+ my $texdirnoslash;
+ if ($vars{'TEXDIR'}=~/^(.*)\/$texlive_release$/) {
+ $texdirnoslash = $1;
+ $vars{'TEXMFLOCAL'}="$texdirnoslash/texmf-local";
+ $vars{'TEXMFSYSVAR'}="$texdirnoslash/$texlive_release/texmf-var";
+ $vars{'TEXMFSYSCONFIG'}="$texdirnoslash/$texlive_release/texmf-config";
+ } elsif ($vars{'TEXDIR'}=~/^(.*)$/) {
+ $texdirnoslash = $1;
+ $texdirnoslash =~ s!/$!!;
+ $vars{'TEXMFLOCAL'}="$texdirnoslash/texmf-local";
+ $vars{'TEXMFSYSVAR'}="$texdirnoslash/texmf-var";
+ $vars{'TEXMFSYSCONFIG'}="$texdirnoslash/texmf-config";
+ }
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq '2' and !$vars{'instopt_portable'}) {
+ print "New value for TEXMFLOCAL [$vars{'TEXMFLOCAL'}]: ";
+ $answer = &input_dirname ();
+ $vars{'TEXMFLOCAL'} = $answer if $answer ne "";
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq '3' and !$vars{'instopt_portable'}) {
+ print "New value for TEXMFSYSVAR [$vars{'TEXMFSYSVAR'}]: ";
+ $answer = &input_dirname ();
+ $vars{'TEXMFSYSVAR'} = $answer if $answer ne "";
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq '4' and !$vars{'instopt_portable'}) {
+ print "New value for TEXMFSYSCONFIG [$vars{'TEXMFSYSCONFIG'}]: ";
+ $answer = &input_dirname ();
+ $vars{'TEXMFSYSCONFIG'} = $answer if $answer ne "";
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq '5' and !$vars{'instopt_portable'}) {
+ print "New value for TEXMFVAR [$vars{'TEXMFVAR'}]: ";
+ $answer = &input_dirname ("noexpansion");
+ $vars{'TEXMFVAR'} = $answer if $answer ne "";
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq '6' and !$vars{'instopt_portable'}) {
+ print "New value for TEXMFCONFIG [$vars{'TEXMFCONFIG'}]: ";
+ $answer = &input_dirname ("noexpansion");
+ $vars{'TEXMFCONFIG'} = $answer if $answer ne "";
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq '7' and !$vars{'instopt_portable'}) {
+ print "New value for TEXMFHOME [$vars{'TEXMFHOME'}]: ";
+ $answer = &input_dirname ("noexpansion");
+ $vars{'TEXMFHOME'} = $answer if $answer ne "";
+ return $command{'self'};
+ }
+
+ if (defined $command{"\u$answer"}) {
+ return $command{"\u$answer"}->();
+ } else {
+ print "Unknown command: $answer\n\n";
+ return $command{'self'}->();
+ }
+}
+
+
+# Helper function to read a directory name and clean it up.
+# Unless NO_EXPANSION is true, convert to absolute path.
+#
+sub input_dirname
+{
+ my $noexpansion = shift;
+ chomp (my $answer = <STDIN>);
+ return "" if $answer eq "";
+
+ $answer =~ s!\\!/!g if win32(); # switch to forward slashes
+
+ if (!$noexpansion) {
+ my $home = getenv('HOME');
+ $home = getenv('USERPROFILE') if win32();
+ $home ||= '~';
+ $answer =~ s/^~/$home/; # $home expansion
+ }
+
+ if ($answer !~ m/^~/) {
+ # relative paths are unlikely to work in texmf.cnf, et al.,
+ # and don't have any apparent practical use. Convert to absolute.
+ if (! File::Spec->file_name_is_absolute($answer)) {
+ $answer = TeXLive::TLUtils::tl_abs_path($answer);
+ $answer = "" unless defined $answer;
+ }
+ }
+ return $answer;
+}
+
+
+$vars{'page'}=0;
+
+sub html2text {
+ my $filename=shift;
+ my @text;
+ open IN, "$filename";
+ @all_lines=<IN>;
+ close IN;
+ chomp @all_lines;
+
+ my $itemcnt;
+ my $ordered_list=0;
+ my $h1_indent=25;
+ my $h2_indent=3;
+ my $h3_indent=6;
+
+ for (@all_lines) {
+ next if /DOCTYPE/;
+ next if /<!--/;
+ next if /<title/i;
+ next if /<\/?body/i;
+ next if /<\/?html/i;
+ next if /<\/?head/i;
+ next if /<\/?meta/i;
+ next if /^\s*$/; # ignore empty lines
+
+ s/<i>/"/gi; s/<\/i>/"/gi; # italics
+ s/<tt>/'/gi; s/<\/tt>/'/gi; # typewriter
+ s/<p>.*//gi; # paragraphs
+ s/<\/ul>.*//gi; # unsorted lists
+ s/<\/ol>.*//gi; # ordered lists
+ s/&mdash;/--/gi; # mdash
+ s/&lt;/</gi; s/&gt;/>/gi; # < and >
+ if (/<h1>(.*?)<\/h1>/i) {
+ push @text, " " x $h1_indent. "$1\n";
+ push @text, " " x $h1_indent. "=" x (length $1). "\n";
+ push @text, "\n";
+ } elsif (/<h2>(.*?)<\/h2>/i) {
+ push @text, "\n";
+ push @text, " " x $h2_indent. "$1\n";
+ push @text, " " x $h2_indent. "~" x (length $1). "\n";
+ push @text, "\n";
+ } elsif (/<h3>(.*?)<\/h3>/i) {
+ push @text, "\n";
+ push @text, " " x $h3_indent. "$1\n";
+ push @text, " " x $h3_indent. "-" x (length $1). "\n";
+ push @text, "\n";
+ } elsif (/<ol>/i) {
+ $ordered_list=1;
+ $itemcnt=1;
+ } elsif (/<ul>/i) {
+ $ordered_list=0;
+ } elsif (/^\s*<li>\s*(.*)/) {
+ if ($ordered_list) {
+ push @text, "\n";
+ push @text, " $itemcnt. $1\n";
+ ++$itemcnt;
+ } else {
+ push @text, "\n";
+ push @text, " * $1\n";
+ }
+ } else {
+ push @text, "$_\n";
+ }
+ }
+ return @text;
+}
+
+
+sub help_menu {
+ my %command=(
+ 'self' => \&help_menu,
+ 'R' => \&main_menu,
+ 'Q' => \&quit
+ );
+ my $installer_help="$installerdir/tlpkg/installer/install-tl.html";
+
+ clear_screen;
+
+ my @text=html2text "$installer_help";
+ my $lines=(@text);
+ my $overlap=3;
+ my $lps=32; # lines per screen - overlap
+ my $firstline=$vars{'page'}*$lps;
+ my $lastline=$firstline+$lps+$overlap;
+ my $line=0;
+# print "<<<$firstline>>> <<<$lastline>>>\n";
+ for (@text) {
+ print "$_" if ($line>=$firstline and $line<=$lastline);
+ ++$line;
+ }
+ print "\n", hbar,
+ " <T> top <N> next page <P> previous page <R> return"
+ . " <Q> quit --", $vars{'page'}+1, "--\n";
+
+ my $answer = prompt 'Enter command';
+
+ if ("\u$answer" eq 'T') {
+ $vars{'page'}=0;
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq 'N') {
+ $vars{'page'}+=1 unless $lastline>$lines;
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq 'P') {
+ $vars{'page'}-=1 if $vars{'page'}>=1;
+ return $command{'self'};
+
+ } elsif (defined $command{"\u$answer"}) {
+ return $command{"\u$answer"};
+
+ } else {
+ print "Unknown command: $answer\n\n";
+ return $command{'self'};
+ }
+}
+
+
+sub options_menu {
+ my $b_path=obutton($vars{'instopt_adjustpath'});
+ my $b_doc=obutton($vars{'tlpdbopt_install_docfiles'});
+ my $b_src=obutton($vars{'tlpdbopt_install_srcfiles'});
+ my $b_fmt=obutton($vars{'tlpdbopt_create_formats'});
+ my $b_letter=obutton($vars{'instopt_letter'});
+ my $b_adjustrepo=obutton($vars{'instopt_adjustrepo'});
+ my $b_deskint=obutton(
+ $vars{'tlpdbopt_desktop_integration'}, \@::deskintdesc);
+ my $b_admin=obutton($vars{'tlpdbopt_w32_multi_user'});
+ my $b_addoneditor=obutton($vars{'collection-texworks'});
+ my $b_restricted=obutton($vars{'instopt_write18_restricted'});
+
+ my $sys_bin=$vars{'tlpdbopt_sys_bin'};
+ my $sys_man=$vars{'tlpdbopt_sys_man'};
+ my $sys_info=$vars{'tlpdbopt_sys_info'};
+
+ my $t_sys_bin=($vars{'instopt_adjustpath'})? $vars{'tlpdbopt_sys_bin'}:'';
+ my $t_sys_man=($vars{'instopt_adjustpath'})? $vars{'tlpdbopt_sys_man'}:'';
+ my $t_sys_info=($vars{'instopt_adjustpath'})? $vars{'tlpdbopt_sys_info'}:'';
+
+ my %command=(
+ 'self' => \&options_menu,
+ 'R' => \&main_menu,
+ 'Q' => \&quit
+ );
+
+ clear_screen;
+ menu_head "Options customization:";
+
+ print <<"EOF";
+ <P> use letter size instead of A4 by default: $b_letter
+ <E> execution of restricted list of programs: $b_restricted
+ <F> create all format files: $b_fmt
+EOF
+;
+ if ($vars{'doc_splitting_supported'} and !$opt_in_place) {
+ print " <D> install font/macro doc tree: $b_doc\n";
+ }
+ if ($vars{'src_splitting_supported'} and !$opt_in_place) {
+ print " <S> install font/macro source tree: $b_src\n";
+ }
+ if (!$vars{'instopt_portable'}) {
+ if (unix() || $::opt_all_options) {
+ print <<"EOF";
+ <L> create symlinks in standard directories: $b_path
+ binaries to: $t_sys_bin
+ manpages to: $t_sys_man
+ info to: $t_sys_info
+EOF
+;
+ } else {
+ print <<"EOF";
+ <L> adjust registry entry for path: $b_path
+EOF
+;
+ }
+ if ((win32() && !$vars{'instopt_portable'}) || $::opt_all_options) {
+ print " <M> Start menu shortcuts / launcher: ".obutton(
+ $vars{'tlpdbopt_desktop_integration'}, \@::deskintdesc)."\n";
+ print " <N> update file associations: ".obutton(
+ $vars{'tlpdbopt_file_assocs'}, \@::fileassocdesc)."\n";
+ if ($::opt_all_options || TeXLive::TLWinGoo::admin()) {
+ # if we are admin we allow normal user installation, too
+ print " <U> make installation available to all users: $b_admin\n";
+ }
+ }
+ }
+ if (win32() || $::opt_all_options) {
+ print " <W> install TeXworks front end: $b_addoneditor\n";
+ }
+ if ($media ne "NET") {
+ print " <Y> after install, set CTAN as source for package updates: $b_adjustrepo\n";
+ }
+ other_options qw(R Q diskspace);
+ my $answer = prompt 'Enter command';
+
+ # instopt_adjustpath
+
+ if (unix()) {
+ if (("\u$answer" eq 'L') and !$vars{'instopt_portable'}) {
+ my $home = getenv('HOME');
+ $home = getenv('USERPROFILE') if (win32());
+ $home ||= '~';
+ toggle 'instopt_adjustpath';
+ if ($vars{'instopt_adjustpath'}) {
+ print "New value for binary directory [$sys_bin]: ";
+ chomp($answer=<STDIN>);
+ $vars{'tlpdbopt_sys_bin'} = "$answer" if (length $answer);
+ $vars{'tlpdbopt_sys_bin'} =~ s@\\@/@g if (win32());
+ $vars{'tlpdbopt_sys_bin'} =~ s/^~/$home/;
+ if ($vars{'tlpdbopt_sys_bin'}=~/^(.*)\/bin$/) {
+ $vars{'tlpdbopt_sys_man'}="$1/man";
+ $vars{'tlpdbopt_sys_info'}="$1/info";
+ }
+ print "New value for man directory [$vars{'tlpdbopt_sys_man'}]: ";
+ chomp($answer=<STDIN>);
+ $vars{'tlpdbopt_sys_man'}="$answer" if (length $answer);
+ $vars{'tlpdbopt_sys_man'} =~ s@\\@/@g if (win32());
+ $vars{'tlpdbopt_sys_man'} =~ s/^~/$home/;
+
+ print "New value for info directory [$vars{'tlpdbopt_sys_info'}]: ";
+ chomp($answer=<STDIN>);
+ $vars{'tlpdbopt_sys_info'}="$answer" if (length $answer);
+ $vars{'tlpdbopt_sys_info'} =~ s@\\@/@g if (win32());
+ $vars{'tlpdbopt_sys_info'} =~ s/^~/$home/;
+ }
+ return $command{'self'};
+ }
+ } else {
+ if (("\u$answer" eq 'L') and !$vars{'instopt_portable'}) {
+ my $home = getenv('HOME');
+ $home = getenv('USERPROFILE') if (win32());
+ $home ||= '~';
+ toggle 'instopt_adjustpath';
+ return $command{'self'};
+ }
+ }
+
+# # tlpdbopt_desktop_integration, tlpdbopt_file_assocs
+#
+# if (win32() || $::opt_all_options) {
+# if ("\u$answer" eq 'M' and !$vars{'instopt_portable'}) {
+# toggle 'tlpdbopt_desktop_integration';
+# return $command{'self'};
+#
+# } elsif ("\u$answer" eq 'N' and !$vars{'instopt_portable'}) {
+# print "New value for file_assocs:\n";
+# print " 0 -- don't tweak the file associations\n";
+# print " 1 -- only add new file associations, don't overwrite old ones\n";
+# print " 2 -- always create file associations to TeX Live programs\n";
+# print "New value for file_assocs [$vars{'tlpdbopt_file_assocs'}]: ";
+# chomp (my $a = <STDIN>);
+# if ($a eq "0" || $a eq "1" || $a eq "2") {
+# $vars{'tlpdbopt_file_assocs'} = $a;
+# }
+# return $command{'self'};
+#
+# } elsif ("\u$answer" eq 'U' and !$vars{'instopt_portable'}) {
+# toggle 'tlpdbopt_w32_multi_user';
+# return $command{'self'};
+# }
+# }
+
+ # other options
+
+ if (("\u$answer" eq 'M') && !$vars{'instopt_portable'}) {
+ toggle ('tlpdbopt_desktop_integration', \@::deskintdesc);
+ return $command{'self'};
+
+ } elsif (("\u$answer" eq 'N') && !$vars{'instopt_portable'}) {
+ toggle ('tlpdbopt_file_assocs', \@::fileassocdesc);
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq 'P') {
+ toggle 'instopt_letter';
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq 'F') {
+ toggle 'tlpdbopt_create_formats';
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq 'E') {
+ toggle 'instopt_write18_restricted';
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq 'S' and !$opt_in_place) {
+ toggle 'tlpdbopt_install_srcfiles';
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq 'D' and !$opt_in_place) {
+ toggle 'tlpdbopt_install_docfiles';
+ return $command{'self'};
+
+ } elsif (defined $command{"\u$answer"}) {
+ return $command{"\u$answer"};
+
+ } elsif (("\u$answer" eq 'W') && ($::opt_all_options || win32()) &&
+ !$opt_in_place ) {
+ toggle 'collection-texworks';
+ return $command{'self'};
+
+ } elsif ("\u$answer" eq 'Y' and $media ne "NET") {
+ toggle 'instopt_adjustrepo';
+ return $command{'self'};
+
+ } else {
+ print "Unknown or unsupported command: $answer\n\n";
+ return $command{'self'};
+ }
+}
+
+
+sub quit {
+ exit 0;
+ $RETURN = $MENU_QUIT;
+}
+
+sub do_install {
+ $RETURN = $MENU_INSTALL;
+}
+
+sub toggle_portable {
+ if ($vars{'instopt_portable'}) {
+ $vars{'instopt_portable'} = 0;
+ $vars{'tlpdbopt_desktop_integration'} = 0;
+ $vars{'instopt_adjustpath'} = 0;
+ $vars{'tlpdbopt_file_assocs'} = 0;
+ $vars{'tlpdbopt_w32_multi_user'} = 0;
+ } else {
+ $vars{'instopt_portable'} = 1;
+ $vars{'tlpdbopt_desktop_integration'} = 1;
+ $vars{'instopt_adjustpath'} = 1;
+ $vars{'tlpdbopt_file_assocs'} = 1;
+ $vars{'tlpdbopt_w32_multi_user'} = 1;
+ }
+ $portable_toggled = 1;
+ set_texlive_default_dirs(); # this sub tests for portable and in_place
+ main_menu;
+}
+
+sub callback_save_profile {
+ create_profile("texlive.profile");
+ print "Installation profile saved to 'texlive.profile', exiting.\n";
+ exit(0);
+}
+
+sub main_menu {
+ my $this_platform=platform_desc($vars{'this_platform'});
+
+ my $b_path=button($vars{'instopt_adjustpath'});
+ my $b_doc=button($vars{'tlpdbopt_install_docfiles'});
+ my $b_src=button($vars{'tlpdbopt_install_srcfiles'});
+ my $b_fmt=button($vars{'tlpdbopt_create_formats'});
+ my $b_letter=button($vars{'instopt_letter'});
+ my $b_deskint=button($vars{'tlpdbopt_desktop_integration'}, \@::deskintdesc);
+ if (win32()) {
+ my $b_fileassoc=button($vars{'tlpdbopt_file_assocs'}, \@::fileassocdesc);
+ }
+ my $b_admin=button($vars{'tlpdbopt_w32_multi_user'});
+ my $b_addoneditor=button($vars{'collection-texworks'});
+ my $b_restricted=button($vars{'instopt_write18_restricted'});
+ my $b_adjustrepo=button($vars{'instopt_adjustrepo'});
+
+ my $warn_nobin;
+
+ $warn_nobin=set_install_platform;
+
+ $vars{'n_systems_selected'}=0;
+ $vars{'n_collections_selected'}=0;
+ foreach my $key (keys %vars) {
+ if ($key=~/^binary.*/) {
+ ++$vars{'n_systems_selected'} if $vars{$key}==1;
+ }
+ if ($key=~/^collection/) {
+ ++$vars{'n_collections_selected'} if $vars{$key}==1;
+ }
+ }
+ calc_depends();
+
+ my %command = (
+ 'self' => \&main_menu,
+ 'D' => \&directories_menu,
+ 'H' => \&help_menu,
+ 'I' => \&do_install,
+ 'O' => \&options_menu,
+ 'Q' => \&quit,
+ 'V' => \&toggle_portable,
+ 'P' => \&callback_save_profile,
+ );
+ if (!$opt_in_place) {
+ $command{'B'} = \&binary_menu if unix();
+ $command{'C'} = \&collection_menu;
+ $command{'S'} = \&scheme_menu;
+ }
+
+ clear_screen;
+ print <<"EOF";
+======================> TeX Live installation procedure <=====================
+
+======> Letters/digits in <angle brackets> indicate <=======
+======> menu items for actions or customizations <=======
+
+ Detected platform: $this_platform
+ $warn_nobin
+EOF
+
+ if (!$opt_in_place) {
+ print <<"EOF";
+ <B> set binary platforms: $vars{'n_systems_selected'} out of $vars{'n_systems_available'}
+
+ <S> set installation scheme: $vars{'selected_scheme'}
+
+ <C> set installation collections:
+ $vars{'n_collections_selected'} collections out of $vars{'n_collections_available'}, disk space required: $vars{'total_size'} MB
+EOF
+
+ }
+ if ($portable_toggled) {
+ print $ptoggle_alert;
+ $portable_toggled = 0;
+ }
+ print <<"EOF";
+
+ <D> set directories:
+ TEXDIR (the main TeX directory):
+EOF
+
+ if (TeXLive::TLUtils::texdir_check($vars{'TEXDIR'})) {
+ print " $vars{'TEXDIR'}\n";
+ } else {
+ print " !! default location: $vars{'TEXDIR'}\n";
+ print " !! is not writable or not allowed, please select a different one!\n";
+ }
+ print <<"EOF";
+ TEXMFLOCAL (directory for site-wide local files):
+ $vars{'TEXMFLOCAL'}
+ TEXMFSYSVAR (directory for variable and automatically generated data):
+ $vars{'TEXMFSYSVAR'}
+ TEXMFSYSCONFIG (directory for local config):
+ $vars{'TEXMFSYSCONFIG'}
+ TEXMFVAR (personal directory for variable and automatically generated data):
+ $vars{'TEXMFVAR'}
+ TEXMFCONFIG (personal directory for local config):
+ $vars{'TEXMFCONFIG'}
+ TEXMFHOME (directory for user-specific files):
+ $vars{'TEXMFHOME'}
+
+EOF
+
+print <<"EOF";
+ <O> options:
+ $b_letter use letter size instead of A4 by default
+ $b_restricted allow execution of restricted list of programs via \\write18
+ $b_fmt create all format files
+EOF
+
+ if (!$opt_in_place) {
+ if ($vars{'doc_splitting_supported'}) {
+ print " $b_doc install macro/font doc tree\n";
+ }
+ if ($vars{'src_splitting_supported'}) {
+ print " $b_src install macro/font source tree\n";
+ }
+ }
+ if (win32()) {
+ if (!$vars{'instopt_portable'}) {
+ print " $b_path adjust search path\n";
+ print " $b_deskint add menu items, shortcuts, etc.\n";
+ print " [$vars{'tlpdbopt_file_assocs'}] update file associations\n";
+ if (admin()) {
+ print " $b_admin make installation available to all users\n";
+ }
+ }
+ print " $b_addoneditor install TeXworks front end\n";
+ }
+
+ print " $b_path create symlinks to standard directories\n"
+ unless ($vars{'instopt_portable'} || win32());
+
+ print " $b_adjustrepo after install, set CTAN as source "
+ . "for package updates\n"
+ unless ($media eq 'NET');
+
+ if ($vars{'instopt_portable'}) {
+ print "\n <V> set up for regular installation to hard disk\n";
+ } else {
+ print "\n <V> set up for portable installation\n";
+ }
+
+ other_options qw(I P H Q);
+ my $answer = prompt 'Enter command';
+
+ if (defined $command{"\u$answer"}) {
+ return $command{"\u$answer"};
+ } else {
+ print "Unknown command: $answer\n\n";
+ return $command{'self'};
+ }
+}
+# needs a terminal 1 for require to succeed!
+1;
+
+__END__
+
+### Local Variables:
+### perl-indent-level: 2
+### tab-width: 2
+### indent-tabs-mode: nil
+### End:
+# vim:set tabstop=2 expandtab: #