#!/bin/bash set -a USAGE='go to the wiki web you want to process, run it by wiki-list-tree [options] topics... it will output all the topics sons of the listed topics. Options: -t outputs the file names (.txt appended) -i ignore errors and print the results anyways in case of errors -s ignore errors only if none happens in topics to be outputted (sons) -_ allow underscores in wiki topic names -as) alphabetical sort (default) topics are printed in alphabetical sort, and appear only once -ts) topological sort, they are sorted from top to bottom, appear once -is) indented sort, tree-like, but topics may appear many times ' pext='' topicnamechars='a-zA-Z0-9' ignore_errors=false subset=false type=alphabetical while test -z "${1##-*}" -a -n "$1";do case $1 in -t) pext='.txt';; -i) ignore_errors=true;; -_) topicnamechars="_$topicnamechars";; -s) subset=true;; -ts) type=topological;; -as) type=alphabetical;; -is) type=indented;; *) echo "$USAGE"; exit;; esac;shift done if test -z "$*"; then echo "$USAGE"; exit;fi # the list of topics with errors in_err= # the list of roots of the to-be-printed hierarchy topics= # cache are lines of space seprarated topics and ancestors till WebHome cache=/tmp/wiki-list-tree.$$ echo "WebHome " >$cache # error still continues to perform all checks, but nothing will be printed # $topic MUST contain the topic name ERROR () { in_err="$in_err $topic"; echo "ERROR: $*" >&2; } for i in "$@"; do topic="${i%.txt}"; file="$topic.txt" if test ! -e "$file"; then ERROR "topic $topic not found"; exit 1; fi topics="$topics $topic" done find_ancestry () { # $1=file local file parent ancestry topic tname wname file="$1" topic="${file%.txt}" parent=`grep '^%META:TOPICPARENT{name="[^"]*"}%[\r\t ]*$' "$file"` parent="${parent%\"*}"; parent="${parent#*\"}" parent="${parent:=WebHome}" case "$topic" in *[^$topicnamechars]*) ERROR "Illegal topic name $topic";; esac case "$parent" in *[^.$topicnamechars]*) ERROR "Illegal parent name $parent for topic $topic";; esac case "$parent" in *.*) tname=${parent#*.}; wname=${parent%.*} local details if test -e ../$wname/$tname.txt; then details="which exists" else details="which do not exist" fi if test -e $tname.txt; then details="$details, but local topic exists" else details="$details, and local topic do not exist" fi ERROR "non-local parent $parent for $topic $details";; esac if test "$topic" = "$parent" -a "$topic" != WebHome; then ERROR "topic has himself as parent: $parent" fi if test -n "$in_err"; then return; fi if test ! -e "$parent.txt"; then ERROR "parent $parent of topic $topic not found" fi if test "$parent" = WebHome; then # one-level deep ancestry="WebHome " fi if test -z "$ancestry"; then ancestry=`grep "^$parent " $cache` if test -z "$ancestry"; then # recurse to complete parent ancestry find_ancestry $parent.txt fi ancestry=`grep "^$parent " $cache` if test -z "$ancestry"; then # arg.... something broken ERROR "hierarchy broken for $parent parent of $topic" fi fi if ! grep -q "^$topic " $cache; then # not yet, add it echo "$topic $ancestry" >>$cache fi } process_web () { while read file; do find_ancestry "${file#./}"; done topics="${topics# }"; in_err="${in_err# }" if test -z "$in_err" -o $ignore_errors = true; then print_results elif test -z "$in_err" -o $subset = true; then in_err_subset=`egrep "${topics// /|}" $cache \ | sed -e 's/ .*//' | egrep "${in_err// |}"` if test -z "$in_err_subset"; then print_results fi fi #mv $cache /tmp/wiki-list-tree.cache # DEBUG rm -f $cache } print_results () { if test $type = topological; then egrep " (${topics// /|})( |$)" $cache | sed -e 's/\([^ ]* [^ ]*\) .*/\1/'\ | tsort | tac elif test $type = indented; then for topic in $topics; do print_level "" $topic done else egrep "( |^)(${topics// /|})( |$)" $cache | sed -e 's/ .*//' \ | sort | uniq | sed -e "s/$/$pext/" fi } print_level () { local topic parent echo "$1$2" egrep "^[^ ]* $2( |$)" $cache | while read topic parent; do print_level "$1 " $topic done } find . -type f -name '[A-Z]*.txt' | process_web