Inputs and Outputs

  This document describes how you can override Twiddler's default
  input parser and output renderer to allow the source to be something
  other than html or xml and the output to be something other than a
  unicode or string.

  We've already seen the two default parsers in action, one of which
  recognises code blocks while the other, which is used if no parser
  is explicitly specified, ignores them.

  Other input parsers are also available and can be found in the
  'inputs' sub-package of the twiddler package. Full documentation for
  each input parser can be found in the text file accompanying the
  module containing the parser in that sub-package.

  As a simple example, here's how to perform some basic twiddler
  operations using the plain text input parser:

  >>> from twiddler import Twiddler
  >>> from twiddler.input.plaintext import PlainText
  >>> t = Twiddler('<line>$first $second</line>\n',input=PlainText)
  >>> line = t['line'].repeater()
  >>> n = line.repeat()
  >>> n['first'].replace('1st')
  >>> n['second'].replace('2nd')
  >>> n = line.repeat()
  >>> n['first'].replace('3rd')
  >>> n['second'].replace('4th')
  >>> print t.render()
  1st 2nd
  3rd 4th
  <BLANKLINE>

  Similarly, other output renderers are also available and can be
  found in the 'outputs' sub-package of the twiddler package. Full
  documentation for each output renderer can be found in the text file
  accompanying the module containing the renderer in that sub-package.

  As an example, here's how to produce and send an email using the
  emailer output renderer:

  >>> from twiddler.output.emailer import Email,DummySMTP
  >>> email = Email(smtp_host=DummySMTP)
  >>> t = Twiddler('''<html>
  ... <body>
  ... <p>Dear <span id="name">Mr Smith</span>,</p>
  ... <p>Thankyou for your order!</p>
  ... </body>
  ... </html>''',output=email)  
  >>> t['name'].replace('Mr Jones',tag=False)
  >>> t.render(mfrom='orders@simplistix.co.uk',
  ...          mto='jones@example.com',
  ...          subject='Your order',
  ...          content_type='text/html')
  Dummy SMTP send from 'orders@simplistix.co.uk' to 'jones@example.com'
  Content-Type: text/html; charset="utf-8"
  MIME-Version: 1.0
  Content-Transfer-Encoding: quoted-printable
  Date: ...
  From: orders@simplistix.co.uk
  Message-ID: ...
  Subject: Your order
  To: jones@example.com
  <BLANKLINE>
  <html>
  <body>
  <p>Dear Mr Jones,</p>
  <p>Thankyou for your order!</p>
  </body>
  </html>

  So now that we've seen how to use the alternates available, you may
  find you need to write your own input or output.

  In order to do this, you just need to provide callables that
  implement either twiddler.interfaces.IInput or
  twiddler.interfaces.IOutput, respectively. Please note the text at
  the top of twiddler.interfaces: the callables you provide must be
  pickleable. 

  As an aside, if you find either your custom inputs or custom outputs
  need to be configured, then make them callable objects, rather than
  functions, and pass the configuration to the constructor of the
  object. The emailer output is a good example of this.

  It's a good idea, if at all possible, to make any configuration
  passed to the constuctor of an input or output optional so that
  component configuration systems have an easier time of snapping
  together the input, output and filters that make up a Twiddler's
  configuration without having to worry about all the configuration
  options right at the start.


