Skip to main content

About indent-tools

Indenti is a Python package with tools that make text indentation and XML/HTML markup generation easier and more functional.

The indent_tools package contains the following modules:

  • text
    • IndentWriter
    • IndentBuilder
  • xml
    • Node -> Text, Comment, XML -> HTML
    • XML, XML.Factory, XML.Parser
    • HTML, HTML.Factory, HTML.Parser

Installation

Installation is simple. With python3-pip, do the following:

$ sudo pip install -e .

Documentation

text.IndentWriter

The IndentWriter is a class that simplifies the task of indenting output. It keeps track of indent levels and provides a pythonic way of incrementing and decrementing the indent level using the optional 'with' syntax. By default, IndentWriter writes to sys.stdout, but can be told to write to any other File object at construction.

from indent_tools.text import IndentWriter

iw = IndentWriter()

iw('def hello():')
with iw:
    iw('print "Hello!"')

text.IndentBuilder

The IndentBuilder is a specialization of the IndentWriter which collects output in an internal io.StringIO buffer. Use str() to fetch the contents of the buffer once you are done building the indented string.

from indent_tools.text import IndentBuilder

sb = IndentBuilder()

sb('def hello():')
with sb:
    sb('print "Hello!"')

print str(sb)

xml.Node

This base class represents any node in an XML/HTML DOM. Use type() to determine which Node.Type the node represents:

  • Node.Type.Element: An XML or HTML element/tag.
  • Node.Type.Text: Text contents of an XML or HTML element/tag.
  • Node.Type.CDATA: CDATA blocks, not currently supported.
  • Node.Type.Comment: An XML/HTML comment block.

xml.XML

A specialization of Node for Node.Type.Element, this class represents an XML element/tag and is the main building block of an XML DOM. Child nodes can be added using append(), apply(), or __call__(), while attributes can be specified either as dictionaries or keyword arguments to apply() or __call__().

Use XML.Factory to create an XML DOM structure in Python code. Via __getattr__, any node name can be specified as a method name to construct a node of that name, and further parameters to apply()/__call__() can be provided to chain construction.

import cherrypy
from indent_tools.xml import XML

class HelloWorld:
    def index(self):
        xf = XML.Factory(html=True)

        xml = xf.html(
            xf.head(
                xf.title("Hello, world!")),
            xf.body(
                xf.h1("Hello, CherryPy!", style='color: red; font-size: 20px')))

        return str(xml)

    index.exposed = True

XML.Parser can be used to construct a DOM from an XML string using the built-in xml.sax parser:

from indent_tools.xml import XML

parser = XML.Parser()
with open("input.xml", "w") as infile:
    doc = parser.parse(infile.read())

xml.HTML

This class is a shorthand specialization of XML where HTML mode (html=True) is always true. Several differences should be noted:

  • A <!DOCTYPE html> declarative will be emitted before the root element. To disable this, set doctype=None in the HTML or HTML.Factory constructor.
  • The <?xml ...?> declarative will not be emitted in HTML mode.
  • While writing out in HTML mode:
    • Only "void" elements can be specified as "open-close" tags, e.g. <img src="image.png"/>. All other tags will be given open and close tags regardless of their contents, e.g. <p></p>.
      • This applies to area, base, br, col, embed, hr, img, input, link, meta, param, source, track, and wbr.
    • Certain "no-indent" elements will not have their contents indented to match the indent level of the output, as this would affect their rendered contents.
      • This applies only to textarea.
    • "Inline" elements will be written without line breaks so long as their contents are all either text nodes or other inline elements.
      • This applies to a, abbr, b, bdi, bdo, br, cite, code, data, dfn, em, i, kdb, mark, q, rp, rt, ruby, s, samp, small, strong, sub, sup, time, u, var, and wbr.
  • Any attributes with a boolean True value will be emitted as HTML boolean attributes, i.e. they will not have a value listed, e.g. <button disabled>Disabled Button</button> if disabled=True.
  • The HTML.Parser uses the more lenient html.parser, which allows for parsing many malformed documents which would not be valid XML.

NOTE:

The word 'class' is a python keyword, so we can't use it as a keyword argument to create an attribute name. In this case, we pass a dictionary, which is interpreted as a map of attributes for the node, to the __call__ or apply methods of the XML or HTML object. You can always do this instead of using keyword arguments, if this is your preference.

Change Log

Version 2.0: January 6th, 2025

  • Major overhaul and modernization, moved packages to indent_tools parent package.

Version 1.4: April 22nd, 2017

  • Make XmlFactory callable, allowing tags with dashes, e.g. xf('my-dash-tag')()

Version 1.2: November 1st, 2016

  • Make parents respect the NOINDENT status of their children in HTML mode.

Version 1.1: October 18th, 2016

  • Added support for unindented blocks in HTML mode (for textarea)
  • Fixed escaping of XML attributes

Metadata

Release files for indent-tools 2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for indent-tools 2.0
File Size Uploaded Provenance Actions
indent_tools-2.0.tar.gz 10.9 kB Without provenance Details for indent_tools-2.0.tar.gz

Release files / indent_tools-2.0.tar.gz

Download URL indent_tools-2.0.tar.gz
Size 10.9 kB
Tags Source
SHA-256 checksum
How to use checksums
ce9c17107d1926a3e60db644165b612d25c96e63a03a80a0650907880ba0fea1
BLAKE2b-256 checksum
How to use checksums
845373fc061f7f99335f7cf490aa30185198f5a3df5fcbd09547034942491fdf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.0.1 CPython/3.13.1

Security for indent-tools 2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

2.0 This release

1 release file No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page