Personal Command Line Everything (or PCLE for short) is a small Perl script that emulates a command line version of Everything2. It's more a joke than anything else, but it may be useful as a small note manager and to get yourself properly trained at Putting Things In Brackets when an internet connection is not available.

Features

  • Small, self-contained version of Everything running in some 150 lines of Perl;
  • Both Hard links and Pipe links supported
  • Recent nodes feature
  • Node traversal history
  • Navigate backwards and forwards
Requirements
  • A machine with Perl 5 installed, and
  • A writable directory on said machine, and
  • A command line editor installed on said machine, something like vi, vim or DOS's edit.
How do I use it?

To run PCLE, make sure the file pcle.pl is in the local directory, and run it by typing perl pcle.pl at the command prompt.

You can call a node by typing its name on PCLE; it will show it if it's present or invite you to create it if it's not present. If a node contains hyperlinks, they will be displayed as a number in square brackets after each hyperlink (no way to underscore things in the command prompt). If you type the number, PCLE will take you there. PCLE keeps a history of nodes you visited; to go back to the previous node, type -1, to the one before that type -2, and so on.

You can create or edit a node by typing new nodename or edit nodename. It will start the text editor you defined in variable $system_editor and you'll be free to edit it.

Creation of links and pipe links works as in Everything2, so you should already know how they work.

latest and history let you see the latest nodes that were created and the user navigation history.

help lets you see a brief help text.

bye exits PCLE.

Have fun.


This is PCLE version 0.2, as of 2003-12-1


use strict;

my $node_now;
my $command_line  = 'pcle' or $ARGV[1];
my $system_editor = 'vim'; #change this to suit your needs
my @node_info;
my @visited_nodes;
my $pcle_ver = '0.2';

my $help = << "__HELP__";
This is Personal Command-Line Everything version $pcle_ver by lenz

Commands are as follows:
 - 'help' prints this message
 - 'quit' or 'bye' exits PCLE
 - 'latest' shows latest nodes ('latest 3' shows latest 3 nodes)
 - 'history' shows node history ('history 3' shows latest 3 entries)
 - 'new' creates a node
 - 'edit' edits a node
 - enter node number (like '3' or '#3') or name to reach it.
 - enter '-1', '-2' to navigate backwards 

__HELP__

print $help;
print loadNode( $command_line );

for(;;) {
	print "> ";
	$command_line = lc ;
	
	exit if $command_line =~ /^quit|bye/i;
    
    if ($command_line =~ /^(edit|new) (.+?)$/i) {
    	createNode( $2 );
    	$command_line = $2;	
    };

	if ($command_line =~ /^latest\s*(\d*)$/i) {
		latestNodes( $1 || 99999 );
    	$command_line = '';	
	}
	
	if ($command_line =~ /^history\s*(\d*)$/i) {
		showHistory( $1 || 99999 );
    	$command_line = '';	
	}
	
	
	
	if ($command_line =~ /^help$/i) {
		print $help;
    	$command_line = '';	
	}
	
	if ($command_line =~ /^#*\s*(\d+)/i) {
		$command_line = $node_info[$1];
	}
	
	if ($command_line =~ /^-(\d+)/i) {
		$command_line = $visited_nodes[-$1 - 1];
	}
	
		
	print loadNode( $command_line );
}




sub loadNode() {
	my ($nodeName) = @_;
	chomp $nodeName;
	
	return if length($nodeName) == 0;
		
	my $nodePath = lc $nodeName . ".node";
	my $n = "Node '$nodeName' - ";
	my $dt;
		
	if ( -f $nodePath ) {
		undef @node_info;
		open F, $nodePath or die "$! $nodePath";
		$n .= localtime( (stat( $nodePath ))[9] ) . "\n----\n";
		
		while () {
			$n .= $_;
		}
		close F;
		
		# replace and number bracketed stuff
		#my $set = "[^\[\]]"; # everything but square brackets
		$n =~ s/\[([^\[\]]+?)\|([^\[\]]+?)\]/doSubst($1, $2)/gime; #pipe links
		$n =~ s/\[([^\[\]]+?)\]/doSubst($1, $1)/gime;              #normal links
		
		push @visited_nodes, $nodeName;
	} else {
		$n = "The node '$nodeName' does not exist\n\nType 'new $nodeName' to create it.";
	}
	return $n . "\n";
}

sub doSubst() {
	my ($n, $t) = @_;
	push @node_info, $n;
	return "$t [" . $#node_info . "]";
}
	


sub createNode() {
	my ($nodeName) = @_;
	chomp $nodeName;
	my $nodePath = lc $nodeName . ".node";
	
	system( "$system_editor $nodePath" );

}

sub latestNodes() {
	my ($howMany) = @_;
	
	my @files = glob( '*.node' );
	my %dtupd;
	my $n = 0;
	
	foreach my $f (@files) {
		my $tm = (stat( $f ))[9] ;
		$dtupd{ $tm . ':' . $n++ } = $1 if $f =~ /(.+)\.node/i;
	}	

	$n = 0;
	foreach my $f (reverse sort keys %dtupd ) {
		last if ($n++ >= $howMany);
		my ($d) = split /:/, $f;
		print localtime( $d ) . "  - " . $dtupd{$f} . "\n";
	}
}

sub showHistory() {
	my ($howMany) = @_;
	my @cmd = reverse @visited_nodes;
	my $i = 0;
	
	foreach my $n (@cmd[0..$howMany]) {
		last if length($n) == 0;
		print "-$i: $n\n";
		$i++;
	}
}


Having just found this intriguing little program, I tried it and discovered that a couple lines had lost their angle brackets (due to HTML fubar somewhere along the line), there was an odd issue with pipelinks (because of two regexen applied sequentially), and saw the opportunity to add ANSI color codes to visually differentiate the output (on supporting terminals, such as gnome-terminal). The variables for the link underline and colors (change to suit your taste!) are at the top of the file.

Here is the updated code. I will leave it as an exercise for the reader to get a diff. Credit goes to lenz for writing the original.


#!/usr/bin/env perl
use strict;

my $node_now;
my $command_line  = 'pcle' or $ARGV[1];
my $system_editor = 'vim'; #change this to suit your needs
my $color_system = '33;1';  # yellow, bold
my $color_header = '34;1';  # blue, bold
my $color_link = '4';  # underline
my @node_info;
my @visited_nodes;
my $pcle_ver = '0.3';

my $help = << "__HELP__";
\x1b[${color_system}m
This is Personal Command-Line Everything version $pcle_ver
created by lenz, updated by raincomplex

Commands are as follows:
 - 'help' prints this message
 - 'quit' or 'bye' exits PCLE
 - 'latest' shows latest nodes ('latest 3' shows latest 3 nodes)
 - 'history' shows node history ('history 3' shows latest 3 entries)
 - 'new' creates a node
 - 'edit' edits a node
 - enter node number (like '3' or '#3') or name to reach it.
 - enter '-1', '-2' to navigate backwards 
\x1b[0m
__HELP__

print $help;
print loadNode( $command_line );

for(;;) {
	print "> ";
	$command_line = lc <>;
	
	exit if $command_line =~ /^quit|bye/i;
    
    if ($command_line =~ /^(edit|new) (.+?)$/i) {
    	createNode( $2 );
    	$command_line = $2;	
    };

	if ($command_line =~ /^latest\s*(\d*)$/i) {
		latestNodes( $1 || 99999 );
    	$command_line = '';	
	}
	
	if ($command_line =~ /^history\s*(\d*)$/i) {
		showHistory( $1 || 99999 );
    	$command_line = '';	
	}
	
	
	
	if ($command_line =~ /^help$/i) {
		print $help;
    	$command_line = '';	
	}
	
	if ($command_line =~ /^#*\s*(\d+)/i) {
		$command_line = $node_info[$1];
	}
	
	if ($command_line =~ /^-(\d+)/i) {
		$command_line = $visited_nodes[-$1 - 1];
	}
	
		
	print loadNode( $command_line );
}




sub loadNode() {
	my ($nodeName) = @_;
	chomp $nodeName;
	
	return if length($nodeName) == 0;
		
	my $nodePath = lc $nodeName . ".node";
	my $n = "\x1b[${color_header}mNode '$nodeName' - ";
	my $dt;
		
	if ( -f $nodePath ) {
		undef @node_info;
		open F, $nodePath or die "$! $nodePath";
		$n .= localtime( (stat( $nodePath ))[9] ) . "\n";
		$n .= ('-' x (-8 + length $n)) . "\x1b[0m\n";
		
		while (<F>) {
			$n .= $_;
		}
		close F;
		
		# replace and number bracketed stuff
		$n =~ s/\[([^\[\]]+?)(\|[^\[\]]+?)?\]/doSubst($1, $2)/gime;
		
		push @visited_nodes, $nodeName;
	} else {
		$n = "\x1b[${color_system}mThe node '$nodeName' does not exist\nType 'new $nodeName' to create it.\x1b[0m\n";
	}
	return $n . "\n";
}

sub doSubst() {
	my ($n, $t) = @_;
	if (!$t) { $t = $n; }  # regular links: display text = link text
	else { $t = substr $t, 1; }  # remove pipes from display text
	push @node_info, $n;
	return "\x1b[${color_link}m$t\x1b[0m[" . $#node_info . "]";
}
	


sub createNode() {
	my ($nodeName) = @_;
	chomp $nodeName;
	my $nodePath = lc $nodeName . ".node";
	
	system( "$system_editor $nodePath" );

}

sub latestNodes() {
	my ($howMany) = @_;
	
	my @files = glob( '*.node' );
	my %dtupd;
	my $n = 0;
	
	foreach my $f (@files) {
		my $tm = (stat( $f ))[9] ;
		$dtupd{ $tm . ':' . $n++ } = $1 if $f =~ /(.+)\.node/i;
	}	

	$n = 0;
	foreach my $f (reverse sort keys %dtupd ) {
		last if ($n++ >= $howMany);
		my ($d) = split /:/, $f;
		print localtime( $d ) . "  - " . $dtupd{$f} . "\n";
	}
}

sub showHistory() {
	my ($howMany) = @_;
	my @cmd = reverse @visited_nodes;
	my $i = 0;
	
	foreach my $n (@cmd[0..$howMany]) {
		last if length($n) == 0;
		print "-$i: $n\n";
		$i++;
	}
}

Log in or register to write something here or to contact authors.