From 94ea7a8cd41b5b0cebf2606f4319ca5050e80520 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Sun, 5 Jul 2020 21:03:38 -0400 Subject: Add some new stuff --- crc32 | 9 + dumprpath | 6 + imagebin | 16 + netqiv | 7 + slacklog | 4 + smartfmt | 51 ++++ uleft | 41 +++ unibmptxt.pl | 875 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ urxvt-change-font | 9 + utf8ord | 12 + vipaste | 53 ++++ wide.pl | 112 +++++++ x1 | 13 + xcleanpaste | 153 ++++++++++ 14 files changed, 1361 insertions(+) create mode 100755 crc32 create mode 100755 dumprpath create mode 100755 imagebin create mode 100755 netqiv create mode 100755 slacklog create mode 100755 smartfmt create mode 100755 uleft create mode 100755 unibmptxt.pl create mode 100755 urxvt-change-font create mode 100755 utf8ord create mode 100755 vipaste create mode 100755 wide.pl create mode 100755 x1 create mode 100755 xcleanpaste diff --git a/crc32 b/crc32 new file mode 100755 index 0000000..1adfa3b --- /dev/null +++ b/crc32 @@ -0,0 +1,9 @@ +#!/bin/sh + +# Horribly inefficient way to calculate crc32 of a file. + +Z=/tmp/crc32hack.$$.$RANDOM.zip +rm -f $Z +zip -q $Z "$1" +zipinfo -v $Z | grep CRC | sed 's,.* ,,' +rm -f $Z diff --git a/dumprpath b/dumprpath new file mode 100755 index 0000000..cc07fd0 --- /dev/null +++ b/dumprpath @@ -0,0 +1,6 @@ +#!/bin/sh + +for i in "$@"; do + echo -n "$i: " + objdump -x "$i" | grep RPATH +done diff --git a/imagebin b/imagebin new file mode 100755 index 0000000..a5de360 --- /dev/null +++ b/imagebin @@ -0,0 +1,16 @@ +#!/bin/sh + +# pastebin an image. if xsel is installed, copy the URL to the X clipboard. +# uses this API: https://ibin.co/tools.php +# no support for using a login + API key, don't need it. + +url="$( + curl -F file="@${1:-}" https://imagebin.ca/upload.php | \ + grep ^url: | \ + cut -d: -f2- +)" + +if [ -n "$url" ]; then + echo "$url" + which xsel &>/dev/null && echo -n "$url" | xsel +fi diff --git a/netqiv b/netqiv new file mode 100755 index 0000000..c5bea0f --- /dev/null +++ b/netqiv @@ -0,0 +1,7 @@ +#!/bin/sh + +set -e +mkdir -p ~/.netqiv +cd ~/.netqiv +wget "$1" +qiv "$@" "$( basename "$1" )" diff --git a/slacklog b/slacklog new file mode 100755 index 0000000..819b4b1 --- /dev/null +++ b/slacklog @@ -0,0 +1,4 @@ +#!/bin/sh + +VER=${@:-14.2} +exec tmux new links ftp://ftp.osuosl.org/pub/slackware/slackware-$VER/ChangeLog.txt diff --git a/smartfmt b/smartfmt new file mode 100755 index 0000000..71ca8c7 --- /dev/null +++ b/smartfmt @@ -0,0 +1,51 @@ +#!/usr/bin/perl -w + +# wrapper for fmt, detects when every line has +# the same prefix (or is blank) and passes the prefix +# as a -p option to fmt. Called by ~/.vimrc, F mapping. + +sub shortest { + my $oldprefix = shift; + my $line = shift; + my $newprefix = ""; + + for(my $i = 0; $i < length($oldprefix) && $i < length($line); $i++) { + last if substr($line, $i, 1) ne substr($oldprefix, $i, 1); + $newprefix .= substr($line, $i, 1); + } + + return $newprefix; +} + +$nonblank = 0; +while() { + chomp; + s/^\s+$//; + push @lines, $_; + next if /^$/; + + $nonblank++; + + if(not defined $prefix) { + $prefix = $_; + } elsif($prefix ne "") { + $prefix = shortest($prefix, $_); + } +} + +$width = 71; +if($nonblank > 1 && $prefix ne "" && ($prefix =~ /[^A-Za-z]$/)) { + $opt = ' -p' . quotemeta($prefix) . ' '; + if(@ARGV && ($ARGV[0] eq '-s')) { + $width = (length($prefix) + 71); + } +} + +$opt.= "-w $width -g $width"; + +#warn "line: $_" for @lines; +#warn "opt: $opt"; + +open OUT,"|fmt $opt" or die $!; +print OUT "$_\n" for @lines; +close OUT; diff --git a/uleft b/uleft new file mode 100755 index 0000000..0efe972 --- /dev/null +++ b/uleft @@ -0,0 +1,41 @@ +#!/bin/sh + +# uleft, uright, ukill, ufull, unext - start & kill urxvt with +# preferred geometry. the terminals persist when their shells exit +# (they just start a new one). + +# any arguments passed to this script are passed thru to urxvt. + +GLEFT="96x53+0+0" +GRIGHT="88x53+968+0" +GFULL="185x53+0+0" + +murder_shell() { + # kill the shell that called the shell that's running this script + kill $( ps -o ppid --no-headers $( ps -o ppid --no-headers $$ ) ) + exit 0 +} + +get_next_geom() { + # lets this script alternate between starting left and right terminals + if [ ! -e ~/.uleftright ] || grep -q right ~/.uleftright; then + G=$GLEFT + echo left > ~/.uleftright + else + G=$GRIGHT + echo right > ~/.uleftright + fi + + echo "$G" +} + +case "$0" in + *kill*) murder_shell ;; + *left*) G=$GLEFT ;; + *full*) G=$GFULL ;; + *next*) G=$( get_next_geom ) ;; + *) G=$GRIGHT ;; +esac + +urxvt -g "$G" "$@" -e sh -c "while true; do bash -login; done" &>/dev/null & +disown diff --git a/unibmptxt.pl b/unibmptxt.pl new file mode 100755 index 0000000..e20de65 --- /dev/null +++ b/unibmptxt.pl @@ -0,0 +1,875 @@ +#!/usr/bin/perl + +use warnings; +no warnings 'utf8'; +use utf8; + +@block4x4s = split "", " ▗▖▄▝▐▞▟▘▚▌▙▀▜▛█"; + +for($i = 0; $i < 95; $i++) { + ; # skip comment + for($j = 0; $j < 6; $j++) { + my $row = ; + chomp($row); + $row =~ s/X/1/g; + $row =~ s/\./0/g; + #warn @s; + $font[$i + 32][$j] = $row; + } + ; # skip blank +} + +if(!@ARGV) { + @ARGV = ( + " !\"#\$%&'()*+,-./", + "0123456789:;<=>?", + "\@ABCDEFGHIJKLMNO", + "PQRSTUVWXYZ[\\]^_", + "\`abcdefghijklmno", + "pqrstuvwxyz{|}~"); +} + +for $input (@ARGV) { + my @lines = (); + for(split "", $input) { + my $o = ord($_); + next if $o < 32 || $o > 126; + for(0..5) { + $lines[$_] .= $font[$o][$_]; + } + } + +# always want an even number of columns + if(length($lines[0]) % 1) { + $lines[$_] .= "0" for 0..5; + } + +#print "$_\n" for @lines; + + my @output = (); + for($y = 0; $y < 6; $y += 2) { + my $out = ""; + for($x = 0; $x < length($lines[0]); $x += 2) { + my $index = 0; + $index |= 8 if substr($lines[$y], $x, 1) eq '1'; + $index |= 4 if substr($lines[$y], $x + 1, 1) eq '1'; + $index |= 2 if substr($lines[$y + 1], $x, 1) eq '1'; + $index |= 1 if substr($lines[$y + 1], $x + 1, 1) eq '1'; + $out .= $block4x4s[$index]; + } + push @output, $out; + } + + print "$_\n" for @output; +} + +=for reference +# __DATA__ section originally made thus: +open my $f, ") { + chomp; + if(/^ENCODING\s+(\d+)/) { + $encoding = $1; + next; + } + + if($in_bitmap) { + if(/^ENDCHAR/) { + $in_bitmap = 0; + $bitmaps{$encoding} = [ @bitmap ]; + } else { + push @bitmap, $_; + #warn "encoding $encoding, byte $_"; + } + } else { + if(/^BITMAP/) { + $in_bitmap = 1; + @bitmap = (); + } + } +} + +## for(sort { $a <=> $b } keys %bitmaps) { +## print $_ . " => " . join(" ", @{$bitmaps{$_}}) . "\n"; +## } + +for($i = 32; $i < 127; $i++) { + print "# $i " . chr($i) . "\n"; + for(@{$bitmaps{$i}}) { + my $byte = hex($_); + my $bin = sprintf("%08b", $byte); + $bin =~ s/000$//; + $bin =~ s/0/./g; + $bin =~ s/1/X/g; + print $bin . "\n"; + } + print "\n"; +} +=cut + +# This stuff was taken from 5x7.bdf, but hand-edited to make it 6 rows +# high, proportional, and fix some of the uglier glyphs. +__DATA__ +# 32 +... +... +... +... +... +... + +# 33 ! +X. +X. +X. +.. +X. +.. + +# 34 " +X.X. +X.X. +.... +.... +.... +.... + +# 35 # +.X.X.. +XXXXX. +.X.X.. +XXXXX. +.X.X.. +...... + +# 36 $ +.XXXX. +X.X... +.XXX.. +..X.X. +XXXX.. +...... + +# 37 % +..... +X..X. +..X.. +.X... +X..X. +..... + +# 38 & +.X... +X.X.. +.X... +X.X.. +.X.X. +..... + +# 39 ' +X. +X. +.. +.. +.. +.. + +# 40 ( +.X. +X.. +X.. +X.. +.X. +... + +# 41 ) +X.. +.X. +.X. +.X. +X.. +... + +# 42 * +...... +X.X.X. +.XXX.. +X.X.X. +...... +...... + +# 43 + +.... +.X.. +XXX. +.X.. +.... +.... + +# 44 , +... +... +... +... +.X. +X.. + +# 45 - +.... +.... +XXX. +.... +.... +.... + +# 46 . +.. +.. +.. +.. +X. +.. + +# 47 / +..... +...X. +..X.. +.X... +X.... +..... + +# 48 0 +.XX.. +X..X. +X.XX. +X..X. +.XX.. +..... + +# 49 1 +.X.. +XX.. +.X.. +.X.. +XXX. +.... + +# 50 2 +.XX.. +X..X. +..X.. +.X... +XXXX. +..... + +# 51 3 +.XX.. +X..X. +. X.. +X..X. +.XX.. +..... + +# 52 4 +..X.. +.XX.. +X.X.. +XXXX. +..X.. +..... + +# 53 5 +XXXX. +X.... +XXX.. +...X. +XXX.. +..... + +# 54 6 +.XX.. +X.... +XXX.. +X..X. +.XX.. +..... + +# 55 7 +XXXX. +...X. +..X.. +.X... +.X... +..... + +# 56 8 +.XX.. +X..X. +.XX.. +X..X. +.XX.. +..... + +# 57 9 +.XX.. +X..X. +.XXX. +...X. +.XX.. +..... + +# 58 : +.. +X. +.. +X. +.. +.. + +# 59 ; +... +.X. +... +.X. +X.. +... + +# 60 < +..X. +.X.. +X... +.X.. +..X. +.... + +# 61 = +.... +XXX. +.... +XXX. +.... +.... + +# 62 > +X... +.X.. +..X. +.X.. +X... +.... + +# 63 ? +.XX.. +X..X. +..X.. +..... +..X.. +..... + +# 64 @ +.XX.. +X..X. +X.XX. +X.... +.XX.. +..... + +# 65 A +.XX.. +X..X. +XXXX. +X..X. +X..X. +..... + +# 66 B +XXX.. +X..X. +XXX.. +X..X. +XXX.. +..... + +# 67 C +.XX.. +X..X. +X.... +X..X. +.XX.. +..... + +# 68 D +XXX.. +X..X. +X..X. +X..X. +XXX.. +..... + +# 69 E +XXXX. +X.... +XXX.. +X.... +XXXX. +..... + +# 70 F +XXXX. +X.... +XXX.. +X.... +X.... +..... + +# 71 G +.XXX. +X.... +X.XX. +X..X. +.XXX. +..... + +# 72 H +X..X. +X..X. +XXXX. +X..X. +X..X. +..... + +# 73 I +XXX. +.X.. +.X.. +.X.. +XXX. +.... + +# 74 J +...X. +...X. +...X. +X..X. +.XX.. +..... + +# 75 K +X..X. +X.X.. +XX... +X.X.. +X..X. +..... + +# 76 L +X.... +X.... +X.... +X.... +XXXX. +..... + +# 77 M +X...X. +XX.XX. +X.X.X. +X.X.X. +X...X. +...... + +# 78 N +X..X. +XX.X. +X.XX. +X.XX. +X..X. +..... + +# 79 O +.XX.. +X..X. +X..X. +X..X. +.XX.. +..... + +# 80 P +XXX.. +X..X. +XXX.. +X.... +X.... +..... + +# 81 Q +.XX.. +X..X. +X..X. +X..X. +.XX.. +..XX. + +# 82 R +XXX.. +X..X. +XXX.. +X.X.. +X..X. +..... + +# 83 S +.XXX. +X.... +.XX.. +...X. +XXX.. +..... + +# 84 T +XXXXX. +..X... +..X... +..X... +..X... +...... + +# 85 U +X..X. +X..X. +X..X. +X..X. +.XX.. +..... + +# 86 V +X...X. +X...X. +X...X. +.X.X.. +..X... +...... + +# 87 W +X...X. +X...X. +X.X.X. +XX.XX. +X...X. +...... + +# 88 X +X..X. +X..X. +.XX.. +X..X. +X..X. +..... + +# 89 Y +X...X. +X...X. +.XXX.. +..X... +..X... +...... + +# 90 Z +XXXX. +...X. +.XX.. +X.... +XXXX. +..... + +# 91 [ +XX. +X.. +X.. +X.. +XX. +... + +# 92 \ +..... +X.... +.X... +..X.. +...X. +..... + +# 93 ] +XX. +.X. +.X. +.X. +XX. +.... + +# 94 ^ +.X.. +X.X. +.... +.... +.... +.... + +# 95 _ +..... +..... +..... +..... +XXXX. +..... + +# 96 ` +X.. +.X. +... +... +... +... + +# 97 a +..... +..... +.XXX. +X..X. +.XXX. +..... + +# 98 b +X.... +X.... +XXX.. +X..X. +XXX.. +..... + +# 99 c +.... +.... +.XX. +X... +.XX. +.... + +# 100 d +...X. +...X. +.XXX. +X..X. +.XXX. +..... + +# 101 e +..... +.XX.. +X..X. +X.X.. +.XXX. +..... + +# 102 f +..XX. +.X... +XXX.. +.X... +.X... +..... + +# 103 g +..... +.XXX. +X..X. +.XXX. +...X. +.XX.. + +# 104 h +X.... +X.... +XXX.. +X..X. +X..X. +..... + +# 105 i +.X.. +.... +XX.. +.X.. +XXX. +.... + +# 106 j +..X. +.... +..X. +..X. +X.X. +.X.. + +# 107 k +X... +X... +X.X. +XX.. +X.X. +.... + +# 108 l +XX.. +.X.. +.X.. +.X.. +XXX. +.... + +# 109 m +...... +...... +X.XX.. +XXXXX. +X.X.X. +...... + +# 110 n +..... +..... +XXX.. +X..X. +X..X. +..... + +# 111 o +..... +..... +.XX.. +X..X. +.XX.. +..... + +# 112 p +..... +..... +XXX.. +X..X. +XXX.. +X.... + +# 113 q +..... +..... +.XXX. +X..X. +.XXX. +...X. + +# 114 r +..... +..... +XXX.. +X..X. +X.... +..... + +# 115 s +..... +.XXX. +XX... +..XX. +XXX.. +..... + +# 116 t +.X... +.X... +XXX.. +.X... +..XX. +..... + +# 117 u +..... +..... +X..X. +X..X. +.XXX. +..... + +# 118 v +.... +.... +X.X. +X.X. +.X.. +.... + +# 119 w +...... +...... +X...X. +X.X.X. +XX.XX. +...... + +# 120 x +..... +..... +X..X. +.XX.. +X..X. +..... + +# 121 y +..... +..... +X..X. +.X.X. +..X.. +.X... + +# 122 z +..... +XXXX. +..X.. +.X... +XXXX. +..... + +# 123 { +..X. +.X.. +XX.. +.X.. +..X. +.... + +# 124 | +X. +X. +X. +X. +X. +.. + +# 125 } +X... +.X.. +.XX. +.X.. +X... +.... + +# 126 ~ +.X.X. +X.X.. +..... +..... +..... +..... + diff --git a/urxvt-change-font b/urxvt-change-font new file mode 100755 index 0000000..6556a2d --- /dev/null +++ b/urxvt-change-font @@ -0,0 +1,9 @@ +#!/bin/sh + +# Read default from X resources +DFLT="$( xrdb -query |grep '^URxvt\*font'|cut -f2 )" +DFLT="${DFLT:-xft:Deja Vu Sans Mono:size=13}" +NEWFONT="$@" +FONT=${NEWFONT:-$DFLT} +echo "Setting urxvt font to '$FONT'" +printf '\e]710;%s\007' "${1:-$FONT}" diff --git a/utf8ord b/utf8ord new file mode 100755 index 0000000..f413906 --- /dev/null +++ b/utf8ord @@ -0,0 +1,12 @@ +#!/usr/bin/perl -CIOESA -w + +use charnames qw/:full/; + +#print ord($_), "\n" for @ARGV; + +for(@ARGV) { + for(split "") { + my $c = ord; + printf("%s\t%d\t%04x\t%s\n", $_, $c, $c, charnames::viacode($c)) for split ""; + } +} diff --git a/vipaste b/vipaste new file mode 100755 index 0000000..15cc892 --- /dev/null +++ b/vipaste @@ -0,0 +1,53 @@ +#!/bin/bash + +usage() { + cat < and released under the WTFPL. +EOF + exit $1 +} + +set -e + +SELF="$( basename $0 )" +CMD="xsel -o" + +[ "$1" = "--help" ] && usage 0 +[ "$1" = "-n" ] && CMD=":" && shift +[ "$1" != "" ] && usage 1 + +TMPFILE="$( mktemp -t $SELF.XXXXXX )" +trap "rm -f \"$TMPFILE\"" EXIT + +$CMD > "$TMPFILE" +${VISUAL:-${EDITOR:-vi}} "$TMPFILE" + +# remove the newline(s) from the end of the file +perl -i -0777 -pe 's/\n*$//' "$TMPFILE" + +[ -s "$TMPFILE" ] && xsel -i < "$TMPFILE" diff --git a/wide.pl b/wide.pl new file mode 100755 index 0000000..dc93be7 --- /dev/null +++ b/wide.pl @@ -0,0 +1,112 @@ +#!/usr/bin/perl + +=pod + +=head1 NAME + +wide.pl - print double-width characters + +=head1 SYNOPSIS + +=head2 From the shell: + +wide.pl <[args ...]> + +=head2 From within irssi: + +/script load wide.pl + +/wide [args] + +=head1 DESCRIPTION + +wide.pl converts printable ASCII characters to their double-width +equivalent from the Unicode 0xff block. See: + +https://en.wikipedia.org/wiki/Halfwidth_and_Fullwidth_Forms_(Unicode_block) + +Characters that don't have double-wide equivalents are simply printed +with a trailing space. + +This script can be run standalone or as an irssi /script. For things to work +properly in irssi, you'll need UTF-8 and Unicode support in irssi and in the +terminal you're using to run irssi. + +When run standalone with no arguments, reads from stdin and writes to stdout. +If arguments are given, they're treated as input (not filenames). Use shell +redirection to read from a file: wide.pl < message.txt + +=head1 AUTHOR + +Urchlay + +=head1 LICENSE + +wide.pl is released under the WTFPL: Do WTF you want with this. + +=cut + +use warnings; +use strict; + +sub wide { + my $text = shift; + my $res = ""; + + for (split "", $text) { + my $c = ord($_); + if($c >= 0x21 && $c <= 0x7e) { + $res .= chr($c + 0xfee0); + } else { + $res .= "$_$_"; + } + } + + return $res; +} + +# main() if we're not running under irssi +if(__PACKAGE__ eq 'main') { + no warnings 'utf8'; + + exec "perldoc $0" if @ARGV && $ARGV[0] =~ /--?h(elp)?/; + + if(@ARGV) { + print wide($_) for @ARGV; + print "\n"; + } else { + while(<>) { + chomp; + print wide($_); + print "\n"; + } + } + + exit 0; +} + +# irssi stuff here +require Irssi; +Irssi->import(qw/command command_bind/); + +our $VERSION = "0.1"; +our %IRSSI = ( + authors => 'Urchlay', + contact => 'Urchlay on FreeNode', + name => 'wide', + description => 'print double-width characters', + license => 'WTFPL', + url => 'none', + ); + +sub cmd_wide { + my ($text, $srv, $chan) = @_; + + return unless $text; + return unless $srv; + return unless $chan; + + $chan->command('MSG ' . $chan->{name} . ' ' . wide($text)); +} + +command_bind("wide", \&cmd_wide); diff --git a/x1 b/x1 new file mode 100755 index 0000000..e3f3dca --- /dev/null +++ b/x1 @@ -0,0 +1,13 @@ +#!/bin/sh + +WM="${1:-/etc/X11/xinit/xinitrc.fvwm2}" +case "$1" in + "") ;; + /*) ;; + *) WM=/etc/X11/xinit/xinitrc.$1 ;; +esac + +[ ! -x "$WM" ] && WM="$( which $1 )" + +echo startx $WM -- :1 +exec startx $WM -- :1 diff --git a/xcleanpaste b/xcleanpaste new file mode 100755 index 0000000..c122002 --- /dev/null +++ b/xcleanpaste @@ -0,0 +1,153 @@ +#!/usr/bin/perl -w + +=pod + +=head1 NAME + +xcleanpaste - join multi-line copy/paste into one long line + +=head1 SYNOPSIS + +B [-n] [-u] [-e] [-v] [xsel-options] + +=head1 DESCRIPTION + +"Cleans" the X selection buffer: trims whitespace from the start +and end of every line, replaces all newlines with spaces, replaces +all tabs with 3 spaces each. Result is written back to the selection +buffer, where you can paste it into whatever application you want. + +This is useful even for single-line pastes: it removes tabs and any +newline at the end, so e.g. copying a command from a browser into the +shell won't trigger tab-completion or execute the command immediately. + +The selection buffer is read/written using xsel, which must be +installed and available on your PATH. + +xcleanpaste is best used by binding to a key using xbindkeys or +similar, though you can run it from the shell too. + +If you're using keybinding, you probably want at least separate keys +for xcleanpaste with no options and xcleanpaste with the -u option +(URL cleaner; see below). + +=head1 OPTIONS + +=over 4 + +=item B<-e> + +Replace line endings with the given string rather than a space. Don't +use a space between the -e and the ending. Beware of shell quoting +rules. + +=item B<-n> + +Replace line endings with the string " \n " rather than a space. This is +space, backslash, lowercase n, space. Equivalent to B<-e ' \n '>. + +=item B<-u> + +Remove CGI arguments from any URLs found in the buffer. Some sites +including tracking info, e.g. https://site.blah/stuff?sessionID=12345, +which you shouldn't be pasting into anything others can see (e.g. IRC +or emails). + +=item B<-v> + +Verbose mode. Shows lines read and written from the xsel instances on +stderr. Not much use with xbindkeys though. + +=back + +Any other arguments are passed to xsel. This is probably only useful +for xsel's -p/-s/-b options (see xsel man page). + +=head1 EXAMPLE + +In B<~/.xbindkeys>: + + "xcleanpaste &" + Control+Alt + period + + "xcleanpaste -u &" + Control+Alt + slash + +If you copy these three lines: + + This is + a long URL: + https://long.url?with=lots&of=arguments + +Then press Ctrl+Alt+Period, then paste into some window, you will get: + + This is a long URL: https://long.url?with=lots&of=arguments + +If you instead press Ctrl+Alt+Slash, you'll get: + + This is a long URL: https://long.url + +=head1 AUTHOR + +xcleanpaste was written by B. Watson and released +under the WTFPL: Do WTF you want with this. + +=cut + +( $SELF = $0 ) =~ s,.*/,,; + +@xselargs = (); +$line_ends = " "; +$url_clean = $verbose = 0; + +for(@ARGV) { + if(/^-?-h(?:elp)/) { + exec "perldoc $0"; + exit 1; # if the exec failed + } elsif(/^-v/) { + $verbose++; + } elsif(/^-n/) { + $line_ends = " \\n "; + } elsif(/^-u/) { + $url_clean = 1; + } elsif(/^-e(.*)$/) { + if(!defined($1) || $1 eq "") { + die("$SELF: no space allowed between -e option and its argument\n"); + } + $line_ends = $1; + } else { + push @xselargs, $_; + } +} + +$xsel_extra_args = join(" ", @xselargs); +warn "$SELF: xsel arguments: \"$xsel_extra_args\"\n" if $verbose; + +# We have to read the entire output of xsel -o into memory before +# spawning the xsel -i, because otherwise the 2nd xsel will obliterate +# the selection buffer the first one's still trying to read from. +open my $in, "xsel -o $xsel_extra_args|" or die $!; +while(<$in>) { + chomp; + warn "$SELF: read line $.: $_\n" if $verbose; + s,\s+$,,; # remove any trailing whitespace + s,^\s+,,; # remove any leading whitespace + s,[\r\n], ,g; # replace all CR or LF with a single space + s,\t, ,g; # replace all tabs with 3 spaces + if($url_clean) { + # get rid of ? and anything after it, in anything that looks like a URL + s,(https?:\/\/[^?\s]*)\?\S+,$1,g; + } + s/\S$/$&$line_ends/; # our ending LF became a space above; make it + # whatever the line ending is supposed to be + push @lines, $_; +} +close $in; + +$output = join("", @lines); +$output =~ s/\s+$//; # trim trailing whitespace from last line only +warn "$SELF: writing: $output\n" if $verbose; + +open my $out, "|xsel -i $xsel_extra_args" or die $!; +print $out $output; +close $out; -- cgit v1.2.3