-
-
Save mralexgray/1209534 to your computer and use it in GitHub Desktop.
Revisions
-
tlrobinson revised this gist
Jul 10, 2011 . 5 changed files with 171 additions and 121 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 1,40 @@ #!/usr/bin/env bash # Bash Stack set -o errtrace set -o errexit set -o nounset declare -a stack stack_push () { [ $# -eq 1 ] || _stack_err "stack_push takes one argument" || return 1 stack[${#stack[@]}]="$1" } stack_pop () { index=$(_stack_index) || _stack_err "index out of range" || return 1 unset stack[$index] } stack_get () { [ $# -ge 1 ] && item="$1" || item="0" index=$(_stack_index $item) || _stack_err "index out of range" || return 1 echo ${stack[$index]} } stack_list () { echo ${stack[@]} } stack_size () { echo ${#stack[@]} } # internal: _stack_index () { [ $# -ge 1 ] && index="$1" || index="0" || true [ "$index" -ge 0 ] && [ "$index" -lt ${#stack[@]} ] || return 1 expr ${#stack[@]} - "$index" - 1 || true } _stack_err () { echo "Stack error: $@" 1>&2 return 1 } This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 1,39 @@ #!/usr/bin/env bash # Bash XML parser (SAX) # # EXAMPLE: echo '<foo><bar>hello world</bar></foo>' | ./bash-xml.bash 'echo START:' 'echo END:' 'echo TEXT:' # set -o errtrace set -o errexit set -o nounset bash_xml_sax_parse () { handle_element_start="$1" handle_element_end="$2" handle_characters="$3" # assumes each line contains one element cat "/dev/stdin" | bash_xml_split | while read line; do case "$line" in "<?"*) ;; "</"*) [ -z "$handle_element_end" ] || $handle_element_end "$line" "$(expr "$line" : '</*\([^ />]*\)')" ;; "<"*"/>") [ -z "$handle_element_start" ] || $handle_element_start "$line" "$(expr "$line" : '</*\([^ />]*\)')" [ -z "$handle_element_end" ] || $handle_element_end "$line" "$(expr "$line" : '</*\([^ />]*\)')" ;; "<"*) [ -z "$handle_element_start" ] || $handle_element_start "$line" "$(expr "$line" : '</*\([^ />]*\)')" ;; *) [ -z "$handle_characters" ] || $handle_characters "$line" ;; esac done } # splits an XML document into a stream of lines containing one element each and removes blanks # TODO: make this more robust bash_xml_split () { sed -e 's/</\ </g' -e 's/>/>\ /g' | sed -e '/^ *$/d' } if [ "$0" == "$BASH_SOURCE" ]; then bash_xml_split | bash_xml_sax_parse "$@" fi This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 1,49 @@ #!/usr/bin/env bash # Gmail inbox feed parser # # EXAMPLE: ./gmail.bash GMAIL_USER # # GMAIL_USER can include username and optionally a password set -o errtrace set -o errexit set -o nounset parent=$(dirname -- "$BASH_SOURCE") source "$parent/bash-xml.bash" source "$parent/bash-stack.bash" gmail_parse_feed () { bash_xml_sax_parse gmail_parse_feed_element_start gmail_parse_feed_element_end gmail_parse_feed_characters } gmail_parse_feed_element_start () { [ "$2" != "entry" ] || (gmail_entry_name="" && gmail_entry_title="" && gmail_entry_date="") stack_push "$2" } gmail_parse_feed_element_end () { [ "$2" != "entry" ] || printf " s | %-25s | %s\n" "$gmail_entry_date" "$gmail_entry_name" "$gmail_entry_title" stack_pop } gmail_parse_feed_characters () { case "$(stack_list)" in "feed entry title") gmail_entry_title="$1" ;; "feed entry issued") gmail_entry_date="$1" ;; "feed entry author name") gmail_entry_name="$1" ;; esac } gmail_fetch_feed () { curl -u "$1" --silent 'https://mail.google.com/mail/feed/atom' } gmail_inbox () { if [ $# -gt 0 ]; then GMAIL_USER="$1" fi gmail_fetch_feed "$GMAIL_USER" | gmail_parse_feed } if [ "$0" == "$BASH_SOURCE" ]; then gmail_inbox "$@" fi This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 1,43 @@ #!/usr/bin/env bash # XML prettifier # # EXAMPLE: echo '<foo><bar>hello world</bar></foo>' | ./xml-prettify.bash # set -o errtrace set -o errexit set -o nounset parent=$(dirname -- "$BASH_SOURCE") source "$parent/bash-xml.bash" source "$parent/bash-stack.bash" xml_prettify_indent="2" xml_prettify_print () { printf "%*s%s\n" $(expr $(stack_size) \* $xml_prettify_indent) "" "$1" } xml_prettify () { bash_xml_sax_parse xml_prettify_start xml_prettify_end xml_prettify_characters } xml_prettify_start () { case "$1" in *"/>") ;; # HACK: skip self terminating tags *) xml_prettify_print "$1" ;; esac stack_push "$2" } xml_prettify_end () { stack_pop xml_prettify_print "$1" } xml_prettify_characters () { xml_prettify_print "$1" return 0 } if [ "$0" == "$BASH_SOURCE" ]; then xml_prettify fi This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,121 0,0 @@ -
tlrobinson created this gist
Jul 10, 2011 .There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 1,121 @@ #!/usr/bin/env bash set -o errtrace set -o errexit set -o nounset # BASH STACK: declare -a stack stack_push () { [ $# -eq 1 ] || stack_err "stack_push takes one argument" || return 1 stack[${#stack[@]}]="$1" } stack_pop () { index=$(stack_index) || stack_err "index out of range" || return 1 unset stack[$index] } stack_item () { [ $# -ge 1 ] && item="$1" || item="0" index=$(stack_index $item) || stack_err "index out of range" || return 1 echo ${stack[$index]} } stack_index () { [ $# -ge 1 ] && index="$1" || index="0" || true [ "$index" -ge 0 ] && [ "$index" -lt ${#stack[@]} ] || return 1 expr ${#stack[@]} - "$index" - 1 || true } stack_count () { echo ${#stack[@]} } stack_list () { echo ${stack[@]} } stack_err () { echo "Stack error: $@" 1>&2 return 1 } # BASH XML PARSER: bash_sax_parse () { handle_element_start="$1" handle_element_end="$2" handle_characters="$3" # assumes each line contains one element cat "/dev/stdin" | bash_xml_split | while read line; do case "$line" in "<?"*) ;; "</"*) [ -z "$handle_element_end" ] || "$handle_element_end" "$line" "$(expr "$line" : '</*\([^ />]*\)')" ;; "<"*"/>") [ -z "$handle_element_start" ] || "$handle_element_start" "$line" "$(expr "$line" : '</*\([^ />]*\)')" [ -z "$handle_element_end" ] || "$handle_element_end" "$line" "$(expr "$line" : '</*\([^ />]*\)')" ;; "<"*) [ -z "$handle_element_start" ] || "$handle_element_start" "$line" "$(expr "$line" : '</*\([^ />]*\)')" ;; *) [ -z "$handle_characters" ] || "$handle_characters" "$line" ;; esac done } # splits an XML document into a stream of lines containing one element each and removes blanks # TODO: make this more robust bash_xml_split () { sed -e 's/</\ </g' -e 's/>/>\ /g' | sed -e '/^ *$/d' } # EXAMPLE: XML prettifier xml_prettify () { bash_sax_parse xml_prettify_start xml_prettify_end xml_prettify_characters } xml_prettify_indent="2" xml_prettify_print () { printf "%*s%s\n" $(expr $(stack_count) \* $xml_prettify_indent) "" "$1" } xml_prettify_start () { case "$1" in *"/>") ;; # HACK: skip self terminating tags *) xml_prettify_print "$1" ;; esac stack_push "$2" } xml_prettify_end () { stack_pop xml_prettify_print "$1" } xml_prettify_characters () { xml_prettify_print "$1" return 0 } # EXAMPLE: Gmail feed parser gmail_parse_feed () { bash_sax_parse gmail_parse_feed_element_start gmail_parse_feed_element_end gmail_parse_feed_characters } gmail_parse_feed_element_start () { [ "$2" != "entry" ] || (gmail_entry_name="" && gmail_entry_title="" && gmail_entry_date="") stack_push "$2" } gmail_parse_feed_element_end () { [ "$2" != "entry" ] || printf " s | %-25s | %s\n" "$gmail_entry_date" "$gmail_entry_name" "$gmail_entry_title" stack_pop } gmail_parse_feed_characters () { case "$(stack_list)" in "feed entry title") gmail_entry_title="$1" ;; "feed entry issued") gmail_entry_date="$1" ;; "feed entry author name") gmail_entry_name="$1" ;; esac } gmail_user='USERNAME' gmail_fetch_feed () { curl -u "$gmail_user" --silent 'https://mail.google.com/mail/feed/atom' } gmail_fetch_feed | gmail_parse_feed