Library Documentation

In addition to the easy to use command-line script, you can also write programs using the purdy library. The purdy command-line script uses this library to display a simple file to the screen.

Example Program

# reads 'my_code.py' and displays it to the screen with line numbers

from purdy.actions import Append
from purdy.content import Code
from purdy.ui import SimpleScreen

# Screen is the entry to showing content
screen = SimpleScreen(starting_line_number=1)

# Screen has one display area called "code_box", your actions need access
# to this to write the code
code_box = screen.code_box

# read 'my_code.py' and parse it using the Python 3 lexer
blob = Code('code.py', lexer_name='py3')

# actions are like slides in the slides show that is purdy
actions = [
    # append the contents of the blob to the display code box
    Append(code_box, blob),
]

# start the display event loop
screen.run(actions)

Every purdy library program needs to create a Screen or one of its children. The Screen is what controls the display. Screen and its children provide one or more CodeBox objects which is a widget on the screen that displays code. You combine a series of purdy.ui.actions to display and alter the code. View more examples in the Sample Code section.


Library API

UI (purdy.ui.py)

This module is the entry point for the code viewers. It is a lightweight proxy to implementation of a screen. Screen implementations are found in purdy.iscreen. All programs using the purdy library need to create a Screen object or one of its children. The factory in this module determines which actual implementation is loaded.

class purdy.ui.CodeBox(starting_line_number=-1, auto_scroll=True, height=0, compact=False)

Specifies a box to contain code. Screen uses these to determine widget layout, subsequent actions are done within the context of this box. When CodeBox.build() is called by a Screen class a widget is built and this box is added to the screen.

Parameters:
  • starting_line_number – -1 means no line numbers, anything larger will be the first line number displayed. Defaults to -1

  • auto_scroll – When True, purdy.widgets.CodeBox created by this specification automatically scrolls to newly added content. Defaults to True.

  • height – Number of lines the row containing this box should be. A value of 0 indicates automatic spacing. Defaults to 0.

  • compact – if False, the dividing line between this box and the next has a 1-line empty boundary. Parameter is ignored if there is no item after this one in the rows=[] listing. Defaults to False

class purdy.ui.Screen(settings=None, rows=[], max_height=0)

Represents the main UI window for the TUI application. The layout is specified by passing in one or more CodeBox or TwinCodeBox objects to the constructor. Each box will have a corresponding purdy.widgets.CodeWidget inside of the UI for displaying code.

Parameters:
  • settings – a settings dictionary object. Defaults to None which uses the default settings dictionary: settings.settings

  • rows – a list containing one or more CodeBox or TwinCodeBox definitions, to specify the layout of the screen

  • max_height – maximum display height in TUI mode, defaults to 0, meaning no max

Example:

from purdy.actions import AppendAll
from purdy.content import Code
from purdy.ui import Screen, CodeBox, TwinCodeBox

screen = Screen(rows=[TwinCodeBox(height=8),
        CodeBox(auto_scroll=False)])

c1 = Code(contents_filename='c1.py', starting_line_number=1)
c2 = Code(contents_filename='c2.py')
c3 = Code(contents_filename='c3.py')

actions = [
    AppendAll(screen.code_boxes[0], c1),
    AppendAll(screen.code_boxes[1], c2),
    AppendAll(screen.code_boxes[2], c3),
]

screen.run(actions)

The above would produce a screen with two rows, the first row having two purdy.widgets.CodeWidget objects side by side, the second having a single one. The top left box would have line numbers turned on, both top boxes are 8 lines tall, and the bottom box has auto scrolling turned off.

The screen would be divided like this:

Command Line Parameters

Unless “deactivate_args” is set to True in purdy.settings (False by default), Screen will also parse command line arguments. This allows scripts calling the library to change their behaviour with switches.

Supported switches are:

  • –debugsteps Print out the animation steps, grouped by Cell and exit

  • –export Print out the results of the actions

  • –exportrtf Print out the results of the actions in RTF format

run(actions)

Calls the main display event loop. Does not return until the UI exits.

class purdy.ui.SimpleScreen(settings=None, starting_line_number=-1, auto_scroll=True, max_height=0)

Convenience implementation of Screen that supports a single CodeBox. The code box is available as SimpleScreen.code_box.

Parameters:
  • settings – a settings dictionary object. Defaults to None which uses the default settings dictionary: settings.settings

  • starting_line_number – starting line number for the created code box

  • auto_scroll – When True, the class:ui.CodeBox automatically scrolls to newly added content. Defaults to True.

  • max_height – maximum display height in TUI mode, defaults to 0, meaning no max

class purdy.ui.SplitScreen(settings=None, top_starting_line_number=-1, top_auto_scroll=True, bottom_starting_line_number=-1, bottom_auto_scroll=True, top_height=0, compact=False, max_height=0)

Convenience implementation of Screen that supports two CodeBox instances, stacked vertically and separated by a dividing line. The code boxes are SplitScreen.top and SplitScreen.bottom.

Parameters:
  • settings – a settings dictionary object. Defaults to None which uses the default settings dictionary: settings.settings

  • top_starting_line_number – starting line number for the top code box

  • top_auto_scroll – When True, the top ui.CodeBox automatically scrolls to newly added content. Defaults to True.

  • bottom_starting_line_number – starting line number for the bottom code box

  • bottom_auto_scroll – When True, the bottom ui.CodeBox automatically scrolls to newly added content. Defaults to True.

  • top_height – Number of lines the top box should be. A value of 0 indicates top and bottom should be the same size. Defaults to 0.

  • compact – True if for the dividing line between the top and bottom screens is to have no margin. Defaults to False

  • max_height – maximum display height in TUI mode, defaults to 0, meaning no max

class purdy.ui.TwinCodeBox(left_starting_line_number=-1, left_auto_scroll=True, left_weight=1, right_starting_line_number=-1, right_auto_scroll=True, right_weight=1, height=0, compact=False)

Specifies two side-by-side CodeBoxes. The contained CodeBoxes can be either accessed as twin.left and twin.right, or twin[0] and twin[1]. When TwinCodeBox.build() is called, the widgets are created and added to the Screen.code_boxes list sequentially, i.e. a single TwinCodeBox results in two CodeBox items in Screen’s list.

Parameters:
  • left_starting_line_number

  • right_starting_line_number – -1 to turn line numbers off, any higher value is the first number to display. Defaults to -1

  • left_auto_scroll

  • right_auto_scroll – True to specify that scrolling happens automatically for the left and right boxes created by this spec. Defaults to True.

  • left_weight

  • right_weight – relative weights for the widths of the columns, if the values are the same then the columns are the same width, otherwise the widths are formed based on the ratio of left:right. Example: left_weight=2, right_weight=1 means the left side will be twice the width of the right side. Both values default to 1.

  • height – number of lines for the row this set of boxes is in. The default of 0 specifies automatic height

  • compact – if False, the dividing line between this box and the next has a 1-line empty boundary. Parameter is ignored if there is no item after this one in the rows=[] listing. Defaults to False

Content

Reperesntations of source code are found in this module.

class purdy.content.Code(filename='', text='', lexer_name='detect', purdy_lexer=None)

Represents source code from the user.

Parameters:
  • filename – name of a file to read for content. If both this and text is given, filename is used first

  • text – a string containing code

  • lexer_name – name of lexer to use to tokenize the code, defaults to ‘detect’, attempting to auto detect the type of content. See purdy.parser.PurdyLexer for a list of available lexers.

  • purdy_lexer – if lexer_name is “custom” this parameter is expected to contain a purdy.parser.PurdyLexer object.

fold_lines(start, end)

Call this method to replace one or more lines with a vertical elipses, i.e. a fold of the code.

Parameters:
  • start – line number of the listing to start code folding on. 1-indexed.

  • end – line number to fold until, inclusive (1-indexed).

inline_replace(line_no, pos, content)

Replaces the contents of a line starting at pos with the new content

Parameters:
  • line_no – number of the line to replace, 1-indexed

  • pos – position number to start the replacement at, 1-indexed

  • content – content to replace with

insert_line(line_no, content)

Inserts the given line into the source, pushing the content down from the given line number

Parameters:
  • line_no – number of the line to insert at, 1-indexed

  • content – content to insert

left_justify()

Removes a consistent amount of leading whitespace from the front of each line so that at least one line is left-justified.

Warning

will not work with mixed tabs and spaces

python_portion(name, header=None)

Treates the source in this object as Python and then finds either the named function, class, or assigned variable and replaces the source with only the found item.

Warning

If the named item is not found your source will be empty!

Parameters:
  • name – dot notated name of a function or class. Examples: Foo.bar would find the bar method of class Foo or an inner function named bar in a function named Foo

  • header – optionally include another part of the source file before the parsed content. Typically used to include the header portion of a file. If given an integer, it will include the first X number of lines. If given a tuple “(x, y)” includes lines from x to y (inclusive)

remove_double_blanks(trim_whitespace=True)

Removes the second of two blanks in a row. If trim_whitespace is True (default) a line with only whitespace is considered blank, otherwise it only looks for n

remove_lines(line_no, count=1)

Removes one or more lines from the source listing.

Parameters:
  • line_no – number of the line to remove, 1-indexed

  • count – number of lines to remove, defaults to 1

replace_line(line_no, content)

Replaces the given line with new content

Parameters:
  • line_no – number of the line to replace, 1-indexed

  • content – content to replace it with

subset(start, end)

Returns a new Code object containing just the subset of lines identified in this call

Parameters:
  • start – line number of the listing to start the subset at. 1-indexed

  • end – line number to finish the subset on, inclusive. 1-indexed.

Returns:

Code object

Actions

Library users specify a series of actions that turn into the presentation animations in the Urwid client. An action is similar to a slide in a slide show, except it can both present and change lines of code on the screen.

All purdy library programs have the following basic structure:

screen = Screen(...)
actions = [ ... ]
screen.run(actions)

Each action gets translated into a series of steps defined in the purdy.animation module.

class purdy.actions.Append(code_box, code, pauses=[])

Adds the content of a purdy.content.Code object to the end of a purdy.ui.CodeBox.

Parameters:
class purdy.actions.AppendPrompt(code_box, code, response)

This action is used to show a prompt and its response. It appends the content of a purdy.content.Code object to a purdy.ui.CodeBox as a prompt, waits for the ‘right arrow’ key, then uses the typewriter animation to add the response to the same line.

Parameters:
  • code_box – the purdy.ui.CodeBox instance to append code into

  • code – a purdy.content.Code object containing the prompt code to insert.

  • response – text to place after the prompt

class purdy.actions.Clear(code_box)

Clears the contents of a purdy.ui.CodeBox.

Parameters:

code_box – the purdy.ui.CodeBox instance where the code is to be replaced

class purdy.actions.Fold(code_box, position, end=-1)

Folds code by replacing one or more lines with a vertical elipses symbol.

Parameters:
  • code_box – the purdy.ui.CodeBox instance to modify

  • position – line number to begin the fold at. Position is 1-indexed.

  • end – line number to finish the folding at, inclusive. A value of -1 can be used to fold to the end of the box. Defaults to -1.

class purdy.actions.Highlight(code_box, spec, highlight_on)

Cause one or more lines of code to have highlighting turned on or off

Parameters:
  • code_boxpurdy.ui.CodeBox to perform on

  • spec – either a string containing comma separated and/or hyphen separated integers (e.g. “1,3,7-9”) or a list of integers specifying the lines in the code box to highlight. Line numbers are 1-indexed

  • highlight_on – True to turn highligthing on, False to turn it off

class purdy.actions.HighlightChain(code_box, spec_list)

A common pattern with highlighting lines is to turn a highlight on for some set of lines, then turn it off and turn it on for more lines. This is a convenience wrapper to the Highlight action, turning items on and off in series.

Parameters:
  • code_boxpurdy.ui.CodeBox to perform series of highlight on

  • spec_list – a list of highlight specs (see Highlight for details on a spec)

class purdy.actions.Insert(code_box, position, code, pauses=[])

Inserts the content of a purdy.content.Code object to a specified line in a purdy.ui.CodeBox. Pushes content down, inserting at “1” is the beginning of the list. Position is 1-indexed

Parameters:
  • code_box – the purdy.ui.CodeBox instance to insert code into

  • position – line number to insert code at. Position is 1-indexed. Content is pushed down, so a value of “1” inserts at the beginning. Negative indicies are supported. A value of “0” will append the code to the bottom.

  • code – a purdy.content.Code object containing the source code to insert.

  • pauses – optional list of purdy.actions.Pause objects that specify where to insert pauses in the output

class purdy.actions.Pause(line_no, duration)

Used by some actions to indicate a delay between output lines.

Parameters:
  • line_no – line in block to insert pause after. Note that this does not differentiate between code and output, just lines in a block

  • duartion – time in seconds to delay (ints and floats supported)

class purdy.actions.Remove(code_box, position, size)

Removes one or more lines of a purdy.ui.CodeBox.

Parameters:
  • code_box – the purdy.ui.CodeBox instance where the code is to be replaced

  • position – line number to replace the code at. Position is 1-indexed. Negative indicies are supported.

  • size – number of lines to remove.

class purdy.actions.Replace(code_box, position, code)

Replaces one or more lines of a purdy.ui.CodeBox using the content of a purdy.content.Code object. This action attempts to overwrite using the number of lines in the purdy.content.Code object passed in, it is up to you to make sure there is enough space in your CodeBox.

Parameters:
  • code_box – the purdy.ui.CodeBox instance where the code is to be replaced

  • position – line number to replace the code at. Position is 1-indexed. Negative indicies are supported.

  • code – a purdy.content.Code object containing the source code to insert.

class purdy.actions.RunFunction(fn, undo, *args, **kwargs)

Calls the function passed in, allowing the execution of code during the playing of actions.

Parameters:
  • fn – function to be called

  • undo – function to be called when this Action is undone, can be None

  • *args – any remaining arguments are passed to the functions when they are called

  • **kwargs – any remaining arguments are passed to the functions when they are called

class purdy.actions.Section

Marker for the beginning of a section. In the TUI you can skip to the next section marker using “S”.

class purdy.actions.Shell(code_box, cmd)

Runs a shell command via subprocess. Does not display the command (you’re better off using a typewriter command to show it, then use this to spit out the results). Command and results are added to the purdy.ui.CodeBox.

Parameters:
  • code_box – the purdy.ui.CodeBox instance where the code is to be appended

  • cmd – string containing the shell command and its paramters. Example: ls -la.

class purdy.actions.Sleep(time)

Causes animations to pause for the given amount of time. Note that this action happens within a cell, so is considered part of the group of animation steps done together. For example if Append + Sleep + Append is part of the same cell it is all done/undone together.

Parameters:

time – Either the amount of time to sleep in seconds (ints and floats supported), or a tuple containing a pair of times specifying the range of a random value to sleep.

class purdy.actions.StopMovie

Causes the presentation purdy.ui.Screen to exit movie mode

class purdy.actions.Suffix(code_box, position, source)

Adds the provided text to the end of an existing line in a purdy.ui.CodeBox.

Parameters:
  • code_box – the purdy.ui.CodeBox instance where the code is to be appended

  • position – line number to replace the code at. Position is 1-indexed. Negative indicies are supported.

  • source – string containing content to append to the line

class purdy.actions.Transition(code_box, code=None, code_box_to_copy=None)

Replaces the contents of a purdy.ui.CodeBox with new content, doing a wipe animation from top to bottom. Only one of code or code_box_to_copy should be given, both can be blank to transition to an empty screen.

Parameters:
  • code_box – the purdy.ui.CodeBox instance to perform the transition on

  • code – a purdy.content.Code object containing the source code replacing the existing content. Should not be used at the same time as code_box_to_copy parameter.

  • code_box_to_copy – a code box containing rendered code to copy into this one to display. This is typically a VirtualCodeBox. Should not be used at the same time as code parameter.

class purdy.actions.Wait

Causes the animations to wait for a right arrow key press before continuing.

Typewriter Actions

Typewriter actions display code using a typewriter animation. Code content is displayed a letter at a time as if someone is typing. The purdy.settings module contains default values for typing speeds and variance time between letters being pressed.

When the code in question is based on a console, the typewriter will wait for the right arrow to be pressed whenever it sees a prompt. For example, when appending Python REPL code, the >>> will cause the interface to wait.

class purdy.actions.AppendTypewriter(code_box, code, pauses=[])

Adds the content of a purdy.content.Code object to a purdy.ui.CodeBox using the typewriter animation.

Parameters:
class purdy.actions.InsertTypewriter(code_box, position, code, pauses=[])

Inserts the contents of a purdy.content.Code object at the given position using the typewriter animation.

Parameters:
  • code_box – the purdy.ui.CodeBox instance to append code into

  • position – line number to insert the code at. Position is 1-indexed.

  • code – a purdy.content.Code object containing the source code to insert.

  • pauses – optional list of purdy.actions.Pause objects that specify where to insert pauses in the output

class purdy.actions.SuffixTypewriter(code_box, position, source)

Adds the provided text to the end of an existing line in a purdy.ui.CodeBox using a typewriter animation.

Parameters:
  • code_box – the purdy.ui.CodeBox instance to append code into

  • position – line number to insert the code at. Position is 1-indexed. Negative indicies are supported.

  • source – a string to be appended to the given line

Default Settings

settings.settings
"""
Settings (purdy.settings.py)
============================

Defines the default settings for :class:`purdy.ui.Screen` objects, can be
overridden by passing an altered dictionary into the Screen's constructor. 
"""

settings = {
    # delay between characters appearing on screen (in milliseconds)
    'delay':130,

    # range of random time in milliseconds to change the delay; makes typing
    # look more natural
    'delay_variance':30,

    # movie mode: instead of waiting for key presses, play like a movie, -1
    # disables, otherwise value in milliseconds for delay between played steps
    # (like 'delay' field
    'movie_mode':-1,

    # xterm colour mode, anything but 256 gives 16 colour mode
    'colour':256,

    # if True, stops Screen from running argparse
    'deactivate_args':False,

    # max height for presentation, only works in TUI mode, 0 == no max
    'max_height':0,
}