-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathr2h
executable file
·293 lines (243 loc) · 10.2 KB
/
r2h
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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
#!/bin/bash
### This only works with bash. dash/ash does not support the text
# substitutions that we make. I should just rewrite this in perl
####!/bin/sh
### If this script is NOT a symlink, readlink should just
# return $0. If it is a symlink, readlink will dereference it.
#
# NOTE: if you want to install this script in a separate
# directory from bootstrap_rst2html then edit the code
# below and explicitly set INSTALL_DIR.
INSTALL_DIR=`dirname $(readlink -f $0)`
BOOTSTRAP_SCRIPT="$INSTALL_DIR/bootstrap_rst2html"
TEMPLATE_DIR="${INSTALL_DIR}/templates"
CSS_DIR="${INSTALL_DIR}/css"
### Defaults:
TEMPLATE="${TEMPLATE_DIR}/pygments_template.txt"
HIGHLIGHTER=pygments
STYLE=autumn
BLOGGER_STYLESHEET="${CSS_DIR}/blogger_compat.css"
BROWSER_CMD="x-www-browser {FILE}"
ACTION="print"
usage()
{
script_name=`basename $0`
cat <<END_USAGE
Usage: $script_name [OPTIONS] [RST_FILE]
Translates the contents of RST_FILE to html.
If RST_FILE is not specified, $script_name reads its input from STDIN.
Options:
-c, --clipboard send output to your clipboard
instead of to STDOUT (the default)
-v, --validate validate the markup. This will discard
STDOUT and print only STDERR, which will
print errors (if any) without printing
the output html.
-w, --preview preview HTML output in a web browser
instead of to STDOUT.
-b, --browser set the web browser command to use
for --preview. You must include {FILE}
as a placeholder for the temporary
file that your browser will open if
you define a custom command. Default is
${BROWSER_CMD}.
Note that {FILE} will automatically be
expressed in
file:///path/to/auto/generated/tempfile
URL notation.
-l, --lib the name of the syntax highlighting library
to use. These opt args are supported
(case insensitive):
sh | SyntaxHighlighter = SyntaxHighlighter
p | pygments = Pygments
-L, --list List syntax highlighting backends and
styles.
-s, --style The name of the syntax highlighting style
to use. Look in css/[LIBRARY NAME]/*css
for the list of css files. Specify an
unambiguous substring of the css
filename (no need for abs path).
-t, --tmpfile the basename of the file to use as a
tempfile. If this is not supplied and
we do a preview using STDIN as input,
mktemp is used to generate a temp filename.
If RST_FILE is defined (not reading STDIN),
then the temp file will be
\$TMPDIR/RST_FILE.html (TMPDIR defaults to
/tmp if not defined)
Notes:
Some examples for --browser:
--browser "chromium-browser --app={FILE} --temp-profile"
--browser "epiphany --new-window {FILE}"
--browser "iceweasel -safe-mode -new-window {FILE}"
--browser "gnome-terminal -e 'w3m {FILE}'"
BROWSER="rxvt-unicode --font"
BROWSER="\$BROWSER '-misc-fixed-medium-r-normal--15-120-100-100-c-90-iso8859-1'"
BROWSER="\$BROWSER -e w3m {FILE}"
--browser="\$BROWSER"
Tip: If you are editing an .rst file in vim and you want to
translate the current buffer to html and copy it to the clipboard
in one step (so you can then paste it into, e.g., your
blog-publishing client), do:
:!r2h -c %
To alias the above as just R2hclip, put this in your ~/.vimrc:
command R2hclip !r2h --clip
Examples:
# Preview using SyntaxHighlighter for code formatting with the Midnight theme:
r2h --preview --style=midnight --lib=sh myfile.rst
# Preview using Pygments for code formatting with the Manni theme:
r2h --preview --style=manni --lib=pygments myfile.rst
END_USAGE
}
### The <body> tag is always followed by <div class="document", and
# the last 2 lines will close the div and the body... This is fragile,
# but it is also trivial to fix if changes to the output format in
# a future docutils version break it.
extract_document_body()
{
sed -n '/^<body>/,/^<\/body>/p' | sed -e '1,2d' | head -n '-2'
}
cleanup_tmp_file()
{
r2h_tmp_file="$1"
#[ -f "$r2h_tmp_file" ] && rm "$r2h_tmp_file"
echo "MUST CLEAN UP: $r2h_tmp_file"
}
### Copy STDIN to the Xwindows CLIPBOARD paste buffer
to_clip()
{
xsel -bi
}
list_backends()
{
pattern="%-22s %s\n"
printf "$pattern" "----------------------" "------------------------"
printf "$pattern" "Highlighting Backend" Theme
printf "$pattern" "----------------------" "------------------------"
be=Pygments
for f in `ls "$INSTALL_DIR"/css/pygments`; do
f=`basename "$f"`
theme=${f%.css}
printf "$pattern" $be $theme
done
echo
be=SyntaxHighlighter
for f in `ls "$INSTALL_DIR"/css/syntax_highlighter |grep -v shCore`; do
f=`basename "$f"`
theme=${f%.css}
theme=${theme#shTheme}
printf "$pattern" $be $theme
done
printf "$pattern" "----------------------" "------------------------"
echo
}
### By default, pipe to cat, which will just print to STDOUT
OUTPUT_FILTER=cat
RST_ARGS='--link-stylesheet --no-doc-title'
### getopt boilerplate:
LONG_OPTS="help,clipboard,preview,list,validate,lib:,style:,browser:,tmpfile:"
OPTS=$(getopt --long "$LONG_OPTS" "hcwvLb:t:l:s:" "$@")
[ $? != 0 ] && ( usage; exit 1 )
eval set -- "$OPTS"
while true; do
case "$1" in
-h|--help) usage; exit 0;;
-c|--clip*) OUTPUT_FILTER="to_clip"; shift;;
-w|--prev*) ACTION=preview; shift;;
-v|--valid*) ACTION=validate; shift;;
-L|--list*) ACTION=list; shift;;
-b|--browser) BROWSER_CMD="$2"; shift 2;;
-l|--lib)
export SYNTAX_HIGHLIGHTING_FRAMEWORK="$2"
is_sh=0
for s in SH SYNTAXHIGHLIGHTER; do
m=`expr match "${SYNTAX_HIGHLIGHTING_FRAMEWORK^^}" "$s"`
is_sh=$((is_sh+m))
done
if [ $is_sh -gt 0 ]; then
TEMPLATE="${TEMPLATE_DIR}/syntax_highlighter_template.txt"
HIGHLIGHTER=syntax_highlighter
fi
shift 2
;;
-s|--style) STYLE="$2"; shift 2;;
-t|--tmpfile) TMP_FILE="$2"; shift 2;;
--) shift; break ;;
*) break ;;
esac
done
RST_DOCUMENT="$1"
### If RST_DOCUMENT is specified, validate that it is a real file
if [ -n "$RST_DOCUMENT" ] && [ ! -f "$RST_DOCUMENT" ]; then
usage; exit 1
fi
case "$ACTION" in
validate)
$BOOTSTRAP_SCRIPT $RST_ARGS --exit-status=3 \
$RST_DOCUMENT 1> /dev/null
exit_status=$?
[ $exit_status = 0 ] && echo "No Errors in Markup."
;;
list)
list_backends
exit 0
;;
print)
$BOOTSTRAP_SCRIPT \
$RST_ARGS --template="$TEMPLATE_DIR/template_clipboard.txt" \
$RST_DOCUMENT \
| $OUTPUT_FILTER
;;
preview)
if [ -f "$RST_DOCUMENT" ] || [ -n "$TMP_FILE" ]; then
[ ! -d "$TMPDIR" ] && TMPDIR=/tmp
if [ -z "$TMP_FILE" ]; then
TMP_FILE="$RST_DOCUMENT"
fi
fname=`basename "$TMP_FILE"`
r2h_tmp_file="${TMPDIR}/${fname}.html"
else
r2h_tmp_file=`mktemp --suffix=.html`
fi
LIB_CSS_DIR="${CSS_DIR}/${HIGHLIGHTER}"
if [ -z "$STYLE" ] && [ "$HIGHLIGHTER" = syntax_highlighter ]; then
STYLE=Default
fi
STYLE_DEF="$BLOGGER_STYLESHEET"
STYLE_FILE=`find "$LIB_CSS_DIR" -iregex ".*$STYLE.*" |head -n1`
if [ ! -z "$STYLE_FILE" ]; then
sf=`readlink -f "$STYLE_FILE"`
STYLE_DEF="${STYLE_DEF},${sf}"
fi
$BOOTSTRAP_SCRIPT \
$RST_ARGS --template="$TEMPLATE" \
--stylesheet="$STYLE_DEF" \
$RST_DOCUMENT > "$r2h_tmp_file"
# ensure the file is cleaned up on EXIT, even if the user
# sends a SIGINT. Below we have a hack for firefox/iceweasel, which
# do not block when you call them on the command line if a current
# browser process is running. Because firefox does not block, there
# is a race-condition between the trap to delete the tmp file
# and the loading of the file in FF. Our lame workaround is to
# just sleep in the EXIT trap to allow FF to load the file before
# we delete it. I also include a check for setsid
# in case we want to run with, e.g., "setsid chromium-browser {FILE}".
# setsid gives responsiveness, but b/c we have to sleep for the browser
# to win the race condition (and we want to ensure that the file is
# cleaned up on exit), using it makes no sense
is_race_condition=0
for s in firefox iceweasel setsid chromium-browser; do
idx=`expr match "$BROWSER_CMD" "$s"`
is_race_condition=$((is_race_condition+idx))
done
if [ $is_race_condition -gt 0 ]; then
trap '[ -f "$r2h_tmp_file" ] && sleep 4 ; rm "$r2h_tmp_file"' EXIT
else
trap '[ -f "$r2h_tmp_file" ] && rm "$r2h_tmp_file"' EXIT
fi
### This only works in bash (not, e.g., dash). I should this entire
# script in perl or python
${BROWSER_CMD/\{FILE\}/file://$r2h_tmp_file} >/dev/null 2>&1
;;
*) usage; exit 1;;
esac