6 How to Write Literate Programs with PyLit
11 We start with a classic example in Python_
16 save it as ``hello.py`` and convert to a `reStructured Text`_ document
19 #> python pylit.py hello.py
20 extract written to hello.py.txt
22 The output file ``hello.py.txt`` looks like
24 .. include:: hello.py.txt
27 We can see the difference between "commented code" and "code living in a
32 * One can start literate programming with an existing code file (and without
33 knowledge of reStructured Text syntax).
35 * *Documentation* is uncommented (if it is separated from code by a
36 blank line and has a recognised comment string at the start of each line).
38 * A double colon is added at the end of the text block. It is the
39 `reStructured Text`_ marker for the following `literal block`_.
40 (No marker is added, if the text block already ends with a double colon.)
42 * *Code* is indented to form a literal block. It will be printed using a
43 monospaced font and without reStructured Text substitutions.
45 * PyLit adds ".txt" to the filename for the text version.
47 Now we can add some more documentation and a link (of course, knowledge of
48 `reStructured Text syntax`_ helps in this stage):
50 .. include:: hello_2.py.txt
53 Pretty-printed with Docutils, it looks like
55 .. topic:: Example Output
57 .. include:: hello_2.py.txt
59 If we re-convert the result to code, ::
61 #> python pylit.py hello_2.py.txt
62 extract written to hello_2.py
66 .. include:: hello_2.py
71 * The double colon that was added in the first conversion is not stripped in
74 (Generally, a round-trip should not introduce changes after the first
75 cycle. This way it is ensured that the line-numbers are the same in text
78 * The code block ends at the first non indented line (Precisely, at the
79 first line that is not more indented than the preceding text block.)
82 Text Blocks and Comments
83 ------------------------
85 Comment lines are only transformed to a text block, if they
87 * start with a matching `comment string` (whitespace counts!, the Python
88 default is ``'# '``), and
89 * are separated from non-text lines by at least one blank [#]_ line
91 Otherwise, they are kept as commented code.
93 An example will illustrate this. The code::
95 # 99bottles.py -- print the famous "99 bottles of beer" song lyrics
97 # Introductory example to literate programming
99 # count down from 99 to 1
100 for bottles in range(99,0,-1):
103 is mapped to text as::
105 99bottles.py -- print the famous "99 bottles of beer" song lyrics
109 # Introductory example to literate programming
111 # count down from 99 to 1
112 for bottles in range(99,0,-1):
115 The comment in the 5th line marks the "secondary documentation" as part of
120 # 99bottles.py -- print the famous "99 bottles of beer" song lyrics
122 # Introductory example to literate programming
124 # count down from 99 to 1
125 for bottles in range(99,0,-1):
128 is mapped to text as::
130 99bottles.py -- print the famous "99 bottles of beer" song lyrics
132 Introductory example to literate programming
136 # count down from 99 to 1
137 for bottles in range(99,0,-1):
140 The comment in the 2nd line is removed, as it is inside a documentation block.
142 .. [#] a line is considered blank, if it contains only whitespace
145 Ordinary Literal Blocks
146 -----------------------
148 How can I include a literal block that should not be in the executable code
149 (e.g. an example, an earlier version or variant)?
153 - Python session examples and doctests can use `doctest block`_ syntax.
154 See the `doctests`_ section.
156 - Use a "code-block" directive and set the `code_block_marker` option.
162 Sometimes code needs to remain on the first line(s) of the document to be
163 valid. The most common example is the shebang_ line that tells a POSIX shell
164 how to process an executable file. In Python, the magic comment specifying
165 the `source code encoding`_ must occur on line one or two:
167 .. include:: hello_with_header.py
170 Headers are converted to a comment in the text source:
172 .. include:: hello_with_header.py.txt
175 Pretty-printed with Docutils, it looks like
177 .. admonition:: hello_with_header
179 .. include:: hello_with_header.py.txt
181 Everything before the first text block (i.e. before the first paragraph
182 using the matching comment string) will be hidden in HTML or PDF output.
184 It may come as surprise that a part of the file is not "printed".
185 (In the case that there is no matching comment at all, the complete code
186 source will become a comment, however, in this case it is not likely
187 the source is a literate program anyway). But there are advantages also:
189 * line numbers are kept during the text <--> code conversion (which would be
190 impossible with a literal block marker as this needs to be at the end of
191 the preceding paragraph)
192 * you can hide a repeating (or boring) header in a project consisting of
195 If needed for the documentation, it is possible to repeat the header in the
196 the first text block, e.g. using a `parsed literal block`_:
200 #!/usr/bin/env python
201 # -*- coding: iso-8859-1 -*-
207 Pylit supports `Python doctests`_ in a literate script.
209 We add a `doctest block`_ [#]_ to our example:
211 .. include:: hello_with_doctest.py
216 #> python -c "import doctest; doctest.testfile('hello_with_doctest.py')"
218 There is no output. So everything is OK? Unfortunately not:
219 ``doctest.testfile`` does not find the test, as it is "hidden" in a comment.
222 Pylit converts the source to the text version, feeds it to the doctest_
223 module's `Advanced API`_ (introduced in Python 2.4), and we get ::
225 #> pylit --doctest hello_with_doctest.py
226 **********************************************************************
227 File "hello_with_doctest.py", line 3, in
229 execfile("hello_with_doctest.py")
235 Ah yes, we forgot the full-stop in our test. Adding it and testing again::
237 #> pylit --doctest hello_with_doctest_2.py
238 0 failures in 1 tests
240 The printed summary will ensure us that the test actually passed.
242 Read more about doctests in the `literate doctests example`_.
245 .. [#] There is no double colon before the doctest; a doctest block is
246 recognised by starting with the Python interpreter prompt ``>>>``
249 .. [#] The tests will be found, if ``doctest.testfile`` is run on the text
251 ``python -c "import doctest; doctest.testfile('hello_with_doctest.py.txt')"``
257 PyLit does not allow the specification of a separate output file for
258 individual code blocks like e.g. noweb_. The "dual source" concept limits
259 the choice to one output file per input file. However, this can be
260 compensated by the use of the `include directive`_.
262 Let us assume that for some reason, the friendly greeting should be defined
263 in a separate file ``greeting.py``:
265 .. include:: greeting.py
268 The documentation of the calling file can include the executed file
270 .. include:: hello_multifile.py
273 Saved to ``hello_multifile.py.txt`` and pretty-printed with Docutils, this
276 .. admonition:: hello_multifile
278 .. include:: hello_multifile.py.txt
281 * you have to convert both, ``greeting.py`` and ``hello_multifile.py``.
282 (Currently, pylit cannot do 'batch processing' of multiple input files.)
287 .. _reStructured Text:
288 http://docutils.sourceforge.net/docs/user/rst/quickref.html
290 .. _Installation: ../download/index.html#installation
292 .. _shebang: http://en.wikipedia.org/wiki/Shebang_(Unix)
294 .. _reStructured Text syntax:
295 http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html
298 http://docutils.sourceforge.net/docs/user/rst/quickref.html#literal-blocks
300 .. _parsed literal block:
301 http://docutils.sourceforge.net/docs/ref/rst/directives.html#parsed-literal-block
302 .. _noweb: https://www.cs.tufts.edu/~nr/noweb/
304 .. _include directive:
305 http://docutils.sourceforge.net/docs/ref/rst/directives.html#including-an-external-document-fragment
307 .. _source code encoding:
308 http://docs.python.org/tutorial/interpreter.html
310 .. _Python doctests: http://docs.python.org/library/doctest.html
311 .. _Advanced API: http://docs.python.org/library/doctest.html#doctest-advanced-api
312 .. _literate doctests example: ../examples/literate-doctests.html
313 .. _parsed-literal block:
314 http://docutils.sourceforge.net/docs/ref/rst/directives.html#parsed-literal-block
316 http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#doctest-blocks
319 http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#line-blocks
322 http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#inline-literals
323 .. _syntax highlight: ../features/syntax-highlight.html