#!/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