#!/usr/bin/perl -w # Created by Ben Okopnik on Fri Apr 23 18:29:52 EDT 2010 use strict; use YAML qw/LoadFile DumpFile/; ################ Start user-configurable section ################# # YAML source DB my $file = "$ENV{HOME}/.linux_notes.db"; # If the shell's '$EDITOR' is defined, use that, else use 'vi' my $editor = $ENV{EDITOR} || "/usr/bin/vi"; # Category match strictness, 0-1: # 0: string match anywhere in the category name # 1: delimited word match in the category name my $category_match_level = 1; # Item match strictness, 0-2: # 0: string match in either the item name OR the item text # 1: string match in the item name # 2: delimited word match in the item name my $item_match_level = 0; ################# End user-configurable section ################## my ($cat, $item, $txt); my $help_txt = " -h|--help|-e|category [item] -h|--help This text -e Edit YAML DB using '$editor' category Display all entries in matching category (regex) category item Display all matching items in matching category (regex) "; my %list = %{LoadFile($file)}; if (@ARGV){ if ($ARGV[0] =~ /^-(h|-help)$/){ die $0 =~ /([^\/]+)$/, $help_txt; } exec "$editor $file" if $ARGV[0] eq '-e'; my $H_on = qx[/usr/bin/tput smul]; my $H_off = qx[/usr/bin/tput rmul]; $cat = shift; $item = shift || '.*'; # Page the output if it's more than a screen's worth open Less, "|/bin/less -FXR" or die "less: $!\n"; my $old_Fh = select Less; my $found; for my $s (keys %list){ if ($category_match_level == 0){ next unless $s =~ /$cat/i; } if ($category_match_level == 1){ next unless $s =~ /\b$cat\b/i; } $found++; for my $i (keys %{$list{$s}}){ if ($item_match_level == 0){ if ($i =~ /$item/i || $list{$s}{$i} =~ /$item/i){ print "*** Category: $s ***\n" if $item eq '.*'; print "# $H_on$i$H_off\n", $list{$s}{$i}; } } if ($item_match_level == 1){ if ($i =~ /$item/i){ print "*** Category: $s ***\n" if $item eq '.*'; print "# $H_on$i$H_off\n", $list{$s}{$i}; } } if ($item_match_level == 2){ if ($i =~ /\b$item\b/i){ print "*** Category: $s ***\n" if $item eq '.*'; print "# $H_on$i$H_off\n", $list{$s}{$i}; } } } } print "No match for specified category.\n" unless $found; # Reset output back to STDOUT select $old_Fh; } else { my @categories = sort keys %list; my ($max_length) = sort { $b <=> $a } map { length } @categories; my $total_length; print "Existing categories:\n\n"; for (@categories){ printf "| %-${max_length}s ", $_; $total_length += $max_length; if ($total_length >= 80){ $total_length = 0; print "|\n"; } } print "\n\n"; do { print "Add (to) Category (separate multiple categories with '/')? "; chomp($cat = ); exit if $cat =~ /^$/; } while $cat =~ m(^\s*/|\s*/$); do { print "Item name/synopsis (at least 3 characters)? "; chomp($item = ); exit if $item =~ /^$/; } while length($item) < 3; print "Enter the item; terminate with '.' on a line by itself.\n"; { $_ = ; $txt .= $_ and redo unless /^\.$/; } # Fit item into existing category if one matches for (keys %list){ $cat = $_ if /\b$cat\b/i; } $list{$cat}{$item} .= defined $list{$cat}{$item} ? "\n\n$txt" : $txt; DumpFile($file, \%list); }