Skip to content
Newer
Older
100644 472 lines (420 sloc) 16.2 KB
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
1 #!/bin/sh
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
2 # **shocco** is a quick-and-dirty, literate-programming-style documentation
3 # generator written for and in __POSIX shell__. It borrows liberally from
4 # [Docco][do], the original Q&D literate-programming-style doc generator.
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
5 #
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
6 # `shocco(1)` reads shell scripts and produces annotated source documentation
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
7 # in HTML format. Comments are formatted with Markdown and presented
8 # alongside syntax highlighted code so as to give an annotation effect. This
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
9 # page is the result of running `shocco` against [its own source file][sh].
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
10 #
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
11 # shocco is built with `make(1)` and installs under `/usr/local` by default:
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
12 #
103fee7 @bmizerany FIX: typo in clone url
bmizerany authored Jul 19, 2010
13 # git clone git://github.com/rtomayko/shocco.git
5f12c2a @rtomayko s/schocco/shocco/ fixes #6
authored Apr 27, 2011
14 # cd shocco
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
15 # make
16 # sudo make install
17 # # or just copy 'shocco' wherever you need it
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
18 #
19 # Once installed, the `shocco` program can be used to generate documentation
20 # for a shell script:
21 #
22 # shocco shocco.sh
23 #
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
24 # The generated HTML is written to `stdout`.
cb97eba @rtomayko link to shocco source
authored Mar 10, 2010
25 #
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
26 # [do]: http://jashkenas.github.com/docco/
cb97eba @rtomayko link to shocco source
authored Mar 10, 2010
27 # [sh]: https://github.com/rtomayko/shocco/blob/master/shocco.sh#commit
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
28
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
29 # Usage and Prerequisites
30 # -----------------------
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
31
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
32 # The most important line in any shell program.
33 set -e
34
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
35 # There's a lot of different ways to do usage messages in shell scripts.
36 # This is my favorite: you write the usage message in a comment --
37 # typically right after the shebang line -- *BUT*, use a special comment prefix
38 # like `#/` so that its easy to pull these lines out.
39 #
40 # This also illustrates one of shocco's corner features. Only comment lines
41 # padded with a space are considered documentation. A `#` followed by any
42 # other character is considered code.
43 #
c225c62 @rtomayko -t <title> sets the title in <head> and <h1>
authored Mar 16, 2010
44 #/ Usage: shocco [-t <title>] [<source>]
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
45 #/ Create literate-programming-style documentation for shell scripts.
46 #/
c225c62 @rtomayko -t <title> sets the title in <head> and <h1>
authored Mar 16, 2010
47 #/ The shocco program reads a shell script from <source> and writes
48 #/ generated documentation in HTML format to stdout. When <source> is
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
49 #/ '-' or not specified, shocco reads from stdin.
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
50
51 # This is the second part of the usage message technique: `grep` yourself
52 # for the usage message comment prefix and then cut off the first few
53 # characters so that everything lines up.
8896caf Fix expr for BSD. Tested on FreeBSD and Debian
Curt Micol authored Mar 17, 2010
54 expr -- "$*" : ".*--help" >/dev/null && {
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
55 grep '^#/' <"$0" | cut -c4-
56 exit 0
57 }
58
c225c62 @rtomayko -t <title> sets the title in <head> and <h1>
authored Mar 16, 2010
59 # A custom title may be specified with the `-t` option. We use the filename
60 # as the title if none is given.
61 test "$1" = '-t' && {
62 title="$2"
63 shift;shift
64 }
65
66 # Next argument should be the `<source>` file. Grab it, and use its basename
67 # as the title if none was given with the `-t` option.
68 file="$1"
b60c7ed @rtomayko fix title not being set properly
authored Mar 16, 2010
69 : ${title:=$(basename "$file")}
c225c62 @rtomayko -t <title> sets the title in <head> and <h1>
authored Mar 16, 2010
70
c2a2742 @rtomayko munge in configured markdown and pygmentize
authored Mar 16, 2010
71 # These are replaced with the full paths to real utilities by the
b60c7ed @rtomayko fix title not being set properly
authored Mar 16, 2010
72 # configure/make system.
c2a2742 @rtomayko munge in configured markdown and pygmentize
authored Mar 16, 2010
73 MARKDOWN='@@MARKDOWN@@'
74 PYGMENTIZE='@@PYGMENTIZE@@'
75
0b94d5d @roller Check for GNU csplit and add --elide-empty-files
roller authored Aug 15, 2011
76 # On GNU systems, csplit doesn't elide empty files by default:
b389f6f @roller Be sure to || true when checking for gnu
roller authored Aug 16, 2011
77 CSPLITARGS=$( (csplit --version 2>/dev/null | grep -i gnu >/dev/null) && echo "--elide-empty-files" || true )
0b94d5d @roller Check for GNU csplit and add --elide-empty-files
roller authored Aug 15, 2011
78
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
79 # We're going to need a `markdown` command to run comments through. This can
80 # be [Gruber's `Markdown.pl`][md] (included in the shocco distribution) or
81 # Discount's super fast `markdown(1)` in C. Try to figure out if either are
82 # available and then bail if we can't find anything.
83 #
84 # [md]: http://daringfireball.net/projects/markdown/
85 # [ds]: http://www.pell.portland.or.us/~orc/Code/discount/
c2a2742 @rtomayko munge in configured markdown and pygmentize
authored Mar 16, 2010
86 command -v "$MARKDOWN" >/dev/null || {
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
87 if command -v Markdown.pl >/dev/null
88 then alias markdown='Markdown.pl'
89 elif test -f "$(dirname $0)/Markdown.pl"
90 then alias markdown="perl $(dirname $0)/Markdown.pl"
91 else echo "$(basename $0): markdown command not found." 1>&2
92 exit 1
93 fi
94 }
95
96 # Check that [Pygments][py] is installed for syntax highlighting.
97 #
98 # This is a fairly hefty prerequisite. Eventually, I'd like to fallback
99 # on a simple non-highlighting preformatter when Pygments isn't available. For
100 # now, just bail out if we can't find the `pygmentize` program.
101 #
102 # [py]: http://pygments.org/
c2a2742 @rtomayko munge in configured markdown and pygmentize
authored Mar 16, 2010
103 command -v "$PYGMENTIZE" >/dev/null || {
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
104 echo "$(basename $0): pygmentize command not found." 1>&2
105 exit 1
106 }
107
108 # Work and Cleanup
109 # ----------------
110
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
111 # Make sure we have a `TMPDIR` set. The `:=` parameter expansion assigns
112 # the value if `TMPDIR` is unset or null.
113 : ${TMPDIR:=/tmp}
114
115 # Create a temporary directory for doing work. Use `mktemp(1)` if
116 # available; but, since `mktemp(1)` is not POSIX specified, fallback on naive
117 # (and insecure) temp dir generation using the program's basename and pid.
118 : ${WORK:=$(
119 if command -v mktemp 1>/dev/null 2>&1
120 then
d307521 @rtomayko use more portable mktemp usage, fixes #5
authored Apr 27, 2011
121 mktemp -d "$TMPDIR/$(basename $0).XXXXXXXXXX"
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
122 else
123 dir="$TMPDIR/$(basename $0).$$"
124 mkdir "$dir"
125 echo "$dir"
126 fi
127 )}
128
7241273 @rtomayko sanity check the work dir was created properly
authored Mar 16, 2010
129 # We want to be absolutely sure we're not going to do something stupid like
130 # use `.` or `/` as a work dir. Better safe than sorry.
131 test -z "$WORK" -o "$WORK" = '/' && {
132 echo "$(basename $0): could not create a temp work dir."
133 exit 1
134 }
135
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
136 # We're about to create a ton of shit under our `$WORK` directory. Register
137 # an `EXIT` trap that cleans everything up. This guarantees we don't leave
138 # anything hanging around unless we're killed with a `SIGKILL`.
ff2fcaa @rtomayko since we mention EXIT already
authored Mar 16, 2010
139 trap "rm -rf $WORK" 0
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
140
141 # Preformatting
142 # -------------
143 #
bc8843c @rtomayko trying to work around strange last section issues
authored Mar 16, 2010
144 # Start out by applying some light preformatting to the `<source>` file to
145 # make the code and doc formatting phases a bit easier. The result of this
146 # pipeline is written to a temp file under the `$WORK` directory so we can
147 # take a few passes over it.
148
149 # Get a pipeline going with the `<source>` data. We write a single blank
150 # line at the end of the file to make sure we have an equal number of code/comment
151 # pairs.
152 (cat "$file" && printf "\n\n# \n\n") |
b2946c8 @rtomayko invert first comment and code block
authored Mar 16, 2010
153
154 # We want the shebang line and any code preceding the first comment to
155 # appear as the first code block. This inverts the normal flow of things.
156 # Usually, we have comment text followed by code; in this case, we have
157 # code followed by comment text.
158 #
159 # Read the first code and docs headers and flip them so the first docs block
160 # comes before the first code block.
161 (
162 lineno=0
163 codebuf=;codehead=
164 docsbuf=;docshead=
165 while read -r line
166 do
167 # Issue a warning if the first line of the script is not a shebang
168 # line. This can screw things up and wreck our attempt at
169 # flip-flopping the two headings.
170 lineno=$(( $lineno + 1 ))
171 test $lineno = 1 && ! expr "$line" : "#!.*" >/dev/null &&
e4660e5 Fix expansion of $file
Adam Spiers authored Oct 5, 2013
172 echo "$(basename $0): ${file}:1 [warn] shebang! line missing." 1>&2
b2946c8 @rtomayko invert first comment and code block
authored Mar 16, 2010
173
174 # Accumulate comment lines into `$docsbuf` and code lines into
175 # `$codebuf`. Only lines matching `/#(?: |$)/` are considered doc
176 # lines.
177 if expr "$line" : '# ' >/dev/null || test "$line" = "#"
178 then docsbuf="$docsbuf$line
179 "
180 else codebuf="$codebuf$line
181 "
182 fi
183
184 # If we have stuff in both `$docsbuf` and `$codebuf`, it means
185 # we're at some kind of boundary. If `$codehead` isn't set, we're at
186 # the first comment/doc line, so store the buffer to `$codehead` and
187 # keep going. If `$codehead` *is* set, we've crossed into another code
188 # block and are ready to output both blocks and then straight pipe
189 # everything by `exec`'ing `cat`.
190 if test -n "$docsbuf" -a -n "$codebuf"
191 then
192 if test -n "$codehead"
193 then docshead="$docsbuf"
194 docsbuf=""
bc8843c @rtomayko trying to work around strange last section issues
authored Mar 16, 2010
195 printf "%s" "$docshead"
196 printf "%s" "$codehead"
b2946c8 @rtomayko invert first comment and code block
authored Mar 16, 2010
197 echo "$line"
198 exec cat
199 else codehead="$codebuf"
200 codebuf=
201 fi
202 fi
203 done
bc8843c @rtomayko trying to work around strange last section issues
authored Mar 16, 2010
204
205 # We made it to the end of the file without a single comment line, or
206 # there was only a single comment block ending the file. Output our
207 # docsbuf or a fake comment and then the codebuf or codehead.
208 echo "${docsbuf:-#}"
209 echo "${codebuf:-"$codehead"}"
b2946c8 @rtomayko invert first comment and code block
authored Mar 16, 2010
210 ) |
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
211
212 # Remove comment leader text from all comment lines. Then prefix all
213 # comment lines with "DOCS" and interpreted / code lines with "CODE".
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
214 # The stream text might look like this after moving through the `sed`
215 # filters:
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
216 #
217 # CODE #!/bin/sh
5f12c2a @rtomayko s/schocco/shocco/ fixes #6
authored Apr 27, 2011
218 # CODE #/ Usage: shocco <file>
b2946c8 @rtomayko invert first comment and code block
authored Mar 16, 2010
219 # DOCS Docco for and in POSIX shell.
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
220 # CODE
221 # CODE PATH="/bin:/usr/bin"
222 # CODE
223 # DOCS Start by numbering all lines in the input file...
224 # ...
225 #
732cad1 @rtomayko fix some needless uses of cat
authored Mar 16, 2010
226 # Once we pass through `sed`, save this off in our work directory so
227 # we can take a few passes over it.
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
228 sed -n '
229 s/^/:/
e5557a3 @elmimmo Support tabs for code nesting
elmimmo authored Jul 4, 2011
230 s/^:[ ]\{0,\}# /DOCS /p
231 s/^:[ ]\{0,\}#$/DOCS /p
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
232 s/^:/CODE /p
732cad1 @rtomayko fix some needless uses of cat
authored Mar 16, 2010
233 ' > "$WORK/raw"
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
234
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
235 # Now that we've read and formatted our input file for further parsing,
236 # change into the work directory. The program will finish up in there.
237 cd "$WORK"
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
238
239 # First Pass: Comment Formatting
240 # ------------------------------
241
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
242 # Start a pipeline going on our preformatted input.
243 # Replace all CODE lines with entirely blank lines. We're not interested
244 # in code right now, other than knowing where comments end and code begins
245 # and code begins and comments end.
732cad1 @rtomayko fix some needless uses of cat
authored Mar 16, 2010
246 sed 's/^CODE.*//' < raw |
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
247
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
248 # Now squeeze multiple blank lines into a single blank line.
249 #
250 # __TODO:__ `cat -s` is not POSIX and doesn't squeeze lines on BSD. Use
251 # the sed line squeezing code mentioned in the POSIX `cat(1)` manual page
252 # instead.
253 cat -s |
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
254
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
255 # At this point in the pipeline, our stream text looks something like this:
256 #
257 # DOCS Now that we've read and formatted ...
258 # DOCS change into the work directory. The rest ...
259 # DOCS in there.
260 #
261 # DOCS First Pass: Comment Formatting
262 # DOCS ------------------------------
263 #
264 # Blank lines represent code segments. We want to replace all blank lines
265 # with a dividing marker and remove the "DOCS" prefix from docs lines.
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
266 sed '
267 s/^$/##### DIVIDER/
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
268 s/^DOCS //' |
269
270 # The current stream text is suitable for input to `markdown(1)`. It takes
271 # our doc text with embedded `DIVIDER`s and outputs HTML.
c2a2742 @rtomayko munge in configured markdown and pygmentize
authored Mar 16, 2010
272 $MARKDOWN |
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
273
274 # Now this where shit starts to get a little crazy. We use `csplit(1)` to
275 # split the HTML into a bunch of individual files. The files are named
276 # as `docs0000`, `docs0001`, `docs0002`, ... Each file includes a single
732cad1 @rtomayko fix some needless uses of cat
authored Mar 16, 2010
277 # doc *section*. These files will sit here while we take a similar pass over
278 # the source code.
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
279 (
280 csplit -sk \
0b94d5d @roller Check for GNU csplit and add --elide-empty-files
roller authored Aug 15, 2011
281 $CSPLITARGS \
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
282 -f docs \
283 -n 4 \
284 - '/<h5>DIVIDER<\/h5>/' '{9999}' \
285 2>/dev/null ||
286 true
287 )
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
288
bc8843c @rtomayko trying to work around strange last section issues
authored Mar 16, 2010
289
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
290 # Second Pass: Code Formatting
291 # ----------------------------
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
292 #
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
293 # This is exactly like the first pass but we're focusing on code instead of
294 # comments. We use the same basic technique to separate the two and isolate
295 # the code blocks.
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
296
297 # Get another pipeline going on our performatted input file.
298 # Replace DOCS lines with blank lines.
732cad1 @rtomayko fix some needless uses of cat
authored Mar 16, 2010
299 sed 's/^DOCS.*//' < raw |
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
300
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
301 # Squeeze multiple blank lines into a single blank line.
74bae39 @rtomayko various shell fixes
authored Mar 16, 2010
302 cat -s |
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
303
732cad1 @rtomayko fix some needless uses of cat
authored Mar 16, 2010
304 # Replace blank lines with a `DIVIDER` marker and remove prefix
305 # from `CODE` lines.
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
306 sed '
307 s/^$/# DIVIDER/
74bae39 @rtomayko various shell fixes
authored Mar 16, 2010
308 s/^CODE //' |
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
309
732cad1 @rtomayko fix some needless uses of cat
authored Mar 16, 2010
310 # Now pass the code through `pygmentize` for syntax highlighting. We tell it
311 # the the input is `sh` and that we want HTML output.
9cab2d8 @elmimmo Support non-ASCII characters in code
elmimmo authored Jul 4, 2011
312 $PYGMENTIZE -l sh -f html -O encoding=utf8 |
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
313
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
314 # Post filter the pygments output to remove partial `<pre>` blocks. We add
315 # these back in at each section when we build the output document.
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
316 sed '
317 s/<div class="highlight"><pre>//
74bae39 @rtomayko various shell fixes
authored Mar 16, 2010
318 s/^<\/pre><\/div>//' |
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
319
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
320 # Again with the `csplit(1)`. Each code section is written to a separate
321 # file, this time with a `codeXXX` prefix. There should be the same number
322 # of `codeXXX` files as there are `docsXXX` files.
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
323 (
b2946c8 @rtomayko invert first comment and code block
authored Mar 16, 2010
324 DIVIDER='/<span class="c"># DIVIDER</span>/'
325 csplit -sk \
0b94d5d @roller Check for GNU csplit and add --elide-empty-files
roller authored Aug 15, 2011
326 $CSPLITARGS \
b2946c8 @rtomayko invert first comment and code block
authored Mar 16, 2010
327 -f code \
328 -n 4 - \
329 "$DIVIDER" '{9999}' \
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
330 2>/dev/null ||
331 true
332 )
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
333
334 # At this point, we have separate files for each docs section and separate
335 # files for each code section.
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
336
337 # HTML Template
338 # -------------
339
340 # Create a function for apply the standard [Docco][do] HTML layout, using
341 # [jashkenas][ja]'s gorgeous CSS for styles. Wrapping the layout in a function
342 # lets us apply it elsewhere simply by piping in a body.
343 #
344 # [ja]: http://github.com/jashkenas/
345 # [do]: http://jashkenas.github.com/docco/
346 layout () {
347 cat <<HTML
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
348 <!DOCTYPE html>
349 <html>
350 <head>
4df0971 @kstep Typo fix: 'http-equiv', not 'http-eqiv'
kstep authored Aug 7, 2012
351 <meta http-equiv='content-type' content='text/html;charset=utf-8'>
c225c62 @rtomayko -t <title> sets the title in <head> and <h1>
authored Mar 16, 2010
352 <title>$1</title>
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
353 <link rel=stylesheet href="http://jashkenas.github.com/docco/resources/docco.css">
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
354 </head>
355 <body>
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
356 <div id=container>
357 <div id=background></div>
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
358 <table cellspacing=0 cellpadding=0>
359 <thead>
360 <tr>
c225c62 @rtomayko -t <title> sets the title in <head> and <h1>
authored Mar 16, 2010
361 <th class=docs><h1>$1</h1></th>
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
362 <th class=code></th>
363 </tr>
364 </thead>
365 <tbody>
bc8843c @rtomayko trying to work around strange last section issues
authored Mar 16, 2010
366 <tr><td class='docs'>$(cat)</td><td class='code'></td></tr>
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
367 </tbody>
368 </table>
369 </div>
370 </body>
371 </html>
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
372 HTML
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
373 }
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
374
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
375 # Recombining
376 # -----------
377
378 # Alright, we have separate files for each docs section and separate
379 # files for each code section. We've defined a function to wrap the
380 # results in the standard layout. All that's left to do now is put
381 # everything back together.
382
0d24998 @rcrowley Properly order output when code0000 is empty.
rcrowley authored Oct 22, 2011
383 # Before starting the pipeline, decide the order in which to present the
384 # files. If `code0000` is empty, it should appear first so the remaining
385 # files are presented `docs0000`, `code0001`, `docs0001`, and so on. If
386 # `code0000` is not empty, `docs0000` should appear first so the files
387 # are presented `docs0000`, `code0000`, `docs0001`, `code0001` and so on.
388 #
389 # Ultimately, this means that if `code0000` is empty, the `-r` option
390 # should not be provided with the final `-k` option group to `sort`(1) in
391 # the pipeline below.
527e65a @stijnvn Fix stat incompatibility with BSD variants.
stijnvn authored Dec 10, 2011
392 if stat -c"%s" /dev/null >/dev/null 2>/dev/null ; then
393 # GNU stat
394 [ "$(stat -c"%s" "code0000")" = 0 ] && sortopt="" || sortopt="r"
395 else
396 # BSD stat
397 [ "$(stat -f"%z" "code0000")" = 0 ] && sortopt="" || sortopt="r"
398 fi
0d24998 @rcrowley Properly order output when code0000 is empty.
rcrowley authored Oct 22, 2011
399
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
400 # Start the pipeline with a simple list of split out temp filename. One file
401 # per line.
74bae39 @rtomayko various shell fixes
authored Mar 16, 2010
402 ls -1 docs[0-9]* code[0-9]* 2>/dev/null |
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
403
aaad1c0 @rtomayko more doc toward the crazy end part there
authored Mar 10, 2010
404 # Now sort the list of files by the *number* first and then by the type. The
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
405 # list will look something like this when `sort(1)` is done with it:
aaad1c0 @rtomayko more doc toward the crazy end part there
authored Mar 10, 2010
406 #
407 # docs0000
408 # code0000
409 # docs0001
410 # code0001
411 # docs0002
412 # code0002
413 # ...
414 #
0d24998 @rcrowley Properly order output when code0000 is empty.
rcrowley authored Oct 22, 2011
415 sort -n -k"1.5" -k"1.1$sortopt" |
aaad1c0 @rtomayko more doc toward the crazy end part there
authored Mar 10, 2010
416
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
417 # And if we pass those files to `cat(1)` in that order, it concatenates them
418 # in exactly the way we need. `xargs(1)` reads from `stdin` and passes each
419 # line of input as a separate argument to the program given.
420 #
421 # We could also have written this as:
aaad1c0 @rtomayko more doc toward the crazy end part there
authored Mar 10, 2010
422 #
423 # cat $(ls -1 docs* code* | sort -n -k1.5 -k1.1r)
424 #
425 # I like to keep things to a simple flat pipeline when possible, hence the
426 # `xargs` approach.
74bae39 @rtomayko various shell fixes
authored Mar 16, 2010
427 xargs cat |
52c1454 @rtomayko clean up csplit spew on EXIT. a ton more docs
authored Mar 10, 2010
428
c2c0268 @rtomayko first working version, for some definition of "working"
authored Mar 10, 2010
429
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
430 # Run a quick substitution on the embedded dividers to turn them into table
431 # rows and cells. This also wraps each code block in a `<div class=highlight>`
432 # so that the CSS kicks in properly.
b2946c8 @rtomayko invert first comment and code block
authored Mar 16, 2010
433 {
434 DOCSDIVIDER='<h5>DIVIDER</h5>'
435 DOCSREPLACE='</pre></div></td></tr><tr><td class=docs>'
436 CODEDIVIDER='<span class="c"># DIVIDER</span>'
437 CODEREPLACE='</td><td class=code><div class=highlight><pre>'
438 sed "
439 s@${DOCSDIVIDER}@${DOCSREPLACE}@
440 s@${CODEDIVIDER}@${CODEREPLACE}@
441 "
442 } |
443
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
444 # Pipe our recombined HTML into the layout and let it write the result to
445 # `stdout`.
c225c62 @rtomayko -t <title> sets the title in <head> and <h1>
authored Mar 16, 2010
446 layout "$title"
aaad1c0 @rtomayko more doc toward the crazy end part there
authored Mar 10, 2010
447
a69bf33 @rtomayko wrap up docs
authored Mar 12, 2010
448 # More
449 # ----
450 #
451 # **shocco** is the third tool in a growing family of quick-and-dirty,
452 # literate-programming-style documentation generators:
453 #
454 # * [Docco][do] - The original. Written in CoffeeScript and generates
455 # documentation for CoffeeScript, JavaScript, and Ruby.
456 # * [Rocco][ro] - A port of Docco to Ruby.
457 #
458 # If you like this sort of thing, you may also find interesting Knuth's
459 # massive body of work on literate programming:
460 #
461 # * [Knuth: Literate Programming][kn]
462 # * [Literate Programming on Wikipedia][wi]
463 #
464 # [ro]: http://rtomayko.github.com/rocco/
465 # [do]: http://jashkenas.github.com/docco/
466 # [kn]: http://www-cs-faculty.stanford.edu/~knuth/lp.html
467 # [wi]: http://en.wikipedia.org/wiki/Literate_programming
468
469 # Copyright (C) [Ryan Tomayko <tomayko.com/about>](http://tomayko.com/about)<br>
470 # This is Free Software distributed under the MIT license.
471 :
Something went wrong with that request. Please try again.