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!

https://badge.waffle.io/jacquev6/RecursiveDocument.png?label=ready&title=ready

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 (a Paragraph will be created for you) or Section or DefinitionList or None.
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 (a Paragraph will be created for you) or Section or DefinitionList or None.
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:
Returns:

self to allow chaining.