#!/bin/bash
#
# ANGELSCRiPTS
#
# created: Dharamsala 2007
# thierry.blanc@gmx.ch
#
# version 0.2.3-2
#
# join in and create some angels!!
#
# files required:
# angels.conf
# folders required:
# angels (with angels inside)s
conffile=/etc/angels.conf
if [[ ! -f "$conffile" ]] ; then
echo -e "$conffile not found \n exit"
exit
fi
. "$conffile"
# exec 6>&2
# exec 2>>$ERRORLOG
#### create files/folders, if missing
#create tmp folder for command scripts
mkdir -p $ANGELDOTFOLDER
mkdir -p $CMDDIR
mkdir -p $ANSWERDIR
mkdir -p $VARIABLED
mkdir -p $VARDLOCAL
mkdir -p $TMP
# check for logfile
[[ ! -s "$LOGFILE" ]] && touch "$LOGFILE"
# create the directory for downloaded angels
if [[ ! -d "$WGETANGELS" ]]; then
mkdir -p "$WGETANGELS"
echo 'ENCODING="ISO-8859-1"
TITLE="directory for downloaded angels"' > "$WGETANGELS"/.directory.ngl
fi
# flags
FLAGS=$ANGELDOTFOLDER/flags
if [[ ! -s "$FLAGS" ]] ; then
cat <<EOF >"$FLAGS"
fBRACKETS=1 # show {{ braces
fINCLUDE_FILES=1 # show file or $file:...
fDEFVALUE=1 # show variable or value
fDUMMY=-1 # show dummy or commands
fVARHEIGHLIGHT=-1 # heighlight variable (value only)
EOF
fi
ORIGPATH="$PWD"
# name of file or link that called the script, i.e. angel, a number or (b,r,u)
SCRIPTNAME=${0##*/}
# prepare header file to give LASTxx variables
# LASTTYPE, LASTTITLE, LASTGROUP, ...
# LASTFILE becomes LASTANGEL!!!
sed '/^[^#]/s|^ *|LAST|;s|LASTFILE=|LASTANGEL=|' $SHEAD > $SHEAD.old 2>/dev/null
. $SHEAD.old
# set lastgroup, if not set
[[ -z "$LASTGROUP" ]] && LASTGROUP=$(echo "${LASTANGEL#$ANGELPATH}"| sed 's|/||')
# empty variable.d directory here, before precommands are executed!
[[ ! -z "$VARDLOCAL" ]] && rm "$VARDLOCAL"/* &>/dev/null
# read flags value
. $FLAGS
#### FUNCTIONS
function create_oneletter_commands ()
{ # create single-letter commands
[[ ! -z "$LINKS" ]] && rm -f "$LINKS"/* &>/dev/null
pushd "$LINKS" >/dev/null
target=$(which angel)
for i in `seq 1 16` r b f p n q u z d x h e
do ln -s "$target" "$i" 2>/dev/null
done
popd &>/dev/null
}
function E_noangel ()
{ # check for angel file
if [[ ! -e "$1" ]] ;then
echo "angel "$ACTIVEANGEL" does not exist!"
exit 128
fi
}
# check for errors in angel file
function futsch ()
{
echo "syntax error in file $1"
exit 127
}
function check_syntax ()
{
# $1 ngl-file
B='#PRECOMMANDS
#VARIABLES
#MAIN'
# check for TITLE TYPE in header
A=$(sed '0,/#PRECOMMANDS/!d' $1)
for i in "TYPE=" "TITLE="
do
if ! echo "$A"|grep -q "$i" ;then
futsch "$1 no $i"
fi
done
#check for presence and right order
A=$(sed -nr '
/(^#PRECOMMANDS).*/s||\1|p
/(^#VARIABLES).*/s||\1|p
/(^#MAIN).*/s||\1|p
' $1)
[[ ! "$A" == "$B" ]] && futsch "$1"
}
#
function create_links ()
{
# $1 amount of links
for ((i=1;i<=$1;i++))
do which $i &>2 || ln -s `which angel` "$LINKS/$i" 2>/dev/null
done
}
# get functions
function get_angel ()
{ # get line no $1 from $SMAIN
# $1 is position
[[ -z "$1" ]] && return 127
EXTRACT=$(sed $1'!d' $SMAIN )
}
function add_line ()
{ # adds a line to a file at the top
# $2 is target file to set the type=
# $ section (future)
local line="$1"
sed -i '1s|$|\n'"$line"'|' "$2"
}
function set_vars ()
{ # set standard variables according to input string
# set FILE TYPE TITLE UUID TAGS with line from $ANGEL or .index file
# $1 is input string : FILE::TYPE::TITLE::UUID::TAGS
# $2 is a list of variable names, if omitted standard is used
local u="$1"
local vars="${2:-FILE TYPE TITLE UUID TAGS}"
for i in $vars
do
eval $i=\""${u//::*}"\"
u="${u#*::}"
done
}
function get_reference ()
{
# $1 is reference UUID
# EXTRACT is : FILE::TYPE::TITLE::UUID::TAGS
local F
F=$(grep "::$1::" $(find "$ANGELPATH" -name ".index.txt" -printf "%p\n")| sed 's|/.index.txt:|/|')
EXTRACT="${F:-n/a}"
}
#### b, f, u procedures
function go_up ()
{ # move up one directory
ACTIVEANGEL=$(dirname "$LASTANGEL" 2>/dev/null)
TYPE=directory
# stop at ANGELPATH;
[[ "${#ACTIVEANGEL}" -lt "${#ANGELPATH}" ]] && ACTIVEANGEL="$ANGELPATH"
}
function one_down ()
{ # move the @-sign one line *down* in $1
# $1 = target file
# if no @ sign then set it to 1st line
if ! grep -q "^@" "$1" ;then
SED='1s|^|@|'
else
SED=' $q;
/^@/{s///
N;
s/\n/\n@/
}'
fi
sed -i "$SED" "$1"
}
function one_up ()
{ # move the @-sign one line *up* in $1
# $1 = target file
# if no @ sign set, set it to last line
if ! grep -q "^@" "$1" ;then
SED='$s|^|@|'
else
SED='$!N
/\n@/{
s/@//
s/^/@/
}
P
D'
fi
sed -i "$SED" "$1"
}
function update_logfile ()
{ # append latest used angel to logfile
echo "$ACTIVEANGEL"::"$TYPE"::"$TITLE" >> $LOGFILE
# clear @-signs, uniq, set the "last command" sign to last command
sed 's/^@//' "$LOGFILE"| uniq|sed '$s/^/@/' >"$LOGFILE.tmp"
cp "$LOGFILE.tmp" "$LOGFILE"
}
function move_one ()
{ # move to the next or previous entry (ONE entry)
# $1 = target file
# down/up in list (file) or end for last line of file (reset)
local direction=$2
case $direction in
down) one_down "$1"
;;
up) one_up "$1"
;;
end) sed -i 's|^@||;$s|^|@|' "$1"
return
;;
esac
# set ACTIVEANGEL, TITLE and TYPE
EXTRACT=$(sed -n '/^@/{s|||;p} ' "$1")
[[ -z "$EXTRACT" ]] && exit 127
set_vars "$EXTRACT"
ACTIVEANGEL="$FILE"
LOGFILEUPDATE=no # do not update the logfile
}
function renew_screen ()
{
# renew screen
ACTIVEANGEL="${LASTANGEL%.ngl}"
TYPE="$LASTTYPE"
}
function wget_angel ()
{
pushd $WGETANGELS 2>/dev/null
wget -O my.tar.gz "$1"
tar -xvvf my.tar.gz
create_index $PWD
popd 2>/dev/null
if [[ ! -d $ANGELPATH/imported ]]; then
ln -s "$WGETANGELS" "$ANGELPATH/imported"
create_index "$ANGELPATH"
fi
}
######## $ANGEL functions
function exec_header ()
{
# $1 = TYPE
. $SHEAD # execute #HEADER > set TYPE, TITLE...
# if there is no group, create one based on filename
if [[ -z "$GROUP" ]] ; then
local f="${ACTIVEANGEL#$ANGELPATH}"
GROUP="${f//\/}"
fi
# add VARS to file
add_line "FILE=$ACTIVEANGEL" $SHEAD
add_line "TYPE=$1" $SHEAD
add_line "GROUP=\"$GROUP\"" $SHEAD # if group exists, no effect
}
######## flag functions
function flag_onoff ()
{ # change the flag to opposite value
local VALUE=$1
local FLAGNAME=$2
(( VALUE *= -1 ))
sed -ri '/'$FLAGNAME'=/s/=.*/='$VALUE'/' $FLAGS
. $FLAGS
TYPE=show # recreate showfile but not $ANGEL
LOGFILEUPDATE=no
}
function flag_status ()
{ # display the value of a flag in human readable form
# $1 is value of flag # name of flag
if [[ "$1" -eq -1 ]]
then STATUS="off"
else
STATUS="on"
fi
}
######## insert functions
function insert_variable ()
{ # insert all variables stored in $VARIABLELIST in the place of the variable placeholder
# $1 = target file to insert variables
# $2 suppress style settings
local style="" styleoff=""
if [[ "$fVARHEIGHLIGHT" -eq 1 && ! "$2" == "style_off" ]]; then
style="$varcolor"
styleoff="$varcoloroff"
fi
OFS=$IFS; IFS=$'\n'
for i in $(cat "$VARIABLELIST")
do
var="${i%%:*}"
value="${i#*:}"
sed -i 's|{{'"$var"'}}|'"$style$value$styleoff"'|g' "$1"
done
IFS=$OFS
}
function include_references ()
{ # insert file: title where a {{@ref: occurs
# with data from the corresponding angel
local ref link=101 string
sed 's|{{|\n|g' "$1"|sed -rn 's/^@ref:([^}]*)}}.*/\1/p' |while read ref
do
get_reference "$ref"
set_vars "$EXTRACT" "rfile rtype rtitle ruuid rtags"
string="n/a$snormal"
case "$rtype" in
directory) string="$sCFOLDER${rfile##*/}: $sCTITLE$rtitle $snormal"
;;
file) string="$sCFILE${rfile##*/}: $sCTITLE$rtitle $snormal"
;;
esac
# insert into file
sed -i 's|{{@ref:'"$ref"'}}|'"$sCCMD$link$NUMSEP$string"'|g' "$1"
# set link and create command
[[ -z `which $link` ]] && ln -s `which angel` "$LINKS/$link"
echo "angel -r $ref" > "$CMDDIR/$link"
((link++))
done
}
function include_files ()
{ # include files into a file
# type is the indicator
# {{@file:...}}-statements
# {{@include ...
# replace all {{@file: with the corresponing files
local FILE="$1" # target file
local ttc="$2" # type (@file)
local line text in_file
sed 's|{{|\n|g' "$FILE"| sed -rn '/^'"$ttc"':/{s|||;s|([^}]*)}}.*|\1|p}' | while read line
do
if [[ "${line:0:1}" == / ]] ;then # prepend ANSERDIR
in_file="$line"
else
in_file="$ANSWERDIR/$line"
fi
text=$(cat "$in_file"|sed ':a;$!N;s|\n|\\n|g;$!ba')
sed -i 's|{{'"$ttc:${line//|/\|}"'}}|'"${text//|/\|}"'|g' "$FILE"
done
}
function set_numbers ()
{ # set identifiers in a-commands with x to number
# replaces x with number; skips if x is followed by any char; adapts to identifier
local COUNT=0
sed -n '/^@[cd]md:/{s|||;p}' $SMAIN | while read -r cmd
do
ID="${cmd%%:*}"
[[ $ID == x* && "${#ID}" -gt 1 ]] || ((COUNT++))
[[ $COUNT -le $ID ]] && COUNT=$ID
if [[ "${cmd:0:1}" == "x" ]]
then sed -ri '0,/^@[cd]md:x/s|:x|:'"$COUNT"'|' $SMAIN
fi
done
}
######## variable functions
function edit_angel ()
{
myfile="$1"
# directory or angel file
if [[ -z "$myfile" ]] ; then
if [[ $LASTTYPE == directory ]]
then myfile="$LASTANGEL/".directory.ngl
else
myfile="$LASTANGEL".ngl
fi
fi
# play around .... find out, if file has been changed
atime=$(ls -l "$myfile" --time-style=full|cut -d ' ' -f7)
sudo $EDITOR "$myfile"
if [[ $atime == `ls -l $myfile --time-style=full|cut -d ' ' -f7` ]]
then
echo "file left unchanged."
else
echo "file changed." ;fi
}
function create_variable_list ()
{ # extract the variables from various files and create variable.txt list
# $VARIABLELIST stores the FINAL values for a variable (one entry per variable)
# empty variable list
echo >"$VARIABLELIST"
# create list from main variable directory
# variable-file is identified by $GROUP
# last entry in file is used
# this file stores a choosen variable!
tac "$VARIABLED/$GROUP" > "$VARIABLELIST".tmp 2>/dev/null
# variables from variable-section, main place for static variables
sed '/^#/d;1d;$d' $SVAR 2>/dev/null >> "$VARIABLELIST".tmp
# create first list of variable from main section (on-the-fly variable)
sed 's|[^{]{[^{]||g;s|[^}]}[^}]||g' "$SMAIN" |sed -n '/{{.*}}/{s|^[^{]*{{||;s|}}[^{]*{{|\n|g;s|}}[^{]*$||;p}'| sed -r '/^@/d;;s/^:(.*)/\1:\1/'>> "$VARIABLELIST".tmp
# from variable.d directory for variables created in the precommand section
if pushd "$VARDLOCAL" &>/dev/null ;then
for i in *; do
sed 's|^|'"$i"':|' "$i" 2>/dev/null >> "$VARIABLELIST".tmp
done
popd &>/dev/null
fi
# first value is used in loop, latter variable entries are ignored
while read -r line
do
if ! grep -q "${line%%:*}" "$VARIABLELIST"
then echo "$line" >> "$VARIABLELIST"
fi
done<"$VARIABLELIST".tmp
sed -i '/^$/d;' "$VARIABLELIST"
}
function set_variables ()
{ # let user enter new values for a variable
local DEF newdef VALUE answer
local myvar_group="$VARIABLED/$LASTGROUP"
# lines containing variable
local LINES=$(sed '/{{[^@].*}}/!d;s|<[^>]*>||g;s|@cmdend||' "$SMAIN")
# show lines with variable
echo "==== LINES with VARIABLES to SET =============="
echo "$LINES"| sed 's/{{/'$sred'&/g;s/}}/&'$snormal'/g'
echo
echo "==== VARIABLES ================== VALUE ========"
# show list of variables
cat $VARIABLELIST | sed -r 's|:| :|;s|^(.{26}) *:|\1|'| cat -b -
echo -n " Choose a variable: "
read -u 1 answer
[[ ! "$answer" -gt 0 ]] && exit 127
# set $DEF to a variable according to choosen number
DEF=$(sed -rn $answer'p' "$VARIABLELIST"| cut -d: -f1 )
[[ -z "$DEF" ]] && exit 127
# get list of stored alternatives for the variable
VALUE=$(cat "$VARIABLELIST".tmp |sed -n '/^'"$DEF"':/{s///;p}'| sort| uniq | sed '/^[[:blank:]]*$/d' )
# show list of values for choosen variable
echo -e " Values for \"$DEF\":"
echo -e "$VALUE" |cat -b -| sed 's/^/ /'
echo -n " Choose a value or press [enter] for new: "
read answer
# promt for a new value or choose one from list
if [[ -z "$answer" ]]; then # just enter
echo -n " Enter a new value: "
read -u 1 newdef
elif [[ -z "${answer//[0-9]}" ]] ;then # variable stripped of numbers
newdef=$(echo "$VALUE" |sed -n "$answer"'p')
else
newdef="$answer"
fi
echo
# save variable
# create group-file if not existing
[[ ! -f "$myvar_group" ]] && touch "$myvar_group"
# delete entry if already there and append at the end
sed -i '/'"$DEF:${newdef////\/}"'/d' "$myvar_group"
# save new var
echo -e "$DEF:$newdef" >> "$myvar_group"
echo "changed \"$DEF\" to \"$newdef\""
# update variablelist file
sed -i '/^'"$DEF"'/d' "$VARIABLELIST"
echo -e "$DEF:$newdef" >> "$VARIABLELIST"
echo -e "$DEF:$newdef" >> "$VARIABLELIST".tmp
}
function extract_commands
{ #extract the statements according to positional parameteres
local tmp="$TMP"/angelcmd
local file
# copy angel for commands
cat $SMAIN > $tmp
# remove all old commands
[[ ! -z "$CMDDIR" ]] && rm $CMDDIR/* 2>/dev/null
# change all variables to values
insert_variable $tmp "style_off"
include_files "$tmp" "@file"
# extract all @cmd:xx-to-@cmdend statements and put them into $CMDDIR/xx as files
sed '/^@cmd/,/@cmdend$/!d;s|@cmdend$|\n|' $tmp|while read -r line
do
i="$(echo "$line" | sed -rn 's|^@cmd:([^:]*).*|\1|p')"
if [[ ! -z "$i" ]] ;then
file=$i # create link if needed
[[ -z `which $i` ]] && ln -s `which angel` "$LINKS/$file"
else
echo "$line" >> "$CMDDIR/$file"
fi
done
}
function execute_command ()
{ # execute a command
CMD=$1
CMDFILE="$CMDDIR/$1"
local RESTORE
# check is command exists
if [[ ! -f "$CMDFILE" ]]; then
echo "Sorry, command $CMD does not exist"
exit $E_NO_FILE
fi
# backup command file BEFORE replacing ask statements
cp "$CMDFILE" "$CMDFILE".before
# check for {{@?}}-statements (ask-statements)
while grep -q "{{@?:.*}}" "$CMDFILE"
do
echo -n "$(sed 's|[^{]{[^{]|NIL|' "$CMDFILE" |sed -nr '/\{\{/{s|^[^{]*\{\{@\?:([^}]*)\}\}.*|\1|p;q}' ) "
read -e ANSWER
sed -ri '0,/\{\{[^}]*\}\}/s||'"$ANSWER"'|' "$CMDFILE"
RESTORE=yes
done
# execute the command
# exec 2>&6 # redirect error to stdout not error.log
pushd "$ORIGPATH" &>/dev/null
echo "----- command -----"
cat "$CMDFILE"
echo "------ output -----"
. "$CMDFILE"
popd &>/dev/null
# exec 2>>$ERRORLOG
# restore command if needed
[[ $RESTORE == yes ]] && cp "$CMDFILE".before "$CMDFILE"
}
######## create functions
function create_newangel ()
{ # create a new angel in the current angel-dir
# $1 = filename for angel
local xfile xuuid lpath
xfile="$1"
xuuid=$(uuidgen)
[[ -z "$xfile" ]] && read -p "Enter a filename for new angel (default=newangel): " xfile
xfile="${xfile:-newangel}"; xfile="${xfile%.ngl}"
if [[ "$LASTTYPE" == directory ]];then
lpath="$LASTANGEL"/$xfile.ngl
else
lpath="$(dirname "$FILE")/$xfile.ngl";fi
sudo cat <<EOF > "$lpath"
ENCODING="ISO-8859-1"
TYPE="file"
TITLE="$xfile"
TAGS=""
UUID="$xuuid"
GROUP=""
#PRECOMMANDS
#VARIABLES
#MAIN
@cmd:x
@cmdend
EOF
create_index "$(dirname $lpath)"
}
### create index
function _create_index ()
{
# $1 = directory
# .directory.ngl contains informatinon about the directory
# .index.txt is the index for the directory
local directories files
# enter directory, return, if not possible
if ! pushd "$1" &>/dev/null ;then
return
fi
echo > $TMP/directories # empty file for directory enties
# find all *.ngl files and directories
# skips dot-files ;
# squeezes data into one line for further search!
# for directories
for FILE in $(find -L . -maxdepth 1 -type d -printf "%P$IFS")
do
[[ -z "$FILE" ]] && continue
TITLE="n/a";UUID='';TAGS=''
if [[ -f "$FILE/.directory.ngl" ]];then
for ff in TITLE TAGS UUID; do
eval $(sed -n '/'"$ff"'/p' $FILE/.directory.ngl)
done
fi
# print entry in .index.txt
echo -e "$FILE::directory::$TITLE::$UUID::$TAGS" >> $TMP/directories
done
# for files
echo > $TMP/files # empty file for angels (file) entries
for FILE in $(find . -maxdepth 1 -not -name ".*" -name "*.ngl" -printf "%P$IFS")
do
if [[ -f "$FILE" ]]
then
TITLE="n/a";UUID='';TAGS=''
echo $FILE
# get parameters from file
for ff in TITLE TAGS UUID; do
eval $(sed -n '0,/^#PRECOMMANDS/{/'"$ff"'=/p}' $FILE)
done
# print entry in .index.txt
echo -e "${FILE%.ngl}::file::$TITLE::$UUID::$TAGS" >> $TMP/files
fi
done
# create header
header=$(cat ".directory.ngl")
[[ -z "$header" ]] && header="TITLE=\"n/a\""
# add header
echo "$header" > .index.txt
echo -n "#MAIN" >> .index.txt
# add tmp-file from before and sort it
cat $TMP/directories| sort -g >> .index.txt
cat $TMP/files |sort -g >> .index.txt
chgrp angels .index.txt 2>/dev/null
chmod 664 .index.txt 2>/dev/null
popd &>/dev/null
}
function create_index ()
{ # create .index.xml file
# -r = recursive
# $1 [$2] = directory
case "$1" in
"")
echo "Usage ${0##*/} [-r] directory"
echo " full path of directory needed!"
echo " use ${0##*/} --create-index \$PWD for present directory"
exit
;;
"-r") recursive=yes
shift
;;
esac
if [[ ! -d "$1" ]] ;then
echo "directory not found"
exit
fi
base="${OLDPWD#$ANGELPATH/}"
if [[ "$recursive" == "yes" ]] ; then
# finds all subdirectories, but....
LIST=$(find "$1" -type d )
else
LIST="$1"
fi
echo "$LIST"
for i in $LIST
do
echo $i
_create_index "$i"
done
}
#### end functions
#### BEGIN MAIN PROGRAM
# check, if link directory is empty
[[ `ls "$LINKS"|wc -l` -lt 28 ]] && create_oneletter_commands
# check name of script that called this script
case "$SCRIPTNAME" in
angel) # base program, parse parameter
# options only for angel, not for links
# start options
case "$1" in
"") # angel invoked witout arguments >> go basedir
TYPE=directory
ACTIVEANGEL="$ANGELPATH"
;;
"-f") # find in index-file, ie. filename,title,tags
# *ALL* parameters must match (logical and)
shift
TYPE=find
ACTIVEANGEL="$@"
;;
"-F") # full-text search
exit
;;
"-r") # reference: go to reference <uuid>
shift
get_reference "$1"
set_vars "$EXTRACT"
ACTIVEANGEL=$FILE
;;
"-x") # execute an angel-file
shift
ACTIVEANGEL="$PWD/$1"
[[ -f $ACTIVEANGEL ]] && TYPE=file
[[ -d $ACTIVEANGEL ]] && TYPE=directory
;;
"-u") # URL
shift
wget_angel "$1"
exit
;;
"-i") # inactivate one letter links
[[ ! -z "$LINKS" ]] && rm -f "$LINKS"/* &>/dev/null
exit
;;
"-c") #create angel
set -x
shift
create_newangel "$1"
exit
;;
"-e") shift
edit_angel "$1"
exit
;;
--create-index)
shift
create_index $@
exit 0
;;
--h*|-h*|yelp) # show help message
ACTIVEANGEL="$ANGELPATH/"help
TYPE=directory
;;
# end options
*) # direct directory/file reference
file="${1%.ngl}"
if [[ -f "$ANGELPATH/$file.ngl" ]] ;then
TYPE=file
ACTIVEANGEL="$ANGELPATH/$file"
elif [[ -d "$ANGELPATH/$1" ]] ;then
TYPE=directory
ACTIVEANGEL="$ANGELPATH/$1"
else
E_noangel
fi
;;
esac
;;
# one-letter commands
b) move_one "$LOGFILE" up # back: previous selection
;;
f) move_one "$LOGFILE" down # forward: next selection
;;
n) move_one "$ANGELS_IN_DIR" down # go next angel in dir
;;
p) move_one "$ANGELS_IN_DIR" up # go previous angel in dir
;;
u) go_up # up one level
;;
r) renew_screen
;;
d) set_variables
renew_screen
;;
# ]) flag_onoff "$fBRACKETS" fBRACKETS
# ;;
z) flag_onoff "$fINCLUDE_FILES" fINCLUDE_FILES
flag_status $fINCLUDE_FILES
echo "Show files is" $STATUS
;;
q) flag_onoff "$fDEFVALUE" fDEFVALUE
flag_status $fDEFVALUE
echo "Show values is" $STATUS
;;
x) flag_onoff "$fDUMMY" fDUMMY
flag_status $fDUMMY
echo "Hide commands is" $STATUS
;;
h) flag_onoff "$fVARHEIGHLIGHT" fVARHEIGHLIGHT
flag_status $fVARHEIGHLIGHT
echo "Highlighting variables is" $STATUS
;;
e) if [[ -z $1 ]]; then
echo "argument required"
else
echo "changed command \"$1\" temporarily to:"
sudo $EDITOR ~/.angels/`tty |sed 's|/||g'`/commands/$1
cat $_
fi
exit
;;
# link is a number, choose entry from list
[0-9]*) POS=$SCRIPTNAME
case $LASTTYPE in
directory) # show the directory or file with respective number
get_angel $POS # get line $POS of $ANGEL file
set_vars "$EXTRACT"
ACTIVEANGEL="$LASTANGEL/$FILE"
;;
file) # execute the command
move_one "$LOGFILE" end # reset log
execute_command $POS
exit
;;
find)
get_angel $POS # get line $POS of $ANGEL file
set_vars "$EXTRACT"
ACTIVEANGEL="$ANGELPATH/$FILE"
;;
esac
;;
esac
# create files $ANGEL and $SHOWFILE (list and display)
case $TYPE in
directory) # create $ANGEL file for case "directory"
# check for angel
E_noangel "$ACTIVEANGEL"
pushd "$ACTIVEANGEL" &>/dev/null
# check if index file exists
[[ ! -f .index.txt ]] && create_index "$PWD"
# parse .index.txt file for head and main
sed '0,/^#MAIN/!d' .index.txt > $SHEAD
sed '/^#MAIN/,$!d;/^#MAIN/d;/^$/d' .index.txt> $SMAIN
exec_header directory
# create $ANGELS_IN_DIR, filter only lines with a file entry
sed -n '/::file::/s|^|'"$ACTIVEANGEL"'/|p' $SMAIN > "$ANGELS_IN_DIR"
# if more than 16 entries, create links
LINKSNO=$(sed -n '$=' "$SMAIN")
[[ "$LINKSNO" -gt 16 ]] && create_links $LINKSNO
;;
find) # perform a search matching *ALL* positional parameters
# create $ANGEL file for case "find"
# search for all positional parameters inclusive in title, tag, name
# create header
echo "ENCODING=\"ISO-8859-1\"" > "$SHEAD"
echo -e "TYPE=find" >> "$SHEAD"
echo -e "FILE=\"$ACTIVEANGEL\"">> "$SHEAD"
echo -e "TITLE=\"search results\"">> "$SHEAD"
# execute #HEADER
. $SHEAD
# create searchstring from @* for sed: /$1/!d; /$2/!d; /$3/!d ....
SEARCHSTRING=$(echo "$ACTIVEANGEL" |sed -r 's|([^ ])|[\U\1\L\1]|g;s|^|/|;s| |/!d; /|g;s|$|/!d|')
pushd "$ANGELPATH" &>/dev/null
echo > "$SMAIN"
# check all .index-files files for search string
for i in $(find -name ".index.txt" -printf "%P\n")
do
u="$(dirname "$i")/"; [[ "$u" == "./" ]] && u="" # dirname behaviour
sed '0,/#MAIN/d' $i| sed "$SEARCHSTRING" | sed 's|^|'$u'|'>> "$SMAIN"
done
popd &>/dev/null
sed -i '/^$/d' "$SMAIN"
# create links if missing
LINKSNO=$(sed -n '$=' "$SMAIN")
[[ "$LINKSNO" -gt 16 ]] && create_links $LINKSNO
;;
file) # create $ANGEL for file
E_noangel "$ACTIVEANGEL".ngl
check_syntax "$ACTIVEANGEL".ngl
# parse activeangel to create head, pre, main
sed '0,/^#PRECOMMANDS/!d' "$ACTIVEANGEL.ngl" > $SHEAD
sed '/^#PRECOMMANDS/,/^#VARIABLES/!d' "$ACTIVEANGEL.ngl"> $SPRE
sed '/^#VARIABLES/,/^#MAIN/!d' "$ACTIVEANGEL.ngl"> $SVAR
sed '/^#MAIN/,$!d;/^#MAIN/d' "$ACTIVEANGEL.ngl"> $SMAIN
exec_header file
. $SPRE # execute precommand section
#include @include (source a script)
include_files "$SMAIN" "@include"
# extract variables and create variables.txt list
create_variable_list
# delete variable values set inside main section, leave var-name only!
sed -i 's/\({{[^:@]\+\):[^}{]*\(}}\)/\1\2/g' "$SMAIN"
# set automatic numbers, if needed
set_numbers
# extract the commands
extract_commands
# set references
include_references "$SMAIN"
;;
show) # renew showfile
ACTIVEANGEL="$LASTANGEL"
TITLE="$LASTTITLE"
TYPE=$LASTTYPE
sed -i '1,3!d' $SHOWFILE
;;
esac
######## create showfile
# creates the first 3 lines with title and tags and filename
echo -e "$bold""$TITLE""$boldoff" > $SHOWFILE
echo -e " $TYPE: $red${ACTIVEANGEL#$ANGELPATH}" >> $SHOWFILE
echo -e "$normal$CTAGS tags: $TAGS$normal" >> $SHOWFILE
case $TYPE in
directory|find) # list directories first then list files
sed -r 's/(^[^:]*::[^:]*::[^:]*)::.*/\1/
/::directory::/{
s||: '"$sCTITLE"'|
s|^|'"$sCFOLDER"'|
s|$|'"$snormal"'|
}
/::file::/{
s||: '"$sCTITLE"'|
s|^|'"$sCFILE"'|
s|$|'"$snormal"'|
}' $SMAIN | sed '/^$/d' | cat -n >> "$SHOWFILE"
;;
file) #remove cmd- and dmd-statements, insert colours and adjust nicely
SED=''
# hide the commands, if DUMMY is set
if [[ "$fDUMMY" -eq 1 ]]; then
# delete the commands when hide commands is on
SED=' /^@cmd:[^:]*:/{
/^@cmd:/{s|||
s|:|'"$NUMSEP"':|
s|:|'"$sCCMDCOMMENT"'|1
s|^|'"$sCCMD"'|
s|$|'"$snormal"'|
p}
:a
/.*@cmdend$/d
s|.*||;
N
ba}
'
fi
# layout commands and ajust nicely (the unsolvable problem)
SED1="$SED"'
/^@[cd]md:/{
s///
s|([^:]*:).*|\1|
s|^[^:]*$|&:| # insert ':' if no
s|:|'"$NUMSEP"':|
h
s|.| |g
s|^.||
x
s|:|| # delete : if not previously
N
s/\n *//
s|^|'"$sCCMD"'|
bip}
G
s|(.*)\n(.*)|\2\1|
:ip
/@[cd]mdend$/{ s||'"$snormal"'|
h
s|.*||
x
}'
# fmt simulate, break line at col and preserve tabs in the beginning
SED3=' /\t/s|$|\t|
:a
/^.{'"$COLS"'}/{
s//&\a/
Tc;tc
:c
/.*\a/{
s|^(.*) (.*)\a|\1\n\2|
tb # change a space
s|^(.*[-/;:])(.*)\a|\1\n\2|
tb # if no space use one of -/;:
s|\a|\n|
:b # hard core at col size
P
s|^.*\n||
/\t$/s|^|\t|
ba
}
x
s|.*||
x
}
p
'
sed -r "$SED1" $SMAIN|sed -nr "$SED3" >> $SHOWFILE
# adjust showfile - | fmt -s -w $COLS -t
[[ "$fINCLUDE_FILES" -eq 1 ]] && include_files "$SHOWFILE" "@file"
# value of variable on or off
[[ "$fDEFVALUE" -eq 1 ]] && insert_variable "$SHOWFILE"
# variablename of variable on or off
# [[ "$fDEFAULTNAME" -eq -1 ]] && variablename_off
# brackets on or off
# [[ "$fBRACKETS" -eq 1 ]] && sed -i 's|{{||g;s|}}||g' $SHOWFILE
# set colors
sed -i 's/<black>/'"$sblack"'/g
s/<red>/'"$sred"'/g
s/<green>/'"$sgreen"'/g
s/<yellow>/'"$syellow"'/g
s/<blue>/'"$sblue"'/g
s/<magenta>/'"$smagenta"'/g
s/<cyan>/'"$scyan"'/g
s/<white>/'"$swhite"'/g
s/<normal>/'"$snormal"'/g
s/<bold>/'"$sbold"'/g
s/<\/bold>/'"$sboldoff"'/g
s/<italics>/'"$sitalics"'/g
s/<\/italics>/'"$sitalicsoff"'/g
s/<ul>/'"$sul"'/g
s/<\/ul>/'"$suloff"'/g
s/<inv>/'"$sinv"'/g
s/<\/inv>/'"$sinvoff"'/g' $SHOWFILE
;;
esac
# display showfile
echo -e "`cat $SHOWFILE`$normal" |sed '1,3!s|^| |'
# add entry to logfile
[[ $LOGFILEUPDATE == yes ]] && update_logfile