summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
a552717)
Reparse usenet data to extended metadata hashes:
perl -MData::Dumper=Dumper -MList::MoreUtils=mesh -wE'
while (<>) { last if s/^ +// }
my @cols = split /\s+/;
my %level = (
Y => {}, N => undef, F => {alt => "function"}, L => {optional => "requires readline"},
"Y(1)" => {since => 0},
"Y(2)" => {since => undef},
"Y(3)" => {partial => 1, note => "emulation is thought by many to be incomplete"},
"N(4)" => {alt => "patch", note => "unofficial patches exist to perform this"},
"N(5)" => {alt => "patch", note => "A version called \47pdksh\47 is freely available, but does not have the full functionality of the AT&T version."},
"N(6)" => {alt => "function", note => "This can be done via the shells programmable completion mechanism."},
"Y(7)" => {alt => "config", note => "Only by specifying a file via the ENV environment variable."},
);
while (<>) {
chomp; $_ or last;
my ($title, $support) = split / +/, $_, 2;
my @support = map { exists $level{$_} ? $level{$_} : $_ } split / +/, $support;
push @data, { title => $title, support => { mesh(@cols, @support) } };
}
print Data::Dumper->new([\@data], ["feature"])
->Deepcopy(1)->Indent(1)->Quotekeys(0)->Sortkeys(1)->Trailingcomma(1)
->Dump;
' todo/shell.inc.txt >shell.inc.pl
- bash => "Y",
- csh => "Y",
- es => "N",
- ksh => "Y",
- rc => "N",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => {},
+ csh => {},
+ es => undef,
+ ksh => {},
+ rc => undef,
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- bash => "Y",
- csh => "Y",
- es => "N",
- ksh => "Y",
- rc => "N",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => {},
+ csh => {},
+ es => undef,
+ ksh => {},
+ rc => undef,
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- bash => "Y",
- csh => "N",
- es => "Y",
- ksh => "Y",
- rc => "Y",
- sh => "Y(1)",
- tcsh => "N",
- zsh => "Y",
+ bash => {},
+ csh => undef,
+ es => {},
+ ksh => {},
+ rc => {},
+ sh => {
+ since => 0,
+ },
+ tcsh => undef,
+ zsh => {},
- title => "Shell functions",
+ title => 'Shell functions',
- bash => "Y",
- csh => "N",
- es => "Y",
- ksh => "Y",
- rc => "Y",
- sh => "Y",
- tcsh => "N",
- zsh => "Y",
+ bash => {},
+ csh => undef,
+ es => {},
+ ksh => {},
+ rc => {},
+ sh => {},
+ tcsh => undef,
+ zsh => {},
- title => "\"Sensible\" Input/Output redirection",
+ title => '"Sensible" Input/Output redirection',
- bash => "Y",
- csh => "Y",
- es => "F",
- ksh => "Y",
- rc => "F",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => {},
+ csh => {},
+ es => {
+ alt => 'function',
+ },
+ ksh => {},
+ rc => {
+ alt => 'function',
+ },
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "Directory stack",
+ title => 'Directory stack',
- bash => "Y",
- csh => "Y",
- es => "L",
- ksh => "Y",
- rc => "L",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => {},
+ csh => {},
+ es => {
+ optional => 'requires readline',
+ },
+ ksh => {},
+ rc => {
+ optional => 'requires readline',
+ },
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "Command history",
+ title => 'Command history',
- bash => "Y",
- csh => "N",
- es => "L",
- ksh => "Y",
- rc => "L",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => {},
+ csh => undef,
+ es => {
+ optional => 'requires readline',
+ },
+ ksh => {},
+ rc => {
+ optional => 'requires readline',
+ },
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "Command line editing",
+ title => 'Command line editing',
- bash => "Y",
- csh => "N",
- es => "L",
- ksh => "Y",
- rc => "L",
- sh => "N",
- tcsh => "Y(3)",
- zsh => "Y",
+ bash => {},
+ csh => undef,
+ es => {
+ optional => 'requires readline',
+ },
+ ksh => {},
+ rc => {
+ optional => 'requires readline',
+ },
+ sh => undef,
+ tcsh => {
+ note => 'emulation is thought by many to be incomplete',
+ partial => 1,
+ },
+ zsh => {},
- title => "Vi Command line editing",
+ title => 'Vi Command line editing',
- bash => "Y",
- csh => "N",
- es => "L",
- ksh => "Y",
- rc => "L",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => {},
+ csh => undef,
+ es => {
+ optional => 'requires readline',
+ },
+ ksh => {},
+ rc => {
+ optional => 'requires readline',
+ },
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "Emacs Command line editing",
+ title => 'Emacs Command line editing',
- bash => "Y",
- csh => "N",
- es => "L",
- ksh => "N",
- rc => "L",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => {},
+ csh => undef,
+ es => {
+ optional => 'requires readline',
+ },
+ ksh => undef,
+ rc => {
+ optional => 'requires readline',
+ },
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "Rebindable Command line editing",
+ title => 'Rebindable Command line editing',
- bash => "Y",
- csh => "Y",
- es => "L",
- ksh => "Y",
- rc => "L",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => {},
+ csh => {},
+ es => {
+ optional => 'requires readline',
+ },
+ ksh => {},
+ rc => {
+ optional => 'requires readline',
+ },
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "User name look up",
+ title => 'User name look up',
- bash => "N",
- csh => "N",
- es => "F",
- ksh => "N",
- rc => "F",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => undef,
+ csh => undef,
+ es => {
+ alt => 'function',
+ },
+ ksh => undef,
+ rc => {
+ alt => 'function',
+ },
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "Login/Logout watching",
+ title => 'Login/Logout watching',
- bash => "Y",
- csh => "Y(1)",
- es => "L",
- ksh => "Y",
- rc => "L",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => {},
+ csh => {
+ since => 0,
+ },
+ es => {
+ optional => 'requires readline',
+ },
+ ksh => {},
+ rc => {
+ optional => 'requires readline',
+ },
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "Filename completion",
+ title => 'Filename completion',
- bash => "Y",
- csh => "Y(2)",
- es => "L",
- ksh => "Y",
- rc => "L",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => {},
+ csh => {
+ since => undef,
+ },
+ es => {
+ optional => 'requires readline',
+ },
+ ksh => {},
+ rc => {
+ optional => 'requires readline',
+ },
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "Username completion",
+ title => 'Username completion',
- bash => "Y",
- csh => "Y(2)",
- es => "L",
- ksh => "Y",
- rc => "L",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => {},
+ csh => {
+ since => undef,
+ },
+ es => {
+ optional => 'requires readline',
+ },
+ ksh => {},
+ rc => {
+ optional => 'requires readline',
+ },
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "Hostname completion",
+ title => 'Hostname completion',
- bash => "Y",
- csh => "N",
- es => "L",
- ksh => "N",
- rc => "L",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => {},
+ csh => undef,
+ es => {
+ optional => 'requires readline',
+ },
+ ksh => undef,
+ rc => {
+ optional => 'requires readline',
+ },
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "History completion",
+ title => 'History completion',
- bash => "N",
- csh => "N",
- es => "N",
- ksh => "N",
- rc => "N",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => undef,
+ csh => undef,
+ es => undef,
+ ksh => undef,
+ rc => undef,
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "Fully programmable Completion",
+ title => 'Fully programmable Completion',
- bash => "N(4)",
- csh => "N",
- es => "N",
- ksh => "N",
- rc => "N",
- sh => "N",
- tcsh => "N(6)",
- zsh => "N(6)",
+ bash => {
+ alt => 'patch',
+ note => 'unofficial patches exist to perform this',
+ },
+ csh => undef,
+ es => undef,
+ ksh => undef,
+ rc => undef,
+ sh => undef,
+ tcsh => {
+ alt => 'function',
+ note => 'This can be done via the shells programmable completion mechanism.',
+ },
+ zsh => {
+ alt => 'function',
+ note => 'This can be done via the shells programmable completion mechanism.',
+ },
- title => "Mh Mailbox completion",
+ title => 'Mh Mailbox completion',
- bash => "N",
- csh => "N",
- es => "N",
- ksh => "Y",
- rc => "N",
- sh => "N",
- tcsh => "N",
- zsh => "Y",
+ bash => undef,
+ csh => undef,
+ es => undef,
+ ksh => {},
+ rc => undef,
+ sh => undef,
+ tcsh => undef,
+ zsh => {},
- title => "Co Processes",
+ title => 'Co Processes',
- bash => "Y",
- csh => "Y",
- es => "N",
- ksh => "Y",
- rc => "N",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => {},
+ csh => {},
+ es => undef,
+ ksh => {},
+ rc => undef,
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "Builtin artithmetic evaluation",
+ title => 'Builtin artithmetic evaluation',
- bash => "Y",
- csh => "N",
- es => "N",
- ksh => "Y",
- rc => "N",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => {},
+ csh => undef,
+ es => undef,
+ ksh => {},
+ rc => undef,
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "Can follow symbolic links invisibly",
+ title => 'Can follow symbolic links invisibly',
- bash => "N",
- csh => "N",
- es => "N",
- ksh => "N",
- rc => "N",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => undef,
+ csh => undef,
+ es => undef,
+ ksh => undef,
+ rc => undef,
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "Periodic command execution",
+ title => 'Periodic command execution',
- bash => "Y",
- csh => "N",
- es => "Y",
- ksh => "Y",
- rc => "Y",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => {},
+ csh => undef,
+ es => {},
+ ksh => {},
+ rc => {},
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "Custom Prompt (easily)",
+ title => 'Custom Prompt (easily)',
- bash => "N",
- csh => "N",
- es => "N",
- ksh => "N",
- rc => "N",
- sh => "N",
- tcsh => "N",
- zsh => "Y",
+ bash => undef,
+ csh => undef,
+ es => undef,
+ ksh => undef,
+ rc => undef,
+ sh => undef,
+ tcsh => undef,
+ zsh => {},
- title => "Sun Keyboard Hack",
+ title => 'Sun Keyboard Hack',
- bash => "N",
- csh => "N",
- es => "N",
- ksh => "N",
- rc => "N",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => undef,
+ csh => undef,
+ es => undef,
+ ksh => undef,
+ rc => undef,
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "Spelling Correction",
+ title => 'Spelling Correction',
- bash => "Y(2)",
- csh => "N",
- es => "Y",
- ksh => "N",
- rc => "Y",
- sh => "N",
- tcsh => "N",
- zsh => "Y",
+ bash => {
+ since => undef,
+ },
+ csh => undef,
+ es => {},
+ ksh => undef,
+ rc => {},
+ sh => undef,
+ tcsh => undef,
+ zsh => {},
- title => "Process Substitution",
+ title => 'Process Substitution',
- bash => "sh",
- csh => "csh",
- es => "rc",
- ksh => "sh",
- rc => "rc",
- sh => "sh",
- tcsh => "csh",
- zsh => "sh",
+ bash => 'sh',
+ csh => 'csh',
+ es => 'rc',
+ ksh => 'sh',
+ rc => 'rc',
+ sh => 'sh',
+ tcsh => 'csh',
+ zsh => 'sh',
- title => "Underlying Syntax",
+ title => 'Underlying Syntax',
- bash => "Y",
- csh => "N",
- es => "Y",
- ksh => "N(5)",
- rc => "Y",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => {},
+ csh => undef,
+ es => {},
+ ksh => {
+ alt => 'patch',
+ note => "A version called 'pdksh' is freely available, but does not have the full functionality of the AT&T version.",
+ },
+ rc => {},
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "Freely Available",
+ title => 'Freely Available',
- bash => "Y",
- csh => "Y",
- es => "F",
- ksh => "Y",
- rc => "F",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => {},
+ csh => {},
+ es => {
+ alt => 'function',
+ },
+ ksh => {},
+ rc => {
+ alt => 'function',
+ },
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "Checks Mailbox",
+ title => 'Checks Mailbox',
- bash => "N",
- csh => "N",
- es => "N",
- ksh => "N",
- rc => "N",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => undef,
+ csh => undef,
+ es => undef,
+ ksh => undef,
+ rc => undef,
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "Tty Sanity Checking",
+ title => 'Tty Sanity Checking',
- bash => "Y",
- csh => "N",
- es => "Y",
- ksh => "Y",
- rc => "Y",
- sh => "Y",
- tcsh => "Y",
- zsh => "Y",
+ bash => {},
+ csh => undef,
+ es => {},
+ ksh => {},
+ rc => {},
+ sh => {},
+ tcsh => {},
+ zsh => {},
- title => "Can cope with large argument lists",
+ title => 'Can cope with large argument lists',
- bash => "Y(7)",
- csh => "Y",
- es => "N",
- ksh => "Y(7)",
- rc => "N",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => {
+ alt => 'config',
+ note => 'Only by specifying a file via the ENV environment variable.',
+ },
+ csh => {},
+ es => undef,
+ ksh => {
+ alt => 'config',
+ note => 'Only by specifying a file via the ENV environment variable.',
+ },
+ rc => undef,
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "Has non-interactive startup file",
+ title => 'Has non-interactive startup file',
- bash => "Y",
- csh => "Y",
- es => "N",
- ksh => "Y(7)",
- rc => "N",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => {},
+ csh => {},
+ es => undef,
+ ksh => {
+ alt => 'config',
+ note => 'Only by specifying a file via the ENV environment variable.',
+ },
+ rc => undef,
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "Has non-login startup file",
+ title => 'Has non-login startup file',
- bash => "Y",
- csh => "Y",
- es => "Y",
- ksh => "N",
- rc => "Y",
- sh => "N",
- tcsh => "N",
- zsh => "Y",
+ bash => {},
+ csh => {},
+ es => {},
+ ksh => undef,
+ rc => {},
+ sh => undef,
+ tcsh => undef,
+ zsh => {},
- title => "Can avoid user startup files",
+ title => 'Can avoid user startup files',
- bash => "Y",
- csh => "N",
- es => "N",
- ksh => "Y",
- rc => "N",
- sh => "N",
- tcsh => "N",
- zsh => "N",
+ bash => {},
+ csh => undef,
+ es => undef,
+ ksh => {},
+ rc => undef,
+ sh => undef,
+ tcsh => undef,
+ zsh => undef,
- title => "Can specify startup file",
+ title => 'Can specify startup file',
- bash => "N",
- csh => "N",
- es => "Y",
- ksh => "N",
- rc => "N",
- sh => "N",
- tcsh => "N",
- zsh => "N",
+ bash => undef,
+ csh => undef,
+ es => {},
+ ksh => undef,
+ rc => undef,
+ sh => undef,
+ tcsh => undef,
+ zsh => undef,
- title => "Low level command redefinition",
+ title => 'Low level command redefinition',
- bash => "N",
- csh => "N",
- es => "Y",
- ksh => "N",
- rc => "Y",
- sh => "N",
- tcsh => "N",
- zsh => "N",
+ bash => undef,
+ csh => undef,
+ es => {},
+ ksh => undef,
+ rc => {},
+ sh => undef,
+ tcsh => undef,
+ zsh => undef,
- title => "Has anonymous functions",
+ title => 'Has anonymous functions',
- bash => "N",
- csh => "Y",
- es => "Y",
- ksh => "Y",
- rc => "Y",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => undef,
+ csh => {},
+ es => {},
+ ksh => {},
+ rc => {},
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "List Variables",
+ title => 'List Variables',
- bash => "Y",
- csh => "N",
- es => "Y",
- ksh => "Y",
- rc => "Y",
- sh => "Y",
- tcsh => "N",
- zsh => "Y",
+ bash => {},
+ csh => undef,
+ es => {},
+ ksh => {},
+ rc => {},
+ sh => {},
+ tcsh => undef,
+ zsh => {},
- title => "Full signal trap handling",
+ title => 'Full signal trap handling',
- bash => "Y",
- csh => "Y",
- es => "F",
- ksh => "Y",
- rc => "N",
- sh => "N",
- tcsh => "Y",
- zsh => "Y",
+ bash => {},
+ csh => {},
+ es => {
+ alt => 'function',
+ },
+ ksh => {},
+ rc => undef,
+ sh => undef,
+ tcsh => {},
+ zsh => {},
- title => "File no clobber ability",
+ title => 'File no clobber ability',
- bash => "Y",
- csh => "N",
- es => "Y",
- ksh => "Y",
- rc => "Y",
- sh => "N",
- tcsh => "N",
- zsh => "Y",
+ bash => {},
+ csh => undef,
+ es => {},
+ ksh => {},
+ rc => {},
+ sh => undef,
+ tcsh => undef,
+ zsh => {},
- title => "Local variables",
+ title => 'Local variables',
- bash => "N",
- csh => "N",
- es => "Y",
- ksh => "N",
- rc => "N",
- sh => "N",
- tcsh => "N",
- zsh => "N",
+ bash => undef,
+ csh => undef,
+ es => {},
+ ksh => undef,
+ rc => undef,
+ sh => undef,
+ tcsh => undef,
+ zsh => undef,
- title => "Lexically scoped variables",
+ title => 'Lexically scoped variables',
- bash => "N",
- csh => "N",
- es => "Y",
- ksh => "N",
- rc => "N",
- sh => "N",
- tcsh => "N",
- zsh => "N",
+ bash => undef,
+ csh => undef,
+ es => {},
+ ksh => undef,
+ rc => undef,
+ sh => undef,
+ tcsh => undef,
+ zsh => undef,
'<tr>',
'<th>feature',
(map {
'<tr>',
'<th>feature',
(map {
- sprintf('<th>%s', Entity($_->{name}))
- } @{ $data->{agents} }{@agents}),
+ sprintf('<th%s>%s',
+ (map {
+ sprintf ' title="%s"', Entity($_)
+ } $data->{agents}->{$_}->{name} // ()),
+ $_
+ )
+ } @agents),
);
print '<thead>', $header;
say '</thead>';
);
print '<thead>', $header;
say '</thead>';
print '<td>', Entity($row->{title});
}
print '<td>', Entity($row->{title});
}
-my %DSTATS = (
- Y => 'feature can be done',
- N => 'feature is not present',
- F => 'feature can only be done by using the shells function mechanism',
- L => 'the readline library must be linked into the shell to enable this feature',
-);
-my %CSTATS = (
- N => 'l1',
- F => 'l2',
- L => 'l4',
- Y => 'l5',
+my %TSTATS = (
+ l5 => '✔',
+ l4 => '✔',
+ l3 => '±',
+ l2 => '*',
+ l1 => '✘',
);
sub saysupportcols {
my ($row, $agent) = @_;
);
sub saysupportcols {
my ($row, $agent) = @_;
- my $stat = $row->{support}->{$agent};
+ my $support = $row->{support}->{$agent};
+ my $level = (
+ !defined $support ? 'l1' :
+ ref $support ne 'HASH' ? 'l0' :
+ $support->{alt} ? 'l2' :
+ $support->{partial} ? 'l3' :
+ $support->{optional} ? 'l4' :
+ 'l5'
+ );
- $DSTATS{$stat} // 'unknown support',
- 'in', $agent,
+ defined $support ? 'supported' : 'unsupported',
+ 'in', $data->{agents}->{$agent}->{abbr} // $agent,
+ $title .= " ($_)"
+ for ref $support && ($support->{note} // $support->{optional}) || ();
+ my $header = defined $support ? '✔' : '✘';
printf('<td class="%s" title="%s">%s',
printf('<td class="%s" title="%s">%s',
- join(' ',
- X => $CSTATS{$stat},
- ),
+ join(' ', X => $level),
+ $TSTATS{$level} // (ref $support ? '?' : $support),