-
Notifications
You must be signed in to change notification settings - Fork 3
/
mdwc
executable file
·181 lines (163 loc) · 5.83 KB
/
mdwc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#! /usr/bin/env bash
# Copyright (c) 2016, 2018 Phillip Alday
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# argument parsing adapted from http://stackoverflow.com/a/29754866/2022326
getopt --test > /dev/null
if [[ $? != 4 ]]; then
echo "I'm sorry, 'getopt --test' failed in this environment."
echo "Exiting (your shell doesn't support needed functionality)."
exit 1
fi
SHORT=cmlLwtbhf:k:
LONG=bytes,chars,lines,max-line-length,words,files0-from:,title,body,help,field:,key:
# -temporarily store output to be able to check for errors
# -activate advanced mode getopt quoting e.g. via “--options”
# -pass arguments only via -- "$@" to separate them correctly
PARSED=$(getopt --options $SHORT --longoptions $LONG --name "$0" -- "$@")
if [[ $? != 0 ]]; then
# e.g. $? == 1
# then getopt has complained about wrong arguments to stdout
exit 2
fi
# use eval with "$PARSED" to properly handle the quoting
eval set -- "$PARSED"
WCOPTS=""
BODY=false
TITLE=false
FIELDS=""
# now enjoy the options in order and nicely split until we see --
while true; do
case "$1" in
-c|--bytes)
WCOPTS="${WCOPTS} -c"
shift
;;
-m|--chars)
WCOPTS="${WCOPTS} -m"
shift
;;
-l|--lines)
WCOPTS="${WCOPTS} -l"
shift
;;
-L|--max-line-length)
WCOPTS="${WCOPTS} -L"
shift
;;
-w|--words)
WCOPTS="${WCOPTS} -w"
shift
;;
--files0-from)
WCOPTS="${WCOPTS} --files0-from=$2"
shift 2
;;
--title|-t)
TITLE=true
shift
;;
--field|--key|-f|-k)
FIELDS="${FIELDS},$2"
shift 2
;;
--body|-b)
BODY=true
shift
;;
--help|-h)
echo "$0: wc wrapper for pandoc MarkDown files with YAML block."
echo
echo "arguments:"
echo -e " --title, -t \t run wc on title line in initial YAML block"
echo -e " \t (note: will not work on multiline titles)"
echo
echo -e " --body, -b \t run wc on body (everything after initial YAML block)"
echo
echo -e " --field, -f \t run wc on specified top-level YAML field"
echo -e " \t Note: this will extract multiline fields and can be"
echo -e " \t used to extract multliline titles. This method is "
echo -e " \t slower, which may be come apparant when applied to "
echo -e " \t large (numbers of) files."
echo
echo -e " --key, -k \t synonym for --field. One of these may be removed"
echo -e " \t in the future"
echo
echo "wc arguments supported: (see man wc for more details)"
echo " --bytes, -c"
echo " --chars, -m"
echo " --words, -w"
echo " --lines, -l"
echo " --max-line-length, -L"
echo " --files0-from"
echo
echo "Default is wc on just the body (useful for situations with length limits such as abstracts)" | fold -s
exit
;;
--) # end of options
shift
break
;;
*)
echo "Unrecognized option: $1"
echo "(How did you get here? Please consider reporting a bug)"
exit 3
;;
esac
done
# handle non-option arguments
# set default behavior to report body stats
if [[ "$TITLE" = false && "$BODY" = false && "$FIELDS" = "" ]]; then
BODY=true
fi
# if there are no arguments, then something is being piped in, so we need to handle that
# the temporary file is not terribly efficient, but it's easy and we expect this to be a corner case
if [[ $# == 0 ]]; then
TMP=$(mktemp)
tee $TMP 1>/dev/null
eval set -- "$TMP"
fi
while [[ $# != 0 ]]; do
# don't display the gibberish temporary filename
if [ "$1" != "$TMP" ]; then
FNAME=$1
else
FNAME=""
fi
if [ "$FIELDS" ]; then
for key in $(echo ${FIELDS} | tr ", " "\n\n")
do
value=$(sed -Ee '/^---\w*$/,/^(---|...)$/!d' $1 | egrep "^${key}" | awk -e'{$1="";print $0}')
# trim whitespace
value=$(echo $value| xargs echo -n)
if [[ "$value" = "|" ]]; then
# extract the relevant chunk then
# remove first empty line and last line, which is the next key
value=$(sed -Ee '/^---\w*$/,/^(---|...)$/!d' $1 | sed -Ee "/^${key}/,/^[a-z]/!d" | sed -e '1d;$d')
fi
echo $value | wc $WCOPTS | awk -e '{print $0, "'${FNAME}'", "('${key}')"}'
done
fi
if [ "$TITLE" = true ]; then
sed -Ee '/^---\w*$/,/^(---|...)$/!d' $1 | egrep '^title:' | awk -e'{$1="";print $0}'| wc $WCOPTS | awk -e '{print $0, "'${FNAME}'", "(title)"}'
fi
if [ "$BODY" = true ]; then
sed -Ee '/^---\w*$/,/^(---|...)\w*$/d' $1 | wc $WCOPTS | awk -e '{print $0, "'${FNAME}'", "(body)"}'
fi
shift
done
# clean up the tempfile if necessary
if [ -e "$TMP" ]; then
rm "$TMP"
fi