diff options
author | Norbert Preining <preining@logic.at> | 2008-03-29 14:28:19 +0000 |
---|---|---|
committer | Norbert Preining <preining@logic.at> | 2008-03-29 14:28:19 +0000 |
commit | d4eedbeb6301b3ed03a6b6f703020f7dc5dcdc63 (patch) | |
tree | 2e75e7be0a5c8389343b511710f59c3e87dd65d9 | |
parent | 90c3bb4dc0c455df131af548a15d4cf875a86708 (diff) |
too many changes, see email, basically tl.-package-manager work
git-svn-id: svn://tug.org/texlive/trunk@7221 c570f23f-e606-0410-a88d-b1316a301751
59 files changed, 8772 insertions, 552 deletions
diff --git a/Build/source/texk/texlive/Makefile.in b/Build/source/texk/texlive/Makefile.in index 94e062f020c..f4e79e859ed 100644 --- a/Build/source/texk/texlive/Makefile.in +++ b/Build/source/texk/texlive/Makefile.in @@ -11,7 +11,7 @@ LIVESCRIPTS = simpdftex \ pdfthumb wordcount.sh \ texlua-perl-runner -TEXLUARUNNERS = generate-updmap generate-language generate-fmtutil +TEXLUARUNNERS = tl-package-manager manpgs = getnonfreefonts getnonfreefonts-sys diff --git a/Master/bin/alpha-linux/texlua-perl-runner b/Master/bin/alpha-linux/texlua-perl-runner new file mode 100755 index 00000000000..ca2bfbf7418 --- /dev/null +++ b/Master/bin/alpha-linux/texlua-perl-runner @@ -0,0 +1,53 @@ +#!/usr/bin/env texlua +--*-Lua-*- +-- $Id: texlua-perl-runner 6485 2008-02-01 20:15:06Z reinhardk $ + +-- Copyright (C) 2007 2008 Reinhard Kotucha, Norbert Preining +-- You may freely use, modify and/or distribute this file. + +-- Wrapper for Perl scripts. +-- Support for -sys variants + + +if string.find(arg[0], "/") then -- UNIX path + filename=select(1, string.gsub(arg[0], ".*/", "")) +elseif string.find(arg[0], "\\") then -- Windows path + filename=select(1, string.gsub(arg[0], ".*\\", "")) +else -- no path + filename=arg[0] +end + +basename=select(1, string.gsub(filename, "\.texlua$", "")) + +kpse.set_program_name(filename) + +TEXDIR=kpse.var_value("SELFAUTOPARENT") + +-- if we are on win32 we have to use the shipped perl +perlbin="perl" +if (os.type == "windows") then + os.setenv("PERL5LIB", TEXDIR.."/tlpkg/tlperl/lib") + perlbin=TEXDIR.."/tlpkg/tlperl/bin/perl.exe" +end + +script=kpse.find_file(basename..".pl", "texmfscripts") + +if (not(script)) then + print ("Cannot find "..basename..".pl".." using kpse, exiting!") + os.exit(1) +end + +if (os.type == "windows") then + command={'"'..perlbin..'"', '"'..script..'"'} +else + command={ perlbin, script } +end +command[0] = perlbin + +for i=1, #arg do + command[#command+1]=arg[i] +end + +ret=os.spawn(command) +os.exit(ret) + diff --git a/Master/bin/alpha-linux/tl-package-manager b/Master/bin/alpha-linux/tl-package-manager new file mode 120000 index 00000000000..331c9dd59df --- /dev/null +++ b/Master/bin/alpha-linux/tl-package-manager @@ -0,0 +1 @@ +texlua-perl-runner
\ No newline at end of file diff --git a/Master/bin/hppa-hpux/texlua-perl-runner b/Master/bin/hppa-hpux/texlua-perl-runner new file mode 100755 index 00000000000..ca2bfbf7418 --- /dev/null +++ b/Master/bin/hppa-hpux/texlua-perl-runner @@ -0,0 +1,53 @@ +#!/usr/bin/env texlua +--*-Lua-*- +-- $Id: texlua-perl-runner 6485 2008-02-01 20:15:06Z reinhardk $ + +-- Copyright (C) 2007 2008 Reinhard Kotucha, Norbert Preining +-- You may freely use, modify and/or distribute this file. + +-- Wrapper for Perl scripts. +-- Support for -sys variants + + +if string.find(arg[0], "/") then -- UNIX path + filename=select(1, string.gsub(arg[0], ".*/", "")) +elseif string.find(arg[0], "\\") then -- Windows path + filename=select(1, string.gsub(arg[0], ".*\\", "")) +else -- no path + filename=arg[0] +end + +basename=select(1, string.gsub(filename, "\.texlua$", "")) + +kpse.set_program_name(filename) + +TEXDIR=kpse.var_value("SELFAUTOPARENT") + +-- if we are on win32 we have to use the shipped perl +perlbin="perl" +if (os.type == "windows") then + os.setenv("PERL5LIB", TEXDIR.."/tlpkg/tlperl/lib") + perlbin=TEXDIR.."/tlpkg/tlperl/bin/perl.exe" +end + +script=kpse.find_file(basename..".pl", "texmfscripts") + +if (not(script)) then + print ("Cannot find "..basename..".pl".." using kpse, exiting!") + os.exit(1) +end + +if (os.type == "windows") then + command={'"'..perlbin..'"', '"'..script..'"'} +else + command={ perlbin, script } +end +command[0] = perlbin + +for i=1, #arg do + command[#command+1]=arg[i] +end + +ret=os.spawn(command) +os.exit(ret) + diff --git a/Master/bin/hppa-hpux/tl-package-manager b/Master/bin/hppa-hpux/tl-package-manager new file mode 120000 index 00000000000..331c9dd59df --- /dev/null +++ b/Master/bin/hppa-hpux/tl-package-manager @@ -0,0 +1 @@ +texlua-perl-runner
\ No newline at end of file diff --git a/Master/bin/i386-darwin/texlua-perl-runner b/Master/bin/i386-darwin/texlua-perl-runner new file mode 100755 index 00000000000..ca2bfbf7418 --- /dev/null +++ b/Master/bin/i386-darwin/texlua-perl-runner @@ -0,0 +1,53 @@ +#!/usr/bin/env texlua +--*-Lua-*- +-- $Id: texlua-perl-runner 6485 2008-02-01 20:15:06Z reinhardk $ + +-- Copyright (C) 2007 2008 Reinhard Kotucha, Norbert Preining +-- You may freely use, modify and/or distribute this file. + +-- Wrapper for Perl scripts. +-- Support for -sys variants + + +if string.find(arg[0], "/") then -- UNIX path + filename=select(1, string.gsub(arg[0], ".*/", "")) +elseif string.find(arg[0], "\\") then -- Windows path + filename=select(1, string.gsub(arg[0], ".*\\", "")) +else -- no path + filename=arg[0] +end + +basename=select(1, string.gsub(filename, "\.texlua$", "")) + +kpse.set_program_name(filename) + +TEXDIR=kpse.var_value("SELFAUTOPARENT") + +-- if we are on win32 we have to use the shipped perl +perlbin="perl" +if (os.type == "windows") then + os.setenv("PERL5LIB", TEXDIR.."/tlpkg/tlperl/lib") + perlbin=TEXDIR.."/tlpkg/tlperl/bin/perl.exe" +end + +script=kpse.find_file(basename..".pl", "texmfscripts") + +if (not(script)) then + print ("Cannot find "..basename..".pl".." using kpse, exiting!") + os.exit(1) +end + +if (os.type == "windows") then + command={'"'..perlbin..'"', '"'..script..'"'} +else + command={ perlbin, script } +end +command[0] = perlbin + +for i=1, #arg do + command[#command+1]=arg[i] +end + +ret=os.spawn(command) +os.exit(ret) + diff --git a/Master/bin/i386-darwin/tl-package-manager b/Master/bin/i386-darwin/tl-package-manager new file mode 120000 index 00000000000..331c9dd59df --- /dev/null +++ b/Master/bin/i386-darwin/tl-package-manager @@ -0,0 +1 @@ +texlua-perl-runner
\ No newline at end of file diff --git a/Master/bin/i386-freebsd/texlua-perl-runner b/Master/bin/i386-freebsd/texlua-perl-runner new file mode 100755 index 00000000000..ca2bfbf7418 --- /dev/null +++ b/Master/bin/i386-freebsd/texlua-perl-runner @@ -0,0 +1,53 @@ +#!/usr/bin/env texlua +--*-Lua-*- +-- $Id: texlua-perl-runner 6485 2008-02-01 20:15:06Z reinhardk $ + +-- Copyright (C) 2007 2008 Reinhard Kotucha, Norbert Preining +-- You may freely use, modify and/or distribute this file. + +-- Wrapper for Perl scripts. +-- Support for -sys variants + + +if string.find(arg[0], "/") then -- UNIX path + filename=select(1, string.gsub(arg[0], ".*/", "")) +elseif string.find(arg[0], "\\") then -- Windows path + filename=select(1, string.gsub(arg[0], ".*\\", "")) +else -- no path + filename=arg[0] +end + +basename=select(1, string.gsub(filename, "\.texlua$", "")) + +kpse.set_program_name(filename) + +TEXDIR=kpse.var_value("SELFAUTOPARENT") + +-- if we are on win32 we have to use the shipped perl +perlbin="perl" +if (os.type == "windows") then + os.setenv("PERL5LIB", TEXDIR.."/tlpkg/tlperl/lib") + perlbin=TEXDIR.."/tlpkg/tlperl/bin/perl.exe" +end + +script=kpse.find_file(basename..".pl", "texmfscripts") + +if (not(script)) then + print ("Cannot find "..basename..".pl".." using kpse, exiting!") + os.exit(1) +end + +if (os.type == "windows") then + command={'"'..perlbin..'"', '"'..script..'"'} +else + command={ perlbin, script } +end +command[0] = perlbin + +for i=1, #arg do + command[#command+1]=arg[i] +end + +ret=os.spawn(command) +os.exit(ret) + diff --git a/Master/bin/i386-freebsd/tl-package-manager b/Master/bin/i386-freebsd/tl-package-manager new file mode 120000 index 00000000000..331c9dd59df --- /dev/null +++ b/Master/bin/i386-freebsd/tl-package-manager @@ -0,0 +1 @@ +texlua-perl-runner
\ No newline at end of file diff --git a/Master/bin/i386-linux/texlua-perl-runner b/Master/bin/i386-linux/texlua-perl-runner new file mode 100755 index 00000000000..ca2bfbf7418 --- /dev/null +++ b/Master/bin/i386-linux/texlua-perl-runner @@ -0,0 +1,53 @@ +#!/usr/bin/env texlua +--*-Lua-*- +-- $Id: texlua-perl-runner 6485 2008-02-01 20:15:06Z reinhardk $ + +-- Copyright (C) 2007 2008 Reinhard Kotucha, Norbert Preining +-- You may freely use, modify and/or distribute this file. + +-- Wrapper for Perl scripts. +-- Support for -sys variants + + +if string.find(arg[0], "/") then -- UNIX path + filename=select(1, string.gsub(arg[0], ".*/", "")) +elseif string.find(arg[0], "\\") then -- Windows path + filename=select(1, string.gsub(arg[0], ".*\\", "")) +else -- no path + filename=arg[0] +end + +basename=select(1, string.gsub(filename, "\.texlua$", "")) + +kpse.set_program_name(filename) + +TEXDIR=kpse.var_value("SELFAUTOPARENT") + +-- if we are on win32 we have to use the shipped perl +perlbin="perl" +if (os.type == "windows") then + os.setenv("PERL5LIB", TEXDIR.."/tlpkg/tlperl/lib") + perlbin=TEXDIR.."/tlpkg/tlperl/bin/perl.exe" +end + +script=kpse.find_file(basename..".pl", "texmfscripts") + +if (not(script)) then + print ("Cannot find "..basename..".pl".." using kpse, exiting!") + os.exit(1) +end + +if (os.type == "windows") then + command={'"'..perlbin..'"', '"'..script..'"'} +else + command={ perlbin, script } +end +command[0] = perlbin + +for i=1, #arg do + command[#command+1]=arg[i] +end + +ret=os.spawn(command) +os.exit(ret) + diff --git a/Master/bin/i386-linux/tl-package-manager b/Master/bin/i386-linux/tl-package-manager new file mode 120000 index 00000000000..331c9dd59df --- /dev/null +++ b/Master/bin/i386-linux/tl-package-manager @@ -0,0 +1 @@ +texlua-perl-runner
\ No newline at end of file diff --git a/Master/bin/i386-openbsd/texlua-perl-runner b/Master/bin/i386-openbsd/texlua-perl-runner new file mode 100755 index 00000000000..ca2bfbf7418 --- /dev/null +++ b/Master/bin/i386-openbsd/texlua-perl-runner @@ -0,0 +1,53 @@ +#!/usr/bin/env texlua +--*-Lua-*- +-- $Id: texlua-perl-runner 6485 2008-02-01 20:15:06Z reinhardk $ + +-- Copyright (C) 2007 2008 Reinhard Kotucha, Norbert Preining +-- You may freely use, modify and/or distribute this file. + +-- Wrapper for Perl scripts. +-- Support for -sys variants + + +if string.find(arg[0], "/") then -- UNIX path + filename=select(1, string.gsub(arg[0], ".*/", "")) +elseif string.find(arg[0], "\\") then -- Windows path + filename=select(1, string.gsub(arg[0], ".*\\", "")) +else -- no path + filename=arg[0] +end + +basename=select(1, string.gsub(filename, "\.texlua$", "")) + +kpse.set_program_name(filename) + +TEXDIR=kpse.var_value("SELFAUTOPARENT") + +-- if we are on win32 we have to use the shipped perl +perlbin="perl" +if (os.type == "windows") then + os.setenv("PERL5LIB", TEXDIR.."/tlpkg/tlperl/lib") + perlbin=TEXDIR.."/tlpkg/tlperl/bin/perl.exe" +end + +script=kpse.find_file(basename..".pl", "texmfscripts") + +if (not(script)) then + print ("Cannot find "..basename..".pl".." using kpse, exiting!") + os.exit(1) +end + +if (os.type == "windows") then + command={'"'..perlbin..'"', '"'..script..'"'} +else + command={ perlbin, script } +end +command[0] = perlbin + +for i=1, #arg do + command[#command+1]=arg[i] +end + +ret=os.spawn(command) +os.exit(ret) + diff --git a/Master/bin/i386-openbsd/tl-package-manager b/Master/bin/i386-openbsd/tl-package-manager new file mode 120000 index 00000000000..331c9dd59df --- /dev/null +++ b/Master/bin/i386-openbsd/tl-package-manager @@ -0,0 +1 @@ +texlua-perl-runner
\ No newline at end of file diff --git a/Master/bin/i386-solaris/texlua-perl-runner b/Master/bin/i386-solaris/texlua-perl-runner new file mode 100755 index 00000000000..ca2bfbf7418 --- /dev/null +++ b/Master/bin/i386-solaris/texlua-perl-runner @@ -0,0 +1,53 @@ +#!/usr/bin/env texlua +--*-Lua-*- +-- $Id: texlua-perl-runner 6485 2008-02-01 20:15:06Z reinhardk $ + +-- Copyright (C) 2007 2008 Reinhard Kotucha, Norbert Preining +-- You may freely use, modify and/or distribute this file. + +-- Wrapper for Perl scripts. +-- Support for -sys variants + + +if string.find(arg[0], "/") then -- UNIX path + filename=select(1, string.gsub(arg[0], ".*/", "")) +elseif string.find(arg[0], "\\") then -- Windows path + filename=select(1, string.gsub(arg[0], ".*\\", "")) +else -- no path + filename=arg[0] +end + +basename=select(1, string.gsub(filename, "\.texlua$", "")) + +kpse.set_program_name(filename) + +TEXDIR=kpse.var_value("SELFAUTOPARENT") + +-- if we are on win32 we have to use the shipped perl +perlbin="perl" +if (os.type == "windows") then + os.setenv("PERL5LIB", TEXDIR.."/tlpkg/tlperl/lib") + perlbin=TEXDIR.."/tlpkg/tlperl/bin/perl.exe" +end + +script=kpse.find_file(basename..".pl", "texmfscripts") + +if (not(script)) then + print ("Cannot find "..basename..".pl".." using kpse, exiting!") + os.exit(1) +end + +if (os.type == "windows") then + command={'"'..perlbin..'"', '"'..script..'"'} +else + command={ perlbin, script } +end +command[0] = perlbin + +for i=1, #arg do + command[#command+1]=arg[i] +end + +ret=os.spawn(command) +os.exit(ret) + diff --git a/Master/bin/i386-solaris/tl-package-manager b/Master/bin/i386-solaris/tl-package-manager new file mode 120000 index 00000000000..331c9dd59df --- /dev/null +++ b/Master/bin/i386-solaris/tl-package-manager @@ -0,0 +1 @@ +texlua-perl-runner
\ No newline at end of file diff --git a/Master/bin/mips-irix/texlua-perl-runner b/Master/bin/mips-irix/texlua-perl-runner new file mode 100755 index 00000000000..ca2bfbf7418 --- /dev/null +++ b/Master/bin/mips-irix/texlua-perl-runner @@ -0,0 +1,53 @@ +#!/usr/bin/env texlua +--*-Lua-*- +-- $Id: texlua-perl-runner 6485 2008-02-01 20:15:06Z reinhardk $ + +-- Copyright (C) 2007 2008 Reinhard Kotucha, Norbert Preining +-- You may freely use, modify and/or distribute this file. + +-- Wrapper for Perl scripts. +-- Support for -sys variants + + +if string.find(arg[0], "/") then -- UNIX path + filename=select(1, string.gsub(arg[0], ".*/", "")) +elseif string.find(arg[0], "\\") then -- Windows path + filename=select(1, string.gsub(arg[0], ".*\\", "")) +else -- no path + filename=arg[0] +end + +basename=select(1, string.gsub(filename, "\.texlua$", "")) + +kpse.set_program_name(filename) + +TEXDIR=kpse.var_value("SELFAUTOPARENT") + +-- if we are on win32 we have to use the shipped perl +perlbin="perl" +if (os.type == "windows") then + os.setenv("PERL5LIB", TEXDIR.."/tlpkg/tlperl/lib") + perlbin=TEXDIR.."/tlpkg/tlperl/bin/perl.exe" +end + +script=kpse.find_file(basename..".pl", "texmfscripts") + +if (not(script)) then + print ("Cannot find "..basename..".pl".." using kpse, exiting!") + os.exit(1) +end + +if (os.type == "windows") then + command={'"'..perlbin..'"', '"'..script..'"'} +else + command={ perlbin, script } +end +command[0] = perlbin + +for i=1, #arg do + command[#command+1]=arg[i] +end + +ret=os.spawn(command) +os.exit(ret) + diff --git a/Master/bin/mips-irix/tl-package-manager b/Master/bin/mips-irix/tl-package-manager new file mode 120000 index 00000000000..331c9dd59df --- /dev/null +++ b/Master/bin/mips-irix/tl-package-manager @@ -0,0 +1 @@ +texlua-perl-runner
\ No newline at end of file diff --git a/Master/bin/powerpc-aix/texlua-perl-runner b/Master/bin/powerpc-aix/texlua-perl-runner new file mode 100755 index 00000000000..ca2bfbf7418 --- /dev/null +++ b/Master/bin/powerpc-aix/texlua-perl-runner @@ -0,0 +1,53 @@ +#!/usr/bin/env texlua +--*-Lua-*- +-- $Id: texlua-perl-runner 6485 2008-02-01 20:15:06Z reinhardk $ + +-- Copyright (C) 2007 2008 Reinhard Kotucha, Norbert Preining +-- You may freely use, modify and/or distribute this file. + +-- Wrapper for Perl scripts. +-- Support for -sys variants + + +if string.find(arg[0], "/") then -- UNIX path + filename=select(1, string.gsub(arg[0], ".*/", "")) +elseif string.find(arg[0], "\\") then -- Windows path + filename=select(1, string.gsub(arg[0], ".*\\", "")) +else -- no path + filename=arg[0] +end + +basename=select(1, string.gsub(filename, "\.texlua$", "")) + +kpse.set_program_name(filename) + +TEXDIR=kpse.var_value("SELFAUTOPARENT") + +-- if we are on win32 we have to use the shipped perl +perlbin="perl" +if (os.type == "windows") then + os.setenv("PERL5LIB", TEXDIR.."/tlpkg/tlperl/lib") + perlbin=TEXDIR.."/tlpkg/tlperl/bin/perl.exe" +end + +script=kpse.find_file(basename..".pl", "texmfscripts") + +if (not(script)) then + print ("Cannot find "..basename..".pl".." using kpse, exiting!") + os.exit(1) +end + +if (os.type == "windows") then + command={'"'..perlbin..'"', '"'..script..'"'} +else + command={ perlbin, script } +end +command[0] = perlbin + +for i=1, #arg do + command[#command+1]=arg[i] +end + +ret=os.spawn(command) +os.exit(ret) + diff --git a/Master/bin/powerpc-aix/tl-package-manager b/Master/bin/powerpc-aix/tl-package-manager new file mode 120000 index 00000000000..331c9dd59df --- /dev/null +++ b/Master/bin/powerpc-aix/tl-package-manager @@ -0,0 +1 @@ +texlua-perl-runner
\ No newline at end of file diff --git a/Master/bin/powerpc-darwin/texlua-perl-runner b/Master/bin/powerpc-darwin/texlua-perl-runner new file mode 100755 index 00000000000..ca2bfbf7418 --- /dev/null +++ b/Master/bin/powerpc-darwin/texlua-perl-runner @@ -0,0 +1,53 @@ +#!/usr/bin/env texlua +--*-Lua-*- +-- $Id: texlua-perl-runner 6485 2008-02-01 20:15:06Z reinhardk $ + +-- Copyright (C) 2007 2008 Reinhard Kotucha, Norbert Preining +-- You may freely use, modify and/or distribute this file. + +-- Wrapper for Perl scripts. +-- Support for -sys variants + + +if string.find(arg[0], "/") then -- UNIX path + filename=select(1, string.gsub(arg[0], ".*/", "")) +elseif string.find(arg[0], "\\") then -- Windows path + filename=select(1, string.gsub(arg[0], ".*\\", "")) +else -- no path + filename=arg[0] +end + +basename=select(1, string.gsub(filename, "\.texlua$", "")) + +kpse.set_program_name(filename) + +TEXDIR=kpse.var_value("SELFAUTOPARENT") + +-- if we are on win32 we have to use the shipped perl +perlbin="perl" +if (os.type == "windows") then + os.setenv("PERL5LIB", TEXDIR.."/tlpkg/tlperl/lib") + perlbin=TEXDIR.."/tlpkg/tlperl/bin/perl.exe" +end + +script=kpse.find_file(basename..".pl", "texmfscripts") + +if (not(script)) then + print ("Cannot find "..basename..".pl".." using kpse, exiting!") + os.exit(1) +end + +if (os.type == "windows") then + command={'"'..perlbin..'"', '"'..script..'"'} +else + command={ perlbin, script } +end +command[0] = perlbin + +for i=1, #arg do + command[#command+1]=arg[i] +end + +ret=os.spawn(command) +os.exit(ret) + diff --git a/Master/bin/powerpc-darwin/tl-package-manager b/Master/bin/powerpc-darwin/tl-package-manager new file mode 120000 index 00000000000..331c9dd59df --- /dev/null +++ b/Master/bin/powerpc-darwin/tl-package-manager @@ -0,0 +1 @@ +texlua-perl-runner
\ No newline at end of file diff --git a/Master/bin/powerpc-linux/texlua-perl-runner b/Master/bin/powerpc-linux/texlua-perl-runner new file mode 100755 index 00000000000..ca2bfbf7418 --- /dev/null +++ b/Master/bin/powerpc-linux/texlua-perl-runner @@ -0,0 +1,53 @@ +#!/usr/bin/env texlua +--*-Lua-*- +-- $Id: texlua-perl-runner 6485 2008-02-01 20:15:06Z reinhardk $ + +-- Copyright (C) 2007 2008 Reinhard Kotucha, Norbert Preining +-- You may freely use, modify and/or distribute this file. + +-- Wrapper for Perl scripts. +-- Support for -sys variants + + +if string.find(arg[0], "/") then -- UNIX path + filename=select(1, string.gsub(arg[0], ".*/", "")) +elseif string.find(arg[0], "\\") then -- Windows path + filename=select(1, string.gsub(arg[0], ".*\\", "")) +else -- no path + filename=arg[0] +end + +basename=select(1, string.gsub(filename, "\.texlua$", "")) + +kpse.set_program_name(filename) + +TEXDIR=kpse.var_value("SELFAUTOPARENT") + +-- if we are on win32 we have to use the shipped perl +perlbin="perl" +if (os.type == "windows") then + os.setenv("PERL5LIB", TEXDIR.."/tlpkg/tlperl/lib") + perlbin=TEXDIR.."/tlpkg/tlperl/bin/perl.exe" +end + +script=kpse.find_file(basename..".pl", "texmfscripts") + +if (not(script)) then + print ("Cannot find "..basename..".pl".." using kpse, exiting!") + os.exit(1) +end + +if (os.type == "windows") then + command={'"'..perlbin..'"', '"'..script..'"'} +else + command={ perlbin, script } +end +command[0] = perlbin + +for i=1, #arg do + command[#command+1]=arg[i] +end + +ret=os.spawn(command) +os.exit(ret) + diff --git a/Master/bin/powerpc-linux/tl-package-manager b/Master/bin/powerpc-linux/tl-package-manager new file mode 120000 index 00000000000..331c9dd59df --- /dev/null +++ b/Master/bin/powerpc-linux/tl-package-manager @@ -0,0 +1 @@ +texlua-perl-runner
\ No newline at end of file diff --git a/Master/bin/sparc-linux/texlua-perl-runner b/Master/bin/sparc-linux/texlua-perl-runner new file mode 100755 index 00000000000..ca2bfbf7418 --- /dev/null +++ b/Master/bin/sparc-linux/texlua-perl-runner @@ -0,0 +1,53 @@ +#!/usr/bin/env texlua +--*-Lua-*- +-- $Id: texlua-perl-runner 6485 2008-02-01 20:15:06Z reinhardk $ + +-- Copyright (C) 2007 2008 Reinhard Kotucha, Norbert Preining +-- You may freely use, modify and/or distribute this file. + +-- Wrapper for Perl scripts. +-- Support for -sys variants + + +if string.find(arg[0], "/") then -- UNIX path + filename=select(1, string.gsub(arg[0], ".*/", "")) +elseif string.find(arg[0], "\\") then -- Windows path + filename=select(1, string.gsub(arg[0], ".*\\", "")) +else -- no path + filename=arg[0] +end + +basename=select(1, string.gsub(filename, "\.texlua$", "")) + +kpse.set_program_name(filename) + +TEXDIR=kpse.var_value("SELFAUTOPARENT") + +-- if we are on win32 we have to use the shipped perl +perlbin="perl" +if (os.type == "windows") then + os.setenv("PERL5LIB", TEXDIR.."/tlpkg/tlperl/lib") + perlbin=TEXDIR.."/tlpkg/tlperl/bin/perl.exe" +end + +script=kpse.find_file(basename..".pl", "texmfscripts") + +if (not(script)) then + print ("Cannot find "..basename..".pl".." using kpse, exiting!") + os.exit(1) +end + +if (os.type == "windows") then + command={'"'..perlbin..'"', '"'..script..'"'} +else + command={ perlbin, script } +end +command[0] = perlbin + +for i=1, #arg do + command[#command+1]=arg[i] +end + +ret=os.spawn(command) +os.exit(ret) + diff --git a/Master/bin/sparc-linux/tl-package-manager b/Master/bin/sparc-linux/tl-package-manager new file mode 120000 index 00000000000..331c9dd59df --- /dev/null +++ b/Master/bin/sparc-linux/tl-package-manager @@ -0,0 +1 @@ +texlua-perl-runner
\ No newline at end of file diff --git a/Master/bin/sparc-solaris/texlua-perl-runner b/Master/bin/sparc-solaris/texlua-perl-runner new file mode 100755 index 00000000000..ca2bfbf7418 --- /dev/null +++ b/Master/bin/sparc-solaris/texlua-perl-runner @@ -0,0 +1,53 @@ +#!/usr/bin/env texlua +--*-Lua-*- +-- $Id: texlua-perl-runner 6485 2008-02-01 20:15:06Z reinhardk $ + +-- Copyright (C) 2007 2008 Reinhard Kotucha, Norbert Preining +-- You may freely use, modify and/or distribute this file. + +-- Wrapper for Perl scripts. +-- Support for -sys variants + + +if string.find(arg[0], "/") then -- UNIX path + filename=select(1, string.gsub(arg[0], ".*/", "")) +elseif string.find(arg[0], "\\") then -- Windows path + filename=select(1, string.gsub(arg[0], ".*\\", "")) +else -- no path + filename=arg[0] +end + +basename=select(1, string.gsub(filename, "\.texlua$", "")) + +kpse.set_program_name(filename) + +TEXDIR=kpse.var_value("SELFAUTOPARENT") + +-- if we are on win32 we have to use the shipped perl +perlbin="perl" +if (os.type == "windows") then + os.setenv("PERL5LIB", TEXDIR.."/tlpkg/tlperl/lib") + perlbin=TEXDIR.."/tlpkg/tlperl/bin/perl.exe" +end + +script=kpse.find_file(basename..".pl", "texmfscripts") + +if (not(script)) then + print ("Cannot find "..basename..".pl".." using kpse, exiting!") + os.exit(1) +end + +if (os.type == "windows") then + command={'"'..perlbin..'"', '"'..script..'"'} +else + command={ perlbin, script } +end +command[0] = perlbin + +for i=1, #arg do + command[#command+1]=arg[i] +end + +ret=os.spawn(command) +os.exit(ret) + diff --git a/Master/bin/sparc-solaris/tl-package-manager b/Master/bin/sparc-solaris/tl-package-manager new file mode 120000 index 00000000000..331c9dd59df --- /dev/null +++ b/Master/bin/sparc-solaris/tl-package-manager @@ -0,0 +1 @@ +texlua-perl-runner
\ No newline at end of file diff --git a/Master/bin/win32/tl-package-manager.texlua b/Master/bin/win32/tl-package-manager.texlua new file mode 100755 index 00000000000..ee2edadb197 --- /dev/null +++ b/Master/bin/win32/tl-package-manager.texlua @@ -0,0 +1,90 @@ +#! /usr/bin/env texlua +--*-Lua-*- +-- $Id: tl-package-manager.texlua 6943 2008-03-11 21:38:19Z reinhardk $ + +-- Copyright (C) 2007 Reinhard Kotucha, Norbert Preining. +-- You may freely use, modify and/or distribute this file. + +-- Wrapper for scripts. + +function fixwin(args_unix) + if os.type == 'windows' then + local args_win={} -- new table + args_win[0]=args_unix[1] + for i=1, #args_unix do + args_win[i]='"'..args_unix[i]..'"' + end + return args_win + else + return args_unix + end +end + +if string.find(arg[0], '/') then -- UNIX path + filename=select(1, string.gsub(arg[0], '.*/', '')) +elseif string.find(arg[0], '\\') then -- Windows path + filename=select(1, string.gsub(arg[0], '.*\\', '')) +else -- no path + filename=arg[0] +end + +basename=select(1, string.gsub(filename, '\.texlua$', '')) + +sys=false + +if string.find(basename, '-sys$') then + basename=select(1, string.gsub(basename, '-sys$', '')) + sys=true +end + +kpse.set_program_name(filename, basename) +TEXDIR=kpse.var_value('SELFAUTOPARENT') +BINDIR=kpse.var_value('SELFAUTOLOC') + +os.setenv('PERL5LIB', TEXDIR..'/tlpkg/tlperl/lib') +os.setenv('GS_LIB', TEXDIR..'/tlpkg/tlgs/lib') +os.setenv('PATH', TEXDIR..'/tlpkg/tlgs/bin;'..os.getenv('PATH')) + +if sys then + os.setenv('TEXMFVAR', kpse.var_value('TEXMFSYSVAR')) + os.setenv('TEXMFCONFIG', kpse.var_value('TEXMFSYSCONFIG')) + os.setenv('TEX_SYS_PROG', 'true') +end + +if sys and lfs.isfile(BINDIR..'/'..basename..'.exe') then + command={BINDIR..'/'..basename..'.exe'} +elseif lfs.isfile(BINDIR..'/'..basename..'-bin.exe') then + command={BINDIR..'/'..basename..'-bin.exe'} +elseif lfs.isdir(BINDIR..'/'..basename..'.pl') then + perlbin=TEXDIR..'/tlpkg/tlperl/bin/perl.exe' + script=BINDIR..'/'..basename..'.pl' + command={perlbin, script} +elseif kpse.find_file(basename..'.pl', 'texmfscripts') then + perlbin=TEXDIR..'/tlpkg/tlperl/bin/perl.exe' + script=kpse.find_file(basename..'.pl', 'texmfscripts') + command={perlbin, script} +elseif kpse.find_file(basename..'.rb', 'texmfscripts') then + script=kpse.find_file(basename..'.rb', 'texmfscripts') + command={'ruby', script} +elseif kpse.find_file(basename..'.py', 'texmfscripts') then + script=kpse.find_file(basename..'.py', 'texmfscripts') + command={'python', script} +elseif kpse.find_file(basename..'.texlua', 'texmfscripts') then + script=kpse.find_file(basename..'.texlua', 'texmfscripts') + command={'texlua', script} +elseif kpse.find_file(basename..'.lua', 'texmfscripts') then + script=kpse.find_file(basename..'.lua', 'texmfscripts') + command={'texlua', script} +else + os.stderr:write(filename..'.texlua: No interpreter found for '.. + basename..'\n') +end + +for i=1, #arg do + command[#command+1]=arg[i] +end + +command=fixwin(command) + +ret=os.spawn(command) +os.exit(ret) diff --git a/Master/bin/x86_64-linux/texlua-perl-runner b/Master/bin/x86_64-linux/texlua-perl-runner new file mode 100755 index 00000000000..ca2bfbf7418 --- /dev/null +++ b/Master/bin/x86_64-linux/texlua-perl-runner @@ -0,0 +1,53 @@ +#!/usr/bin/env texlua +--*-Lua-*- +-- $Id: texlua-perl-runner 6485 2008-02-01 20:15:06Z reinhardk $ + +-- Copyright (C) 2007 2008 Reinhard Kotucha, Norbert Preining +-- You may freely use, modify and/or distribute this file. + +-- Wrapper for Perl scripts. +-- Support for -sys variants + + +if string.find(arg[0], "/") then -- UNIX path + filename=select(1, string.gsub(arg[0], ".*/", "")) +elseif string.find(arg[0], "\\") then -- Windows path + filename=select(1, string.gsub(arg[0], ".*\\", "")) +else -- no path + filename=arg[0] +end + +basename=select(1, string.gsub(filename, "\.texlua$", "")) + +kpse.set_program_name(filename) + +TEXDIR=kpse.var_value("SELFAUTOPARENT") + +-- if we are on win32 we have to use the shipped perl +perlbin="perl" +if (os.type == "windows") then + os.setenv("PERL5LIB", TEXDIR.."/tlpkg/tlperl/lib") + perlbin=TEXDIR.."/tlpkg/tlperl/bin/perl.exe" +end + +script=kpse.find_file(basename..".pl", "texmfscripts") + +if (not(script)) then + print ("Cannot find "..basename..".pl".." using kpse, exiting!") + os.exit(1) +end + +if (os.type == "windows") then + command={'"'..perlbin..'"', '"'..script..'"'} +else + command={ perlbin, script } +end +command[0] = perlbin + +for i=1, #arg do + command[#command+1]=arg[i] +end + +ret=os.spawn(command) +os.exit(ret) + diff --git a/Master/bin/x86_64-linux/tl-package-manager b/Master/bin/x86_64-linux/tl-package-manager new file mode 120000 index 00000000000..331c9dd59df --- /dev/null +++ b/Master/bin/x86_64-linux/tl-package-manager @@ -0,0 +1 @@ +texlua-perl-runner
\ No newline at end of file diff --git a/Master/install-tl.pl b/Master/install-tl.pl index 76ac273ad18..e3346f83310 100755 --- a/Master/install-tl.pl +++ b/Master/install-tl.pl @@ -49,7 +49,9 @@ use TeXLive::TLUtils qw(initialize_installer media platform platform_desc install_packages dirname tllog); use TeXLive::TLPOBJ; use TeXLive::TLPDB; -use TeXLive::TLConfig qw($DefaultContainerExtension $InfraLocation); +use TeXLive::TLConfig; +use Pod::Usage; +use Cwd 'abs_path'; if (win32) { require TeXLive::TLWinGoo; @@ -92,12 +94,6 @@ my %install; # if we should try to get additional binaries from the net # needs our since for menu ... our $trynet=0; -# the url of net location, can be changed with -url .... -# -# for my own testing in the virtual machine -#$::texlive_url = 'http://localhost/norbert/tltesting'; -#$::texlive_url = 'http://10.0.2.2/norbert/tltesting'; -$::texlive_url = 'ftp://tug.org/texlive/tlnet/tldev'; # the default scheme to be installed my $default_scheme='scheme-full'; @@ -107,9 +103,6 @@ my $default_scheme='scheme-full'; our @collections_std; our @collections_lang; our @collections_lang_doc; -# The maximum number of binary systems on the CD. This number must be -# smaller than the number of binaries available from the network. -our $max_bins_on_CD=7; # for win dealing #our $Registry; # The global variable %vars is an associative list which contains all @@ -146,9 +139,8 @@ my $opt_quiet = 0; my $opt_qquiet = 0; my $opt_arch = 0; my $opt_portable = 0; - -$::netarchive = "tlpkg"; -$::diskarchive = "archive"; +my $opt_help = 0; +my $opt_version = 0; # default language for GUI installer $::lang = "en"; @@ -157,9 +149,9 @@ GetOptions("media=s" => \$opt_media, "profile=s"=> \$opt_profile, "no-cls", "gui", \$opt_gui, - "netarchive=s" => \$::netarchive, - "diskarchive=s" => \$::diskarchive, - "lang=s" => \$::lang, + "netarchive=s" => \$NetArchive, + "diskarchive=s" => \$DiskArchive, + "lang=s" => \$::opt_lang, "print-arch" => \$opt_arch, "portable" => \$opt_portable, "d" => \$opt_debug, @@ -167,7 +159,24 @@ GetOptions("media=s" => \$opt_media, "ddd" => \$opt_dddebug, "q" => \$opt_quiet, "qq" => \$opt_qquiet, - "url=s" => \$opt_url ) or die("No pod doc till now!"); + "url=s" => \$opt_url, + "version" => \$opt_version, + "help|?" => \$opt_help) or pod2usage(1); + +if (win32()) { + pod2usage(-exitstatus => 0, -verbose => 2, -noperldoc => 1) if $opt_help; +} else { + pod2usage(-exitstatus => 0, -verbose => 2) if $opt_help; +} + +if ($opt_version) { + print "TeX Live Cross Platform Installer, Revision $::installerrevision\n"; + exit 0; +} + +if (defined($::opt_lang)) { + $::lang = $::opt_lang; +} if ($opt_quiet) { $::LOGLEVELTERMINAL = $::LOG_ZERO; @@ -203,7 +212,7 @@ if ("$opt_profile" ne "") { } if ("$opt_url" ne "") { - $::texlive_url = "$opt_url"; + $TeXLiveURL = "$opt_url"; } # the TLPDB instances we will use. $tlpdb is for the one from the installation @@ -400,6 +409,7 @@ sub do_installation { } calc_depends(); prepare_installation(); + save_options_into_tlpdb(); do_install_packages(); if (win32()) { do_win_registry_magic(); @@ -408,7 +418,6 @@ sub do_installation { &$h(); } do_postinst_stuff(); - save_options_into_tlpdb(); $localtlpdb->save; foreach my $h (@::end_install_hook) { &$h(); @@ -467,13 +476,11 @@ sub set_texlive_default_dirs { $tex_prefix=getenv('TEXLIVE_INSTALL_PREFIX'); if (win32) { my $prog = getenv('ProgramFiles'); - $tex_prefix ||= $prog . '/texlive' if TeXLive::TLWinGoo::dir_writable($prog); - $tex_prefix||=getenv('USERPROFILE') . '/texlive'; + $tex_prefix ||= $prog . '/texlive'; + # $tex_prefix ||= $prog . '/texlive' if TeXLive::TLWinGoo::dir_writable($prog); + # $tex_prefix||=getenv('USERPROFILE') . '/texlive'; } else { $tex_prefix||='/usr/local/texlive'; - # $tex_prefix||='/usr/local/texlive' if (-w '/usr/local'); - # $tex_prefix||='/usr/local/texlive' if ( (-d '/usr/local/texlive') && (-w '/usr/local/texlive') ); - # $tex_prefix||=getenv('HOME') . '/texlive'; } $vars{'TEXDIR'}="$tex_prefix/$texlive_release"; @@ -600,7 +607,7 @@ sub calc_depends { sub load_tlpdb { my $master; if (media eq 'NET') { - $master="$::texlive_url"; + $master="$TeXLiveURL"; } else { $master="$::installerdir"; } @@ -766,23 +773,29 @@ sub save_options_into_tlpdb { $tlp->name("00texlive-installation.config"); $tlp->category("TLCore"); my @deps; + push @deps, "platform/$::_platform_"; + if ($::_media_ eq 'NET') { + push @deps, "location/$TeXLiveURL"; + } else { + push @deps, "location/" . abs_path($::installerdir); + } if ($vars{'option_letter'}) { - push @deps, "option_letter"; + push @deps, "letter"; } if ($vars{'option_fmt'}) { - push @deps, "option_fmt"; + push @deps, "formats"; } if ($vars{'option_symlinks'}) { - push @deps, "option_symlinks"; + push @deps, "symlinks"; push @deps, "sys_bin/$vars{'sys_bin'}"; push @deps, "sys_info/$vars{'sys_info'}"; push @deps, "sys_man/$vars{'sys_man'}"; } if ($vars{'option_doc'}) { - push @deps, "option_doc"; + push @deps, "docfiles"; } if ($vars{'option_src'}) { - push @deps, "option_src"; + push @deps, "srcfiles"; } push @deps, "TEXDIR/$vars{'TEXDIR'}"; push @deps, "TEXMFSYSVAR/$vars{'TEXMFSYSVAR'}"; @@ -1100,6 +1113,97 @@ sub flushlog { __END__ +=head1 NAME + +install-tl.pl - the TeX Live Cross Platform Installer + +=head1 SYNOPSIS + +install-tl.pl [OPTION] ... + +install-tl.bat [OPTION] ... + +=head1 OPTIONS + +=over 8 + +=item B<-gui> + +Tries to load the GUI installer using Perl/Tk. If Perl/Tk is not +available continue with the text mode installer. + +=item B<-lang> I<2-letter lang code> + +(only for GUI installer) tries to start the installer translated into +the language specified by the 2-letter language code. Currently supported +languages are English (en, default), Polish (pl), and German (de). + +=item B<-media> I<[CD|DVD|NET]> + +Overrides the autodetection of the media. + +=item B<-profile> I<profile> + +Preloads a TeX Live profile for equal installations on different systems. + +=item B<-url> I<url> + +Overrides the default URL for network installs. Should start with +either ftp:// or http:// + +=item B<-netarchive> I<dir> + +Overrides the default settings for netarchive. Should be used with care. + +=item B<-diskarchive> I<dir> + +Overrides the default settings for diskarchive. Should be used with care. + +=item B<-no-cls> + +(only for text mode installer) do not clear the screen when entering +a new menu. For debugging purposes. + +=item B<-print-arch> + +Print the detected arch-os combination and exit. + +=item B<-portable> + +Starts the installer for portable use. See below for details. + +=item B<-d>, B<-dd>, B<-ddd> + +Debugging levels. + +=item B<-q>, B<-qq> + +B<-q> disables output to the terminal, while B<-qq> also disables output +to the logfile. + +=item B<-help>, B<-h>, B<-?> + +print a help message. + +=back + +=head1 DESCRIPTION + +The TeX Live installer works across all supported platforms and allows +to install TeX Live from various media including the network. + +=head1 PORTABLE USE + +To be written + +=head1 AUTHORS AND COPYRIGHT + +This script and its documentation were written for the TeX Live +distribution (L<http://tug.org/texlive>) and both are licensed under the +GNU General Public License Version 2 or later. + +=cut + ### Local Variables: ### perl-indent-level: 2 ### tab-width: 2 diff --git a/Master/texmf/scripts/texlive/tl-package-manager.pl b/Master/texmf/scripts/texlive/tl-package-manager.pl new file mode 100755 index 00000000000..ced4b7af94b --- /dev/null +++ b/Master/texmf/scripts/texlive/tl-package-manager.pl @@ -0,0 +1,525 @@ +#!/usr/bin/env perl + +# $Id: tl-package-manager.pl 6381 2008-01-23 17:50:54Z preining $ +# +# Copyright 2008 Norbert Preining +# This file is licensed under the GNU General Public License version 2 +# or any later version. +# +# TODO: +# - ordering or collections removal (see below for details) +# - (?) removal does not remove created format files from TEXMFSYSVAR +# - other features: dependency check?, ...? +# - improve search function + + +my $Master; + +BEGIN { + $^W = 1; + $Master = `kpsewhich -var-value=SELFAUTOPARENT`; + chomp($Master); + unshift (@INC, "$Master/tlpkg"); +} + +use TeXLive::TLPOBJ; +use TeXLive::TLPDB; +use TeXLive::TLConfig; +use TeXLive::TLMedia; +use Cwd qw/abs_path/; +use Getopt::Long; +use Pod::Usage; +$Getopt::Long::autoabbrev=0; +use strict; + + +# used variables +# the TLMedia from which we install/update +my $tlmediasrc; +# the tlpdb of the install media +my $tlpdb; +# the local tlpdb +my $localtlpdb; +# a hash for saving the options saved into the local tlpdb +my %options; +# the location from where we install +my $location; + +# option handling +my $opt_location; +my $opt_nodepends = 0; +my $opt_help = 0; +my $opt_debug = 0; +my $opt_force = 0; +my $opt_dry = 0; + +GetOptions("location=s" => \$opt_location, + "netarchive=s" => \$NetArchive, + "diskarchive=s" => \$DiskArchive, + "no-depends" => \$opt_nodepends, + "force" => \$opt_force, + "dry-run" => \$opt_dry, + "debug!", "h|help|?" => \$opt_help) or pod2usage(1); + +if ($^O=~/^MSWin(32|64)$/i) { + pod2usage(-exitstatus => 0, -verbose => 2, -noperldoc => 1) if $opt_help; +} else { + pod2usage(-exitstatus => 0, -verbose => 2) if $opt_help; +} + +my $action = shift; + +if ($opt_debug) { + $::LOGLEVELFILE = $::LOG_DDDEBUG; + $::LOGLEVELTERMINAL = $::LOG_DDDEBUG; +} + +# +# here starts the magic +# +$localtlpdb = TeXLive::TLPDB->new ("root" => "$Master"); +die("cannot find tlpdb!") unless (defined($localtlpdb)); + +# let cmd line options override the settings in localtlpdb +my $loc = $localtlpdb->option_location; +if (defined($loc)) { + $location = $loc; +} +if (defined($opt_location)) { + $location = $opt_location; +} + +# in most cases we need to have access to the wget/tar/etc for win32 +# and TLPDB assumes that wget.exe is in the path, so for win32 we +# add the tlpkg/installer to the path +# That could be solved the way that TLPDB uses for win32 always the +# wget from root/tlpkg/installer/. This would also allow to remove the +# adding of the installer dir to the path in install-tl.bat +if ($^O=~/^MSWin(32|64)$/i) { + $ENV{'PATH'} = "$Master/tlpkg/installer;$ENV{'PATH'}"; +} + +my $ret = 0; + +if ($action =~ m/^install$/i) { + # initialize the TLMedia from $location + $tlmediasrc = TeXLive::TLMedia->new($location); + foreach my $pkg (@ARGV) { + if ($opt_dry) { + print "Installing $pkg\n"; + } else { + $ret |= $tlmediasrc->install_package($pkg, $localtlpdb, $opt_nodepends); + } + } +} elsif ($action =~ m/^update$/i) { + # initialize the TLMedia from $location + $tlmediasrc = TeXLive::TLMedia->new($location); + my $mediatlpdb = $tlmediasrc->tlpdb; + foreach my $pkg ($localtlpdb->list_packages) { + next if ($pkg =~ m/^00texlive/); + my $tlp = $localtlpdb->get_package($pkg); + my $rev = $tlp->revision; + my $mediatlp = $mediatlpdb->get_package($pkg); + if (!defined($mediatlp)) { + print "$pkg cannot be found in $location\n"; + next; + } + my $mediarev = $mediatlp->revision; + if ($rev < $mediarev) { + if ($opt_dry) { + print "Installing $pkg\n"; + } else { + $ret |= $tlmediasrc->install_package($pkg, $localtlpdb, $opt_nodepends); + } + } elsif ($rev > $mediarev) { + print "revision in $location is less then local revision, not updating!\n"; + next; + } + } +} elsif ($action =~ m/^(global)?search$/i) { + my $r = shift; + my $ret = ""; + my $tlpdb; + if ($action =~ m/^globalsearch$/i) { + my $tlmediasrc = TeXLive::TLMedia->new($location); + $tlpdb = $tlmediasrc->tlpdb; + } else { + $tlpdb = $localtlpdb; + } + foreach my $pkg ($tlpdb->list_packages) { + next if ($pkg =~ m/\./); + my $t = $tlpdb->get_package($pkg)->shortdesc; + $t |= ""; + if (($pkg =~ m/$r/) || ($t =~ m/$r/)) { + $ret .= " $pkg - $t\n"; + } + } + print "$ret"; + exit(0); +} elsif ($action =~ m/^remove$/i) { + # we do the following: + # - (not implemented) order collections such that those depending on + # other collections are first removed, and then those which only + # depend on packages. Otherwise + # remove collection-latex collection-latexrecommended + # will not succeed + # - first loop over all cmd line args and consider only the collections + # - for each to be removed collection: + # . check that no other collections/scheme asks for that collection + # . remove the collection + # . remove all dependencies + # - for each normal package not already removed (via the above) + # . check that no collection/scheme still depends on this package + # . remove the package + # + my %already_removed; + my @more_removal; + foreach my $pkg (@ARGV) { + my $tlp = $localtlpdb->get_package($pkg); + next if defined($already_removed{$pkg}); + if (!defined($tlp)) { + print "Package $pkg not present, cannot remove it!\n"; + } else { + # in the first round we only remove collections, nothing else + # but removing collections will remove all dependencies, too + # save the information of which packages have already been removed + # into %already_removed. + if ($tlp->category eq "Collection") { + # for collections we also remove all dependencies which are + # not Collections or Schemes + my $foo; + if ($opt_dry) { + print "Removing $pkg\n"; + # we need to set $foo to something positive otherwise + # the rest will not be run in dry_run mode + $foo = 0x0001; + } else { + $foo = &remove_package($pkg, $localtlpdb, $opt_force); + } + if ($foo) { + # removal was successful, so the return is at least 0x0001 mktexlsr + # remove dependencies, too + $ret |= $foo; + $already_removed{$pkg} = 1; + if (!$opt_nodepends) { + foreach my $d ($tlp->depends) { + my $tlpdd = $localtlpdb->get_package($d); + if (defined($tlpdd)) { + if ($tlpdd->category !~ m/$MetaCategoriesRegexp/) { + if ($opt_dry) { + print "Removing $d\n"; + } else { + $ret |= &remove_package($d, $localtlpdb, $opt_force); + } + $already_removed{$d} = 1; + } + } + } + } + } + } else { + # save all the other packages into the @more_removal list to + # be removed at the second state. Note that if a package has + # already been removed due to a removal of a collection + # it will be marked as such in %already_removed and not tried again + push @more_removal, $pkg; + } + } + } + foreach my $pkg (@more_removal) { + if (!defined($already_removed{$pkg})) { + if ($opt_dry) { + print "Removing $pkg\n"; + } else { + $ret |= &remove_package($pkg, $localtlpdb, $opt_force); + } + } + } + if (!$opt_dry) { + $localtlpdb->save; + } +} else { + die "Unknown action: $action"; +} + +if ($opt_dry) { + # stop here, don't do any postinstall actions + exit(0); +} + +if ($ret & 0x0001) { + print "running mktexlsr\n"; + system("mktexlsr"); +} +my $TEXMFSYSVAR = `kpsewhich -var-value=TEXMFSYSVAR`; +chomp $TEXMFSYSVAR; +my $TEXMFLOCAL = `kpsewhich -var-value=TEXMFLOCAL`; +chomp $TEXMFLOCAL; +if ($ret & 0x0010) { + print "regenerating updmap.cfg\n"; + TeXLive::TLUtils::create_updmap ($localtlpdb, + "$TEXMFSYSVAR/web2c/updmap.cfg", + "$TEXMFLOCAL/web2c/updmap-local.cfg"); + # system("texconfig-sys", "generate", "updmap"); + print "running updmap-sys\n"; + system("updmap-sys"); +} +if ($ret & 0x0100) { + print "regenerating fmtutil.cnf\n"; + TeXLive::TLUtils::create_fmtutil($localtlpdb, + "$TEXMFSYSVAR/web2c/fmtutil.cnf", + "$TEXMFLOCAL/web2c/fmtutil-local.cnf"); + # system("texconfig-sys", "generate", "fmtutil"); + print "running fmtutil-sys --missing\n"; + system("fmtutil-sys", "--missing"); +} +if ($ret & 0x1000) { + print "regenerating language.dat\n"; + TeXLive::TLUtils::create_language($localtlpdb, + "$TEXMFSYSVAR/tex/generic/config/language.dat", + "$TEXMFLOCAL/tex/generic/config/language-local.dat"); + # system("texconfig-sys", "generate", "language"); + print "running fmtutil-sys --byhyphen language.dat\n"; + system("fmtutil-sys", "--byhyphen", "language.dat"); +} + +exit(0); + +# +# remove_package removes a single package with all files (including the +# tlpobj files) and the entry from the tlpdb. +# +sub remove_package { + my ($pkg, $localtlpdb, $force) = @_; + my $tlp = $localtlpdb->get_package($pkg); + my $ret = 0; + if (!defined($tlp)) { + print "Package $pkg not present, cannot remove it!\n"; + } else { + if (!$force) { + # do some checking + my @needed = $localtlpdb->needed_by($pkg); + if (@needed) { + print "Not removing $pkg, is referenced in @needed!\n"; + return $ret; + } + } + print "remove package $pkg\n"; + # we have to chdir to $localtlpdb->root + my $Master = $localtlpdb->root; + chdir ($Master) || die "chdir($Master) failed: $!"; + my @files = $tlp->all_files; + # also remove the .tlpobj file + push @files, "tlpkg/tlpobj/$pkg.tlpobj"; + # and the ones from src/doc splitting + if (-r "tlpkg/tlpobj/$pkg.src.tlpobj") { + push @files, "tlpkg/tlpobj/$pkg.src.tlpobj"; + } + if (-r "tlpkg/tlpobj/$pkg.doc.tlpobj") { + push @files, "tlpkg/tlpobj/$pkg.doc.tlpobj"; + } + my @removals = &removed_dirs (@files); + foreach my $entry (@files) { + unlink $entry; + } + foreach my $entry (@removals) { + rmdir $entry; + } + $localtlpdb->remove_package($pkg); + $ret |= 0x0001; # call mktexlsr + foreach my $e ($tlp->executes) { + if ($e =~ m/^add/) { + $ret |= 0x0010; + } elsif ($e =~ m/^BuildFormat/) { + $ret |= 0x0100; + } elsif ($e =~ m/^BuildLanguageDat/) { + $ret |= 0x1000; + } else { + warn("Unknown execute $e in $pkg"); + } + } + # remove those bin dependencies .ARCH + foreach my $d ($tlp->depends) { + if ($d eq "$pkg.ARCH") { + foreach my $a ($localtlpdb->available_architectures) { + $ret |= &remove_package("$pkg.$a", $localtlpdb, $force); + } + } + } + # should we save at each removal??? + # advantage: the tlpdb actually reflects what is installed + # disadvantage: removing a collection calls the save routine several times + # still I consider it better that the tlpdb is in a consistent state + $localtlpdb->save; + } + return $ret; +} + + +# +# return all the directories from which all content will be removed +# +# idea: +# - create a hashes by_dir listing all files that should be removed +# by directory, i.e., key = dir, value is list of files +# - for each of the dirs (keys of by_dir and ordered deepest first) +# check that all actually contained files are removed +# and all the contained dirs are in the removal list. If this is the +# case put that directory into the removal list +# - return this removal list +# +sub removed_dirs +{ + my (@files) = @_; + my %removed_dirs; + my %by_dir; + + # construct hash of all directories mentioned, values are lists of the + # files/dirs in that directory. + for my $f (@files) { + my $abs_f = abs_path ($f); + die ("oops, no abs_path($f) from " . `pwd`) unless $abs_f; + (my $d = $abs_f) =~ s,/[^/]*$,,; + my @a = exists $by_dir{$d} ? @{$by_dir{$d}} : (); + push (@a, $abs_f); + $by_dir{$d} = \@a; + } + + # for each of our directories, see if we are removing everything in + # the directory. if so, return the directory; else return the + # individual files. + for my $d (reverse sort keys %by_dir) { + opendir (DIR, $d) || die "opendir($d) failed: $!"; + my @dirents = readdir (DIR); + closedir (DIR) || warn "closedir($d) failed: $!"; + + # initialize test hash with all the files we saw in this dir. + # (These idioms are due to "Finding Elements in One Array and Not + # Another" in the Perl Cookbook.) + my %seen; + my @rmfiles = @{$by_dir{$d}}; + @seen{@rmfiles} = (); + + # see if everything is the same. + my $cleandir = 1; + for my $dirent (@dirents) { + next if $dirent =~ /^\.(\.|svn)?$/; # ignore . .. .svn + my $item = "$d/$dirent"; # prepend directory for comparison + if ( + ((-d $item) && (defined($removed_dirs{$item}))) + || + (exists $seen{$item}) + ) { + # do nothing + } else { + $cleandir = 0; + last; + } + } + if ($cleandir) { + $removed_dirs{$d} = 1; + } + } + return keys %removed_dirs; +} + +__END__ + +=head1 NAME + +tl-package-manager - the TeX Live Package Manager + +=head1 SYNOPSIS + +tl-package-manager ACTION [OPTION] ... [PACKAGE] ... + +=head1 ACTION + +=over 8 + +=item B<install> + +Install all packages given on the cmdline. By default this installs all +dependencies, too. See below for the option B<-no-depends>. + +=item B<update> + +Update all packages if newer ones are available + +=item B<remove> + +Remove all packages given on the cmdline. Removing a collection will +remove all dependencies, too, unless with option B<-no-depends>. + +Removing a package which is referenced as a dependency in another +collection or scheme will not succeed unless the B<-force> option is given. + +=item B<search> + +Search the names and short descriptions of all locally installed packages +for the given argument (interpreted as regexp). + +=item B<globalsearch> + +Search the names and short descriptions of all packages available on +the install media. + +=back + +=head1 OPTIONS + +=over 8 + +=item B<-location> I<location> + +Overrides the location as found in the tlpdb of the installation. Specifies +the location from which packages should be installed or updated. + +=item B<-no-depends> + +Do not install dependencies. If this option is not given installing +a package will check that all dependencies of this package are fulfilled. + +=item B<-force> + +When removing a package or collection would invalidate a dependency +of another collection/scheme, the package will not be removed and +a warning issued. With this options the package will be removed +unconditionally. Use with care. + +=item B<-dry-run> + +Do not actually install or remove anything, just echo what would be +done. + +=item B<-netarchive> I<dir> + +Overrides the default settings for netarchive. Should be used with care. + +=item B<-diskarchive> I<dir> + +Overrides the default settings for diskarchive. Should be used with care. + +=back + +The standard options C<-help/-h/-?> and C<-debug> are also accepted. + +=head1 DESCRIPTION + +The B<tl-package-manager> allows to install and update packages after +an initial installation. + +=head1 AUTHORS AND COPYRIGHT + +This script and its documentation were written for the TeX Live +distribution (L<http://tug.org/texlive>) and both are licensed under the +GNU General Public License Version 2 or later. + +=cut + +### Local Variables: +### perl-indent-level: 2 +### tab-width: 2 +### indent-tabs-mode: nil +### End: +# vim:set tabstop=2 expandtab: # diff --git a/Master/tlpkg/TeXLive/TLConfig.pm b/Master/tlpkg/TeXLive/TLConfig.pm index b2d359609e6..77ab65d8d6a 100644 --- a/Master/tlpkg/TeXLive/TLConfig.pm +++ b/Master/tlpkg/TeXLive/TLConfig.pm @@ -8,7 +8,7 @@ package TeXLive::TLConfig; BEGIN { use Exporter (); - use vars qw( @ISA @EXPORT_OK ); + use vars qw( @ISA @EXPORT_OK @EXPORT ); @ISA = qw(Exporter); @EXPORT_OK = qw( @MetaCategories @@ -21,7 +21,12 @@ BEGIN { $InfraLocation $DatabaseName $BlockSize + $NetArchive + $DiskArchive + $TeXLiveURL + $MaxBinOnCD ); + @EXPORT = @EXPORT_OK; } # Meta Categories do not ship files, but call only for other packages @@ -47,6 +52,13 @@ our $BlockSize = 4096; # the way we package things on the web our $DefaultContainerExtension = "tar.lzma"; +our $NetArchive = "tlpkg"; +our $DiskArchive = "archive"; +our $TeXLiveURL = 'ftp://tug.org/texlive/tlnet/tldev'; +#our $TeXLiveURL = 'http://10.0.2.2/norbert/tltesting'; + +our $MaxBinOnCD = 7; + 1; @@ -102,6 +114,17 @@ etc) relative to the root of the installation. The assumed block size, currently 4k. +=item C<$TeXLive::TLConfig::NetArchive> +=item C<$TeXLive::TLConfig::DiskArchive> +=item C<$TeXLive::TLConfig::TeXLiveURL> + +These values specify where to find packages. + +=item <$TeXLive::TLConfig::MaxBinOnCD> + +The maximum number of binary systems on the CD. This number must be +smaller than the number of binaries available from the network. + =back =head1 SEE ALSO diff --git a/Master/tlpkg/TeXLive/TLMedia.pm b/Master/tlpkg/TeXLive/TLMedia.pm new file mode 100644 index 00000000000..8d38ff3c184 --- /dev/null +++ b/Master/tlpkg/TeXLive/TLMedia.pm @@ -0,0 +1,420 @@ +# $Id: TLMedia.pm 6947 2008-03-13 00:40:12Z karl $ +# TeXLive::TLMedia.pm - module for accessing TeX Live Media +# Copyright 2008 Norbert Preining +# +# This file is licensed under the GNU General Public License version 2 +# or any later version. +# + +package TeXLive::TLMedia; + +use TeXLive::TLConfig; +use TeXLive::TLUtils qw(tllog copy win32 dirname mkdirhier conv_to_win_path basename); +use TeXLive::TLPDB; +use Cwd qw/abs_path/; + +sub shortnew +{ + my ($class, $location) = @_; + my $media; + # of no argument is given we assume NET and default URL + $location = "$TeXLiveURL" unless (defined($location)); + # do media autodetection + if ($location =~ m,http://|ftp://,) { + $media = 'NET'; + } else { + if (-d "$location/texmf/web2c") { + $media = 'DVD'; + } elsif (-d "$location/$DiskArchive") { + $media = 'CD'; + } else { + die ("Cannot find the correct media for $location, please specify!"); + } + } + my $database; + if ($media eq 'NET') { + $database = "$location/$NetArchive/texlive.pkgver"; + open(WGET, "wget -q --output-document=- $database|") or + tllog($::LOG_NORMAL, "Cannot get texlive.pkgver the net!\n"); + } elsif ($media eq 'CD') { + $database = "$location/$DiskArchive/texlive.pkgver"; + open(WGET, "<$database") or + tllog($::LOG_NORMAL, "Cannot get texlive.pkgver from CD!\n"); + } else { + $database = "$location/$InfraLocation/texlive.pkgver"; + open(WGET, "<$database") or + tllog($::LOG_NORMAL, "Cannot get texlive.pkgver from DVD!\n"); + } + my %revs; + my @platforms; + while (<WGET>) { + chop; + my $line=$_; + my ($pkg, $rev) = split " ", $line; + $revs{$pkg} = $rev; + if ($rev == -1) { + push @platforms, $pkg; + } + } + $self->{'media'} = $media; + $self->{'location'} = $location; + %{ $self->{'pkgrevs'} } = %revs; + @{ $self->{'systems'} } = @platforms; + bless $self, $class; + return $self; +} + +sub new +{ + my ($class, $location) = @_; + my $media; + # of no argument is given we assume NET and default URL + $location = "$TeXLiveURL" unless (defined($location)); + # do media autodetection + if ($location =~ m,http://|ftp://,) { + $media = 'NET'; + } else { + if (-d "$location/texmf/web2c") { + $media = 'DVD'; + } elsif (-d "$location/$DiskArchive") { + $media = 'CD'; + } else { + die ("Cannot find the correct media for $location, please specify!"); + } + } + tllog($::LOG_DEBUG, "Loading $location/$InfraLocation/$DatabaseName ...\n"); + my $tlpdb = TeXLive::TLPDB->new(root => "$location"); + my (@all_c, @std_c, @lang_c, @lang_doc_c); + my (@schemes); + my %revs; + foreach my $pkg ($tlpdb->list_packages) { + my $tlpobj = $tlpdb->{'tlps'}{$pkg}; + $revs{$tlpobj->name} = $tlpobj->revision; + if ($tlpobj->category eq "Collection") { + push @all_c, $pkg; + if ($pkg =~ /collection-lang/) { + push @lang_c, $pkg; + } elsif ($pkg =~ /documentation/) { + if ($pkg =~ /documentation-base/) { + push @std_c, $pkg; + } else { + push @lang_doc_c, $pkg; + } + } else { + push @std_c, $pkg; + } + } elsif ($tlpobj->category eq "Scheme") { + push @schemes, $pkg; + } + } + my (@systems); + @systems = $tlpdb->available_architectures; + $self->{'media'} = $media; + $self->{'location'} = $location; + $self->{'tlpdb'} = $tlpdb; + $self->{'release'} = $tlpdb->config_release; + @{ $self->{'all_collections'} } = @all_c; + @{ $self->{'std_collections'} } = @std_c; + @{ $self->{'lang_collections'} } = @lang_c; + @{ $self->{'lang_doc_collections'} } = @lang_doc_c; + @{ $self->{'schemes'} } = @schemes; + @{ $self->{'systems'} } = @systems; + %{ $self->{'pkgrevs'} } = %revs; + bless $self, $class; + return $self; +} + +# returns 0 for error +# otherwise a bitmap which specifies what commands have to be run +# always: 0x0001 mktexlsr +# addMap: 0x0010 updmap-sys +# BuildFormat: 0x0100 fmtutil-sys --missing +# BuildLanguageDat: 0x1000 fmtutil-sys --by-hyphen language.dat +# +sub install_package { + my ($self, $pkg, $totlpdb, $nodepends, $fallbackmedia) = @_; + my $fromtlpdb = $self->tlpdb; + my $ret; + die("TLMedia not initialized, cannot find tlpdb!") unless (defined($fromtlpdb)); + my $tlpobj = $fromtlpdb->get_package($pkg); + if (!defined($tlpobj)) { + if (defined($fallbackmedia)) { + if ($ret = $fallbackmedia->install_package($pkg,$totlpdb)) { + tllog($::LOG_DEBUG, "installed $pkg from fallback"); + return $ret; + } else { + tllog($::LOG_NORMAL, "couldn't find $pkg"); + return 0; + } + } else { + tllog($::LOG_NORMAL, "couldn't find $pkg"); + return 0; + } + } else { + my $container_src_split = $fromtlpdb->config_src_container; + my $container_doc_split = $fromtlpdb->config_doc_container; + # get options about src/doc splitting from $totlpdb + my $opt_src = $totlpdb->option_srcfiles; + my $opt_doc = $totlpdb->option_docfiles; + tllog($::LOG_NORMAL, "Installing: $pkg\n"); + foreach my $h (@::install_packages_hook) { + &$h("Installing: $package"); + } + my $container; + my @installfiles; + my $location = $self->location; + foreach ($tlpobj->runfiles) { + s!^!$location/!; + push @installfiles, $_; + } + foreach ($tlpobj->allbinfiles) { + s!^!$location/!; + push @installfiles, $_; + } + if ($opt_src) { + foreach ($tlpobj->srcfiles) { + s!^!$location/!; + push @installfiles, $_; + } + } + if ($opt_doc) { + foreach ($tlpobj->docfiles) { + s!^!$location/!; + push @installfiles, $_; + } + } + my $media = $self->media; + if ($media eq 'DVD') { + $container = \@installfiles; + } elsif ($media eq 'CD') { + if (-r "$location/$DiskArchive/$pkg.zip") { + $container = "$location/$DiskArchive/$pkg.zip"; + } elsif (-r "$location/$DiskArchive/$pkg.tar.lzma") { + $container = "$location/$DiskArchive/$pkg.tar.lzma"; + } else { + # for now only warn and return, should (?) be die!? + warn "Cannot find a package $pkg (.zip or .lzma) in $location/$DiskArchive\n"; + next; + } + } elsif (&media eq 'NET') { + $container = "$location/$NetArchive/$pkg.$DefaultContainerExtension"; + } + $self->_install_package($container,\@installfiles,$totlpdb); + # if we are installing from CD or NET we have to fetch the respective + # source and doc packages $pkg.source and $pkg.doc and install them, too + if (($media eq 'NET') || ($media eq 'CD')) { + # we install split containers under the following conditions: + # - the container were split generated + # - src/doc files should be installed + # - the package is not already a split one (like .i386-linux) + # - there are actually src/doc files present + if ($container_src_split && $opt_src && + ($pkg !~ m/\./) && $tlpobj->srcfiles) { + my $srccontainer = $container; + $srccontainer =~ s/(.tar.lzma|.zip)/.source$1/; + $self->_install_package($srccontainer,\@installfiles,$totlpdb); + } + if ($container_doc_split && $opt_doc && + ($pkg !~ m/\./) && $tlpobj->docfiles) { + my $doccontainer = $container; + $doccontainer =~ s/(.tar.lzma|.zip)/.doc$1/; + $self->_install_package($doccontainer,\@installfiles,$totlpdb); + } + } + # we don't want to have wrong information in the tlpdb, so remove the + # src/doc files if they are not installed ... + if (!$opt_src) { + $tlpobj->clear_srcfiles; + } + if (!$opt_doc) { + $tlpobj->clear_docfiles; + } + $totlpdb->add_tlpobj($tlpobj); + $totlpdb->save; + # compute the return value + $ret |= 0x0001; # mktexlsr + foreach my $e ($tlpobj->executes) { + if ($e =~ m/^add/) { + $ret |= 0x0010; + } elsif ($e =~ m/^BuildFormat/) { + $ret |= 0x0100; + } elsif ($e =~ m/^BuildLanguageDat/) { + $ret |= 0x1000; + } else { + warn("Unknown execute $e in $pkg"); + } + } + # now install all the depends if they are not already present + if (!$nodepends) { + foreach my $d ($tlpobj->depends) { + if ($d =~ m/^(.*)\.ARCH$/) { + my $foo = $1; + foreach my $a ($totlpdb->available_architectures) { + if (!defined($totlpdb->get_package("$foo.$a"))) { + $ret |= $self->install_package("$foo.$a", $totlpdb, $nodepends, $fallbackmedia); + } + } + } elsif ($d =~ m/^(.*).win32$/) { + # install only of win32 is under the available archs + if (TeXLive::TLUtils::member("win32",$totlpdb->available_architectures)) { + $ret |= $self->install_package($d, $totlpdb, $nodepends, $fallbackmedia); + } + } else { + if (!defined($totlpdb->get_package($d))) { + # we have to install it! + $ret |= $self->install_package($d, $totlpdb, $nodepends, $fallbackmedia); + } + } + } + } + return $ret; + } +} + +sub _install_package { + sub mysystem { + my $cmd = shift; + # print "DEBUG: $cmd\n"; + system("$cmd"); + } + my ($self, $what, $filelistref, $totlpdb) = @_; + my $buffer; + my $offset; + my $blocksize=2048; + my $media = $self->media; + my $target = $totlpdb->root; + + $blocksize=4096 if ($media eq 'NET'); + + my @filelist = @$filelistref; + + my $bindir = "$target/tlpkg/installer"; + my $platform = $totlpdb->option_platform; + # unix defaults + my $wget = "wget"; + my $lzmadec = "$bindir/lzmadec.$platform"; + my $tar = "tar"; + if (win32()) { + $wget = conv_to_win_path("$bindir/wget.exe"); + #$tar = conv_to_win_path("$bindir/bsdtar.exe"); + # try Akira's tar.exe + $tar = conv_to_win_path("$bindir/tar.exe"); + $lzmadec = conv_to_win_path("$lzmadec"); + $target =~ s!/!\\!g; + } + if (ref $what) { + # we are getting a ref to a list of files, so install from DVD + foreach my $file (@$what) { + # @what is taken, not @filelist! + # is this still needed? + my $dn=dirname($file); + mkdirhier("$target/$dn"); + copy "$file", "$target/$dn"; + } + } elsif ($what =~ m,http://|ftp://,) { + # we are installing from the NET + # currently the list of file @filelist is NOT EVALUATED!!! + if (win32()) { + # we need temporary files here + # tmpdir is $target/temp + my $fn = basename($what); + my $tarfile = $fn; + $tarfile =~ s/\.lzma$//; + mkdirhier("$target/temp"); + tllog($::LOG_DEBUG, "Downloading $what to $target\\temp\\$fn\n"); + tllog($::LOG_DEBUG, `$wget --tries=2 --timeout=60 -q -O \"$target\\temp\\$fn\" \"$what\" 2>\&1`); + tllog($::LOG_DEBUG, "Un-lzmaing $target\\temp\\$fn to $target\\temp\\$tarfile\n"); + #tllog($::LOG_DEBUG, `type \"$target\\temp\\$fn\" | $lzmadec > \"$target\\temp\\$tarfile\" 2>&1`); + tllog($::LOG_DEBUG, `$lzmadec < \"$target\\temp\\$fn\" > \"$target\\temp\\$tarfile\" 2>&1`); + tllog($::LOG_DEBUG, "Unpacking temp\\$tarfile\n"); + tllog($::LOG_DEBUG, `pushd \"$target\" & $tar -xf \"temp\\$tarfile\" 2>&1`); + unlink("$target/temp/$tarfile", "$target/temp/$fn"); + } else { + tllog($::LOG_DEBUG, "downloading/unlzma-ing/unpacking $what\n"); + tllog($::LOG_NORMAL, `$wget --tries=2 --timeout=60 -q -O- \"$what\"|\"$lzmadec\"|$tar -xf - -C \"$target\"`); + } + } elsif ($what =~ m,\.tar.lzma$,) { + if (win32()) { + my $fn = basename($what); + my $tarfile = $fn; + $tarfile =~ s/\.lzma$//; + mkdirhier("$target/temp"); + tllog($::LOG_DEBUG, "Un-lzmaing $what to $target\\temp\\$tarfile\n"); + tllog($::LOG_DEBUG, `$lzmadec < \"$what\" > \"$target\\temp\\$tarfile\" 2>&1`); + tllog($::LOG_DEBUG, "Unpacking temp\\$tarfile\n"); + tllog($::LOG_DEBUG, `pushd \"$target\" & $tar -xf \"temp\\$tarfile\" 2>&1`); + unlink("$target/temp/$tarfile"); + } else { + tllog($::LOG_DEBUG, "downloading/unlzma-ing/unpacking $what\n"); + tllog($::LOG_DEBUG, `cat \"$what\"|\"$lzmadec\"|$tar -xf - -C \"$target\" 2>&1`); + } + } else { + die "Don't know how to install $what!\n"; + } +} + + + +# member access functions +# +sub media { my $self = shift ; return $self->{'media'}; } +sub location { my $self = shift ; return $self->{'location'}; } +sub tlpdb { my $self = shift ; return $self->{'tlpdb'}; } +sub release { my $self = shift ; return $self->{'release'}; } +sub all_collections { my $self = shift; return @{ $self->{'all_collections'} }; } +sub std_collections { my $self = shift; return @{ $self->{'std_collections'} }; } +sub lang_collections { my $self = shift; return @{ $self->{'lang_collections'} }; } +sub lang_doc_collections { my $self = shift; return @{ $self->{'lang_doc_collections'} }; } +sub schemes { my $self = shift; return @{ $self->{'schemes'} }; } +sub systems { my $self = shift; return @{ $self->{'systems'} }; } + +1; + + +__END__ + + +=head1 NAME + +C<TeXLive::TLMedia> -- TeX Live Media module + +=head1 SYNOPSIS + + use TeXLive::TLMedia; + + my $tlnet = TeXLive::TLMedia->new('NET'); + my $tlneo = TeXLive::TLMedia->new('NET','http://www.ctan.org/mirror/tl/'); + my $tlcd = TeXLive::TLMedia->new('CD','/mnt/tl-cd/'); + my $tldvd = TeXLive::TLMedia->new('DVD','/mnt/tl-dvd/'); + +=head1 DESCRIPTION + +missing + +=head1 MEMBER ACCESS FUNCTIONS + +scalars: media, location, tlpdb, release +lists: all_collections, std_collections, lang_collections, lang_doc_collections, +schemes, systems + +=back + +=head1 SEE ALSO + +The modules L<TeXLive::TLConfig>, L<TeXLive::TLUtils>, L<TeXLive::TLPOBJ>, +L<TeXLive::TLPDB>, L<TeXLive::TLTREE>. + +=head1 AUTHORS AND COPYRIGHT + +This script and its documentation were written for the TeX Live +distribution (L<http://tug.org/texlive>) and both are licensed under the +GNU General Public License Version 2 or later. + +=cut + +### Local Variables: +### perl-indent-level: 2 +### tab-width: 2 +### indent-tabs-mode: nil +### End: +# vim:set tabstop=2 expandtab: # diff --git a/Master/tlpkg/TeXLive/TLPDB.pm b/Master/tlpkg/TeXLive/TLPDB.pm index 696342ecf18..19df28c30e6 100644 --- a/Master/tlpkg/TeXLive/TLPDB.pm +++ b/Master/tlpkg/TeXLive/TLPDB.pm @@ -28,6 +28,8 @@ C<TeXLive::TLPDB> -- A database of TeX Live Packages $tlpdb->available_architectures(); $tlpdb->add_tlpcontainer($pkg, $ziploc [, $archrefs [, $dest ]] ); $tlpdb->add_tlpobj($tlpobj); + $tlpdb->needed_by($pkg); + $tlpdb->remove_package($pkg); $tlpdb->get_package("packagename"); $tlpdb->list_packages; $tlpdb->find_file("filename"); @@ -51,8 +53,8 @@ C<TeXLive::TLPDB> -- A database of TeX Live Packages =cut use TeXLive::TLConfig qw($CategoriesRegexp $DefaultCategory $InfraLocation - $DatabaseName); -use TeXLive::TLUtils qw(dirname mkdirhier tllog); + $DatabaseName $MetaCategoriesRegexp); +use TeXLive::TLUtils qw(dirname mkdirhier tllog member); use TeXLive::TLPOBJ; my $_listdir; @@ -103,6 +105,59 @@ sub add_tlpobj { =pod +=item C<< $tlpdb->needed_by($pkg) >> + +Returns an array of package names depending on $pkg. + +=cut + +sub needed_by { + my ($self,$pkg) = @_; + my @ret; + # we only check collections and schemes ... + foreach my $p ($self->list_packages) { + my $tlp = $self->get_package($p); + if ($tlp->category =~ m/$MetaCategoriesRegexp/) { + foreach my $d ($tlp->depends) { + if ($d =~ m/^(.*)\.win32$/) { + if (member("win32", $self->available_architectures)) { + if ($d eq $pkg) { + push @ret, $p; + last; + } + } + } else { + if ($d eq $pkg) { + push @ret, $p; + last; + } + } + } + } + } + return @ret; +} + +=pod + +=item C<< $tlpdb->remove_package($pkg) >> + +Remove the package named C<$pkg> from the tlpdb. Gives a warning if the +package is not present + +=cut + +sub remove_package { + my ($self,$pkg) = @_; + if (defined($self->{'tlps'}{$pkg})) { + delete $self->{'tlps'}{$pkg}; + } else { + warn "Cannot find package $pkg for removal in tlpdb!"; + } +} + +=pod + =item C<< $tlpdb->from_file($filename) >> The C<from_file> function initializes the C<TLPDB> in case the @@ -198,7 +253,7 @@ sub available_architectures { my $self = shift; my @packs = $self->list_packages; my @archs; - map { s@^$tltree/@@ ; push @nf, $_; } @files; + # map { s@^$tltree/@@ ; push @nf, $_; } @files; map { s/^bin-tex\.// ; push @archs, $_ ; } grep(/^bin-tex\.(.*)$/, @packs); return @archs; } @@ -602,6 +657,8 @@ sub config_src_container { return 0; } +=pod + =item C<< $tlpdb->config_doc_container >> Returns 1 if the the texlive config option for doc files splitting on @@ -621,6 +678,8 @@ sub config_doc_container { return 0; } +=pod + =item C<< $tlpdb->config_doc_container >> Returns the currently set default container format. See Options below. @@ -639,6 +698,8 @@ sub config_container_format { return ""; } +=pod + =item C<< $tlpdb->config_release >> Returns the currently set release. See Options below. @@ -659,6 +720,54 @@ sub config_release { =pod +=item C<< $tlpdb->option_XXXXX >> + +Need to be documented + +=cut + +sub _option_value { + my ($self,$key) = @_; + if (defined($self->{'tlps'}{'00texlive-installation.config'})) { + foreach my $d ($self->{'tlps'}{'00texlive-installation.config'}->depends) { + if ($d =~ m!^$key/(.*)$!) { + return "$1"; + } + } + return ""; + } + return; +} +sub _option_setting { + my ($self,$key) = @_; + if (defined($self->{'tlps'}{'00texlive-installation.config'})) { + foreach my $d ($self->{'tlps'}{'00texlive-installation.config'}->depends) { + if ($d =~ m!^$key$!) { + return 1; + } + } + return 0; + } + return; +} + +sub option_symlinks { my $self = shift; return $self->_option_setting("symlinks"); } +sub option_docfiles { my $self = shift; return $self->_option_setting("docfiles"); } +sub option_srcfiles { my $self = shift; return $self->_option_setting("srcfiles"); } +sub option_formats { my $self = shift; return $self->_option_setting("formats"); } +sub option_letter { my $self = shift; return $self->_option_setting("letter"); } +sub option_location { my $self = shift; return $self->_option_value("location"); } +sub option_TEXDIR { my $self = shift; return $self->_option_value("TEXDIR"); } +sub option_TEXMFSYSVAR { my $self = shift; return $self->_option_value("TEXMFSYSVAR"); } +sub option_TEXMFLOCAL { my $self = shift; return $self->_option_value("TEXMFLOCAL"); } +sub option_TEXMFHOME { my $self = shift; return $self->_option_value("TEXMFHOME"); } +sub option_sys_bin { my $self = shift; return $self->_option_value("sys_bin"); } +sub option_sys_man { my $self = shift; return $self->_option_value("sys_man"); } +sub option_sys_info { my $self = shift; return $self->_option_value("sys_info"); } +sub option_platform { my $self = shift; return $self->_option_value("platform"); } + +=pod + =item C<< $tlpdb->fmtutil_cnf_lines >> The function C<fmtutil_cnf_lines> returns the list of a fmtutil.cnf file diff --git a/Master/tlpkg/TeXLive/TLPSRC.pm b/Master/tlpkg/TeXLive/TLPSRC.pm index efa390a2194..c1cf75656a1 100644 --- a/Master/tlpkg/TeXLive/TLPSRC.pm +++ b/Master/tlpkg/TeXLive/TLPSRC.pm @@ -82,7 +82,7 @@ sub from_file if ($line =~ /^ /) { die "$srcfile: continuation line not allowed in tlpsrc: $line\n"; } - if ($line =~ /^name\s*([-\w]+(\.win32)?|00texlive\..*)$/) { + if ($line =~ /^name\s*([-\w]+(\.win32)?|00texlive\..*|0texlive\..*)$/) { $name = "$1"; $started && die("$srcfile: tlpsrc cannot have two name directives"); $started = 1; diff --git a/Master/tlpkg/TeXLive/TLUtils.pm b/Master/tlpkg/TeXLive/TLUtils.pm index a96df736414..14fbc8bc8cc 100644 --- a/Master/tlpkg/TeXLive/TLUtils.pm +++ b/Master/tlpkg/TeXLive/TLUtils.pm @@ -51,7 +51,7 @@ C<TeXLive::TLUtils> -- utilities used in the TeX Live infrastructure TeXLive::TLUtils::create_fmtutil($tlpdb,$dest,$localconf); TeXLive::TLUtils::create_updmap($tlpdb,$dest,$localconf); TeXLive::TLUtils::create_language($tlpdb,$dest,$localconf); - TeXLive::TLUtils::install_packages($from_tlpdb,$to_tlpdb,@list); + TeXLive::TLUtils::install_packages($from_tlpdb,$to_tlpdb,$what, $netarchsref, $opt_src, $opt_doc)>); TeXLive::TLUtils::install_package($what, $filelistref, $target, $platform); =head2 Miscellaneous @@ -104,14 +104,13 @@ BEGIN { &member &kpsewhich "ewords + &conv_to_win_path ); @EXPORT = qw(tllog); } -use TeXLive::TLConfig qw($DefaultContainerExtension); - - +use TeXLive::TLConfig; =pod @@ -541,10 +540,10 @@ sub install_packages { if (&media eq 'DVD') { $container = \@installfiles; } elsif (&media eq 'CD') { - if (-r "$::installerdir/$::diskarchive/$package.zip") { - $container = "$::installerdir/$::diskarchive/$package.zip"; - } elsif (-r "$::installerdir/$::diskarchive/$package.tar.lzma") { - $container = "$::installerdir/$::diskarchive/$package.tar.lzma"; + if (-r "$::installerdir/$DiskArchive/$package.zip") { + $container = "$::installerdir/$DiskArchive/$package.zip"; + } elsif (-r "$::installerdir/$DiskArchive/$package.tar.lzma") { + $container = "$::installerdir/$DiskArchive/$package.tar.lzma"; } else { # ok, it could be a binary package which should be installed from # the net @@ -552,19 +551,19 @@ sub install_packages { foreach my $a (@$netarchs) { if ($package =~ m/\.$a$/) { # ok this is a binary we should install from the net - $container = "$::texlive_url/$::netarchive/$package.$DefaultContainerExtension"; + $container = "$TeXLiveURL/$NetArchive/$package.$DefaultContainerExtension"; $donefromnet = 1; last; } } if (!$donefromnet) { # for now only warn and return, should (?) be die!? - warn "Cannot find a package $package (.zip or .lzma) in $::installerdir/$::diskarchive\n"; + warn "Cannot find a package $package (.zip or .lzma) in $::installerdir/$DiskArchive\n"; next; } } } elsif (&media eq 'NET') { - $container = "$::texlive_url/$::netarchive/$package.$DefaultContainerExtension"; + $container = "$TeXLiveURL/$NetArchive/$package.$DefaultContainerExtension"; } install_package($container,\@installfiles,$totlpdb->root,$vars{'this_platform'}); # if we are installing from CD or NET we have to fetch the respective @@ -704,7 +703,6 @@ sub install_package { } } - sub install_package_old { # either a list of files or a name of one .zip or .tar.lzma file. my @what=@_; @@ -734,7 +732,7 @@ sub install_package_old { copy "$file", "$target/$dn"; } } elsif (&media eq 'CD') { - my $package="$::installerdir/$::diskarchive/$what[0]"; + my $package="$::installerdir/$DiskArchive/$what[0]"; open IN, "$package", or warn "Can't open '$package': $!\n" or die "Can't open '$package': $!\n"; binmode IN; @@ -755,7 +753,7 @@ sub install_package_old { close OUT; close IN; } elsif (&media eq 'NET') { - my $package="$::texlive_url/$::netarchive/$what[0]"; + my $package="$TeXLiveURL/$NetArchive/$what[0]"; system "$wget $package|$lzmadec|$tar $target"; } else { die "This can't happen."; @@ -783,7 +781,7 @@ CD/DVD. sub media { unless (defined $::_media_) { - if (-d "$::installerdir/$::diskarchive") { + if (-d "$::installerdir/$DiskArchive") { $::_media_='CD'; } elsif (-d "$::installerdir/texmf/web2c") { $::_media_='DVD'; @@ -826,7 +824,7 @@ sub architectures_available { my @dir; my @platforms; if (&media eq "CD") { - opendir DIR, "$::installerdir/$::diskarchive"; + opendir DIR, "$::installerdir/$DiskArchive"; @dir=readdir DIR; chomp @dir; for (@dir) { @@ -855,7 +853,7 @@ sub architectures_available { The function C<additional_architectures_available_from_net> returns a list of additional platforms supported by the TeX Live server. It -downloads the file C<$::texlive_url/$::netarchive/texlive.pkgver> and +downloads the file C<$TeXLiveURL/$NetArchive/texlive.pkgver> and creates a new object c<$::tlpdb_netbin>. The argument is a reference of the global C<%vars> hash. @@ -864,7 +862,7 @@ the global C<%vars> hash. sub additional_architectures_available_from_net { my $vars=shift; my @platforms; - my $database="$::texlive_url/$::netarchive/texlive.pkgver"; + my $database="$TeXLiveURL/$NetArchive/texlive.pkgver"; tllog($::LOG_NORMAL, "Loading '$database' ...\n"); my $wget = "wget"; @@ -1108,13 +1106,20 @@ writing permissions. sub texdir_check { my ($texdir) = shift; # PATH/texlive/2008 - return 1 if (win32()); my $texdirparent = dirname($texdir); # PATH/texlive my $texdirpparent = dirname($texdirparent); # PATH - if ( (-w $texdirpparent) || - ( (-d $texdirparent) && (-w $texdirparent) ) || - ( (-d $texdir) && (-w $texdir) ) ) { - return 1; + if (win32()) { + if ( (TeXLive::TLWinGoo::dir_writable($texdirpparent)) || + ( (-d $texdirparent) && (TeXLive::TLWinGoo::dir_writable($texdirparent)) ) || + ( (-d $texdir) && (TeXLive::TLWinGoo::dir_writable($texdir)) ) ) { + return 1; + } + } else { + if ( (-w $texdirpparent) || + ( (-d $texdirparent) && (-w $texdirparent) ) || + ( (-d $texdir) && (-w $texdir) ) ) { + return 1; + } } return 0; } diff --git a/Master/tlpkg/bin/tl-make-install-pkg b/Master/tlpkg/bin/tl-make-install-pkg index 18396e5615d..dcb376f3bce 100755 --- a/Master/tlpkg/bin/tl-make-install-pkg +++ b/Master/tlpkg/bin/tl-make-install-pkg @@ -112,8 +112,13 @@ die("Cannot find tlpdb in $installerdir!\n") unless defined($tlpdb); my $tlp = $tlpdb->get_package("00texlive.installer"); die("Cannot find package 00texlive.installer in ${installerdir}'s texlive.tlpdb\n") unless defined($tlp); +my $tlpinfra = $tlpdb->get_package("texlive-infra"); +die("Cannot find package texlive-infra in ${installerdir}'s texlive.tlpdb\n") unless defined($tlp); + + my @unix; push @unix, $tlp->runfiles; +push @unix, $tlpinfra->runfiles; push @unix, $tlp->docfiles; my %tlpbin = %{$tlp->binfiles}; foreach my $a (keys %tlpbin) { diff --git a/Master/tlpkg/doc/vars-docu.txt b/Master/tlpkg/doc/vars-docu.txt new file mode 100644 index 00000000000..3b869c4e1fc --- /dev/null +++ b/Master/tlpkg/doc/vars-docu.txt @@ -0,0 +1,100 @@ +Documentation of the content of the %vars hash which is the only way to +transport ship information between various installer menus and the main +program. + +1) collections and schemes +-------------------------- +selected collections/schemes + collection-<collection> 0|1 OUT + scheme-<scheme> 0|1 OUT +total number of collections + n_collections_available 84 IN +and the number of collections selected: + n_collections_selected 1 OUT +the selected scheme + selected_scheme scheme-<scheme> OUT + + +2) platforms +------------ +location of the arch + diskbin_<arch-os> 0|1 IN/OUT + netbin_<arch-os> 0|1 IN/OUT +the current one + inst_platform <arch-os> IN +the current platform ??? + this_platform <arch-os> IN +number of systems available in total + n_systems_available 15 IN +number of systems selected + n_systems_selected 3 OUT + + +3) options +---------- +build all formats + option_fmt 0|1 OUT +letter instead of A4 + option_letter 0|1 OUT +install symlinks (on unix) + option_symlinks 0|1 OUT +and the respective destinations for the symlinks + sys_info <path/to/info/dir> OUT + sys_bin /usr/local/bin OUT + sys_man /usr/local/man OUT +do install the doc files + option_doc 0|1 OUT +do install the src files + option_src 0|1 OUT +destination paths + TEXMFSYSVAR /home/norbert/tltest/2008/texmf-var OUT + TEXDIR /home/norbert/tltest/2008 OUT + TEXMFLOCAL /home/norbert/tltest/texmf-local OUT + TEXMFHOME ~/texmf OUT + +4) other stuff ??? +------------------ +total size to be used + total_size 54 DEDUCED +no idea ???? + page 0 + + +NEW LAYOUT +========== + +%MediaData = ( + media => CD|DVD|NET + location => /path/to/master | base-url + release => NNNN + tlpdb => the respective tlpdb + all_collections => [ ... ] + std_collections => [ ... ] + lang_collections => [ ... ] + lang_doc_collections => [ ... ] + schemes => [ ... ] + n_collections => NN + n_schemes => NN + diskbins => [ ... ] + netbins => [ ... ] + n_systems_available => NN (== #(#diskbins u #netbins)) + this_platform => <arch-os> +) + +%vars = ( + systems => [ ... ] # those selected for installation + collections => [ ... ] # those selected for installation + selected_scheme => scheme-<scheme> + option_fmt => 0|1 + option_letter 0|1 OUT + option_symlinks 0|1 OUT + sys_info <path/to/info/dir> OUT + sys_bin /usr/local/bin OUT + sys_man /usr/local/man OUT + option_doc 0|1 OUT + option_src 0|1 OUT + TEXMFSYSVAR /home/norbert/tltest/2008/texmf-var OUT + TEXDIR /home/norbert/tltest/2008 OUT + TEXMFLOCAL /home/norbert/tltest/texmf-local OUT + TEXMFHOME ~/texmf OUT +) diff --git a/Master/tlpkg/installer/install-menu-perltk.pl b/Master/tlpkg/installer/install-menu-perltk.pl index 67dbed6a8e2..169b1388126 100644 --- a/Master/tlpkg/installer/install-menu-perltk.pl +++ b/Master/tlpkg/installer/install-menu-perltk.pl @@ -20,7 +20,6 @@ our @collections_lang; our @collections_lang_doc; our $texlive_release; our $trynet; -our $max_bins_on_CD; our $MENU_INSTALL = 0; our $MENU_ABORT = 1; @@ -35,25 +34,29 @@ require Tk::PNG; use utf8; no utf8; -if ($^O =~ /^MSWin(32|64)$/i) { - # trying to deduce automatically the country code - my $foo = TeXLive::TLWinGoo::reg_country(); - if ($foo) { - $::lang = $foo; - } else { - tllog($::LOG_DEBUG, "Didn't get any usuful code from reg_country: $foo...\n"); - } +if (defined($::opt_lang)) { + $::lang = $::opt_lang; } else { - # we load POSIX and locale stuff - require POSIX; - import POSIX qw/locale_h/; - # now we try to deduce $::lang - my $loc = setlocale(&POSIX::LC_CTYPE); - my ($lang,$area,$codeset); - if ($loc =~ m/^([^_.]*)(_([^.]*))?(\.([^@]*))?(@.*)?$/) { - $lang = defined($1)?$1:""; + if ($^O =~ /^MSWin(32|64)$/i) { + # trying to deduce automatically the country code + my $foo = TeXLive::TLWinGoo::reg_country(); + if ($foo) { + $::lang = $foo; + } else { + tllog($::LOG_DEBUG, "Didn't get any usuful code from reg_country: $foo...\n"); + } + } else { + # we load POSIX and locale stuff + require POSIX; + import POSIX qw/locale_h/; + # now we try to deduce $::lang + my $loc = setlocale(&POSIX::LC_CTYPE); + my ($lang,$area,$codeset); + if ($loc =~ m/^([^_.]*)(_([^.]*))?(\.([^@]*))?(@.*)?$/) { + $lang = defined($1)?$1:""; + } + $::lang = $lang if ($lang); } - $::lang = $lang if ($lang); } my $mw; @@ -138,6 +141,8 @@ my %text = ( title => 'TeX Live 2008 Installation', diskreq => 'disk space required', yes => 'Yes', no => 'No', + notwritable => '(default not writable - please change!)', + changetexdir => '(please change TEXDIR first!)' ); @@ -635,7 +640,7 @@ sub menu_set_pathes_text { if (TeXLive::TLUtils::texdir_check($vars{'TEXDIR'})) { menu_set_text($texdirtext, "$vars{'TEXDIR'}"); } else { - menu_set_text($texdirtext, "(default not writable - please change!)"); + menu_set_text($texdirtext, $text{'notwritable'}); } menu_set_text($texmflocaltext, "$vars{'TEXMFLOCAL'}"); if (-w $vars{'TEXMFSYSVAR'}) { @@ -644,10 +649,10 @@ sub menu_set_pathes_text { if (TeXLive::TLUtils::texdir_check($vars{'TEXDIR'})) { menu_set_text($texmfsysvartext, "$vars{'TEXMFSYSVAR'}"); } else { - menu_set_text($texmfsysvartext, "(please change TEXDIR first!)"); + menu_set_text($texmfsysvartext, $text{'changetexdir'}); } } else { - menu_set_text($texmfsysvartext, "(default not writable - please change!)"); + menu_set_text($texmfsysvartext, $text{'notwritable'}); } menu_set_text($texmfhometext, "$vars{'TEXMFHOME'}"); } diff --git a/Master/tlpkg/installer/install-menu-text.pl b/Master/tlpkg/installer/install-menu-text.pl index 88ed73355e7..c3d01a7a885 100755 --- a/Master/tlpkg/installer/install-menu-text.pl +++ b/Master/tlpkg/installer/install-menu-text.pl @@ -17,7 +17,6 @@ our @collections_lang; our @collections_lang_doc; our $texlive_release; our $trynet; -our $max_bins_on_CD; my $MENU_CONTINUE = -1; our $MENU_INSTALL = 0; @@ -137,10 +136,10 @@ sub binary_menu { } $diskbin=' ' - if (media eq 'CD' and $vars{'n_systems_available'}>$max_bins_on_CD); + if (media eq 'CD' and $vars{'n_systems_available'}>$MaxBinOnCD); foreach my $binary (@binaries) { - if (media eq 'CD' and $vars{'n_systems_available'}>$max_bins_on_CD) { + if (media eq 'CD' and $vars{'n_systems_available'}>$MaxBinOnCD) { $diskbin=$from_net{"$binary"}? "* ":" "; } printf " %s %s %s%-16s %s\n", $keys[$index], @@ -152,7 +151,7 @@ sub binary_menu { "netbin_$binary":"diskbin_$binary"; ++$index; } - if ($vars{'n_systems_available'}<=$max_bins_on_CD ) { + if ($vars{'n_systems_available'}<=$MaxBinOnCD ) { print "\n Binaries for additional systems are available on the DVD.\n" . " If you have network access, try option <N>.\n"; diff --git a/Master/tlpkg/installer/lang/perltk-de b/Master/tlpkg/installer/lang/perltk-de index 0d59792da7d..987b605cf3d 100644 --- a/Master/tlpkg/installer/lang/perltk-de +++ b/Master/tlpkg/installer/lang/perltk-de @@ -1,5 +1,6 @@ # -# german strings for texlive installer +# German strings for texlive installer +# Norbert Preining # text.title: TeX Live 2008 Installation text.custom: Weitere Einstellungen @@ -37,6 +38,9 @@ text.collof: Sammlungen von text.diskreq: benötigter Festplattenplatz text.yes: Ja text.no: Nein +text.notwritable: (Vorgabe ohne Schreibberechtigung - bitte ändern!) +text.changetexdir: (Bitte zuerst TEXDIR ändern!) + label.scheme: Ausgewähltes Schema label.stdcoll: Standardsammlungen diff --git a/Master/tlpkg/installer/lang/perltk-en.sample b/Master/tlpkg/installer/lang/perltk-en.sample index 7683178f5bc..08d91e8a9b2 100644 --- a/Master/tlpkg/installer/lang/perltk-en.sample +++ b/Master/tlpkg/installer/lang/perltk-en.sample @@ -41,6 +41,8 @@ text.collof: collections out of text.diskreq: disk space required text.yes: Yes text.no: No +text.notwritable: (default not writable - please change!) +text.changetexdir: (please change TEXDIR first!) label.binsys: Binary System(s) label.scheme: Selected Scheme diff --git a/Master/tlpkg/installer/lang/perltk-pl b/Master/tlpkg/installer/lang/perltk-pl index 5923594d7d0..cd26bb1b18d 100644 --- a/Master/tlpkg/installer/lang/perltk-pl +++ b/Master/tlpkg/installer/lang/perltk-pl @@ -1,5 +1,5 @@ # -# install-menu-perltk-pl.pl +# Polish strings for texlive installer # Jerzy B. Ludwichowski # text.title: Instalowanie TeX Live 2008 diff --git a/Master/tlpkg/installer/perllib/File/Spec.pm b/Master/tlpkg/installer/perllib/File/Spec.pm new file mode 100644 index 00000000000..0c8cd21e057 --- /dev/null +++ b/Master/tlpkg/installer/perllib/File/Spec.pm @@ -0,0 +1,322 @@ +package File::Spec; + +use strict; +use vars qw(@ISA $VERSION); + +$VERSION = '3.12'; +$VERSION = eval $VERSION; + +my %module = (MacOS => 'Mac', + MSWin32 => 'Win32', + os2 => 'OS2', + VMS => 'VMS', + epoc => 'Epoc', + NetWare => 'Win32', # Yes, File::Spec::Win32 works on NetWare. + symbian => 'Win32', # Yes, File::Spec::Win32 works on symbian. + dos => 'OS2', # Yes, File::Spec::OS2 works on DJGPP. + cygwin => 'Cygwin'); + + +my $module = $module{$^O} || 'Unix'; + +require "File/Spec/$module.pm"; +@ISA = ("File::Spec::$module"); + +1; + +__END__ + +=head1 NAME + +File::Spec - portably perform operations on file names + +=head1 SYNOPSIS + + use File::Spec; + + $x=File::Spec->catfile('a', 'b', 'c'); + +which returns 'a/b/c' under Unix. Or: + + use File::Spec::Functions; + + $x = catfile('a', 'b', 'c'); + +=head1 DESCRIPTION + +This module is designed to support operations commonly performed on file +specifications (usually called "file names", but not to be confused with the +contents of a file, or Perl's file handles), such as concatenating several +directory and file names into a single path, or determining whether a path +is rooted. It is based on code directly taken from MakeMaker 5.17, code +written by Andreas KE<ouml>nig, Andy Dougherty, Charles Bailey, Ilya +Zakharevich, Paul Schinder, and others. + +Since these functions are different for most operating systems, each set of +OS specific routines is available in a separate module, including: + + File::Spec::Unix + File::Spec::Mac + File::Spec::OS2 + File::Spec::Win32 + File::Spec::VMS + +The module appropriate for the current OS is automatically loaded by +File::Spec. Since some modules (like VMS) make use of facilities available +only under that OS, it may not be possible to load all modules under all +operating systems. + +Since File::Spec is object oriented, subroutines should not be called directly, +as in: + + File::Spec::catfile('a','b'); + +but rather as class methods: + + File::Spec->catfile('a','b'); + +For simple uses, L<File::Spec::Functions> provides convenient functional +forms of these methods. + +=head1 METHODS + +=over 2 + +=item canonpath + +No physical check on the filesystem, but a logical cleanup of a +path. + + $cpath = File::Spec->canonpath( $path ) ; + +Note that this does *not* collapse F<x/../y> sections into F<y>. This +is by design. If F</foo> on your system is a symlink to F</bar/baz>, +then F</foo/../quux> is actually F</bar/quux>, not F</quux> as a naive +F<../>-removal would give you. If you want to do this kind of +processing, you probably want C<Cwd>'s C<realpath()> function to +actually traverse the filesystem cleaning up paths like this. + +=item catdir + +Concatenate two or more directory names to form a complete path ending +with a directory. But remove the trailing slash from the resulting +string, because it doesn't look good, isn't necessary and confuses +OS/2. Of course, if this is the root directory, don't cut off the +trailing slash :-) + + $path = File::Spec->catdir( @directories ); + +=item catfile + +Concatenate one or more directory names and a filename to form a +complete path ending with a filename + + $path = File::Spec->catfile( @directories, $filename ); + +=item curdir + +Returns a string representation of the current directory. + + $curdir = File::Spec->curdir(); + +=item devnull + +Returns a string representation of the null device. + + $devnull = File::Spec->devnull(); + +=item rootdir + +Returns a string representation of the root directory. + + $rootdir = File::Spec->rootdir(); + +=item tmpdir + +Returns a string representation of the first writable directory from a +list of possible temporary directories. Returns the current directory +if no writable temporary directories are found. The list of directories +checked depends on the platform; e.g. File::Spec::Unix checks C<$ENV{TMPDIR}> +(unless taint is on) and F</tmp>. + + $tmpdir = File::Spec->tmpdir(); + +=item updir + +Returns a string representation of the parent directory. + + $updir = File::Spec->updir(); + +=item no_upwards + +Given a list of file names, strip out those that refer to a parent +directory. (Does not strip symlinks, only '.', '..', and equivalents.) + + @paths = File::Spec->no_upwards( @paths ); + +=item case_tolerant + +Returns a true or false value indicating, respectively, that alphabetic +case is not or is significant when comparing file specifications. + + $is_case_tolerant = File::Spec->case_tolerant(); + +=item file_name_is_absolute + +Takes as its argument a path, and returns true if it is an absolute path. + + $is_absolute = File::Spec->file_name_is_absolute( $path ); + +This does not consult the local filesystem on Unix, Win32, OS/2, or +Mac OS (Classic). It does consult the working environment for VMS +(see L<File::Spec::VMS/file_name_is_absolute>). + +=item path + +Takes no argument. Returns the environment variable C<PATH> (or the local +platform's equivalent) as a list. + + @PATH = File::Spec->path(); + +=item join + +join is the same as catfile. + +=item splitpath + +Splits a path in to volume, directory, and filename portions. On systems +with no concept of volume, returns '' for volume. + + ($volume,$directories,$file) = File::Spec->splitpath( $path ); + ($volume,$directories,$file) = File::Spec->splitpath( $path, $no_file ); + +For systems with no syntax differentiating filenames from directories, +assumes that the last file is a path unless C<$no_file> is true or a +trailing separator or F</.> or F</..> is present. On Unix, this means that C<$no_file> +true makes this return ( '', $path, '' ). + +The directory portion may or may not be returned with a trailing '/'. + +The results can be passed to L</catpath()> to get back a path equivalent to +(usually identical to) the original path. + +=item splitdir + +The opposite of L</catdir()>. + + @dirs = File::Spec->splitdir( $directories ); + +C<$directories> must be only the directory portion of the path on systems +that have the concept of a volume or that have path syntax that differentiates +files from directories. + +Unlike just splitting the directories on the separator, empty +directory names (C<''>) can be returned, because these are significant +on some OSes. + +=item catpath() + +Takes volume, directory and file portions and returns an entire path. Under +Unix, C<$volume> is ignored, and directory and file are concatenated. A '/' is +inserted if need be. On other OSes, C<$volume> is significant. + + $full_path = File::Spec->catpath( $volume, $directory, $file ); + +=item abs2rel + +Takes a destination path and an optional base path returns a relative path +from the base path to the destination path: + + $rel_path = File::Spec->abs2rel( $path ) ; + $rel_path = File::Spec->abs2rel( $path, $base ) ; + +If C<$base> is not present or '', then L<cwd()|Cwd> is used. If C<$base> is +relative, then it is converted to absolute form using +L</rel2abs()>. This means that it is taken to be relative to +L<cwd()|Cwd>. + +On systems with the concept of volume, if C<$path> and C<$base> appear to be +on two different volumes, we will not attempt to resolve the two +paths, and we will instead simply return C<$path>. Note that previous +versions of this module ignored the volume of C<$base>, which resulted in +garbage results part of the time. + +On systems that have a grammar that indicates filenames, this ignores the +C<$base> filename as well. Otherwise all path components are assumed to be +directories. + +If C<$path> is relative, it is converted to absolute form using L</rel2abs()>. +This means that it is taken to be relative to L<cwd()|Cwd>. + +No checks against the filesystem are made. On VMS, there is +interaction with the working environment, as logicals and +macros are expanded. + +Based on code written by Shigio Yamaguchi. + +=item rel2abs() + +Converts a relative path to an absolute path. + + $abs_path = File::Spec->rel2abs( $path ) ; + $abs_path = File::Spec->rel2abs( $path, $base ) ; + +If C<$base> is not present or '', then L<cwd()|Cwd> is used. If C<$base> is relative, +then it is converted to absolute form using L</rel2abs()>. This means that it +is taken to be relative to L<cwd()|Cwd>. + +On systems with the concept of volume, if C<$path> and C<$base> appear to be +on two different volumes, we will not attempt to resolve the two +paths, and we will instead simply return C<$path>. Note that previous +versions of this module ignored the volume of C<$base>, which resulted in +garbage results part of the time. + +On systems that have a grammar that indicates filenames, this ignores the +C<$base> filename as well. Otherwise all path components are assumed to be +directories. + +If C<$path> is absolute, it is cleaned up and returned using L</canonpath()>. + +No checks against the filesystem are made. On VMS, there is +interaction with the working environment, as logicals and +macros are expanded. + +Based on code written by Shigio Yamaguchi. + +=back + +For further information, please see L<File::Spec::Unix>, +L<File::Spec::Mac>, L<File::Spec::OS2>, L<File::Spec::Win32>, or +L<File::Spec::VMS>. + +=head1 SEE ALSO + +L<File::Spec::Unix>, L<File::Spec::Mac>, L<File::Spec::OS2>, +L<File::Spec::Win32>, L<File::Spec::VMS>, L<File::Spec::Functions>, +L<ExtUtils::MakeMaker> + +=head1 AUTHOR + +Currently maintained by Ken Williams C<< <KWILLIAMS@cpan.org> >>. + +The vast majority of the code was written by +Kenneth Albanowski C<< <kjahds@kjahds.com> >>, +Andy Dougherty C<< <doughera@lafayette.edu> >>, +Andreas KE<ouml>nig C<< <A.Koenig@franz.ww.TU-Berlin.DE> >>, +Tim Bunce C<< <Tim.Bunce@ig.co.uk> >>. +VMS support by Charles Bailey C<< <bailey@newman.upenn.edu> >>. +OS/2 support by Ilya Zakharevich C<< <ilya@math.ohio-state.edu> >>. +Mac support by Paul Schinder C<< <schinder@pobox.com> >>, and +Thomas Wegner C<< <wegner_thomas@yahoo.com> >>. +abs2rel() and rel2abs() written by Shigio Yamaguchi C<< <shigio@tamacom.com> >>, +modified by Barrie Slaymaker C<< <barries@slaysys.com> >>. +splitpath(), splitdir(), catpath() and catdir() by Barrie Slaymaker. + +=head1 COPYRIGHT + +Copyright (c) 2004 by the Perl 5 Porters. All rights reserved. + +This program is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut diff --git a/Master/tlpkg/installer/perllib/File/Spec/Unix.pm b/Master/tlpkg/installer/perllib/File/Spec/Unix.pm new file mode 100644 index 00000000000..4a25fe632f2 --- /dev/null +++ b/Master/tlpkg/installer/perllib/File/Spec/Unix.pm @@ -0,0 +1,510 @@ +package File::Spec::Unix; + +use strict; +use vars qw($VERSION); + +$VERSION = '1.5'; + +=head1 NAME + +File::Spec::Unix - File::Spec for Unix, base for other File::Spec modules + +=head1 SYNOPSIS + + require File::Spec::Unix; # Done automatically by File::Spec + +=head1 DESCRIPTION + +Methods for manipulating file specifications. Other File::Spec +modules, such as File::Spec::Mac, inherit from File::Spec::Unix and +override specific methods. + +=head1 METHODS + +=over 2 + +=item canonpath() + +No physical check on the filesystem, but a logical cleanup of a +path. On UNIX eliminates successive slashes and successive "/.". + + $cpath = File::Spec->canonpath( $path ) ; + +Note that this does *not* collapse F<x/../y> sections into F<y>. This +is by design. If F</foo> on your system is a symlink to F</bar/baz>, +then F</foo/../quux> is actually F</bar/quux>, not F</quux> as a naive +F<../>-removal would give you. If you want to do this kind of +processing, you probably want C<Cwd>'s C<realpath()> function to +actually traverse the filesystem cleaning up paths like this. + +=cut + +sub canonpath { + my ($self,$path) = @_; + + # Handle POSIX-style node names beginning with double slash (qnx, nto) + # Handle network path names beginning with double slash (cygwin) + # (POSIX says: "a pathname that begins with two successive slashes + # may be interpreted in an implementation-defined manner, although + # more than two leading slashes shall be treated as a single slash.") + my $node = ''; + if ( $^O =~ m/^(?:qnx|nto|cygwin)$/ && $path =~ s:^(//[^/]+)(/|\z):/:s ) { + $node = $1; + } + # This used to be + # $path =~ s|/+|/|g unless($^O eq 'cygwin'); + # but that made tests 29, 30, 35, 46, and 213 (as of #13272) to fail + # (Mainly because trailing "" directories didn't get stripped). + # Why would cygwin avoid collapsing multiple slashes into one? --jhi + $path =~ s|/+|/|g; # xx////xx -> xx/xx + $path =~ s@(/\.)+(/|\Z(?!\n))@/@g; # xx/././xx -> xx/xx + $path =~ s|^(\./)+||s unless $path eq "./"; # ./xx -> xx + $path =~ s|^/(\.\./)+|/|; # /../../xx -> xx + $path =~ s|^/\.\.$|/|; # /.. -> / + $path =~ s|/\Z(?!\n)|| unless $path eq "/"; # xx/ -> xx + return "$node$path"; +} + +=item catdir() + +Concatenate two or more directory names to form a complete path ending +with a directory. But remove the trailing slash from the resulting +string, because it doesn't look good, isn't necessary and confuses +OS2. Of course, if this is the root directory, don't cut off the +trailing slash :-) + +=cut + +sub catdir { + my $self = shift; + + $self->canonpath(join('/', @_, '')); # '' because need a trailing '/' +} + +=item catfile + +Concatenate one or more directory names and a filename to form a +complete path ending with a filename + +=cut + +sub catfile { + my $self = shift; + my $file = $self->canonpath(pop @_); + return $file unless @_; + my $dir = $self->catdir(@_); + $dir .= "/" unless substr($dir,-1) eq "/"; + return $dir.$file; +} + +=item curdir + +Returns a string representation of the current directory. "." on UNIX. + +=cut + +sub curdir () { '.' } + +=item devnull + +Returns a string representation of the null device. "/dev/null" on UNIX. + +=cut + +sub devnull () { '/dev/null' } + +=item rootdir + +Returns a string representation of the root directory. "/" on UNIX. + +=cut + +sub rootdir () { '/' } + +=item tmpdir + +Returns a string representation of the first writable directory from +the following list or the current directory if none from the list are +writable: + + $ENV{TMPDIR} + /tmp + +Since perl 5.8.0, if running under taint mode, and if $ENV{TMPDIR} +is tainted, it is not used. + +=cut + +my $tmpdir; +sub _tmpdir { + return $tmpdir if defined $tmpdir; + my $self = shift; + my @dirlist = @_; + { + no strict 'refs'; + if (${"\cTAINT"}) { # Check for taint mode on perl >= 5.8.0 + require Scalar::Util; + @dirlist = grep { ! Scalar::Util::tainted($_) } @dirlist; + } + } + foreach (@dirlist) { + next unless defined && -d && -w _; + $tmpdir = $_; + last; + } + $tmpdir = $self->curdir unless defined $tmpdir; + $tmpdir = defined $tmpdir && $self->canonpath($tmpdir); + return $tmpdir; +} + +sub tmpdir { + return $tmpdir if defined $tmpdir; + $tmpdir = $_[0]->_tmpdir( $ENV{TMPDIR}, "/tmp" ); +} + +=item updir + +Returns a string representation of the parent directory. ".." on UNIX. + +=cut + +sub updir () { '..' } + +=item no_upwards + +Given a list of file names, strip out those that refer to a parent +directory. (Does not strip symlinks, only '.', '..', and equivalents.) + +=cut + +sub no_upwards { + my $self = shift; + return grep(!/^\.{1,2}\Z(?!\n)/s, @_); +} + +=item case_tolerant + +Returns a true or false value indicating, respectively, that alphabetic +is not or is significant when comparing file specifications. + +=cut + +sub case_tolerant () { 0 } + +=item file_name_is_absolute + +Takes as argument a path and returns true if it is an absolute path. + +This does not consult the local filesystem on Unix, Win32, OS/2 or Mac +OS (Classic). It does consult the working environment for VMS (see +L<File::Spec::VMS/file_name_is_absolute>). + +=cut + +sub file_name_is_absolute { + my ($self,$file) = @_; + return scalar($file =~ m:^/:s); +} + +=item path + +Takes no argument, returns the environment variable PATH as an array. + +=cut + +sub path { + return () unless exists $ENV{PATH}; + my @path = split(':', $ENV{PATH}); + foreach (@path) { $_ = '.' if $_ eq '' } + return @path; +} + +=item join + +join is the same as catfile. + +=cut + +sub join { + my $self = shift; + return $self->catfile(@_); +} + +=item splitpath + + ($volume,$directories,$file) = File::Spec->splitpath( $path ); + ($volume,$directories,$file) = File::Spec->splitpath( $path, $no_file ); + +Splits a path into volume, directory, and filename portions. On systems +with no concept of volume, returns '' for volume. + +For systems with no syntax differentiating filenames from directories, +assumes that the last file is a path unless $no_file is true or a +trailing separator or /. or /.. is present. On Unix this means that $no_file +true makes this return ( '', $path, '' ). + +The directory portion may or may not be returned with a trailing '/'. + +The results can be passed to L</catpath()> to get back a path equivalent to +(usually identical to) the original path. + +=cut + +sub splitpath { + my ($self,$path, $nofile) = @_; + + my ($volume,$directory,$file) = ('','',''); + + if ( $nofile ) { + $directory = $path; + } + else { + $path =~ m|^ ( (?: .* / (?: \.\.?\Z(?!\n) )? )? ) ([^/]*) |xs; + $directory = $1; + $file = $2; + } + + return ($volume,$directory,$file); +} + + +=item splitdir + +The opposite of L</catdir()>. + + @dirs = File::Spec->splitdir( $directories ); + +$directories must be only the directory portion of the path on systems +that have the concept of a volume or that have path syntax that differentiates +files from directories. + +Unlike just splitting the directories on the separator, empty +directory names (C<''>) can be returned, because these are significant +on some OSs. + +On Unix, + + File::Spec->splitdir( "/a/b//c/" ); + +Yields: + + ( '', 'a', 'b', '', 'c', '' ) + +=cut + +sub splitdir { + return split m|/|, $_[1], -1; # Preserve trailing fields +} + + +=item catpath() + +Takes volume, directory and file portions and returns an entire path. Under +Unix, $volume is ignored, and directory and file are concatenated. A '/' is +inserted if needed (though if the directory portion doesn't start with +'/' it is not added). On other OSs, $volume is significant. + +=cut + +sub catpath { + my ($self,$volume,$directory,$file) = @_; + + if ( $directory ne '' && + $file ne '' && + substr( $directory, -1 ) ne '/' && + substr( $file, 0, 1 ) ne '/' + ) { + $directory .= "/$file" ; + } + else { + $directory .= $file ; + } + + return $directory ; +} + +=item abs2rel + +Takes a destination path and an optional base path returns a relative path +from the base path to the destination path: + + $rel_path = File::Spec->abs2rel( $path ) ; + $rel_path = File::Spec->abs2rel( $path, $base ) ; + +If $base is not present or '', then L<cwd()|Cwd> is used. If $base is +relative, then it is converted to absolute form using +L</rel2abs()>. This means that it is taken to be relative to +L<cwd()|Cwd>. + +On systems that have a grammar that indicates filenames, this ignores the +$base filename. Otherwise all path components are assumed to be +directories. + +If $path is relative, it is converted to absolute form using L</rel2abs()>. +This means that it is taken to be relative to L<cwd()|Cwd>. + +No checks against the filesystem are made. On VMS, there is +interaction with the working environment, as logicals and +macros are expanded. + +Based on code written by Shigio Yamaguchi. + +=cut + +sub abs2rel { + my($self,$path,$base) = @_; + + # Clean up $path + if ( ! $self->file_name_is_absolute( $path ) ) { + $path = $self->rel2abs( $path ) ; + } + else { + $path = $self->canonpath( $path ) ; + } + + # Figure out the effective $base and clean it up. + if ( !defined( $base ) || $base eq '' ) { + $base = $self->_cwd(); + } + elsif ( ! $self->file_name_is_absolute( $base ) ) { + $base = $self->rel2abs( $base ) ; + } + else { + $base = $self->canonpath( $base ) ; + } + + # Now, remove all leading components that are the same + my @pathchunks = $self->splitdir( $path); + my @basechunks = $self->splitdir( $base); + + while (@pathchunks && @basechunks && $pathchunks[0] eq $basechunks[0]) { + shift @pathchunks ; + shift @basechunks ; + } + + $path = CORE::join( '/', @pathchunks ); + $base = CORE::join( '/', @basechunks ); + + # $base now contains the directories the resulting relative path + # must ascend out of before it can descend to $path_directory. So, + # replace all names with $parentDir + $base =~ s|[^/]+|..|g ; + + # Glue the two together, using a separator if necessary, and preventing an + # empty result. + if ( $path ne '' && $base ne '' ) { + $path = "$base/$path" ; + } else { + $path = "$base$path" ; + } + + return $self->canonpath( $path ) ; +} + +=item rel2abs() + +Converts a relative path to an absolute path. + + $abs_path = File::Spec->rel2abs( $path ) ; + $abs_path = File::Spec->rel2abs( $path, $base ) ; + +If $base is not present or '', then L<cwd()|Cwd> is used. If $base is +relative, then it is converted to absolute form using +L</rel2abs()>. This means that it is taken to be relative to +L<cwd()|Cwd>. + +On systems that have a grammar that indicates filenames, this ignores +the $base filename. Otherwise all path components are assumed to be +directories. + +If $path is absolute, it is cleaned up and returned using L</canonpath()>. + +No checks against the filesystem are made. On VMS, there is +interaction with the working environment, as logicals and +macros are expanded. + +Based on code written by Shigio Yamaguchi. + +=cut + +sub rel2abs { + my ($self,$path,$base ) = @_; + + # Clean up $path + if ( ! $self->file_name_is_absolute( $path ) ) { + # Figure out the effective $base and clean it up. + if ( !defined( $base ) || $base eq '' ) { + $base = $self->_cwd(); + } + elsif ( ! $self->file_name_is_absolute( $base ) ) { + $base = $self->rel2abs( $base ) ; + } + else { + $base = $self->canonpath( $base ) ; + } + + # Glom them together + $path = $self->catdir( $base, $path ) ; + } + + return $self->canonpath( $path ) ; +} + +=back + +=head1 COPYRIGHT + +Copyright (c) 2004 by the Perl 5 Porters. All rights reserved. + +This program is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=head1 SEE ALSO + +L<File::Spec> + +=cut + +# Internal routine to File::Spec, no point in making this public since +# it is the standard Cwd interface. Most of the platform-specific +# File::Spec subclasses use this. +sub _cwd { + require Cwd; + Cwd::cwd(); +} + + +# Internal method to reduce xx\..\yy -> yy +sub _collapse { + my($fs, $path) = @_; + + my $updir = $fs->updir; + my $curdir = $fs->curdir; + + my($vol, $dirs, $file) = $fs->splitpath($path); + my @dirs = $fs->splitdir($dirs); + + my @collapsed; + foreach my $dir (@dirs) { + if( $dir eq $updir and # if we have an updir + @collapsed and # and something to collapse + length $collapsed[-1] and # and its not the rootdir + $collapsed[-1] ne $updir and # nor another updir + $collapsed[-1] ne $curdir # nor the curdir + ) + { # then + pop @collapsed; # collapse + } + else { # else + push @collapsed, $dir; # just hang onto it + } + } + + return $fs->catpath($vol, + $fs->catdir(@collapsed), + $file + ); +} + + +1; diff --git a/Master/tlpkg/installer/perllib/File/Spec/Win32.pm b/Master/tlpkg/installer/perllib/File/Spec/Win32.pm new file mode 100644 index 00000000000..a324306a74b --- /dev/null +++ b/Master/tlpkg/installer/perllib/File/Spec/Win32.pm @@ -0,0 +1,369 @@ +package File::Spec::Win32; + +use strict; + +use vars qw(@ISA $VERSION); +require File::Spec::Unix; + +$VERSION = '1.6'; + +@ISA = qw(File::Spec::Unix); + +=head1 NAME + +File::Spec::Win32 - methods for Win32 file specs + +=head1 SYNOPSIS + + require File::Spec::Win32; # Done internally by File::Spec if needed + +=head1 DESCRIPTION + +See File::Spec::Unix for a documentation of the methods provided +there. This package overrides the implementation of these methods, not +the semantics. + +=over 4 + +=item devnull + +Returns a string representation of the null device. + +=cut + +sub devnull { + return "nul"; +} + +sub rootdir () { '\\' } + + +=item tmpdir + +Returns a string representation of the first existing directory +from the following list: + + $ENV{TMPDIR} + $ENV{TEMP} + $ENV{TMP} + SYS:/temp + C:\system\temp + C:/temp + /tmp + / + +The SYS:/temp is preferred in Novell NetWare and the C:\system\temp +for Symbian (the File::Spec::Win32 is used also for those platforms). + +Since Perl 5.8.0, if running under taint mode, and if the environment +variables are tainted, they are not used. + +=cut + +my $tmpdir; +sub tmpdir { + return $tmpdir if defined $tmpdir; + $tmpdir = $_[0]->_tmpdir( @ENV{qw(TMPDIR TEMP TMP)}, + 'SYS:/temp', + 'C:\system\temp', + 'C:/temp', + '/tmp', + '/' ); +} + +sub case_tolerant { + return 1; +} + +sub file_name_is_absolute { + my ($self,$file) = @_; + return scalar($file =~ m{^([a-z]:)?[\\/]}is); +} + +=item catfile + +Concatenate one or more directory names and a filename to form a +complete path ending with a filename + +=cut + +sub catfile { + my $self = shift; + my $file = $self->canonpath(pop @_); + return $file unless @_; + my $dir = $self->catdir(@_); + $dir .= "\\" unless substr($dir,-1) eq "\\"; + return $dir.$file; +} + +sub catdir { + my $self = shift; + my @args = @_; + foreach (@args) { + tr[/][\\]; + # append a backslash to each argument unless it has one there + $_ .= "\\" unless m{\\$}; + } + return $self->canonpath(join('', @args)); +} + +sub path { + my @path = split(';', $ENV{PATH}); + s/"//g for @path; + @path = grep length, @path; + unshift(@path, "."); + return @path; +} + +=item canonpath + +No physical check on the filesystem, but a logical cleanup of a +path. On UNIX eliminated successive slashes and successive "/.". +On Win32 makes + + dir1\dir2\dir3\..\..\dir4 -> \dir\dir4 and even + dir1\dir2\dir3\...\dir4 -> \dir\dir4 + +=cut + +sub canonpath { + my ($self,$path) = @_; + + $path =~ s/^([a-z]:)/\u$1/s; + $path =~ s|/|\\|g; + $path =~ s|([^\\])\\+|$1\\|g; # xx\\\\xx -> xx\xx + $path =~ s|(\\\.)+\\|\\|g; # xx\.\.\xx -> xx\xx + $path =~ s|^(\.\\)+||s unless $path eq ".\\"; # .\xx -> xx + $path =~ s|\\\Z(?!\n)|| + unless $path =~ m{^([A-Z]:)?\\\Z(?!\n)}s; # xx\ -> xx + # xx1/xx2/xx3/../../xx -> xx1/xx + $path =~ s|\\\.\.\.\\|\\\.\.\\\.\.\\|g; # \...\ is 2 levels up + $path =~ s|^\.\.\.\\|\.\.\\\.\.\\|g; # ...\ is 2 levels up + return $path if $path =~ m|^\.\.|; # skip relative paths + return $path unless $path =~ /\.\./; # too few .'s to cleanup + return $path if $path =~ /\.\.\.\./; # too many .'s to cleanup + $path =~ s{^\\\.\.$}{\\}; # \.. -> \ + 1 while $path =~ s{^\\\.\.}{}; # \..\xx -> \xx + + return $self->_collapse($path); +} + +=item splitpath + + ($volume,$directories,$file) = File::Spec->splitpath( $path ); + ($volume,$directories,$file) = File::Spec->splitpath( $path, $no_file ); + +Splits a path into volume, directory, and filename portions. Assumes that +the last file is a path unless the path ends in '\\', '\\.', '\\..' +or $no_file is true. On Win32 this means that $no_file true makes this return +( $volume, $path, '' ). + +Separators accepted are \ and /. + +Volumes can be drive letters or UNC sharenames (\\server\share). + +The results can be passed to L</catpath> to get back a path equivalent to +(usually identical to) the original path. + +=cut + +sub splitpath { + my ($self,$path, $nofile) = @_; + my ($volume,$directory,$file) = ('','',''); + if ( $nofile ) { + $path =~ + m{^( (?:[a-zA-Z]:|(?:\\\\|//)[^\\/]+[\\/][^\\/]+)? ) + (.*) + }xs; + $volume = $1; + $directory = $2; + } + else { + $path =~ + m{^ ( (?: [a-zA-Z]: | + (?:\\\\|//)[^\\/]+[\\/][^\\/]+ + )? + ) + ( (?:.*[\\/](?:\.\.?\Z(?!\n))?)? ) + (.*) + }xs; + $volume = $1; + $directory = $2; + $file = $3; + } + + return ($volume,$directory,$file); +} + + +=item splitdir + +The opposite of L<catdir()|File::Spec/catdir()>. + + @dirs = File::Spec->splitdir( $directories ); + +$directories must be only the directory portion of the path on systems +that have the concept of a volume or that have path syntax that differentiates +files from directories. + +Unlike just splitting the directories on the separator, leading empty and +trailing directory entries can be returned, because these are significant +on some OSs. So, + + File::Spec->splitdir( "/a/b/c" ); + +Yields: + + ( '', 'a', 'b', '', 'c', '' ) + +=cut + +sub splitdir { + my ($self,$directories) = @_ ; + # + # split() likes to forget about trailing null fields, so here we + # check to be sure that there will not be any before handling the + # simple case. + # + if ( $directories !~ m|[\\/]\Z(?!\n)| ) { + return split( m|[\\/]|, $directories ); + } + else { + # + # since there was a trailing separator, add a file name to the end, + # then do the split, then replace it with ''. + # + my( @directories )= split( m|[\\/]|, "${directories}dummy" ) ; + $directories[ $#directories ]= '' ; + return @directories ; + } +} + + +=item catpath + +Takes volume, directory and file portions and returns an entire path. Under +Unix, $volume is ignored, and this is just like catfile(). On other OSs, +the $volume become significant. + +=cut + +sub catpath { + my ($self,$volume,$directory,$file) = @_; + + # If it's UNC, make sure the glue separator is there, reusing + # whatever separator is first in the $volume + my $v; + $volume .= $v + if ( (($v) = $volume =~ m@^([\\/])[\\/][^\\/]+[\\/][^\\/]+\Z(?!\n)@s) && + $directory =~ m@^[^\\/]@s + ) ; + + $volume .= $directory ; + + # If the volume is not just A:, make sure the glue separator is + # there, reusing whatever separator is first in the $volume if possible. + if ( $volume !~ m@^[a-zA-Z]:\Z(?!\n)@s && + $volume =~ m@[^\\/]\Z(?!\n)@ && + $file =~ m@[^\\/]@ + ) { + $volume =~ m@([\\/])@ ; + my $sep = $1 ? $1 : '\\' ; + $volume .= $sep ; + } + + $volume .= $file ; + + return $volume ; +} + + +sub abs2rel { + my($self,$path,$base) = @_; + $base = $self->_cwd() unless defined $base and length $base; + + for ($path, $base) { $_ = $self->canonpath($_) } + + my ($path_volume) = $self->splitpath($path, 1); + my ($base_volume) = $self->splitpath($base, 1); + + # Can't relativize across volumes + return $path unless $path_volume eq $base_volume; + + for ($path, $base) { $_ = $self->rel2abs($_) } + + my $path_directories = ($self->splitpath($path, 1))[1]; + my $base_directories = ($self->splitpath($base, 1))[1]; + + # Now, remove all leading components that are the same + my @pathchunks = $self->splitdir( $path_directories ); + my @basechunks = $self->splitdir( $base_directories ); + + while ( @pathchunks && + @basechunks && + lc( $pathchunks[0] ) eq lc( $basechunks[0] ) + ) { + shift @pathchunks ; + shift @basechunks ; + } + + my $result_dirs = $self->catdir( ($self->updir) x @basechunks, @pathchunks ); + + return $self->canonpath( $self->catpath('', $result_dirs, '') ); +} + + +sub rel2abs { + my ($self,$path,$base ) = @_; + + if ( ! $self->file_name_is_absolute( $path ) ) { + + if ( !defined( $base ) || $base eq '' ) { + require Cwd ; + $base = Cwd::getdcwd( ($self->splitpath( $path ))[0] ) if defined &Cwd::getdcwd ; + $base = $self->_cwd() unless defined $base ; + } + elsif ( ! $self->file_name_is_absolute( $base ) ) { + $base = $self->rel2abs( $base ) ; + } + else { + $base = $self->canonpath( $base ) ; + } + + my ( $path_directories, $path_file ) = + ($self->splitpath( $path, 1 ))[1,2] ; + + my ( $base_volume, $base_directories ) = + $self->splitpath( $base, 1 ) ; + + $path = $self->catpath( + $base_volume, + $self->catdir( $base_directories, $path_directories ), + $path_file + ) ; + } + + return $self->canonpath( $path ) ; +} + +=back + +=head2 Note For File::Spec::Win32 Maintainers + +Novell NetWare inherits its File::Spec behaviour from File::Spec::Win32. + +=head1 COPYRIGHT + +Copyright (c) 2004 by the Perl 5 Porters. All rights reserved. + +This program is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=head1 SEE ALSO + +See L<File::Spec> and L<File::Spec::Unix>. This package overrides the +implementation of these methods, not the semantics. + +=cut + +1; diff --git a/Master/tlpkg/installer/perllib/Pod/InputObjects.pm b/Master/tlpkg/installer/perllib/Pod/InputObjects.pm new file mode 100644 index 00000000000..fa5f61f9a70 --- /dev/null +++ b/Master/tlpkg/installer/perllib/Pod/InputObjects.pm @@ -0,0 +1,941 @@ +############################################################################# +# Pod/InputObjects.pm -- package which defines objects for input streams +# and paragraphs and commands when parsing POD docs. +# +# Copyright (C) 1996-2000 by Bradford Appleton. All rights reserved. +# This file is part of "PodParser". PodParser is free software; +# you can redistribute it and/or modify it under the same terms +# as Perl itself. +############################################################################# + +package Pod::InputObjects; + +use vars qw($VERSION); +$VERSION = 1.30; ## Current version of this package +require 5.005; ## requires this Perl version or later + +############################################################################# + +=head1 NAME + +Pod::InputObjects - objects representing POD input paragraphs, commands, etc. + +=head1 SYNOPSIS + + use Pod::InputObjects; + +=head1 REQUIRES + +perl5.004, Carp + +=head1 EXPORTS + +Nothing. + +=head1 DESCRIPTION + +This module defines some basic input objects used by B<Pod::Parser> when +reading and parsing POD text from an input source. The following objects +are defined: + +=over 4 + +=begin __PRIVATE__ + +=item package B<Pod::InputSource> + +An object corresponding to a source of POD input text. It is mostly a +wrapper around a filehandle or C<IO::Handle>-type object (or anything +that implements the C<getline()> method) which keeps track of some +additional information relevant to the parsing of PODs. + +=end __PRIVATE__ + +=item package B<Pod::Paragraph> + +An object corresponding to a paragraph of POD input text. It may be a +plain paragraph, a verbatim paragraph, or a command paragraph (see +L<perlpod>). + +=item package B<Pod::InteriorSequence> + +An object corresponding to an interior sequence command from the POD +input text (see L<perlpod>). + +=item package B<Pod::ParseTree> + +An object corresponding to a tree of parsed POD text. Each "node" in +a parse-tree (or I<ptree>) is either a text-string or a reference to +a B<Pod::InteriorSequence> object. The nodes appear in the parse-tree +in the order in which they were parsed from left-to-right. + +=back + +Each of these input objects are described in further detail in the +sections which follow. + +=cut + +############################################################################# + +use strict; +#use diagnostics; +#use Carp; + +############################################################################# + +package Pod::InputSource; + +##--------------------------------------------------------------------------- + +=begin __PRIVATE__ + +=head1 B<Pod::InputSource> + +This object corresponds to an input source or stream of POD +documentation. When parsing PODs, it is necessary to associate and store +certain context information with each input source. All of this +information is kept together with the stream itself in one of these +C<Pod::InputSource> objects. Each such object is merely a wrapper around +an C<IO::Handle> object of some kind (or at least something that +implements the C<getline()> method). They have the following +methods/attributes: + +=end __PRIVATE__ + +=cut + +##--------------------------------------------------------------------------- + +=begin __PRIVATE__ + +=head2 B<new()> + + my $pod_input1 = Pod::InputSource->new(-handle => $filehandle); + my $pod_input2 = new Pod::InputSource(-handle => $filehandle, + -name => $name); + my $pod_input3 = new Pod::InputSource(-handle => \*STDIN); + my $pod_input4 = Pod::InputSource->new(-handle => \*STDIN, + -name => "(STDIN)"); + +This is a class method that constructs a C<Pod::InputSource> object and +returns a reference to the new input source object. It takes one or more +keyword arguments in the form of a hash. The keyword C<-handle> is +required and designates the corresponding input handle. The keyword +C<-name> is optional and specifies the name associated with the input +handle (typically a file name). + +=end __PRIVATE__ + +=cut + +sub new { + ## Determine if we were called via an object-ref or a classname + my $this = shift; + my $class = ref($this) || $this; + + ## Any remaining arguments are treated as initial values for the + ## hash that is used to represent this object. Note that we default + ## certain values by specifying them *before* the arguments passed. + ## If they are in the argument list, they will override the defaults. + my $self = { -name => '(unknown)', + -handle => undef, + -was_cutting => 0, + @_ }; + + ## Bless ourselves into the desired class and perform any initialization + bless $self, $class; + return $self; +} + +##--------------------------------------------------------------------------- + +=begin __PRIVATE__ + +=head2 B<name()> + + my $filename = $pod_input->name(); + $pod_input->name($new_filename_to_use); + +This method gets/sets the name of the input source (usually a filename). +If no argument is given, it returns a string containing the name of +the input source; otherwise it sets the name of the input source to the +contents of the given argument. + +=end __PRIVATE__ + +=cut + +sub name { + (@_ > 1) and $_[0]->{'-name'} = $_[1]; + return $_[0]->{'-name'}; +} + +## allow 'filename' as an alias for 'name' +*filename = \&name; + +##--------------------------------------------------------------------------- + +=begin __PRIVATE__ + +=head2 B<handle()> + + my $handle = $pod_input->handle(); + +Returns a reference to the handle object from which input is read (the +one used to contructed this input source object). + +=end __PRIVATE__ + +=cut + +sub handle { + return $_[0]->{'-handle'}; +} + +##--------------------------------------------------------------------------- + +=begin __PRIVATE__ + +=head2 B<was_cutting()> + + print "Yes.\n" if ($pod_input->was_cutting()); + +The value of the C<cutting> state (that the B<cutting()> method would +have returned) immediately before any input was read from this input +stream. After all input from this stream has been read, the C<cutting> +state is restored to this value. + +=end __PRIVATE__ + +=cut + +sub was_cutting { + (@_ > 1) and $_[0]->{-was_cutting} = $_[1]; + return $_[0]->{-was_cutting}; +} + +##--------------------------------------------------------------------------- + +############################################################################# + +package Pod::Paragraph; + +##--------------------------------------------------------------------------- + +=head1 B<Pod::Paragraph> + +An object representing a paragraph of POD input text. +It has the following methods/attributes: + +=cut + +##--------------------------------------------------------------------------- + +=head2 Pod::Paragraph-E<gt>B<new()> + + my $pod_para1 = Pod::Paragraph->new(-text => $text); + my $pod_para2 = Pod::Paragraph->new(-name => $cmd, + -text => $text); + my $pod_para3 = new Pod::Paragraph(-text => $text); + my $pod_para4 = new Pod::Paragraph(-name => $cmd, + -text => $text); + my $pod_para5 = Pod::Paragraph->new(-name => $cmd, + -text => $text, + -file => $filename, + -line => $line_number); + +This is a class method that constructs a C<Pod::Paragraph> object and +returns a reference to the new paragraph object. It may be given one or +two keyword arguments. The C<-text> keyword indicates the corresponding +text of the POD paragraph. The C<-name> keyword indicates the name of +the corresponding POD command, such as C<head1> or C<item> (it should +I<not> contain the C<=> prefix); this is needed only if the POD +paragraph corresponds to a command paragraph. The C<-file> and C<-line> +keywords indicate the filename and line number corresponding to the +beginning of the paragraph + +=cut + +sub new { + ## Determine if we were called via an object-ref or a classname + my $this = shift; + my $class = ref($this) || $this; + + ## Any remaining arguments are treated as initial values for the + ## hash that is used to represent this object. Note that we default + ## certain values by specifying them *before* the arguments passed. + ## If they are in the argument list, they will override the defaults. + my $self = { + -name => undef, + -text => (@_ == 1) ? shift : undef, + -file => '<unknown-file>', + -line => 0, + -prefix => '=', + -separator => ' ', + -ptree => [], + @_ + }; + + ## Bless ourselves into the desired class and perform any initialization + bless $self, $class; + return $self; +} + +##--------------------------------------------------------------------------- + +=head2 $pod_para-E<gt>B<cmd_name()> + + my $para_cmd = $pod_para->cmd_name(); + +If this paragraph is a command paragraph, then this method will return +the name of the command (I<without> any leading C<=> prefix). + +=cut + +sub cmd_name { + (@_ > 1) and $_[0]->{'-name'} = $_[1]; + return $_[0]->{'-name'}; +} + +## let name() be an alias for cmd_name() +*name = \&cmd_name; + +##--------------------------------------------------------------------------- + +=head2 $pod_para-E<gt>B<text()> + + my $para_text = $pod_para->text(); + +This method will return the corresponding text of the paragraph. + +=cut + +sub text { + (@_ > 1) and $_[0]->{'-text'} = $_[1]; + return $_[0]->{'-text'}; +} + +##--------------------------------------------------------------------------- + +=head2 $pod_para-E<gt>B<raw_text()> + + my $raw_pod_para = $pod_para->raw_text(); + +This method will return the I<raw> text of the POD paragraph, exactly +as it appeared in the input. + +=cut + +sub raw_text { + return $_[0]->{'-text'} unless (defined $_[0]->{'-name'}); + return $_[0]->{'-prefix'} . $_[0]->{'-name'} . + $_[0]->{'-separator'} . $_[0]->{'-text'}; +} + +##--------------------------------------------------------------------------- + +=head2 $pod_para-E<gt>B<cmd_prefix()> + + my $prefix = $pod_para->cmd_prefix(); + +If this paragraph is a command paragraph, then this method will return +the prefix used to denote the command (which should be the string "=" +or "=="). + +=cut + +sub cmd_prefix { + return $_[0]->{'-prefix'}; +} + +##--------------------------------------------------------------------------- + +=head2 $pod_para-E<gt>B<cmd_separator()> + + my $separator = $pod_para->cmd_separator(); + +If this paragraph is a command paragraph, then this method will return +the text used to separate the command name from the rest of the +paragraph (if any). + +=cut + +sub cmd_separator { + return $_[0]->{'-separator'}; +} + +##--------------------------------------------------------------------------- + +=head2 $pod_para-E<gt>B<parse_tree()> + + my $ptree = $pod_parser->parse_text( $pod_para->text() ); + $pod_para->parse_tree( $ptree ); + $ptree = $pod_para->parse_tree(); + +This method will get/set the corresponding parse-tree of the paragraph's text. + +=cut + +sub parse_tree { + (@_ > 1) and $_[0]->{'-ptree'} = $_[1]; + return $_[0]->{'-ptree'}; +} + +## let ptree() be an alias for parse_tree() +*ptree = \&parse_tree; + +##--------------------------------------------------------------------------- + +=head2 $pod_para-E<gt>B<file_line()> + + my ($filename, $line_number) = $pod_para->file_line(); + my $position = $pod_para->file_line(); + +Returns the current filename and line number for the paragraph +object. If called in a list context, it returns a list of two +elements: first the filename, then the line number. If called in +a scalar context, it returns a string containing the filename, followed +by a colon (':'), followed by the line number. + +=cut + +sub file_line { + my @loc = ($_[0]->{'-file'} || '<unknown-file>', + $_[0]->{'-line'} || 0); + return (wantarray) ? @loc : join(':', @loc); +} + +##--------------------------------------------------------------------------- + +############################################################################# + +package Pod::InteriorSequence; + +##--------------------------------------------------------------------------- + +=head1 B<Pod::InteriorSequence> + +An object representing a POD interior sequence command. +It has the following methods/attributes: + +=cut + +##--------------------------------------------------------------------------- + +=head2 Pod::InteriorSequence-E<gt>B<new()> + + my $pod_seq1 = Pod::InteriorSequence->new(-name => $cmd + -ldelim => $delimiter); + my $pod_seq2 = new Pod::InteriorSequence(-name => $cmd, + -ldelim => $delimiter); + my $pod_seq3 = new Pod::InteriorSequence(-name => $cmd, + -ldelim => $delimiter, + -file => $filename, + -line => $line_number); + + my $pod_seq4 = new Pod::InteriorSequence(-name => $cmd, $ptree); + my $pod_seq5 = new Pod::InteriorSequence($cmd, $ptree); + +This is a class method that constructs a C<Pod::InteriorSequence> object +and returns a reference to the new interior sequence object. It should +be given two keyword arguments. The C<-ldelim> keyword indicates the +corresponding left-delimiter of the interior sequence (e.g. 'E<lt>'). +The C<-name> keyword indicates the name of the corresponding interior +sequence command, such as C<I> or C<B> or C<C>. The C<-file> and +C<-line> keywords indicate the filename and line number corresponding +to the beginning of the interior sequence. If the C<$ptree> argument is +given, it must be the last argument, and it must be either string, or +else an array-ref suitable for passing to B<Pod::ParseTree::new> (or +it may be a reference to a Pod::ParseTree object). + +=cut + +sub new { + ## Determine if we were called via an object-ref or a classname + my $this = shift; + my $class = ref($this) || $this; + + ## See if first argument has no keyword + if (((@_ <= 2) or (@_ % 2)) and $_[0] !~ /^-\w/) { + ## Yup - need an implicit '-name' before first parameter + unshift @_, '-name'; + } + + ## See if odd number of args + if ((@_ % 2) != 0) { + ## Yup - need an implicit '-ptree' before the last parameter + splice @_, $#_, 0, '-ptree'; + } + + ## Any remaining arguments are treated as initial values for the + ## hash that is used to represent this object. Note that we default + ## certain values by specifying them *before* the arguments passed. + ## If they are in the argument list, they will override the defaults. + my $self = { + -name => (@_ == 1) ? $_[0] : undef, + -file => '<unknown-file>', + -line => 0, + -ldelim => '<', + -rdelim => '>', + @_ + }; + + ## Initialize contents if they havent been already + my $ptree = $self->{'-ptree'} || new Pod::ParseTree(); + if ( ref $ptree =~ /^(ARRAY)?$/ ) { + ## We have an array-ref, or a normal scalar. Pass it as an + ## an argument to the ptree-constructor + $ptree = new Pod::ParseTree($1 ? [$ptree] : $ptree); + } + $self->{'-ptree'} = $ptree; + + ## Bless ourselves into the desired class and perform any initialization + bless $self, $class; + return $self; +} + +##--------------------------------------------------------------------------- + +=head2 $pod_seq-E<gt>B<cmd_name()> + + my $seq_cmd = $pod_seq->cmd_name(); + +The name of the interior sequence command. + +=cut + +sub cmd_name { + (@_ > 1) and $_[0]->{'-name'} = $_[1]; + return $_[0]->{'-name'}; +} + +## let name() be an alias for cmd_name() +*name = \&cmd_name; + +##--------------------------------------------------------------------------- + +## Private subroutine to set the parent pointer of all the given +## children that are interior-sequences to be $self + +sub _set_child2parent_links { + my ($self, @children) = @_; + ## Make sure any sequences know who their parent is + for (@children) { + next unless (length and ref and ref ne 'SCALAR'); + if (UNIVERSAL::isa($_, 'Pod::InteriorSequence') or + UNIVERSAL::can($_, 'nested')) + { + $_->nested($self); + } + } +} + +## Private subroutine to unset child->parent links + +sub _unset_child2parent_links { + my $self = shift; + $self->{'-parent_sequence'} = undef; + my $ptree = $self->{'-ptree'}; + for (@$ptree) { + next unless (length and ref and ref ne 'SCALAR'); + $_->_unset_child2parent_links() + if UNIVERSAL::isa($_, 'Pod::InteriorSequence'); + } +} + +##--------------------------------------------------------------------------- + +=head2 $pod_seq-E<gt>B<prepend()> + + $pod_seq->prepend($text); + $pod_seq1->prepend($pod_seq2); + +Prepends the given string or parse-tree or sequence object to the parse-tree +of this interior sequence. + +=cut + +sub prepend { + my $self = shift; + $self->{'-ptree'}->prepend(@_); + _set_child2parent_links($self, @_); + return $self; +} + +##--------------------------------------------------------------------------- + +=head2 $pod_seq-E<gt>B<append()> + + $pod_seq->append($text); + $pod_seq1->append($pod_seq2); + +Appends the given string or parse-tree or sequence object to the parse-tree +of this interior sequence. + +=cut + +sub append { + my $self = shift; + $self->{'-ptree'}->append(@_); + _set_child2parent_links($self, @_); + return $self; +} + +##--------------------------------------------------------------------------- + +=head2 $pod_seq-E<gt>B<nested()> + + $outer_seq = $pod_seq->nested || print "not nested"; + +If this interior sequence is nested inside of another interior +sequence, then the outer/parent sequence that contains it is +returned. Otherwise C<undef> is returned. + +=cut + +sub nested { + my $self = shift; + (@_ == 1) and $self->{'-parent_sequence'} = shift; + return $self->{'-parent_sequence'} || undef; +} + +##--------------------------------------------------------------------------- + +=head2 $pod_seq-E<gt>B<raw_text()> + + my $seq_raw_text = $pod_seq->raw_text(); + +This method will return the I<raw> text of the POD interior sequence, +exactly as it appeared in the input. + +=cut + +sub raw_text { + my $self = shift; + my $text = $self->{'-name'} . $self->{'-ldelim'}; + for ( $self->{'-ptree'}->children ) { + $text .= (ref $_) ? $_->raw_text : $_; + } + $text .= $self->{'-rdelim'}; + return $text; +} + +##--------------------------------------------------------------------------- + +=head2 $pod_seq-E<gt>B<left_delimiter()> + + my $ldelim = $pod_seq->left_delimiter(); + +The leftmost delimiter beginning the argument text to the interior +sequence (should be "<"). + +=cut + +sub left_delimiter { + (@_ > 1) and $_[0]->{'-ldelim'} = $_[1]; + return $_[0]->{'-ldelim'}; +} + +## let ldelim() be an alias for left_delimiter() +*ldelim = \&left_delimiter; + +##--------------------------------------------------------------------------- + +=head2 $pod_seq-E<gt>B<right_delimiter()> + +The rightmost delimiter beginning the argument text to the interior +sequence (should be ">"). + +=cut + +sub right_delimiter { + (@_ > 1) and $_[0]->{'-rdelim'} = $_[1]; + return $_[0]->{'-rdelim'}; +} + +## let rdelim() be an alias for right_delimiter() +*rdelim = \&right_delimiter; + +##--------------------------------------------------------------------------- + +=head2 $pod_seq-E<gt>B<parse_tree()> + + my $ptree = $pod_parser->parse_text($paragraph_text); + $pod_seq->parse_tree( $ptree ); + $ptree = $pod_seq->parse_tree(); + +This method will get/set the corresponding parse-tree of the interior +sequence's text. + +=cut + +sub parse_tree { + (@_ > 1) and $_[0]->{'-ptree'} = $_[1]; + return $_[0]->{'-ptree'}; +} + +## let ptree() be an alias for parse_tree() +*ptree = \&parse_tree; + +##--------------------------------------------------------------------------- + +=head2 $pod_seq-E<gt>B<file_line()> + + my ($filename, $line_number) = $pod_seq->file_line(); + my $position = $pod_seq->file_line(); + +Returns the current filename and line number for the interior sequence +object. If called in a list context, it returns a list of two +elements: first the filename, then the line number. If called in +a scalar context, it returns a string containing the filename, followed +by a colon (':'), followed by the line number. + +=cut + +sub file_line { + my @loc = ($_[0]->{'-file'} || '<unknown-file>', + $_[0]->{'-line'} || 0); + return (wantarray) ? @loc : join(':', @loc); +} + +##--------------------------------------------------------------------------- + +=head2 Pod::InteriorSequence::B<DESTROY()> + +This method performs any necessary cleanup for the interior-sequence. +If you override this method then it is B<imperative> that you invoke +the parent method from within your own method, otherwise +I<interior-sequence storage will not be reclaimed upon destruction!> + +=cut + +sub DESTROY { + ## We need to get rid of all child->parent pointers throughout the + ## tree so their reference counts will go to zero and they can be + ## garbage-collected + _unset_child2parent_links(@_); +} + +##--------------------------------------------------------------------------- + +############################################################################# + +package Pod::ParseTree; + +##--------------------------------------------------------------------------- + +=head1 B<Pod::ParseTree> + +This object corresponds to a tree of parsed POD text. As POD text is +scanned from left to right, it is parsed into an ordered list of +text-strings and B<Pod::InteriorSequence> objects (in order of +appearance). A B<Pod::ParseTree> object corresponds to this list of +strings and sequences. Each interior sequence in the parse-tree may +itself contain a parse-tree (since interior sequences may be nested). + +=cut + +##--------------------------------------------------------------------------- + +=head2 Pod::ParseTree-E<gt>B<new()> + + my $ptree1 = Pod::ParseTree->new; + my $ptree2 = new Pod::ParseTree; + my $ptree4 = Pod::ParseTree->new($array_ref); + my $ptree3 = new Pod::ParseTree($array_ref); + +This is a class method that constructs a C<Pod::Parse_tree> object and +returns a reference to the new parse-tree. If a single-argument is given, +it must be a reference to an array, and is used to initialize the root +(top) of the parse tree. + +=cut + +sub new { + ## Determine if we were called via an object-ref or a classname + my $this = shift; + my $class = ref($this) || $this; + + my $self = (@_ == 1 and ref $_[0]) ? $_[0] : []; + + ## Bless ourselves into the desired class and perform any initialization + bless $self, $class; + return $self; +} + +##--------------------------------------------------------------------------- + +=head2 $ptree-E<gt>B<top()> + + my $top_node = $ptree->top(); + $ptree->top( $top_node ); + $ptree->top( @children ); + +This method gets/sets the top node of the parse-tree. If no arguments are +given, it returns the topmost node in the tree (the root), which is also +a B<Pod::ParseTree>. If it is given a single argument that is a reference, +then the reference is assumed to a parse-tree and becomes the new top node. +Otherwise, if arguments are given, they are treated as the new list of +children for the top node. + +=cut + +sub top { + my $self = shift; + if (@_ > 0) { + @{ $self } = (@_ == 1 and ref $_[0]) ? ${ @_ } : @_; + } + return $self; +} + +## let parse_tree() & ptree() be aliases for the 'top' method +*parse_tree = *ptree = \⊤ + +##--------------------------------------------------------------------------- + +=head2 $ptree-E<gt>B<children()> + +This method gets/sets the children of the top node in the parse-tree. +If no arguments are given, it returns the list (array) of children +(each of which should be either a string or a B<Pod::InteriorSequence>. +Otherwise, if arguments are given, they are treated as the new list of +children for the top node. + +=cut + +sub children { + my $self = shift; + if (@_ > 0) { + @{ $self } = (@_ == 1 and ref $_[0]) ? ${ @_ } : @_; + } + return @{ $self }; +} + +##--------------------------------------------------------------------------- + +=head2 $ptree-E<gt>B<prepend()> + +This method prepends the given text or parse-tree to the current parse-tree. +If the first item on the parse-tree is text and the argument is also text, +then the text is prepended to the first item (not added as a separate string). +Otherwise the argument is added as a new string or parse-tree I<before> +the current one. + +=cut + +use vars qw(@ptree); ## an alias used for performance reasons + +sub prepend { + my $self = shift; + local *ptree = $self; + for (@_) { + next unless length; + if (@ptree and !(ref $ptree[0]) and !(ref $_)) { + $ptree[0] = $_ . $ptree[0]; + } + else { + unshift @ptree, $_; + } + } +} + +##--------------------------------------------------------------------------- + +=head2 $ptree-E<gt>B<append()> + +This method appends the given text or parse-tree to the current parse-tree. +If the last item on the parse-tree is text and the argument is also text, +then the text is appended to the last item (not added as a separate string). +Otherwise the argument is added as a new string or parse-tree I<after> +the current one. + +=cut + +sub append { + my $self = shift; + local *ptree = $self; + my $can_append = @ptree && !(ref $ptree[-1]); + for (@_) { + if (ref) { + push @ptree, $_; + } + elsif(!length) { + next; + } + elsif ($can_append) { + $ptree[-1] .= $_; + } + else { + push @ptree, $_; + } + } +} + +=head2 $ptree-E<gt>B<raw_text()> + + my $ptree_raw_text = $ptree->raw_text(); + +This method will return the I<raw> text of the POD parse-tree +exactly as it appeared in the input. + +=cut + +sub raw_text { + my $self = shift; + my $text = ""; + for ( @$self ) { + $text .= (ref $_) ? $_->raw_text : $_; + } + return $text; +} + +##--------------------------------------------------------------------------- + +## Private routines to set/unset child->parent links + +sub _unset_child2parent_links { + my $self = shift; + local *ptree = $self; + for (@ptree) { + next unless (defined and length and ref and ref ne 'SCALAR'); + $_->_unset_child2parent_links() + if UNIVERSAL::isa($_, 'Pod::InteriorSequence'); + } +} + +sub _set_child2parent_links { + ## nothing to do, Pod::ParseTrees cant have parent pointers +} + +=head2 Pod::ParseTree::B<DESTROY()> + +This method performs any necessary cleanup for the parse-tree. +If you override this method then it is B<imperative> +that you invoke the parent method from within your own method, +otherwise I<parse-tree storage will not be reclaimed upon destruction!> + +=cut + +sub DESTROY { + ## We need to get rid of all child->parent pointers throughout the + ## tree so their reference counts will go to zero and they can be + ## garbage-collected + _unset_child2parent_links(@_); +} + +############################################################################# + +=head1 SEE ALSO + +See L<Pod::Parser>, L<Pod::Select> + +=head1 AUTHOR + +Please report bugs using L<http://rt.cpan.org>. + +Brad Appleton E<lt>bradapp@enteract.comE<gt> + +=cut + +1; diff --git a/Master/tlpkg/installer/perllib/Pod/ParseLink.pm b/Master/tlpkg/installer/perllib/Pod/ParseLink.pm new file mode 100644 index 00000000000..7e4153da3d0 --- /dev/null +++ b/Master/tlpkg/installer/perllib/Pod/ParseLink.pm @@ -0,0 +1,184 @@ +# Pod::ParseLink -- Parse an L<> formatting code in POD text. +# $Id: ParseLink.pm,v 1.6 2002/07/15 05:46:00 eagle Exp $ +# +# Copyright 2001 by Russ Allbery <rra@stanford.edu> +# +# This program is free software; you may redistribute it and/or modify it +# under the same terms as Perl itself. +# +# This module implements parsing of the text of an L<> formatting code as +# defined in perlpodspec. It should be suitable for any POD formatter. It +# exports only one function, parselink(), which returns the five-item parse +# defined in perlpodspec. +# +# Perl core hackers, please note that this module is also separately +# maintained outside of the Perl core as part of the podlators. Please send +# me any patches at the address above in addition to sending them to the +# standard Perl mailing lists. + +############################################################################## +# Modules and declarations +############################################################################## + +package Pod::ParseLink; + +require 5.004; + +use strict; +use vars qw(@EXPORT @ISA $VERSION); + +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(parselink); + +# Don't use the CVS revision as the version, since this module is also in Perl +# core and too many things could munge CVS magic revision strings. This +# number should ideally be the same as the CVS revision in podlators, however. +$VERSION = 1.06; + + +############################################################################## +# Implementation +############################################################################## + +# Parse the name and section portion of a link into a name and section. +sub _parse_section { + my ($link) = @_; + $link =~ s/^\s+//; + $link =~ s/\s+$//; + + # If the whole link is enclosed in quotes, interpret it all as a section + # even if it contains a slash. + return (undef, $1) if ($link =~ /^"\s*(.*?)\s*"$/); + + # Split into page and section on slash, and then clean up quoting in the + # section. If there is no section and the name contains spaces, also + # guess that it's an old section link. + my ($page, $section) = split (/\s*\/\s*/, $link, 2); + $section =~ s/^"\s*(.*?)\s*"$/$1/ if $section; + if ($page && $page =~ / / && !defined ($section)) { + $section = $page; + $page = undef; + } else { + $page = undef unless $page; + $section = undef unless $section; + } + return ($page, $section); +} + +# Infer link text from the page and section. +sub _infer_text { + my ($page, $section) = @_; + my $inferred; + if ($page && !$section) { + $inferred = $page; + } elsif (!$page && $section) { + $inferred = '"' . $section . '"'; + } elsif ($page && $section) { + $inferred = '"' . $section . '" in ' . $page; + } + return $inferred; +} + +# Given the contents of an L<> formatting code, parse it into the link text, +# the possibly inferred link text, the name or URL, the section, and the type +# of link (pod, man, or url). +sub parselink { + my ($link) = @_; + $link =~ s/\s+/ /g; + if ($link =~ /\A\w+:[^:\s]\S*\Z/) { + return (undef, $link, $link, undef, 'url'); + } else { + my $text; + if ($link =~ /\|/) { + ($text, $link) = split (/\|/, $link, 2); + } + my ($name, $section) = _parse_section ($link); + my $inferred = $text || _infer_text ($name, $section); + my $type = ($name && $name =~ /\(\S*\)/) ? 'man' : 'pod'; + return ($text, $inferred, $name, $section, $type); + } +} + + +############################################################################## +# Module return value and documentation +############################################################################## + +# Ensure we evaluate to true. +1; +__END__ + +=head1 NAME + +Pod::ParseLink - Parse an LE<lt>E<gt> formatting code in POD text + +=head1 SYNOPSIS + + use Pod::ParseLink; + my ($text, $inferred, $name, $section, $type) = parselink ($link); + +=head1 DESCRIPTION + +This module only provides a single function, parselink(), which takes the +text of an LE<lt>E<gt> formatting code and parses it. It returns the anchor +text for the link (if any was given), the anchor text possibly inferred from +the name and section, the name or URL, the section if any, and the type of +link. The type will be one of 'url', 'pod', or 'man', indicating a URL, a +link to a POD page, or a link to a Unix manual page. + +Parsing is implemented per L<perlpodspec>. For backward compatibility, +links where there is no section and name contains spaces, or links where the +entirety of the link (except for the anchor text if given) is enclosed in +double-quotes are interpreted as links to a section (LE<lt>/sectionE<gt>). + +The inferred anchor text is implemented per L<perlpodspec>: + + L<name> => L<name|name> + L</section> => L<"section"|/section> + L<name/section> => L<"section" in name|name/section> + +The name may contain embedded EE<lt>E<gt> and ZE<lt>E<gt> formatting codes, +and the section, anchor text, and inferred anchor text may contain any +formatting codes. Any double quotes around the section are removed as part +of the parsing, as is any leading or trailing whitespace. + +If the text of the LE<lt>E<gt> escape is entirely enclosed in double quotes, +it's interpreted as a link to a section for backwards compatibility. + +No attempt is made to resolve formatting codes. This must be done after +calling parselink (since EE<lt>E<gt> formatting codes can be used to escape +characters that would otherwise be significant to the parser and resolving +them before parsing would result in an incorrect parse of a formatting code +like: + + L<verticalE<verbar>barE<sol>slash> + +which should be interpreted as a link to the C<vertical|bar/slash> POD page +and not as a link to the C<slash> section of the C<bar> POD page with an +anchor text of C<vertical>. Note that not only the anchor text will need to +have formatting codes expanded, but so will the target of the link (to deal +with EE<lt>E<gt> and ZE<lt>E<gt> formatting codes), and special handling of +the section may be necessary depending on whether the translator wants to +consider markup in sections to be significant when resolving links. See +L<perlpodspec> for more information. + +=head1 SEE ALSO + +L<Pod::Parser> + +The current version of this module is always available from its web site at +L<http://www.eyrie.org/~eagle/software/podlators/>. + +=head1 AUTHOR + +Russ Allbery <rra@stanford.edu>. + +=head1 COPYRIGHT AND LICENSE + +Copyright 2001 by Russ Allbery <rra@stanford.edu>. + +This program is free software; you may redistribute it and/or modify it +under the same terms as Perl itself. + +=cut diff --git a/Master/tlpkg/installer/perllib/Pod/Parser.pm b/Master/tlpkg/installer/perllib/Pod/Parser.pm new file mode 100644 index 00000000000..a5fde848503 --- /dev/null +++ b/Master/tlpkg/installer/perllib/Pod/Parser.pm @@ -0,0 +1,1799 @@ +############################################################################# +# Pod/Parser.pm -- package which defines a base class for parsing POD docs. +# +# Copyright (C) 1996-2000 by Bradford Appleton. All rights reserved. +# This file is part of "PodParser". PodParser is free software; +# you can redistribute it and/or modify it under the same terms +# as Perl itself. +############################################################################# + +package Pod::Parser; + +use vars qw($VERSION); +$VERSION = 1.32; ## Current version of this package +require 5.005; ## requires this Perl version or later + +############################################################################# + +=head1 NAME + +Pod::Parser - base class for creating POD filters and translators + +=head1 SYNOPSIS + + use Pod::Parser; + + package MyParser; + @ISA = qw(Pod::Parser); + + sub command { + my ($parser, $command, $paragraph, $line_num) = @_; + ## Interpret the command and its text; sample actions might be: + if ($command eq 'head1') { ... } + elsif ($command eq 'head2') { ... } + ## ... other commands and their actions + my $out_fh = $parser->output_handle(); + my $expansion = $parser->interpolate($paragraph, $line_num); + print $out_fh $expansion; + } + + sub verbatim { + my ($parser, $paragraph, $line_num) = @_; + ## Format verbatim paragraph; sample actions might be: + my $out_fh = $parser->output_handle(); + print $out_fh $paragraph; + } + + sub textblock { + my ($parser, $paragraph, $line_num) = @_; + ## Translate/Format this block of text; sample actions might be: + my $out_fh = $parser->output_handle(); + my $expansion = $parser->interpolate($paragraph, $line_num); + print $out_fh $expansion; + } + + sub interior_sequence { + my ($parser, $seq_command, $seq_argument) = @_; + ## Expand an interior sequence; sample actions might be: + return "*$seq_argument*" if ($seq_command eq 'B'); + return "`$seq_argument'" if ($seq_command eq 'C'); + return "_${seq_argument}_'" if ($seq_command eq 'I'); + ## ... other sequence commands and their resulting text + } + + package main; + + ## Create a parser object and have it parse file whose name was + ## given on the command-line (use STDIN if no files were given). + $parser = new MyParser(); + $parser->parse_from_filehandle(\*STDIN) if (@ARGV == 0); + for (@ARGV) { $parser->parse_from_file($_); } + +=head1 REQUIRES + +perl5.005, Pod::InputObjects, Exporter, Symbol, Carp + +=head1 EXPORTS + +Nothing. + +=head1 DESCRIPTION + +B<Pod::Parser> is a base class for creating POD filters and translators. +It handles most of the effort involved with parsing the POD sections +from an input stream, leaving subclasses free to be concerned only with +performing the actual translation of text. + +B<Pod::Parser> parses PODs, and makes method calls to handle the various +components of the POD. Subclasses of B<Pod::Parser> override these methods +to translate the POD into whatever output format they desire. + +=head1 QUICK OVERVIEW + +To create a POD filter for translating POD documentation into some other +format, you create a subclass of B<Pod::Parser> which typically overrides +just the base class implementation for the following methods: + +=over 2 + +=item * + +B<command()> + +=item * + +B<verbatim()> + +=item * + +B<textblock()> + +=item * + +B<interior_sequence()> + +=back + +You may also want to override the B<begin_input()> and B<end_input()> +methods for your subclass (to perform any needed per-file and/or +per-document initialization or cleanup). + +If you need to perform any preprocesssing of input before it is parsed +you may want to override one or more of B<preprocess_line()> and/or +B<preprocess_paragraph()>. + +Sometimes it may be necessary to make more than one pass over the input +files. If this is the case you have several options. You can make the +first pass using B<Pod::Parser> and override your methods to store the +intermediate results in memory somewhere for the B<end_pod()> method to +process. You could use B<Pod::Parser> for several passes with an +appropriate state variable to control the operation for each pass. If +your input source can't be reset to start at the beginning, you can +store it in some other structure as a string or an array and have that +structure implement a B<getline()> method (which is all that +B<parse_from_filehandle()> uses to read input). + +Feel free to add any member data fields you need to keep track of things +like current font, indentation, horizontal or vertical position, or +whatever else you like. Be sure to read L<"PRIVATE METHODS AND DATA"> +to avoid name collisions. + +For the most part, the B<Pod::Parser> base class should be able to +do most of the input parsing for you and leave you free to worry about +how to intepret the commands and translate the result. + +Note that all we have described here in this quick overview is the +simplest most straightforward use of B<Pod::Parser> to do stream-based +parsing. It is also possible to use the B<Pod::Parser::parse_text> function +to do more sophisticated tree-based parsing. See L<"TREE-BASED PARSING">. + +=head1 PARSING OPTIONS + +A I<parse-option> is simply a named option of B<Pod::Parser> with a +value that corresponds to a certain specified behavior. These various +behaviors of B<Pod::Parser> may be enabled/disabled by setting +or unsetting one or more I<parse-options> using the B<parseopts()> method. +The set of currently accepted parse-options is as follows: + +=over 3 + +=item B<-want_nonPODs> (default: unset) + +Normally (by default) B<Pod::Parser> will only provide access to +the POD sections of the input. Input paragraphs that are not part +of the POD-format documentation are not made available to the caller +(not even using B<preprocess_paragraph()>). Setting this option to a +non-empty, non-zero value will allow B<preprocess_paragraph()> to see +non-POD sections of the input as well as POD sections. The B<cutting()> +method can be used to determine if the corresponding paragraph is a POD +paragraph, or some other input paragraph. + +=item B<-process_cut_cmd> (default: unset) + +Normally (by default) B<Pod::Parser> handles the C<=cut> POD directive +by itself and does not pass it on to the caller for processing. Setting +this option to a non-empty, non-zero value will cause B<Pod::Parser> to +pass the C<=cut> directive to the caller just like any other POD command +(and hence it may be processed by the B<command()> method). + +B<Pod::Parser> will still interpret the C<=cut> directive to mean that +"cutting mode" has been (re)entered, but the caller will get a chance +to capture the actual C<=cut> paragraph itself for whatever purpose +it desires. + +=item B<-warnings> (default: unset) + +Normally (by default) B<Pod::Parser> recognizes a bare minimum of +pod syntax errors and warnings and issues diagnostic messages +for errors, but not for warnings. (Use B<Pod::Checker> to do more +thorough checking of POD syntax.) Setting this option to a non-empty, +non-zero value will cause B<Pod::Parser> to issue diagnostics for +the few warnings it recognizes as well as the errors. + +=back + +Please see L<"parseopts()"> for a complete description of the interface +for the setting and unsetting of parse-options. + +=cut + +############################################################################# + +use vars qw(@ISA); +use strict; +#use diagnostics; +use Pod::InputObjects; +use Carp; +use Exporter; +BEGIN { + if ($] < 5.6) { + require Symbol; + import Symbol; + } +} +@ISA = qw(Exporter); + +## These "variables" are used as local "glob aliases" for performance +use vars qw(%myData %myOpts @input_stack); + +############################################################################# + +=head1 RECOMMENDED SUBROUTINE/METHOD OVERRIDES + +B<Pod::Parser> provides several methods which most subclasses will probably +want to override. These methods are as follows: + +=cut + +##--------------------------------------------------------------------------- + +=head1 B<command()> + + $parser->command($cmd,$text,$line_num,$pod_para); + +This method should be overridden by subclasses to take the appropriate +action when a POD command paragraph (denoted by a line beginning with +"=") is encountered. When such a POD directive is seen in the input, +this method is called and is passed: + +=over 3 + +=item C<$cmd> + +the name of the command for this POD paragraph + +=item C<$text> + +the paragraph text for the given POD paragraph command. + +=item C<$line_num> + +the line-number of the beginning of the paragraph + +=item C<$pod_para> + +a reference to a C<Pod::Paragraph> object which contains further +information about the paragraph command (see L<Pod::InputObjects> +for details). + +=back + +B<Note> that this method I<is> called for C<=pod> paragraphs. + +The base class implementation of this method simply treats the raw POD +command as normal block of paragraph text (invoking the B<textblock()> +method with the command paragraph). + +=cut + +sub command { + my ($self, $cmd, $text, $line_num, $pod_para) = @_; + ## Just treat this like a textblock + $self->textblock($pod_para->raw_text(), $line_num, $pod_para); +} + +##--------------------------------------------------------------------------- + +=head1 B<verbatim()> + + $parser->verbatim($text,$line_num,$pod_para); + +This method may be overridden by subclasses to take the appropriate +action when a block of verbatim text is encountered. It is passed the +following parameters: + +=over 3 + +=item C<$text> + +the block of text for the verbatim paragraph + +=item C<$line_num> + +the line-number of the beginning of the paragraph + +=item C<$pod_para> + +a reference to a C<Pod::Paragraph> object which contains further +information about the paragraph (see L<Pod::InputObjects> +for details). + +=back + +The base class implementation of this method simply prints the textblock +(unmodified) to the output filehandle. + +=cut + +sub verbatim { + my ($self, $text, $line_num, $pod_para) = @_; + my $out_fh = $self->{_OUTPUT}; + print $out_fh $text; +} + +##--------------------------------------------------------------------------- + +=head1 B<textblock()> + + $parser->textblock($text,$line_num,$pod_para); + +This method may be overridden by subclasses to take the appropriate +action when a normal block of POD text is encountered (although the base +class method will usually do what you want). It is passed the following +parameters: + +=over 3 + +=item C<$text> + +the block of text for the a POD paragraph + +=item C<$line_num> + +the line-number of the beginning of the paragraph + +=item C<$pod_para> + +a reference to a C<Pod::Paragraph> object which contains further +information about the paragraph (see L<Pod::InputObjects> +for details). + +=back + +In order to process interior sequences, subclasses implementations of +this method will probably want to invoke either B<interpolate()> or +B<parse_text()>, passing it the text block C<$text>, and the corresponding +line number in C<$line_num>, and then perform any desired processing upon +the returned result. + +The base class implementation of this method simply prints the text block +as it occurred in the input stream). + +=cut + +sub textblock { + my ($self, $text, $line_num, $pod_para) = @_; + my $out_fh = $self->{_OUTPUT}; + print $out_fh $self->interpolate($text, $line_num); +} + +##--------------------------------------------------------------------------- + +=head1 B<interior_sequence()> + + $parser->interior_sequence($seq_cmd,$seq_arg,$pod_seq); + +This method should be overridden by subclasses to take the appropriate +action when an interior sequence is encountered. An interior sequence is +an embedded command within a block of text which appears as a command +name (usually a single uppercase character) followed immediately by a +string of text which is enclosed in angle brackets. This method is +passed the sequence command C<$seq_cmd> and the corresponding text +C<$seq_arg>. It is invoked by the B<interpolate()> method for each interior +sequence that occurs in the string that it is passed. It should return +the desired text string to be used in place of the interior sequence. +The C<$pod_seq> argument is a reference to a C<Pod::InteriorSequence> +object which contains further information about the interior sequence. +Please see L<Pod::InputObjects> for details if you need to access this +additional information. + +Subclass implementations of this method may wish to invoke the +B<nested()> method of C<$pod_seq> to see if it is nested inside +some other interior-sequence (and if so, which kind). + +The base class implementation of the B<interior_sequence()> method +simply returns the raw text of the interior sequence (as it occurred +in the input) to the caller. + +=cut + +sub interior_sequence { + my ($self, $seq_cmd, $seq_arg, $pod_seq) = @_; + ## Just return the raw text of the interior sequence + return $pod_seq->raw_text(); +} + +############################################################################# + +=head1 OPTIONAL SUBROUTINE/METHOD OVERRIDES + +B<Pod::Parser> provides several methods which subclasses may want to override +to perform any special pre/post-processing. These methods do I<not> have to +be overridden, but it may be useful for subclasses to take advantage of them. + +=cut + +##--------------------------------------------------------------------------- + +=head1 B<new()> + + my $parser = Pod::Parser->new(); + +This is the constructor for B<Pod::Parser> and its subclasses. You +I<do not> need to override this method! It is capable of constructing +subclass objects as well as base class objects, provided you use +any of the following constructor invocation styles: + + my $parser1 = MyParser->new(); + my $parser2 = new MyParser(); + my $parser3 = $parser2->new(); + +where C<MyParser> is some subclass of B<Pod::Parser>. + +Using the syntax C<MyParser::new()> to invoke the constructor is I<not> +recommended, but if you insist on being able to do this, then the +subclass I<will> need to override the B<new()> constructor method. If +you do override the constructor, you I<must> be sure to invoke the +B<initialize()> method of the newly blessed object. + +Using any of the above invocations, the first argument to the +constructor is always the corresponding package name (or object +reference). No other arguments are required, but if desired, an +associative array (or hash-table) my be passed to the B<new()> +constructor, as in: + + my $parser1 = MyParser->new( MYDATA => $value1, MOREDATA => $value2 ); + my $parser2 = new MyParser( -myflag => 1 ); + +All arguments passed to the B<new()> constructor will be treated as +key/value pairs in a hash-table. The newly constructed object will be +initialized by copying the contents of the given hash-table (which may +have been empty). The B<new()> constructor for this class and all of its +subclasses returns a blessed reference to the initialized object (hash-table). + +=cut + +sub new { + ## Determine if we were called via an object-ref or a classname + my $this = shift; + my $class = ref($this) || $this; + ## Any remaining arguments are treated as initial values for the + ## hash that is used to represent this object. + my %params = @_; + my $self = { %params }; + ## Bless ourselves into the desired class and perform any initialization + bless $self, $class; + $self->initialize(); + return $self; +} + +##--------------------------------------------------------------------------- + +=head1 B<initialize()> + + $parser->initialize(); + +This method performs any necessary object initialization. It takes no +arguments (other than the object instance of course, which is typically +copied to a local variable named C<$self>). If subclasses override this +method then they I<must> be sure to invoke C<$self-E<gt>SUPER::initialize()>. + +=cut + +sub initialize { + #my $self = shift; + #return; +} + +##--------------------------------------------------------------------------- + +=head1 B<begin_pod()> + + $parser->begin_pod(); + +This method is invoked at the beginning of processing for each POD +document that is encountered in the input. Subclasses should override +this method to perform any per-document initialization. + +=cut + +sub begin_pod { + #my $self = shift; + #return; +} + +##--------------------------------------------------------------------------- + +=head1 B<begin_input()> + + $parser->begin_input(); + +This method is invoked by B<parse_from_filehandle()> immediately I<before> +processing input from a filehandle. The base class implementation does +nothing, however, subclasses may override it to perform any per-file +initializations. + +Note that if multiple files are parsed for a single POD document +(perhaps the result of some future C<=include> directive) this method +is invoked for every file that is parsed. If you wish to perform certain +initializations once per document, then you should use B<begin_pod()>. + +=cut + +sub begin_input { + #my $self = shift; + #return; +} + +##--------------------------------------------------------------------------- + +=head1 B<end_input()> + + $parser->end_input(); + +This method is invoked by B<parse_from_filehandle()> immediately I<after> +processing input from a filehandle. The base class implementation does +nothing, however, subclasses may override it to perform any per-file +cleanup actions. + +Please note that if multiple files are parsed for a single POD document +(perhaps the result of some kind of C<=include> directive) this method +is invoked for every file that is parsed. If you wish to perform certain +cleanup actions once per document, then you should use B<end_pod()>. + +=cut + +sub end_input { + #my $self = shift; + #return; +} + +##--------------------------------------------------------------------------- + +=head1 B<end_pod()> + + $parser->end_pod(); + +This method is invoked at the end of processing for each POD document +that is encountered in the input. Subclasses should override this method +to perform any per-document finalization. + +=cut + +sub end_pod { + #my $self = shift; + #return; +} + +##--------------------------------------------------------------------------- + +=head1 B<preprocess_line()> + + $textline = $parser->preprocess_line($text, $line_num); + +This method should be overridden by subclasses that wish to perform +any kind of preprocessing for each I<line> of input (I<before> it has +been determined whether or not it is part of a POD paragraph). The +parameter C<$text> is the input line; and the parameter C<$line_num> is +the line number of the corresponding text line. + +The value returned should correspond to the new text to use in its +place. If the empty string or an undefined value is returned then no +further processing will be performed for this line. + +Please note that the B<preprocess_line()> method is invoked I<before> +the B<preprocess_paragraph()> method. After all (possibly preprocessed) +lines in a paragraph have been assembled together and it has been +determined that the paragraph is part of the POD documentation from one +of the selected sections, then B<preprocess_paragraph()> is invoked. + +The base class implementation of this method returns the given text. + +=cut + +sub preprocess_line { + my ($self, $text, $line_num) = @_; + return $text; +} + +##--------------------------------------------------------------------------- + +=head1 B<preprocess_paragraph()> + + $textblock = $parser->preprocess_paragraph($text, $line_num); + +This method should be overridden by subclasses that wish to perform any +kind of preprocessing for each block (paragraph) of POD documentation +that appears in the input stream. The parameter C<$text> is the POD +paragraph from the input file; and the parameter C<$line_num> is the +line number for the beginning of the corresponding paragraph. + +The value returned should correspond to the new text to use in its +place If the empty string is returned or an undefined value is +returned, then the given C<$text> is ignored (not processed). + +This method is invoked after gathering up all the lines in a paragraph +and after determining the cutting state of the paragraph, +but before trying to further parse or interpret them. After +B<preprocess_paragraph()> returns, the current cutting state (which +is returned by C<$self-E<gt>cutting()>) is examined. If it evaluates +to true then input text (including the given C<$text>) is cut (not +processed) until the next POD directive is encountered. + +Please note that the B<preprocess_line()> method is invoked I<before> +the B<preprocess_paragraph()> method. After all (possibly preprocessed) +lines in a paragraph have been assembled together and either it has been +determined that the paragraph is part of the POD documentation from one +of the selected sections or the C<-want_nonPODs> option is true, +then B<preprocess_paragraph()> is invoked. + +The base class implementation of this method returns the given text. + +=cut + +sub preprocess_paragraph { + my ($self, $text, $line_num) = @_; + return $text; +} + +############################################################################# + +=head1 METHODS FOR PARSING AND PROCESSING + +B<Pod::Parser> provides several methods to process input text. These +methods typically won't need to be overridden (and in some cases they +can't be overridden), but subclasses may want to invoke them to exploit +their functionality. + +=cut + +##--------------------------------------------------------------------------- + +=head1 B<parse_text()> + + $ptree1 = $parser->parse_text($text, $line_num); + $ptree2 = $parser->parse_text({%opts}, $text, $line_num); + $ptree3 = $parser->parse_text(\%opts, $text, $line_num); + +This method is useful if you need to perform your own interpolation +of interior sequences and can't rely upon B<interpolate> to expand +them in simple bottom-up order. + +The parameter C<$text> is a string or block of text to be parsed +for interior sequences; and the parameter C<$line_num> is the +line number curresponding to the beginning of C<$text>. + +B<parse_text()> will parse the given text into a parse-tree of "nodes." +and interior-sequences. Each "node" in the parse tree is either a +text-string, or a B<Pod::InteriorSequence>. The result returned is a +parse-tree of type B<Pod::ParseTree>. Please see L<Pod::InputObjects> +for more information about B<Pod::InteriorSequence> and B<Pod::ParseTree>. + +If desired, an optional hash-ref may be specified as the first argument +to customize certain aspects of the parse-tree that is created and +returned. The set of recognized option keywords are: + +=over 3 + +=item B<-expand_seq> =E<gt> I<code-ref>|I<method-name> + +Normally, the parse-tree returned by B<parse_text()> will contain an +unexpanded C<Pod::InteriorSequence> object for each interior-sequence +encountered. Specifying B<-expand_seq> tells B<parse_text()> to "expand" +every interior-sequence it sees by invoking the referenced function +(or named method of the parser object) and using the return value as the +expanded result. + +If a subroutine reference was given, it is invoked as: + + &$code_ref( $parser, $sequence ) + +and if a method-name was given, it is invoked as: + + $parser->method_name( $sequence ) + +where C<$parser> is a reference to the parser object, and C<$sequence> +is a reference to the interior-sequence object. +[I<NOTE>: If the B<interior_sequence()> method is specified, then it is +invoked according to the interface specified in L<"interior_sequence()">]. + +=item B<-expand_text> =E<gt> I<code-ref>|I<method-name> + +Normally, the parse-tree returned by B<parse_text()> will contain a +text-string for each contiguous sequence of characters outside of an +interior-sequence. Specifying B<-expand_text> tells B<parse_text()> to +"preprocess" every such text-string it sees by invoking the referenced +function (or named method of the parser object) and using the return value +as the preprocessed (or "expanded") result. [Note that if the result is +an interior-sequence, then it will I<not> be expanded as specified by the +B<-expand_seq> option; Any such recursive expansion needs to be handled by +the specified callback routine.] + +If a subroutine reference was given, it is invoked as: + + &$code_ref( $parser, $text, $ptree_node ) + +and if a method-name was given, it is invoked as: + + $parser->method_name( $text, $ptree_node ) + +where C<$parser> is a reference to the parser object, C<$text> is the +text-string encountered, and C<$ptree_node> is a reference to the current +node in the parse-tree (usually an interior-sequence object or else the +top-level node of the parse-tree). + +=item B<-expand_ptree> =E<gt> I<code-ref>|I<method-name> + +Rather than returning a C<Pod::ParseTree>, pass the parse-tree as an +argument to the referenced subroutine (or named method of the parser +object) and return the result instead of the parse-tree object. + +If a subroutine reference was given, it is invoked as: + + &$code_ref( $parser, $ptree ) + +and if a method-name was given, it is invoked as: + + $parser->method_name( $ptree ) + +where C<$parser> is a reference to the parser object, and C<$ptree> +is a reference to the parse-tree object. + +=back + +=cut + +sub parse_text { + my $self = shift; + local $_ = ''; + + ## Get options and set any defaults + my %opts = (ref $_[0]) ? %{ shift() } : (); + my $expand_seq = $opts{'-expand_seq'} || undef; + my $expand_text = $opts{'-expand_text'} || undef; + my $expand_ptree = $opts{'-expand_ptree'} || undef; + + my $text = shift; + my $line = shift; + my $file = $self->input_file(); + my $cmd = ""; + + ## Convert method calls into closures, for our convenience + my $xseq_sub = $expand_seq; + my $xtext_sub = $expand_text; + my $xptree_sub = $expand_ptree; + if (defined $expand_seq and $expand_seq eq 'interior_sequence') { + ## If 'interior_sequence' is the method to use, we have to pass + ## more than just the sequence object, we also need to pass the + ## sequence name and text. + $xseq_sub = sub { + my ($self, $iseq) = @_; + my $args = join("", $iseq->parse_tree->children); + return $self->interior_sequence($iseq->name, $args, $iseq); + }; + } + ref $xseq_sub or $xseq_sub = sub { shift()->$expand_seq(@_) }; + ref $xtext_sub or $xtext_sub = sub { shift()->$expand_text(@_) }; + ref $xptree_sub or $xptree_sub = sub { shift()->$expand_ptree(@_) }; + + ## Keep track of the "current" interior sequence, and maintain a stack + ## of "in progress" sequences. + ## + ## NOTE that we push our own "accumulator" at the very beginning of the + ## stack. It's really a parse-tree, not a sequence; but it implements + ## the methods we need so we can use it to gather-up all the sequences + ## and strings we parse. Thus, by the end of our parsing, it should be + ## the only thing left on our stack and all we have to do is return it! + ## + my $seq = Pod::ParseTree->new(); + my @seq_stack = ($seq); + my ($ldelim, $rdelim) = ('', ''); + + ## Iterate over all sequence starts text (NOTE: split with + ## capturing parens keeps the delimiters) + $_ = $text; + my @tokens = split /([A-Z]<(?:<+\s)?)/; + while ( @tokens ) { + $_ = shift @tokens; + ## Look for the beginning of a sequence + if ( /^([A-Z])(<(?:<+\s)?)$/ ) { + ## Push a new sequence onto the stack of those "in-progress" + my $ldelim_orig; + ($cmd, $ldelim_orig) = ($1, $2); + ($ldelim = $ldelim_orig) =~ s/\s+$//; + ($rdelim = $ldelim) =~ tr/</>/; + $seq = Pod::InteriorSequence->new( + -name => $cmd, + -ldelim => $ldelim_orig, -rdelim => $rdelim, + -file => $file, -line => $line + ); + (@seq_stack > 1) and $seq->nested($seq_stack[-1]); + push @seq_stack, $seq; + } + ## Look for sequence ending + elsif ( @seq_stack > 1 ) { + ## Make sure we match the right kind of closing delimiter + my ($seq_end, $post_seq) = ("", ""); + if ( ($ldelim eq '<' and /\A(.*?)(>)/s) + or /\A(.*?)(\s+$rdelim)/s ) + { + ## Found end-of-sequence, capture the interior and the + ## closing the delimiter, and put the rest back on the + ## token-list + $post_seq = substr($_, length($1) + length($2)); + ($_, $seq_end) = ($1, $2); + (length $post_seq) and unshift @tokens, $post_seq; + } + if (length) { + ## In the middle of a sequence, append this text to it, and + ## dont forget to "expand" it if that's what the caller wanted + $seq->append($expand_text ? &$xtext_sub($self,$_,$seq) : $_); + $_ .= $seq_end; + } + if (length $seq_end) { + ## End of current sequence, record terminating delimiter + $seq->rdelim($seq_end); + ## Pop it off the stack of "in progress" sequences + pop @seq_stack; + ## Append result to its parent in current parse tree + $seq_stack[-1]->append($expand_seq ? &$xseq_sub($self,$seq) + : $seq); + ## Remember the current cmd-name and left-delimiter + if(@seq_stack > 1) { + $cmd = $seq_stack[-1]->name; + $ldelim = $seq_stack[-1]->ldelim; + $rdelim = $seq_stack[-1]->rdelim; + } else { + $cmd = $ldelim = $rdelim = ''; + } + } + } + elsif (length) { + ## In the middle of a sequence, append this text to it, and + ## dont forget to "expand" it if that's what the caller wanted + $seq->append($expand_text ? &$xtext_sub($self,$_,$seq) : $_); + } + ## Keep track of line count + $line += tr/\n//; + ## Remember the "current" sequence + $seq = $seq_stack[-1]; + } + + ## Handle unterminated sequences + my $errorsub = (@seq_stack > 1) ? $self->errorsub() : undef; + while (@seq_stack > 1) { + ($cmd, $file, $line) = ($seq->name, $seq->file_line); + $ldelim = $seq->ldelim; + ($rdelim = $ldelim) =~ tr/</>/; + $rdelim =~ s/^(\S+)(\s*)$/$2$1/; + pop @seq_stack; + my $errmsg = "*** ERROR: unterminated ${cmd}${ldelim}...${rdelim}". + " at line $line in file $file\n"; + (ref $errorsub) and &{$errorsub}($errmsg) + or (defined $errorsub) and $self->$errorsub($errmsg) + or warn($errmsg); + $seq_stack[-1]->append($expand_seq ? &$xseq_sub($self,$seq) : $seq); + $seq = $seq_stack[-1]; + } + + ## Return the resulting parse-tree + my $ptree = (pop @seq_stack)->parse_tree; + return $expand_ptree ? &$xptree_sub($self, $ptree) : $ptree; +} + +##--------------------------------------------------------------------------- + +=head1 B<interpolate()> + + $textblock = $parser->interpolate($text, $line_num); + +This method translates all text (including any embedded interior sequences) +in the given text string C<$text> and returns the interpolated result. The +parameter C<$line_num> is the line number corresponding to the beginning +of C<$text>. + +B<interpolate()> merely invokes a private method to recursively expand +nested interior sequences in bottom-up order (innermost sequences are +expanded first). If there is a need to expand nested sequences in +some alternate order, use B<parse_text> instead. + +=cut + +sub interpolate { + my($self, $text, $line_num) = @_; + my %parse_opts = ( -expand_seq => 'interior_sequence' ); + my $ptree = $self->parse_text( \%parse_opts, $text, $line_num ); + return join "", $ptree->children(); +} + +##--------------------------------------------------------------------------- + +=begin __PRIVATE__ + +=head1 B<parse_paragraph()> + + $parser->parse_paragraph($text, $line_num); + +This method takes the text of a POD paragraph to be processed, along +with its corresponding line number, and invokes the appropriate method +(one of B<command()>, B<verbatim()>, or B<textblock()>). + +For performance reasons, this method is invoked directly without any +dynamic lookup; Hence subclasses may I<not> override it! + +=end __PRIVATE__ + +=cut + +sub parse_paragraph { + my ($self, $text, $line_num) = @_; + local *myData = $self; ## alias to avoid deref-ing overhead + local *myOpts = ($myData{_PARSEOPTS} ||= {}); ## get parse-options + local $_; + + ## See if we want to preprocess nonPOD paragraphs as well as POD ones. + my $wantNonPods = $myOpts{'-want_nonPODs'}; + + ## Update cutting status + $myData{_CUTTING} = 0 if $text =~ /^={1,2}\S/; + + ## Perform any desired preprocessing if we wanted it this early + $wantNonPods and $text = $self->preprocess_paragraph($text, $line_num); + + ## Ignore up until next POD directive if we are cutting + return if $myData{_CUTTING}; + + ## Now we know this is block of text in a POD section! + + ##----------------------------------------------------------------- + ## This is a hook (hack ;-) for Pod::Select to do its thing without + ## having to override methods, but also without Pod::Parser assuming + ## $self is an instance of Pod::Select (if the _SELECTED_SECTIONS + ## field exists then we assume there is an is_selected() method for + ## us to invoke (calling $self->can('is_selected') could verify this + ## but that is more overhead than I want to incur) + ##----------------------------------------------------------------- + + ## Ignore this block if it isnt in one of the selected sections + if (exists $myData{_SELECTED_SECTIONS}) { + $self->is_selected($text) or return ($myData{_CUTTING} = 1); + } + + ## If we havent already, perform any desired preprocessing and + ## then re-check the "cutting" state + unless ($wantNonPods) { + $text = $self->preprocess_paragraph($text, $line_num); + return 1 unless ((defined $text) and (length $text)); + return 1 if ($myData{_CUTTING}); + } + + ## Look for one of the three types of paragraphs + my ($pfx, $cmd, $arg, $sep) = ('', '', '', ''); + my $pod_para = undef; + if ($text =~ /^(={1,2})(?=\S)/) { + ## Looks like a command paragraph. Capture the command prefix used + ## ("=" or "=="), as well as the command-name, its paragraph text, + ## and whatever sequence of characters was used to separate them + $pfx = $1; + $_ = substr($text, length $pfx); + ($cmd, $sep, $text) = split /(\s+)/, $_, 2; + ## If this is a "cut" directive then we dont need to do anything + ## except return to "cutting" mode. + if ($cmd eq 'cut') { + $myData{_CUTTING} = 1; + return unless $myOpts{'-process_cut_cmd'}; + } + } + ## Save the attributes indicating how the command was specified. + $pod_para = new Pod::Paragraph( + -name => $cmd, + -text => $text, + -prefix => $pfx, + -separator => $sep, + -file => $myData{_INFILE}, + -line => $line_num + ); + # ## Invoke appropriate callbacks + # if (exists $myData{_CALLBACKS}) { + # ## Look through the callback list, invoke callbacks, + # ## then see if we need to do the default actions + # ## (invoke_callbacks will return true if we do). + # return 1 unless $self->invoke_callbacks($cmd, $text, $line_num, $pod_para); + # } + if (length $cmd) { + ## A command paragraph + $self->command($cmd, $text, $line_num, $pod_para); + } + elsif ($text =~ /^\s+/) { + ## Indented text - must be a verbatim paragraph + $self->verbatim($text, $line_num, $pod_para); + } + else { + ## Looks like an ordinary block of text + $self->textblock($text, $line_num, $pod_para); + } + return 1; +} + +##--------------------------------------------------------------------------- + +=head1 B<parse_from_filehandle()> + + $parser->parse_from_filehandle($in_fh,$out_fh); + +This method takes an input filehandle (which is assumed to already be +opened for reading) and reads the entire input stream looking for blocks +(paragraphs) of POD documentation to be processed. If no first argument +is given the default input filehandle C<STDIN> is used. + +The C<$in_fh> parameter may be any object that provides a B<getline()> +method to retrieve a single line of input text (hence, an appropriate +wrapper object could be used to parse PODs from a single string or an +array of strings). + +Using C<$in_fh-E<gt>getline()>, input is read line-by-line and assembled +into paragraphs or "blocks" (which are separated by lines containing +nothing but whitespace). For each block of POD documentation +encountered it will invoke a method to parse the given paragraph. + +If a second argument is given then it should correspond to a filehandle where +output should be sent (otherwise the default output filehandle is +C<STDOUT> if no output filehandle is currently in use). + +B<NOTE:> For performance reasons, this method caches the input stream at +the top of the stack in a local variable. Any attempts by clients to +change the stack contents during processing when in the midst executing +of this method I<will not affect> the input stream used by the current +invocation of this method. + +This method does I<not> usually need to be overridden by subclasses. + +=cut + +sub parse_from_filehandle { + my $self = shift; + my %opts = (ref $_[0] eq 'HASH') ? %{ shift() } : (); + my ($in_fh, $out_fh) = @_; + $in_fh = \*STDIN unless ($in_fh); + local *myData = $self; ## alias to avoid deref-ing overhead + local *myOpts = ($myData{_PARSEOPTS} ||= {}); ## get parse-options + local $_; + + ## Put this stream at the top of the stack and do beginning-of-input + ## processing. NOTE that $in_fh might be reset during this process. + my $topstream = $self->_push_input_stream($in_fh, $out_fh); + (exists $opts{-cutting}) and $self->cutting( $opts{-cutting} ); + + ## Initialize line/paragraph + my ($textline, $paragraph) = ('', ''); + my ($nlines, $plines) = (0, 0); + + ## Use <$fh> instead of $fh->getline where possible (for speed) + $_ = ref $in_fh; + my $tied_fh = (/^(?:GLOB|FileHandle|IO::\w+)$/ or tied $in_fh); + + ## Read paragraphs line-by-line + while (defined ($textline = $tied_fh ? <$in_fh> : $in_fh->getline)) { + $textline = $self->preprocess_line($textline, ++$nlines); + next unless ((defined $textline) && (length $textline)); + + if ((! length $paragraph) && ($textline =~ /^==/)) { + ## '==' denotes a one-line command paragraph + $paragraph = $textline; + $plines = 1; + $textline = ''; + } else { + ## Append this line to the current paragraph + $paragraph .= $textline; + ++$plines; + } + + ## See if this line is blank and ends the current paragraph. + ## If it isnt, then keep iterating until it is. + next unless (($textline =~ /^([^\S\r\n]*)[\r\n]*$/) + && (length $paragraph)); + + ## Issue a warning about any non-empty blank lines + if (length($1) > 0 and $myOpts{'-warnings'} and ! $myData{_CUTTING}) { + my $errorsub = $self->errorsub(); + my $file = $self->input_file(); + my $errmsg = "*** WARNING: line containing nothing but whitespace". + " in paragraph at line $nlines in file $file\n"; + (ref $errorsub) and &{$errorsub}($errmsg) + or (defined $errorsub) and $self->$errorsub($errmsg) + or warn($errmsg); + } + + ## Now process the paragraph + parse_paragraph($self, $paragraph, ($nlines - $plines) + 1); + $paragraph = ''; + $plines = 0; + } + ## Dont forget about the last paragraph in the file + if (length $paragraph) { + parse_paragraph($self, $paragraph, ($nlines - $plines) + 1) + } + + ## Now pop the input stream off the top of the input stack. + $self->_pop_input_stream(); +} + +##--------------------------------------------------------------------------- + +=head1 B<parse_from_file()> + + $parser->parse_from_file($filename,$outfile); + +This method takes a filename and does the following: + +=over 2 + +=item * + +opens the input and output files for reading +(creating the appropriate filehandles) + +=item * + +invokes the B<parse_from_filehandle()> method passing it the +corresponding input and output filehandles. + +=item * + +closes the input and output files. + +=back + +If the special input filename "-" or "<&STDIN" is given then the STDIN +filehandle is used for input (and no open or close is performed). If no +input filename is specified then "-" is implied. + +If a second argument is given then it should be the name of the desired +output file. If the special output filename "-" or ">&STDOUT" is given +then the STDOUT filehandle is used for output (and no open or close is +performed). If the special output filename ">&STDERR" is given then the +STDERR filehandle is used for output (and no open or close is +performed). If no output filehandle is currently in use and no output +filename is specified, then "-" is implied. +Alternatively, an L<IO::String> object is also accepted as an output +file handle. + +This method does I<not> usually need to be overridden by subclasses. + +=cut + +sub parse_from_file { + my $self = shift; + my %opts = (ref $_[0] eq 'HASH') ? %{ shift() } : (); + my ($infile, $outfile) = @_; + my ($in_fh, $out_fh) = (gensym(), gensym()) if ($] < 5.006); + my ($close_input, $close_output) = (0, 0); + local *myData = $self; + local *_; + + ## Is $infile a filename or a (possibly implied) filehandle + if (defined $infile && ref $infile) { + if (ref($infile) =~ /^(SCALAR|ARRAY|HASH|CODE|REF)$/) { + croak "Input from $1 reference not supported!\n"; + } + ## Must be a filehandle-ref (or else assume its a ref to an object + ## that supports the common IO read operations). + $myData{_INFILE} = ${$infile}; + $in_fh = $infile; + } + elsif (!defined($infile) || !length($infile) || ($infile eq '-') + || ($infile =~ /^<&(?:STDIN|0)$/i)) + { + ## Not a filename, just a string implying STDIN + $infile ||= '-'; + $myData{_INFILE} = "<standard input>"; + $in_fh = \*STDIN; + } + else { + ## We have a filename, open it for reading + $myData{_INFILE} = $infile; + open($in_fh, "< $infile") or + croak "Can't open $infile for reading: $!\n"; + $close_input = 1; + } + + ## NOTE: we need to be *very* careful when "defaulting" the output + ## file. We only want to use a default if this is the beginning of + ## the entire document (but *not* if this is an included file). We + ## determine this by seeing if the input stream stack has been set-up + ## already + + ## Is $outfile a filename, a (possibly implied) filehandle, maybe a ref? + if (ref $outfile) { + ## we need to check for ref() first, as other checks involve reading + if (ref($outfile) =~ /^(ARRAY|HASH|CODE)$/) { + croak "Output to $1 reference not supported!\n"; + } + elsif (ref($outfile) eq 'SCALAR') { +# # NOTE: IO::String isn't a part of the perl distribution, +# # so probably we shouldn't support this case... +# require IO::String; +# $myData{_OUTFILE} = "$outfile"; +# $out_fh = IO::String->new($outfile); + croak "Output to SCALAR reference not supported!\n"; + } + else { + ## Must be a filehandle-ref (or else assume its a ref to an + ## object that supports the common IO write operations). + $myData{_OUTFILE} = ${$outfile}; + $out_fh = $outfile; + } + } + elsif (!defined($outfile) || !length($outfile) || ($outfile eq '-') + || ($outfile =~ /^>&?(?:STDOUT|1)$/i)) + { + if (defined $myData{_TOP_STREAM}) { + $out_fh = $myData{_OUTPUT}; + } + else { + ## Not a filename, just a string implying STDOUT + $outfile ||= '-'; + $myData{_OUTFILE} = "<standard output>"; + $out_fh = \*STDOUT; + } + } + elsif ($outfile =~ /^>&(STDERR|2)$/i) { + ## Not a filename, just a string implying STDERR + $myData{_OUTFILE} = "<standard error>"; + $out_fh = \*STDERR; + } + else { + ## We have a filename, open it for writing + $myData{_OUTFILE} = $outfile; + (-d $outfile) and croak "$outfile is a directory, not POD input!\n"; + open($out_fh, "> $outfile") or + croak "Can't open $outfile for writing: $!\n"; + $close_output = 1; + } + + ## Whew! That was a lot of work to set up reasonably/robust behavior + ## in the case of a non-filename for reading and writing. Now we just + ## have to parse the input and close the handles when we're finished. + $self->parse_from_filehandle(\%opts, $in_fh, $out_fh); + + $close_input and + close($in_fh) || croak "Can't close $infile after reading: $!\n"; + $close_output and + close($out_fh) || croak "Can't close $outfile after writing: $!\n"; +} + +############################################################################# + +=head1 ACCESSOR METHODS + +Clients of B<Pod::Parser> should use the following methods to access +instance data fields: + +=cut + +##--------------------------------------------------------------------------- + +=head1 B<errorsub()> + + $parser->errorsub("method_name"); + $parser->errorsub(\&warn_user); + $parser->errorsub(sub { print STDERR, @_ }); + +Specifies the method or subroutine to use when printing error messages +about POD syntax. The supplied method/subroutine I<must> return TRUE upon +successful printing of the message. If C<undef> is given, then the B<warn> +builtin is used to issue error messages (this is the default behavior). + + my $errorsub = $parser->errorsub() + my $errmsg = "This is an error message!\n" + (ref $errorsub) and &{$errorsub}($errmsg) + or (defined $errorsub) and $parser->$errorsub($errmsg) + or warn($errmsg); + +Returns a method name, or else a reference to the user-supplied subroutine +used to print error messages. Returns C<undef> if the B<warn> builtin +is used to issue error messages (this is the default behavior). + +=cut + +sub errorsub { + return (@_ > 1) ? ($_[0]->{_ERRORSUB} = $_[1]) : $_[0]->{_ERRORSUB}; +} + +##--------------------------------------------------------------------------- + +=head1 B<cutting()> + + $boolean = $parser->cutting(); + +Returns the current C<cutting> state: a boolean-valued scalar which +evaluates to true if text from the input file is currently being "cut" +(meaning it is I<not> considered part of the POD document). + + $parser->cutting($boolean); + +Sets the current C<cutting> state to the given value and returns the +result. + +=cut + +sub cutting { + return (@_ > 1) ? ($_[0]->{_CUTTING} = $_[1]) : $_[0]->{_CUTTING}; +} + +##--------------------------------------------------------------------------- + +##--------------------------------------------------------------------------- + +=head1 B<parseopts()> + +When invoked with no additional arguments, B<parseopts> returns a hashtable +of all the current parsing options. + + ## See if we are parsing non-POD sections as well as POD ones + my %opts = $parser->parseopts(); + $opts{'-want_nonPODs}' and print "-want_nonPODs\n"; + +When invoked using a single string, B<parseopts> treats the string as the +name of a parse-option and returns its corresponding value if it exists +(returns C<undef> if it doesn't). + + ## Did we ask to see '=cut' paragraphs? + my $want_cut = $parser->parseopts('-process_cut_cmd'); + $want_cut and print "-process_cut_cmd\n"; + +When invoked with multiple arguments, B<parseopts> treats them as +key/value pairs and the specified parse-option names are set to the +given values. Any unspecified parse-options are unaffected. + + ## Set them back to the default + $parser->parseopts(-warnings => 0); + +When passed a single hash-ref, B<parseopts> uses that hash to completely +reset the existing parse-options, all previous parse-option values +are lost. + + ## Reset all options to default + $parser->parseopts( { } ); + +See L<"PARSING OPTIONS"> for more information on the name and meaning of each +parse-option currently recognized. + +=cut + +sub parseopts { + local *myData = shift; + local *myOpts = ($myData{_PARSEOPTS} ||= {}); + return %myOpts if (@_ == 0); + if (@_ == 1) { + local $_ = shift; + return ref($_) ? $myData{_PARSEOPTS} = $_ : $myOpts{$_}; + } + my @newOpts = (%myOpts, @_); + $myData{_PARSEOPTS} = { @newOpts }; +} + +##--------------------------------------------------------------------------- + +=head1 B<output_file()> + + $fname = $parser->output_file(); + +Returns the name of the output file being written. + +=cut + +sub output_file { + return $_[0]->{_OUTFILE}; +} + +##--------------------------------------------------------------------------- + +=head1 B<output_handle()> + + $fhandle = $parser->output_handle(); + +Returns the output filehandle object. + +=cut + +sub output_handle { + return $_[0]->{_OUTPUT}; +} + +##--------------------------------------------------------------------------- + +=head1 B<input_file()> + + $fname = $parser->input_file(); + +Returns the name of the input file being read. + +=cut + +sub input_file { + return $_[0]->{_INFILE}; +} + +##--------------------------------------------------------------------------- + +=head1 B<input_handle()> + + $fhandle = $parser->input_handle(); + +Returns the current input filehandle object. + +=cut + +sub input_handle { + return $_[0]->{_INPUT}; +} + +##--------------------------------------------------------------------------- + +=begin __PRIVATE__ + +=head1 B<input_streams()> + + $listref = $parser->input_streams(); + +Returns a reference to an array which corresponds to the stack of all +the input streams that are currently in the middle of being parsed. + +While parsing an input stream, it is possible to invoke +B<parse_from_file()> or B<parse_from_filehandle()> to parse a new input +stream and then return to parsing the previous input stream. Each input +stream to be parsed is pushed onto the end of this input stack +before any of its input is read. The input stream that is currently +being parsed is always at the end (or top) of the input stack. When an +input stream has been exhausted, it is popped off the end of the +input stack. + +Each element on this input stack is a reference to C<Pod::InputSource> +object. Please see L<Pod::InputObjects> for more details. + +This method might be invoked when printing diagnostic messages, for example, +to obtain the name and line number of the all input files that are currently +being processed. + +=end __PRIVATE__ + +=cut + +sub input_streams { + return $_[0]->{_INPUT_STREAMS}; +} + +##--------------------------------------------------------------------------- + +=begin __PRIVATE__ + +=head1 B<top_stream()> + + $hashref = $parser->top_stream(); + +Returns a reference to the hash-table that represents the element +that is currently at the top (end) of the input stream stack +(see L<"input_streams()">). The return value will be the C<undef> +if the input stack is empty. + +This method might be used when printing diagnostic messages, for example, +to obtain the name and line number of the current input file. + +=end __PRIVATE__ + +=cut + +sub top_stream { + return $_[0]->{_TOP_STREAM} || undef; +} + +############################################################################# + +=head1 PRIVATE METHODS AND DATA + +B<Pod::Parser> makes use of several internal methods and data fields +which clients should not need to see or use. For the sake of avoiding +name collisions for client data and methods, these methods and fields +are briefly discussed here. Determined hackers may obtain further +information about them by reading the B<Pod::Parser> source code. + +Private data fields are stored in the hash-object whose reference is +returned by the B<new()> constructor for this class. The names of all +private methods and data-fields used by B<Pod::Parser> begin with a +prefix of "_" and match the regular expression C</^_\w+$/>. + +=cut + +##--------------------------------------------------------------------------- + +=begin _PRIVATE_ + +=head1 B<_push_input_stream()> + + $hashref = $parser->_push_input_stream($in_fh,$out_fh); + +This method will push the given input stream on the input stack and +perform any necessary beginning-of-document or beginning-of-file +processing. The argument C<$in_fh> is the input stream filehandle to +push, and C<$out_fh> is the corresponding output filehandle to use (if +it is not given or is undefined, then the current output stream is used, +which defaults to standard output if it doesnt exist yet). + +The value returned will be reference to the hash-table that represents +the new top of the input stream stack. I<Please Note> that it is +possible for this method to use default values for the input and output +file handles. If this happens, you will need to look at the C<INPUT> +and C<OUTPUT> instance data members to determine their new values. + +=end _PRIVATE_ + +=cut + +sub _push_input_stream { + my ($self, $in_fh, $out_fh) = @_; + local *myData = $self; + + ## Initialize stuff for the entire document if this is *not* + ## an included file. + ## + ## NOTE: we need to be *very* careful when "defaulting" the output + ## filehandle. We only want to use a default value if this is the + ## beginning of the entire document (but *not* if this is an included + ## file). + unless (defined $myData{_TOP_STREAM}) { + $out_fh = \*STDOUT unless (defined $out_fh); + $myData{_CUTTING} = 1; ## current "cutting" state + $myData{_INPUT_STREAMS} = []; ## stack of all input streams + } + + ## Initialize input indicators + $myData{_OUTFILE} = '(unknown)' unless (defined $myData{_OUTFILE}); + $myData{_OUTPUT} = $out_fh if (defined $out_fh); + $in_fh = \*STDIN unless (defined $in_fh); + $myData{_INFILE} = '(unknown)' unless (defined $myData{_INFILE}); + $myData{_INPUT} = $in_fh; + my $input_top = $myData{_TOP_STREAM} + = new Pod::InputSource( + -name => $myData{_INFILE}, + -handle => $in_fh, + -was_cutting => $myData{_CUTTING} + ); + local *input_stack = $myData{_INPUT_STREAMS}; + push(@input_stack, $input_top); + + ## Perform beginning-of-document and/or beginning-of-input processing + $self->begin_pod() if (@input_stack == 1); + $self->begin_input(); + + return $input_top; +} + +##--------------------------------------------------------------------------- + +=begin _PRIVATE_ + +=head1 B<_pop_input_stream()> + + $hashref = $parser->_pop_input_stream(); + +This takes no arguments. It will perform any necessary end-of-file or +end-of-document processing and then pop the current input stream from +the top of the input stack. + +The value returned will be reference to the hash-table that represents +the new top of the input stream stack. + +=end _PRIVATE_ + +=cut + +sub _pop_input_stream { + my ($self) = @_; + local *myData = $self; + local *input_stack = $myData{_INPUT_STREAMS}; + + ## Perform end-of-input and/or end-of-document processing + $self->end_input() if (@input_stack > 0); + $self->end_pod() if (@input_stack == 1); + + ## Restore cutting state to whatever it was before we started + ## parsing this file. + my $old_top = pop(@input_stack); + $myData{_CUTTING} = $old_top->was_cutting(); + + ## Dont forget to reset the input indicators + my $input_top = undef; + if (@input_stack > 0) { + $input_top = $myData{_TOP_STREAM} = $input_stack[-1]; + $myData{_INFILE} = $input_top->name(); + $myData{_INPUT} = $input_top->handle(); + } else { + delete $myData{_TOP_STREAM}; + delete $myData{_INPUT_STREAMS}; + } + + return $input_top; +} + +############################################################################# + +=head1 TREE-BASED PARSING + +If straightforward stream-based parsing wont meet your needs (as is +likely the case for tasks such as translating PODs into structured +markup languages like HTML and XML) then you may need to take the +tree-based approach. Rather than doing everything in one pass and +calling the B<interpolate()> method to expand sequences into text, it +may be desirable to instead create a parse-tree using the B<parse_text()> +method to return a tree-like structure which may contain an ordered +list of children (each of which may be a text-string, or a similar +tree-like structure). + +Pay special attention to L<"METHODS FOR PARSING AND PROCESSING"> and +to the objects described in L<Pod::InputObjects>. The former describes +the gory details and parameters for how to customize and extend the +parsing behavior of B<Pod::Parser>. B<Pod::InputObjects> provides +several objects that may all be used interchangeably as parse-trees. The +most obvious one is the B<Pod::ParseTree> object. It defines the basic +interface and functionality that all things trying to be a POD parse-tree +should do. A B<Pod::ParseTree> is defined such that each "node" may be a +text-string, or a reference to another parse-tree. Each B<Pod::Paragraph> +object and each B<Pod::InteriorSequence> object also supports the basic +parse-tree interface. + +The B<parse_text()> method takes a given paragraph of text, and +returns a parse-tree that contains one or more children, each of which +may be a text-string, or an InteriorSequence object. There are also +callback-options that may be passed to B<parse_text()> to customize +the way it expands or transforms interior-sequences, as well as the +returned result. These callbacks can be used to create a parse-tree +with custom-made objects (which may or may not support the parse-tree +interface, depending on how you choose to do it). + +If you wish to turn an entire POD document into a parse-tree, that process +is fairly straightforward. The B<parse_text()> method is the key to doing +this successfully. Every paragraph-callback (i.e. the polymorphic methods +for B<command()>, B<verbatim()>, and B<textblock()> paragraphs) takes +a B<Pod::Paragraph> object as an argument. Each paragraph object has a +B<parse_tree()> method that can be used to get or set a corresponding +parse-tree. So for each of those paragraph-callback methods, simply call +B<parse_text()> with the options you desire, and then use the returned +parse-tree to assign to the given paragraph object. + +That gives you a parse-tree for each paragraph - so now all you need is +an ordered list of paragraphs. You can maintain that yourself as a data +element in the object/hash. The most straightforward way would be simply +to use an array-ref, with the desired set of custom "options" for each +invocation of B<parse_text>. Let's assume the desired option-set is +given by the hash C<%options>. Then we might do something like the +following: + + package MyPodParserTree; + + @ISA = qw( Pod::Parser ); + + ... + + sub begin_pod { + my $self = shift; + $self->{'-paragraphs'} = []; ## initialize paragraph list + } + + sub command { + my ($parser, $command, $paragraph, $line_num, $pod_para) = @_; + my $ptree = $parser->parse_text({%options}, $paragraph, ...); + $pod_para->parse_tree( $ptree ); + push @{ $self->{'-paragraphs'} }, $pod_para; + } + + sub verbatim { + my ($parser, $paragraph, $line_num, $pod_para) = @_; + push @{ $self->{'-paragraphs'} }, $pod_para; + } + + sub textblock { + my ($parser, $paragraph, $line_num, $pod_para) = @_; + my $ptree = $parser->parse_text({%options}, $paragraph, ...); + $pod_para->parse_tree( $ptree ); + push @{ $self->{'-paragraphs'} }, $pod_para; + } + + ... + + package main; + ... + my $parser = new MyPodParserTree(...); + $parser->parse_from_file(...); + my $paragraphs_ref = $parser->{'-paragraphs'}; + +Of course, in this module-author's humble opinion, I'd be more inclined to +use the existing B<Pod::ParseTree> object than a simple array. That way +everything in it, paragraphs and sequences, all respond to the same core +interface for all parse-tree nodes. The result would look something like: + + package MyPodParserTree2; + + ... + + sub begin_pod { + my $self = shift; + $self->{'-ptree'} = new Pod::ParseTree; ## initialize parse-tree + } + + sub parse_tree { + ## convenience method to get/set the parse-tree for the entire POD + (@_ > 1) and $_[0]->{'-ptree'} = $_[1]; + return $_[0]->{'-ptree'}; + } + + sub command { + my ($parser, $command, $paragraph, $line_num, $pod_para) = @_; + my $ptree = $parser->parse_text({<<options>>}, $paragraph, ...); + $pod_para->parse_tree( $ptree ); + $parser->parse_tree()->append( $pod_para ); + } + + sub verbatim { + my ($parser, $paragraph, $line_num, $pod_para) = @_; + $parser->parse_tree()->append( $pod_para ); + } + + sub textblock { + my ($parser, $paragraph, $line_num, $pod_para) = @_; + my $ptree = $parser->parse_text({<<options>>}, $paragraph, ...); + $pod_para->parse_tree( $ptree ); + $parser->parse_tree()->append( $pod_para ); + } + + ... + + package main; + ... + my $parser = new MyPodParserTree2(...); + $parser->parse_from_file(...); + my $ptree = $parser->parse_tree; + ... + +Now you have the entire POD document as one great big parse-tree. You +can even use the B<-expand_seq> option to B<parse_text> to insert +whole different kinds of objects. Just don't expect B<Pod::Parser> +to know what to do with them after that. That will need to be in your +code. Or, alternatively, you can insert any object you like so long as +it conforms to the B<Pod::ParseTree> interface. + +One could use this to create subclasses of B<Pod::Paragraphs> and +B<Pod::InteriorSequences> for specific commands (or to create your own +custom node-types in the parse-tree) and add some kind of B<emit()> +method to each custom node/subclass object in the tree. Then all you'd +need to do is recursively walk the tree in the desired order, processing +the children (most likely from left to right) by formatting them if +they are text-strings, or by calling their B<emit()> method if they +are objects/references. + +=head1 SEE ALSO + +L<Pod::InputObjects>, L<Pod::Select> + +B<Pod::InputObjects> defines POD input objects corresponding to +command paragraphs, parse-trees, and interior-sequences. + +B<Pod::Select> is a subclass of B<Pod::Parser> which provides the ability +to selectively include and/or exclude sections of a POD document from being +translated based upon the current heading, subheading, subsubheading, etc. + +=for __PRIVATE__ +B<Pod::Callbacks> is a subclass of B<Pod::Parser> which gives its users +the ability the employ I<callback functions> instead of, or in addition +to, overriding methods of the base class. + +=for __PRIVATE__ +B<Pod::Select> and B<Pod::Callbacks> do not override any +methods nor do they define any new methods with the same name. Because +of this, they may I<both> be used (in combination) as a base class of +the same subclass in order to combine their functionality without +causing any namespace clashes due to multiple inheritance. + +=head1 AUTHOR + +Please report bugs using L<http://rt.cpan.org>. + +Brad Appleton E<lt>bradapp@enteract.comE<gt> + +Based on code for B<Pod::Text> written by +Tom Christiansen E<lt>tchrist@mox.perl.comE<gt> + +=cut + +1; +# vim: ts=4 sw=4 et diff --git a/Master/tlpkg/installer/perllib/Pod/Select.pm b/Master/tlpkg/installer/perllib/Pod/Select.pm new file mode 100644 index 00000000000..1cc14dff4b6 --- /dev/null +++ b/Master/tlpkg/installer/perllib/Pod/Select.pm @@ -0,0 +1,754 @@ +############################################################################# +# Pod/Select.pm -- function to select portions of POD docs +# +# Copyright (C) 1996-2000 by Bradford Appleton. All rights reserved. +# This file is part of "PodParser". PodParser is free software; +# you can redistribute it and/or modify it under the same terms +# as Perl itself. +############################################################################# + +package Pod::Select; + +use vars qw($VERSION); +$VERSION = 1.30; ## Current version of this package +require 5.005; ## requires this Perl version or later + +############################################################################# + +=head1 NAME + +Pod::Select, podselect() - extract selected sections of POD from input + +=head1 SYNOPSIS + + use Pod::Select; + + ## Select all the POD sections for each file in @filelist + ## and print the result on standard output. + podselect(@filelist); + + ## Same as above, but write to tmp.out + podselect({-output => "tmp.out"}, @filelist): + + ## Select from the given filelist, only those POD sections that are + ## within a 1st level section named any of: NAME, SYNOPSIS, OPTIONS. + podselect({-sections => ["NAME|SYNOPSIS", "OPTIONS"]}, @filelist): + + ## Select the "DESCRIPTION" section of the PODs from STDIN and write + ## the result to STDERR. + podselect({-output => ">&STDERR", -sections => ["DESCRIPTION"]}, \*STDIN); + +or + + use Pod::Select; + + ## Create a parser object for selecting POD sections from the input + $parser = new Pod::Select(); + + ## Select all the POD sections for each file in @filelist + ## and print the result to tmp.out. + $parser->parse_from_file("<&STDIN", "tmp.out"); + + ## Select from the given filelist, only those POD sections that are + ## within a 1st level section named any of: NAME, SYNOPSIS, OPTIONS. + $parser->select("NAME|SYNOPSIS", "OPTIONS"); + for (@filelist) { $parser->parse_from_file($_); } + + ## Select the "DESCRIPTION" and "SEE ALSO" sections of the PODs from + ## STDIN and write the result to STDERR. + $parser->select("DESCRIPTION"); + $parser->add_selection("SEE ALSO"); + $parser->parse_from_filehandle(\*STDIN, \*STDERR); + +=head1 REQUIRES + +perl5.005, Pod::Parser, Exporter, Carp + +=head1 EXPORTS + +podselect() + +=head1 DESCRIPTION + +B<podselect()> is a function which will extract specified sections of +pod documentation from an input stream. This ability is provided by the +B<Pod::Select> module which is a subclass of B<Pod::Parser>. +B<Pod::Select> provides a method named B<select()> to specify the set of +POD sections to select for processing/printing. B<podselect()> merely +creates a B<Pod::Select> object and then invokes the B<podselect()> +followed by B<parse_from_file()>. + +=head1 SECTION SPECIFICATIONS + +B<podselect()> and B<Pod::Select::select()> may be given one or more +"section specifications" to restrict the text processed to only the +desired set of sections and their corresponding subsections. A section +specification is a string containing one or more Perl-style regular +expressions separated by forward slashes ("/"). If you need to use a +forward slash literally within a section title you can escape it with a +backslash ("\/"). + +The formal syntax of a section specification is: + +=over 4 + +=item * + +I<head1-title-regex>/I<head2-title-regex>/... + +=back + +Any omitted or empty regular expressions will default to ".*". +Please note that each regular expression given is implicitly +anchored by adding "^" and "$" to the beginning and end. Also, if a +given regular expression starts with a "!" character, then the +expression is I<negated> (so C<!foo> would match anything I<except> +C<foo>). + +Some example section specifications follow. + +=over 4 + +=item * + +Match the C<NAME> and C<SYNOPSIS> sections and all of their subsections: + +C<NAME|SYNOPSIS> + +=item * + +Match only the C<Question> and C<Answer> subsections of the C<DESCRIPTION> +section: + +C<DESCRIPTION/Question|Answer> + +=item * + +Match the C<Comments> subsection of I<all> sections: + +C</Comments> + +=item * + +Match all subsections of C<DESCRIPTION> I<except> for C<Comments>: + +C<DESCRIPTION/!Comments> + +=item * + +Match the C<DESCRIPTION> section but do I<not> match any of its subsections: + +C<DESCRIPTION/!.+> + +=item * + +Match all top level sections but none of their subsections: + +C</!.+> + +=back + +=begin _NOT_IMPLEMENTED_ + +=head1 RANGE SPECIFICATIONS + +B<podselect()> and B<Pod::Select::select()> may be given one or more +"range specifications" to restrict the text processed to only the +desired ranges of paragraphs in the desired set of sections. A range +specification is a string containing a single Perl-style regular +expression (a regex), or else two Perl-style regular expressions +(regexs) separated by a ".." (Perl's "range" operator is ".."). +The regexs in a range specification are delimited by forward slashes +("/"). If you need to use a forward slash literally within a regex you +can escape it with a backslash ("\/"). + +The formal syntax of a range specification is: + +=over 4 + +=item * + +/I<start-range-regex>/[../I<end-range-regex>/] + +=back + +Where each the item inside square brackets (the ".." followed by the +end-range-regex) is optional. Each "range-regex" is of the form: + + =cmd-expr text-expr + +Where I<cmd-expr> is intended to match the name of one or more POD +commands, and I<text-expr> is intended to match the paragraph text for +the command. If a range-regex is supposed to match a POD command, then +the first character of the regex (the one after the initial '/') +absolutely I<must> be a single '=' character; it may not be anything +else (not even a regex meta-character) if it is supposed to match +against the name of a POD command. + +If no I<=cmd-expr> is given then the text-expr will be matched against +plain textblocks unless it is preceded by a space, in which case it is +matched against verbatim text-blocks. If no I<text-expr> is given then +only the command-portion of the paragraph is matched against. + +Note that these two expressions are each implicitly anchored. This +means that when matching against the command-name, there will be an +implicit '^' and '$' around the given I<=cmd-expr>; and when matching +against the paragraph text there will be an implicit '\A' and '\Z' +around the given I<text-expr>. + +Unlike with section-specs, the '!' character does I<not> have any special +meaning (negation or otherwise) at the beginning of a range-spec! + +Some example range specifications follow. + +=over 4 + +=item +Match all C<=for html> paragraphs: + +C</=for html/> + +=item +Match all paragraphs between C<=begin html> and C<=end html> +(note that this will I<not> work correctly if such sections +are nested): + +C</=begin html/../=end html/> + +=item +Match all paragraphs between the given C<=item> name until the end of the +current section: + +C</=item mine/../=head\d/> + +=item +Match all paragraphs between the given C<=item> until the next item, or +until the end of the itemized list (note that this will I<not> work as +desired if the item contains an itemized list nested within it): + +C</=item mine/../=(item|back)/> + +=back + +=end _NOT_IMPLEMENTED_ + +=cut + +############################################################################# + +use strict; +#use diagnostics; +use Carp; +use Pod::Parser 1.04; +use vars qw(@ISA @EXPORT $MAX_HEADING_LEVEL); + +@ISA = qw(Pod::Parser); +@EXPORT = qw(&podselect); + +## Maximum number of heading levels supported for '=headN' directives +*MAX_HEADING_LEVEL = \3; + +############################################################################# + +=head1 OBJECT METHODS + +The following methods are provided in this module. Each one takes a +reference to the object itself as an implicit first parameter. + +=cut + +##--------------------------------------------------------------------------- + +## =begin _PRIVATE_ +## +## =head1 B<_init_headings()> +## +## Initialize the current set of active section headings. +## +## =cut +## +## =end _PRIVATE_ + +use vars qw(%myData @section_headings); + +sub _init_headings { + my $self = shift; + local *myData = $self; + + ## Initialize current section heading titles if necessary + unless (defined $myData{_SECTION_HEADINGS}) { + local *section_headings = $myData{_SECTION_HEADINGS} = []; + for (my $i = 0; $i < $MAX_HEADING_LEVEL; ++$i) { + $section_headings[$i] = ''; + } + } +} + +##--------------------------------------------------------------------------- + +=head1 B<curr_headings()> + + ($head1, $head2, $head3, ...) = $parser->curr_headings(); + $head1 = $parser->curr_headings(1); + +This method returns a list of the currently active section headings and +subheadings in the document being parsed. The list of headings returned +corresponds to the most recently parsed paragraph of the input. + +If an argument is given, it must correspond to the desired section +heading number, in which case only the specified section heading is +returned. If there is no current section heading at the specified +level, then C<undef> is returned. + +=cut + +sub curr_headings { + my $self = shift; + $self->_init_headings() unless (defined $self->{_SECTION_HEADINGS}); + my @headings = @{ $self->{_SECTION_HEADINGS} }; + return (@_ > 0 and $_[0] =~ /^\d+$/) ? $headings[$_[0] - 1] : @headings; +} + +##--------------------------------------------------------------------------- + +=head1 B<select()> + + $parser->select($section_spec1,$section_spec2,...); + +This method is used to select the particular sections and subsections of +POD documentation that are to be printed and/or processed. The existing +set of selected sections is I<replaced> with the given set of sections. +See B<add_selection()> for adding to the current set of selected +sections. + +Each of the C<$section_spec> arguments should be a section specification +as described in L<"SECTION SPECIFICATIONS">. The section specifications +are parsed by this method and the resulting regular expressions are +stored in the invoking object. + +If no C<$section_spec> arguments are given, then the existing set of +selected sections is cleared out (which means C<all> sections will be +processed). + +This method should I<not> normally be overridden by subclasses. + +=cut + +use vars qw(@selected_sections); + +sub select { + my $self = shift; + my @sections = @_; + local *myData = $self; + local $_; + +### NEED TO DISCERN A SECTION-SPEC FROM A RANGE-SPEC (look for m{^/.+/$}?) + + ##--------------------------------------------------------------------- + ## The following is a blatant hack for backward compatibility, and for + ## implementing add_selection(). If the *first* *argument* is the + ## string "+", then the remaining section specifications are *added* + ## to the current set of selections; otherwise the given section + ## specifications will *replace* the current set of selections. + ## + ## This should probably be fixed someday, but for the present time, + ## it seems incredibly unlikely that "+" would ever correspond to + ## a legitimate section heading + ##--------------------------------------------------------------------- + my $add = ($sections[0] eq "+") ? shift(@sections) : ""; + + ## Reset the set of sections to use + unless (@sections > 0) { + delete $myData{_SELECTED_SECTIONS} unless ($add); + return; + } + $myData{_SELECTED_SECTIONS} = [] + unless ($add && exists $myData{_SELECTED_SECTIONS}); + local *selected_sections = $myData{_SELECTED_SECTIONS}; + + ## Compile each spec + my $spec; + for $spec (@sections) { + if ( defined($_ = &_compile_section_spec($spec)) ) { + ## Store them in our sections array + push(@selected_sections, $_); + } + else { + carp "Ignoring section spec \"$spec\"!\n"; + } + } +} + +##--------------------------------------------------------------------------- + +=head1 B<add_selection()> + + $parser->add_selection($section_spec1,$section_spec2,...); + +This method is used to add to the currently selected sections and +subsections of POD documentation that are to be printed and/or +processed. See <select()> for replacing the currently selected sections. + +Each of the C<$section_spec> arguments should be a section specification +as described in L<"SECTION SPECIFICATIONS">. The section specifications +are parsed by this method and the resulting regular expressions are +stored in the invoking object. + +This method should I<not> normally be overridden by subclasses. + +=cut + +sub add_selection { + my $self = shift; + $self->select("+", @_); +} + +##--------------------------------------------------------------------------- + +=head1 B<clear_selections()> + + $parser->clear_selections(); + +This method takes no arguments, it has the exact same effect as invoking +<select()> with no arguments. + +=cut + +sub clear_selections { + my $self = shift; + $self->select(); +} + +##--------------------------------------------------------------------------- + +=head1 B<match_section()> + + $boolean = $parser->match_section($heading1,$heading2,...); + +Returns a value of true if the given section and subsection heading +titles match any of the currently selected section specifications in +effect from prior calls to B<select()> and B<add_selection()> (or if +there are no explictly selected/deselected sections). + +The arguments C<$heading1>, C<$heading2>, etc. are the heading titles of +the corresponding sections, subsections, etc. to try and match. If +C<$headingN> is omitted then it defaults to the current corresponding +section heading title in the input. + +This method should I<not> normally be overridden by subclasses. + +=cut + +sub match_section { + my $self = shift; + my (@headings) = @_; + local *myData = $self; + + ## Return true if no restrictions were explicitly specified + my $selections = (exists $myData{_SELECTED_SECTIONS}) + ? $myData{_SELECTED_SECTIONS} : undef; + return 1 unless ((defined $selections) && (@{$selections} > 0)); + + ## Default any unspecified sections to the current one + my @current_headings = $self->curr_headings(); + for (my $i = 0; $i < $MAX_HEADING_LEVEL; ++$i) { + (defined $headings[$i]) or $headings[$i] = $current_headings[$i]; + } + + ## Look for a match against the specified section expressions + my ($section_spec, $regex, $negated, $match); + for $section_spec ( @{$selections} ) { + ##------------------------------------------------------ + ## Each portion of this spec must match in order for + ## the spec to be matched. So we will start with a + ## match-value of 'true' and logically 'and' it with + ## the results of matching a given element of the spec. + ##------------------------------------------------------ + $match = 1; + for (my $i = 0; $i < $MAX_HEADING_LEVEL; ++$i) { + $regex = $section_spec->[$i]; + $negated = ($regex =~ s/^\!//); + $match &= ($negated ? ($headings[$i] !~ /${regex}/) + : ($headings[$i] =~ /${regex}/)); + last unless ($match); + } + return 1 if ($match); + } + return 0; ## no match +} + +##--------------------------------------------------------------------------- + +=head1 B<is_selected()> + + $boolean = $parser->is_selected($paragraph); + +This method is used to determine if the block of text given in +C<$paragraph> falls within the currently selected set of POD sections +and subsections to be printed or processed. This method is also +responsible for keeping track of the current input section and +subsections. It is assumed that C<$paragraph> is the most recently read +(but not yet processed) input paragraph. + +The value returned will be true if the C<$paragraph> and the rest of the +text in the same section as C<$paragraph> should be selected (included) +for processing; otherwise a false value is returned. + +=cut + +sub is_selected { + my ($self, $paragraph) = @_; + local $_; + local *myData = $self; + + $self->_init_headings() unless (defined $myData{_SECTION_HEADINGS}); + + ## Keep track of current sections levels and headings + $_ = $paragraph; + if (/^=((?:sub)*)(?:head(?:ing)?|sec(?:tion)?)(\d*)\s+(.*)\s*$/) + { + ## This is a section heading command + my ($level, $heading) = ($2, $3); + $level = 1 + (length($1) / 3) if ((! length $level) || (length $1)); + ## Reset the current section heading at this level + $myData{_SECTION_HEADINGS}->[$level - 1] = $heading; + ## Reset subsection headings of this one to empty + for (my $i = $level; $i < $MAX_HEADING_LEVEL; ++$i) { + $myData{_SECTION_HEADINGS}->[$i] = ''; + } + } + + return $self->match_section(); +} + +############################################################################# + +=head1 EXPORTED FUNCTIONS + +The following functions are exported by this module. Please note that +these are functions (not methods) and therefore C<do not> take an +implicit first argument. + +=cut + +##--------------------------------------------------------------------------- + +=head1 B<podselect()> + + podselect(\%options,@filelist); + +B<podselect> will print the raw (untranslated) POD paragraphs of all +POD sections in the given input files specified by C<@filelist> +according to the given options. + +If any argument to B<podselect> is a reference to a hash +(associative array) then the values with the following keys are +processed as follows: + +=over 4 + +=item B<-output> + +A string corresponding to the desired output file (or ">&STDOUT" +or ">&STDERR"). The default is to use standard output. + +=item B<-sections> + +A reference to an array of sections specifications (as described in +L<"SECTION SPECIFICATIONS">) which indicate the desired set of POD +sections and subsections to be selected from input. If no section +specifications are given, then all sections of the PODs are used. + +=begin _NOT_IMPLEMENTED_ + +=item B<-ranges> + +A reference to an array of range specifications (as described in +L<"RANGE SPECIFICATIONS">) which indicate the desired range of POD +paragraphs to be selected from the desired input sections. If no range +specifications are given, then all paragraphs of the desired sections +are used. + +=end _NOT_IMPLEMENTED_ + +=back + +All other arguments should correspond to the names of input files +containing POD sections. A file name of "-" or "<&STDIN" will +be interpeted to mean standard input (which is the default if no +filenames are given). + +=cut + +sub podselect { + my(@argv) = @_; + my %defaults = (); + my $pod_parser = new Pod::Select(%defaults); + my $num_inputs = 0; + my $output = ">&STDOUT"; + my %opts; + local $_; + for (@argv) { + if (ref($_)) { + next unless (ref($_) eq 'HASH'); + %opts = (%defaults, %{$_}); + + ##------------------------------------------------------------- + ## Need this for backward compatibility since we formerly used + ## options that were all uppercase words rather than ones that + ## looked like Unix command-line options. + ## to be uppercase keywords) + ##------------------------------------------------------------- + %opts = map { + my ($key, $val) = (lc $_, $opts{$_}); + $key =~ s/^(?=\w)/-/; + $key =~ /^-se[cl]/ and $key = '-sections'; + #! $key eq '-range' and $key .= 's'; + ($key => $val); + } (keys %opts); + + ## Process the options + (exists $opts{'-output'}) and $output = $opts{'-output'}; + + ## Select the desired sections + $pod_parser->select(@{ $opts{'-sections'} }) + if ( (defined $opts{'-sections'}) + && ((ref $opts{'-sections'}) eq 'ARRAY') ); + + #! ## Select the desired paragraph ranges + #! $pod_parser->select(@{ $opts{'-ranges'} }) + #! if ( (defined $opts{'-ranges'}) + #! && ((ref $opts{'-ranges'}) eq 'ARRAY') ); + } + else { + $pod_parser->parse_from_file($_, $output); + ++$num_inputs; + } + } + $pod_parser->parse_from_file("-") unless ($num_inputs > 0); +} + +############################################################################# + +=head1 PRIVATE METHODS AND DATA + +B<Pod::Select> makes uses a number of internal methods and data fields +which clients should not need to see or use. For the sake of avoiding +name collisions with client data and methods, these methods and fields +are briefly discussed here. Determined hackers may obtain further +information about them by reading the B<Pod::Select> source code. + +Private data fields are stored in the hash-object whose reference is +returned by the B<new()> constructor for this class. The names of all +private methods and data-fields used by B<Pod::Select> begin with a +prefix of "_" and match the regular expression C</^_\w+$/>. + +=cut + +##--------------------------------------------------------------------------- + +=begin _PRIVATE_ + +=head1 B<_compile_section_spec()> + + $listref = $parser->_compile_section_spec($section_spec); + +This function (note it is a function and I<not> a method) takes a +section specification (as described in L<"SECTION SPECIFICATIONS">) +given in C<$section_sepc>, and compiles it into a list of regular +expressions. If C<$section_spec> has no syntax errors, then a reference +to the list (array) of corresponding regular expressions is returned; +otherwise C<undef> is returned and an error message is printed (using +B<carp>) for each invalid regex. + +=end _PRIVATE_ + +=cut + +sub _compile_section_spec { + my ($section_spec) = @_; + my (@regexs, $negated); + + ## Compile the spec into a list of regexs + local $_ = $section_spec; + s|\\\\|\001|g; ## handle escaped backward slashes + s|\\/|\002|g; ## handle escaped forward slashes + + ## Parse the regexs for the heading titles + @regexs = split('/', $_, $MAX_HEADING_LEVEL); + + ## Set default regex for ommitted levels + for (my $i = 0; $i < $MAX_HEADING_LEVEL; ++$i) { + $regexs[$i] = '.*' unless ((defined $regexs[$i]) + && (length $regexs[$i])); + } + ## Modify the regexs as needed and validate their syntax + my $bad_regexs = 0; + for (@regexs) { + $_ .= '.+' if ($_ eq '!'); + s|\001|\\\\|g; ## restore escaped backward slashes + s|\002|\\/|g; ## restore escaped forward slashes + $negated = s/^\!//; ## check for negation + eval "/$_/"; ## check regex syntax + if ($@) { + ++$bad_regexs; + carp "Bad regular expression /$_/ in \"$section_spec\": $@\n"; + } + else { + ## Add the forward and rear anchors (and put the negator back) + $_ = '^' . $_ unless (/^\^/); + $_ = $_ . '$' unless (/\$$/); + $_ = '!' . $_ if ($negated); + } + } + return (! $bad_regexs) ? [ @regexs ] : undef; +} + +##--------------------------------------------------------------------------- + +=begin _PRIVATE_ + +=head2 $self->{_SECTION_HEADINGS} + +A reference to an array of the current section heading titles for each +heading level (note that the first heading level title is at index 0). + +=end _PRIVATE_ + +=cut + +##--------------------------------------------------------------------------- + +=begin _PRIVATE_ + +=head2 $self->{_SELECTED_SECTIONS} + +A reference to an array of references to arrays. Each subarray is a list +of anchored regular expressions (preceded by a "!" if the expression is to +be negated). The index of the expression in the subarray should correspond +to the index of the heading title in C<$self-E<gt>{_SECTION_HEADINGS}> +that it is to be matched against. + +=end _PRIVATE_ + +=cut + +############################################################################# + +=head1 SEE ALSO + +L<Pod::Parser> + +=head1 AUTHOR + +Please report bugs using L<http://rt.cpan.org>. + +Brad Appleton E<lt>bradapp@enteract.comE<gt> + +Based on code for B<pod2text> written by +Tom Christiansen E<lt>tchrist@mox.perl.comE<gt> + +=cut + +1; +# vim: ts=4 sw=4 et diff --git a/Master/tlpkg/installer/perllib/Pod/Text.pm b/Master/tlpkg/installer/perllib/Pod/Text.pm new file mode 100644 index 00000000000..1028f2e9e1b --- /dev/null +++ b/Master/tlpkg/installer/perllib/Pod/Text.pm @@ -0,0 +1,848 @@ +# Pod::Text -- Convert POD data to formatted ASCII text. +# $Id: Text.pm,v 2.21 2002/08/04 03:34:58 eagle Exp $ +# +# Copyright 1999, 2000, 2001, 2002 by Russ Allbery <rra@stanford.edu> +# +# This program is free software; you may redistribute it and/or modify it +# under the same terms as Perl itself. +# +# This module converts POD to formatted text. It replaces the old Pod::Text +# module that came with versions of Perl prior to 5.6.0 and attempts to match +# its output except for some specific circumstances where other decisions +# seemed to produce better output. It uses Pod::Parser and is designed to be +# very easy to subclass. +# +# Perl core hackers, please note that this module is also separately +# maintained outside of the Perl core as part of the podlators. Please send +# me any patches at the address above in addition to sending them to the +# standard Perl mailing lists. + +############################################################################## +# Modules and declarations +############################################################################## + +package Pod::Text; + +require 5.004; + +use Carp qw(carp croak); +use Exporter (); +use Pod::ParseLink qw(parselink); +use Pod::Select (); + +use strict; +use vars qw(@ISA @EXPORT %ESCAPES $VERSION); + +# We inherit from Pod::Select instead of Pod::Parser so that we can be used by +# Pod::Usage. +@ISA = qw(Pod::Select Exporter); + +# We have to export pod2text for backward compatibility. +@EXPORT = qw(pod2text); + +# Don't use the CVS revision as the version, since this module is also in Perl +# core and too many things could munge CVS magic revision strings. This +# number should ideally be the same as the CVS revision in podlators, however. +$VERSION = 2.21; + + +############################################################################## +# Table of supported E<> escapes +############################################################################## + +# This table is taken near verbatim from Pod::PlainText in Pod::Parser, which +# got it near verbatim from the original Pod::Text. It is therefore credited +# to Tom Christiansen, and I'm glad I didn't have to write it. :) "iexcl" to +# "divide" added by Tim Jenness. +%ESCAPES = ( + 'amp' => '&', # ampersand + 'apos' => "'", # apostrophe + 'lt' => '<', # left chevron, less-than + 'gt' => '>', # right chevron, greater-than + 'quot' => '"', # double quote + 'sol' => '/', # solidus (forward slash) + 'verbar' => '|', # vertical bar + + "Aacute" => "\xC1", # capital A, acute accent + "aacute" => "\xE1", # small a, acute accent + "Acirc" => "\xC2", # capital A, circumflex accent + "acirc" => "\xE2", # small a, circumflex accent + "AElig" => "\xC6", # capital AE diphthong (ligature) + "aelig" => "\xE6", # small ae diphthong (ligature) + "Agrave" => "\xC0", # capital A, grave accent + "agrave" => "\xE0", # small a, grave accent + "Aring" => "\xC5", # capital A, ring + "aring" => "\xE5", # small a, ring + "Atilde" => "\xC3", # capital A, tilde + "atilde" => "\xE3", # small a, tilde + "Auml" => "\xC4", # capital A, dieresis or umlaut mark + "auml" => "\xE4", # small a, dieresis or umlaut mark + "Ccedil" => "\xC7", # capital C, cedilla + "ccedil" => "\xE7", # small c, cedilla + "Eacute" => "\xC9", # capital E, acute accent + "eacute" => "\xE9", # small e, acute accent + "Ecirc" => "\xCA", # capital E, circumflex accent + "ecirc" => "\xEA", # small e, circumflex accent + "Egrave" => "\xC8", # capital E, grave accent + "egrave" => "\xE8", # small e, grave accent + "ETH" => "\xD0", # capital Eth, Icelandic + "eth" => "\xF0", # small eth, Icelandic + "Euml" => "\xCB", # capital E, dieresis or umlaut mark + "euml" => "\xEB", # small e, dieresis or umlaut mark + "Iacute" => "\xCD", # capital I, acute accent + "iacute" => "\xED", # small i, acute accent + "Icirc" => "\xCE", # capital I, circumflex accent + "icirc" => "\xEE", # small i, circumflex accent + "Igrave" => "\xCC", # capital I, grave accent + "igrave" => "\xEC", # small i, grave accent + "Iuml" => "\xCF", # capital I, dieresis or umlaut mark + "iuml" => "\xEF", # small i, dieresis or umlaut mark + "Ntilde" => "\xD1", # capital N, tilde + "ntilde" => "\xF1", # small n, tilde + "Oacute" => "\xD3", # capital O, acute accent + "oacute" => "\xF3", # small o, acute accent + "Ocirc" => "\xD4", # capital O, circumflex accent + "ocirc" => "\xF4", # small o, circumflex accent + "Ograve" => "\xD2", # capital O, grave accent + "ograve" => "\xF2", # small o, grave accent + "Oslash" => "\xD8", # capital O, slash + "oslash" => "\xF8", # small o, slash + "Otilde" => "\xD5", # capital O, tilde + "otilde" => "\xF5", # small o, tilde + "Ouml" => "\xD6", # capital O, dieresis or umlaut mark + "ouml" => "\xF6", # small o, dieresis or umlaut mark + "szlig" => "\xDF", # small sharp s, German (sz ligature) + "THORN" => "\xDE", # capital THORN, Icelandic + "thorn" => "\xFE", # small thorn, Icelandic + "Uacute" => "\xDA", # capital U, acute accent + "uacute" => "\xFA", # small u, acute accent + "Ucirc" => "\xDB", # capital U, circumflex accent + "ucirc" => "\xFB", # small u, circumflex accent + "Ugrave" => "\xD9", # capital U, grave accent + "ugrave" => "\xF9", # small u, grave accent + "Uuml" => "\xDC", # capital U, dieresis or umlaut mark + "uuml" => "\xFC", # small u, dieresis or umlaut mark + "Yacute" => "\xDD", # capital Y, acute accent + "yacute" => "\xFD", # small y, acute accent + "yuml" => "\xFF", # small y, dieresis or umlaut mark + + "laquo" => "\xAB", # left pointing double angle quotation mark + "lchevron" => "\xAB", # synonym (backwards compatibility) + "raquo" => "\xBB", # right pointing double angle quotation mark + "rchevron" => "\xBB", # synonym (backwards compatibility) + + "iexcl" => "\xA1", # inverted exclamation mark + "cent" => "\xA2", # cent sign + "pound" => "\xA3", # (UK) pound sign + "curren" => "\xA4", # currency sign + "yen" => "\xA5", # yen sign + "brvbar" => "\xA6", # broken vertical bar + "sect" => "\xA7", # section sign + "uml" => "\xA8", # diaresis + "copy" => "\xA9", # Copyright symbol + "ordf" => "\xAA", # feminine ordinal indicator + "not" => "\xAC", # not sign + "shy" => '', # soft (discretionary) hyphen + "reg" => "\xAE", # registered trademark + "macr" => "\xAF", # macron, overline + "deg" => "\xB0", # degree sign + "plusmn" => "\xB1", # plus-minus sign + "sup2" => "\xB2", # superscript 2 + "sup3" => "\xB3", # superscript 3 + "acute" => "\xB4", # acute accent + "micro" => "\xB5", # micro sign + "para" => "\xB6", # pilcrow sign = paragraph sign + "middot" => "\xB7", # middle dot = Georgian comma + "cedil" => "\xB8", # cedilla + "sup1" => "\xB9", # superscript 1 + "ordm" => "\xBA", # masculine ordinal indicator + "frac14" => "\xBC", # vulgar fraction one quarter + "frac12" => "\xBD", # vulgar fraction one half + "frac34" => "\xBE", # vulgar fraction three quarters + "iquest" => "\xBF", # inverted question mark + "times" => "\xD7", # multiplication sign + "divide" => "\xF7", # division sign + + "nbsp" => "\x01", # non-breaking space +); + + +############################################################################## +# Initialization +############################################################################## + +# Initialize the object. Must be sure to call our parent initializer. +sub initialize { + my $self = shift; + + $$self{alt} = 0 unless defined $$self{alt}; + $$self{indent} = 4 unless defined $$self{indent}; + $$self{margin} = 0 unless defined $$self{margin}; + $$self{loose} = 0 unless defined $$self{loose}; + $$self{sentence} = 0 unless defined $$self{sentence}; + $$self{width} = 76 unless defined $$self{width}; + + # Figure out what quotes we'll be using for C<> text. + $$self{quotes} ||= '"'; + if ($$self{quotes} eq 'none') { + $$self{LQUOTE} = $$self{RQUOTE} = ''; + } elsif (length ($$self{quotes}) == 1) { + $$self{LQUOTE} = $$self{RQUOTE} = $$self{quotes}; + } elsif ($$self{quotes} =~ /^(.)(.)$/ + || $$self{quotes} =~ /^(..)(..)$/) { + $$self{LQUOTE} = $1; + $$self{RQUOTE} = $2; + } else { + croak qq(Invalid quote specification "$$self{quotes}"); + } + + # Stack of indentations. + $$self{INDENTS} = []; + + # Current left margin. + $$self{MARGIN} = $$self{indent} + $$self{margin}; + + $self->SUPER::initialize; + + # Tell Pod::Parser that we want the non-POD stuff too if code was set. + $self->parseopts ('-want_nonPODs' => 1) if $$self{code}; +} + + +############################################################################## +# Core overrides +############################################################################## + +# Called for each command paragraph. Gets the command, the associated +# paragraph, the line number, and a Pod::Paragraph object. Just dispatches +# the command to a method named the same as the command. =cut is handled +# internally by Pod::Parser. +sub command { + my $self = shift; + my $command = shift; + return if $command eq 'pod'; + return if ($$self{EXCLUDE} && $command ne 'end'); + if ($self->can ('cmd_' . $command)) { + $command = 'cmd_' . $command; + $self->$command (@_); + } else { + my ($text, $line, $paragraph) = @_; + my $file; + ($file, $line) = $paragraph->file_line; + $text =~ s/\n+\z//; + $text = " $text" if ($text =~ /^\S/); + warn qq($file:$line: Unknown command paragraph: =$command$text\n); + return; + } +} + +# Called for a verbatim paragraph. Gets the paragraph, the line number, and a +# Pod::Paragraph object. Just output it verbatim, but with tabs converted to +# spaces. +sub verbatim { + my $self = shift; + return if $$self{EXCLUDE}; + $self->item if defined $$self{ITEM}; + local $_ = shift; + return if /^\s*$/; + s/^(\s*\S+)/(' ' x $$self{MARGIN}) . $1/gme; + $self->output ($_); +} + +# Called for a regular text block. Gets the paragraph, the line number, and a +# Pod::Paragraph object. Perform interpolation and output the results. +sub textblock { + my $self = shift; + return if $$self{EXCLUDE}; + $self->output ($_[0]), return if $$self{VERBATIM}; + local $_ = shift; + my $line = shift; + + # Interpolate and output the paragraph. + $_ = $self->interpolate ($_, $line); + s/\s+$/\n/; + if (defined $$self{ITEM}) { + $self->item ($_ . "\n"); + } else { + $self->output ($self->reformat ($_ . "\n")); + } +} + +# Called for a formatting code. Gets the command, argument, and a +# Pod::InteriorSequence object and is expected to return the resulting text. +# Calls methods for code, bold, italic, file, and link to handle those types +# of codes, and handles S<>, E<>, X<>, and Z<> directly. +sub interior_sequence { + local $_; + my ($self, $command, $seq); + ($self, $command, $_, $seq) = @_; + + # We have to defer processing of the inside of an L<> formatting code. If + # this code is nested inside an L<> code, return the literal raw text of + # it. + my $parent = $seq->nested; + while (defined $parent) { + return $seq->raw_text if ($parent->cmd_name eq 'L'); + $parent = $parent->nested; + } + + # Index entries are ignored in plain text. + return '' if ($command eq 'X' || $command eq 'Z'); + + # Expand escapes into the actual character now, warning if invalid. + if ($command eq 'E') { + if (/^\d+$/) { + return chr; + } else { + return $ESCAPES{$_} if defined $ESCAPES{$_}; + my ($file, $line) = $seq->file_line; + warn "$file:$line: Unknown escape: E<$_>\n"; + return "E<$_>"; + } + } + + # For all the other formatting codes, empty content produces no output. + return if $_ eq ''; + + # For S<>, compress all internal whitespace and then map spaces to \01. + # When we output the text, we'll map this back. + if ($command eq 'S') { + s/\s+/ /g; + tr/ /\01/; + return $_; + } + + # Anything else needs to get dispatched to another method. + if ($command eq 'B') { return $self->seq_b ($_) } + elsif ($command eq 'C') { return $self->seq_c ($_) } + elsif ($command eq 'F') { return $self->seq_f ($_) } + elsif ($command eq 'I') { return $self->seq_i ($_) } + elsif ($command eq 'L') { return $self->seq_l ($_, $seq) } + else { + my ($file, $line) = $seq->file_line; + warn "$file:$line: Unknown formatting code: $command<$_>\n"; + } +} + +# Called for each paragraph that's actually part of the POD. We take +# advantage of this opportunity to untabify the input. Also, if given the +# code option, we may see paragraphs that aren't part of the POD and need to +# output them directly. +sub preprocess_paragraph { + my $self = shift; + local $_ = shift; + 1 while s/^(.*?)(\t+)/$1 . ' ' x (length ($2) * 8 - length ($1) % 8)/me; + $self->output_code ($_) if $self->cutting; + $_; +} + + +############################################################################## +# Command paragraphs +############################################################################## + +# All command paragraphs take the paragraph and the line number. + +# First level heading. +sub cmd_head1 { + my ($self, $text, $line) = @_; + $self->heading ($text, $line, 0, '===='); +} + +# Second level heading. +sub cmd_head2 { + my ($self, $text, $line) = @_; + $self->heading ($text, $line, $$self{indent} / 2, '== '); +} + +# Third level heading. +sub cmd_head3 { + my ($self, $text, $line) = @_; + $self->heading ($text, $line, $$self{indent} * 2 / 3 + 0.5, '= '); +} + +# Third level heading. +sub cmd_head4 { + my ($self, $text, $line) = @_; + $self->heading ($text, $line, $$self{indent} * 3 / 4 + 0.5, '- '); +} + +# Start a list. +sub cmd_over { + my $self = shift; + local $_ = shift; + $self->item ("\n\n") if defined $$self{ITEM}; + unless (/^[-+]?\d+\s+$/) { $_ = $$self{indent} } + push (@{ $$self{INDENTS} }, $$self{MARGIN}); + $$self{MARGIN} += ($_ + 0); +} + +# End a list. +sub cmd_back { + my ($self, $text, $line, $paragraph) = @_; + $self->item ("\n\n") if defined $$self{ITEM}; + $$self{MARGIN} = pop @{ $$self{INDENTS} }; + unless (defined $$self{MARGIN}) { + my $file; + ($file, $line) = $paragraph->file_line; + warn "$file:$line: Unmatched =back\n"; + $$self{MARGIN} = $$self{indent}; + } +} + +# An individual list item. +sub cmd_item { + my $self = shift; + if (defined $$self{ITEM}) { $self->item } + local $_ = shift; + s/\s+$//; + $$self{ITEM} = $_ ? $self->interpolate ($_) : '*'; +} + +# Begin a block for a particular translator. Setting VERBATIM triggers +# special handling in textblock(). +sub cmd_begin { + my $self = shift; + local $_ = shift; + my ($kind) = /^(\S+)/ or return; + if ($kind eq 'text') { + $$self{VERBATIM} = 1; + } else { + $$self{EXCLUDE} = 1; + } +} + +# End a block for a particular translator. We assume that all =begin/=end +# pairs are properly closed. +sub cmd_end { + my $self = shift; + $$self{EXCLUDE} = 0; + $$self{VERBATIM} = 0; +} + +# One paragraph for a particular translator. Ignore it unless it's intended +# for text, in which case we treat it as a verbatim text block. +sub cmd_for { + my $self = shift; + local $_ = shift; + my $line = shift; + return unless s/^text\b[ \t]*\n?//; + $self->verbatim ($_, $line); +} + + +############################################################################## +# Formatting codes +############################################################################## + +# The simple ones. These are here mostly so that subclasses can override them +# and do more complicated things. +sub seq_b { return $_[0]{alt} ? "``$_[1]''" : $_[1] } +sub seq_f { return $_[0]{alt} ? "\"$_[1]\"" : $_[1] } +sub seq_i { return '*' . $_[1] . '*' } + +# Apply a whole bunch of messy heuristics to not quote things that don't +# benefit from being quoted. These originally come from Barrie Slaymaker and +# largely duplicate code in Pod::Man. +sub seq_c { + my $self = shift; + local $_ = shift; + + # A regex that matches the portion of a variable reference that's the + # array or hash index, separated out just because we want to use it in + # several places in the following regex. + my $index = '(?: \[.*\] | \{.*\} )?'; + + # Check for things that we don't want to quote, and if we find any of + # them, return the string with just a font change and no quoting. + m{ + ^\s* + (?: + ( [\'\`\"] ) .* \1 # already quoted + | \` .* \' # `quoted' + | \$+ [\#^]? \S $index # special ($^Foo, $") + | [\$\@%&*]+ \#? [:\'\w]+ $index # plain var or func + | [\$\@%&*]* [:\'\w]+ (?: -> )? \(\s*[^\s,]\s*\) # 0/1-arg func call + | [+-]? ( \d[\d.]* | \.\d+ ) (?: [eE][+-]?\d+ )? # a number + | 0x [a-fA-F\d]+ # a hex constant + ) + \s*\z + }xo && return $_; + + # If we didn't return, go ahead and quote the text. + return $$self{alt} ? "``$_''" : "$$self{LQUOTE}$_$$self{RQUOTE}"; +} + +# Handle links. Since this is plain text, we can't actually make any real +# links, so this is all to figure out what text we print out. Most of the +# work is done by Pod::ParseLink. +sub seq_l { + my ($self, $link, $seq) = @_; + my ($text, $type) = (parselink ($link))[1,4]; + my ($file, $line) = $seq->file_line; + $text = $self->interpolate ($text, $line); + $text = '<' . $text . '>' if $type eq 'url'; + return $text || ''; +} + + +############################################################################## +# Header handling +############################################################################## + +# The common code for handling all headers. Takes the interpolated header +# text, the line number, the indentation, and the surrounding marker for the +# alt formatting method. +sub heading { + my ($self, $text, $line, $indent, $marker) = @_; + $self->item ("\n\n") if defined $$self{ITEM}; + $text =~ s/\s+$//; + $text = $self->interpolate ($text, $line); + if ($$self{alt}) { + my $closemark = reverse (split (//, $marker)); + my $margin = ' ' x $$self{margin}; + $self->output ("\n" . "$margin$marker $text $closemark" . "\n\n"); + } else { + $text .= "\n" if $$self{loose}; + my $margin = ' ' x ($$self{margin} + $indent); + $self->output ($margin . $text . "\n"); + } +} + + +############################################################################## +# List handling +############################################################################## + +# This method is called whenever an =item command is complete (in other words, +# we've seen its associated paragraph or know for certain that it doesn't have +# one). It gets the paragraph associated with the item as an argument. If +# that argument is empty, just output the item tag; if it contains a newline, +# output the item tag followed by the newline. Otherwise, see if there's +# enough room for us to output the item tag in the margin of the text or if we +# have to put it on a separate line. +sub item { + my $self = shift; + local $_ = shift; + my $tag = $$self{ITEM}; + unless (defined $tag) { + carp "Item called without tag"; + return; + } + undef $$self{ITEM}; + my $indent = $$self{INDENTS}[-1]; + unless (defined $indent) { $indent = $$self{indent} } + my $margin = ' ' x $$self{margin}; + if (!$_ || /^\s+$/ || ($$self{MARGIN} - $indent < length ($tag) + 1)) { + my $realindent = $$self{MARGIN}; + $$self{MARGIN} = $indent; + my $output = $self->reformat ($tag); + $output =~ s/^$margin /$margin:/ if ($$self{alt} && $indent > 0); + $output =~ s/\n*$/\n/; + + # If the text is just whitespace, we have an empty item paragraph; + # this can result from =over/=item/=back without any intermixed + # paragraphs. Insert some whitespace to keep the =item from merging + # into the next paragraph. + $output .= "\n" if $_ && $_ =~ /^\s*$/; + + $self->output ($output); + $$self{MARGIN} = $realindent; + $self->output ($self->reformat ($_)) if $_ && /\S/; + } else { + my $space = ' ' x $indent; + $space =~ s/^$margin /$margin:/ if $$self{alt}; + $_ = $self->reformat ($_); + s/^$margin /$margin:/ if ($$self{alt} && $indent > 0); + my $tagspace = ' ' x length $tag; + s/^($space)$tagspace/$1$tag/ or warn "Bizarre space in item"; + $self->output ($_); + } +} + + +############################################################################## +# Output formatting +############################################################################## + +# Wrap a line, indenting by the current left margin. We can't use Text::Wrap +# because it plays games with tabs. We can't use formline, even though we'd +# really like to, because it screws up non-printing characters. So we have to +# do the wrapping ourselves. +sub wrap { + my $self = shift; + local $_ = shift; + my $output = ''; + my $spaces = ' ' x $$self{MARGIN}; + my $width = $$self{width} - $$self{MARGIN}; + while (length > $width) { + if (s/^([^\n]{0,$width})\s+// || s/^([^\n]{$width})//) { + $output .= $spaces . $1 . "\n"; + } else { + last; + } + } + $output .= $spaces . $_; + $output =~ s/\s+$/\n\n/; + $output; +} + +# Reformat a paragraph of text for the current margin. Takes the text to +# reformat and returns the formatted text. +sub reformat { + my $self = shift; + local $_ = shift; + + # If we're trying to preserve two spaces after sentences, do some munging + # to support that. Otherwise, smash all repeated whitespace. + if ($$self{sentence}) { + s/ +$//mg; + s/\.\n/. \n/g; + s/\n/ /g; + s/ +/ /g; + } else { + s/\s+/ /g; + } + $self->wrap ($_); +} + +# Output text to the output device. +sub output { $_[1] =~ tr/\01/ /; print { $_[0]->output_handle } $_[1] } + +# Output a block of code (something that isn't part of the POD text). Called +# by preprocess_paragraph only if we were given the code option. Exists here +# only so that it can be overridden by subclasses. +sub output_code { $_[0]->output ($_[1]) } + + +############################################################################## +# Backwards compatibility +############################################################################## + +# The old Pod::Text module did everything in a pod2text() function. This +# tries to provide the same interface for legacy applications. +sub pod2text { + my @args; + + # This is really ugly; I hate doing option parsing in the middle of a + # module. But the old Pod::Text module supported passing flags to its + # entry function, so handle -a and -<number>. + while ($_[0] =~ /^-/) { + my $flag = shift; + if ($flag eq '-a') { push (@args, alt => 1) } + elsif ($flag =~ /^-(\d+)$/) { push (@args, width => $1) } + else { + unshift (@_, $flag); + last; + } + } + + # Now that we know what arguments we're using, create the parser. + my $parser = Pod::Text->new (@args); + + # If two arguments were given, the second argument is going to be a file + # handle. That means we want to call parse_from_filehandle(), which means + # we need to turn the first argument into a file handle. Magic open will + # handle the <&STDIN case automagically. + if (defined $_[1]) { + my @fhs = @_; + local *IN; + unless (open (IN, $fhs[0])) { + croak ("Can't open $fhs[0] for reading: $!\n"); + return; + } + $fhs[0] = \*IN; + return $parser->parse_from_filehandle (@fhs); + } else { + return $parser->parse_from_file (@_); + } +} + + +############################################################################## +# Module return value and documentation +############################################################################## + +1; +__END__ + +=head1 NAME + +Pod::Text - Convert POD data to formatted ASCII text + +=head1 SYNOPSIS + + use Pod::Text; + my $parser = Pod::Text->new (sentence => 0, width => 78); + + # Read POD from STDIN and write to STDOUT. + $parser->parse_from_filehandle; + + # Read POD from file.pod and write to file.txt. + $parser->parse_from_file ('file.pod', 'file.txt'); + +=head1 DESCRIPTION + +Pod::Text is a module that can convert documentation in the POD format (the +preferred language for documenting Perl) into formatted ASCII. It uses no +special formatting controls or codes whatsoever, and its output is therefore +suitable for nearly any device. + +As a derived class from Pod::Parser, Pod::Text supports the same methods and +interfaces. See L<Pod::Parser> for all the details; briefly, one creates a +new parser with C<< Pod::Text->new() >> and then calls either +parse_from_filehandle() or parse_from_file(). + +new() can take options, in the form of key/value pairs, that control the +behavior of the parser. The currently recognized options are: + +=over 4 + +=item alt + +If set to a true value, selects an alternate output format that, among other +things, uses a different heading style and marks C<=item> entries with a +colon in the left margin. Defaults to false. + +=item code + +If set to a true value, the non-POD parts of the input file will be included +in the output. Useful for viewing code documented with POD blocks with the +POD rendered and the code left intact. + +=item indent + +The number of spaces to indent regular text, and the default indentation for +C<=over> blocks. Defaults to 4. + +=item loose + +If set to a true value, a blank line is printed after a C<=head1> heading. +If set to false (the default), no blank line is printed after C<=head1>, +although one is still printed after C<=head2>. This is the default because +it's the expected formatting for manual pages; if you're formatting +arbitrary text documents, setting this to true may result in more pleasing +output. + +=item margin + +The width of the left margin in spaces. Defaults to 0. This is the margin +for all text, including headings, not the amount by which regular text is +indented; for the latter, see the I<indent> option. To set the right +margin, see the I<width> option. + +=item quotes + +Sets the quote marks used to surround CE<lt>> text. If the value is a +single character, it is used as both the left and right quote; if it is two +characters, the first character is used as the left quote and the second as +the right quoted; and if it is four characters, the first two are used as +the left quote and the second two as the right quote. + +This may also be set to the special value C<none>, in which case no quote +marks are added around CE<lt>> text. + +=item sentence + +If set to a true value, Pod::Text will assume that each sentence ends in two +spaces, and will try to preserve that spacing. If set to false, all +consecutive whitespace in non-verbatim paragraphs is compressed into a +single space. Defaults to true. + +=item width + +The column at which to wrap text on the right-hand side. Defaults to 76. + +=back + +The standard Pod::Parser method parse_from_filehandle() takes up to two +arguments, the first being the file handle to read POD from and the second +being the file handle to write the formatted output to. The first defaults +to STDIN if not given, and the second defaults to STDOUT. The method +parse_from_file() is almost identical, except that its two arguments are the +input and output disk files instead. See L<Pod::Parser> for the specific +details. + +=head1 DIAGNOSTICS + +=over 4 + +=item Bizarre space in item + +=item Item called without tag + +(W) Something has gone wrong in internal C<=item> processing. These +messages indicate a bug in Pod::Text; you should never see them. + +=item Can't open %s for reading: %s + +(F) Pod::Text was invoked via the compatibility mode pod2text() interface +and the input file it was given could not be opened. + +=item Invalid quote specification "%s" + +(F) The quote specification given (the quotes option to the constructor) was +invalid. A quote specification must be one, two, or four characters long. + +=item %s:%d: Unknown command paragraph: %s + +(W) The POD source contained a non-standard command paragraph (something of +the form C<=command args>) that Pod::Man didn't know about. It was ignored. + +=item %s:%d: Unknown escape: %s + +(W) The POD source contained an C<EE<lt>E<gt>> escape that Pod::Text didn't +know about. + +=item %s:%d: Unknown formatting code: %s + +(W) The POD source contained a non-standard formatting code (something of +the form C<XE<lt>E<gt>>) that Pod::Text didn't know about. + +=item %s:%d: Unmatched =back + +(W) Pod::Text encountered a C<=back> command that didn't correspond to an +C<=over> command. + +=back + +=head1 RESTRICTIONS + +Embedded Ctrl-As (octal 001) in the input will be mapped to spaces on +output, due to an internal implementation detail. + +=head1 NOTES + +This is a replacement for an earlier Pod::Text module written by Tom +Christiansen. It has a revamped interface, since it now uses Pod::Parser, +but an interface roughly compatible with the old Pod::Text::pod2text() +function is still available. Please change to the new calling convention, +though. + +The original Pod::Text contained code to do formatting via termcap +sequences, although it wasn't turned on by default and it was problematic to +get it to work at all. This rewrite doesn't even try to do that, but a +subclass of it does. Look for L<Pod::Text::Termcap>. + +=head1 SEE ALSO + +L<Pod::Parser>, L<Pod::Text::Termcap>, L<pod2text(1)> + +The current version of this module is always available from its web site at +L<http://www.eyrie.org/~eagle/software/podlators/>. It is also part of the +Perl core distribution as of 5.6.0. + +=head1 AUTHOR + +Russ Allbery <rra@stanford.edu>, based I<very> heavily on the original +Pod::Text by Tom Christiansen <tchrist@mox.perl.com> and its conversion to +Pod::Parser by Brad Appleton <bradapp@enteract.com>. + +=head1 COPYRIGHT AND LICENSE + +Copyright 1999, 2000, 2001, 2002 by Russ Allbery <rra@stanford.edu>. + +This program is free software; you may redistribute it and/or modify it +under the same terms as Perl itself. + +=cut diff --git a/Master/tlpkg/installer/perllib/Pod/Usage.pm b/Master/tlpkg/installer/perllib/Pod/Usage.pm new file mode 100644 index 00000000000..c298e941f21 --- /dev/null +++ b/Master/tlpkg/installer/perllib/Pod/Usage.pm @@ -0,0 +1,659 @@ +############################################################################# +# Pod/Usage.pm -- print usage messages for the running script. +# +# Copyright (C) 1996-2000 by Bradford Appleton. All rights reserved. +# This file is part of "PodParser". PodParser is free software; +# you can redistribute it and/or modify it under the same terms +# as Perl itself. +############################################################################# + +package Pod::Usage; + +use vars qw($VERSION); +$VERSION = 1.33; ## Current version of this package +require 5.005; ## requires this Perl version or later + +=head1 NAME + +Pod::Usage, pod2usage() - print a usage message from embedded pod documentation + +=head1 SYNOPSIS + + use Pod::Usage + + my $message_text = "This text precedes the usage message."; + my $exit_status = 2; ## The exit status to use + my $verbose_level = 0; ## The verbose level to use + my $filehandle = \*STDERR; ## The filehandle to write to + + pod2usage($message_text); + + pod2usage($exit_status); + + pod2usage( { -message => $message_text , + -exitval => $exit_status , + -verbose => $verbose_level, + -output => $filehandle } ); + + pod2usage( -msg => $message_text , + -exitval => $exit_status , + -verbose => $verbose_level, + -output => $filehandle ); + + pod2usage( -verbose => 2, + -noperldoc => 1 ) + +=head1 ARGUMENTS + +B<pod2usage> should be given either a single argument, or a list of +arguments corresponding to an associative array (a "hash"). When a single +argument is given, it should correspond to exactly one of the following: + +=over 4 + +=item * + +A string containing the text of a message to print I<before> printing +the usage message + +=item * + +A numeric value corresponding to the desired exit status + +=item * + +A reference to a hash + +=back + +If more than one argument is given then the entire argument list is +assumed to be a hash. If a hash is supplied (either as a reference or +as a list) it should contain one or more elements with the following +keys: + +=over 4 + +=item C<-message> + +=item C<-msg> + +The text of a message to print immediately prior to printing the +program's usage message. + +=item C<-exitval> + +The desired exit status to pass to the B<exit()> function. +This should be an integer, or else the string "NOEXIT" to +indicate that control should simply be returned without +terminating the invoking process. + +=item C<-verbose> + +The desired level of "verboseness" to use when printing the usage +message. If the corresponding value is 0, then only the "SYNOPSIS" +section of the pod documentation is printed. If the corresponding value +is 1, then the "SYNOPSIS" section, along with any section entitled +"OPTIONS", "ARGUMENTS", or "OPTIONS AND ARGUMENTS" is printed. If the +corresponding value is 2 or more then the entire manpage is printed. + +The special verbosity level 99 requires to also specify the -section +parameter; then these sections are extracted (see L<Pod::Select>) +and printed. + +=item C<-section> + +A string representing a selection list for sections to be printed +when -verbose is set to 99, e.g. C<"NAME|SYNOPSIS|DESCRIPTION|VERSION">. + +=item C<-output> + +A reference to a filehandle, or the pathname of a file to which the +usage message should be written. The default is C<\*STDERR> unless the +exit value is less than 2 (in which case the default is C<\*STDOUT>). + +=item C<-input> + +A reference to a filehandle, or the pathname of a file from which the +invoking script's pod documentation should be read. It defaults to the +file indicated by C<$0> (C<$PROGRAM_NAME> for users of F<English.pm>). + +=item C<-pathlist> + +A list of directory paths. If the input file does not exist, then it +will be searched for in the given directory list (in the order the +directories appear in the list). It defaults to the list of directories +implied by C<$ENV{PATH}>. The list may be specified either by a reference +to an array, or by a string of directory paths which use the same path +separator as C<$ENV{PATH}> on your system (e.g., C<:> for Unix, C<;> for +MSWin32 and DOS). + +=item C<-noperldoc> + +By default, Pod::Usage will call L<perldoc> when -verbose >= 2 is +specified. This does not work well e.g. if the script was packed +with L<PAR>. The -noperldoc option suppresses the external call to +L<perldoc> and uses the simple text formatter (L<Pod::Text>) to +output the POD. + +=back + +=head1 DESCRIPTION + +B<pod2usage> will print a usage message for the invoking script (using +its embedded pod documentation) and then exit the script with the +desired exit status. The usage message printed may have any one of three +levels of "verboseness": If the verbose level is 0, then only a synopsis +is printed. If the verbose level is 1, then the synopsis is printed +along with a description (if present) of the command line options and +arguments. If the verbose level is 2, then the entire manual page is +printed. + +Unless they are explicitly specified, the default values for the exit +status, verbose level, and output stream to use are determined as +follows: + +=over 4 + +=item * + +If neither the exit status nor the verbose level is specified, then the +default is to use an exit status of 2 with a verbose level of 0. + +=item * + +If an exit status I<is> specified but the verbose level is I<not>, then the +verbose level will default to 1 if the exit status is less than 2 and +will default to 0 otherwise. + +=item * + +If an exit status is I<not> specified but verbose level I<is> given, then +the exit status will default to 2 if the verbose level is 0 and will +default to 1 otherwise. + +=item * + +If the exit status used is less than 2, then output is printed on +C<STDOUT>. Otherwise output is printed on C<STDERR>. + +=back + +Although the above may seem a bit confusing at first, it generally does +"the right thing" in most situations. This determination of the default +values to use is based upon the following typical Unix conventions: + +=over 4 + +=item * + +An exit status of 0 implies "success". For example, B<diff(1)> exits +with a status of 0 if the two files have the same contents. + +=item * + +An exit status of 1 implies possibly abnormal, but non-defective, program +termination. For example, B<grep(1)> exits with a status of 1 if +it did I<not> find a matching line for the given regular expression. + +=item * + +An exit status of 2 or more implies a fatal error. For example, B<ls(1)> +exits with a status of 2 if you specify an illegal (unknown) option on +the command line. + +=item * + +Usage messages issued as a result of bad command-line syntax should go +to C<STDERR>. However, usage messages issued due to an explicit request +to print usage (like specifying B<-help> on the command line) should go +to C<STDOUT>, just in case the user wants to pipe the output to a pager +(such as B<more(1)>). + +=item * + +If program usage has been explicitly requested by the user, it is often +desireable to exit with a status of 1 (as opposed to 0) after issuing +the user-requested usage message. It is also desireable to give a +more verbose description of program usage in this case. + +=back + +B<pod2usage> doesn't force the above conventions upon you, but it will +use them by default if you don't expressly tell it to do otherwise. The +ability of B<pod2usage()> to accept a single number or a string makes it +convenient to use as an innocent looking error message handling function: + + use Pod::Usage; + use Getopt::Long; + + ## Parse options + GetOptions("help", "man", "flag1") || pod2usage(2); + pod2usage(1) if ($opt_help); + pod2usage(-verbose => 2) if ($opt_man); + + ## Check for too many filenames + pod2usage("$0: Too many files given.\n") if (@ARGV > 1); + +Some user's however may feel that the above "economy of expression" is +not particularly readable nor consistent and may instead choose to do +something more like the following: + + use Pod::Usage; + use Getopt::Long; + + ## Parse options + GetOptions("help", "man", "flag1") || pod2usage(-verbose => 0); + pod2usage(-verbose => 1) if ($opt_help); + pod2usage(-verbose => 2) if ($opt_man); + + ## Check for too many filenames + pod2usage(-verbose => 2, -message => "$0: Too many files given.\n") + if (@ARGV > 1); + +As with all things in Perl, I<there's more than one way to do it>, and +B<pod2usage()> adheres to this philosophy. If you are interested in +seeing a number of different ways to invoke B<pod2usage> (although by no +means exhaustive), please refer to L<"EXAMPLES">. + +=head1 EXAMPLES + +Each of the following invocations of C<pod2usage()> will print just the +"SYNOPSIS" section to C<STDERR> and will exit with a status of 2: + + pod2usage(); + + pod2usage(2); + + pod2usage(-verbose => 0); + + pod2usage(-exitval => 2); + + pod2usage({-exitval => 2, -output => \*STDERR}); + + pod2usage({-verbose => 0, -output => \*STDERR}); + + pod2usage(-exitval => 2, -verbose => 0); + + pod2usage(-exitval => 2, -verbose => 0, -output => \*STDERR); + +Each of the following invocations of C<pod2usage()> will print a message +of "Syntax error." (followed by a newline) to C<STDERR>, immediately +followed by just the "SYNOPSIS" section (also printed to C<STDERR>) and +will exit with a status of 2: + + pod2usage("Syntax error."); + + pod2usage(-message => "Syntax error.", -verbose => 0); + + pod2usage(-msg => "Syntax error.", -exitval => 2); + + pod2usage({-msg => "Syntax error.", -exitval => 2, -output => \*STDERR}); + + pod2usage({-msg => "Syntax error.", -verbose => 0, -output => \*STDERR}); + + pod2usage(-msg => "Syntax error.", -exitval => 2, -verbose => 0); + + pod2usage(-message => "Syntax error.", + -exitval => 2, + -verbose => 0, + -output => \*STDERR); + +Each of the following invocations of C<pod2usage()> will print the +"SYNOPSIS" section and any "OPTIONS" and/or "ARGUMENTS" sections to +C<STDOUT> and will exit with a status of 1: + + pod2usage(1); + + pod2usage(-verbose => 1); + + pod2usage(-exitval => 1); + + pod2usage({-exitval => 1, -output => \*STDOUT}); + + pod2usage({-verbose => 1, -output => \*STDOUT}); + + pod2usage(-exitval => 1, -verbose => 1); + + pod2usage(-exitval => 1, -verbose => 1, -output => \*STDOUT}); + +Each of the following invocations of C<pod2usage()> will print the +entire manual page to C<STDOUT> and will exit with a status of 1: + + pod2usage(-verbose => 2); + + pod2usage({-verbose => 2, -output => \*STDOUT}); + + pod2usage(-exitval => 1, -verbose => 2); + + pod2usage({-exitval => 1, -verbose => 2, -output => \*STDOUT}); + +=head2 Recommended Use + +Most scripts should print some type of usage message to C<STDERR> when a +command line syntax error is detected. They should also provide an +option (usually C<-H> or C<-help>) to print a (possibly more verbose) +usage message to C<STDOUT>. Some scripts may even wish to go so far as to +provide a means of printing their complete documentation to C<STDOUT> +(perhaps by allowing a C<-man> option). The following complete example +uses B<Pod::Usage> in combination with B<Getopt::Long> to do all of these +things: + + use Getopt::Long; + use Pod::Usage; + + my $man = 0; + my $help = 0; + ## Parse options and print usage if there is a syntax error, + ## or if usage was explicitly requested. + GetOptions('help|?' => \$help, man => \$man) or pod2usage(2); + pod2usage(1) if $help; + pod2usage(-verbose => 2) if $man; + + ## If no arguments were given, then allow STDIN to be used only + ## if it's not connected to a terminal (otherwise print usage) + pod2usage("$0: No files given.") if ((@ARGV == 0) && (-t STDIN)); + __END__ + + =head1 NAME + + sample - Using GetOpt::Long and Pod::Usage + + =head1 SYNOPSIS + + sample [options] [file ...] + + Options: + -help brief help message + -man full documentation + + =head1 OPTIONS + + =over 8 + + =item B<-help> + + Print a brief help message and exits. + + =item B<-man> + + Prints the manual page and exits. + + =back + + =head1 DESCRIPTION + + B<This program> will read the given input file(s) and do something + useful with the contents thereof. + + =cut + +=head1 CAVEATS + +By default, B<pod2usage()> will use C<$0> as the path to the pod input +file. Unfortunately, not all systems on which Perl runs will set C<$0> +properly (although if C<$0> isn't found, B<pod2usage()> will search +C<$ENV{PATH}> or else the list specified by the C<-pathlist> option). +If this is the case for your system, you may need to explicitly specify +the path to the pod docs for the invoking script using something +similar to the following: + + pod2usage(-exitval => 2, -input => "/path/to/your/pod/docs"); + +In the pathological case that a script is called via a relative path +I<and> the script itself changes the current working directory +(see L<perlfunc/chdir>) I<before> calling pod2usage, Pod::Usage will +fail even on robust platforms. Don't do that. + +=head1 AUTHOR + +Please report bugs using L<http://rt.cpan.org>. + +Brad Appleton E<lt>bradapp@enteract.comE<gt> + +Based on code for B<Pod::Text::pod2text()> written by +Tom Christiansen E<lt>tchrist@mox.perl.comE<gt> + +=head1 ACKNOWLEDGEMENTS + +Steven McDougall E<lt>swmcd@world.std.comE<gt> for his help and patience +with re-writing this manpage. + +=cut + +############################################################################# + +use strict; +#use diagnostics; +use Carp; +use Config; +use Exporter; +use File::Spec; + +use vars qw(@ISA @EXPORT); +@EXPORT = qw(&pod2usage); +BEGIN { + if ( $] >= 5.005_58 ) { + require Pod::Text; + @ISA = qw( Pod::Text ); + } + else { + require Pod::PlainText; + @ISA = qw( Pod::PlainText ); + } +} + + +##--------------------------------------------------------------------------- + +##--------------------------------- +## Function definitions begin here +##--------------------------------- + +sub pod2usage { + local($_) = shift; + my %opts; + ## Collect arguments + if (@_ > 0) { + ## Too many arguments - assume that this is a hash and + ## the user forgot to pass a reference to it. + %opts = ($_, @_); + } + elsif (!defined $_) { + $_ = ""; + } + elsif (ref $_) { + ## User passed a ref to a hash + %opts = %{$_} if (ref($_) eq 'HASH'); + } + elsif (/^[-+]?\d+$/) { + ## User passed in the exit value to use + $opts{"-exitval"} = $_; + } + else { + ## User passed in a message to print before issuing usage. + $_ and $opts{"-message"} = $_; + } + + ## Need this for backward compatibility since we formerly used + ## options that were all uppercase words rather than ones that + ## looked like Unix command-line options. + ## to be uppercase keywords) + %opts = map { + my $val = $opts{$_}; + s/^(?=\w)/-/; + /^-msg/i and $_ = '-message'; + /^-exit/i and $_ = '-exitval'; + lc($_) => $val; + } (keys %opts); + + ## Now determine default -exitval and -verbose values to use + if ((! defined $opts{"-exitval"}) && (! defined $opts{"-verbose"})) { + $opts{"-exitval"} = 2; + $opts{"-verbose"} = 0; + } + elsif (! defined $opts{"-exitval"}) { + $opts{"-exitval"} = ($opts{"-verbose"} > 0) ? 1 : 2; + } + elsif (! defined $opts{"-verbose"}) { + $opts{"-verbose"} = (lc($opts{"-exitval"}) eq "noexit" || + $opts{"-exitval"} < 2); + } + + ## Default the output file + $opts{"-output"} = (lc($opts{"-exitval"}) eq "noexit" || + $opts{"-exitval"} < 2) ? \*STDOUT : \*STDERR + unless (defined $opts{"-output"}); + ## Default the input file + $opts{"-input"} = $0 unless (defined $opts{"-input"}); + + ## Look up input file in path if it doesnt exist. + unless ((ref $opts{"-input"}) || (-e $opts{"-input"})) { + my ($dirname, $basename) = ('', $opts{"-input"}); + my $pathsep = ($^O =~ /^(?:dos|os2|MSWin32)$/) ? ";" + : (($^O eq 'MacOS' || $^O eq 'VMS') ? ',' : ":"); + my $pathspec = $opts{"-pathlist"} || $ENV{PATH} || $ENV{PERL5LIB}; + + my @paths = (ref $pathspec) ? @$pathspec : split($pathsep, $pathspec); + for $dirname (@paths) { + $_ = File::Spec->catfile($dirname, $basename) if length; + last if (-e $_) && ($opts{"-input"} = $_); + } + } + + ## Now create a pod reader and constrain it to the desired sections. + my $parser = new Pod::Usage(USAGE_OPTIONS => \%opts); + if ($opts{"-verbose"} == 0) { + $parser->select('SYNOPSIS\s*'); + } + elsif ($opts{"-verbose"} == 1) { + my $opt_re = '(?i)' . + '(?:OPTIONS|ARGUMENTS)' . + '(?:\s*(?:AND|\/)\s*(?:OPTIONS|ARGUMENTS))?'; + $parser->select( 'SYNOPSIS', $opt_re, "DESCRIPTION/$opt_re" ); + } + elsif ($opts{"-verbose"} == 99) { + $parser->select( $opts{"-sections"} ); + $opts{"-verbose"} = 1; + } + + ## Now translate the pod document and then exit with the desired status + if ( !$opts{"-noperldoc"} + and $opts{"-verbose"} >= 2 + and !ref($opts{"-input"}) + and $opts{"-output"} == \*STDOUT ) + { + ## spit out the entire PODs. Might as well invoke perldoc + my $progpath = File::Spec->catfile($Config{scriptdir}, "perldoc"); + system($progpath, $opts{"-input"}); + } + else { + $parser->parse_from_file($opts{"-input"}, $opts{"-output"}); + } + + exit($opts{"-exitval"}) unless (lc($opts{"-exitval"}) eq 'noexit'); +} + +##--------------------------------------------------------------------------- + +##------------------------------- +## Method definitions begin here +##------------------------------- + +sub new { + my $this = shift; + my $class = ref($this) || $this; + my %params = @_; + my $self = {%params}; + bless $self, $class; + if ($self->can('initialize')) { + $self->initialize(); + } else { + $self = $self->SUPER::new(); + %$self = (%$self, %params); + } + return $self; +} + +sub select { + my ($self, @res) = @_; + if ($ISA[0]->can('select')) { + $self->SUPER::select(@_); + } else { + $self->{USAGE_SELECT} = \@res; + } +} + +# Override Pod::Text->seq_i to return just "arg", not "*arg*". +sub seq_i { return $_[1] } + +# This overrides the Pod::Text method to do something very akin to what +# Pod::Select did as well as the work done below by preprocess_paragraph. +# Note that the below is very, very specific to Pod::Text. +sub _handle_element_end { + my ($self, $element) = @_; + if ($element eq 'head1') { + $$self{USAGE_HEAD1} = $$self{PENDING}[-1][1]; + $$self{PENDING}[-1][1] =~ s/^\s*SYNOPSIS\s*$/USAGE/; + } elsif ($element eq 'head2') { + $$self{USAGE_HEAD2} = $$self{PENDING}[-1][1]; + } + if ($element eq 'head1' || $element eq 'head2') { + $$self{USAGE_SKIPPING} = 1; + my $heading = $$self{USAGE_HEAD1}; + $heading .= '/' . $$self{USAGE_HEAD2} if defined $$self{USAGE_HEAD2}; + for (@{ $$self{USAGE_SELECT} }) { + if ($heading =~ /^$_\s*$/) { + $$self{USAGE_SKIPPING} = 0; + last; + } + } + + # Try to do some lowercasing instead of all-caps in headings, and use + # a colon to end all headings. + local $_ = $$self{PENDING}[-1][1]; + s{([A-Z])([A-Z]+)}{((length($2) > 2) ? $1 : lc($1)) . lc($2)}ge; + s/\s*$/:/ unless (/:\s*$/); + $_ .= "\n"; + $$self{PENDING}[-1][1] = $_; + } + if ($$self{USAGE_SKIPPING}) { + pop @{ $$self{PENDING} }; + } else { + $self->SUPER::_handle_element_end($element); + } +} + +sub start_document { + my $self = shift; + $self->SUPER::start_document(); + my $msg = $self->{USAGE_OPTIONS}->{-message} or return 1; + my $out_fh = $self->output_fh(); + print $out_fh "$msg\n"; +} + +sub begin_pod { + my $self = shift; + $self->SUPER::begin_pod(); ## Have to call superclass + my $msg = $self->{USAGE_OPTIONS}->{-message} or return 1; + my $out_fh = $self->output_handle(); + print $out_fh "$msg\n"; +} + +sub preprocess_paragraph { + my $self = shift; + local $_ = shift; + my $line = shift; + ## See if this is a heading and we arent printing the entire manpage. + if (($self->{USAGE_OPTIONS}->{-verbose} < 2) && /^=head/) { + ## Change the title of the SYNOPSIS section to USAGE + s/^=head1\s+SYNOPSIS\s*$/=head1 USAGE/; + ## Try to do some lowercasing instead of all-caps in headings + s{([A-Z])([A-Z]+)}{((length($2) > 2) ? $1 : lc($1)) . lc($2)}ge; + ## Use a colon to end all headings + s/\s*$/:/ unless (/:\s*$/); + $_ .= "\n"; + } + return $self->SUPER::preprocess_paragraph($_); +} + +1; # keep require happy diff --git a/Master/tlpkg/texlive.tlpdb b/Master/tlpkg/texlive.tlpdb index 9917cec7832..8f9f49009c8 100644 --- a/Master/tlpkg/texlive.tlpdb +++ b/Master/tlpkg/texlive.tlpdb @@ -35,12 +35,11 @@ runfiles size=92 name 00texlive.installer category TLCore -revision 7102 -runfiles size=90 +revision 7089 +runfiles size=89 config.guess install-tl.html install-tl.pl - tl-portable.sh tlpkg/TeXLive/TLConfig.pm tlpkg/TeXLive/TLPDB.pm tlpkg/TeXLive/TLPOBJ.pm @@ -1266,8 +1265,8 @@ catalogue-license lppl name MemoirChapStyles category Documentation -revision 7211 -docfiles size=232 +revision 4479 +docfiles size=206 texmf-doc/doc/english/MemoirChapStyles/MemoirChapStyles.pdf texmf-doc/doc/english/MemoirChapStyles/MemoirChapStyles.tex texmf-doc/doc/english/MemoirChapStyles/README @@ -3893,14 +3892,14 @@ docfiles size=31 name animate category Package -revision 7209 +revision 7046 shortdesc Create PDF animations from graphics files and inline graphics. longdesc The package provides an interface to create portable, longdesc JavaScript driven PDF animations from sets of graphics files or longdesc from inline graphics, such as LaTeX picture environment, longdesc PSTricks or pgf/TikZ generated pictures, or just from typeset longdesc text. -docfiles size=354 +docfiles size=353 texmf-dist/doc/latex/animate/README details="Readme" texmf-dist/doc/latex/animate/doc/animate.pdf details="Package documentation" texmf-dist/doc/latex/animate/doc/animate.tex @@ -3916,7 +3915,7 @@ runfiles size=33 texmf-dist/tex/latex/animate/animate-noocg.sty texmf-dist/tex/latex/animate/animate.sty catalogue-version -catalogue-date 2008-03-26 12:52:35 +0100 +catalogue-date 2008-03-08 13:49:29 +0100 catalogue-ctan /macros/latex/contrib/animate catalogue-license lppl @@ -13039,7 +13038,7 @@ binfiles arch=x86_64-linux size=109 name bin-dvipdfm category TLCore -revision 7115 +revision 6473 depend bin-dvipdfm.ARCH docfiles size=74 texmf/doc/dvipdfm/Makefile @@ -13059,7 +13058,7 @@ docfiles size=74 texmf/doc/man/man1/dvipdfm.1 texmf/doc/man/man1/dvipdft.1 texmf/doc/man/man1/ebb.1 -runfiles size=157 +runfiles size=160 texmf/dvipdfm/config/config texmf/dvipdfm/config/config-win32 texmf/fonts/map/dvipdfm/updmap/dvipdfm.map @@ -13069,7 +13068,7 @@ runfiles size=157 name bin-dvipdfm.alpha-linux category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-dvipdfm for alpha-linux binfiles arch=alpha-linux size=227 bin/alpha-linux/dvipdfm @@ -13078,7 +13077,7 @@ binfiles arch=alpha-linux size=227 name bin-dvipdfm.hppa-hpux category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-dvipdfm for hppa-hpux binfiles arch=hppa-hpux size=180 bin/hppa-hpux/dvipdfm @@ -13087,7 +13086,7 @@ binfiles arch=hppa-hpux size=180 name bin-dvipdfm.i386-darwin category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-dvipdfm for i386-darwin binfiles arch=i386-darwin size=136 bin/i386-darwin/dvipdfm @@ -13096,7 +13095,7 @@ binfiles arch=i386-darwin size=136 name bin-dvipdfm.i386-freebsd category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-dvipdfm for i386-freebsd binfiles arch=i386-freebsd size=133 bin/i386-freebsd/dvipdfm @@ -13105,7 +13104,7 @@ binfiles arch=i386-freebsd size=133 name bin-dvipdfm.i386-linux category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-dvipdfm for i386-linux binfiles arch=i386-linux size=135 bin/i386-linux/dvipdfm @@ -13114,7 +13113,7 @@ binfiles arch=i386-linux size=135 name bin-dvipdfm.i386-openbsd category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-dvipdfm for i386-openbsd binfiles arch=i386-openbsd size=135 bin/i386-openbsd/dvipdfm @@ -13123,7 +13122,7 @@ binfiles arch=i386-openbsd size=135 name bin-dvipdfm.i386-solaris category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-dvipdfm for i386-solaris binfiles arch=i386-solaris size=145 bin/i386-solaris/dvipdfm @@ -13132,7 +13131,7 @@ binfiles arch=i386-solaris size=145 name bin-dvipdfm.mips-irix category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-dvipdfm for mips-irix binfiles arch=mips-irix size=251 bin/mips-irix/dvipdfm @@ -13141,7 +13140,7 @@ binfiles arch=mips-irix size=251 name bin-dvipdfm.powerpc-aix category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-dvipdfm for powerpc-aix binfiles arch=powerpc-aix size=186 bin/powerpc-aix/dvipdfm @@ -13150,7 +13149,7 @@ binfiles arch=powerpc-aix size=186 name bin-dvipdfm.powerpc-darwin category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-dvipdfm for powerpc-darwin binfiles arch=powerpc-darwin size=129 bin/powerpc-darwin/dvipdfm @@ -13159,7 +13158,7 @@ binfiles arch=powerpc-darwin size=129 name bin-dvipdfm.powerpc-linux category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-dvipdfm for powerpc-linux binfiles arch=powerpc-linux size=154 bin/powerpc-linux/dvipdfm @@ -13168,7 +13167,7 @@ binfiles arch=powerpc-linux size=154 name bin-dvipdfm.sparc-linux category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-dvipdfm for sparc-linux binfiles arch=sparc-linux size=150 bin/sparc-linux/dvipdfm @@ -13177,7 +13176,7 @@ binfiles arch=sparc-linux size=150 name bin-dvipdfm.sparc-solaris category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-dvipdfm for sparc-solaris binfiles arch=sparc-solaris size=232 bin/sparc-solaris/dvipdfm @@ -13186,7 +13185,7 @@ binfiles arch=sparc-solaris size=232 name bin-dvipdfm.win32 category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-dvipdfm for win32 binfiles arch=win32 size=117 bin/win32/dvipdfm.exe @@ -13194,7 +13193,7 @@ binfiles arch=win32 size=117 name bin-dvipdfm.x86_64-linux category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-dvipdfm for x86_64-linux binfiles arch=x86_64-linux size=170 bin/x86_64-linux/dvipdfm @@ -13548,7 +13547,7 @@ binfiles arch=x86_64-linux size=26 name bin-dvipsk category TLCore -revision 7115 +revision 6814 depend bin-dvipsk.ARCH docfiles size=239 texmf/doc/dvips/dvips.html @@ -13557,7 +13556,7 @@ docfiles size=239 texmf/doc/man/man1/afm2tfm.1 texmf/doc/man/man1/dvips.1 texmf/doc/pkfix/README -runfiles size=555 +runfiles size=564 texmf/dvips/base/color.pro texmf/dvips/base/crop.pro texmf/dvips/base/finclude.pro @@ -13606,7 +13605,7 @@ runfiles size=555 name bin-dvipsk.alpha-linux category TLCore -revision 7115 +revision 6814 shortdesc binary files of bin-dvipsk for alpha-linux binfiles arch=alpha-linux size=116 bin/alpha-linux/afm2tfm @@ -13615,7 +13614,7 @@ binfiles arch=alpha-linux size=116 name bin-dvipsk.hppa-hpux category TLCore -revision 7115 +revision 6814 shortdesc binary files of bin-dvipsk for hppa-hpux binfiles arch=hppa-hpux size=105 bin/hppa-hpux/afm2tfm @@ -13624,7 +13623,7 @@ binfiles arch=hppa-hpux size=105 name bin-dvipsk.i386-darwin category TLCore -revision 7115 +revision 6814 shortdesc binary files of bin-dvipsk for i386-darwin binfiles arch=i386-darwin size=88 bin/i386-darwin/afm2tfm @@ -13633,7 +13632,7 @@ binfiles arch=i386-darwin size=88 name bin-dvipsk.i386-freebsd category TLCore -revision 7115 +revision 6814 shortdesc binary files of bin-dvipsk for i386-freebsd binfiles arch=i386-freebsd size=77 bin/i386-freebsd/afm2tfm @@ -13642,7 +13641,7 @@ binfiles arch=i386-freebsd size=77 name bin-dvipsk.i386-linux category TLCore -revision 7115 +revision 6814 shortdesc binary files of bin-dvipsk for i386-linux binfiles arch=i386-linux size=173 bin/i386-linux/afm2tfm @@ -13651,7 +13650,7 @@ binfiles arch=i386-linux size=173 name bin-dvipsk.i386-openbsd category TLCore -revision 7115 +revision 6814 shortdesc binary files of bin-dvipsk for i386-openbsd binfiles arch=i386-openbsd size=76 bin/i386-openbsd/afm2tfm @@ -13660,7 +13659,7 @@ binfiles arch=i386-openbsd size=76 name bin-dvipsk.i386-solaris category TLCore -revision 7115 +revision 6814 shortdesc binary files of bin-dvipsk for i386-solaris binfiles arch=i386-solaris size=82 bin/i386-solaris/afm2tfm @@ -13669,7 +13668,7 @@ binfiles arch=i386-solaris size=82 name bin-dvipsk.mips-irix category TLCore -revision 7115 +revision 6814 shortdesc binary files of bin-dvipsk for mips-irix binfiles arch=mips-irix size=135 bin/mips-irix/afm2tfm @@ -13678,7 +13677,7 @@ binfiles arch=mips-irix size=135 name bin-dvipsk.powerpc-aix category TLCore -revision 7115 +revision 6814 shortdesc binary files of bin-dvipsk for powerpc-aix binfiles arch=powerpc-aix size=96 bin/powerpc-aix/afm2tfm @@ -13687,7 +13686,7 @@ binfiles arch=powerpc-aix size=96 name bin-dvipsk.powerpc-darwin category TLCore -revision 7115 +revision 6814 shortdesc binary files of bin-dvipsk for powerpc-darwin binfiles arch=powerpc-darwin size=88 bin/powerpc-darwin/afm2tfm @@ -13696,7 +13695,7 @@ binfiles arch=powerpc-darwin size=88 name bin-dvipsk.powerpc-linux category TLCore -revision 7115 +revision 6814 shortdesc binary files of bin-dvipsk for powerpc-linux binfiles arch=powerpc-linux size=89 bin/powerpc-linux/afm2tfm @@ -13705,7 +13704,7 @@ binfiles arch=powerpc-linux size=89 name bin-dvipsk.sparc-linux category TLCore -revision 7115 +revision 6814 shortdesc binary files of bin-dvipsk for sparc-linux binfiles arch=sparc-linux size=87 bin/sparc-linux/afm2tfm @@ -13714,7 +13713,7 @@ binfiles arch=sparc-linux size=87 name bin-dvipsk.sparc-solaris category TLCore -revision 7115 +revision 6814 shortdesc binary files of bin-dvipsk for sparc-solaris binfiles arch=sparc-solaris size=136 bin/sparc-solaris/afm2tfm @@ -13723,7 +13722,7 @@ binfiles arch=sparc-solaris size=136 name bin-dvipsk.win32 category TLCore -revision 7115 +revision 6814 shortdesc binary files of bin-dvipsk for win32 binfiles arch=win32 size=40 bin/win32/afm2tfm.exe @@ -13732,7 +13731,7 @@ binfiles arch=win32 size=40 name bin-dvipsk.x86_64-linux category TLCore -revision 7115 +revision 6814 shortdesc binary files of bin-dvipsk for x86_64-linux binfiles arch=x86_64-linux size=88 bin/x86_64-linux/afm2tfm @@ -17521,7 +17520,7 @@ binfiles arch=x86_64-linux size=9 name bin-pdftex category TLCore -revision 7115 +revision 6473 depend bin-kpathsea depend lib-gnu.win32 depend lib-md5.win32 @@ -17581,7 +17580,7 @@ docfiles size=2132 texmf/doc/pdftex/thanh/ext/protcode.tex texmf/doc/pdftex/thanh/ext/ufntinst.sty texmf/doc/pdftex/thanh/thesis-png.pdf -runfiles size=475 +runfiles size=482 texmf/fmtutil/format.pdftex.cnf texmf/fonts/map/pdftex/updmap/pdftex.map texmf/fonts/map/pdftex/updmap/pdftex_dl14.map @@ -17593,7 +17592,7 @@ runfiles size=475 name bin-pdftex.alpha-linux category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-pdftex for alpha-linux binfiles arch=alpha-linux size=454 bin/alpha-linux/pdfetex @@ -17603,7 +17602,7 @@ binfiles arch=alpha-linux size=454 name bin-pdftex.hppa-hpux category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-pdftex for hppa-hpux binfiles arch=hppa-hpux size=391 bin/hppa-hpux/pdfetex @@ -17613,7 +17612,7 @@ binfiles arch=hppa-hpux size=391 name bin-pdftex.i386-darwin category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-pdftex for i386-darwin binfiles arch=i386-darwin size=320 bin/i386-darwin/pdfetex @@ -17623,7 +17622,7 @@ binfiles arch=i386-darwin size=320 name bin-pdftex.i386-freebsd category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-pdftex for i386-freebsd binfiles arch=i386-freebsd size=301 bin/i386-freebsd/pdfetex @@ -17633,7 +17632,7 @@ binfiles arch=i386-freebsd size=301 name bin-pdftex.i386-linux category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-pdftex for i386-linux binfiles arch=i386-linux size=295 bin/i386-linux/pdfetex @@ -17643,7 +17642,7 @@ binfiles arch=i386-linux size=295 name bin-pdftex.i386-openbsd category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-pdftex for i386-openbsd binfiles arch=i386-openbsd size=295 bin/i386-openbsd/pdfetex @@ -17653,7 +17652,7 @@ binfiles arch=i386-openbsd size=295 name bin-pdftex.i386-solaris category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-pdftex for i386-solaris binfiles arch=i386-solaris size=359 bin/i386-solaris/pdfetex @@ -17663,7 +17662,7 @@ binfiles arch=i386-solaris size=359 name bin-pdftex.mips-irix category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-pdftex for mips-irix binfiles arch=mips-irix size=487 bin/mips-irix/pdfetex @@ -17673,7 +17672,7 @@ binfiles arch=mips-irix size=487 name bin-pdftex.powerpc-aix category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-pdftex for powerpc-aix binfiles arch=powerpc-aix size=387 bin/powerpc-aix/pdfetex @@ -17683,7 +17682,7 @@ binfiles arch=powerpc-aix size=387 name bin-pdftex.powerpc-darwin category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-pdftex for powerpc-darwin binfiles arch=powerpc-darwin size=309 bin/powerpc-darwin/pdfetex @@ -17693,7 +17692,7 @@ binfiles arch=powerpc-darwin size=309 name bin-pdftex.powerpc-linux category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-pdftex for powerpc-linux binfiles arch=powerpc-linux size=347 bin/powerpc-linux/pdfetex @@ -17703,7 +17702,7 @@ binfiles arch=powerpc-linux size=347 name bin-pdftex.sparc-linux category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-pdftex for sparc-linux binfiles arch=sparc-linux size=331 bin/sparc-linux/pdfetex @@ -17713,7 +17712,7 @@ binfiles arch=sparc-linux size=331 name bin-pdftex.sparc-solaris category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-pdftex for sparc-solaris binfiles arch=sparc-solaris size=428 bin/sparc-solaris/pdfetex @@ -17723,7 +17722,7 @@ binfiles arch=sparc-solaris size=428 name bin-pdftex.win32 category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-pdftex for win32 binfiles arch=win32 size=266 bin/win32/pdfetex.exe @@ -17733,7 +17732,7 @@ binfiles arch=win32 size=266 name bin-pdftex.x86_64-linux category TLCore -revision 7115 +revision 6473 shortdesc binary files of bin-pdftex for x86_64-linux binfiles arch=x86_64-linux size=353 bin/x86_64-linux/pdfetex @@ -19320,7 +19319,7 @@ binfiles arch=x86_64-linux size=50 name bin-tetex category TLCore -revision 7115 +revision 7081 depend bin-tetex.ARCH docfiles size=106 texmf/doc/man/man1/a2ping.1 @@ -19379,7 +19378,7 @@ runfiles size=55 name bin-tetex.alpha-linux category TLCore -revision 7115 +revision 7081 shortdesc binary files of bin-tetex for alpha-linux binfiles arch=alpha-linux size=63 bin/alpha-linux/a2ping @@ -19401,7 +19400,7 @@ binfiles arch=alpha-linux size=63 name bin-tetex.hppa-hpux category TLCore -revision 7115 +revision 7081 shortdesc binary files of bin-tetex for hppa-hpux binfiles arch=hppa-hpux size=63 bin/hppa-hpux/a2ping @@ -19423,7 +19422,7 @@ binfiles arch=hppa-hpux size=63 name bin-tetex.i386-darwin category TLCore -revision 7115 +revision 7081 shortdesc binary files of bin-tetex for i386-darwin binfiles arch=i386-darwin size=63 bin/i386-darwin/a2ping @@ -19445,7 +19444,7 @@ binfiles arch=i386-darwin size=63 name bin-tetex.i386-freebsd category TLCore -revision 7115 +revision 7081 shortdesc binary files of bin-tetex for i386-freebsd binfiles arch=i386-freebsd size=63 bin/i386-freebsd/a2ping @@ -19467,7 +19466,7 @@ binfiles arch=i386-freebsd size=63 name bin-tetex.i386-linux category TLCore -revision 7115 +revision 7081 shortdesc binary files of bin-tetex for i386-linux binfiles arch=i386-linux size=40 bin/i386-linux/a2ping @@ -19489,7 +19488,7 @@ binfiles arch=i386-linux size=40 name bin-tetex.i386-openbsd category TLCore -revision 7115 +revision 7081 shortdesc binary files of bin-tetex for i386-openbsd binfiles arch=i386-openbsd size=63 bin/i386-openbsd/a2ping @@ -19511,7 +19510,7 @@ binfiles arch=i386-openbsd size=63 name bin-tetex.i386-solaris category TLCore -revision 7115 +revision 7081 shortdesc binary files of bin-tetex for i386-solaris binfiles arch=i386-solaris size=63 bin/i386-solaris/a2ping @@ -19533,7 +19532,7 @@ binfiles arch=i386-solaris size=63 name bin-tetex.mips-irix category TLCore -revision 7115 +revision 7081 shortdesc binary files of bin-tetex for mips-irix binfiles arch=mips-irix size=63 bin/mips-irix/a2ping @@ -19555,7 +19554,7 @@ binfiles arch=mips-irix size=63 name bin-tetex.powerpc-aix category TLCore -revision 7115 +revision 7081 shortdesc binary files of bin-tetex for powerpc-aix binfiles arch=powerpc-aix size=63 bin/powerpc-aix/a2ping @@ -19577,7 +19576,7 @@ binfiles arch=powerpc-aix size=63 name bin-tetex.powerpc-darwin category TLCore -revision 7115 +revision 7081 shortdesc binary files of bin-tetex for powerpc-darwin binfiles arch=powerpc-darwin size=63 bin/powerpc-darwin/a2ping @@ -19599,7 +19598,7 @@ binfiles arch=powerpc-darwin size=63 name bin-tetex.powerpc-linux category TLCore -revision 7115 +revision 7081 shortdesc binary files of bin-tetex for powerpc-linux binfiles arch=powerpc-linux size=63 bin/powerpc-linux/a2ping @@ -19621,7 +19620,7 @@ binfiles arch=powerpc-linux size=63 name bin-tetex.sparc-linux category TLCore -revision 7115 +revision 7081 shortdesc binary files of bin-tetex for sparc-linux binfiles arch=sparc-linux size=63 bin/sparc-linux/a2ping @@ -19643,7 +19642,7 @@ binfiles arch=sparc-linux size=63 name bin-tetex.sparc-solaris category TLCore -revision 7115 +revision 7081 shortdesc binary files of bin-tetex for sparc-solaris binfiles arch=sparc-solaris size=63 bin/sparc-solaris/a2ping @@ -19665,7 +19664,7 @@ binfiles arch=sparc-solaris size=63 name bin-tetex.win32 category TLCore -revision 7115 +revision 7081 shortdesc binary files of bin-tetex for win32 binfiles arch=win32 size=7 bin/win32/fmtutil-sys.texlua @@ -19675,7 +19674,7 @@ binfiles arch=win32 size=7 name bin-tetex.x86_64-linux category TLCore -revision 7115 +revision 7081 shortdesc binary files of bin-tetex for x86_64-linux binfiles arch=x86_64-linux size=63 bin/x86_64-linux/a2ping @@ -25399,7 +25398,7 @@ catalogue-license lppl name caption category Package -revision 7101 +revision 5898 shortdesc Customising captions in floating environments. longdesc The caption package provides many ways to customise the longdesc captions in floating environments like figure and table, and @@ -25410,7 +25409,7 @@ longdesc notes, for other packages, is provided in the documentation. longdesc The package also provides the "caption outside float" facility, longdesc in the same way that simpler packages like capt-of do. The longdesc package supersedes caption2. -docfiles size=587 +docfiles size=539 texmf-dist/doc/latex/caption/README texmf-dist/doc/latex/caption/caption-deu.pdf details="German documentation" language="de" texmf-dist/doc/latex/caption/caption-deu.tex @@ -25420,17 +25419,15 @@ docfiles size=587 texmf-dist/doc/latex/caption/caption-rus.tex texmf-dist/doc/latex/caption/caption.pdf details="Documented source (English)" language="en" texmf-dist/doc/latex/caption/caption2.pdf - texmf-dist/doc/latex/caption/cat.eps - texmf-dist/doc/latex/caption/elephant.eps texmf-dist/doc/latex/caption/ltcaption.pdf texmf-dist/doc/latex/caption/subcaption.pdf -srcfiles size=93 +srcfiles size=91 texmf-dist/source/latex/caption/caption.dtx texmf-dist/source/latex/caption/caption.ins texmf-dist/source/latex/caption/caption2.dtx texmf-dist/source/latex/caption/ltcaption.dtx texmf-dist/source/latex/caption/subcaption.dtx -runfiles size=35 +runfiles size=34 texmf-dist/tex/latex/caption/caption.sty texmf-dist/tex/latex/caption/caption2.sty texmf-dist/tex/latex/caption/caption3.sty @@ -26126,23 +26123,6 @@ catalogue-date 2006-12-31 16:08:10 +0100 catalogue-ctan /macros/latex/contrib/changebar catalogue-license lppl -name changepage -category Package -revision 7208 -shortdesc Margin adjustment and detection of odd/even pages. -longdesc The package provides commands to change the page layout in the -longdesc middle of a document, and to robustly check for typesetting on -longdesc odd or even pages. Instructions for use are at the end of the -longdesc file. The package is an extraction of code from the memoir -longdesc class, whose user interface it share. It is intended the this -longdesc package will eventually replace the chngpage package. -runfiles size=4 - texmf-dist/tex/latex/changepage/changepage.sty -catalogue-version 1.0 -catalogue-date 2008-03-27 17:48:34 +0100 -catalogue-ctan /macros/latex/contrib/misc/changepage.sty -catalogue-license lppl - name changes category Package revision 5161 @@ -26444,8 +26424,8 @@ runfiles size=14 texmf-dist/tex/latex/chemstyle/orglett.jdf texmf-dist/tex/latex/chemstyle/rsc.jdf texmf-dist/tex/latex/chemstyle/tetlett.jdf -catalogue-version 1.2a -catalogue-date 2008-03-25 13:52:02 +0100 +catalogue-version 1.2 +catalogue-date 2008-03-08 20:47:21 +0100 catalogue-ctan /macros/latex/contrib/chemstyle catalogue-license gpl @@ -30435,7 +30415,7 @@ depend collection-latex name collection-binextra category Collection -revision 7207 +revision 6950 shortdesc TeX auxiliary programs longdesc Various useful, but non-essential, support programs. Includes longdesc programs and macros for DVI file manipulation, literate @@ -30467,7 +30447,6 @@ depend cweb depend hyphenex depend mkind-english depend texcount -depend xindy name collection-context category Collection @@ -30735,7 +30714,7 @@ depend collection-basic name collection-fontsextra category Collection -revision 7103 +revision 6630 shortdesc Extra fonts longdesc All sorts of extra fonts depend Asana-Math @@ -30859,7 +30838,6 @@ depend sauterfonts depend semaphor depend simpsons depend skull -depend staves depend tapir depend tengwarscript depend tpslifonts @@ -31458,7 +31436,7 @@ depend collection-latex name collection-latexextra category Collection -revision 7208 +revision 7061 shortdesc LaTeX supplementary packages longdesc A large collection of add-on packages for LaTeX. depend AkkTeX @@ -31517,7 +31495,6 @@ depend cd-cover depend cdpbundl depend cellspace depend changebar -depend changepage depend changes depend chappg depend chapterfolder @@ -49409,7 +49386,7 @@ runfiles size=2 name hyphen-base category TLCore -revision 7126 +revision 5633 runfiles size=24 texmf/tex/generic/config/language.dat texmf/tex/generic/config/language.us @@ -49605,7 +49582,7 @@ runfiles size=4 name hyphen-mongolian category TLCore -revision 7128 +revision 5962 execute BuildLanguageDat mn execute BuildLanguageDat mn2a runfiles size=7 @@ -53023,27 +53000,25 @@ docfiles size=180 name kpfonts category Package -revision 7131 +revision 6374 shortdesc A complete set of fonts for text and mathematics. longdesc The family contains text fonts in roman, sans-serif and -longdesc monospaced shapes, with true small caps and old-style numbers; -longdesc the package offers full support of the textcomp package. The -longdesc mathematics fonts include all the AMS fonts, in both normal and -longdesc bold weights. The fonts originally derived from URW Palladio -longdesc (with URW’s agreement) though the fonts are very clearly -longdesc different in appearance from their parent. +longdesc monospaced shapes, with true small caps and old-style numbers. +longdesc The mathematics fonts include all the AMS fonts, in both normal +longdesc and bold weights. The fonts originally derived from URW +longdesc Palladio (with URW’s agreement) though the fonts are very +longdesc clearly different in appearance from their parent. execute addMap kpfonts.map -docfiles size=176 +docfiles size=158 texmf-dist/doc/fonts/kpfonts/Kpfonts-Doc-French.pdf texmf-dist/doc/fonts/kpfonts/Kpfonts-Doc-French.tex - texmf-dist/doc/fonts/kpfonts/README details="Readme" - texmf-dist/doc/fonts/kpfonts/jkpmn7c.pl + texmf-dist/doc/fonts/kpfonts/README.txt texmf-dist/doc/fonts/kpfonts/kpfonts.pdf texmf-dist/doc/fonts/kpfonts/kpfonts.tex -srcfiles size=78 +srcfiles size=59 texmf-dist/source/fonts/kpfonts/kpfonts-afm.zip texmf-dist/source/fonts/kpfonts/kpfonts-fontinst.zip -runfiles size=2205 +runfiles size=1865 texmf-dist/fonts/map/dvips/kpfonts/kpfonts.map texmf-dist/fonts/tfm/public/kpfonts/jkpbex.tfm texmf-dist/fonts/tfm/public/kpfonts/jkpbexa.tfm @@ -53231,30 +53206,6 @@ runfiles size=2205 texmf-dist/fonts/tfm/public/kpfonts/jkplosmsl7c.tfm texmf-dist/fonts/tfm/public/kpfonts/jkplosmsl7t.tfm texmf-dist/fonts/tfm/public/kpfonts/jkplosmsl8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnbit7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnbit8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnbn7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnbn8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnbsc7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnbsc8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnbsl7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnbsl8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnbxit7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnbxit8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnbxn7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnbxn8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnbxsc7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnbxsc8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnbxsl7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnbxsl8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnmit7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnmit8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnmn7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnmn8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnmsc7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnmsc8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnmsl7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkplosnmsl8t.tfm texmf-dist/fonts/tfm/public/kpfonts/jkplsy.tfm texmf-dist/fonts/tfm/public/kpfonts/jkplsyb.tfm texmf-dist/fonts/tfm/public/kpfonts/jkplsyc.tfm @@ -53346,30 +53297,6 @@ runfiles size=2205 texmf-dist/fonts/tfm/public/kpfonts/jkposmsl7c.tfm texmf-dist/fonts/tfm/public/kpfonts/jkposmsl7t.tfm texmf-dist/fonts/tfm/public/kpfonts/jkposmsl8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnbit7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnbit8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnbn7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnbn8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnbsc7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnbsc8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnbsl7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnbsl8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnbxit7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnbxit8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnbxn7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnbxn8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnbxsc7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnbxsc8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnbxsl7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnbxsl8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnmit7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnmit8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnmn7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnmn8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnmsc7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnmsc8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnmsl7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkposnmsl8t.tfm texmf-dist/fonts/tfm/public/kpfonts/jkpssbn7c.tfm texmf-dist/fonts/tfm/public/kpfonts/jkpssbn7t.tfm texmf-dist/fonts/tfm/public/kpfonts/jkpssbn8a.tfm @@ -53443,24 +53370,6 @@ runfiles size=2205 texmf-dist/fonts/tfm/public/kpfonts/jkpssosmsc8t.tfm texmf-dist/fonts/tfm/public/kpfonts/jkpssosmsl7t.tfm texmf-dist/fonts/tfm/public/kpfonts/jkpssosmsl8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpssosnbn7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpssosnbn8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpssosnbsc7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpssosnbsc8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpssosnbsl7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpssosnbsl8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpssosnbxn7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpssosnbxn8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpssosnbxsc7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpssosnbxsc8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpssosnbxsl7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpssosnbxsl8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpssosnmn7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpssosnmn8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpssosnmsc7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpssosnmsc8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpssosnmsl7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpssosnmsl8t.tfm texmf-dist/fonts/tfm/public/kpfonts/jkpssvosbn7t.tfm texmf-dist/fonts/tfm/public/kpfonts/jkpssvosbn8t.tfm texmf-dist/fonts/tfm/public/kpfonts/jkpssvosbsc7t.tfm @@ -53518,14 +53427,6 @@ runfiles size=2205 texmf-dist/fonts/tfm/public/kpfonts/jkpttosmn8t.tfm texmf-dist/fonts/tfm/public/kpfonts/jkpttosmsl7t.tfm texmf-dist/fonts/tfm/public/kpfonts/jkpttosmsl8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpttosnbn7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpttosnbn8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpttosnbsl7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpttosnbsl8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpttosnmn7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpttosnmn8t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpttosnmsl7t.tfm - texmf-dist/fonts/tfm/public/kpfonts/jkpttosnmsl8t.tfm texmf-dist/fonts/tfm/public/kpfonts/jkpttvosbn7t.tfm texmf-dist/fonts/tfm/public/kpfonts/jkpttvosbn8t.tfm texmf-dist/fonts/tfm/public/kpfonts/jkpttvosbsl7t.tfm @@ -53737,30 +53638,6 @@ runfiles size=2205 texmf-dist/fonts/vf/public/kpfonts/jkplosmsl7c.vf texmf-dist/fonts/vf/public/kpfonts/jkplosmsl7t.vf texmf-dist/fonts/vf/public/kpfonts/jkplosmsl8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnbit7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnbit8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnbn7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnbn8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnbsc7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnbsc8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnbsl7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnbsl8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnbxit7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnbxit8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnbxn7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnbxn8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnbxsc7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnbxsc8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnbxsl7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnbxsl8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnmit7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnmit8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnmn7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnmn8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnmsc7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnmsc8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnmsl7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkplosnmsl8t.vf texmf-dist/fonts/vf/public/kpfonts/jkplvosbit7t.vf texmf-dist/fonts/vf/public/kpfonts/jkplvosbit8t.vf texmf-dist/fonts/vf/public/kpfonts/jkplvosbmi.vf @@ -53832,30 +53709,6 @@ runfiles size=2205 texmf-dist/fonts/vf/public/kpfonts/jkposmsl7c.vf texmf-dist/fonts/vf/public/kpfonts/jkposmsl7t.vf texmf-dist/fonts/vf/public/kpfonts/jkposmsl8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnbit7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnbit8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnbn7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnbn8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnbsc7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnbsc8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnbsl7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnbsl8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnbxit7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnbxit8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnbxn7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnbxn8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnbxsc7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnbxsc8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnbxsl7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnbxsl8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnmit7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnmit8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnmn7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnmn8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnmsc7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnmsc8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnmsl7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkposnmsl8t.vf texmf-dist/fonts/vf/public/kpfonts/jkpospmit7c.vf texmf-dist/fonts/vf/public/kpfonts/jkpospmsl7c.vf texmf-dist/fonts/vf/public/kpfonts/jkpssbn7c.vf @@ -53903,24 +53756,6 @@ runfiles size=2205 texmf-dist/fonts/vf/public/kpfonts/jkpssosmsc8t.vf texmf-dist/fonts/vf/public/kpfonts/jkpssosmsl7t.vf texmf-dist/fonts/vf/public/kpfonts/jkpssosmsl8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpssosnbn7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpssosnbn8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpssosnbsc7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpssosnbsc8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpssosnbsl7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpssosnbsl8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpssosnbxn7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpssosnbxn8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpssosnbxsc7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpssosnbxsc8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpssosnbxsl7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpssosnbxsl8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpssosnmn7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpssosnmn8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpssosnmsc7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpssosnmsc8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpssosnmsl7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpssosnmsl8t.vf texmf-dist/fonts/vf/public/kpfonts/jkpssvosbn7t.vf texmf-dist/fonts/vf/public/kpfonts/jkpssvosbn8t.vf texmf-dist/fonts/vf/public/kpfonts/jkpssvosbsc7t.vf @@ -53959,14 +53794,6 @@ runfiles size=2205 texmf-dist/fonts/vf/public/kpfonts/jkpttosmn8t.vf texmf-dist/fonts/vf/public/kpfonts/jkpttosmsl7t.vf texmf-dist/fonts/vf/public/kpfonts/jkpttosmsl8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpttosnbn7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpttosnbn8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpttosnbsl7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpttosnbsl8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpttosnmn7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpttosnmn8t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpttosnmsl7t.vf - texmf-dist/fonts/vf/public/kpfonts/jkpttosnmsl8t.vf texmf-dist/fonts/vf/public/kpfonts/jkpttvosbn7t.vf texmf-dist/fonts/vf/public/kpfonts/jkpttvosbn8t.vf texmf-dist/fonts/vf/public/kpfonts/jkpttvosbsl7t.vf @@ -54010,62 +53837,45 @@ runfiles size=2205 texmf-dist/tex/latex/kpfonts/ot1jkp.fd texmf-dist/tex/latex/kpfonts/ot1jkpl.fd texmf-dist/tex/latex/kpfonts/ot1jkplos.fd - texmf-dist/tex/latex/kpfonts/ot1jkplosn.fd texmf-dist/tex/latex/kpfonts/ot1jkplvos.fd texmf-dist/tex/latex/kpfonts/ot1jkpos.fd - texmf-dist/tex/latex/kpfonts/ot1jkposn.fd texmf-dist/tex/latex/kpfonts/ot1jkpss.fd texmf-dist/tex/latex/kpfonts/ot1jkpssos.fd - texmf-dist/tex/latex/kpfonts/ot1jkpssosn.fd texmf-dist/tex/latex/kpfonts/ot1jkpssvos.fd texmf-dist/tex/latex/kpfonts/ot1jkptt.fd texmf-dist/tex/latex/kpfonts/ot1jkpttos.fd - texmf-dist/tex/latex/kpfonts/ot1jkpttosn.fd texmf-dist/tex/latex/kpfonts/ot1jkpttvos.fd texmf-dist/tex/latex/kpfonts/ot1jkpvos.fd texmf-dist/tex/latex/kpfonts/ot1jkpx.fd texmf-dist/tex/latex/kpfonts/ot1jkpxos.fd - texmf-dist/tex/latex/kpfonts/ot1jkpxosn.fd texmf-dist/tex/latex/kpfonts/ot1jkpxvos.fd texmf-dist/tex/latex/kpfonts/t1jkp.fd texmf-dist/tex/latex/kpfonts/t1jkpl.fd texmf-dist/tex/latex/kpfonts/t1jkplos.fd - texmf-dist/tex/latex/kpfonts/t1jkplosn.fd texmf-dist/tex/latex/kpfonts/t1jkplvos.fd texmf-dist/tex/latex/kpfonts/t1jkpos.fd - texmf-dist/tex/latex/kpfonts/t1jkposn.fd texmf-dist/tex/latex/kpfonts/t1jkpss.fd texmf-dist/tex/latex/kpfonts/t1jkpssos.fd - texmf-dist/tex/latex/kpfonts/t1jkpssosn.fd texmf-dist/tex/latex/kpfonts/t1jkpssvos.fd texmf-dist/tex/latex/kpfonts/t1jkptt.fd texmf-dist/tex/latex/kpfonts/t1jkpttos.fd - texmf-dist/tex/latex/kpfonts/t1jkpttosn.fd texmf-dist/tex/latex/kpfonts/t1jkpttvos.fd texmf-dist/tex/latex/kpfonts/t1jkpvos.fd texmf-dist/tex/latex/kpfonts/t1jkpx.fd texmf-dist/tex/latex/kpfonts/t1jkpxos.fd - texmf-dist/tex/latex/kpfonts/t1jkpxosn.fd texmf-dist/tex/latex/kpfonts/t1jkpxvos.fd texmf-dist/tex/latex/kpfonts/ts1jkp.fd texmf-dist/tex/latex/kpfonts/ts1jkpl.fd texmf-dist/tex/latex/kpfonts/ts1jkplos.fd - texmf-dist/tex/latex/kpfonts/ts1jkplosn.fd texmf-dist/tex/latex/kpfonts/ts1jkplvos.fd texmf-dist/tex/latex/kpfonts/ts1jkpos.fd - texmf-dist/tex/latex/kpfonts/ts1jkposn.fd texmf-dist/tex/latex/kpfonts/ts1jkpss.fd texmf-dist/tex/latex/kpfonts/ts1jkpssos.fd - texmf-dist/tex/latex/kpfonts/ts1jkpssosn.fd texmf-dist/tex/latex/kpfonts/ts1jkpssvos.fd texmf-dist/tex/latex/kpfonts/ts1jkptt.fd - texmf-dist/tex/latex/kpfonts/ts1jkpttos.fd - texmf-dist/tex/latex/kpfonts/ts1jkpttosn.fd - texmf-dist/tex/latex/kpfonts/ts1jkpttvos.fd texmf-dist/tex/latex/kpfonts/ts1jkpvos.fd texmf-dist/tex/latex/kpfonts/ts1jkpx.fd texmf-dist/tex/latex/kpfonts/ts1jkpxos.fd - texmf-dist/tex/latex/kpfonts/ts1jkpxosn.fd texmf-dist/tex/latex/kpfonts/ts1jkpxvos.fd texmf-dist/tex/latex/kpfonts/ujkpexa.fd texmf-dist/tex/latex/kpfonts/ujkplexa.fd @@ -54078,8 +53888,8 @@ runfiles size=2205 texmf-dist/tex/latex/kpfonts/ujkpsyb.fd texmf-dist/tex/latex/kpfonts/ujkpsyc.fd texmf-dist/tex/latex/kpfonts/ujkpsyd.fd -catalogue-version 2.1 -catalogue-date 2008-03-24 22:11:46 +0100 +catalogue-version 2.0 +catalogue-date 2008-01-22 10:22:41 +0100 catalogue-ctan /fonts/kpfonts catalogue-license gpl @@ -73914,7 +73724,7 @@ catalogue-license knuth name pxfonts category Package -revision 7213 +revision 5153 shortdesc Palatino-like fonts in support of mathematics. longdesc Pxfonts supplies virtual text roman fonts using Adobe Palatino longdesc (or URWPalladioL) with some modified and additional text @@ -73928,13 +73738,15 @@ longdesc derived from the parallel TX font set. All the fonts are in longdesc Type 1 format (AFM and PFB files), and are supported by TeX longdesc metrics (VF and TFM files) and macros for use with LaTeX. execute addMap pxfonts.map -docfiles size=661 +docfiles size=166 texmf-dist/doc/fonts/pxfonts/COPYRIGHT - texmf-dist/doc/fonts/pxfonts/px_patch1.zip + texmf-dist/doc/fonts/pxfonts/patch1.txt texmf-dist/doc/fonts/pxfonts/pxfontsdoc.pdf texmf-dist/doc/fonts/pxfonts/pxfontsdoc.tex texmf-dist/doc/fonts/pxfonts/pxfontsdocA4.pdf texmf-dist/doc/fonts/pxfonts/pxfontsdocA4.tex + texmf-dist/doc/fonts/pxfonts/pxmi.vpl + texmf-dist/doc/fonts/pxfonts/pxmi1.vpl runfiles size=305 texmf-dist/fonts/afm/public/pxfonts/pxbex.afm texmf-dist/fonts/afm/public/pxfonts/pxbexa.afm @@ -76898,7 +76710,7 @@ category Package revision 4479 shortdesc SIGGRAPH conference class. longdesc Document class for formatting papers according to the -longdesc specifications for submission to the annual ACM SIGGRAPH +longdesc specifications for submission to the annual ACM Siggraph longdesc conference. docfiles size=1 texmf-dist/doc/latex/siggraph/README details="Readme" @@ -76908,9 +76720,9 @@ srcfiles size=12 runfiles size=4 texmf-dist/tex/latex/siggraph/siggraph.cls catalogue-version -catalogue-date 2008-03-26 00:41:49 +0100 +catalogue-date 2007-01-14 23:54:50 +0100 catalogue-ctan /macros/latex/contrib/siggraph -catalogue-license other-free +catalogue-license other name simplecv category Package @@ -77746,32 +77558,6 @@ catalogue-date 2007-01-15 00:27:07 +0100 catalogue-ctan /macros/latex/contrib/statistik catalogue-license gpl -name staves -category Package -revision 7133 -shortdesc Typeset Icelandic staves and runic letters. -longdesc This package contains all the necessary tools to typeset the -longdesc “magical” Icelandic staves plus the runic letters used in -longdesc Iceland. Included are a font in Adobe Type 1 format and LaTeX -longdesc support. -execute addMap icelandic.map -docfiles size=74 - texmf-dist/doc/fonts/staves/README details="Package README" - texmf-dist/doc/fonts/staves/staves.pdf - texmf-dist/doc/fonts/staves/symbols.pdf -srcfiles size=4 - texmf-dist/source/latex/staves/staves.dtx - texmf-dist/source/latex/staves/staves.ins -runfiles size=34 - texmf-dist/fonts/map/dvips/staves/icelandic.map - texmf-dist/fonts/tfm/public/staves/icelandic.tfm - texmf-dist/fonts/type1/public/staves/icelandic.pfb - texmf-dist/tex/latex/staves/staves.sty -catalogue-version -catalogue-date 2008-03-23 12:08:21 +0100 -catalogue-ctan /language/staves -catalogue-license lppl - name stdclsdv category Package revision 4479 @@ -78741,26 +78527,25 @@ catalogue-license lppl name tablor category Package -revision 7210 +revision 7062 shortdesc Create tables of signs and of variations. longdesc The package allows the user to use the computer algebra system longdesc XCAS to generate tables of signs and of variations (the actual longdesc plotting of the tables uses the MetaPost macro package longdesc tableauVariations. The tablor package requires that shell longdesc escape be enabled. -docfiles size=155 +docfiles size=139 texmf-dist/doc/latex/tablor/Figures.zip texmf-dist/doc/latex/tablor/README details="Readme (English)" language="en" texmf-dist/doc/latex/tablor/README-fr.txt details="Readme (French)" language="fr" texmf-dist/doc/latex/tablor/tablor.html texmf-dist/doc/latex/tablor/tablor.pdf details="Package documentation (French)" language="fr" texmf-dist/doc/latex/tablor/tablor.tex -runfiles size=33 +runfiles size=13 texmf-dist/tex/latex/tablor/tablor.cfg texmf-dist/tex/latex/tablor/tablor.sty - texmf-dist/tex/latex/tablor/tablorutf8.sty -catalogue-version 2.01 -catalogue-date 2008-03-24 21:13:25 +0100 +catalogue-version 1.9 +catalogue-date 2008-03-19 21:21:02 +0100 catalogue-ctan /macros/latex/contrib/tablor catalogue-license lppl @@ -84279,7 +84064,7 @@ srcfiles size=45 name texlive-en category Documentation -revision 7154 +revision 7080 docfiles size=266 texmf-doc/doc/english/texlive-en/live.css texmf-doc/doc/english/texlive-en/live.html @@ -84347,19 +84132,19 @@ srcfiles size=54 name texlive-infra category TLCore -revision 7206 -docfiles size=152 +revision 7081 +docfiles size=151 tlpkg/README tlpkg/doc/Perl-API.txt tlpkg/doc/Shell-API.txt tlpkg/doc/installer-layout.txt tlpkg/doc/list-file-format.txt tlpkg/doc/specification.txt + tlpkg/doc/tl-portable.txt tlpkg/doc/tlinfra-guit07.pdf tlpkg/doc/tlinfra-guit07.tex tlpkg/doc/tlinst-BT08-abstract.pdf tlpkg/doc/tlinst-BT08-abstract.tex - tlpkg/doc/tlinst-BT08.tex tlpkg/doc/windemo.bat tlpkg/doc/windemo.pl tlpkg/doc/wingoo-demo.bat @@ -87518,7 +87303,7 @@ runfiles size=2 name txfonts category Package -revision 7212 +revision 5153 shortdesc Times-like fonts in support of mathematics. longdesc Txfonts supplies virtual text roman fonts using Adobe Times (or longdesc URW NimbusRomNo9L) with some modified and additional text @@ -87532,14 +87317,15 @@ longdesc All the fonts are in Type 1 format (AFM and PFB files), and are longdesc supported by TeX metrics (VF and TFM files) and macros for use longdesc with LaTeX. execute addMap txfonts.map -docfiles size=889 +docfiles size=238 + texmf-dist/doc/fonts/txfonts/00patch1.txt texmf-dist/doc/fonts/txfonts/COPYRIGHT - texmf-dist/doc/fonts/txfonts/input.zip - texmf-dist/doc/fonts/txfonts/tx_patch1.zip texmf-dist/doc/fonts/txfonts/txfontsdoc.pdf texmf-dist/doc/fonts/txfonts/txfontsdoc.tex texmf-dist/doc/fonts/txfonts/txfontsdocA4.pdf texmf-dist/doc/fonts/txfonts/txfontsdocA4.tex + texmf-dist/doc/fonts/txfonts/txmi.vpl + texmf-dist/doc/fonts/txfonts/txmi1.vpl runfiles size=558 texmf-dist/fonts/afm/public/txfonts/rtcxb.afm texmf-dist/fonts/afm/public/txfonts/rtcxbi.afm @@ -91607,9 +91393,9 @@ runfiles size=6 texmf-dist/tex/latex/ulsy/Uulsy.fd texmf-dist/tex/latex/ulsy/ulsy.sty catalogue-version -catalogue-date 2008-03-24 19:35:58 +0100 +catalogue-date 2008-01-16 21:31:11 +0100 catalogue-ctan /fonts/ulsy -catalogue-license other +catalogue-license unknown name umich-thesis category Package @@ -94651,22 +94437,22 @@ catalogue-license unknown name xargs category Package -revision 7129 +revision 6920 shortdesc Define commands with many optional arguments. longdesc The package provides extended versions of \newcommand and longdesc related LaTeX commands, which allow easy and robust definition longdesc of macros with many optional arguments, using a clear and longdesc simple xkeyval-style syntax. -docfiles size=58 +docfiles size=48 texmf-dist/doc/latex/xargs/README details="Readme" texmf-dist/doc/latex/xargs/xargs-fr.pdf details="Package documentation (French)" language="fr" texmf-dist/doc/latex/xargs/xargs.pdf details="Package documentation (English)" language="en" -srcfiles size=15 +srcfiles size=13 texmf-dist/source/latex/xargs/xargs.dtx runfiles size=4 texmf-dist/tex/latex/xargs/xargs.sty -catalogue-version 1.1 -catalogue-date 2008-03-24 21:13:25 +0100 +catalogue-version 1.09 +catalogue-date 2008-03-09 13:32:20 +0100 catalogue-ctan /macros/latex/contrib/xargs catalogue-license lppl @@ -95031,126 +94817,6 @@ catalogue-date 2007-07-17 10:47:48 +0200 catalogue-ctan /macros/latex/contrib/xifthen catalogue-license lppl -name xindy -category TLCore -revision 7207 -shortdesc A general-purpose index processor. -longdesc Xindy was designed to avoid an impasse encountered in the -longdesc attempt to complete internationalisation of makeindex. Xindy -longdesc can be used to process indexes for documents marked up using -longdesc (La)TeX, Nroff family and SGML-based languages. Xindy is highly -longdesc configurable, both in markup terms and in terms of the -longdesc collating order of the text being processed. -depend xindy.ARCH -docfiles size=157 - texmf/doc/xindy/NEWS - texmf/doc/xindy/README - texmf/doc/xindy/README.distrib-source - texmf/doc/xindy/alphabets-doc.pdf - texmf/doc/xindy/dataflow.gif - texmf/doc/xindy/faq-1.html - texmf/doc/xindy/faq-2.html - texmf/doc/xindy/faq-3.html - texmf/doc/xindy/faq-4.html - texmf/doc/xindy/faq.html - texmf/doc/xindy/index.gif - texmf/doc/xindy/manual-1.html - texmf/doc/xindy/manual-2.html - texmf/doc/xindy/manual-3.html - texmf/doc/xindy/manual-4.html - texmf/doc/xindy/manual-5.html - texmf/doc/xindy/manual-6.html - texmf/doc/xindy/manual-7.html - texmf/doc/xindy/manual.html - texmf/doc/xindy/mappings.gif - texmf/doc/xindy/style-tutorial-1.html - texmf/doc/xindy/style-tutorial-2.html - texmf/doc/xindy/style-tutorial-3.html - texmf/doc/xindy/style-tutorial-4.html - texmf/doc/xindy/style-tutorial.html - texmf/doc/xindy/tex2xindy.pdf - texmf/doc/xindy/texindy.pdf - texmf/doc/xindy/xindy.pdf -catalogue-version 2.3 -catalogue-date 2008-01-10 08:34:23 +0100 -catalogue-ctan /indexing/xindy -catalogue-license gpl - -name xindy.alpha-linux -category TLCore -revision 7207 -shortdesc binary files of xindy for alpha-linux - -name xindy.hppa-hpux -category TLCore -revision 7207 -shortdesc binary files of xindy for hppa-hpux - -name xindy.i386-darwin -category TLCore -revision 7207 -shortdesc binary files of xindy for i386-darwin - -name xindy.i386-freebsd -category TLCore -revision 7207 -shortdesc binary files of xindy for i386-freebsd - -name xindy.i386-linux -category TLCore -revision 7207 -shortdesc binary files of xindy for i386-linux - -name xindy.i386-openbsd -category TLCore -revision 7207 -shortdesc binary files of xindy for i386-openbsd - -name xindy.i386-solaris -category TLCore -revision 7207 -shortdesc binary files of xindy for i386-solaris - -name xindy.mips-irix -category TLCore -revision 7207 -shortdesc binary files of xindy for mips-irix - -name xindy.powerpc-aix -category TLCore -revision 7207 -shortdesc binary files of xindy for powerpc-aix - -name xindy.powerpc-darwin -category TLCore -revision 7207 -shortdesc binary files of xindy for powerpc-darwin - -name xindy.powerpc-linux -category TLCore -revision 7207 -shortdesc binary files of xindy for powerpc-linux - -name xindy.sparc-linux -category TLCore -revision 7207 -shortdesc binary files of xindy for sparc-linux - -name xindy.sparc-solaris -category TLCore -revision 7207 -shortdesc binary files of xindy for sparc-solaris - -name xindy.win32 -category TLCore -revision 7207 -shortdesc binary files of xindy for win32 - -name xindy.x86_64-linux -category TLCore -revision 7207 -shortdesc binary files of xindy for x86_64-linux - name xinitials category Package revision 4479 diff --git a/Master/tlpkg/tlpsrc/00texlive.installer.tlpsrc b/Master/tlpkg/tlpsrc/00texlive.installer.tlpsrc index b5fa98ab1dc..acc14f930fe 100644 --- a/Master/tlpkg/tlpsrc/00texlive.installer.tlpsrc +++ b/Master/tlpkg/tlpsrc/00texlive.installer.tlpsrc @@ -4,7 +4,8 @@ runpattern f install-tl.pl runpattern f install-tl.html runpattern f tl-portable.sh runpattern f config.guess -runpattern d tlpkg/TeXLive +# automatically added by tl-make-installer-package +#runpattern d tlpkg/TeXLive runpattern d tlpkg/installer # we don't want the perllib in runfiles, but only in bin/win32 files binpattern d/win32 tlpkg/installer/perllib diff --git a/Master/tlpkg/tlpsrc/0texlive.support.tlpsrc b/Master/tlpkg/tlpsrc/0texlive.support.tlpsrc new file mode 100644 index 00000000000..f30725d47e5 --- /dev/null +++ b/Master/tlpkg/tlpsrc/0texlive.support.tlpsrc @@ -0,0 +1,11 @@ +name 0texlive.support +category TLCore +depend texlive-infra +# package installer +binpattern f/win32 tlpkg/installer/tar.exe +binpattern f/win32 tlpkg/installer/lzmadec.win32.exe +binpattern f/win32 tlpkg/installer/wget.exe +binpattern f tlpkg/installer/lzmadec.${ARCH} +# uninstall program +runpattern f tlpkg/installer/uninstall-tl.pl +binpattern f/win32 tlpkg/installer/uninstall-tl.bat diff --git a/Master/tlpkg/tlpsrc/bin-tetex.tlpsrc b/Master/tlpkg/tlpsrc/bin-tetex.tlpsrc index b3c634037cc..17847a45b64 100644 --- a/Master/tlpkg/tlpsrc/bin-tetex.tlpsrc +++ b/Master/tlpkg/tlpsrc/bin-tetex.tlpsrc @@ -1,16 +1,11 @@ name bin-tetex category TLCore runpattern f texmf/dvips/tetex/* -runpattern f texmf/fmtutil/fmtutil-hdr.cnf runpattern f texmf/fonts/enc/dvips/tetex/* runpattern f texmf/fonts/map/dvipdfm/tetex/* runpattern f texmf/fonts/map/dvips/tetex/* runpattern f texmf/scripts/tetex/updmap.pl -runpattern f texmf/scripts/texlive/generate-fmtutil.pl -runpattern f texmf/scripts/texlive/generate-language.pl -runpattern f texmf/scripts/texlive/generate-updmap.pl runpattern f texmf/web2c/updmap.cfg -runpattern f texmf/web2c/updmap-hdr.cfg docpattern f texmf/doc/man/man1/a2ping.* docpattern f texmf/doc/man/man1/allcm.* docpattern f texmf/doc/man/man1/allec.* diff --git a/Master/tlpkg/tlpsrc/bin-texlive.tlpsrc b/Master/tlpkg/tlpsrc/bin-texlive.tlpsrc new file mode 100644 index 00000000000..e6a33e3b463 --- /dev/null +++ b/Master/tlpkg/tlpsrc/bin-texlive.tlpsrc @@ -0,0 +1,13 @@ +name bin-texlive +category TLCore +depend texlive-infra +# 0texlive.support ships the lzmadec, and for win32 tar, wget etc +depend 0texlive.support +runpattern f texmf/fmtutil/fmtutil-hdr.cnf +runpattern f texmf/scripts/texlive/generate-fmtutil.pl +runpattern f texmf/scripts/texlive/generate-language.pl +runpattern f texmf/scripts/texlive/generate-updmap.pl +runpattern f texmf/scripts/texlive/tl-package-manager.pl +runpattern f texmf/web2c/updmap-hdr.cfg +binpattern f bin/${ARCH}/texlua-perl-runner +binpattern f bin/${ARCH}/tl-package-manager diff --git a/Master/tlpkg/tlpsrc/collection-basicbin.tlpsrc b/Master/tlpkg/tlpsrc/collection-basicbin.tlpsrc index 5a796cf3952..896e72e612c 100644 --- a/Master/tlpkg/tlpsrc/collection-basicbin.tlpsrc +++ b/Master/tlpkg/tlpsrc/collection-basicbin.tlpsrc @@ -20,6 +20,7 @@ depend bin-metafont depend bin-mfware depend bin-pdftex depend bin-tetex +depend bin-texlive depend bin-tex depend bin-texconfig depend bin-xdvi |