Skip to content

Commit 39676d3

Browse files
committed
Add mkdoc.sh script
1 parent ee3dfff commit 39676d3

File tree

1 file changed

+174
-0
lines changed

1 file changed

+174
-0
lines changed

mkdoc.sh

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
#!/bin/bash
2+
# vim: set ts=4 sw=4 st=4 expandtab
3+
4+
# mkdoc.sh -
5+
# Copyright (c) 2015, 2016, 2017 Timothy Savannah, All Rights Reserved
6+
#
7+
# Licensed under the terms of the GNU General Purpose License (GPL) Version 3.0
8+
#
9+
# If you did not recieve a copy of the license as LICENSE with this distribution,
10+
# it can be found at: https://github.com/kata198/python-mkdoc/blob/master/LICENSE
11+
#
12+
13+
14+
# mkdoc.sh - Generate pydoc for an arbitrary project (via argument), or
15+
# if DEFAULT_PROJECT_NAME is set within this file then
16+
# this script can be copied into your project's root directory
17+
# and executed without argment to generate using thatname.
18+
19+
# DEFAULT_PROJECT_NAME - Set to the name of the folder containing your package
20+
# (i.e. the folder containing the highest-level __init__.py)
21+
#
22+
# This will be used in lieu of an argument (so just running ./mkdoc.sh vs ./mkdoc.sh "myFolderName")
23+
DEFAULT_PROJECT_NAME="YOUR_PROJECT_DIR_HERE"
24+
25+
if [ -z "$1" ];
26+
then
27+
if [ "${DEFAULT_PROJECT_NAME}" = "YOUR_PROJECT_DIR_HERE" ];
28+
then
29+
printf "Error: Missing argument of root package folder, and DEFAULT_PROJECT_NAME within the script was not set.\n\n" >&2
30+
exit 1;
31+
fi
32+
PROJECT_NAME="${DEFAULT_PROJECT_NAME}"
33+
else
34+
PROJECT_NAME="${1}"
35+
fi
36+
37+
if [ ! -d "${PROJECT_NAME}" ];
38+
then
39+
printf "Error: No such directory \"%s\"\n\n" "${PROJECT_NAME}" >&2
40+
exit 2;
41+
fi
42+
43+
if [ ! -e "${PROJECT_NAME}/__init__.py" ];
44+
then
45+
printf "Error: Directory \"%s\" does not contain __init__.py, and thus cannot be imported as a module. Check path?\n\n" "${PROJECT_NAME}" >&2
46+
exit 2;
47+
fi
48+
49+
50+
if [ "$(basename "${PROJECT_NAME}")" != "${PROJECT_NAME}" ] || [ ! -d "./${PROJECT_NAME}" ];
51+
then
52+
printf "Error: Directory \"%s\" must be present in the current directory.\n Navigate to the project root directory and try again.\n\n" "${PROJECT_NAME}" >&2
53+
exit 2;
54+
fi
55+
56+
57+
# note_action - Print an "action" (what the script is doing), in a noticable format different from output.
58+
#
59+
# Args are same as printf (use "%s" and extra args for variables, etc.)
60+
#
61+
note_action() {
62+
63+
FORMAT_STR="${1}"
64+
shift
65+
66+
echo -en "\e[34m"
67+
68+
printf "==> ${FORMAT_STR}" "$@"
69+
70+
echo -en "\e[39m"
71+
72+
}
73+
74+
# note_failure - Note a failure to stderr, in a noticable format different from output.
75+
#
76+
# Args are same as printf (use "%s" and extra args for variables, etc.)
77+
#
78+
note_failure() {
79+
FORMAT_STR="${1}"
80+
shift
81+
82+
echo -en "\e[31m" >&2
83+
84+
printf "==X ${FORMAT_STR}" "$@" >&2
85+
86+
echo -en "\e[39m" >&2
87+
88+
}
89+
90+
91+
92+
note_action "Scanning for .py files within \"%s\"\n" "${PROJECT_NAME}"
93+
94+
shopt -s globstar
95+
shopt -s nullglob
96+
97+
ALL_FILES="$(echo ${PROJECT_NAME}/**.py ${PROJECT_NAME}/**/*.py)"
98+
99+
if [ -z "${ALL_FILES}" ];
100+
then
101+
printf "Error: No .py files found in \"%s\"\n\n" "${PROJECT_NAME}" >&2
102+
exit 2;
103+
fi
104+
105+
ALL_FILES="$(echo "${ALL_FILES}" | tr ' ' '\n' | sort | uniq | tr '\n' ' ')"
106+
107+
ALL_MODS="$(echo "${ALL_FILES}" | tr ' ' '\n' | sed -e 's|/|.|g' -e 's|.py$||g' -e 's|.__init__$||g' | tr '\n' ' ')"
108+
109+
printf "Found the following modules: %s\n\n" "$(echo "${ALL_MODS}" | tr '\n' ' ')"
110+
111+
112+
note_action "Generating pydocs...\n"
113+
pydoc -w ${ALL_MODS}
114+
115+
note_action "Preparing 'doc' dir\n"
116+
mkdir -p doc
117+
rm -f doc/index.html
118+
119+
note_action "Converting absolute local paths to relative web-safe paths...\n"
120+
for fnamePy in ${ALL_FILES};
121+
do
122+
fname="$(echo "${fnamePy}" | sed 's/.py$/.html/g' | tr '/' '.' | sed 's/\.__init__//g' )"
123+
python <<EOT
124+
125+
import AdvancedHTMLParser
126+
import sys
127+
128+
if __name__ == '__main__':
129+
130+
filename = "${fname}"
131+
132+
parser = AdvancedHTMLParser.AdvancedHTMLParser()
133+
parser.parseFile(filename)
134+
135+
em = parser.filter(tagName='a', href='.')
136+
137+
if len(em) == 0:
138+
sys.exit(0)
139+
140+
em = em[0]
141+
142+
em.href = '${PROJECT_NAME}.html'
143+
144+
parentNode = em.parentNode
145+
146+
emIndex = parentNode.children.index(em)
147+
148+
i = len(parentNode.children) - 1
149+
150+
while i > emIndex:
151+
parentNode.removeChild( parentNode.children[i] )
152+
i -= 1
153+
154+
155+
with open(filename, 'wt') as f:
156+
f.write(parser.getHTML())
157+
158+
EOT
159+
RET=$?
160+
161+
if [ "${RET}" -ne 0 ];
162+
then
163+
note_failure "Failed to clean up \"%s\" (from \"%s\"). Exit code: %d\n" "${fname}" "${fnamePy}" "${RET}"
164+
fi
165+
166+
mv "${fname}" 'doc/'
167+
168+
done
169+
170+
pushd "doc" >/dev/null 2>&1
171+
172+
ln -s ${PROJECT_NAME}.html index.html
173+
174+
popd >/dev/null 2>&1

0 commit comments

Comments
 (0)