RecursiveDocument¶
RecursiveDocument is a Python (2.7+ and 3.3+) library formating, in a console-friendly and human-readable way, a document specified through its structure (sections, sub-sections, paragraphs, etc.). It is especially well suited for printing help messages for command-line executables.
It’s licensed under the MIT license. It’s available on the Python package index, its documentation is hosted by Python and its source code is on GitHub.
Questions? Remarks? Bugs? Want to contribute? Open an issue!
Quick start¶
Install from PyPI:
$ pip install RecursiveDocument
Import:
>>> from RecursiveDocument import *
Create a document:
>>> doc = Document().add(
... Section("Introduction")
... .add("This is the first paragraph of a very interesting story. It begins with this paragraph.")
... .add("After the first paragraph comes the second paragraph. As incredible as it may sound, it can go on and on and on...")
... )
And print it:
>>> print doc.format()
Introduction
This is the first paragraph of a very interesting story. It begins
with this paragraph.
After the first paragraph comes the second paragraph. As incredible
as it may sound, it can go on and on and on...
User guide¶
RecursiveDocument does absolutely nothing fancy (Italic? Bold? Underline? No!). It just prints your document on 70 columns and it does it well. It was written for help messages in InteractiveCommandLine and released separately because, well, you know, reusability.
Introduction¶
Import:
>>> from RecursiveDocument import Document, Section
>>> from RecursiveDocument import Paragraph, DefinitionList
Create a simple document and format it:
>>> doc = Document()
>>> doc.add("Some text")
<RecursiveDocument.Document ...>
>>> doc.add("Some other text")
<RecursiveDocument.Document ...>
>>> print doc.format()
Some text
Some other text
Add¶
Because add
returns self
, RecursiveDocument allows chaining of calls to add
:
>>> print Document().add("Some text").add("Some other text").format()
Some text
Some other text
add
is also variadic so you can add several things at once:
>>> print Document().add("Some text", "Some other text").format()
Some text
Some other text
Wrapping¶
When the document is wide, it is wrapped to 70 caracters:
>>> lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque facilisis nisi vel nibh luctus sit amet semper tellus gravida."
>>> print Document().add(
... lorem + " " + lorem,
... lorem + " " + lorem,
... ).format()
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque
facilisis nisi vel nibh luctus sit amet semper tellus gravida. Lorem
ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque
facilisis nisi vel nibh luctus sit amet semper tellus gravida.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque
facilisis nisi vel nibh luctus sit amet semper tellus gravida. Lorem
ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque
facilisis nisi vel nibh luctus sit amet semper tellus gravida.
Sections¶
Sections and sub-sections can be nested. They are indented by 2 spaces to improve readability:
>>> print Document().add(
... Section("First section").add(
... "Some text.",
... Section("Sub-section").add("This is so deep."),
... "This is not that deep.",
... ),
... Section("Second section").add(
... "Some other text.",
... ),
... ).format()
First section
Some text.
Sub-section
This is so deep.
This is not that deep.
Second section
Some other text.
Paragraphs¶
When you add a string, it’s like adding a Paragraph
containing this string:
>>> print Document().add(
... Paragraph("Some text"),
... Paragraph("Some other text"),
... ).format()
Some text
Some other text
You can also create a Paragraph
from several strings:
>>> print Document().add(
... Paragraph("Some text.", "Some other text.")
... ).format()
Some text. Some other text.
Definition lists¶
>>> print Document().add(
... DefinitionList()
... .add("term 1", "definition 1")
... .add(
... "term 2",
... Section("definition 2 is a section")
... .add("With some text. Can you believe it?")
... .add("Oh, and next term has no definition.")
... )
... .add("term 3", None)
... .add("longest term", "The longest term decides on which column definitions start.")
... .add("very very very very long term", "Except that this term is so long that we couldn't put it's definition on the same line. So we didn't shrink other terms' definitions.")
... ).format()
term 1 definition 1
term 2 definition 2 is a section
With some text. Can you believe it?
Oh, and next term has no definition.
term 3
longest term The longest term decides on which column definitions
start.
very very very very long term
Except that this term is so long that we couldn't put
it's definition on the same line. So we didn't shrink
other terms' definitions.
Reference¶
-
class
Document
¶ The top-level document.
-
format
()¶ Format the document and return the generated string.
-
add
(*contents)¶ Append contents to this object.
Parameters: contents – one or several Paragraph
or string (aParagraph
will be created for you) orSection
orDefinitionList
orNone
.Returns: self to allow chaining.
-
-
class
Section
(title)¶ A section in a document. Sections can be nested.
-
add
(*contents)¶ Append contents to this object.
Parameters: contents – one or several Paragraph
or string (aParagraph
will be created for you) orSection
orDefinitionList
orNone
.Returns: self to allow chaining.
-
-
class
Paragraph
(*text)¶ A paragraph in a document.
Parameters: text – one or more strings.
-
class
DefinitionList
¶ A list of terms with their definitions.
>>> print Document().add(Section("Section title") ... .add(DefinitionList() ... .add("Item", Paragraph("Definition 1")) ... .add("Other item", Paragraph("Definition 2")) ... ) ... ).format() Section title Item Definition 1 Other item Definition 2
-
add
(name, definition)¶ Append a new term to the list.
Parameters: - name – string.
- definition –
Paragraph
or string (aParagraph
will be created for you) orSection
orDefinitionList
orNone
.
Returns: self to allow chaining.
-