ambevar-dotfiles/.shell.d/funs_rc

891 lines
22 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

## -*- mode:sh -*- #
################################################################################
## Shell -- Functions.
## Date 2012-12-05
################################################################################
## Colored man pager.
man()
{
env \
LESS_TERMCAP_mb=$(printf "\e[1;31m") \
LESS_TERMCAP_md=$(printf "\e[1;31m") \
LESS_TERMCAP_me=$(printf "\e[0m") \
LESS_TERMCAP_se=$(printf "\e[0m") \
LESS_TERMCAP_so=$(printf "\e[1;44;33m") \
LESS_TERMCAP_ue=$(printf "\e[0m") \
LESS_TERMCAP_us=$(printf "\e[1;32m") \
man "$@"
}
## Make directories and change into the first one.
mkcd () {
mkdir -p "$@"
cd "$1"
}
## Quick search.
search()
{
find . -iname "*$1*"
}
## Cut last n lines in file, 10 by default.
cuttail()
{
local nlines=${2:-10}
sed -n -e ":begin ; 1,${nlines}!{P;N;D} ; N ; b begin" $1
}
## Cut first n lines in file, 10 by default.
cuthead()
{
local nlines=${2:-10}
sed -n -e "1,${nlines}!p" $1
}
## Move filenames to lowercase.
## Use ranger + bulkrename + vim/emacs (+ TwindleCase) for more flexibility.
renamelower()
{
local file
local filename
local dirname
for file ; do
filename=${file##*/}
case "$filename" in
*/*) dirname="${file%/*}" ;;
*) dirname="." ;;
esac
local nf=$(echo $filename | tr A-Z a-z)
local newname="${dirname}/${nf}"
if [ "$nf" != "$filename" ]; then
mv "$file" "$newname"
echo "lowercase: $file --> $newname"
else
echo "lowercase: $file not changed."
fi
done
}
## Swap 2 filenames around.
renameswap()
{
local TEMPFILE="$(mktemp)"
mv "$1" "$TEMPFILE"
mv "$2" "$1"
mv "$TEMPFILE" "$2"
}
## Finds directory sizes and lists them for the current directory.
dirsize ()
{
local TEMPFILE="$(mktemp)"
# du -shx * 2> /dev/null | \
du -shx * .[a-zA-Z0-9_]* 2> /dev/null | \
egrep '^ *[0-9.]*[MG]' | sort -n > "${TEMPFILE}"
egrep '^ *[0-9.]*M' "${TEMPFILE}"
egrep '^ *[0-9.]*G' "${TEMPFILE}"
rm -rf "${TEMPFILE}"
}
## Network operations
if [ -n "$(command -v nmap)" ]; then
network-map()
{
echo "$1"
for SCANIP in $( nmap -sL "$1" | grep -i "\([[:digit:]]\+\.\)\{3,\}[[:digit:]]\+" | awk '{print $5}' ); do
sudo nmap -oX - -n -sT -T Normal -O -sR -I -F -P0 "$SCANIP"
echo
done
}
fi
netspeed ()
{
local INTERFACE="eth0"
if [ -n "$1" ]; then
INTERFACE="$1"
fi
if [ ! -d "/sys/class/net/${INTERFACE}" ]; then
echo "Error: no such interface (${INTERFACE})"
return
fi
local RX_BEFORE=$(cat /sys/class/net/${INTERFACE}/statistics/rx_bytes)
local TX_BEFORE=$(cat /sys/class/net/${INTERFACE}/statistics/tx_bytes)
sleep 1
local RX_AFTER=$(cat /sys/class/net/${INTERFACE}/statistics/rx_bytes)
local TX_AFTER=$(cat /sys/class/net/${INTERFACE}/statistics/tx_bytes)
local RX_RESULT=$(((${RX_AFTER:-0}-${RX_BEFORE:-0})/1024))
local TX_RESULT=$(((${TX_AFTER:-0}-${TX_BEFORE:-0})/1024))
echo "RX $RX_RESULT KiB/s"
echo "TX $TX_RESULT KiB/s"
}
## CPU usage
##
## A typical CPU array is (on Linux Kernel 3.0)
## cpu 158150 0 52354 18562746 1472 0 10198 0 0 0
##
## The meanings of the columns are as follows, from left to right:
##
## user: normal processes executing in user mode
## nice: niced processes executing in user mode
## system: processes executing in kernel mode
## idle: twiddling thumbs
## iowait: waiting for I/O to complete
## irq: servicing interrupts
## softirq: servicing softirqs
## ... (see 'man 5 proc' for further details)
##
## Only the first 4 values are interesting here.
cpuusage()
{
local cpuarray
local f1
local f2
local f3
local f4
cpuarray="$(grep 'cpu ' /proc/stat)"
f1=$(echo $cpuarray | cut -f3 -d' ')
f2=$(echo $cpuarray | cut -f4 -d' ')
f3=$(echo $cpuarray | cut -f5 -d' ')
f4=$(echo $cpuarray | cut -f6 -d' ')
local totalA=$(($f1+$f2+$f3+$f4))
local idleA=$f4
sleep 0.4
cpuarray="$(grep 'cpu ' /proc/stat)"
f1=$(echo $cpuarray | cut -f3 -d' ')
f2=$(echo $cpuarray | cut -f4 -d' ')
f3=$(echo $cpuarray | cut -f5 -d' ')
f4=$(echo $cpuarray | cut -f6 -d' ')
local totalB=$(($f1+$f2+$f3+$f4))
local idleB=$f4
local totaldiff=$((${totalB:-0}-${totalA:-0}))
if [ $totaldiff -eq 0 ]; then
echo 0
else
echo "$((100 - 100 * ($idleB-$idleA) / $totaldiff ))"
fi
}
## Wget batch DL
wget_batch ()
{
if [ $# -ne 2 ]; then
echo "Usage: $0 <ext> <uri>"
return
fi
wget -r -l1 --no-parent -A$1 $2
}
## Webcam
webcam ()
{
## With mplayer.
mplayer -fps 30 -tv driver=v4l2:width=640:height=480:device=/dev/video0 tv:// -flip
}
## Vim-only: search the vim reference manual for a keyword.
## Usage: :h <keyword>
if [ -n "$(command -v vim)" ]; then
:h()
{
vim --cmd ":silent help $@" --cmd "only";
}
fi
## Set file/directory owner and permissions.
## Usage: sanitize [FOLDER]
sanitize()
{
local WORKDIR="$PWD"
if [ $# -eq 1 ]; then
WORKDIR="$1"
fi
local FMASK=$(umask -S | sed 's/x//g')
local DMASK=$(umask -S)
find "$WORKDIR" -exec chown -R ${UID}:${GID} {} \;
find "$WORKDIR" -type d -exec chmod ${DMASK} {} \;
find "$WORKDIR" -type f -exec chmod ${FMASK} {} \;
}
asciify()
{
asciify_help()
{
echo
echo "Usage:"
echo -e "\t$1 FILES"
echo
echo "Synopsis:"
echo -e "\tConvert non-ASCII characters to their ASCII equivalent."
echo
}
if [ $# -eq 0 ]; then
echo "Missing arguments."
asciify_help $0
return
fi
for i; do
sed -i \
-e 's/[áàâä]/a/g' \
-e 's/[éèêë]/e/g' \
-e 's/[íìîï]/i/g' \
-e 's/[óòôö]/o/g' \
-e 's/[úùûü]/u/g' \
-e 's/[ýỳŷÿ]/y/g' \
-e 's/[ÁÀÂÄ]/A/g' \
-e 's/[ÉÈÊË]/E/g' \
-e 's/[ÍÌÎÏ]/I/g' \
-e 's/[ÓÒÔÖ]/O/g' \
-e 's/[ÚÙÛÜ]/U/g' \
-e 's/[ÝỲŶŸ]/Y/g' \
-e 's/[ñ]/n/g' \
-e 's/[œ]/oe/g' \
-e 's/[Œ]/Oe/g' \
-e 's/[æ]/ae/g' \
-e 's/[Æ]/Ae/g' \
-e 's/[ç]/c/g' \
-e 's/[Ç]/C/g' \
-e 's/[ß]/ss/g' \
-e 's/[«»„“”‚‘’]/"/g' \
-e 's/[©]/(C)/g' \
-e 's/[®]/(R)/g' \
-e 's/[™]/(TM)/g' \
-e 's/[¥]/Y/g' \
-e 's/[Ð]/D/g' \
-e 's/[ŀ]/l/g' \
-e 's/[Ŀ]/L/g' \
-e 's/[€]/euro/g' \
-e 's/[¢]/cent/g' \
-e 's/[£]/pound/g' \
-e 's/[µ]/mu/g' \
-e 's/[²]/^2/g' \
-e 's/[³]/^3/g' \
-e 's/[¡]/!/g' \
-e 's/[¿]/?/g' \
-e 's/[]/-/g' \
-e 's/[…]/.../g' \
-e 's/[≤]/<=/g' \
-e 's/[≥]/>=/g' \
-e 's/[±]/+\/-/g' \
-e 's/[≠]/!=/g' \
-e 's/[⋅]/./g' \
-e 's/[×]/x/g' \
-e 's/[÷]/\//g' \
-e 's/[↓]/|/g' \
-e 's/[↑]/^/g' \
-e 's/[←]/<=/g' \
-e 's/[→]/=>/g' \
"$i"
done;
}
blind-append()
{
blind_help()
{
echo
echo "Usage:"
echo -e "\t$1 FILE [STRING]"
echo
echo "Synopsis:"
echo -e "\tAppend to all STRING found in FILE a secret phrase being prompted."
echo -e "\tIf STRING is omitted, secret phrase will be appended to the end of the file."
echo -e "\tIf FILE does not exist, it will be created and secret phrase will be inserted. STRING will be ignored."
echo
}
if [ $# -gt 2 ] || [ $# -lt 1 ]; then
echo "Wrong number of arguments."
blind_help $0
return
fi
local FILE="$1"
local STRING=""
local DUMMY
if [ $# -eq 2 ]; then
STRING="$2"
fi
echo -n "Secret: "
read -s DUMMY
echo ""
if [ ! -e "$FILE" ] || [ -z "$STRING" ]; then
echo "$DUMMY" >> "$FILE"
echo "Secret appended to ${FILE} at the end."
return
fi
if [ $# -eq 1 ]; then
echo "$DUMMY" >> "$FILE"
else
sed -i "s/${STRING}/${STRING}${DUMMY}/g" "${FILE}"
fi
echo "Secret appended to ${FILE}."
return
}
## Term properties
termcolors256()
{
x=$(tput op)
y=$(printf %76s)
for i in {0..256}; do
o=00$i
echo -e "${o:${#o}-3:3} $(tput setaf $i;tput setab $i)${y// /=}$x"
done
}
termcolors()
{
# The test text. Must be 3 letters.
T='Doh'
echo -e "\n 40m 41m 42m 43m\
44m 45m 46m 47m";
for FGs in ' m' ' 1m' ' 30m' '1;30m' ' 31m' '1;31m' ' 32m' \
'1;32m' ' 33m' '1;33m' ' 34m' '1;34m' ' 35m' '1;35m' \
' 36m' '1;36m' ' 37m' '1;37m';
do FG=${FGs// /}
echo -en " $FGs \033[$FG $T "
for BG in 40m 41m 42m 43m 44m 45m 46m 47m;
do echo -en "$EINS \033[$FG\033[$BG $T \033[0m";
done
echo;
done
echo
}
termprop()
{
infocmp -1 | sed -nu 's/^[ \000\t]*//;s/[ \000\t]*$//;/[^ \t\000]\{1,\}/!d;/acsc/d;s/=.*,//p'| column -c80
}
termsupport()
{
for T in `find "/usr/share/terminfo" -type f -printf '%f\n'`;do
echo "$T `tput -T $T colors`"
done | sort -nk2
}
## Highlight themes viewer for 256-colors terminals.
if [ -n "$(command -v highlight)" ] ; then
hlt-viewer ()
{
print_help()
{
echo "Synopsis:"
echo -e " $1"
echo
echo "This script displays a preview for every highlight's theme."
echo "Press ENTER to display next preview. Press anything else then ENTER to quit."
}
if [ $# -gt 0 ]; then
print_help "$0"
return
fi
local LIST=$(highlight -w | grep -v "\s\|^$")
local SAMPLE="void function(char* pointer, int &ref)
{
int integer=3;
char* string=\"Hello!\";
// Line comment
for ( i=0; i<10; i++)
{
printf(\"Sum: %d\\\n\", i*( integer+14 ) );
}
}"
unset DUMMY
for i in $(highlight -w | grep -v "\s\|^$"); do
echo "******************** $i ********************"
highlight -S c -O xterm256 <(echo $SAMPLE) -s "$i"
read -s DUMMY
if [ -n "$DUMMY" ]; then
return
fi
done
}
fi
## Extractor -- Useless when using 'atool'.
if [ ! -n "$(command -v atool)" ]; then
extract ()
{
if [ -f $1 ] ; then
case $1 in
*.tar.bz2) tar xvjf $1 ;;
*.tar.gz) tar xvzf $1 ;;
*.tar.xz) tar xvJf $1 ;;
*.bz2) bunzip2 $1 ;;
*.rar) unrar x $1 ;;
*.gz) gunzip $1 ;;
*.tar) tar xvf $1 ;;
*.tbz2) tar xvjf $1 ;;
*.tgz) tar xvzf $1 ;;
*.zip) unzip $1 ;;
*.Z) uncompress $1 ;;
*.7z) 7z x $1 ;;
*.xz) unxz $1 ;;
*.exe) cabextract $1 ;;
*) echo "\`$1': unrecognized file compression" ;;
esac
else
echo "\`$1' is not a valid file"
fi
}
fi
## WARNING: use this function with caution. It may drastically improve
## compression of some PDF files, but in some case, the output filesize will be
## greater! You should not use it over PDF files embedding pictures as well.
pdfcompress ()
{
if [ $# -lt 1 -o $# -gt 2 ]; then
echo "Usage: pdfcompress PDFFILE [DESTFILE]"
return
fi
if [ ! -f "$1" ]; then
echo "$1 is not a valid PDF file!"
fi
local INPUTFILE="$1"
if [ -z "$2" ]; then
gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile="${INPUTFILE%%.*}-COMPRESSED.pdf" "${INPUTFILE}"
rm -rf "${INPUTFILE}"
mv "${INPUTFILE%%.*}-COMPRESSED.pdf" "${INPUTFILE}"
else
local OUTPUTFILE="$2"
gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile="${OUTPUTFILE}" "${INPUTFILE}"
fi
}
## Extract a range of pages from a PDF.
pdfextract ()
{
if [ $# -ne 4 ]; then
echo "Usage: $0 PDFFILE FIRSTPAGE LASTPAGE DESTFILE"
return
fi
if [ ! -f "$1" ]; then
echo "$1 is not a valid PDF file!"
fi
gs -sDEVICE=pdfwrite -dNOPAUSE -dSAFER -dSAFER -dFirstPage=$2 -dBATCH -dLastPage=$3 -sOutputFile=$4 $1
}
## Resize input PDF to an A4 output PDF.
pdfresize ()
{
if [ $# -ne 2 ]; then
echo "Usage: $0 <input> <output>"
return
fi
gs -q -o $2 -sDEVICE=pdfwrite -sPAPERSIZE=a4 -dFIXEDMEDIA -dPDFFitPage -dCompatibilityLevel=1.4 $1
}
## Create an archive from a single or multiples files/folders.
archive ()
{
printhelp()
{
echo "Synopsis:"
echo -e " $1 [-m METHOD] [-v] FILES|FOLDERS"
echo
echo "Usage:"
echo -e " default:\tCreate an archive of specified FILES and/or FOLDERS."
echo -e " -h:\t\tDisplay this help."
echo -e " -m:\t\tChoose compression method."
echo -e " gz\t\tgzip (default)."
echo -e " xz\t\tLZMA."
echo -e " -v:\t\tExclude VCS data. (GNU tar only)."
}
local OPTION_VCS=""
local OPTION_METHOD=""
while getopts ":hm:v" opt; do
case $opt in
h)
printhelp "$0"
return 1
;;
m)
OPTION_METHOD="${OPTARG}"
;;
v)
OPTION_VCS="--exclude-vcs"
;;
?)
printhelp "$0"
return 1
;;
:)
echo "Missing argument."
echo "Use $0 -h for help."
return 1
;;
esac
done
local ARCEXT
local ARCOPT
case $OPTION_METHOD in
"gz")
ARCEXT="tar.gz"
ARCOPT="z"
;;
"xz")
ARCEXT="tar.xz"
ARCOPT="J"
;;
*)
ARCEXT="tar.gz"
ARCOPT="z"
;;
esac
shift $(($OPTIND - 1))
local ARCPATH
local ARCSOURCE
local ARCNAME
if [ $# -eq 1 ]; then
ARCPATH="$(dirname $(readlink -f "$1"))"
ARCSOURCE="$(basename $(readlink -f "$1"))"
ARCNAME="${ARCSOURCE}-$(date +%y-%m-%d-%H%M%S).${ARCEXT}"
(cd "$ARCPATH" && \
tar -${ARCOPT} -cf "$ARCNAME" "$ARCSOURCE" ${OPTION_VCS})
else
ARCSOURCE="$(basename $PWD)"
ARCNAME="$(basename "$ARCSOURCE")-$(date +%y-%m-%d-%H%M%S).${ARCEXT}"
if [ $# = 0 ];then
(cd "$PWD/.." && \
tar -${ARCOPT} -cf "$ARCNAME" "$ARCSOURCE" ${OPTION_VCS})
else
## Note for zsh: do NOT initialize an array with "myarray=()".
local FILELIST
for i; do
FILELIST=(${FILELIST[*]} "$i")
done
tar -${ARCOPT} -cf "$ARCNAME" ${FILELIST[*]} ${OPTION_VCS}
fi
fi
}
## Git compare
git-compare()
{
if [ $# -ne 1 ]; then
echo "Wrong number of argument."
return
fi
comm -3 <(git ls-files | sort) <(find "$1" -type f | sed 's/^[^\/]*\///g' | sort)
}
## This function will clean TeX/LaTeX project folders recursively.
texclean ()
{
if [ -z "$1" ]; then
WORKDIR="$PWD"
else
WORKDIR="$1"
fi
## WARNING: removing .idx files is messy in a .git folder.
find "$WORKDIR" -type f \( \
-name "*.aux" -o \
-name "*.glg" -o \
-name "*.glo" -o \
-name "*.gls" -o \
-name "*.ilg" -o \
-name "*.ind" -o \
-name "*.lof" -o \
-name "*.log" -o \
-name "*.nav" -o \
-name "*.out" -o \
-name "*.snm" -o \
-name "*.tns" -o \
-name "*.toc" -o \
-name "*.xdy" \) \
-print \
-delete
}
## Clean current folder
vcsclean()
{
local WORKDIR
if [ -z "$1" ]; then
WORKDIR="$PWD"
else
WORKDIR="$1"
fi
local CHOICE
echo "This will clean current folder from all VCS control files."
echo -n "Proceed ? [y/N] "
while [ -z "$CHOICE" ];
do
read CHOICE
done
CHOICE=$(echo $CHOICE | tr '[:upper:]' '[:lower:]')
if [ "$CHOICE" = "y" ]; then
find "$WORKDIR" -type d \( \
-name ".bzr" -o \
-name ".cvs" -o \
-name ".git" -o \
-name ".hg" -o \
-name ".svn" \) \
-print \
-delete
echo "VCS files cleaned."
fi
}
## LSOF stats. Print number of open files per process.
lsofstat()
{
local LSOFOUT=$(lsof|awk '{print $1}')
for i in $(echo $LSOFOUT |sort -u);do
echo -n "$i "
echo $LSOFOUT | grep ^$i | wc -l
done
}
## Executable info
xinf()
{
if [ $# -ne 1 ]; then
echo "Give an executable in PATH as parameter."
return
fi
local xpath="$(type $1 | cut -d' ' -f3)"
ls -l "$xpath"
file "$xpath" | cut -d':' -f2 | cut -b 2-
}
## This function will try to find an input binary file in the content of binary
## files in current folder.
bindatasearch()
{
if [ $# -eq 0 ] || [ $# -gt 2 ] || [ ! -f "$1" ]; then
echo "Usage: $0 FILE [FOLDER]"
return
fi
## Must be a folder.
local TARGET=$PWD
if [ $# -eq 2 ] && [ -d "$2" ]; then
TARGET="$2"
fi
## The awk command suppresses first column, spaces and line breaks.
local SOURCE=$(od -tx8 "$1" | awk '($1="")1 gsub ( /\s/,"") { printf ("%s", $0) }')
## This special, not well-known syntax allows us to execute a set of
## functions upon the result of find. Since everything MUST be between
## simple quotes, we cannot use external variables directly. So we pass the
## $SOURCE variable as argument. The underscore at the end allows the use of
## arguments.
find "$TARGET" -type f -exec bash -c '
FILEDUMP=$(od -tx8 "$1" | awk '"'"'($1="")1 gsub ( /\s/,"") { printf ("%s", $0) }'"'"')
grep -q "$2" <(echo $FILEDUMP)
[ $? -eq 0 ] && echo "$1"
' _ {} "$SOURCE" \;
}
## Xrandr
xmulti ()
{
if [ $# -ne 1 ]; then
echo "Wrong number of argument."
return
fi
xrandr --output "$1" --auto --right-of $(xrandr | sed -n "/current/{n;p;q}" | cut -f1 -d" ")
}
xmultioff ()
{
if [ $# -ne 1 ]; then
echo "Wrong number of argument."
return
fi
xrandr --output "$1" --off
}
## Format C using 'indent'. Alternative to indent: astyle, uncrustify.
formatc()
{
if [ -n "$(command -v indent)" ]; then
echo "Please install 'indent'"
return
fi
local WORKDIR
if [ -z "$1" ]; then
WORKDIR="$PWD"
else
WORKDIR="$1"
fi
find "$WORKDIR" -type f \
-name "*.[ch]" \
-print \
-exec indent -i4 -ppi4 -bli0 -cli4 -nut {} \;
## Remove backup files.
find "$WORKDIR" -type f \( \
-name "*.[ch]~" -o \
-name "*.[ch]~[0-9]*~" \) \
-delete
# ## Manual method.
# ## Remove trailing whitespace
# sed -i 's/\s*$//g' "$FILE"
# ## Function parenthesis
# sed -i 's/\([^ ]\)(/\1 (/g' "$FILE"
# sed -i 's/\s\s\+(/ (/g' "$FILE"
# ## Semicolon
# sed -i 's/\([^ ]\);/\1 ;/g' "$FILE"
# sed -i 's/;\([^ ]\)/; \1/g' "$FILE"
# # Skip line -- Bad idea because of 'for' loops.
# # sed -i 's/^\(\s*\)\(.*\);\s*\(.\+\)$/\1\2;\n\1\3/g' "$FILE"
# ## Commas
# sed -i 's/\s\s\+,/,/g' "$FILE"
# sed -i 's/,\([^ ]\)/, \1/g' "$FILE"
# ## Plus/Minus
# sed -i 's/\([^+-]\)\([-+]\)\([^ +-]\)/\1\2 \3/g' "$FILE"
# sed -i 's/\([^ +-]\)\([-+]\)\([^+-]\)/\1 \2\3/g' "$FILE"
# sed -i 's/\( \+++\)/++/g' "$FILE"
# sed -i 's/\(++ \+\)/++/g' "$FILE"
# sed -i 's/\( \+--\)/--/g' "$FILE"
# sed -i 's/\(-- \+\)/--/g' "$FILE"
# ## Modulus, equality, affectation, binary ops, comparison
# sed -i 's/\s\s\+\(%\|==\|&&\|||\|<=\|>=\|!=\)/ \1/g' "$FILE"
# sed -i 's/\(%\|==\|&&\|||\|<=\|>=\|!=\)\s\s\+/\1 /g' "$FILE"
# sed -i 's/\([^ ]\)\(%\|==\|&&\|||\|<=\|>=\|!=\)/\1 \2/g' "$FILE"
# sed -i 's/\(%\|==\|&&\|||\|<=\|>=\|!=\)\([^ ]\)/\1 \2/g' "$FILE"
# ## Equality, >, <
# sed -i 's/\s\s\+\([<>=]\)/ \1/g' "$FILE"
# sed -i 's/\([<>=]\)\s\s\+/\1 /g' "$FILE"
# sed -i 's/\([<>=]\)\([^ =]\)/\1 \2/g' "$FILE"
# sed -i 's/\([^ ]\)\([<>]\)/\1 \2/g' "$FILE"
# sed -i 's/\([^ =<>]\)\(=\)/\1 \2/g' "$FILE"
# ## Asterisk, slash
# sed -i 's/\s\s\+\*/ \*/g' "$FILE"
# sed -i 's/\*\s\s\+/\* /g' "$FILE"
# sed -i 's/\([^\/]\)\/\s\+/\1\//g' "$FILE"
# sed -i 's/\s\+\/\([^\/]\)/\/\1/g' "$FILE"
# ## Braces
# sed -i 's/^\( *\)\(.\+\) *{ *$/\1\2\n\1{/g' "$FILE"
# ## Proper comments
# sed -i 's:// *\([[:lower:]]\):// \u\1:g' "$FILE"
# sed -i 's:\(//.*[^\.]\)$:\1\.:g' "$FILE"
}
##==============================================================================
## Pacman functions
##==============================================================================
[ -n "$(command -v pacman)" ] && . "${SHELL_DIR}/funs_pacman"
##==============================================================================
## FreeBSD functions
##==============================================================================
[ "$(uname)" = FreeBSD ] && . "${SHELL_DIR}/funs_freebsd"
##==============================================================================
## TeXlive functions
##==============================================================================
## TeXlive
if [ -d "/usr/local/texlive" ]; then
## WARNING: it is important to set umask properly, otherwise users might
## not have authorization to use the packages.
## This is bad pratice to write args without double quotes, but since we
## are sure there is no space in TeX Live packages, it is OK here.
tli ()
{
sudo sh -c 'umask 022 && tlmgr install $0 $@' "$@"
}
tlr ()
{
sudo sh -c 'umask 022 && tlmgr remove $0 $@' "$@"
}
fi
##==============================================================================
## Transcoding functions
##==============================================================================
[ -n "$(command -v ffmpeg)" ] && . "${SHELL_DIR}/funs_transcode"